Skip to content

What BitBadges is, how the chain, the hosted services, and the tools fit together, what one collection looks like, and where to start.

BitBadges is a Cosmos SDK Layer 1 whose core module, x/tokenization, is a complete token standard: every collection, balance, approval, and permission is chain state that the module enforces on every transfer. This page explains the system end to end, shows what a token collection looks like, and sends you to the right tab.

You May Not Need These Docs

Many common tasks need no code. On bitbadges.io, you can create collections, set transferability, run claims, and trade with a wallet. Start there for those tasks. These docs explain the token model and cover integrations, automation, custom plugins, and node operations that need developer tools.

Build in Three Steps

  1. Install the CLI:
bash
curl -fsSL https://install.bitbadges.io | sh
  1. Add the MCP builder tools to your editor. Claude Code is shown; Cursor, Codex, Claude Desktop, and others are in Set Up Your AI:
bash
claude mcp add bitbadges-builder -e BITBADGES_API_KEY="$BITBADGES_API_KEY" -- npx -y -p bitbadges bitbadges-builder
  1. Tell it what to build:
text
Create me a payment request for 10 USDC
text
Build a subscription token that renews monthly for 5 USDC
text
Make a 500-piece NFT collection where only I can mint

The agent assembles the transaction and returns a review link. Open it, check the summary, and sign with your wallet.

What You Get

LayerPiecesWhat it does
Chain (bitbadges-1)x/tokenization, x/gamm, x/managersplitter, IBC, EVM precompilesTokens with time-based balances and three-level transfer approvals. A Balancer-style DEX. Wrapping to x/bank denoms for IBC. Solidity access through precompiles at 0x...1001 to 0x...1003.
Hosted servicesBitBadges API, claims and plugins, Sign In with BitBadges, bitbadges.ioIndexed reads (balances, metadata, activity), off-chain claim gating with 16 built-in plugins plus your own HTTP plugins, OAuth-style sign in, and a no-code site.
Toolsbb CLI, bitbadges npm package, MCP builder tools, Claude Code pluginBuild, check, simulate, preview, sign, and broadcast transactions from a terminal, TypeScript, or an AI agent.

The chain enforces the rules. The hosted services make them easy to read and to gate. The tools generate valid transactions so you rarely hand-write the structures below.

One Collection, Annotated

A collection is created with one message. This example fixes the valid IDs at 1 through 100 and caps supply at one unit per ID. Its locked mint rule lets only the creator initiate up to 100 mints, issuing IDs in order. The manager can still edit metadata and add post-mint transfer rules, but cannot change minting or force holders to transfer their tokens.

The addresses and metadata URIs are illustrative. Replace both creator and manager, plus the mint rule's initiatedByListId, with your wallet address. Supply your own metadata URIs. Recipients accept incoming transfers by default and can change their own incoming approvals. The example has no post-mint transfer rule, so holders cannot transfer tokens until the manager adds one.

