UNPKG

@atomiqlabs/sdk-lib

Version:

Basic SDK functionality library for atomiq

142 lines (125 loc) 4.45 kB
import {ISwapPrice} from "../prices/abstract/ISwapPrice"; export type BtcToken<L = boolean> = { chain: "BTC", lightning: L, ticker: L extends true ? "BTCLN" : "BTC", decimals: 8, name: L extends true ? "Bitcoin (lightning L2)" : "Bitcoin (on-chain L1)", displayDecimals?: number }; export function isBtcToken(obj: any): obj is BtcToken { return typeof(obj)==="object" && obj.chain==="BTC" && typeof(obj.lightning)==="boolean" && typeof(obj.ticker)==="string" && typeof(obj.decimals)==="number" && typeof(obj.name)==="string"; } export const BitcoinTokens: { BTC: BtcToken<false>, BTCLN: BtcToken<true> } = { BTC: { chain: "BTC", lightning: false, ticker: "BTC", decimals: 8, name: "Bitcoin (on-chain L1)" }, BTCLN: { chain: "BTC", lightning: true, ticker: "BTCLN", decimals: 8, name: "Bitcoin (lightning L2)" } }; export type SCToken<ChainIdentifier extends string = string> = { chain: "SC", chainId: ChainIdentifier, address: string, ticker: string, decimals: number, displayDecimals?: number, name: string } export function isSCToken(obj: any): obj is SCToken { return typeof(obj)==="object" && obj.chain==="SC" && typeof(obj.chainId)==="string" && typeof(obj.address)==="string" && typeof(obj.ticker)==="string" && typeof(obj.decimals)==="number" && typeof(obj.name)==="string"; } export type Token<ChainIdentifier extends string = string> = BtcToken | SCToken<ChainIdentifier>; export function isToken(obj: any): obj is Token { return isBtcToken(obj) || isSCToken(obj); } export type TokenAmount< ChainIdentifier extends string = string, T extends Token<ChainIdentifier> = Token<ChainIdentifier> > = { rawAmount: bigint, amount: string, _amount: number, token: T, usdValue: (abortSignal?: AbortSignal, preFetchedUsdPrice?: number) => Promise<number> }; export function fromDecimal(amount: string, decimalCount: number) { if(amount.includes(".")) { const [before, after] = amount.split("."); if(decimalCount<0) { return BigInt(before.substring(0, before.length+decimalCount)); } if(after.length>decimalCount) { //Cut the last digits return BigInt((before==="0" ? "" : before)+after.substring(0, decimalCount)); } return BigInt((before==="0" ? "" : before)+after.padEnd(decimalCount, "0")); } else { if(decimalCount<0) { return BigInt(amount.substring(0, amount.length+decimalCount)); } else { return BigInt(amount+"0".repeat(decimalCount)); } } } export function toDecimal(amount: bigint, decimalCount: number, cut?: boolean, displayDecimals?: number) { if(decimalCount<=0) { return amount.toString(10)+"0".repeat(-decimalCount); } const amountStr = amount.toString(10).padStart(decimalCount+1, "0"); const splitPoint = amountStr.length-decimalCount; const decimalPart = amountStr.substring(splitPoint, amountStr.length); let cutTo = decimalPart.length; if(cut && cutTo>0) { for(let i=decimalPart.length-1;i--;i>=0) { if(decimalPart.charAt(i)==="0") { cutTo = i; } else break; } if(cutTo===0) cutTo = 1; } if(displayDecimals===0) return amountStr.substring(0, splitPoint); if(displayDecimals!=null && cutTo > displayDecimals) cutTo = displayDecimals; return amountStr.substring(0, splitPoint)+"."+decimalPart.substring(0, cutTo); } export function toTokenAmount< ChainIdentifier extends string = string, T extends Token<ChainIdentifier> = Token<ChainIdentifier> >( amount: bigint, token: T, prices: ISwapPrice ): TokenAmount<ChainIdentifier, T> { let amountStr = toDecimal(amount, token.decimals, undefined, token.displayDecimals); return { rawAmount: amount, amount: amountStr, _amount: parseFloat(amountStr), token, usdValue: (abortSignal?: AbortSignal, preFetchedUsdPrice?: number) => prices.getUsdValue(amount, token, abortSignal, preFetchedUsdPrice) }; }