import axios from "axios"; import { KeyValueConfig, Storable } from "./base"; export type TokenId = string; /** * A quantity of a token, represented as an integer number of the minimum denomination of the token. * This can also represent a quantity of an unknown token (represented by an undefined denom). */ export type TokenQty = { amount: bigint; denom: TokenId | undefined; }; /** * A token represents a cryptocurrency like ETH or BTC. * The main use of this class is to calculate the dollar value of accrued fees. */ export class Token extends Storable { static type = "token"; public constructor( public id: TokenId, // The hexadecimal pyth id of the tokens X/USD price feed // (get this from hermes or the Pyth docs page) public pythId: string | undefined, public decimals: number ) { super(); } getId(): TokenId { return this.id; } getType(): string { return Token.type; } /** * Get the dollar value of 1 token. Returns undefined for tokens that do * not have a configured pricing method. */ async getPrice(): Promise { if (this.pythId) { const url = `https://hermes.pyth.network/v2/updates/price/latest?ids%5B%5D=${this.pythId}&parsed=true`; const response = await axios.get(url); const price = response.data.parsed[0].price; // Note that this conversion can lose some precision. // We don't really care about that in this application. return parseInt(price.price) * Math.pow(10, price.expo); } else { // We may support other pricing methodologies in the future but whatever. return undefined; } } /** * Get the dollar value of the minimum representable quantity of this token. * E.g., for ETH, this method will return the dollar value of 1 wei. */ async getPriceForMinUnit(): Promise { const price = await this.getPrice(); return price ? price / Math.pow(10, this.decimals) : undefined; } toJson(): KeyValueConfig { return { id: this.id, ...(this.pythId !== undefined ? { pythId: this.pythId } : {}), }; } static fromJson(parsed: { id: string; pythId?: string; decimals: number; }): Token { return new Token(parsed.id, parsed.pythId, parsed.decimals); } }