Skip to content

Use Products for a catalog of fixed-price purchases, and Credit Token for a prepaid balance bought in scalable units. Neither standard proves off-chain delivery or automatically settles refunds.

Product catalog variants

bb build product-catalog --products <json> --store-address <address> creates one token ID per array entry, beginning at 1. bb products build is the corresponding alias. Each product has name, price, and denom; optional fields are storeAddress, maxSupply, burn, uri, image, and description. A product's storeAddress overrides the catalog's default recipient for that product only; BitBadges and EVM account addresses are accepted. Provide collection metadata with --uri or the complete inline metadata fields.

ConfigurationPurchase resultTracking
Default productBuyer keeps one unit of the product IDIts purchase approval tracks sales when capped
burn: truePurchase mints directly to the burn addressA sale does not leave the buyer a collectible balance
Positive maxSupplyAt most that many successful purchases through the product approvalOverall transfer count, separately scoped per product approval
Missing or zero maxSupplyUnlimited sales through that approvalDo not interpret zero as sold out
Multiple catalog entriesIndependent product IDs, prices, denominations, and capsNo shared catalog-wide stock cap

Prices are display-unit numbers converted to the resolved denomination's base units. maxSupply must be a non-negative integer. Per-product metadata overrides catalog defaults; a catalog URI can supply a fallback when product metadata is omitted.

bash
bb build product-catalog --products '[{"name":"Admission","price":5,"denom":"USDC","maxSupply":100,"burn":true}]' \
  --store-address "$STORE" --creator "$CREATOR" --uri "$METADATA_URI"
bb products list "$COLLECTION_ID"
bb products show "$COLLECTION_ID"
bb products purchase "$COLLECTION_ID" --token-id 1 --creator "$BUYER"

The purchase action buys one unit. The standard also contains a holder burn approval, but no dedicated bb products burn command is registered. Use the generic transfer tools with the matching approval when needed. Burning a receipt is not a refund, and a purchase count is not a delivery count. The builder freezes collection permissions; do not assume a mutable stock or price editor exists for the created catalog.

Catalog lifecycle

Products, prices, supply caps, recipients and metadata are frozen when a standard catalog is created. Publish a new catalog to offer new terms. The frontend catalog form only creates collections; adding, deleting or reordering products applies to unsigned drafts, and keeps product metadata together with the corresponding payment terms.

The specialized catalog editor rejects existing collection IDs. Custom collections with mutable permissions can use the advanced editor, but any update must preserve existing token IDs, approval IDs and tracker IDs. Replacing a sold product with a new product under its old ID would mislabel receipts; replacing its approval or tracker can detach the sales count and reopen capped stock. The current standard does not expose an automated migration, retirement or restocking action.

Payments settle directly to the selected recipient, so cancellation, automatic refunds and conditional release are not built-in. A holder burn does not reverse payment or restore stock. Escrowed returns require a separately reviewed, funded approval design before freezing the collection. Off-chain fulfillment and delivery disputes remain application responsibilities.

Credit Token variants

bash
bb build credit-token --payment-denom USDC --recipient "$STORE" \
  --tokens-per-unit 100 --creator "$CREATOR" --uri "$METADATA_URI"
bb credit-tokens list "$COLLECTION_ID"
bb credit-tokens show "$COLLECTION_ID"
bb credit-tokens quote "$COLLECTION_ID" --units 3
bb credit-tokens purchase "$COLLECTION_ID" --units 3 --creator "$BUYER"

The builder's credit-scaled approval defines the tokens received per payment unit. --units is an integer multiplier of that purchase unit, not a token display amount: with 100 tokens per unit, three units buy 300 raw token units and scale the required payment by three. The current builder sets the payment leg to one base unit of the payment denomination per multiplier; the tokensPerUnit parameter is minted base units per payment base unit. Wrapper display decimals are separate from raw token amounts. --payment-denom also accepts the builder alias --denom. The token symbol defaults to CREDIT.

The action also recognizes older fixed purchase tiers through --tier <approvalId>; those require --units 1 per invocation. Oversized scaled requests are rejected; neither SDK, CLI nor the frontend silently reduces the quantity. When multiple tiers exist, choose one explicitly with --tier. The frontend selects one exact pack for legacy tiers instead of decomposing an arbitrary payment into a potentially incomplete basket. --api-credits selects BitBadges' own API credit collection where configured and is mutually exclusive with a positional collection ID; the standard otherwise supports arbitrary recognized Credit Token collections.

