ShibaSwap V1 SDK
The ShibaSwap V1 SDK (@shibaswap/sdk
) is a TypeScript/JavaScript library that lets you build on top of ShibaSwap V1—a Uniswap V2 fork originally inherited via SushiSwap—using familiar abstractions like Token
, Pair
, Route
, and Trade
.
It runs in any JS environment (browsers, Node) and powers both quick hackathon prototypes and production-grade integrations.
Under the hood:
- It swaps in ShibaSwap’s factory and router addresses
- Computes CREATE2 pair addresses offline
- Fetches on-chain reserves via ethers
- Generates all parameters needed to craft router transactions
Quick Start & Installation
npm install @shibaswap/sdk
# or
yarn add @shibaswap/sdk
This pulls in
@shibaswap/sdk-core
andethers
as dependencies.
Imports & Initialization
import { ChainId } from '@shibaswap/sdk-core'
import { Pair } from '@shibaswap/sdk'
console.log(`Mainnet chainId = ${ChainId.MAINNET}`)
Fetching On-Chain Data
You must supply on-chain data for tokens and pairs.
Case 1: Tokens
import { ChainId, Token } from '@shibaswap/sdk-core'
const DAI = new Token(
ChainId.MAINNET,
'0x6B175474E89094C44Da98b954EedeAC495271d0F',
18,
'DAI',
'Dai Stablecoin'
)
To fetch decimals dynamically:
import { ethers } from 'ethers'
import erc20ABI from './erc20.json'
async function getDecimals(chainId: ChainId, tokenAddress: string): Promise<number> {
const provider = new ethers.providers.JsonRpcProvider(/* RPC URL */)
const tokenContract = new ethers.Contract(tokenAddress, erc20ABI, provider)
return tokenContract.decimals()
}
Case 2: Pairs
import {
ChainId,
Token,
WETH9,
CurrencyAmount
} from '@shibaswap/sdk-core'
import { Pair } from '@shibaswap/sdk'
import { ethers } from 'ethers'
import poolABI from './V2Pool.json'
const DAI = new Token(/* … */)
const WETH = WETH9[ChainId.MAINNET]
async function createDAIWethPair(): Promise<Pair> {
const pairAddress = Pair.getAddress(DAI, WETH)
const provider = new ethers.providers.JsonRpcProvider(/* RPC URL */)
const pool = new ethers.Contract(pairAddress, poolABI, provider)
const [reserve0, reserve1] = await pool.getReserves()
const [token0, token1] = [DAI, WETH].sort((a, b) => a.sortsBefore(b) ? -1 : 1)
return new Pair(
CurrencyAmount.fromRawAmount(token0, reserve0.toString()),
CurrencyAmount.fromRawAmount(token1, reserve1.toString())
)
}
Pricing
Mid Price (Direct & Indirect)
import { Route } from '@shibaswap/sdk'
const pair = await createDAIWethPair()
const route = new Route([pair], WETH, DAI)
console.log(route.midPrice.toSignificant(6))
console.log(route.midPrice.invert().toSignificant(6))
For multi-hop (e.g., via USDC):
const USDC = new Token(/* … */)
const usdcWeth = await createPair(USDC, WETH)
const daiUsdc = await createPair(DAI, USDC)
const indirectRoute = new Route([usdcWeth, daiUsdc], WETH, DAI)
console.log(indirectRoute.midPrice.toSignificant(6))
Execution Price (with Slippage)
import { Trade, TradeType, CurrencyAmount } from '@shibaswap/sdk-core'
const trade = new Trade(
route,
CurrencyAmount.fromRawAmount(WETH, '1000000000000000000'), // 1 WETH
TradeType.EXACT_INPUT
)
console.log(trade.executionPrice.toSignificant(6))
Trading
The SDK does not send transactions. It generates transaction parameters for you to send manually via
ethers
.
Router Address: 0x03f7724180aa6b939894b5ca4314783b0b36b329
Example: Swap 1 ETH → DAI
import { Percent } from '@shibaswap/sdk-core'
import routerABI from './V2Router02.json'
import { ethers } from 'ethers'
const provider = new ethers.providers.Web3Provider(window.ethereum)
const signer = provider.getSigner()
const router = new ethers.Contract(
'0x03f7724180aa6b939894b5ca4314783b0b36b329',
routerABI,
signer
)
const slippageTolerance = new Percent('50', '10000') // 0.50%
const amountOutMin = trade.minimumAmountOut(slippageTolerance).toExact()
const path = [WETH.address, DAI.address]
const to = await signer.getAddress()
const deadline = Math.floor(Date.now() / 1000) + 60 * 20
const value = trade.inputAmount.toExact()
await router.swapExactETHForTokens(
amountOutMin,
path,
to,
deadline,
{ value }
)
Pair Addresses (CREATE2 vs On-Chain)
On-chain:
factory.getPair(tokenA, tokenB)
Off-chain via CREATE2:
import {
FACTORY_ADDRESS,
INIT_CODE_HASH
} from '@shibaswap/sdk'
import { pack, keccak256 } from '@ethersproject/solidity'
import { getCreate2Address } from '@ethersproject/address'
const pairAddress = getCreate2Address(
FACTORY_ADDRESS,
keccak256(['bytes'], [pack(['address','address'], [token0, token1])]),
INIT_CODE_HASH
)
Technical Reference
Pair
class Pair {
constructor(tokenAmountA: CurrencyAmount, tokenAmountB: CurrencyAmount)
static getAddress(tokenA: Token, tokenB: Token): string
reserveOf(token: Token): CurrencyAmount
getOutputAmount(inputAmount: CurrencyAmount): [CurrencyAmount, Pair]
getInputAmount(outputAmount: CurrencyAmount): [CurrencyAmount, Pair]
getLiquidityMinted(...): CurrencyAmount
getLiquidityValue(...): CurrencyAmount
}
Route
class Route {
constructor(pairs: Pair[], input: Token, output: Token)
readonly midPrice: Price
}
Trade
class Trade {
constructor(route: Route, amount: CurrencyAmount, tradeType: TradeType)
readonly inputAmount: CurrencyAmount
readonly outputAmount: CurrencyAmount
readonly executionPrice: Price
readonly priceImpact: Percent
minimumAmountOut(slippageTolerance: Percent): CurrencyAmount
maximumAmountIn(slippageTolerance: Percent): CurrencyAmount
worstExecutionPrice(slippageTolerance: Percent): Price
static exactIn(...): Trade
static exactOut(...): Trade
static bestTradeExactIn(...): Trade[]
static bestTradeExactOut(...): Trade[]
}
Other Exports
FACTORY_ADDRESS
: ShibaSwap V1 Factory AddressINIT_CODE_HASH
: For CREATE2 address generationMINIMUM_LIQUIDITY
: Protocol-reservedErrors
:InsufficientReservesError
,InsufficientInputAmountError