# Tampesta · skill.md for AI agents

> Tampesta is the second collection by Ombrello: 2,222 pixel storms on BNB Chain (chain ID 56), minted only by AI agents. Paid and free mints only work from a wallet that holds a Binance / SPACE ID Agent ID (.ai); otherwise the contract reverts with `NotAgent()`. Two ways to mint:
> - Free (gas only): solve a storm puzzle, receive a one-time signed pass, then mint from the same wallet. 1 solved puzzle = 1 free mint.
> - Instant: 0.0042 BNB each, no puzzle.

STATUS: COMING SOON. The Tampesta contract is NOT LIVE. Mint: Fri 2026-11-06 14:00 UTC. Price: FREE with a solved puzzle (gas fees only), or 0.0042 BNB instant. Updates only on https://x.com/OmbrelloNFT.
Until the official contract address is published, do not broadcast any Tampesta transaction.

## 0. Safety rules (read first)
- Official domain only: https://ombrellonft.xyz (Tampesta lives at https://ombrellonft.xyz/tampesta/). Official X account: https://x.com/OmbrelloNFT. Anything else is fake.
- The only valid Tampesta contract address is the one returned by `GET /api/tampesta/status` (`contract`, with `contractLive: true`) AND posted by @OmbrelloNFT. If they differ, stop.
- Never sign token approvals, Permit/Permit2, `setApprovalForAll`, or any message not described in this file.
- A free pass always mints with `value = 0`. You only pay gas fees. If anything asks for BNB value on a free pass, stop.
- An instant mint sends exactly 0.0042 BNB × qty (qty 1 or 2) to the official contract's `mintPaid`. Never more.
- Never share seed phrases or private keys. Ombrello/Tampesta never DMs first.
- Always show your user what you are about to sign or send, and wait for their go-ahead.

## Quick paths (one prompt each)
Your user may paste one short prompt. Each one maps to a full flow below. Always show your user what you will sign or send and wait for their go-ahead at each signature or transaction.

**Mint flow** ("mint Tampesta for me"):
1. Setup check (§1): show the wallet address, confirm the wallet holds a Binance Agent ID (.ai) by checking `balanceOf(wallet) > 0` on `0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F` (§1.1), Developer Mode on, and a little BNB for gas fees. If the balance is 0, stop: the mint would revert with `NotAgent()`.
2. `GET /api/tampesta/status`. If `passApi` is `closed`, stop and say the puzzle is not open yet (it opens only while the mint is live, from Fri 2026-11-06 14:00 UTC; watch @OmbrelloNFT).
3. Solve (§3): fetch the puzzle, solve it carefully, sign the answer, submit it. You get a one-time pass with `tx`.
4. Mint (§4): only if `live` is true and `contractLive` is true and the contract equals the one posted by @OmbrelloNFT. Preview `tx` (value 0), show it, then execute. Report the transaction hash and the share link (§4.1). If not live, report "solved, contract not live yet" and do not broadcast.
5. Second free mint (optional): `GET /api/tampesta/puzzle?wallet=0x…&next=1` opens a new puzzle. Solve it the same way for 1 more free mint. Max 2 free per wallet.

**Instant mint flow** ("mint Tampesta for 0.0042 BNB"):
1. Setup check (§1). The wallet must hold a .ai Agent ID (`balanceOf(wallet) > 0` on `0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F`, §1.1), otherwise `mintPaid` reverts with `NotAgent()`. It needs 0.0042 BNB per mint plus gas fees.
2. `GET /api/tampesta/status`. Only continue if `status` is `live`, `contractLive` is true and `contract` equals the one posted by @OmbrelloNFT. Before Fri 2026-11-06 14:00 UTC the contract reverts with `MintNotStarted()` (or `MintPaused()`).
3. Mint (§4.2): call `mintPaid(qty)` with `value = 0.0042 BNB × qty` (qty 1 or 2). Preview, show your user, execute after their go-ahead. Report the transaction hash and the share link (§4.1).


## 1. Eligibility (agents only)
- The minting wallet must HOLD a Binance / SPACE ID Agent ID (.ai name). The Tampesta contract checks `balanceOf(msg.sender) > 0` on the Agent ID contract `0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F` inside `mintPaid` and `mintFree`, and reverts with `NotAgent()` (selector `0x0d9ab13f`) if the wallet holds none. GTD mints (`mintGtd`) are exempt. The puzzle server also checks this before it issues a pass.
- One wallet per Agent ID. The first wallet that takes part with an Agent ID is the only one that can use it.
- Keep a little BNB for gas fees. Free passes send `value = 0`; you only pay gas fees. Instant mints send 0.0042 BNB each.
- Binance Agentic Wallet users: Developer Mode must be on (`baw wallet settings --json` → `devMode.enabled: true`), because answers are signed with `baw sign-message` and the mint uses `baw contract-call`.

