---
name: arc-robo-agent-mint
description: Agent-native NFT mint skill for Arc Robo on Arc Mainnet. Use this skill to read mint status, request a signed voucher, approve native USDC, submit one to three NFTs, and verify the on-chain receipt.
version: 1.0.0
---

# Arc Robo Agent Mint

## Network

- Network: Arc Mainnet
- Chain ID: 5042
- RPC: https://rpc.mainnet.arc.io
- Native gas token: USDC
- Explorer: use the Arc Mainnet explorer available for the current deployment; never use a testnet explorer link.

## Contract

- NFT contract: `0x59774AF24B8792AA0627EcFCD15008363d1DB37d`
- Payment token: `0x3600000000000000000000000000000000000000`
- Payment token symbol: USDC
- Payment token decimals: 6
- Max supply: 2525
- Mint price: 1500000 base units per NFT (1.5 USDC)
- Maximum quantity per wallet: 3
- Mint state: read from the status endpoint before every voucher request
- Voucher signer: returned by the health endpoint; never request or handle its private key

## Public API

Base URL: `https://arcrobo.tech`

The deployed site serves the API through the same HTTPS origin.

### Read mint status

`GET /api/info`

Expected response fields:

- `chainId`
- `contract`
- `mintActive`
- `maxSupply`
- `totalMinted`
- `mintPrice`
- `metadataCID`

Require `chainId == 5042`, the expected contract address, `mintActive == true`, and `totalMinted < maxSupply`.

### Request a voucher

`POST /api/voucher`

JSON body:

- `wallet`: recipient and transaction sender, checksummed or lowercase EVM address
- `quantity`: integer from 1 through 3

The oracle reads the wallet nonce and returns:

- `chainId`
- `contract`
- `wallet`
- `quantity`
- `nonce`
- `deadline`
- `signature`

The voucher is one-time per wallet and nonce. Request it only after the wallet, quantity, and mint status are final.

## Voucher validation

Before submitting any transaction, verify:

1. `chainId` is `5042`.
2. `contract` equals `0x59774AF24B8792AA0627EcFCD15008363d1DB37d`.
3. `wallet` equals the transaction sender and intended NFT recipient.
4. `quantity` is the requested quantity and is between 1 and 3.
5. `deadline` is in the future, with no more than five minutes of expected validity.
6. The current on-chain nonce for the wallet equals the voucher nonce.
7. The signature is not reused after a successful mint.

The signed message digest is built from ABI-encoded values in this exact order:

`address contract, uint256 chainId, address wallet, uint256 quantity, uint256 nonce, uint256 deadline`

Hash the ABI encoding with keccak256, then verify the Ethereum signed-message signature against the configured voucher signer. The contract performs the authoritative signature and nonce validation.

## Mint flow

1. Call `GET /api/info`.
2. Confirm the contract, chain, active state, supply, and price.
3. Confirm the wallet has enough USDC for `quantity * 1.5` and enough native USDC for gas.
4. Approve the NFT contract to spend exactly `quantity * 1500000` USDC, unless the current allowance already covers the amount.
5. Request `POST /api/voucher` with the same wallet and quantity.
6. Validate every voucher field before broadcasting.
7. Submit `mintWithVoucher(quantity, deadline, signature)` from the approved wallet.
8. Wait for a receipt with status 1.
9. Verify the `AgentMinted` event, token ID, NFT owner, wallet mint count, and total minted count.
10. Resolve the token URI and verify it uses the collection metadata CID.

The contract rejects native `msg.value`; payment must be made through the USDC `transferFrom` path.

## Contract methods used by agents

Read methods:

- `mintActive() -> bool`
- `maxSupply() -> uint256`
- `totalMinted() -> uint256`
- `mintPrice() -> uint256`
- `nonces(address) -> uint256`
- `mintedByWallet(address) -> uint256`
- `ownerOf(uint256) -> address`
- `tokenURI(uint256) -> string`

Write methods:

- USDC `approve(address spender, uint256 amount)`
- NFT `mintWithVoucher(uint256 quantity, uint256 deadline, bytes signature)`

## Failure handling

- `invalid_wallet`: correct the EVM address format.
- `invalid_quantity`: use an integer from 1 to 3.
- `mint_inactive`: stop and re-check `/api/info`.
- `voucher_already_issued`: read the current nonce; do not repeatedly request vouchers.
- `voucher_failed`: retry only after checking RPC health and rate limits.
- `WrongPayment`: check USDC allowance, amount, decimals, and zero native value.
- `WalletLimit`: read `mintedByWallet` and reduce quantity.
- `InvalidVoucher`: request a fresh voucher for the current nonce; do not reuse the old signature.
- `ExpiredVoucher`: request a fresh voucher and submit promptly.
- reverted transaction: do not claim a mint; inspect the receipt and verify `totalMinted` and ownership.

## Security rules

- Never request, log, expose, or handle private keys, seed phrases, or mnemonics.
- The oracle signs vouchers only; it does not custody or broadcast the user's USDC.
- Never trust an HTTP 200 response as proof of mint success.
- Never submit a voucher when recipient, chain, contract, nonce, quantity, or expiry does not match the intended transaction.
- Keep API responses and signed payloads out of public logs.
- Respect the oracle rate limit: 60 requests per minute.

## Verification states

Report states separately:

- `STATUS_VERIFIED`: chain, contract, active state, price, and supply read successfully.
- `VOUCHER_ISSUED`: voucher returned and locally validated.
- `PAYMENT_APPROVED`: allowance covers the requested amount.
- `MINT_CONFIRMED`: receipt status is 1 and `AgentMinted` was emitted.
- `NFT_VERIFIED`: token owner and token URI match the intended wallet and collection.

Never report `MINT_CONFIRMED` from voucher issuance alone.
