new SteleClient(options)class
new SteleClient({ apiBaseUrl: string; fetch?: typeof fetch })const client = new SteleClient({ apiBaseUrl: "https://stele.site/api" });@stelehq/sdk for browsers, React and Node.js, and @stelehq/verifier. Step-by-step guides: Proof · Gate.npm install @stelehq/sdk. In the browser the SDK talks to a Stele app; every answer it uses is checked against Solana (program, network, fingerprints).import { SteleClient } from "@stelehq/sdk";new SteleClient(options)class
new SteleClient({ apiBaseUrl: string; fetch?: typeof fetch })const client = new SteleClient({ apiBaseUrl: "https://stele.site/api" });client.getNetwork()method
getNetwork(): Promise<NetworkInfo>
// { cluster, chainId, label, walletChain, programId, relayer, publicRpcUrls, … }SteleApiErrorclass
class SteleApiError extends Error { status: number; code: string }already_accepted (409) when this signer already accepted this version.import { createSteleGate } from "@stelehq/sdk";createSteleGate(options)function
createSteleGate({
apiBaseUrl?: string; // or client
client?: SteleClient;
wallet?: MessageSigner | (() => MessageSigner | Promise<MessageSigner>);
ui?: "modal" | "none"; // default "modal"
theme?: "auto" | "dark" | "light";
requestDomain?: string; // default location.hostname
onStatus?: (status: GateStatus) => void;
}): SteleGateconst stele = createSteleGate({
apiBaseUrl: "https://stele.site/api",
wallet: {
address: wallet.publicKey.toBase58(),
signMessage: (message) => wallet.signMessage(message),
},
});stele.gate(request)method
gate<T>({
policy: string; // the policy address
action: () => T | Promise<T>; // your transaction
acceptLabel?: string; // default "Accept & Continue"
wallet?: MessageSigner;
}): Promise<T>action right away. Otherwise shows the exact required text, records the acceptance (free for the user), waits until the pass is on Solana, then runs it. Closing the window throws GateCancelledError and nothing runs.await stele.gate({
policy: "YOUR_POLICY_ADDRESS",
action: () => sendDepositTransaction(),
acceptLabel: "Accept & Deposit",
});stele.check(policy, wallet)method
check(policy: string, holder: string): Promise<AccessCheck>
// { status: "VALID" | "MISSING" | "OUTDATED", requiredVersion, accessPass, pass, document }GateCancelledError · AccessRequiredError · StaleTermsErrorerrors
GateCancelledError: the user closed the window. AccessRequiredError: with ui: "none", acceptance is needed — show your own UI. StaleTermsError: the document changed while open; the SDK loads the new version.import { loadVerifiedDocument, acceptDocument } from "@stelehq/sdk";loadVerifiedDocument(options)function
loadVerifiedDocument({
client: SteleClient;
organization: string; // address or verified domain, e.g. "acme.com"
document: string; // slug, e.g. "terms-of-service"
loadPrevious?: boolean; // also load the previous version (for "what changed")
}): Promise<VerifiedDocument>acceptDocument(options)function
acceptDocument({
client: SteleClient;
verified: VerifiedDocument;
signer: MessageSigner; // wallet or passkey
requestDomain: string; // location.hostname
sessionToken?: string; // from your server, links the acceptance to your user
onStatus?: (s: "requesting" | "awaiting-signature" | "recording" | "recorded") => void;
}): Promise<AcceptanceResult>
// { acceptanceId, transactionSignature, message, receiptPath, evidenceMode, … }const verified = await loadVerifiedDocument({ client, organization: "acme.com", document: "terms-of-service" });
const result = await acceptDocument({ client, verified, signer, requestDomain: location.hostname });<script> + data attributesHTML
<div data-stele-organization="acme.com" data-stele-document="terms-of-service"></div>
<script src="https://stele.site/sdk/v1/stele.js" defer></script>window.Stele: mount, mountProof, createGate, client().mount(target, options)function
mount(target: string | Element, {
apiBaseUrl: string;
organization: string;
document: string;
onAccepted?: (result: AcceptanceResult) => void;
}): { destroy(): void }<TermsAcceptance />React
import { TermsAcceptance } from "@stelehq/sdk/react";
<TermsAcceptance apiBaseUrl="https://stele.site/api" organization="acme.com" document="terms-of-service"
onAccepted={(result) => …} />mountProof(target, options)function
mountProof(target, { apiBaseUrl, requestId, token, onConfirmed? }): { destroy(): void }watchWallets(chain, onChange)function
watchWallets(chain: string, onChange: (wallets: AvailableWallet[]) => void): () => voidconnectWallet(wallet, chain)function
connectWallet(wallet: AvailableWallet, chain: string): Promise<MessageSigner>identifyPasskeySigner(options)function
identifyPasskeySigner({ client, organization }): Promise<NativePasskeySigner | PasskeySigner>passkeySigningSupport() · nativePasskeySupport()functions
isUserRejection(error)function
isUserRejection(error: unknown): booleanimport { loadProofRequest, confirmProof } from "@stelehq/sdk";loadProofRequest(options)function
loadProofRequest({ client, requestId, token }): Promise<VerifiedProofRequest>confirmProof(options)function
confirmProof({ client, request, signer, requestDomain, onStatus? }): Promise<ProofResult>downloadAcceptanceReceipt(client, acceptanceId)function
verificationLink(appUrl, acceptanceId)function
verificationLink(appUrl: string, acceptanceId: string): stringimport { SteleServerClient, verifyWebhook } from "@stelehq/sdk/server";new SteleServerClient(options)class
new SteleServerClient({ apiBaseUrl: string; apiKey: string; fetch?: typeof fetch })const stele = new SteleServerClient({ apiBaseUrl: "https://stele.site/api", apiKey: process.env.STELE_API_KEY! });createAcceptanceSession(input)method
createAcceptanceSession({ document?, externalUserRef?, ttlSeconds? }): Promise<{ sessionToken, expiresAt }>hasAcceptedLatest(externalUserRef, slug)method
hasAcceptedLatest(externalUserRef: string, slug: string): Promise<AcceptanceRecord | null>listAcceptances(query) · getAcceptance(id) · latestVersion(slug)methods
createProofRequest(input) · listProofs() · getProofReceipt(id)methods
listSigners(ref?) · revokeSigner(publicKey, reason)methods
verifyWebhook(secret, signatureHeader, rawBody)function
verifyWebhook(secret: string, signatureHeader: string | undefined, rawBody: string | Buffer): WebhookEventnpm install @stelehq/verifier — checks evidence against Solana without asking Stele.import { verifyAcceptance, verifyDocumentVersion, verifyProof, chainFromUrls } from "@stelehq/verifier";verifyAcceptance(input, options)function
verifyAcceptance(
{ receipt } | { transactionSignature } | { acceptanceId },
{ chain: chainFromUrls(["https://api.devnet.solana.com"]) },
): Promise<VerificationReport> // { verdict: "VALID" | "VALID_WITH_WARNINGS" | "INVALID" | "INCONCLUSIVE", checks }verifyDocumentVersion · verifyProoffunctions