An agent token is the one canonical token for a Leash agent. Genesis routes its creator fees to the agent’s Asset Signer PDA (the treasury) and wraps the launch transactions inmpl-core::Executeso the agent itself executes them on-chain. The Leash SDK (@leash/registry-utils) ships a thin, typed wrapper plus a one-click playground UI on/agents/[mint]. Mirrors the Metaplex Create an Agent Token guide.
What this guide covers
- Launching a token from an existing registered agent using
launchAgentToken. - The web playground flow on
/agents/<mint>→ Token (Genesis) tab. - Reading the on-chain agent → token binding with
getAgentToken. - Binding an existing Genesis token to an agent later via
setAgentToken(the docs’ “Set Agent Token” snippet).
firstBuyAmount) and must be the agent’s owner.
One-shot launch
agentTokenSet: boolean so callers can
unambiguously check whether the on-chain bind happened (it only does
when setToken: true and the bundle confirms cleanly).
Required inputs (from the Metaplex API)
| Field | Notes |
|---|---|
| name | 1–32 characters |
| symbol | 1–10 characters |
| image | Must match the HTTPS pattern Metaplex validates for Genesis (see their docs). Other hosts are rejected. |
description (≤250 chars) and externalLinks (website, twitter,
telegram) are optional.
About the image URL. The Metaplex Genesis API validates token.image
against a specific HTTPS host pattern (see Create an Agent Token).
Host your artwork accordingly, then paste the full URL into the playground.
Two-step variant
For hardware wallets, custom priority fees, or “inspect-then-send” flows:Read agent → token state
source tells you which Identity flavour was read. 'v1' agents
predate the agentToken field — they always return hasToken: false
and need a manual setAgentToken upgrade after launching, even if
the Genesis registry shows them as having a token.
Bind an existing Genesis launch
If you launched a token outside Leash and now want to associate it with an agent (the “Set Agent Token” path from the Metaplex docs):setAgentTokenV1 in mpl-core::Execute with the asset signer
PDA as the inner authority — same pattern Leash uses for spend
delegation and withdraws.
Permanence reminder. Each agent can only ever be bound to one token. There is no instruction to change, replace, or unset it.
The web playground flow
The agent profile page (/agents/<mint>) ships a Token (Genesis)
tab that wires launchAgentToken + getAgentToken directly to the
connected Privy embedded wallet:
- The card reads
getAgentTokenon mount and shows the current binding (linked + mint, or “no token yet”), the treasury PDA where creator fees will accrue, and which identity flavour is on-chain. - The Image URL field accepts the HTTPS URL for your token artwork. The UI validates the host pattern Metaplex requires and shows a warning when the URL would fail API validation.
- The Permanently bind checkbox defaults to off. A second warning appears if you tick it on an agent that already has a token.
- After a successful launch the card prints the mint address, the
Genesis launch link, and every base58 signature with a Solscan
link, then re-runs
getAgentTokenso the “linked” badge updates in place.
umi.identity (the user’s connected wallet).
CLI demo
apps/agent-token-demo is an end-to-end CLI that drives
launchAgentToken from a Solana keypair. Useful as a copy-paste
template for ops scripts and CI smoke tests.
- Reads the agent’s current
getAgentTokenstate and refuses to re-launch withsetToken: trueif one is already bound (the bind is irreversible — re-running would just waste fees). - Calls
launchAgentTokenwith the env-provided metadata. - Prints every signature with a Solscan deep link.
- Re-reads
getAgentTokenafter the launch and warns ifsetTokenwas true but the on-chain field hasn’t caught up yet (RPC lag).
LEASH_SET_TOKEN=true only when you’re certain this is the
final token for the agent. Defaults to false.
Errors
The Genesis SDK exposes typed errors so callers can branch precisely:| Error | Guard | Cause |
|---|---|---|
| Validation | isGenesisValidationError | Bad input (invalid image URL, name too long, …) |
| Network | isGenesisApiNetworkError | Cannot reach https://api.metaplex.com |
| API 4xx | isGenesisApiError | Rejected by the API; check err.responseBody |
| API 5xx | isGenesisApiError | Metaplex API unavailable; retry with back-off |
@metaplex-foundation/genesis directly when
you need them — Leash doesn’t wrap them.
Related
- Create an agent — required pre-step.
- Withdraw treasury funds — drain creator
fees out of the treasury PDA once they accrue. Genesis fees land as
native SOL, so use
withdrawTreasurySol{,All}(or pickSOL (native)in the playground’s withdraw card). - Run an agent — executive delegation flow that lets the agent spend received fees via x402.
- Metaplex docs: Create an Agent Token.

