# HEART OF AFRICA (HOA) — mint guide for AI agents

Machine-readable instructions for an AI agent that holds a **Binance Agentic Wallet** (with a `.ai` Agent ID) and wants to mint HOA Miner Passes on BNB Smart Chain (chainId 56).

## 1. Contract addresses

Read them from the site config at `/cfg.js` (`window.HOA`):

| key     | meaning                                  |
|---------|------------------------------------------|
| `sale`  | Sale contract: free claim, buy passes    |
| `mine`  | Mine contract: passes (ERC-721) + Hearts |
| `token` | HOA token (ERC-20, 18 decimals)          |
| `pool`  | HOA/USDT PancakeSwap pool (after open)   |
| `usdt`  | `0x55d398326f99059fF775485246999027B3197955` (BSC USDT, 18 decimals) |
| `start` | sale start, unix seconds (1793707200 = 2026-11-03 12:00 UTC) |

If an address is empty, the contracts are not live yet. Do not guess addresses; only use the ones in `cfg.js`.

## 2. Rules an agent must respect

- Shares #1–#1,000 are free: `claimFree()` once per `.ai` Agent ID (5,000 HOA, unlocked when the pool opens). Paid passes revert with `FreePhase()` until 1,000 shares are claimed.
- Shares #1,001–#10,000: tiers `0` = 5U, `1` = 10U, `2` = 15U. 10,000 HOA per 1U.
- Before the pool opens: the caller must own a `.ai` Agent ID; max 5 passes per tier per ID (+1 extra per friend whose first paid pass names you as `inviter`); max 5 per transaction.
- Share #10,000 opens the HOA/USDT pool automatically at the mint price and the LP is burned.
- Check state first with `stats()` and `account(address)`.

## 3. Function signatures

Sale (`cfg.sale`):

```
function stats() view returns (uint256 sold, uint256 free, bool started, bool open, uint256 lp, uint256 pot, uint256 raised, uint256 priceX112, uint256[3] nextUsd)
function account(address a) view returns (bool hasId, uint256 id, uint256[3] bought, uint256[3] left, uint256 inviteCount, bool free)
function passAmount(uint8 tier) view returns (uint256)                  // HOA (wei) per pass right now
function quoteBnb(uint8 tier, uint256 count) view returns (uint256)     // BNB wei for `count` passes
function quoteUsdt(uint8 tier, uint256 count) view returns (uint256)    // USDT wei for `count` passes
function claimFree()                                                    // selector 0xf366afc9
function buy(uint8 tier, uint256 count, address inviter, bool payBnb, uint256 maxPay) payable   // selector 0xa097c76b
```

- `payBnb = true`: send `value = maxPay = quoteBnb(tier,count) * 101 / 100`. Any excess BNB is returned in the same transaction.
- `payBnb = false`: first `approve(sale, quoteUsdt(tier,count))` on USDT, then `buy(..., false, quoteUsdt(tier,count))` with `value = 0`.
- `inviter`: a wallet address, or `0x0000000000000000000000000000000000000000` for none.

Mine (`cfg.mine`):

```
function passesOf(address owner) view returns (uint256[] ids, uint8[] tiers, uint256[] amounts, uint8[] status, uint256[] hoursDone)
// status: 0 idle, 1 mining, 2 Heart found (needs settle), 3 finished without a Heart (needs settle)
function redeem(uint256[] ids)     // idle passes -> HOA now; the pass is used up and can never mine
function stake(uint256[] ids)      // idle passes mine for 72 hours
function settle(uint256[] ids)     // status 2 or 3 -> finalize (Heart created, or the finished pass is closed out)
function heartsOf(address owner) view returns (uint256[])
function claimableOf(uint256 heartId) view returns (uint256)
function claim(uint256[] heartIds) // claim released HOA from Hearts
```

USDT (`cfg.usdt`): `approve(address spender, uint256 value)` (selector `0x095ea7b3`), `allowance(address owner, address spender)`.

## 4. Example: buy 1 tier-0 pass with BNB via `baw`

1. Read the quote (any BSC RPC, e.g. `https://bsc-dataseed.bnbchain.org`): `quoteBnb(0, 1)` -> e.g. `8333333333333333` wei.
2. Add the 1% buffer: `value = 8333333333333333 * 101 / 100 = 8416666666666666`.
3. Encode calldata for `buy(0, 1, 0x000…000, true, 8416666666666666)` (selector `0xa097c76b`, ABI-encoded args).
4. Preview, then execute:

```
baw contract-call preview --binanceChainId 56 --to <sale> --value 8416666666666666 --data 0xa097c76b<abi-encoded args>
baw contract-call execute --requestId <requestId from preview>
```

5. Wait for the transaction hash, then confirm with `passesOf(<your wallet>)`.

Free claim (while fewer than 1,000 shares are sold):

```
baw contract-call preview --binanceChainId 56 --to <sale> --value 0 --data 0xf366afc9
```

## 5. Common reverts

`NotStarted` sale not open yet · `FreePhase` free shares still running · `NoAgentId` wallet has no `.ai` Agent ID (before pool open) · `OverLimit` per-ID tier limit reached · `BadCount` count is 0 or over the per-transaction max · `TooExpensive` price moved, re-quote · `StaleFeed` BNB price feed stale, pay with USDT · `FreeUsed` / `FreeGone` free share taken or gone · `Staking` pass already staked · `Nothing` nothing to claim.

Human site: the home page of this domain. Nothing here is financial advice.
