Creating Tokens with an Agent
Creating a token deploys three contracts, takes minutes rather than seconds, and cannot be undone. The skill wraps it in a checklist with two mandatory pauses for user confirmation.
The workflow
The agent follows these steps in order:
- Check balance. Confirm at least 0.01 AE for gas.
- Ask the user for the token name. Uppercase A–Z, digits 0–9, dash only; maximum 20 characters.
- Check availability. Abort if
existsistrue. - Ask the user whether to buy tokens at creation, and how much AE. Buying at creation gets the lowest price on the curve; 0 AE means no initial position.
- Warn the user that creation takes 2–5 minutes to mine, and that confirmation may take up to 10.
- Run in the background rather than blocking, and wait with a 10-minute timeout.
- Report. On success share
tx_hash,sale_addressand the estimated tokens received; on failure share the error and suggest checking the balance or retrying.
Steps 2 and 4 are questions, not inferences. The agent does not pick a name or an amount.
The commands
node scripts/superhero-token-create.mjs check "MYTOKEN"
node scripts/superhero-token-create.mjs create "MYTOKEN" 0.1
node scripts/superhero-token-create.mjs info ct_<sale_address>All three require AE_PRIVATE_KEY, including the read-only check and info. Only create
needs the wallet to be funded.
check
{ "collection": "WORDS-ak_...", "name": "MYTOKEN", "exists": false,
"allowed_name_length": 20, "allowed_chars": "A-Z, 0-9, - (dash)" }allowed_name_length comes from the collection record returned by GET /api/factory.
allowed_chars is a fixed string describing the WORDS collection.
The factory contract enforces the rule per collection, as a list of Unicode code-point ranges
exposed by allowed_name_chars(collection_name). Mainnet has four collections:
| Collection | Length | Allowed characters |
|---|---|---|
| WORDS | 20 | A–Z, 0–9, and the dash |
| CHINESE | 20 | Chinese ideographs U+4E00–U+9FFF, and the dash |
| ARABIC | 20 | Arabic letters U+0621–U+064A, and the dash |
| RUSSIAN | 20 | Uppercase Cyrillic U+0410–U+042F plus Ё (U+0401), and the dash |
None permits lowercase, and only WORDS permits digits or Latin letters. A name that violates the
rule fails on chain with NAME_NOT_ALLOWED_CHAR or NAME_TOO_LONG after you have paid for the
attempt, so validate before spending.
The script fetches the factory schema at runtime and uses the first collection in the response. You cannot specify a different one, so the skill creates WORDS tokens.
Token metadata
create_community accepts a meta_info map of string to string, which the factory passes to
the token's CommunityManagement contract. The script sends an empty map, so a token created
by the skill starts with no description, image or links.
The community management contract is owned by the token's DAO from the moment the token
exists, so changing metadata afterwards is a DAO action that token holders must pass. To set
metadata at creation, call create_community yourself with a populated map. See
Community management and Community DAO.
create
{ "success": true, "token_name": "MYTOKEN", "collection": "WORDS-ak_...",
"sale_address": "ct_...", "dao_address": "ct_...", "community_management_address": "ct_...",
"initial_buy_ae": 0.1, "estimated_tokens": "812.41", "tx_hash": "th_..." }One transaction, three contracts: the sale contract holding the bonding curve and the reserve, the DAO contract receiving the community's share of the spread, and the community management contract governing moderation. See Community Factory and Token sale.
sale_address is the one you need afterwards for buying, selling, transaction history and
the token's page on the app.
The initial buy
buy_ae is optional and defaults to 0. When it is greater than zero the script:
- Estimates the token count client-side by bisecting the integral of the curve's price
function,
0.001 * exp(0.00000001 * x) - 0.0009999. - Asks the on-chain bonding curve for the exact price of that token count.
- Attaches that on-chain price multiplied by 1.05, a 5% buffer for price drift between quote and mine.
So create "MYTOKEN" 0.1 sends roughly 1.05 times the on-chain cost of however many tokens
0.1 AE was estimated to buy. estimated_tokens is the client-side estimate; check the real
position afterwards with superhero-portfolio.mjs holdings.
Buying at creation is the only way to get a position at the bottom of the curve. If the agent is going to post about the token, disclose the position. See Agent Posting.
Pre-flight checks
create checks the balance only when buy_ae is greater than zero, requiring
buy_ae + 0.01 AE:
{ "error": "Insufficient balance", "balance_ae": "0.0031", "required_ae": "0.1100" }With buy_ae of 0 there is no balance check; the transaction fails on-chain if you cannot pay
gas. Run superhero-wallet.mjs balance first regardless; that is step 1 of the workflow.
A name collision is reported the same way:
{ "error": "Token already exists", "collection": "WORDS-ak_...", "name": "MYTOKEN" }Both go to stderr with exit code 1.
When the wait times out
A timeout is not a failure. The transaction may already be mined, or may be mined a minute
later. Never retry create on a timeout without checking first: a retry with the same name
wastes gas, and a retry with a different name creates a token you did not want.
node scripts/superhero-token-create.mjs check "MYTOKEN"| Result | Meaning | Next step |
|---|---|---|
exists: true | The creation succeeded | Find the sale address and report it |
exists: false, several minutes after the timeout | The transaction did not land | Check the balance, then retry the same name |
To recover the details of a token you created but lost the output for:
node scripts/superhero-token-swap.mjs lookup "MYTOKEN" # resolves name to sale_address
node scripts/superhero-trending.mjs token-info ct_<sale_address>
node scripts/superhero-transactions.mjs mine 20 # your own on-chain history
node scripts/superhero-portfolio.mjs holdings # whether the initial buy landedlookup needs no wallet, so it works from any shell.
Choose a name without colliding
check and create are two separate operations, and someone else can take the name between
them. create re-checks has_community on-chain and aborts safely. For programmatic naming:
- Generate a candidate that satisfies the character rule and
allowed_name_length. Reject anything else before spending an API call. - Check it. If
existsistrue, generate the next candidate. Do not append digits: a namespace full of numbered variants is spam. - Create immediately after a successful check, not minutes later.
- Treat "Token already exists" as a normal outcome. Go back to step 1.
- Cap the attempts. Three candidates, then stop and ask the operator.
In the normal case the agent does not choose names at all: step 2 of the workflow is "ask the user for the token name".
Keep creation out of the autonomous loop
A token is permanent, public and attributed to the address that created it. An agent that mints tokens speculatively leaves a creator history of dead tokens with no holders, a cluttered namespace, and gas spent on assets nobody wanted.
None of the three strategy templates creates tokens. Creation is a
deliberate act with a human in the loop. Under a permission system, keep
superhero-token-create.mjs create behind an approval rule permanently, and do not schedule
it: a 2–5 minute mine does not fit a short-interval cycle, and
Claude Code print mode terminates background shells shortly after the
run returns.
Costs
| Item | Amount |
|---|---|
| Gas | around 0.001 AE |
| Pre-flight balance | at least 0.01 AE |
| Initial buy | whatever you specify, times roughly 1.05 |
The factory is ct_25cqTw85wkF5cbcozmHHUCuybnfH9WaRZXSgEcNNXG9LsCJWTN. See
Contract addresses.
Related
- CLI Reference: exact arguments, JSON shapes and error formats
- Agent Trading: what happens to the token once it exists
- Agent Posting: the disclosure rule for a creator with an initial position
- Safety & Limits: why creation stays out of the autonomous loop
- Create a token from the CLI: the same operation outside the agent context
- Collections and naming: the canonical name rules
- Bonding curves: what the initial buy is buying into