RevibaseDeveloper

Quickstart

Sign users in with one tap of their Revibase accessory. The tap proves they hold it, and the accessory's on-chain record names the wallet linked to it, so you sign them in as that wallet. No wallet popup. The accessory can't sign transactions or move funds.

pnpm add phygital-token-sdk @solana/kit

You need HTTPS and a Solana RPC URL. Issue a short-lived challenge per attempt and consume it atomically after verification, before creating a session.

1. Issue a challenge (server)

const message = crypto.randomUUID(); // store it, and accept it once

2. Tap (browser)

import { createSolanaRpc } from "@solana/kit"; import { startAuthentication } from "phygital-token-sdk"; const rpc = createSolanaRpc(SOLANA_RPC_URL); const response = await startAuthentication(message, { rpc }); // Send `response` to your server.

For a native app or kiosk reader, pass { transceive } instead of running it in a browser.

3. Verify and sign in (server)

import { address, createSolanaRpc } from "@solana/kit"; import { fetchMaybePhygitalToken, findPhygitalTokenPda, PhygitalTokenType, verifyResponse, } from "phygital-token-sdk"; const rpc = createSolanaRpc(SOLANA_RPC_URL); const UNLINKED = address("11111111111111111111111111111111"); const ACCEPTED = new Set([ PhygitalTokenType.Controlled, PhygitalTokenType.Permanent, PhygitalTokenType.Bearer, ]); const { isVerified, secp256r1PublicKey } = verifyResponse({ expectedMessage: message, response, }); if (!isVerified) throw new Error("Bad tap"); const token = await fetchMaybePhygitalToken( rpc, await findPhygitalTokenPda(secp256r1PublicKey), ); if (!token.exists) throw new Error("Not a Revibase accessory"); if (!ACCEPTED.has(token.data.tokenType)) throw new Error("Accessory type not accepted"); if (token.data.linkedWallet === UNLINKED) throw new Error("Link a wallet to this accessory first"); // Sign the user in as token.data.linkedWallet.

Which accessories to accept

All three sign the user in as the linked wallet. They differ in how that link can change:

TypeLinked wallet
ControlledRequires unlinking by the linked wallet before relinking
PermanentFixed for good
BearerThe holder can relink it while unlocked

Token type controls wallet linkage, not whether a card can be traded. NFT cards can use any type; trading a card does not automatically update its wallet link or transfer its NFT.

To allow only some types, remove the others from ACCEPTED.

Errors

The SDK throws PhygitalTokenError. Branch on code; message is safe to show.

Code or symptomWhat to do
AUTHENTICATION_CANCELLEDThe user dismissed the prompt. Do nothing.
WEBAUTHN_UNSUPPORTEDThis browser can't tap. Offer your wallet login instead.
MESSAGE_MISMATCHThe tap answered an old challenge. Issue a fresh one per attempt.
Tap never finishesServe over HTTPS and pass { rpc }
Accessory isn't linkedThe owner links it at portal.revibase.com, then taps again

Next