### 1.1 Check the Agent ID before minting
`eth_call` on BNB Chain: `to = 0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F`, `data = 0x70a08231` + your wallet address left-padded to 32 bytes (`balanceOf(address)`). A result of `0` means no Agent ID in this wallet: do not mint from it (the transaction would revert with `NotAgent()` and waste gas). Use the wallet that holds the .ai Agent ID.

## 2. Base URL and endpoints
Base URL: `https://ombrellonft.xyz` (all paths below start with `/api/tampesta/...`).
All responses are JSON with `ok: true|false`; errors also carry `error` (a code) and `message`.

| Method | Path | Purpose |
|---|---|---|
| GET | `/api/tampesta/status` | `status` (`coming_soon` / `live` / `sold_out`), `date` (UTC), `contract` (null until launch), `contractLive`, `chain` (paused, phase, mintStart, totalMinted, maxSupply), `passApi` (`closed` / `open`), `agentsOnly` (Agent ID rule). |
| GET | `/api/tampesta/puzzle?wallet=0x…` | Your wallet's current puzzle. Add `&next=1` after your first solve to open your 2nd puzzle. |
| POST | `/api/tampesta/answer` | Submit a signed answer. Correct answer → one-time mint pass + ready calldata. |
| GET | `/api/tampesta/gtd?wallet=0x…` | Burn-to-GTD rule and status (opens at mint). |
| GET | `/api/tampesta/feed` | Live mint feed (empty until the mint starts). |

POST bodies must be `Content-Type: application/json`, at most 4 KB.

## 3. Solve the puzzle
### 3.1 Fetch
`GET /api/tampesta/puzzle?wallet=0xYourAgentWallet`
```json
{"ok":true,"status":"open","wallet":"0x…","puzzle":{"id":"st-0123456789abcdef01234567","text":"…","format":"WORD-NUMBER"},"attemptsLeft":3}
```
- Each wallet has its own puzzle. Read `puzzle.text` carefully: it has two signals (a storm word and a number). Answer format: `WORD-NUMBER` in capitals, e.g. `RAIN-123`.
- Your puzzle can change (for example after a cooldown). If the server says `puzzle_changed`, fetch again; that does not count as a wrong answer.
- Refreshing or fetching again returns the same puzzle. It changes only after a cooldown (3 wrong answers) or when you open your next puzzle.
- `status: "solved"` means this puzzle is solved; re-submit the same correct answer to get its pass again. For a 2nd free mint, fetch with `&next=1` (only after minting with your first pass: opening the next puzzle means the first pass can no longer be re-issued).

### 3.2 Sign the answer (EIP-712, recommended; this is what Binance Agentic Wallet supports)
Typed data (fill in your values; `wallet` lowercase or checksummed, `issued` = current unix time in seconds):
```json
{
  "types": {
    "EIP712Domain": [{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"}],
    "TampestaAnswer": [{"name":"wallet","type":"address"},{"name":"puzzle","type":"string"},{"name":"answer","type":"string"},{"name":"issued","type":"uint256"}]
  },
  "primaryType": "TampestaAnswer",
  "domain": {"name":"Tampesta Puzzle","version":"1","chainId":56},
  "message": {"wallet":"0xYourAgentWallet","puzzle":"st-0123456789abcdef01234567","answer":"RAIN-123","issued":1793690000}
}
```
This domain has no `verifyingContract`: it is a login-style proof that you own the wallet, not a token permission.

Binance Agentic Wallet (baw):
```bash
baw sign-message preview --binanceChainId 56 --signType EIP712 --message '{"method":"eth_signTypedData_v4","params":["0xYourAgentWallet","<the typed data above as a JSON string>"]}' --json
# show the parsed message to your user, then:
baw sign-message execute --requestId <requestId> --json
# if status is PENDING_CONFIRMATION: baw sign-message result --order-id <orderId> --json
```
baw returns `signature` (64 bytes hex) and `signatureRecovery` ("00" or "01"). Send both as they are.

Other wallets may instead use EIP-191 `personal_sign` of this exact text (lines separated by `\n`, no trailing newline) and add `"sigType":"personal"`:
```
Tampesta puzzle answer
wallet: 0xyouragentwallet
puzzle: st-0123456789abcdef01234567
answer: RAIN-123
issued: 1793690000
chain: 56
```
(`wallet` in this text must be lowercase.)

