Skip to content

Creating a Standalone Token

The Deploy Token flow creates an ICRC token without running a Liquidity Generation Event (LGE). It is the path to take when you want a token your own dApp drives — custom minting account, custom parameters, programmatic minting — rather than a fair-launch campaign with a bonding curve and a DAO. The two paths are distinct: a standalone token gets no lock or vesting facility on the platform unless it later becomes an Imported DAO (see below). See the full flow in Core Workflows.

Standalone creation is a two-call ICRC-2 payment then a deploy. The user pays 5 ICP; the backend verifies the payment and deploys the token’s ledger and index canisters. No governance canister, bonding curve, escrow, or pool is involved — those belong to the LGE path.

StepMethod (ohshii_launcher_backend)What happens
Prepareprepare_token_creation()Returns payment_info (amount, expiry, subaccount).
ApproveICP ledger icrc2_approve(backend, amount)User authorizes the 5 ICP collection.
Deploycreate_token_with_icrc2_payment(args)Backend runs icrc2_transfer_from to collect, allocates funds, deploys the ledger + index, returns Ok(ledger_id, index_id).
BackendICPLedgerFrontendUserBackendICPLedgerFrontendUserDeploy token (metadata, payment)prepare_token_creation()payment_info (amount, expiry, subaccount)icrc2_approve(backend, amount)create_token_with_icrc2_payment(args)icrc2_transfer_from (collect)allocate funds, deploy ledger + indexOk(ledger_id, index_id)Token created

The deployed token is ICRC-1/2/3 compliant and ships with an index canister for transaction tracking — the same ledger + index infrastructure every OhShii token receives.

The standalone minter exposes the token’s economic and custody parameters at creation time:

ParameterNotes
Minting accountThe account authorized to create supply — a transfer from it is a mint. Permanent, and it defaults to the management canister (aaaaa-aa), which can never mint. Set it to your dApp’s backend canister to mint programmatically (see below). It closes only the ledger’s own mint path: any controller of the ledger canister can still replace its code (see Controllers).
Subnet selectionWhere the token canisters are created: let the network choose, a named subnet type, a subnet from the list, or a typed principal — see below. Permanent.
Transaction feesThe per-transfer ICRC ledger fee.
DecimalsToken decimal precision.
Initial supplyThe starting supply, credited in full to one account: the creator’s default account (the creating principal, no subaccount). The install takes no list of recipients. May be set to 0 when supply will be minted later by your backend.
ControllerThe token creator is always a controller; further controllers are creator-chosen (see below).

Because these parameters are creator-defined rather than the LGE’s standardized, pre-tested configuration, standalone tokens are not added to OhShii Locker. A standalone token that has not been imported as a DAO has no lock or vesting facility on the platform: the Locker accepts direct locks of OHSHII only, listing new tokens there is disabled, and the per-DAO lock system needs the token’s own DAO governance canister.

The ledger is born with a single balance, so distribution happens after creation: the creator sends ordinary ICRC-1 transfers from that account (a team allocation, a treasury, a liquidity deposit, an airdrop). Each transfer pays the token’s transfer fee and appears in the ledger’s history like any other transfer.

Locks, treasury and handover through an Imported DAO

Section titled “Locks, treasury and handover through an Imported DAO”

An Imported DAO adds, for the token: locks in the DAO’s governance canister (any holder can lock; each lock gives voting power in that DAO; the rules are in OhShii Locker integration), an optional treasury (the governance canister’s main account, empty until someone transfers to it) and an optional handover of the ledger’s controllers to the DAO. Prerequisites: ICRC-1 and ICRC-2, 8 decimals, an approved ledger build (every OhShii standalone-minter ledger qualifies), a ledger not already used by another OhShii DAO; an ICPSwap pool is optional. Imported DAO creation is currently disabled — see Importing a DAO.

The Cycles Minting Canister (rkp4c-7iaaa-aaaaa-aaaca-cai) decides which subnet a new canister may be created on. The form offers four answers, and the choice is permanent for the canisters this creation deploys.

ChoiceWhat is sentWhat happens
Let the network choose (default)no subnet_selectionThe Cycles Minting Canister places the canister on one of its own default subnets.
A named subnet typeFilter { subnet_type }Two types are offered: Higher replication (fiduciary) and Europe only (european).
A subnet from the listSubnet { subnet }The canister is created on that subnet.
A typed principalSubnet { subnet }Free text, for a subnet whose id you already have.

