Skip to content

Server Wallets

OxGasServerWallet is a server-side wallet primitive in @0xgasless/core. Each userId you pass becomes a unique, persistent EOA whose private key lives in AWS KMS. Your server signs by calling an API — the key never leaves the platform.

Terminal window
npm install @0xgasless/core
Use caseFit
Telegram, Discord, or WhatsApp bots with one wallet per user★★★★★
Cron jobs, scheduled tasks, and worker queues★★★★★
Trading bots and market makers★★★★★
AI agents that hold balances and sign transactions★★★★★
Browser dApp where users approve their own transactionsUse Embedded Wallets instead
Agent that pays per HTTP call with x402 micropaymentsUse Agent SDK instead
  • One wallet per user, on demand. Pass any string as userId (a Telegram ID, a UUID, an email) and you get the same wallet back every time.
  • No key management. No env vars, no JSON keystores, no rotation jobs. Keys live in AWS KMS.
  • Instant signing. API call → signed transaction in 50-100 ms. No human in the loop, no waiting for approval.
  • No client gas. Each call is authenticated with your project API key — your bot never needs gas to authenticate.
  • Broadcast anywhere. The SDK signs; you broadcast to any EVM RPC. Your bot keeps the tx hash.
Your server Platform Chain
─────────── ──────── ─────
│ │
wallet.getAddress(uid) ──────────► │ │
│ KMS lookup / create │
◄───────────────────│ return EOA │
│ │
wallet.signTransaction(uid, tx) ──► │ │
│ KMS signs │
◄───────────────────│ return rawTx + hash │
│ │
your.broadcast(rawTx) ────────────────────────────────────────► │ submit
◄───────────────────────────────────────────── │ block

The platform owns the key and the signing operation. Your code owns the broadcast and your business logic. Clean split.

Thing you don’t writeWhy
Key generationKMS does it on first getOrCreateWallet for each userId.
Key storageKeys live in KMS — never in your filesystem, env vars, or DB.
Nonce tracking across hot rebootsWe surface the chain nonce; you pass it in. (Or store it in your DB.)
Gas estimationReasonable defaults are baked in; override per call when needed.
User auth UIThere is none — wallets are addressed by userId only.