Example wallet
One wallet: the code below is the code this page runs on its server, and the example beneath it shows what the distributor API answered for the wallet named in that code when the page was served, or why nothing was read.
The call
The printed call is the one this page's read makes when it reads: it connects the SDK's client and asks the eligibility read for one wallet. The printed code carries a placeholder where the key stands; this page's own key never reaches it or your browser.
import { connectDistributorApi } from "@yutai/sdk-web/client";
const client = connectDistributorApi({ base: "https://api.yutai.com", key: "ytk_your-key" });
const answer = await client.askEligibility(["0xcd8a4c3f9d3ab5c8817729a4d1420b95869b5928"]);GET /v1/eligibilitythe tokens a wallet holds and the benefits they reach: the read the example's answer draws and the paste box asksPOST /v1/claims/challengethe words the wallet signs, before the claim is askedPOST /v1/claimsthe claim, recorded on the proof the wallet signedGET /v1/claims/{id}the claim's own state, in the words the read answers
The example
The live example is not wired yet: its key is not set, so nothing was read.
The claim flow
A benefit the wallet reaches is one its holder can claim. The claim flow is the wallet's own: its wallet signs the one message Yutai asks for, Yutai records the claim on that proof, and the read answers the state the claim stands in. Each press names the way its own benefit reaches the holder: a code reaches the holder in their own Yutai app, and the answers Yutai hands back carry the claim's facts alone, never the holder's code.
The flow's own code, the order the presses run it in: the two asks the SDK's client carries, then the read, the calls the panel above names.
import { connectDistributorApi, refusedSentenceOf } from "@yutai/sdk-web/client";
const key = "ytk_your-key";
const client = connectDistributorApi({ base: "https://api.yutai.com", key });
const headers = { Authorization: `Bearer ${key}`, Accept: "application/json" };
// The words the wallet signs, before the claim is asked.
const challenge = await client.askClaimChallenge(benefitId, [wallet]);
const signature = await wallet.signMessage(challenge.message);
// The claim, recorded on that proof.
const answer = await client.askClaim({ benefitId, wallet, nonce: challenge.nonce, signature });
if (answer.status !== "claimed") throw new Error(refusedSentenceOf(answer.reason));
// The claim's own state, in the words the read answers.
const claim = await fetch(`https://api.yutai.com/v1/claims/${answer.claimId}`, { headers }).then((read) => read.json());Try an address
The paste box takes one address and asks the same read for it: the answer draws the way the example above does, and an address of a chain Yutai carries no wallet on is refused before anything is sent. The read answers live per paste, and the shared call's own cache window stands on it, so one pasted address asks the API at most once a minute.