Core concepts
Five ideas explain almost everything about integrating IAMGame Wallet. Read this once and the rest of the docs will click into place: apps & keys, environments, the custodial wallet, identities & scope, and the money models.
Apps & keys
You create an app in the developer portal. Every app gets two API keys that split cleanly by where they run:
| Key | Prefix | Runs where | Can do |
|---|---|---|---|
| Publishable | pk_test_… / pk_live_… | Frontend (shipped in your game client) | Start logins, read the signed-in user's own wallet |
| Secret | sk_test_… / sk_live_… | Backend only — never in the browser | Verify sessions, move money, run the ledger, pay referrals |
pk_ is safe in client code — it can only act for the wallet of whoever is currently signed in. An sk_ can move money for any user in your app; keep it on your server and in your secret manager.Multiple apps belong to a studio (your team/organisation). Team members, billing, and live-access approvals live at the studio level; keys, currencies, and config are per-app.
Environments: test and live
Every app has two isolated environments, keyed off which key you use:
- test (
pk_test_/sk_test_) — runs on Solana devnet. Free test tokens, nothing is real. New apps start here. - live (
pk_live_/sk_live_) — runs on Solana mainnet, real money. You request live access in the portal once you’re ready.
Users, wallets, balances, and sessions are completely separate across the two environments — a test user is not a live user. Point your dev/staging builds at test keys and your production build at live keys; the same code works against both.
The custodial wallet
When a player signs in, IAMGame provisions them an embedded Solana wallet — a real on-chain address whose key is held in secure hardware (KMS) on the signer, not in the browser. Players never see a seed phrase or install an extension. Your game asks the wallet to sign or move funds through the SDK; the signer does the cryptography.
Players can also sign in with an external wallet (Phantom, Solflare, Backpack) via Sign-In-With-Solana — that’s a login method, covered in Authentication.
Identities & scope
A user is identified by how they logged in — an identity is a(type, externalId) pair: a Solana pubkey (SIWS), a Telegram user id, or an email address. The same person signing in the same way always resolves to the same user and the same wallet.
Scope decides whether wallets are shared across your apps. By default apps are GLOBAL-scoped: a player who signs in with the same identity across two of your apps gets one wallet, shared. An app can instead be isolated, giving its users their own wallets separate from your other apps. Most integrations want the shared default.
The money models
There are three server-side ways to move value, and picking the right one is the most important integration decision. A quick map — the Choose a money model page goes deep:
| Model | Use it for | How it works |
|---|---|---|
| Ledger | High-frequency play (slots, crash, per-tick betting) | Open a session with a lock, then bet/win/rollback off-chain at speed, settle once. No on-chain tx per action. |
| Custodial treasury | Real-money balances users top up and cash out | User's real wallet ↔ your game treasury. deposit / withdraw move actual on-chain USDC, tracked to a confirmed signature. |
| Pool-escrow custody | Pari-mutuel pools (everyone stakes, winners split) | Lock each stake into a pool, settle the whole pool atomically with a conservation guard, refund if voided. |
They compose. A typical real-money game uses the ledger for fast in-round play, the treasury for deposits/withdrawals at the cash boundary, and referrals on top to pay a network cut of the rake.
Amounts are integers
Every amount in the API is an integer string in the token’s smallest unit — never a float. SOL is in lamports (109), USDC in micro-USDC (106). Use BigInt, and pass amounts as strings so nothing rounds.
const oneUsdc = "1000000"; // 1 USDC = 10^6 micro-USDC
const halfSol = "500000000"; // 0.5 SOL = 5 × 10^8 lamports
// format for display with the SDK helper — never parseFloat a raw amount
import { formatTokenAmount } from "@iamgame/wallet-sdk";Referrals — the full loop
The wallet has a built-in multi-level referral system so you can reward players who bring other players. It spans the client and your server; here’s the whole loop end-to-end so the two halves make sense together:
| Step | Where | What happens |
|---|---|---|
| 1. Capture | Client | A player arrives on a ?ref=CODE link. The SDK captures the code and holds it (see Referrals in your UI). |
| 2. Attribute | Client → server | On their first sign-in the code is attached, and the wallet records first-touch attribution (immutable, within a 7-day window). |
| 3. Build the chain | Automatic | Attribution forms an upward chain: L1 = whose code they used, L2 = that person’s referrer, and so on. |
| 4. Reward | Server | When a round takes house rake, you call server.referrals.distribute to split a cut up that chain. You choose what % of the rake and how it splits per level. |
| 5. Withdraw | Server / player | Earnings accrue as off-chain credits; the referrer withdraws them to their wallet with server.referrals.withdraw. |
Client side you only capture and display; all the money logic (attribution, the split, payouts) is server-side with your sk_ key. Full detail: Referrals in your UI (capture) and Referral payouts (reward & withdraw).
Where to go next
- Quickstart — a working login in ~10 minutes.
- Client SDK setup — mount the provider and build your wallet UI.
- Choose a money model — the decision that shapes your backend.
- Referral payouts — reward your referral network from the rake.