Skip to content
SwapKit is a powerful suite of tools for building blockchain applications.

Ethereum Integration

This guide covers Ethereum integration with SwapKit, including wallet connections, token transfers, cross-chain swaps, and EVM-specific features.

Ethereum is the leading smart contract blockchain and the foundation of DeFi. SwapKit 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
Terminal window
# Full SDK (recommended)
bun add @swapkit/sdk
# Individual packages for smaller bundles
bun add @swapkit/toolboxes @swapkit/plugins
// @noErrorValidation
import { createSwapKit, Chain } from '@swapkit/sdk';
const swapKit = createSwapKit();
const ethWallet = await swapKit.getWallet(Chain.Ethereum);

Connect to Ethereum using various wallet types:

// @noErrorValidation
import { Chain, FeeOption } from "@swapkit/sdk";
await swapKit.connectKeystore([Chain.Ethereum], "your mnemonic phrase");
await swapKit.connectBrowserWallet(Chain.Ethereum);
await swapKit.connectWalletConnect([Chain.Ethereum]);
await swapKit.connectLedger([Chain.Ethereum]);
// @noErrorValidation
import { AssetValue } from "@swapkit/sdk";
const txHash = await swapKit.transfer({
recipient: "0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7",
assetValue: AssetValue.from({
chain: Chain.Ethereum,
value: "0.1",
}),
feeOptionKey: FeeOption.Fast,
});
console.log(`Transaction hash: ${txHash}`);
// @noErrorValidation
const usdcTransfer = await swapKit.transfer({
recipient: "0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7",
assetValue: AssetValue.from({
chain: Chain.Ethereum,
symbol: "USDC",
address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
value: "100",
}),
feeOptionKey: FeeOption.Average,
});
const toolbox = await getEthereumToolbox({ phrase: "..." });
const balance = await toolbox.getBalance(
"0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7",
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
);
const tokenInfo = await toolbox.getTokenInfo(
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
);
console.log(tokenInfo);

The Ethereum toolbox provides multiple ways to interact with smart contracts:

// @noErrorValidation
const result = await toolbox.call({
contractAddress: "0x...",
abi: contractABI,
funcName: "balanceOf",
funcParams: ["0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7"],
});
const txHash = await toolbox.call({
contractAddress: "0x...",
abi: contractABI,
funcName: "transfer",
funcParams: ["0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7", "1000000"],
txOverrides: {
gasLimit: "100000",
value: "0",
},
});
const gasEstimate = await toolbox.estimateCall({
contractAddress: "0x...",
abi: contractABI,
funcName: "complexOperation",
funcParams: [
/* ... */
],
});

ERC-20 tokens require approvals before they can be spent by contracts:

// @noErrorValidation
const isApproved = await toolbox.isApproved({
contractAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
spenderAddress: "0x...",
amount: "1000000000",
});
if (!isApproved) {
const approveTx = await toolbox.approve({
contractAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
spenderAddress: "0x...",
amount: "1000000000",
});
console.log(`Approval transaction: ${approveTx}`);
await toolbox.waitForTransaction(approveTx);
}

Ethereum supports both legacy and EIP-1559 fee structures:

// @noErrorValidation
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,
gasPrice: "20000000000",
});
const gasInfo = await toolbox.getGasPrices();
console.log({
slow: gasInfo.average,
standard: gasInfo.fast,
fast: gasInfo.fastest,
});

Use Ethereum as source or destination for cross-chain swaps via THORChain:

// @noErrorValidation
const ethToBtcQuote = await swapKit.getQuote({
sellAsset: "ETH.ETH",
sellAmount: "1",
buyAsset: "BTC.BTC",
senderAddress: swapKit.getAddress(Chain.Ethereum),
recipientAddress: swapKit.getAddress(Chain.Bitcoin),
});
const swapTx = await swapKit.swap({
route: ethToBtcQuote.routes[0],
feeOptionKey: FeeOption.Fast,
});
const usdcToRuneQuote = await swapKit.getQuote({
sellAsset: "ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
sellAmount: "1000",
buyAsset: "THOR.RUNE",
senderAddress: swapKit.getAddress(Chain.Ethereum),
recipientAddress: swapKit.getAddress(Chain.THORChain),
});
const swapResult = await swapKit.swap({
route: usdcToRuneQuote.routes[0],
feeOptionKey: FeeOption.Average,
});

SwapKit supports major Ethereum DEXs through integrated routing:

// @noErrorValidation
const uniswapQuote = await swapKit.getQuote({
sellAsset: "ETH.ETH",
sellAmount: "1",
buyAsset: "ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
senderAddress: swapKit.getAddress(Chain.Ethereum),
recipientAddress: swapKit.getAddress(Chain.Ethereum),
providers: ["UNISWAPV3"],
});
const oneinchQuote = await swapKit.getQuote({
sellAsset: "ETH.DAI-0x6B175474E89094C44Da98b954EedeAC495271d0F",
sellAmount: "1000",
buyAsset: "ETH.WBTC-0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
senderAddress: swapKit.getAddress(Chain.Ethereum),
recipientAddress: swapKit.getAddress(Chain.Ethereum),
providers: ["ONEINCH"],
});
const dexSwap = await swapKit.swap({
route: oneinchQuote.routes[0],
feeOptionKey: FeeOption.Fast,
});
// @noErrorValidation
import { validateEthereumAddress } from "@swapkit/toolboxes/evm";
const isValidAddress = validateEthereumAddress(
"0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7"
);
console.log(isValidAddress);
import { getAddress } from "ethers";
try {
const checksumAddress = getAddress(
"0x742c4b4f3e0b5b069f5dcf8a65eaf8d3e888a3e7"
);
console.log(checksumAddress);
} catch (error) {
console.error("Invalid address");
}