json
{
  "creator": "bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d",
  "defaultBalances": {
    "autoApproveAllIncomingTransfers": true
  },
  "validTokenIds": [{ "start": "1", "end": "100" }],
  "collectionPermissions": {
    "canUpdateValidTokenIds": [
      {
        "tokenIds": [{ "start": "1", "end": "18446744073709551615" }],
        "permanentlyForbiddenTimes": [{ "start": "1", "end": "18446744073709551615" }]
      }
    ],
    "canUpdateCollectionApprovals": [
      {
        "fromListId": "Mint",
        "toListId": "All",
        "initiatedByListId": "All",
        "transferTimes": [{ "start": "1", "end": "18446744073709551615" }],
        "tokenIds": [{ "start": "1", "end": "18446744073709551615" }],
        "ownershipTimes": [{ "start": "1", "end": "18446744073709551615" }],
        "approvalId": "All",
        "permanentlyForbiddenTimes": [{ "start": "1", "end": "18446744073709551615" }]
      }
    ]
  },
  "manager": "bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d",
  "collectionMetadata": {
    "uri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/collection.json"
  },
  "tokenMetadata": [
    {
      "uri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/{id}.json",
      "tokenIds": [{ "start": "1", "end": "100" }]
    }
  ],
  "collectionApprovals": [
    {
      "fromListId": "Mint",
      "toListId": "All",
      "initiatedByListId": "bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d",
      "transferTimes": [{ "start": "1", "end": "18446744073709551615" }],
      "tokenIds": [{ "start": "1", "end": "100" }],
      "ownershipTimes": [{ "start": "1", "end": "18446744073709551615" }],
      "approvalId": "manager-mint",
      "approvalCriteria": {
        "predeterminedBalances": {
          "incrementedBalances": {
            "startBalances": [
              {
                "amount": "1",
                "ownershipTimes": [{ "start": "1", "end": "18446744073709551615" }],
                "tokenIds": [{ "start": "1", "end": "1" }]
              }
            ],
            "incrementTokenIdsBy": "1",
            "recurringOwnershipTimes": { "startTime": "0", "intervalLength": "0", "chargePeriodLength": "0" }
          },
          "orderCalculationMethod": {
            "useOverallNumTransfers": true
          }
        },
        "approvalAmounts": {
          "resetTimeIntervals": { "startTime": "0", "intervalLength": "0" }
        },
        "maxNumTransfers": {
          "overallMaxNumTransfers": "100",
          "amountTrackerId": "mint",
          "resetTimeIntervals": { "startTime": "0", "intervalLength": "0" }
        },
        "overridesFromOutgoingApprovals": true,
        "userApprovalSettings": {
          "userRoyalties": { "percentage": "0", "payoutAddress": "" }
        }
      }
    }
  ],
  "standards": ["NFTs"],
  "invariants": {
    "maxSupplyPerId": "1",
    "noForcefulPostMintTransfers": true
  }
}
{
  "creator": "bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d",
  "defaultBalances": {
    "balances": [],
    "outgoingApprovals": [],
    "incomingApprovals": [],
    "autoApproveSelfInitiatedOutgoingTransfers": false,
    "autoApproveSelfInitiatedIncomingTransfers": false,
    "autoApproveAllIncomingTransfers": true,
    "userPermissions": {
      "canUpdateOutgoingApprovals": [],
      "canUpdateIncomingApprovals": [],
      "canUpdateAutoApproveSelfInitiatedOutgoingTransfers": [],
      "canUpdateAutoApproveSelfInitiatedIncomingTransfers": [],
      "canUpdateAutoApproveAllIncomingTransfers": []
    }
  },
  "validTokenIds": [{ "start": "1", "end": "100" }],
  "collectionPermissions": {
    "canDeleteCollection": [],
    "canArchiveCollection": [],
    "canUpdateStandards": [],
    "canUpdateCustomData": [],
    "canUpdateManager": [],
    "canUpdateCollectionMetadata": [],
    "canUpdateValidTokenIds": [
      {
        "tokenIds": [{ "start": "1", "end": "18446744073709551615" }],
        "permanentlyPermittedTimes": [],
        "permanentlyForbiddenTimes": [{ "start": "1", "end": "18446744073709551615" }]
      }
    ],
    "canUpdateTokenMetadata": [],
    "canUpdateCollectionApprovals": [
      {
        "fromListId": "Mint",
        "toListId": "All",
        "initiatedByListId": "All",
        "transferTimes": [{ "start": "1", "end": "18446744073709551615" }],
        "tokenIds": [{ "start": "1", "end": "18446744073709551615" }],
        "ownershipTimes": [{ "start": "1", "end": "18446744073709551615" }],
        "approvalId": "All",
        "permanentlyPermittedTimes": [],
        "permanentlyForbiddenTimes": [{ "start": "1", "end": "18446744073709551615" }]
      }
    ],
    "canAddMoreAliasPaths": [],
    "canAddMoreCosmosCoinWrapperPaths": []
  },
  "manager": "bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d",
  "collectionMetadata": {
    "uri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/collection.json",
    "customData": ""
  },
  "tokenMetadata": [
    {
      "uri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/{id}.json",
      "customData": "",
      "tokenIds": [{ "start": "1", "end": "100" }]
    }
  ],
  "customData": "",
  "collectionApprovals": [
    {
      "fromListId": "Mint",
      "toListId": "All",
      "initiatedByListId": "bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d",
      "transferTimes": [{ "start": "1", "end": "18446744073709551615" }],
      "tokenIds": [{ "start": "1", "end": "100" }],
      "ownershipTimes": [{ "start": "1", "end": "18446744073709551615" }],
      "uri": "",
      "customData": "",
      "approvalId": "manager-mint",
      "approvalCriteria": {
        "merkleChallenges": [],
        "predeterminedBalances": {
          "manualBalances": [],
          "incrementedBalances": {
            "startBalances": [
              {
                "amount": "1",
                "ownershipTimes": [{ "start": "1", "end": "18446744073709551615" }],
                "tokenIds": [{ "start": "1", "end": "1" }]
              }
            ],
            "incrementTokenIdsBy": "1",
            "incrementOwnershipTimesBy": "0",
            "durationFromTimestamp": "0",
            "allowOverrideTimestamp": false,
            "recurringOwnershipTimes": { "startTime": "0", "intervalLength": "0", "chargePeriodLength": "0" },
            "allowOverrideWithAnyValidToken": false,
            "allowAmountScaling": false,
            "maxScalingMultiplier": "0"
          },
          "orderCalculationMethod": {
            "useOverallNumTransfers": true,
            "usePerToAddressNumTransfers": false,
            "usePerFromAddressNumTransfers": false,
            "usePerInitiatedByAddressNumTransfers": false,
            "useMerkleChallengeLeafIndex": false,
            "challengeTrackerId": ""
          }
        },
        "approvalAmounts": {
          "overallApprovalAmount": "0",
          "perToAddressApprovalAmount": "0",
          "perFromAddressApprovalAmount": "0",
          "perInitiatedByAddressApprovalAmount": "0",
          "amountTrackerId": "",
          "resetTimeIntervals": { "startTime": "0", "intervalLength": "0" }
        },
        "maxNumTransfers": {
          "overallMaxNumTransfers": "100",
          "perToAddressMaxNumTransfers": "0",
          "perFromAddressMaxNumTransfers": "0",
          "perInitiatedByAddressMaxNumTransfers": "0",
          "amountTrackerId": "mint",
          "resetTimeIntervals": { "startTime": "0", "intervalLength": "0" }
        },
        "coinTransfers": [],
        "requireToEqualsInitiatedBy": false,
        "requireFromEqualsInitiatedBy": false,
        "requireToDoesNotEqualInitiatedBy": false,
        "requireFromDoesNotEqualInitiatedBy": false,
        "overridesFromOutgoingApprovals": true,
        "overridesToIncomingApprovals": false,
        "autoDeletionOptions": {
          "afterOneUse": false,
          "afterOverallMaxNumTransfers": false,
          "allowCounterpartyPurge": false,
          "allowPurgeIfExpired": false
        },
        "mustOwnTokens": [],
        "dynamicStoreChallenges": [],
        "ethSignatureChallenges": [],
        "senderChecks": {
          "mustBeEvmContract": false,
          "mustNotBeEvmContract": false,
          "mustBeLiquidityPool": false,
          "mustNotBeLiquidityPool": false
        },
        "recipientChecks": {
          "mustBeEvmContract": false,
          "mustNotBeEvmContract": false,
          "mustBeLiquidityPool": false,
          "mustNotBeLiquidityPool": false
        },
        "initiatorChecks": {
          "mustBeEvmContract": false,
          "mustNotBeEvmContract": false,
          "mustBeLiquidityPool": false,
          "mustNotBeLiquidityPool": false
        },
        "altTimeChecks": {
          "offlineHours": [],
          "offlineDays": [],
          "offlineMonths": [],
          "offlineDaysOfMonth": [],
          "offlineWeeksOfYear": [],
          "timezoneOffsetMinutes": "0",
          "timezoneOffsetNegative": false
        },
        "mustPrioritize": false,
        "votingChallenges": [],
        "allowBackedMinting": false,
        "allowSpecialWrapping": false,
        "evmQueryChallenges": [],
        "userApprovalSettings": {
          "allowedDenoms": [],
          "disableUserCoinTransfers": false,
          "userRoyalties": { "percentage": "0", "payoutAddress": "" }
        }
      },
      "version": "0"
    }
  ],
  "standards": ["NFTs"],
  "isArchived": false,
  "mintEscrowCoinsToTransfer": [],
  "cosmosCoinWrapperPathsToAdd": [],
  "invariants": {
    "noCustomOwnershipTimes": false,
    "maxSupplyPerId": "1",
    "noForcefulPostMintTransfers": true,
    "disablePoolCreation": false,
    "evmQueryChallenges": []
  },
  "aliasPathsToAdd": []
}

