UNPKG

@coinbase/cdp-sdk

Version:

SDK for interacting with the Coinbase Developer Platform Wallet API

146 lines 4.91 kB
import { createPublicClient, createWalletClient, http, } from "viem"; import { toAccount } from "viem/accounts"; import * as chains from "viem/chains"; import { getBaseNodeRpcUrl } from "./getBaseNodeRpcUrl.js"; import { NETWORK_TO_CHAIN_MAP, resolveNetworkToChain } from "./networkToChainResolver.js"; import { UserInputValidationError } from "../../errors.js"; /** * Get a chain from the viem chains object * * @param id - The chain ID * @returns The chain */ function getChain(id) { const chainList = Object.values(chains); const found = chainList.find(chain => chain.id === id); if (!found) throw new Error(`Unsupported chain ID: ${id}`); return found; } /** * Determines if the input string is a network identifier or a Node URL * * @param input - The string to check * @returns True if the input is a network identifier, false otherwise */ function isNetworkIdentifier(input) { const normalizedInput = input.toLowerCase(); return NETWORK_TO_CHAIN_MAP[normalizedInput] !== undefined; } /** * Resolves a Node URL to a viem chain by making a getChainId call * * @param nodeUrl - The Node URL to resolve * @returns Promise resolving to the viem chain */ async function resolveNodeUrlToChain(nodeUrl) { // First validate that it's a proper URL if (!isValidUrl(nodeUrl)) { throw new UserInputValidationError(`Invalid URL format: ${nodeUrl}`); } // Create a temporary public client to get the chain ID const tempPublicClient = createPublicClient({ transport: http(nodeUrl), }); try { const chainId = await tempPublicClient.getChainId(); const chain = getChain(Number(chainId)); return chain; } catch (error) { throw new Error(`Failed to resolve chain ID from Node URL: ${error instanceof Error ? error.message : "Unknown error"}`); } } /** * Determines if the input string is a valid URL * * @param input - The string to validate as a URL * @returns True if the input is a valid URL, false otherwise */ function isValidUrl(input) { try { new URL(input); return true; } catch { return false; } } /** * Resolves viem clients based on a network identifier or Node URL. * * @param options - Configuration options * @param options.networkOrNodeUrl - Either a network identifier (e.g., "base", "base-sepolia") or a full Node URL * @param options.account - Optional account to use for the wallet client * @returns Promise resolving to an object containing the chain, publicClient, and walletClient * * @example * ```typescript * // Using network identifier * const clients = await resolveViemClients({ * networkOrNodeUrl: "base", * account: myAccount * }); * * // Using Node URL * const clients = await resolveViemClients({ * networkOrNodeUrl: "https://mainnet.base.org", * account: myAccount * }); * ``` */ export async function resolveViemClients(options) { const { networkOrNodeUrl } = options; let chain; // If it's a valid network identifier, use the mapping if (isNetworkIdentifier(networkOrNodeUrl)) { const rpcUrl = networkOrNodeUrl === "base" || networkOrNodeUrl === "base-sepolia" ? await getBaseNodeRpcUrl(networkOrNodeUrl) : undefined; chain = resolveNetworkToChain(networkOrNodeUrl); const publicClient = createPublicClient({ chain, transport: http(rpcUrl), }); const walletClient = createWalletClient({ account: toAccount(options.account), chain, transport: http(rpcUrl), }); return { chain, publicClient, walletClient, }; } // If it's not a valid network identifier, try to treat it as a Node URL try { chain = await resolveNodeUrlToChain(networkOrNodeUrl); const publicClient = createPublicClient({ chain, transport: http(networkOrNodeUrl), }); const walletClient = createWalletClient({ account: toAccount(options.account), chain, transport: http(networkOrNodeUrl), }); return { chain, publicClient, walletClient, }; } catch (error) { // If the error is from resolveNodeUrlToChain, re-throw it as-is if (error instanceof Error && (error.message.includes("Invalid URL format") || error.message.includes("Unsupported chain ID") || error.message.includes("Failed to resolve chain ID"))) { throw error; } // Otherwise, throw a generic error about unsupported input throw new UserInputValidationError(`Unsupported network identifier or invalid Node URL: ${networkOrNodeUrl}`); } } //# sourceMappingURL=resolveViemClients.js.map