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
.
CreateCollectEssenceTypedData
is used to present data to the user in a readable format:
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
}
}
}
`;
Relay
is responsible for broadcasting the transaction, minting and transferring the NFT:
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:
- Get data in a readable format and the
typedDataID
for it; - Get the user to sign the message data and get its
signature
; - Call the
relay
and pass it thetypedDataID
andsignature
;
/* 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.
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).
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!