Skip to main content

Wallet API

Manage wallets for on-chain transactions and payments. Supports session-based wallets, Coinbase Developer Platform (CDP) wallets, and Tempo network balance queries.

Get wallet

GET /api/wallet
Returns wallet information. Behavior depends on whether an address query parameter is provided and on your server configuration.

Tempo balance query

When the address query parameter is present, the endpoint queries the Tempo blockchain for the wallet’s balance and fee token information.
GET /api/wallet?address=0xd8fd...db56f

Query parameters

ParameterTypeRequiredDescription
addressstringYesHex-encoded wallet address (0x-prefixed)

Response

{
  "address": "0xd8fd0e1dce89beaab924ac68098ddb17613db56f",
  "chain": "Tempo",
  "chainId": 4217,
  "testnet": false,
  "feeToken": {
    "address": "0x20c0000000000000000000000000000000000000",
    "balance": "12.470000",
    "balanceRaw": "12470000"
  },
  "pathUsd": {
    "address": "0x20c0000000000000000000000000000000000000",
    "balance": "12.470000",
    "balanceRaw": "12470000"
  }
}

Response fields

FieldTypeDescription
addressstringThe queried wallet address
chainstringNetwork name (Tempo or Tempo Testnet)
chainIdnumberChain ID (4217 for mainnet, 42431 for testnet)
testnetbooleanWhether the server is configured for testnet
feeToken.addressstringContract address of the user’s configured fee token
feeToken.balancestringFee token balance formatted with 6 decimals
feeToken.balanceRawstringFee token balance in raw units
pathUsd.addressstringpathUSD contract address
pathUsd.balancestringpathUSD balance formatted with 6 decimals
pathUsd.balanceRawstringpathUSD balance in raw units
Balance values are formatted to 6 decimal places. pathUSD uses 6 decimals, not 18. The network is determined server-side by the TEMPO_TESTNET environment variable.

Errors

CodeDescription
400Missing address parameter
500Failed to fetch wallet data from Tempo RPC

CDP / session wallet query

When no address parameter is provided, the endpoint returns CDP or session-based wallet information. When CDP is configured, returns CDP status without authentication. Otherwise, requires session authentication.

Response (CDP configured)

{
  "agenticWallet": {
    "status": "configured",
    "projectId": "abc12345...",
    "features": [
      "create_wallet",
      "get_balance",
      "send_usdc",
      "trade_tokens",
      "x402_payments"
    ]
  },
  "instructions": "CDP Agentic Wallet is configured. Use /api/wallet/cdp/* endpoints."
}

Response (user wallet exists)

{
  "address": "0x...",
  "balance": "0",
  "network": "base-sepolia",
  "hasWallet": true,
  "createdAt": "2026-03-01T00:00:00Z"
}

Response (no wallet)

{
  "address": null,
  "balance": "0",
  "network": "base-sepolia",
  "hasWallet": false,
  "message": "No wallet found. Create one to get started."
}

Errors

CodeDescription
401Unauthorized (no session and CDP not configured)

Wallet actions

POST /api/wallet
Requires session authentication.

Request body

FieldTypeRequiredDescription
actionstringYesOne of: create, get_seed, export_seed

Action: create

Creates a new wallet for the authenticated user.
{
  "address": "0x...",
  "network": "base-sepolia",
  "message": "Wallet created successfully"
}
Returns 400 if a wallet already exists.

Action: get_seed

Returns wallet metadata. Private keys are stored encrypted server-side and are never exposed.
{
  "address": "0x...",
  "network": "base-sepolia",
  "createdAt": "2026-03-01T00:00:00Z",
  "warning": "Private keys are stored encrypted server-side and never exposed."
}

Action: export_seed

Seed export is disabled for security. Returns 403.
{
  "error": "Seed export is disabled for security. Contact support if you need your private key."
}

Errors

CodeDescription
400Invalid action or wallet already exists
401Unauthorized
404No wallet found (for get_seed)

Get CDP wallet address

GET /api/wallet/address
Returns the address of the CDP Agentic Wallet.

Response (authenticated)

{
  "authenticated": true,
  "address": "0x..."
}

Response (not authenticated)

