Documentation Index Fetch the complete documentation index at: https://docs.crossmint.com/llms.txt
Use this file to discover all available pages before exploring further.
Latest Node.js SDK version -
Typescript SDK (@crossmint/wallets-sdk) for creating and managing Crossmint Wallets on EVM, Solana, and Stellar chains.
Prerequisites
Get a Crossmint API key from the developer console . Ensure your key has the Wallet API scopes enabled.
Client-side (browser): Use a client API key
Server-side (Node.js): Use a server API key
Installation
npm install @crossmint/wallets-sdk
# or
pnpm add @crossmint/wallets-sdk
# or
yarn add @crossmint/wallets-sdk
Quick Start
Server-side (Node.js)
import { createCrossmint , CrossmintWallets } from "@crossmint/wallets-sdk" ;
const crossmint = createCrossmint ({ apiKey: "<YOUR_SERVER_API_KEY>" });
const wallets = CrossmintWallets . from ( crossmint );
// Create a wallet with a server signer
const wallet = await wallets . createWallet ({
chain: "base-sepolia" ,
recovery: { type: "server" , secret: "<RECOVERY_SECRET>" },
});
console . log ( wallet . address );
// Send tokens
const tx = await wallet . send ( "0xRecipientAddress" , "usdc" , "10" );
console . log ( tx . explorerLink );
Client-side (Headless)
For client-side usage without React, you can use the SDK directly with JWT authentication:
import { createCrossmint , CrossmintWallets } from "@crossmint/wallets-sdk" ;
const crossmint = createCrossmint ({ apiKey: "<YOUR_CLIENT_API_KEY>" });
crossmint . setJwt ( "<USER_JWT>" );
const wallets = CrossmintWallets . from ( crossmint );
const wallet = await wallets . getWallet ({ chain: "base-sepolia" });
console . log ( wallet . address );
For React apps, use @crossmint/client-sdk-react-ui which provides CrossmintWalletProvider, hooks, and built-in UI for OTP and passkey flows.
Core Concepts
Signers
Wallets SDK uses a two-tier signer model:
Recovery signer — High-security, used for wallet recovery and adding new signers. Supports email OTP, phone OTP, external wallet, or server key.
Operational signer — Low-friction, used for day-to-day signing. The default is the device signer , which uses hardware-backed keys (no OTP needed). Also supports passkey, server key, and external wallet.
When no operational signer is available, the recovery signer automatically serves as a fallback for signing.
Wallet Lifecycle
// Create a new wallet
const wallet = await wallets . createWallet ({
chain: "base-sepolia" ,
recovery: { type: "email" , email: "user@example.com" },
signers: [{ type: "device" }], // optional — device is the default
});
// Retrieve an existing wallet (client-side)
const wallet = await wallets . getWallet ({ chain: "base-sepolia" });
// Retrieve an existing wallet (server-side)
const wallet = await wallets . getWallet ( "0xWalletAddress" , {
chain: "base-sepolia" ,
});
Usage
Balances
const balances = await wallet . balances ();
console . log ( balances . nativeToken . amount );
console . log ( balances . usdc . amount );
Send Tokens
const tx = await wallet . send ( "0xRecipient" , "usdc" , "100" );
console . log ( tx . explorerLink );
Transfers
const transfers = await wallet . transfers ({
tokens: "usdc" ,
status: "successful" ,
});
NFTs
const nfts = await wallet . nfts ({ perPage: 10 , page: 1 });
Chain-Specific Transactions
import { EVMWallet , SolanaWallet , StellarWallet } from "@crossmint/wallets-sdk" ;
// EVM — smart contract interaction
const evmWallet = EVMWallet . from ( wallet );
const tx = await evmWallet . sendTransaction ({
to: "0xContractAddress" ,
abi: contractAbi ,
functionName: "mint" ,
args: [ 1 ],
value: 0 n ,
});
// EVM — sign a message
const sig = await evmWallet . signMessage ({ message: "Hello" });
// EVM — viem public client
const client = evmWallet . getViemClient ();
// Solana
const solWallet = SolanaWallet . from ( wallet );
const solTx = await solWallet . sendTransaction ({
serializedTransaction: "<base64-encoded-transaction>" ,
});
// Stellar
const stellarWallet = StellarWallet . from ( wallet );
const stellarTx = await stellarWallet . sendTransaction ({
contractId: "C..." ,
method: "transfer" ,
args: { to: "G..." , amount: "1000000" },
});
Signer Management
// Add a new signer
await wallet . addSigner ({ type: "server" , secret: "<SECRET>" });
// List signers
const signers = await wallet . signers ();
console . log ( signers ); // [{ type: "device", locator: "device:...", status: "success" }, ...]
// Set the active signer
await wallet . useSigner ({ type: "server" , secret: "<SECRET>" });
// Recovery flow (new device)
if ( wallet . needsRecovery ()) {
await wallet . recover (); // uses recovery signer to register a new device signer
}
Transaction Approval (Prepare-Only Mode)
For flows that require multi-step approval:
// Create a transaction without auto-approving
const pendingTx = await wallet . send ( "0xRecipient" , "usdc" , "10" , {
prepareOnly: true ,
});
console . log ( pendingTx . transactionId );
// Approve later
const result = await wallet . approve ({
transactionId: pendingTx . transactionId ,
});
Signer Types
Type Use Case Platforms deviceDefault day-to-day signer. Hardware-backed, no OTP. Browser, React Native serverServer-side automated operations (AI agents, backends). Node.js emailOTP-based recovery signer. All phoneOTP-based recovery signer. All passkeyWebAuthn/FIDO2 biometric signer. Browser (EVM only) external-walletBring-your-own key (MetaMask, KMS, etc). All
React / React Native
For React applications, use @crossmint/client-sdk-react-ui which provides wallet providers, hooks (useWallet, useWalletOtpSigner), and built-in UI for OTP and passkey flows.
For React Native, see @crossmint/client-sdk-react-native-ui .
Documentation
License
Apache-2.0
Signers Learn about signer types and how to choose the right ones.