From c61679bc8a4ba5281c8c7fd2820bcf44649d26da Mon Sep 17 00:00:00 2001 From: gregfromstl Date: Mon, 5 May 2025 22:25:39 -0700 Subject: [PATCH] feat: adds Bridge.chains function --- .changeset/free-lemons-find.md | 15 +++++ packages/thirdweb/src/bridge/Chains.test.ts | 28 ++++++++ packages/thirdweb/src/bridge/Chains.ts | 75 +++++++++++++++++++++ packages/thirdweb/src/bridge/index.ts | 2 + packages/thirdweb/src/bridge/types/Chain.ts | 40 +++++++++++ 5 files changed, 160 insertions(+) create mode 100644 .changeset/free-lemons-find.md create mode 100644 packages/thirdweb/src/bridge/Chains.test.ts create mode 100644 packages/thirdweb/src/bridge/Chains.ts create mode 100644 packages/thirdweb/src/bridge/types/Chain.ts diff --git a/.changeset/free-lemons-find.md b/.changeset/free-lemons-find.md new file mode 100644 index 00000000000..6ee62584ed5 --- /dev/null +++ b/.changeset/free-lemons-find.md @@ -0,0 +1,15 @@ +--- +"thirdweb": minor +--- + +feat(bridge): Add chains endpoint to retrieve Universal Bridge supported chains + +```typescript +import { Bridge } from "thirdweb"; + +const chains = await Bridge.chains({ + client: thirdwebClient, +}); +``` + +Returned chains include chain information such as chainId, name, icon, and nativeCurrency details. diff --git a/packages/thirdweb/src/bridge/Chains.test.ts b/packages/thirdweb/src/bridge/Chains.test.ts new file mode 100644 index 00000000000..80f42c8d67b --- /dev/null +++ b/packages/thirdweb/src/bridge/Chains.test.ts @@ -0,0 +1,28 @@ +import { describe, expect, it } from "vitest"; +import { TEST_CLIENT } from "~test/test-clients.js"; +import { chains } from "./Chains.js"; + +describe("chains", () => { + it("should fetch chains", async () => { + // Setup + const client = TEST_CLIENT; + + // Test + const result = await chains({ client }); + + // Verify + expect(result).toBeInstanceOf(Array); + + // Basic structure validation + if (result.length > 0) { + const chain = result[0]; + expect(chain).toHaveProperty("chainId"); + expect(chain).toHaveProperty("name"); + expect(chain).toHaveProperty("icon"); + expect(chain).toHaveProperty("nativeCurrency"); + expect(chain?.nativeCurrency).toHaveProperty("name"); + expect(chain?.nativeCurrency).toHaveProperty("symbol"); + expect(chain?.nativeCurrency).toHaveProperty("decimals"); + } + }); +}); diff --git a/packages/thirdweb/src/bridge/Chains.ts b/packages/thirdweb/src/bridge/Chains.ts new file mode 100644 index 00000000000..fb1f214738e --- /dev/null +++ b/packages/thirdweb/src/bridge/Chains.ts @@ -0,0 +1,75 @@ +import type { ThirdwebClient } from "../client/client.js"; +import { getClientFetch } from "../utils/fetch.js"; +import { UNIVERSAL_BRIDGE_URL } from "./constants.js"; +import type { Chain } from "./types/Chain.js"; + +/** + * Retrieves supported Universal Bridge chains. + * + * @example + * ```typescript + * import { Bridge } from "thirdweb"; + * + * const chains = await Bridge.chains({ + * client: thirdwebClient, + * }); + * ``` + * + * Returned chains might look something like: + * ```typescript + * [ + * { + * chainId: 1, + * name: "Ethereum", + * icon: "https://assets.thirdweb.com/chains/1.png", + * nativeCurrency: { + * name: "Ether", + * symbol: "ETH", + * decimals: 18 + * } + * }, + * { + * chainId: 137, + * name: "Polygon", + * icon: "https://assets.thirdweb.com/chains/137.png", + * nativeCurrency: { + * name: "MATIC", + * symbol: "MATIC", + * decimals: 18 + * } + * } + * ] + * ``` + * + * @param options - The options for fetching chains. + * @param options.client - Your thirdweb client. + * + * @returns A promise that resolves to an array of chains. + * + * @throws Will throw an error if there is an issue fetching the chains. + * @bridge + * @beta + */ +export async function chains(options: chains.Options): Promise { + const { client } = options; + + const clientFetch = getClientFetch(client); + const url = new URL(`${UNIVERSAL_BRIDGE_URL}/chains`); + + const response = await clientFetch(url.toString()); + if (!response.ok) { + const errorJson = await response.json(); + throw new Error(`${errorJson.code} | ${errorJson.message}`); + } + + const { data }: { data: Chain[] } = await response.json(); + return data; +} + +export declare namespace chains { + type Options = { + client: ThirdwebClient; + }; + + type Result = Chain[]; +} diff --git a/packages/thirdweb/src/bridge/index.ts b/packages/thirdweb/src/bridge/index.ts index cc978a43263..d5bd00cfc23 100644 --- a/packages/thirdweb/src/bridge/index.ts +++ b/packages/thirdweb/src/bridge/index.ts @@ -2,7 +2,9 @@ export * as Buy from "./Buy.js"; export * as Sell from "./Sell.js"; export { status } from "./Status.js"; export { routes } from "./Routes.js"; +export { chains } from "./Chains.js"; export type { Status } from "./types/Status.js"; export type { Route } from "./types/Route.js"; export type { Quote, PreparedQuote } from "./types/Quote.js"; +export type { Chain } from "./types/Chain.js"; diff --git a/packages/thirdweb/src/bridge/types/Chain.ts b/packages/thirdweb/src/bridge/types/Chain.ts new file mode 100644 index 00000000000..a3208126f8b --- /dev/null +++ b/packages/thirdweb/src/bridge/types/Chain.ts @@ -0,0 +1,40 @@ +/** + * Represents a blockchain chain in the Universal Bridge. + * @public + */ +export interface Chain { + /** + * The chain ID of the chain. + */ + chainId: number; + + /** + * The name of the chain. + */ + name: string; + + /** + * The URL of the chain's icon. + */ + icon: string; + + /** + * Information about the native currency of the chain. + */ + nativeCurrency: { + /** + * The name of the native currency. + */ + name: string; + + /** + * The symbol of the native currency. + */ + symbol: string; + + /** + * The number of decimals used by the native currency. + */ + decimals: number; + }; +}