PHP WebShell

Текущая директория: /opt/BitGoJS/node_modules/@substrate/light-client-extension-helpers/dist/background

Просмотр файла: background-helper.mjs.map

{"version":3,"sources":["../../src/background/background-helper.ts","../../src/background/json-rpc-provider.ts","../../src/background/smoldot-provider.ts","../../src/background/createBackgroundRpc.ts"],"sourcesContent":["import type { ToApplication } from \"@substrate/connect-extension-protocol\"\nimport {\n  type SubstrateClient,\n  createClient,\n} from \"@polkadot-api/substrate-client\"\nimport { getObservableClient } from \"@polkadot-api/observable-client\"\nimport { getSyncProvider } from \"@polkadot-api/json-rpc-provider-proxy\"\nimport {\n  Observable,\n  firstValueFrom,\n  catchError,\n  defer,\n  EMPTY,\n  repeat,\n} from \"rxjs\"\nimport type {\n  AddOnAddChainByUserListener,\n  LightClientPageHelper,\n  PageChain,\n} from \"./types\"\nimport { smoldotProvider } from \"./smoldot-provider\"\nimport { ALARM, PORT, isSubstrateConnectToExtensionMessage } from \"@/shared\"\nimport { isRpcMessage, type RpcMessage } from \"@/utils\"\nimport * as storage from \"@/storage\"\nimport { createBackgroundRpc } from \"./createBackgroundRpc\"\nimport { Client, Chain, AddChainOptions, supervise } from \"../smoldot\"\n\nexport type * from \"./types\"\n\nlet isRegistered = false\n\ntype RegisterOptions = {\n  smoldotClient: Client\n  getWellKnownChainSpecs: () => Promise<string[] | Record<string, string>>\n}\nexport const register = ({\n  smoldotClient,\n  getWellKnownChainSpecs,\n}: RegisterOptions) => {\n  if (isRegistered) throw new Error(\"helper already registered\")\n  isRegistered = true\n\n  supervise(smoldotClient, { onError: console.error })\n\n  const wellKnownChainSpecsPromise: Promise<Record<string, string>> =\n    getWellKnownChainSpecs().then(async (chainSpecs) =>\n      chainSpecs instanceof Array\n        ? Object.fromEntries(\n            await Promise.all(\n              chainSpecs.map(async (chainSpec) => {\n                const { genesisHash } = await getChainData({\n                  smoldotClient,\n                  chainSpec,\n                })\n                return [genesisHash, chainSpec] as const\n              }),\n            ),\n          )\n        : chainSpecs,\n    )\n\n  const initialized = wellKnownChainSpecsPromise\n    .then((wellKnownChainSpecs) =>\n      Promise.all(\n        Object.values(wellKnownChainSpecs).map((chainSpec) =>\n          lightClientPageHelper.persistChain(chainSpec),\n        ),\n      ),\n    )\n    .catch((error) =>\n      console.error(\"Error persisting well-known chainspecs\", error),\n    )\n\n  storage.getChains().then((chains) => {\n    Object.values(chains).forEach(\n      ({ chainSpec, genesisHash, relayChainGenesisHash }) =>\n        followChain({\n          smoldotClient,\n          chainSpec,\n          genesisHash,\n          relayChainGenesisHash,\n        }),\n    )\n  })\n\n  storage.onChainsChanged((chains) => {\n    for (const [genesisHash] of followedChains) {\n      if (chains[genesisHash]) continue\n      unfollowChain(genesisHash)\n    }\n    Object.values(chains).forEach(\n      ({ genesisHash, chainSpec, relayChainGenesisHash }) => {\n        if (followedChains.has(genesisHash)) return\n        followChain({\n          smoldotClient,\n          chainSpec,\n          genesisHash,\n          relayChainGenesisHash,\n        })\n      },\n    )\n  })\n\n  chrome.alarms.onAlarm.addListener(async (alarm) => {\n    if (alarm.name !== ALARM.DATABASE_UPDATE) return\n    Object.values(await storage.getChains()).forEach(\n      async ({ genesisHash, chainSpec, relayChainGenesisHash }) => {\n        try {\n          const finalizedDatabase = await getFinalizedDatabase({\n            smoldotClient,\n            chainSpec,\n            databaseContent: await storage.get({\n              type: \"databaseContent\",\n              genesisHash,\n            }),\n            relayChainGenesisHash,\n          })\n          await storage.set(\n            { type: \"databaseContent\", genesisHash },\n            finalizedDatabase,\n          )\n        } catch (error) {\n          console.error(\"Error updating DB\", error)\n        }\n      },\n    )\n  })\n\n  chrome.runtime.onInstalled.addListener(({ reason }) => {\n    if (\n      reason !== chrome.runtime.OnInstalledReason.INSTALL &&\n      reason !== chrome.runtime.OnInstalledReason.UPDATE\n    )\n      return\n\n    chrome.alarms.create(ALARM.DATABASE_UPDATE, {\n      periodInMinutes: 2,\n    })\n  })\n\n  const lightClientPageHelper: LightClientPageHelper = {\n    async deleteChain(genesisHash) {\n      if ((await wellKnownChainSpecsPromise)[genesisHash])\n        throw new Error(\"Cannot delete well-known-chain\")\n\n      await Promise.all([\n        storage.remove([\n          { type: \"chain\", genesisHash },\n          { type: \"bootNodes\", genesisHash },\n          { type: \"databaseContent\", genesisHash },\n        ]),\n        Object.keys(activeChains).map((tabId) =>\n          this.disconnect(+tabId, genesisHash),\n        ),\n      ])\n      for (const {\n        genesisHash: parachainGenesisHash,\n        relayChainGenesisHash,\n      } of Object.values(await storage.getChains())) {\n        if (relayChainGenesisHash !== genesisHash) continue\n        await this.deleteChain(parachainGenesisHash)\n      }\n    },\n    async persistChain(chainSpec, relayChainGenesisHash) {\n      const chainData = await getChainData({\n        smoldotClient,\n        chainSpec,\n        relayChainGenesisHash,\n      })\n      if (\n        await storage.get({ type: \"chain\", genesisHash: chainData.genesisHash })\n      )\n        return\n\n      const chainSpecJson = JSON.parse(chainSpec)\n      const bootNodes = chainSpecJson.bootNodes\n      let minimalChainSpec: string = \"\"\n      delete chainSpecJson.bootNodes\n      delete chainSpecJson.protocolId\n      delete chainSpecJson.telemetryEndpoints\n\n      if (!chainSpecJson.genesis.stateRootHash) {\n        chainSpecJson.genesis.stateRootHash = await getGenesisStateRoot({\n          smoldotClient,\n          chainSpec,\n          relayChainGenesisHash,\n        })\n      }\n\n      // TODO: check if .lightSyncState could be removed and use chainHead_unstable_finalizedDatabase\n\n      minimalChainSpec = JSON.stringify(chainSpecJson)\n\n      await Promise.all([\n        storage.set(\n          { type: \"chain\", genesisHash: chainData.genesisHash },\n          {\n            ...chainData,\n            chainSpec: minimalChainSpec,\n            relayChainGenesisHash,\n          },\n        ),\n        storage.set(\n          { type: \"bootNodes\", genesisHash: chainData.genesisHash },\n          bootNodes,\n        ),\n      ])\n    },\n    async getChains() {\n      const chains = await storage.getChains()\n      return Promise.all(\n        Object.entries(chains).map(async ([genesisHash, chain]) => ({\n          ...chain,\n          bootNodes:\n            (await storage.get({ type: \"bootNodes\", genesisHash })) ??\n            (JSON.parse(chain.chainSpec).bootNodes as string[]),\n          provider: await createSmoldotProvider({\n            smoldotClient,\n            chainSpec: chain.chainSpec,\n            genesisHash: chain.genesisHash,\n            relayChainGenesisHash: chain.relayChainGenesisHash,\n          }),\n        })),\n      )\n    },\n    async getActiveConnections() {\n      return Object.entries(activeChains).reduce(\n        (acc, [tabIdStr, tabChains]) => {\n          const tabId = parseInt(tabIdStr)\n          Object.values(tabChains).forEach(\n            ({\n              genesisHash,\n              name,\n              ss58Format,\n              bootNodes,\n              chainSpec,\n              relayChainGenesisHash,\n            }) =>\n              acc.push({\n                tabId,\n                chain: {\n                  genesisHash,\n                  chainSpec,\n                  relayChainGenesisHash,\n                  name,\n                  ss58Format,\n                  bootNodes,\n                  provider: createSmoldotSyncProvider({\n                    smoldotClient,\n                    chainSpec,\n                    genesisHash,\n                    relayChainGenesisHash,\n                  }),\n                },\n              }),\n          )\n          return acc\n        },\n        [] as { tabId: number; chain: PageChain }[],\n      )\n    },\n    async disconnect(tabId: number, genesisHash: string) {\n      Object.entries(activeChains[tabId] ?? {})\n        .filter(\n          ([_, { genesisHash: activeGenesisHash }]) =>\n            activeGenesisHash === genesisHash,\n        )\n        .forEach(([chainId]) => {\n          removeChain(tabId, chainId)\n          chrome.tabs.sendMessage(tabId, {\n            origin: \"substrate-connect-extension\",\n            type: \"error\",\n            chainId,\n            errorMessage: \"Disconnected\",\n          } as ToApplication)\n        })\n    },\n    setBootNodes(genesisHash, bootNodes) {\n      return storage.set({ type: \"bootNodes\", genesisHash }, bootNodes)\n    },\n  }\n\n  // Chains by TabId\n  const activeChains: Record<\n    number,\n    Record<\n      string,\n      {\n        chain: Chain\n        genesisHash: string\n        chainSpec: string\n        relayChainGenesisHash?: string\n        name: string\n        ss58Format: number\n        bootNodes: Array<string>\n      }\n    >\n  > = {}\n  const helperPortNames: string[] = [\n    PORT.CONTENT_SCRIPT,\n    PORT.EXTENSION_PAGE,\n    PORT.WEB_PAGE,\n  ]\n  chrome.runtime.onConnect.addListener((port) => {\n    if (!helperPortNames.includes(port.name)) return\n\n    // use chrome.tabs.TAB_ID_NONE for popup port\n    const tabId = port.sender?.tab?.id ?? chrome.tabs.TAB_ID_NONE\n\n    const postMessage = (message: ToApplication | RpcMessage) =>\n      port.postMessage(message)\n\n    const rpc = createBackgroundRpc(postMessage)\n\n    const unsubscribeOnChainsChanged = storage.onChainsChanged((chains) =>\n      rpc.notify(\"onAddChains\", [chains]),\n    )\n\n    let isPortDisconnected = false\n    port.onDisconnect.addListener(() => {\n      isPortDisconnected = true\n      unsubscribeOnChainsChanged()\n      if (!activeChains[tabId]) return\n      for (const [chainId, { chain }] of Object.entries(activeChains[tabId])) {\n        try {\n          chain.remove()\n        } catch (error) {\n          console.error(\"error removing chain\", error)\n        }\n        delete activeChains[tabId][chainId]\n      }\n      delete activeChains[tabId]\n    })\n\n    const pendingAddChains: Record<string, boolean> = {}\n    port.onMessage.addListener(async (msg) => {\n      await initialized\n      if (isRpcMessage(msg))\n        return rpc.handle(msg, {\n          port,\n          lightClientPageHelper,\n          addChainByUserListener,\n          getChainData: ({ chainSpec, relayChainGenesisHash }) =>\n            getChainData({\n              smoldotClient,\n              chainSpec,\n              relayChainGenesisHash,\n            }),\n        })\n      else if (isSubstrateConnectToExtensionMessage(msg))\n        switch (msg.type) {\n          case \"add-well-known-chain\":\n          case \"add-chain\": {\n            activeChains[tabId] ??= {}\n            try {\n              if (\n                activeChains[tabId][msg.chainId] ||\n                pendingAddChains[msg.chainId]\n              )\n                throw new Error(\"Requested chainId already in use\")\n\n              pendingAddChains[msg.chainId] = true\n              const chains = await storage.getChains()\n\n              let addChainOptions: AddChainOptions\n              if (msg.type === \"add-well-known-chain\") {\n                const chain =\n                  Object.values(chains).find(\n                    (chain) => chain.genesisHash === msg.chainName,\n                  ) ??\n                  Object.values(chains).find(\n                    (chain) => chain.name === msg.chainName,\n                  )\n                if (!chain) throw new Error(\"Unknown well-known chain\")\n                addChainOptions = {\n                  chainSpec: chain.chainSpec,\n                  disableJsonRpc: false,\n                  potentialRelayChains: chain.relayChainGenesisHash\n                    ? [\n                        {\n                          chainSpec:\n                            chains[chain.relayChainGenesisHash].chainSpec,\n                          disableJsonRpc: true,\n                          databaseContent: await storage.get({\n                            type: \"databaseContent\",\n                            genesisHash: chain.relayChainGenesisHash,\n                          }),\n                        },\n                      ]\n                    : [],\n                  databaseContent: await storage.get({\n                    type: \"databaseContent\",\n                    genesisHash: chain.genesisHash,\n                  }),\n                }\n              } else {\n                const relayChainGenesisHashOrChainId =\n                  msg.potentialRelayChainIds[0]\n                addChainOptions = {\n                  chainSpec: msg.chainSpec,\n                  disableJsonRpc: false,\n                  potentialRelayChains: chains[relayChainGenesisHashOrChainId]\n                    ? [\n                        {\n                          chainSpec:\n                            chains[relayChainGenesisHashOrChainId].chainSpec,\n                          disableJsonRpc: true,\n                          databaseContent: await storage.get({\n                            type: \"databaseContent\",\n                            genesisHash: relayChainGenesisHashOrChainId,\n                          }),\n                        },\n                      ]\n                    : msg.potentialRelayChainIds\n                        .filter((chainId) => activeChains[tabId][chainId])\n                        .map((chainId) => ({\n                          chainSpec: activeChains[tabId][chainId].chainSpec,\n                          disableJsonRpc: true,\n                        })),\n                }\n              }\n\n              const [smoldotChain, { genesisHash, name, ss58Format }] =\n                await Promise.all([\n                  smoldotClient.addChain(addChainOptions),\n                  getChainData({ smoldotClient, addChainOptions }),\n                ])\n\n              ;(async () => {\n                while (true) {\n                  let jsonRpcMessage: string | undefined\n                  try {\n                    jsonRpcMessage = await smoldotChain.nextJsonRpcResponse()\n                  } catch (_) {\n                    break\n                  }\n\n                  if (isPortDisconnected) break\n\n                  // `nextJsonRpcResponse` throws an exception if we pass `disableJsonRpc: true` in the\n                  // config. We pass `disableJsonRpc: true` if `jsonRpcCallback` is undefined. Therefore,\n                  // this code is never reachable if `jsonRpcCallback` is undefined.\n                  try {\n                    postMessage({\n                      origin: \"substrate-connect-extension\",\n                      type: \"rpc\",\n                      chainId: msg.chainId,\n                      jsonRpcMessage,\n                    })\n                  } catch (error) {\n                    console.error(\n                      \"JSON-RPC callback has thrown an exception:\",\n                      error,\n                    )\n                  }\n                }\n              })()\n\n              if (!pendingAddChains[msg.chainId]) {\n                smoldotChain.remove()\n                return\n              }\n              delete pendingAddChains[msg.chainId]\n\n              // FIXME: double check this and dedupe from above\n              let relayChainGenesisHash: string | undefined = undefined\n              if (msg.type === \"add-chain\") {\n                const relayChainGenesisHashOrChainId =\n                  msg.potentialRelayChainIds[0]\n                relayChainGenesisHash = chains[relayChainGenesisHashOrChainId]\n                  ? chains[relayChainGenesisHashOrChainId].genesisHash\n                  : msg.potentialRelayChainIds\n                      .filter((chainId) => activeChains[tabId][chainId])\n                      .map(\n                        (chainId) => activeChains[tabId][chainId].genesisHash,\n                      )[0]\n              }\n\n              activeChains[tabId][msg.chainId] = {\n                chain: smoldotChain,\n                genesisHash,\n                relayChainGenesisHash,\n                chainSpec: addChainOptions.chainSpec,\n                name,\n                ss58Format,\n                bootNodes:\n                  JSON.parse(addChainOptions.chainSpec)?.bootNodes ?? [],\n              }\n\n              postMessage({\n                origin: \"substrate-connect-extension\",\n                type: \"chain-ready\",\n                chainId: msg.chainId,\n              })\n            } catch (error) {\n              delete pendingAddChains[msg.chainId]\n              postMessage({\n                origin: \"substrate-connect-extension\",\n                type: \"error\",\n                chainId: msg.chainId,\n                errorMessage:\n                  error instanceof Error\n                    ? error.toString()\n                    : \"Unknown error when adding chain\",\n              })\n            }\n\n            break\n          }\n          case \"remove-chain\": {\n            delete pendingAddChains[msg.chainId]\n\n            removeChain(tabId, msg.chainId)\n\n            break\n          }\n          case \"rpc\": {\n            const chain = activeChains?.[tabId]?.[msg.chainId]?.chain\n            if (!chain) return\n\n            try {\n              chain.sendJsonRpc(msg.jsonRpcMessage)\n            } catch (error) {\n              removeChain(tabId, msg.chainId)\n              postMessage({\n                origin: \"substrate-connect-extension\",\n                type: \"error\",\n                chainId: msg.chainId,\n                errorMessage:\n                  error instanceof Error\n                    ? error.toString()\n                    : \"Unknown error when sending RPC message\",\n              })\n            }\n\n            break\n          }\n          default: {\n            const unrecognizedMsg: never = msg\n            console.warn(\"Unrecognized message\", unrecognizedMsg)\n            break\n          }\n        }\n      else console.warn(\"Unrecognized message\", msg)\n    })\n  })\n\n  let addChainByUserListener:\n    | Parameters<AddOnAddChainByUserListener>[0]\n    | undefined = undefined\n\n  const addOnAddChainByUserListener: AddOnAddChainByUserListener = async (\n    onAddChainByUser,\n  ) => {\n    if (addChainByUserListener)\n      throw new Error(\"addChainByUserCallback is already set\")\n    addChainByUserListener = onAddChainByUser\n  }\n\n  const removeChain = (tabId: number, chainId: string) => {\n    const chain = activeChains?.[tabId]?.[chainId]?.chain\n    delete activeChains?.[tabId]?.[chainId]\n    try {\n      chain?.remove()\n    } catch (error) {\n      console.error(\"error removing chain\", error)\n    }\n  }\n\n  return { lightClientPageHelper, addOnAddChainByUserListener }\n}\n\nconst withClient =\n  <T>(fn: (client: SubstrateClient) => T | Promise<T>) =>\n  async (\n    options:\n      | { smoldotClient: Client; addChainOptions: AddChainOptions }\n      | {\n          smoldotClient: Client\n          chainSpec: string\n          databaseContent?: string\n          relayChainGenesisHash?: string\n        },\n  ) => {\n    const client = createClient(\n      await smoldotProvider(\n        \"addChainOptions\" in options\n          ? options\n          : {\n              smoldotClient: options.smoldotClient,\n              chainSpec: options.chainSpec,\n              databaseContent: options.databaseContent,\n              relayChainSpec: options.relayChainGenesisHash\n                ? (await storage.getChains())[options.relayChainGenesisHash]\n                    .chainSpec\n                : undefined,\n              relayChainDatabaseContent: options.relayChainGenesisHash\n                ? await storage.get({\n                    type: \"databaseContent\",\n                    genesisHash: options.relayChainGenesisHash,\n                  })\n                : undefined,\n            },\n      ),\n    )\n    try {\n      return await fn(client)\n    } finally {\n      client.destroy()\n    }\n  }\n\nconst withClientChainHead$ = <T>(\n  fn: (\n    chainHead: ReturnType<ReturnType<typeof getObservableClient>[\"chainHead$\"]>,\n    client: SubstrateClient,\n  ) => T | Promise<T>,\n) =>\n  withClient(async (client) => {\n    const chainHead = getObservableClient(client).chainHead$()\n    try {\n      return await fn(chainHead, client)\n    } finally {\n      chainHead.unfollow()\n    }\n  })\n\nconst getChainData = withClient(async (client) => {\n  const [genesisHash, name, { ss58Format }] = (await Promise.all(\n    [\n      \"chainSpec_v1_genesisHash\",\n      \"chainSpec_v1_chainName\",\n      \"chainSpec_v1_properties\",\n    ].map((method) => substrateClientRequest(client, method)),\n  )) as [string, string, { ss58Format: number }]\n  return {\n    genesisHash,\n    name,\n    ss58Format,\n  }\n})\n\n// TODO: update this implementation when these issues are implemented\n// https://github.com/paritytech/json-rpc-interface-spec/issues/110\n// https://github.com/smol-dot/smoldot/issues/1186\nconst getGenesisStateRoot = withClientChainHead$(\n  async ({ runtime$ }, client) => {\n    await firstValueFrom(runtime$)\n    const genesisHash = await substrateClientRequest<string>(\n      client,\n      \"chainSpec_v1_genesisHash\",\n    )\n    const { stateRoot } = await substrateClientRequest<{\n      stateRoot: string\n    }>(client, \"chain_getHeader\", [genesisHash])\n    return stateRoot\n  },\n)\n\nconst getFinalizedDatabase = withClientChainHead$(\n  async ({ runtime$ }, client) => {\n    await firstValueFrom(runtime$)\n    const finalizedDatabase = await substrateClientRequest<string>(\n      client,\n      \"chainHead_unstable_finalizedDatabase\",\n      (await chrome.permissions.contains({\n        permissions: [\"unlimitedStorage\"],\n      }))\n        ? []\n        : // 1mb will strip the runtime code\n          // See https://github.com/smol-dot/smoldot/blob/0a9e9cd802169bc07dd681e55278fd67c6f8f9bc/light-base/src/database.rs#L134-L140\n          [1024 * 1024],\n    )\n    return finalizedDatabase\n  },\n)\n\nconst substrateClientRequest = <T>(\n  client: SubstrateClient,\n  method: string,\n  params: any[] = [],\n) =>\n  new Promise<T>((resolve, reject) => {\n    try {\n      client._request(method, params, {\n        onSuccess: resolve,\n        onError: reject,\n      })\n    } catch (error) {\n      reject(error)\n    }\n  })\n\nconst followedChains = new Map<string, () => void>()\nconst followChain = ({\n  smoldotClient,\n  chainSpec,\n  genesisHash,\n  relayChainGenesisHash,\n}: {\n  smoldotClient: Client\n  chainSpec: string\n  genesisHash: string\n  relayChainGenesisHash?: string\n}) => {\n  const subscription = new Observable<boolean>((observer) => {\n    observer.next(false)\n    const client = getObservableClient(\n      createClient(\n        createSmoldotSyncProvider({\n          smoldotClient,\n          chainSpec,\n          genesisHash,\n          relayChainGenesisHash,\n        }),\n      ),\n    )\n    let unfollow: ReturnType<(typeof client)[\"chainHead$\"]>[\"unfollow\"]\n    const finalizedSubscription = defer(() => {\n      const chainHead = client.chainHead$()\n      unfollow = chainHead.unfollow\n      return chainHead.finalized$\n    })\n      .pipe(\n        catchError(() => {\n          observer.next(false)\n          return EMPTY\n        }),\n        repeat({ delay: 1 }),\n      )\n      .subscribe({\n        next() {\n          observer.next(true)\n        },\n        error: observer.error,\n        complete: observer.complete,\n      })\n\n    return () => {\n      finalizedSubscription.unsubscribe()\n      unfollow()\n      client.destroy()\n    }\n  }).subscribe()\n  followedChains.set(genesisHash, () => {\n    followedChains.delete(genesisHash)\n    subscription.unsubscribe()\n  })\n}\n\nconst unfollowChain = (genesisHash: string) => {\n  followedChains.get(genesisHash)?.()\n}\n\ntype CreateSmoldotProviderOptions = {\n  smoldotClient: Client\n  chainSpec: string\n  genesisHash: string\n  relayChainGenesisHash?: string\n}\nconst createSmoldotProvider = async ({\n  smoldotClient,\n  chainSpec,\n  genesisHash,\n  relayChainGenesisHash,\n}: CreateSmoldotProviderOptions) =>\n  smoldotProvider({\n    smoldotClient,\n    chainSpec,\n    relayChainSpec: relayChainGenesisHash\n      ? (await storage.getChains())[relayChainGenesisHash].chainSpec\n      : undefined,\n    databaseContent: await storage.get({\n      type: \"databaseContent\",\n      genesisHash,\n    }),\n    relayChainDatabaseContent: relayChainGenesisHash\n      ? await storage.get({\n          type: \"databaseContent\",\n          genesisHash: relayChainGenesisHash,\n        })\n      : undefined,\n  })\n\nconst createSmoldotSyncProvider = (options: CreateSmoldotProviderOptions) =>\n  getSyncProvider(() => createSmoldotProvider(options))\n","import type * as smoldot from \"../smoldot\"\n\nimport type { JsonRpcConnection } from \"@polkadot-api/json-rpc-provider\"\nimport { getSyncProvider } from \"@polkadot-api/json-rpc-provider-proxy\"\n\nexport type Client = Pick<smoldot.Client, \"addChain\">\nexport type AddChainOptions = smoldot.AddChainOptions\n\n/**\n * Adds a chain to check if the add chain options are valid and then\n * subsequently removes it, so that it is not included in smoldot's internal\n * reference count.\n *\n */\nconst validateAddChainOptions = async (\n  client: Client,\n  options: AddChainOptions,\n) => {\n  const chain = await client.addChain(options)\n  try {\n    chain.remove()\n  } catch {}\n}\n\n/**\n * Creates a new JSON RPC provider using a client and options.\n *\n * This provider will automatically re-connect to the chain if the\n * connection is lost.\n *\n * @param client - The client to use for creating the provider.\n * @param options - The options for adding a chain.\n */\nexport const make = async (client: Client, options: AddChainOptions) => {\n  // The chain that is added in this function is removed only to be added\n  // again when the provider is created. This doesn't matter from a performance\n  // perspective, and is done to keep things simple rather than keep a separate\n  // variable to track whether it is the first time the chain is being added.\n  await validateAddChainOptions(client, options)\n\n  const provider = getSyncProvider(async () => {\n    const chain = await client.addChain(options)\n\n    return (onMessage, onError) => {\n      let connected = true\n      ;(async () => {\n        while (connected) {\n          try {\n            const message = await chain.nextJsonRpcResponse()\n            onMessage(message)\n          } catch {\n            connected = false\n            try {\n              onError()\n            } catch {}\n            break\n          }\n        }\n      })()\n\n      const send: JsonRpcConnection[\"send\"] = (message) => {\n        try {\n          chain.sendJsonRpc(message)\n        } catch {}\n      }\n\n      const disconnect: JsonRpcConnection[\"disconnect\"] = () => {\n        connected = false\n        try {\n          chain.remove()\n        } catch {}\n      }\n\n      return {\n        send,\n        disconnect,\n      }\n    }\n  })\n\n  return provider\n}\n","import type { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nimport type { Client, AddChainOptions } from \"../smoldot\"\nimport { make as makeJsonRpcProvider } from \"./json-rpc-provider\"\n\ntype SmoldotProviderOptions =\n  | { smoldotClient: Client; addChainOptions: AddChainOptions }\n  | {\n      smoldotClient: Client\n      chainSpec: string\n      relayChainSpec?: string\n      databaseContent?: string\n      relayChainDatabaseContent?: string\n    }\n\nexport const smoldotProvider = async ({\n  smoldotClient,\n  ...options\n}: SmoldotProviderOptions): Promise<JsonRpcProvider> => {\n  const provider = await makeJsonRpcProvider(\n    smoldotClient,\n    \"addChainOptions\" in options\n      ? options.addChainOptions\n      : {\n          chainSpec: options.chainSpec,\n          disableJsonRpc: false,\n          potentialRelayChains: options.relayChainSpec\n            ? [\n                {\n                  chainSpec: options.relayChainSpec,\n                  disableJsonRpc: true,\n                  databaseContent: options.relayChainDatabaseContent,\n                },\n              ]\n            : [],\n          databaseContent: options.databaseContent,\n        },\n  )\n\n  return provider\n}\n","import { ContentScriptRpcSpec } from \"@/content-script/types\"\nimport type {\n  AddOnAddChainByUserListener,\n  BackgroundRpcSpec as BackgroundRpcSpec,\n  LightClientPageHelper,\n} from \"./types\"\nimport { PORT } from \"@/shared\"\nimport {\n  createRpc,\n  RpcError,\n  type RpcMethodHandlers,\n  type RpcMessage,\n  type RpcMethodMiddleware,\n} from \"@/utils\"\nimport * as storage from \"@/storage\"\nimport { WebPageRpcSpec } from \"@/web-page/types\"\n\ntype Context = {\n  port: chrome.runtime.Port\n  addChainByUserListener?: Parameters<AddOnAddChainByUserListener>[0]\n  lightClientPageHelper: LightClientPageHelper\n  getChainData: (opts: {\n    chainSpec: string\n    relayChainGenesisHash?: string\n  }) => Promise<{ genesisHash: string; name: string }>\n}\n\nconst handlers: RpcMethodHandlers<BackgroundRpcSpec, Context> = {\n  //#region content-script RPCs\n  keepAlive() {},\n  async getChain([chainSpec, relayChainGenesisHash], ctx) {\n    if (!ctx) throw new Error(\"no context\")\n\n    const tabId = ctx.port.sender?.tab?.id\n    if (!tabId) throw new Error(\"Undefined tabId\")\n\n    const chains = await storage.getChains()\n\n    if (relayChainGenesisHash && !chains[relayChainGenesisHash])\n      throw new Error(`Unknown relayChainGenesisHash ${relayChainGenesisHash}`)\n    const { genesisHash, name } = await ctx.getChainData({\n      chainSpec,\n      relayChainGenesisHash,\n    })\n\n    if (chains[genesisHash]) return chains[genesisHash]\n\n    const chain = {\n      genesisHash,\n      name,\n      chainSpec,\n      relayChainGenesisHash,\n    }\n\n    await ctx.addChainByUserListener?.(chain, tabId)\n\n    return chain\n  },\n  getChains() {\n    return storage.getChains()\n  },\n  //#endregion\n  //#region ExtensionPage RPCs\n  deleteChain([genesisHash], ctx) {\n    if (!ctx) throw new Error(\"no context\")\n    return ctx.lightClientPageHelper.deleteChain(genesisHash)\n  },\n  persistChain([chainSpec, relayChainGenesisHash], ctx) {\n    if (!ctx) throw new Error(\"no context\")\n    return ctx.lightClientPageHelper.persistChain(\n      chainSpec,\n      relayChainGenesisHash,\n    )\n  },\n  async getActiveConnections([], ctx) {\n    if (!ctx) throw new Error(\"no context\")\n    return (await ctx.lightClientPageHelper.getActiveConnections()).map(\n      ({ tabId, chain: { provider, ...chain } }) => ({\n        tabId,\n        chain,\n      }),\n    )\n  },\n  disconnect([tabId, genesisHash], ctx) {\n    if (!ctx) throw new Error(\"no context\")\n    return ctx.lightClientPageHelper.disconnect(tabId, genesisHash)\n  },\n  setBootNodes([genesisHash, bootNodes], ctx) {\n    if (!ctx) throw new Error(\"no context\")\n    return ctx.lightClientPageHelper.setBootNodes(genesisHash, bootNodes)\n  },\n  //#endregion\n}\n\ntype Method = keyof typeof handlers\nconst ALLOWED_WEB_METHODS: Method[] = [\"getChain\", \"getChains\"]\nconst ALLOWED_CONTENT_SCRIPT_METHODS: Method[] = [\n  \"getChain\",\n  \"getChains\",\n  \"keepAlive\",\n]\nconst allowedMethodsMiddleware: RpcMethodMiddleware<Context> = async (\n  next,\n  request,\n  context,\n) => {\n  if (!context) throw new Error(\"no ctx\")\n  const { port } = context\n\n  if (\n    !(\n      port.name === PORT.EXTENSION_PAGE ||\n      (port.name === PORT.CONTENT_SCRIPT &&\n        ALLOWED_CONTENT_SCRIPT_METHODS.includes(request.method as Method)) ||\n      (port.name === PORT.WEB_PAGE &&\n        ALLOWED_WEB_METHODS.includes(request.method as Method))\n    )\n  )\n    throw new RpcError(\"Method not found\", -32601)\n  return next(request, context)\n}\n\nexport const createBackgroundRpc = (\n  sendMessage: (message: RpcMessage) => void,\n) =>\n  createRpc(sendMessage, handlers, [allowedMethodsMiddleware]).withClient<\n    WebPageRpcSpec & ContentScriptRpcSpec\n  >()\n"],"mappings":"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","names":["getSyncProvider","chain","getSyncProvider"]}

Выполнить команду


Для локальной разработки. Не используйте в интернете!