The Collapsed view hides default fields. Select Full to inspect the complete JSON. The field reference is in MsgCreateCollection.

This object is the message value, not a transaction envelope. Save the Full JSON as collection-value.json, make the replacements above, then wrap it for the CLI using jq:

bash
jq '{messages: [{typeUrl: "/tokenization.MsgCreateCollection", value: .}]}' collection-value.json > collection.json
bb check collection.json --depth structural
FieldWhat it decidesRead
validTokenIdsWhich token IDs exist. IDs are numbers; fungible or non-fungible depends only on how many units you mint per ID.Collections
collectionMetadata, tokenMetadataWhere the name, image, and description live. {id} expands per token. Inline JSON in customData needs no hosting.Collections
collectionApprovalsWho can move which tokens from whom to whom, when, and under which conditions. fromListId: "Mint" makes this a mint rule.Transferability
approvalCriteriaThe conditions: caps via trackers, a fixed mint order via predetermined balances, payments, Merkle proofs, votes, ownership checks, EVM queries, time windows.Approval Criteria
ownershipTimesBalances carry a time range. A subscription is a balance that expires; a vesting schedule is a balance that starts later. No follow-up transaction.Balances
collectionPermissionsWhat the manager may still change, per time range, and whether that answer is frozen. This example locks the valid ID range and mint rules; invariants.maxSupplyPerId caps supply per ID.Permissions
standardsLabels that tell apps how to interpret the collection.Collections