When the CDP wallet address cannot be retrieved, the response includes authenticated: false and needsAuth: true. The remaining fields vary by failure reason:
{
  "authenticated": false,
  "needsAuth": true,
  "message": "Run: npx awal auth login your@email.com"
}
If the failure is caused by a configuration error, the response includes error and setup fields instead of message:
{
  "authenticated": false,
  "needsAuth": true,
  "error": "Error description",
  "setup": "Install: npx skills add coinbase/agentic-wallet-skills"
}

Create CDP wallet

POST /api/wallet/create
Creates a new wallet using the Coinbase Developer Platform SDK.

Request body

FieldTypeRequiredDescription
emailstringYesEmail address for wallet registration

Response

{
  "success": true,
  "walletAddress": "0x...",
  "walletId": "wallet_789",
  "networks": ["base-sepolia", "base"]
}

Errors

CodeDescription
400Email required
500CDP not configured. Response includes a setup field with configuration instructions. Generic errors include a details field with the error message.

CDP wallet status

GET /api/wallet/cdp
Returns supported chain information for the CDP wallet.
{
  "status": "ok",
  "type": "evm_wallet",
  "supportedChains": ["base", "base-sepolia"]
}

Create CDP wallet client

POST /api/wallet/cdp
Creates a viem wallet client on Base Sepolia.

Request body

FieldTypeRequiredDescription
privateKeystringNoPrivate key (0x-prefixed). A new key is generated if omitted.

Response

{
  "success": true,
  "address": "0x...",
  "network": "base-sepolia"
}

USDC transfer validation

When transferring USDC through the wallet service, the following validation rules apply:
  • The transfer amount must be a positive finite number. Values such as NaN, Infinity, negative numbers, and zero are rejected.
  • Amounts are rounded to 6 decimal places (USDC precision). If the rounded value equals zero, the transfer is rejected.
These checks run before any on-chain transaction is initiated.
When payments are initiated through the x402 pay action, additional protections apply: a per-payment maximum of $100, recipient address format validation (EVM or Solana), and audit logging of every payment attempt. See the x402 gateway reference for details.

Wallet top-up

Fund your wallet via Stripe checkout to credit your payment session balance.

Create checkout session

GET /api/wallet/top-up?amount=1000
Creates a Stripe checkout session for wallet top-up. Requires session authentication.

Query parameters

ParameterTypeRequiredDefaultDescription
amountnumberNo1000Amount in cents. Valid values: 500 (5),1000(5), `1000` (10), 2500 (25),5000(25), `5000` (50).

Response

{
  "url": "https://checkout.stripe.com/...",
  "sessionId": "cs_live_..."
}
FieldTypeDescription
urlstringStripe checkout URL. Redirect the user here to complete payment.
sessionIdstringStripe checkout session ID

Errors

CodeDescription
400Invalid amount. Must be one of: 500, 1000, 2500, 5000 (cents).
401Unauthorized — session authentication required
500Stripe not configured or failed to create checkout session

Stripe webhook

POST /api/wallet/top-up
Handles the Stripe checkout.session.completed webhook to credit the user’s wallet after payment. This endpoint verifies the Stripe webhook signature before processing.
This endpoint is called by Stripe, not by your application. Configure your Stripe webhook to point to this URL with the checkout.session.completed event.

Errors

CodeDescription
400Invalid Stripe webhook signature
500Stripe not configured or webhook processing failed

MPP payment sessions

Payment sessions enable off-chain, per-call billing for agent requests. Instead of settling every call on-chain, you deposit funds into a session and sign lightweight vouchers that are batched and settled periodically. When you send a request to the gateway with X-Session-Id and X-Wallet-Address headers, the gateway auto-debits your session balance and returns the updated balance in the X-Session-Remaining response header. See MPP payments — sessions for the full protocol description.

List sessions

GET /api/wallet/sessions?address=0x...
Returns all sessions (active and closed) for the given wallet address.

Query parameters

ParameterTypeRequiredDescription
addressstringYesHex-encoded wallet address (0x-prefixed)

Response

