Ward/Port
DEPTH 000
Open the dashboard
Embedded walletsigned guardrailsany EVM chain

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.

Get started See the code
it is self-hostable too
$ docker compose up → first transaction in 10 minutes
zero custodyEd25519-signed policysponsored gasUnreal Engine + TypeScriptself-host or hosted
01How it works

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.

01
Server
Prepares.

Builds the transaction, applies your signed policy (allowed functions, daily caps per player) and tops up gas within the caps you signed.

02
Device
Signs.

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.

03
Server
Re-checks and broadcasts.

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.

02In your game

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.

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" }

// your own contract, inline ABI, nothing to declare
Send Contract Call  "0xAbc…"  "mint"  [ id ]  abi
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,  // retries never double-charge
});
03Features

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.

Players
Email in, wallet out

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.

Studios
Rules you sign, we can't widen

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.

Gas
Sponsored, precisely

We top a player up with exactly the gas they are missing, within your signed caps. Their transaction still comes from their own address.

Safety
Retry-proof by design

Idempotency keys on every write: a network timeout never charges a player twice. Cancel a pending transaction with one call. Signed, replay-proof webhooks.

Escape hatches
Never boxed in

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.

Ops
One binary, your servers

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.

Open the dashboard Read the docs