Configure gas fees based on network conditions:

// @noErrorValidation
import { FeeOption } from "@swapkit/sdk";
const feeOptions = {
[FeeOption.Average]: 1.0,
[FeeOption.Fast]: 1.5,
[FeeOption.Fastest]: 2.0,
};
const customTx = await swapKit.transfer({
recipient: "0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7",
assetValue: AssetValue.from({ chain: Chain.Ethereum, value: "0.1" }),
gasLimit: "21000",
maxFeePerGas: "30000000000",
maxPriorityFeePerGas: "2000000000",
});

Handle Ethereum-specific errors appropriately:

// @noErrorValidation
import { SwapKitError } from "@swapkit/sdk";
try {
await swapKit.transfer({
/* ... */
});
} catch (error) {
if (error instanceof SwapKitError) {
switch (error.code) {
case "toolbox_evm_insufficient_funds":
console.error("Insufficient ETH for transaction");
break;
case "toolbox_evm_gas_estimation_failed":
console.error("Could not estimate gas");
break;
case "toolbox_evm_transaction_failed":
console.error("Transaction failed:", error.cause);
break;
case "toolbox_evm_invalid_address":
console.error("Invalid Ethereum address");
break;
case "toolbox_evm_token_not_approved":
console.error("Token approval required");
break;
default:
console.error("Unknown error:", error);
}
}
}
// @noErrorValidation
import { JsonRpcProvider } from 'ethers';
const customProvider = new JsonRpcProvider("https:
const toolbox = await getEthereumToolbox({
phrase: "your mnemonic",
provider: customProvider
});
import { SKConfig } from '@swapkit/sdk';
SKConfig.setRpcUrl(Chain.Ethereum, [
"https:
"https:
"https:
]);
// @noErrorValidation
SKConfig.setRpcUrl(Chain.Ethereum, "https:
SKConfig.setEnv('isMainnet', false);
const testToolbox = await getEthereumToolbox({ phrase: "..." });
// @noErrorValidation
const txHash = await swapKit.transfer({
/* ... */
});
const receipt = await toolbox.waitForTransaction(txHash);
console.log(`Confirmed in block ${receipt.blockNumber}`);
const status = await toolbox.getTransactionStatus(txHash);
console.log(status);
const txDetails = await toolbox.getTransaction(txHash);
console.log({
blockNumber: txDetails.blockNumber,
gasUsed: txDetails.gasUsed,
status: txDetails.status,
});
  1. Always validate addresses before sending transactions:

    import { isAddress } from "ethers";
    if (!isAddress(recipient)) {
    throw new Error("Invalid Ethereum address");
    }
  2. Check balances before transactions:

    const balance = await toolbox.getBalance(senderAddress);
    const requiredAmount = AssetValue.from({
    chain: Chain.Ethereum,
    value: "0.1",
    });
    if (balance.lt(requiredAmount.add(estimatedGas))) {
    throw new Error("Insufficient balance");
    }
  3. Use appropriate gas limits for different operations:

    const gasLimits = {
    ethTransfer: "21000",
    erc20Transfer: "65000",
    contractCall: "100000-500000",
    complexDeFi: "500000+",
    };
  4. Handle network congestion:

    const gasInfo = await toolbox.getGasPrices();
    if (gasInfo.fast > 50000000000) {
    console.warn("Network is congested, consider waiting");
    }
  5. Batch operations when possible:

    const multicallResults = await toolbox.multicall([
    { target: "0x...", callData: "0x..." },
    { target: "0x...", callData: "0x..." },
    ]);
// @noErrorValidation
const address = await toolbox.resolveName("vitalik.eth");
console.log(address);
const ensName = await toolbox.lookupAddress(
"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
);
console.log(ensName);
// @noErrorValidation
const protectedProvider = new JsonRpcProvider("https:
const privateTx = await toolbox.sendPrivateTransaction({
/* transaction parameters */
});
  1. “Insufficient funds for gas”

    • Ensure you have enough ETH to cover transaction gas costs
    • Check gas price isn’t set too high
  2. “Transaction underpriced”

    • Increase gas price or use EIP-1559 with higher maxFeePerGas
    • Use FeeOption.Fast or FeeOption.Fastest
  3. “Nonce too low”

    • Transaction nonce conflicts with pending transaction
    • Wait for previous transactions to confirm
  4. Token transfer fails

    • Check token approval status
    • Verify token contract address is correct
    • Ensure recipient address can receive tokens
// @noErrorValidation
import { SKConfig } from "@swapkit/sdk";
SKConfig.setEnv("debug", true);
const txParams = await toolbox.buildTransaction({
recipient: "0x...",
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

🌐 Other EVM Chains

Leverage the same patterns on other EVM-compatible networks. - Arbitrum - Layer 2 scaling with lower fees - Polygon - Faster transactions and DeFi ecosystem - Avalanche - High-throughput smart contracts - BNB Smart Chain - BSC DeFi ecosystem

💳 Wallet Integration

Connect Ethereum wallets across different types and providers. - MetaMask - Most popular browser wallet - WalletConnect - Mobile wallet connections - Hardware Wallets - Secure hardware signing

New to SwapKit? Start with Getting Started to learn the basics.

Building multi-chain apps? Explore Bitcoin and Cosmos integrations.

Need help? Join our [Discord community](https: