AgentAddress Generator
Universal identity for AI agents on the internet
AgentAddress is an open-source agent identification system: a unique, verifiable identity that works across any website that accepts AgentAddress authentication.
This tool runs locally in your browser. We don't store anything — your recovery phrase and secret key never leave your device.
Repo: github.com/Apoth3osis-ai/agent-address
Using AgentAddress with AgentPMT credits and workflows: /autonomous-agents
Programmatic no-auth endpoint for agents: POST /api/external/agentaddress
Click Generate New Agent Address to create a new identity.
Works on all EVM-compatible chains
API Flow Example (No Auth + x402 + Signed Tool Invoke)
This end-to-end Node/TypeScript example shows how an agent can: call /api/external/agentaddress, buy credits with x402 using a payment signature, and invoke a tool using a wallet signature.
import { createHash, randomBytes, randomUUID } from "node:crypto";
import { createPublicClient, createWalletClient, http, parseAbi } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { base, baseSepolia } from "viem/chains";
const API_BASE_URL = "https://www.agentpmt.com";
const BASE_RPC_URL = process.env.BASE_RPC_URL as string;
if (!BASE_RPC_URL) throw new Error("Set BASE_RPC_URL");
function canonicalize(value: unknown): unknown {
if (Array.isArray(value)) return value.map(canonicalize);
if (value && typeof value === "object") {
return Object.fromEntries(
Object.keys(value as Record<string, unknown>)
.sort()
.map((k) => [k, canonicalize((value as Record<string, unknown>)[k])]),
);
}
return value;
}
function canonicalJson(value: unknown): string {
return JSON.stringify(canonicalize(value));
}
async function run() {
// 1) No-auth wallet bootstrap
const walletResp = await fetch(\`\${API_BASE_URL}/api/external/agentaddress\`, {
method: "POST",
headers: { "Content-Type": "application/json" },
});
const walletJson = await walletResp.json();
const agent = walletJson.data as {
evmAddress: \`0x\${string}\`;
evmPrivateKey: \`0x\${string}\`;
mnemonic: string;
};
const account = privateKeyToAccount(agent.evmPrivateKey);
// 2) x402 credit purchase (PAYMENT-REQUIRED -> PAYMENT-SIGNATURE)
const desiredCredits = 500;
const purchaseInit = await fetch(\`\${API_BASE_URL}/api/external/credits/purchase\`, {
method: "POST",
headers: { "Content-Type": "application/json", Accept: "application/json" },
body: JSON.stringify({
wallet_address: account.address,
credits: desiredCredits,
payment_method: "x402",
}),
});
if (purchaseInit.status !== 402) {
throw new Error(\`Expected 402, got \${purchaseInit.status}\`);
}
const paymentRequiredHeader = purchaseInit.headers.get("PAYMENT-REQUIRED");
if (!paymentRequiredHeader) throw new Error("Missing PAYMENT-REQUIRED header");
const paymentRequired = JSON.parse(
Buffer.from(paymentRequiredHeader, "base64").toString("utf8"),
) as {
accepts: Array<{
network: string;
amount: string;
asset: \`0x\${string}\`;
payTo: \`0x\${string}\`;
}>;
};
const acceptance = paymentRequired.accepts[0];
const chainId = Number(acceptance.network.replace("eip155:", ""));
const chain = chainId === 8453 ? base : chainId === 84532 ? baseSepolia : null;
if (!chain) throw new Error(\`Unsupported chainId: \${chainId}\`);
const publicClient = createPublicClient({
chain,
transport: http(BASE_RPC_URL),
});
const walletClient = createWalletClient({
account,
chain,
transport: http(BASE_RPC_URL),
});
const usdcAbi = parseAbi([
"function name() view returns (string)",
"function version() view returns (string)",
]);
const [name, version] = await Promise.all([
publicClient.readContract({
address: acceptance.asset,
abi: usdcAbi,
functionName: "name",
}),
publicClient.readContract({
address: acceptance.asset,
abi: usdcAbi,
functionName: "version",
}),
]);
const validAfter = 0n;
const validBefore = BigInt(Math.floor(Date.now() / 1000) + 30 * 60);
const nonce = \`0x\${randomBytes(32).toString("hex")}\` as \`0x\${string}\`;
const amount = BigInt(acceptance.amount);
const signature = await walletClient.signTypedData({
account,
domain: {
name,
version,
chainId,
verifyingContract: acceptance.asset,
},
primaryType: "TransferWithAuthorization",
types: {
TransferWithAuthorization: [
{ name: "from", type: "address" },
{ name: "to", type: "address" },
{ name: "value", type: "uint256" },
{ name: "validAfter", type: "uint256" },
{ name: "validBefore", type: "uint256" },
{ name: "nonce", type: "bytes32" },
],
},
message: {
from: account.address,
to: acceptance.payTo,
value: amount,
validAfter,
validBefore,
nonce,
},
});
const paymentHeader = Buffer.from(
JSON.stringify({
x402Version: 2,
scheme: "exact",
network: acceptance.network,
payload: {
signature,
authorization: {
from: account.address,
to: acceptance.payTo,
value: acceptance.amount,
validAfter: validAfter.toString(),
validBefore: validBefore.toString(),
nonce,
},
},
}),
"utf8",
).toString("base64");
const purchaseResp = await fetch(\`\${API_BASE_URL}/api/external/credits/purchase\`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
"PAYMENT-SIGNATURE": paymentHeader,
},
body: JSON.stringify({
wallet_address: account.address,
credits: desiredCredits,
payment_method: "x402",
request_id: \`purchase-\${randomUUID()}\`,
}),
});
const purchaseJson = await purchaseResp.json();
if (!purchaseResp.ok) throw new Error(\`Purchase failed: \${JSON.stringify(purchaseJson)}\`);
// 3) Signed tool invocation using the purchased credits
const sessionResp = await fetch(\`\${API_BASE_URL}/api/external/auth/session\`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ wallet_address: account.address }),
});
const sessionJson = await sessionResp.json();
const sessionNonce = sessionJson.session_nonce as string;
const productId = "<productId>";
const parameters = { action: "get_instructions" };
const payloadHash = createHash("sha256").update(canonicalJson(parameters)).digest("hex");
const requestId = \`invoke-\${randomUUID()}\`;
const signMessage = [
"agentpmt-external",
\`wallet:\${account.address.toLowerCase()}\`,
\`session:\${sessionNonce}\`,
\`request:\${requestId}\`,
"action:invoke",
\`product:\${productId}\`,
\`payload:\${payloadHash}\`,
].join("\n");
const invokeSignature = await walletClient.signMessage({
account,
message: signMessage,
});
const invokeResp = await fetch(\`\${API_BASE_URL}/api/external/tools/\${productId}/invoke\`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
wallet_address: account.address,
session_nonce: sessionNonce,
request_id: requestId,
signature: invokeSignature,
parameters,
}),
});
const invokeJson = await invokeResp.json();
if (!invokeResp.ok) throw new Error(\`Invoke failed: \${JSON.stringify(invokeJson)}\`);
console.log({
wallet: account.address,
purchased_credits: purchaseJson.balance_credits,
invoke: invokeJson,
});
}
run().catch((err) => {
console.error(err);
process.exit(1);
});