@swapkit/api

API Wrapper on usefull calls to thornode, midgard/MicroGard and THORSwap api.

Getting started

Installation

<pnpm|bun> add @swapkit/api

Usage

import { SwapKitApi, setRequestClientConfig } from '@swapkit/api'

const { routes } = await SwapKitApi.getSwapQuote({
    sellAsset: "BTC.BTC"
    sellAmount: 1,
    buyAsset: "ETH.ETH",
    senderAddress: "bc1...."
    recipientAddress: "0x...."
    slippage: "3", // %
});

const bestRouteToSwapWith = routes[0]

Methods

getBorrowQuote(params: BorrowParams): Promise<BorrowResponse>

Returns borrow quote params for requested asset to open loan. It includes all necessary info to execute transaction

const response = await SwapKitApi.getBorrowQuote({
    assetIn: string;
    assetOut: string;
    slippage: string;
    amount: string;
    senderAddress: string;
    recipientAddress: string;
})

getCachedPrices(params: CachedPricesParams): Promise<CachedPrice[]>

Returns last price of provided tokens array. Price is cached for up to 10 seconds.

const response = await SwapKitApi.getCachedPrice({
    //     [{ identifier: "BTC.BTC" / assetValue.toString() }]
    tokens: { identifier: string }[];
    metadata?: "true" | "false";
    lookup?: "true" | "false";
    sparkline?: "true" | "false";
})

const btcUsdPrice = response.find(
    (price) => price?.identifier === "BTC.BTC"
)?.price_usd

getGasRates(): Promise<GasPriceInfo[]>

Returns gas rates for THORChain supported chains

const response = await SwapKitApi.getGasRates()

const ethGasRate = response.find((rate) => rate.chainId === ChainId.Ethereum)?.gas

getInboundAddresses(params?: ThornodeEndpointParams): Promise<InboundAddressesItem[]>

const response = await SwapKitApi.getInboundAddresses()

const btcOnTCHalted = response.find(({ chain }) => chainId === Chain.Bitcoin)?.halted
const ethRouter = response.find(({ chain }) => chainId === Chain.Ethereum)?.router

getLastBlock(): Promise<LastBlockItem[]>

const response = await SwapKitApi.getLastBlock()

const lastETHBlockObserved = response.find(
    ({ chain }) => chain === Chain.Ethereum
)?.last_observed_in

getLendingAssets(): Promise<LendingAssetItem[]>

const response = await SwapKitApi.getLendingAssets()

const btc = AssetValue.fromChainOrSignature(Chain.Bitcoin)
const currentBtcLTV = response.find(({ asset }) => asset === btc.toString())?.ltvPercentage

getLoans(searchParams: LoansParams): Promise<LoansResponse>

// { address: '...', asset: assetValue.toString()
const response = await SwapKitApi.getLoans({ address: string; asset: string })

const { debtIssued, debtRepaid } = response || {}

getLogoForAsset(assetString: string): string

const btc = AssetValue.fromChainOrSignature(Chain.Bitcoin)
const btcLogo = SwapKitApi.getLogoForAsset(btc.toString()) // https://static.thorswap.net/images/...

// ...

function Component() {
    <img src={btcLogo} /> 
}

getMimirInfo(params: ThornodeEndpointParams): Promise<MimirData>

const thorchainMimir = await SwapKitApi.getMimirInfo()
const mayaStagenetMimir = await SwapKitApi.getMimirInfo({ stagenet: true, type: "mayachain" })

const tcHalted = thorchainMimir.HALTCHAINGLOBAL >= 1
const mayaStagenetHalted = thorchainMimir.HALTCHAINGLOBAL >= 1

getNodes(params: ThornodeEndpointParams): Promise<NodeItem[]>

const nodes = await SwapKitApi.getNodes()

const mostSlashedNode = nodes.concat().sort((a, b) => b.slash_points - a.slash_points)[0]

getRepayQuote(searchParams: RepayParams): Promise<RepayResponse>

const response = await SwapKitApi.getRepayQuote({
    repayAsset: string;
    collateralAsset: string;
    amountPercentage: string;
    senderAddress: string;
    collateralAddress: string;
    affiliateBasisPoints: string;
    affiliateAddress: string;
})

const repayValue = response?.repayAssetAmountUSD
const memoToRepayLoan = response?.memo

