BitBadges
  • Overview
    • ๐Ÿ‘‹BitBadges Overview
    • ๐Ÿ‘จโ€๐Ÿ’ปLearn the Basics
      • BitBadges Claims
      • Multi-Chain Accounts
      • Sign In with BitBadges
      • Badges
      • Address Lists
      • Attestations
      • Applications (Points)
      • Additional Badge Concepts
        • Manager
        • Total Supplys
        • Time-Dependent Ownership
        • Transferability
        • Balances Types
      • Wallets and Sign Ins
        • Supported Wallets
        • Alternate Sign Ins / Mobile
        • Approved Transactors
    • ๐Ÿ”จGetting Started
    • ๐Ÿ’ปHow Do I Check...?
    • ๐Ÿ”How Do I Gate...?
    • ๐ŸŽจUse Cases
    • ๐Ÿ”—Official Links and Resources
    • โš–๏ธBitBadges L1 vs Others
    • ๐Ÿช™Launch Phases
    • ๐ŸŒดEcosystem
      • WordPress Plugin
      • MetaMask Snap
      • Browser Extensions
      • LinkedIn Certifications
      • Blockin
    • ๐ŸคBrand Guidelines
    • โ“FAQ
  • โŒจ๏ธFor Developers
    • ๐Ÿšดโ€โ™‚๏ธGetting Started
    • ๐Ÿ‘คHandling Addresses
    • ๐ŸงชTestnet Mode
    • ๐Ÿ“šBitBadges API
      • Getting Started
      • Full Reference
      • Typed SDK Types
      • Upgrading an API Key Tier
      • Concepts
        • Native Chain Algorithm
        • Refresh / Claim Completion Queue
        • Designing for Compatibility
        • Limits / Restrictions
        • Managing Views
        • Use via Pipedream
    • ๐Ÿ–ฑ๏ธSign In with BitBadges
      • Overview
      • Already Have Web3 Auth?
      • Alternative - P2P Verification
      • Templates and Frameworks
        • WordPress
        • Auth0
        • ExpressJS
        • Discourse
        • Supabase
        • Others
      • Setting Up an App
      • Connecting a Claim
      • Authorization URL
        • Configuration
        • Generating the URL
      • Approaches
        • QR Codes
        • Redirect Callback
      • Verification
        • Verification Flow
        • Access Tokens
        • Offline Verification
        • Security Considerations
      • Blockin Docs
    • ๐Ÿ—๏ธBitBadges Claims
      • Overview
      • Concepts
        • Standard vs On-Demand
        • Completion Methods
        • Gating Badge Distribution
        • Claim Numbers
        • Success Logic
        • Claim Links (URLs)
        • Signed In vs Select Address
        • Universal Approach - Claim Codes
        • Identify By Socials / Emails?
        • Payment Checking
        • Receiving Attestations
      • Checking Custom Criteria
      • Implementing Custom Utility
      • Leveraging AI
      • BitBadges API & Claims
        • Verifying Claim Attempts w/ the API
        • Fetching Claims
        • Auto-Complete Claims w/ BitBadges API
      • Dynamic Stores
        • Overview
        • Adding Data
      • Custom Plugins / Webhooks
        • Overview
        • Pre-Built Webhook Plugins
        • Creating a Custom Plugin
          • Implement Your Plugin
            • Getting Started
            • Hook Types and Simulations
            • Design Considerations
            • Parameters
            • Custom Inputs
            • API Handler
          • Managing Your Plugin
          • Testing Your Plugin
        • Configuration Tools
      • Integrate with Zapier
        • Overview
        • Dynamic Store Zaps
        • Automatic Claim Tutorial
        • Post-Success Zaps
        • Leveraging Zapier AI Actions / MCP
        • Automate Any Part of the Process
          • Google Forms
      • Integrate with Pipedream
        • Overview
        • Leveraging Pipedream MCP
        • Build Custom Plugins
        • Workflow Actions
          • Complete Claim
          • Get Claim Attempt Status
          • Get Claim Code by Idx
          • Add User to Dynamic Store
        • Workflow Triggers
          • Poll Claim Attempts
        • End to End Example
      • In-Site Plugins
        • Plugins Directory
        • Plugin Documentation
        • Ownership Requirements
      • Tutorials
        • In-Site Guides
        • Get Integration User IDs
          • Get Discord User ID
          • Get Discord Server ID
          • X / Twitch / GitHub IDs
        • Add Telegram Bot to Channel
    • โš’๏ธBitBadges JS / SDK
      • Overview
      • SDK Types
      • Common Snippets
        • Address Conversions
        • NumberType Conversions
        • Uint Ranges
        • Balances
        • Transfers
        • Address Lists
        • Badge Metadata
        • Approvals / Transferability
        • Off-Chain Balances
        • Timelines
    • ๐ŸŒŸBadges - Advanced
      • Overview
      • Balances / Transfers
        • ๐Ÿ“ŠBalances
        • โž•Valid Badge IDs
        • ๐Ÿช™Balance Types
        • ๐ŸคTransferability / Approvals
        • โœ…Approval Criteria
          • Overview
          • $BADGE Transfers
          • Override User Level Approvals
          • Approval Trackers
          • Tallied Approval Amounts
          • Max Number of Transfers
          • Predetermined Balances
          • Requires
          • Merkle Challenges
          • Extending the Approval (Advanced)
      • Self-Hosted Balances
        • Overview
        • Examples / Tutorials
          • Indexed
          • Non-Indexed
      • Permissions
        • Overview
        • Action Permission
        • Timed Update Permission
        • Timed Update With Badge Ids Permission
        • Badge IDs Action Permission
        • Update Approval Permission
      • Standards
      • Archived Collections
      • Metadata
      • Timelines
      • Different Time Fields
      • List IDs
      • Uint Ranges
    • โ›“๏ธBitBadges Blockchain
      • Overview
      • Chain Details
      • REST API Docs - Node
      • Staking / Validators
      • Run a Node
        • Overview
        • Run a Mainnet Node
        • Run a Local Dev Node
        • Cosmovisor
      • Create a Smart Contract
      • ๐Ÿ”ƒCreate, Generate, and Sign Txs
        • Transaction Context
        • Generate Msg Contents
        • Signing - Cosmos
        • Signing - Ethereum
        • Signing - Solana
        • Signing - Bitcoin
        • Broadcast to a Node
        • Sign + Broadcast - bitbadges.io
      • ๐Ÿ“ฉCosmos SDK Msgs
        • x/anchor
          • MsgAddCustomData
        • x/badges
          • MsgCreateCollection
          • MsgUpdateCollection
          • MsgDeleteCollection
          • MsgCreateAddressLists
          • MsgTransferBadges
          • MsgUpdateUserApprovals
          • MsgUniversalUpdateCollection
        • x/wasmx
          • MsgStoreCodeCompat
          • MsgInstantiateContractCompat
          • MsgExecuteContractCompat
        • x/maps
          • MsgCreateMap
          • MsgUpdateMap
          • MsgDeleteMap
          • MsgSetValue
        • MsgSend
        • Cosmos Native Msgs
    • ๐Ÿง Other Concepts
      • Uint Ranges
      • Accounts (Low-Level)
      • Address Lists
      • Maps / Protocols
      • Attestations - Advanced
        • Overview
        • Creating an Attestation
        • Custom Creation Links
        • Proofs vs Attestations
        • Deriving a Proof
        • Design Considerations
        • Verification / Presentations
        • Custom Schemes
          • WITNESS Proofs
