
Register an asset, then mint and burn
Asset registry and custody-backed assets
One record fixes symbol, decimals, supply cap and custody kind for every balance.
Register an asset with its symbol, name, decimals, supply cap and custody kind, and the module writes a canonical record and opens the issuance account. Holders open one account per asset, and you mint units out of issuance or burn them back into it. Pause the asset and transfers, mints, burns and account opens stop. Read the registry through lx_listAssets, lx_getAsset and lx_getBalances. Register, mint and burn are LayerX activities, each priced at 1/10 of a cent.
What it does
The asset module is the balance authority for LayerX payments. An agent registers an asset with a symbol, name, decimals, supply cap and custody kind, and the module writes a canonical record and opens that asset's issuance account. Holders then open one account per asset, and the issuer mints units out of issuance or burns them back into it. Amounts are unsigned counts of the smallest unit; decimals is display metadata only.
Key capabilities
- Registers native assets under a derived asset id, or Paxeer-custody assets under a supplied id.
- Holds every balance in a per-asset account named
agent:<DID>:asset:<asset_id_hex64>. - Mints from the issuance account and burns back into it, enforcing a nonzero supply cap.
- Pauses and unpauses an asset; while paused it refuses transfers, mints, burns and account opens.
- Restricts pause, unpause and mint to the registered issuer; a burn needs the account's own authority key.
- Serves the registry through authenticated reads:
lx_listAssets,lx_getAssetandlx_getBalances.
Who it's for
Issuers of agent-domain assets, and developers building payment or treasury flows on LayerX.
Why it matters
One registry record fixes an asset's symbol, decimals, cap and custody kind, so every balance and payment refers to the same definition. Minted units come out of a dedicated issuance account, so the outstanding total is the cap minus whatever is left in issuance, and that identity is checked before every mint and burn.
Differentiators
Every asset activity binds the supply before and after the activity into the transition context, and a disagreement between the record's total_units and the issuance balance is a fatal supply error rather than a refusal. Custody-backed assets can be reconciled against a finalized custody attestation: the reserve report sums each asset's balances by account kind, and reconciliation fails if the circulating amount exceeds the attested backing or the effective total does not equal it.
Outcomes
- Every balance and payment refers to one registry definition
- Outstanding supply equals the cap minus whatever remains in issuance
- Only the registered issuer can pause, unpause or mint
Technical notes
- Registry capacity is 1024 assets. Symbol is 1-16 ASCII bytes, name 1-32 bytes, decimals at most 38, and the supply cap is a
u128where zero means uncapped. issuer_kindis1for native or2for Paxeer custody. A native asset requires an empty custody reference and the idSHA-256("LX:ASSET:v1" || issuer_did_id32 || salt32); a custody asset requires a custody reference of 1-128 bytes and keeps the supplied id.- Activity types run
0x00010001to0x0001000b: register, pause, unpause, account open, send0x00010005, receive, grant issue, grant revoke, withdraw, mint0x0001000a, burn0x0001000b. The public RPC admits all of these except pause and unpause. - Refusals include
ASSET_ALREADY_REGISTERED (-411),ASSET_PAUSED (-403),ASSET_MISMATCH (-402),PAUSED_SCOPE (-735)for a pause that changes nothing, andARENA_EXHAUSTED (-905)at capacity. - Value movement goes through the transfer-set primitive; a direct balance write is refused with
BALANCE_BYPASS (-408). A reserve report carries at most 128 escrow lines per asset. - Register, pause, unpause, account open, mint and burn are LayerX activities, each priced at 1/10 of a cent.
- Reads are available from the TypeScript
layerx-sdkclient below (Node.js 22 or newer); the joined network-wide asset table islist_assetsonpaxeer-xdk(Python 3.11 or newer).
import { JsonRpcClient } from "layerx-sdk";
const rpc = new JsonRpcClient(process.env.LAYERX_RPC_URL!);
const page = await rpc.listAssetsPage(undefined, 64);
for (const asset of page.assets) {
console.log(asset.symbol, asset.decimals, asset.paused, asset.totalUnits);
}
const first = await rpc.getAsset(page.assets[0]!.assetId);
console.log(first.asset.supplyCap, first.asset.custodyKind, first.stateRoot);More in LayerX agent domain
Agent wallets and account namespaces
Typed subaccounts from readable account names
ExploreAtomic transfer sets
Every payment settles as one unit
ExploreCustody bridge and emergency exit
Deposits proven, withdrawals settled on chain
ExploreEscrow holds, capture and disputes
Pay on delivery, not up front
ExploreBuild on Paxeer.
Give your agent a wallet, set its policy, and settle your first call on LayerX.