pyth.ts 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import { parse } from "superjson";
  2. import { z } from "zod";
  3. import { DEFAULT_CACHE_TTL } from "../cache";
  4. import { VERCEL_REQUEST_HEADERS } from "../config/server";
  5. import { getHost } from "../get-host";
  6. import { Cluster, ClusterToName, priceFeedsSchema } from "../services/pyth";
  7. export async function getPublishersForFeedRequest(
  8. cluster: Cluster,
  9. symbol: string,
  10. ) {
  11. const url = new URL(
  12. `/api/pyth/get-publishers/${encodeURIComponent(symbol)}`,
  13. await getHost(),
  14. );
  15. url.searchParams.set("cluster", ClusterToName[cluster]);
  16. const data = await fetch(url, {
  17. next: {
  18. revalidate: DEFAULT_CACHE_TTL,
  19. },
  20. headers: VERCEL_REQUEST_HEADERS,
  21. });
  22. const parsedData: unknown = await data.json();
  23. return z.array(z.string()).parse(parsedData);
  24. }
  25. export async function getFeedsForPublisherRequest(
  26. cluster: Cluster,
  27. publisher: string,
  28. ) {
  29. const url = new URL(
  30. `/api/pyth/get-feeds-for-publisher/${encodeURIComponent(publisher)}`,
  31. await getHost(),
  32. );
  33. url.searchParams.set("cluster", ClusterToName[cluster]);
  34. const data = await fetch(url, {
  35. next: {
  36. revalidate: DEFAULT_CACHE_TTL,
  37. },
  38. headers: VERCEL_REQUEST_HEADERS,
  39. });
  40. const rawData = await data.text();
  41. const parsedData = parse(rawData);
  42. return priceFeedsSchema.parse(parsedData);
  43. }
  44. export const getFeedsRequest = async (cluster: Cluster) => {
  45. const url = new URL(`/api/pyth/get-feeds`, await getHost());
  46. url.searchParams.set("cluster", ClusterToName[cluster]);
  47. url.searchParams.set("excludePriceComponents", "true");
  48. const data = await fetch(url, {
  49. next: {
  50. revalidate: DEFAULT_CACHE_TTL,
  51. },
  52. headers: VERCEL_REQUEST_HEADERS,
  53. });
  54. const rawData = await data.text();
  55. const parsedData = parse(rawData);
  56. return priceFeedsSchema.element
  57. .omit({ price: true })
  58. .array()
  59. .parse(parsedData);
  60. };
  61. export const getFeedForSymbolRequest = async ({
  62. symbol,
  63. cluster = Cluster.Pythnet,
  64. }: {
  65. symbol: string;
  66. cluster?: Cluster;
  67. }): Promise<z.infer<typeof priceFeedsSchema.element> | undefined> => {
  68. const url = new URL(
  69. `/api/pyth/get-feeds/${encodeURIComponent(symbol)}`,
  70. await getHost(),
  71. );
  72. url.searchParams.set("cluster", ClusterToName[cluster]);
  73. const data = await fetch(url, {
  74. next: {
  75. revalidate: DEFAULT_CACHE_TTL,
  76. },
  77. headers: VERCEL_REQUEST_HEADERS,
  78. });
  79. if (!data.ok) {
  80. return undefined;
  81. }
  82. const rawData = await data.text();
  83. const parsedData = parse(rawData);
  84. return priceFeedsSchema.element.parse(parsedData);
  85. };