pnpm dlx shadcn@latest add "https://build.abs.xyz/r/abstract-contracts.json"
Access contract addresses directly.
import { ABSTRACT_CONTRACTS } from "@/config/abstract-contracts"
const wethMainnet = ABSTRACT_CONTRACTS.tokens.weth.addresses.mainnet
// "0x3439153EB7AF838Ad19d56E1571FBD09333C2809"
const usdcTestnet = ABSTRACT_CONTRACTS.tokens.usdc.addresses.testnet
// "0xe4C7fBB0a626ed208021ccabA6Be1566905E2dFc"
Get contract addresses for mainnet or testnet specifically.
import { ABSTRACT_CONTRACTS } from "@/config/abstract-contracts";
import { getContract, getContractAddress } from "@/lib/chain-utils";
import { abstract, abstractTestnet } from "viem/chains";
// Get contract for specific chain
const wethMainnet = getContract("weth", abstract.id);
const wethTestnet = getContract("weth", abstractTestnet.id);
// Get just address for specific chain
const usdcMainnetAddress = getContractAddress(
ABSTRACT_CONTRACTS.tokens.usdc.addresses,
abstract.id
);
Get contract addresses for the currently active chain (mainnet or testnet).
// Automatically uses mainnet or testnet based on config
import { getContractWithCurrentChain, getContractAddressWithCurrentChain } from "@/lib/chain-utils"
const wethContract = getContractWithCurrentChain("weth") // Returns an object with metadata
console.log(wethContract.address) // Just the contract address
// Get just the contract address for the current chain
const usdcAddress = getContractAddressWithCurrentChain("usdc")
Some helpful utility functions for working with Abstract networks.
import { isAbstractNetwork, getNetworkName } from "@/lib/chain-utils"
// Check if chain ID is supported
if (isAbstractNetwork(chainId)) {
const networkName = getNetworkName(chainId)
console.log(`Connected to ${networkName}`)
}
This command installs the following files:
/config
abstract-contracts.ts
- Contract addresses, ABIs, and configuration/lib
chain-utils.ts
- Network-aware utility functions for address resolution/types
contracts.ts
- Contract addresses, ABIs, and configurationabstract-contracts.ts
Contract configuration containing addresses for both Abstract mainnet and testnet, along with complete ABIs for tokens (WETH, USDC, USDT) and Uniswap V2/V3 infrastructure.
import type { ContractsConfig } from "@/types/contracts";
const WETH9_ABI = [
{
anonymous: false,
inputs: [
{ indexed: true, internalType: "address", name: "src", type: "address" },
{ indexed: true, internalType: "address", name: "guy", type: "address" },
{ indexed: false, internalType: "uint256", name: "wad", type: "uint256" },
],
name: "Approval",
type: "event",
},
{
anonymous: false,
inputs: [
{ indexed: true, internalType: "address", name: "dst", type: "address" },
{ indexed: false, internalType: "uint256", name: "wad", type: "uint256" },
],
name: "Deposit",
type: "event",
},
{
anonymous: false,
inputs: [
{ indexed: true, internalType: "address", name: "src", type: "address" },
{ indexed: true, internalType: "address", name: "dst", type: "address" },
{ indexed: false, internalType: "uint256", name: "wad", type: "uint256" },
],
name: "Transfer",
type: "event",
},
{
anonymous: false,
inputs: [
{ indexed: true, internalType: "address", name: "src", type: "address" },
{ indexed: false, internalType: "uint256", name: "wad", type: "uint256" },
],
name: "Withdrawal",
type: "event",
},
{
inputs: [
{ internalType: "address", name: "", type: "address" },
{ internalType: "address", name: "", type: "address" },
],
name: "allowance",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "guy", type: "address" },
{ internalType: "uint256", name: "wad", type: "uint256" },
],
name: "approve",
outputs: [{ internalType: "bool", name: "", type: "bool" }],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [{ internalType: "address", name: "", type: "address" }],
name: "balanceOf",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "decimals",
outputs: [{ internalType: "uint8", name: "", type: "uint8" }],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "deposit",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [],
name: "name",
outputs: [{ internalType: "string", name: "", type: "string" }],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "symbol",
outputs: [{ internalType: "string", name: "", type: "string" }],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "totalSupply",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "dst", type: "address" },
{ internalType: "uint256", name: "wad", type: "uint256" },
],
name: "transfer",
outputs: [{ internalType: "bool", name: "", type: "bool" }],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "src", type: "address" },
{ internalType: "address", name: "dst", type: "address" },
{ internalType: "uint256", name: "wad", type: "uint256" },
],
name: "transferFrom",
outputs: [{ internalType: "bool", name: "", type: "bool" }],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [{ internalType: "uint256", name: "wad", type: "uint256" }],
name: "withdraw",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{ stateMutability: "payable", type: "receive" },
] as const;
const USDC_ABI = [
{
inputs: [
{
internalType: "address",
name: "implementationContract",
type: "address",
},
],
stateMutability: "nonpayable",
type: "constructor",
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: "address",
name: "previousAdmin",
type: "address",
},
{
indexed: false,
internalType: "address",
name: "newAdmin",
type: "address",
},
],
name: "AdminChanged",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: "address",
name: "implementation",
type: "address",
},
],
name: "Upgraded",
type: "event",
},
{ stateMutability: "payable", type: "fallback" },
{
inputs: [],
name: "admin",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
type: "function",
},
{
inputs: [{ internalType: "address", name: "newAdmin", type: "address" }],
name: "changeAdmin",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [],
name: "implementation",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "newImplementation", type: "address" },
],
name: "upgradeTo",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "newImplementation", type: "address" },
{ internalType: "bytes", name: "data", type: "bytes" },
],
name: "upgradeToAndCall",
outputs: [],
stateMutability: "payable",
type: "function",
},
] as const;
const USDT_ABI = [
{
inputs: [
{ internalType: "address", name: "_logic", type: "address" },
{ internalType: "address", name: "admin_", type: "address" },
{ internalType: "bytes", name: "_data", type: "bytes" },
],
stateMutability: "payable",
type: "constructor",
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: "address",
name: "previousAdmin",
type: "address",
},
{
indexed: false,
internalType: "address",
name: "newAdmin",
type: "address",
},
],
name: "AdminChanged",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "beacon",
type: "address",
},
],
name: "BeaconUpgraded",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "implementation",
type: "address",
},
],
name: "Upgraded",
type: "event",
},
{ stateMutability: "payable", type: "fallback" },
{
inputs: [],
name: "admin",
outputs: [{ internalType: "address", name: "admin_", type: "address" }],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [{ internalType: "address", name: "newAdmin", type: "address" }],
name: "changeAdmin",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [],
name: "implementation",
outputs: [
{ internalType: "address", name: "implementation_", type: "address" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "newImplementation", type: "address" },
],
name: "upgradeTo",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "newImplementation", type: "address" },
{ internalType: "bytes", name: "data", type: "bytes" },
],
name: "upgradeToAndCall",
outputs: [],
stateMutability: "payable",
type: "function",
},
{ stateMutability: "payable", type: "receive" },
] as const;
const UNISWAP_V2_FACTORY_ABI = [
{
inputs: [
{ internalType: "address", name: "_feeToSetter", type: "address" },
],
payable: false,
stateMutability: "nonpayable",
type: "constructor",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "token0",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "token1",
type: "address",
},
{
indexed: false,
internalType: "address",
name: "pair",
type: "address",
},
{ indexed: false, internalType: "uint256", name: "", type: "uint256" },
],
name: "PairCreated",
type: "event",
},
{
constant: true,
inputs: [{ internalType: "uint256", name: "", type: "uint256" }],
name: "allPairs",
outputs: [{ internalType: "address", name: "", type: "address" }],
payable: false,
stateMutability: "view",
type: "function",
},
{
constant: true,
inputs: [],
name: "allPairsLength",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
payable: false,
stateMutability: "view",
type: "function",
},
{
constant: false,
inputs: [
{ internalType: "address", name: "tokenA", type: "address" },
{ internalType: "address", name: "tokenB", type: "address" },
],
name: "createPair",
outputs: [{ internalType: "address", name: "pair", type: "address" }],
payable: false,
stateMutability: "nonpayable",
type: "function",
},
{
constant: true,
inputs: [],
name: "feeTo",
outputs: [{ internalType: "address", name: "", type: "address" }],
payable: false,
stateMutability: "view",
type: "function",
},
{
constant: true,
inputs: [],
name: "feeToSetter",
outputs: [{ internalType: "address", name: "", type: "address" }],
payable: false,
stateMutability: "view",
type: "function",
},
{
constant: true,
inputs: [
{ internalType: "address", name: "", type: "address" },
{ internalType: "address", name: "", type: "address" },
],
name: "getPair",
outputs: [{ internalType: "address", name: "", type: "address" }],
payable: false,
stateMutability: "view",
type: "function",
},
{
constant: false,
inputs: [{ internalType: "address", name: "_feeTo", type: "address" }],
name: "setFeeTo",
outputs: [],
payable: false,
stateMutability: "nonpayable",
type: "function",
},
{
constant: false,
inputs: [
{ internalType: "address", name: "_feeToSetter", type: "address" },
],
name: "setFeeToSetter",
outputs: [],
payable: false,
stateMutability: "nonpayable",
type: "function",
},
] as const;
const UNISWAP_V2_ROUTER_ABI = [
{
inputs: [
{ internalType: "address", name: "_factory", type: "address" },
{ internalType: "address", name: "_WETH", type: "address" },
],
stateMutability: "nonpayable",
type: "constructor",
},
{
inputs: [],
name: "WETH",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "tokenA", type: "address" },
{ internalType: "address", name: "tokenB", type: "address" },
{ internalType: "uint256", name: "amountADesired", type: "uint256" },
{ internalType: "uint256", name: "amountBDesired", type: "uint256" },
{ internalType: "uint256", name: "amountAMin", type: "uint256" },
{ internalType: "uint256", name: "amountBMin", type: "uint256" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "addLiquidity",
outputs: [
{ internalType: "uint256", name: "amountA", type: "uint256" },
{ internalType: "uint256", name: "amountB", type: "uint256" },
{ internalType: "uint256", name: "liquidity", type: "uint256" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "amountTokenDesired", type: "uint256" },
{ internalType: "uint256", name: "amountTokenMin", type: "uint256" },
{ internalType: "uint256", name: "amountETHMin", type: "uint256" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "addLiquidityETH",
outputs: [
{ internalType: "uint256", name: "amountToken", type: "uint256" },
{ internalType: "uint256", name: "amountETH", type: "uint256" },
{ internalType: "uint256", name: "liquidity", type: "uint256" },
],
stateMutability: "payable",
type: "function",
},
{
inputs: [],
name: "factory",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountOut", type: "uint256" },
{ internalType: "uint256", name: "reserveIn", type: "uint256" },
{ internalType: "uint256", name: "reserveOut", type: "uint256" },
],
name: "getAmountIn",
outputs: [{ internalType: "uint256", name: "amountIn", type: "uint256" }],
stateMutability: "pure",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountIn", type: "uint256" },
{ internalType: "uint256", name: "reserveIn", type: "uint256" },
{ internalType: "uint256", name: "reserveOut", type: "uint256" },
],
name: "getAmountOut",
outputs: [{ internalType: "uint256", name: "amountOut", type: "uint256" }],
stateMutability: "pure",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountOut", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
],
name: "getAmountsIn",
outputs: [
{ internalType: "uint256[]", name: "amounts", type: "uint256[]" },
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountIn", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
],
name: "getAmountsOut",
outputs: [
{ internalType: "uint256[]", name: "amounts", type: "uint256[]" },
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountA", type: "uint256" },
{ internalType: "uint256", name: "reserveA", type: "uint256" },
{ internalType: "uint256", name: "reserveB", type: "uint256" },
],
name: "quote",
outputs: [{ internalType: "uint256", name: "amountB", type: "uint256" }],
stateMutability: "pure",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "tokenA", type: "address" },
{ internalType: "address", name: "tokenB", type: "address" },
{ internalType: "uint256", name: "liquidity", type: "uint256" },
{ internalType: "uint256", name: "amountAMin", type: "uint256" },
{ internalType: "uint256", name: "amountBMin", type: "uint256" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "removeLiquidity",
outputs: [
{ internalType: "uint256", name: "amountA", type: "uint256" },
{ internalType: "uint256", name: "amountB", type: "uint256" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "liquidity", type: "uint256" },
{ internalType: "uint256", name: "amountTokenMin", type: "uint256" },
{ internalType: "uint256", name: "amountETHMin", type: "uint256" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "removeLiquidityETH",
outputs: [
{ internalType: "uint256", name: "amountToken", type: "uint256" },
{ internalType: "uint256", name: "amountETH", type: "uint256" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "liquidity", type: "uint256" },
{ internalType: "uint256", name: "amountTokenMin", type: "uint256" },
{ internalType: "uint256", name: "amountETHMin", type: "uint256" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "removeLiquidityETHSupportingFeeOnTransferTokens",
outputs: [{ internalType: "uint256", name: "amountETH", type: "uint256" }],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "liquidity", type: "uint256" },
{ internalType: "uint256", name: "amountTokenMin", type: "uint256" },
{ internalType: "uint256", name: "amountETHMin", type: "uint256" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
{ internalType: "bool", name: "approveMax", type: "bool" },
{ internalType: "uint8", name: "v", type: "uint8" },
{ internalType: "bytes32", name: "r", type: "bytes32" },
{ internalType: "bytes32", name: "s", type: "bytes32" },
],
name: "removeLiquidityETHWithPermit",
outputs: [
{ internalType: "uint256", name: "amountToken", type: "uint256" },
{ internalType: "uint256", name: "amountETH", type: "uint256" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "liquidity", type: "uint256" },
{ internalType: "uint256", name: "amountTokenMin", type: "uint256" },
{ internalType: "uint256", name: "amountETHMin", type: "uint256" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
{ internalType: "bool", name: "approveMax", type: "bool" },
{ internalType: "uint8", name: "v", type: "uint8" },
{ internalType: "bytes32", name: "r", type: "bytes32" },
{ internalType: "bytes32", name: "s", type: "bytes32" },
],
name: "removeLiquidityETHWithPermitSupportingFeeOnTransferTokens",
outputs: [{ internalType: "uint256", name: "amountETH", type: "uint256" }],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "tokenA", type: "address" },
{ internalType: "address", name: "tokenB", type: "address" },
{ internalType: "uint256", name: "liquidity", type: "uint256" },
{ internalType: "uint256", name: "amountAMin", type: "uint256" },
{ internalType: "uint256", name: "amountBMin", type: "uint256" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
{ internalType: "bool", name: "approveMax", type: "bool" },
{ internalType: "uint8", name: "v", type: "uint8" },
{ internalType: "bytes32", name: "r", type: "bytes32" },
{ internalType: "bytes32", name: "s", type: "bytes32" },
],
name: "removeLiquidityWithPermit",
outputs: [
{ internalType: "uint256", name: "amountA", type: "uint256" },
{ internalType: "uint256", name: "amountB", type: "uint256" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountOut", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "swapETHForExactTokens",
outputs: [
{ internalType: "uint256[]", name: "amounts", type: "uint256[]" },
],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountOutMin", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "swapExactETHForTokens",
outputs: [
{ internalType: "uint256[]", name: "amounts", type: "uint256[]" },
],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountOutMin", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "swapExactETHForTokensSupportingFeeOnTransferTokens",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountIn", type: "uint256" },
{ internalType: "uint256", name: "amountOutMin", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "swapExactTokensForETH",
outputs: [
{ internalType: "uint256[]", name: "amounts", type: "uint256[]" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountIn", type: "uint256" },
{ internalType: "uint256", name: "amountOutMin", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "swapExactTokensForETHSupportingFeeOnTransferTokens",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountIn", type: "uint256" },
{ internalType: "uint256", name: "amountOutMin", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "swapExactTokensForTokens",
outputs: [
{ internalType: "uint256[]", name: "amounts", type: "uint256[]" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountIn", type: "uint256" },
{ internalType: "uint256", name: "amountOutMin", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "swapExactTokensForTokensSupportingFeeOnTransferTokens",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountOut", type: "uint256" },
{ internalType: "uint256", name: "amountInMax", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "swapTokensForExactETH",
outputs: [
{ internalType: "uint256[]", name: "amounts", type: "uint256[]" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountOut", type: "uint256" },
{ internalType: "uint256", name: "amountInMax", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "swapTokensForExactTokens",
outputs: [
{ internalType: "uint256[]", name: "amounts", type: "uint256[]" },
],
stateMutability: "nonpayable",
type: "function",
},
{ stateMutability: "payable", type: "receive" },
] as const;
const UNISWAP_V3_FACTORY_ABI = [
{ inputs: [], stateMutability: "nonpayable", type: "constructor" },
{
anonymous: false,
inputs: [
{ indexed: true, internalType: "uint24", name: "fee", type: "uint24" },
{
indexed: true,
internalType: "int24",
name: "tickSpacing",
type: "int24",
},
],
name: "FeeAmountEnabled",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "oldOwner",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "newOwner",
type: "address",
},
],
name: "OwnerChanged",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "token0",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "token1",
type: "address",
},
{ indexed: true, internalType: "uint24", name: "fee", type: "uint24" },
{
indexed: false,
internalType: "int24",
name: "tickSpacing",
type: "int24",
},
{
indexed: false,
internalType: "address",
name: "pool",
type: "address",
},
],
name: "PoolCreated",
type: "event",
},
{
inputs: [
{ internalType: "address", name: "tokenA", type: "address" },
{ internalType: "address", name: "tokenB", type: "address" },
{ internalType: "uint24", name: "fee", type: "uint24" },
],
name: "createPool",
outputs: [{ internalType: "address", name: "pool", type: "address" }],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "uint24", name: "fee", type: "uint24" },
{ internalType: "int24", name: "tickSpacing", type: "int24" },
],
name: "enableFeeAmount",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [{ internalType: "uint24", name: "", type: "uint24" }],
name: "feeAmountTickSpacing",
outputs: [{ internalType: "int24", name: "", type: "int24" }],
stateMutability: "view",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "", type: "address" },
{ internalType: "address", name: "", type: "address" },
{ internalType: "uint24", name: "", type: "uint24" },
],
name: "getPool",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "owner",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "parameters",
outputs: [
{ internalType: "address", name: "factory", type: "address" },
{ internalType: "address", name: "token0", type: "address" },
{ internalType: "address", name: "token1", type: "address" },
{ internalType: "uint24", name: "fee", type: "uint24" },
{ internalType: "int24", name: "tickSpacing", type: "int24" },
],
stateMutability: "view",
type: "function",
},
{
inputs: [{ internalType: "address", name: "_owner", type: "address" }],
name: "setOwner",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
] as const;
const QUOTER_V2_ABI = [
{
inputs: [
{ internalType: "address", name: "_factory", type: "address" },
{ internalType: "address", name: "_WETH9", type: "address" },
],
stateMutability: "nonpayable",
type: "constructor",
},
{
inputs: [],
name: "WETH9",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "factory",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
type: "function",
},
{
inputs: [
{ internalType: "bytes", name: "path", type: "bytes" },
{ internalType: "uint256", name: "amountIn", type: "uint256" },
],
name: "quoteExactInput",
outputs: [
{ internalType: "uint256", name: "amountOut", type: "uint256" },
{
internalType: "uint160[]",
name: "sqrtPriceX96AfterList",
type: "uint160[]",
},
{
internalType: "uint32[]",
name: "initializedTicksCrossedList",
type: "uint32[]",
},
{ internalType: "uint256", name: "gasEstimate", type: "uint256" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
components: [
{ internalType: "address", name: "tokenIn", type: "address" },
{ internalType: "address", name: "tokenOut", type: "address" },
{ internalType: "uint256", name: "amountIn", type: "uint256" },
{ internalType: "uint24", name: "fee", type: "uint24" },
{
internalType: "uint160",
name: "sqrtPriceLimitX96",
type: "uint160",
},
],
internalType: "struct IQuoterV2.QuoteExactInputSingleParams",
name: "params",
type: "tuple",
},
],
name: "quoteExactInputSingle",
outputs: [
{ internalType: "uint256", name: "amountOut", type: "uint256" },
{ internalType: "uint160", name: "sqrtPriceX96After", type: "uint160" },
{
internalType: "uint32",
name: "initializedTicksCrossed",
type: "uint32",
},
{ internalType: "uint256", name: "gasEstimate", type: "uint256" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "bytes", name: "path", type: "bytes" },
{ internalType: "uint256", name: "amountOut", type: "uint256" },
],
name: "quoteExactOutput",
outputs: [
{ internalType: "uint256", name: "amountIn", type: "uint256" },
{
internalType: "uint160[]",
name: "sqrtPriceX96AfterList",
type: "uint160[]",
},
{
internalType: "uint32[]",
name: "initializedTicksCrossedList",
type: "uint32[]",
},
{ internalType: "uint256", name: "gasEstimate", type: "uint256" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
components: [
{ internalType: "address", name: "tokenIn", type: "address" },
{ internalType: "address", name: "tokenOut", type: "address" },
{ internalType: "uint256", name: "amount", type: "uint256" },
{ internalType: "uint24", name: "fee", type: "uint24" },
{
internalType: "uint160",
name: "sqrtPriceLimitX96",
type: "uint160",
},
],
internalType: "struct IQuoterV2.QuoteExactOutputSingleParams",
name: "params",
type: "tuple",
},
],
name: "quoteExactOutputSingle",
outputs: [
{ internalType: "uint256", name: "amountIn", type: "uint256" },
{ internalType: "uint160", name: "sqrtPriceX96After", type: "uint160" },
{
internalType: "uint32",
name: "initializedTicksCrossed",
type: "uint32",
},
{ internalType: "uint256", name: "gasEstimate", type: "uint256" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "int256", name: "amount0Delta", type: "int256" },
{ internalType: "int256", name: "amount1Delta", type: "int256" },
{ internalType: "bytes", name: "path", type: "bytes" },
],
name: "uniswapV3SwapCallback",
outputs: [],
stateMutability: "view",
type: "function",
},
] as const;
const SWAP_ROUTER_02_ABI = [
{
inputs: [
{ internalType: "address", name: "_factoryV2", type: "address" },
{ internalType: "address", name: "factoryV3", type: "address" },
{ internalType: "address", name: "_positionManager", type: "address" },
{ internalType: "address", name: "_WETH9", type: "address" },
],
stateMutability: "nonpayable",
type: "constructor",
},
{
inputs: [],
name: "WETH9",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
type: "function",
},
{
inputs: [{ internalType: "address", name: "token", type: "address" }],
name: "approveMax",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [{ internalType: "address", name: "token", type: "address" }],
name: "approveMaxMinusOne",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [{ internalType: "address", name: "token", type: "address" }],
name: "approveZeroThenMax",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [{ internalType: "address", name: "token", type: "address" }],
name: "approveZeroThenMaxMinusOne",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [{ internalType: "bytes", name: "data", type: "bytes" }],
name: "callPositionManager",
outputs: [{ internalType: "bytes", name: "result", type: "bytes" }],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "bytes[]", name: "paths", type: "bytes[]" },
{ internalType: "uint128[]", name: "amounts", type: "uint128[]" },
{ internalType: "uint24", name: "maximumTickDivergence", type: "uint24" },
{ internalType: "uint32", name: "secondsAgo", type: "uint32" },
],
name: "checkOracleSlippage",
outputs: [],
stateMutability: "view",
type: "function",
},
{
inputs: [
{ internalType: "bytes", name: "path", type: "bytes" },
{ internalType: "uint24", name: "maximumTickDivergence", type: "uint24" },
{ internalType: "uint32", name: "secondsAgo", type: "uint32" },
],
name: "checkOracleSlippage",
outputs: [],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
components: [
{ internalType: "bytes", name: "path", type: "bytes" },
{ internalType: "address", name: "recipient", type: "address" },
{ internalType: "uint256", name: "amountIn", type: "uint256" },
{
internalType: "uint256",
name: "amountOutMinimum",
type: "uint256",
},
],
internalType: "struct IV3SwapRouter.ExactInputParams",
name: "params",
type: "tuple",
},
],
name: "exactInput",
outputs: [{ internalType: "uint256", name: "amountOut", type: "uint256" }],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{
components: [
{ internalType: "address", name: "tokenIn", type: "address" },
{ internalType: "address", name: "tokenOut", type: "address" },
{ internalType: "uint24", name: "fee", type: "uint24" },
{ internalType: "address", name: "recipient", type: "address" },
{ internalType: "uint256", name: "amountIn", type: "uint256" },
{
internalType: "uint256",
name: "amountOutMinimum",
type: "uint256",
},
{
internalType: "uint160",
name: "sqrtPriceLimitX96",
type: "uint160",
},
],
internalType: "struct IV3SwapRouter.ExactInputSingleParams",
name: "params",
type: "tuple",
},
],
name: "exactInputSingle",
outputs: [{ internalType: "uint256", name: "amountOut", type: "uint256" }],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{
components: [
{ internalType: "bytes", name: "path", type: "bytes" },
{ internalType: "address", name: "recipient", type: "address" },
{ internalType: "uint256", name: "amountOut", type: "uint256" },
{ internalType: "uint256", name: "amountInMaximum", type: "uint256" },
],
internalType: "struct IV3SwapRouter.ExactOutputParams",
name: "params",
type: "tuple",
},
],
name: "exactOutput",
outputs: [{ internalType: "uint256", name: "amountIn", type: "uint256" }],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{
components: [
{ internalType: "address", name: "tokenIn", type: "address" },
{ internalType: "address", name: "tokenOut", type: "address" },
{ internalType: "uint24", name: "fee", type: "uint24" },
{ internalType: "address", name: "recipient", type: "address" },
{ internalType: "uint256", name: "amountOut", type: "uint256" },
{ internalType: "uint256", name: "amountInMaximum", type: "uint256" },
{
internalType: "uint160",
name: "sqrtPriceLimitX96",
type: "uint160",
},
],
internalType: "struct IV3SwapRouter.ExactOutputSingleParams",
name: "params",
type: "tuple",
},
],
name: "exactOutputSingle",
outputs: [{ internalType: "uint256", name: "amountIn", type: "uint256" }],
stateMutability: "payable",
type: "function",
},
{
inputs: [],
name: "factory",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "factoryV2",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "amount", type: "uint256" },
],
name: "getApprovalType",
outputs: [
{
internalType: "enum IApproveAndCall.ApprovalType",
name: "",
type: "uint8",
},
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
components: [
{ internalType: "address", name: "token0", type: "address" },
{ internalType: "address", name: "token1", type: "address" },
{ internalType: "uint256", name: "tokenId", type: "uint256" },
{ internalType: "uint256", name: "amount0Min", type: "uint256" },
{ internalType: "uint256", name: "amount1Min", type: "uint256" },
],
internalType: "struct IApproveAndCall.IncreaseLiquidityParams",
name: "params",
type: "tuple",
},
],
name: "increaseLiquidity",
outputs: [{ internalType: "bytes", name: "result", type: "bytes" }],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{
components: [
{ internalType: "address", name: "token0", type: "address" },
{ internalType: "address", name: "token1", type: "address" },
{ internalType: "uint24", name: "fee", type: "uint24" },
{ internalType: "int24", name: "tickLower", type: "int24" },
{ internalType: "int24", name: "tickUpper", type: "int24" },
{ internalType: "uint256", name: "amount0Min", type: "uint256" },
{ internalType: "uint256", name: "amount1Min", type: "uint256" },
{ internalType: "address", name: "recipient", type: "address" },
],
internalType: "struct IApproveAndCall.MintParams",
name: "params",
type: "tuple",
},
],
name: "mint",
outputs: [{ internalType: "bytes", name: "result", type: "bytes" }],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "bytes32", name: "previousBlockhash", type: "bytes32" },
{ internalType: "bytes[]", name: "data", type: "bytes[]" },
],
name: "multicall",
outputs: [{ internalType: "bytes[]", name: "", type: "bytes[]" }],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "deadline", type: "uint256" },
{ internalType: "bytes[]", name: "data", type: "bytes[]" },
],
name: "multicall",
outputs: [{ internalType: "bytes[]", name: "", type: "bytes[]" }],
stateMutability: "payable",
type: "function",
},
{
inputs: [{ internalType: "bytes[]", name: "data", type: "bytes[]" }],
name: "multicall",
outputs: [{ internalType: "bytes[]", name: "results", type: "bytes[]" }],
stateMutability: "payable",
type: "function",
},
{
inputs: [],
name: "positionManager",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "value", type: "uint256" },
],
name: "pull",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [],
name: "refundETH",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "value", type: "uint256" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
{ internalType: "uint8", name: "v", type: "uint8" },
{ internalType: "bytes32", name: "r", type: "bytes32" },
{ internalType: "bytes32", name: "s", type: "bytes32" },
],
name: "selfPermit",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "nonce", type: "uint256" },
{ internalType: "uint256", name: "expiry", type: "uint256" },
{ internalType: "uint8", name: "v", type: "uint8" },
{ internalType: "bytes32", name: "r", type: "bytes32" },
{ internalType: "bytes32", name: "s", type: "bytes32" },
],
name: "selfPermitAllowed",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "nonce", type: "uint256" },
{ internalType: "uint256", name: "expiry", type: "uint256" },
{ internalType: "uint8", name: "v", type: "uint8" },
{ internalType: "bytes32", name: "r", type: "bytes32" },
{ internalType: "bytes32", name: "s", type: "bytes32" },
],
name: "selfPermitAllowedIfNecessary",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "value", type: "uint256" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
{ internalType: "uint8", name: "v", type: "uint8" },
{ internalType: "bytes32", name: "r", type: "bytes32" },
{ internalType: "bytes32", name: "s", type: "bytes32" },
],
name: "selfPermitIfNecessary",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountIn", type: "uint256" },
{ internalType: "uint256", name: "amountOutMin", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
{ internalType: "address", name: "to", type: "address" },
],
name: "swapExactTokensForTokens",
outputs: [{ internalType: "uint256", name: "amountOut", type: "uint256" }],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountOut", type: "uint256" },
{ internalType: "uint256", name: "amountInMax", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
{ internalType: "address", name: "to", type: "address" },
],
name: "swapTokensForExactTokens",
outputs: [{ internalType: "uint256", name: "amountIn", type: "uint256" }],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "amountMinimum", type: "uint256" },
{ internalType: "address", name: "recipient", type: "address" },
],
name: "sweepToken",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "amountMinimum", type: "uint256" },
],
name: "sweepToken",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "amountMinimum", type: "uint256" },
{ internalType: "uint256", name: "feeBips", type: "uint256" },
{ internalType: "address", name: "feeRecipient", type: "address" },
],
name: "sweepTokenWithFee",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "amountMinimum", type: "uint256" },
{ internalType: "address", name: "recipient", type: "address" },
{ internalType: "uint256", name: "feeBips", type: "uint256" },
{ internalType: "address", name: "feeRecipient", type: "address" },
],
name: "sweepTokenWithFee",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "int256", name: "amount0Delta", type: "int256" },
{ internalType: "int256", name: "amount1Delta", type: "int256" },
{ internalType: "bytes", name: "_data", type: "bytes" },
],
name: "uniswapV3SwapCallback",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountMinimum", type: "uint256" },
{ internalType: "address", name: "recipient", type: "address" },
],
name: "unwrapWETH9",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountMinimum", type: "uint256" },
],
name: "unwrapWETH9",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountMinimum", type: "uint256" },
{ internalType: "address", name: "recipient", type: "address" },
{ internalType: "uint256", name: "feeBips", type: "uint256" },
{ internalType: "address", name: "feeRecipient", type: "address" },
],
name: "unwrapWETH9WithFee",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountMinimum", type: "uint256" },
{ internalType: "uint256", name: "feeBips", type: "uint256" },
{ internalType: "address", name: "feeRecipient", type: "address" },
],
name: "unwrapWETH9WithFee",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [{ internalType: "uint256", name: "value", type: "uint256" }],
name: "wrapETH",
outputs: [],
stateMutability: "payable",
type: "function",
},
{ stateMutability: "payable", type: "receive" },
] as const;
export const ABSTRACT_CONTRACTS: ContractsConfig = {
tokens: {
weth: {
name: "Wrapped Ether",
description: "WETH9 - Wrapped Ether contract for Abstract",
addresses: {
mainnet: "0x3439153EB7AF838Ad19d56E1571FBD09333C2809",
testnet: "0x9EDCde0257F2386Ce177C3a7FCdd97787F0D841d",
} as const,
abi: WETH9_ABI,
},
usdc: {
name: "USD Coin",
description: "USDC - Circle's stablecoin on Abstract",
addresses: {
mainnet: "0x84A71ccD554Cc1b02749b35d22F684CC8ec987e1",
testnet: "0xe4C7fBB0a626ed208021ccabA6Be1566905E2dFc",
} as const,
abi: USDC_ABI,
},
usdt: {
name: "Tether USD",
description: "USDT - Tether's stablecoin on Abstract",
addresses: {
mainnet: "0x0709F39376dEEe2A2dfC94A58EdEb2Eb9DF012bD",
// Note: No testnet address available for USDT.
} as const,
abi: USDT_ABI,
},
},
dex: {
uniswapV2Factory: {
name: "Uniswap V2 Factory",
description: "Factory contract for creating Uniswap V2 pairs",
addresses: {
mainnet: "0x566d7510dEE58360a64C9827257cF6D0Dc43985E",
testnet: "0x566d7510dEE58360a64C9827257cF6D0Dc43985E",
} as const,
abi: UNISWAP_V2_FACTORY_ABI,
},
uniswapV2Router: {
name: "Uniswap V2 Router02",
description: "Router contract for Uniswap V2 swaps and liquidity",
addresses: {
mainnet: "0xad1eCa41E6F772bE3cb5A48A6141f9bcc1AF9F7c",
testnet: "0x96ff7D9dbf52FdcAe79157d3b249282c7FABd409",
} as const,
abi: UNISWAP_V2_ROUTER_ABI,
},
uniswapV3Factory: {
name: "Uniswap V3 Factory",
description: "Factory contract for creating Uniswap V3 pools",
addresses: {
mainnet: "0xA1160e73B63F322ae88cC2d8E700833e71D0b2a1",
testnet: "0x2E17FF9b877661bDFEF8879a4B31665157a960F0",
} as const,
abi: UNISWAP_V3_FACTORY_ABI,
},
quoterV2: {
name: "Quoter V2",
description: "Uniswap V3 quoter for getting swap quotes",
addresses: {
mainnet: "0x728BD3eC25D5EDBafebB84F3d67367Cd9EBC7693",
testnet: "0xdE41045eb15C8352413199f35d6d1A32803DaaE2",
} as const,
abi: QUOTER_V2_ABI,
},
swapRouter02: {
name: "Swap Router 02",
description: "Uniswap V3 router for executing swaps",
addresses: {
mainnet: "0x7712FA47387542819d4E35A23f8116C90C18767C",
testnet: "0xb9D4347d129a83cBC40499Cd4fF223dE172a70dF",
} as const,
abi: SWAP_ROUTER_02_ABI,
},
},
};
// Export individual ABIs for easy importing
export {
WETH9_ABI,
USDC_ABI,
USDT_ABI,
UNISWAP_V2_FACTORY_ABI,
UNISWAP_V2_ROUTER_ABI,
UNISWAP_V3_FACTORY_ABI,
QUOTER_V2_ABI,
SWAP_ROUTER_02_ABI,
};
Tokens:
weth
- Wrapped Ether (WETH9)usdc
- USD Coin stablecoinusdt
- Tether USD stablecoin (mainnet only)DEX Infrastructure:
uniswapV2Factory
- Uniswap V2 factory for pair creationuniswapV2Router
- Uniswap V2 router for swaps and liquidityuniswapV3Factory
- Uniswap V3 factory for pool creationquoterV2
- Uniswap V3 quoter for swap price quotesswapRouter02
- Uniswap V3 router for executing swapschain-utils.ts
Utility functions for network-aware contract address resolution with automatic mainnet/testnet selection and error handling.
import type {
NetworkId,
ContractAddress,
ContractInfo,
} from "@/types/contracts";
import { abstract, abstractTestnet } from "viem/chains";
import { chain } from "@/config/chain";
import type { Address } from "viem";
import { ABSTRACT_CONTRACTS } from "@/lib/abstract-contracts";
export function getNetworkName(chainId: NetworkId): string {
switch (chainId) {
case abstract.id:
return "Abstract Mainnet";
case abstractTestnet.id:
return "Abstract Testnet";
default:
return "Unknown Network";
}
}
export function isAbstractNetwork(chainId: number): chainId is NetworkId {
return chainId === abstract.id || chainId === abstractTestnet.id;
}
export function getContractAddress(
addresses: ContractAddress,
chainId: NetworkId
): Address {
const address =
chainId === abstract.id ? addresses.mainnet : addresses.testnet;
if (!address) {
const networkName = getNetworkName(chainId);
throw new Error(`Contract address not available on ${networkName}`);
}
return address;
}
function findContractInCategories(contractKey: string): ContractInfo | null {
for (const category of Object.values(ABSTRACT_CONTRACTS)) {
if (typeof category === "object" && category[contractKey]) {
return category[contractKey];
}
}
return null;
}
export function findContract(contractKey: string): ContractInfo | null {
return findContractInCategories(contractKey);
}
export function getContract(
contractKey: string,
chainId: NetworkId
): ContractInfo & { address: Address } {
const contract = findContractInCategories(contractKey);
if (!contract) {
throw new Error(`Contract "${contractKey}" not found`);
}
if (!isAbstractNetwork(chainId)) {
throw new Error(
`Unsupported chain ID: ${chainId}. Only Abstract networks are supported.`
);
}
const address = getContractAddress(contract.addresses, chainId);
return {
...contract,
address,
};
}
// Convenience function that uses the current chain configuration
export function getContractWithCurrentChain(
contractKey: string
): ContractInfo & { address: Address } {
return getContract(contractKey, chain.id as NetworkId);
}
// Convenience function to get contract address with current chain
export function getContractAddressWithCurrentChain(
contractKey: string
): Address {
const contract = findContractInCategories(contractKey);
if (!contract) {
throw new Error(`Contract "${contractKey}" not found`);
}
const address = getContractAddress(contract.addresses, chain.id as NetworkId);
if (!address) {
throw new Error(
`Contract address not available for "${contractKey}" on current chain`
);
}
return address;
}
Function | Description |
---|---|
getContract(key, chainId) | Get full contract info with address for specific chain |
getContractWithCurrentChain(key) | Get contract info using current chain configuration |
getContractAddress(addresses, chainId) | Get contract address for specific chain |
getContractAddressWithCurrentChain(key) | Get address using current chain configuration |
findContract(key) | Search for contract by key across all categories |
isAbstractNetwork(chainId) | Check if chain ID is Abstract mainnet or testnet |
getNetworkName(chainId) | Get human-readable network name |
types/contracts.ts
TypeScript type definitions for contract configuration, network IDs, and utility function options.
import type { Address, Abi } from "viem"
export interface ContractAddress {
mainnet?: Address
testnet?: Address
}
export interface ContractInfo {
name: string
description: string
addresses: ContractAddress
abi?: Abi
}
export interface ContractsConfig {
tokens: Record<string, ContractInfo>
dex: Record<string, ContractInfo>
}
export type NetworkId = 2741 | 11124 // Abstract mainnet | Abstract testnet
export interface UseContractAddressOptions {
chainId?: NetworkId
throwOnMissing?: boolean
}