Collab.Land Token Gating Tutorial
Collab.Land offers a token gating feature that allows you to restrict access to elements or pages of your site based on ownership of certain blockchain assets. This tutorial walks you through the process of creating your own token gate for your website using the Collab.Land API.
You can follow this tutorial in a video format here: https://www.youtube.com/watch?v=EUVdGQuD_kw
Website Gating Logic Flow
- Define Token Gating Rules (TGRs) for your website.
- User visits your website.
- Collect user's wallet address.
- Call Collab.Land API to check if the user has the required tokens to fulfil your rules.
- Display gated content if the user has the required tokens.
To check if a user has the required tokens via the Collab.Land API, you need:
- The user's wallet address.
- Token Gating Rules for your site.
This tutorial implements the gating logic by calling the Collab.Land access-control/check-roles
endpoint with the user's wallet address and the token gating rules as the payload for the request. Collab.Land returns true/false
for each rule to indicate if the given address fits the provided criteria or not.
Get Collab.Land API keys
To call Collab.Land APIs, you need to register an API key for your client application. In addition, your API key needs a specific scope (token-gating
) to call the token gating endpoint. You can request API access here.
This feature is available on the access-control/check-roles
endpoint.
It is also available in the Collab.Land SDK:
await getCollabClient().accessControl.checkRoles({
account: <wallet_address>,
rules: [{...}],
});
Define Token Gating Rules
Token Gating Rules (TGRs) are schemas that describe the required tokens. TGRs usually include token information such as chain id
, contract address
, token types
, metadata
, etc. The following is an example TGR that requires at least one NFT of contract address 0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d
on mainnet.
"rules": [
{
"type": "ERC721",
"chainId": 1,
"minToken": "1",
"contractAddress": "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d",
"roleId": "001"
}
]
Collab.Land supports many fungible and non-fungible tokens on many chains. To gate your website with a certain token, you need to provide the token details in the example above. You can find chain IDs here and here's a guide to find your token details
Tutorial
The following are steps and explanations of our token gating sample implementation.
You will need a Collab.Land API key to run the demo locally.
1. Request an API Key
See API section
2. Define API payload
The API payload is the data that will be sent to the Collab.Land API. It must include the user's wallet address and the Token Gating Rules.
2.1 Get user's wallet address
Your app will get the user's wallet address and pass it to the endpoint. In the future, Collab.Land may expose the Collab.Land wallet connect UI component for developers to use.
In this demo, we use Sign-in with Ethereum to get the user's wallet address. You can use your preferred wallet provider to obtain a user's wallet address. You can also add sessions to logins based on your use case.
If you need some help to get user addresses, here are a few options:
- Sign-In with Ethereum Documentation.
- "Connect Wallet" tutorial by ThirdWeb.
2.2 Define Token Gating Rules
TGRs are the rules that the wallet assets will be checked against by the Collab.Land. The API will return boolean true
/false
for each rule to indicate if the account address fulfills the defined rules or not.
rules: [
{
chainId: 137,
minToken: '1',
contractAddress: '0x1fdf................81166e4ec02',
roleId: MEMBER_ROLE,
type: 'ERC721',
name: 'MemberNFT Holder',
},
{
chainId: 1,
minToken: '1',
contractAddress: '0x1fdf................81166e4ec02',
roleId: PATRON_ROLE,
type: 'ERC721',
name: 'PatronNFT Holder',
},
]
Please see Configuring your TGRs for rule definition details.
3. Call the Collab.Land API
In this demo, we use the Collab.Land SDK to call the API:
const res = await getCollabClient().accessControl.checkRoles({
account: addr,
rules: [
{
chainId: 137,
minToken: '1',
contractAddress: '0x1fdf................81166e4ec02',
roleId: MEMBER_ROLE,
type: 'ERC721',
name: 'MemberNFT Holder',
},
{
chainId: 1,
minToken: '1',
contractAddress: '0x1fdf................81166e4ec02',
roleId: PATRON_ROLE,
type: 'ERC721',
name: 'PatronNFT Holder',
},
],
});
However, you can also use fetch
:
const res = await fetch(`https://api-qa.collab.land/access-control/check-roles`, {
method: 'POST',
headers: new Headers({
Accept: 'application/json',
'X-API-KEY': process.env.COLLABLAND_KEY,
'Content-Type': 'application/json',
}),
body: JSON.stringify({
account: myWalletAddr,
rules: [
...
]
})
});
4. Handle API response
There are several response options available with the Collab.Land API. Select which method you would like to use.
Check roles synchronously
- Receive
true
/false
from API for each Token Gating Rule
Sample response:
{
"roles": [
{
"id": "my-role-001",
"granted": true
},
{
"id": "another-role-002",
"granted": false
}
]
}
Learn more about synchronous API responses.
Collab.Land also offer two asynchronous methods for handling API responses.
5. Render gated content based on API response
Your app can display page content or new pages based on the true
/false
response of the Collab.Land API.
React example code
This code snippet displays certain content when each rule returns true
.
// React component
...
const [isPatron, setIsPatron] = useState<boolean>(false);
const [isMember, setIsMember] = useState<boolean>(false);
...
const checkRoles = async () => {
await connectToSDK();
const apiResponse = await getCollabClient().accessControl.checkRoles({
account: addr,
rules: [
{
chainId: 137,
minToken: '1',
contractAddress: '0x1fdf................81166e4ec02',
roleId: MEMBER_ROLE,
type: 'ERC721',
name: 'MemberNFT Holder',
},
{
chainId: 1,
minToken: '1',
contractAddress: '0x1fdf................81166e4ec02',
roleId: PATRON_ROLE,
type: 'ERC721',
name: 'PatronNFT Holder',
},
],
});
for (const role of apiResponse.roles) {
if (role.granted) {
switch (role.id) {
case PATRON_ROLE: // set to true if PATRON_ROLE rule returns true
setIsPatron(true);
break;
case MEMBER_ROLE: // set to true if MEMBER_ROLE rule returns true
setIsMember(true);
break;
}
}
}
}
...
return (
<div>
{isPatron ? (
<div>
Hey Patron NFT Holder! ❤️ 🖤
...
</div>
) : (
<div>
You can view this content if you own Collab.Land Patron
NFTs.
</div>
)}
{isMember ? (
<div>
Hey Membership NFT Holder!
</div>
) : (
<div>
You can view this content if you own Collab.Land
Membership NFTs.
</div>
)}
</div>
)
When both rules are false
:
When both rules are true
:
Next steps
- Get access to the source code on Github
- Go build amazing things with Collab.Land!