Token transfers are checked against collection-level, sender outgoing, and recipient incoming approvals. Collection criteria can explicitly override the user approval layers. Wrapped-token movements on BitBadges also use this approval model; remote chains do not execute BitBadges approval rules. Concepts walks the model in dependency order.

What Changes Versus ERC-20 and ERC-721

NeedContract standardsBitBadges
Fungible and non-fungibleTwo standards, two contractsOne collection. amount per token ID.
Expiring or scheduled ownershipCustom contract, a cron job, or a burn laterownershipTimes on the balance. The chain reports the balance as absent outside the range.
Transfer rulesrequire statements in Solidity, per contract, audited each timeApprovals with criteria, checked on token transfers and wrapped-token movements on BitBadges.
Allowlists and blocklistsMappings in the contractReusable Address Lists: "All", "Mint", "!bb1py4mfpg6uf59qkyzg0nmau322c5873eeysp5ue", or stored lists.
Mint gatingA merkle-drop contractMerkle Challenges on-chain, or Claims with plugins off-chain that produce the proof.
Royalties and paymentsEIP-2981 hints that marketplaces may ignoreCoin Transfers and user royalties enforced inside the transfer.
UpgradabilityProxy patternsPermissions with permitted and forbidden time ranges, freezable per field.
Compliance checksOff-chain, or a per-token contractKYC via dynamic stores, business hours via Alt Time Checks, on-chain EVM reads via EVM Query Challenges. See Compliance Zones.
Cross-chainBridgesWrapper paths turn tokens into x/bank denoms for IBC and DEX trading. Approvals apply on the BitBadges side; remote voucher transfers follow the remote chain's rules.
ContractsEverythingOptional. Solidity reads and writes the module through precompiles.

The longer argument is in Why BitBadges and Comparisons.

What People Build

Each row below has a longer pitch, with the fields that matter and a prompt for an agent, under Use Cases.

