CLI Reference
With @chaindaddy/cli you can create tokens, manage registrations, launch on the launchpad, build and publish apps, and run your coin's store and community from the terminal.
Installation
The CLI is in beta: commands, flags and output may change between releases.
npm install -g @chaindaddy/cli@betaRequires Node.js 20+.
Each release is built from public source with npm provenance: verify it with npm audit signatures in a project that installs it.
Sign in
chaindaddy loginThe CLI opens chaindaddy.io and prints a link and a short code. Sign in there the way you always do: any wallet, a hardware wallet, a Safe, or email, Google, Apple or X. Check the code matches, then approve. Every command then acts as your account. There is no API key to create.
That includes publishing an app: the first chaindaddy app sign on a computer makes that computer's own developer key through your login, says so in one line, and reuses it afterwards. It is listed with your other keys on the portal's API keys page, named for the computer. If your account cannot publish yet (no paid plan, or the Developer Beta Program agreement not signed), the command says which, with the link. chaindaddy app whoami shows where your account stands.
- No browser on this machine (SSH, a server): open the printed link on any other device and approve there.
- Agents and scripts: with
--non-interactive,--jsonor no terminal, the first line printed is one JSON object,{"verification_uri", "verification_uri_complete", "user_code", "expires_in"}. Relay the link and code to the person, and the command finishes when they approve. - The login stays on this computer: in the macOS keychain, the Linux keyring, or else
~/.chaindaddy/login.json(readable only by you). It is tied to a key made on this computer, so a copy of it does not work anywhere else. chaindaddy logoutsigns this computer out, and revokes the developer key it made. To sign out a computer you no longer have, open Settings → Connected sites on chaindaddy.io and sign out that device. The developer key that computer made stops working with it.- A computer that was signed out, or whose key was revoked, says so on its next command (
This computer's Chain Daddy sign-in has ended, orThe developer key saved on this computer was revoked): runchaindaddy loginagain. A key inCHAINDADDY_API_KEYis used ahead of the login, so a revoked one there has to be replaced or unset first; the message names the variable. - Money still moves only with your wallet's signature or a payment, exactly as on the site.
Global Options
| Flag | Description |
|---|---|
--json | Output as JSON (machine-readable, no colors). Works on any command |
--non-interactive | Never prompt; fail when required input is missing (for CI and agents) |
--sign-timeout <seconds> | How long to wait for a wallet to approve (default 600). See Signing |
--version | Display CLI version |
--help | Display help for any command |
Environment variables: CHAINDADDY_API_KEY (or CROWN_API_KEY, a cd_live_… API key) and a command's --token flag win over your login; CROWN_DEV_TOKEN overrides the stored developer credential; CHAINDADDY_API_URL (or CROWN_API_URL) points the CLI at another API.
Signing
Any command that needs your wallet takes --signer, so you can approve with the wallet you already use:
--signer | Where you approve |
|---|---|
walletconnect | Any WalletConnect wallet, on your phone or desktop. Scan the QR code the CLI prints, or paste its wc: link. You pair once; later commands go straight to the wallet |
browser | chaindaddy.io, with the wallet you are signed in with there: email, Google, Apple, X, a passkey, or a browser wallet. The CLI opens a page and prints its link and a match code |
ledger | A Ledger on USB, with the Ethereum app open |
trezor | A Trezor, through trezorctl (pip install trezor). Without it, the CLI prints the exact command to run |
keystore | A wallet in ~/.chaindaddy/keystore. Asks for its password |
external | Anything else. The CLI writes what to sign to a file and waits for the signature |
Set a default once and leave the flag off:
chaindaddy signer use walletconnect # every wallet
chaindaddy signer use ledger --account 0xYourWallet # one wallet
chaindaddy signer show # defaults and paired wallets
chaindaddy signer pair # pair a WalletConnect wallet now
chaindaddy signer forget # disconnect themSign or send anything with any signer:
chaindaddy signer sign --message "hello" --signer walletconnect
chaindaddy signer sign --typed-data safe-login-typed-data.json --address <owner> --signer ledger
chaindaddy signer send --chain base --to <contract> --data <hex> --signer browserCommands that take --signer: launchpad login start, app login, developer accept-agreement, airdrop fund, launchpad buy and launchpad release. The last three send a transaction only when you pass --signer; without it they print it, as before. A Safe still signs in two steps: each owner signs with chaindaddy signer sign --typed-data <file>, then finish combines them.
browser acts for the account this CLI is signed in to, so sign in once with another signer first. The page only works when you are signed in on chaindaddy.io as the same account. It shows exactly what you sign, field by field. Check the match code against your terminal. A request expires after 10 minutes and can be approved once.
Agents. With --non-interactive or --json, each signer prints one line on stderr and waits for the approval (up to --sign-timeout), so your agent can pass it to you:
{"sign_request":{"method":"browser","purpose":"Sign in to Chain Daddy as 0x…","url":"https://chaindaddy.io/_sign/…","match_code":"K7P-4QX","expires_at":"…"}}walletconnect gives a wc_uri to pair, and external gives the file to sign, the answer_file to write the signature to, and a command. The CLI never takes a private key in a flag or an environment variable. keystore needs its password typed at a prompt, so an agent uses another signer.
Naming a coin page
Commands that act on a coin page take it as you would say it, with --page: its ticker (--page FLUXGP) or its address (--page chaindaddy.io/FLUXGP/base). The command prints the page it found before it acts (Flux GP (FLUXGP) on Base, page #8); if the ticker has pages on several chains it lists them and stops.
Two ids appear in that line, in API payloads and in a few older flags:
- the chain key: the short name of the page's chain, such as
baseorarbitrum; - the registration id (
crownIdin the API,--crownin flags): the number Chain Daddy gave the page on that chain, the8inpage #8. Ids repeat across chains, so it is always used with a chain.
--chain <key> --crown <id> names a page by its ids wherever --page is accepted.
Commands
login, logout, whoami
| Command | Description |
|---|---|
login | Sign this computer in through the browser (see Sign in). --device-name sets what Settings shows (default: the hostname), --no-browser only prints the link, --read-only asks only to read your account |
logout | End this computer's login on the server and delete it here; revoke the developer key this computer made to sign packages |
whoami | Show the wallet, linked wallets and permissions your credentials act as, and where they come from |
keys
Long-lived API keys, only for a server or CI job that runs with no person present. On your own computer, chaindaddy login is all you need.
| Command | Description |
|---|---|
keys create | Create a cd_live_ developer key, shown once (--save keeps it in ~/.chaindaddy/credentials.json) |
keys create --store <storeId> --name <name> --scopes <scope…> | Create a cd_iap_ store key for your app's server: one store, only the scopes you list |
keys list / keys rotate <id|prefix> / keys revoke <id|prefix> | List, rotate (old key expires in 24h) or revoke developer keys |
Put a key in the server's secrets as CHAINDADDY_API_KEY (or CHAINDADDY_IAP_KEY for a store key).
wallet
Manage the local wallet keystore used for signing transactions.
# Create a new wallet keypair (add --solana for a Solana keypair too)
chaindaddy wallet init
# Import an existing private key or mnemonic
chaindaddy wallet import
# Import a Solana keypair (base58 secret key)
chaindaddy wallet import --solana
# Register a Ledger hardware wallet
chaindaddy wallet add-hardware --type ledger --path "44'/60'/0'/0/0"
# List stored wallet addresses
chaindaddy wallet listWallets are encrypted and stored locally. Hardware wallet entries store only the derivation path and address.
discover
Find inactive registrations available to reclaim.
# List inactive registrations
chaindaddy discover
# Filter by chain
chaindaddy discover --chain arbitrum
# Filter by symbol
chaindaddy discover --symbol DOGE
# Filter by minimum market cap
chaindaddy discover --min-mcap 10000
# Limit results
chaindaddy discover --limit 20| Option | Description |
|---|---|
--chain <chain> | Filter by chain identifier |
--symbol <symbol> | Filter by symbol name |
--min-mcap <amount> | Minimum market cap in USD |
--limit <n> | Max results (default: 50) |
reclaim
Reclaim an inactive registration.
chaindaddy reclaim --crown <crown_id>| Option | Description |
|---|---|
--crown <id> | Registration ID to reclaim (required) |
--wallet <address> | Wallet address to use |
--yes | Skip confirmation |
--dry-run | Simulate without broadcasting transactions |
Prompts for the wallet and confirms the fee before submitting.
status
Show heartbeat health for one token, everything a wallet owns, or every at-risk registration.
# Single token
chaindaddy status --symbol DOGE --chain arbitrum
# Resolve a registration id, then show its heartbeat
chaindaddy status --crown <crown_id>
# Every registration a wallet owns, with heartbeat
chaindaddy status --wallet 0x1234...
# List at-risk / inactive registrations
chaindaddy status --at-risk --limit 100| Option | Description |
|---|---|
--symbol <symbol> | Token symbol (use with --chain) |
--chain <chain> | Chain key, e.g. arbitrum (required with --symbol) |
--crown <id> | Registration/token id to resolve, then show heartbeat |
--wallet <address> | Show every registration a wallet owns |
--at-risk | List registrations that are at-risk or inactive |
--limit <n> | Max ids to scan with --at-risk (default: 100) |
estimate
Estimate what an order will cost: creating a token, its registration included, or with --claim, registering a token that already exists.
chaindaddy estimate --symbol DOGE --chains arbitrum| Option | Description |
|---|---|
--symbol <symbol> | Token symbol |
--chains <chains> | Target chains, comma-separated (default: arbitrum) |
--claim | Price registering an existing token instead of creating one |
--address <address> | With --claim, the token's address, so an OG token shows its free registration |
create
Create a token and its registration, with a wizard or entirely from flags.
# Interactive wizard
chaindaddy create
# Non-interactive
chaindaddy create --symbol MTK --name "My Token" --chains arbitrum,base \
--supply 1000000000 --decimals 18 --mintable --yes
# Batch mode from a JSON spec file
chaindaddy create --batch tokens.json| Option | Description |
|---|---|
--symbol <symbol> / --name <name> | Token symbol and name (skip prompts) |
--chains <chains> | Target chains, comma-separated |
--supply <supply> | Total supply (default: 1000000000) |
--decimals <decimals> | Decimals (default: 18) |
--mintable / --burnable | Token features |
--wallet <address> | Wallet address to use |
--yes | Skip confirmation (required for non-interactive) |
--dry-run | Simulate without broadcasting transactions |
--batch <file> | Read token specs from a JSON file |
profile
Manage coin page profiles.
# Set or update profile fields
chaindaddy profile set --page EXAMPLE --website https://example.com --twitter example \
--description "The example token"profile set takes the coin page as --page. The fields it can set are --description, --tags, --website, --twitter, --discord, --telegram, --logo.
An edit shows on the coin page at once and reaches the published metadata when the holder publishes from their coin page, which their wallet signs.
listings
Prepare listing submissions for CoinMarketCap, CoinGecko and DEX Screener.
# List supported platforms and their submission URLs
chaindaddy listings platforms
# Check how submission-ready a token is for a platform
chaindaddy listings readiness --symbol DOGE --platform cmc
# Build a submission template (real URL + field checklist)
chaindaddy listings export --symbol DOGE --platform coingecko --out ./doge-cg.json| Option | Description |
|---|---|
--symbol <symbol> | Token symbol |
--crown <id> | Registration/token id to resolve to a symbol |
--platform <id> | Platform id: cmc, coingecko, dexscreener (default: cmc) |
--out <file> | Write the template JSON to a file instead of stdout (export only) |
clone
Expand a token to more chains.
chaindaddy clone --token <id> --to arbitrum,base| Option | Description |
|---|---|
--token <id> | Registration/token id to expand (required) |
--to <chains> | Comma-separated target chains (required) |
--supply <supply> / --decimals <decimals> | Override supply/decimals for new chains |
--wallet <address> | Wallet address |
--yes | Skip confirmation |
--dry-run | Simulate without broadcasting transactions |
Shows the chains the token is on, the price for each new one, then sends the deployment.
app
Build, sign and submit apps. Publish your first app walks the path; this is every command.
| Command | Description |
|---|---|
app login | The same as chaindaddy login. For CI, --token cd_live_… stores an existing key, --wallet --challenge --signature signs in with a signature made elsewhere, --signer signs the challenge with any signer, and --keystore signs with a local keystore wallet |
app key create | Create a new developer API key — returned exactly once (the same as keys create) |
app key list | List your API keys |
app key rotate <id|prefix> | Create a new key and schedule the old one for expiry in 24h |
app key revoke <id|prefix> | Immediately deactivate an API key (--force for your last one) |
app init <template> [dir] | Scaffold a new app project: widget, headless, or full; godot or unity for a game made in that engine (the manifest's engine block, the files that let the game talk to the page, and the export settings to use); web for a browser game you already built. With godot, unity or web, --build <dir> copies the export you already have into engine/. Or start from a working app with --template interactive, community or game (--from <path> takes the templates from a local copy). The manifest id defaults to <developer ID>/<dir> |
app validate [dir] | Validate capp.json against the manifest schema |
app build [dir] | Bundle a widget with esbuild (one ESM file, react external); fails on a missing export or an import the page cannot provide |
app dev [dir] | Run a widget on a local coin page, in the same sandbox as production, with sample data; rebuilds on save. A game's fullscreen view draws the page's HUD (switches: HUD mark, HUD price, HUD Trade). --bundle <file> watches your own bundler's output; --fixtures <file> replaces the sample data; --unreviewed applies an unreviewed build's limits. A project's paid/ folder is served the way the platform serves it, by a signed URL only; the page's owns paid files switch (?paid=no) plays a visitor who has not bought. See Test locally |
app scan [target] | Run the platform security/size scanner on a bundle or .capp package. With no target in an engine app project, or on its package, it checks the engine/ export the way review will (--engine <dir> names another folder). --run also starts the app in a headless Chrome on your machine, in the page's sandbox, and fails if it does not start (the boot check); --screenshot <file> keeps what it drew, --chrome <path> picks the browser. Either way it lists the paid folders (--paid <dir>), and warns about one whose name is not a store item key or a paid folder inside engine/ or assets/, which is public |
app pack [dir] | Produce dist/<name>-<version>.capp from the manifest, bundle, and assets. For an engine app it packs engine/ (--engine <dir>) and lists engine.files from the folder when capp.json leaves it out. A paid/ folder (--paid <dir>) is packed as paid files: one folder per store item, paid/<sku>/… |
app sign [package] | This computer signs a package as your developer account; defaults to the newest in dist/ (--in-place overwrites it, otherwise it writes <package>.signed.capp). After chaindaddy login it needs no key: the first run makes this computer's own. A server or CI job sets CHAINDADDY_API_KEY |
app verify <package> | Verify a package: structure, hashes, and (with --check-signature) HMAC |
app inspect <package> | Show the contents and metadata of a package |
app submit [package] | Upload a signed package (--watch streams the scan log; --request-review sends it for review once the checks pass) |
app publish [package] | Pin a signed package with your own storage and submit its CID instead of uploading it (--pin pinata, or --pin none if you pinned it yourself); see Publish from your own storage. A package with paid/ files is refused: nothing pinned on IPFS can be kept for buyers |
app status <submissionId> | Get the current status of a submission |
app logs <submissionId> | Fetch or stream the scan log for a submission |
app list [apps|submissions] | List your apps or submissions |
app request-publish <submissionId> | Send a checked build for review |
app rollback <app> <version> | Make one of your approved builds the live one again, with no review. <app> is the slug or id from app list. Any approved version can be chosen, so the same command switches back; asking for the live build changes nothing. Coin pages run it from their next load. See After approval |
app whoami | Show who is signed in, your plan, the program agreement, your developer ID and whether this computer can publish, each with its next step |
An uploaded build can be tried on your own coin page before review, where only you see it: Preview a build on your own coin page.
Exit codes (stable, for agents and CI): 0 success, 1 user error, 2 system error, 3 validation failed, 4 auth error, 5 server error, 6 temporary (rate limited, the service unavailable, or no answer came back: run the same command again later). With --json the error on stderr is {"error", "code", "retryable", "retryAfterSeconds", "details"}; retryAfterSeconds is how long the server asked you to wait, or null. A write that exits 6 may have landed: run it again with the same idempotency key.
What is in a package
app pack writes dist/{name}-{version}.capp, a zip. The same source gives byte-identical archives (--no-reproducible for real timestamps), and app inspect <package> shows what one contains.
| Entry | In | Purpose |
|---|---|---|
META.json, manifest.json | every package | Format and build details; your capp.json |
bundle.js | a widget | Your compiled widget (app build, or app pack --bundle <file> from your own bundler) |
engine/** | an engine app | Your web build or Godot or Unity export |
runner.config.json | an app with a runner | The runner's registration |
assets/** | optional | Files your app loads, and the icon capp.json names |
paid/<sku>/** | optional | Paid files, from ./paid |
HASHES.json | every package | The SHA-256 fingerprint of every other entry |
signature.json | after app sign | Proof of which developer key signed the manifest and HASHES.json |
Signing here means your computer's developer key, not your wallet: app sign computes an HMAC-SHA256 over the manifest, HASHES.json and your identity with the key's secret. The server checks it against the key, so it knows which of your keys uploaded the build. A signature is good for 24 hours, and unsigned packages are refused. A server or CI job signs with CHAINDADDY_API_KEY (or --key-secret); the secret never travels with the package.
Publish from your own storage
Instead of uploading a package, app publish pins it with your own IPFS storage and submits only its content address (CID). Chain Daddy keeps no copy: the build is checked from your storage, and visitors load it from your gateway first, so its traffic is on your plan. Most apps should upload with app submit.
export PINATA_JWT=… # your Pinata key; it goes to Pinata, never to Chain Daddy
chaindaddy app publishIt checks the signed package, computes the CID on your machine (Kubo's CIDv1 defaults, the same CID ipfs add --cid-version 1 -r gives, except when a folder holds more than 1,000 files: there the two can differ, so let app publish pin it rather than --pin none), pins the files with your Pinata account, and submits the CID with your dedicated gateway (from PINATA_GATEWAY, or your account). The build starts in fetching while Chain Daddy fetches it, for up to 30 minutes, then goes through the same checks and states as an upload (chaindaddy app status <id> --watch). A failed fetch shows as SOURCE_UNREACHABLE.
| Option | |
|---|---|
--pin none | You pinned it yourself; just submit the CID (with --gateway) |
--gateway <url> | Your own gateways, tried first, in order: up to 4 https origins (replaces the Pinata default) |
--dry-run | Compute the CID only; nothing is uploaded or submitted |
--car-out <file> | Also write the package as a CAR with the same CID, for a provider or node that takes CARs |
--no-submit | Pin, but don't submit |
--pin-tag key=value | Tag the pin in your Pinata dashboard (app and version are always set) |
- Keep every approved build pinned for as long as it is live, or you might roll back to it.
- No paid files: anyone can read a file pinned on IPFS, so a package with
paid/is refused (PACKAGE_PAID_NEEDS_UPLOAD). - Preview: a web build published this way can be previewed on your coin page once we have confirmed its CID holds the package you signed. A Godot or Unity export cannot.
- Godot and Unity builds must be Gzip-compressed, not Brotli:
app publishrefuses a.brbuild. A web build publishes as it is. - Gateway access controls: if your Pinata gateway restricts host origins, allow
*.play.chaindaddy.live, or players fall back to slower public gateways.
launchpad
Launch a token in a launchpad pool through the API. Built for launchers that are a Safe, whose owners sign from the command line; an EOA works too.
| Command | Description |
|---|---|
launchpad login start --address <addr> [--safe] [--chain <id>] | Fetch a sign-in nonce (valid 5 minutes). With --signer, signs and signs you in at once. With --safe, writes the typed data each owner signs (--out) |
launchpad login finish --sig <sig> [--sig <sig>] | Submit the signature(s) and store the session. For a Safe, one signature per signing owner, any order |
launchpad launch --config <file> | Launch from a JSON request. --dry-run --rpc <url> builds and simulates only. --safe <addr> --rpc <url> writes an approveHash plan so the Safe launches, with a dev-buy, in one transaction |
launchpad confirm --chain <id> --tx <hash> --config <file> | Record a launch the launcher sent itself (a Safe transaction) so its coin page and crown follow |
launchpad buy --chain <id> --token <addr> --numeraire <addr> --amount <eth> --recipient <addr> | Dev-buy a launched token. --signer sends it from your wallet; --safe <addr> writes a plan entry instead of printing calldata |
launchpad safe-plan --chain <id> --safe <addr> --to <addr> --data <hex> --rpc <url> | Write any call a Safe must make (an approve, a fee claim, a vesting release) as an approveHash plan |
launchpad sign-message --address <Safe> --chain <id> --text-file <file> | Sign any message as a Safe: writes what the owners sign; --finish --sig … combines their signatures |
launchpad release --chain <id> --token <addr> --beneficiary <addr> --rpc <url> | Show and build the calls that release vested tokens. --signer sends the ones with tokens to release |
developer
Join the Developer Beta Program from the command line: as your own wallet with --signer, or as a Safe, whose owners sign the agreement.
| Command | Description |
|---|---|
developer accept-agreement --signer <kind> | Signs the agreement as the wallet you are signed in with, and submits it. Joining for the first time also takes --display-name and --email |
developer accept-agreement --safe <address> | Fetches the agreement for the signed-in Safe and writes the typed data each owner signs (--out, default developer-agreement-typed-data.json). Joining for the first time also takes --display-name and --email (--website-url and --bio are optional). --chain is the chain the Safe lives on (default 8453, Base) |
developer accept-agreement --finish --sig <owner sig> --sig <owner sig> | Combines the owners' signatures, in any order, and submits them |
Sign in as the Safe first: chaindaddy launchpad login start --address <Safe> --safe --chain <id>, then chaindaddy launchpad login finish --sig <owner sig> --sig <owner sig>. The Safe needs an active paid plan, like any member. Once it has joined, create its developer key with that session (chaindaddy app key create --token <session> --wallet <Safe>): app login signs as a single wallet and cannot sign for a Safe.
iap
Run the store for your token: items you sell for it, rewards, and what each user holds. Each command is one API call, so a script or agent can do anything the dashboard does. See Store and Rewards.
Name the coin page with --page. Wherever a command takes <store>, give the store's id or its coin page the same way (chaindaddy iap sku list FLUXGP).
| Command | Description |
|---|---|
iap store open --page <page> | Open the store for a coin page you manage |
iap store list · iap store show <store> | Your stores / one store (fee, payout, whether it is live, the token's live dollar price) |
iap store update <store> | --name, --pause / --resume, --payout <address> |
iap store test <store> | The test store beside a live store: created on first use with a copy of its catalog, returned after that. Prints the test store's id, which iap key create takes to make a cd_iap_test_… key |
iap sku list <store> | Every SKU, including drafts and archived |
iap sku create <store> | From --file sku.json and/or flags (--sku --type --name --price or --price-tokens, or --price-usd 5 with optional --min-price-tokens / --max-price-tokens (Price in dollars, recommended), --currency token|native|usdc (What the buyer pays in; default and recommended: token), --grants, --split address:percent (Revenue splits, repeatable; --clear-splits on update), --max-app-spend <n> (let apps spend a consumable; --clear-app-spend on update), --rule, --duration, …) |
iap sku update <store> <sku> · iap sku archive <store> <sku> | Change a SKU (only the fields given) / stop selling it |
iap order create <store> --sku <key> --wallet <w> | Create an order for a user (your server, with a store key); the response says how to pay |
iap order list <store> · iap order show <store> <order> | --status, --wallet, --cursor, --limit. show prints paid by (the wallet the money came from) and, on a checkout's second payment, which order completed the checkout first and what to send back to whom |
iap order test-pay <order> | Pay a test store's order with no chain and no money: it is confirmed at once, with its receipt, items and webhooks (livemode: false). iap orders is the same command group |
iap order refund <store> <order> | The store's owner records paying a buyer back from their own wallet (--tx, --note); the items are taken back. All sales are final, so this is never a refund from Chain Daddy, and it is refused on an app's sales |
iap entitlements <store> --wallet <w> | What a wallet holds (--sku <key> lists holders instead) |
iap grant · iap consume · iap revoke | <store> --wallet --sku --qty; consume fails with INSUFFICIENT_QUANTITY, revoke without --qty takes all |
iap drop list · create --file · show · status <status> · recipients --csv · award --wallet | Rewards: claim links, pushes to a list, awards from your server |
iap key create <store> --name --scope … | A store key for your server; the secret is printed once |
iap key list <store> · iap key revoke <store> <keyId> | |
iap events <store> [--after <id>] [--follow] | The store's event feed; --follow --json prints one event per line |
iap webhook set <store> --url <https-url> | Send the store's events to your endpoint (--event to filter). A new webhook prints its signing secret once |
iap webhook show · test · rotate · delete | Last 20 deliveries / queue an iap.test event / new signing secret / remove it |
iap webhook redeliver <store> [--after <eventId>] [--limit <n>] | Send the store's events after --after (up to 1000) to the webhook again, under their original ids. Prints the --after to continue from |
iap link <store> <sku> · iap link <sku> --symbol <sym> --chain <key> | A payment link: the coin page with the item's purchase sheet open. --qty 1-99, --ref <tag> (kept on the order and its webhooks). With a store id it checks the item is on sale in the live store; test stores have no links |
Credentials: your account key or login (as for app), or a store key with --key or CHAINDADDY_IAP_KEY for the store-scoped commands. A store key is sent alone; store routes need no cd_live_ key. These always run as your account, never as a store key: iap store open, test and list, every iap key command, and iap webhook set, rotate and delete. Every other command uses the key in CHAINDADDY_IAP_KEY when that variable is set, ahead of your login, so the key needs the command's scope (iap webhook test and show need events:read). There is no command for checkout sessions: your server opens, reads and test-pays one over HTTP. Every command that POSTs sends an Idempotency-Key: pass --idempotency-key or let the CLI generate one, and with --json it is printed as idempotencyKey so a retry cannot grant or sell twice.
airdrop
Token prizes: a pool funded from your wallet that your server pays winners from.
| Command | Description |
|---|---|
airdrop create --page <page> --name <name> | Create a prize pool as a draft for a coin page. Caps: --budget-tokens, --max-award-tokens, --max-awards, --wallet-max-count, --wallet-max-amount-tokens, --wallet-window, --daily-max-tokens (each also in base units) |
airdrop list · airdrop get <id> | Your pools / one pool: budget left, awards made, caps and its key |
airdrop status <id> <status> | active, paused, completed or cancelled |
airdrop fund <id> | Print the approve to send from your wallet and the gas still to pay. Nothing is sent unless you pass --signer, which sends the approve (EVM) |
airdrop key create --campaign <id> | Create a store key for your server and pin it to the pool. The secret is printed once |
airdrop award <id> --store <id> --wallet <address> --amount-tokens <n> | Pay a winner. --reason, and --wait to wait for confirmation |
airdrop awards <id> | Find a pool's awards by --idempotency-key, --wallet or --status |
poll
Polls on a coin page: free, with no stakes and no prizes. Name the page with --page.
| Command | Description |
|---|---|
poll create --page <page> --title <question> --option <label> --option <label> | Create a poll on a page you own, with 2 to 10 options. Who can vote: --audience everyone|members|holders (default holders), or --group <name or id> for a holder group. --counting holdings|one_per_wallet where holdings can be weighed, --min <coins> for a holders poll. It opens in 5 minutes and closes 7 days later; --starts and --ends take a date-time or a duration such as 2h or 7d |
poll list --page <page> | The page's polls, newest first (--status active|ended|canceled|draft) |
poll get <pollId> · poll results <pollId> | One poll / its tally, up to 30 seconds old |
poll vote <pollId> <option> | Vote, or change your vote, as the wallet you are signed in with. The option is its number in poll get, or its label |
poll my-vote <pollId> | Your vote, if you have voted |
poll cancel <pollId> | Cancel a poll you created. Its votes stay recorded |
poll post <pollId> --telegram · --discord <channel> | Post it in the Telegram group, or a channel of the Discord server, connected to the coin: now if it is open, else when it opens. --chat <id> and --guild <id> name another one |
A vote cast with chaindaddy login is an agent's vote: the server records it with via: agent, and the results count it apart from people's votes (agentVotes), never in the totals or shares. poll vote says how its vote was recorded.
broadcast
Message your coin's community. For the page's owner or a manager.
| Command | Description |
|---|---|
broadcast send --page <page> --title <text> --body <text> | Send now, or later with --at (a date-time, or a wait such as 2h; at least 5 minutes ahead). --group <name or id> sends to one holder group (paid plan). --channel push,email,telegram,discord,sms adds channels to in-app for members who turned them on; sms is a daily text from Chain Daddy with a link, never your message. --urgent also reaches members who chose big news only. --image and --link take https links. Prints the page's limits first. A sent message cannot be recalled |
broadcast history --page <page> | Past sends, newest first (--limit, --offset). Anyone can read the public ones |
broadcast stats · limits · delivery | Members and sends / sends left this week / what Telegram and Discord do with a send |
broadcast scheduled --page <page> · broadcast cancel <broadcastId> | Scheduled broadcasts not sent yet / cancel one |
The sender is the wallet you are signed in with; --wallet names another of yours. There is nothing to sign.
community
| Command | Description |
|---|---|
community members --page <page> | Members, with the contact details they shared (--group, --status all|verified|unverified, --limit, --offset). --csv <file> writes every match to a file only you can read, or - for stdout (Developer plan) |
community remove <wallet> --page <page> | Remove a member and their contact details. They can join again |
community groups --page <page> | Your holder groups, with each one's id and member count |
community unverified --page <page> · community reverify <wallet> --page <page> | Members whose holdings did not verify / check one again |
community join-settings --page <page> | Who may join. --open-to holders|everyone and --min-usd <dollars> change it |
community join --page <page> · community leave --page <page> | Join or leave a page's community as the wallet you are signed in with. join --channel email,telegram adds channels you set up on chaindaddy.io |
All but join and leave are for the page's owner or a manager.
poll, broadcast and community act as your sign-in: chaindaddy login, or a session token in --token. A cd_live_ key cannot vote, send or manage members, and one in CHAINDADDY_API_KEY is used ahead of the login, so the error says to unset it. Every change sends an Idempotency-Key: pass --idempotency-key to retry it safely (with --json it is printed as idempotencyKey). The same key and request within 24 hours changes nothing twice.
oauth
Register the sites and apps that use Sign in with Chain Daddy. Uses your account key or login (a Developer program member).
| Command | Description |
|---|---|
oauth client create --name <name> --redirect-uri <url> … | Register a client. --redirect-uri is exact and repeatable (https, or http://localhost / http://127.0.0.1); --confidential issues a client secret, printed once; --page <page> binds it to a coin page you hold or manage |
oauth client list · oauth client get <clientId> | Your clients / one client |
oauth client update <clientId> | --name, --redirect-uri (replaces the list), --page (or --crown) or --unbind-crown |
oauth client delete <clientId> | Sign-in through it stops at once |
embed
The embeds for your own site or README, the same ones the Coin Manager gives you. No credential needed.
| Command | Description |
|---|---|
embed badge <symbol> <chain> | The "Verified on Chain Daddy" badge as HTML (--markdown for a README) |
embed card <symbol> <chain> | The token card iframe with its link |
embed item <symbol> <chain> <sku> | One item's card, which opens its payment link (ref=embed); --name sets the frame's title |
Each takes --check, which fetches the page's badge and reports whether its embeds answer (they show only for a verified coin page), exiting 3 when they don't, and --site to point at another site.
JSON Output
All commands support --json for scripting and automation:
# Get machine-readable output
chaindaddy status --wallet 0x1234... --json | jq '.'
# Use in scripts
EXPIRED=$(chaindaddy discover --chain arbitrum --json | jq -r '.tokens[0].tokenId')
chaindaddy reclaim --crown "$EXPIRED" --yes