UNPKG

@pinax/graph-networks-registry

Version:

TypeScript types and helpers for The Graph Networks Registry

654 lines (649 loc) 22.6 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { APIURLKind: () => APIURLKind, BytesEncoding: () => BytesEncoding, Convert: () => Convert, Feature: () => Feature, NetworkType: () => NetworkType, NetworksRegistry: () => NetworksRegistry, Protocol: () => Protocol, RelationKind: () => RelationKind }); module.exports = __toCommonJS(index_exports); // src/types.ts var APIURLKind = /* @__PURE__ */ ((APIURLKind2) => { APIURLKind2["Blockscout"] = "blockscout"; APIURLKind2["Etherscan"] = "etherscan"; APIURLKind2["Ethplorer"] = "ethplorer"; APIURLKind2["Other"] = "other"; APIURLKind2["Subscan"] = "subscan"; return APIURLKind2; })(APIURLKind || {}); var BytesEncoding = /* @__PURE__ */ ((BytesEncoding2) => { BytesEncoding2["Base58"] = "base58"; BytesEncoding2["Base64"] = "base64"; BytesEncoding2["Hex"] = "hex"; BytesEncoding2["Other"] = "other"; BytesEncoding2["The0Xhex"] = "0xhex"; return BytesEncoding2; })(BytesEncoding || {}); var Protocol = /* @__PURE__ */ ((Protocol2) => { Protocol2["Arweave"] = "arweave"; Protocol2["Cosmos"] = "cosmos"; Protocol2["Ethereum"] = "ethereum"; Protocol2["Near"] = "near"; Protocol2["Other"] = "other"; Protocol2["Starknet"] = "starknet"; return Protocol2; })(Protocol || {}); var NetworkType = /* @__PURE__ */ ((NetworkType2) => { NetworkType2["Beacon"] = "beacon"; NetworkType2["Devnet"] = "devnet"; NetworkType2["Mainnet"] = "mainnet"; NetworkType2["Testnet"] = "testnet"; return NetworkType2; })(NetworkType || {}); var RelationKind = /* @__PURE__ */ ((RelationKind2) => { RelationKind2["BeaconOf"] = "beaconOf"; RelationKind2["EvmOf"] = "evmOf"; RelationKind2["ForkedFrom"] = "forkedFrom"; RelationKind2["L2Of"] = "l2Of"; RelationKind2["Other"] = "other"; RelationKind2["ShardOf"] = "shardOf"; RelationKind2["SvmOf"] = "svmOf"; RelationKind2["TestnetOf"] = "testnetOf"; return RelationKind2; })(RelationKind || {}); var Feature = /* @__PURE__ */ ((Feature2) => { Feature2["Dexes"] = "dexes"; Feature2["Nfts"] = "nfts"; Feature2["Other"] = "other"; Feature2["Tokens"] = "tokens"; return Feature2; })(Feature || {}); var Convert = class { static toNetworksRegistryInner(json) { return cast(JSON.parse(json), r("NetworksRegistryInner")); } static networksRegistryInnerToJson(value) { return JSON.stringify(uncast(value, r("NetworksRegistryInner")), null, 2); } }; function invalidValue(typ, val, key, parent = "") { const prettyTyp = prettyTypeName(typ); const parentText = parent ? ` on ${parent}` : ""; const keyText = key ? ` for key "${key}"` : ""; throw Error(`Invalid value${keyText}${parentText}. Expected ${prettyTyp} but got ${JSON.stringify(val)}`); } function prettyTypeName(typ) { if (Array.isArray(typ)) { if (typ.length === 2 && typ[0] === void 0) { return `an optional ${prettyTypeName(typ[1])}`; } else { return `one of [${typ.map((a2) => { return prettyTypeName(a2); }).join(", ")}]`; } } else if (typeof typ === "object" && typ.literal !== void 0) { return typ.literal; } else { return typeof typ; } } function jsonToJSProps(typ) { if (typ.jsonToJS === void 0) { const map = {}; typ.props.forEach((p) => map[p.json] = { key: p.js, typ: p.typ }); typ.jsonToJS = map; } return typ.jsonToJS; } function jsToJSONProps(typ) { if (typ.jsToJSON === void 0) { const map = {}; typ.props.forEach((p) => map[p.js] = { key: p.json, typ: p.typ }); typ.jsToJSON = map; } return typ.jsToJSON; } function transform(val, typ, getProps, key = "", parent = "") { function transformPrimitive(typ2, val2) { if (typeof typ2 === typeof val2) return val2; return invalidValue(typ2, val2, key, parent); } function transformUnion(typs, val2) { const l2 = typs.length; for (let i = 0; i < l2; i++) { const typ2 = typs[i]; try { return transform(val2, typ2, getProps); } catch (_) { } } return invalidValue(typs, val2, key, parent); } function transformEnum(cases, val2) { if (cases.indexOf(val2) !== -1) return val2; return invalidValue(cases.map((a2) => { return l(a2); }), val2, key, parent); } function transformArray(typ2, val2) { if (!Array.isArray(val2)) return invalidValue(l("array"), val2, key, parent); return val2.map((el) => transform(el, typ2, getProps)); } function transformDate(val2) { if (val2 === null) { return null; } const d = new Date(val2); if (isNaN(d.valueOf())) { return invalidValue(l("Date"), val2, key, parent); } return d; } function transformObject(props, additional, val2) { if (val2 === null || typeof val2 !== "object" || Array.isArray(val2)) { return invalidValue(l(ref || "object"), val2, key, parent); } const result = {}; Object.getOwnPropertyNames(props).forEach((key2) => { const prop = props[key2]; const v = Object.prototype.hasOwnProperty.call(val2, key2) ? val2[key2] : void 0; result[prop.key] = transform(v, prop.typ, getProps, key2, ref); }); Object.getOwnPropertyNames(val2).forEach((key2) => { if (!Object.prototype.hasOwnProperty.call(props, key2)) { result[key2] = transform(val2[key2], additional, getProps, key2, ref); } }); return result; } if (typ === "any") return val; if (typ === null) { if (val === null) return val; return invalidValue(typ, val, key, parent); } if (typ === false) return invalidValue(typ, val, key, parent); let ref = void 0; while (typeof typ === "object" && typ.ref !== void 0) { ref = typ.ref; typ = typeMap[typ.ref]; } if (Array.isArray(typ)) return transformEnum(typ, val); if (typeof typ === "object") { return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) : invalidValue(typ, val, key, parent); } if (typ === Date && typeof val !== "number") return transformDate(val); return transformPrimitive(typ, val); } function cast(val, typ) { return transform(val, typ, jsonToJSProps); } function uncast(val, typ) { return transform(val, typ, jsToJSONProps); } function l(typ) { return { literal: typ }; } function a(typ) { return { arrayItems: typ }; } function u(...typs) { return { unionMembers: typs }; } function o(props, additional) { return { props, additional }; } function r(name) { return { ref: name }; } var typeMap = { "NetworksRegistryInner": o([ { json: "$schema", js: "$schema", typ: "" }, { json: "description", js: "description", typ: "" }, { json: "networks", js: "networks", typ: a(r("Network")) }, { json: "title", js: "title", typ: "" }, { json: "updatedAt", js: "updatedAt", typ: Date }, { json: "version", js: "version", typ: "" } ], false), "Network": o([ { json: "aliases", js: "aliases", typ: u(void 0, a("")) }, { json: "apiUrls", js: "apiUrls", typ: u(void 0, a(r("APIURL"))) }, { json: "caip2Id", js: "caip2Id", typ: "" }, { json: "docsUrl", js: "docsUrl", typ: u(void 0, "") }, { json: "explorerUrls", js: "explorerUrls", typ: u(void 0, a("")) }, { json: "firehose", js: "firehose", typ: u(void 0, r("Firehose")) }, { json: "fullName", js: "fullName", typ: "" }, { json: "graphNode", js: "graphNode", typ: u(void 0, r("GraphNode")) }, { json: "icon", js: "icon", typ: u(void 0, r("Icon")) }, { json: "id", js: "id", typ: "" }, { json: "indexerDocsUrls", js: "indexerDocsUrls", typ: u(void 0, a(r("IndexerDocsURL"))) }, { json: "issuanceRewards", js: "issuanceRewards", typ: true }, { json: "nativeToken", js: "nativeToken", typ: u(void 0, "") }, { json: "networkType", js: "networkType", typ: r("NetworkType") }, { json: "relations", js: "relations", typ: u(void 0, a(r("Relation"))) }, { json: "rpcUrls", js: "rpcUrls", typ: u(void 0, a("")) }, { json: "secondName", js: "secondName", typ: u(void 0, "") }, { json: "services", js: "services", typ: r("Services") }, { json: "shortName", js: "shortName", typ: "" }, { json: "tokenApi", js: "tokenApi", typ: u(void 0, r("TokenAPI")) } ], false), "APIURL": o([ { json: "kind", js: "kind", typ: r("APIURLKind") }, { json: "url", js: "url", typ: "" } ], false), "Firehose": o([ { json: "blockFeatures", js: "blockFeatures", typ: u(void 0, a("")) }, { json: "blockType", js: "blockType", typ: "" }, { json: "bufUrl", js: "bufUrl", typ: "" }, { json: "bytesEncoding", js: "bytesEncoding", typ: r("BytesEncoding") }, { json: "deprecatedAt", js: "deprecatedAt", typ: u(void 0, Date) }, { json: "evmExtendedModel", js: "evmExtendedModel", typ: u(void 0, true) }, { json: "firstStreamableBlock", js: "firstStreamableBlock", typ: u(void 0, r("FirstStreamableBlock")) } ], false), "FirstStreamableBlock": o([ { json: "height", js: "height", typ: 0 }, { json: "id", js: "id", typ: "" } ], false), "GraphNode": o([ { json: "deprecatedAt", js: "deprecatedAt", typ: u(void 0, Date) }, { json: "protocol", js: "protocol", typ: u(void 0, r("Protocol")) } ], false), "Icon": o([ { json: "web3Icons", js: "web3Icons", typ: u(void 0, r("Web3Icons")) } ], false), "Web3Icons": o([ { json: "name", js: "name", typ: "" }, { json: "variants", js: "variants", typ: u(void 0, a("")) } ], false), "IndexerDocsURL": o([ { json: "description", js: "description", typ: u(void 0, "") }, { json: "url", js: "url", typ: "" } ], false), "Relation": o([ { json: "kind", js: "kind", typ: r("RelationKind") }, { json: "network", js: "network", typ: "" } ], false), "Services": o([ { json: "firehose", js: "firehose", typ: u(void 0, a("")) }, { json: "sps", js: "sps", typ: u(void 0, a("")) }, { json: "subgraphs", js: "subgraphs", typ: u(void 0, a("")) }, { json: "substreams", js: "substreams", typ: u(void 0, a("")) }, { json: "tokenApi", js: "tokenApi", typ: u(void 0, a("")) } ], false), "TokenAPI": o([ { json: "deprecatedAt", js: "deprecatedAt", typ: u(void 0, Date) }, { json: "features", js: "features", typ: u(void 0, a(r("Feature"))) }, { json: "networkId", js: "networkId", typ: u(void 0, "") } ], false), "APIURLKind": [ "blockscout", "etherscan", "ethplorer", "other", "subscan" ], "BytesEncoding": [ "base58", "base64", "hex", "other", "0xhex" ], "Protocol": [ "arweave", "cosmos", "ethereum", "near", "other", "starknet" ], "NetworkType": [ "beacon", "devnet", "mainnet", "testnet" ], "RelationKind": [ "beaconOf", "evmOf", "forkedFrom", "l2Of", "other", "shardOf", "svmOf", "testnetOf" ], "Feature": [ "dexes", "nfts", "other", "tokens" ] }; // src/env.ts function applyEnvVars(url) { const envVars = url.match(/\{([^}]+)\}/g); if (!envVars) return url; for (const envVar of envVars) { const value = process?.env?.[envVar.slice(1, -1)]; if (!value) { return ""; } url = url.replace(envVar, value); } return url; } // src/version.ts var schemaVersion = "0.7"; // src/client.ts var REGISTRY_BASE_URL = "https://networks-registry.thegraph.com"; var FALLBACK_BASE_URL = "https://raw.githubusercontent.com/graphprotocol/networks-registry/refs/heads/main/public"; var readFileSync; try { const fs = require("fs"); readFileSync = fs.readFileSync; } catch { } var NetworksRegistry = class _NetworksRegistry { /** * Creates a new NetworksRegistry instance. * @param registry - The parsed NetworksRegistry data */ constructor(registry) { this.registry = registry; } /** * Gets all networks in the registry. * @returns Array of all network elements */ get networks() { return this.registry.networks; } /** * Gets the version of the loaded registry. * @returns Version string */ get version() { return this.registry.version; } /** * Gets the date of the last update of the registry. * @returns Date object */ get updatedAt() { return new Date(this.registry.updatedAt); } /** * Attempts to fetch the registry from a given URL, returns null if fetch fails * @internal */ static async tryFetchRegistry(url) { try { return await _NetworksRegistry.fromUrl(url); } catch { return null; } } /** * Fetches and loads the latest version of the networks registry. First tries to fetch from * the primary registry URL at networks-registry.thegraph.com, then falls back to the fallback URL at GitHub * Uses the library version to determine the latest compatible registry URL. * Library version 0.5.x will use the latest registry version 0.5.y even if 0.6.z is available * * @returns Promise that resolves to a new NetworksRegistry instance * @throws Error if the registry fetch fails * * @example * ```typescript * const registry = await NetworksRegistry.fromLatestVersion(); * ``` */ static async fromLatestVersion() { const primaryUrl = _NetworksRegistry.getLatestVersionUrl(); const primaryRegistry = await _NetworksRegistry.tryFetchRegistry(primaryUrl); if (primaryRegistry) return primaryRegistry; const fallbackUrl = _NetworksRegistry.getLatestVersionFallbackUrl(); const fallbackRegistry = await _NetworksRegistry.tryFetchRegistry(fallbackUrl); if (fallbackRegistry) return fallbackRegistry; throw new Error(`Failed to fetch registry from ${primaryUrl}`); } /** * Fetches and loads a specific version of the networks registry. First tries to fetch from * the primary registry URL at networks-registry.thegraph.com, then falls back to the fallback URL at GitHub * * @param version - The exact version to fetch (e.g. "0.5.0") * @returns Promise that resolves to a new NetworksRegistry instance * @throws Error if the registry fetch fails * * @example * ```typescript * const registry = await NetworksRegistry.fromExactVersion("0.5.0"); * ``` */ static async fromExactVersion(version) { const primaryUrl = _NetworksRegistry.getExactVersionUrl(version); const primaryRegistry = await _NetworksRegistry.tryFetchRegistry(primaryUrl); if (primaryRegistry) return primaryRegistry; const fallbackUrl = _NetworksRegistry.getExactVersionFallbackUrl(version); const fallbackRegistry = await _NetworksRegistry.tryFetchRegistry(fallbackUrl); if (fallbackRegistry) return fallbackRegistry; throw new Error(`Failed to fetch registry from ${primaryUrl}`); } /** * Loads the networks registry from a URL. * * @param url - The URL to fetch the registry from * @returns Promise that resolves to a new NetworksRegistry instance * @throws Error if the fetch fails or the response is invalid */ static async fromUrl(url) { const response = await fetch(url); if (!response.ok) { throw new Error(`Failed to fetch registry: ${response.statusText}`); } const json = await response.text(); return _NetworksRegistry.fromJson(json); } /** * Creates a new registry instance from a JSON string. * * @param json - The JSON string containing registry data * @returns A new NetworksRegistry instance * @throws Error if the JSON is invalid */ static fromJson(json) { const parsedData = JSON.parse(json); const networksRegistry = parsedData; return new _NetworksRegistry(networksRegistry); } /** * Loads the networks registry from a local JSON file. * * @param path - Path to the JSON file * @returns A new NetworksRegistry instance * @throws Error if the file cannot be read or contains invalid data */ static fromFile(path) { if (!readFileSync) { throw new Error("File system operations are not supported in this environment"); } const contents = readFileSync(path, "utf-8"); return _NetworksRegistry.fromJson(contents); } /** * Gets the URL for the latest compatible version of the registry. * Uses the major and minor version from package.json. * * @returns The URL string for the latest version */ static getLatestVersionUrl() { const [major, minor] = schemaVersion.split("."); return `${REGISTRY_BASE_URL}/TheGraphNetworksRegistry_v${major}_${minor}_x.json`; } /** * Gets the URL for the latest compatible version of the registry at GitHub. * Uses the major and minor version from package.json. * * @returns The URL string for the latest version */ static getLatestVersionFallbackUrl() { const [major, minor] = schemaVersion.split("."); return `${FALLBACK_BASE_URL}/TheGraphNetworksRegistry_v${major}_${minor}_x.json`; } /** * Gets the URL for a specific version of the registry. * * @param version - The exact version (e.g. "0.5.0") * @returns The URL string for the specified version */ static getExactVersionUrl(version) { return `${REGISTRY_BASE_URL}/TheGraphNetworksRegistry_v${version.replace(/\./g, "_")}.json`; } /** * Gets the URL for a specific version of the registry at GitHub. * * @param version - The exact version (e.g. "0.5.0") * @returns The URL string for the specified version */ static getExactVersionFallbackUrl(version) { return `${FALLBACK_BASE_URL}/TheGraphNetworksRegistry_v${version.replace(/\./g, "_")}.json`; } /** * Finds a network by its unique identifier. * * @param id - The network ID (e.g. "mainnet", "optimism") * @returns The network if found, undefined otherwise * @deprecated Use getNetworkByGraphId instead * * @example * ```typescript * const mainnet = registry.getNetworkById("mainnet"); * ``` */ getNetworkById(id) { return this.registry.networks.find((network) => network.id === id); } /** * Finds a network by its ID or one of its aliases. * * @param alias - The network ID or alias (e.g. "eth" for Ethereum mainnet) * @returns The network if found, undefined otherwise * @deprecated Use getNetworkByGraphId instead * * @example * ```typescript * const ethereum = registry.getNetworkByAlias("eth"); * ``` */ getNetworkByAlias(alias) { return this.registry.networks.find((network) => network.id === alias || network.aliases?.includes(alias)); } /** * Finds a network by its graph ID (either its ID field or one of its aliases). * * @param id - The graph ID, which could be either the network's ID or one of its aliases * @returns The network if found, undefined otherwise * * @example * ```typescript * const mainnet = registry.getNetworkByGraphId("mainnet"); * const ethereum = registry.getNetworkByGraphId("eth"); * ``` */ getNetworkByGraphId(id) { return this.registry.networks.find((network) => network.id === id || network.aliases?.includes(id)); } /** * Finds a network by its CAIP-2 chain ID. * * @param chainId - The CAIP-2 chain ID in the format "[namespace]:[reference]" (e.g., "eip155:1") * @returns The network if found, undefined otherwise * * @example * ```typescript * const ethereum = registry.getNetworkByCaip2Id("eip155:1"); * ``` */ getNetworkByCaip2Id(chainId) { if (!chainId.includes(":")) { console.warn("Warning: CAIP-2 Chain ID should be in the format '[namespace]:[reference]', e.g., 'eip155:1'"); return void 0; } return this.registry.networks.find((network) => network.caip2Id === chainId); } /** * Gets API URLs for a network, filtered by kind and with environment variables applied. * Environment variable placeholders in the format {VARIABLE_NAME} will be replaced with * actual environment variable values. URLs that reference non-existent environment * variables will be omitted from the result. * * @param networkId - The network ID or alias * @param kinds - Optional array of API URL kinds to filter by. If not provided or empty, returns all kinds * @returns Array of API URLs with environment variables applied * * @example * ```typescript * // Get all Etherscan API URLs * const etherscanUrls = registry.getApiUrls("mainnet", [APIURLKind.Etherscan]); * * // Get all API URLs for the network * const allUrls = registry.getApiUrls("mainnet"); * ``` */ getApiUrls(networkId, kinds = []) { const apis = this.getNetworkById(networkId)?.apiUrls ?? this.getNetworkByAlias(networkId)?.apiUrls ?? []; return apis.filter(({ kind }) => kinds.length === 0 || kinds.includes(kind)).map(({ url }) => applyEnvVars(url)).filter(Boolean); } /** * Gets RPC URLs for a network with environment variables applied. * Environment variable placeholders in the format {VARIABLE_NAME} will be replaced with * actual environment variable values. URLs that reference non-existent environment * variables will be omitted from the result. * * @param networkId - The network ID or alias * @returns Array of RPC URLs with environment variables applied * * @example * ```typescript * // Get all RPC URLs for ethereum mainnet * const rpcUrls = registry.getRpcUrls("mainnet"); * ``` */ getRpcUrls(networkId) { const urls = this.getNetworkById(networkId)?.rpcUrls ?? this.getNetworkByAlias(networkId)?.rpcUrls ?? []; return urls.map((url) => applyEnvVars(url)).filter(Boolean); } }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { APIURLKind, BytesEncoding, Convert, Feature, NetworkType, NetworksRegistry, Protocol, RelationKind }); //# sourceMappingURL=index.js.map