Wallets
Understanding wallet types and custody models in the Cilantro Smart SDK
Wallets
The Cilantro Smart SDK supports two fundamentally different wallet architectures, each with distinct security, regulatory, and UX implications.
What is a Cilantro Smart Wallet?
A Cilantro wallet is a smart contract wallet (Program Derived Address) on Solana that:
- Has a unique Solana address controlled by an on-chain program
- Can hold SOL, SPL tokens, and NFTs
- Supports multiple signers for flexible authentication
- Implements programmable security policies (spending limits, time locks, etc.)
- Can execute transactions via Cross-Program Invocation (CPI)
- Provides transaction history and asset tracking
Wallet Types
1. Platform-Controlled Wallets (Custodial)
What It Is: A smart contract wallet where the platform retains custody of the signing keys.
How It Works:
User Request → Platform API → Platform Signs → Blockchain
When you create a platform-controlled wallet (without specifying adminSigner):
- Wallet Creation: Platform generates a PDA (Program Derived Address) on Solana
- Key Generation: Platform generates an Ed25519 keypair
- Key Storage: Private key stored in platform's secure key management system (HSM, KMS, etc.)
- Signer Registration: Public key registered as the admin signer on-chain
- Transaction Flow: Platform signs all transactions on behalf of the user
Advantages:
- ✅ Simple UX: No wallet downloads, no seed phrases, no gas management
- ✅ Instant Transactions: No waiting for user to sign
- ✅ Batch Operations: Platform can execute many operations efficiently
- ✅ Gasless Experience: Platform pays all transaction fees
- ✅ Account Recovery: Platform can reset access via email/2FA
- ✅ Fiat Integration: Easier to integrate with traditional payment systems
Disadvantages:
- ❌ Custodial Risk: Platform can access user funds
- ❌ Regulatory Burden: Platform may need money transmitter licenses
- ❌ Single Point of Failure: Platform breach = all wallets compromised
- ❌ User Trust Required: Users must trust platform won't misuse funds
- ❌ Not "True" Crypto: Doesn't follow crypto ethos of self-custody
Best Use Cases:
- 🎮 Gaming: In-game currency, NFT rewards, asset trading
- 🎁 Reward Programs: Loyalty points, cashback, referral bonuses
- 💳 Fiat On-Ramps: Converting fiat to crypto for users
- 🏢 Enterprise: Corporate accounts with centralized control
- 👶 Onboarding: First-time crypto users who aren't ready for self-custody
Code Example (responses have a data field; see Response and errors):
import { create, sendSOL } from 'cilantro-sdk/wallet';
// Platform-controlled wallet - simple creation
const { data } = await create({
name: 'Gaming Wallet',
userId: 'user-id'
// No adminSigner = platform controlled
});
const walletId = data.id;
// Platform can immediately sign transactions
const result = await sendSOL(walletId, {
recipientAddress: 'DYw8j...',
amountLamports: 1000000
});
// Transaction signed and sent without user interaction
2. User-Controlled Wallets (Non-Custodial)
What It Is: A smart contract wallet where the user retains full custody through their own signing mechanism.
How It Works:
User Request → Platform Prepares TX → User Signs Locally → Platform Submits → Blockchain
When you create a user-controlled wallet (with adminSigner specified):
- User Generates Keys: User creates signing keys on their device (email/phone device key, passkey, or external wallet)
- Wallet Creation: Platform generates PDA on Solana
- Signer Registration: User's public key registered as admin signer on-chain
- Key Custody: User's private key never leaves their device
- Transaction Flow:
- Platform prepares transaction
- User signs on their device
- Platform submits signed transaction
- Smart contract verifies signature on-chain
Advantages:
- ✅ True Ownership: User has complete control of funds
- ✅ No Platform Risk: Platform breach doesn't compromise user keys
- ✅ Regulatory Clarity: Platform isn't custodian, simpler compliance
- ✅ Censorship Resistant: Platform can't block user transactions
- ✅ Transparent: All operations verifiable on-chain
- ✅ Crypto Native: Aligns with decentralization principles
Disadvantages:
- ❌ Complex UX: Users must understand key management
- ❌ Key Loss Risk: Lost keys = lost funds (unless recovery set up)
- ❌ Slower Transactions: Requires user interaction to sign
- ❌ Gas Management: Users may need to manage SOL for fees
- ❌ Device Dependency: Keys tied to specific devices (unless multi-device)
Best Use Cases:
- 💰 DeFi: Trading, lending, staking high-value assets
- 🏦 Personal Banking: Long-term savings, investment accounts
- 🖼️ NFT Collections: Valuable digital art and collectibles
- 🔒 High Security: Applications requiring maximum security
- 🌐 dApp Integration: Connecting to other decentralized apps
Admin Signer Options:
Comparison Table
| Feature | Platform-Controlled | User-Controlled |
|---|---|---|
| Key Custody | Platform | User |
| Transaction Speed | Instant | Requires user action |
| UX Complexity | Simple | Moderate to Complex |
| Security Model | Trust platform | Trustless |
| Regulatory | Custodian rules apply | Not a custodian |
| Recovery | Email/phone reset | Must set up recovery |
| Batch Operations | Easy | Complex |
| Gasless TXs | Yes | Optional (platform can sponsor) |
| Best For | Gaming, rewards | DeFi, personal assets |
Hybrid Approach - Best of Both Worlds
Many applications use both wallet types:
// Strategy: Start custodial, upgrade to non-custodial
// 1. User signs up - create platform-controlled wallet
const { data } = await create({ name: 'Quick Start Wallet', userId: 'user-id' });
const walletId = data.id;
// User can immediately start using it
await sendSOL(walletId, {...});
// 2. User gains experience and wants more control
// Add email signer for user control
const signer = await createEmailSignerHelper(walletId, {
email: '[email protected]',
deviceKeyManager: storage
});
// 3. User can now choose: platform signs (fast) or user signs (secure)
Decision Framework
- Building a game with in-game currency
- Users are new to crypto
- Need instant, frictionless transactions
- Low transaction values
- Willing to handle custodial responsibilities
- Building DeFi application
- Handling significant value
- Users are crypto-experienced
- Need regulatory clarity as non-custodian
- Want to avoid key custody liability
Wallet Operations
Creating Wallets
Platform-Controlled (Custodial):
import { create } from 'cilantro-sdk/wallet';
const wallet = await create({
walletName: 'My Gaming Wallet',
chain: 'solana' // Optional: defaults to 'solana'
});
console.log('Wallet created:', wallet.data);
User-Controlled (Non-Custodial with Email):
import { create } from 'cilantro-sdk/wallet';
import { generateDeviceKeyPair } from 'cilantro-sdk/helpers';
const deviceKey = await generateDeviceKeyPair();
const wallet = await create({
walletName: 'My Personal Wallet',
chain: 'solana',
adminSigner: {
type: 'email',
authId: '[email protected]',
devicePublicKey: deviceKey.publicKey
}
});
Managing Wallets
- Find All - List all wallets with optional filters
- Find One - Get wallet by ID
- Find By Address - Get wallet by Solana address
- Update - Update wallet configuration
- Remove - Delete a wallet
- Activate/Deactivate - Manage wallet status
Transactions
- Send SOL - Send SOL to another address
- Send SPL - Send SPL tokens
- Send Transaction - Execute arbitrary transaction via CPI
- Simulate Transaction - Simulate a transaction without executing
Assets & Balances
- Get Assets - Get all assets for a wallet (cached with auto-refresh)
- Sync Assets - Force sync wallet balance and assets from blockchain
- Get Total Balance - Get combined balance across all wallets
NFTs & Tokens
- Mint NFT - Mint NFT using Metaplex via CPI (Advanced)
- Mint NFT Simple - Mint NFT with metadata (handles all logic internally)
- Mint Token - Mint fungible token (SPL or Token-2022)