Challenge Parameters

challengeParams are the Blockin parameters for the sign-in challenge. See here for the full type definition https://blockin-labs.github.io/blockin/docs/interfaces/ChallengeParams.html. These will make up the base message that is expected. Here, you include all details about the sign-in like expiration date, badges to be owned, etc. Most fields inherit from the EIP 4361: Sign In with Ethereum spec. We refer you there for further information ont he inherited fields.

If allowAddressSelect is true, we will handle the address selection on our end. Meaning, we override challengeParams.address and the native chain with the user's selected address / chain on the user interface, respectively. This allows you to have one URL for all of your users rather than generating each individually. If false, we enforce that the connected address is exactly what is specified in challengeParams.

Likewise, if autoGenerateNonce, we override the provided nonce with a random nonce generated by BitBadges. Note that autoGenerateNonce is a way to make each request unique, but it is not sufficient if you need to check that all requests were issued by you and not phished (see phished signature attacks on the verification page).

Differences of Blockin vs SIWE:

  • Sign in with "Insert Chain Here" rather than always Ethereum

  • Addresses can be any supported chain's address, not just Ethereum

  • Resources do not have to be URIs (can be any string)

  • Supports assetOwnershipRequirements

const challengeParams = new BlockinChallengeParams<bigint>({
    domain: 'https://bitbadges.io',
    statement: 'This request ...',
    address, //0x or cosmos1 or bc1 or other supported address
    uri: 'https://bitbadges.io',
    nonce: '*',
    expirationDate: new Date(Date.now() + 1000 * 60 * 60 * 24 * 14).toISOString(),
    notBefore: undefined,
    resources: ['Full Access: Full access to all features.'],
    assetOwnershipRequirements: {
      $and: [
        {
          assets: [
            {
              chain: 'BitBadges',
              collectionId: 1n,
              assetIds: [{ start: 1n, end: 1n }],
              ownershipTimes: UintRangeArray.FullRanges(),
              mustOwnAmounts: { start: 0n, end: 0n }
            }
          ]
        },
        {
          assets: [
            {
              chain: 'BitBadges',
              collectionId: 2n,
              assetIds: [{ start: 1n, end: 1n }],
              ownershipTimes: UintRangeArray.FullRanges(),
              mustOwnAmounts: { start: 0n, end: 0n }
            }
          ]
        }
      ]
    }
  });

const popupParams = {
  ...
  
  challengeParams,
  allowAddressSelect: true
}

Time Fields

Note that Blockin provides a place for you to include details about the authentication request times such as notBefore or expirationDate. These are optional and may not make sense for some use cases, such as rolling session cookies, refresh tokens, etc where the authenticated times are dynamic.

Asset Ownership Requirements

The assetOwnershipRequirements uses an $and, $or, and base case schema to allow you to implement custom logical requirements. For $and requirements, all criteria in the array must be satisfied. For $or, one of the criteria in the array needs tobe satisfied. You can implement the "not" case by saying owns x0 of a badge.

assetOwnershipRequirements: {
  $or: [
    {
      assets: [
        {
          chain: 'BitBadges',
          collectionId: 1n,
          assetIds: [{ start: 1n, end: 1n }],
          ownershipTimes: UintRangeArray.FullRanges(),
          mustOwnAmounts: { start: 0n, end: 0n }
        }
      ]
    },
    {
      assets: [
        {
          chain: 'BitBadges',
          collectionId: 2n,
          assetIds: [{ start: 1n, end: 1n }],
          ownershipTimes: UintRangeArray.FullRanges(),
          mustOwnAmounts: { start: 1n, end: 1n }
        }
      ]
    }
  ]
}

Options

As an alternative to $or, we also support specifying options.numMatchesForVerification which sets a threshold for how many assets in the current group the criteria needs to pass for. For example, below requires 1 / 1000 badges to be owned out of the IDs 1-1000.

assetOwnershipRequirements: {
  assets: [
    {
      chain: 'BitBadges',
      collectionId: 1n,
      assetIds: [{ start: 1n, end: 1000n }],
      ownershipTimes: UintRangeArray.FullRanges(),
      mustOwnAmounts: { start: 1n, end: 1n }
    }
  ],
  options: { numMatchesForVerification: 1n }
}

BitBadges Badge Collections

For BitBadges assets, we expect the chain = ' BitBadges', all collection IDs to be numeric, and all assetIds to be UintRanges. Querying a user owns a badge at a specific time is also supported via ownership times.

{
  chain: 'BitBadges',
  collectionId: 1n,
  assetIds: [{ start: 1n, end: 1000n }],
  ownershipTimes: UintRangeArray.FullRanges(),
  mustOwnAmounts: { start: 0n, end: 0n }
}

BitBadges Address Lists

For BitBadges address lists, they are supported with the collection ID = 'BitBadges Lists'. The assetIds will be the string list ID. A user will be considered to own x1 if they are on the list and x0 if they are not on the list. Note that with blacklists, they are flipped. Not being on a blacklist equals x1 owned.

{
    chain: 'BitBadges',
    collectionId: 'BitBadges Lists',
    assetIds: ["listId"],
    ownershipTimes: UintRangeArray.FullRanges(),
    mustOwnAmounts: { start: 1n, end: 1n }
}

Ethereum / Polygon NFTs

We also support verifying Ethereum Polygon NFTs through this interface. However, note that we use external APIs to check this, so is not reliant on our infrastructure.

{
  $and: [
    {
      assets: [
        {
          chain: 'Polygon', //Or 'Ethereum'
          collectionId: '0x9a7f0b7d4b6c1c3f3b6d4e6d5b6e6d5b6e6d5b6e',
          assetIds: ['1'],
          ownershipTimes: [],
          mustOwnAmounts: { start: 0n, end: 0n }
        }
      ]
    }
  ]
}

Ownership Times

ownershipTimes: []

The default when ownership times is empty or missing is to verify at the current time. If this is the case, we dynamically add the current time as [{ start: currTime, end: currTime }].

ownershipTimes: UintRangeArray.FullRanges()

For assets that support ownership times like BitBadges badges, you can specify custom times to check.

Last updated