Arbitrum Integration
This guide covers Arbitrum One integration with SwapKit, including wallet connections, token transfers, cross-chain swaps, and Layer 2 specific optimizations.
Overview
Section titled “Overview”Arbitrum One is a leading Ethereum Layer 2 scaling solution that provides faster and cheaper transactions while maintaining Ethereum security. SwapKit provides full Arbitrum support through:
- Arbitrum Toolbox: Optimized Layer 2 operations with lower gas costs
 - Cross-Chain Bridging: Seamless transfers between Ethereum and Arbitrum
 - DEX Integration: Access to Arbitrum DEXs like Camelot, TraderJoe, and SushiSwap
 - Multi-Wallet Support: Compatible with all Ethereum wallets
 - Gas Optimization: Layer 2 gas estimation and fee management
 
Getting Started
Section titled “Getting Started”Installation
Section titled “Installation”# Full SDK (recommended)bun add @swapkit/sdk
# Individual packages for smaller bundlesbun add @swapkit/toolboxes @swapkit/pluginsBasic Setup
Section titled “Basic Setup”// @noErrorValidationimport { createSwapKit, Chain } from '@swapkit/sdk';
const swapKit = createSwapKit();
const arbWallet = await swapKit.getWallet(Chain.Arbitrum);// @noErrorValidationimport { getArbitrumToolbox } from '@swapkit/toolboxes/evm';
const arbToolbox = await getArbitrumToolbox({  phrase: "your twelve word mnemonic phrase here",
  derivationPath: [44, 60, 0, 0, 0]});
