Their keys
stay theirs.
Your rules stay sealed.
Players sign in with an email code and get a wallet on their device: no extension, no seed phrase, no popup. You sign the rules in your browser; the server enforces them and cannot widen them. Not by policy. By construction.
One transaction, three checks, one line it never crosses
The private key is generated on the player's device and encrypted in the OS keystore. The server only ever sees transactions that are already signed.
Builds the transaction, applies your signed policy (allowed functions, daily caps per player) and tops up gas within the caps you signed.
Re-verifies the policy locally, then signs with the key from the keystore. The key never leaves. The player does not have to trust us; they can check.
The signed transaction is verified against the policy once more, then sent. Receipt tracked, your backend notified by signed webhook.
A fully compromised server can refuse a transaction. It cannot authorize one more. That is the whole product.
Zero crypto in your gameplay code
Define an action once in the dashboard (buy_gems = deposit(player), amounts in human units) then call it by name. No ABI, no wei, no nonces, no gas math.
// player signs in, wallet created on the device Create Widget (Ward Login Widget) → Add to Viewport // the purchase: returns a confirmed tx hash Do Action "buy_gems" { amount : "0.5" } // your own contract, inline ABI, nothing to declare Send Contract Call "0xAbc…" "mint" [ id ] abi
import { WardWalletClient, doAction } from '@wardwallet/sdk'; const client = new WardWalletClient({ baseUrl }); await client.otpVerify(APP_ID, CLIENT_KEY, email, code); await doAction(client, { account, name: 'buy_gems', params: { amount: '0.5' }, idempotencyKey: orderId, // retries never double-charge });
Everything a studio needs. Nothing it has to trust.
Built for game teams that want on-chain items without becoming a custodian, and without sending players to a browser extension.
A code by email, a wallet on the device. Recovery with a code only the player holds: 600k-round PBKDF2, AES-256-GCM, sealed client-side. Key export any time: leaving is allowed, which is what makes "non-custodial" checkable.
The policy (contracts, functions, per-player daily caps, sponsored-gas rules) is signed with an Ed25519 key that stays in your browser. Verified server-side and on the device.
We top a player up with exactly the gas they are missing, within your signed caps. Their transaction still comes from their own address.
Idempotency keys on every write: a network timeout never charges a player twice. Cancel a pending transaction with one call. Signed, replay-proof webhooks.
Named actions are the comfortable path, not the only one: registered contracts, inline ABI, raw calldata, read-only JSON-RPC proxy, all through the same guardrails.
Go + PostgreSQL, distroless image, GDPR player-erasure built in, Prometheus metrics. Self-host it, or use the hosted service. Any EVM chain: we manage chain IDs, not a whitelist.
Ship on-chain items without becoming a custodian.
First transaction in ten minutes, on your laptop, with a local chain.