@talismn/chain-connectors 0.0.19 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -43,7 +43,7 @@ __export(index_exports, {
43
43
  module.exports = __toCommonJS(index_exports);
44
44
 
45
45
  // src/dot/ChainConnectorDot.ts
46
- var import_util2 = require("@talismn/util");
46
+ var import_util = require("@talismn/util");
47
47
 
48
48
  // src/log.ts
49
49
  var import_anylogger = __toESM(require("anylogger"));
@@ -51,7 +51,7 @@ var import_anylogger = __toESM(require("anylogger"));
51
51
  // package.json
52
52
  var package_default = {
53
53
  name: "@talismn/chain-connectors",
54
- version: "0.0.19",
54
+ version: "0.1.0",
55
55
  author: "Talisman",
56
56
  homepage: "https://talisman.xyz",
57
57
  license: "GPL-3.0-or-later",
@@ -84,20 +84,18 @@ var package_default = {
84
84
  "@talismn/util": "workspace:*",
85
85
  anylogger: "^1.0.11",
86
86
  eventemitter3: "^5.0.0",
87
- "lodash-es": "4.17.21",
88
- viem: "^2.27.3"
87
+ "lodash-es": "4.18.1",
88
+ viem: "2.52.2"
89
89
  },
90
90
  devDependencies: {
91
91
  "@polkadot/rpc-provider": "16.1.2",
92
- "@polkadot/util": "13.5.3",
93
92
  "@polkadot/x-global": "13.5.3",
94
93
  "@polkadot/x-ws": "13.5.3",
95
94
  "@talismn/tsconfig": "workspace:*",
96
- typescript: "^5.6.3"
95
+ typescript: "^6.0.3"
97
96
  },
98
97
  peerDependencies: {
99
98
  "@polkadot/rpc-provider": "*",
100
- "@polkadot/util": "*",
101
99
  "@polkadot/x-global": "*",
102
100
  "@polkadot/x-ws": "*"
103
101
  },
@@ -123,7 +121,6 @@ var log_default = (0, import_anylogger.default)(package_default.name);
123
121
  // src/dot/Websocket.ts
124
122
  var import_coder = require("@polkadot/rpc-provider/coder");
125
123
  var import_errors = require("@polkadot/rpc-provider/ws/errors");
126
- var import_util = require("@polkadot/util");
127
124
  var import_x_global = require("@polkadot/x-global");
128
125
  var import_x_ws = require("@polkadot/x-ws");
129
126
  var import_eventemitter3 = __toESM(require("eventemitter3"));
@@ -184,6 +181,7 @@ var ExponentialBackoff = class {
184
181
  };
185
182
 
186
183
  // src/dot/Websocket.ts
184
+ var isChildClass = (Parent, Child) => Child != null && (Child === Parent || Child.prototype instanceof Parent);
187
185
  var ALIASES = {
188
186
  chain_finalisedHead: "chain_finalizedHead",
189
187
  chain_subscribeFinalisedHeads: "chain_subscribeFinalizedHeads",
@@ -298,7 +296,7 @@ var Websocket = class _Websocket {
298
296
  }
299
297
  try {
300
298
  this.#endpointIndex = this.selectEndpointIndex(this.#endpoints);
301
- this.#websocket = typeof import_x_global.xglobal.WebSocket !== "undefined" && (0, import_util.isChildClass)(import_x_global.xglobal.WebSocket, import_x_ws.WebSocket) ? new import_x_ws.WebSocket(this.endpoint) : (
299
+ this.#websocket = typeof import_x_global.xglobal.WebSocket !== "undefined" && isChildClass(import_x_global.xglobal.WebSocket, import_x_ws.WebSocket) ? new import_x_ws.WebSocket(this.endpoint) : (
302
300
  // @ts-expect-error - WS may be an instance of ws, which supports options
303
301
  new import_x_ws.WebSocket(this.endpoint, void 0, {
304
302
  headers: this.#headers
@@ -429,12 +427,12 @@ var Websocket = class _Websocket {
429
427
  */
430
428
  async unsubscribe(type, method, id) {
431
429
  const subscription = `${type}::${id}`;
432
- if ((0, import_util.isUndefined)(this.#subscriptions[subscription])) {
430
+ if (this.#subscriptions[subscription] === void 0) {
433
431
  return false;
434
432
  }
435
433
  delete this.#subscriptions[subscription];
436
434
  try {
437
- return this.isConnected && !(0, import_util.isNull)(this.#websocket) ? this.send(method, [id]) : true;
435
+ return this.isConnected && this.#websocket !== null ? this.send(method, [id]) : true;
438
436
  } catch {
439
437
  return false;
440
438
  }
@@ -478,7 +476,7 @@ var Websocket = class _Websocket {
478
476
  #onSocketMessage = (message) => {
479
477
  try {
480
478
  const response = JSON.parse(message.data);
481
- return (0, import_util.isUndefined)(response.method) ? this.#onSocketMessageResult(response) : this.#onSocketMessageSubscribe(response);
479
+ return response.method === void 0 ? this.#onSocketMessageResult(response) : this.#onSocketMessageSubscribe(response);
482
480
  } catch (e) {
483
481
  this.#emit("error", new Error("Invalid websocket message received", { cause: e }));
484
482
  }
@@ -494,10 +492,7 @@ var Websocket = class _Websocket {
494
492
  handler.callback(null, result);
495
493
  if (subscription) {
496
494
  const subId = `${subscription.type}::${result}`;
497
- this.#subscriptions[subId] = (0, import_util.objectSpread)({}, subscription, {
498
- method,
499
- params
500
- });
495
+ this.#subscriptions[subId] = { ...subscription, method, params };
501
496
  if (this.#waitingForId[subId]) {
502
497
  this.#onSocketMessageSubscribe(this.#waitingForId[subId]);
503
498
  }
@@ -701,7 +696,7 @@ var ChainConnectorDot = class {
701
696
  const timeout = 3e4;
702
697
  var response = await Promise.race([
703
698
  ws.send(method, params, isCacheable),
704
- (0, import_util2.throwAfter)(timeout, "TIMEOUT")
699
+ (0, import_util.throwAfter)(timeout, "TIMEOUT")
705
700
  ]);
706
701
  } catch (err) {
707
702
  const error = err;
@@ -763,7 +758,7 @@ params: ${JSON.stringify(params)}`,
763
758
  } catch (error) {
764
759
  throw new StaleRpcError(chainId, { cause: error });
765
760
  }
766
- const unsubDeferred = (0, import_util2.Deferred)();
761
+ const unsubDeferred = (0, import_util.Deferred)();
767
762
  const unsubscribe = (unsubscribeMethod) => unsubDeferred.reject(new CallerUnsubscribedError(chainId, unsubscribeMethod));
768
763
  const callerUnsubscribed = unsubDeferred.promise;
769
764
  let noMoreSocketsTimeout;
@@ -857,10 +852,10 @@ params: ${JSON.stringify(params)}`,
857
852
  * Wait for websocket to be ready, but don't wait forever
858
853
  */
859
854
  async waitForWs(ws, timeout = 3e4) {
860
- const timer = timeout ? (0, import_util2.sleep)(timeout).then(() => {
855
+ const timer = timeout ? (0, import_util.sleep)(timeout).then(() => {
861
856
  throw new Error(`RPC connect timeout reached: ${ws.endpoint}`);
862
857
  }) : false;
863
- await Promise.race([ws.isReady, timer].filter(import_util2.isTruthy));
858
+ await Promise.race([ws.isReady, timer].filter(import_util.isTruthy));
864
859
  }
865
860
  /**
866
861
  * Connect to an RPC via chainId
@@ -1004,7 +999,7 @@ var isEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
1004
999
 
1005
1000
  // src/dot/ChainConnectorDotStub.ts
1006
1001
  var import_rpc_provider = require("@polkadot/rpc-provider");
1007
- var import_util3 = require("@talismn/util");
1002
+ var import_util2 = require("@talismn/util");
1008
1003
  var AUTO_CONNECT_TIMEOUT = 3e3;
1009
1004
  var TIMEOUT = 1e4;
1010
1005
  var ChainConnectorDotStub = class {
@@ -1025,7 +1020,7 @@ var ChainConnectorDotStub = class {
1025
1020
  async subscribe(_chainId, subscribeMethod, responseMethod, params, callback, timeout) {
1026
1021
  await this.#provider.isReady;
1027
1022
  const subId = await Promise.race([
1028
- (0, import_util3.throwAfter)(timeout || TIMEOUT, `Subscription timed out after ${timeout}ms`),
1023
+ (0, import_util2.throwAfter)(timeout || TIMEOUT, `Subscription timed out after ${timeout}ms`),
1029
1024
  this.#provider.subscribe(responseMethod, subscribeMethod, params, callback)
1030
1025
  ]);
1031
1026
  return (unsubscribeMethod) => {
@@ -1204,11 +1199,10 @@ var ChainConnectorSol = class {
1204
1199
  };
1205
1200
 
1206
1201
  // src/sol/ChainConnectorSolStub.ts
1207
- var import_web32 = require("@solana/web3.js");
1208
1202
  var ChainConnectorSolStub = class {
1209
1203
  #connection;
1210
1204
  constructor(networkOrConnection) {
1211
- this.#connection = networkOrConnection instanceof import_web32.Connection ? networkOrConnection : getSolConnection(networkOrConnection.id, networkOrConnection.rpcs);
1205
+ this.#connection = "rpcs" in networkOrConnection ? getSolConnection(networkOrConnection.id, networkOrConnection.rpcs) : networkOrConnection;
1212
1206
  }
1213
1207
  async getConnection() {
1214
1208
  return this.#connection;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/dot/ChainConnectorDot.ts","../src/log.ts","../package.json","../src/dot/Websocket.ts","../src/dot/helpers.ts","../src/dot/ChainConnectorDotStub.ts","../src/eth/getEvmNetworkPublicClient.ts","../src/eth/getChainFromEvmNetwork.ts","../src/eth/getTransportForEvmNetwork.ts","../src/eth/getEvmNetworkWalletClient.ts","../src/eth/ChainConnectorEth.ts","../src/eth/ChainConnectorEthStub.ts","../src/sol/getSolConnection.ts","../src/sol/ChainConnectorSol.ts","../src/sol/ChainConnectorSolStub.ts"],"sourcesContent":["export * from \"./dot\"\nexport * from \"./eth\"\nexport * from \"./sol\"\n","import type { ProviderInterface, ProviderInterfaceCallback } from \"@polkadot/rpc-provider/types\"\nimport type { DotNetworkId, IChaindataNetworkProvider } from \"@talismn/chaindata-provider\"\nimport type { TalismanConnectionMetaDatabase } from \"@talismn/connection-meta\"\nimport { Deferred, isTruthy, sleep, throwAfter } from \"@talismn/util\"\n\nimport log from \"../log\"\nimport type { IChainConnectorDot } from \"./IChainConnectorDot\"\nimport { Websocket } from \"./Websocket\"\n\n// errors that require an rpc fallback\n// https://docs.blastapi.io/blast-documentation/things-you-need-to-know/error-reference\nconst BAD_RPC_ERRORS: Record<string, string> = {\n \"-32097\": \"Rate limit exceeded\",\n \"-32098\": \"Capacity exceeded\",\n}\n\nexport class ChainConnectionError extends Error {\n type: \"CHAIN_CONNECTION_ERROR\"\n chainId: string\n\n constructor(chainId: string, options?: ErrorOptions) {\n super(`Unable to connect to chain ${chainId}`, options)\n\n this.type = \"CHAIN_CONNECTION_ERROR\"\n this.chainId = chainId\n }\n}\n\nexport class StaleRpcError extends Error {\n type: \"STALE_RPC_ERROR\"\n chainId: string\n\n constructor(chainId: string, options?: ErrorOptions) {\n super(`RPCs are stale/unavailable for chain ${chainId}`, options)\n\n this.type = \"STALE_RPC_ERROR\"\n this.chainId = chainId\n }\n}\nexport class WebsocketAllocationExhaustedError extends Error {\n type: \"WEBSOCKET_ALLOCATION_EXHAUSTED_ERROR\"\n chainId: string\n\n constructor(chainId: string, options?: ErrorOptions) {\n super(\n `No websockets are available from the browser pool to connect to chain ${chainId}`,\n options\n )\n\n this.type = \"WEBSOCKET_ALLOCATION_EXHAUSTED_ERROR\"\n this.chainId = chainId\n }\n}\nclass CallerUnsubscribedError extends Error {\n type: \"CALLER_UNSUBSCRIBED_ERROR\"\n chainId: string\n unsubscribeMethod: string\n\n constructor(chainId: string, unsubscribeMethod: string, options?: ErrorOptions) {\n super(`Caller unsubscribed from ${chainId}`, options)\n\n this.type = \"CALLER_UNSUBSCRIBED_ERROR\"\n this.chainId = chainId\n this.unsubscribeMethod = unsubscribeMethod\n }\n}\n\ntype SocketUserId = number\n\n/**\n * ChainConnector provides an interface similar to WsProvider, but with three points of difference:\n *\n * 1. ChainConnector methods all accept a `chainId` instead of an array of RPCs. RPCs are then fetched internally from chaindata.\n * 2. ChainConnector creates only one `WsProvider` per chain and ensures that all downstream requests to a chain share the one socket connection.\n * 3. Subscriptions return a callable `unsubscribe` method instead of an id.\n *\n * Additionally, when run on the clientside of a dapp where `window.talismanSub` is available, instead of spinning up new websocket\n * connections this class will forward all requests through to the wallet backend - where another instance of this class will\n * handle the websocket connections.\n */\nexport class ChainConnectorDot implements IChainConnectorDot {\n #chaindataChainProvider: IChaindataNetworkProvider\n #connectionMetaDb?: TalismanConnectionMetaDatabase\n\n #socketConnections: Record<DotNetworkId, Websocket> = {}\n #socketKeepAliveIntervals: Record<DotNetworkId, ReturnType<typeof setInterval>> = {}\n #socketUsers: Record<DotNetworkId, SocketUserId[]> = {}\n\n constructor(\n chaindataChainProvider: IChaindataNetworkProvider,\n connectionMetaDb?: TalismanConnectionMetaDatabase\n ) {\n this.#chaindataChainProvider = chaindataChainProvider\n this.#connectionMetaDb = connectionMetaDb\n\n if (this.#connectionMetaDb) {\n this.#chaindataChainProvider.getNetworkIds(\"polkadot\").then((chainIds) => {\n // tidy up connectionMeta for chains which no longer exist\n this.#connectionMetaDb?.chainPriorityRpcs.where(\"id\").noneOf(chainIds).delete()\n this.#connectionMetaDb?.chainBackoffInterval.where(\"id\").noneOf(chainIds).delete()\n })\n }\n }\n\n /**\n * Creates a facade over this ChainConnector which conforms to the PJS ProviderInterface\n * @example // Using a chainConnector as a Provider for an ApiPromise\n * const provider = chainConnector.asProvider('polkadot')\n * const api = new ApiPromise({ provider })\n */\n asProvider(chainId: DotNetworkId): ProviderInterface {\n const unsubHandler = new Map<string, (unsubscribeMethod: string) => void>()\n\n const providerFacade: ProviderInterface = {\n hasSubscriptions: true,\n isClonable: false,\n isConnected: true,\n clone: () => providerFacade,\n connect: () => Promise.resolve(),\n disconnect: () => Promise.resolve(),\n on: () => () => {},\n\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n send: async <T = any>(method: string, params: unknown[], isCacheable?: boolean): Promise<T> =>\n await this.send(chainId, method, params, isCacheable),\n\n subscribe: async (\n type: string,\n method: string,\n params: unknown[],\n cb: ProviderInterfaceCallback\n ): Promise<string> => {\n const unsubscribe = await this.subscribe(chainId, method, type, params, cb)\n\n const subscriptionId = this.getExclusiveRandomId(\n [...unsubHandler.keys()].map(Number)\n ).toString()\n unsubHandler.set(subscriptionId, unsubscribe)\n\n return subscriptionId\n },\n\n unsubscribe: async (_type: string, unsubscribeMethod: string, subscriptionId: string) => {\n unsubHandler.get(subscriptionId)?.(unsubscribeMethod)\n unsubHandler.delete(subscriptionId)\n\n return true\n },\n }\n\n return providerFacade\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n async send<T = any>(\n chainId: DotNetworkId,\n method: string,\n params: unknown[],\n isCacheable?: boolean | undefined,\n extraOptions?: {\n /**\n * Set to `true` if this query is speculative, i.e. if on some chains it's expected that it will raise a wasm unreachable error of the form:\n *\n * 4003: Client error: Execution failed: Execution aborted due to trap: wasm trap: wasm `unreachable` instruction executed\n *\n * By setting expectErrors to true, this method won't pollute the logs with errors we intend to have happen.\n * An example use case of this is when you plan to catch the wasm unreachable error on chains that don't support the query, and then fall back\n * to another query or perhaps an empty result.\n */\n expectErrors?: boolean\n }\n ): Promise<T> {\n const talismanSub = this.getTalismanSub()\n if (talismanSub !== undefined) {\n try {\n const chain = await this.#chaindataChainProvider.getNetworkById(chainId, \"polkadot\")\n if (!chain) throw new Error(`Chain ${chainId} not found in store`)\n\n const { genesisHash } = chain\n if (typeof genesisHash !== \"string\")\n throw new Error(`Chain ${chainId} has no genesisHash in store`)\n\n return await talismanSub.send(genesisHash, method, params)\n } catch (error) {\n log.warn(\n `Failed to make wallet-proxied send request for chain ${chainId}. Falling back to plain websocket`,\n error\n )\n }\n }\n\n try {\n // biome-ignore lint/correctness/noInnerDeclarations: legacy\n var [socketUserId, ws] = await this.connectChainSocket(chainId)\n } catch (error) {\n throw new StaleRpcError(chainId, { cause: error })\n }\n\n try {\n // wait for ws to be ready, but don't wait forever\n const timeout = 15_000 // 15 seconds in milliseconds\n await this.waitForWs(ws, timeout)\n } catch (error) {\n await this.disconnectChainSocket(chainId, socketUserId)\n throw new ChainConnectionError(chainId, { cause: error })\n }\n\n try {\n const timeout = 30_000 // throw after 30 seconds if no response\n // biome-ignore lint/correctness/noInnerDeclarations: legacy\n var response = await Promise.race([\n ws.send(method, params, isCacheable),\n throwAfter(timeout, \"TIMEOUT\"),\n ])\n } catch (err) {\n const error = err as (Error & { code?: number; data?: unknown }) | null\n\n if (error?.message === \"TIMEOUT\") {\n log.error(`ChainConnector timeout`, { chainId, endpoint: ws.endpoint, error })\n await this.updateRpcPriority(chainId, ws.endpoint, \"last\")\n await this.reset(chainId)\n throw new Error(\"Timeout\")\n }\n\n const badRpcError = BAD_RPC_ERRORS[error?.code?.toString() ?? \"\"]\n if (badRpcError) {\n log.error(`ChainConnector ${badRpcError}`, { error, chainId, endpoint: ws.endpoint })\n await this.updateRpcPriority(chainId, ws.endpoint, \"last\")\n await this.reset(chainId)\n throw new Error(badRpcError)\n }\n\n if (!extraOptions?.expectErrors)\n log.error(\n `Failed to send ${method} on chain ${chainId}\\nparams: ${JSON.stringify(params)}`,\n {\n error,\n endpoint: ws.endpoint,\n }\n )\n\n await this.disconnectChainSocket(chainId, socketUserId)\n throw error\n }\n\n await this.disconnectChainSocket(chainId, socketUserId)\n\n return response\n }\n\n async subscribe(\n chainId: DotNetworkId,\n subscribeMethod: string,\n responseMethod: string,\n params: unknown[],\n callback: ProviderInterfaceCallback,\n timeout: number | false = 30_000 // 30 seconds in milliseconds\n ): Promise<(unsubscribeMethod: string) => void> {\n const talismanSub = this.getTalismanSub()\n if (talismanSub !== undefined) {\n try {\n const chain = await this.#chaindataChainProvider.getNetworkById(chainId, \"polkadot\")\n if (!chain) throw new Error(`Chain ${chainId} not found in store`)\n\n const { genesisHash } = chain\n if (typeof genesisHash !== \"string\")\n throw new Error(`Chain ${chainId} has no genesisHash in store`)\n\n const subscriptionId = await talismanSub.subscribe(\n genesisHash,\n subscribeMethod,\n responseMethod,\n params,\n callback,\n timeout\n )\n\n return (unsubscribeMethod: string) =>\n talismanSub.unsubscribe(subscriptionId, unsubscribeMethod)\n } catch (error) {\n log.warn(\n `Failed to create wallet-proxied subscription for chain ${chainId}. Falling back to plain websocket`,\n error\n )\n }\n }\n\n try {\n // biome-ignore lint/correctness/noInnerDeclarations: legacy\n var [socketUserId, ws] = await this.connectChainSocket(chainId)\n } catch (error) {\n throw new StaleRpcError(chainId, { cause: error })\n }\n\n // by using this `Deferred` promise\n // (a promise which can be resolved or rejected by code outside of the scope of the promise's constructor)\n // we can queue up our async cleanup on the promise and then immediately return an unsubscribe method to the caller\n const unsubDeferred = Deferred()\n // we return this to the caller so that they can let us know when they're no longer interested in this subscription\n const unsubscribe = (unsubscribeMethod: string) =>\n unsubDeferred.reject(new CallerUnsubscribedError(chainId, unsubscribeMethod))\n // we queue up our work to clean up our subscription when this promise rejects\n const callerUnsubscribed = unsubDeferred.promise\n\n // used to detect when there are no more websockets available from the browser websocket pool\n // in this scenario, we'll be waiting for ws.isReady until some existing sockets are closed\n //\n // while we're waiting, we'll send an error back to the caller so that they can show some useful\n // info to the user\n let noMoreSocketsTimeout: NodeJS.Timeout | undefined\n\n // create subscription asynchronously so that the caller can unsubscribe without waiting for\n // the subscription to be created (which can take some time if e.g. the connection can't be established)\n ;(async () => {\n // wait for ws to be ready, but don't wait forever\n // if timeout is number, cancel when timeout is reached (or caller unsubscribes)\n // if timeout is false, only cancel when the caller unsubscribes\n let unsubRpcStatus: (() => void) | null = null\n try {\n const unsubStale = ws.on(\n \"stale-rpcs\",\n ({ nextBackoffInterval }: { nextBackoffInterval?: number } = {}) => {\n callback(new StaleRpcError(chainId), null)\n\n if (this.#connectionMetaDb && nextBackoffInterval) {\n const id = chainId\n this.#connectionMetaDb.chainBackoffInterval.put(\n { id, interval: nextBackoffInterval },\n id\n )\n }\n }\n )\n const unsubConnected = ws.on(\"connected\", () => {\n if (this.#connectionMetaDb) this.#connectionMetaDb.chainBackoffInterval.delete(chainId)\n })\n unsubRpcStatus = () => {\n unsubStale()\n unsubConnected()\n }\n\n noMoreSocketsTimeout = setTimeout(\n () => callback(new WebsocketAllocationExhaustedError(chainId), null),\n 30_000 // 30 seconds in ms\n )\n\n if (timeout) await Promise.race([this.waitForWs(ws, timeout), callerUnsubscribed])\n else await Promise.race([ws.isReady, callerUnsubscribed])\n\n clearTimeout(noMoreSocketsTimeout)\n } catch {\n clearTimeout(noMoreSocketsTimeout)\n\n unsubRpcStatus?.()\n await this.disconnectChainSocket(chainId, socketUserId)\n return\n }\n\n // create subscription on ws\n // handle the scenarios where the caller unsubscribes before the subscription has been created and:\n // - the subscriptionId is already set\n // - the subscriptionId is not set yet, but will be\n let subscriptionId: string | number | null = null\n let disconnected = false\n let unsubscribeMethod: string | undefined\n try {\n await Promise.race([\n ws.subscribe(responseMethod, subscribeMethod, params, callback).then((id) => {\n if (disconnected) {\n unsubscribeMethod && ws.unsubscribe(responseMethod, unsubscribeMethod, id)\n } else subscriptionId = id\n }),\n callerUnsubscribed,\n ])\n } catch (error) {\n if (error instanceof CallerUnsubscribedError) unsubscribeMethod = error.unsubscribeMethod\n\n unsubRpcStatus?.()\n disconnected = true\n\n if (subscriptionId !== null && unsubscribeMethod)\n await ws.unsubscribe(responseMethod, unsubscribeMethod, subscriptionId)\n\n await this.disconnectChainSocket(chainId, socketUserId)\n return\n }\n\n // unsubscribe from ws subscription when the caller has unsubscribed\n callerUnsubscribed\n .catch(async (error) => {\n // biome-ignore lint/suspicious/noImplicitAnyLet: legacy\n let unsubscribeMethod\n if (error instanceof CallerUnsubscribedError) unsubscribeMethod = error.unsubscribeMethod\n\n unsubRpcStatus?.()\n\n if (subscriptionId !== null && unsubscribeMethod)\n await ws.unsubscribe(responseMethod, unsubscribeMethod, subscriptionId)\n\n await this.disconnectChainSocket(chainId, socketUserId)\n })\n .catch((error) => log.warn(error))\n })()\n\n return unsubscribe\n }\n\n /**\n * Kills current websocket if any\n * Useful after changing rpc order to make sure it's applied for futher requests\n */\n async reset(chainId: DotNetworkId) {\n log.info(\"ChainConnector reset\", chainId)\n const ws = this.#socketConnections[chainId]\n if (!ws) return\n\n try {\n clearTimeout(this.#socketKeepAliveIntervals[chainId])\n delete this.#socketConnections[chainId]\n delete this.#socketUsers[chainId]\n await ws.disconnect()\n } catch (error) {\n log.warn(`Error occurred reseting socket ${chainId}`, error)\n }\n }\n\n /**\n * Wait for websocket to be ready, but don't wait forever\n */\n private async waitForWs(\n ws: Websocket,\n timeout: number | false = 30_000 // 30 seconds in milliseconds\n ): Promise<void> {\n const timer = timeout\n ? sleep(timeout).then(() => {\n throw new Error(`RPC connect timeout reached: ${ws.endpoint}`)\n })\n : false\n\n await Promise.race([ws.isReady, timer].filter(isTruthy))\n }\n\n /**\n * Connect to an RPC via chainId\n *\n * The caller must call disconnectChainSocket with the returned SocketUserId once they are finished with it\n */\n private async connectChainSocket(chainId: DotNetworkId): Promise<[SocketUserId, Websocket]> {\n const rpcs = await this.getEndpoints(chainId)\n const socketUserId = this.addSocketUser(chainId)\n\n // retrieve next rpc backoff interval from connection meta db (if one exists)\n let nextBackoffInterval: number | undefined\n if (this.#connectionMetaDb)\n nextBackoffInterval = (await this.#connectionMetaDb.chainBackoffInterval.get(chainId))\n ?.interval\n\n // NOTE: Make sure there are no calls to `await` between this check and the\n // next step where we assign a `new Websocket` to `this.#socketConnections[chainId]`\n //\n // If there is an `await` between these two steps then there will be a race condition introduced.\n // The result of this race condition will be the unnecessary creation of multiple instances of\n // `Websocket` per chain, rather than the intended behaviour where every call to send/subscribe\n // shares a single `Websocket` per chain.\n if (this.#socketConnections[chainId]) return [socketUserId, this.#socketConnections[chainId]]\n\n if (rpcs.length)\n this.#socketConnections[chainId] = new Websocket(\n rpcs,\n undefined,\n undefined,\n nextBackoffInterval\n )\n else {\n throw new Error(`No healthy RPCs available for chain ${chainId}`)\n }\n\n // on ws connected event, store current rpc as most recently connected rpc\n if (this.#connectionMetaDb) {\n this.#socketConnections[chainId].on(\"connected\", () => {\n if (!this.#connectionMetaDb) return\n\n const id = chainId\n const url = this.#socketConnections[chainId]?.endpoint\n if (!url) return\n\n this.updateRpcPriority(id, url, \"first\").catch((err) =>\n log.warn(`updateRpcPriority failed`, err)\n )\n })\n }\n // set up healthcheck (keeps ws open when idle), don't wait for setup to complete\n ;(async () => {\n if (!this.#socketConnections[chainId])\n return log.warn(`ignoring ${chainId} rpc ws healthcheck initialization: ws is not defined`)\n await this.#socketConnections[chainId].isReady\n\n if (this.#socketKeepAliveIntervals[chainId])\n clearInterval(this.#socketKeepAliveIntervals[chainId])\n\n const intervalMs = 10_000 // 10,000ms = 10s\n this.#socketKeepAliveIntervals[chainId] = setInterval(() => {\n if (!this.#socketConnections[chainId])\n return log.warn(`skipping ${chainId} rpc ws healthcheck: ws is not defined`)\n\n if (!this.#socketConnections[chainId].isConnected)\n return log.warn(`skipping ${chainId} rpc ws healthcheck: ws is not connected`)\n\n this.#socketConnections[chainId]\n .send(\"system_health\", [])\n .catch((error) => log.warn(`Failed keep-alive for socket ${chainId}`, error))\n }, intervalMs)\n })()\n\n return [socketUserId, this.#socketConnections[chainId]]\n }\n\n private async disconnectChainSocket(\n chainId: DotNetworkId,\n socketUserId: SocketUserId\n ): Promise<void> {\n this.removeSocketUser(chainId, socketUserId)\n\n if (this.#socketUsers[chainId].length > 0) return\n\n if (!this.#socketConnections[chainId])\n return log.warn(`Failed to disconnect socket: socket ${chainId} not found`)\n\n try {\n this.#socketConnections[chainId].disconnect()\n } catch (error) {\n log.warn(`Error occurred disconnecting socket ${chainId}`, error)\n }\n delete this.#socketConnections[chainId]\n clearInterval(this.#socketKeepAliveIntervals[chainId])\n delete this.#socketKeepAliveIntervals[chainId]\n }\n\n private addSocketUser(chainId: DotNetworkId): SocketUserId {\n if (!Array.isArray(this.#socketUsers[chainId])) this.#socketUsers[chainId] = []\n const socketUserId: SocketUserId = this.getExclusiveRandomId(this.#socketUsers[chainId])\n this.#socketUsers[chainId].push(socketUserId)\n return socketUserId\n }\n private removeSocketUser(chainId: DotNetworkId, socketUserId: SocketUserId) {\n const userIndex = this.#socketUsers[chainId].indexOf(socketUserId)\n if (userIndex === -1)\n throw new Error(\n `Can't remove user ${socketUserId} from socket ${chainId}: user not in list ${this.#socketUsers[\n chainId\n ].join(\", \")}`\n )\n this.#socketUsers[chainId].splice(userIndex, 1)\n }\n\n /** continues to generate a random number until it finds one which is not present in the exclude list */\n private getExclusiveRandomId(exclude: number[] = []): number {\n let id = this.getRandomId()\n while (exclude.includes(id)) {\n id = this.getRandomId()\n }\n return id\n }\n /** generates a random number */\n private getRandomId(): number {\n return Math.trunc(Math.random() * 10 ** 8)\n }\n\n private getTalismanSub() {\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n const talismanSub = typeof window !== \"undefined\" && (window as any).talismanSub\n\n // biome-ignore lint/complexity/noBannedTypes: legacy\n const rpcByGenesisHashSend: Function | undefined = talismanSub?.rpcByGenesisHashSend\n // biome-ignore lint/complexity/noBannedTypes: legacy\n const rpcByGenesisHashSubscribe: Function | undefined = talismanSub?.rpcByGenesisHashSubscribe\n // biome-ignore lint/complexity/noBannedTypes: legacy\n const rpcByGenesisHashUnsubscribe: Function | undefined =\n talismanSub?.rpcByGenesisHashUnsubscribe\n\n if (typeof rpcByGenesisHashSend !== \"function\") return\n if (typeof rpcByGenesisHashSubscribe !== \"function\") return\n if (typeof rpcByGenesisHashUnsubscribe !== \"function\") return\n\n return {\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n send: <T = any>(genesisHash: string, method: string, params: unknown[]): Promise<T> =>\n rpcByGenesisHashSend(genesisHash, method, params),\n\n subscribe: (\n genesisHash: string,\n subscribeMethod: string,\n responseMethod: string,\n params: unknown[],\n callback: ProviderInterfaceCallback,\n timeout: number | false\n ): Promise<string> =>\n rpcByGenesisHashSubscribe(\n genesisHash,\n subscribeMethod,\n responseMethod,\n params,\n callback,\n timeout\n ),\n\n unsubscribe: (subscriptionId: string, unsubscribeMethod: string): Promise<void> =>\n rpcByGenesisHashUnsubscribe(subscriptionId, unsubscribeMethod),\n }\n }\n\n private async updateRpcPriority(chainId: DotNetworkId, rpc: string, priority: \"first\" | \"last\") {\n if (!this.#connectionMetaDb) return\n\n const rpcs = await this.getEndpoints(chainId)\n if (!rpcs.includes(rpc)) throw new Error(`Unknown rpc for chain ${chainId} : ${rpc}`)\n\n const urls = rpcs.filter((r) => r !== rpc)\n\n if (priority === \"first\") urls.unshift(rpc)\n if (priority === \"last\") urls.push(rpc)\n\n if (!isEqual(urls, rpcs)) {\n // order may not change, especially if there is only one\n await this.#connectionMetaDb.chainPriorityRpcs.put({ id: chainId, urls }, chainId)\n }\n }\n\n private async getEndpoints(chainId: DotNetworkId): Promise<string[]> {\n const chain = await this.#chaindataChainProvider.getNetworkById(chainId, \"polkadot\")\n if (!chain) throw new Error(`Chain ${chainId} not found in store`)\n\n let rpcs = chain.rpcs.concat() // clone to avoid mutating the original array\n const priorityRpcs = this.#connectionMetaDb\n ? await this.#connectionMetaDb.chainPriorityRpcs.get(chainId)\n : undefined\n\n if (priorityRpcs) {\n // use existing priority list of rpcs that still exist, and include missing ones\n rpcs = [\n ...priorityRpcs.urls.filter((rpc) => rpcs.includes(rpc)),\n ...rpcs.filter((rpc) => !priorityRpcs.urls.includes(rpc)),\n ]\n }\n\n return rpcs\n }\n}\n\nconst isEqual = (a: string[], b: string[]) => a.length === b.length && a.every((v, i) => v === b[i])\n","import anylogger from \"anylogger\"\n\nimport packageJson from \"../package.json\"\n\nexport default anylogger(packageJson.name)\n","{\n \"name\": \"@talismn/chain-connectors\",\n \"version\": \"0.0.19\",\n \"author\": \"Talisman\",\n \"homepage\": \"https://talisman.xyz\",\n \"license\": \"GPL-3.0-or-later\",\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"repository\": {\n \"directory\": \"packages/chain-connectors\",\n \"type\": \"git\",\n \"url\": \"https://github.com/TalismanSociety/talisman.git\"\n },\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.mjs\",\n \"files\": [\n \"dist\"\n ],\n \"engines\": {\n \"node\": \">=20\"\n },\n \"scripts\": {\n \"test\": \"vitest run\",\n \"clean\": \"rm -rf dist .turbo node_modules\",\n \"build\": \"tsup --silent\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"@solana/web3.js\": \"^1.98.2\",\n \"@talismn/chaindata-provider\": \"workspace:*\",\n \"@talismn/connection-meta\": \"workspace:*\",\n \"@talismn/util\": \"workspace:*\",\n \"anylogger\": \"^1.0.11\",\n \"eventemitter3\": \"^5.0.0\",\n \"lodash-es\": \"4.17.21\",\n \"viem\": \"^2.27.3\"\n },\n \"devDependencies\": {\n \"@polkadot/rpc-provider\": \"16.1.2\",\n \"@polkadot/util\": \"13.5.3\",\n \"@polkadot/x-global\": \"13.5.3\",\n \"@polkadot/x-ws\": \"13.5.3\",\n \"@talismn/tsconfig\": \"workspace:*\",\n \"typescript\": \"^5.6.3\"\n },\n \"peerDependencies\": {\n \"@polkadot/rpc-provider\": \"*\",\n \"@polkadot/util\": \"*\",\n \"@polkadot/x-global\": \"*\",\n \"@polkadot/x-ws\": \"*\"\n },\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"@talismn/source\": \"./src/index.ts\",\n \"import\": {\n \"types\": \"./dist/index.d.mts\",\n \"default\": \"./dist/index.mjs\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n }\n }\n }\n}\n","import { RpcCoder } from \"@polkadot/rpc-provider/coder\"\nimport type {\n JsonRpcResponse,\n ProviderInterfaceEmitted as PjsProviderInterfaceEmitted,\n ProviderInterface,\n ProviderInterfaceCallback,\n ProviderInterfaceEmitCb,\n} from \"@polkadot/rpc-provider/types\"\nimport { getWSErrorString } from \"@polkadot/rpc-provider/ws/errors\"\nimport { isChildClass, isNull, isUndefined, objectSpread } from \"@polkadot/util\"\nimport { xglobal } from \"@polkadot/x-global\"\nimport { WebSocket } from \"@polkadot/x-ws\"\nimport EventEmitter from \"eventemitter3\"\n\nimport log from \"../log\"\nimport { ExponentialBackoff } from \"./helpers\"\n\ntype ProviderInterfaceEmitted = PjsProviderInterfaceEmitted | \"stale-rpcs\"\n\n// to account for new requirement for generic arg in this type https://github.com/polkadot-js/api/commit/f4c2b150d3d69d43c56699613666b96dd0a763f4#diff-f87c17bc7fae027ec6d43bac5fc089614d9fa097f466aa2be333b44cee81f0fd\n// TODO incrementally replace 'unknown' with proper types where possible\ntype UnknownJsonRpcResponse<T = unknown> = JsonRpcResponse<T>\n\ninterface SubscriptionHandler {\n callback: ProviderInterfaceCallback\n type: string\n}\n\ninterface WsStateAwaiting {\n callback: ProviderInterfaceCallback\n method: string\n params: unknown[]\n start: number\n subscription?: SubscriptionHandler\n}\n\ninterface WsStateSubscription extends SubscriptionHandler {\n method: string\n params: unknown[]\n}\n\nconst ALIASES: { [index: string]: string } = {\n chain_finalisedHead: \"chain_finalizedHead\",\n chain_subscribeFinalisedHeads: \"chain_subscribeFinalizedHeads\",\n chain_unsubscribeFinalisedHeads: \"chain_unsubscribeFinalizedHeads\",\n}\n\nconst DEFAULT_TIMEOUT_MS = 60 * 1000\nconst TIMEOUT_INTERVAL = 5_000\n\nfunction eraseRecord<T>(record: Record<string, T>, cb?: (item: T) => void): void {\n Object.keys(record).forEach((key): void => {\n if (cb) {\n cb(record[key])\n }\n\n delete record[key]\n })\n}\n\n/**\n * # @talismn/chain-connector/Websocket\n *\n * @name Websocket\n *\n * @description The WebSocket Provider allows sending requests using WebSocket to a WebSocket RPC server TCP port. Unlike the [[HttpProvider]], it does support subscriptions and allows listening to events such as new blocks or balance changes.\n *\n * @example\n * <BR>\n *\n * ```javascript\n * import { Websocket } from '@talismn/chain-connector';\n *\n * const provider = new Websocket('ws://127.0.0.1:9944');\n * ```\n *\n * @see [[HttpProvider]]\n */\nexport class Websocket implements ProviderInterface {\n readonly #coder: RpcCoder\n readonly #endpoints: string[]\n readonly #headers: Record<string, string>\n readonly #eventemitter: EventEmitter\n readonly #handlers: Record<string, WsStateAwaiting> = {}\n readonly #isReadyPromise: Promise<Websocket>\n readonly #waitingForId: Record<string, UnknownJsonRpcResponse> = {}\n\n #autoConnectBackoff: ExponentialBackoff\n #endpointIndex: number\n #endpointsTriedSinceLastConnection = 0\n #isConnected = false\n #subscriptions: Record<string, WsStateSubscription> = {}\n #timeoutId?: ReturnType<typeof setInterval> | null = null\n #websocket: WebSocket | null\n #timeout: number\n\n /**\n * @param {string | string[]} endpoint The endpoint url. Usually `ws://ip:9944` or `wss://ip:9944`, may provide an array of endpoint strings.\n * @param {Record<string, string>} headers The headers provided to the underlying WebSocket\n * @param {number} [timeout] Custom timeout value used per request . Defaults to `DEFAULT_TIMEOUT_MS`\n */\n constructor(\n endpoint: string | string[],\n headers: Record<string, string> = {},\n timeout?: number,\n nextBackoffInterval?: number\n ) {\n const endpoints = Array.isArray(endpoint) ? endpoint : [endpoint]\n\n if (endpoints.length === 0) {\n throw new Error(\"Websocket requires at least one Endpoint\")\n }\n\n endpoints.forEach((endpoint) => {\n if (!/^(wss|ws):\\/\\//.test(endpoint)) {\n throw new Error(`Endpoint should start with 'ws://', received '${endpoint}'`)\n }\n })\n\n this.#eventemitter = new EventEmitter()\n this.#autoConnectBackoff = new ExponentialBackoff()\n if (nextBackoffInterval) this.#autoConnectBackoff.resetTo(nextBackoffInterval)\n this.#coder = new RpcCoder()\n this.#endpointIndex = -1\n this.#endpoints = endpoints\n this.#headers = headers\n this.#websocket = null\n this.#timeout = timeout || DEFAULT_TIMEOUT_MS\n\n if (this.#autoConnectBackoff.isActive) {\n this.connectWithRetry().catch(() => {\n // does not throw\n })\n }\n\n this.#isReadyPromise = new Promise((resolve): void => {\n this.#eventemitter.once(\"connected\", (): void => {\n resolve(this)\n })\n })\n }\n\n /**\n * @summary `true` when this provider supports subscriptions\n */\n public get hasSubscriptions(): boolean {\n return true\n }\n\n /**\n * @summary `true` when this provider supports clone()\n */\n public get isClonable(): boolean {\n return true\n }\n\n /**\n * @summary Whether the node is connected or not.\n * @return {boolean} true if connected\n */\n public get isConnected(): boolean {\n return this.#isConnected\n }\n\n /**\n * @description Promise that resolves the first time we are connected and loaded\n */\n public get isReady(): Promise<Websocket> {\n return this.#isReadyPromise\n }\n\n public get endpoint(): string {\n return this.#endpoints[this.#endpointIndex]\n }\n\n /**\n * @description Returns a clone of the object\n */\n public clone(): Websocket {\n return new Websocket(this.#endpoints)\n }\n\n protected selectEndpointIndex(endpoints: string[]): number {\n this.#endpointsTriedSinceLastConnection += 1\n return (this.#endpointIndex + 1) % endpoints.length\n }\n\n /**\n * @summary Manually connect\n * @description The [[Websocket]] connects automatically by default, however if you decided otherwise, you may\n * connect manually using this method.\n */\n public async connect(): Promise<void> {\n if (this.#websocket) {\n throw new Error(\"WebSocket is already connected\")\n }\n\n try {\n this.#endpointIndex = this.selectEndpointIndex(this.#endpoints)\n\n // the as typeof WebSocket here is Deno-specific - not available on the globalThis\n this.#websocket =\n typeof xglobal.WebSocket !== \"undefined\" &&\n isChildClass(xglobal.WebSocket as typeof WebSocket, WebSocket)\n ? new WebSocket(this.endpoint)\n : // @ts-expect-error - WS may be an instance of ws, which supports options\n new WebSocket(this.endpoint, undefined, {\n headers: this.#headers,\n })\n\n if (this.#websocket) {\n this.#websocket.onclose = this.#onSocketClose\n this.#websocket.onerror = this.#onSocketError\n this.#websocket.onmessage = this.#onSocketMessage\n this.#websocket.onopen = this.#onSocketOpen\n }\n\n // timeout any handlers that have not had a response\n this.#timeoutId = setInterval(() => this.#timeoutHandlers(), TIMEOUT_INTERVAL)\n } catch (error) {\n log.error(error)\n\n this.#emit(\"error\", error)\n\n throw error\n }\n }\n\n /**\n * @description Connect, never throwing an error, but rather forcing a retry\n */\n public async connectWithRetry(): Promise<void> {\n if (!this.#autoConnectBackoff.isActive) return\n\n try {\n await this.connect()\n } catch {\n this.scheduleNextRetry()\n }\n }\n\n protected scheduleNextRetry() {\n if (!this.#autoConnectBackoff.isActive) return\n\n const haveTriedAllEndpoints =\n this.#endpointsTriedSinceLastConnection > 0 &&\n this.#endpointsTriedSinceLastConnection % this.#endpoints.length === 0\n\n setTimeout(\n (): void => {\n this.connectWithRetry().catch(() => {\n // does not throw\n })\n },\n haveTriedAllEndpoints ? this.#autoConnectBackoff.next : 0\n )\n\n // Increase backoff when we've tried all endpoints\n if (haveTriedAllEndpoints) this.#autoConnectBackoff.increase()\n\n // Fire a stale-rpcs event when we've tried all endpoints in the list\n // but haven't successfully connected to any of them\n if (haveTriedAllEndpoints)\n this.#emit(\"stale-rpcs\", { nextBackoffInterval: this.#autoConnectBackoff.next })\n }\n\n /**\n * @description Manually disconnect from the connection, clearing auto-connect logic\n */\n public async disconnect(): Promise<void> {\n // switch off autoConnect, we are in manual mode now\n this.#autoConnectBackoff.disable()\n\n try {\n if (this.#websocket) {\n // 1000 - Normal closure; the connection successfully completed\n this.#websocket.close(1000)\n }\n } catch (error) {\n log.error(error)\n\n this.#emit(\"error\", error)\n\n throw error\n }\n }\n\n /**\n * @summary Listens on events after having subscribed using the [[subscribe]] function.\n * @param {ProviderInterfaceEmitted} type Event\n * @param {ProviderInterfaceEmitCb} sub Callback\n * @return unsubscribe function\n */\n public on(type: ProviderInterfaceEmitted, sub: ProviderInterfaceEmitCb): () => void {\n this.#eventemitter.on(type, sub)\n\n return (): void => {\n this.#eventemitter.removeListener(type, sub)\n }\n }\n\n /**\n * @summary Send JSON data using WebSockets to configured HTTP Endpoint or queue.\n * @param method The RPC methods to execute\n * @param params Encoded parameters as applicable for the method\n * @param subscription Subscription details (internally used)\n */\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n public send<T = any>(\n method: string,\n params: unknown[],\n /** @deprecated \\@talismn/chain-connector doesn't implement a cache */\n _isCacheable?: boolean,\n subscription?: SubscriptionHandler\n ): Promise<T> {\n const [id, body] = this.#coder.encodeJson(method, params)\n const resultPromise: Promise<T> = this.#send(id, body, method, params, subscription)\n\n return resultPromise\n }\n\n async #send<T>(\n id: number,\n body: string,\n method: string,\n params: unknown[],\n subscription?: SubscriptionHandler\n ): Promise<T> {\n return new Promise<T>((resolve, reject): void => {\n try {\n if (!this.isConnected || this.#websocket === null) {\n throw new Error(\"WebSocket is not connected\")\n }\n\n const callback = (error?: Error | null, result?: T): void => {\n error ? reject(error) : resolve(result as T)\n }\n\n // log.debug(() => [\"calling\", method, body])\n\n this.#handlers[id] = {\n callback,\n method,\n params,\n start: Date.now(),\n subscription,\n }\n this.#websocket.send(body)\n } catch (error) {\n reject(error)\n }\n })\n }\n\n /**\n * @name subscribe\n * @summary Allows subscribing to a specific event.\n *\n * @example\n * <BR>\n *\n * ```javascript\n * const provider = new Websocket('ws://127.0.0.1:9944');\n * const rpc = new Rpc(provider);\n *\n * rpc.state.subscribeStorage([[storage.system.account, <Address>]], (_, values) => {\n * console.log(values)\n * }).then((subscriptionId) => {\n * console.log('balance changes subscription id: ', subscriptionId)\n * })\n * ```\n */\n public subscribe(\n type: string,\n method: string,\n params: unknown[],\n callback: ProviderInterfaceCallback\n ): Promise<number | string> {\n return this.send<number | string>(method, params, false, { callback, type })\n }\n\n /**\n * @summary Allows unsubscribing to subscriptions made with [[subscribe]].\n */\n public async unsubscribe(type: string, method: string, id: number | string): Promise<boolean> {\n const subscription = `${type}::${id}`\n\n // FIXME This now could happen with re-subscriptions. The issue is that with a re-sub\n // the assigned id now does not match what the API user originally received. It has\n // a slight complication in solving - since we cannot rely on the send id, but rather\n // need to find the actual subscription id to map it\n if (isUndefined(this.#subscriptions[subscription])) {\n // log.debug(() => `Unable to find active subscription=${subscription}`)\n\n return false\n }\n\n delete this.#subscriptions[subscription]\n\n try {\n return this.isConnected && !isNull(this.#websocket) ? this.send<boolean>(method, [id]) : true\n } catch {\n return false\n }\n }\n\n #emit = (type: ProviderInterfaceEmitted, ...args: unknown[]): void => {\n this.#eventemitter.emit(type, ...args)\n }\n\n #onSocketClose = (event: CloseEvent): void => {\n const error = new Error(\n `disconnected from ${this.endpoint}: ${event.code}:: ${\n event.reason || getWSErrorString(event.code)\n }`\n )\n\n if (this.#autoConnectBackoff.isActive) {\n // 1000 is a normal closure and should not be logged as an error\n if (event.code !== 1000) log.error(error.message)\n }\n\n this.#isConnected = false\n\n if (this.#websocket) {\n this.#websocket.onclose = null\n this.#websocket.onerror = null\n this.#websocket.onmessage = null\n this.#websocket.onopen = null\n this.#websocket = null\n }\n\n if (this.#timeoutId) {\n clearInterval(this.#timeoutId)\n this.#timeoutId = null\n }\n\n // reject all hanging requests\n eraseRecord(this.#handlers, (h) => {\n try {\n h.callback(error, undefined)\n } catch (err) {\n // does not throw\n log.error(err)\n }\n })\n eraseRecord(this.#waitingForId)\n\n this.#emit(\"disconnected\")\n\n this.scheduleNextRetry()\n }\n\n #onSocketError = (error: Event): void => {\n // log.debug(() => [\"socket error\", error])\n this.#emit(\"error\", error)\n }\n\n #onSocketMessage = (message: MessageEvent<string>): void => {\n // log.debug(() => [\"received\", message.data])\n try {\n const response = JSON.parse(message.data) as UnknownJsonRpcResponse\n\n // biome-ignore lint/correctness/noVoidTypeReturn: legacy\n return isUndefined(response.method)\n ? this.#onSocketMessageResult(response)\n : this.#onSocketMessageSubscribe(response)\n } catch (e) {\n this.#emit(\"error\", new Error(\"Invalid websocket message received\", { cause: e }))\n }\n }\n\n #onSocketMessageResult = (response: UnknownJsonRpcResponse): void => {\n const handler = this.#handlers[response.id]\n\n if (!handler) {\n // log.debug(() => `Unable to find handler for id=${response.id}`)\n\n return\n }\n\n try {\n const { method, params, subscription } = handler\n const result = this.#coder.decodeResponse(response) as string\n\n // first send the result - in case of subs, we may have an update\n // immediately if we have some queued results already\n handler.callback(null, result)\n\n if (subscription) {\n const subId = `${subscription.type}::${result}`\n\n this.#subscriptions[subId] = objectSpread({}, subscription, {\n method,\n params,\n })\n\n // if we have a result waiting for this subscription already\n if (this.#waitingForId[subId]) {\n this.#onSocketMessageSubscribe(this.#waitingForId[subId])\n }\n }\n } catch (error) {\n handler.callback(error as Error, undefined)\n }\n\n delete this.#handlers[response.id]\n }\n\n #onSocketMessageSubscribe = (response: UnknownJsonRpcResponse): void => {\n const method = ALIASES[response.method as string] || response.method || \"invalid\"\n const subId = `${method}::${response.params.subscription}`\n const handler = this.#subscriptions[subId]\n\n if (!handler) {\n // store the JSON, we could have out-of-order subid coming in\n this.#waitingForId[subId] = response\n\n // log.debug(() => `Unable to find handler for subscription=${subId}`)\n\n return\n }\n\n // housekeeping\n delete this.#waitingForId[subId]\n\n try {\n const result = this.#coder.decodeResponse(response)\n\n handler.callback(null, result)\n } catch (error) {\n handler.callback(error as Error, undefined)\n }\n }\n\n #onSocketOpen = (): boolean => {\n if (this.#websocket === null) {\n throw new Error(\"WebSocket cannot be null in onOpen\")\n }\n\n // log.debug(() => [\"connected to\", this.endpoint])\n\n this.#isConnected = true\n this.#endpointsTriedSinceLastConnection = 0\n this.#autoConnectBackoff.reset()\n\n this.#resubscribe()\n\n this.#emit(\"connected\")\n\n return true\n }\n\n #resubscribe = (): void => {\n const subscriptions = this.#subscriptions\n\n this.#subscriptions = {}\n\n Promise.all(\n Object.keys(subscriptions).map(async (id): Promise<void> => {\n const { callback, method, params, type } = subscriptions[id]\n\n // only re-create subscriptions which are not in author (only area where\n // transactions are created, i.e. submissions such as 'author_submitAndWatchExtrinsic'\n // are not included (and will not be re-broadcast)\n if (type.startsWith(\"author_\")) {\n return\n }\n\n try {\n await this.subscribe(type, method, params, callback)\n } catch (error) {\n log.error(error)\n }\n })\n ).catch(log.error)\n }\n\n #timeoutHandlers = (): void => {\n const now = Date.now()\n const ids = Object.keys(this.#handlers)\n\n for (let i = 0; i < ids.length; i++) {\n const handler = this.#handlers[ids[i]]\n\n if (now - handler.start > this.#timeout) {\n try {\n handler.callback(\n new Error(`No response received from RPC endpoint in ${this.#timeout / 1000}s`),\n undefined\n )\n } catch {\n // ignore\n }\n\n delete this.#handlers[ids[i]]\n }\n }\n }\n}\n","const twoSecondsMs = 2 * 1000\nconst twoMinutesMs = 2 * 60 * 1000\n\nexport class ExponentialBackoff {\n #minInterval: number\n #maxInterval: number\n #nextInterval = 0\n #active = true\n\n constructor(maxIntervalMs = twoMinutesMs, minIntervalMs = twoSecondsMs) {\n this.#minInterval = minIntervalMs\n this.#maxInterval = maxIntervalMs\n\n this.reset()\n }\n\n enable() {\n this.#active = true\n }\n disable() {\n this.#active = false\n }\n\n increase() {\n if (this.#nextInterval === 0) this.#nextInterval = 1\n this.#nextInterval = this.#capMax(this.#capMin(this.#nextInterval * 2))\n }\n decrease() {\n this.#nextInterval = this.#capMax(this.#capMin(this.#nextInterval / 2))\n }\n\n reset() {\n this.#nextInterval = this.#minInterval\n }\n resetTo(nextInterval: number) {\n this.#nextInterval = this.#capMax(this.#capMin(nextInterval))\n }\n resetToMax() {\n this.#nextInterval = this.#maxInterval\n }\n\n get isActive() {\n return this.#active\n }\n get next() {\n return this.#nextInterval\n }\n\n get isMin() {\n return this.#nextInterval === this.#minInterval\n }\n get isMax() {\n return this.#nextInterval === this.#maxInterval\n }\n\n #capMin(value: number) {\n return Math.max(this.#minInterval, value)\n }\n #capMax(value: number) {\n return Math.min(this.#maxInterval, value)\n }\n}\n","import { WsProvider } from \"@polkadot/rpc-provider\"\nimport type { ProviderInterface, ProviderInterfaceCallback } from \"@polkadot/rpc-provider/types\"\nimport type { DotNetwork, DotNetworkId } from \"@talismn/chaindata-provider\"\nimport { throwAfter } from \"@talismn/util\"\n\nimport type { IChainConnectorDot } from \"./IChainConnectorDot\"\n\nconst AUTO_CONNECT_TIMEOUT = 3_000\nconst TIMEOUT = 10_000\n\nexport class ChainConnectorDotStub implements IChainConnectorDot {\n // biome-ignore lint/correctness/noUnusedPrivateClassMembers: legacy\n #network: DotNetwork\n #provider: WsProvider\n\n constructor(network: DotNetwork) {\n this.#network = network\n this.#provider = new WsProvider(network.rpcs, AUTO_CONNECT_TIMEOUT, undefined, TIMEOUT)\n }\n\n asProvider(): ProviderInterface {\n return this.#provider as ProviderInterface\n }\n\n async send<T = unknown>(\n _chainId: DotNetworkId,\n method: string,\n params: unknown[],\n isCacheable?: boolean\n ): Promise<T> {\n await this.#provider.isReady\n\n return this.#provider.send(method, params, isCacheable) as Promise<T>\n }\n\n async subscribe(\n _chainId: DotNetworkId,\n subscribeMethod: string,\n responseMethod: string,\n params: unknown[],\n callback: ProviderInterfaceCallback,\n timeout?: number | false\n ): Promise<(unsubscribeMethod: string) => void> {\n await this.#provider.isReady\n\n const subId = await Promise.race([\n throwAfter(timeout || TIMEOUT, `Subscription timed out after ${timeout}ms`),\n this.#provider.subscribe(responseMethod, subscribeMethod, params, callback),\n ])\n\n return (unsubscribeMethod: string) => {\n this.#provider.unsubscribe(responseMethod, unsubscribeMethod, subId)\n }\n }\n\n reset(): Promise<void> {\n throw new Error(\"ChainConnectorDotStub does not implement reset\")\n }\n}\n","import type { EthNetwork } from \"@talismn/chaindata-provider\"\nimport { createPublicClient, type PublicClient } from \"viem\"\n\nimport { clearChainsCache, getChainFromEvmNetwork } from \"./getChainFromEvmNetwork\"\nimport { getTransportForEvmNetwork, type TransportOptions } from \"./getTransportForEvmNetwork\"\n\nconst MUTLICALL_BATCH_WAIT = 25\nconst MUTLICALL_BATCH_SIZE = 100\n\nconst HTTP_BATCH_WAIT = 25\nconst HTTP_BATCH_SIZE_WITH_MULTICALL = 10\nconst HTTP_BATCH_SIZE_WITHOUT_MULTICALL = 30\n\n// cache to reuse previously created public clients\nconst publicClientCache = new Map<string, PublicClient>()\n\nexport const clearPublicClientCache = (evmNetworkId?: string) => {\n clearChainsCache(evmNetworkId)\n\n if (evmNetworkId) publicClientCache.delete(evmNetworkId)\n else publicClientCache.clear()\n}\n\nexport const getEvmNetworkPublicClient = (network: EthNetwork): PublicClient => {\n const chain = getChainFromEvmNetwork(network)\n\n if (!publicClientCache.has(network.id)) {\n if (!network.rpcs.length) throw new Error(\"No RPCs found for Ethereum network\")\n\n const batch = chain.contracts?.multicall3\n ? { multicall: { wait: MUTLICALL_BATCH_WAIT, batchSize: MUTLICALL_BATCH_SIZE } }\n : undefined\n\n const transportOptions: TransportOptions = {\n batch: {\n batchSize: chain.contracts?.multicall3\n ? HTTP_BATCH_SIZE_WITH_MULTICALL\n : HTTP_BATCH_SIZE_WITHOUT_MULTICALL,\n wait: HTTP_BATCH_WAIT,\n },\n }\n\n const transport = getTransportForEvmNetwork(network, transportOptions)\n\n publicClientCache.set(\n network.id,\n createPublicClient({\n chain,\n transport,\n batch,\n })\n )\n }\n\n return publicClientCache.get(network.id) as PublicClient\n}\n","import type { EthNetwork, EthNetworkId } from \"@talismn/chaindata-provider\"\nimport { camelCase, fromPairs, toPairs } from \"lodash-es\"\nimport type { Chain, ChainContract } from \"viem\"\nimport * as viemChains from \"viem/chains\"\n\n// exclude zoraTestnet which uses Hyperliquid's chain id\nconst { zoraTestnet, ...validViemChains } = viemChains\n\n// viem chains benefit from multicall config & other viem goodies\nconst VIEM_CHAINS = Object.keys(validViemChains).reduce(\n (acc, curr) => {\n const chain = validViemChains[curr as keyof typeof validViemChains]\n acc[chain.id] = chain\n return acc\n },\n {} as Record<number, Chain>\n)\n\nconst chainsCache = new Map<string, Chain>()\n\nexport const clearChainsCache = (networkId?: EthNetworkId) => {\n if (networkId) chainsCache.delete(networkId)\n else chainsCache.clear()\n}\n\nexport const getChainFromEvmNetwork = (network: EthNetwork): Chain => {\n const { symbol, decimals } = network.nativeCurrency\n\n if (!chainsCache.has(network.id)) {\n const chainRpcs = network.rpcs ?? []\n\n const viemChain = VIEM_CHAINS[Number(network.id)] ?? {}\n\n const chain: Chain = {\n ...viemChain,\n id: Number(network.id),\n name: network.name ?? `Ethereum Chain ${network.id}`,\n rpcUrls: {\n public: { http: chainRpcs },\n default: { http: chainRpcs },\n },\n nativeCurrency: {\n symbol,\n decimals,\n name: symbol,\n },\n contracts: {\n ...viemChain.contracts,\n ...(network.contracts\n ? fromPairs(\n toPairs(network.contracts).map(([name, address]): [string, ChainContract] => [\n camelCase(name),\n { address },\n ])\n )\n : {}),\n },\n }\n\n chainsCache.set(network.id, chain)\n }\n\n return chainsCache.get(network.id) as Chain\n}\n","import type { EthNetwork } from \"@talismn/chaindata-provider\"\nimport { fallback, http } from \"viem\"\n\nexport type TransportOptions = {\n batch?:\n | boolean\n | {\n batchSize?: number | undefined\n wait?: number | undefined\n }\n}\n\nexport const getTransportForEvmNetwork = (\n evmNetwork: EthNetwork,\n options: TransportOptions = {}\n) => {\n if (!evmNetwork.rpcs?.length) throw new Error(\"No RPCs found for EVM network\")\n\n const { batch } = options\n\n return fallback(\n evmNetwork.rpcs.map((url) => http(url, { batch, retryCount: 0 })),\n { retryCount: 0 }\n )\n}\n","import type { EthNetwork } from \"@talismn/chaindata-provider\"\nimport { type Account, createWalletClient, type WalletClient } from \"viem\"\n\nimport { getChainFromEvmNetwork } from \"./getChainFromEvmNetwork\"\nimport { getTransportForEvmNetwork } from \"./getTransportForEvmNetwork\"\n\ntype WalletClientOptions = {\n account?: `0x${string}` | Account\n}\n\nexport const getEvmNetworkWalletClient = (\n network: EthNetwork,\n options: WalletClientOptions = {}\n): WalletClient => {\n const chain = getChainFromEvmNetwork(network)\n\n const transport = getTransportForEvmNetwork(network)\n\n return createWalletClient({ chain, transport, account: options.account })\n}\n","import type {\n EthNetworkId,\n IChaindataNetworkProvider,\n IChaindataTokenProvider,\n} from \"@talismn/chaindata-provider\"\nimport type { Account, PublicClient, WalletClient } from \"viem\"\n\nimport { clearPublicClientCache, getEvmNetworkPublicClient } from \"./getEvmNetworkPublicClient\"\nimport { getEvmNetworkWalletClient } from \"./getEvmNetworkWalletClient\"\nimport type { IChainConnectorEth } from \"./IChainConnectorEth\"\n\nexport class ChainConnectorEth implements IChainConnectorEth {\n #chaindataProvider: IChaindataNetworkProvider & IChaindataTokenProvider\n\n constructor(chaindataProvider: IChaindataNetworkProvider & IChaindataTokenProvider) {\n this.#chaindataProvider = chaindataProvider\n }\n\n async getPublicClientForEvmNetwork(evmNetworkId: EthNetworkId): Promise<PublicClient | null> {\n const network = await this.#chaindataProvider.getNetworkById(evmNetworkId, \"ethereum\")\n if (!network) return null\n\n return getEvmNetworkPublicClient(network)\n }\n\n async getWalletClientForEvmNetwork(\n evmNetworkId: EthNetworkId,\n account?: `0x${string}` | Account\n ): Promise<WalletClient | null> {\n const network = await this.#chaindataProvider.getNetworkById(evmNetworkId, \"ethereum\")\n if (!network) return null\n\n return getEvmNetworkWalletClient(network, { account })\n }\n\n public clearRpcProvidersCache(evmNetworkId?: EthNetworkId) {\n clearPublicClientCache(evmNetworkId)\n }\n}\n","import type { EthNetwork, EthNetworkId } from \"@talismn/chaindata-provider\"\nimport type { Account, PublicClient, WalletClient } from \"viem\"\n\nimport { getEvmNetworkPublicClient } from \"./getEvmNetworkPublicClient\"\nimport { getEvmNetworkWalletClient } from \"./getEvmNetworkWalletClient\"\nimport type { IChainConnectorEth } from \"./IChainConnectorEth\"\n\nexport class ChainConnectorEthStub implements IChainConnectorEth {\n #network: EthNetwork\n\n constructor(network: EthNetwork) {\n this.#network = network\n }\n\n async getPublicClientForEvmNetwork(): Promise<PublicClient | null> {\n return getEvmNetworkPublicClient(this.#network)\n }\n\n async getWalletClientForEvmNetwork(\n _networkId: EthNetworkId,\n account?: `0x${string}` | Account\n ): Promise<WalletClient | null> {\n return getEvmNetworkWalletClient(this.#network, { account })\n }\n\n clearRpcProvidersCache(): void {\n // No-op for stub\n }\n}\n","import { Connection } from \"@solana/web3.js\"\nimport type { SolNetworkId } from \"@talismn/chaindata-provider\"\n\n// TODO leverage multiple rpcs with fallback\nexport const getSolConnection = (_networkId: SolNetworkId, rpcs: string[]) => {\n return new Connection(rpcs[0], {\n commitment: \"confirmed\",\n })\n}\n","import type { Connection } from \"@solana/web3.js\"\nimport type {\n IChaindataNetworkProvider,\n IChaindataTokenProvider,\n SolNetworkId,\n} from \"@talismn/chaindata-provider\"\n\nimport { getSolConnection } from \"./getSolConnection\"\nimport type { IChainConnectorSol } from \"./IChainConnectorSol\"\n\nexport class ChainConnectorSol implements IChainConnectorSol {\n #chaindataProvider: IChaindataNetworkProvider & IChaindataTokenProvider\n\n constructor(chaindataProvider: IChaindataNetworkProvider & IChaindataTokenProvider) {\n this.#chaindataProvider = chaindataProvider\n }\n\n async getConnection(networkId: SolNetworkId): Promise<Connection> {\n const network = await this.#chaindataProvider.getNetworkById(networkId, \"solana\")\n if (!network) throw new Error(`Network not found: ${networkId}`)\n\n return getSolConnection(networkId, network.rpcs)\n }\n}\n","import { Connection } from \"@solana/web3.js\"\nimport type { SolNetwork } from \"@talismn/chaindata-provider\"\n\nimport { getSolConnection } from \"./getSolConnection\"\nimport type { IChainConnectorSol } from \"./IChainConnectorSol\"\n\nexport class ChainConnectorSolStub implements IChainConnectorSol {\n #connection: Connection\n\n constructor(networkOrConnection: Pick<SolNetwork, \"id\" | \"rpcs\"> | Connection) {\n this.#connection =\n networkOrConnection instanceof Connection\n ? networkOrConnection\n : getSolConnection(networkOrConnection.id, networkOrConnection.rpcs)\n }\n\n async getConnection(): Promise<Connection> {\n return this.#connection\n }\n}\n"],"mappings":"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","names":["import_util","anylogger","endpoint","EventEmitter","unsubscribeMethod","import_util","import_viem","import_viem","import_web3"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/dot/ChainConnectorDot.ts","../src/log.ts","../package.json","../src/dot/Websocket.ts","../src/dot/helpers.ts","../src/dot/ChainConnectorDotStub.ts","../src/eth/getEvmNetworkPublicClient.ts","../src/eth/getChainFromEvmNetwork.ts","../src/eth/getTransportForEvmNetwork.ts","../src/eth/getEvmNetworkWalletClient.ts","../src/eth/ChainConnectorEth.ts","../src/eth/ChainConnectorEthStub.ts","../src/sol/getSolConnection.ts","../src/sol/ChainConnectorSol.ts","../src/sol/ChainConnectorSolStub.ts"],"sourcesContent":["export * from \"./dot\"\nexport * from \"./eth\"\nexport * from \"./sol\"\n","import type { ProviderInterface, ProviderInterfaceCallback } from \"@polkadot/rpc-provider/types\"\nimport type { DotNetworkId, IChaindataNetworkProvider } from \"@talismn/chaindata-provider\"\nimport type { TalismanConnectionMetaDatabase } from \"@talismn/connection-meta\"\nimport { Deferred, isTruthy, sleep, throwAfter } from \"@talismn/util\"\n\nimport log from \"../log\"\nimport type { IChainConnectorDot } from \"./IChainConnectorDot\"\nimport { Websocket } from \"./Websocket\"\n\n// errors that require an rpc fallback\n// https://docs.blastapi.io/blast-documentation/things-you-need-to-know/error-reference\nconst BAD_RPC_ERRORS: Record<string, string> = {\n \"-32097\": \"Rate limit exceeded\",\n \"-32098\": \"Capacity exceeded\",\n}\n\nexport class ChainConnectionError extends Error {\n type: \"CHAIN_CONNECTION_ERROR\"\n chainId: string\n\n constructor(chainId: string, options?: ErrorOptions) {\n super(`Unable to connect to chain ${chainId}`, options)\n\n this.type = \"CHAIN_CONNECTION_ERROR\"\n this.chainId = chainId\n }\n}\n\nexport class StaleRpcError extends Error {\n type: \"STALE_RPC_ERROR\"\n chainId: string\n\n constructor(chainId: string, options?: ErrorOptions) {\n super(`RPCs are stale/unavailable for chain ${chainId}`, options)\n\n this.type = \"STALE_RPC_ERROR\"\n this.chainId = chainId\n }\n}\nexport class WebsocketAllocationExhaustedError extends Error {\n type: \"WEBSOCKET_ALLOCATION_EXHAUSTED_ERROR\"\n chainId: string\n\n constructor(chainId: string, options?: ErrorOptions) {\n super(\n `No websockets are available from the browser pool to connect to chain ${chainId}`,\n options\n )\n\n this.type = \"WEBSOCKET_ALLOCATION_EXHAUSTED_ERROR\"\n this.chainId = chainId\n }\n}\nclass CallerUnsubscribedError extends Error {\n type: \"CALLER_UNSUBSCRIBED_ERROR\"\n chainId: string\n unsubscribeMethod: string\n\n constructor(chainId: string, unsubscribeMethod: string, options?: ErrorOptions) {\n super(`Caller unsubscribed from ${chainId}`, options)\n\n this.type = \"CALLER_UNSUBSCRIBED_ERROR\"\n this.chainId = chainId\n this.unsubscribeMethod = unsubscribeMethod\n }\n}\n\ntype SocketUserId = number\n\n/**\n * ChainConnector provides an interface similar to WsProvider, but with three points of difference:\n *\n * 1. ChainConnector methods all accept a `chainId` instead of an array of RPCs. RPCs are then fetched internally from chaindata.\n * 2. ChainConnector creates only one `WsProvider` per chain and ensures that all downstream requests to a chain share the one socket connection.\n * 3. Subscriptions return a callable `unsubscribe` method instead of an id.\n *\n * Additionally, when run on the clientside of a dapp where `window.talismanSub` is available, instead of spinning up new websocket\n * connections this class will forward all requests through to the wallet backend - where another instance of this class will\n * handle the websocket connections.\n */\nexport class ChainConnectorDot implements IChainConnectorDot {\n #chaindataChainProvider: IChaindataNetworkProvider\n #connectionMetaDb?: TalismanConnectionMetaDatabase\n\n #socketConnections: Record<DotNetworkId, Websocket> = {}\n #socketKeepAliveIntervals: Record<DotNetworkId, ReturnType<typeof setInterval>> = {}\n #socketUsers: Record<DotNetworkId, SocketUserId[]> = {}\n\n constructor(\n chaindataChainProvider: IChaindataNetworkProvider,\n connectionMetaDb?: TalismanConnectionMetaDatabase\n ) {\n this.#chaindataChainProvider = chaindataChainProvider\n this.#connectionMetaDb = connectionMetaDb\n\n if (this.#connectionMetaDb) {\n this.#chaindataChainProvider.getNetworkIds(\"polkadot\").then((chainIds) => {\n // tidy up connectionMeta for chains which no longer exist\n this.#connectionMetaDb?.chainPriorityRpcs.where(\"id\").noneOf(chainIds).delete()\n this.#connectionMetaDb?.chainBackoffInterval.where(\"id\").noneOf(chainIds).delete()\n })\n }\n }\n\n /**\n * Creates a facade over this ChainConnector which conforms to the PJS ProviderInterface\n * @example // Using a chainConnector as a Provider for an ApiPromise\n * const provider = chainConnector.asProvider('polkadot')\n * const api = new ApiPromise({ provider })\n */\n asProvider(chainId: DotNetworkId): ProviderInterface {\n const unsubHandler = new Map<string, (unsubscribeMethod: string) => void>()\n\n const providerFacade: ProviderInterface = {\n hasSubscriptions: true,\n isClonable: false,\n isConnected: true,\n clone: () => providerFacade,\n connect: () => Promise.resolve(),\n disconnect: () => Promise.resolve(),\n on: () => () => {},\n\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n send: async <T = any>(method: string, params: unknown[], isCacheable?: boolean): Promise<T> =>\n await this.send(chainId, method, params, isCacheable),\n\n subscribe: async (\n type: string,\n method: string,\n params: unknown[],\n cb: ProviderInterfaceCallback\n ): Promise<string> => {\n const unsubscribe = await this.subscribe(chainId, method, type, params, cb)\n\n const subscriptionId = this.getExclusiveRandomId(\n [...unsubHandler.keys()].map(Number)\n ).toString()\n unsubHandler.set(subscriptionId, unsubscribe)\n\n return subscriptionId\n },\n\n unsubscribe: async (_type: string, unsubscribeMethod: string, subscriptionId: string) => {\n unsubHandler.get(subscriptionId)?.(unsubscribeMethod)\n unsubHandler.delete(subscriptionId)\n\n return true\n },\n }\n\n return providerFacade\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n async send<T = any>(\n chainId: DotNetworkId,\n method: string,\n params: unknown[],\n isCacheable?: boolean | undefined,\n extraOptions?: {\n /**\n * Set to `true` if this query is speculative, i.e. if on some chains it's expected that it will raise a wasm unreachable error of the form:\n *\n * 4003: Client error: Execution failed: Execution aborted due to trap: wasm trap: wasm `unreachable` instruction executed\n *\n * By setting expectErrors to true, this method won't pollute the logs with errors we intend to have happen.\n * An example use case of this is when you plan to catch the wasm unreachable error on chains that don't support the query, and then fall back\n * to another query or perhaps an empty result.\n */\n expectErrors?: boolean\n }\n ): Promise<T> {\n const talismanSub = this.getTalismanSub()\n if (talismanSub !== undefined) {\n try {\n const chain = await this.#chaindataChainProvider.getNetworkById(chainId, \"polkadot\")\n if (!chain) throw new Error(`Chain ${chainId} not found in store`)\n\n const { genesisHash } = chain\n if (typeof genesisHash !== \"string\")\n throw new Error(`Chain ${chainId} has no genesisHash in store`)\n\n return await talismanSub.send(genesisHash, method, params)\n } catch (error) {\n log.warn(\n `Failed to make wallet-proxied send request for chain ${chainId}. Falling back to plain websocket`,\n error\n )\n }\n }\n\n try {\n // biome-ignore lint/correctness/noInnerDeclarations: legacy\n var [socketUserId, ws] = await this.connectChainSocket(chainId)\n } catch (error) {\n throw new StaleRpcError(chainId, { cause: error })\n }\n\n try {\n // wait for ws to be ready, but don't wait forever\n const timeout = 15_000 // 15 seconds in milliseconds\n await this.waitForWs(ws, timeout)\n } catch (error) {\n await this.disconnectChainSocket(chainId, socketUserId)\n throw new ChainConnectionError(chainId, { cause: error })\n }\n\n try {\n const timeout = 30_000 // throw after 30 seconds if no response\n // biome-ignore lint/correctness/noInnerDeclarations: legacy\n var response = await Promise.race([\n ws.send(method, params, isCacheable),\n throwAfter(timeout, \"TIMEOUT\"),\n ])\n } catch (err) {\n const error = err as (Error & { code?: number; data?: unknown }) | null\n\n if (error?.message === \"TIMEOUT\") {\n log.error(`ChainConnector timeout`, { chainId, endpoint: ws.endpoint, error })\n await this.updateRpcPriority(chainId, ws.endpoint, \"last\")\n await this.reset(chainId)\n throw new Error(\"Timeout\")\n }\n\n const badRpcError = BAD_RPC_ERRORS[error?.code?.toString() ?? \"\"]\n if (badRpcError) {\n log.error(`ChainConnector ${badRpcError}`, { error, chainId, endpoint: ws.endpoint })\n await this.updateRpcPriority(chainId, ws.endpoint, \"last\")\n await this.reset(chainId)\n throw new Error(badRpcError)\n }\n\n if (!extraOptions?.expectErrors)\n log.error(\n `Failed to send ${method} on chain ${chainId}\\nparams: ${JSON.stringify(params)}`,\n {\n error,\n endpoint: ws.endpoint,\n }\n )\n\n await this.disconnectChainSocket(chainId, socketUserId)\n throw error\n }\n\n await this.disconnectChainSocket(chainId, socketUserId)\n\n return response\n }\n\n async subscribe(\n chainId: DotNetworkId,\n subscribeMethod: string,\n responseMethod: string,\n params: unknown[],\n callback: ProviderInterfaceCallback,\n timeout: number | false = 30_000 // 30 seconds in milliseconds\n ): Promise<(unsubscribeMethod: string) => void> {\n const talismanSub = this.getTalismanSub()\n if (talismanSub !== undefined) {\n try {\n const chain = await this.#chaindataChainProvider.getNetworkById(chainId, \"polkadot\")\n if (!chain) throw new Error(`Chain ${chainId} not found in store`)\n\n const { genesisHash } = chain\n if (typeof genesisHash !== \"string\")\n throw new Error(`Chain ${chainId} has no genesisHash in store`)\n\n const subscriptionId = await talismanSub.subscribe(\n genesisHash,\n subscribeMethod,\n responseMethod,\n params,\n callback,\n timeout\n )\n\n return (unsubscribeMethod: string) =>\n talismanSub.unsubscribe(subscriptionId, unsubscribeMethod)\n } catch (error) {\n log.warn(\n `Failed to create wallet-proxied subscription for chain ${chainId}. Falling back to plain websocket`,\n error\n )\n }\n }\n\n try {\n // biome-ignore lint/correctness/noInnerDeclarations: legacy\n var [socketUserId, ws] = await this.connectChainSocket(chainId)\n } catch (error) {\n throw new StaleRpcError(chainId, { cause: error })\n }\n\n // by using this `Deferred` promise\n // (a promise which can be resolved or rejected by code outside of the scope of the promise's constructor)\n // we can queue up our async cleanup on the promise and then immediately return an unsubscribe method to the caller\n const unsubDeferred = Deferred()\n // we return this to the caller so that they can let us know when they're no longer interested in this subscription\n const unsubscribe = (unsubscribeMethod: string) =>\n unsubDeferred.reject(new CallerUnsubscribedError(chainId, unsubscribeMethod))\n // we queue up our work to clean up our subscription when this promise rejects\n const callerUnsubscribed = unsubDeferred.promise\n\n // used to detect when there are no more websockets available from the browser websocket pool\n // in this scenario, we'll be waiting for ws.isReady until some existing sockets are closed\n //\n // while we're waiting, we'll send an error back to the caller so that they can show some useful\n // info to the user\n let noMoreSocketsTimeout: NodeJS.Timeout | undefined\n\n // create subscription asynchronously so that the caller can unsubscribe without waiting for\n // the subscription to be created (which can take some time if e.g. the connection can't be established)\n ;(async () => {\n // wait for ws to be ready, but don't wait forever\n // if timeout is number, cancel when timeout is reached (or caller unsubscribes)\n // if timeout is false, only cancel when the caller unsubscribes\n let unsubRpcStatus: (() => void) | null = null\n try {\n const unsubStale = ws.on(\n \"stale-rpcs\",\n ({ nextBackoffInterval }: { nextBackoffInterval?: number } = {}) => {\n callback(new StaleRpcError(chainId), null)\n\n if (this.#connectionMetaDb && nextBackoffInterval) {\n const id = chainId\n this.#connectionMetaDb.chainBackoffInterval.put(\n { id, interval: nextBackoffInterval },\n id\n )\n }\n }\n )\n const unsubConnected = ws.on(\"connected\", () => {\n if (this.#connectionMetaDb) this.#connectionMetaDb.chainBackoffInterval.delete(chainId)\n })\n unsubRpcStatus = () => {\n unsubStale()\n unsubConnected()\n }\n\n noMoreSocketsTimeout = setTimeout(\n () => callback(new WebsocketAllocationExhaustedError(chainId), null),\n 30_000 // 30 seconds in ms\n )\n\n if (timeout) await Promise.race([this.waitForWs(ws, timeout), callerUnsubscribed])\n else await Promise.race([ws.isReady, callerUnsubscribed])\n\n clearTimeout(noMoreSocketsTimeout)\n } catch {\n clearTimeout(noMoreSocketsTimeout)\n\n unsubRpcStatus?.()\n await this.disconnectChainSocket(chainId, socketUserId)\n return\n }\n\n // create subscription on ws\n // handle the scenarios where the caller unsubscribes before the subscription has been created and:\n // - the subscriptionId is already set\n // - the subscriptionId is not set yet, but will be\n let subscriptionId: string | number | null = null\n let disconnected = false\n let unsubscribeMethod: string | undefined\n try {\n await Promise.race([\n ws.subscribe(responseMethod, subscribeMethod, params, callback).then((id) => {\n if (disconnected) {\n unsubscribeMethod && ws.unsubscribe(responseMethod, unsubscribeMethod, id)\n } else subscriptionId = id\n }),\n callerUnsubscribed,\n ])\n } catch (error) {\n if (error instanceof CallerUnsubscribedError) unsubscribeMethod = error.unsubscribeMethod\n\n unsubRpcStatus?.()\n disconnected = true\n\n if (subscriptionId !== null && unsubscribeMethod)\n await ws.unsubscribe(responseMethod, unsubscribeMethod, subscriptionId)\n\n await this.disconnectChainSocket(chainId, socketUserId)\n return\n }\n\n // unsubscribe from ws subscription when the caller has unsubscribed\n callerUnsubscribed\n .catch(async (error) => {\n // biome-ignore lint/suspicious/noImplicitAnyLet: legacy\n let unsubscribeMethod\n if (error instanceof CallerUnsubscribedError) unsubscribeMethod = error.unsubscribeMethod\n\n unsubRpcStatus?.()\n\n if (subscriptionId !== null && unsubscribeMethod)\n await ws.unsubscribe(responseMethod, unsubscribeMethod, subscriptionId)\n\n await this.disconnectChainSocket(chainId, socketUserId)\n })\n .catch((error) => log.warn(error))\n })()\n\n return unsubscribe\n }\n\n /**\n * Kills current websocket if any\n * Useful after changing rpc order to make sure it's applied for futher requests\n */\n async reset(chainId: DotNetworkId) {\n log.info(\"ChainConnector reset\", chainId)\n const ws = this.#socketConnections[chainId]\n if (!ws) return\n\n try {\n clearTimeout(this.#socketKeepAliveIntervals[chainId])\n delete this.#socketConnections[chainId]\n delete this.#socketUsers[chainId]\n await ws.disconnect()\n } catch (error) {\n log.warn(`Error occurred reseting socket ${chainId}`, error)\n }\n }\n\n /**\n * Wait for websocket to be ready, but don't wait forever\n */\n private async waitForWs(\n ws: Websocket,\n timeout: number | false = 30_000 // 30 seconds in milliseconds\n ): Promise<void> {\n const timer = timeout\n ? sleep(timeout).then(() => {\n throw new Error(`RPC connect timeout reached: ${ws.endpoint}`)\n })\n : false\n\n await Promise.race([ws.isReady, timer].filter(isTruthy))\n }\n\n /**\n * Connect to an RPC via chainId\n *\n * The caller must call disconnectChainSocket with the returned SocketUserId once they are finished with it\n */\n private async connectChainSocket(chainId: DotNetworkId): Promise<[SocketUserId, Websocket]> {\n const rpcs = await this.getEndpoints(chainId)\n const socketUserId = this.addSocketUser(chainId)\n\n // retrieve next rpc backoff interval from connection meta db (if one exists)\n let nextBackoffInterval: number | undefined\n if (this.#connectionMetaDb)\n nextBackoffInterval = (await this.#connectionMetaDb.chainBackoffInterval.get(chainId))\n ?.interval\n\n // NOTE: Make sure there are no calls to `await` between this check and the\n // next step where we assign a `new Websocket` to `this.#socketConnections[chainId]`\n //\n // If there is an `await` between these two steps then there will be a race condition introduced.\n // The result of this race condition will be the unnecessary creation of multiple instances of\n // `Websocket` per chain, rather than the intended behaviour where every call to send/subscribe\n // shares a single `Websocket` per chain.\n if (this.#socketConnections[chainId]) return [socketUserId, this.#socketConnections[chainId]]\n\n if (rpcs.length)\n this.#socketConnections[chainId] = new Websocket(\n rpcs,\n undefined,\n undefined,\n nextBackoffInterval\n )\n else {\n throw new Error(`No healthy RPCs available for chain ${chainId}`)\n }\n\n // on ws connected event, store current rpc as most recently connected rpc\n if (this.#connectionMetaDb) {\n this.#socketConnections[chainId].on(\"connected\", () => {\n if (!this.#connectionMetaDb) return\n\n const id = chainId\n const url = this.#socketConnections[chainId]?.endpoint\n if (!url) return\n\n this.updateRpcPriority(id, url, \"first\").catch((err) =>\n log.warn(`updateRpcPriority failed`, err)\n )\n })\n }\n // set up healthcheck (keeps ws open when idle), don't wait for setup to complete\n ;(async () => {\n if (!this.#socketConnections[chainId])\n return log.warn(`ignoring ${chainId} rpc ws healthcheck initialization: ws is not defined`)\n await this.#socketConnections[chainId].isReady\n\n if (this.#socketKeepAliveIntervals[chainId])\n clearInterval(this.#socketKeepAliveIntervals[chainId])\n\n const intervalMs = 10_000 // 10,000ms = 10s\n this.#socketKeepAliveIntervals[chainId] = setInterval(() => {\n if (!this.#socketConnections[chainId])\n return log.warn(`skipping ${chainId} rpc ws healthcheck: ws is not defined`)\n\n if (!this.#socketConnections[chainId].isConnected)\n return log.warn(`skipping ${chainId} rpc ws healthcheck: ws is not connected`)\n\n this.#socketConnections[chainId]\n .send(\"system_health\", [])\n .catch((error) => log.warn(`Failed keep-alive for socket ${chainId}`, error))\n }, intervalMs)\n })()\n\n return [socketUserId, this.#socketConnections[chainId]]\n }\n\n private async disconnectChainSocket(\n chainId: DotNetworkId,\n socketUserId: SocketUserId\n ): Promise<void> {\n this.removeSocketUser(chainId, socketUserId)\n\n if (this.#socketUsers[chainId].length > 0) return\n\n if (!this.#socketConnections[chainId])\n return log.warn(`Failed to disconnect socket: socket ${chainId} not found`)\n\n try {\n this.#socketConnections[chainId].disconnect()\n } catch (error) {\n log.warn(`Error occurred disconnecting socket ${chainId}`, error)\n }\n delete this.#socketConnections[chainId]\n clearInterval(this.#socketKeepAliveIntervals[chainId])\n delete this.#socketKeepAliveIntervals[chainId]\n }\n\n private addSocketUser(chainId: DotNetworkId): SocketUserId {\n if (!Array.isArray(this.#socketUsers[chainId])) this.#socketUsers[chainId] = []\n const socketUserId: SocketUserId = this.getExclusiveRandomId(this.#socketUsers[chainId])\n this.#socketUsers[chainId].push(socketUserId)\n return socketUserId\n }\n private removeSocketUser(chainId: DotNetworkId, socketUserId: SocketUserId) {\n const userIndex = this.#socketUsers[chainId].indexOf(socketUserId)\n if (userIndex === -1)\n throw new Error(\n `Can't remove user ${socketUserId} from socket ${chainId}: user not in list ${this.#socketUsers[\n chainId\n ].join(\", \")}`\n )\n this.#socketUsers[chainId].splice(userIndex, 1)\n }\n\n /** continues to generate a random number until it finds one which is not present in the exclude list */\n private getExclusiveRandomId(exclude: number[] = []): number {\n let id = this.getRandomId()\n while (exclude.includes(id)) {\n id = this.getRandomId()\n }\n return id\n }\n /** generates a random number */\n private getRandomId(): number {\n return Math.trunc(Math.random() * 10 ** 8)\n }\n\n private getTalismanSub() {\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n const talismanSub = typeof window !== \"undefined\" && (window as any).talismanSub\n\n // biome-ignore lint/complexity/noBannedTypes: legacy\n const rpcByGenesisHashSend: Function | undefined = talismanSub?.rpcByGenesisHashSend\n // biome-ignore lint/complexity/noBannedTypes: legacy\n const rpcByGenesisHashSubscribe: Function | undefined = talismanSub?.rpcByGenesisHashSubscribe\n // biome-ignore lint/complexity/noBannedTypes: legacy\n const rpcByGenesisHashUnsubscribe: Function | undefined =\n talismanSub?.rpcByGenesisHashUnsubscribe\n\n if (typeof rpcByGenesisHashSend !== \"function\") return\n if (typeof rpcByGenesisHashSubscribe !== \"function\") return\n if (typeof rpcByGenesisHashUnsubscribe !== \"function\") return\n\n return {\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n send: <T = any>(genesisHash: string, method: string, params: unknown[]): Promise<T> =>\n rpcByGenesisHashSend(genesisHash, method, params),\n\n subscribe: (\n genesisHash: string,\n subscribeMethod: string,\n responseMethod: string,\n params: unknown[],\n callback: ProviderInterfaceCallback,\n timeout: number | false\n ): Promise<string> =>\n rpcByGenesisHashSubscribe(\n genesisHash,\n subscribeMethod,\n responseMethod,\n params,\n callback,\n timeout\n ),\n\n unsubscribe: (subscriptionId: string, unsubscribeMethod: string): Promise<void> =>\n rpcByGenesisHashUnsubscribe(subscriptionId, unsubscribeMethod),\n }\n }\n\n private async updateRpcPriority(chainId: DotNetworkId, rpc: string, priority: \"first\" | \"last\") {\n if (!this.#connectionMetaDb) return\n\n const rpcs = await this.getEndpoints(chainId)\n if (!rpcs.includes(rpc)) throw new Error(`Unknown rpc for chain ${chainId} : ${rpc}`)\n\n const urls = rpcs.filter((r) => r !== rpc)\n\n if (priority === \"first\") urls.unshift(rpc)\n if (priority === \"last\") urls.push(rpc)\n\n if (!isEqual(urls, rpcs)) {\n // order may not change, especially if there is only one\n await this.#connectionMetaDb.chainPriorityRpcs.put({ id: chainId, urls }, chainId)\n }\n }\n\n private async getEndpoints(chainId: DotNetworkId): Promise<string[]> {\n const chain = await this.#chaindataChainProvider.getNetworkById(chainId, \"polkadot\")\n if (!chain) throw new Error(`Chain ${chainId} not found in store`)\n\n let rpcs = chain.rpcs.concat() // clone to avoid mutating the original array\n const priorityRpcs = this.#connectionMetaDb\n ? await this.#connectionMetaDb.chainPriorityRpcs.get(chainId)\n : undefined\n\n if (priorityRpcs) {\n // use existing priority list of rpcs that still exist, and include missing ones\n rpcs = [\n ...priorityRpcs.urls.filter((rpc) => rpcs.includes(rpc)),\n ...rpcs.filter((rpc) => !priorityRpcs.urls.includes(rpc)),\n ]\n }\n\n return rpcs\n }\n}\n\nconst isEqual = (a: string[], b: string[]) => a.length === b.length && a.every((v, i) => v === b[i])\n","import anylogger from \"anylogger\"\n\nimport packageJson from \"../package.json\"\n\nexport default anylogger(packageJson.name)\n","{\n \"name\": \"@talismn/chain-connectors\",\n \"version\": \"0.1.0\",\n \"author\": \"Talisman\",\n \"homepage\": \"https://talisman.xyz\",\n \"license\": \"GPL-3.0-or-later\",\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"repository\": {\n \"directory\": \"packages/chain-connectors\",\n \"type\": \"git\",\n \"url\": \"https://github.com/TalismanSociety/talisman.git\"\n },\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.mjs\",\n \"files\": [\n \"dist\"\n ],\n \"engines\": {\n \"node\": \">=20\"\n },\n \"scripts\": {\n \"test\": \"vitest run\",\n \"clean\": \"rm -rf dist .turbo node_modules\",\n \"build\": \"tsup --silent\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"@solana/web3.js\": \"^1.98.2\",\n \"@talismn/chaindata-provider\": \"workspace:*\",\n \"@talismn/connection-meta\": \"workspace:*\",\n \"@talismn/util\": \"workspace:*\",\n \"anylogger\": \"^1.0.11\",\n \"eventemitter3\": \"^5.0.0\",\n \"lodash-es\": \"4.18.1\",\n \"viem\": \"2.52.2\"\n },\n \"devDependencies\": {\n \"@polkadot/rpc-provider\": \"16.1.2\",\n \"@polkadot/x-global\": \"13.5.3\",\n \"@polkadot/x-ws\": \"13.5.3\",\n \"@talismn/tsconfig\": \"workspace:*\",\n \"typescript\": \"^6.0.3\"\n },\n \"peerDependencies\": {\n \"@polkadot/rpc-provider\": \"*\",\n \"@polkadot/x-global\": \"*\",\n \"@polkadot/x-ws\": \"*\"\n },\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"@talismn/source\": \"./src/index.ts\",\n \"import\": {\n \"types\": \"./dist/index.d.mts\",\n \"default\": \"./dist/index.mjs\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n }\n }\n }\n}\n","import { RpcCoder } from \"@polkadot/rpc-provider/coder\"\nimport type {\n JsonRpcResponse,\n ProviderInterfaceEmitted as PjsProviderInterfaceEmitted,\n ProviderInterface,\n ProviderInterfaceCallback,\n ProviderInterfaceEmitCb,\n} from \"@polkadot/rpc-provider/types\"\nimport { getWSErrorString } from \"@polkadot/rpc-provider/ws/errors\"\nimport { xglobal } from \"@polkadot/x-global\"\nimport { WebSocket } from \"@polkadot/x-ws\"\nimport EventEmitter from \"eventemitter3\"\n\nimport log from \"../log\"\nimport { ExponentialBackoff } from \"./helpers\"\n\n// biome-ignore lint/complexity/noBannedTypes: checking class hierarchy\nconst isChildClass = (Parent: Function, Child: Function | undefined | null): boolean =>\n Child != null && (Child === Parent || Child.prototype instanceof Parent)\n\ntype ProviderInterfaceEmitted = PjsProviderInterfaceEmitted | \"stale-rpcs\"\n\n// to account for new requirement for generic arg in this type https://github.com/polkadot-js/api/commit/f4c2b150d3d69d43c56699613666b96dd0a763f4#diff-f87c17bc7fae027ec6d43bac5fc089614d9fa097f466aa2be333b44cee81f0fd\n// TODO incrementally replace 'unknown' with proper types where possible\ntype UnknownJsonRpcResponse<T = unknown> = JsonRpcResponse<T>\n\ninterface SubscriptionHandler {\n callback: ProviderInterfaceCallback\n type: string\n}\n\ninterface WsStateAwaiting {\n callback: ProviderInterfaceCallback\n method: string\n params: unknown[]\n start: number\n subscription?: SubscriptionHandler\n}\n\ninterface WsStateSubscription extends SubscriptionHandler {\n method: string\n params: unknown[]\n}\n\nconst ALIASES: { [index: string]: string } = {\n chain_finalisedHead: \"chain_finalizedHead\",\n chain_subscribeFinalisedHeads: \"chain_subscribeFinalizedHeads\",\n chain_unsubscribeFinalisedHeads: \"chain_unsubscribeFinalizedHeads\",\n}\n\nconst DEFAULT_TIMEOUT_MS = 60 * 1000\nconst TIMEOUT_INTERVAL = 5_000\n\nfunction eraseRecord<T>(record: Record<string, T>, cb?: (item: T) => void): void {\n Object.keys(record).forEach((key): void => {\n if (cb) {\n cb(record[key])\n }\n\n delete record[key]\n })\n}\n\n/**\n * # @talismn/chain-connector/Websocket\n *\n * @name Websocket\n *\n * @description The WebSocket Provider allows sending requests using WebSocket to a WebSocket RPC server TCP port. Unlike the [[HttpProvider]], it does support subscriptions and allows listening to events such as new blocks or balance changes.\n *\n * @example\n * <BR>\n *\n * ```javascript\n * import { Websocket } from '@talismn/chain-connector';\n *\n * const provider = new Websocket('ws://127.0.0.1:9944');\n * ```\n *\n * @see [[HttpProvider]]\n */\nexport class Websocket implements ProviderInterface {\n readonly #coder: RpcCoder\n readonly #endpoints: string[]\n readonly #headers: Record<string, string>\n readonly #eventemitter: EventEmitter\n readonly #handlers: Record<string, WsStateAwaiting> = {}\n readonly #isReadyPromise: Promise<Websocket>\n readonly #waitingForId: Record<string, UnknownJsonRpcResponse> = {}\n\n #autoConnectBackoff: ExponentialBackoff\n #endpointIndex: number\n #endpointsTriedSinceLastConnection = 0\n #isConnected = false\n #subscriptions: Record<string, WsStateSubscription> = {}\n #timeoutId?: ReturnType<typeof setInterval> | null = null\n #websocket: WebSocket | null\n #timeout: number\n\n /**\n * @param {string | string[]} endpoint The endpoint url. Usually `ws://ip:9944` or `wss://ip:9944`, may provide an array of endpoint strings.\n * @param {Record<string, string>} headers The headers provided to the underlying WebSocket\n * @param {number} [timeout] Custom timeout value used per request . Defaults to `DEFAULT_TIMEOUT_MS`\n */\n constructor(\n endpoint: string | string[],\n headers: Record<string, string> = {},\n timeout?: number,\n nextBackoffInterval?: number\n ) {\n const endpoints = Array.isArray(endpoint) ? endpoint : [endpoint]\n\n if (endpoints.length === 0) {\n throw new Error(\"Websocket requires at least one Endpoint\")\n }\n\n endpoints.forEach((endpoint) => {\n if (!/^(wss|ws):\\/\\//.test(endpoint)) {\n throw new Error(`Endpoint should start with 'ws://', received '${endpoint}'`)\n }\n })\n\n this.#eventemitter = new EventEmitter()\n this.#autoConnectBackoff = new ExponentialBackoff()\n if (nextBackoffInterval) this.#autoConnectBackoff.resetTo(nextBackoffInterval)\n this.#coder = new RpcCoder()\n this.#endpointIndex = -1\n this.#endpoints = endpoints\n this.#headers = headers\n this.#websocket = null\n this.#timeout = timeout || DEFAULT_TIMEOUT_MS\n\n if (this.#autoConnectBackoff.isActive) {\n this.connectWithRetry().catch(() => {\n // does not throw\n })\n }\n\n this.#isReadyPromise = new Promise((resolve): void => {\n this.#eventemitter.once(\"connected\", (): void => {\n resolve(this)\n })\n })\n }\n\n /**\n * @summary `true` when this provider supports subscriptions\n */\n public get hasSubscriptions(): boolean {\n return true\n }\n\n /**\n * @summary `true` when this provider supports clone()\n */\n public get isClonable(): boolean {\n return true\n }\n\n /**\n * @summary Whether the node is connected or not.\n * @return {boolean} true if connected\n */\n public get isConnected(): boolean {\n return this.#isConnected\n }\n\n /**\n * @description Promise that resolves the first time we are connected and loaded\n */\n public get isReady(): Promise<Websocket> {\n return this.#isReadyPromise\n }\n\n public get endpoint(): string {\n return this.#endpoints[this.#endpointIndex]\n }\n\n /**\n * @description Returns a clone of the object\n */\n public clone(): Websocket {\n return new Websocket(this.#endpoints)\n }\n\n protected selectEndpointIndex(endpoints: string[]): number {\n this.#endpointsTriedSinceLastConnection += 1\n return (this.#endpointIndex + 1) % endpoints.length\n }\n\n /**\n * @summary Manually connect\n * @description The [[Websocket]] connects automatically by default, however if you decided otherwise, you may\n * connect manually using this method.\n */\n public async connect(): Promise<void> {\n if (this.#websocket) {\n throw new Error(\"WebSocket is already connected\")\n }\n\n try {\n this.#endpointIndex = this.selectEndpointIndex(this.#endpoints)\n\n // the as typeof WebSocket here is Deno-specific - not available on the globalThis\n this.#websocket =\n typeof xglobal.WebSocket !== \"undefined\" &&\n isChildClass(xglobal.WebSocket as typeof WebSocket, WebSocket)\n ? new WebSocket(this.endpoint)\n : // @ts-expect-error - WS may be an instance of ws, which supports options\n new WebSocket(this.endpoint, undefined, {\n headers: this.#headers,\n })\n\n if (this.#websocket) {\n this.#websocket.onclose = this.#onSocketClose\n this.#websocket.onerror = this.#onSocketError\n this.#websocket.onmessage = this.#onSocketMessage\n this.#websocket.onopen = this.#onSocketOpen\n }\n\n // timeout any handlers that have not had a response\n this.#timeoutId = setInterval(() => this.#timeoutHandlers(), TIMEOUT_INTERVAL)\n } catch (error) {\n log.error(error)\n\n this.#emit(\"error\", error)\n\n throw error\n }\n }\n\n /**\n * @description Connect, never throwing an error, but rather forcing a retry\n */\n public async connectWithRetry(): Promise<void> {\n if (!this.#autoConnectBackoff.isActive) return\n\n try {\n await this.connect()\n } catch {\n this.scheduleNextRetry()\n }\n }\n\n protected scheduleNextRetry() {\n if (!this.#autoConnectBackoff.isActive) return\n\n const haveTriedAllEndpoints =\n this.#endpointsTriedSinceLastConnection > 0 &&\n this.#endpointsTriedSinceLastConnection % this.#endpoints.length === 0\n\n setTimeout(\n (): void => {\n this.connectWithRetry().catch(() => {\n // does not throw\n })\n },\n haveTriedAllEndpoints ? this.#autoConnectBackoff.next : 0\n )\n\n // Increase backoff when we've tried all endpoints\n if (haveTriedAllEndpoints) this.#autoConnectBackoff.increase()\n\n // Fire a stale-rpcs event when we've tried all endpoints in the list\n // but haven't successfully connected to any of them\n if (haveTriedAllEndpoints)\n this.#emit(\"stale-rpcs\", { nextBackoffInterval: this.#autoConnectBackoff.next })\n }\n\n /**\n * @description Manually disconnect from the connection, clearing auto-connect logic\n */\n public async disconnect(): Promise<void> {\n // switch off autoConnect, we are in manual mode now\n this.#autoConnectBackoff.disable()\n\n try {\n if (this.#websocket) {\n // 1000 - Normal closure; the connection successfully completed\n this.#websocket.close(1000)\n }\n } catch (error) {\n log.error(error)\n\n this.#emit(\"error\", error)\n\n throw error\n }\n }\n\n /**\n * @summary Listens on events after having subscribed using the [[subscribe]] function.\n * @param {ProviderInterfaceEmitted} type Event\n * @param {ProviderInterfaceEmitCb} sub Callback\n * @return unsubscribe function\n */\n public on(type: ProviderInterfaceEmitted, sub: ProviderInterfaceEmitCb): () => void {\n this.#eventemitter.on(type, sub)\n\n return (): void => {\n this.#eventemitter.removeListener(type, sub)\n }\n }\n\n /**\n * @summary Send JSON data using WebSockets to configured HTTP Endpoint or queue.\n * @param method The RPC methods to execute\n * @param params Encoded parameters as applicable for the method\n * @param subscription Subscription details (internally used)\n */\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n public send<T = any>(\n method: string,\n params: unknown[],\n /** @deprecated \\@talismn/chain-connector doesn't implement a cache */\n _isCacheable?: boolean,\n subscription?: SubscriptionHandler\n ): Promise<T> {\n const [id, body] = this.#coder.encodeJson(method, params)\n const resultPromise: Promise<T> = this.#send(id, body, method, params, subscription)\n\n return resultPromise\n }\n\n async #send<T>(\n id: number,\n body: string,\n method: string,\n params: unknown[],\n subscription?: SubscriptionHandler\n ): Promise<T> {\n return new Promise<T>((resolve, reject): void => {\n try {\n if (!this.isConnected || this.#websocket === null) {\n throw new Error(\"WebSocket is not connected\")\n }\n\n const callback = (error?: Error | null, result?: T): void => {\n error ? reject(error) : resolve(result as T)\n }\n\n // log.debug(() => [\"calling\", method, body])\n\n this.#handlers[id] = {\n callback,\n method,\n params,\n start: Date.now(),\n subscription,\n }\n this.#websocket.send(body)\n } catch (error) {\n reject(error)\n }\n })\n }\n\n /**\n * @name subscribe\n * @summary Allows subscribing to a specific event.\n *\n * @example\n * <BR>\n *\n * ```javascript\n * const provider = new Websocket('ws://127.0.0.1:9944');\n * const rpc = new Rpc(provider);\n *\n * rpc.state.subscribeStorage([[storage.system.account, <Address>]], (_, values) => {\n * console.log(values)\n * }).then((subscriptionId) => {\n * console.log('balance changes subscription id: ', subscriptionId)\n * })\n * ```\n */\n public subscribe(\n type: string,\n method: string,\n params: unknown[],\n callback: ProviderInterfaceCallback\n ): Promise<number | string> {\n return this.send<number | string>(method, params, false, { callback, type })\n }\n\n /**\n * @summary Allows unsubscribing to subscriptions made with [[subscribe]].\n */\n public async unsubscribe(type: string, method: string, id: number | string): Promise<boolean> {\n const subscription = `${type}::${id}`\n\n // FIXME This now could happen with re-subscriptions. The issue is that with a re-sub\n // the assigned id now does not match what the API user originally received. It has\n // a slight complication in solving - since we cannot rely on the send id, but rather\n // need to find the actual subscription id to map it\n if (this.#subscriptions[subscription] === undefined) {\n // log.debug(() => `Unable to find active subscription=${subscription}`)\n\n return false\n }\n\n delete this.#subscriptions[subscription]\n\n try {\n return this.isConnected && this.#websocket !== null ? this.send<boolean>(method, [id]) : true\n } catch {\n return false\n }\n }\n\n #emit = (type: ProviderInterfaceEmitted, ...args: unknown[]): void => {\n this.#eventemitter.emit(type, ...args)\n }\n\n #onSocketClose = (event: CloseEvent): void => {\n const error = new Error(\n `disconnected from ${this.endpoint}: ${event.code}:: ${\n event.reason || getWSErrorString(event.code)\n }`\n )\n\n if (this.#autoConnectBackoff.isActive) {\n // 1000 is a normal closure and should not be logged as an error\n if (event.code !== 1000) log.error(error.message)\n }\n\n this.#isConnected = false\n\n if (this.#websocket) {\n this.#websocket.onclose = null\n this.#websocket.onerror = null\n this.#websocket.onmessage = null\n this.#websocket.onopen = null\n this.#websocket = null\n }\n\n if (this.#timeoutId) {\n clearInterval(this.#timeoutId)\n this.#timeoutId = null\n }\n\n // reject all hanging requests\n eraseRecord(this.#handlers, (h) => {\n try {\n h.callback(error, undefined)\n } catch (err) {\n // does not throw\n log.error(err)\n }\n })\n eraseRecord(this.#waitingForId)\n\n this.#emit(\"disconnected\")\n\n this.scheduleNextRetry()\n }\n\n #onSocketError = (error: Event): void => {\n // log.debug(() => [\"socket error\", error])\n this.#emit(\"error\", error)\n }\n\n #onSocketMessage = (message: MessageEvent<string>): void => {\n // log.debug(() => [\"received\", message.data])\n try {\n const response = JSON.parse(message.data) as UnknownJsonRpcResponse\n\n // biome-ignore lint/correctness/noVoidTypeReturn: legacy\n return response.method === undefined\n ? this.#onSocketMessageResult(response)\n : this.#onSocketMessageSubscribe(response)\n } catch (e) {\n this.#emit(\"error\", new Error(\"Invalid websocket message received\", { cause: e }))\n }\n }\n\n #onSocketMessageResult = (response: UnknownJsonRpcResponse): void => {\n const handler = this.#handlers[response.id]\n\n if (!handler) {\n // log.debug(() => `Unable to find handler for id=${response.id}`)\n\n return\n }\n\n try {\n const { method, params, subscription } = handler\n const result = this.#coder.decodeResponse(response) as string\n\n // first send the result - in case of subs, we may have an update\n // immediately if we have some queued results already\n handler.callback(null, result)\n\n if (subscription) {\n const subId = `${subscription.type}::${result}`\n\n this.#subscriptions[subId] = { ...subscription, method, params }\n\n // if we have a result waiting for this subscription already\n if (this.#waitingForId[subId]) {\n this.#onSocketMessageSubscribe(this.#waitingForId[subId])\n }\n }\n } catch (error) {\n handler.callback(error as Error, undefined)\n }\n\n delete this.#handlers[response.id]\n }\n\n #onSocketMessageSubscribe = (response: UnknownJsonRpcResponse): void => {\n const method = ALIASES[response.method as string] || response.method || \"invalid\"\n const subId = `${method}::${response.params.subscription}`\n const handler = this.#subscriptions[subId]\n\n if (!handler) {\n // store the JSON, we could have out-of-order subid coming in\n this.#waitingForId[subId] = response\n\n // log.debug(() => `Unable to find handler for subscription=${subId}`)\n\n return\n }\n\n // housekeeping\n delete this.#waitingForId[subId]\n\n try {\n const result = this.#coder.decodeResponse(response)\n\n handler.callback(null, result)\n } catch (error) {\n handler.callback(error as Error, undefined)\n }\n }\n\n #onSocketOpen = (): boolean => {\n if (this.#websocket === null) {\n throw new Error(\"WebSocket cannot be null in onOpen\")\n }\n\n // log.debug(() => [\"connected to\", this.endpoint])\n\n this.#isConnected = true\n this.#endpointsTriedSinceLastConnection = 0\n this.#autoConnectBackoff.reset()\n\n this.#resubscribe()\n\n this.#emit(\"connected\")\n\n return true\n }\n\n #resubscribe = (): void => {\n const subscriptions = this.#subscriptions\n\n this.#subscriptions = {}\n\n Promise.all(\n Object.keys(subscriptions).map(async (id): Promise<void> => {\n const { callback, method, params, type } = subscriptions[id]\n\n // only re-create subscriptions which are not in author (only area where\n // transactions are created, i.e. submissions such as 'author_submitAndWatchExtrinsic'\n // are not included (and will not be re-broadcast)\n if (type.startsWith(\"author_\")) {\n return\n }\n\n try {\n await this.subscribe(type, method, params, callback)\n } catch (error) {\n log.error(error)\n }\n })\n ).catch(log.error)\n }\n\n #timeoutHandlers = (): void => {\n const now = Date.now()\n const ids = Object.keys(this.#handlers)\n\n for (let i = 0; i < ids.length; i++) {\n const handler = this.#handlers[ids[i]]\n\n if (now - handler.start > this.#timeout) {\n try {\n handler.callback(\n new Error(`No response received from RPC endpoint in ${this.#timeout / 1000}s`),\n undefined\n )\n } catch {\n // ignore\n }\n\n delete this.#handlers[ids[i]]\n }\n }\n }\n}\n","const twoSecondsMs = 2 * 1000\nconst twoMinutesMs = 2 * 60 * 1000\n\nexport class ExponentialBackoff {\n #minInterval: number\n #maxInterval: number\n #nextInterval = 0\n #active = true\n\n constructor(maxIntervalMs = twoMinutesMs, minIntervalMs = twoSecondsMs) {\n this.#minInterval = minIntervalMs\n this.#maxInterval = maxIntervalMs\n\n this.reset()\n }\n\n enable() {\n this.#active = true\n }\n disable() {\n this.#active = false\n }\n\n increase() {\n if (this.#nextInterval === 0) this.#nextInterval = 1\n this.#nextInterval = this.#capMax(this.#capMin(this.#nextInterval * 2))\n }\n decrease() {\n this.#nextInterval = this.#capMax(this.#capMin(this.#nextInterval / 2))\n }\n\n reset() {\n this.#nextInterval = this.#minInterval\n }\n resetTo(nextInterval: number) {\n this.#nextInterval = this.#capMax(this.#capMin(nextInterval))\n }\n resetToMax() {\n this.#nextInterval = this.#maxInterval\n }\n\n get isActive() {\n return this.#active\n }\n get next() {\n return this.#nextInterval\n }\n\n get isMin() {\n return this.#nextInterval === this.#minInterval\n }\n get isMax() {\n return this.#nextInterval === this.#maxInterval\n }\n\n #capMin(value: number) {\n return Math.max(this.#minInterval, value)\n }\n #capMax(value: number) {\n return Math.min(this.#maxInterval, value)\n }\n}\n","import { WsProvider } from \"@polkadot/rpc-provider\"\nimport type { ProviderInterface, ProviderInterfaceCallback } from \"@polkadot/rpc-provider/types\"\nimport type { DotNetwork, DotNetworkId } from \"@talismn/chaindata-provider\"\nimport { throwAfter } from \"@talismn/util\"\n\nimport type { IChainConnectorDot } from \"./IChainConnectorDot\"\n\nconst AUTO_CONNECT_TIMEOUT = 3_000\nconst TIMEOUT = 10_000\n\nexport class ChainConnectorDotStub implements IChainConnectorDot {\n // biome-ignore lint/correctness/noUnusedPrivateClassMembers: legacy\n #network: DotNetwork\n #provider: WsProvider\n\n constructor(network: DotNetwork) {\n this.#network = network\n this.#provider = new WsProvider(network.rpcs, AUTO_CONNECT_TIMEOUT, undefined, TIMEOUT)\n }\n\n asProvider(): ProviderInterface {\n return this.#provider as ProviderInterface\n }\n\n async send<T = unknown>(\n _chainId: DotNetworkId,\n method: string,\n params: unknown[],\n isCacheable?: boolean\n ): Promise<T> {\n await this.#provider.isReady\n\n return this.#provider.send(method, params, isCacheable) as Promise<T>\n }\n\n async subscribe(\n _chainId: DotNetworkId,\n subscribeMethod: string,\n responseMethod: string,\n params: unknown[],\n callback: ProviderInterfaceCallback,\n timeout?: number | false\n ): Promise<(unsubscribeMethod: string) => void> {\n await this.#provider.isReady\n\n const subId = await Promise.race([\n throwAfter(timeout || TIMEOUT, `Subscription timed out after ${timeout}ms`),\n this.#provider.subscribe(responseMethod, subscribeMethod, params, callback),\n ])\n\n return (unsubscribeMethod: string) => {\n this.#provider.unsubscribe(responseMethod, unsubscribeMethod, subId)\n }\n }\n\n reset(): Promise<void> {\n throw new Error(\"ChainConnectorDotStub does not implement reset\")\n }\n}\n","import type { EthNetwork } from \"@talismn/chaindata-provider\"\nimport { createPublicClient, type PublicClient } from \"viem\"\n\nimport { clearChainsCache, getChainFromEvmNetwork } from \"./getChainFromEvmNetwork\"\nimport { getTransportForEvmNetwork, type TransportOptions } from \"./getTransportForEvmNetwork\"\n\nconst MUTLICALL_BATCH_WAIT = 25\nconst MUTLICALL_BATCH_SIZE = 100\n\nconst HTTP_BATCH_WAIT = 25\nconst HTTP_BATCH_SIZE_WITH_MULTICALL = 10\nconst HTTP_BATCH_SIZE_WITHOUT_MULTICALL = 30\n\n// cache to reuse previously created public clients\nconst publicClientCache = new Map<string, PublicClient>()\n\nexport const clearPublicClientCache = (evmNetworkId?: string) => {\n clearChainsCache(evmNetworkId)\n\n if (evmNetworkId) publicClientCache.delete(evmNetworkId)\n else publicClientCache.clear()\n}\n\nexport const getEvmNetworkPublicClient = (network: EthNetwork): PublicClient => {\n const chain = getChainFromEvmNetwork(network)\n\n if (!publicClientCache.has(network.id)) {\n if (!network.rpcs.length) throw new Error(\"No RPCs found for Ethereum network\")\n\n const batch = chain.contracts?.multicall3\n ? { multicall: { wait: MUTLICALL_BATCH_WAIT, batchSize: MUTLICALL_BATCH_SIZE } }\n : undefined\n\n const transportOptions: TransportOptions = {\n batch: {\n batchSize: chain.contracts?.multicall3\n ? HTTP_BATCH_SIZE_WITH_MULTICALL\n : HTTP_BATCH_SIZE_WITHOUT_MULTICALL,\n wait: HTTP_BATCH_WAIT,\n },\n }\n\n const transport = getTransportForEvmNetwork(network, transportOptions)\n\n publicClientCache.set(\n network.id,\n createPublicClient({\n chain,\n transport,\n batch,\n })\n )\n }\n\n return publicClientCache.get(network.id) as PublicClient\n}\n","import type { EthNetwork, EthNetworkId } from \"@talismn/chaindata-provider\"\nimport { camelCase, fromPairs, toPairs } from \"lodash-es\"\nimport type { Chain, ChainContract } from \"viem\"\nimport * as viemChains from \"viem/chains\"\n\n// exclude zoraTestnet which uses Hyperliquid's chain id\nconst { zoraTestnet, ...validViemChains } = viemChains\n\n// viem chains benefit from multicall config & other viem goodies\nconst VIEM_CHAINS = Object.keys(validViemChains).reduce(\n (acc, curr) => {\n const chain = validViemChains[curr as keyof typeof validViemChains]\n acc[chain.id] = chain\n return acc\n },\n {} as Record<number, Chain>\n)\n\nconst chainsCache = new Map<string, Chain>()\n\nexport const clearChainsCache = (networkId?: EthNetworkId) => {\n if (networkId) chainsCache.delete(networkId)\n else chainsCache.clear()\n}\n\nexport const getChainFromEvmNetwork = (network: EthNetwork): Chain => {\n const { symbol, decimals } = network.nativeCurrency\n\n if (!chainsCache.has(network.id)) {\n const chainRpcs = network.rpcs ?? []\n\n const viemChain = VIEM_CHAINS[Number(network.id)] ?? {}\n\n const chain: Chain = {\n ...viemChain,\n id: Number(network.id),\n name: network.name ?? `Ethereum Chain ${network.id}`,\n rpcUrls: {\n public: { http: chainRpcs },\n default: { http: chainRpcs },\n },\n nativeCurrency: {\n symbol,\n decimals,\n name: symbol,\n },\n contracts: {\n ...viemChain.contracts,\n ...(network.contracts\n ? fromPairs(\n toPairs(network.contracts).map(([name, address]): [string, ChainContract] => [\n camelCase(name),\n { address },\n ])\n )\n : {}),\n },\n }\n\n chainsCache.set(network.id, chain)\n }\n\n return chainsCache.get(network.id) as Chain\n}\n","import type { EthNetwork } from \"@talismn/chaindata-provider\"\nimport { fallback, http } from \"viem\"\n\nexport type TransportOptions = {\n batch?:\n | boolean\n | {\n batchSize?: number | undefined\n wait?: number | undefined\n }\n}\n\nexport const getTransportForEvmNetwork = (\n evmNetwork: EthNetwork,\n options: TransportOptions = {}\n) => {\n if (!evmNetwork.rpcs?.length) throw new Error(\"No RPCs found for EVM network\")\n\n const { batch } = options\n\n return fallback(\n evmNetwork.rpcs.map((url) => http(url, { batch, retryCount: 0 })),\n { retryCount: 0 }\n )\n}\n","import type { EthNetwork } from \"@talismn/chaindata-provider\"\nimport { type Account, createWalletClient, type WalletClient } from \"viem\"\n\nimport { getChainFromEvmNetwork } from \"./getChainFromEvmNetwork\"\nimport { getTransportForEvmNetwork } from \"./getTransportForEvmNetwork\"\n\ntype WalletClientOptions = {\n account?: `0x${string}` | Account\n}\n\nexport const getEvmNetworkWalletClient = (\n network: EthNetwork,\n options: WalletClientOptions = {}\n): WalletClient => {\n const chain = getChainFromEvmNetwork(network)\n\n const transport = getTransportForEvmNetwork(network)\n\n return createWalletClient({ chain, transport, account: options.account })\n}\n","import type {\n EthNetworkId,\n IChaindataNetworkProvider,\n IChaindataTokenProvider,\n} from \"@talismn/chaindata-provider\"\nimport type { Account, PublicClient, WalletClient } from \"viem\"\n\nimport { clearPublicClientCache, getEvmNetworkPublicClient } from \"./getEvmNetworkPublicClient\"\nimport { getEvmNetworkWalletClient } from \"./getEvmNetworkWalletClient\"\nimport type { IChainConnectorEth } from \"./IChainConnectorEth\"\n\nexport class ChainConnectorEth implements IChainConnectorEth {\n #chaindataProvider: IChaindataNetworkProvider & IChaindataTokenProvider\n\n constructor(chaindataProvider: IChaindataNetworkProvider & IChaindataTokenProvider) {\n this.#chaindataProvider = chaindataProvider\n }\n\n async getPublicClientForEvmNetwork(evmNetworkId: EthNetworkId): Promise<PublicClient | null> {\n const network = await this.#chaindataProvider.getNetworkById(evmNetworkId, \"ethereum\")\n if (!network) return null\n\n return getEvmNetworkPublicClient(network)\n }\n\n async getWalletClientForEvmNetwork(\n evmNetworkId: EthNetworkId,\n account?: `0x${string}` | Account\n ): Promise<WalletClient | null> {\n const network = await this.#chaindataProvider.getNetworkById(evmNetworkId, \"ethereum\")\n if (!network) return null\n\n return getEvmNetworkWalletClient(network, { account })\n }\n\n public clearRpcProvidersCache(evmNetworkId?: EthNetworkId) {\n clearPublicClientCache(evmNetworkId)\n }\n}\n","import type { EthNetwork, EthNetworkId } from \"@talismn/chaindata-provider\"\nimport type { Account, PublicClient, WalletClient } from \"viem\"\n\nimport { getEvmNetworkPublicClient } from \"./getEvmNetworkPublicClient\"\nimport { getEvmNetworkWalletClient } from \"./getEvmNetworkWalletClient\"\nimport type { IChainConnectorEth } from \"./IChainConnectorEth\"\n\nexport class ChainConnectorEthStub implements IChainConnectorEth {\n #network: EthNetwork\n\n constructor(network: EthNetwork) {\n this.#network = network\n }\n\n async getPublicClientForEvmNetwork(): Promise<PublicClient | null> {\n return getEvmNetworkPublicClient(this.#network)\n }\n\n async getWalletClientForEvmNetwork(\n _networkId: EthNetworkId,\n account?: `0x${string}` | Account\n ): Promise<WalletClient | null> {\n return getEvmNetworkWalletClient(this.#network, { account })\n }\n\n clearRpcProvidersCache(): void {\n // No-op for stub\n }\n}\n","import { Connection } from \"@solana/web3.js\"\nimport type { SolNetworkId } from \"@talismn/chaindata-provider\"\n\n// TODO leverage multiple rpcs with fallback\nexport const getSolConnection = (_networkId: SolNetworkId, rpcs: string[]) => {\n return new Connection(rpcs[0], {\n commitment: \"confirmed\",\n })\n}\n","import type { Connection } from \"@solana/web3.js\"\nimport type {\n IChaindataNetworkProvider,\n IChaindataTokenProvider,\n SolNetworkId,\n} from \"@talismn/chaindata-provider\"\n\nimport { getSolConnection } from \"./getSolConnection\"\nimport type { IChainConnectorSol } from \"./IChainConnectorSol\"\n\nexport class ChainConnectorSol implements IChainConnectorSol {\n #chaindataProvider: IChaindataNetworkProvider & IChaindataTokenProvider\n\n constructor(chaindataProvider: IChaindataNetworkProvider & IChaindataTokenProvider) {\n this.#chaindataProvider = chaindataProvider\n }\n\n async getConnection(networkId: SolNetworkId): Promise<Connection> {\n const network = await this.#chaindataProvider.getNetworkById(networkId, \"solana\")\n if (!network) throw new Error(`Network not found: ${networkId}`)\n\n return getSolConnection(networkId, network.rpcs)\n }\n}\n","import type { Connection } from \"@solana/web3.js\"\nimport type { SolNetwork } from \"@talismn/chaindata-provider\"\n\nimport { getSolConnection } from \"./getSolConnection\"\nimport type { IChainConnectorSol } from \"./IChainConnectorSol\"\n\nexport class ChainConnectorSolStub implements IChainConnectorSol {\n #connection: Connection\n\n constructor(networkOrConnection: Pick<SolNetwork, \"id\" | \"rpcs\"> | Connection) {\n // NOTE: do not use `instanceof Connection` here. In bundled builds @solana/web3.js\n // can be duplicated across chunks, so a Connection created from one copy of the\n // module fails an `instanceof` check against another copy's class. That silently\n // fell through to getSolConnection() with an undefined `rpcs`, throwing\n // \"Cannot read properties of undefined (reading '0')\" and breaking every Solana\n // transfer. Duck-type on the network-only `rpcs` field instead (a Connection never\n // has it), which is robust regardless of how many module instances exist.\n this.#connection =\n \"rpcs\" in networkOrConnection\n ? getSolConnection(networkOrConnection.id, networkOrConnection.rpcs)\n : networkOrConnection\n }\n\n async getConnection(): Promise<Connection> {\n return this.#connection\n }\n}\n"],"mappings":"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","names":["anylogger","endpoint","EventEmitter","unsubscribeMethod","import_util","import_viem","import_viem"]}
package/dist/index.mjs CHANGED
@@ -7,7 +7,7 @@ import anylogger from "anylogger";
7
7
  // package.json
8
8
  var package_default = {
9
9
  name: "@talismn/chain-connectors",
10
- version: "0.0.19",
10
+ version: "0.1.0",
11
11
  author: "Talisman",
12
12
  homepage: "https://talisman.xyz",
13
13
  license: "GPL-3.0-or-later",
@@ -40,20 +40,18 @@ var package_default = {
40
40
  "@talismn/util": "workspace:*",
41
41
  anylogger: "^1.0.11",
42
42
  eventemitter3: "^5.0.0",
43
- "lodash-es": "4.17.21",
44
- viem: "^2.27.3"
43
+ "lodash-es": "4.18.1",
44
+ viem: "2.52.2"
45
45
  },
46
46
  devDependencies: {
47
47
  "@polkadot/rpc-provider": "16.1.2",
48
- "@polkadot/util": "13.5.3",
49
48
  "@polkadot/x-global": "13.5.3",
50
49
  "@polkadot/x-ws": "13.5.3",
51
50
  "@talismn/tsconfig": "workspace:*",
52
- typescript: "^5.6.3"
51
+ typescript: "^6.0.3"
53
52
  },
54
53
  peerDependencies: {
55
54
  "@polkadot/rpc-provider": "*",
56
- "@polkadot/util": "*",
57
55
  "@polkadot/x-global": "*",
58
56
  "@polkadot/x-ws": "*"
59
57
  },
@@ -79,7 +77,6 @@ var log_default = anylogger(package_default.name);
79
77
  // src/dot/Websocket.ts
80
78
  import { RpcCoder } from "@polkadot/rpc-provider/coder";
81
79
  import { getWSErrorString } from "@polkadot/rpc-provider/ws/errors";
82
- import { isChildClass, isNull, isUndefined, objectSpread } from "@polkadot/util";
83
80
  import { xglobal } from "@polkadot/x-global";
84
81
  import { WebSocket } from "@polkadot/x-ws";
85
82
  import EventEmitter from "eventemitter3";
@@ -140,6 +137,7 @@ var ExponentialBackoff = class {
140
137
  };
141
138
 
142
139
  // src/dot/Websocket.ts
140
+ var isChildClass = (Parent, Child) => Child != null && (Child === Parent || Child.prototype instanceof Parent);
143
141
  var ALIASES = {
144
142
  chain_finalisedHead: "chain_finalizedHead",
145
143
  chain_subscribeFinalisedHeads: "chain_subscribeFinalizedHeads",
@@ -385,12 +383,12 @@ var Websocket = class _Websocket {
385
383
  */
386
384
  async unsubscribe(type, method, id) {
387
385
  const subscription = `${type}::${id}`;
388
- if (isUndefined(this.#subscriptions[subscription])) {
386
+ if (this.#subscriptions[subscription] === void 0) {
389
387
  return false;
390
388
  }
391
389
  delete this.#subscriptions[subscription];
392
390
  try {
393
- return this.isConnected && !isNull(this.#websocket) ? this.send(method, [id]) : true;
391
+ return this.isConnected && this.#websocket !== null ? this.send(method, [id]) : true;
394
392
  } catch {
395
393
  return false;
396
394
  }
@@ -434,7 +432,7 @@ var Websocket = class _Websocket {
434
432
  #onSocketMessage = (message) => {
435
433
  try {
436
434
  const response = JSON.parse(message.data);
437
- return isUndefined(response.method) ? this.#onSocketMessageResult(response) : this.#onSocketMessageSubscribe(response);
435
+ return response.method === void 0 ? this.#onSocketMessageResult(response) : this.#onSocketMessageSubscribe(response);
438
436
  } catch (e) {
439
437
  this.#emit("error", new Error("Invalid websocket message received", { cause: e }));
440
438
  }
@@ -450,10 +448,7 @@ var Websocket = class _Websocket {
450
448
  handler.callback(null, result);
451
449
  if (subscription) {
452
450
  const subId = `${subscription.type}::${result}`;
453
- this.#subscriptions[subId] = objectSpread({}, subscription, {
454
- method,
455
- params
456
- });
451
+ this.#subscriptions[subId] = { ...subscription, method, params };
457
452
  if (this.#waitingForId[subId]) {
458
453
  this.#onSocketMessageSubscribe(this.#waitingForId[subId]);
459
454
  }
@@ -1160,11 +1155,10 @@ var ChainConnectorSol = class {
1160
1155
  };
1161
1156
 
1162
1157
  // src/sol/ChainConnectorSolStub.ts
1163
- import { Connection as Connection2 } from "@solana/web3.js";
1164
1158
  var ChainConnectorSolStub = class {
1165
1159
  #connection;
1166
1160
  constructor(networkOrConnection) {
1167
- this.#connection = networkOrConnection instanceof Connection2 ? networkOrConnection : getSolConnection(networkOrConnection.id, networkOrConnection.rpcs);
1161
+ this.#connection = "rpcs" in networkOrConnection ? getSolConnection(networkOrConnection.id, networkOrConnection.rpcs) : networkOrConnection;
1168
1162
  }
1169
1163
  async getConnection() {
1170
1164
  return this.#connection;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/dot/ChainConnectorDot.ts","../src/log.ts","../package.json","../src/dot/Websocket.ts","../src/dot/helpers.ts","../src/dot/ChainConnectorDotStub.ts","../src/eth/getEvmNetworkPublicClient.ts","../src/eth/getChainFromEvmNetwork.ts","../src/eth/getTransportForEvmNetwork.ts","../src/eth/getEvmNetworkWalletClient.ts","../src/eth/ChainConnectorEth.ts","../src/eth/ChainConnectorEthStub.ts","../src/sol/getSolConnection.ts","../src/sol/ChainConnectorSol.ts","../src/sol/ChainConnectorSolStub.ts"],"sourcesContent":["import type { ProviderInterface, ProviderInterfaceCallback } from \"@polkadot/rpc-provider/types\"\nimport type { DotNetworkId, IChaindataNetworkProvider } from \"@talismn/chaindata-provider\"\nimport type { TalismanConnectionMetaDatabase } from \"@talismn/connection-meta\"\nimport { Deferred, isTruthy, sleep, throwAfter } from \"@talismn/util\"\n\nimport log from \"../log\"\nimport type { IChainConnectorDot } from \"./IChainConnectorDot\"\nimport { Websocket } from \"./Websocket\"\n\n// errors that require an rpc fallback\n// https://docs.blastapi.io/blast-documentation/things-you-need-to-know/error-reference\nconst BAD_RPC_ERRORS: Record<string, string> = {\n \"-32097\": \"Rate limit exceeded\",\n \"-32098\": \"Capacity exceeded\",\n}\n\nexport class ChainConnectionError extends Error {\n type: \"CHAIN_CONNECTION_ERROR\"\n chainId: string\n\n constructor(chainId: string, options?: ErrorOptions) {\n super(`Unable to connect to chain ${chainId}`, options)\n\n this.type = \"CHAIN_CONNECTION_ERROR\"\n this.chainId = chainId\n }\n}\n\nexport class StaleRpcError extends Error {\n type: \"STALE_RPC_ERROR\"\n chainId: string\n\n constructor(chainId: string, options?: ErrorOptions) {\n super(`RPCs are stale/unavailable for chain ${chainId}`, options)\n\n this.type = \"STALE_RPC_ERROR\"\n this.chainId = chainId\n }\n}\nexport class WebsocketAllocationExhaustedError extends Error {\n type: \"WEBSOCKET_ALLOCATION_EXHAUSTED_ERROR\"\n chainId: string\n\n constructor(chainId: string, options?: ErrorOptions) {\n super(\n `No websockets are available from the browser pool to connect to chain ${chainId}`,\n options\n )\n\n this.type = \"WEBSOCKET_ALLOCATION_EXHAUSTED_ERROR\"\n this.chainId = chainId\n }\n}\nclass CallerUnsubscribedError extends Error {\n type: \"CALLER_UNSUBSCRIBED_ERROR\"\n chainId: string\n unsubscribeMethod: string\n\n constructor(chainId: string, unsubscribeMethod: string, options?: ErrorOptions) {\n super(`Caller unsubscribed from ${chainId}`, options)\n\n this.type = \"CALLER_UNSUBSCRIBED_ERROR\"\n this.chainId = chainId\n this.unsubscribeMethod = unsubscribeMethod\n }\n}\n\ntype SocketUserId = number\n\n/**\n * ChainConnector provides an interface similar to WsProvider, but with three points of difference:\n *\n * 1. ChainConnector methods all accept a `chainId` instead of an array of RPCs. RPCs are then fetched internally from chaindata.\n * 2. ChainConnector creates only one `WsProvider` per chain and ensures that all downstream requests to a chain share the one socket connection.\n * 3. Subscriptions return a callable `unsubscribe` method instead of an id.\n *\n * Additionally, when run on the clientside of a dapp where `window.talismanSub` is available, instead of spinning up new websocket\n * connections this class will forward all requests through to the wallet backend - where another instance of this class will\n * handle the websocket connections.\n */\nexport class ChainConnectorDot implements IChainConnectorDot {\n #chaindataChainProvider: IChaindataNetworkProvider\n #connectionMetaDb?: TalismanConnectionMetaDatabase\n\n #socketConnections: Record<DotNetworkId, Websocket> = {}\n #socketKeepAliveIntervals: Record<DotNetworkId, ReturnType<typeof setInterval>> = {}\n #socketUsers: Record<DotNetworkId, SocketUserId[]> = {}\n\n constructor(\n chaindataChainProvider: IChaindataNetworkProvider,\n connectionMetaDb?: TalismanConnectionMetaDatabase\n ) {\n this.#chaindataChainProvider = chaindataChainProvider\n this.#connectionMetaDb = connectionMetaDb\n\n if (this.#connectionMetaDb) {\n this.#chaindataChainProvider.getNetworkIds(\"polkadot\").then((chainIds) => {\n // tidy up connectionMeta for chains which no longer exist\n this.#connectionMetaDb?.chainPriorityRpcs.where(\"id\").noneOf(chainIds).delete()\n this.#connectionMetaDb?.chainBackoffInterval.where(\"id\").noneOf(chainIds).delete()\n })\n }\n }\n\n /**\n * Creates a facade over this ChainConnector which conforms to the PJS ProviderInterface\n * @example // Using a chainConnector as a Provider for an ApiPromise\n * const provider = chainConnector.asProvider('polkadot')\n * const api = new ApiPromise({ provider })\n */\n asProvider(chainId: DotNetworkId): ProviderInterface {\n const unsubHandler = new Map<string, (unsubscribeMethod: string) => void>()\n\n const providerFacade: ProviderInterface = {\n hasSubscriptions: true,\n isClonable: false,\n isConnected: true,\n clone: () => providerFacade,\n connect: () => Promise.resolve(),\n disconnect: () => Promise.resolve(),\n on: () => () => {},\n\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n send: async <T = any>(method: string, params: unknown[], isCacheable?: boolean): Promise<T> =>\n await this.send(chainId, method, params, isCacheable),\n\n subscribe: async (\n type: string,\n method: string,\n params: unknown[],\n cb: ProviderInterfaceCallback\n ): Promise<string> => {\n const unsubscribe = await this.subscribe(chainId, method, type, params, cb)\n\n const subscriptionId = this.getExclusiveRandomId(\n [...unsubHandler.keys()].map(Number)\n ).toString()\n unsubHandler.set(subscriptionId, unsubscribe)\n\n return subscriptionId\n },\n\n unsubscribe: async (_type: string, unsubscribeMethod: string, subscriptionId: string) => {\n unsubHandler.get(subscriptionId)?.(unsubscribeMethod)\n unsubHandler.delete(subscriptionId)\n\n return true\n },\n }\n\n return providerFacade\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n async send<T = any>(\n chainId: DotNetworkId,\n method: string,\n params: unknown[],\n isCacheable?: boolean | undefined,\n extraOptions?: {\n /**\n * Set to `true` if this query is speculative, i.e. if on some chains it's expected that it will raise a wasm unreachable error of the form:\n *\n * 4003: Client error: Execution failed: Execution aborted due to trap: wasm trap: wasm `unreachable` instruction executed\n *\n * By setting expectErrors to true, this method won't pollute the logs with errors we intend to have happen.\n * An example use case of this is when you plan to catch the wasm unreachable error on chains that don't support the query, and then fall back\n * to another query or perhaps an empty result.\n */\n expectErrors?: boolean\n }\n ): Promise<T> {\n const talismanSub = this.getTalismanSub()\n if (talismanSub !== undefined) {\n try {\n const chain = await this.#chaindataChainProvider.getNetworkById(chainId, \"polkadot\")\n if (!chain) throw new Error(`Chain ${chainId} not found in store`)\n\n const { genesisHash } = chain\n if (typeof genesisHash !== \"string\")\n throw new Error(`Chain ${chainId} has no genesisHash in store`)\n\n return await talismanSub.send(genesisHash, method, params)\n } catch (error) {\n log.warn(\n `Failed to make wallet-proxied send request for chain ${chainId}. Falling back to plain websocket`,\n error\n )\n }\n }\n\n try {\n // biome-ignore lint/correctness/noInnerDeclarations: legacy\n var [socketUserId, ws] = await this.connectChainSocket(chainId)\n } catch (error) {\n throw new StaleRpcError(chainId, { cause: error })\n }\n\n try {\n // wait for ws to be ready, but don't wait forever\n const timeout = 15_000 // 15 seconds in milliseconds\n await this.waitForWs(ws, timeout)\n } catch (error) {\n await this.disconnectChainSocket(chainId, socketUserId)\n throw new ChainConnectionError(chainId, { cause: error })\n }\n\n try {\n const timeout = 30_000 // throw after 30 seconds if no response\n // biome-ignore lint/correctness/noInnerDeclarations: legacy\n var response = await Promise.race([\n ws.send(method, params, isCacheable),\n throwAfter(timeout, \"TIMEOUT\"),\n ])\n } catch (err) {\n const error = err as (Error & { code?: number; data?: unknown }) | null\n\n if (error?.message === \"TIMEOUT\") {\n log.error(`ChainConnector timeout`, { chainId, endpoint: ws.endpoint, error })\n await this.updateRpcPriority(chainId, ws.endpoint, \"last\")\n await this.reset(chainId)\n throw new Error(\"Timeout\")\n }\n\n const badRpcError = BAD_RPC_ERRORS[error?.code?.toString() ?? \"\"]\n if (badRpcError) {\n log.error(`ChainConnector ${badRpcError}`, { error, chainId, endpoint: ws.endpoint })\n await this.updateRpcPriority(chainId, ws.endpoint, \"last\")\n await this.reset(chainId)\n throw new Error(badRpcError)\n }\n\n if (!extraOptions?.expectErrors)\n log.error(\n `Failed to send ${method} on chain ${chainId}\\nparams: ${JSON.stringify(params)}`,\n {\n error,\n endpoint: ws.endpoint,\n }\n )\n\n await this.disconnectChainSocket(chainId, socketUserId)\n throw error\n }\n\n await this.disconnectChainSocket(chainId, socketUserId)\n\n return response\n }\n\n async subscribe(\n chainId: DotNetworkId,\n subscribeMethod: string,\n responseMethod: string,\n params: unknown[],\n callback: ProviderInterfaceCallback,\n timeout: number | false = 30_000 // 30 seconds in milliseconds\n ): Promise<(unsubscribeMethod: string) => void> {\n const talismanSub = this.getTalismanSub()\n if (talismanSub !== undefined) {\n try {\n const chain = await this.#chaindataChainProvider.getNetworkById(chainId, \"polkadot\")\n if (!chain) throw new Error(`Chain ${chainId} not found in store`)\n\n const { genesisHash } = chain\n if (typeof genesisHash !== \"string\")\n throw new Error(`Chain ${chainId} has no genesisHash in store`)\n\n const subscriptionId = await talismanSub.subscribe(\n genesisHash,\n subscribeMethod,\n responseMethod,\n params,\n callback,\n timeout\n )\n\n return (unsubscribeMethod: string) =>\n talismanSub.unsubscribe(subscriptionId, unsubscribeMethod)\n } catch (error) {\n log.warn(\n `Failed to create wallet-proxied subscription for chain ${chainId}. Falling back to plain websocket`,\n error\n )\n }\n }\n\n try {\n // biome-ignore lint/correctness/noInnerDeclarations: legacy\n var [socketUserId, ws] = await this.connectChainSocket(chainId)\n } catch (error) {\n throw new StaleRpcError(chainId, { cause: error })\n }\n\n // by using this `Deferred` promise\n // (a promise which can be resolved or rejected by code outside of the scope of the promise's constructor)\n // we can queue up our async cleanup on the promise and then immediately return an unsubscribe method to the caller\n const unsubDeferred = Deferred()\n // we return this to the caller so that they can let us know when they're no longer interested in this subscription\n const unsubscribe = (unsubscribeMethod: string) =>\n unsubDeferred.reject(new CallerUnsubscribedError(chainId, unsubscribeMethod))\n // we queue up our work to clean up our subscription when this promise rejects\n const callerUnsubscribed = unsubDeferred.promise\n\n // used to detect when there are no more websockets available from the browser websocket pool\n // in this scenario, we'll be waiting for ws.isReady until some existing sockets are closed\n //\n // while we're waiting, we'll send an error back to the caller so that they can show some useful\n // info to the user\n let noMoreSocketsTimeout: NodeJS.Timeout | undefined\n\n // create subscription asynchronously so that the caller can unsubscribe without waiting for\n // the subscription to be created (which can take some time if e.g. the connection can't be established)\n ;(async () => {\n // wait for ws to be ready, but don't wait forever\n // if timeout is number, cancel when timeout is reached (or caller unsubscribes)\n // if timeout is false, only cancel when the caller unsubscribes\n let unsubRpcStatus: (() => void) | null = null\n try {\n const unsubStale = ws.on(\n \"stale-rpcs\",\n ({ nextBackoffInterval }: { nextBackoffInterval?: number } = {}) => {\n callback(new StaleRpcError(chainId), null)\n\n if (this.#connectionMetaDb && nextBackoffInterval) {\n const id = chainId\n this.#connectionMetaDb.chainBackoffInterval.put(\n { id, interval: nextBackoffInterval },\n id\n )\n }\n }\n )\n const unsubConnected = ws.on(\"connected\", () => {\n if (this.#connectionMetaDb) this.#connectionMetaDb.chainBackoffInterval.delete(chainId)\n })\n unsubRpcStatus = () => {\n unsubStale()\n unsubConnected()\n }\n\n noMoreSocketsTimeout = setTimeout(\n () => callback(new WebsocketAllocationExhaustedError(chainId), null),\n 30_000 // 30 seconds in ms\n )\n\n if (timeout) await Promise.race([this.waitForWs(ws, timeout), callerUnsubscribed])\n else await Promise.race([ws.isReady, callerUnsubscribed])\n\n clearTimeout(noMoreSocketsTimeout)\n } catch {\n clearTimeout(noMoreSocketsTimeout)\n\n unsubRpcStatus?.()\n await this.disconnectChainSocket(chainId, socketUserId)\n return\n }\n\n // create subscription on ws\n // handle the scenarios where the caller unsubscribes before the subscription has been created and:\n // - the subscriptionId is already set\n // - the subscriptionId is not set yet, but will be\n let subscriptionId: string | number | null = null\n let disconnected = false\n let unsubscribeMethod: string | undefined\n try {\n await Promise.race([\n ws.subscribe(responseMethod, subscribeMethod, params, callback).then((id) => {\n if (disconnected) {\n unsubscribeMethod && ws.unsubscribe(responseMethod, unsubscribeMethod, id)\n } else subscriptionId = id\n }),\n callerUnsubscribed,\n ])\n } catch (error) {\n if (error instanceof CallerUnsubscribedError) unsubscribeMethod = error.unsubscribeMethod\n\n unsubRpcStatus?.()\n disconnected = true\n\n if (subscriptionId !== null && unsubscribeMethod)\n await ws.unsubscribe(responseMethod, unsubscribeMethod, subscriptionId)\n\n await this.disconnectChainSocket(chainId, socketUserId)\n return\n }\n\n // unsubscribe from ws subscription when the caller has unsubscribed\n callerUnsubscribed\n .catch(async (error) => {\n // biome-ignore lint/suspicious/noImplicitAnyLet: legacy\n let unsubscribeMethod\n if (error instanceof CallerUnsubscribedError) unsubscribeMethod = error.unsubscribeMethod\n\n unsubRpcStatus?.()\n\n if (subscriptionId !== null && unsubscribeMethod)\n await ws.unsubscribe(responseMethod, unsubscribeMethod, subscriptionId)\n\n await this.disconnectChainSocket(chainId, socketUserId)\n })\n .catch((error) => log.warn(error))\n })()\n\n return unsubscribe\n }\n\n /**\n * Kills current websocket if any\n * Useful after changing rpc order to make sure it's applied for futher requests\n */\n async reset(chainId: DotNetworkId) {\n log.info(\"ChainConnector reset\", chainId)\n const ws = this.#socketConnections[chainId]\n if (!ws) return\n\n try {\n clearTimeout(this.#socketKeepAliveIntervals[chainId])\n delete this.#socketConnections[chainId]\n delete this.#socketUsers[chainId]\n await ws.disconnect()\n } catch (error) {\n log.warn(`Error occurred reseting socket ${chainId}`, error)\n }\n }\n\n /**\n * Wait for websocket to be ready, but don't wait forever\n */\n private async waitForWs(\n ws: Websocket,\n timeout: number | false = 30_000 // 30 seconds in milliseconds\n ): Promise<void> {\n const timer = timeout\n ? sleep(timeout).then(() => {\n throw new Error(`RPC connect timeout reached: ${ws.endpoint}`)\n })\n : false\n\n await Promise.race([ws.isReady, timer].filter(isTruthy))\n }\n\n /**\n * Connect to an RPC via chainId\n *\n * The caller must call disconnectChainSocket with the returned SocketUserId once they are finished with it\n */\n private async connectChainSocket(chainId: DotNetworkId): Promise<[SocketUserId, Websocket]> {\n const rpcs = await this.getEndpoints(chainId)\n const socketUserId = this.addSocketUser(chainId)\n\n // retrieve next rpc backoff interval from connection meta db (if one exists)\n let nextBackoffInterval: number | undefined\n if (this.#connectionMetaDb)\n nextBackoffInterval = (await this.#connectionMetaDb.chainBackoffInterval.get(chainId))\n ?.interval\n\n // NOTE: Make sure there are no calls to `await` between this check and the\n // next step where we assign a `new Websocket` to `this.#socketConnections[chainId]`\n //\n // If there is an `await` between these two steps then there will be a race condition introduced.\n // The result of this race condition will be the unnecessary creation of multiple instances of\n // `Websocket` per chain, rather than the intended behaviour where every call to send/subscribe\n // shares a single `Websocket` per chain.\n if (this.#socketConnections[chainId]) return [socketUserId, this.#socketConnections[chainId]]\n\n if (rpcs.length)\n this.#socketConnections[chainId] = new Websocket(\n rpcs,\n undefined,\n undefined,\n nextBackoffInterval\n )\n else {\n throw new Error(`No healthy RPCs available for chain ${chainId}`)\n }\n\n // on ws connected event, store current rpc as most recently connected rpc\n if (this.#connectionMetaDb) {\n this.#socketConnections[chainId].on(\"connected\", () => {\n if (!this.#connectionMetaDb) return\n\n const id = chainId\n const url = this.#socketConnections[chainId]?.endpoint\n if (!url) return\n\n this.updateRpcPriority(id, url, \"first\").catch((err) =>\n log.warn(`updateRpcPriority failed`, err)\n )\n })\n }\n // set up healthcheck (keeps ws open when idle), don't wait for setup to complete\n ;(async () => {\n if (!this.#socketConnections[chainId])\n return log.warn(`ignoring ${chainId} rpc ws healthcheck initialization: ws is not defined`)\n await this.#socketConnections[chainId].isReady\n\n if (this.#socketKeepAliveIntervals[chainId])\n clearInterval(this.#socketKeepAliveIntervals[chainId])\n\n const intervalMs = 10_000 // 10,000ms = 10s\n this.#socketKeepAliveIntervals[chainId] = setInterval(() => {\n if (!this.#socketConnections[chainId])\n return log.warn(`skipping ${chainId} rpc ws healthcheck: ws is not defined`)\n\n if (!this.#socketConnections[chainId].isConnected)\n return log.warn(`skipping ${chainId} rpc ws healthcheck: ws is not connected`)\n\n this.#socketConnections[chainId]\n .send(\"system_health\", [])\n .catch((error) => log.warn(`Failed keep-alive for socket ${chainId}`, error))\n }, intervalMs)\n })()\n\n return [socketUserId, this.#socketConnections[chainId]]\n }\n\n private async disconnectChainSocket(\n chainId: DotNetworkId,\n socketUserId: SocketUserId\n ): Promise<void> {\n this.removeSocketUser(chainId, socketUserId)\n\n if (this.#socketUsers[chainId].length > 0) return\n\n if (!this.#socketConnections[chainId])\n return log.warn(`Failed to disconnect socket: socket ${chainId} not found`)\n\n try {\n this.#socketConnections[chainId].disconnect()\n } catch (error) {\n log.warn(`Error occurred disconnecting socket ${chainId}`, error)\n }\n delete this.#socketConnections[chainId]\n clearInterval(this.#socketKeepAliveIntervals[chainId])\n delete this.#socketKeepAliveIntervals[chainId]\n }\n\n private addSocketUser(chainId: DotNetworkId): SocketUserId {\n if (!Array.isArray(this.#socketUsers[chainId])) this.#socketUsers[chainId] = []\n const socketUserId: SocketUserId = this.getExclusiveRandomId(this.#socketUsers[chainId])\n this.#socketUsers[chainId].push(socketUserId)\n return socketUserId\n }\n private removeSocketUser(chainId: DotNetworkId, socketUserId: SocketUserId) {\n const userIndex = this.#socketUsers[chainId].indexOf(socketUserId)\n if (userIndex === -1)\n throw new Error(\n `Can't remove user ${socketUserId} from socket ${chainId}: user not in list ${this.#socketUsers[\n chainId\n ].join(\", \")}`\n )\n this.#socketUsers[chainId].splice(userIndex, 1)\n }\n\n /** continues to generate a random number until it finds one which is not present in the exclude list */\n private getExclusiveRandomId(exclude: number[] = []): number {\n let id = this.getRandomId()\n while (exclude.includes(id)) {\n id = this.getRandomId()\n }\n return id\n }\n /** generates a random number */\n private getRandomId(): number {\n return Math.trunc(Math.random() * 10 ** 8)\n }\n\n private getTalismanSub() {\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n const talismanSub = typeof window !== \"undefined\" && (window as any).talismanSub\n\n // biome-ignore lint/complexity/noBannedTypes: legacy\n const rpcByGenesisHashSend: Function | undefined = talismanSub?.rpcByGenesisHashSend\n // biome-ignore lint/complexity/noBannedTypes: legacy\n const rpcByGenesisHashSubscribe: Function | undefined = talismanSub?.rpcByGenesisHashSubscribe\n // biome-ignore lint/complexity/noBannedTypes: legacy\n const rpcByGenesisHashUnsubscribe: Function | undefined =\n talismanSub?.rpcByGenesisHashUnsubscribe\n\n if (typeof rpcByGenesisHashSend !== \"function\") return\n if (typeof rpcByGenesisHashSubscribe !== \"function\") return\n if (typeof rpcByGenesisHashUnsubscribe !== \"function\") return\n\n return {\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n send: <T = any>(genesisHash: string, method: string, params: unknown[]): Promise<T> =>\n rpcByGenesisHashSend(genesisHash, method, params),\n\n subscribe: (\n genesisHash: string,\n subscribeMethod: string,\n responseMethod: string,\n params: unknown[],\n callback: ProviderInterfaceCallback,\n timeout: number | false\n ): Promise<string> =>\n rpcByGenesisHashSubscribe(\n genesisHash,\n subscribeMethod,\n responseMethod,\n params,\n callback,\n timeout\n ),\n\n unsubscribe: (subscriptionId: string, unsubscribeMethod: string): Promise<void> =>\n rpcByGenesisHashUnsubscribe(subscriptionId, unsubscribeMethod),\n }\n }\n\n private async updateRpcPriority(chainId: DotNetworkId, rpc: string, priority: \"first\" | \"last\") {\n if (!this.#connectionMetaDb) return\n\n const rpcs = await this.getEndpoints(chainId)\n if (!rpcs.includes(rpc)) throw new Error(`Unknown rpc for chain ${chainId} : ${rpc}`)\n\n const urls = rpcs.filter((r) => r !== rpc)\n\n if (priority === \"first\") urls.unshift(rpc)\n if (priority === \"last\") urls.push(rpc)\n\n if (!isEqual(urls, rpcs)) {\n // order may not change, especially if there is only one\n await this.#connectionMetaDb.chainPriorityRpcs.put({ id: chainId, urls }, chainId)\n }\n }\n\n private async getEndpoints(chainId: DotNetworkId): Promise<string[]> {\n const chain = await this.#chaindataChainProvider.getNetworkById(chainId, \"polkadot\")\n if (!chain) throw new Error(`Chain ${chainId} not found in store`)\n\n let rpcs = chain.rpcs.concat() // clone to avoid mutating the original array\n const priorityRpcs = this.#connectionMetaDb\n ? await this.#connectionMetaDb.chainPriorityRpcs.get(chainId)\n : undefined\n\n if (priorityRpcs) {\n // use existing priority list of rpcs that still exist, and include missing ones\n rpcs = [\n ...priorityRpcs.urls.filter((rpc) => rpcs.includes(rpc)),\n ...rpcs.filter((rpc) => !priorityRpcs.urls.includes(rpc)),\n ]\n }\n\n return rpcs\n }\n}\n\nconst isEqual = (a: string[], b: string[]) => a.length === b.length && a.every((v, i) => v === b[i])\n","import anylogger from \"anylogger\"\n\nimport packageJson from \"../package.json\"\n\nexport default anylogger(packageJson.name)\n","{\n \"name\": \"@talismn/chain-connectors\",\n \"version\": \"0.0.19\",\n \"author\": \"Talisman\",\n \"homepage\": \"https://talisman.xyz\",\n \"license\": \"GPL-3.0-or-later\",\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"repository\": {\n \"directory\": \"packages/chain-connectors\",\n \"type\": \"git\",\n \"url\": \"https://github.com/TalismanSociety/talisman.git\"\n },\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.mjs\",\n \"files\": [\n \"dist\"\n ],\n \"engines\": {\n \"node\": \">=20\"\n },\n \"scripts\": {\n \"test\": \"vitest run\",\n \"clean\": \"rm -rf dist .turbo node_modules\",\n \"build\": \"tsup --silent\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"@solana/web3.js\": \"^1.98.2\",\n \"@talismn/chaindata-provider\": \"workspace:*\",\n \"@talismn/connection-meta\": \"workspace:*\",\n \"@talismn/util\": \"workspace:*\",\n \"anylogger\": \"^1.0.11\",\n \"eventemitter3\": \"^5.0.0\",\n \"lodash-es\": \"4.17.21\",\n \"viem\": \"^2.27.3\"\n },\n \"devDependencies\": {\n \"@polkadot/rpc-provider\": \"16.1.2\",\n \"@polkadot/util\": \"13.5.3\",\n \"@polkadot/x-global\": \"13.5.3\",\n \"@polkadot/x-ws\": \"13.5.3\",\n \"@talismn/tsconfig\": \"workspace:*\",\n \"typescript\": \"^5.6.3\"\n },\n \"peerDependencies\": {\n \"@polkadot/rpc-provider\": \"*\",\n \"@polkadot/util\": \"*\",\n \"@polkadot/x-global\": \"*\",\n \"@polkadot/x-ws\": \"*\"\n },\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"@talismn/source\": \"./src/index.ts\",\n \"import\": {\n \"types\": \"./dist/index.d.mts\",\n \"default\": \"./dist/index.mjs\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n }\n }\n }\n}\n","import { RpcCoder } from \"@polkadot/rpc-provider/coder\"\nimport type {\n JsonRpcResponse,\n ProviderInterfaceEmitted as PjsProviderInterfaceEmitted,\n ProviderInterface,\n ProviderInterfaceCallback,\n ProviderInterfaceEmitCb,\n} from \"@polkadot/rpc-provider/types\"\nimport { getWSErrorString } from \"@polkadot/rpc-provider/ws/errors\"\nimport { isChildClass, isNull, isUndefined, objectSpread } from \"@polkadot/util\"\nimport { xglobal } from \"@polkadot/x-global\"\nimport { WebSocket } from \"@polkadot/x-ws\"\nimport EventEmitter from \"eventemitter3\"\n\nimport log from \"../log\"\nimport { ExponentialBackoff } from \"./helpers\"\n\ntype ProviderInterfaceEmitted = PjsProviderInterfaceEmitted | \"stale-rpcs\"\n\n// to account for new requirement for generic arg in this type https://github.com/polkadot-js/api/commit/f4c2b150d3d69d43c56699613666b96dd0a763f4#diff-f87c17bc7fae027ec6d43bac5fc089614d9fa097f466aa2be333b44cee81f0fd\n// TODO incrementally replace 'unknown' with proper types where possible\ntype UnknownJsonRpcResponse<T = unknown> = JsonRpcResponse<T>\n\ninterface SubscriptionHandler {\n callback: ProviderInterfaceCallback\n type: string\n}\n\ninterface WsStateAwaiting {\n callback: ProviderInterfaceCallback\n method: string\n params: unknown[]\n start: number\n subscription?: SubscriptionHandler\n}\n\ninterface WsStateSubscription extends SubscriptionHandler {\n method: string\n params: unknown[]\n}\n\nconst ALIASES: { [index: string]: string } = {\n chain_finalisedHead: \"chain_finalizedHead\",\n chain_subscribeFinalisedHeads: \"chain_subscribeFinalizedHeads\",\n chain_unsubscribeFinalisedHeads: \"chain_unsubscribeFinalizedHeads\",\n}\n\nconst DEFAULT_TIMEOUT_MS = 60 * 1000\nconst TIMEOUT_INTERVAL = 5_000\n\nfunction eraseRecord<T>(record: Record<string, T>, cb?: (item: T) => void): void {\n Object.keys(record).forEach((key): void => {\n if (cb) {\n cb(record[key])\n }\n\n delete record[key]\n })\n}\n\n/**\n * # @talismn/chain-connector/Websocket\n *\n * @name Websocket\n *\n * @description The WebSocket Provider allows sending requests using WebSocket to a WebSocket RPC server TCP port. Unlike the [[HttpProvider]], it does support subscriptions and allows listening to events such as new blocks or balance changes.\n *\n * @example\n * <BR>\n *\n * ```javascript\n * import { Websocket } from '@talismn/chain-connector';\n *\n * const provider = new Websocket('ws://127.0.0.1:9944');\n * ```\n *\n * @see [[HttpProvider]]\n */\nexport class Websocket implements ProviderInterface {\n readonly #coder: RpcCoder\n readonly #endpoints: string[]\n readonly #headers: Record<string, string>\n readonly #eventemitter: EventEmitter\n readonly #handlers: Record<string, WsStateAwaiting> = {}\n readonly #isReadyPromise: Promise<Websocket>\n readonly #waitingForId: Record<string, UnknownJsonRpcResponse> = {}\n\n #autoConnectBackoff: ExponentialBackoff\n #endpointIndex: number\n #endpointsTriedSinceLastConnection = 0\n #isConnected = false\n #subscriptions: Record<string, WsStateSubscription> = {}\n #timeoutId?: ReturnType<typeof setInterval> | null = null\n #websocket: WebSocket | null\n #timeout: number\n\n /**\n * @param {string | string[]} endpoint The endpoint url. Usually `ws://ip:9944` or `wss://ip:9944`, may provide an array of endpoint strings.\n * @param {Record<string, string>} headers The headers provided to the underlying WebSocket\n * @param {number} [timeout] Custom timeout value used per request . Defaults to `DEFAULT_TIMEOUT_MS`\n */\n constructor(\n endpoint: string | string[],\n headers: Record<string, string> = {},\n timeout?: number,\n nextBackoffInterval?: number\n ) {\n const endpoints = Array.isArray(endpoint) ? endpoint : [endpoint]\n\n if (endpoints.length === 0) {\n throw new Error(\"Websocket requires at least one Endpoint\")\n }\n\n endpoints.forEach((endpoint) => {\n if (!/^(wss|ws):\\/\\//.test(endpoint)) {\n throw new Error(`Endpoint should start with 'ws://', received '${endpoint}'`)\n }\n })\n\n this.#eventemitter = new EventEmitter()\n this.#autoConnectBackoff = new ExponentialBackoff()\n if (nextBackoffInterval) this.#autoConnectBackoff.resetTo(nextBackoffInterval)\n this.#coder = new RpcCoder()\n this.#endpointIndex = -1\n this.#endpoints = endpoints\n this.#headers = headers\n this.#websocket = null\n this.#timeout = timeout || DEFAULT_TIMEOUT_MS\n\n if (this.#autoConnectBackoff.isActive) {\n this.connectWithRetry().catch(() => {\n // does not throw\n })\n }\n\n this.#isReadyPromise = new Promise((resolve): void => {\n this.#eventemitter.once(\"connected\", (): void => {\n resolve(this)\n })\n })\n }\n\n /**\n * @summary `true` when this provider supports subscriptions\n */\n public get hasSubscriptions(): boolean {\n return true\n }\n\n /**\n * @summary `true` when this provider supports clone()\n */\n public get isClonable(): boolean {\n return true\n }\n\n /**\n * @summary Whether the node is connected or not.\n * @return {boolean} true if connected\n */\n public get isConnected(): boolean {\n return this.#isConnected\n }\n\n /**\n * @description Promise that resolves the first time we are connected and loaded\n */\n public get isReady(): Promise<Websocket> {\n return this.#isReadyPromise\n }\n\n public get endpoint(): string {\n return this.#endpoints[this.#endpointIndex]\n }\n\n /**\n * @description Returns a clone of the object\n */\n public clone(): Websocket {\n return new Websocket(this.#endpoints)\n }\n\n protected selectEndpointIndex(endpoints: string[]): number {\n this.#endpointsTriedSinceLastConnection += 1\n return (this.#endpointIndex + 1) % endpoints.length\n }\n\n /**\n * @summary Manually connect\n * @description The [[Websocket]] connects automatically by default, however if you decided otherwise, you may\n * connect manually using this method.\n */\n public async connect(): Promise<void> {\n if (this.#websocket) {\n throw new Error(\"WebSocket is already connected\")\n }\n\n try {\n this.#endpointIndex = this.selectEndpointIndex(this.#endpoints)\n\n // the as typeof WebSocket here is Deno-specific - not available on the globalThis\n this.#websocket =\n typeof xglobal.WebSocket !== \"undefined\" &&\n isChildClass(xglobal.WebSocket as typeof WebSocket, WebSocket)\n ? new WebSocket(this.endpoint)\n : // @ts-expect-error - WS may be an instance of ws, which supports options\n new WebSocket(this.endpoint, undefined, {\n headers: this.#headers,\n })\n\n if (this.#websocket) {\n this.#websocket.onclose = this.#onSocketClose\n this.#websocket.onerror = this.#onSocketError\n this.#websocket.onmessage = this.#onSocketMessage\n this.#websocket.onopen = this.#onSocketOpen\n }\n\n // timeout any handlers that have not had a response\n this.#timeoutId = setInterval(() => this.#timeoutHandlers(), TIMEOUT_INTERVAL)\n } catch (error) {\n log.error(error)\n\n this.#emit(\"error\", error)\n\n throw error\n }\n }\n\n /**\n * @description Connect, never throwing an error, but rather forcing a retry\n */\n public async connectWithRetry(): Promise<void> {\n if (!this.#autoConnectBackoff.isActive) return\n\n try {\n await this.connect()\n } catch {\n this.scheduleNextRetry()\n }\n }\n\n protected scheduleNextRetry() {\n if (!this.#autoConnectBackoff.isActive) return\n\n const haveTriedAllEndpoints =\n this.#endpointsTriedSinceLastConnection > 0 &&\n this.#endpointsTriedSinceLastConnection % this.#endpoints.length === 0\n\n setTimeout(\n (): void => {\n this.connectWithRetry().catch(() => {\n // does not throw\n })\n },\n haveTriedAllEndpoints ? this.#autoConnectBackoff.next : 0\n )\n\n // Increase backoff when we've tried all endpoints\n if (haveTriedAllEndpoints) this.#autoConnectBackoff.increase()\n\n // Fire a stale-rpcs event when we've tried all endpoints in the list\n // but haven't successfully connected to any of them\n if (haveTriedAllEndpoints)\n this.#emit(\"stale-rpcs\", { nextBackoffInterval: this.#autoConnectBackoff.next })\n }\n\n /**\n * @description Manually disconnect from the connection, clearing auto-connect logic\n */\n public async disconnect(): Promise<void> {\n // switch off autoConnect, we are in manual mode now\n this.#autoConnectBackoff.disable()\n\n try {\n if (this.#websocket) {\n // 1000 - Normal closure; the connection successfully completed\n this.#websocket.close(1000)\n }\n } catch (error) {\n log.error(error)\n\n this.#emit(\"error\", error)\n\n throw error\n }\n }\n\n /**\n * @summary Listens on events after having subscribed using the [[subscribe]] function.\n * @param {ProviderInterfaceEmitted} type Event\n * @param {ProviderInterfaceEmitCb} sub Callback\n * @return unsubscribe function\n */\n public on(type: ProviderInterfaceEmitted, sub: ProviderInterfaceEmitCb): () => void {\n this.#eventemitter.on(type, sub)\n\n return (): void => {\n this.#eventemitter.removeListener(type, sub)\n }\n }\n\n /**\n * @summary Send JSON data using WebSockets to configured HTTP Endpoint or queue.\n * @param method The RPC methods to execute\n * @param params Encoded parameters as applicable for the method\n * @param subscription Subscription details (internally used)\n */\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n public send<T = any>(\n method: string,\n params: unknown[],\n /** @deprecated \\@talismn/chain-connector doesn't implement a cache */\n _isCacheable?: boolean,\n subscription?: SubscriptionHandler\n ): Promise<T> {\n const [id, body] = this.#coder.encodeJson(method, params)\n const resultPromise: Promise<T> = this.#send(id, body, method, params, subscription)\n\n return resultPromise\n }\n\n async #send<T>(\n id: number,\n body: string,\n method: string,\n params: unknown[],\n subscription?: SubscriptionHandler\n ): Promise<T> {\n return new Promise<T>((resolve, reject): void => {\n try {\n if (!this.isConnected || this.#websocket === null) {\n throw new Error(\"WebSocket is not connected\")\n }\n\n const callback = (error?: Error | null, result?: T): void => {\n error ? reject(error) : resolve(result as T)\n }\n\n // log.debug(() => [\"calling\", method, body])\n\n this.#handlers[id] = {\n callback,\n method,\n params,\n start: Date.now(),\n subscription,\n }\n this.#websocket.send(body)\n } catch (error) {\n reject(error)\n }\n })\n }\n\n /**\n * @name subscribe\n * @summary Allows subscribing to a specific event.\n *\n * @example\n * <BR>\n *\n * ```javascript\n * const provider = new Websocket('ws://127.0.0.1:9944');\n * const rpc = new Rpc(provider);\n *\n * rpc.state.subscribeStorage([[storage.system.account, <Address>]], (_, values) => {\n * console.log(values)\n * }).then((subscriptionId) => {\n * console.log('balance changes subscription id: ', subscriptionId)\n * })\n * ```\n */\n public subscribe(\n type: string,\n method: string,\n params: unknown[],\n callback: ProviderInterfaceCallback\n ): Promise<number | string> {\n return this.send<number | string>(method, params, false, { callback, type })\n }\n\n /**\n * @summary Allows unsubscribing to subscriptions made with [[subscribe]].\n */\n public async unsubscribe(type: string, method: string, id: number | string): Promise<boolean> {\n const subscription = `${type}::${id}`\n\n // FIXME This now could happen with re-subscriptions. The issue is that with a re-sub\n // the assigned id now does not match what the API user originally received. It has\n // a slight complication in solving - since we cannot rely on the send id, but rather\n // need to find the actual subscription id to map it\n if (isUndefined(this.#subscriptions[subscription])) {\n // log.debug(() => `Unable to find active subscription=${subscription}`)\n\n return false\n }\n\n delete this.#subscriptions[subscription]\n\n try {\n return this.isConnected && !isNull(this.#websocket) ? this.send<boolean>(method, [id]) : true\n } catch {\n return false\n }\n }\n\n #emit = (type: ProviderInterfaceEmitted, ...args: unknown[]): void => {\n this.#eventemitter.emit(type, ...args)\n }\n\n #onSocketClose = (event: CloseEvent): void => {\n const error = new Error(\n `disconnected from ${this.endpoint}: ${event.code}:: ${\n event.reason || getWSErrorString(event.code)\n }`\n )\n\n if (this.#autoConnectBackoff.isActive) {\n // 1000 is a normal closure and should not be logged as an error\n if (event.code !== 1000) log.error(error.message)\n }\n\n this.#isConnected = false\n\n if (this.#websocket) {\n this.#websocket.onclose = null\n this.#websocket.onerror = null\n this.#websocket.onmessage = null\n this.#websocket.onopen = null\n this.#websocket = null\n }\n\n if (this.#timeoutId) {\n clearInterval(this.#timeoutId)\n this.#timeoutId = null\n }\n\n // reject all hanging requests\n eraseRecord(this.#handlers, (h) => {\n try {\n h.callback(error, undefined)\n } catch (err) {\n // does not throw\n log.error(err)\n }\n })\n eraseRecord(this.#waitingForId)\n\n this.#emit(\"disconnected\")\n\n this.scheduleNextRetry()\n }\n\n #onSocketError = (error: Event): void => {\n // log.debug(() => [\"socket error\", error])\n this.#emit(\"error\", error)\n }\n\n #onSocketMessage = (message: MessageEvent<string>): void => {\n // log.debug(() => [\"received\", message.data])\n try {\n const response = JSON.parse(message.data) as UnknownJsonRpcResponse\n\n // biome-ignore lint/correctness/noVoidTypeReturn: legacy\n return isUndefined(response.method)\n ? this.#onSocketMessageResult(response)\n : this.#onSocketMessageSubscribe(response)\n } catch (e) {\n this.#emit(\"error\", new Error(\"Invalid websocket message received\", { cause: e }))\n }\n }\n\n #onSocketMessageResult = (response: UnknownJsonRpcResponse): void => {\n const handler = this.#handlers[response.id]\n\n if (!handler) {\n // log.debug(() => `Unable to find handler for id=${response.id}`)\n\n return\n }\n\n try {\n const { method, params, subscription } = handler\n const result = this.#coder.decodeResponse(response) as string\n\n // first send the result - in case of subs, we may have an update\n // immediately if we have some queued results already\n handler.callback(null, result)\n\n if (subscription) {\n const subId = `${subscription.type}::${result}`\n\n this.#subscriptions[subId] = objectSpread({}, subscription, {\n method,\n params,\n })\n\n // if we have a result waiting for this subscription already\n if (this.#waitingForId[subId]) {\n this.#onSocketMessageSubscribe(this.#waitingForId[subId])\n }\n }\n } catch (error) {\n handler.callback(error as Error, undefined)\n }\n\n delete this.#handlers[response.id]\n }\n\n #onSocketMessageSubscribe = (response: UnknownJsonRpcResponse): void => {\n const method = ALIASES[response.method as string] || response.method || \"invalid\"\n const subId = `${method}::${response.params.subscription}`\n const handler = this.#subscriptions[subId]\n\n if (!handler) {\n // store the JSON, we could have out-of-order subid coming in\n this.#waitingForId[subId] = response\n\n // log.debug(() => `Unable to find handler for subscription=${subId}`)\n\n return\n }\n\n // housekeeping\n delete this.#waitingForId[subId]\n\n try {\n const result = this.#coder.decodeResponse(response)\n\n handler.callback(null, result)\n } catch (error) {\n handler.callback(error as Error, undefined)\n }\n }\n\n #onSocketOpen = (): boolean => {\n if (this.#websocket === null) {\n throw new Error(\"WebSocket cannot be null in onOpen\")\n }\n\n // log.debug(() => [\"connected to\", this.endpoint])\n\n this.#isConnected = true\n this.#endpointsTriedSinceLastConnection = 0\n this.#autoConnectBackoff.reset()\n\n this.#resubscribe()\n\n this.#emit(\"connected\")\n\n return true\n }\n\n #resubscribe = (): void => {\n const subscriptions = this.#subscriptions\n\n this.#subscriptions = {}\n\n Promise.all(\n Object.keys(subscriptions).map(async (id): Promise<void> => {\n const { callback, method, params, type } = subscriptions[id]\n\n // only re-create subscriptions which are not in author (only area where\n // transactions are created, i.e. submissions such as 'author_submitAndWatchExtrinsic'\n // are not included (and will not be re-broadcast)\n if (type.startsWith(\"author_\")) {\n return\n }\n\n try {\n await this.subscribe(type, method, params, callback)\n } catch (error) {\n log.error(error)\n }\n })\n ).catch(log.error)\n }\n\n #timeoutHandlers = (): void => {\n const now = Date.now()\n const ids = Object.keys(this.#handlers)\n\n for (let i = 0; i < ids.length; i++) {\n const handler = this.#handlers[ids[i]]\n\n if (now - handler.start > this.#timeout) {\n try {\n handler.callback(\n new Error(`No response received from RPC endpoint in ${this.#timeout / 1000}s`),\n undefined\n )\n } catch {\n // ignore\n }\n\n delete this.#handlers[ids[i]]\n }\n }\n }\n}\n","const twoSecondsMs = 2 * 1000\nconst twoMinutesMs = 2 * 60 * 1000\n\nexport class ExponentialBackoff {\n #minInterval: number\n #maxInterval: number\n #nextInterval = 0\n #active = true\n\n constructor(maxIntervalMs = twoMinutesMs, minIntervalMs = twoSecondsMs) {\n this.#minInterval = minIntervalMs\n this.#maxInterval = maxIntervalMs\n\n this.reset()\n }\n\n enable() {\n this.#active = true\n }\n disable() {\n this.#active = false\n }\n\n increase() {\n if (this.#nextInterval === 0) this.#nextInterval = 1\n this.#nextInterval = this.#capMax(this.#capMin(this.#nextInterval * 2))\n }\n decrease() {\n this.#nextInterval = this.#capMax(this.#capMin(this.#nextInterval / 2))\n }\n\n reset() {\n this.#nextInterval = this.#minInterval\n }\n resetTo(nextInterval: number) {\n this.#nextInterval = this.#capMax(this.#capMin(nextInterval))\n }\n resetToMax() {\n this.#nextInterval = this.#maxInterval\n }\n\n get isActive() {\n return this.#active\n }\n get next() {\n return this.#nextInterval\n }\n\n get isMin() {\n return this.#nextInterval === this.#minInterval\n }\n get isMax() {\n return this.#nextInterval === this.#maxInterval\n }\n\n #capMin(value: number) {\n return Math.max(this.#minInterval, value)\n }\n #capMax(value: number) {\n return Math.min(this.#maxInterval, value)\n }\n}\n","import { WsProvider } from \"@polkadot/rpc-provider\"\nimport type { ProviderInterface, ProviderInterfaceCallback } from \"@polkadot/rpc-provider/types\"\nimport type { DotNetwork, DotNetworkId } from \"@talismn/chaindata-provider\"\nimport { throwAfter } from \"@talismn/util\"\n\nimport type { IChainConnectorDot } from \"./IChainConnectorDot\"\n\nconst AUTO_CONNECT_TIMEOUT = 3_000\nconst TIMEOUT = 10_000\n\nexport class ChainConnectorDotStub implements IChainConnectorDot {\n // biome-ignore lint/correctness/noUnusedPrivateClassMembers: legacy\n #network: DotNetwork\n #provider: WsProvider\n\n constructor(network: DotNetwork) {\n this.#network = network\n this.#provider = new WsProvider(network.rpcs, AUTO_CONNECT_TIMEOUT, undefined, TIMEOUT)\n }\n\n asProvider(): ProviderInterface {\n return this.#provider as ProviderInterface\n }\n\n async send<T = unknown>(\n _chainId: DotNetworkId,\n method: string,\n params: unknown[],\n isCacheable?: boolean\n ): Promise<T> {\n await this.#provider.isReady\n\n return this.#provider.send(method, params, isCacheable) as Promise<T>\n }\n\n async subscribe(\n _chainId: DotNetworkId,\n subscribeMethod: string,\n responseMethod: string,\n params: unknown[],\n callback: ProviderInterfaceCallback,\n timeout?: number | false\n ): Promise<(unsubscribeMethod: string) => void> {\n await this.#provider.isReady\n\n const subId = await Promise.race([\n throwAfter(timeout || TIMEOUT, `Subscription timed out after ${timeout}ms`),\n this.#provider.subscribe(responseMethod, subscribeMethod, params, callback),\n ])\n\n return (unsubscribeMethod: string) => {\n this.#provider.unsubscribe(responseMethod, unsubscribeMethod, subId)\n }\n }\n\n reset(): Promise<void> {\n throw new Error(\"ChainConnectorDotStub does not implement reset\")\n }\n}\n","import type { EthNetwork } from \"@talismn/chaindata-provider\"\nimport { createPublicClient, type PublicClient } from \"viem\"\n\nimport { clearChainsCache, getChainFromEvmNetwork } from \"./getChainFromEvmNetwork\"\nimport { getTransportForEvmNetwork, type TransportOptions } from \"./getTransportForEvmNetwork\"\n\nconst MUTLICALL_BATCH_WAIT = 25\nconst MUTLICALL_BATCH_SIZE = 100\n\nconst HTTP_BATCH_WAIT = 25\nconst HTTP_BATCH_SIZE_WITH_MULTICALL = 10\nconst HTTP_BATCH_SIZE_WITHOUT_MULTICALL = 30\n\n// cache to reuse previously created public clients\nconst publicClientCache = new Map<string, PublicClient>()\n\nexport const clearPublicClientCache = (evmNetworkId?: string) => {\n clearChainsCache(evmNetworkId)\n\n if (evmNetworkId) publicClientCache.delete(evmNetworkId)\n else publicClientCache.clear()\n}\n\nexport const getEvmNetworkPublicClient = (network: EthNetwork): PublicClient => {\n const chain = getChainFromEvmNetwork(network)\n\n if (!publicClientCache.has(network.id)) {\n if (!network.rpcs.length) throw new Error(\"No RPCs found for Ethereum network\")\n\n const batch = chain.contracts?.multicall3\n ? { multicall: { wait: MUTLICALL_BATCH_WAIT, batchSize: MUTLICALL_BATCH_SIZE } }\n : undefined\n\n const transportOptions: TransportOptions = {\n batch: {\n batchSize: chain.contracts?.multicall3\n ? HTTP_BATCH_SIZE_WITH_MULTICALL\n : HTTP_BATCH_SIZE_WITHOUT_MULTICALL,\n wait: HTTP_BATCH_WAIT,\n },\n }\n\n const transport = getTransportForEvmNetwork(network, transportOptions)\n\n publicClientCache.set(\n network.id,\n createPublicClient({\n chain,\n transport,\n batch,\n })\n )\n }\n\n return publicClientCache.get(network.id) as PublicClient\n}\n","import type { EthNetwork, EthNetworkId } from \"@talismn/chaindata-provider\"\nimport { camelCase, fromPairs, toPairs } from \"lodash-es\"\nimport type { Chain, ChainContract } from \"viem\"\nimport * as viemChains from \"viem/chains\"\n\n// exclude zoraTestnet which uses Hyperliquid's chain id\nconst { zoraTestnet, ...validViemChains } = viemChains\n\n// viem chains benefit from multicall config & other viem goodies\nconst VIEM_CHAINS = Object.keys(validViemChains).reduce(\n (acc, curr) => {\n const chain = validViemChains[curr as keyof typeof validViemChains]\n acc[chain.id] = chain\n return acc\n },\n {} as Record<number, Chain>\n)\n\nconst chainsCache = new Map<string, Chain>()\n\nexport const clearChainsCache = (networkId?: EthNetworkId) => {\n if (networkId) chainsCache.delete(networkId)\n else chainsCache.clear()\n}\n\nexport const getChainFromEvmNetwork = (network: EthNetwork): Chain => {\n const { symbol, decimals } = network.nativeCurrency\n\n if (!chainsCache.has(network.id)) {\n const chainRpcs = network.rpcs ?? []\n\n const viemChain = VIEM_CHAINS[Number(network.id)] ?? {}\n\n const chain: Chain = {\n ...viemChain,\n id: Number(network.id),\n name: network.name ?? `Ethereum Chain ${network.id}`,\n rpcUrls: {\n public: { http: chainRpcs },\n default: { http: chainRpcs },\n },\n nativeCurrency: {\n symbol,\n decimals,\n name: symbol,\n },\n contracts: {\n ...viemChain.contracts,\n ...(network.contracts\n ? fromPairs(\n toPairs(network.contracts).map(([name, address]): [string, ChainContract] => [\n camelCase(name),\n { address },\n ])\n )\n : {}),\n },\n }\n\n chainsCache.set(network.id, chain)\n }\n\n return chainsCache.get(network.id) as Chain\n}\n","import type { EthNetwork } from \"@talismn/chaindata-provider\"\nimport { fallback, http } from \"viem\"\n\nexport type TransportOptions = {\n batch?:\n | boolean\n | {\n batchSize?: number | undefined\n wait?: number | undefined\n }\n}\n\nexport const getTransportForEvmNetwork = (\n evmNetwork: EthNetwork,\n options: TransportOptions = {}\n) => {\n if (!evmNetwork.rpcs?.length) throw new Error(\"No RPCs found for EVM network\")\n\n const { batch } = options\n\n return fallback(\n evmNetwork.rpcs.map((url) => http(url, { batch, retryCount: 0 })),\n { retryCount: 0 }\n )\n}\n","import type { EthNetwork } from \"@talismn/chaindata-provider\"\nimport { type Account, createWalletClient, type WalletClient } from \"viem\"\n\nimport { getChainFromEvmNetwork } from \"./getChainFromEvmNetwork\"\nimport { getTransportForEvmNetwork } from \"./getTransportForEvmNetwork\"\n\ntype WalletClientOptions = {\n account?: `0x${string}` | Account\n}\n\nexport const getEvmNetworkWalletClient = (\n network: EthNetwork,\n options: WalletClientOptions = {}\n): WalletClient => {\n const chain = getChainFromEvmNetwork(network)\n\n const transport = getTransportForEvmNetwork(network)\n\n return createWalletClient({ chain, transport, account: options.account })\n}\n","import type {\n EthNetworkId,\n IChaindataNetworkProvider,\n IChaindataTokenProvider,\n} from \"@talismn/chaindata-provider\"\nimport type { Account, PublicClient, WalletClient } from \"viem\"\n\nimport { clearPublicClientCache, getEvmNetworkPublicClient } from \"./getEvmNetworkPublicClient\"\nimport { getEvmNetworkWalletClient } from \"./getEvmNetworkWalletClient\"\nimport type { IChainConnectorEth } from \"./IChainConnectorEth\"\n\nexport class ChainConnectorEth implements IChainConnectorEth {\n #chaindataProvider: IChaindataNetworkProvider & IChaindataTokenProvider\n\n constructor(chaindataProvider: IChaindataNetworkProvider & IChaindataTokenProvider) {\n this.#chaindataProvider = chaindataProvider\n }\n\n async getPublicClientForEvmNetwork(evmNetworkId: EthNetworkId): Promise<PublicClient | null> {\n const network = await this.#chaindataProvider.getNetworkById(evmNetworkId, \"ethereum\")\n if (!network) return null\n\n return getEvmNetworkPublicClient(network)\n }\n\n async getWalletClientForEvmNetwork(\n evmNetworkId: EthNetworkId,\n account?: `0x${string}` | Account\n ): Promise<WalletClient | null> {\n const network = await this.#chaindataProvider.getNetworkById(evmNetworkId, \"ethereum\")\n if (!network) return null\n\n return getEvmNetworkWalletClient(network, { account })\n }\n\n public clearRpcProvidersCache(evmNetworkId?: EthNetworkId) {\n clearPublicClientCache(evmNetworkId)\n }\n}\n","import type { EthNetwork, EthNetworkId } from \"@talismn/chaindata-provider\"\nimport type { Account, PublicClient, WalletClient } from \"viem\"\n\nimport { getEvmNetworkPublicClient } from \"./getEvmNetworkPublicClient\"\nimport { getEvmNetworkWalletClient } from \"./getEvmNetworkWalletClient\"\nimport type { IChainConnectorEth } from \"./IChainConnectorEth\"\n\nexport class ChainConnectorEthStub implements IChainConnectorEth {\n #network: EthNetwork\n\n constructor(network: EthNetwork) {\n this.#network = network\n }\n\n async getPublicClientForEvmNetwork(): Promise<PublicClient | null> {\n return getEvmNetworkPublicClient(this.#network)\n }\n\n async getWalletClientForEvmNetwork(\n _networkId: EthNetworkId,\n account?: `0x${string}` | Account\n ): Promise<WalletClient | null> {\n return getEvmNetworkWalletClient(this.#network, { account })\n }\n\n clearRpcProvidersCache(): void {\n // No-op for stub\n }\n}\n","import { Connection } from \"@solana/web3.js\"\nimport type { SolNetworkId } from \"@talismn/chaindata-provider\"\n\n// TODO leverage multiple rpcs with fallback\nexport const getSolConnection = (_networkId: SolNetworkId, rpcs: string[]) => {\n return new Connection(rpcs[0], {\n commitment: \"confirmed\",\n })\n}\n","import type { Connection } from \"@solana/web3.js\"\nimport type {\n IChaindataNetworkProvider,\n IChaindataTokenProvider,\n SolNetworkId,\n} from \"@talismn/chaindata-provider\"\n\nimport { getSolConnection } from \"./getSolConnection\"\nimport type { IChainConnectorSol } from \"./IChainConnectorSol\"\n\nexport class ChainConnectorSol implements IChainConnectorSol {\n #chaindataProvider: IChaindataNetworkProvider & IChaindataTokenProvider\n\n constructor(chaindataProvider: IChaindataNetworkProvider & IChaindataTokenProvider) {\n this.#chaindataProvider = chaindataProvider\n }\n\n async getConnection(networkId: SolNetworkId): Promise<Connection> {\n const network = await this.#chaindataProvider.getNetworkById(networkId, \"solana\")\n if (!network) throw new Error(`Network not found: ${networkId}`)\n\n return getSolConnection(networkId, network.rpcs)\n }\n}\n","import { Connection } from \"@solana/web3.js\"\nimport type { SolNetwork } from \"@talismn/chaindata-provider\"\n\nimport { getSolConnection } from \"./getSolConnection\"\nimport type { IChainConnectorSol } from \"./IChainConnectorSol\"\n\nexport class ChainConnectorSolStub implements IChainConnectorSol {\n #connection: Connection\n\n constructor(networkOrConnection: Pick<SolNetwork, \"id\" | \"rpcs\"> | Connection) {\n this.#connection =\n networkOrConnection instanceof Connection\n ? networkOrConnection\n : getSolConnection(networkOrConnection.id, networkOrConnection.rpcs)\n }\n\n async getConnection(): Promise<Connection> {\n return this.#connection\n }\n}\n"],"mappings":"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","names":["endpoint","unsubscribeMethod","throwAfter","Connection","Connection"]}
1
+ {"version":3,"sources":["../src/dot/ChainConnectorDot.ts","../src/log.ts","../package.json","../src/dot/Websocket.ts","../src/dot/helpers.ts","../src/dot/ChainConnectorDotStub.ts","../src/eth/getEvmNetworkPublicClient.ts","../src/eth/getChainFromEvmNetwork.ts","../src/eth/getTransportForEvmNetwork.ts","../src/eth/getEvmNetworkWalletClient.ts","../src/eth/ChainConnectorEth.ts","../src/eth/ChainConnectorEthStub.ts","../src/sol/getSolConnection.ts","../src/sol/ChainConnectorSol.ts","../src/sol/ChainConnectorSolStub.ts"],"sourcesContent":["import type { ProviderInterface, ProviderInterfaceCallback } from \"@polkadot/rpc-provider/types\"\nimport type { DotNetworkId, IChaindataNetworkProvider } from \"@talismn/chaindata-provider\"\nimport type { TalismanConnectionMetaDatabase } from \"@talismn/connection-meta\"\nimport { Deferred, isTruthy, sleep, throwAfter } from \"@talismn/util\"\n\nimport log from \"../log\"\nimport type { IChainConnectorDot } from \"./IChainConnectorDot\"\nimport { Websocket } from \"./Websocket\"\n\n// errors that require an rpc fallback\n// https://docs.blastapi.io/blast-documentation/things-you-need-to-know/error-reference\nconst BAD_RPC_ERRORS: Record<string, string> = {\n \"-32097\": \"Rate limit exceeded\",\n \"-32098\": \"Capacity exceeded\",\n}\n\nexport class ChainConnectionError extends Error {\n type: \"CHAIN_CONNECTION_ERROR\"\n chainId: string\n\n constructor(chainId: string, options?: ErrorOptions) {\n super(`Unable to connect to chain ${chainId}`, options)\n\n this.type = \"CHAIN_CONNECTION_ERROR\"\n this.chainId = chainId\n }\n}\n\nexport class StaleRpcError extends Error {\n type: \"STALE_RPC_ERROR\"\n chainId: string\n\n constructor(chainId: string, options?: ErrorOptions) {\n super(`RPCs are stale/unavailable for chain ${chainId}`, options)\n\n this.type = \"STALE_RPC_ERROR\"\n this.chainId = chainId\n }\n}\nexport class WebsocketAllocationExhaustedError extends Error {\n type: \"WEBSOCKET_ALLOCATION_EXHAUSTED_ERROR\"\n chainId: string\n\n constructor(chainId: string, options?: ErrorOptions) {\n super(\n `No websockets are available from the browser pool to connect to chain ${chainId}`,\n options\n )\n\n this.type = \"WEBSOCKET_ALLOCATION_EXHAUSTED_ERROR\"\n this.chainId = chainId\n }\n}\nclass CallerUnsubscribedError extends Error {\n type: \"CALLER_UNSUBSCRIBED_ERROR\"\n chainId: string\n unsubscribeMethod: string\n\n constructor(chainId: string, unsubscribeMethod: string, options?: ErrorOptions) {\n super(`Caller unsubscribed from ${chainId}`, options)\n\n this.type = \"CALLER_UNSUBSCRIBED_ERROR\"\n this.chainId = chainId\n this.unsubscribeMethod = unsubscribeMethod\n }\n}\n\ntype SocketUserId = number\n\n/**\n * ChainConnector provides an interface similar to WsProvider, but with three points of difference:\n *\n * 1. ChainConnector methods all accept a `chainId` instead of an array of RPCs. RPCs are then fetched internally from chaindata.\n * 2. ChainConnector creates only one `WsProvider` per chain and ensures that all downstream requests to a chain share the one socket connection.\n * 3. Subscriptions return a callable `unsubscribe` method instead of an id.\n *\n * Additionally, when run on the clientside of a dapp where `window.talismanSub` is available, instead of spinning up new websocket\n * connections this class will forward all requests through to the wallet backend - where another instance of this class will\n * handle the websocket connections.\n */\nexport class ChainConnectorDot implements IChainConnectorDot {\n #chaindataChainProvider: IChaindataNetworkProvider\n #connectionMetaDb?: TalismanConnectionMetaDatabase\n\n #socketConnections: Record<DotNetworkId, Websocket> = {}\n #socketKeepAliveIntervals: Record<DotNetworkId, ReturnType<typeof setInterval>> = {}\n #socketUsers: Record<DotNetworkId, SocketUserId[]> = {}\n\n constructor(\n chaindataChainProvider: IChaindataNetworkProvider,\n connectionMetaDb?: TalismanConnectionMetaDatabase\n ) {\n this.#chaindataChainProvider = chaindataChainProvider\n this.#connectionMetaDb = connectionMetaDb\n\n if (this.#connectionMetaDb) {\n this.#chaindataChainProvider.getNetworkIds(\"polkadot\").then((chainIds) => {\n // tidy up connectionMeta for chains which no longer exist\n this.#connectionMetaDb?.chainPriorityRpcs.where(\"id\").noneOf(chainIds).delete()\n this.#connectionMetaDb?.chainBackoffInterval.where(\"id\").noneOf(chainIds).delete()\n })\n }\n }\n\n /**\n * Creates a facade over this ChainConnector which conforms to the PJS ProviderInterface\n * @example // Using a chainConnector as a Provider for an ApiPromise\n * const provider = chainConnector.asProvider('polkadot')\n * const api = new ApiPromise({ provider })\n */\n asProvider(chainId: DotNetworkId): ProviderInterface {\n const unsubHandler = new Map<string, (unsubscribeMethod: string) => void>()\n\n const providerFacade: ProviderInterface = {\n hasSubscriptions: true,\n isClonable: false,\n isConnected: true,\n clone: () => providerFacade,\n connect: () => Promise.resolve(),\n disconnect: () => Promise.resolve(),\n on: () => () => {},\n\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n send: async <T = any>(method: string, params: unknown[], isCacheable?: boolean): Promise<T> =>\n await this.send(chainId, method, params, isCacheable),\n\n subscribe: async (\n type: string,\n method: string,\n params: unknown[],\n cb: ProviderInterfaceCallback\n ): Promise<string> => {\n const unsubscribe = await this.subscribe(chainId, method, type, params, cb)\n\n const subscriptionId = this.getExclusiveRandomId(\n [...unsubHandler.keys()].map(Number)\n ).toString()\n unsubHandler.set(subscriptionId, unsubscribe)\n\n return subscriptionId\n },\n\n unsubscribe: async (_type: string, unsubscribeMethod: string, subscriptionId: string) => {\n unsubHandler.get(subscriptionId)?.(unsubscribeMethod)\n unsubHandler.delete(subscriptionId)\n\n return true\n },\n }\n\n return providerFacade\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n async send<T = any>(\n chainId: DotNetworkId,\n method: string,\n params: unknown[],\n isCacheable?: boolean | undefined,\n extraOptions?: {\n /**\n * Set to `true` if this query is speculative, i.e. if on some chains it's expected that it will raise a wasm unreachable error of the form:\n *\n * 4003: Client error: Execution failed: Execution aborted due to trap: wasm trap: wasm `unreachable` instruction executed\n *\n * By setting expectErrors to true, this method won't pollute the logs with errors we intend to have happen.\n * An example use case of this is when you plan to catch the wasm unreachable error on chains that don't support the query, and then fall back\n * to another query or perhaps an empty result.\n */\n expectErrors?: boolean\n }\n ): Promise<T> {\n const talismanSub = this.getTalismanSub()\n if (talismanSub !== undefined) {\n try {\n const chain = await this.#chaindataChainProvider.getNetworkById(chainId, \"polkadot\")\n if (!chain) throw new Error(`Chain ${chainId} not found in store`)\n\n const { genesisHash } = chain\n if (typeof genesisHash !== \"string\")\n throw new Error(`Chain ${chainId} has no genesisHash in store`)\n\n return await talismanSub.send(genesisHash, method, params)\n } catch (error) {\n log.warn(\n `Failed to make wallet-proxied send request for chain ${chainId}. Falling back to plain websocket`,\n error\n )\n }\n }\n\n try {\n // biome-ignore lint/correctness/noInnerDeclarations: legacy\n var [socketUserId, ws] = await this.connectChainSocket(chainId)\n } catch (error) {\n throw new StaleRpcError(chainId, { cause: error })\n }\n\n try {\n // wait for ws to be ready, but don't wait forever\n const timeout = 15_000 // 15 seconds in milliseconds\n await this.waitForWs(ws, timeout)\n } catch (error) {\n await this.disconnectChainSocket(chainId, socketUserId)\n throw new ChainConnectionError(chainId, { cause: error })\n }\n\n try {\n const timeout = 30_000 // throw after 30 seconds if no response\n // biome-ignore lint/correctness/noInnerDeclarations: legacy\n var response = await Promise.race([\n ws.send(method, params, isCacheable),\n throwAfter(timeout, \"TIMEOUT\"),\n ])\n } catch (err) {\n const error = err as (Error & { code?: number; data?: unknown }) | null\n\n if (error?.message === \"TIMEOUT\") {\n log.error(`ChainConnector timeout`, { chainId, endpoint: ws.endpoint, error })\n await this.updateRpcPriority(chainId, ws.endpoint, \"last\")\n await this.reset(chainId)\n throw new Error(\"Timeout\")\n }\n\n const badRpcError = BAD_RPC_ERRORS[error?.code?.toString() ?? \"\"]\n if (badRpcError) {\n log.error(`ChainConnector ${badRpcError}`, { error, chainId, endpoint: ws.endpoint })\n await this.updateRpcPriority(chainId, ws.endpoint, \"last\")\n await this.reset(chainId)\n throw new Error(badRpcError)\n }\n\n if (!extraOptions?.expectErrors)\n log.error(\n `Failed to send ${method} on chain ${chainId}\\nparams: ${JSON.stringify(params)}`,\n {\n error,\n endpoint: ws.endpoint,\n }\n )\n\n await this.disconnectChainSocket(chainId, socketUserId)\n throw error\n }\n\n await this.disconnectChainSocket(chainId, socketUserId)\n\n return response\n }\n\n async subscribe(\n chainId: DotNetworkId,\n subscribeMethod: string,\n responseMethod: string,\n params: unknown[],\n callback: ProviderInterfaceCallback,\n timeout: number | false = 30_000 // 30 seconds in milliseconds\n ): Promise<(unsubscribeMethod: string) => void> {\n const talismanSub = this.getTalismanSub()\n if (talismanSub !== undefined) {\n try {\n const chain = await this.#chaindataChainProvider.getNetworkById(chainId, \"polkadot\")\n if (!chain) throw new Error(`Chain ${chainId} not found in store`)\n\n const { genesisHash } = chain\n if (typeof genesisHash !== \"string\")\n throw new Error(`Chain ${chainId} has no genesisHash in store`)\n\n const subscriptionId = await talismanSub.subscribe(\n genesisHash,\n subscribeMethod,\n responseMethod,\n params,\n callback,\n timeout\n )\n\n return (unsubscribeMethod: string) =>\n talismanSub.unsubscribe(subscriptionId, unsubscribeMethod)\n } catch (error) {\n log.warn(\n `Failed to create wallet-proxied subscription for chain ${chainId}. Falling back to plain websocket`,\n error\n )\n }\n }\n\n try {\n // biome-ignore lint/correctness/noInnerDeclarations: legacy\n var [socketUserId, ws] = await this.connectChainSocket(chainId)\n } catch (error) {\n throw new StaleRpcError(chainId, { cause: error })\n }\n\n // by using this `Deferred` promise\n // (a promise which can be resolved or rejected by code outside of the scope of the promise's constructor)\n // we can queue up our async cleanup on the promise and then immediately return an unsubscribe method to the caller\n const unsubDeferred = Deferred()\n // we return this to the caller so that they can let us know when they're no longer interested in this subscription\n const unsubscribe = (unsubscribeMethod: string) =>\n unsubDeferred.reject(new CallerUnsubscribedError(chainId, unsubscribeMethod))\n // we queue up our work to clean up our subscription when this promise rejects\n const callerUnsubscribed = unsubDeferred.promise\n\n // used to detect when there are no more websockets available from the browser websocket pool\n // in this scenario, we'll be waiting for ws.isReady until some existing sockets are closed\n //\n // while we're waiting, we'll send an error back to the caller so that they can show some useful\n // info to the user\n let noMoreSocketsTimeout: NodeJS.Timeout | undefined\n\n // create subscription asynchronously so that the caller can unsubscribe without waiting for\n // the subscription to be created (which can take some time if e.g. the connection can't be established)\n ;(async () => {\n // wait for ws to be ready, but don't wait forever\n // if timeout is number, cancel when timeout is reached (or caller unsubscribes)\n // if timeout is false, only cancel when the caller unsubscribes\n let unsubRpcStatus: (() => void) | null = null\n try {\n const unsubStale = ws.on(\n \"stale-rpcs\",\n ({ nextBackoffInterval }: { nextBackoffInterval?: number } = {}) => {\n callback(new StaleRpcError(chainId), null)\n\n if (this.#connectionMetaDb && nextBackoffInterval) {\n const id = chainId\n this.#connectionMetaDb.chainBackoffInterval.put(\n { id, interval: nextBackoffInterval },\n id\n )\n }\n }\n )\n const unsubConnected = ws.on(\"connected\", () => {\n if (this.#connectionMetaDb) this.#connectionMetaDb.chainBackoffInterval.delete(chainId)\n })\n unsubRpcStatus = () => {\n unsubStale()\n unsubConnected()\n }\n\n noMoreSocketsTimeout = setTimeout(\n () => callback(new WebsocketAllocationExhaustedError(chainId), null),\n 30_000 // 30 seconds in ms\n )\n\n if (timeout) await Promise.race([this.waitForWs(ws, timeout), callerUnsubscribed])\n else await Promise.race([ws.isReady, callerUnsubscribed])\n\n clearTimeout(noMoreSocketsTimeout)\n } catch {\n clearTimeout(noMoreSocketsTimeout)\n\n unsubRpcStatus?.()\n await this.disconnectChainSocket(chainId, socketUserId)\n return\n }\n\n // create subscription on ws\n // handle the scenarios where the caller unsubscribes before the subscription has been created and:\n // - the subscriptionId is already set\n // - the subscriptionId is not set yet, but will be\n let subscriptionId: string | number | null = null\n let disconnected = false\n let unsubscribeMethod: string | undefined\n try {\n await Promise.race([\n ws.subscribe(responseMethod, subscribeMethod, params, callback).then((id) => {\n if (disconnected) {\n unsubscribeMethod && ws.unsubscribe(responseMethod, unsubscribeMethod, id)\n } else subscriptionId = id\n }),\n callerUnsubscribed,\n ])\n } catch (error) {\n if (error instanceof CallerUnsubscribedError) unsubscribeMethod = error.unsubscribeMethod\n\n unsubRpcStatus?.()\n disconnected = true\n\n if (subscriptionId !== null && unsubscribeMethod)\n await ws.unsubscribe(responseMethod, unsubscribeMethod, subscriptionId)\n\n await this.disconnectChainSocket(chainId, socketUserId)\n return\n }\n\n // unsubscribe from ws subscription when the caller has unsubscribed\n callerUnsubscribed\n .catch(async (error) => {\n // biome-ignore lint/suspicious/noImplicitAnyLet: legacy\n let unsubscribeMethod\n if (error instanceof CallerUnsubscribedError) unsubscribeMethod = error.unsubscribeMethod\n\n unsubRpcStatus?.()\n\n if (subscriptionId !== null && unsubscribeMethod)\n await ws.unsubscribe(responseMethod, unsubscribeMethod, subscriptionId)\n\n await this.disconnectChainSocket(chainId, socketUserId)\n })\n .catch((error) => log.warn(error))\n })()\n\n return unsubscribe\n }\n\n /**\n * Kills current websocket if any\n * Useful after changing rpc order to make sure it's applied for futher requests\n */\n async reset(chainId: DotNetworkId) {\n log.info(\"ChainConnector reset\", chainId)\n const ws = this.#socketConnections[chainId]\n if (!ws) return\n\n try {\n clearTimeout(this.#socketKeepAliveIntervals[chainId])\n delete this.#socketConnections[chainId]\n delete this.#socketUsers[chainId]\n await ws.disconnect()\n } catch (error) {\n log.warn(`Error occurred reseting socket ${chainId}`, error)\n }\n }\n\n /**\n * Wait for websocket to be ready, but don't wait forever\n */\n private async waitForWs(\n ws: Websocket,\n timeout: number | false = 30_000 // 30 seconds in milliseconds\n ): Promise<void> {\n const timer = timeout\n ? sleep(timeout).then(() => {\n throw new Error(`RPC connect timeout reached: ${ws.endpoint}`)\n })\n : false\n\n await Promise.race([ws.isReady, timer].filter(isTruthy))\n }\n\n /**\n * Connect to an RPC via chainId\n *\n * The caller must call disconnectChainSocket with the returned SocketUserId once they are finished with it\n */\n private async connectChainSocket(chainId: DotNetworkId): Promise<[SocketUserId, Websocket]> {\n const rpcs = await this.getEndpoints(chainId)\n const socketUserId = this.addSocketUser(chainId)\n\n // retrieve next rpc backoff interval from connection meta db (if one exists)\n let nextBackoffInterval: number | undefined\n if (this.#connectionMetaDb)\n nextBackoffInterval = (await this.#connectionMetaDb.chainBackoffInterval.get(chainId))\n ?.interval\n\n // NOTE: Make sure there are no calls to `await` between this check and the\n // next step where we assign a `new Websocket` to `this.#socketConnections[chainId]`\n //\n // If there is an `await` between these two steps then there will be a race condition introduced.\n // The result of this race condition will be the unnecessary creation of multiple instances of\n // `Websocket` per chain, rather than the intended behaviour where every call to send/subscribe\n // shares a single `Websocket` per chain.\n if (this.#socketConnections[chainId]) return [socketUserId, this.#socketConnections[chainId]]\n\n if (rpcs.length)\n this.#socketConnections[chainId] = new Websocket(\n rpcs,\n undefined,\n undefined,\n nextBackoffInterval\n )\n else {\n throw new Error(`No healthy RPCs available for chain ${chainId}`)\n }\n\n // on ws connected event, store current rpc as most recently connected rpc\n if (this.#connectionMetaDb) {\n this.#socketConnections[chainId].on(\"connected\", () => {\n if (!this.#connectionMetaDb) return\n\n const id = chainId\n const url = this.#socketConnections[chainId]?.endpoint\n if (!url) return\n\n this.updateRpcPriority(id, url, \"first\").catch((err) =>\n log.warn(`updateRpcPriority failed`, err)\n )\n })\n }\n // set up healthcheck (keeps ws open when idle), don't wait for setup to complete\n ;(async () => {\n if (!this.#socketConnections[chainId])\n return log.warn(`ignoring ${chainId} rpc ws healthcheck initialization: ws is not defined`)\n await this.#socketConnections[chainId].isReady\n\n if (this.#socketKeepAliveIntervals[chainId])\n clearInterval(this.#socketKeepAliveIntervals[chainId])\n\n const intervalMs = 10_000 // 10,000ms = 10s\n this.#socketKeepAliveIntervals[chainId] = setInterval(() => {\n if (!this.#socketConnections[chainId])\n return log.warn(`skipping ${chainId} rpc ws healthcheck: ws is not defined`)\n\n if (!this.#socketConnections[chainId].isConnected)\n return log.warn(`skipping ${chainId} rpc ws healthcheck: ws is not connected`)\n\n this.#socketConnections[chainId]\n .send(\"system_health\", [])\n .catch((error) => log.warn(`Failed keep-alive for socket ${chainId}`, error))\n }, intervalMs)\n })()\n\n return [socketUserId, this.#socketConnections[chainId]]\n }\n\n private async disconnectChainSocket(\n chainId: DotNetworkId,\n socketUserId: SocketUserId\n ): Promise<void> {\n this.removeSocketUser(chainId, socketUserId)\n\n if (this.#socketUsers[chainId].length > 0) return\n\n if (!this.#socketConnections[chainId])\n return log.warn(`Failed to disconnect socket: socket ${chainId} not found`)\n\n try {\n this.#socketConnections[chainId].disconnect()\n } catch (error) {\n log.warn(`Error occurred disconnecting socket ${chainId}`, error)\n }\n delete this.#socketConnections[chainId]\n clearInterval(this.#socketKeepAliveIntervals[chainId])\n delete this.#socketKeepAliveIntervals[chainId]\n }\n\n private addSocketUser(chainId: DotNetworkId): SocketUserId {\n if (!Array.isArray(this.#socketUsers[chainId])) this.#socketUsers[chainId] = []\n const socketUserId: SocketUserId = this.getExclusiveRandomId(this.#socketUsers[chainId])\n this.#socketUsers[chainId].push(socketUserId)\n return socketUserId\n }\n private removeSocketUser(chainId: DotNetworkId, socketUserId: SocketUserId) {\n const userIndex = this.#socketUsers[chainId].indexOf(socketUserId)\n if (userIndex === -1)\n throw new Error(\n `Can't remove user ${socketUserId} from socket ${chainId}: user not in list ${this.#socketUsers[\n chainId\n ].join(\", \")}`\n )\n this.#socketUsers[chainId].splice(userIndex, 1)\n }\n\n /** continues to generate a random number until it finds one which is not present in the exclude list */\n private getExclusiveRandomId(exclude: number[] = []): number {\n let id = this.getRandomId()\n while (exclude.includes(id)) {\n id = this.getRandomId()\n }\n return id\n }\n /** generates a random number */\n private getRandomId(): number {\n return Math.trunc(Math.random() * 10 ** 8)\n }\n\n private getTalismanSub() {\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n const talismanSub = typeof window !== \"undefined\" && (window as any).talismanSub\n\n // biome-ignore lint/complexity/noBannedTypes: legacy\n const rpcByGenesisHashSend: Function | undefined = talismanSub?.rpcByGenesisHashSend\n // biome-ignore lint/complexity/noBannedTypes: legacy\n const rpcByGenesisHashSubscribe: Function | undefined = talismanSub?.rpcByGenesisHashSubscribe\n // biome-ignore lint/complexity/noBannedTypes: legacy\n const rpcByGenesisHashUnsubscribe: Function | undefined =\n talismanSub?.rpcByGenesisHashUnsubscribe\n\n if (typeof rpcByGenesisHashSend !== \"function\") return\n if (typeof rpcByGenesisHashSubscribe !== \"function\") return\n if (typeof rpcByGenesisHashUnsubscribe !== \"function\") return\n\n return {\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n send: <T = any>(genesisHash: string, method: string, params: unknown[]): Promise<T> =>\n rpcByGenesisHashSend(genesisHash, method, params),\n\n subscribe: (\n genesisHash: string,\n subscribeMethod: string,\n responseMethod: string,\n params: unknown[],\n callback: ProviderInterfaceCallback,\n timeout: number | false\n ): Promise<string> =>\n rpcByGenesisHashSubscribe(\n genesisHash,\n subscribeMethod,\n responseMethod,\n params,\n callback,\n timeout\n ),\n\n unsubscribe: (subscriptionId: string, unsubscribeMethod: string): Promise<void> =>\n rpcByGenesisHashUnsubscribe(subscriptionId, unsubscribeMethod),\n }\n }\n\n private async updateRpcPriority(chainId: DotNetworkId, rpc: string, priority: \"first\" | \"last\") {\n if (!this.#connectionMetaDb) return\n\n const rpcs = await this.getEndpoints(chainId)\n if (!rpcs.includes(rpc)) throw new Error(`Unknown rpc for chain ${chainId} : ${rpc}`)\n\n const urls = rpcs.filter((r) => r !== rpc)\n\n if (priority === \"first\") urls.unshift(rpc)\n if (priority === \"last\") urls.push(rpc)\n\n if (!isEqual(urls, rpcs)) {\n // order may not change, especially if there is only one\n await this.#connectionMetaDb.chainPriorityRpcs.put({ id: chainId, urls }, chainId)\n }\n }\n\n private async getEndpoints(chainId: DotNetworkId): Promise<string[]> {\n const chain = await this.#chaindataChainProvider.getNetworkById(chainId, \"polkadot\")\n if (!chain) throw new Error(`Chain ${chainId} not found in store`)\n\n let rpcs = chain.rpcs.concat() // clone to avoid mutating the original array\n const priorityRpcs = this.#connectionMetaDb\n ? await this.#connectionMetaDb.chainPriorityRpcs.get(chainId)\n : undefined\n\n if (priorityRpcs) {\n // use existing priority list of rpcs that still exist, and include missing ones\n rpcs = [\n ...priorityRpcs.urls.filter((rpc) => rpcs.includes(rpc)),\n ...rpcs.filter((rpc) => !priorityRpcs.urls.includes(rpc)),\n ]\n }\n\n return rpcs\n }\n}\n\nconst isEqual = (a: string[], b: string[]) => a.length === b.length && a.every((v, i) => v === b[i])\n","import anylogger from \"anylogger\"\n\nimport packageJson from \"../package.json\"\n\nexport default anylogger(packageJson.name)\n","{\n \"name\": \"@talismn/chain-connectors\",\n \"version\": \"0.1.0\",\n \"author\": \"Talisman\",\n \"homepage\": \"https://talisman.xyz\",\n \"license\": \"GPL-3.0-or-later\",\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"repository\": {\n \"directory\": \"packages/chain-connectors\",\n \"type\": \"git\",\n \"url\": \"https://github.com/TalismanSociety/talisman.git\"\n },\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.mjs\",\n \"files\": [\n \"dist\"\n ],\n \"engines\": {\n \"node\": \">=20\"\n },\n \"scripts\": {\n \"test\": \"vitest run\",\n \"clean\": \"rm -rf dist .turbo node_modules\",\n \"build\": \"tsup --silent\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"@solana/web3.js\": \"^1.98.2\",\n \"@talismn/chaindata-provider\": \"workspace:*\",\n \"@talismn/connection-meta\": \"workspace:*\",\n \"@talismn/util\": \"workspace:*\",\n \"anylogger\": \"^1.0.11\",\n \"eventemitter3\": \"^5.0.0\",\n \"lodash-es\": \"4.18.1\",\n \"viem\": \"2.52.2\"\n },\n \"devDependencies\": {\n \"@polkadot/rpc-provider\": \"16.1.2\",\n \"@polkadot/x-global\": \"13.5.3\",\n \"@polkadot/x-ws\": \"13.5.3\",\n \"@talismn/tsconfig\": \"workspace:*\",\n \"typescript\": \"^6.0.3\"\n },\n \"peerDependencies\": {\n \"@polkadot/rpc-provider\": \"*\",\n \"@polkadot/x-global\": \"*\",\n \"@polkadot/x-ws\": \"*\"\n },\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"@talismn/source\": \"./src/index.ts\",\n \"import\": {\n \"types\": \"./dist/index.d.mts\",\n \"default\": \"./dist/index.mjs\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n }\n }\n }\n}\n","import { RpcCoder } from \"@polkadot/rpc-provider/coder\"\nimport type {\n JsonRpcResponse,\n ProviderInterfaceEmitted as PjsProviderInterfaceEmitted,\n ProviderInterface,\n ProviderInterfaceCallback,\n ProviderInterfaceEmitCb,\n} from \"@polkadot/rpc-provider/types\"\nimport { getWSErrorString } from \"@polkadot/rpc-provider/ws/errors\"\nimport { xglobal } from \"@polkadot/x-global\"\nimport { WebSocket } from \"@polkadot/x-ws\"\nimport EventEmitter from \"eventemitter3\"\n\nimport log from \"../log\"\nimport { ExponentialBackoff } from \"./helpers\"\n\n// biome-ignore lint/complexity/noBannedTypes: checking class hierarchy\nconst isChildClass = (Parent: Function, Child: Function | undefined | null): boolean =>\n Child != null && (Child === Parent || Child.prototype instanceof Parent)\n\ntype ProviderInterfaceEmitted = PjsProviderInterfaceEmitted | \"stale-rpcs\"\n\n// to account for new requirement for generic arg in this type https://github.com/polkadot-js/api/commit/f4c2b150d3d69d43c56699613666b96dd0a763f4#diff-f87c17bc7fae027ec6d43bac5fc089614d9fa097f466aa2be333b44cee81f0fd\n// TODO incrementally replace 'unknown' with proper types where possible\ntype UnknownJsonRpcResponse<T = unknown> = JsonRpcResponse<T>\n\ninterface SubscriptionHandler {\n callback: ProviderInterfaceCallback\n type: string\n}\n\ninterface WsStateAwaiting {\n callback: ProviderInterfaceCallback\n method: string\n params: unknown[]\n start: number\n subscription?: SubscriptionHandler\n}\n\ninterface WsStateSubscription extends SubscriptionHandler {\n method: string\n params: unknown[]\n}\n\nconst ALIASES: { [index: string]: string } = {\n chain_finalisedHead: \"chain_finalizedHead\",\n chain_subscribeFinalisedHeads: \"chain_subscribeFinalizedHeads\",\n chain_unsubscribeFinalisedHeads: \"chain_unsubscribeFinalizedHeads\",\n}\n\nconst DEFAULT_TIMEOUT_MS = 60 * 1000\nconst TIMEOUT_INTERVAL = 5_000\n\nfunction eraseRecord<T>(record: Record<string, T>, cb?: (item: T) => void): void {\n Object.keys(record).forEach((key): void => {\n if (cb) {\n cb(record[key])\n }\n\n delete record[key]\n })\n}\n\n/**\n * # @talismn/chain-connector/Websocket\n *\n * @name Websocket\n *\n * @description The WebSocket Provider allows sending requests using WebSocket to a WebSocket RPC server TCP port. Unlike the [[HttpProvider]], it does support subscriptions and allows listening to events such as new blocks or balance changes.\n *\n * @example\n * <BR>\n *\n * ```javascript\n * import { Websocket } from '@talismn/chain-connector';\n *\n * const provider = new Websocket('ws://127.0.0.1:9944');\n * ```\n *\n * @see [[HttpProvider]]\n */\nexport class Websocket implements ProviderInterface {\n readonly #coder: RpcCoder\n readonly #endpoints: string[]\n readonly #headers: Record<string, string>\n readonly #eventemitter: EventEmitter\n readonly #handlers: Record<string, WsStateAwaiting> = {}\n readonly #isReadyPromise: Promise<Websocket>\n readonly #waitingForId: Record<string, UnknownJsonRpcResponse> = {}\n\n #autoConnectBackoff: ExponentialBackoff\n #endpointIndex: number\n #endpointsTriedSinceLastConnection = 0\n #isConnected = false\n #subscriptions: Record<string, WsStateSubscription> = {}\n #timeoutId?: ReturnType<typeof setInterval> | null = null\n #websocket: WebSocket | null\n #timeout: number\n\n /**\n * @param {string | string[]} endpoint The endpoint url. Usually `ws://ip:9944` or `wss://ip:9944`, may provide an array of endpoint strings.\n * @param {Record<string, string>} headers The headers provided to the underlying WebSocket\n * @param {number} [timeout] Custom timeout value used per request . Defaults to `DEFAULT_TIMEOUT_MS`\n */\n constructor(\n endpoint: string | string[],\n headers: Record<string, string> = {},\n timeout?: number,\n nextBackoffInterval?: number\n ) {\n const endpoints = Array.isArray(endpoint) ? endpoint : [endpoint]\n\n if (endpoints.length === 0) {\n throw new Error(\"Websocket requires at least one Endpoint\")\n }\n\n endpoints.forEach((endpoint) => {\n if (!/^(wss|ws):\\/\\//.test(endpoint)) {\n throw new Error(`Endpoint should start with 'ws://', received '${endpoint}'`)\n }\n })\n\n this.#eventemitter = new EventEmitter()\n this.#autoConnectBackoff = new ExponentialBackoff()\n if (nextBackoffInterval) this.#autoConnectBackoff.resetTo(nextBackoffInterval)\n this.#coder = new RpcCoder()\n this.#endpointIndex = -1\n this.#endpoints = endpoints\n this.#headers = headers\n this.#websocket = null\n this.#timeout = timeout || DEFAULT_TIMEOUT_MS\n\n if (this.#autoConnectBackoff.isActive) {\n this.connectWithRetry().catch(() => {\n // does not throw\n })\n }\n\n this.#isReadyPromise = new Promise((resolve): void => {\n this.#eventemitter.once(\"connected\", (): void => {\n resolve(this)\n })\n })\n }\n\n /**\n * @summary `true` when this provider supports subscriptions\n */\n public get hasSubscriptions(): boolean {\n return true\n }\n\n /**\n * @summary `true` when this provider supports clone()\n */\n public get isClonable(): boolean {\n return true\n }\n\n /**\n * @summary Whether the node is connected or not.\n * @return {boolean} true if connected\n */\n public get isConnected(): boolean {\n return this.#isConnected\n }\n\n /**\n * @description Promise that resolves the first time we are connected and loaded\n */\n public get isReady(): Promise<Websocket> {\n return this.#isReadyPromise\n }\n\n public get endpoint(): string {\n return this.#endpoints[this.#endpointIndex]\n }\n\n /**\n * @description Returns a clone of the object\n */\n public clone(): Websocket {\n return new Websocket(this.#endpoints)\n }\n\n protected selectEndpointIndex(endpoints: string[]): number {\n this.#endpointsTriedSinceLastConnection += 1\n return (this.#endpointIndex + 1) % endpoints.length\n }\n\n /**\n * @summary Manually connect\n * @description The [[Websocket]] connects automatically by default, however if you decided otherwise, you may\n * connect manually using this method.\n */\n public async connect(): Promise<void> {\n if (this.#websocket) {\n throw new Error(\"WebSocket is already connected\")\n }\n\n try {\n this.#endpointIndex = this.selectEndpointIndex(this.#endpoints)\n\n // the as typeof WebSocket here is Deno-specific - not available on the globalThis\n this.#websocket =\n typeof xglobal.WebSocket !== \"undefined\" &&\n isChildClass(xglobal.WebSocket as typeof WebSocket, WebSocket)\n ? new WebSocket(this.endpoint)\n : // @ts-expect-error - WS may be an instance of ws, which supports options\n new WebSocket(this.endpoint, undefined, {\n headers: this.#headers,\n })\n\n if (this.#websocket) {\n this.#websocket.onclose = this.#onSocketClose\n this.#websocket.onerror = this.#onSocketError\n this.#websocket.onmessage = this.#onSocketMessage\n this.#websocket.onopen = this.#onSocketOpen\n }\n\n // timeout any handlers that have not had a response\n this.#timeoutId = setInterval(() => this.#timeoutHandlers(), TIMEOUT_INTERVAL)\n } catch (error) {\n log.error(error)\n\n this.#emit(\"error\", error)\n\n throw error\n }\n }\n\n /**\n * @description Connect, never throwing an error, but rather forcing a retry\n */\n public async connectWithRetry(): Promise<void> {\n if (!this.#autoConnectBackoff.isActive) return\n\n try {\n await this.connect()\n } catch {\n this.scheduleNextRetry()\n }\n }\n\n protected scheduleNextRetry() {\n if (!this.#autoConnectBackoff.isActive) return\n\n const haveTriedAllEndpoints =\n this.#endpointsTriedSinceLastConnection > 0 &&\n this.#endpointsTriedSinceLastConnection % this.#endpoints.length === 0\n\n setTimeout(\n (): void => {\n this.connectWithRetry().catch(() => {\n // does not throw\n })\n },\n haveTriedAllEndpoints ? this.#autoConnectBackoff.next : 0\n )\n\n // Increase backoff when we've tried all endpoints\n if (haveTriedAllEndpoints) this.#autoConnectBackoff.increase()\n\n // Fire a stale-rpcs event when we've tried all endpoints in the list\n // but haven't successfully connected to any of them\n if (haveTriedAllEndpoints)\n this.#emit(\"stale-rpcs\", { nextBackoffInterval: this.#autoConnectBackoff.next })\n }\n\n /**\n * @description Manually disconnect from the connection, clearing auto-connect logic\n */\n public async disconnect(): Promise<void> {\n // switch off autoConnect, we are in manual mode now\n this.#autoConnectBackoff.disable()\n\n try {\n if (this.#websocket) {\n // 1000 - Normal closure; the connection successfully completed\n this.#websocket.close(1000)\n }\n } catch (error) {\n log.error(error)\n\n this.#emit(\"error\", error)\n\n throw error\n }\n }\n\n /**\n * @summary Listens on events after having subscribed using the [[subscribe]] function.\n * @param {ProviderInterfaceEmitted} type Event\n * @param {ProviderInterfaceEmitCb} sub Callback\n * @return unsubscribe function\n */\n public on(type: ProviderInterfaceEmitted, sub: ProviderInterfaceEmitCb): () => void {\n this.#eventemitter.on(type, sub)\n\n return (): void => {\n this.#eventemitter.removeListener(type, sub)\n }\n }\n\n /**\n * @summary Send JSON data using WebSockets to configured HTTP Endpoint or queue.\n * @param method The RPC methods to execute\n * @param params Encoded parameters as applicable for the method\n * @param subscription Subscription details (internally used)\n */\n // biome-ignore lint/suspicious/noExplicitAny: legacy\n public send<T = any>(\n method: string,\n params: unknown[],\n /** @deprecated \\@talismn/chain-connector doesn't implement a cache */\n _isCacheable?: boolean,\n subscription?: SubscriptionHandler\n ): Promise<T> {\n const [id, body] = this.#coder.encodeJson(method, params)\n const resultPromise: Promise<T> = this.#send(id, body, method, params, subscription)\n\n return resultPromise\n }\n\n async #send<T>(\n id: number,\n body: string,\n method: string,\n params: unknown[],\n subscription?: SubscriptionHandler\n ): Promise<T> {\n return new Promise<T>((resolve, reject): void => {\n try {\n if (!this.isConnected || this.#websocket === null) {\n throw new Error(\"WebSocket is not connected\")\n }\n\n const callback = (error?: Error | null, result?: T): void => {\n error ? reject(error) : resolve(result as T)\n }\n\n // log.debug(() => [\"calling\", method, body])\n\n this.#handlers[id] = {\n callback,\n method,\n params,\n start: Date.now(),\n subscription,\n }\n this.#websocket.send(body)\n } catch (error) {\n reject(error)\n }\n })\n }\n\n /**\n * @name subscribe\n * @summary Allows subscribing to a specific event.\n *\n * @example\n * <BR>\n *\n * ```javascript\n * const provider = new Websocket('ws://127.0.0.1:9944');\n * const rpc = new Rpc(provider);\n *\n * rpc.state.subscribeStorage([[storage.system.account, <Address>]], (_, values) => {\n * console.log(values)\n * }).then((subscriptionId) => {\n * console.log('balance changes subscription id: ', subscriptionId)\n * })\n * ```\n */\n public subscribe(\n type: string,\n method: string,\n params: unknown[],\n callback: ProviderInterfaceCallback\n ): Promise<number | string> {\n return this.send<number | string>(method, params, false, { callback, type })\n }\n\n /**\n * @summary Allows unsubscribing to subscriptions made with [[subscribe]].\n */\n public async unsubscribe(type: string, method: string, id: number | string): Promise<boolean> {\n const subscription = `${type}::${id}`\n\n // FIXME This now could happen with re-subscriptions. The issue is that with a re-sub\n // the assigned id now does not match what the API user originally received. It has\n // a slight complication in solving - since we cannot rely on the send id, but rather\n // need to find the actual subscription id to map it\n if (this.#subscriptions[subscription] === undefined) {\n // log.debug(() => `Unable to find active subscription=${subscription}`)\n\n return false\n }\n\n delete this.#subscriptions[subscription]\n\n try {\n return this.isConnected && this.#websocket !== null ? this.send<boolean>(method, [id]) : true\n } catch {\n return false\n }\n }\n\n #emit = (type: ProviderInterfaceEmitted, ...args: unknown[]): void => {\n this.#eventemitter.emit(type, ...args)\n }\n\n #onSocketClose = (event: CloseEvent): void => {\n const error = new Error(\n `disconnected from ${this.endpoint}: ${event.code}:: ${\n event.reason || getWSErrorString(event.code)\n }`\n )\n\n if (this.#autoConnectBackoff.isActive) {\n // 1000 is a normal closure and should not be logged as an error\n if (event.code !== 1000) log.error(error.message)\n }\n\n this.#isConnected = false\n\n if (this.#websocket) {\n this.#websocket.onclose = null\n this.#websocket.onerror = null\n this.#websocket.onmessage = null\n this.#websocket.onopen = null\n this.#websocket = null\n }\n\n if (this.#timeoutId) {\n clearInterval(this.#timeoutId)\n this.#timeoutId = null\n }\n\n // reject all hanging requests\n eraseRecord(this.#handlers, (h) => {\n try {\n h.callback(error, undefined)\n } catch (err) {\n // does not throw\n log.error(err)\n }\n })\n eraseRecord(this.#waitingForId)\n\n this.#emit(\"disconnected\")\n\n this.scheduleNextRetry()\n }\n\n #onSocketError = (error: Event): void => {\n // log.debug(() => [\"socket error\", error])\n this.#emit(\"error\", error)\n }\n\n #onSocketMessage = (message: MessageEvent<string>): void => {\n // log.debug(() => [\"received\", message.data])\n try {\n const response = JSON.parse(message.data) as UnknownJsonRpcResponse\n\n // biome-ignore lint/correctness/noVoidTypeReturn: legacy\n return response.method === undefined\n ? this.#onSocketMessageResult(response)\n : this.#onSocketMessageSubscribe(response)\n } catch (e) {\n this.#emit(\"error\", new Error(\"Invalid websocket message received\", { cause: e }))\n }\n }\n\n #onSocketMessageResult = (response: UnknownJsonRpcResponse): void => {\n const handler = this.#handlers[response.id]\n\n if (!handler) {\n // log.debug(() => `Unable to find handler for id=${response.id}`)\n\n return\n }\n\n try {\n const { method, params, subscription } = handler\n const result = this.#coder.decodeResponse(response) as string\n\n // first send the result - in case of subs, we may have an update\n // immediately if we have some queued results already\n handler.callback(null, result)\n\n if (subscription) {\n const subId = `${subscription.type}::${result}`\n\n this.#subscriptions[subId] = { ...subscription, method, params }\n\n // if we have a result waiting for this subscription already\n if (this.#waitingForId[subId]) {\n this.#onSocketMessageSubscribe(this.#waitingForId[subId])\n }\n }\n } catch (error) {\n handler.callback(error as Error, undefined)\n }\n\n delete this.#handlers[response.id]\n }\n\n #onSocketMessageSubscribe = (response: UnknownJsonRpcResponse): void => {\n const method = ALIASES[response.method as string] || response.method || \"invalid\"\n const subId = `${method}::${response.params.subscription}`\n const handler = this.#subscriptions[subId]\n\n if (!handler) {\n // store the JSON, we could have out-of-order subid coming in\n this.#waitingForId[subId] = response\n\n // log.debug(() => `Unable to find handler for subscription=${subId}`)\n\n return\n }\n\n // housekeeping\n delete this.#waitingForId[subId]\n\n try {\n const result = this.#coder.decodeResponse(response)\n\n handler.callback(null, result)\n } catch (error) {\n handler.callback(error as Error, undefined)\n }\n }\n\n #onSocketOpen = (): boolean => {\n if (this.#websocket === null) {\n throw new Error(\"WebSocket cannot be null in onOpen\")\n }\n\n // log.debug(() => [\"connected to\", this.endpoint])\n\n this.#isConnected = true\n this.#endpointsTriedSinceLastConnection = 0\n this.#autoConnectBackoff.reset()\n\n this.#resubscribe()\n\n this.#emit(\"connected\")\n\n return true\n }\n\n #resubscribe = (): void => {\n const subscriptions = this.#subscriptions\n\n this.#subscriptions = {}\n\n Promise.all(\n Object.keys(subscriptions).map(async (id): Promise<void> => {\n const { callback, method, params, type } = subscriptions[id]\n\n // only re-create subscriptions which are not in author (only area where\n // transactions are created, i.e. submissions such as 'author_submitAndWatchExtrinsic'\n // are not included (and will not be re-broadcast)\n if (type.startsWith(\"author_\")) {\n return\n }\n\n try {\n await this.subscribe(type, method, params, callback)\n } catch (error) {\n log.error(error)\n }\n })\n ).catch(log.error)\n }\n\n #timeoutHandlers = (): void => {\n const now = Date.now()\n const ids = Object.keys(this.#handlers)\n\n for (let i = 0; i < ids.length; i++) {\n const handler = this.#handlers[ids[i]]\n\n if (now - handler.start > this.#timeout) {\n try {\n handler.callback(\n new Error(`No response received from RPC endpoint in ${this.#timeout / 1000}s`),\n undefined\n )\n } catch {\n // ignore\n }\n\n delete this.#handlers[ids[i]]\n }\n }\n }\n}\n","const twoSecondsMs = 2 * 1000\nconst twoMinutesMs = 2 * 60 * 1000\n\nexport class ExponentialBackoff {\n #minInterval: number\n #maxInterval: number\n #nextInterval = 0\n #active = true\n\n constructor(maxIntervalMs = twoMinutesMs, minIntervalMs = twoSecondsMs) {\n this.#minInterval = minIntervalMs\n this.#maxInterval = maxIntervalMs\n\n this.reset()\n }\n\n enable() {\n this.#active = true\n }\n disable() {\n this.#active = false\n }\n\n increase() {\n if (this.#nextInterval === 0) this.#nextInterval = 1\n this.#nextInterval = this.#capMax(this.#capMin(this.#nextInterval * 2))\n }\n decrease() {\n this.#nextInterval = this.#capMax(this.#capMin(this.#nextInterval / 2))\n }\n\n reset() {\n this.#nextInterval = this.#minInterval\n }\n resetTo(nextInterval: number) {\n this.#nextInterval = this.#capMax(this.#capMin(nextInterval))\n }\n resetToMax() {\n this.#nextInterval = this.#maxInterval\n }\n\n get isActive() {\n return this.#active\n }\n get next() {\n return this.#nextInterval\n }\n\n get isMin() {\n return this.#nextInterval === this.#minInterval\n }\n get isMax() {\n return this.#nextInterval === this.#maxInterval\n }\n\n #capMin(value: number) {\n return Math.max(this.#minInterval, value)\n }\n #capMax(value: number) {\n return Math.min(this.#maxInterval, value)\n }\n}\n","import { WsProvider } from \"@polkadot/rpc-provider\"\nimport type { ProviderInterface, ProviderInterfaceCallback } from \"@polkadot/rpc-provider/types\"\nimport type { DotNetwork, DotNetworkId } from \"@talismn/chaindata-provider\"\nimport { throwAfter } from \"@talismn/util\"\n\nimport type { IChainConnectorDot } from \"./IChainConnectorDot\"\n\nconst AUTO_CONNECT_TIMEOUT = 3_000\nconst TIMEOUT = 10_000\n\nexport class ChainConnectorDotStub implements IChainConnectorDot {\n // biome-ignore lint/correctness/noUnusedPrivateClassMembers: legacy\n #network: DotNetwork\n #provider: WsProvider\n\n constructor(network: DotNetwork) {\n this.#network = network\n this.#provider = new WsProvider(network.rpcs, AUTO_CONNECT_TIMEOUT, undefined, TIMEOUT)\n }\n\n asProvider(): ProviderInterface {\n return this.#provider as ProviderInterface\n }\n\n async send<T = unknown>(\n _chainId: DotNetworkId,\n method: string,\n params: unknown[],\n isCacheable?: boolean\n ): Promise<T> {\n await this.#provider.isReady\n\n return this.#provider.send(method, params, isCacheable) as Promise<T>\n }\n\n async subscribe(\n _chainId: DotNetworkId,\n subscribeMethod: string,\n responseMethod: string,\n params: unknown[],\n callback: ProviderInterfaceCallback,\n timeout?: number | false\n ): Promise<(unsubscribeMethod: string) => void> {\n await this.#provider.isReady\n\n const subId = await Promise.race([\n throwAfter(timeout || TIMEOUT, `Subscription timed out after ${timeout}ms`),\n this.#provider.subscribe(responseMethod, subscribeMethod, params, callback),\n ])\n\n return (unsubscribeMethod: string) => {\n this.#provider.unsubscribe(responseMethod, unsubscribeMethod, subId)\n }\n }\n\n reset(): Promise<void> {\n throw new Error(\"ChainConnectorDotStub does not implement reset\")\n }\n}\n","import type { EthNetwork } from \"@talismn/chaindata-provider\"\nimport { createPublicClient, type PublicClient } from \"viem\"\n\nimport { clearChainsCache, getChainFromEvmNetwork } from \"./getChainFromEvmNetwork\"\nimport { getTransportForEvmNetwork, type TransportOptions } from \"./getTransportForEvmNetwork\"\n\nconst MUTLICALL_BATCH_WAIT = 25\nconst MUTLICALL_BATCH_SIZE = 100\n\nconst HTTP_BATCH_WAIT = 25\nconst HTTP_BATCH_SIZE_WITH_MULTICALL = 10\nconst HTTP_BATCH_SIZE_WITHOUT_MULTICALL = 30\n\n// cache to reuse previously created public clients\nconst publicClientCache = new Map<string, PublicClient>()\n\nexport const clearPublicClientCache = (evmNetworkId?: string) => {\n clearChainsCache(evmNetworkId)\n\n if (evmNetworkId) publicClientCache.delete(evmNetworkId)\n else publicClientCache.clear()\n}\n\nexport const getEvmNetworkPublicClient = (network: EthNetwork): PublicClient => {\n const chain = getChainFromEvmNetwork(network)\n\n if (!publicClientCache.has(network.id)) {\n if (!network.rpcs.length) throw new Error(\"No RPCs found for Ethereum network\")\n\n const batch = chain.contracts?.multicall3\n ? { multicall: { wait: MUTLICALL_BATCH_WAIT, batchSize: MUTLICALL_BATCH_SIZE } }\n : undefined\n\n const transportOptions: TransportOptions = {\n batch: {\n batchSize: chain.contracts?.multicall3\n ? HTTP_BATCH_SIZE_WITH_MULTICALL\n : HTTP_BATCH_SIZE_WITHOUT_MULTICALL,\n wait: HTTP_BATCH_WAIT,\n },\n }\n\n const transport = getTransportForEvmNetwork(network, transportOptions)\n\n publicClientCache.set(\n network.id,\n createPublicClient({\n chain,\n transport,\n batch,\n })\n )\n }\n\n return publicClientCache.get(network.id) as PublicClient\n}\n","import type { EthNetwork, EthNetworkId } from \"@talismn/chaindata-provider\"\nimport { camelCase, fromPairs, toPairs } from \"lodash-es\"\nimport type { Chain, ChainContract } from \"viem\"\nimport * as viemChains from \"viem/chains\"\n\n// exclude zoraTestnet which uses Hyperliquid's chain id\nconst { zoraTestnet, ...validViemChains } = viemChains\n\n// viem chains benefit from multicall config & other viem goodies\nconst VIEM_CHAINS = Object.keys(validViemChains).reduce(\n (acc, curr) => {\n const chain = validViemChains[curr as keyof typeof validViemChains]\n acc[chain.id] = chain\n return acc\n },\n {} as Record<number, Chain>\n)\n\nconst chainsCache = new Map<string, Chain>()\n\nexport const clearChainsCache = (networkId?: EthNetworkId) => {\n if (networkId) chainsCache.delete(networkId)\n else chainsCache.clear()\n}\n\nexport const getChainFromEvmNetwork = (network: EthNetwork): Chain => {\n const { symbol, decimals } = network.nativeCurrency\n\n if (!chainsCache.has(network.id)) {\n const chainRpcs = network.rpcs ?? []\n\n const viemChain = VIEM_CHAINS[Number(network.id)] ?? {}\n\n const chain: Chain = {\n ...viemChain,\n id: Number(network.id),\n name: network.name ?? `Ethereum Chain ${network.id}`,\n rpcUrls: {\n public: { http: chainRpcs },\n default: { http: chainRpcs },\n },\n nativeCurrency: {\n symbol,\n decimals,\n name: symbol,\n },\n contracts: {\n ...viemChain.contracts,\n ...(network.contracts\n ? fromPairs(\n toPairs(network.contracts).map(([name, address]): [string, ChainContract] => [\n camelCase(name),\n { address },\n ])\n )\n : {}),\n },\n }\n\n chainsCache.set(network.id, chain)\n }\n\n return chainsCache.get(network.id) as Chain\n}\n","import type { EthNetwork } from \"@talismn/chaindata-provider\"\nimport { fallback, http } from \"viem\"\n\nexport type TransportOptions = {\n batch?:\n | boolean\n | {\n batchSize?: number | undefined\n wait?: number | undefined\n }\n}\n\nexport const getTransportForEvmNetwork = (\n evmNetwork: EthNetwork,\n options: TransportOptions = {}\n) => {\n if (!evmNetwork.rpcs?.length) throw new Error(\"No RPCs found for EVM network\")\n\n const { batch } = options\n\n return fallback(\n evmNetwork.rpcs.map((url) => http(url, { batch, retryCount: 0 })),\n { retryCount: 0 }\n )\n}\n","import type { EthNetwork } from \"@talismn/chaindata-provider\"\nimport { type Account, createWalletClient, type WalletClient } from \"viem\"\n\nimport { getChainFromEvmNetwork } from \"./getChainFromEvmNetwork\"\nimport { getTransportForEvmNetwork } from \"./getTransportForEvmNetwork\"\n\ntype WalletClientOptions = {\n account?: `0x${string}` | Account\n}\n\nexport const getEvmNetworkWalletClient = (\n network: EthNetwork,\n options: WalletClientOptions = {}\n): WalletClient => {\n const chain = getChainFromEvmNetwork(network)\n\n const transport = getTransportForEvmNetwork(network)\n\n return createWalletClient({ chain, transport, account: options.account })\n}\n","import type {\n EthNetworkId,\n IChaindataNetworkProvider,\n IChaindataTokenProvider,\n} from \"@talismn/chaindata-provider\"\nimport type { Account, PublicClient, WalletClient } from \"viem\"\n\nimport { clearPublicClientCache, getEvmNetworkPublicClient } from \"./getEvmNetworkPublicClient\"\nimport { getEvmNetworkWalletClient } from \"./getEvmNetworkWalletClient\"\nimport type { IChainConnectorEth } from \"./IChainConnectorEth\"\n\nexport class ChainConnectorEth implements IChainConnectorEth {\n #chaindataProvider: IChaindataNetworkProvider & IChaindataTokenProvider\n\n constructor(chaindataProvider: IChaindataNetworkProvider & IChaindataTokenProvider) {\n this.#chaindataProvider = chaindataProvider\n }\n\n async getPublicClientForEvmNetwork(evmNetworkId: EthNetworkId): Promise<PublicClient | null> {\n const network = await this.#chaindataProvider.getNetworkById(evmNetworkId, \"ethereum\")\n if (!network) return null\n\n return getEvmNetworkPublicClient(network)\n }\n\n async getWalletClientForEvmNetwork(\n evmNetworkId: EthNetworkId,\n account?: `0x${string}` | Account\n ): Promise<WalletClient | null> {\n const network = await this.#chaindataProvider.getNetworkById(evmNetworkId, \"ethereum\")\n if (!network) return null\n\n return getEvmNetworkWalletClient(network, { account })\n }\n\n public clearRpcProvidersCache(evmNetworkId?: EthNetworkId) {\n clearPublicClientCache(evmNetworkId)\n }\n}\n","import type { EthNetwork, EthNetworkId } from \"@talismn/chaindata-provider\"\nimport type { Account, PublicClient, WalletClient } from \"viem\"\n\nimport { getEvmNetworkPublicClient } from \"./getEvmNetworkPublicClient\"\nimport { getEvmNetworkWalletClient } from \"./getEvmNetworkWalletClient\"\nimport type { IChainConnectorEth } from \"./IChainConnectorEth\"\n\nexport class ChainConnectorEthStub implements IChainConnectorEth {\n #network: EthNetwork\n\n constructor(network: EthNetwork) {\n this.#network = network\n }\n\n async getPublicClientForEvmNetwork(): Promise<PublicClient | null> {\n return getEvmNetworkPublicClient(this.#network)\n }\n\n async getWalletClientForEvmNetwork(\n _networkId: EthNetworkId,\n account?: `0x${string}` | Account\n ): Promise<WalletClient | null> {\n return getEvmNetworkWalletClient(this.#network, { account })\n }\n\n clearRpcProvidersCache(): void {\n // No-op for stub\n }\n}\n","import { Connection } from \"@solana/web3.js\"\nimport type { SolNetworkId } from \"@talismn/chaindata-provider\"\n\n// TODO leverage multiple rpcs with fallback\nexport const getSolConnection = (_networkId: SolNetworkId, rpcs: string[]) => {\n return new Connection(rpcs[0], {\n commitment: \"confirmed\",\n })\n}\n","import type { Connection } from \"@solana/web3.js\"\nimport type {\n IChaindataNetworkProvider,\n IChaindataTokenProvider,\n SolNetworkId,\n} from \"@talismn/chaindata-provider\"\n\nimport { getSolConnection } from \"./getSolConnection\"\nimport type { IChainConnectorSol } from \"./IChainConnectorSol\"\n\nexport class ChainConnectorSol implements IChainConnectorSol {\n #chaindataProvider: IChaindataNetworkProvider & IChaindataTokenProvider\n\n constructor(chaindataProvider: IChaindataNetworkProvider & IChaindataTokenProvider) {\n this.#chaindataProvider = chaindataProvider\n }\n\n async getConnection(networkId: SolNetworkId): Promise<Connection> {\n const network = await this.#chaindataProvider.getNetworkById(networkId, \"solana\")\n if (!network) throw new Error(`Network not found: ${networkId}`)\n\n return getSolConnection(networkId, network.rpcs)\n }\n}\n","import type { Connection } from \"@solana/web3.js\"\nimport type { SolNetwork } from \"@talismn/chaindata-provider\"\n\nimport { getSolConnection } from \"./getSolConnection\"\nimport type { IChainConnectorSol } from \"./IChainConnectorSol\"\n\nexport class ChainConnectorSolStub implements IChainConnectorSol {\n #connection: Connection\n\n constructor(networkOrConnection: Pick<SolNetwork, \"id\" | \"rpcs\"> | Connection) {\n // NOTE: do not use `instanceof Connection` here. In bundled builds @solana/web3.js\n // can be duplicated across chunks, so a Connection created from one copy of the\n // module fails an `instanceof` check against another copy's class. That silently\n // fell through to getSolConnection() with an undefined `rpcs`, throwing\n // \"Cannot read properties of undefined (reading '0')\" and breaking every Solana\n // transfer. Duck-type on the network-only `rpcs` field instead (a Connection never\n // has it), which is robust regardless of how many module instances exist.\n this.#connection =\n \"rpcs\" in networkOrConnection\n ? getSolConnection(networkOrConnection.id, networkOrConnection.rpcs)\n : networkOrConnection\n }\n\n async getConnection(): Promise<Connection> {\n return this.#connection\n }\n}\n"],"mappings":"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","names":["endpoint","unsubscribeMethod","throwAfter"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@talismn/chain-connectors",
3
- "version": "0.0.19",
3
+ "version": "0.1.0",
4
4
  "author": "Talisman",
5
5
  "homepage": "https://talisman.xyz",
6
6
  "license": "GPL-3.0-or-later",
@@ -24,23 +24,21 @@
24
24
  "@solana/web3.js": "^1.98.2",
25
25
  "anylogger": "^1.0.11",
26
26
  "eventemitter3": "^5.0.0",
27
- "lodash-es": "4.17.21",
28
- "viem": "^2.27.3",
29
- "@talismn/connection-meta": "0.2.39",
30
- "@talismn/chaindata-provider": "1.4.0",
31
- "@talismn/util": "1.0.1"
27
+ "lodash-es": "4.18.1",
28
+ "viem": "2.52.2",
29
+ "@talismn/chaindata-provider": "1.5.0",
30
+ "@talismn/connection-meta": "0.3.0",
31
+ "@talismn/util": "1.1.0"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@polkadot/rpc-provider": "16.1.2",
35
- "@polkadot/util": "13.5.3",
36
35
  "@polkadot/x-global": "13.5.3",
37
36
  "@polkadot/x-ws": "13.5.3",
38
- "typescript": "^5.6.3",
37
+ "typescript": "^6.0.3",
39
38
  "@talismn/tsconfig": "0.0.4"
40
39
  },
41
40
  "peerDependencies": {
42
41
  "@polkadot/rpc-provider": "*",
43
- "@polkadot/util": "*",
44
42
  "@polkadot/x-global": "*",
45
43
  "@polkadot/x-ws": "*"
46
44
  },