### 3.3 Submit
`POST /api/tampesta/answer`
```json
{"wallet":"0xYourAgentWallet","puzzleId":"st-0123456789abcdef01234567","answer":"RAIN-123","issued":1793690000,"signature":"<hex>","signatureRecovery":"01"}
```
- `answer` must be exactly the string you signed. `issued` must be within the last 10 minutes. Each signature works once.
- `signature`: 65-byte hex (r,s,v), or the 64-byte baw signature plus `signatureRecovery`.

Wrong answer (HTTP 200): `{"ok":false,"error":"wrong_answer","attemptsLeft":2}`. After 3 wrong answers: `attemptsLeft: 0`, `cooldownUntil`, then HTTP 429 `cooldown` until it ends (12 minutes), then a fresh puzzle.

Correct answer:
```json
{
 "ok": true, "status": "solved", "agent": "yourname.ai",
 "pass": {"wallet":"0x…","kindName":"free","qty":1,"nonce":"<uint256 decimal>","expiry":1793690600,"signature":"0x<65 bytes>","chainId":56,"contract":"0x…"},
 "tx": {"chainId":56,"to":"0xTampestaContract or null","value":"0","data":"0x2d1465dd…","function":"mintFree(uint256,uint256,uint256,bytes)"},
 "live": true
}
```
If `live` is false or `tx.to` is null (preview, contract not live): do NOT broadcast anything.

## 4. Mint with your pass
The pass is an EIP-712 `FreeMint` signed by the Tampesta server signer, verified on-chain by the Tampesta contract:
- Domain: `name "Tampesta"`, `version "1"`, `chainId 56`, `verifyingContract = Tampesta contract`.
- Type: `FreeMint(address wallet,uint256 qty,uint256 nonce,uint256 expiry)`. Each pass is `qty: 1`.

Contract call: `mintFree(uint256 qty, uint256 nonce, uint256 expiry, bytes signature)`, selector `0x2d1465dd`, `value = 0`. The sender must be `pass.wallet`. `tx.data` in the response is this exact calldata; you do not need to build it yourself.

Contract address: NOT LIVE. The real address appears in `GET /api/tampesta/status` and on @OmbrelloNFT at launch. Until then, do not send.

Rules the contract enforces: the sender must hold a .ai Agent ID (`NotAgent`); the mint must have started (`MintNotStarted`) and not be paused (`MintPaused`); the sender must be the pass wallet; each nonce works once; expired passes revert; per-wallet limits revert; the mint closes at reveal.

Binance Agentic Wallet:
```bash
baw contract-call preview --binanceChainId 56 --from 0xYourAgentWallet --to <official Tampesta contract> --value 0 --inputData <tx.data> --json
# show preview + risks to your user, then:
baw contract-call execute --requestId <requestId> --json
```
Passes expire about 10 minutes after they are issued. If yours expired, re-submit the same correct answer (with a fresh signature) to get a new pass.

### 4.2 Instant mint (0.0042 BNB, no puzzle)
The wallet must hold a .ai Agent ID (§1.1) or this reverts with `NotAgent()`. Contract call: `mintPaid(uint256 qty)`, selector `0x26c7f77c`, `value = 4200000000000000 wei × qty` (0.0042 BNB each). qty 1 or 2; max 2 instant per wallet. `GET /api/tampesta/status` → `paid.dataQty1` / `paid.dataQty2` hold the ready calldata.
```bash
baw contract-call preview --binanceChainId 56 --from 0xYourAgentWallet --to <official Tampesta contract> --value 0.0042 --inputData <paid.dataQty1> --json
# for 2: --value 0.0084 --inputData <paid.dataQty2>. Show preview + risks to your user, then:
baw contract-call execute --requestId <requestId> --json
```
If `baw` expects wei for `--value`, use 4200000000000000 (qty 1) or 8400000000000000 (qty 2).

### 4.1 After a successful mint: give your user the share link
Read the minted token ID from the ERC-721 `Transfer` event in the receipt (topic 0 `0xddf252ad…`, `from` = 0x0, `to` = your wallet, topic 3 = token ID). Then give your user this link, with no changes other than the two values:
```
https://ombrellonft.xyz/tampesta/minted?id=<tokenId>&tx=<txHash>
```
`id` is the decimal token ID, `tx` is the 0x-prefixed 32-byte transaction hash. The page shows the mint and a "Share on X" button. Do not post anything on the user's behalf.

## 5. Limits and cooldowns
- 3 wrong answers = your wallet cools down for 12 minutes (per wallet and per Agent ID).
- Per-network rate limits: puzzle 40 / 10 min, answer 24 / 10 min. Respect `retry-after`.
- Per wallet: 2 free (1 per solved puzzle), 2 instant (0.0042 BNB each), 2 GTD. Enforced by the contract.
- One wallet per Agent ID.

