Ward/Port
DEPTH 000
Open the dashboard
Documentation

Ship on-chain items in ten minutes

A studio integrates WardWallet in three surfaces: a game engine (Unreal), a web app (the TypeScript SDK), and a backend (a plain HTTP API). Every path goes through the same signed guardrails.

Quickstart

Run the whole stack locally — Postgres, a dev chain, and the server — and land your first transaction without touching a testnet.

terminal · 10 minutes
# postgres + anvil (chain 31337) + the server
cd deploy && MASTER_KEY_HEX=$(openssl rand -hex 32) [email protected] docker compose up -d
docker compose logs -f server   # sign-in codes print here while SMTP is unset

Open the dashboard, sign in with the emailed code, create an app, and follow its checklist: register a contract with its ABI, define an action, sign and publish the policy, paste the setup key into the plugin, watch the first transaction land in Activity.

Actions — zero crypto in gameplay code

Define an operation 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 in your game.

Unreal Engine · Blueprint
// 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" }
Web · @wardwallet/sdk
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 });

Named actions are the comfortable path, not the only one. Drop a level and keep the same guardrails: registered contracts, inline ABI passed in the request, raw calldata, or a read-only JSON-RPC proxy. Going lower buys more freedom of expression, never more rights — what the signed policy forbids stays forbidden, even in raw calldata.

The signed policy

The rules — which contract functions are callable, per-player daily caps, which calls get their gas paid — are a document signed with an Ed25519 key that stays in your browser. The server holds the public key, verifies the signature, and enforces it. A fully compromised server can refuse a transaction; it cannot authorize one more.

Every transaction is checked three times: when the server prepares it, on the player's device before signing, and again at broadcast. The player does not have to trust the server — they can see the call matches the published rules.

Recovery — the studio is never the custodian

The private key is generated on the device and encrypted in the OS keystore; it never reaches the server. Recovery runs on a code only the player holds: a 120-bit code → PBKDF2-HMAC-SHA256, 600,000 iterations → AES-256-GCM. The server stores only an opaque blob it cannot decrypt. The player can export the key any time and open it in any wallet — leaving is allowed, which is what makes “non-custodial” checkable instead of a claim.

Retry-proof writes

Pass an Idempotency-Key on any write. A network timeout that makes the game retry returns the same prepared transaction — the player is never charged twice — while the same key with a different body is refused. A pending transaction can be cancelled with one call, freeing its daily caps immediately. Outgoing webhooks are signed with a timestamp and are replay-proof.

idempotent action + cancel + batch read
await doAction(client, { account, name: 'buy_gems', params, idempotencyKey: orderId });
await client.cancel(prepareId);                 // give up a pending tx
await client.batchRead([{ address, function: 'balanceOf', args: [addr] }, /* …up to 20 */]);

API surface

One binary serves four surfaces, each with its own authentication, and no surface can call another's routes.

/v1The player and the studio backend — a player JWT, or a server API key. Auth, balances, reads, prepare/broadcast, actions, sessions, encrypted backup.
/dashboardThe studio — a session cookie. Apps, keys, contracts, policy signing, players, sponsored gas, webhooks, billing.
/adminUs — cookie + admin role.
publicHealth, status, the OpenAPI spec, the chain catalogue.

The OpenAPI spec is embedded in the binary and served as JSON — the published docs can never drift from the server. Any EVM chain works: we manage chain IDs, not a whitelist.

Player erasure (GDPR)

One call erases a player: profile, sessions, wallet backups and sign-in codes are deleted; transactions are kept for the financial record but scrubbed of IP and device data. The audit log records only a pseudonymous hash, never re-introducing the erased identity.

Open the dashboard See pricing