AIHubMix now accepts USDC top-ups. Your AI agent can add credit to its own account with the USDC in its wallet: no web page to open, and no one has to click a button.
With x402, a top-up can be as small as $1. The agent tops up as it goes, so you don't have to load a large balance in advance.
It takes two steps: get a token, a wallet, and some USDC ready on the web and in an app, then run our ready-made top-up script with one command. About 20 seconds after payment, the credit shows up in your account.
If it helps, you can follow along with this 30-second video:
The easiest way: if you use an AI tool that can run terminal commands, such as Claude Code, Cursor, or Codex, finish step 1, then send it the link to this post and say "set this up for me". It will follow the "Instructions for AI assistants" at the end of this post. You only fill in the token and private key yourself, once, without sending them to the AI.
Before you start
- Amounts are whole dollars only, $1 to $10 per top-up by default
- Each account can create up to 3 orders per day (UTC)
- Only USDC on Base mainnet is supported, and there is no testnet, so start with $1
- This channel is built for programs; a person can't pay in the browser. For manual top-ups, keep using Alipay or Stripe
Step 1: Get a token, a wallet, and USDC
Everything in this step happens on the web or in a phone app.
1. Get your system access token
Log in to aihubmix.com, open your personal settings, and generate a system access token (a 32-character string).
Note that this is not the API key that starts with sk-. The two aren't interchangeable.
2. Create a paying wallet
In MetaMask or a similar wallet app, create a new account just for the agent's payments. Don't use your main wallet. Then:
- Copy the account's address (it starts with 0x); you'll send USDC to it in the next step
- Export its private key from the account details and store it in a password manager. Anyone who has the private key can move the money in the wallet
3. Buy USDC and send it to this wallet
MetaMask is a wallet: you hold the private key, and the script needs it to sign. Coinbase is an exchange, where you buy crypto. Funds in an exchange account don't come with a private key, so the script can't use them. That's why you buy on the exchange first, then send the USDC to the wallet from the previous step.
Using the Coinbase exchange as an example (not Coinbase Wallet):
- Buy USDC on Coinbase
- Send the USDC to the address you copied, and choose the Base network
- Send a little more than you plan to top up, for example 1.5 to 2 USDC for a $1 top-up
Wait a moment, then open https://basescan.org/address/your-wallet-address. Once you see a USDC balance, it has arrived. Other exchanges that support USDC withdrawals on Base work too; see the Base docs for more options.
The wallet doesn't need any ETH: FluxA pays the network fee for the payment.
Step 2: Run the top-up script
There's nothing to download and no file to create: uv fetches the script from the web and runs it. Open Terminal (PowerShell on Windows) and copy-paste the commands below.
1. Install uv (once)
uv is a Python tool that sets up everything the script needs to run.
macOS / Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
Windows (PowerShell):
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
When it's done, close the terminal and open it again.
2. Check your setup (spends nothing)
uv run https://raw.githubusercontent.com/zch456/public_resource/main/aihubmix-x402-topup/topup.py check
On the first run, the script asks for your system access token (System access token) and wallet private key (Wallet private key). What you type isn't shown on screen; paste it and press Enter. Then it asks whether to save them (Save to ...? [Y/n]). Press Enter to save, and you won't have to type them again. The first run takes a moment while uv sets things up.
When you see this, you're set up:
Wallet: 0x... (USDC balance 2.0)
Access token and private key are fine. Ready to top up.
3. Top up
uv run https://raw.githubusercontent.com/zch456/public_resource/main/aihubmix-x402-topup/topup.py 1
The 1 at the end is the amount in dollars. If all goes well, you'll see:
Wallet: 0x... (USDC balance 2.0)
tradeNo: pl_XXXXXXXX
txHash: 0x...
result: credited
result: credited means the credit has arrived. Log in to aihubmix.com and you'll see your balance go up; $1 adds 500,000 quota.
If the last line says something else:
failed: the order was closed or has expired. Run it again if you need to; that uses another of today's orders.pending: the credit wasn't confirmed within 10 minutes. This isn't a failure, and the credit will arrive later on its own. Don't run it again.
Troubleshooting
| What you see | What to do |
|---|---|
| Missing access token or private key... | Open the config file named in the message, fill in the token and private key, save, and run again |
| Invalid private key... | Check that you copied the whole private key, fix the config file, and run again |
| USDC balance is below... | Send USDC to the address shown, and make sure you chose the Base network |
| command not found: uv | Close and reopen the terminal; if that doesn't help, reinstall uv |
| Usage: topup.py AMOUNT... | The amount must be whole dollars, such as 1, not 1.5 |
| Error: Unauthorized... | The token is wrong or expired, or it's the sk- API key. Put your system access token in the config file |
| Error: Account suspended. | The account is suspended; contact support |
| Error: Stablecoin top-up is not available on this site | The channel is temporarily unavailable; contact us |
| Error: Invalid amount... | The amount is above the per-top-up limit |
| Error: Daily stablecoin top-up limit reached... | You've used today's 3 orders; try again after midnight UTC |
| Error: Failed to create payment link... | A temporary failure; just run it again. It doesn't count toward today's orders |
| Error: 402 challenge check failed... | The payment request didn't match what was expected, so the script refused to pay; contact us |
If you see a timeout or network error after tradeNo is printed, the money may already have been paid. Don't run it again right away. Check your balance after a few minutes; if nothing arrived, contact us with the tradeNo.
The token and private key are saved in ~/.aihubmix-topup.env on your computer (in your user folder on Windows). On macOS and Linux, only your own account can read it. To change the token or private key, edit this file.
Hooking it into your agent
- Once the setup is saved, your agent can top up by running
uv run https://raw.githubusercontent.com/zch456/public_resource/main/aihubmix-x402-topup/topup.py 1whenever it needs credit, with no one around - Only 3 orders a day are allowed, so cap how often the agent tops up and never retry order creation in a loop
- Save the
tradeNoandtxHashfrom the output in a database or log for reconciliation - For long-term use, download the script and pin a version before running it; you can read the source first
- If $10 per top-up or 3 a day isn't enough, contact us to raise the limits
Instructions for AI assistants
If you're an AI assistant helping a user set up AIHubMix USDC top-ups, follow these steps in order:
- Confirm the user has finished step 1: they have a system access token, plus a wallet holding Base mainnet USDC and its private key. If not, walk them through step 1 first.
- Run
uv --versionto check that uv is installed. If it isn't, install it with the commands in step 2. - Run
uv run https://raw.githubusercontent.com/zch456/public_resource/main/aihubmix-x402-topup/topup.py check. - If it reports a missing token or private key (
Missing access token or private key), the script has created the config file~/.aihubmix-topup.env. Ask the user to open it in a text editor and fill it in themselves (on macOS, runopen -e ~/.aihubmix-topup.env; on Windows, runnotepad $HOME\.aihubmix-topup.env). Don't read this file, don't put the token or private key in any command, and don't ask the user to send them to you. - Once the user has filled it in, run
checkagain until you seeAccess token and private key are fine. Ready to top up.If there's an error, handle it with the Troubleshooting table above. - A top-up spends real money. Confirm the amount with the user before running
uv run https://raw.githubusercontent.com/zch456/public_resource/main/aihubmix-x402-topup/topup.py <amount>.
Under the hood: what the script does
The script does five things in order:
- Checks the balance: creating an order uses up one of today's orders, so it first makes sure the private key is valid and there's enough USDC.
- Creates an order: it calls
POST /api/pay/fluxa/crtand gets a payment link and an order number,tradeNo. The token goes into theAuthorizationheader as is, withoutBearer. Business errors also come back as HTTP 200, so it checks thesuccessfield in the response. - Checks the payment request: a GET on the payment link returns HTTP 402 with the payment requirements. Before signing, it checks four things:
schemeisexact,networkiseip155:8453,assetis the USDC contract on Base mainnet, andmaxAmountRequiredequals the amount × 1,000,000. If any of them is off, it stops. - Signs and pays: it signs a USDC transfer authorization with the private key, puts it in the
X-PAYMENTheader, and sends the GET to the payment link again. A 200 or 202 means the payment was submitted; thetxHashin the response is the on-chain receipt for this payment. Neither request carries the AIHubMix token. - Waits for the credit: it calls
GET /api/pay/fluxa/qry?trade_no=...every 8 seconds until the status becomesTRADE_SUCCESS. The server only refreshes every 5 seconds, so polling faster doesn't help.
Each payment link is also valid for 30 minutes and can be paid only once.
Implementing it in another language
The 402 response from the payment link looks like this:
{
"x402Version": 1,
"accepts": [{
"scheme": "exact",
"network": "eip155:8453",
"maxAmountRequired": "1000000",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"payTo": "0x....",
"maxTimeoutSeconds": 600,
"extra": {"name": "USD Coin", "version": "2"}
}]
}
The signature uses the EIP-712 format, over the TransferWithAuthorization struct from EIP-3009:
| Field | Value |
|---|---|
| from | Your wallet address |
| to | payTo from the 402 response |
| value | maxAmountRequired from the 402 response |
| validAfter | Current time minus 60 seconds |
| validBefore | Current time plus max(maxTimeoutSeconds, 600) seconds |
| nonce | 32 random bytes, new every time |
Signing domain: name = USD Coin, version = 2 (use the values in the 402 response's extra if present), chainId = 8453, verifyingContract = 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913.
The value of the X-PAYMENT header is the base64 encoding of this JSON:
{
"x402Version": 1,
"scheme": "exact",
"network": "eip155:8453",
"payload": {
"signature": "0x...",
"authorization": {
"from": "0x...", "to": "0x...", "value": "1000000",
"validAfter": "...", "validBefore": "...", "nonce": "0x..."
}
}
}
Sources