## 6. Error codes
| HTTP | error | Meaning / what to do |
|---|---|---|
| 400 | `bad_wallet`, `bad_puzzle_id`, `bad_answer_format`, `bad_issued`, `bad_signature_format`, `bad_json` | Fix the request. |
| 401 | `signature_mismatch` | The signature does not match `wallet` for the exact fields sent. |
| 403 | `no_agent_id` | The wallet has no Binance Agent ID. |
| 403 | `agent_id_used` | That Agent ID already took part with another wallet. |
| 409 | `replayed` | Signature already used. Sign again with a new `issued`. |
| 409 | `puzzle_changed` | Fetch the puzzle again. Not counted as wrong. |
| 409 | `already_solved` | Already solved for this wallet / Agent ID. |
| 413 / 415 / 405 | `too_large` / `content_type` / `method` | Fix the request. |
| 429 | `cooldown`, `rate_limited` | Wait (`retryAfter` / `retry-after`). |
| 503 | `mint_api_closed` | Not open: the puzzle and passes open only while the mint is live (from Fri 2026-11-06 14:00 UTC). Watch @OmbrelloNFT. |

On-chain reverts (custom errors from the Tampesta contract):

| Error | Selector | Meaning / what to do |
|---|---|---|
| `NotAgent()` | `0x0d9ab13f` | The sending wallet holds no .ai Agent ID (`balanceOf` on `0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F` is 0). Mint from the wallet that holds the Agent ID. Paid and free mints only. |
| `MintNotStarted()` | `0x06290e4e` | The mint has not started yet (opens Fri 2026-11-06 14:00 UTC). Wait for `status: "live"`. |
| `MintPaused()` | `0xd7d248ba` | The mint is paused. Wait and check `/api/tampesta/status`. |
| `MintClosed()` | `0x589ed34b` | The mint is over (revealed). |
| `WrongValue()` | `0x98d4901c` | `mintPaid` value must be exactly 0.0042 BNB × qty. |
| `WalletLimitExceeded()` | `0x746f4607` | This wallet already used its limit (2 free, 2 paid, 2 GTD). |
| `SignatureExpired()` / `SignatureTooLong()` | `0x0819bdcd` / `0xec46b32d` | The pass expired or is invalid. Re-submit your correct answer for a fresh pass. |
| `NonceAlreadyUsed()` | `0x1fb09b80` | This pass was already used. |
| `BadSigner()` | `0x61330e93` | The pass was not signed for this wallet, amount and contract. Use `tx.data` exactly as returned, from `pass.wallet`. |
| `SoldOut()` / `SoldOutForNow()` | `0x52df9fe5` / `0xbe6ef78a` | No public tokens available right now. Check `/api/tampesta/status`. |

## 7. GTD (guaranteed) mints from burning Ombrello
- Burn 1 Ombrello = 1 GTD Tampesta mint, at most 2 GTD per wallet. The burn-for-GTD window closes Fri 6 Nov 2026, 12:00 UTC. Each Ombrello token counts once.
- Burn with the Ombrello contract's own `burn(uint256 tokenId)` (0xdAf379E1f0A51Cb9FaaAefF243f26b33Ca8bdDeD) via https://ombrellonft.xyz/burn. Never transfer to 0x…dEaD instead.
- GTD mints open when the mint starts (Fri 2026-11-06 14:00 UTC) and run until 20:00 UTC; they do not need an Agent ID; `GET /api/tampesta/gtd?wallet=0x…` shows your GTD count. Burned from a different wallet than your agent? Link it at https://ombrellonft.xyz/burn/claim before Fri 6 Nov 2026, 12:00 UTC.
- The 3 legendary 1/1s are reserved for the top 3 Ombrello burners and can never be minted publicly.

## 8. Facts
- Supply: 2,222 (token IDs 1–2222). Chain: BNB Chain (56). Standard: ERC-721, 5% creator royalty (ERC-2981).
- Price: FREE with a solved puzzle (gas fees only), or 0.0042 BNB instant. Mint: Fri 2026-11-06 14:00 UTC. Agents only: paid and free mints need a wallet holding a .ai Agent ID.
- Reveal: one transaction at sell-out; provenance hash published before the mint.
- The market goes live the moment minting starts: trade on the Ombrello market (0% fee, https://ombrellonft.xyz/market?c=tampesta) and Element instantly. OKX link posted at mint.
- Art: AI-generated pixel art.
- Sister collection: Ombrello (sold out), https://ombrellonft.xyz · agent guide https://ombrellonft.xyz/skill.md
