Wallet Adapters Overview
SpendSafe works with any wallet SDK through a simple adapter pattern. Choose the adapter that matches your preferred wallet library.
Quick Comparison
| Adapter | Best For | Chains | Notes |
|---|---|---|---|
| ethers.js | Production EVM projects | All EVM | Most mature; broad ecosystem support |
| viem | Modern TS / smaller bundles | All EVM | Functional API, great for tree-shaking |
| Solana | SOL + SPL tokens | Solana | Native keypair support |
| Coinbase SDK | Enterprise custody | Multi-chain | Gasless USDC, managed wallet infra |
| Dynamic | Embedded/social wallets | All EVM | 4337 + MPC wallets, UX friendly |
| Privy | Server-side signing | All EVM | Minimal setup for backend agents |
Bundle sizes vary by bundler; treat the table as directional guidance.
Supported Chains
- EVM adapters (ethers, viem, Coinbase, Dynamic, Privy) support Ethereum, Base, Polygon, Optimism, Arbitrum, Avalanche, and other EVM-compatible networks your wallet SDK can reach.
- Solana adapter covers Solana Mainnet, Devnet, and Testnet.
- Multi-chain use cases can mix adapters side by side inside the same application.
How Adapters Work
All adapters implement the same WalletAdapter interface:
interface WalletAdapter {
// Get wallet address
getAddress(): Promise<string>;
// Get chain/network ID
getChainId(): Promise<string>;
// Sign and broadcast transaction
sendTransaction(request: TransactionRequest): Promise<TransactionResponse>;
// Get account balance
getBalance(): Promise<string>;
}
SpendSafe's PolicyWallet wraps any adapter and adds policy enforcement:
import { PolicyWallet, createEthersAdapter } from '@spendsafe/sdk';
// 1. Create adapter for your preferred wallet SDK
const adapter = await createEthersAdapter(privateKey, rpcUrl);
// 2. Wrap with PolicyWallet
const wallet = new PolicyWallet(adapter, {
apiUrl: process.env.SPENDSAFE_API_URL!,
apiKey: process.env.SPENDSAFE_AGENT_KEY!,
});
// 3. Use normally - policies enforced automatically
await wallet.send({
to: '0x...',
amount: '1000000', // 1 USDC (6 decimals)
});
Choosing an Adapter
Every adapter enforces the same policies. Choose based on your wallet stack, UX, and infrastructure needs.
Use ethers.js if:
- ✅ You need maximum compatibility
- ✅ You're already using ethers.js
- ✅ You want the most battle-tested library
- ✅ Bundle size isn't critical
Use viem if:
- ✅ You want modern TypeScript features
- ✅ Bundle size matters (significantly smaller than ethers)
- ✅ You prefer functional programming style
- ✅ You want better tree-shaking
Use Solana if:
- ✅ You're building on Solana blockchain
- ✅ You need SOL or SPL token transfers
- ✅ You want native Solana support
We’re validating the Solana adapter now—documentation will be expanded once testing completes.
Use Coinbase SDK if:
- ✅ You need enterprise-grade infrastructure
- ✅ You want multi-chain support out of the box
- ✅ You need gasless USDC transfers
- ✅ You're okay with developer-custodied wallets
Use Dynamic.xyz if:
- ✅ You need social login (email, Google, Twitter)
- ✅ You want embedded wallets with MPC security
- ✅ You need ERC-4337 smart wallet support
- ✅ You're building consumer-facing apps
Detailed guide coming soon. Reach out via support if you need early help.
Use Privy if:
- ✅ You need simple server-side transaction signing
- ✅ You want embedded wallets with minimal setup
- ✅ You prefer Privy's infrastructure
- ✅ You're building backend AI agents
Installation
Each adapter has its own installation requirements. See individual guides:
- ethers.js Installation
- viem Installation
- Solana Installation
- Coinbase SDK Installation
- Dynamic.xyz Installation
- Privy Installation
Multi-Wallet Support
You can use multiple adapters in the same project:
// EVM chains via ethers.js
const evmAdapter = await createEthersAdapter(evmKey, evmRpc);
const evmWallet = new PolicyWallet(evmAdapter, { apiKey: 'key-1' });
// Solana via Solana adapter
const solAdapter = await createSolanaAdapter(solKeypair, solRpc);
const solWallet = new PolicyWallet(solAdapter, { apiKey: 'key-2' });
// Each wallet enforces its own policies
await evmWallet.send({ to: '0x...', amount: '1000000' });
await solWallet.send({ to: 'Abc...', amount: '1000000' });
Next Steps
Choose your adapter and follow the detailed guide: