Install
openclaw skills install @clawallex-tech/clawallexPay for anything with USDC — virtual cards for any online checkout
openclaw skills install @clawallex-tech/clawallexPay for anything with USDC. Clawallex converts your stablecoin balance into virtual cards that work at any online checkout.
refillNew user — browser signup (recommended):
python3 {baseDir}/scripts/clawallex.py signup
Returns a URL and token. Show the URL to the user, ask them to open it and click Authorize. The command polls automatically. If polling fails, retry with the token:
python3 {baseDir}/scripts/clawallex.py signup-check --token <token>
Existing user — connect with API keys:
Get your API Key and Secret at app.clawallex.com/dashboard/settings, then run:
python3 {baseDir}/scripts/clawallex.py setup --action connect --api-key YOUR_KEY --api-secret YOUR_SECRET
python3 {baseDir}/scripts/clawallex.py wallet # check balance
python3 {baseDir}/scripts/clawallex.py cards # list cards
setup --action status before any payment. If not configured: use signup for new accounts, or setup --action connect if the user already has API keys.wallet before pay or subscribe to verify sufficient funds (Mode A only).masked_pan from card-details.1. setup --action status → check config
2. wallet → check balance
3. pay --amount 50 --description "OpenAI" → create flash card
4. card-details --card-id <ID from step 3> → get encrypted card data
5. Decrypt PAN/CVV (HKDF + AES-256-GCM) → use ONLY for checkout form
1. wallet → check balance
2. subscribe --amount 100 --description "AWS billing" → create stream card
3. card-details --card-id <ID from step 2> → get card for sign-up form
4. refill --card-id <ID> --amount 50 → top up when balance is low
All commands:
python3 {baseDir}/scripts/clawallex.py <command> [args]
| User Intent | Command |
|---|---|
| Quick signup — browser-based new account creation (recommended for first-time setup) | signup |
| Check signup result with existing token | signup-check --token TOKEN |
| Connect account | setup --action connect --api-key KEY --api-secret SECRET |
| Check config status | setup --action status |
| Get sign-up link | setup --action register |
| Check API Key binding | whoami |
| Bind client_id | bootstrap or bootstrap --preferred-client-id MY_ID |
| User Intent | Command |
|---|---|
| Pay for something | pay --amount N --description "X" |
| Pay with custom expiry | pay --amount N --description "X" --ttl SECONDS — flash card only; default 86400 (24 h) |
| Start subscription | subscribe --amount N --description "X" |
| Top up card | refill --card-id CID --amount N |
| User Intent | Command |
|---|---|
| Check balance | wallet |
| Deposit funds | recharge-addresses --wallet-id WID |
| List cards | cards — returns mode_code (100=Mode A, 200=Mode B) to determine refill path |
| Check card balance | card-balance --card-id CID |
| Batch check balances | batch-balances --card-ids CID1,CID2 — multiple cards in one call |
| Update card controls | update-card --card-id CID --client-request-id UUID [--tx-limit] [--allowed-mcc] [--blocked-mcc] |
| Get card details | card-details --card-id CID — returns masked_pan, expiry, balance, first_name, last_name, tx_limit, allowed_mcc, blocked_mcc, encrypted PAN/CVV |
| View transactions | transactions |
| User Intent | Command |
|---|---|
| Get x402 payee address | x402-address --chain ETH --token USDC — MUST call before Mode B Refill |
When the user wants to use Clawallex for the first time:
setup --action status to check current configuration.setup --action connect --api-key KEY --api-secret SECRET
signup
signup-check --token <token from signup output>
wallet to confirm connection works.Signup result statuses — all returned as success: true:
pending — user hasn't authorized yet, call signup-check againok — credentials saved, ready to usecancelled — user cancelled, ask if they want to try againalready_exists — account already has API keys, switch to setup --action connectMode B is for callers with self-custody wallets (agent or user) (DeFi bots, autonomous purchasing agents). The agent signs on-chain transactions using its own signing system — no human intervention needed.
Stage 1 — Quote:
pay --amount 200 --description "GPU rental" --mode-code 200 --chain-code ETH --token-code USDC
The 402 response is EXPECTED — it is a quote, NOT an error. Returns:
client_request_id, payee_address, asset_address, x402_reference_idfinal_card_amount, issue_fee_amount, fx_fee_amount, fee_amount, payable_amountFee structure:
fee_amount = issue_fee_amount + fx_fee_amountfee_amount = issue_fee_amount + monthly_fee_amount + fx_fee_amountAgent signs — construct and sign an EIP-3009 transferWithAuthorization using your own wallet/signing library and the quote details. Only the resulting signature and your wallet address are needed for Stage 2.
EIP-3009 enables gasless USDC transfers via off-chain signatures. The authorization fields map to:
from: your wallet address (the payer)to: payee_address from Stage 1 (system receiving address)value: maxAmountRequired (payable_amount in token minimal units, USDC = 6 decimals)validAfter / validBefore: unix timestamps (seconds) defining the signature validity windownonce: random 32-byte hex, must be unique per authorizationStage 2 — Settle (MUST use same client_request_id):
pay --amount 200 --description "GPU rental" \
--mode-code 200 \
--client-request-id "uuid-from-stage-1" \
--x402-version 1 \
--payment-payload '{
"scheme": "exact",
"network": "ETH",
"payload": {
"signature": "0x<agent EIP-3009 signature>",
"authorization": {
"from": "0x<agent wallet address>",
"to": "<payee_address from stage 1>",
"value": "<maxAmountRequired, e.g. 207590000>",
"validAfter": "<unix timestamp seconds>",
"validBefore": "<unix timestamp seconds>",
"nonce": "0x<random 32-byte hex>"
}
}
}' \
--payment-requirements '{
"scheme": "exact",
"network": "ETH",
"asset": "<asset_address from stage 1>",
"payTo": "<payee_address from stage 1>",
"maxAmountRequired": "<payable_amount × 10^6, e.g. 207590000>",
"extra": {
"referenceId": "<x402_reference_id from stage 1>"
}
}' \
--extra '{"card_amount": "200.0000", "paid_amount": "<payable_amount, e.g. 207.5900>"}'
Stage 2 constraints:
--client-request-id MUST be identical to Stage 1 — a different value creates a NEW orderpayment_requirements.payTo MUST equal payee_address from Stage 1payment_requirements.asset MUST equal asset_address from Stage 1payment_requirements.maxAmountRequired MUST equal payable_amount × 10^decimals (USDC = 6 decimals)payment_requirements.extra.referenceId MUST equal x402_reference_id from Stage 1extra.card_amount MUST equal the --amountextra.paid_amount MUST equal payable_amount from Stage 1 (amount + fee_amount)payment_payload.network MUST equal payment_requirements.networkpayload.authorization.to MUST equal payment_requirements.payTopayload.authorization.value MUST equal payment_requirements.maxAmountRequiredextra.mode=STANDARD — any client-provided value is ignoredpending_payment — fix params and retry with same client_request_idMode B refill goes directly to x402 settle — no 402 challenge stage. Caller signs the EIP-3009 authorization independently using their own wallet/signing library; only the resulting signature and wallet address are submitted. Must call x402-address first to get payee_address.
1. x402-address --chain ETH --token USDC → get payee_address
2. refill --card-id c_123 --amount 50 \
--x402-reference-id "<unique reference id>" \
--x402-version 1 \
--payment-payload '{
"scheme": "exact",
"network": "ETH",
"payload": {
"signature": "0x<EIP-3009 signature>",
"authorization": {
"from": "0x<agent wallet>",
"to": "<payee_address from step 1>",
"value": "<amount × 10^6>",
"validAfter": "<unix seconds>",
"validBefore": "<unix seconds>",
"nonce": "0x<random 32-byte hex>"
}
}
}' \
--payment-requirements '{
"scheme": "exact",
"network": "ETH",
"asset": "<asset contract address>",
"payTo": "<payee_address from step 1>",
"maxAmountRequired": "<amount × 10^6>",
"extra": { "referenceId": "<x402_reference_id>" }
}'
Mode B refill idempotency key is x402_reference_id (not client_request_id).
Check cards mode_code to determine which refill path the card uses.
card-details returns encrypted_sensitive_data with encrypted PAN/CVV:
HKDF-SHA256(ikm=api_secret, salt=empty, info="clawallex/card-sensitive-data/v1", length=32)nonce = base64_decode(nonce), raw = base64_decode(ciphertext)encrypted_data = raw[:-16], auth_tag = raw[-16:]AES-256-GCM(key, nonce, encrypted_data, auth_tag) → JSON{"pan": "4111111111111111", "cvv": "123"}| Error | Cause | Action |
|---|---|---|
| "not configured" | No credentials saved | Run setup --action connect with valid credentials |
| "Invalid credentials" | Wrong API Key/Secret | Check at app.clawallex.com/dashboard/settings |
| Insufficient balance | Wallet balance too low | Run recharge-addresses for deposit info, or use Mode B |
| 402 response | Mode B Stage 1 (expected) | This is the quote — proceed to Stage 2 with same client_request_id |
| Settle rejected (Mode B) | Invalid x402 params | Order stays pending_payment — fix params and retry with same client_request_id |
| Card not found | Wrong card_id | Run cards to list valid card IDs |
| Decryption failed | Bad data or apiSecret changed | Re-fetch via card-details, verify credentials |
All commands return JSON:
success: true → data in data field, next steps in _hintsuccess: false → error message in error fieldpay. Single-use, auto-destroyed after one transaction. Cannot be refilled.subscribe. Reloadable, top up with refill.client_id never changes. Cards and transactions are isolated per client_id. When switching to a new API Key, keep using the same client_id — the new key auto-binds on first request. Once bound, it cannot be changed (TOFU). Stored locally at ~/.clawallex/credentials.json.