Skip to main content

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 and ethers 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 Address
  • INIT_CODE_HASH: For CREATE2 address generation
  • MINIMUM_LIQUIDITY: Protocol-reserved
  • Errors: InsufficientReservesError, InsufficientInputAmountError