Powered by GitBook
On this page
  • Non-Indexed Balances (On-Demand)
  • Indexed Balances
  1. For Developers
  2. Badges - Advanced
  3. Self-Hosted Balances

Overview

PreviousSelf-Hosted BalancesNextExamples / Tutorials

Last updated 2 months ago

For off-chain balances, the collection will be stored on the blockchain, but all balances will be allocated off-chain via a server endpoint. This allows you to have complete control over assignment of the balances at no cost and no transactions required. You can integrate with any application (even non-crypto ones).

Examples:

  • Spreadsheets - Assign badges based on addresses in a spreadsheet.

  • Subscriptions - Set up your own subscription service and allocate badges to subscribers!

  • Custom Integrations - Integrate with any app you want!

There are two types of off-chain balances: indexed and non-indexed. See the for more information. For both options, you must create or have a collection with the desired balances type. The recommended way to create a collection is via the Create form on the BitBadges app. You will be able to enter all self-hosted details (your URL) directly into the form.

Refresh Queue

Note that while balance updates on your site will be instant. BitBadges uses a queue-like system. Upon a refresh or changes detected, the balance update will get added to the queue. This may take some time to fully populate on the site.

Claim / Assignment System

Self-hosted balances can be customized to be assigned for anything. You can setup your own assignment process or connect it to a claiming tool (e.g. when a user does something, update their balances). This is all left up to you.

