@debros/root
v0.104.0
Published
Platform-agnostic wallet SDK for Solana and EVM chains - Root Wallet
Maintainers
Readme
@debros/root
⚠️ Status: superseded. New code should depend on
@debros/root-coredirectly. This package will be reshaped into a thin re-export layer over@debros/root-corein v0.103+; the standalone reimplementations ofWallet,AccountManager,ChainManager, etc. that live here today will go away.Why: this SDK duplicates a substantial slice of
@debros/root-core(Wallet.ts is 1411 LOC, mirroring services that already exist in core) and has no internal consumers in the monorepo (see docs/ARCHITECTURE.md — "Open questions"). Maintaining two copies invites silent drift; the recent post-audit hardening went into core only.If you're starting fresh: import from
@debros/root-core. If you're already using@debros/root: keep going for now; the next major version will provide a migration path.
Platform-agnostic wallet SDK for building crypto wallet functionality into your apps. Supports Solana and EVM chains (Ethereum, Polygon, BSC, Arbitrum, Optimism) with full NFT support.
Features
- Zero Config - No API keys needed (only optional RPC endpoints)
- Platform Agnostic - Works in Node.js, Browser, and React Native
- Framework Agnostic - Vanilla JS core, React hooks as thin wrapper
- True Self-Custody - Keys never leave device
- Tree-Shakeable - Import only what you need (<50KB core)
- Unified Account Model - One account = all chain addresses
- Multi-Chain Support - Solana + EVM chains (Ethereum, Polygon, BSC, Arbitrum, Optimism)
- Token Support - Native tokens, SPL tokens, ERC-20 tokens
- NFT Support - Metaplex NFTs (Solana), ERC-721 & ERC-1155 (EVM)
Installation
# Using pnpm (recommended)
pnpm add @debros/root
# Using npm
npm install @debros/root
# Using yarn
yarn add @debros/rootPlatform-Specific Setup
# For React Native
pnpm add @debros/root react
# Optional: expo-secure-store for secure storage
# For Browser
pnpm add @debros/root
# Uses IndexedDB with optional encryption
# For Node.js
pnpm add @debros/root
# Uses file-based storage with encryptionQuick Start
Vanilla JavaScript / Node.js
import { Wallet } from "@debros/root";
// Create wallet with minimal config
const wallet = new Wallet();
// Create new wallet
const { mnemonic, account } = await wallet.create({ password: "secret" });
console.log("Mnemonic:", mnemonic);
console.log("Solana Address:", account.addresses.solana);
console.log("EVM Address:", account.addresses.evm);
// Send transaction
await wallet.send({
chain: "solana",
to: "recipient-address",
amount: "1.5", // Human-readable amount
password: "secret",
});React
import { WalletProvider, useWallet, useAccount, useBalance } from "@debros/root/react";
// Wrap your app
function App() {
return (
<WalletProvider config={{ chains: ["solana", "ethereum"] }}>
<YourApp />
</WalletProvider>
);
}
// Use hooks
function YourApp() {
const { isUnlocked, create, unlock } = useWallet();
const { accounts, activeAccount } = useAccount();
const { balances, loading, refresh } = useBalance();
// Your app logic
}Import Paths
// Main SDK entry point
import { Wallet } from "@debros/root";
// React bindings (WalletProvider, hooks)
import { WalletProvider, useWallet, useAccount, useBalance } from "@debros/root/react";
// Platform-specific storage
import { FileStorageAdapter, MemoryStorageAdapter } from "@debros/root/node";
import { IndexedDBAdapter } from "@debros/root/web";
import { SecureStoreAdapter, AsyncStorageAdapter } from "@debros/root/native";API Reference
Wallet
const wallet = new Wallet({
chains: ['solana', 'ethereum', 'polygon'], // Optional, defaults to all
rpc: { ethereum: 'https://...', solana: 'https://...' }, // Optional
storage: customStorage, // Optional, auto-detected by platform
});
// Lifecycle
await wallet.create({ password, mnemonicLength: 12 | 24 });
await wallet.import({ password, mnemonic });
await wallet.unlock(password);
wallet.lock();
await wallet.changePassword(oldPassword, newPassword);
await wallet.delete(password);
await wallet.getMnemonic(password);
// Accounts
const accounts = wallet.listAccounts();
await wallet.createAccount(password, { name: 'Trading' });
wallet.setActiveAccount(accountId);
await wallet.getPrivateKey(accountId, 'solana' | 'evm', password);
// Transactions
await wallet.send({ chain, to, amount, password, token? });
await wallet.estimateFee({ chain, to, amount });
await wallet.simulate({ chain, to, amount });
await wallet.waitForConfirmation(txHash, chain);
await wallet.cancelTransaction(txHash, chain, password); // EVM only
await wallet.speedUpTransaction(txHash, chain, password); // EVM only
// Balances
const balances = await wallet.getBalance(accountId?, chain?);
const tokens = await wallet.getTokenBalances(accountId?, chain?);
const portfolio = await wallet.getPortfolio(accountId?);
await wallet.refreshBalance(accountId?, chain?);React Hooks
useWallet()
const {
state, // WalletState
isUnlocked, // boolean
isInitialized, // boolean
create, // Create new wallet
import: importWallet,
unlock,
lock,
changePassword,
deleteWallet,
getMnemonic,
} = useWallet();useAccount()
const {
accounts, // UnifiedAccount[]
activeAccount, // UnifiedAccount | undefined
createAccount,
setActiveAccount,
renameAccount,
getPrivateKey,
} = useAccount();useBalance(options?)
const {
balances, // Balance[]
tokens, // TokenBalance[]
portfolio, // PortfolioSummary | null
loading,
error,
refresh,
} = useBalance({
accountId?: string,
chain?: ChainId,
refreshInterval?: number,
});useTransaction()
const {
send, // Send transaction
estimateFee, // Get fee estimate
waitForConfirmation,
cancelTransaction, // EVM only
speedUpTransaction, // EVM only
pendingTx,
sending,
error,
} = useTransaction();Unified Account Model
Each SDK account contains addresses for ALL supported chains:
interface UnifiedAccount {
id: string;
name: string;
index: number; // Same derivation index for all chains
addresses: {
solana: string; // e.g., "GjJW9Y..."
evm: string; // e.g., "0x742d..." (same for all EVM chains)
};
isDefault: boolean;
createdAt: number;
}Custom Storage
import { Wallet } from "@debros/root";
import { FileStorageAdapter } from "@debros/root/node";
// Node.js with encrypted file storage
const wallet = new Wallet({
storage: new FileStorageAdapter({
directory: "./wallet-data",
encryptionKey: "your-32-byte-key",
}),
});
// Or use memory storage for testing
import { MemoryStorageAdapter } from "@debros/root/node";
const wallet = new Wallet({
storage: new MemoryStorageAdapter(),
});Supported Chains
| Chain | Chain ID | Type | | ---------------------- | -------- | ------ | | Solana | 'solana' | Native | | Ethereum | 1 | EVM | | Polygon | 137 | EVM | | BSC | 56 | EVM | | Arbitrum | 42161 | EVM | | Optimism | 10 | EVM | | Sepolia (testnet) | 11155111 | EVM | | Polygon Amoy (testnet) | 80002 | EVM |
Security
- BIP-39 mnemonic generation (12/24 words)
- BIP-44 HD key derivation
- AES-256-GCM encryption for stored data
- Keys never leave the device
- Memory cleared after use
Development
# Install dependencies
pnpm install
# Build
pnpm build
# Test
pnpm test
# Type check
pnpm type-checkLicense
AGPL-3.0-only — see the top-level LICENSE for the full text.
