Using Compass API with ZeroDev Smart Accounts

This guide demonstrates how to integrate Compass API SDK with ZeroDev to create and use smart accounts for DeFi operations. The combination enables:

  • Account abstraction features
  • Gas fee abstraction (pay in any token)
  • Simplified DeFi operations
  • Enhanced security through smart account features

Prerequisites

1

Install Dependencies

Install the required packages:

npm install @compass-labs/api-sdk @zerodev/sdk @zerodev/ecdsa-validator viem
2

Set Environment Variables

Create a .env file in your project root:

# .env
ZERODEV_RPC="your_zerodev_rpc_url"
COMPASS_API_KEY="your_compass_api_key"

Implementation Guide

1. Initial Setup

First, import the necessary dependencies and set up environment variables:

import { Call, createPublicClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { arbitrum } from 'viem/chains';
import { signerToEcdsaValidator } from '@zerodev/ecdsa-validator';
import {
	createKernelAccount,
	createKernelAccountClient,
	createZeroDevPaymasterClient,
} from '@zerodev/sdk';
import { getEntryPoint, KERNEL_V3_1 } from '@zerodev/sdk/constants';
import { CompassApiSDK } from '@compass-labs/api-sdk';

import dotenv from 'dotenv';
dotenv.config();


const ZERODEV_RPC = process.env.ZERODEV_RPC;
const PRIVATE_KEY = process.env.PRIVATE_KEY as `0x${string}`;
const COMPASS_API_KEY = process.env.COMPASS_API_KEY;

// Initialize constants
const chain = arbitrum 
const entryPoint = getEntryPoint("0.7")
const kernelVersion = KERNEL_V3_1

2. Create Signer and Public Client

Set up the signer for account management and initialize the public client:

// Create a signer
const signer = privateKeyToAccount(PRIVATE_KEY);

// Create public client
const publicClient = createPublicClient({
  transport: http(ZERODEV_RPC),
  chain
})

3. Set up ECDSA Validator

Create the ECDSA validator for account authentication:

// Create validator
const ecdsaValidator = await signerToEcdsaValidator(publicClient, {
  signer,
  entryPoint,
  kernelVersion
})

4. Create Kernel Account

Initialize the Kernel account with the validator:

// Create Kernel account
const account = await createKernelAccount(publicClient, {
  plugins: {
    sudo: ecdsaValidator,
  },
  entryPoint,
  kernelVersion
})

5. Configure Paymaster

Set up the paymaster for gas abstraction:

const zerodevPaymaster = createZeroDevPaymasterClient({
  chain,
  transport: http(ZERODEV_RPC),
})

// Create Kernel account client
const kernelClient = createKernelAccountClient({
  account,
  chain,
  bundlerTransport: http(ZERODEV_RPC),
  client: publicClient,
  paymaster: {
    getPaymasterData(userOperation) {
      return zerodevPaymaster.sponsorUserOperation({userOperation})
    }
  },
})

6. Initialize Compass API SDK

Set up the Compass API SDK for DeFi operations:

import { CompassApiSDK } from "@compass-labs/api-sdk"

// Initialize Compass API SDK
const compassApiSDK = new CompassApiSDK({
  apiKeyAuth: COMPASS_API_KEY,
})

7. Call Compass API

Now you can perform various DeFi operations. Here’s an example of supplying tokens to Aave:

// Example: Supply tokens to Aave
const result = await compassApiSDK.smartAccount.accountBatchedUserOperations({
  chain: "arbitrum:mainnet",
  actions: [
    // Step 1: Increase allowance
    {
        body: {
            actionType: 'ALLOWANCE_INCREASE',
            token: 'USDC',
            contractName: 'AaveV3Pool',
            amount: '10',
        }
    },
    // Step 2: Supply to Aave
    {
        body: {
            actionType: 'AAVE_SUPPLY',
            token: 'USDC',
            amount: '10',
        },
    },
  ],
})

8. Process and Execute Operations

Handle the operations and wait for confirmation:

// Convert operations to the correct format
const operations = result.operations.map((op) => ({
    to: op.to as `0x${string}`,
    data: op.data as `0x${string}`,
    value: op.value ? BigInt(op.value) : undefined,
})) as Call[];

// Send the user operation
const userOpHash = await kernelClient.sendUserOperation({
  callData: await kernelClient.account.encodeCalls(operations),
})

// Wait for the operation to complete
await kernelClient.waitForUserOperationReceipt({
  hash: userOpHash,
  timeout: 1000 * 15,
})

Common Operation Examples

Here are some examples of different DeFi operations you can perform:

Token Swaps

{
  body: {
    actionType: "UNISWAP_BUY_EXACTLY",
    tokenIn: "WETH",
    tokenOut: "USDC",
    fee: "0.01",
    amountOut: 1.5,
    amountInMaximum: 1.6,
    wrapEth: true,
  }
}

Lending Operations

{
  body: {
    actionType: "AAVE_SUPPLY",
    amount: 1000,
    asset: "USDC",
  }
}

Token Approvals

{
  body: {
    actionType: "ALLOWANCE_INCREASE",
    amount: 1000,
    token: "WETH",
    contract_name: "UniswapV3Router",
  }
}

Resources