getSwapQuote(searchParams: QuoteParams): Promise<{ quoteId: string; routes: QuoteRoute[] }>

const response = await SwapKitApi.getSwapQuote({
    buyAsset: string;
    recipientAddress?: string;
    sellAmount: string;
    sellAsset: string;
    senderAddress?: string;
    slippage: string;
})

const bestQuoteUSD = response.routes?.[0]?.expectedOutputUSD

getTHORChainPools(period: PoolPeriod): Promise<PoolDetail[]>

const response = await SwapKitApi.getTHORChainPools("7d")

const btcPoolAPY = response.find(({ asset }) => asset === "BTC.BTC")?.poolAPY

getTHORNameDetails(thorname: string): Promise<THORNameDetails>

Returns array of thorname details.

const response = await SwapKitApi.getTHORNameDetails("t")

const owner = response?.owner

getTHORNamesByAddress(thorAddress: string): Promise<string[]>

Returns array of thornames assigned by address

const assignedThornames = await SwapKitApi.getTHORNamesByAddress("thor123")

getTHORNamesByOwner(thorAddress: string): Promise<string[]>

Returns array of thornames owned by address

const ownedThornames = await SwapKitApi.getTHORNamesByOwner("thor123")

getTokenList(tokenListProvider: string): Promise<TokensResponse>

const response = await SwapKitApi.getTokenList("Thorchain")

const { name, tokens } = response
const { address, chain, identifier, logoURL } = tokens[0]

getTokenListProviders(): Promise<TokenListProvidersResponse>

const response = await SwapKitApi.getTokenListProviders()
const providers = response?.map((tokenList) => tokenList.provider)

Type references

BorrowParams

type BorrowParams = {
  assetIn: string;
  assetOut: string;
  slippage: string;
  amount: string;
  senderAddress: string;
  recipientAddress: string;
};

BorrowResponse

type BorrowResponse = {
  amountIn: string;
  amountOut: string;
  amountOutMin: string;
  calldata: BorrowCalldata;
  complete: boolean;
  estimatedTime: number;
  expectedCollateralDeposited: string;
  expectedDebtIssued: string;
  expectedOutput: string;
  expectedOutputMaxSlippage: string;
  expectedOutputMaxSlippageUSD: string;
  expectedOutputUSD: string;
  fees: QuoteRoute["fees"];
  fromAsset: string;
  memo: string;
  recipientAddress: string;
  route: { meta: { 
    thornodeMeta: { inboundConfirmationSeconds: number; outboundDelay: number } 
  } };
  streamingSwap?: {
    estimatedTime: number;
    expectedCollateralDeposited: string;
    expectedDebtIssued: string;
    expectedOutput: string;
    expectedOutputMaxSlippage: string;
    expectedOutputMaxSlippageUSD: string;
    expectedOutputUSD: string;
    fees: QuoteRoute["fees"];
    memo: string;
  };
  swaps: QuoteRoute["swaps"];
  targetAddress: string;
  toAsset: string;
};

CachedPricesParams

type CachedPricesParams = {
  tokens: { identifier: string }[];
  metadata?: "true" | "false";
  lookup?: "true" | "false";
  sparkline?: "true" | "false";
};

CachedPrice

type CachedPrice = {
  identifier: string;
  price_usd: number;
  cg?: {
    id?: string;
    name?: string;
    market_cap?: number;
    total_volume?: number;
    price_change_24h_usd?: number;
    price_change_percentage_24h_usd?: number;
    sparkline_in_7d?: string;
    timestamp?: number;
  };
};

GasPriceInfo

type BorrowParams = {
  assetIn: string;
  assetOut: string;
  slippage: string;
  amount: string;
  senderAddress: string;
  recipientAddress: string;
};

InboundAddressesItem

type InboundAddressesItem = {
  address: string;
  chain: string;
  gas_rate?: string;
  halted: boolean;
  pub_key: string;
  router?: string;
};

ThornodeEndpointParams

type ThornodeEndpointParams = {
  type?: "thorchain" | "mayachain";
  stagenet?: boolean;
};

TokenListProvidersResponse

type TokenListProvidersResponse = Array<{
  provider: string;
  nbTokens: number;
}>;

TokensResponse

type TokensResponse = {
  keywords: string[];
  name: string;
  timestamp: string;
  version: { major: number; minor: number; patch: number };
  tokens: Array<{
    address?: string;
    chain: string;
    chainId: string;
    decimals?: number;
    identifier: string;
    logoURL?: string;
    ticker: string;
    tokenlist: string;
  }>
};

