Getting Started
Add policy-enforced spending controls to your autonomous agents in minutes. No custody, no complexity—just wrap your wallet and go.
What SpendSafe Does
SpendSafe stops autonomous agents from draining wallets whilst keeping private keys under your control.
The problem:
- AI agents with wallet access can drain funds through bugs, exploits, or prompt injection
- Traditional solution: share seed phrases (compliance nightmare)
- Custodial solutions: hand over keys to third parties
SpendSafe's approach:
- Wrap your existing wallet with the PolicyWallet SDK
- Every transaction passes through two policy gates before signing
- Keys stay in your infrastructure—we never see them
- Configure limits via dashboard: daily caps, per-transaction limits, recipient whitelists
Result: Automated payments with built-in guardrails.
How It Works (30-Second Version)
Agent → PolicyWallet SDK → Gate 1 (validate) → Gate 2 (verify) → Sign locally → Blockchain
- Gate 1: Evaluates spending rules, reserves budget, issues single-use authorisation token
- Gate 2: Verifies token hasn't expired or been tampered with
- Sign locally: Your keys sign the transaction (SpendSafe never sees private keys)
- Fail-closed: If either gate fails, SDK throws error and never signs
Full technical details in Architecture Overview.
Quick Start (5 Minutes)
1. Install SDK
npm install @spendsafe/sdk
2. Get Dashboard Access
- Sign up at app.spendsafe.ai
- Create an organisation
- Create an agent
- Copy the API key (shown once)
- Set spending limits (daily, hourly, per-transaction, whitelist)
- Copy the policy hash (optional but recommended)
3. Configure Environment
# .env
PRIVATE_KEY=0xabc... # Your wallet (stays local)
RPC_URL=https://... # Your RPC endpoint (chain-specific)
SPENDSAFE_API_KEY=sk_test_xxxxxxxxxxxxx # From dashboard
4. Wrap Your Wallet
import { PolicyWallet } from '@spendsafe/sdk';
import { createYourAdapter } from '@spendsafe/sdk/adapters';
// Create adapter for your chosen wallet SDK
const adapter = await createYourAdapter({
privateKey: process.env.PRIVATE_KEY!,
rpcUrl: process.env.RPC_URL!,
});
// Wrap with PolicyWallet
const wallet = new PolicyWallet(adapter, {
apiKey: process.env.SPENDSAFE_API_KEY!,
});
5. Send Policy-Enforced Transaction
const result = await wallet.send({
chain: 'ethereum',
asset: 'eth',
to: '0xRecipient...',
amount: '1000000000000000000', // 1 ETH in wei
memo: 'Refund #4821',
});
console.log('Hash:', result.hash);
console.log('Remaining daily:', result.counters.remainingDaily);
That's it. Every wallet.send() call now enforces your dashboard policies.
What You Get
Two-Gate Enforcement
Gate 1 evaluates policies:
- Checks daily/hourly/per-transaction limits
- Verifies recipient whitelist (if configured)
- Reserves budget immediately (prevents race conditions)
- Issues single-use authorisation token
Gate 2 prevents tampering:
- Verifies token hasn't expired (60s TTL)
- Compares SHA-256 fingerprint of transaction intent (detects any modifications)
- Checks policy hash matches dashboard configuration
- Marks token consumed (prevents replay attacks)
Only after both gates succeed does the SDK sign locally with your keys.
Security via hashing:
- Intent fingerprint: SHA-256 of transaction details (chain, asset, recipient, amount)
- Policy hash: SHA-256 of dashboard rules
- Any modification between gates → hash mismatch → transaction blocked
Fail-Closed Guarantee
If Gate 1, Gate 2, or your RPC fails, the SDK throws an error and never signs. There's no bypass or "force send" option—safety first.
Decision Proofs
Every transaction returns cryptographic proof of the policy decision:
{
policyHash: 'ba500a3...', // SHA-256 of active dashboard policy
decision: 'allow', // Policy decision (allow/deny)
signature: '0x...', // HMAC signature of decision
signatureIssuedAt: '2025-02-14T12:34:56Z',
apiKeyId: 'api_key_123', // Which API key was used
intentFingerprint: '7c5bb4...' // SHA-256 of transaction intent
}
Use decision proofs to:
- Reconcile SDK responses with dashboard audit logs
- Prove which policy was active at transaction time
- Create compliance audit trails
Real-Time Monitoring
Dashboard provides complete visibility into agent spending:
- Live transaction feed - Every transaction (approved and denied) with timestamps
- Spending counters - Daily, hourly, and total spend by asset
- Value Protected - Total amount blocked by policies (cumulative savings)
- Decline reasons - Detailed breakdown of why transactions were denied
- Audit trail - Complete history with decision proofs for compliance
- Agent management - Create, configure, and monitor multiple agents
- Policy simulator - Test policies safely without broadcasting transactions
- Analytics - Charts showing spending patterns, top decline reasons, busiest hours
Supported Wallets & Chains
Wallet Adapters
- ethers.js - Most popular Ethereum library
- viem - Modern TypeScript-first option
- Coinbase SDK - Enterprise custody
- Dynamic.xyz - Embedded/social wallets
- Privy - Server-side signing
- Solana - Native Solana support
See Adapter Overview for details.
Blockchain Support
Production-ready:
- Ethereum (mainnet, Sepolia)
- Base (mainnet, Sepolia)
- All EVM-compatible chains (Polygon, Optimism, Arbitrum, Avalanche)
Policy validation:
- ETH, WETH
- USDC, USDT, DAI
- WBTC
- Any ERC-20 token
Solana:
- Wallet adapter production-ready
- Policy engine validation supported
Common Use Cases
AI Customer Support Agent
// Agent handles refunds with spending limits
async function processRefund(customerId: string, amount: string) {
const result = await wallet.send({
chain: 'base',
asset: 'usdc',
to: await getCustomerAddress(customerId),
amount: amount, // '1000000' = 1 USDC (6 decimals)
memo: `Refund for customer ${customerId}`,
});
await database.recordRefund(customerId, result.hash);
}
Policies enforced:
- Daily limit: $1,000 USDC
- Per-transaction: $100 USDC max
- Frequency: 50 refunds/hour max
Operations Bot
// Agent pays vendors from treasury wallet
async function payInvoice(invoiceId: string) {
const invoice = await getInvoice(invoiceId);
const result = await wallet.send({
chain: 'ethereum',
asset: 'usdc',
to: invoice.vendorAddress,
amount: invoice.amount,
memo: `Invoice ${invoiceId}`,
});
await markInvoicePaid(invoiceId, result.hash);
}
Policies enforced:
- Recipient whitelist: Only approved vendors
- Daily limit: $10,000 USDC
- Per-transaction: $5,000 USDC max
DeFi Trading Bot
// Agent rebalances portfolio with safety limits
async function rebalancePortfolio() {
const trades = await calculateRebalance();
for (const trade of trades) {
await wallet.send({
chain: 'ethereum',
asset: trade.asset,
to: trade.dexContract,
amount: trade.amount,
memo: `Rebalance ${trade.asset}`,
});
}
}
Policies enforced:
- Hourly limit: 10 ETH
- Daily limit: 50 ETH
- Frequency: 20 trades/hour max
- Recipient whitelist: Approved DEX contracts only
Error Handling
import { PolicyError } from '@spendsafe/sdk';
try {
await wallet.send({ ... });
} catch (error) {
if (error instanceof PolicyError) {
// Policy blocked transaction
console.error('Policy denied:', error.code, error.message);
console.error('Remaining daily:', error.details?.counters?.remainingDaily);
// Common codes:
// - POLICY_DECISION_DENY (limit exceeded, recipient blocked)
// - POLICY_HASH_MISMATCH (dashboard config changed)
// - RATE_LIMIT_VALIDATE_INTENT (too many requests)
} else {
// Network error, RPC failure, insufficient funds
console.error('Transaction failed:', error.message);
}
}
See SDK Reference for complete error code list.
Next Steps
Quick Integration
- Integration Guide - Complete walkthrough with code examples
- SDK Reference - API documentation and method reference
- Adapter Guides - Wallet-specific integration
Technical Deep Dive
- Architecture Overview - Two-gate model, fingerprinting, security guarantees
- Trust Model - Cryptographic verification details
- Policy Controls Roadmap - Current and planned policy features
Practical Resources
- Adapter Guides - ethers, viem, Solana, Coinbase, Dynamic, Privy
- Troubleshooting - Common issues and solutions
Why SpendSafe?
Non-Custodial by Design
Private keys never leave your infrastructure. SpendSafe sees only transaction metadata (chain, asset, recipient, amount) for policy evaluation.
Battle-Tested Architecture
Two-gate model with intent fingerprinting prevents tampering. Fail-closed design means network failures stop transactions, not allow them.
Developer-Friendly
Install SDK, wrap wallet, done. No infrastructure changes, no key management complexity, no compliance headaches.
Production-Ready
Rate limiting, decision proofs, audit trails, multi-chain support. Built for enterprise scale from day one.
Support
Dashboard: app.spendsafe.ai Documentation: docs.spendsafe.ai Email: support@spendsafe.ai
Start building safer autonomous agents today.