RevibaseDeveloper

Gate access

After the Quickstart's verify step you know which accessory tapped (secp256r1PublicKey) and which wallet it's linked to (linkedWallet). Gate on whichever fits.

By wallet

The usual choice. Reuse your wallet rules: an allowlist, token holdings, DAO membership.

if (!allowedWallets.has(token.data.linkedWallet)) throw new Error("Access denied");

By accessory

For staff badges or event passes, allow specific accessories whatever wallet they're linked to. Pass the list to the tap and any other accessory is rejected (PASSKEY_NOT_RECOGNIZED) without an RPC call.

// allowedPasskeys: a Set of base64url compressed public keys const response = await startAuthentication(message, { allowList: allowedPasskeys });

By the NFT a card is bound to

A card and its NFT can be sold separately. Check that the card is bound to an NFT in your collection, and that its linked wallet still owns that NFT. This uses DAS getAsset, so your RPC must support DAS.

const UNASSIGNED = "11111111111111111111111111111111"; async function holdsBoundNft(token: { mint: string; linkedWallet: string }) { if (token.mint === UNASSIGNED) return false; const res = await fetch(DAS_RPC_URL, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", id: "gate", method: "getAsset", params: { id: token.mint } }), }); const asset = (await res.json()).result; const inCollection = asset?.grouping?.some( (g: { group_key: string; group_value: string }) => g.group_key === "collection" && g.group_value === EXPECTED_COLLECTION, ); return !!asset && !asset.burnt && inCollection && asset.ownership.owner === token.linkedWallet; } if (!(await holdsBoundNft(token.data))) throw new Error("Access denied");

To gate on one specific NFT instead, compare token.mint with it.

Fast check-in

For busy doors, build the allowlist ahead of time, so each tap needs no RPC call. On a schedule, list each eligible wallet's accessories:

import { fetchPhygitalTokensByLinkedWallet } from "phygital-token-sdk"; for (const token of await fetchPhygitalTokensByLinkedWallet(rpc, wallet)) { if (!ACCEPTED.has(token.tokenType)) continue; // the tap won't read the token, so check types here allowedPasskeys.add(Buffer.from(token.publicKey[0]).toString("base64url")); }

Then pass allowedPasskeys as allowList, as above. Changes, such as an unlink, apply at the next sync.