Picket Docs
Search…
πŸͺ™
Token Gating - Verify Token Ownership
A guide to start token gating anything in minutes.

Get your API Key

An API key is required to authorize your requests when interacting with the Picket API. Requests without an API key will result in an error.
To get your API key, go to the account dashboard. API keys are associated with projects to make key management easy.
Within each project there are two types of API keys
  • Publishable keys: These keys are used client-side and are meant for client-side libraries, like picket-js.
  • Secret keys: As the name suggests, these must be kept secret. They are meant for server-side libraries, like picket-node​
Authorization to the API is performed via HTTP Basic Auth. Provide your API key as the basic auth username. You do not need to provide a password. When using Picket SDKs, API Authorization is handled for you.
Javascript
Curl
import Picket from "@picketapi/picket-js";
const picket = new Picket('YOUR_PUBLISHABLE_KEY_HERE');
curl https://picketapi.com/v1/{any_endpoint}
-u YOUR_SECRET_KEY

Install the Picket SDK

The best way to interact with our API is to use one of our official libraries.
As a first step after ensuring you have your API keys, install one of the picket libraries for the easiest integration. Type the following into your command line
Javascript
React
Node
# Install via NPM
npm install --save "@picketapi/picket-js"
# Install via NPM
npm install --save "@picketapi/picket-react"
# Install via NPM
npm install --save "@picketapi/picket-node"
Want to use Picket with other web-frameworks? Let us know at [email protected]​

Token Gate Anything

You can use Picket to token gate anything. If you want to authenticate users and verify their token ownership, you can pass the token ownership requirements to the login() function.

Login User w/ Token Ownership Requirements

Javascript
React
Curl
import Picket from "@picketapi/picket-js";
​
const picket = new Picket('YOUR_PUBLISHABLE_KEY_HERE');
​
// These requirements are for the Ethereum Mainnet
// See Token Ownership Requirements section below for examples of
// requirements other supported chain.
const requirements = {
// optional. The default chain is the Ethereum Mainnet
chain: "ethereum",
// Replace this example address with whichever contract you are verifying ownership for
contractAddress: '0x8a90cab2b38dba80c64b7734e58ee1db38b8992e',
// Replace with minimum balance you want to verify users' currently hold,
// or omit if any number of tokens is sufficient
minTokenBalance: 1
}
​
const { accessToken, user } = await picket.login(requirements);
console.log(user);
import { PicketProvider, usePicket } from "@picketapi/picket-react";
​
function MyApp({ children }) {
return (
<PicketProvider apiKey="YOUR_PUBLISHABLE_KEY_HERE">
{children}
</PicketProvider>
);
}
​
const requirements = {
// optional. The default chain is the Ethereum Mainnet
chain: "ethereum",
// Replace this example address with whichever contract you are verifying ownership for
contractAddress: '0x8a90cab2b38dba80c64b7734e58ee1db38b8992e',
// Replace with minimum balance you want to verify users' currently hold,
// or omit if any number of tokens is sufficient
minTokenBalance: 1
}
​
function MySecurePage() {
const {
isAuthenticating,
isAuthenticated,
authState,
logout,
login
} = usePicket();
// user is logging in
if (isAuthenticating) return "Loading";
​
// user is not logged in
if (!isAuthenticated) {
return (
<div>
<p>You are not logged in!</p>
<button onClick={() => login(requirements)}>Login with Wallet</button>
</div>
)
}
​
// user is logged in πŸŽ‰
const { user } = authState;
const { walletAddress } = user;
return (
<div>
<p>You are logged in as {walletAddress} </p>
<button onClick={() => logout()}>Logout</button>
</div>
)
}
curl https://picketapi.com/api/v1/auth \
-X POST \
-u PROJECT_SECRET_KEY \
-H 'Content-Type: application/json' \
-d '{
"chain": "ethereum",
"walletAddress": "0xWALLET_ADDRESS",
"signature": "SUPER_SECRET_SIGNATURE",
"contractAddress": "CONTRACT_ADDRESS",
"minTokenBalance": 1
}'

Token Ownership Requirements

