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 in mpl-core::Execute so 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).
You need a registered Leash agent first — see Create an agent. The launching wallet pays the launch fees (~0.02 SOL on devnet, plus the optional firstBuyAmount) and must be the agent’s owner.

One-shot launch

import { launchAgentToken } from '@leash/registry-utils';

const result = await launchAgentToken(umi, {
  agentAsset: '<Core asset address>',
  network: 'solana-devnet',
  // setToken: true is PERMANENT. Default to false for previews.
  setToken: false,
  token: {
    name: 'Plexpert Token',
    symbol: 'PLX',
    image: 'https://…', // must match Metaplex Genesis image URL rules
    description: 'The official token of Plexpert.',
    externalLinks: { website: 'https://plexpert.example' },
  },
  launch: {
    // Optional fee-free first swap reserved for the agent PDA.
    firstBuyAmount: 0.1, // SOL
  },
});

console.log(result.mintAddress); // base58 mint
console.log(result.launch.link); // metaplex.com landing page
console.log(result.signatures); // base58 tx sigs (1-2)
The returned shape includes 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)

FieldNotes
name1–32 characters
symbol1–10 characters
imageMust 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:
import { prepareAgentTokenLaunch, sendPreparedAgentTokenLaunch } from '@leash/registry-utils';

const prepared = await prepareAgentTokenLaunch(umi, {
  /* same input */
});
// Inspect / modify prepared.transactions here if needed.
const result = await sendPreparedAgentTokenLaunch(umi, prepared);

Read agent → token state

import { getAgentToken, hasAgentToken } from '@leash/registry-utils';

const status = await getAgentToken(umi, '<Core asset>');
// {
//   agentAsset, treasury, hasToken, mint,
//   source: 'v1' | 'v2' | 'none',
// }

if (await hasAgentToken(umi, '<Core asset>')) {
  // The agent already has a permanent token.
}
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):
import { setAgentToken } from '@leash/registry-utils';

const { signature } = await setAgentToken(umi, {
  agentAsset: '<Core asset>',
  genesisAccount: '<Genesis PDA from your earlier launch>',
  collection: '<agent collection>', // recommended; mpl-core::Execute is cheaper with it
});
Wraps 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:
  1. The card reads getAgentToken on 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.
  2. 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.
  3. The Permanently bind checkbox defaults to off. A second warning appears if you tick it on an agent that already has a token.
  4. 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 getAgentToken so the “linked” badge updates in place.
The playground server never sees a signing key — every transaction is signed by 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.
pnpm --filter @leash/agent-token-demo build

LEASH_OWNER_SECRET_KEY='[1,2,3,...,64]' \
LEASH_AGENT_ASSET='<Core asset>' \
LEASH_TOKEN_IMAGE='https://…' \
LEASH_TOKEN_NAME='Plexpert' LEASH_TOKEN_SYMBOL='PLX' \
LEASH_NETWORK='solana-devnet' \
pnpm --filter @leash/agent-token-demo start
The script:
  1. Reads the agent’s current getAgentToken state and refuses to re-launch with setToken: true if one is already bound (the bind is irreversible — re-running would just waste fees).
  2. Calls launchAgentToken with the env-provided metadata.
  3. Prints every signature with a Solscan deep link.
  4. Re-reads getAgentToken after the launch and warns if setToken was true but the on-chain field hasn’t caught up yet (RPC lag).
Set 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:
ErrorGuardCause
ValidationisGenesisValidationErrorBad input (invalid image URL, name too long, …)
NetworkisGenesisApiNetworkErrorCannot reach https://api.metaplex.com
API 4xxisGenesisApiErrorRejected by the API; check err.responseBody
API 5xxisGenesisApiErrorMetaplex API unavailable; retry with back-off
Re-import the guards from @metaplex-foundation/genesis directly when you need them — Leash doesn’t wrap them.
  • 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 pick SOL (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.