How the list is built. Membership comes from the Cycles Minting Canister’s get_default_subnets. Each entry is decorated with figures read from the IC dashboard API — data-centre countries, node count, number of countries, running canisters and memory load — and sorted least-loaded first. The countries render as flags, SVGs vendored with the app rather than fetched from anywhere, with the two-letter code in a mono chip when a file does not load. The dashboard supplies display only: a subnet it does not describe still appears, without its figures. A subnet is listed only when every one of its nodes is up, and the picker names how many were hidden and why. Hiding is a display rule, not a refusal — a hidden subnet is still accepted if you type its id. A typed principal is checked against the accepted set (the default subnets plus every subnet under every type the Cycles Minting Canister names) whenever both lists can be read; when they cannot, it is sent unchecked and the form says the list could not be loaded.

The refusal happens before the payment. At prepare_token_creation, before the quote is issued and before any ICP moves, the backend resolves get_default_subnets and get_subnet_types_to_subnets and refuses a pinned subnet outside their union with SUBNET_NOT_OPEN, or a Filter naming a type the Cycles Minting Canister does not list with SUBNET_TYPE_UNKNOWN (the message names the types it does list). The two lists are read at most once an hour and cached in the canister’s heap, and they are not read at all when nothing is pinned. When neither list can be read the selection is accepted without this check, and the canister records that it accepted the selection unvalidated — an unavailable list never blocks a creation. In that case the Cycles Minting Canister may still refuse the subnet at canister creation, which runs after the debit and after the cycles leg; the refund rules for that case are in Core Workflows.

Creating a token requires a verified account. The prepare endpoint runs the identity gate at “any verified provider”, so either current provider qualifies — Telegram or Google — and nothing on the creation path requires the stronger of the two.

The form reads the connected account’s verification state when it mounts. While that read says the account is not verified, a card sits above the form, the submit button is disabled with the reason next to it, and the card links to /verify with either provider pre-selected. The card is a courtesy, not the gate: the backend refuses an unverified caller at the prepare endpoint regardless, and the form shows that refusal as a verification notice.

What the card discloses, verbatim:

OhShii never receives or stores your e-mail address, phone number or username. The verification canister keeps only a salted fingerprint that binds one account to one wallet, and no query returns it. Telegram counts as the stronger of the two; either one is enough to create.

The same card and the same gate apply to index-canister creation, LGE creation, LGE relaunch and the imported-DAO flow. Provider mechanics are in Google Verification and Telegram Verification.

Every standalone token is deployed creator-controlled:

ControllerAddedRemovable?
The creatoralwaysnever dropped by any platform flow (anti-lockout)
Up to 8 more, creator-chosen — including the opt-in monitoring canisters (CycleOps balance checker, NNS Root status passthrough)only if the creator explicitly picks themyes

The OhShii backend is never a persistent controller — it is rejected even on explicit request. OhShii operates as an escrow, not a custodian: the backend holds control only transiently (during the install, and during updates the creator signs a temporary grant for) and removes itself on every exit path. Nothing else is ever added on the creator’s behalf. The LGE token controller structure is analogous in spirit: the OhShii backend and OHSHII governance hold control only until finalization and are removed at that point to hand the DAO full autonomy.

When you set your dApp’s backend canister as the minting account at creation time, minting becomes a single ICRC-1 call: because the minting account is authorized to create supply, calling icrc1_transfer from that backend canister to a target address effectively mints new tokens to that address. No separate mint endpoint is needed.

This is the model for dApps that need dynamic or continuous issuance — usage-based rewards, activity incentives, performance payouts in skill-based games, referral programs, and gamification (XP, boosts, digital items). Pair it with an initial balance of 0 so all supply originates from your backend’s icrc1_transfer calls.

PathWhat it gives youLocks and vesting
LGE (Launch LGE) — creation currently disabledBonding-curve fair launch, per-campaign governance canister, automatic ICPSwap pool at finalization, standardized parameters, refund-on-failure.Vesting locks and manual locks in the campaign’s own governance canister (never on the OhShii Locker).
Standalone (Deploy Token)Custom minting account, controller, subnet, decimals, transfer fees, initial supply; programmatic minting from your backend.None on the platform, unless the token becomes an Imported DAO.

For the LGE creation, participation, and finalization flows, see Core Workflows.

  • ohshii_launcher_backend — prepare_token_creation, create_token_with_icrc2_payment (src/backend/src/lib.rs).
  • Core Workflows — Create Token (§2), Create LGE, finalization, refunds.