refill_card
Refill a virtual payment card with USDC stablecoin funds for online checkouts. Supports two payment modes: Mode A uses client request ID for idempotency, while Mode B requires EIP-3009 authorization signing for direct wallet transfers.
Instructions
Advanced: refill a stream card with full control over payment mode. Maps directly to POST /payment/cards/:card_id/refill. Refill mode follows the card's creation mode (cannot switch mid-life).
Mode A: client_request_id as idempotency key. Mode B: no 402 challenge — caller signs the EIP-3009 authorization independently. Step 1: call get_x402_payee_address to get payee_address for payment_requirements.payTo. Step 2: sign EIP-3009 transferWithAuthorization using your own wallet/signing library. Step 3: submit with x402_reference_id as idempotency key + payment_payload (signature + wallet address) + payment_requirements.
Only cards created by this agent (same client_id) can be refilled.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| card_id | Yes | Stream card ID to refill, e.g. 'c_123' | |
| amount | Yes | Refill amount in USD, decimal string e.g. '30.0000' | |
| client_request_id | No | UUID idempotency key — REQUIRED for Mode A. Omitting on a Mode A card will cause the server to reject the request. Reuse the same UUID to retry safely without double-charging. | |
| x402_reference_id | No | x402 reference ID. Card creation Stage 1: optional (server generates if omitted). Stage 2: use value from 402 response. Refill Mode B: required, serves as idempotency key. | |
| x402_version | No | x402 version (Mode B Stage 2, required) | |
| payment_payload | No | x402 payment payload (Mode B Stage 2, required) | |
| payment_requirements | No | x402 payment requirements (Mode B Stage 2, required) | |
| payer_address | No | Payer wallet address (optional, final value from verify) |
Implementation Reference
- src/tools/refill.ts:35-55 (handler)The handler function for the refill_card tool, which constructs the request body and calls the ClawallexClient post method to initiate a card refill.
async (params) => { try { const body: Record<string, unknown> = { amount: params.amount, }; if (params.client_request_id !== undefined) body.client_request_id = params.client_request_id; if (params.x402_reference_id !== undefined) body.x402_reference_id = params.x402_reference_id; if (params.x402_version !== undefined) body.x402_version = params.x402_version; if (params.payment_payload !== undefined) body.payment_payload = params.payment_payload; if (params.payment_requirements !== undefined) body.payment_requirements = params.payment_requirements; if (params.payer_address !== undefined) body.payer_address = params.payer_address; const result = await client.post<unknown>( `/payment/cards/${params.card_id}/refill`, body, ); return toolOk(result); } catch (err) { return toolError(err); } }, - src/tools/refill.ts:8-56 (registration)Registration of the refill_card tool, including schema validation definitions.
server.tool( "refill_card", [ "Advanced: refill a stream card with full control over payment mode.", "Maps directly to POST /payment/cards/:card_id/refill.", "Refill mode follows the card's creation mode (cannot switch mid-life).", "", "Mode A: client_request_id as idempotency key.", "Mode B: no 402 challenge — caller signs the EIP-3009 authorization independently.", " Step 1: call get_x402_payee_address to get payee_address for payment_requirements.payTo.", " Step 2: sign EIP-3009 transferWithAuthorization using your own wallet/signing library.", " Step 3: submit with x402_reference_id as idempotency key + payment_payload (signature + wallet address) + payment_requirements.", "", "Only cards created by this agent (same client_id) can be refilled.", ].join("\n"), { card_id: z.string().describe("Stream card ID to refill, e.g. 'c_123'"), amount: z.string().describe("Refill amount in USD, decimal string e.g. '30.0000'"), client_request_id: z .string() .max(64) .describe( "UUID idempotency key — REQUIRED for Mode A. Omitting on a Mode A card will cause the server to reject the request. Reuse the same UUID to retry safely without double-charging.", ) .optional(), ...x402Fields, }, async (params) => { try { const body: Record<string, unknown> = { amount: params.amount, }; if (params.client_request_id !== undefined) body.client_request_id = params.client_request_id; if (params.x402_reference_id !== undefined) body.x402_reference_id = params.x402_reference_id; if (params.x402_version !== undefined) body.x402_version = params.x402_version; if (params.payment_payload !== undefined) body.payment_payload = params.payment_payload; if (params.payment_requirements !== undefined) body.payment_requirements = params.payment_requirements; if (params.payer_address !== undefined) body.payer_address = params.payer_address; const result = await client.post<unknown>( `/payment/cards/${params.card_id}/refill`, body, ); return toolOk(result); } catch (err) { return toolError(err); } }, );