{
  "sessions": [
    {
      "id": "ses_a1b2c3d4e5f6...",
      "userAddress": "0x...",
      "deposit": "10.00",
      "spent": "1.25",
      "remaining": "8.75",
      "vouchers": [],
      "status": "active",
      "createdAt": 1742472000000,
      "lastSettledAt": 1742472000000
    }
  ]
}

Get session

GET /api/wallet/sessions?sessionId=ses_...
Returns a single session by ID.

Query parameters

ParameterTypeRequiredDescription
sessionIdstringYesSession ID (prefixed with ses_)

Response

{
  "session": {
    "id": "ses_a1b2c3d4e5f6...",
    "userAddress": "0x...",
    "deposit": "10.00",
    "spent": "1.25",
    "remaining": "8.75",
    "vouchers": [],
    "status": "active",
    "createdAt": 1742472000000,
    "lastSettledAt": 1742472000000
  }
}

Errors

CodeDescription
400Missing address or sessionId parameter
404Session not found

Session fields

FieldTypeDescription
idstringUnique session ID (ses_ prefix)
userAddressstringWallet address that owns the session
depositstringTotal deposited amount in USD
spentstringTotal spent via vouchers in USD
remainingstringRemaining balance in USD
vouchersarrayPending vouchers not yet settled on-chain
statusstringOne of active, settling, or closed
createdAtnumberUnix timestamp (ms) when the session was created
lastSettledAtnumberUnix timestamp (ms) of the last on-chain settlement

Create session

POST /api/wallet/sessions
Opens a new payment session. If the wallet already has an active session, the existing session is returned instead.

Request body

FieldTypeRequiredDescription
addressstringYesHex-encoded wallet address (0x-prefixed)
depositstringYesDeposit amount in USD (minimum 1.00, maximum 100.00)

Response (201 Created)

{
  "session": {
    "id": "ses_a1b2c3d4e5f6...",
    "userAddress": "0x...",
    "deposit": "10.00",
    "spent": "0.00",
    "remaining": "10.00",
    "vouchers": [],
    "status": "active",
    "createdAt": 1742472000000,
    "lastSettledAt": 1742472000000
  }
}

Response (existing session)

{
  "session": { ... },
  "note": "Active session already exists"
}

Errors

CodeDescription
400Missing address or deposit, deposit below minimum, or deposit above maximum

Close session

DELETE /api/wallet/sessions?sessionId=ses_...
Closes an active session. Any pending vouchers are settled on-chain first, and the remaining balance is returned to the user.

Query parameters

ParameterTypeRequiredDescription
sessionIdstringYesSession ID to close

Response

{
  "success": true,
  "returned": "8.75"
}
FieldTypeDescription
successbooleanWhether the session was closed
returnedstringAmount in USD returned to the user

Errors

CodeDescription
400Missing sessionId, or session could not be closed

Submit voucher

POST /api/wallet/sessions/voucher
Submits a signed voucher to debit the session balance off-chain. This is the primary billing mechanism during an active session — each agent call produces one voucher.

Request body

FieldTypeRequiredDescription
sessionIdstringYesActive session ID
userAddressstringYesWallet address that owns the session (0x-prefixed)
pluginstringYesPlugin identifier (e.g., agent, generate-text, tts, stt)
signaturestringYesUser’s hex-encoded signature (0x-prefixed)
noncestringYesUnique nonce for this voucher
The voucher amount is determined automatically from the plugin’s pricing. See plugin pricing for current rates.

Response

{
  "success": true,
  "session": {
    "id": "ses_a1b2c3d4e5f6...",
    "spent": "0.05",
    "remaining": "9.95",
    "pendingVouchers": 1
  },
  "voucher": {
    "amount": "0.05",
    "plugin": "agent",
    "description": "Agent orchestrator request"
  }
}

Response fields

FieldTypeDescription
session.idstringSession ID
session.spentstringUpdated total spent in USD
session.remainingstringUpdated remaining balance in USD
session.pendingVouchersnumberNumber of vouchers pending on-chain settlement
voucher.amountstringAmount debited for this call in USD
voucher.pluginstringPlugin that was called
voucher.descriptionstringHuman-readable description of the charge

Errors

CodeDescription
400Missing required fields, unknown plugin, session not found, session not active, address mismatch, or insufficient balance
500Internal error processing the voucher