> arkade$ ↑ online  ◆  bitcoin-native assets  ◆  op_return 0x41524b  ◆  mutinynet testnet active  ◆  no sidechain · no bridge · same wallet · same transactions  ◆  stablecoins · loyalty points · rwa · in-game currency  ◆  control assets · conservation rules · vtxos  ◆  
◆ Bitcoin-native · Arkade Protocol

Arkade$ Assets

Issue, send, and explore custom assets on Bitcoin. Stablecoins, loyalty points, real-world assets — the same wallet, the same transactions, with asset balances attached. No sidechain. No bridge.

[ docs.arkadeos.com ↗] [ mainnet explorer ↗] [ infra guide ↓]
mode
network ◆ demo · simulated
What are Arkade Assets

Arkade Assets let anyone issue custom tokens — stablecoins, loyalty points, real-world assets — directly on Bitcoin. They travel with regular Bitcoin transactions using OP_RETURN outputs encoded in TLV format with ARK magic bytes 0x41524b. Recipients need only an Arkade address.

◆ Bitcoin-native No sidechain No bridge Same wallet
How assets are identified

Every asset gets a permanent ID at genesis: (txid, group_index). Metadata — name, ticker, decimals, icon — is committed via BIP-341 Merkle root and cannot be changed after issuance.

AssetId = (genesis_txid, group_index) OP_RETURN <0x41524b> <TLV_Stream> └─ type 0x00 = asset record └─ LEB128 varint length
Use cases
💵
Stablecoins
USD-pegged or custom-pegged tokens settled on Bitcoin rails. Issue with a control asset for managed supply; cap by burning it.
🎫
Loyalty Points
Non-transferable or transferable reward tokens. Fixed supply at genesis or reissuable — you decide at mint time.
🏠
Real-World Assets
Tokenized property, equity, or debt. Onchain metadata, Bitcoin settlement, verifiable inclusion proofs without a full indexer.
🎮
In-game Currency
Game items, credits, collectibles with supply controls. Multi-asset wallets combine BTC and custom assets in one interface.
Asset lifecycle
01
Genesis mint

First issuance. AssetId assigned. Metadata set here is immutable.

02
Control asset

Optional. Holder controls supply. Can reissue more. Non-transitive — one level only.

03
Send / receive

Transfers travel with BTC txs. Recipient needs only an Arkade address.

04
Cap supply

Burn the control asset to permanently freeze total supply. Irreversible.

🔐
Control Assets
Whoever holds it controls supply. Burn it to cap forever. Non-transitive.
⚖️
Conservation Rules
Outputs ≤ inputs per group. Unassigned inputs are burned. Protocol-enforced.
VTXOs
Virtual Transaction Outputs — offchain, fast. Redeemable to base layer via unilateral exit.
🧾
Immutable Metadata
Name, ticker, decimals, icon committed at genesis via Merkle hash. Cannot be changed.
Architecture note — hybrid intent model

Transfers bridge offchain VTXOs to onchain outputs via an intent system: Old Asset VTXO → [Intent TX] → [Commitment TX] → New VTXOs / Onchain outputs. A single intent can split an asset across multiple destinations in one operation — useful for batch payouts and airdrops.

Simulate asset mint
SDK code
import { MnemonicIdentity, Wallet } from '@arkade-os/sdk';

const wallet = await Wallet.create({
  identity: MnemonicIdentity.fromMnemonic(
    process.env.ARKADE_MNEMONIC
  ),
  arkServerUrl: 'https://mutinynet.arkade.sh',
});

const result = await wallet.assetManager.issue({
  amount: 1000000,
  metadata: {
    name: 'My Asset',
    ticker: 'MYA',
    decimals: 8,
  },
});
// result.assetId  — permanent asset identifier
// result.arkTxId  — Arkade transaction ID
Metadata is immutable

Name, ticker, decimals, and icon are committed at genesis using a BIP-341 tagged Merkle hash. Once issued, these fields cannot be updated. Verify everything before issuing on mainnet.

Simulate send
SDK code
const txId = await wallet.assetManager.send({
  assetId: 'ark1assetabc...',
  amount: 1000,
  to: 'ark1qrecipient...',
});
console.log('Tx:', txId);
Docs: Send Assets ↗
Multi-destination in one intent

A single intent transaction can split an asset across multiple destinations — useful for batch payouts, airdrops, or splitting payments between multiple parties simultaneously.

Check balances
SDK code
const balances = await wallet.assetManager.balances();
// Returns: Record<assetId, bigint>

for (const [id, amount] of Object.entries(balances)) {
  console.log(id, amount.toString());
}
Docs: Check Balance ↗
VTXOs

Your balance is the sum of all unspent Virtual Transaction Outputs (VTXOs) holding your asset. VTXOs are offchain outputs managed by the Arkade operator. They can be redeemed to base-layer Bitcoin via unilateral exit at any time.

Reissue — requires holding the control asset
SDK code
// Reissue — requires holding the control asset
const result = await wallet.assetManager.issue({
  amount: 500000,
  controlAssetId: 'ark1asset_control...',
  metadata: {}, // metadata unchanged at reissue
});
Control is non-transitive

Control assets only work one level deep. A control asset cannot delegate control to another asset — no nested supply hierarchies. The controller is designated at genesis only and cannot be changed.

What you can look up
🔍
Transactions
Inspect any Arkade txid — inputs, outputs, asset groups.
💎
Assets
Look up any asset by ID — metadata, total supply, control status.
👤
Addresses
Check an address's VTXO set and full asset balance history.
VTXOs
Current VTXO pool — offchain outputs pending settlement.
Local dev explorer

Run a full local environment with Nigiri — same API as testnet, zero cost.

# Install Nigiri curl https://getnigiri.vulpem.com | bash # Start Bitcoin regtest + Arkade nigiri start --ark # Arkade operator: # http://localhost:7070
Developer resources ↗
◆ Infrastructure guide

Get it working

Step-by-step from zero to issuing assets on mainnet. Full doc also at arkadeinfra.md in the Arkade$ repo.

Phase 1 — Local dev start here
  1. 1 Install Nigiri: curl https://getnigiri.vulpem.com | bash
  2. 2 Run: nigiri start --ark → Arkade at localhost:7070
  3. 3 npm install @arkade-os/sdk
  4. 4 Create wallet, issue test asset, verify AssetId returned
  5. 5 Send test asset to second address, check balance
Phase 2 — Mutinynet testnet
  1. 1 Set arkServerUrl: 'https://mutinynet.arkade.sh'
  2. 2 Fund wallet with Mutinynet faucet test sats
  3. 3 Issue asset — verify on Mutinynet explorer ↗
  4. 4 Test reissuance and supply cap (burn control asset)
  5. 5 Test send/receive between two wallets
Phase 3 — Mainnet launch checklist
☐  Store mnemonic in Infisical as ARKADE_MNEMONIC — never in code
☐  Asset metadata reviewed and finalized (immutable after issuance)
☐  Decision: fixed supply vs. reissuable (control asset)?
☐  Mainnet wallet funded with real sats for fees
☐  Asset icon hosted at stable public URL
☐  Issue on mainnet → verify on arkade.space ↗
☐  Error handling for failed transactions
Environment variables
# .env (add to Infisical → Vercel — never commit) ARKADE_MNEMONIC="12-word BIP-39 seed phrase" ARKADE_SERVER_URL=https://mutinynet.arkade.sh # Frontend-safe (non-sensitive) NEXT_PUBLIC_ARKADE_EXPLORER=\ https://explorer.mutinynet.arkade.sh NEXT_PUBLIC_ARKADE_NETWORK=mutinynet