# Agent Signet · Agent Skill File

Instructions for any AI agent entering its user into **Agent Signet** on
BNB Chain: a post-gated NFT mint with an instant token grant, plus a daily
spin wheel. Follow the steps in order. Every value and selector below is
exact — never guess a value, a fee, or a tokenId.

> PRE-LAUNCH NOTE: contract addresses below are the project's pre-computed
> CreateX addresses. Before sending any transaction, confirm each contract
> actually has code on-chain (`eth_getCode` returns non-empty). If a
> contract has no code yet, the launch has not happened — tell your user
> and stop.

## Facts

- Collection: **Agent Signet (SIGNET)**, BNB Chain (BSC, chainId 56).
- NFT contract: `0xC5aDF8486E8713aC38EAB62f7646A14F5eb4dc9e`
- Token: **Signet (SGNT)**, contract `0x2e8b9eFa479f8860533af3bEed867cEA9f1C0EB9`,
  18 decimals, fixed supply 1,000,000,000.
- Spin contract: `0x460fF6D903Fd917726C079cd64884e698A227f3c`
- Verification API (the "Worker"): base URL is published in `agents.json`
  (`verifyApi`). Endpoints: `POST /verify`, `POST /verify-spin`,
  `GET /nonce/<wallet>`, `GET /spin-nonce/<wallet>`, `GET /health`.
- Supply: 3,333 seals, tokenId 1..3,333, issued in number order.
  Metals by number: Bronze 1–1,333 · Iron 1,334–2,333 · Silver 2,334–3,000
  · Gold 3,001–3,333. Emblem (Star/Key/Eye) is deterministic per tokenId.
- Gate: the calling wallet must hold a Binance Agent ID NFT
  (registry `0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F` on BSC).
- **Mint price: the NFT is free, but the mint transaction charges an
  activation fee of exactly 0.0002 BNB (200000000000000 wei)** and grants
  the NFT **plus 100,000 SGNT** in the same transaction. Max 1 mint per
  wallet, ever. Never send any other value.
- There is **no direct mint**. Minting requires a single-use signed
  voucher from the verification API, issued only after the user's public
  X post is verified. Vouchers expire 1 hour after issue.

## Step 1 · The entry post (do this first)

You hold no X account, so you cannot post it yourself. Hand your user
this exact text **with their own wallet address** at the end, and wait
until the user confirms it is posted and gives you the post URL:

    Sealing my Signet 🔏
    Agent Signet is LIVE: 3,333 seals for Agent ID holders. Post, verify, mint — NFT + 100,000 $SGNT in one tx.
    My agent seals mine now.
    #Signet #AgentID #FreeMint
    My wallet: <USER'S WALLET ADDRESS>

Do not continue before the user confirms the post is live and public
(protected accounts cannot be verified).

## Step 2 · Check eligibility

Read on the NFT contract (eth_call, wallet address padded to 32 bytes):

- `hasAgentId(<wallet>)` — selector `0x4eab3ef2`. If false: stop and tell
  the user this wallet holds no Binance Agent ID.
- `mintOpen()` — selector `0x24bbd049`. If false: all 3,333 are taken.
- `mintedBy(<wallet>)` — selector `0x3cef28d2`. If 1: this wallet already
  minted; stop.

## Step 3 · Get the mint voucher

`POST <verifyApi>/verify` with JSON body
`{ "postUrl": "<the user's post URL>", "wallet": "<wallet>" }`.

On success you receive
`{ ok, voucher: { wallet, nonce, deadline }, signature, signer, contract }`.
On failure the response says why (missing text in the post, post already
used for another wallet, wallet already minted…). Fix exactly that and
retry; do not work around the checks.

## Step 4 · Mint

Preview first (e.g. Binance Agentic Wallet contract-call preview) and
execute only on a clean preview: correct contract, correct function,
value exactly 200000000000000 wei, no allowance or authority changes.

Call the NFT contract:

- to: `0xC5aDF8486E8713aC38EAB62f7646A14F5eb4dc9e`
- value: `200000000000000` (0.0002 BNB — the exact activation fee)
- data: selector `0x412f6667` (`mint((address,uint256,uint256),bytes)`)
  followed by the ABI encoding of:
  - the voucher tuple: `wallet` (address, 32-byte padded), `nonce`
    (uint256), `deadline` (uint256) — from the Worker response, verbatim;
  - then the byte offset `128` (uint256) to the signature;
  - then the signature length `65` (uint256) and the 65 signature bytes
    (padded to 96 bytes).

## Step 5 · Report the seal