THORNameDetails

type THORNameDetails = {
  entries: Array<{ address: string; chain: string }>;
  owner: string;
  expire: string;
};

PoolDetail

 type PoolDetail = {
  annualPercentageRate: string;
  asset: string;
  assetDepth: string;
  assetPrice: string;
  assetPriceUSD: string;
  liquidityUnits: string;
  poolAPY: string;
  runeDepth: string;
  saversAPR: string;
  saversDepth: string;
  saversUnits: string;
  status: string;
  synthSupply: string;
  synthUnits: string;
  units: string;
  volume24h: string;
};

PoolPeriod

type PoolPeriod = "1h" | "24h" | "7d" | "30d" | "90d" | "100d" | "180d" | "365d";

QuoteRoute

type QuoteRoute = {
  approvalTarget?: string;
  approvalToken?: string;
  calldata: Calldata;
  complete?: boolean;
  contract?: string;
  contractInfo: string;
  contractMethod?: string;
  estimatedTime: number;
  evmTransactionDetails?: EVMTransactionDetails;
  expectedOutput: string;
  expectedOutputMaxSlippage: string;
  expectedOutputMaxSlippageUSD: string;
  expectedOutputUSD: string;
  fees: {
    [key in Chain]: Array<{
      type: string;
      asset: string;
      networkFee: number;
      networkFeeUSD: number;
      affiliateFee: number;
      affiliateFeeUSD: number;
      totalFee: number;
      totalFeeUSD: number;
      isOutOfPocket: boolean;
      slipFee?: number;
      slipFeeUSD?: number;
    }>;
  };
  inboundAddress: string;
  index: number;
  isPreferred?: boolean;
  meta: Meta;
  optimal: boolean;
  path: string;
  providers: string[];
  subProviders: string[];
  swaps: {
    [key: string]: Array<
      Array<{
        from: string;
        to: string;
        toTokenAddress: string;
        parts: { provider: string; percentage: number }[];
      }>
    >;
  };
  targetAddress: string;
  timeEstimates?: TimeEstimates;
  transaction?: Todo;
  streamingSwap?: {
    estimatedTime: number;
    fees: QuoteRoute["fees"];
    expectedOutput: string;
    expectedOutputMaxSlippage: string;
    expectedOutputUSD: string;
    expectedOutputMaxSlippageUSD: string;
    savingsInAsset: string;
    savingsInUSD: string;
    maxQuantity: number;
    maxIntervalForMaxQuantity: number;
  };
};

QuoteParams

type QuoteParams = {
  affiliateAddress?: string;
  affiliateBasisPoints?: string;
  buyAsset: string;
  isAffiliateFeeFlat?: string;
  recipientAddress?: string;
  sellAmount: string;
  sellAsset: string;
  senderAddress?: string;
  slippage: string;
};

LastBlockItem

type LastBlockItem = {
  chain: string;
  last_observed_in: number;
  last_signed_out: number;
  thorchain: number;
};

LendingAssetItem

type LendingAssetItem = {
  asset: string;
  assetDepthAssetAmount: string;
  runeDepthAssetAmount: string;
  loanCr: string;
  loanStatus: "GREEN" | "YELLOW" | "RED";
  loanCollateral: string;
  derivedDepthPercentage: string;
  filledPercentage: string;
  lendingAvailable: boolean;
  ltvPercentage: string;
};

LoansResponse

type LoansResponse = {
  owner: string
  asset: string;
  debtIssued: string;
  debtRepaid: string;
  debtCurrent: string;
  collateralCurrent: string;
  collateralDeposited: string;
  collateralWithdrawn: string;
  lastOpenHeight: number;
  ltvPercentage: string;
};

NodeItem

type NodeItem = {
  active_block_height: number;
  bond_address: string;
  current_award: string;
  forced_to_leave: boolean;
  ip_address: string;
  leave_height: number;
  node_address: string;
  requested_to_leave: boolean;
  signer_membership: string[];
  slash_points: number;
  status: string;
  status_since: number;
  total_bond: string;
  validator_cons_pub_key: string;
  version: string;
  jail: Todo;
  preflight_status: Todo;
  pub_key_set: Todo;
  observe_chains: {
    chain: string;
    height: number;
  }[];
};

Last updated