Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Crossmint/crossmint-agentic-finance/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The @crossmint/wallets-sdk provides smart wallet functionality for AI agents in the Agentic Finance platform. Crossmint wallets are smart contract wallets that support ERC-6492 pre-deployment signatures and work seamlessly with the x402 payment protocol.
Installation
npm install @crossmint/wallets-sdk
Core Concepts
Wallet Types
- Smart Contract Wallets: Crossmint creates smart contract wallets that can be pre-deployed (ERC-6492) or fully deployed on-chain
- API Key Signer: Wallets use API key-based signing for autonomous agent operation
- Multi-chain Support: Supports Base Sepolia and other EVM chains
Wallet States
- Pre-deployed: Wallet exists but contract is not yet deployed on-chain (uses ERC-6492 signatures)
- Deployed: Wallet contract is deployed on-chain (uses EIP-1271 signatures)
Creating a Crossmint Client
Basic Setup
import { createCrossmint, CrossmintWallets } from '@crossmint/wallets-sdk';
const crossmint = createCrossmint({
apiKey: process.env.CROSSMINT_API_KEY
});
const crossmintWallets = CrossmintWallets.from(crossmint);
Creating Wallets
Create a Wallet with API Key Signer
const wallet = await crossmintWallets.createWallet({
chain: "base-sepolia",
signer: { type: "api-key" },
owner: "userId:my-app:user-123"
});
console.log("Wallet address:", wallet.address);
Wallet Locator Pattern
Use consistent locators to ensure the same wallet is retrieved:
// Guest agent - consistent wallet per user
const GUEST_WALLET_LOCATOR = "userId:crossmint-merchant-guest:demo-user";
const guestWallet = await crossmintWallets.createWallet({
chain: "base-sepolia",
signer: { type: "api-key" },
owner: GUEST_WALLET_LOCATOR
});
// Host agent - wallet per host user
const hostWallet = await crossmintWallets.createWallet({
chain: "base-sepolia",
signer: { type: "api-key" },
owner: `userId:crossmint-merchant-host:${userScopeId}`
});
EVM Wallet Operations
Converting to EVMWallet
import { EVMWallet } from '@crossmint/wallets-sdk';
const evmWallet = EVMWallet.from(wallet);
console.log("EVM address:", evmWallet.address);
console.log("Chain:", evmWallet.chain);
Signing Typed Data
Sign EIP-712 typed data for payment authorizations:
const signature = await evmWallet.signTypedData({
domain: {
name: "X402",
version: "1",
chainId: 84532,
verifyingContract: "0x..."
},
message: {
from: evmWallet.address,
to: "0x...",
maxAmount: "1000000", // 1 USDC
nonce: 1
},
primaryType: "Payment",
types: {
Payment: [
{ name: "from", type: "address" },
{ name: "to", type: "address" },
{ name: "maxAmount", type: "uint256" },
{ name: "nonce", type: "uint256" }
]
},
chain: evmWallet.chain as any
});
console.log("Signature:", signature.signature);
Sending Transactions
// Send a transaction
const tx = await evmWallet.sendTransaction({
to: "0xRecipientAddress",
value: 1000000n, // 0.001 ETH in wei
data: "0x"
});
console.log("Transaction hash:", tx.hash);
Deploy Pre-deployed Wallet
Deploy a pre-deployed wallet with a minimal self-transfer:
const deploymentTx = await evmWallet.sendTransaction({
to: wallet.address,
value: 1n, // 1 wei
data: "0x"
});
console.log("Wallet deployed:", deploymentTx.hash);
Complete Examples
Guest Agent Wallet Setup
From events-concierge/src/agents/guest.ts:91-113:
import { CrossmintWallets, createCrossmint, type Wallet } from '@crossmint/wallets-sdk';
class Guest {
wallet!: Wallet<any>;
async onStart() {
// Initialize Crossmint SDK and create wallet with API key signer
const crossmint = createCrossmint({
apiKey: this.env.CROSSMINT_API_KEY
});
const crossmintWallets = CrossmintWallets.from(crossmint);
// Create or get wallet using consistent locator
const locator = "userId:crossmint-merchant-guest:demo-user";
this.wallet = await crossmintWallets.createWallet({
chain: "base-sepolia",
signer: { type: "api-key" },
owner: locator
});
console.log(`Guest wallet ready: ${this.wallet.address}`);
}
}
Host Agent Wallet Setup
From events-concierge/src/agents/host.ts:241-265:
import { CrossmintWallets, createCrossmint, type Wallet } from '@crossmint/wallets-sdk';
class Host {
wallet!: Wallet<any>;
async init() {
// Create host wallet for receiving payments
const crossmint = createCrossmint({
apiKey: this.env.CROSSMINT_API_KEY
});
const crossmintWallets = CrossmintWallets.from(crossmint);
this.wallet = await crossmintWallets.createWallet({
chain: "base-sepolia",
signer: { type: "api-key" },
owner: `userId:crossmint-merchant-host:${this.userScopeId}`
});
const recipient = this.wallet.address as `0x${string}`;
// Store wallet address in KV
await this.env.SECRETS.put(
`usersByHash:${this.userScopeId}`,
JSON.stringify({ walletAddress: recipient, userId: this.userScopeId })
);
console.log(`Host wallet created: ${recipient}`);
}
}
Type Definitions
Wallet Interface
interface Wallet<T> {
address: string;
chain: string;
// Additional properties specific to wallet type
}
EVMWallet Methods
class EVMWallet {
address: string;
chain: string;
static from(wallet: Wallet<any>): EVMWallet;
signTypedData(params: {
domain: any;
message: any;
primaryType: string;
types: any;
chain: any;
}): Promise<{ signature: string }>;
sendTransaction(params: {
to: string;
value: bigint;
data: string;
}): Promise<{ hash: string }>;
}
Best Practices
Use Consistent Locators
Always use consistent owner locators to ensure the same wallet is retrieved:
// Good: Deterministic locator
const locator = `userId:my-app:${userId}`;
// Bad: Random locator
const locator = `userId:my-app:${Math.random()}`;
Handle Wallet Deployment
Check if a wallet is deployed before making payments:
import { createPublicClient, http } from 'viem';
import { baseSepolia } from 'viem/chains';
async function checkWalletDeployment(walletAddress: string): Promise<boolean> {
const publicClient = createPublicClient({
chain: baseSepolia,
transport: http("https://sepolia.base.org")
});
const code = await publicClient.getCode({
address: walletAddress as `0x${string}`
});
return code !== undefined && code !== '0x' && code.length > 2;
}
Deploy Before Settlement
For x402 payments, deploy pre-deployed wallets before settlement:
const isDeployed = await checkWalletDeployment(wallet.address);
if (!isDeployed) {
console.log("Deploying wallet...");
const evmWallet = EVMWallet.from(wallet);
await evmWallet.sendTransaction({
to: wallet.address,
value: 1n,
data: "0x"
});
console.log("Wallet deployed!");
}
Error Handling
Insufficient Balance
try {
await evmWallet.sendTransaction({ to, value, data });
} catch (error) {
const errorMsg = error instanceof Error ? error.message : String(error);
if (errorMsg.includes('insufficient') || errorMsg.includes('balance')) {
throw new Error("Insufficient ETH balance for gas fees");
}
throw error;
}
See Also