SKILL.MD
for agents with a payments connector

GIVE THIS TO YOUR
ASSISTANT

You do not need to write any code. Save the file below as a skill, then ask your assistant to mint you a 402. It handles the 402 round trip itself, provided its wallet can reach Arc. No wallet yet? The skill walks you and your assistant through making one, step by step.

> WHAT YOUR AGENT NEEDS

Arc is a new chain, so not every agent wallet reaches it yet. Before pointing an agent here, check that its wallet can hold USDC on Arc and pay through Circle Gateway there. Many popular agent payment connectors currently cover Base, Solana and Polygon but not Arc.

ARC USDC

A balance on Arc itself. Gas is USDC here, so the same USDC pays for the one-time Gateway deposit.

GATEWAY BALANCE

USDC deposited into Circle Gateway once. Each mint then spends 1 USDC from it with a signed message: gasless and popup-free.

A SPEND RULE

Set a limit before you hand an agent a wallet. One mint costs $1, and nothing here should ever need more.

> THE SKILL FILE

Save this as a skill in your assistant, so it knows how to reach the endpoint and what the rules are. Also served raw at /skill.md.

the-402s/SKILL.md
---
name: the-402s-mint
description: Mint a THE 402s NFT on Arc by paying 1 USDC over the x402 protocol, settled through Circle Gateway. Use when the user asks to mint a 402, asks for an agent-minted NFT on Arc, or needs help setting up a wallet or agent that can pay x402 endpoints on Arc.
---

# Minting a 402

The collection is mintable only through an x402-gated
endpoint. There is no website mint button.

- Endpoint: POST https://the402s.xyz/mint
- Price: 1 USDC, paid from a Circle Gateway balance
- Limit: 5 per wallet, for both the paying wallet and the
  receiving wallet
- Network: Arc Testnet (eip155:5042002)
- Testnet USDC has no value. Never send real funds here.

## How paying works

Payments go through Circle Gateway. The wallet first
deposits USDC into Gateway once. After that, each mint
is a signed message (no gas, no popup) that spends
1 USDC from that Gateway balance.

## Start here

Everything lives in one folder: ~/mint-a-402. Your shell
may not remember the folder between commands, so every
command below starts with cd ~/mint-a-402.

First check whether setup was already done:

       test -f ~/mint-a-402/.env && echo "setup done" || echo "no setup yet"

- "setup done": skip to "Minting". Never run setup step 4
  again, the wallet key is already in .env.
- "no setup yet": ask the user one question: "Do you
  already have a wallet or payments tool connected to me
  that can pay x402 on Arc through Circle Gateway?"
  - Yes: skip to "Minting".
  - No, or not sure: go to "Setup". Assume they have
    never done this before. Before each step, say in one
    plain sentence what it does and why.

## Setup (first time)

You will build two tiny scripts in ~/mint-a-402: one to
deposit into Gateway, one to mint. If you can run
commands, run them yourself. If not, give the user one
command at a time and wait for them to paste the result
back.

1. Make the folder first. Everything else goes in it:

       mkdir -p ~/mint-a-402

2. Check Node.js is installed, version 22 or newer:

       node -v

   If it is missing or older, send the user to
   https://nodejs.org to install the LTS version, then
   run the check again.

3. Install the tools into the folder:

       cd ~/mint-a-402 && npm init -y && npm pkg set type=module
       cd ~/mint-a-402 && npm install viem @circle-fin/x402-batching @x402/core @x402/evm

4. Make a fresh wallet just for this. Never use the
   user's main wallet. This writes the secret key into
   .env and prints only the public address. If .env
   already exists it keeps it: never overwrite it.

       cd ~/mint-a-402 && test -f .env && echo "Wallet already exists, keeping it." || node -e "import('viem/accounts').then(({generatePrivateKey:g,privateKeyToAccount:a})=>{const k=g();console.log('PRIVATE_KEY='+k);console.error('Your minting wallet: '+a(k).address)})" > .env
       cd ~/mint-a-402 && echo ".env" > .gitignore

   Tell the user: the key in .env controls this wallet.
   Never paste it into a chat, a website, or a screenshot.

5. Fund the wallet. The user opens https://faucet.circle.com,
   picks Arc Testnet and USDC, and pastes the wallet
   address from step 4. Wait until the user says the USDC
   arrived. Gas on Arc is paid in USDC, so keep a little
   more than you plan to deposit.

6. Save this as ~/mint-a-402/deposit.js:

       import { GatewayClient } from "@circle-fin/x402-batching/client";

       const key = process.env.PRIVATE_KEY;
       const amount = process.argv[2];
       if (!/^0x[0-9a-fA-F]{64}$/.test(key ?? "")) throw new Error("No PRIVATE_KEY in .env, redo setup step 4");
       if (!/^[1-5]$/.test(amount ?? "")) throw new Error("Usage: node --env-file=.env deposit.js <1-5>   (1 USDC per mint, 5 max)");

       const gateway = new GatewayClient({ chain: "arcTestnet", privateKey: key });
       const before = await gateway.getBalances();
       console.log(`Wallet: ${before.wallet.formatted} USDC. Gateway: ${before.gateway.formattedAvailable} USDC.`);
       const result = await gateway.deposit(amount);
       console.log(`Deposited ${result.formattedAmount} USDC into Gateway. Tx: ${result.depositTxHash}`);
       const after = await gateway.getBalances();
       console.log(`Gateway balance now: ${after.gateway.formattedAvailable} USDC.`);

