Skip to main content

Wallet Vault

The Wallet Vault is Steward’s encrypted key storage system. It generates, stores, and manages private keys for AI agents — providing signing capabilities without ever exposing raw keys.

How It Works

When you create an agent, Steward generates keypairs for both EVM and Solana chains:
const agent = await steward.createWallet("trading-agent", "Trading Agent");
// → EVM address: 0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18
// → Solana address: 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU
The private keys are immediately encrypted with AES-256-GCM and stored as ciphertext. They’re only decrypted in-memory for the brief moment needed to sign a transaction, then zeroed.

Encryption Architecture

Master Password (env: STEWARD_MASTER_PASSWORD)

    └─ Argon2id key derivation

        └─ Master Key

            ├─ encrypts → Agent "trading-agent" EVM key (AES-256-GCM)
            ├─ encrypts → Agent "trading-agent" Solana key (AES-256-GCM)
            └─ encrypts → Agent "data-agent" EVM key (AES-256-GCM)
Each encrypted key is stored with:
  • Ciphertext — the encrypted private key
  • IV — 12-byte initialization vector (unique per encryption)
  • Auth Tag — 16-byte GCM authentication tag (tamper detection)

Supported Chains

Steward supports all EVM-compatible chains. Configure the chain via chainId:
ChainChain IDStatus
Base Mainnet8453✅ Production
Base Sepolia84532✅ Testnet
Ethereum Mainnet1✅ Production
Arbitrum One42161✅ Production
Optimism10✅ Production
Polygon137✅ Production
BSC56✅ Production
Signing methods:
  • eth_signTransaction — Standard transaction signing + broadcast
  • eth_signTypedData_v4 (EIP-712) — DEX approvals, permits, structured data
  • personal_sign — Message signing

Signing Flow

Every signing request passes through the Policy Engine before execution:
// 1. Agent requests a transaction
const result = await steward.signTransaction("trading-agent", {
  to: "0xDEX_ROUTER",
  value: "50000000000000000", // 0.05 ETH
  data: "0x...",              // calldata
  chainId: 8453,              // Base
});

// 2. Steward evaluates policies:
//    ✅ spending-limit: 0.05 ETH < 0.1 ETH max per tx
//    ✅ approved-addresses: 0xDEX_ROUTER in whitelist
//    ✅ rate-limit: 5 tx/hour < 10 max
//    ✅ auto-approve: 0.05 ETH ≤ 0.05 ETH threshold → auto-approve

// 3. Key decrypted, transaction signed, broadcast to chain
console.log(result.txHash); // "0x8d7592b..."

Key Import

For agents that already have keys (e.g., migrating from another system), you can import private keys:
// Import requires tenant-level authentication
const result = await fetch("https://api.steward.fi/vault/my-agent/import", {
  method: "POST",
  headers: {
    "X-Steward-Key": "your-tenant-api-key",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    privateKey: "0x...",
    chain: "evm", // or "solana"
  }),
});
Key import requires tenant-level authentication (not agent tokens). The imported key is immediately encrypted and the plaintext is discarded. Never store private keys in environment variables or logs.

Multi-Wallet Addresses

Each agent can have wallets across multiple chain families. Query all addresses:
const addresses = await steward.getAddresses("trading-agent");
// {
//   agentId: "trading-agent",
//   addresses: [
//     { chainFamily: "evm", address: "0x742d35Cc..." },
//     { chainFamily: "solana", address: "7xKXtg2CW87d..." }
//   ]
// }

RPC Passthrough

Agents can make read-only RPC calls through Steward, which injects the RPC provider’s API key:
const result = await steward.rpcPassthrough("trading-agent", {
  method: "eth_getBalance",
  params: ["0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18", "latest"],
  chainId: 8453,
});