const arbToolbox = await getArbitrumToolbox({  signer: customArbitrumSigner,  provider: customArbitrumProvider});Arbitrum Toolbox
Section titled “Arbitrum Toolbox”Wallet Connection
Section titled “Wallet Connection”Connect to Arbitrum using Ethereum-compatible wallets:
// @noErrorValidationimport { Chain, FeeOption } from "@swapkit/sdk";
await swapKit.connectKeystore([Chain.Arbitrum], "your mnemonic phrase");
await swapKit.connectBrowserWallet(Chain.Arbitrum);
await swapKit.connectWalletConnect([Chain.Arbitrum]);
await swapKit.connectLedger([Chain.Arbitrum]);Native ETH Transfers
Section titled “Native ETH Transfers”ETH on Arbitrum is the same as Ethereum ETH, just on Layer 2:
// @noErrorValidationimport { AssetValue } from "@swapkit/sdk";
const txHash = await swapKit.transfer({  recipient: "0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7",  assetValue: AssetValue.from({    chain: Chain.Arbitrum,    value: "0.1",  }),  feeOptionKey: FeeOption.Fast,});
console.log(`Transaction hash: ${txHash}`);ERC-20 Token Transfers
Section titled “ERC-20 Token Transfers”Arbitrum supports the same ERC-20 standard with much lower gas costs:
// @noErrorValidation
const usdcTransfer = await swapKit.transfer({  recipient: "0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7",  assetValue: AssetValue.from({    chain: Chain.Arbitrum,    symbol: "USDC",    address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",    value: "100",  }),  feeOptionKey: FeeOption.Average,});
const toolbox = await getArbitrumToolbox({ phrase: "..." });
const transfers = [  {    to: "0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7",    token: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",    amount: "100000000",  },  {    to: "0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7",    token: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",    amount: "100000000000000000",  },];
for (const transfer of transfers) {  const txHash = await toolbox.transfer({    recipient: transfer.to,    assetValue: AssetValue.from({      chain: Chain.Arbitrum,      address: transfer.token,      value: transfer.amount,    }),  });  console.log(`Transfer ${transfer.token}: ${txHash}`);}Smart Contract Interactions
Section titled “Smart Contract Interactions”Arbitrum contracts work exactly like Ethereum but with lower costs:
// @noErrorValidation
const result = await toolbox.call({  contractAddress: "0x...",  abi: contractABI,  funcName: "balanceOf",  funcParams: ["0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7"],});
const txHash = await toolbox.call({  contractAddress: "0x912CE59144191C1204E64559FE8253a0e49E6548",  abi: erc20ABI,  funcName: "transfer",  funcParams: [    "0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7",    "1000000000000000000",  ],  txOverrides: {    gasLimit: "65000",    value: "0",  },});
const complexDefiTx = await toolbox.call({  contractAddress: "0x...",  abi: protocolABI,  funcName: "multiStepOperation",  funcParams: [    /* complex parameters */  ],  txOverrides: {    gasLimit: "500000",  },});Gas Management on Layer 2
Section titled “Gas Management on Layer 2”Arbitrum has unique gas characteristics compared to Ethereum:
// @noErrorValidation
const gasInfo = await toolbox.getGasPrices();console.log({  slow: gasInfo.average,  standard: gasInfo.fast,  fast: gasInfo.fastest,});
const txParams = await toolbox.buildTransaction({  recipient: "0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7",  amount: AssetValue.from({ chain: Chain.Arbitrum, value: "0.1" }),  feeOptionKey: FeeOption.Fast,  gasLimit: "100000",});
const eip1559Tx = await toolbox.buildTransaction({  recipient: "0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7",  amount: AssetValue.from({ chain: Chain.Arbitrum, value: "0.1" }),  maxFeePerGas: "2000000000",  maxPriorityFeePerGas: "100000000",});Cross-Chain Operations
Section titled “Cross-Chain Operations”Bridging ETH and Tokens
Section titled “Bridging ETH and Tokens”// @noErrorValidation
const bridgeQuote = await swapKit.getQuote({  sellAsset: "ETH.ETH",  sellAmount: "0.1",  buyAsset: "ARB.ETH",  senderAddress: swapKit.getAddress(Chain.Ethereum),  recipientAddress: swapKit.getAddress(Chain.Arbitrum),});
const bridgeTx = await swapKit.swap({  route: bridgeQuote.routes[0],  feeOptionKey: FeeOption.Fast,});
const usdcBridge = await swapKit.getQuote({  sellAsset: "ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",  sellAmount: "1000",  buyAsset: "ARB.USDC-0xaf88d065e77c8cC2239327C5EDb3A432268e5831",  senderAddress: swapKit.getAddress(Chain.Ethereum),  recipientAddress: swapKit.getAddress(Chain.Arbitrum),});Cross-Chain Swaps via THORChain
Section titled “Cross-Chain Swaps via THORChain”// @noErrorValidation
const arbToBtcQuote = await swapKit.getQuote({  sellAsset: "ARB.ARB-0x912CE59144191C1204E64559FE8253a0e49E6548",  sellAmount: "100",  buyAsset: "BTC.BTC",  senderAddress: swapKit.getAddress(Chain.Arbitrum),  recipientAddress: swapKit.getAddress(Chain.Bitcoin),});
const crossChainSwap = await swapKit.swap({  route: arbToBtcQuote.routes[0],  feeOptionKey: FeeOption.Fast,});
const multiHopQuote = await swapKit.getQuote({  sellAsset: "ARB.USDC-0xaf88d065e77c8cC2239327C5EDb3A432268e5831",  sellAmount: "500",  buyAsset: "THOR.RUNE",  senderAddress: swapKit.getAddress(Chain.Arbitrum),  recipientAddress: swapKit.getAddress(Chain.THORChain),});Arbitrum DEX Integration
Section titled “Arbitrum DEX Integration”Access native Arbitrum DEXs for optimal pricing:
// @noErrorValidation
const camelotQuote = await swapKit.getQuote({  sellAsset: "ARB.ETH",  sellAmount: "0.1",  buyAsset: "ARB.USDC-0xaf88d065e77c8cC2239327C5EDb3A432268e5831",  senderAddress: swapKit.getAddress(Chain.Arbitrum),  recipientAddress: swapKit.getAddress(Chain.Arbitrum),  providers: ["CAMELOT"],});
const traderjoeQuote = await swapKit.getQuote({  sellAsset: "ARB.USDC-0xaf88d065e77c8cC2239327C5EDb3A432268e5831",  sellAmount: "100",  buyAsset: "ARB.ARB-0x912CE59144191C1204E64559FE8253a0e49E6548",  senderAddress: swapKit.getAddress(Chain.Arbitrum),  recipientAddress: swapKit.getAddress(Chain.Arbitrum),  providers: ["TRADERJOE_V2"],});
const bestRateQuote = await swapKit.getQuote({  sellAsset: "ARB.WETH-0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",  sellAmount: "1",  buyAsset: "ARB.GMX-0xfc5A1A6EB076a2C7aD06eD22C90d7E710E35ad0a",  senderAddress: swapKit.getAddress(Chain.Arbitrum),  recipientAddress: swapKit.getAddress(Chain.Arbitrum),  providers: ["CAMELOT", "TRADERJOE_V2", "SUSHISWAP"],});Arbitrum-Specific Features
Section titled “Arbitrum-Specific Features”ARB Token Operations
Section titled “ARB Token Operations”// @noErrorValidation
const arbBalance = await toolbox.getBalance(  swapKit.getAddress(Chain.Arbitrum),  "0x912CE59144191C1204E64559FE8253a0e49E6548");
const stakeArb = await toolbox.call({  contractAddress: "0x...",  abi: stakingABI,  funcName: "stake",  funcParams: ["1000000000000000000"],});
const governanceVote = await toolbox.call({  contractAddress: "0x...",  abi: governanceABI,  funcName: "vote",  funcParams: [proposalId, true],});Layer 2 Optimizations
Section titled “Layer 2 Optimizations”// @noErrorValidation
const batchOperations = async () => {  const nonce = await toolbox.getTransactionCount(    swapKit.getAddress(Chain.Arbitrum)  );
  const tx1 = await toolbox.buildTransaction({    recipient: "0x...",    amount: AssetValue.from({ chain: Chain.Arbitrum, value: "0.1" }),    nonce: nonce,  });
  const tx2 = await toolbox.buildTransaction({    recipient: "0x...",    amount: AssetValue.from({ chain: Chain.Arbitrum, value: "0.1" }),    nonce: nonce + 1,  });
  const [hash1, hash2] = await Promise.all([    toolbox.sendTransaction(tx1),    toolbox.sendTransaction(tx2),  ]);
  return [hash1, hash2];};Network Configuration
Section titled “Network Configuration”Custom RPC Setup
Section titled “Custom RPC Setup”// @noErrorValidationimport { SKConfig } from '@swapkit/sdk';
SKConfig.setRpcUrl(Chain.Arbitrum, [  "https:  "https:  "https:]);
import { JsonRpcProvider } from 'ethers';
const arbitrumProvider = new JsonRpcProvider("https:const toolbox = await getArbitrumToolbox({  phrase: "your mnemonic",  provider: arbitrumProvider});Working with Arbitrum Goerli Testnet
Section titled “Working with Arbitrum Goerli Testnet”// @noErrorValidation
SKConfig.setRpcUrl(Chain.Arbitrum, "https:SKConfig.setEnv('isMainnet', false);
const testnetTokens = {  USDC: "0x8FB1E3fC51F3b789dED7557E680551d93Ea9d892",  WETH: "0xe39Ab88f8A4777030A534146A9Ca3B52bd5D43A3"};Error Handling
Section titled “Error Handling”Handle Arbitrum-specific errors:
// @noErrorValidationimport { 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 gas on Arbitrum");        break;      case "toolbox_evm_gas_estimation_failed":        console.error("Gas estimation failed - may be network congestion");        break;      case "network_arbitrum_sequencer_down":        console.error("Arbitrum sequencer is down, try again later");        break;      case "bridge_deposit_not_confirmed":        console.error("Bridge deposit not yet confirmed on L1");        break;      default:        console.error("Unknown error:", error);    }  }}Performance Optimization
Section titled “Performance Optimization”Gas Optimization
Section titled “Gas Optimization”// @noErrorValidation
const optimizedTx = await toolbox.buildTransaction({  recipient: "0x742c4B4F3e0b5b069F5DCF8A65Eaf8d3E888a3E7",  amount: AssetValue.from({ chain: Chain.Arbitrum, value: "0.1" }),  gasLimit: "21000",  maxFeePerGas: "1000000000",});
const multicallData = [  { target: usdcAddress, callData: balanceOfCallData },  { target: arbAddress, callData: balanceOfCallData },  { target: wethAddress, callData: balanceOfCallData },];
const results = await toolbox.multicall(multicallData);Transaction Bundling
Section titled “Transaction Bundling”// @noErrorValidation
const bundledOperations = async () => {  const approveTx = await toolbox.approve({    contractAddress: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",    spenderAddress: "0x...",    amount: "1000000000",  });
  await toolbox.waitForTransaction(approveTx);
  const swapTx = await toolbox.call({    contractAddress: "0x...",    abi: routerABI,    funcName: "swapTokensForTokens",    funcParams: [      /* swap params */    ],  });
  return { approveTx, swapTx };};Best Practices
Section titled “Best Practices”- 
Leverage Lower Gas Costs:
const complexTx = await toolbox.call({contractAddress: "0x...",abi: complexABI,funcName: "multiStepOperation",funcParams: [/* many parameters */],gasLimit: "1000000",}); - 
Use Native Arbitrum Tokens:
const arbitrumTokens = {USDC: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",USDT: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",ARB: "0x912CE59144191C1204E64559FE8253a0e49E6548",}; - 
Monitor Bridge Status:
const bridgeStatus = await toolbox.getBridgeStatus(l1TxHash);if (bridgeStatus.status === "confirmed") {} - 
Optimize for Fast Settlement:
const fastTx = await swapKit.transfer({recipient: "0x...",assetValue: AssetValue.from({ chain: Chain.Arbitrum, value: "0.1" }),feeOptionKey: FeeOption.Fastest,});const receipt = await toolbox.waitForTransaction(fastTx); 
Popular Arbitrum Protocols
Section titled “Popular Arbitrum Protocols”GMX Integration
Section titled “GMX Integration”// @noErrorValidation
const gmxTrade = await toolbox.call({  contractAddress: "0x489ee077994B6658eAfA855C308275EAd8097C4A",  abi: gmxABI,  funcName: "createIncreasePosition",  funcParams: [    "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",    "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",    "1000000000000000000",    0,    "2000000000000000000000",    true,    "1800000000000000000000",  ],});Radiant Capital Integration
Section titled “Radiant Capital Integration”// @noErrorValidation
const radiantSupply = await toolbox.call({  contractAddress: "0x2032b9A8e9F7e76768CA9271003d3e43E1616B1F",  abi: aaveV3ABI,  funcName: "supply",  funcParams: [    "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",    "1000000000",    swapKit.getAddress(Chain.Arbitrum),    0,  ],});Troubleshooting
Section titled “Troubleshooting”Common Issues
Section titled “Common Issues”- 
“Transaction underpriced” - Even on L2:
const txParams = await toolbox.buildTransaction({recipient: "0x...",amount: AssetValue.from({ chain: Chain.Arbitrum, value: "0.1" }),maxFeePerGas: "2000000000",}); - 
Bridge delays:
const checkBridgeStatus = async (l1TxHash: string) => {const status = await toolbox.getBridgeDeposit(l1TxHash);console.log(`Bridge status: ${status.status}`);return status.status === "EXECUTED";}; - 
RPC rate limiting:
const providers = ["https:"https:"https:];SKConfig.setRpcUrl(Chain.Arbitrum, providers); 
API Reference Summary
Section titled “API Reference Summary”Core Methods (Same as Ethereum)
Section titled “Core Methods (Same as Ethereum)”getBalance()- Get ETH or token balancetransfer()- Send ETH or tokensbuildTransaction()- Construct transaction parameterscall()- Execute smart contract functionsestimateCall()- Estimate gas for contract calls
Layer 2 Specific Methods
Section titled “Layer 2 Specific Methods”getBridgeStatus()- Check bridge deposit statusgetBridgeDeposit()- Get bridge transaction detailsestimateL1GasCost()- Estimate L1 data cost portion
Gas Management
Section titled “Gas Management”getGasPrices()- Get current L2 gas pricesestimateGas()- Estimate gas with L2 optimizations
Next Steps
Section titled “Next Steps”- Learn about other Layer 2 solutions like Optimism and Polygon
 - Explore Cross-Chain Swaps using Arbitrum
 - Check out Ethereum Integration for Layer 1 operations
 - Read about Production Best Practices