@@ -2539,6 +2539,95 @@ class TempoTestnet extends Testnet implements EthereumNetwork {
25392539 tokenOperationHashPrefix = '42431' ;
25402540}
25412541
2542+ /**
2543+ * Constructor options for {@link DynamicNetwork}.
2544+ * Accepts string-typed `type` and `family` so AMS JSON can be passed directly.
2545+ * Fields mirror BaseNetwork + AccountNetwork + EthereumNetwork.
2546+ */
2547+ export interface DynamicNetworkOptions {
2548+ // BaseNetwork
2549+ name : string ;
2550+ type : string ;
2551+ family : string ;
2552+ explorerUrl ?: string ;
2553+ // AccountNetwork
2554+ accountExplorerUrl ?: string ;
2555+ blockExplorerUrl ?: string ;
2556+ // EthereumNetwork
2557+ chainId ?: number ;
2558+ batcherContractAddress ?: string ;
2559+ forwarderFactoryAddress ?: string ;
2560+ forwarderImplementationAddress ?: string ;
2561+ walletFactoryAddress ?: string ;
2562+ walletImplementationAddress ?: string ;
2563+ walletV2FactoryAddress ?: string ;
2564+ walletV2ImplementationAddress ?: string ;
2565+ walletV4FactoryAddress ?: string ;
2566+ walletV4ImplementationAddress ?: string ;
2567+ walletV2ForwarderFactoryAddress ?: string ;
2568+ walletV2ForwarderImplementationAddress ?: string ;
2569+ walletV4ForwarderFactoryAddress ?: string ;
2570+ walletV4ForwarderImplementationAddress ?: string ;
2571+ nativeCoinOperationHashPrefix ?: string ;
2572+ tokenOperationHashPrefix ?: string ;
2573+ }
2574+
2575+ /**
2576+ * Concrete network class for AMS-discovered chains not yet registered in local statics.
2577+ * Accepts string-typed type/family and casts to enums internally (safe since both are string enums).
2578+ * Currently covers BaseNetwork + AccountNetwork + EthereumNetwork fields.
2579+ */
2580+ export class DynamicNetwork extends BaseNetwork {
2581+ public readonly name : string ;
2582+ public readonly type : NetworkType ;
2583+ public readonly family : CoinFamily ;
2584+ public readonly explorerUrl : string | undefined ;
2585+ public readonly accountExplorerUrl ?: string ;
2586+ public readonly blockExplorerUrl ?: string ;
2587+ public readonly chainId ?: number ;
2588+ public readonly batcherContractAddress ?: string ;
2589+ public readonly forwarderFactoryAddress ?: string ;
2590+ public readonly forwarderImplementationAddress ?: string ;
2591+ public readonly walletFactoryAddress ?: string ;
2592+ public readonly walletImplementationAddress ?: string ;
2593+ public readonly walletV2FactoryAddress ?: string ;
2594+ public readonly walletV2ImplementationAddress ?: string ;
2595+ public readonly walletV4FactoryAddress ?: string ;
2596+ public readonly walletV4ImplementationAddress ?: string ;
2597+ public readonly walletV2ForwarderFactoryAddress ?: string ;
2598+ public readonly walletV2ForwarderImplementationAddress ?: string ;
2599+ public readonly walletV4ForwarderFactoryAddress ?: string ;
2600+ public readonly walletV4ForwarderImplementationAddress ?: string ;
2601+ public readonly nativeCoinOperationHashPrefix ?: string ;
2602+ public readonly tokenOperationHashPrefix ?: string ;
2603+
2604+ constructor ( options : DynamicNetworkOptions ) {
2605+ super ( ) ;
2606+ this . name = options . name ;
2607+ this . type = options . type as NetworkType ;
2608+ this . family = options . family as CoinFamily ;
2609+ this . explorerUrl = options . explorerUrl ;
2610+ this . accountExplorerUrl = options . accountExplorerUrl ;
2611+ this . blockExplorerUrl = options . blockExplorerUrl ;
2612+ this . chainId = options . chainId ;
2613+ this . batcherContractAddress = options . batcherContractAddress ;
2614+ this . forwarderFactoryAddress = options . forwarderFactoryAddress ;
2615+ this . forwarderImplementationAddress = options . forwarderImplementationAddress ;
2616+ this . walletFactoryAddress = options . walletFactoryAddress ;
2617+ this . walletImplementationAddress = options . walletImplementationAddress ;
2618+ this . walletV2FactoryAddress = options . walletV2FactoryAddress ;
2619+ this . walletV2ImplementationAddress = options . walletV2ImplementationAddress ;
2620+ this . walletV4FactoryAddress = options . walletV4FactoryAddress ;
2621+ this . walletV4ImplementationAddress = options . walletV4ImplementationAddress ;
2622+ this . walletV2ForwarderFactoryAddress = options . walletV2ForwarderFactoryAddress ;
2623+ this . walletV2ForwarderImplementationAddress = options . walletV2ForwarderImplementationAddress ;
2624+ this . walletV4ForwarderFactoryAddress = options . walletV4ForwarderFactoryAddress ;
2625+ this . walletV4ForwarderImplementationAddress = options . walletV4ForwarderImplementationAddress ;
2626+ this . nativeCoinOperationHashPrefix = options . nativeCoinOperationHashPrefix ;
2627+ this . tokenOperationHashPrefix = options . tokenOperationHashPrefix ;
2628+ }
2629+ }
2630+
25422631export const Networks = {
25432632 main : {
25442633 ada : Object . freeze ( new Ada ( ) ) ,
@@ -2798,3 +2887,57 @@ const networkByName: Map<string, BaseNetwork> = new Map(
27982887export function getNetworkByName ( name : string ) : BaseNetwork | undefined {
27992888 return networkByName . get ( name ) ;
28002889}
2890+
2891+ export function getNetworksMap ( ) : Map < string , BaseNetwork > {
2892+ return new Map ( networkByName ) ;
2893+ }
2894+
2895+ /**
2896+ * Dynamically register a new network in the lookup map.
2897+ * Throws if a network with the same name is already registered.
2898+ */
2899+ export function registerNetwork ( network : BaseNetwork ) : void {
2900+ if ( networkByName . has ( network . name ) ) {
2901+ throw new Error ( `Network '${ network . name } ' is already registered` ) ;
2902+ }
2903+ networkByName . set ( network . name , network ) ;
2904+ }
2905+
2906+ /**
2907+ * Look up a network by its display name or JSON representation.
2908+ *
2909+ * Resolution order:
2910+ * 1. If `network` is a JSON string representing a DynamicNetworkOptions object
2911+ * (must have `name`, `type`, and `family` fields), construct and
2912+ * return a new DynamicNetwork instance.
2913+ * 2. Local statics cache via getNetworkByName().
2914+ *
2915+ * @param network - A network display name (e.g. "bitcoin") or a JSON-encoded
2916+ * DynamicNetworkOptions object.
2917+ * @returns The matching BaseNetwork (or DynamicNetwork) instance.
2918+ * @throws {Error } If the network is not found in local statics and the input
2919+ * is not a valid DynamicNetworkOptions JSON string.
2920+ */
2921+ export function getNetwork ( network : string ) : BaseNetwork {
2922+ // Check if the input is a JSON-encoded DynamicNetworkOptions object.
2923+ try {
2924+ const parsed = JSON . parse ( network ) ;
2925+ if (
2926+ parsed !== null &&
2927+ typeof parsed === 'object' &&
2928+ typeof parsed . name === 'string' &&
2929+ typeof parsed . type === 'string' &&
2930+ typeof parsed . family === 'string'
2931+ ) {
2932+ return new DynamicNetwork ( parsed as DynamicNetworkOptions ) ;
2933+ }
2934+ } catch {
2935+ // Not valid JSON — fall through to local lookup by name.
2936+ }
2937+
2938+ const networkObj = getNetworkByName ( network ) ;
2939+ if ( ! networkObj ) {
2940+ throw new Error ( `Network ${ network } not found` ) ;
2941+ }
2942+ return networkObj ;
2943+ }
0 commit comments