BuildMechanismStart
NFT or fungible collectionvalidTokenIds plus a mint approvalCreate a Collection
Subscription, membership, expiring credentialownershipTimes and recurring predetermined balancesSubscriptions and Time-Based Tokens
Tradable, burnable, soulbound, or admin-revocable tokensPost-mint approvals and overridesSet Transferability
Airdrop, allowlist, quest, social-gated mintClaims with plugins that emit a Merkle proofDistribute with Claims
Token-gated API or contentBB-402: a 402 response, a signed proof, a balance checkGate access
Login with a walletSign In with BitBadges (OAuth flow)Sign In Users
Compliant asset with KYC and transfer limitsDynamic stores, trackers, alt time checks, compliance zonesCompliance Zones
Stablecoin-backed or IBC-backed tokenBacked minting against an existing denomSmart Tokens and Vaults
Liquidity pool or swapWrap, then x/gammTrade on the DEX
Auction, bounty, crowdfund, prediction market, payment request, product catalogStandards with bb verbs and agent skillsStandards, Skills
Agent-controlled vault with spend limitsOutgoing approvals with daily-reset trackersSpending Authorization

Pick a Path

Choose a path for reading data or building transactions. Reads need no wallet signature. Writes require review and a signed broadcast. Mainnet is the live network; testnet is offline.

CLI

bash
curl -fsSL https://install.bitbadges.io | sh
bb settings set apiKey "$BITBADGES_API_KEY"  # key from https://bitbadges.io/developer
bb api tokens get-collection 1             # read through the BitBadges API
bb build --help                            # 19 builders: subscription, smart-token, auction, transfer, ...
bb check collection.json                   # validate a saved collection or transaction
bb simulate collection.json
bb deploy collection.json --browser        # review and sign in the browser

Quickstart, CLI reference

TypeScript

ts
import { BigIntify, BitBadgesAPI } from 'bitbadges';

const api = new BitBadgesAPI({ convertFunction: BigIntify, apiKey: process.env.BITBADGES_API_KEY });
const { collection } = await api.getCollection('1');
console.log(collection.collectionId, collection.validTokenIds);

Install bitbadges and set BITBADGES_API_KEY from the developer portal before running this server-side example. It reads collection 1. For a write, follow Transactions to select a signer and prepare a transfer using tokens you own and a recipient you choose.

SDK reference, Transactions

AI Agent

The same npm package ships the bitbadges-builder MCP server and a Claude Code plugin. The agent assembles the transaction with tools such as add_approval, set_permissions, and review_collection, then hands you a review link; you sign in the browser. Works with Claude Code, Claude Desktop, Cursor, Windsurf, Codex, VS Code, Zed, or any model that can output JSON.

bash
claude mcp add bitbadges-builder -e BITBADGES_API_KEY="$BITBADGES_API_KEY" -- npx -y -p bitbadges bitbadges-builder

Set Up Your AI, MCP Builder Tools

No Code

The Create tab and the developer portal create collections, claims, address lists, and API keys without an integration. Paste any transaction JSON at bitbadges.io/mint/local-builder to review and sign it.

Networks

NetworkChain IDEVM chain IDEndpoints
mainnetbitbadges-150024https://rpc.bitbadges.io, https://lcd.bitbadges.io, https://evm-rpc.bitbadges.io, https://api.bitbadges.io
testnetofflineTestnet status

Full table, denoms, and node setup: Network.

The Tabs

TabRead it when you want toStart at
DocsInstall, run a first transaction, do a task, use the site, or read why BitBadges existsQuickstart, Using the Frontend, Guides, About
Token StandardUnderstand the data model, approval criteria, every message and query, and wrappingOverview
ChainThe other modules, the DEX, EVM precompiles, endpoints, denoms, running a nodeChain
APICall the hosted API, run claims and plugins, add Sign In with BitBadgesBitBadges API, OpenAPI reference
SDK & CLIUse bitbadges from TypeScript or drive everything from bbSDK, CLI
AgentsWire Claude, Cursor, Codex, or any MCP client to build tokensAgents

For agents reading this site: Reading the Docs lists llms.txt, the single-file corpus, and the URL patterns.

Edit this page on GitHub