---
name: apescription-mint
version: 2.0.0
description: Mint APE-20 inscription tokens on ApeChain via the Apescription protocol. Genesis ticker $APES, 21,000,000 total supply, 42,000 mints, 500 per mint. Fees are paid in native APE (msg.value) - no ERC-20 approval required.
chain: ApeChain
chain_id: 33139
rpc_url: https://rpc.apechain.com
explorer: https://apescan.io
contract: 0xd8AaFF5AE25CB26FFEeC0838c9087D8D66c6895C
permissionless: true
backend_required: false
fee_model: native
---

# Apescription - Agent Mint Skill

Use this skill to mint $APES inscription tokens on ApeChain on behalf of the user. The contract is fully permissionless - any EOA can call `mint()` or `mintBatch()` directly. There is no allowlist, no captcha, no signature gating. Protocol fees are paid in **native APE** attached to the transaction (`msg.value`). No ERC-20 approval is needed.

## Before you start

You MUST have access to:

1. A funded ApeChain wallet (private key or signer) owned or controlled by the user.
2. Enough native APE to cover gas + the tier fee for the mint(s) you intend to perform.
3. The contract address: `0xd8AaFF5AE25CB26FFEeC0838c9087D8D66c6895C`.

## Protocol rules - critical

| Rule | Value |
|------|-------|
| Token ticker | `APES` |
| Amount per mint | `500` tokens (any other value reverts) |
| Max total mints | `42000` |
| Free tier size | `2000` mints (tier 1) |
| Paid tier size | `10000` mints (tier 2 onward) |
| Free mints per wallet | 1 (tier 1 only, msg.value must be 0 or is refunded) |
| Total mints per wallet | 100 (lifetime, includes the free one) |
| Max batch size | 100 mints per tx |
| Overpayment | refunded automatically to msg.sender |

### Tier schedule
| Tier | Mint range | Fee per mint |
|------|------------|--------------|
| 1 | 0 - 1,999      | FREE |
| 2 | 2,000 - 11,999 | 1 APE |
| 3 | 12,000 - 21,999 | 2 APE |
| 4 | 22,000 - 31,999 | 3 APE |
| 5 | 32,000 - 41,999 | 4 APE |

Total supply: 42,000 × 500 = **21,000,000 $APES** (exact).
After 42,000 mints the ticker closes and the marketplace opens automatically.

## Decision procedure

```
1. Read current state:
     info  = contract.getToken("APES")
     price = contract.getMintPrice("APES")      // wei of native APE
     userM = contract.mintsByWallet("APES", user)
     free  = contract.freeMinted("APES", user)
     mc    = info.mintCount                      // total mints so far

2. If userM >= 100:
     STOP. User has hit the per-wallet lifetime cap.

3. If mc < 2000 (tier 1, free):
     - If `free` is true: STOP, the free slot is already consumed.
     - Otherwise: call mint("APES", 500) with msg.value = 0.
       (Any value sent is refunded.)

4. If mc >= 2000 (tier 2+):
     - Decide N (1 <= N <= 100, and userM + N <= 100).
     - Walk each mint's tier to compute the exact totalValue:
         for i in 0..N:
           pos = mc + i
           cost = pos < 2000 ? 0 : floor((pos - 2000) / 10000 + 1) * 1 APE
       totalValue = sum(cost)
     - Call mintBatch("APES", 500, N) with msg.value = totalValue.
       (Overpayment is refunded.)

5. Read the receipt and parse Minted(tick, to, amount, id) events
   to confirm each inscription ID.
```

## Reference implementation - viem (TypeScript)

```ts
import { createWalletClient, http, parseAbi, defineChain } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'

const apechain = defineChain({
  id: 33139,
  name: 'ApeChain',
  nativeCurrency: { name: 'ApeCoin', symbol: 'APE', decimals: 18 },
  rpcUrls: { default: { http: ['https://rpc.apechain.com'] } },
})

const APESCRIPTION = '0xd8AaFF5AE25CB26FFEeC0838c9087D8D66c6895C'

const ABI = parseAbi([
  'function mint(string tick, uint256 amount) payable',
  'function mintBatch(string tick, uint256 amount, uint256 count) payable',
  'function getToken(string) view returns (tuple(string tick,uint256 maxSupply,uint256 mintLimit,uint256 maxMints,uint256 totalMinted,uint256 mintCount,address deployer,bool exists,bool marketplaceOpen))',
  'function mintsByWallet(string tick, address w) view returns (uint256)',
])

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)
const client  = createWalletClient({ chain: apechain, transport: http(), account })

const info  = await client.readContract({ address: APESCRIPTION, abi: ABI,
  functionName: 'getToken', args: ['APES'] })
const userM = await client.readContract({ address: APESCRIPTION, abi: ABI,
  functionName: 'mintsByWallet', args: ['APES', account.address] })

const mc = info.mintCount
const N = mc < 2000n ? 1n : 5n
if (userM + N > 100n) throw new Error('Per-wallet cap reached')

// Walk each mint's tier so the value is right across tier boundaries.
let totalValue = 0n
for (let i = 0n; i < N; i++) {
  const pos = mc + i
  totalValue += pos < 2000n ? 0n : (((pos - 2000n) / 10000n) + 1n) * 10n ** 18n
}

const hash = await client.writeContract({
  address: APESCRIPTION, abi: ABI,
  functionName: N === 1n ? 'mint' : 'mintBatch',
  args: N === 1n ? ['APES', 500n] : ['APES', 500n, N],
  value: totalValue,
})
console.log('inscribed:', hash)
```

## Errors you may see

| Revert string | Meaning |
|---------------|---------|
| `insufficient value` | msg.value < required. Increase the value you attach. |
| `free mint already used` | This wallet already claimed its 1 free tier-1 mint. |
| `only 1 free mint per batch` | Batch crossed the tier-1 boundary with >1 free mints. Reduce N or start past the free tier. |
| `wallet mint cap reached` | This wallet already minted 100 times. Use a different wallet. |
| `count 1-100` | Batch count out of range. Must be 1..100 inclusive. |
| `wrong amount` | `amount` param must equal `500` exactly for the APES ticker. |
| `mint closed` | 42,000 mints done. Use `list`/`buy` for trading. |

## Marketplace (after mint closes)

Once `mintCount == 42000`, the marketplace opens. Additional functions:

- `list(tick, amount, price)` - escrow your $APES at a fixed native-APE price.
- `buy(id) payable` - attach `price + 1 APE`; overpayment is refunded.
- `cancel(id)` - seller reclaims escrow.

## Hard guarantees

- Contract is immutable: no proxy, no upgrade, no admin mint, no pause.
- The owner can only rotate the treasury address and transfer ownership.
- The contract cannot touch any user's $APES balances.
- Overpayment in native APE is always refunded to msg.sender inside the same tx.
- All inscription IDs are monotonic and unique on-chain.

## What you must NEVER do

- Sign a transaction with the user's key without explicit confirmation.
- Exceed the per-wallet cap (the tx will revert and waste gas).
- Assume the `amount` parameter is flexible (it is validated strictly to 500).
- Call this with chainId != 33139.