7. Ask how many they want to mint (1 to 5, the limit per
   wallet), then deposit that many USDC into Gateway. For
   3 mints:

       cd ~/mint-a-402 && node --env-file=.env deposit.js 3

   The Gateway balance is the spend limit: mints can only
   spend what was deposited, and mint.js below also
   refuses to pay more than 1 USDC per mint.

8. Save this as ~/mint-a-402/mint.js:

       import { GatewayClient } from "@circle-fin/x402-batching/client";

       const URL = "https://the402s.xyz/mint";
       const MAX_PRICE = 1_000_000n; // 1 USDC. This script refuses to pay more per mint.
       const key = process.env.PRIVATE_KEY;
       const to = process.argv[2];
       const count = Number(process.argv[3] ?? 1);
       if (!/^0x[0-9a-fA-F]{64}$/.test(key ?? "")) throw new Error("No PRIVATE_KEY in .env, redo setup step 4");
       if (!/^0x[0-9a-fA-F]{40}$/.test(to ?? "")) throw new Error("Usage: node --env-file=.env mint.js 0xRecipient [count 1-5]");
       if (!Number.isInteger(count) || count < 1 || count > 5) throw new Error("Count must be 1 to 5 (the per-wallet limit)");

       const gateway = new GatewayClient({ chain: "arcTestnet", privateKey: key }).onBeforePaymentCreation(async (ctx) => {
         if (BigInt(ctx.selectedRequirements.amount) > MAX_PRICE) return { abort: true, reason: "Price is above 1 USDC, refusing to pay" };
       });
       const { gateway: balance } = await gateway.getBalances();
       if (balance.available < MAX_PRICE * BigInt(count)) {
         console.log(`Gateway balance is ${balance.formattedAvailable} USDC, ${count} mint(s) need ${count}. Run: cd ~/mint-a-402 && node --env-file=.env deposit.js ${count}`);
         process.exit(1);
       }

       // One paid request per mint. Stops at the first problem, never retries a payment.
       for (let i = 1; i <= count; i++) {
         // Ask without paying first, so a refusal (limit reached, sold out) shows its full reason and nothing is signed.
         const probe = await fetch(URL, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ to }) });
         if (probe.status !== 402) {
           console.log(`mint ${i}/${count}:`, probe.status, await probe.text());
           process.exit(1);
         }
         const result = await gateway.pay(URL, { method: "POST", body: { to } });
         console.log(`mint ${i}/${count}:`, result.status, JSON.stringify(result.data));
       }

9. Ask which address should receive the NFT. Their own
   wallet address (for example from MetaMask) is best.
   Any EVM address works on Arc. If they have none, the
   minting wallet from step 4 can receive it.

10. Go to "Minting" and use this command to pay. The last
    number is how many to mint (leave it off for 1):

       cd ~/mint-a-402 && node --env-file=.env mint.js 0xRecipientAddress 3

## Minting

1. Confirm the recipient address with the user.
2. Confirm how many and the total with the user, for
   example "3 mints, 3 USDC". Wait for a yes.
3. POST {"to": "<address>"} to the endpoint. The first
   answer is a 402 with the payment requirements.
   A Gateway x402 client (like mint.js) signs the
   payment and retries for you.
4. On 200, report the tokenId and the explorer link from
   the response.
5. For more than one, repeat steps 3 and 4 once per mint.
   Each mint is its own 1 USDC payment. mint.js does this
   when given a count, and stops at the first problem.

## If something goes wrong

- 400: the recipient address is malformed. Fix it and retry.
- 403 wallet_limit: that wallet already has 5. Stop and
  tell the user.
- 402 settlement_failed: usually the Gateway balance is
  too low. Nothing was charged. Deposit more (setup
  step 7) before trying again.
- 402 after paying, any other reason: do not retry
  without telling the user first.
- 409: the collection sold out. Nothing was charged.
- 429: too many requests. Wait a minute and try again.
- 500: the payment settled but the mint failed. Save the
  full response and give it to the user. It is their
  proof of payment.
- Leftover Gateway balance can be withdrawn later with
  the same GatewayClient (withdraw).

## Rules

- Confirm the number of mints and the total spend with the
  user before paying.
- Never mint more than the user asked for.
- Never create new wallets to get around the 5 per
  wallet limit.
- Never ask for, print, or repeat a private key.
- Use a fresh wallet funded with testnet USDC only.
- Do not retry a failed settlement without saying so.
> INSTALLING IT

Claude Code: one command installs it. Other assistants: save the file above into their skills folder.

bash · Claude Code
$ mkdir -p ~/.claude/skills/the-402s-mint && curl -fsSL https://the402s.xyz/skill.md -o ~/.claude/skills/the-402s-mint/SKILL.md
01

INSTALL IT

Run the command above, or save the file into your assistant's skills folder.

02

CONNECT PAY

Attach a wallet that can sign on Arc. No wallet? Your assistant sets up a fresh one with you.

03

JUST ASK

"Mint me a 402." Your agent does the rest.

> NEXT