Skip to main content
Version: V2

Collect a Badge

In this section you'll learn how to implement the Collect Essence feature. Previously you've learned that creating a badge means registering an essence, but the process of minting and transferring the SBT is actually executed when a user collects the badge by attending an event.

To keep things simple we will only focus on the actual implementation of users collecting badges. Linking them to an actual event and checking whether users have attended the event falls beyond the scope of the tutorial.

GraphQL mutations

To collect an essence, meaning to collect a SBT badge, is a two step process and requires two GraphQL mutations: CreateCollectEssenceTypedData and Relay.

  1. CreateCollectEssenceTypedData is used to present data to the user in a readable format:
graphql/CreateCollectEssenceTypedData.ts
import { gql } from "@apollo/client";

export const CREATE_COLLECT_ESSENCE_TYPED_DATA = gql`
mutation CreateCollectEssenceTypedData(
$input: CreateCollectEssenceTypedDataInput!
) {
createCollectEssenceTypedData(input: $input) {
typedData {
id
chainID
sender
data
nonce
}
}
}
`;
  1. Relay is responsible for broadcasting the transaction, minting and transferring the NFT:
graphql/Relay.ts
import { gql } from "@apollo/client";

export const RELAY = gql`
mutation Relay($input: RelayInput!) {
relay(input: $input) {
relayTransaction {
id
txHash
typedData {
id
chainID
sender
data
nonce
}
}
}
}
`;

Collect a Badge

Now that you set up the APIs required, you can implement the Collect feature. The approach is similar to the approach from Create a Badge:

  1. Get data in a readable format and the typedDataID for it;
  2. Get the user to sign the message data and get its signature;
  3. Call the relay and pass it the typedDataID and signature;
components/CollectBtn.tsx
/* Create typed data in a readable format */
const typedDataResult = await createCollectEssenceTypedData({
variables: {
input: {
options: {
chainID: chainID,
},
collector: account,
profileID: profileID,
essenceID: essenceID,
},
},
});

const typedData =
typedDataResult.data?.createCollectEssenceTypedData?.typedData;
const message = typedData.data;
const typedDataID = typedData.id;

/* Get the signature for the message signed with the wallet */
const params = [account, message];
const method = "eth_signTypedData_v4";
const signature = await signer.provider.send(method, params);

/* Call the relay to broadcast the transaction */
const relayResult = await relay({
variables: {
input: {
typedDataID: typedDataID,
signature: signature,
},
},
});
const txHash = relayResult.data?.relay?.relayTransaction?.txHash;

If the collect process was successful, you can verify the transaction hash on goerli.etherscan.io.

transaction hash

You can also view the NFT when a user collects a badge on testnets.opensea.io. You'll notice that the image for the NFT and all other details about it correspond to the details passed to the Metadata Schema fields (e.g. image_data, name, attributes, etc).

nft essence

Awesome! You've completed the How to Build Badge app guide! Now you can build your own application that issues baadges. Share your work on our Discord channel. We would love to see what you've built!

Designed by