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
  • Schemes / Expected Formats
  • Creating / Verifying Signatures
  • Alternative Schemes
  1. For Developers
  2. Other Concepts
  3. Attestations - Advanced

Creating an Attestation

PreviousOverviewNextCustom Creation Links

Last updated 1 month ago

Pre-Readings:

On the official site, we provide interfaces to create attestations (Create -> Attestations). You can also self-generate locally and upload via the BitBadges API as well. Below, we provide information on how it works behind the scenes.

Programmatic Generation / Verification

The creation interface is as follows. All attestations are a series of one or more messages which can be either in 'json' or 'plaintext' messageFormat. You can use the corresponding API endpoint to create programmatically.

await BitBadgesApi.createAttestation(...)
await BitBadgesApi.updateAttestation(...)
export interface CreateAttestationPayload {
    /**
     * Proof of issuance is used for BBS+ signatures (scheme = bbs) only.
     * BBS+ signatures are signed with a BBS+ key pair, but you would often want the issuer to be a native address.
     * The prooofOfIssuance establishes a link saying that "I am the issuer of this attestation signed with BBS+ key pair ___".
     *
     * Fields can be left blank for standard signatures.
     */
    proofOfIssuance: {
        message: string;
        signature: string;
        signer: string;
        publicKey?: string;
    };

    /** The message format of the messages. */
    messageFormat: 'plaintext' | 'json';

    /** Whether or not the attestation is displayable on the user's profile / queryable by ID.
      If true, the attestation can be queried by anyone with the ID. */
    publicVisibility?: boolean;

    /**
     * The scheme of the attestation. BBS+ signatures are supported and can be used where selective disclosure is a requirement.
     * Otherwise, you can simply use your native blockchain's signature scheme.
     */
    scheme: 'bbs' | 'standard' | 'custom' | string;

    /** The original provider of the attestation. Used for third-party attestation providers. */
    originalProvider?: string;

    /** The type of the attestation (e.g. credential). */
    type: string;
    /**
     * Thesse are the attestations that are signed.
     * For BBS+ signatures, there can be >1 messages, and the signer can selectively disclose the attestations.
     * For standard signatures, there is only 1 attestationMessage.
     */
    messages: string[];

    /**
     * This is the signature and accompanying details of the messages. The siganture maintains the integrity of the messages.
     *
     * This should match the expected scheme. For example, if the scheme is BBS+, the signature should be a BBS+ signature and signer should be a BBS+ public key.
     */
    dataIntegrityProof: {
        signature: string;
        signer: string;
        publicKey?: string;
        isDerived?: boolean; //Used for BBS signatures to differentiate original vs derived proofs
    };

    /** Metadata for the attestation for display purposes. Note this should not contain anything sensitive. It may be displayed to verifiers. */
    name: string;
    /** Metadata for the attestation for display purposes. Note this should not contain anything sensitive. It may be displayed to verifiers. */
    image: string;
    /** Metadata for the attestation for display purposes. Note this should not contain anything sensitive. It may be displayed to verifiers. */
    description: string;
}

Schemes / Expected Formats

The messageFormat = 'json' or 'plaintext' will determine what format the messages should be in.

The scheme field will determine a lot about the attestation:

  • 'bbs': The N messages must be signed using the BBS+ signature algorithm. A proof of issuance is also required. The schema of the message is left up to the issuer. See below.

  • 'standard': Only 1 attestation message is expected. The message should be signed using a standard wallet signature. The schema of the message is left up to the issuer. See below.

More can be found in the individual scheme documentation later in this section.

Creating / Verifying Signatures

Note: When received from the BitBadges API directly, you can assume that signatures are already correct for non-custom implementations (bb or standard). However, it is always best practice to verify them on your end as well.

Public keys are currently only needed to be provided for Cosmos signatures in order to verify. Otherwise, you can leave them blank.

Standard Signatures

For standard signatures (scheme = 'standard'), you can sign 1 message (so messages.length = 1), and the dataIntegrityProof will be the resulting signature of the only message from your main key pair supported natively by BitBadges. See the signing transaction flow for more information on manually implementing signatures. No proofOfIssuance is required (can be left blank).

const sig = await chain.signChallenge(attestation.messages[0]);
const pubKey = await chain.getPublicKey(chain.address);

body = {
    ...attestation,
    dataIntegrityProof: {
        signer: chain.address,
        signature: sig.signature,
        publicKey: pubKey,
    },
    proofOfIssuance: {
        signature: '',
        signer: '',
        message: '',
    },
};

BBS+ Signatures

For BBS+ signatures (scheme = 'bbs'), you can sign N messages and the dataIntegrityProof will be the BBS signature of those N message. On the BitBadges site, all BBS+ key pairs are one-time use only. The key pair is generated, signs the transaction, and then is discarded because it is never needed again.

Note: blsSign creates the original and proofs can be derived from that (see later pages in this section).

import { BlsKeyPair, blsSign, generateBls12381G2KeyPair } from '@mattrglobal/bbs-signatures';

const signature = await blsSign({
  keyPair: keyPair!,
  messages: attestation.messages.map((message) => Uint8Array.from(Buffer.from(message, 'utf-8')))
});

setAttestation((prev) => ({
  ...prev,
  dataIntegrityProof: {
    signer: Buffer.from(keyPair?.publicKey ?? '').toString('hex'),
    signature: Buffer.from(signature).toString('hex'),
    isDerived: false
  }
}));

Because BBS+ are not actually signed by your "main" address, we also require a proofOfIssuance to establish this link.

const message = `I approve the issuance of credentials signed with BBS+ ${attestation.dataIntegrityProof.signer} as my own.\n\n`;
const sig = await chain.signChallenge(message);
const publicKey = await chain.getPublicKey(chain.bitbadgesAddress);
body = {
    ...attestation,
    proofOfIssuance: {
        message,
        signer: chain.address,
        signature: sig.signature,
        publicKey,
    },
};

Alternative Schemes

Note that non-BitBadges native schemes / approaches may have different verification algorithms. Please make sure your approach follows the verification approach.

'custom' or anything else: If you do not want to use a BitBadges native scheme, you can also simply add your own. Feel free to use existing models such as the model, create your own, or anything else.

โŒจ๏ธ
๐Ÿง 
W3C Verifiable Credentials
Verifiable Attestations