Client & server SDK

Two packages: @iamgame/wallet-sdk runs in the browser (player-facing — auth, wallet, sign, deposit, withdraw, export). @iamgame/wallet-sdk-server runs on your backend with the secret key (verification and the money ledger). The browser must never hold an sk_ or call win on itself.

Client — components

Prebuilt, themeable React components rendered inside the provider.

TS
import {
  WalletLogin,     // sign-in (SIWS / Telegram)
  WalletAddress,   // the player's address, with copy
  WalletBalance,   // live SOL / SPL balance
  WalletWithdraw,  // withdraw to another address
  WalletExport,    // self-custody export (where enabled)
} from "@iamgame/wallet-sdk";

Client — hooks

TS
import {
  useWalletAuth, useWallet, useWalletBalance, useWalletSign,
} from "@iamgame/wallet-sdk";

// Auth — every sign-in method, plus the session token for your backend:
const {
  status,                 // "loading" | "anonymous" | "authenticated"
  user,
  accessToken,            // -> send to YOUR backend for server-side verification
  connectExternal,        // SIWS (pass a browser-wallet adapter)
  connectTelegram,        // Telegram Mini App
  requestEmailOtp,        // email -> sends the 6-digit code
  connectEmail,           // email + code -> session
  logout,
} = useWalletAuth();

// The managed wallet + its balances:
const wallet = useWallet();                     // { id, address, ... }
const balance = useWalletBalance(wallet?.id ?? null);

// Server-side signing — one call signs any Solana transaction:
const { signAction } = useWalletSign();

Prefer <WalletLogin/> / <WalletLoginModal/> to render the login UI for all enabled methods (incl. Telegram zero-tap) — or drive the flows yourself with the hooks above.

Server — verify a session

See Authentication for the full login handshake.

TS
import { IAMGameWalletServer } from "@iamgame/wallet-sdk-server";

const wallet = new IAMGameWalletServer({ secretKey, baseUrl });
const verified = await wallet.verifySession(sessionToken);

Server — the ledger (high-frequency money)

For games that bet many times a second, settling each action on-chain is too slow. The ledger locks a stake once, runs bet/win/rollback in-memory-fast, and settles the net back on-chain at the end. All amounts are integer base units (lamports / micro-USDC), passed as bigint.

TS
// Session start — one lock
const s = await wallet.ledger.openSession({
  userId, gameCode: "momentum", currency: "USDC", lockAmount: 50_000_000n,
});

// Hot path — idempotent on transactionUuid, unlimited frequency
await wallet.ledger.bet({ sessionToken: s.sessionToken, transactionUuid: "r1-bet", amount: 1_000_000n, round: "r1" });
await wallet.ledger.win({ sessionToken: s.sessionToken, transactionUuid: "r1-win",
  referenceTransactionUuid: "r1-bet", amount: 1_800_000n, round: "r1", roundClosed: true });
await wallet.ledger.rollback({ sessionToken: s.sessionToken, referenceTransactionUuid: "r2-bet" });

// Session end — net settlement
const { payout } = await wallet.ledger.settleSession(s.sessionToken);

Contract guarantees: a duplicate transactionUuid returns the stored result (never a double-debit); a win must reference its bet; a rollback for an unseen bet is remembered so the late bet is rejected. Funds held by an open session are untouchable by withdraw and export.