From c63fefda51eedc08d21887917c33f2a1990f709b Mon Sep 17 00:00:00 2001 From: kien-ngo Date: Tue, 5 Nov 2024 01:38:45 +0000 Subject: [PATCH] [SDK] Add tests for chain utils (#5280) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Problem solved Short description of the bug fixed or feature added --- ## PR-Codex overview This PR enhances the `CUSTOM_CHAIN_MAP` and `convertLegacyChain` function to be exported for testing purposes. It also adds new tests for chain handling, including legacy chain conversion and caching functionality. ### Detailed summary - Exported `CUSTOM_CHAIN_MAP` for testing. - Exported `convertLegacyChain` function. - Added a `legacyChain` object for testing. - Created tests for: - `getChainSymbol` - `getChainDecimals` - `getChainNativeCurrencyName` - `convertLegacyChain` - `defineChain` with a legacy chain. - Caching functionality with `cacheChains`. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` --- packages/thirdweb/src/chains/utils.test.ts | 123 +++++++++++++++++++++ packages/thirdweb/src/chains/utils.ts | 10 +- 2 files changed, 131 insertions(+), 2 deletions(-) diff --git a/packages/thirdweb/src/chains/utils.test.ts b/packages/thirdweb/src/chains/utils.test.ts index a57f7dd990b..7d63d148ade 100644 --- a/packages/thirdweb/src/chains/utils.test.ts +++ b/packages/thirdweb/src/chains/utils.test.ts @@ -3,12 +3,18 @@ import { describe, expect, it } from "vitest"; import { ANVIL_CHAIN } from "../../test/src/chains.js"; import { TEST_CLIENT } from "../../test/src/test-clients.js"; import { ANVIL_PKEY_A, TEST_ACCOUNT_B } from "../../test/src/test-wallets.js"; +import { scroll } from "../chains/chain-definitions/scroll.js"; import { getRpcClient, prepareTransaction } from "../exports/thirdweb.js"; import { toSerializableTransaction } from "../transaction/actions/to-serializable-transaction.js"; import { privateKeyToAccount } from "../wallets/private-key.js"; import { avalanche } from "./chain-definitions/avalanche.js"; import { ethereum } from "./chain-definitions/ethereum.js"; +import type { LegacyChain } from "./types.js"; + import { + CUSTOM_CHAIN_MAP, + cacheChains, + convertLegacyChain, defineChain, getCachedChain, getChainDecimals, @@ -16,6 +22,50 @@ import { getChainSymbol, } from "./utils.js"; +const legacyChain: LegacyChain = { + chain: "ETH", + chainId: 1, + ens: { + registry: "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", + }, + explorers: [ + { + name: "etherscan", + url: "https://etherscan.io", + standard: "EIP3091", + }, + ], + faucets: [], + features: [ + { + name: "EIP155", + }, + { + name: "EIP1559", + }, + ], + icon: { + url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/ethereum/512.png", + width: 512, + height: 512, + format: "png", + }, + infoURL: "https://ethereum.org", + name: "Ethereum Mainnet", + nativeCurrency: { + name: "Ether", + symbol: "ETH", + decimals: 18, + }, + networkId: 1, + redFlags: [], + rpc: ["https://1.rpc.thirdweb.com/${THIRDWEB_API_KEY}"], + shortName: "eth", + slip44: 60, + slug: "ethereum", + testnet: false, +}; + describe("defineChain", () => { it("should convert viem chain to thirdweb chain", () => { const zoraViem = viemChain({ @@ -114,4 +164,77 @@ describe("defineChain", () => { const ethResult = await getChainNativeCurrencyName(ethereum); expect(ethResult).toBe("Ether"); }); + + it("getChainSymbol should work for chain object without symbol", async () => { + const chain = defineChain(1); + expect(await getChainSymbol(chain)).toBe("ETH"); + }); + + it("getChainDecimals should work for chain object without decimals", async () => { + const chain = defineChain(1); + expect(await getChainDecimals(chain)).toBe(18); + }); + + it("getChainDecimals should return `18` if fails to resolve chain decimals", async () => { + const nonExistentChain = defineChain(-1); + expect(await getChainDecimals(nonExistentChain)).toBe(18); + }); + + it("getChainNativeCurrencyName should work for chain object without nativeCurrency", async () => { + const chain = defineChain(1); + expect(await getChainNativeCurrencyName(chain)).toBe("Ether"); + }); + + it("should convert LegacyChain", () => { + expect(convertLegacyChain(legacyChain)).toStrictEqual({ + id: 1, + name: "Ethereum Mainnet", + rpc: "https://1.rpc.thirdweb.com/${THIRDWEB_API_KEY}", + blockExplorers: [ + { + name: "etherscan", + url: "https://etherscan.io", + apiUrl: "https://etherscan.io", + }, + ], + nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 }, + faucets: [], + icon: { + url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/ethereum/512.png", + width: 512, + height: 512, + format: "png", + }, + testnet: undefined, + }); + }); + + it("`defineChain` should work with Legacy chain", () => { + expect(defineChain(legacyChain)).toStrictEqual({ + id: 1, + name: "Ethereum Mainnet", + rpc: "https://1.rpc.thirdweb.com/${THIRDWEB_API_KEY}", + blockExplorers: [ + { + name: "etherscan", + url: "https://etherscan.io", + apiUrl: "https://etherscan.io", + }, + ], + nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 }, + faucets: [], + icon: { + url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/ethereum/512.png", + width: 512, + height: 512, + format: "png", + }, + testnet: undefined, + }); + }); + + it("should cache chains properly", () => { + cacheChains([scroll]); + expect(CUSTOM_CHAIN_MAP.get(scroll.id)).toStrictEqual(scroll); + }); }); diff --git a/packages/thirdweb/src/chains/utils.ts b/packages/thirdweb/src/chains/utils.ts index 5ce4eefa70d..2615f7b0c9e 100644 --- a/packages/thirdweb/src/chains/utils.ts +++ b/packages/thirdweb/src/chains/utils.ts @@ -10,7 +10,10 @@ import type { LegacyChain, } from "./types.js"; -const CUSTOM_CHAIN_MAP = new Map(); +/** + * @internal Exported for tests + */ +export const CUSTOM_CHAIN_MAP = new Map(); /** * Defines a chain with the given options. @@ -98,7 +101,10 @@ function isLegacyChain( return "rpc" in chain && Array.isArray(chain.rpc) && "slug" in chain; } -function convertLegacyChain(legacyChain: LegacyChain): Chain { +/** + * @internal + */ +export function convertLegacyChain(legacyChain: LegacyChain): Chain { const RPC_URL = getThirdwebDomains().rpc; return { id: legacyChain.chainId,