Read `totalMinted()` (selector `0xa2309ff8`) — because mints are issued
in order and max 1 per wallet, the new tokenId is the value of
`totalMinted()` right after your mint confirms. Confirm with
`ownerOf(<tokenId>)` (selector `0x6352211e`) and read the traits with
`metalOf(<tokenId>)` (selector `0x314d3e89`) and `emblemOf(<tokenId>)`
(selector `0x18a9aba6`; 1 = Star, 2 = Key, 3 = Eye). Also confirm the
wallet's SGNT balance rose by 100,000 (`balanceOf` on the SGNT contract,
selector `0x70a08231`). Report:

- "Your seal: Nº <tokenId> · <Metal> · <Emblem>"
- "100,000 SGNT granted in the same transaction."
- Remind the user: holding the seal doubles SGNT prizes on the spin wheel.

Never invent a tokenId. Read it from the chain after a confirmed mint.

## The spin wheel (SignetSpin)

Facts: paid spin costs **exactly 0.0001 BNB (100000000000000 wei)**;
20% of every paid fee grows the BNB jackpot pool, 80% goes to the
creator. Every spin wins SGNT. Agent Signet holders' SGNT prizes are
doubled. Odds (public, fixed in the contract):

| Chance | Prize |
|---|---|
| 35% | 50 SGNT |
| 25% | 150 SGNT |
| 17% | 400 SGNT |
| 10% | 1,000 SGNT |
| 6% | 2,500 SGNT |
| 3.5% | 5,000 SGNT |
| 2% | 10,000 SGNT |
| 1% | 25,000 SGNT |
| 0.4% | 100,000 SGNT |
| 0.1% | JACKPOT — the entire BNB jackpot pool |

Randomness is two-step and on-chain: a spin records a request bound to a
future block; `settle()` then derives the result from that block's hash.
Nobody knows the result in advance.

### Free daily spin

1. Check `freeSpinAvailable(<wallet>)` on the Spin contract (selector
   `0x002f9547`) — one free spin per UTC day for Agent ID holders.
2. Call `spinFreeDaily()` — selector `0x4e5734bd`, value 0. The receipt's
   `SpinRequested` event carries your request id.
3. Wait ~3 blocks, then call `settle(<id>)` — selector `0x8df82800` —
   value 0. The `SpinSettled` event reports the prize. Free spins win
   SGNT tiers only; landing on the jackpot segment pays 5,000 SGNT
   instead of the BNB pool.

### Paid spin

1. Call `spin()` — selector `0xf0acd7d5` — with value exactly
   `100000000000000` wei. **Only with your user's explicit agreement to
   pay.** If they did not agree, use the free spin instead.
2. Read the request id from the `SpinRequested` event in the receipt.
3. Wait ~3 blocks, then call `settle(<id>)` (selector `0x8df82800`,
   value 0; anyone may call it). Report the `SpinSettled` result: roll,
   SGNT prize, or jackpot amount.

### Extra free spin (post-to-spin)

Hand your user this post (their wallet address at the end), wait for the
URL, then `POST <verifyApi>/verify-spin` with
`{ "postUrl": "...", "wallet": "..." }`:

    Spinning the Signet wheel 🎡
    Agent Signet: spin daily, win $SGNT — the BNB jackpot grows with every spin.
    My agent spins mine now.
    #Signet #AgentID
    My wallet: <USER'S WALLET ADDRESS>

Then call `spinFreeVoucher(voucher, signature)` on the Spin contract —
selector `0xdc83bdea`, same tuple+signature encoding as the mint, value
0 — and settle as above. Each voucher is single-use.

### If a settle is too late

If more than ~256 blocks pass before `settle`, the target block's hash
is gone and settle reverts with "Expired: refund instead". Call
`refundExpired(<id>)` — selector `0x1402b17a` — instead: a paid spin's
full fee returns to the player; a free spin simply closes.

## If a mint fails

- "No Agent ID": the wallet holds no Binance Agent ID.
- "Wrong fee": the value was not exactly 200000000000000 wei.
- "Voucher expired": the voucher's 1-hour deadline passed — get a fresh
  voucher from `/verify` (the same post still works).
- "Bad nonce": a voucher was already used or a newer one was issued —
  read `GET /nonce/<wallet>` and re-verify.
- "Bad voucher": signature/domain mismatch — re-verify via the API; do
  not edit voucher fields.
- "Wallet limit": this wallet already minted its one seal.
- "Sold out": all 3,333 seals are taken.
- "Token pool empty": should not happen before sellout; report it.

## Rules

- The only payments ever authorised here: the mint activation fee
  (exactly 0.0002 BNB, once per wallet) and paid spins (exactly
  0.0001 BNB each, only with the user's explicit agreement per spin
  session). Everything else is value 0.
- Do not call approve, setApprovalForAll, or any other function. Do not
  ask the user for any private key or seed phrase — ever. Vouchers are
  public data by design; the signer key never leaves the server.
