token.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import axios from "axios";
  2. import { KeyValueConfig, Storable } from "./base";
  3. export type TokenId = string;
  4. /**
  5. * A quantity of a token, represented as an integer number of the minimum denomination of the token.
  6. * This can also represent a quantity of an unknown token (represented by an undefined denom).
  7. */
  8. export type TokenQty = {
  9. amount: bigint;
  10. denom: TokenId | undefined;
  11. };
  12. /**
  13. * A token represents a cryptocurrency like ETH or BTC.
  14. * The main use of this class is to calculate the dollar value of accrued fees.
  15. */
  16. export class Token extends Storable {
  17. static type = "token";
  18. public constructor(
  19. public id: TokenId,
  20. // The hexadecimal pyth id of the tokens X/USD price feed
  21. // (get this from hermes or the Pyth docs page)
  22. public pythId: string | undefined,
  23. public decimals: number
  24. ) {
  25. super();
  26. }
  27. getId(): TokenId {
  28. return this.id;
  29. }
  30. getType(): string {
  31. return Token.type;
  32. }
  33. /**
  34. * Get the dollar value of 1 token. Returns undefined for tokens that do
  35. * not have a configured pricing method.
  36. */
  37. async getPrice(): Promise<number | undefined> {
  38. if (this.pythId) {
  39. const url = `https://hermes.pyth.network/v2/updates/price/latest?ids%5B%5D=${this.pythId}&parsed=true`;
  40. const response = await axios.get(url);
  41. const price = response.data.parsed[0].price;
  42. // Note that this conversion can lose some precision.
  43. // We don't really care about that in this application.
  44. return parseInt(price.price) * Math.pow(10, price.expo);
  45. } else {
  46. // We may support other pricing methodologies in the future but whatever.
  47. return undefined;
  48. }
  49. }
  50. /**
  51. * Get the dollar value of the minimum representable quantity of this token.
  52. * E.g., for ETH, this method will return the dollar value of 1 wei.
  53. */
  54. async getPriceForMinUnit(): Promise<number | undefined> {
  55. const price = await this.getPrice();
  56. return price ? price / Math.pow(10, this.decimals) : undefined;
  57. }
  58. toJson(): KeyValueConfig {
  59. return {
  60. id: this.id,
  61. ...(this.pythId !== undefined ? { pythId: this.pythId } : {}),
  62. };
  63. }
  64. static fromJson(parsed: {
  65. id: string;
  66. pythId?: string;
  67. decimals: number;
  68. }): Token {
  69. return new Token(parsed.id, parsed.pythId, parsed.decimals);
  70. }
  71. }