{"version":3,"sources":["../src/registry.ts"],"sourcesContent":["/**\n * @file Chain and token registry for the 1auth SDK.\n *\n * Wraps `@rhinestone/shared-configs` chain/token data and combines it with\n * viem's chain definitions to expose a filtered, testnet-aware registry.\n * Consumers can look up supported chains and tokens, resolve token addresses\n * by symbol, and retrieve chain metadata such as explorer URLs and default RPC\n * endpoints.\n *\n * Testnet inclusion is controlled by the `includeTestnets` option on each\n * function or, as a project-wide default, by the environment variables\n * `NEXT_PUBLIC_ORCHESTRATOR_USE_TESTNETS` or `ORCHESTRATOR_USE_TESTNETS`.\n */\n\nimport type { Address, Chain } from \"viem\";\nimport { isAddress } from \"viem\";\nimport * as viemChains from \"viem/chains\";\nimport { chainRegistry } from \"@rhinestone/shared-configs\";\n\nexport type TokenConfig = {\n  symbol: string;\n  address: Address;\n  decimals: number;\n};\n\nexport type ChainFilterOptions = {\n  includeTestnets?: boolean;\n  chainIds?: number[];\n};\n\ntype ChainRegistryEntry = (typeof chainRegistry)[keyof typeof chainRegistry];\n\nconst env: Record<string, string | undefined> =\n  typeof process !== \"undefined\" ? process.env : {};\n\n// Build a chain-ID-to-Chain map from viem, resolving collisions by preferring\n// mainnet definitions over testnets. viem exports duplicate numeric IDs (e.g.\n// zoraTestnet and hyperEvm both use 999); a naive Map would silently keep\n// whichever entry happens to appear last in iteration order, which may be the\n// testnet. The loop below only overwrites an existing entry when the incoming\n// chain is NOT a testnet and the existing one IS, ensuring the production chain\n// always wins while still falling back to a testnet entry when no mainnet\n// definition exists for a given ID.\nconst VIEM_CHAIN_BY_ID = new Map<number, Chain>();\nfor (const value of Object.values(viemChains)) {\n  if (typeof value !== \"object\" || value === null || !(\"id\" in value) || !(\"name\" in value)) continue;\n  const chain = value as Chain;\n  const existing = VIEM_CHAIN_BY_ID.get(chain.id);\n  if (!existing || (existing.testnet && !chain.testnet)) {\n    VIEM_CHAIN_BY_ID.set(chain.id, chain);\n  }\n}\n\nfunction isEvmRegistryEntry(\n  entry: ChainRegistryEntry | undefined,\n): entry is ChainRegistryEntry & { vmType: \"evm\" } {\n  return entry?.vmType === \"evm\";\n}\n\nfunction getEvmRegistryEntry(\n  chainId: number,\n): (ChainRegistryEntry & { vmType: \"evm\" }) | undefined {\n  const entry = chainRegistry[String(chainId) as keyof typeof chainRegistry];\n  return isEvmRegistryEntry(entry) ? entry : undefined;\n}\n\n// The shared-configs registry includes non-EVM chains (Solana, Tron). Filter\n// to EVM entries before exposing supported chains — downstream consumers\n// (viem clients, wallet_getCapabilities, RPC proxy) only handle eip155 chains.\nconst REGISTRY_CHAIN_IDS = Object.entries(chainRegistry)\n  .filter(([, entry]) => isEvmRegistryEntry(entry))\n  .map(([id]) => Number(id));\nconst SUPPORTED_CHAIN_IDS = new Set(REGISTRY_CHAIN_IDS);\n\nfunction tokensForChain(chainId: number): TokenConfig[] {\n  const entry = getEvmRegistryEntry(chainId);\n  if (!entry) return [];\n  return entry.tokens.map((token) => ({\n    symbol: token.symbol,\n    address: token.address as Address,\n    decimals: token.decimals,\n  }));\n}\n\n/** Treat any 20-byte hex string as an address; checksum casing is optional for user inputs. */\nfunction isAddressInput(value: string): value is Address {\n  return isAddress(value, { strict: false });\n}\n\n/**\n * Parse a string environment variable into a boolean, returning `undefined`\n * when the value is absent or not a recognised truthy/falsy literal.\n *\n * Accepted truthy values: `\"true\"`, `\"1\"`.\n * Accepted falsy values: `\"false\"`, `\"0\"`.\n */\nfunction parseBool(value?: string): boolean | undefined {\n  if (value === \"true\" || value === \"1\") return true;\n  if (value === \"false\" || value === \"0\") return false;\n  return undefined;\n}\n\n/**\n * Determine whether testnet chains should be included in registry results.\n *\n * Precedence (highest to lowest):\n * 1. `explicit` argument — a caller-supplied boolean always wins.\n * 2. `NEXT_PUBLIC_ORCHESTRATOR_USE_TESTNETS` env var — checked first so\n *    Next.js browser bundles (which only expose `NEXT_PUBLIC_*` variables)\n *    can configure testnet mode without a server-side env var.\n * 3. `ORCHESTRATOR_USE_TESTNETS` env var — server-side / Node.js fallback.\n * 4. Defaults to `false` (testnets excluded) when none of the above is set.\n */\nfunction resolveIncludeTestnets(explicit?: boolean): boolean {\n  if (explicit !== undefined) return explicit;\n  const envValue =\n    parseBool(env.NEXT_PUBLIC_ORCHESTRATOR_USE_TESTNETS) ??\n    parseBool(env.ORCHESTRATOR_USE_TESTNETS);\n  return envValue ?? false;\n}\n\nfunction applyChainFilters(chainIds: number[], options?: ChainFilterOptions): number[] {\n  const includeTestnets = resolveIncludeTestnets(options?.includeTestnets);\n  const allowlist = options?.chainIds;\n  let filtered = chainIds;\n\n  if (!includeTestnets) {\n    filtered = filtered.filter((chainId) => !isTestnet(chainId));\n  }\n\n  if (allowlist) {\n    const allowed = new Set(allowlist);\n    filtered = filtered.filter((chainId) => allowed.has(chainId));\n  }\n\n  return filtered;\n}\n\nexport function getSupportedChainIds(options?: ChainFilterOptions): number[] {\n  return applyChainFilters(REGISTRY_CHAIN_IDS, options);\n}\n\nexport function getSupportedChains(options?: ChainFilterOptions): Chain[] {\n  return getSupportedChainIds(options)\n    .map((chainId) => VIEM_CHAIN_BY_ID.get(chainId))\n    .filter((chain): chain is Chain => Boolean(chain));\n}\n\nexport function getAllSupportedChainsAndTokens(options?: ChainFilterOptions): Array<{\n  chainId: number;\n  tokens: TokenConfig[];\n}> {\n  return getSupportedChainIds(options).map((chainId) => ({\n    chainId,\n    tokens: tokensForChain(chainId),\n  }));\n}\n\nexport function getChainById(chainId: number): Chain {\n  if (!SUPPORTED_CHAIN_IDS.has(chainId)) {\n    throw new Error(`Unsupported chain ID: ${chainId}`);\n  }\n  const chain = VIEM_CHAIN_BY_ID.get(chainId);\n  if (!chain) {\n    throw new Error(`Unsupported chain ID: ${chainId}`);\n  }\n  return chain;\n}\n\nexport function getChainName(chainId: number): string {\n  try {\n    return getChainById(chainId).name;\n  } catch {\n    return `Chain ${chainId}`;\n  }\n}\n\nexport function getChainExplorerUrl(chainId: number): string | undefined {\n  try {\n    return getChainById(chainId).blockExplorers?.default?.url;\n  } catch {\n    return undefined;\n  }\n}\n\nexport function getChainRpcUrl(chainId: number): string | undefined {\n  try {\n    const chain = getChainById(chainId);\n    return chain.rpcUrls?.default?.http?.[0] || chain.rpcUrls?.public?.http?.[0];\n  } catch {\n    return undefined;\n  }\n}\n\nexport function getSupportedTokens(chainId: number): TokenConfig[] {\n  return tokensForChain(chainId);\n}\n\nexport function getSupportedTokenSymbols(chainId: number): string[] {\n  return getSupportedTokens(chainId).map((token) => token.symbol);\n}\n\nexport function getTokenAddress(symbolOrAddress: string, chainId: number): Address {\n  if (isAddressInput(symbolOrAddress)) {\n    return symbolOrAddress;\n  }\n  const match = getSupportedTokens(chainId).find(\n    (t) => t.symbol.toUpperCase() === symbolOrAddress.toUpperCase()\n  );\n  if (!match) {\n    throw new Error(`Unsupported token \"${symbolOrAddress}\" on chain ${chainId}`);\n  }\n  return match.address;\n}\n\nexport function getTokenDecimals(symbolOrAddress: string, chainId: number): number {\n  const match = getSupportedTokens(chainId).find(\n    (t) =>\n      isAddressInput(symbolOrAddress)\n        ? t.address.toLowerCase() === symbolOrAddress.toLowerCase()\n        : t.symbol.toUpperCase() === symbolOrAddress.toUpperCase()\n  );\n  if (!match && isAddressInput(symbolOrAddress) && SUPPORTED_CHAIN_IDS.has(chainId)) {\n    return 18;\n  }\n  if (!match) {\n    throw new Error(`Unsupported token \"${symbolOrAddress}\" on chain ${chainId}`);\n  }\n  return match.decimals;\n}\n\nexport function resolveTokenAddress(token: string, chainId: number): Address {\n  if (isAddressInput(token)) {\n    return token;\n  }\n  return getTokenAddress(token, chainId);\n}\n\nexport function isTestnet(chainId: number): boolean {\n  try {\n    return getChainById(chainId).testnet ?? false;\n  } catch {\n    return false;\n  }\n}\n\nexport function getTokenSymbol(tokenAddress: Address, chainId: number): string {\n  const token = getSupportedTokens(chainId).find(\n    (entry) => entry.address.toLowerCase() === tokenAddress.toLowerCase()\n  );\n  if (token) {\n    return token.symbol;\n  }\n  if (!SUPPORTED_CHAIN_IDS.has(chainId)) {\n    throw new Error(`Unsupported chain ID: ${chainId}`);\n  }\n  return \"Token\";\n}\n\nexport function isTokenAddressSupported(tokenAddress: Address, chainId: number): boolean {\n  return isAddressInput(tokenAddress) && SUPPORTED_CHAIN_IDS.has(chainId);\n}\n"],"mappings":"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","names":[]}