Test environment · No-value assets · UMA sandbox · Real Chainlink VRFChecking service versions…
WORLD LOTTO DOCUMENTATION

Quickstart

Use the chain for writes and finality, the indexer for read models, and the public backend only for the compliance-gated deposit authorization flow.

Choose the right boundary

A third-party client does not need to trust the WF frontend. Read the active manifest, connect a wallet to Polygon Mainnet, read state from the chain or indexer, and submit user transactions directly to the deployed contracts.

The backend is not a general transaction relay. Its public write surface is limited to issuing an EIP-712 deposit authorization after fixed-asset whitelist and AML checks. The new Reserve has no per-transaction or daily quantity cap; balance, reserve liquidity, authorization, signature, minOut and pause checks still apply.

BoundaryUse it forTrust model
Chain RPCContract reads, simulations, receiptsAuthoritative state
User walletapprove, deposit, buy, claim, withdrawUser signs every write
IndexerRounds, tickets, activity, historyEventually consistent cache
Public backendDeposit authorization and token listPolicy-gated service

1. Read the deployment

Do not hard-code an address copied from a blog post or an old environment. The active manifest is the versioned source for chainId, deploymentId, start blocks, feature gates, and contract addresses.

import { deployment } from "@wf-protocol/contract-sdk";

if (deployment.chainId !== 137) throw new Error("wrong network");
if (deployment.status !== "active") throw new Error("deployment is not active");

console.log(deployment.deploymentId);
console.log(deployment.contracts.unifiedLedger);
console.log(deployment.features.btc15m);

2. Fund USD through the authorized deposit flow

The user first requests a signed authorization from the public backend. The response is then consumed by the user's wallet in the StablecoinReserve.deposit call. The backend never receives the user's private key and never submits the deposit transaction.

The EIP-712 domain is WUSDStablecoinReserve v1 on chain 137. The signed message fields are user, token, authorizedAmount, deadline, and nonce. The contract also receives minWusdOut for slippage protection.

const auth = await fetch(`${PUBLIC_API}/api/v1/deposit-authorizations`, {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({ userAddress, token, amount: amount.toString() }),
}).then((r) => r.json());

await wallet.writeContract({
  address: stablecoinReserve,
  functionName: "deposit",
  args: [token, amount, BigInt(auth.amount), amount,
    BigInt(auth.deadline), BigInt(auth.nonce), auth.signature],
});

3. Authorize and enter a game

Standalone UnifiedLedgerV4 is an internal six-decimal ledger, not an ERC-20. Users call executePurchaseV4 themselves, or sign PurchaseRequestV4 for a broadcaster to call executePurchaseWithAuthorizationV4. Both paths bind the owner, game, amount, purchase data, nonce and deadline. No operator allowance is required.

await wallet.writeContract({
  address: unifiedLedger,
  abi: unifiedLedgerV4Abi,
  functionName: "executePurchaseV4",
  args: [request, purchaseData],
});

4. Wait for finality, then reconcile

  • Treat the transaction receipt and contract state as the source of truth for a write.
  • Use the indexer after the receipt to render history and denormalized round state; indexing may lag the chain.
  • Every integration should surface deploymentId and txHash so a user can audit the exact chain and transaction.
  • Never infer a prize, refund, or final draw from an indexer row without checking the corresponding contract state when money is at stake.