Skip to main content
Every user needs to create a Smart Account to interact with DeFi protocols seamlessly. DSA accounts allow developers to build extensible use-cases with maximum security and composability.

Overview

DSA accounts are smart contract wallets that:
  • Act as a proxy to interact with verified DeFi protocols
  • Have a unique Ethereum address
  • Are uniquely numbered for easy identification
  • Support multiple authorities (authorized addresses)
  • Can be created multiple times for a single address

Creating a DSA Account

1

Build a New Account

Use the build() method to create a new DSA account:
const txHash = await dsa.build()
console.log('Transaction Hash:', txHash)
This creates a new DSA account with your connected address as the authority.
2

Wait for Confirmation

Wait for the transaction to be confirmed on-chain:
const receipt = await web3.eth.getTransactionReceipt(txHash)
console.log('DSA created successfully')
3

Get Your DSA ID

Retrieve your newly created DSA account:
const accounts = await dsa.getAccounts(yourAddress)
const latestAccount = accounts[accounts.length - 1]
console.log('DSA ID:', latestAccount.id)
console.log('DSA Address:', latestAccount.address)

Build Options

The build() method accepts optional parameters:
await dsa.build({
  authority: '0x...', // Authority address (defaults to from address)
  origin: '0x...', // Origin address for analytics
  version: 2, // DSA version (default: 2)
  from: '0x...', // Account creating the DSA
  gasPrice: '50000000000', // Gas price in wei
  gas: 500000, // Gas limit
  nonce: 10 // Transaction nonce
})

Parameters

ParameterTypeDescription
authorityaddressThe DSA authority. The address to be added as authority (defaults to from address)
originaddressThe address to track the origin of transaction for analytics and affiliates
versionnumberDSA version (1 or 2, default is 2)
fromaddressThe account creating the DSA (helpful to create DSA for other addresses)
gasPricestring/numberGas price in wei (mostly used in Node implementation)
gasstring/numberGas limit for the transaction
noncestring/numberNonce of your sender account (mostly used in Node implementation)

Advanced Build Examples

// Create DSA with a different authority
await dsa.build({
  authority: '0xMultiSigWallet...', // Use a multisig as authority
  origin: '0xYourDapp...', // Track your dapp as origin
})

Fetching DSA Accounts

Get All Accounts

Fetch all DSA accounts owned by an Ethereum address:
const accounts = await dsa.getAccounts('0xUserAddress...')
console.log(accounts)
Response:
[
  {
    id: 52, // DSA ID
    address: '0x...', // DSA Address
    version: 2 // DSA version
  },
  {
    id: 73,
    address: '0x...',
    version: 2
  }
]

Count Accounts

Get the total number of DSA accounts for an address:
const count = await dsa.count('0xUserAddress...')
console.log(`User has ${count} DSA accounts`)

Setting Active Instance

Before casting spells, you must set which DSA account to use:
// Set the active DSA instance
await dsa.setInstance(52) // Use DSA ID 52

// Verify the instance
console.log('Active DSA:', dsa.instance)
// {
//   id: 52,
//   address: '0x...',
//   version: 2,
//   chainId: 1
// }
The configured account will be used for all subsequent spell casts.

Alternative: setAccount

// setAccount is an alias for setInstance
await dsa.setAccount(52)

Getting Account Details

Retrieve detailed information about a specific DSA:
const accountDetails = await dsa.getAccountIdDetails(52)
console.log(accountDetails)
// {
//   id: 52,
//   address: '0x...',
//   version: 2,
//   chainId: 1
// }

Managing Authorities

Get authorities for a specific DSA account:
const authorities = await dsa.getAuthById(52)
console.log('Authorities:', authorities)
Authorities are addresses that have permission to cast spells from the DSA account.

Complete Workflow Example

1

Check Existing Accounts

// Get user's address
const accounts = await web3.eth.getAccounts()
const userAddress = accounts[0]

// Check if user has any DSA accounts
const dsaAccounts = await dsa.getAccounts(userAddress)
console.log(`Found ${dsaAccounts.length} DSA accounts`)
2

Create or Select Account

let dsaId

if (dsaAccounts.length === 0) {
  // No DSA accounts, create one
  console.log('Creating new DSA account...')
  const txHash = await dsa.build()

  // Wait for confirmation
  await waitForTransaction(txHash)

  // Get the new account
  const updatedAccounts = await dsa.getAccounts(userAddress)
  dsaId = updatedAccounts[updatedAccounts.length - 1].id
  console.log('Created DSA ID:', dsaId)
} else {
  // Use existing account
  dsaId = dsaAccounts[0].id
  console.log('Using existing DSA ID:', dsaId)
}
3

Set Active Instance

// Set the DSA instance for subsequent operations
await dsa.setInstance(dsaId)
console.log('Active DSA:', dsa.instance.address)
4

Ready to Cast Spells

// Now you can start casting spells
const spell = dsa.Spell()
// ... add spells and cast

Version Differences

Version 1 (Legacy)

  • Original DSA implementation
  • Available on Ethereum Mainnet and Polygon
  • Fewer features and optimizations

Version 2 (Current)

  • Improved gas efficiency
  • Enhanced security features
  • Proxy pattern implementation
  • Available on all supported chains
  • Recommended for all new accounts
Always use Version 2 for new accounts unless you have a specific reason to use Version 1.

Building Transaction Objects

For advanced use cases, you can build transaction objects without executing them:
const txConfig = await dsa.buildTransactionConfig({
  authority: '0x...',
  origin: '0x...',
  from: '0x...',
  gasPrice: '50000000000',
  gas: 500000
})

console.log('Transaction config:', txConfig)
// Use this with custom transaction logic

Error Handling

try {
  await dsa.setInstance(999)
} catch (error) {
  if (error.message.includes('does not exist')) {
    console.log('DSA ID does not exist')
    // Create a new one
    await dsa.build()
  }
}

Best Practices

Always create new accounts with Version 2 for better gas efficiency and security.
await dsa.build({ version: 2 }) // Default
Always set an origin address to track transaction sources:
dsa.setOrigin('0xYourDappAddress')
await dsa.build()
Check for existing accounts before creating new ones to avoid unnecessary accounts:
const accounts = await dsa.getAccounts(userAddress)
if (accounts.length > 0) {
  await dsa.setInstance(accounts[0].id)
} else {
  await dsa.build()
}
For users with multiple accounts, let them choose which one to use:
const accounts = await dsa.getAccounts(userAddress)
// Display accounts to user and let them select
const selectedId = await userSelectAccount(accounts)
await dsa.setInstance(selectedId)

Next Steps

Casting Spells

Learn how to compose and execute DeFi transactions

Multi-Chain Operations

Use DSA across different blockchain networks

Build docs developers (and LLMs) love