Overview
Add support for Privy server wallets to enable wallet-level transaction policies (allowlisted contracts, max amounts, time restrictions). Policies are managed in Privy Dashboard; Gateway just registers wallets and signs transactions.
Design Document
Full implementation spec: privy-gateway-design.md
Why Privy?
The main value is wallet-level policies:
- Restrict transactions to specific contracts (DEX routers only)
- Set maximum transfer amounts per transaction
- Allowlist/denylist recipient addresses
- Time-based access controls
- Block private key exports
Policies are configured in the Privy Dashboard and enforced server-side on every signing request.
Implementation Summary
Files to Create
src/wallet/privy/privy-client.ts - REST client for Privy API
src/wallet/privy/privy-evm-signer.ts - ethers.Signer implementation for EVM chains
src/wallet/privy/privy-solana-signer.ts - Solana transaction signer
Files to Modify
src/templates/apiKeys.yml - Add privyAppId, privyAppSecret
src/templates/namespace/apiKeys-schema.json - Add Privy properties
src/wallet/utils.ts - Add Privy wallet utilities (mirrors hardware wallet pattern)
src/chains/ethereum/ethereum.ts - Add isPrivyWallet() and getPrivySigner() methods
src/chains/solana/solana.ts - Add isPrivyWallet() and getPrivySigner() methods
src/wallet/wallet.routes.ts - Add /wallet/add-privy and /wallet/remove-privy routes
- Connectors (Jupiter, Raydium, Meteora, Uniswap) - Add Privy wallet branching
Key Design Decisions
- Uses existing
apiKeys.yml - No new config namespace; Privy credentials go in centralized API keys
- Follows existing hardware wallet pattern - Uses
isPrivyWallet() check and branching like existing isHardwareWallet() pattern
- Policies managed in Privy Dashboard - Gateway doesn't manage policies; it just registers wallets and signs transactions
- Minimal connector changes - Connectors add
else if (isPrivyWallet) branch to existing hardware wallet logic
- No new dependencies - Uses native
fetch for Privy API calls
API Endpoints
POST /wallet/add-privy - Register a Privy wallet (chain, privyWalletId)
DELETE /wallet/remove-privy - Unregister a Privy wallet (chain, address)
Connector Update Pattern
const isHardwareWallet = await solana.isHardwareWallet(walletAddress);
const isPrivyWallet = await solana.isPrivyWallet(walletAddress);
if (isHardwareWallet) {
// existing hardware wallet code...
} else if (isPrivyWallet) {
transaction = await jupiter.buildSwapTransactionForHardwareWallet(walletAddress, quote, ...);
const privySigner = await solana.getPrivySigner(walletAddress);
transaction = await privySigner.signTransaction(transaction);
} else {
// existing local wallet code...
}
Implementation Checklist
References
Overview
Add support for Privy server wallets to enable wallet-level transaction policies (allowlisted contracts, max amounts, time restrictions). Policies are managed in Privy Dashboard; Gateway just registers wallets and signs transactions.
Design Document
Full implementation spec: privy-gateway-design.md
Why Privy?
The main value is wallet-level policies:
Policies are configured in the Privy Dashboard and enforced server-side on every signing request.
Implementation Summary
Files to Create
src/wallet/privy/privy-client.ts- REST client for Privy APIsrc/wallet/privy/privy-evm-signer.ts- ethers.Signer implementation for EVM chainssrc/wallet/privy/privy-solana-signer.ts- Solana transaction signerFiles to Modify
src/templates/apiKeys.yml- Add privyAppId, privyAppSecretsrc/templates/namespace/apiKeys-schema.json- Add Privy propertiessrc/wallet/utils.ts- Add Privy wallet utilities (mirrors hardware wallet pattern)src/chains/ethereum/ethereum.ts- AddisPrivyWallet()andgetPrivySigner()methodssrc/chains/solana/solana.ts- AddisPrivyWallet()andgetPrivySigner()methodssrc/wallet/wallet.routes.ts- Add/wallet/add-privyand/wallet/remove-privyroutesKey Design Decisions
apiKeys.yml- No new config namespace; Privy credentials go in centralized API keysisPrivyWallet()check and branching like existingisHardwareWallet()patternelse if (isPrivyWallet)branch to existing hardware wallet logicfetchfor Privy API callsAPI Endpoints
POST /wallet/add-privy- Register a Privy wallet (chain, privyWalletId)DELETE /wallet/remove-privy- Unregister a Privy wallet (chain, address)Connector Update Pattern
Implementation Checklist
src/templates/apiKeys.ymlsrc/templates/namespace/apiKeys-schema.jsonsrc/wallet/privy/directorysrc/wallet/privy/privy-client.tssrc/wallet/privy/privy-evm-signer.tssrc/wallet/privy/privy-solana-signer.tssrc/wallet/utils.tsisPrivyWallet()andgetPrivySigner()tosrc/chains/ethereum/ethereum.tsisPrivyWallet()andgetPrivySigner()tosrc/chains/solana/solana.ts/wallet/add-privyand/wallet/remove-privyroutespnpm buildto verify no TypeScript errorspnpm testto verify existing tests passReferences