UNPKG

@substrate/api-sidecar

Version:

REST service that makes it easy to interact with blockchain nodes built using Substrate's FRAME framework.

133 lines 5.86 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ApiPromiseRegistry = void 0; /* eslint-disable @typescript-eslint/no-var-requires */ const api_1 = require("@polkadot/api"); const rpc_provider_1 = require("@polkadot/rpc-provider"); const Log_1 = require("../logging/Log"); const typesBundle_1 = __importDefault(require("../override-types/typesBundle")); const SidecarConfig_1 = require("../SidecarConfig"); const MultiKeyBiMap_1 = require("../util/MultiKeyBiMap"); class ApiPromiseRegistry { static setAssetHubInfo(info) { this.assetHubInfo.isAssetHub = info.isAssetHub; this.assetHubInfo.isAssetHubMigrated = info.isAssetHubMigrated; } /** * Get the ApiPromise instance for the given spec name. * @param specName The spec name to get the ApiPromise instance for. * @returns The ApiPromise instance for the given spec name. */ static async initApi(url, type) { const { logger } = Log_1.Log; logger.info(`Initializing API for ${url}`); // TODO: for now use instance by URL as a staging check to make sure we don't need to recreate an API instance if (!this._instancesByUrl.has(url)) { const { config } = SidecarConfig_1.SidecarConfig; const { TYPES_BUNDLE, TYPES_SPEC, TYPES_CHAIN, TYPES, CACHE_CAPACITY } = config.SUBSTRATE; // Instantiate new API Promise instance const api = await api_1.ApiPromise.create({ provider: url.startsWith('http') ? new rpc_provider_1.HttpProvider(url, undefined, CACHE_CAPACITY || 0) : new rpc_provider_1.WsProvider(url, undefined, undefined, undefined, CACHE_CAPACITY || 0), // only use extra types if the url is the same as the one in the config ...(config.SUBSTRATE.URL === url ? { typesBundle: TYPES_BUNDLE ? require(TYPES_BUNDLE) : typesBundle_1.default, typesChain: TYPES_CHAIN ? require(TYPES_CHAIN) : undefined, typesSpec: TYPES_SPEC ? require(TYPES_SPEC) : undefined, types: TYPES ? require(TYPES) : undefined, } : {}), }); const { specName } = await api.rpc.state.getRuntimeVersion(); if (!this.specNameToTypeMap.getByKey(specName.toString())) { if (type) { this.specNameToTypeMap.set(specName.toString(), type); } } // TODO: use a generic store for APis and use a unique Id to reference URLs and specNames if (this._instancesBySpecName.has(specName.toString())) { const existingInstances = this._instancesBySpecName.get(specName.toString()); this._instancesBySpecName.set(specName.toString(), [...existingInstances, api]); } else { this._instancesBySpecName.set(specName.toString(), [api]); } this._instancesByUrl.set(url, api); logger.info(`API initialized for ${url} with specName ${specName.toString()}`); } else { const api = this._instancesByUrl.get(url); // make sure we have stored the type for the SUBSTRATE_URL option if (api && type) { const { specName } = await api.rpc.state.getRuntimeVersion(); if (!this.specNameToTypeMap.getByKey(specName.toString())) { if (type) { this.specNameToTypeMap.set(specName.toString(), type); } } } } return this._instancesByUrl.get(url); } static getApi(specName) { const api = this._instancesBySpecName.get(specName); if (!api) { throw new Error(`API not found for specName: ${specName}`); } // TODO: create logic to return the correct API instance based on workload/necessity return api[0]; } static getApiByUrl(url) { return this._instancesByUrl.get(url); } static getTypeBySpecName(specName) { return this.specNameToTypeMap.getByKey(specName); } static getSpecNameByType(type) { return this.specNameToTypeMap.getByValue(type); } static getApiByType(type) { const specNames = this.specNameToTypeMap.getByValue(type); if (!specNames) { return []; } const specNameApis = []; for (const specName of specNames) { const api = this.getApi(specName); if (api) { specNameApis.push({ specName, api }); } } return specNameApis; } static getAllAvailableSpecNames() { return Array.from(this._instancesBySpecName.keys()); } static clear() { this._instancesBySpecName.clear(); this._instancesByUrl.clear(); this.specNameToTypeMap = new MultiKeyBiMap_1.MultiKeyBiMap(); const { logger } = Log_1.Log; logger.info('Cleared API registry'); } } exports.ApiPromiseRegistry = ApiPromiseRegistry; // SpecName to ApiPromise instances ApiPromiseRegistry._instancesBySpecName = new Map(); // SpecName to Type map ApiPromiseRegistry.specNameToTypeMap = new MultiKeyBiMap_1.MultiKeyBiMap(); // RPC URL to ApiPromise instance ApiPromiseRegistry._instancesByUrl = new Map(); // Asset hub info, will default to static unless its connected. ApiPromiseRegistry.assetHubInfo = { isAssetHub: false, isAssetHubMigrated: false, }; //# sourceMappingURL=index.js.map