Credits are non-transferable: purchase with the address that will hold and use them. A throwaway creator wallet is not a substitute for the buyer. Track remaining usable balance separately from purchase history and any application consumption policy. There is no generic refund or service-delivery action in the credit CLI.

See product catalog primitives, credit token primitives, coin transfers, and approval trackers. Run the command's --help and inspect emitted messages before using optional signing flags.

Product JSON

Save the following input as product-catalog.json, replace the demo addresses and metadata, then build it with the CLI command below. Each array entry receives token ID index + 1. price is a display-unit number; maxSupply counts purchases. burn controls whether the purchase leaves a holder receipt. The catalog-level storeAddress is the default recipient; a product's own storeAddress takes precedence.

json
{
  "products": [
    {
      "name": "Admission",
      "price": 5,
      "denom": "BADGE",
      "maxSupply": 100,
      "burn": true
    }
  ],
  "storeAddress": "bb1xvenxvenxvenxvenxvenxvenxvenxvenlrd2nm",
  "uri": "https://example.com/metadata.json"
}
bash
bb build product-catalog --json product-catalog.json \
  --creator "$CREATOR" --output-file product-catalog-proposal.json

Complete JSON input supplies the required business fields; duplicate flags are not needed. Review the resulting proposal using the CLI lifecycle. SDK reference: buildProductCatalog.

Credit JSON

Save the following input as credit-token.json, replace the demo addresses and metadata, then build it with the CLI command below. tokensPerUnit is a raw-token integer multiplier. The emitted credit-scaled payment leg is one base unit. The caller must inspect the emitted exchange rate before creating a priced service.

json
{
  "paymentDenom": "BADGE",
  "recipient": "bb1xvenxvenxvenxvenxvenxvenxvenxvenlrd2nm",
  "symbol": "CREDIT",
  "tokensPerUnit": 100,
  "uri": "https://example.com/metadata.json"
}
bash
bb build credit-token --json credit-token.json \
  --creator "$CREATOR" --output-file credit-token-proposal.json

Complete JSON input supplies the required business fields; duplicate flags are not needed. Review the resulting proposal using the CLI lifecycle. SDK reference: buildCreditToken.

Creating credit purchase options in the frontend

The credit creation form supports fixed packs and scalable packs, including multiple purchase options. Set a payment recipient and asset, then specify each option's displayed price and credit quantity. Fixed packs require exactly one pack per purchase. Scalable packs accept positive whole-number quantities up to the configured maximum packs per purchase. Amounts are converted exactly to base units; excess decimal precision is rejected rather than rounded.

The cap applies to one purchase. It is not a lifetime per-wallet quota or a collection-wide sales cap, and buyers can make another purchase. The standard credit creation form does not add cumulative quota trackers. Fixed and scalable options can coexist in one collection. Options keep their approval identity when another option is removed.

The SDK/CLI buildCreditToken shortcut above still emits its single default scaled approval. The frontend builds its explicit pack options from that canonical draft; do not pass frontend option fields to the SDK shortcut as undocumented parameters.

Exact credit quotes

bb credit-tokens quote <id> --units <multiplier> [--tier <approvalId>] reports requested and actual multipliers, the configured maximum, the recipient, exact payment/mint base units, and the raw exchange ratio. Display values are decimal strings when registry/collection metadata supplies decimals; unknown decimals and display values are null, never guessed. For the default 100:1 raw ratio, multiplier 1000000 pays 1000000 payment base units and mints 100000000 credit base units.

Quotes describe observed approval terms. They do not reserve capacity, prove eligibility, include network/protocol fees, or authorize payment. Re-read and simulate before signing; consent, limits and balances can change. Purchase proposals prioritize the observed approval version. Unsupported multi-payout or dynamic-recipient tiers require the generic reviewed transfer flow; this exact quote helper does not display only their first payment.

The same quote is available through standard_credit_tokens_quote in MCP. Use bb dev capabilities for the installed tool/schema inventory. Purchasing still emits an unsigned proposal unless the CLI signing flow is explicitly selected.

The canonical credit balance records lifetime purchases. remainingCredits: null is deliberate: usage and remaining credits belong to the service's authenticated external ledger. There is no universal consumption ledger or implied refund claim. On-chain decrementing service packs belong to the separate Redeemable Entitlements proposal (BB-119), not a retrofit of frozen credit collections.

Edit this page on GitHub