diff --git a/.changeset/light-bikes-dance.md b/.changeset/light-bikes-dance.md new file mode 100644 index 0000000..3401c8d --- /dev/null +++ b/.changeset/light-bikes-dance.md @@ -0,0 +1,5 @@ +--- +"stackspulse": patch +--- + +Upgrade "@hirosystems/token-metadata-api-client" to v2. diff --git a/apps/web/package.json b/apps/web/package.json index 4febf5e..f15cfd7 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -11,7 +11,7 @@ }, "dependencies": { "@dotenvx/dotenvx": "1.15.0", - "@hirosystems/token-metadata-api-client": "1.3.0", + "@hirosystems/token-metadata-api-client": "2.0.0", "@radix-ui/themes": "3.0.5", "@sentry/nextjs": "8.33.1", "@stacks/stacks-blockchain-api-types": "7.14.1", diff --git a/apps/web/src/app/tokens/[token]/opengraph-image.tsx b/apps/web/src/app/tokens/[token]/opengraph-image.tsx index e6c4ac5..a672e06 100644 --- a/apps/web/src/app/tokens/[token]/opengraph-image.tsx +++ b/apps/web/src/app/tokens/[token]/opengraph-image.tsx @@ -1,5 +1,5 @@ import { env } from "@/env"; -import { stacksTokensApi } from "@/lib/stacks"; +import { tokenMetadataClient } from "@/lib/stacks"; import { notFound } from "next/navigation"; import { ImageResponse } from "next/og"; @@ -18,14 +18,17 @@ interface PageProps { } export default async function Image({ params }: PageProps) { - const tokenInfo = await stacksTokensApi - .getFtMetadata(params.token) - .catch((error) => { - if (error.status === 404) { - return null; - } - throw error; - }); + const metadata = await tokenMetadataClient.GET( + "/metadata/v1/ft/{principal}", + { + params: { + path: { + principal: params.token, + }, + }, + }, + ); + const tokenInfo = metadata?.data; if (!tokenInfo) { notFound(); } diff --git a/apps/web/src/app/tokens/[token]/page.tsx b/apps/web/src/app/tokens/[token]/page.tsx index 7939853..a4b74ff 100644 --- a/apps/web/src/app/tokens/[token]/page.tsx +++ b/apps/web/src/app/tokens/[token]/page.tsx @@ -2,7 +2,7 @@ import { TokenHoldersTable } from "@/components/Token/TokenHoldersTable"; import { TokenInfo } from "@/components/Token/TokenInfo"; import { TokenStats } from "@/components/Token/TokenStats"; import { TokenTransactionsVolume } from "@/components/Token/TokenTransactionsVolume"; -import { stacksTokensApi } from "@/lib/stacks"; +import { tokenMetadataClient } from "@/lib/stacks"; import { Container } from "@radix-ui/themes"; import type { Metadata } from "next"; import { notFound } from "next/navigation"; @@ -17,14 +17,17 @@ interface PageProps { export async function generateMetadata({ params, }: PageProps): Promise { - const tokenInfo = await stacksTokensApi - .getFtMetadata(params.token) - .catch((error) => { - if (error.status === 404) { - return null; - } - throw error; - }); + const metadata = await tokenMetadataClient.GET( + "/metadata/v1/ft/{principal}", + { + params: { + path: { + principal: params.token, + }, + }, + }, + ); + const tokenInfo = metadata?.data; if (!tokenInfo) { notFound(); } @@ -39,21 +42,22 @@ export async function generateMetadata({ } export default async function ProtocolPage({ params }: PageProps) { - const tokenInfo = await stacksTokensApi - .getFtMetadata(params.token) - .catch((error) => { - if (error.status === 404) { - return null; - } - throw error; - }); + const metadata = await tokenMetadataClient.GET( + "/metadata/v1/ft/{principal}", + { + params: { + path: { + principal: params.token, + }, + }, + }, + ); + const tokenInfo = metadata?.data; if (!tokenInfo) { notFound(); } - // TODO change once https://github.com/hirosystems/token-metadata-api/issues/268 is fixed - const token = (tokenInfo as unknown as { asset_identifier: string }) - .asset_identifier; + const token = tokenInfo.asset_identifier; return ( diff --git a/apps/web/src/components/Token/TokenHoldersTable.tsx b/apps/web/src/components/Token/TokenHoldersTable.tsx index a29fd29..dc0cec3 100644 --- a/apps/web/src/components/Token/TokenHoldersTable.tsx +++ b/apps/web/src/components/Token/TokenHoldersTable.tsx @@ -1,7 +1,7 @@ "use client"; import { useGetTokenHolders } from "@/hooks/api/useGetTokenHolders"; -import type { FtMetadataResponse } from "@hirosystems/token-metadata-api-client"; +import type { FtMetadataResponse } from "@/lib/stacks"; import { Card, Inset, Link, Separator, Table, Text } from "@radix-ui/themes"; interface TokenHoldersTableProps { diff --git a/apps/web/src/components/Token/TokenInfo.tsx b/apps/web/src/components/Token/TokenInfo.tsx index 8bc4bc1..70876e3 100644 --- a/apps/web/src/components/Token/TokenInfo.tsx +++ b/apps/web/src/components/Token/TokenInfo.tsx @@ -1,4 +1,4 @@ -import type { FtMetadataResponse } from "@hirosystems/token-metadata-api-client"; +import type { FtMetadataResponse } from "@/lib/stacks"; import { Heading, Text } from "@radix-ui/themes"; import Image from "next/image"; diff --git a/apps/web/src/components/Token/TokenStats.tsx b/apps/web/src/components/Token/TokenStats.tsx index b011646..e7fbfb4 100644 --- a/apps/web/src/components/Token/TokenStats.tsx +++ b/apps/web/src/components/Token/TokenStats.tsx @@ -1,7 +1,7 @@ "use client"; import { useGetTokenHolders } from "@/hooks/api/useGetTokenHolders"; -import type { FtMetadataResponse } from "@hirosystems/token-metadata-api-client"; +import type { FtMetadataResponse } from "@/lib/stacks"; import { Card, Text } from "@radix-ui/themes"; interface TokenStatsProps { diff --git a/apps/web/src/components/Token/TokenTransactionsVolume.tsx b/apps/web/src/components/Token/TokenTransactionsVolume.tsx index cec1103..ff0f4e6 100644 --- a/apps/web/src/components/Token/TokenTransactionsVolume.tsx +++ b/apps/web/src/components/Token/TokenTransactionsVolume.tsx @@ -1,7 +1,7 @@ "use client"; import { useGetTransactionVolume } from "@/hooks/api/useGetTransactionVolume"; -import type { FtMetadataResponse } from "@hirosystems/token-metadata-api-client"; +import type { FtMetadataResponse } from "@/lib/stacks"; import { Card, Inset, Separator, Text } from "@radix-ui/themes"; import { useMemo } from "react"; import { AreaChart } from "../ui/AreaChart"; diff --git a/apps/web/src/hooks/api/useGetFtMetadata.ts b/apps/web/src/hooks/api/useGetFtMetadata.ts index 46b348c..168b509 100644 --- a/apps/web/src/hooks/api/useGetFtMetadata.ts +++ b/apps/web/src/hooks/api/useGetFtMetadata.ts @@ -1,11 +1,7 @@ -import { TokensApi } from "@hirosystems/token-metadata-api-client"; +import { tokenMetadataClient } from "@/lib/stacks"; import { useQuery } from "@tanstack/react-query"; -const api = new TokensApi(); - -export const useGetFtMetadata = (params: { - principal: string; -}) => { +export const useGetFtMetadata = (params: { principal: string }) => { return useQuery({ queryKey: ["get-transactions", params.principal], queryFn: async () => { @@ -18,8 +14,18 @@ export const useGetFtMetadata = (params: { symbol: "STX", }; } - const result = await api.getFtMetadata(params.principal); - return result; + const metadata = await tokenMetadataClient.GET( + "/metadata/v1/ft/{principal}", + { + params: { + path: { + principal: params.principal, + }, + }, + }, + ); + const tokenInfo = metadata?.data; + return tokenInfo; }, }); }; diff --git a/apps/web/src/lib/stacks.ts b/apps/web/src/lib/stacks.ts index 61eacde..899ba5f 100644 --- a/apps/web/src/lib/stacks.ts +++ b/apps/web/src/lib/stacks.ts @@ -1,3 +1,14 @@ -import { TokensApi } from "@hirosystems/token-metadata-api-client"; +import { createClient } from "@hirosystems/token-metadata-api-client"; -export const stacksTokensApi = new TokensApi({}, "https://api.hiro.so", fetch); +export const tokenMetadataClient = createClient({ + baseUrl: "https://api.mainnet.hiro.so", +}); + +export interface FtMetadataResponse { + decimals?: number; + name?: string; + symbol?: string; + description?: string; + image_uri?: string; + image_thumbnail_uri?: string; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ffd3c3c..6341dc7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -83,8 +83,8 @@ importers: specifier: 1.15.0 version: 1.15.0 '@hirosystems/token-metadata-api-client': - specifier: 1.3.0 - version: 1.3.0 + specifier: 2.0.0 + version: 2.0.0 '@radix-ui/themes': specifier: 3.0.5 version: 3.0.5(@types/react-dom@18.3.0)(@types/react@18.3.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -588,8 +588,8 @@ packages: '@floating-ui/utils@0.2.7': resolution: {integrity: sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==} - '@hirosystems/token-metadata-api-client@1.3.0': - resolution: {integrity: sha512-tMdGa/IDcV7XFezUBbfhoYCEeuxR5U/TOzXSRF/eGdUvi7YZqD+wN355kfB+klRDxiYthatHSdu3eeoxGYHMMw==} + '@hirosystems/token-metadata-api-client@2.0.0': + resolution: {integrity: sha512-Y1M32/l6PmzNISKJzSRHF329DrwGRRogEwyNss5Cv/gRi8RrSyhwXRwYrPktIRQ/oL9bHKylgRwWMwZhwl75fQ==} '@humanwhocodes/config-array@0.11.14': resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} @@ -2305,6 +2305,9 @@ packages: '@types/node@22.7.4': resolution: {integrity: sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==} + '@types/node@22.7.5': + resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} + '@types/pg-pool@2.0.6': resolution: {integrity: sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ==} @@ -4031,9 +4034,6 @@ packages: resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} engines: {node: '>=16'} - isomorphic-fetch@3.0.0: - resolution: {integrity: sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==} - iterator.prototype@1.1.2: resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} @@ -4533,9 +4533,15 @@ packages: openapi-fetch@0.10.6: resolution: {integrity: sha512-6xXfvIEL/POtLGOaFPsp3O+pDe+J3DZYxbD9BrsQHXOTeNK8z/gsWHT6adUy1KcpQOhmkerMzlQrJM6DbN55dQ==} + openapi-fetch@0.12.2: + resolution: {integrity: sha512-ctMQ4LkkSWfIDUMuf1SYuPMsQ7ePcWAkYaMPW1lCDdk4WlV3Vulq1zoyGrwnFVvrBs5t7OOqNF+EKa8SAaovEA==} + openapi-typescript-helpers@0.0.11: resolution: {integrity: sha512-xofUHlVFq+BMquf3nh9I8N2guHckW6mrDO/F3kaFgrL7MGbjldDnQ9TIT+rkH/+H0LiuO+RuZLnNmsJwsjwUKg==} + openapi-typescript-helpers@0.0.13: + resolution: {integrity: sha512-z44WK2e7ygW3aUtAtiurfEACohf/Qt9g6BsejmIYgEoY4REHeRzgFJmO3ium0libsuzPc145I+8lE9aiiZrQvQ==} + openapi-typescript@6.7.6: resolution: {integrity: sha512-c/hfooPx+RBIOPM09GSxABOZhYPblDoyaGhqBkD/59vtpN21jEuWKDlM0KYTvqJVlSYjKs0tBcIdeXKChlSPtw==} hasBin: true @@ -5675,9 +5681,6 @@ packages: webpack-cli: optional: true - whatwg-fetch@3.6.20: - resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==} - whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} @@ -6247,11 +6250,9 @@ snapshots: '@floating-ui/utils@0.2.7': {} - '@hirosystems/token-metadata-api-client@1.3.0': + '@hirosystems/token-metadata-api-client@2.0.0': dependencies: - isomorphic-fetch: 3.0.0 - transitivePeerDependencies: - - encoding + openapi-fetch: 0.12.2 '@humanwhocodes/config-array@0.11.14': dependencies: @@ -8020,7 +8021,7 @@ snapshots: '@types/better-sqlite3@7.6.11': dependencies: - '@types/node': 22.7.4 + '@types/node': 22.7.5 optional: true '@types/bn.js@5.1.5': @@ -8085,13 +8086,18 @@ snapshots: dependencies: undici-types: 6.19.8 + '@types/node@22.7.5': + dependencies: + undici-types: 6.19.8 + optional: true + '@types/pg-pool@2.0.6': dependencies: '@types/pg': 8.6.1 '@types/pg@8.11.10': dependencies: - '@types/node': 22.7.4 + '@types/node': 22.7.5 pg-protocol: 1.7.0 pg-types: 4.0.2 optional: true @@ -9976,13 +9982,6 @@ snapshots: isexe@3.1.1: {} - isomorphic-fetch@3.0.0: - dependencies: - node-fetch: 2.7.0 - whatwg-fetch: 3.6.20 - transitivePeerDependencies: - - encoding - iterator.prototype@1.1.2: dependencies: define-properties: 1.2.1 @@ -10582,8 +10581,14 @@ snapshots: dependencies: openapi-typescript-helpers: 0.0.11 + openapi-fetch@0.12.2: + dependencies: + openapi-typescript-helpers: 0.0.13 + openapi-typescript-helpers@0.0.11: {} + openapi-typescript-helpers@0.0.13: {} + openapi-typescript@6.7.6: dependencies: ansi-colors: 4.1.3 @@ -11822,8 +11827,6 @@ snapshots: - esbuild - uglify-js - whatwg-fetch@3.6.20: {} - whatwg-url@5.0.0: dependencies: tr46: 0.0.3