Note that self-hosted balances are not compatible with BitBadges claims. For BItBadges claims, the balances must be stored and maintained by BitBadges. One workaround is to use BitBadges claims for the claiming process and then migrate to a self-hosted option.

URL Requirements

The URLs should be a GET endpoints accessible to whoever needs it (e.g. BitBadges indexer). It is your responsibility to handle CORS errors and such yourself.

Non-Indexed Balances (On-Demand)

For non-indexed balances, you simply need to set up a server which can return the current balances for a specified BitBadges address.

Couple notes:

  • The URL stored on-chain must have {address} as a placeholder for the address to query.

  • The URL param is expected to support converted BitBadges addresses. It is up to you whether you want to support native addresses as well, but converted BitBadges address support is mandatory. See .

Example:

On-Chain URL: "http://localhost:3000/nonIndexed/{address}"

app.get('/nonIndexed/:address', async (req, res) => {
  const address = req.params.address;
  const bitbadgesAddress = convertToBitBadgesAddress();

  //custom logic - (e.g. check subscription status or check some local DB value)

  const balances: Balance<bigint>[] = [...];
  return res.status(200).send({ balances });
});

Indexed Balances

With indexed balances, you store and host the entire balance map all at one endpoint.

Step 1: Create Your Map

The map is simply a bitbadgesAddress/listId -> Balance<NumberType>[] map. You can create this yourself by using the OffChainBalancesMap<NumberType> type.

const transfers: TransferWithIncrements<bigint>[] = [...];

const balanceMap = await createBalanceMapForOffChainBalances(transfers);

For example,

{
    "bb1qjgpfmk93lqdak3ea7xqp5ec6v8nd79kqtrajy": [
        {
            "amount": "1",
            "badgeIds": [
                {
                    "start": "1",
                    "end": "1"
                }
            ],
            "ownershipTimes": [
                {
                    "start": "1",
                    "end": "18446744073709551615"
                }
            ]
        }
    ],
    "bb1zd5dsage58jfrgmsu377pk6w0q5zhc672wamvw": [
        {
            "amount": "1",
            "badgeIds": [
                {
                    "start": "1",
                    "end": "1"
                }
            ],
            "ownershipTimes": [
                {
                    "start": "1",
                    "end": "18446744073709551615"
                }
            ]
        }
    ]
}

Step 2: Host your map as a JSON file via some URL

This can be via IPFS or any method of your choice.

Note permanent storage (i.e. IPFS) coupled with not being able to update the URL on-chain will make your balances permanent and immutable. This can be a good option if you want your collection to be frozen, non-transferable, and immutable.

Step 3: Create Your Collection

Create your collection and specify your URL via the offChainBalancesMetadata timeline. Decide whether you want to be able to update the URL in the future or not. Set the managerTimeline and canUpdateOffChainBalancesMetadata permission accordingly.

Future Refreshes / Updates

In the future, if you are allowed to update the URL on-chain you can do so via another MsgUpdateCollection transaction. This will auto-trigger a refresh on the BitBadges API / indexer as well.

You can also just update the balances JSON returned by the URL as well without interacting with the blockchain (i.e. URL stays the same). Note that the BitBadges indexer / website caches balances. To trigger a refetch manually, you can use the POST /api/v0/refresh endpoint or do it directly on the website.

Note that if you use address list IDs for the keys (), the corresponding address list must be a whitelist (whitelist = false) and should be stored on-chain for reproducability (not off-chain via the BitBadges servers or somewhere else). You should also not allocate more badge IDs in this map than what was created on-chain (via the "Mint" address).

You may also find the function helpful.

โŒจ๏ธ
๐ŸŒŸ
balances type documentation
here for more information
see here to learn more
createBalanceMapForOffChainBalances