Overview
The EvmSmartAccount is an EVM smart contract account that supports account abstraction features like user operations, batch transactions, and paymasters. It requires one or more owner accounts for signing.
Type Definition
type EvmSmartAccount = {
address : Address ;
name ?: string ;
type : "evm-smart" ;
owners : EvmAccount [];
policies ?: string [];
transfer : ( options : SmartAccountTransferOptions ) => Promise < SendUserOperationReturnType >;
listTokenBalances : ( options : Omit < ListTokenBalancesOptions , "address" >) => Promise < ListTokenBalancesResult >;
sendUserOperation : < callData >( options : Omit < SendUserOperationOptions < callData >, "smartAccount" >) => Promise < SendUserOperationReturnType >;
waitForUserOperation : ( options : Omit < WaitForUserOperationOptions , "smartAccountAddress" >) => Promise < WaitForUserOperationReturnType >;
getUserOperation : ( options : Omit < GetUserOperationOptions , "smartAccount" >) => Promise < UserOperation >;
requestFaucet : ( options : Omit < RequestFaucetOptions , "address" >) => Promise < RequestFaucetResult >;
quoteSwap : ( options : SmartAccountQuoteSwapOptions ) => Promise < SmartAccountQuoteSwapResult >;
swap : ( options : SmartAccountSwapOptions ) => Promise < SmartAccountSwapResult >;
signTypedData : ( options : SignTypedDataOptions & { network : string }) => Promise < Hex >;
useSpendPermission : ( options : UseSpendPermissionOptions ) => Promise < SendUserOperationReturnType >;
useNetwork : < Network >( network : Network ) => Promise < NetworkScopedEvmSmartAccount < Network >>;
};
Properties
The smart account’s contract address.
Optional name for the smart account.
Identifier for the smart account type.
Array of owner accounts that can sign for this smart account. Currently supports one owner, but will be extended to support multiple owners in the future.
Array of Policy IDs that apply to the smart account (includes both project-level and account-level policies).
Methods
sendUserOperation
Sends a user operation (batch of calls) to the network.
The network to send the user operation on.
Array of calls to execute in the user operation.
Optional paymaster URL for gas sponsorship.
Optional data suffix for the user operation.
The smart account address.
The status of the user operation.
import { parseEther } from "viem" ;
const result = await smartAccount . sendUserOperation ({
network: "base-sepolia" ,
calls: [
{
to: "0x4252e0c9A3da5A2700e7d91cb50aEf522D0C6Fe8" ,
value: parseEther ( "0.000001" ),
data: "0x" ,
},
{
to: "0x1234567890123456789012345678901234567890" ,
value: parseEther ( "0.000002" ),
data: "0x" ,
},
],
});
waitForUserOperation
Waits for a user operation to be confirmed on-chain.
The user operation hash to wait for.
The network the user operation was sent on.
Optional timeout in milliseconds.
The final status of the user operation.
The transaction hash if the user operation was successful.
const result = await smartAccount . sendUserOperation ({ ... });
const receipt = await smartAccount . waitForUserOperation ({
userOpHash: result . userOpHash ,
network: "base-sepolia" ,
});
console . log ( "Transaction hash:" , receipt . transactionHash );
getUserOperation
Retrieves details of a user operation by its hash.
The user operation details.
const userOp = await smartAccount . getUserOperation ({
userOpHash: "0x..." ,
network: "base-sepolia" ,
});
console . log ( "Calls:" , userOp . calls );
console . log ( "Status:" , userOp . status );
transfer
Transfers native tokens or ERC-20 tokens using a user operation.
options
SmartAccountTransferOptions
required
The network to transfer on.
The ERC-20 token address (omit for native token).
Optional paymaster URL for gas sponsorship.
import { parseEther } from "viem" ;
const result = await smartAccount . transfer ({
network: "base-sepolia" ,
to: "0x4252e0c9A3da5A2700e7d91cb50aEf522D0C6Fe8" ,
amount: parseEther ( "0.001" ),
});
listTokenBalances
Lists token balances for the smart account.
The network to list balances on.
Number of balances per page.
const { balances } = await smartAccount . listTokenBalances ({
network: "base-sepolia" ,
});
requestFaucet
Requests testnet funds from a faucet.
The faucet transaction hash.
const result = await smartAccount . requestFaucet ({
network: "base-sepolia" ,
token: "eth" ,
});
quoteSwap
Gets a quote for swapping tokens via the smart account.
options
SmartAccountQuoteSwapOptions
required
The swap quote with execute method.
import { parseEther } from "viem" ;
const quote = await smartAccount . quoteSwap ({
network: "base" ,
fromToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" ,
toToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" ,
fromAmount: parseEther ( "1" ),
});
swap
Executes a token swap via the smart account.
options
SmartAccountSwapOptions
required
Swap options or quote from quoteSwap.
// Using a quote
const quote = await smartAccount . quoteSwap ({ ... });
const result = await smartAccount . swap ( quote );
// Or execute directly from the quote
const result = await quote . execute ();
signTypedData
Signs EIP-712 typed data with signature wrapping for smart accounts.
const signature = await smartAccount . signTypedData ({
network: "base-sepolia" ,
domain: {
name: "MyDapp" ,
version: "1" ,
chainId: 84532 ,
},
types: {
Message: [
{ name: "content" , type: "string" },
],
},
primaryType: "Message" ,
message: {
content: "Hello, world!" ,
},
});
useSpendPermission
Uses a spend permission to transfer tokens via a user operation.
options
UseSpendPermissionOptions
required
Spend permission usage options.
const result = await smartAccount . useSpendPermission ({
network: "base-sepolia" ,
spendPermission: { ... },
});
useNetwork
Returns a network-scoped smart account.
NetworkScopedEvmSmartAccount
NetworkScopedEvmSmartAccount
A network-scoped smart account.
const baseSmartAccount = await smartAccount . useNetwork ( "base-sepolia" );
const result = await baseSmartAccount . transfer ({
to: "0x..." ,
amount: parseEther ( "0.001" ),
});
Creating a Smart Account
Smart accounts are created through the CdpClient with an owner account:
import { CdpClient } from "@coinbase/cdp-sdk" ;
const cdp = new CdpClient ();
// Create an owner account
const owner = await cdp . evm . createAccount ();
// Create a smart account with the owner
const smartAccount = await cdp . evm . createSmartAccount ({
owner ,
});
Batch Transactions
Smart accounts support batching multiple calls into a single user operation:
import { parseEther } from "viem" ;
const result = await smartAccount . sendUserOperation ({
network: "base-sepolia" ,
calls: [
// Transfer ETH
{
to: "0x4252e0c9A3da5A2700e7d91cb50aEf522D0C6Fe8" ,
value: parseEther ( "0.000001" ),
data: "0x" ,
},
// Call a contract
{
to: "0x1234567890123456789012345678901234567890" ,
value: 0 n ,
data: "0xabcdef..." , // encoded function call
},
],
});
const result = await smartAccount . sendUserOperation ({
network: "base-sepolia" ,
calls: [ ... ],
paymasterUrl: "https://paymaster.example.com" ,
});