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.
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
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.
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.
// 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.