Picket currently defaults to using the ethereum (Mainnet) chain. While using ethereum contract address can be any contract address for an ERC20 token or an NFT (including ERC-721 and ERC-1155.) Picket also authentication and authorization on other chains like Solana. See supported blockchains for the complete list.
Notice that recommended parameters for token ownership requirements differ between EVM-compatible chains and Solana due to discrepancies between ERC (20/721/1155) tokens and SPL tokens.
Ethereum (Mainnet)
Solana (Beta Mainet)
// Same as the requirements above
const requirements = {
// optional. The default chain is the Ethereum Mainnet
chain: "ethereum",
// Replace this example address with whichever contract you are verifying ownership for
contractAddress: '0x8a90cab2b38dba80c64b7734e58ee1db38b8992e',
// Replace with minimum balance you want to verify users' currently hold,
// or omit if any number of tokens is sufficient
minTokenBalance: 1
}
// Replace requirements from code above with the following
const requirements = {
chain: "solana",
// Replace this the tokens you want to verify ownership for
// the token ID is the mint associated with a SPL token
// user needs to own the minTokenBalance of at least one of the listed token
tokenIds: ["78AZe2223PknLYT9mn2VCJPAsdvuB6LzFAhgQeVoxddW", "2dQG4YYunFrbJjzW6UTcUmePs8UDy5jz43H6uSCZSAcS"],
// Replace with minimum balance you want to verify users' currently hold across all token IDs,
// or omit if any number of tokens is sufficient
minTokenBalance: 1
}
You successfully validated a user's wallet and token ownership!
The returned access token can now act as secure proof of token ownership until expiration. It can be passed server side and verified there in order to restrict resources to authenticated wallets with whichever token ownership requirements you have.

Re-Validate an Authenticated User

Once you have received an access token via picket.login() or the /auth endpoint, you can re-validate the authenticated user's access token as needed. If you are using a client-side Picket library, it will automatically re-validate a users access token every-time it fetches a cached access token.
To validate an access token manually, call the /validate endpoint
Javascript
try {
await picket.validate(accessToken, {
// use the same requirements from login()
contractAddress,
minTokenBalance
});
// Do anything or present any content
// that you want to restrict to verified token holders
}
catch (err) {
console.error("Access token expired, invalid, or doesn't meet the token ownership requirements.");
}

Using Access Tokens

Once you've successfully authenticated a wallet you will have an access token. An access token acts as a secure guarantee of an authenticated wallet until expiration without the need for additional user interactions.
This allows you build and interact with APIs that restrict content based on a user's wallet address. On the client-side, you can include a user's access token API requests, and server-side, you can validate any received access tokens to ensure the request came from a user who owns the wallet address.

1. Include the Access Token in API Requests

Javascript
curl
import Picket from "@picketapi/picket-js";
const picket = new Picket("YOUR_PUBLISHABLE_KEY_HERE");
​
// NOTE: This assumes the user is logged in
const { accessToken } = await picket.authState();
​
await fetch("myapi.com", {
method: "GET",
headers: {
// Use the access token as a bearer auth token
Authorization: `Bearer ${accessToken}`
}
});
curl myapi.com -H "Authorization: Bearer ${ACCESS_TOKEN}"

2. Validate the Access Token Server-Side

Server-side libraries, like picket-node, require a secret API key and must only be used in a secure, server-side environment.
Node
Curl
import Picket from "@picketapi/picket-node";
​
const picket = new Picket("YOUR_SECRET_KEY_HERE");
​
// REPLACE code to get access token from client request
const accessToken = "";
​
try {
// REPLACE with the requirements you used in login()
const requirements = {
chain: "ethereum",
contractAddress: '0x8a90cab2b38dba80c64b7734e58ee1db38b8992e',
minTokenBalance: 1
};
const { walletAddress } = await picket.validate(accessToken, requirements);
// save user's wallet address to the DB
} catch (err) {
console.error("invalid access token!");
}
​
curl https://picketapi.com/api/v1/auth/validate \
-X POST \
-u PROJECT_SECRET_KEY \
-H 'Content-Type: application/json' \
-d '{
"accesssToken": ${ACCESS_TOKEN},
"contractAddress": "CONTRACT_ADDRESS",
"minTokenBalance": 1
}'
Copy link
On this page
Get your API Key
Install the Picket SDK
Token Gate Anything
Login User w/ Token Ownership Requirements
Re-Validate an Authenticated User
Using Access Tokens