This guide covers Ethereum integration with SwapDK, including wallet connections, token transfers, cross-chain swaps, and EVM-specific features.
Ethereum is the leading smart contract blockchain and the foundation of DeFi. SwapDK provides comprehensive Ethereum support through:
Ethereum Toolbox : Core blockchain operations (transfers, contract calls, gas estimation)
EVM Plugin : Enhanced features for decentralized exchanges and cross-chain operations
ERC-20 Support : Full support for Ethereum’s token standard
Multi-Wallet Support : Compatible with MetaMask, WalletConnect, Coinbase Wallet, and hardware wallets
Gas Optimization : EIP-1559 support with dynamic fee estimation
# Individual packages for smaller bundles
bun add @swapdk/toolboxes @swapdk/plugins
import { createSwapKit, Chain } from ' @swapdk/sdk ' ;
const swapDK = createSwapKit ();
const ethWallet = await swapDK . getWallet (Chain . Ethereum );
import { getEthereumToolbox } from ' @swapdk/toolboxes/evm ' ;
const ethToolbox = await getEthereumToolbox ( {
phrase: " your twelve word mnemonic phrase here " ,
derivationPath: [ 44 , 60 , 0 , 0 , 0 ]
const ethToolbox = await getEthereumToolbox ( {
signer: customEthereumSigner ,
Connect to Ethereum using various wallet types:
import { Chain, FeeOption } from " @swapdk/sdk " ;
await swapDK . connectKeystore ([Chain . Ethereum ], " your mnemonic phrase " );
await swapDK . connectBrowserWallet (Chain . Ethereum );
await swapDK . connectWalletConnect ([Chain . Ethereum ]);
await swapDK . connectLedger ([Chain . Ethereum ]);
import { AssetValue } from " @swapdk/sdk " ;
const txHash = await swapDK . transfer ( {
recipient: " 0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7 " ,
assetValue: AssetValue . from ( {
feeOptionKey: FeeOption . Fast ,
console . log ( ` Transaction hash: ${ txHash } ` );
const usdcTransfer = await swapDK . transfer ( {
recipient: " 0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7 " ,
assetValue: AssetValue . from ( {
address: " 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 " ,
feeOptionKey: FeeOption . Average ,
const toolbox = await getEthereumToolbox ( { phrase: " ... " } );
const balance = await toolbox . getBalance (
" 0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7 " ,
" 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 "
const tokenInfo = await toolbox . getTokenInfo (
" 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 "
The Ethereum toolbox provides multiple ways to interact with smart contracts:
const result = await toolbox . call ( {
contractAddress: " 0x... " ,
funcParams: [ " 0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7 " ] ,
const txHash = await toolbox . call ( {
contractAddress: " 0x... " ,
funcParams: [ " 0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7 " , " 1000000 " ] ,
const gasEstimate = await toolbox . estimateCall ( {
contractAddress: " 0x... " ,
funcName: " complexOperation " ,
ERC-20 tokens require approvals before they can be spent by contracts:
const isApproved = await toolbox . isApproved ( {
contractAddress: " 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 " ,
const approveTx = await toolbox . approve ( {
contractAddress: " 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 " ,
console . log ( ` Approval transaction: ${ approveTx } ` );
await toolbox . waitForTransaction (approveTx);
Ethereum supports both legacy and EIP-1559 fee structures:
const txParams = await toolbox . buildTransaction ( {
recipient: " 0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7 " ,
amount: AssetValue . from ( { chain: Chain . Ethereum , value: " 0.1 " } ) ,
feeOptionKey: FeeOption . Fast ,
maxFeePerGas: " 20000000000 " ,
maxPriorityFeePerGas: " 2000000000 " ,
const legacyTx = await toolbox . buildTransaction ( {
recipient: " 0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7 " ,
amount: AssetValue . from ( { chain: Chain . Ethereum , value: " 0.1 " } ) ,
feeOptionKey: FeeOption . Fast ,
const gasInfo = await toolbox . getGasPrices ();
Use Ethereum as source or destination for cross-chain swaps via THORChain:
const ethToBtcQuote = await swapDK . getQuote ( {
senderAddress: swapDK . getAddress (Chain . Ethereum ) ,
recipientAddress: swapDK . getAddress (Chain . Bitcoin ) ,
const swapTx = await swapDK . swap ( {
route: ethToBtcQuote . routes [ 0 ] ,
feeOptionKey: FeeOption . Fast ,
const usdcToRuneQuote = await swapDK . getQuote ( {
sellAsset: " ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 " ,
senderAddress: swapDK . getAddress (Chain . Ethereum ) ,
recipientAddress: swapDK . getAddress (Chain . THORChain ) ,
const swapResult = await swapDK . swap ( {
route: usdcToRuneQuote . routes [ 0 ] ,
feeOptionKey: FeeOption . Average ,
SwapDK supports major Ethereum DEXs through integrated routing:
const uniswapQuote = await swapDK . getQuote ( {
buyAsset: " ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 " ,
senderAddress: swapDK . getAddress (Chain . Ethereum ) ,
recipientAddress: swapDK . getAddress (Chain . Ethereum ) ,
providers: [ " UNISWAPV3 " ] ,
const oneinchQuote = await swapDK . getQuote ( {
sellAsset: " ETH.DAI-0x6B175474E89094C44Da98b954EedeAC495271d0F " ,
buyAsset: " ETH.WBTC-0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599 " ,
senderAddress: swapDK . getAddress (Chain . Ethereum ) ,
recipientAddress: swapDK . getAddress (Chain . Ethereum ) ,
const dexSwap = await swapDK . swap ( {
route: oneinchQuote . routes [ 0 ] ,
feeOptionKey: FeeOption . Fast ,
import { validateEthereumAddress } from " @swapdk/toolboxes/evm " ;
const isValidAddress = validateEthereumAddress (
" 0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7 "
console . log (isValidAddress);
import { getAddress } from " ethers " ;
const checksumAddress = getAddress (
" 0x742c4b4f3e0b5b069f5dcf8a65eaf8d3e888a3e7 "
console . log (checksumAddress);
console . error ( " Invalid address " );
Configure gas fees based on network conditions:
import { FeeOption } from " @swapdk/sdk " ;
[FeeOption . Average ] : 1.0 ,
[FeeOption . Fastest ] : 2.0 ,
const customTx = await swapDK . transfer ( {
recipient: " 0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7 " ,
assetValue: AssetValue . from ( { chain: Chain . Ethereum , value: " 0.1 " } ) ,
maxFeePerGas: " 30000000000 " ,
maxPriorityFeePerGas: " 2000000000 " ,
Handle Ethereum-specific errors appropriately:
import { SwapKitError } from " @swapdk/sdk " ;
if (error instanceof SwapKitError ) {
case " toolbox_evm_insufficient_funds " :
console . error ( " Insufficient ETH for transaction " );
case " toolbox_evm_gas_estimation_failed " :
console . error ( " Could not estimate gas " );
case " toolbox_evm_transaction_failed " :
console . error ( " Transaction failed: " , error . cause );
case " toolbox_evm_invalid_address " :
console . error ( " Invalid Ethereum address " );
case " toolbox_evm_token_not_approved " :
console . error ( " Token approval required " );
console . error ( " Unknown error: " , error);
import { JsonRpcProvider } from ' ethers ' ;
const customProvider = new JsonRpcProvider ( " https://example.com "
const toolbox = await getEthereumToolbox ( {
import { SKConfig } from ' @swapdk/sdk ' ;
SKConfig . setRpcUrl (Chain . Ethereum , [
SKConfig . setRpcUrl (Chain . Ethereum , " https://example.com "
SKConfig . setEnv ( ' isMainnet ' , false );
const testToolbox = await getEthereumToolbox ({ phrase: " ... " });
const txHash = await swapDK . transfer ( {
const receipt = await toolbox . waitForTransaction (txHash);
console . log ( ` Confirmed in block ${ receipt . blockNumber } ` );
const status = await toolbox . getTransactionStatus (txHash);
const txDetails = await toolbox . getTransaction (txHash);
blockNumber: txDetails . blockNumber ,
gasUsed: txDetails . gasUsed ,
status: txDetails . status ,
Always validate addresses before sending transactions:
import { isAddress } from " ethers " ;
if ( ! isAddress (recipient)) {
throw new Error ( " Invalid Ethereum address " );
Check balances before transactions:
const balance = await toolbox . getBalance (senderAddress);
const requiredAmount = AssetValue . from ( {
if (balance . lt (requiredAmount . add (estimatedGas))) {
throw new Error ( " Insufficient balance " );
Use appropriate gas limits for different operations:
contractCall: " 100000-500000 " ,
Handle network congestion :
const gasInfo = await toolbox . getGasPrices ();
if (gasInfo . fast > 50000000000 ) {
console . warn ( " Network is congested, consider waiting " );
Batch operations when possible:
const multicallResults = await toolbox . multicall ([
{ target: " 0x... " , callData: " 0x... " },
{ target: " 0x... " , callData: " 0x... " },
const address = await toolbox . resolveName ( " vitalik.eth " );
const ensName = await toolbox . lookupAddress (
" 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 "
const protectedProvider = new JsonRpcProvider ( " https://example.com "
const privateTx = await toolbox . sendPrivateTransaction ( {
/* transaction parameters */
“Insufficient funds for gas”
Ensure you have enough ETH to cover transaction gas costs
Check gas price isn’t set too high
“Transaction underpriced”
Increase gas price or use EIP-1559 with higher maxFeePerGas
Use FeeOption.Fast or FeeOption.Fastest
“Nonce too low”
Transaction nonce conflicts with pending transaction
Wait for previous transactions to confirm
Token transfer fails
Check token approval status
Verify token contract address is correct
Ensure recipient address can receive tokens
import { SKConfig } from " @swapdk/sdk " ;
SKConfig . setEnv ( " debug " , true );
const txParams = await toolbox . buildTransaction ( {
amount: AssetValue . from ( { chain: Chain . Ethereum , value: " 0.1 " } ) ,
console . log ( " Transaction parameters: " , txParams);
getBalance() - Get ETH or token balance
transfer() - Send ETH or tokens
buildTransaction() - Construct transaction parameters
call() - Execute smart contract functions
estimateCall() - Estimate gas for contract calls
approve() - Approve token spending
isApproved() - Check approval status
getTokenInfo() - Get token metadata
getGasPrices() - Get current gas prices
waitForTransaction() - Wait for confirmation
getTransaction() - Get transaction details
validateAddress() - Validate address format
New to SwapDK? Start with Getting Started to learn the basics.
Building multi-chain apps? Explore Bitcoin and Cosmos integrations.