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
  • Collection Permissions
  • User Permissions
  • Permitted and Forbidden Times
  • First Match Policy
  • Satisfying Criteria
  • Permission Categories
  • Examples
  1. For Developers
  2. Badges - Advanced
  3. Permissions

Overview

PreviousPermissionsNextAction Permission

Last updated 6 months ago

First, read Permissions for an overview.

Note: The and Permissions are the most powerful features of the interface, but they can also be the most confusing. Please ask for help if needed.

"collectionPermissions": {
    ...
}
"userPermissions": {
    ...
}

Collection Permissions

Manager

The collectionPermissions only apply to the current manager of the collection. In other words, the manager is the only one who is able to execute permissions. If there is no manager for a collection, no permissions can be executed.

The current manager is determined by the managerTimeline. Transferring the manager is facilitated via the canUpdateManager permission.

"managerTimeline": [
  {
    "manager": "bb1kfr2xajdvs46h0ttqadu50nhu8x4v0tc2wajnh",
    "timelineTimes": [
      {
        "start": 1,
        "end": "18446744073709551615"
      }
    ]
  }
]

User Permissions

Besides the collection permissions, there are also userPermissions that can be set. Typically, these will remain empty / unset, so that the user can always have full control over their approvals. If empty, they are permitted by default (but not frozen).

However, setting user permissions can be leveraged in some cases for specific purposes.

  • Locking that a specific badge can never be transferred out of the account

  • Locking that a specific approval is always set and uneditable so that two mutually distrusting parties can use the address as an escrow

Defaults

We also give the option for the collection to define default user permissions. These will be used as the starting values when the balance is initially created in storage. This can be used in tandem with the other defaults. The default permissions are also not typically used, but again can be used in certain situations. For example, by default, approve all incoming transfers and lock the permission so all transfers always have incoming approvals and can never be disapproved.

Permitted and Forbidden Times

Permissions allow you to define permitted or forbidden times to be able to execute a permission.

States

