Node.js Library - picket-node
Server side library for accessing picket endpoints.
npm install "@picketapi/picket-node"
The Picket constructor creates a new instance of the Picket class. It takes a secret API key as a parameter.
import Picket from "@picketapi/picket-node";
// Use your secret key when making calls from secure server
const picket = new Picket("YOUR_SECRET_KEY_HERE");
A
nonce
is random value generated by the Picket API to that user must sign to prove ownership a wallet address. The nonce
function can be used to implement your own wallet authentication flow. A
nonce
is unique to a project and wallet address. If a nonce
doesn't exist for the project and wallet address, Picket will generate a new nonce
; otherwise, Picket will return the existing nonce. A nonce
is valid for two minutes before self-destructing.const { nonce, statement, locale } = await picket.nonce({
chain: "ethereum",
walletAddress: "0x_WALLET_ADDRESS"
});
nonce
takes in an optional locale
parameter, which is used to localize the signing message statement in to the given locale
. When using the login
function from picket-js
or picket-react
, the user's browser locale will automatically be passed as the locale
for the signing message statement.Language Codes
const { nonce, statement, format } = await picket.nonce({
chain: "ethereum",
walletAddress: "0x_WALLET_ADDRESS",
// translate the statement to Afrikaans
locale: "af",
});
auth
is the server-side equivalent of login
. auth
should only be used in a trusted server environment. The most common use-case for auth
is linking a wallet to an existing application account. Ethereum (Mainnet)
Solana
await picket.auth({
// optionally omit, the default chain is Ethereum
walletAddress: "0x_WALLET_ADDRESS",
signature: "SIGNATURE"
});
// or specifiy it explicitly
await picket.auth({
chain: "ethereum",
walletAddress: "0x_WALLET_ADDRESS",
signature: "SIGNATURE"
});
await picket.auth({
chain: "solana",
walletAddress: "0x_WALLET_ADDRESS",
signature: "SIGNATURE"
});
EVM-Compatible Chains
Solana
await picket.auth({
// any supported EVM-compatible chain
// if omitted, defaults to "ethereum"
chain: "ethereum",
walletAddress: "0x_WALLET_ADDRESS",
signature: "SIGNATURE",
requirements: {
// restrict access to token holders
contractAddress: "0xCONTRACT_ADDRESS",
// omit if any number of tokens are acceptable
minTokenBalance: 1
}
});
await picket.auth({
chain: "solana",
walletAddress: "0x_WALLET_ADDRESS",
signature: "SIGNATURE",
requirements: {
// 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
},
});
Incremental Authorization (Authz)
authz
stands for authorization. Unlike Auth, which handles both authentication and authorization, Authz only handles authorization. Given an authenticated user's access token and authorization requirements, authz
will issue a new access token on success (user is authorized) or, on failure, it will return a 4xx HTTP error code.EVM-Compatible Chains
Solana
await picket.authz({
// chain and wallet is stored within the access token
accessToken: "xxx.yyy.zzz",
requirements: {
// check ownership of a specific contract address
contractAddress: "0xCONTRACT_ADDRESS",
// omit if any number of tokens are acceptable
minTokenBalance: 1
}
});
await picket.authz({
// chain and wallet is stored within the access token
accessToken: "xxx.yyy.zzz",
requirements: {
// check ownership of a specific Metaplex Collection
collection: "96d973e49267f6bf5b9d68c577fc04ce93757e2c5ae8c086ef6115b3aeee300c",
// omit if any number of tokens are acceptable
minTokenBalance: 1
}
});
If you only want to verify token ownership server side for a given wallet,
tokenOwnership
allows you to do just that. EVM-Compatible Chains
Solana
import Picket from "@picketapi/picket-node"
const picket = new Picket('YOUR_SECRET_KEY_HERE')
const requirements = {
// any supported EVM-compatible chain
// if omitted, defaults to "ethereum"
chain: "ethereum",
walletAddress: "WALLET_ADDRESS",
// 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.
minTokenBalance: 1
}
const { allowed, contractAddress, numTokens } = await picket.tokenOwnership(requirements)
console.log(`Allowed == ${allowed} because ${request.walletAddress} has ${numTokens} for ${contractAddress}.`)
import Picket from "@picketapi/picket-node"
const picket = new Picket('YOUR_SECRET_KEY_HERE')
const requirements = {
chain: "solana",
walletAddress: "WALLET_ADDRESS",
// 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
}
const { allowed, contractAddress, numTokens } = await picket.tokenOwnership(requirements)
console.log(`Allowed == ${allowed} because ${requirements.walletAddress} has ${numTokens} for ${contractAddress}.`)Validate
validate
validates an access token. validate
should be called, or manually access token validation should be done, server-side before trusting a request's access token. It's common to move access token validation and decoding logic to a shared middleware across API endpoints.If the access token is valid,
validate
returns the decoded claims of the access token.const decoded = await picket.validate("ACCESS_TOKEN");
Last modified 1yr ago