There are three states that a permission can be in at any one time:

  1. Forbidden + Permanently Frozen (permanentlyForbiddenTimes): This permission is forbidden and will always remain forbidden.

    1. If a permission is explicitly allowed via the permanentlyPermittedTimes, it will ALWAYS be allowed during those permanentlyPermittedTimes (can't change it).

  2. Permitted + Not Frozen (Unhandled): This permission is currently permitted but can be changed to one of the other two states.

    1. If not explicitly permitted or forbidden - NEUTRAL (not defined or unhandled), permissions are ALLOWED by default but can later be set to be permanently allowed or disallowed. There is no "forbidden currently but updatable" state.

  3. Permitted + Permanently Frozen (permanentlyPermittedTimes): This permission is forbidden and will always remain permitted

    1. If a permission is explicitly forbidden via the permanentlyForbiddenTimes, it will ALWAYS be disallowed during those permanentlyForbiddenTimes.

There is no forbidden + not frozen state because theoretically, it could be updated to permitted at any time and executed (thus making it permitted).

Examples

This means the permission is permanently forbidden and frozen.

permanentlyPermittedTimes: []
permanentlyForbiddenTimes: [{ start: 1, end: GO_MAX_UINT_64 }]

This means it is permanently allowed and frozen.

permanentlyForbiddenTimes: []
permanentlyPermittedTimes: [{ start: 1, end: GO_MAX_UINT_64 }]

This means it is allowed currently but neutral and can be changed to be always permitted or always forbidden in the future.

permanentlyForbiddenTimes: []
permanentlyPermittedTimes: []

First Match Policy

All permissions are a linear array where each element may have some criteria as well as permanentlyForbiddenTimes or permanentlyPermittedTimes. It can be interpreted as if the criteria matches, the permission is permitted or forbidden according to the defined times, respectively.

We do not allow times to be in both the permanentlyPermittedTimes and permanentlyForbiddenTimes array simultaneously.

Unlike approvals, we only allow taking the first match in the case criteria satisfies multiple elements in the permissions array. All subsequent matches are ignored. This makes it so that for any time and for each criteria combination, there is a deterministic permission state (permitted, forbidden, or neutral). This means you have to carefully design your permissions because order and overlaps matter.

Ex: If we have the following permission definitions in an array [elem1, elem2]:

  1. timelineTimes: [{ start: 1, end: 10 }]
    
    permanentlyPermittedTimes: []
    permanentlyForbiddenTimes: [{ start: 1, end: 10 }]
  2. timelineTimes: [{ start: 1, end: 100 }]
    
    permanentlyForbiddenTimes: []
    permanentlyPermittedTimes: [{ start: 1, end: GO_MAX_UINT_64 }]

In this case, the timeline times 1-10 will be forbidden ONLY from times 1-10 because we take the first element that matches for that specific criteria (which is permanentlyPermittedTimes: [], permanentlyForbiddenTimes: [1 to 10]).

Times 11-100 would be permanently permitted since the first match for those times is the second element.

Similar to approved transfers, even though we allow range logic to be specified, we first expand everything maintaining order to their singular values (one value, no ranges) before checking for our first match.

Satisfying Criteria

For permissions, all criteria must be satisfied for it to be a match. If you satisfy N-1 criteria, it is not a match.

For example, lets say you had a permission with badge IDs and ownership times:

badgeIds: [{ start: 1, end: 10 }]
ownershipTimes: [{ start 1, end: 10 }]

permanentlyForbiddenTimes: []
permanentlyPermittedTimes: [{ start: 1, end: GO_MAX_UINT_64 }]

This would result in the manager being able to create more of badges IDs 1-10 which can be owned from times 1-10.

However, this permission does not specify whether they can create more of badge ID 1 at time 11 or badge ID 11 at time 1. These combinations are considered unhandled or not defined by the permission definition above.

Common Misunderstanding

A common misunderstanding is that if the permission below is appended after the above one, this would forbid badges 11+ from ever being created. However, creating badge IDs 11+ at times 11+ would still be unhandled and allowed by default.

badgeIds: [{ start: 11, end: Max }]
ownershipTimes: [{ start 1, end: 10 }]

permanentlyForbiddenTimes: [{ start: 1, end: GO_MAX_UINT_64 }]
permanentlyPermittedTimes: []

To permanently forbid all badgeIds, you must brute force ALL other combinations such as

badgeIds: [{ start: 11, end: Max }]
ownershipTimes: [{ start: 1, end: Max }] // 1-10 never gets matched to bc of first match
//can also do start: 11

permanentlyForbiddenTimes: [{ start: 1, end: GO_MAX_UINT_64 }]
permanentlyPermittedTimes: []

Brute-Forcing

A common pattern you will see is to brute force all possible combinations. For example, in the above example we brute forced all possible combinations for badge IDs 11+. No subsequent element specifying a badge ID 11+ will ever get matched to.

To brute force a specific criteria (such as IDs 11+), you specify it, then for all other N - 1 criteria, you set them equal to ALL values. All values in the case of UintRanges is 1 - max Uint64. For address lists / IDs, this is all possible addresses / IDs.

The following brute forces badge IDs 1-10.

{
  "fromListId": "All",
  "toListId": "All",
  "initiatedByListId": "All",
  "badgeIds":  [{ "start": "1", "end": "10" }],
  "transferTimes":  [{ "start": "1", "end": "18446744073709551615" }],
  "ownershipTimes":  [{ "start": "1", "end": "18446744073709551615" }],
  "approvalId": "All", //forbids approval "xyz" from being updated

  "permanentlyPermittedTimes": [],
  "permanentlyForbiddenTimes": [{ "start": "1", "end": "18446744073709551615" }]
}

Permission Categories

Examples

"collectionPermissions": {
    "canArchiveCollection": [],
    "canCreateMoreBadges": [
      {
        "badgeIds": [
          {
            "start": "1",
            "end": "18446744073709551615"
          }
        ],
        "ownershipTimes": [
          {
            "start": "1",
            "end": "18446744073709551615"
          }
        ],
        "permanentlyPermittedTimes": [],
        "permanentlyForbiddenTimes": [
          {
            "start": "1",
            "end": "18446744073709551615"
          }
        ],
      }
    ],
    "canDeleteCollection": [],
    "canUpdateBadgeMetadata": [],
    "canUpdateCollectionApprovals": [
      {
        "fromListId": "AllWithMint",
        "toListId": "AllWithMint",
        "initiatedByListId": "AllWithMint",
        "timelineTimes": [
          {
            "start": "1",
            "end": "18446744073709551615"
          }
        ],
        "transferTimes": [
          {
            "start": "1",
            "end": "18446744073709551615"
          }
        ],
        "badgeIds": [
          {
            "start": "1",
            "end": "18446744073709551615"
          }
        ],
        "ownershipTimes": [
          {
            "start": "1",
            "end": "18446744073709551615"
          }
        ],
        "approvalId": "All",
        "permanentlyPermittedTimes": [],
        "permanentlyForbiddenTimes": [
          {
            "start": "1",
            "end": "18446744073709551615"
          }
        ]
      }
    ],
    "canUpdateCollectionMetadata": [],
    "canUpdateContractAddress": [],
    "canUpdateCustomData": [],
    "canUpdateManager": [],
    "canUpdateOffChainBalancesMetadata": [],
    "canUpdateStandards": []
  }

There are five categories of permissions, each with different criteria that must be matched with. If you get confused with the different time types, refer to for examples and explanations.

See for further examples. Or, see the page for each permission category.

โŒจ๏ธ
๐ŸŒŸ
Approved Transfers
Different Time Types
Action Permission
Timed Update Permission
Timed Update With Badge Ids Permission
Badge IDs Action Permission
Update Approval Permission
Example Msgs