diff --git a/src/config.ts b/src/config.ts index 81c894a..6b7f67b 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,36 +1,35 @@ // @ts-ignore import BConfig from "bcfg"; -import {errorExit} from "./util.js"; +import { errorExit } from "./util.js"; const config = new BConfig("lumeweb-relay"); config.inject({ - relayPort: 8080, + relayPort: 8080, }); config.load({ - env: true, - argv: true, + env: true, + argv: true, }); try { - config.open("config.conf"); -} catch (e) { -} + config.open("config.conf"); +} catch (e) {} for (const setting of ["relay-domain", "afraid-username", "relay-seed"]) { - if (!config.get(setting)) { - errorExit(`Required config option ${setting} not set`); - } + if (!config.get(setting)) { + errorExit(`Required config option ${setting} not set`); + } } let usingPocketGateway = true; export function usePocketGateway() { - return usingPocketGateway; + return usingPocketGateway; } export function updateUsePocketGateway(state: boolean): void { - usingPocketGateway = state; + usingPocketGateway = state; } export default config; diff --git a/src/dht.ts b/src/dht.ts index 216b811..742d70a 100644 --- a/src/dht.ts +++ b/src/dht.ts @@ -1,57 +1,57 @@ -import {createRequire} from "module"; +import { createRequire } from "module"; const require = createRequire(import.meta.url); const DHT = require("@hyperswarm/dht"); -import {errorExit} from "./util.js"; +import { errorExit } from "./util.js"; import { - deriveMyskyRootKeypair, - ed25519Keypair, - seedPhraseToSeed, - validSeedPhrase, + deriveMyskyRootKeypair, + ed25519Keypair, + seedPhraseToSeed, + validSeedPhrase, } from "libskynet"; import config from "./config.js"; let node: { - ready: () => any; - createServer: () => any; - defaultKeyPair: any; - on: any; + ready: () => any; + createServer: () => any; + defaultKeyPair: any; + on: any; }; let server: { - listen: (arg0: ed25519Keypair) => any; - on: any; + listen: (arg0: ed25519Keypair) => any; + on: any; }; async function start() { - const seed = config.str("relay-seed"); + const seed = config.str("relay-seed"); - let [, err] = validSeedPhrase(seed); - if (err !== null) { - errorExit("RELAY_SEED is invalid. Aborting."); - } + let [, err] = validSeedPhrase(seed); + if (err !== null) { + errorExit("RELAY_SEED is invalid. Aborting."); + } - const keyPair = deriveMyskyRootKeypair(seedPhraseToSeed(seed)[0]); + const keyPair = deriveMyskyRootKeypair(seedPhraseToSeed(seed)[0]); - node = new DHT({keyPair}); + node = new DHT({ keyPair }); - await node.ready(); + await node.ready(); - server = node.createServer(); - await server.listen(keyPair); + server = node.createServer(); + await server.listen(keyPair); - return node; + return node; } export async function get( - ret: "server" | "dht" = "dht" + ret: "server" | "dht" = "dht" ): Promise { - if (!node) { - await start(); - } + if (!node) { + await start(); + } - if (ret == "server") { - return server; - } + if (ret == "server") { + return server; + } - return node; + return node; } diff --git a/src/dns.ts b/src/dns.ts index bac13c0..90ae3d4 100644 --- a/src/dns.ts +++ b/src/dns.ts @@ -1,96 +1,96 @@ import cron from "node-cron"; import fetch from "node-fetch"; -import {get as getDHT} from "./dht.js"; -import {overwriteRegistryEntry} from "libskynetnode"; -import {Buffer} from "buffer"; -import {Parser} from "xml2js"; -import {URL} from "url"; -import {errorExit, hashDataKey} from "./util.js"; -import {pack} from "msgpackr"; +import { get as getDHT } from "./dht.js"; +import { overwriteRegistryEntry } from "libskynetnode"; +import { Buffer } from "buffer"; +import { Parser } from "xml2js"; +import { URL } from "url"; +import { errorExit, hashDataKey } from "./util.js"; +import { pack } from "msgpackr"; import config from "./config.js"; -const {createHash} = await import("crypto"); +const { createHash } = await import("crypto"); let activeIp: string; const REGISTRY_NODE_KEY = "lumeweb-dht-node"; async function ipUpdate() { - let currentIp = await getCurrentIp(); + let currentIp = await getCurrentIp(); - if (activeIp && currentIp === activeIp) { - return; - } + if (activeIp && currentIp === activeIp) { + return; + } - let domain = await getDomainInfo(); + let domain = await getDomainInfo(); - await fetch(domain.url[0].toString()); + await fetch(domain.url[0].toString()); - activeIp = domain.address[0]; + activeIp = domain.address[0]; } export async function start() { - const dht = (await getDHT()) as any; + const dht = (await getDHT()) as any; - await ipUpdate(); + await ipUpdate(); - await overwriteRegistryEntry( - dht.defaultKeyPair, - hashDataKey(REGISTRY_NODE_KEY), - pack(`${config.str("relay-domain")}:${config.uint("relay-port")}`) - ); + await overwriteRegistryEntry( + dht.defaultKeyPair, + hashDataKey(REGISTRY_NODE_KEY), + pack(`${config.str("relay-domain")}:${config.uint("relay-port")}`) + ); - console.log( - "node pubkey:", - Buffer.from(dht.defaultKeyPair.publicKey).toString("hex") - ); + console.log( + "node pubkey:", + Buffer.from(dht.defaultKeyPair.publicKey).toString("hex") + ); - cron.schedule("0 * * * *", ipUpdate); + cron.schedule("0 * * * *", ipUpdate); } async function getDomainInfo() { - const relayDomain = config.str("relay-domain"); - const parser = new Parser(); + const relayDomain = config.str("relay-domain"); + const parser = new Parser(); - const url = new URL("https://freedns.afraid.org/api/"); + const url = new URL("https://freedns.afraid.org/api/"); - const params = url.searchParams; + const params = url.searchParams; - params.append("action", "getdyndns"); - params.append("v", "2"); - params.append("style", "xml"); + params.append("action", "getdyndns"); + params.append("v", "2"); + params.append("style", "xml"); - const hash = createHash("sha1"); - hash.update( - `${config.str("afraid-username")}|${config.str("afraid-password")}` - ); + const hash = createHash("sha1"); + hash.update( + `${config.str("afraid-username")}|${config.str("afraid-password")}` + ); - params.append("sha", hash.digest().toString("hex")); + params.append("sha", hash.digest().toString("hex")); - const response = await (await fetch(url.toString())).text(); + const response = await (await fetch(url.toString())).text(); - if (/could not authenticate/i.test(response)) { - errorExit("Failed to authenticate to afraid.org"); + if (/could not authenticate/i.test(response)) { + errorExit("Failed to authenticate to afraid.org"); + } + + const json = await parser.parseStringPromise(response); + + let domain = null; + + for (const item of json.xml.item) { + if (item.host[0] === relayDomain) { + domain = item; + break; } + } - const json = await parser.parseStringPromise(response); + if (!domain) { + errorExit(`Domain ${relayDomain} not found in afraid.org account`); + } - let domain = null; - - for (const item of json.xml.item) { - if (item.host[0] === relayDomain) { - domain = item; - break; - } - } - - if (!domain) { - errorExit(`Domain ${relayDomain} not found in afraid.org account`); - } - - return domain; + return domain; } async function getCurrentIp(): Promise { - return await (await fetch("http://ip1.dynupdate.no-ip.com/")).text(); + return await (await fetch("http://ip1.dynupdate.no-ip.com/")).text(); } diff --git a/src/index.ts b/src/index.ts index 753c259..fa7bf76 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,13 +1,13 @@ -import {start as startDns} from "./dns.js"; -import {start as startRpc} from "./rpc.js"; -import {start as startRelay} from "./relay.js"; +import { start as startDns } from "./dns.js"; +import { start as startRpc } from "./rpc.js"; +import { start as startRelay } from "./relay.js"; await startDns(); await startRpc(); await startRelay(); process.on("uncaughtException", function (err) { - console.log("Caught exception: " + err); + console.log("Caught exception: " + err); }); export {}; diff --git a/src/networks.json b/src/networks.json index 65d34a8..4493fee 100644 --- a/src/networks.json +++ b/src/networks.json @@ -1,45 +1,45 @@ { - "algorand-mainnet": "29", - "algorand-mainnet-indexer": "dummy", - "algorand-archival": "000D", - "algorand-testnet": "45", - "algorand-testnet-archival": "0A45", - "arweave-mainnet": "30", - "avax-mainnet": "3", - "avax-archival": "00A3", - "avax-fuji": "000E", - "bsc-mainnet": "4", - "bsc-archival": "10", - "bsc-testnet": "11", - "bsc-testnet-archival": "12", - "btc-mainnet": "2", - "eth-mainnet": "21", - "eth-archival": "22", - "eth-archival-trace": "28", - "eth-goerli": "26", - "poa-kovan": "24", - "eth-rinkeby": "25", - "eth-ropsten": "23", - "evmos-mainnet": "46", - "fuse-mainnet": "5", - "fuse-archival": "000A", - "gnosischain-mainnet": "27", - "gnosischain-archival": "000C", - "harmony-0": "40", - "harmony-0-archival": "0A40", - "harmony-1": "41", - "harmony-1-archival": "0A41", - "harmony-2": "42", - "harmony-2-archival": "0A42", - "harmony-3": "43", - "harmony-3-archival": "0A43", - "iotex-mainnet": "44", - "oec-mainnet": "47", - "mainnet": "1", - "poly-mainnet": "9", - "poly-archival": "000B", - "poly-mumbai": "000F", - "poly-mumbai-archival": "00AF", - "sol-mainnet": "6", - "sol-testnet": "31" + "algorand-mainnet": "29", + "algorand-mainnet-indexer": "dummy", + "algorand-archival": "000D", + "algorand-testnet": "45", + "algorand-testnet-archival": "0A45", + "arweave-mainnet": "30", + "avax-mainnet": "3", + "avax-archival": "00A3", + "avax-fuji": "000E", + "bsc-mainnet": "4", + "bsc-archival": "10", + "bsc-testnet": "11", + "bsc-testnet-archival": "12", + "btc-mainnet": "2", + "eth-mainnet": "21", + "eth-archival": "22", + "eth-archival-trace": "28", + "eth-goerli": "26", + "poa-kovan": "24", + "eth-rinkeby": "25", + "eth-ropsten": "23", + "evmos-mainnet": "46", + "fuse-mainnet": "5", + "fuse-archival": "000A", + "gnosischain-mainnet": "27", + "gnosischain-archival": "000C", + "harmony-0": "40", + "harmony-0-archival": "0A40", + "harmony-1": "41", + "harmony-1-archival": "0A41", + "harmony-2": "42", + "harmony-2-archival": "0A42", + "harmony-3": "43", + "harmony-3-archival": "0A43", + "iotex-mainnet": "44", + "oec-mainnet": "47", + "mainnet": "1", + "poly-mainnet": "9", + "poly-archival": "000B", + "poly-mumbai": "000F", + "poly-mumbai-archival": "00AF", + "sol-mainnet": "6", + "sol-testnet": "31" } diff --git a/src/relay.ts b/src/relay.ts index 186c766..4d1b309 100644 --- a/src/relay.ts +++ b/src/relay.ts @@ -1,118 +1,118 @@ // @ts-ignore import DHT from "@hyperswarm/dht"; // @ts-ignore -import {relay} from "@hyperswarm/dht-relay"; +import { relay } from "@hyperswarm/dht-relay"; // @ts-ignore import Stream from "@hyperswarm/dht-relay/ws"; -import express, {Express} from "express"; +import express, { Express } from "express"; import path from "path"; -import {fileURLToPath} from "url"; +import { fileURLToPath } from "url"; import config from "./config.js"; import * as http from "http"; import * as https from "https"; import * as tls from "tls"; import * as acme from "acme-client"; -import {Buffer} from "buffer"; -import {intervalToDuration} from "date-fns"; +import { Buffer } from "buffer"; +import { intervalToDuration } from "date-fns"; import cron from "node-cron"; -import {get as getDHT} from "./dht.js"; +import { get as getDHT } from "./dht.js"; import WS from "ws"; // @ts-ignore import DHT from "@hyperswarm/dht"; -import {pack} from "msgpackr"; -import {overwriteRegistryEntry} from "libskynetnode"; -import {hashDataKey} from "./util.js"; +import { pack } from "msgpackr"; +import { overwriteRegistryEntry } from "libskynetnode"; +import { hashDataKey } from "./util.js"; let sslCtx: tls.SecureContext = tls.createSecureContext(); const sslParams: tls.SecureContextOptions = {}; const sslPrivateKey = await acme.forge.createPrivateKey(); const acmeClient = new acme.Client({ - accountKey: sslPrivateKey, - directoryUrl: acme.directory.letsencrypt.production, + accountKey: sslPrivateKey, + directoryUrl: acme.directory.letsencrypt.production, }); let app: Express; let router = express.Router(); export async function start() { - const relayPort = config.str("relay-port"); - app = express(); - app.use(function (req, res, next) { - router(req, res, next); + const relayPort = config.str("relay-port"); + app = express(); + app.use(function (req, res, next) { + router(req, res, next); + }); + + let httpsServer = https.createServer({ + SNICallback(servername, cb) { + cb(null, sslCtx); + }, + }); + + let httpServer = http.createServer(app); + + cron.schedule("0 * * * *", createOrRenewSSl); + + await new Promise((resolve) => { + httpServer.listen(80, "0.0.0.0", function () { + console.info("HTTP Listening on ", httpServer.address()); + resolve(null); }); + }); + const dht = await getDHT(); - let httpsServer = https.createServer({ - SNICallback(servername, cb) { - cb(null, sslCtx); - }, + let wsServer = new WS.Server({ server: httpsServer }); + + wsServer.on("connection", (socket: any) => { + relay(dht, new Stream(false, socket)); + }); + + await new Promise((resolve) => { + httpsServer.listen(relayPort, "0.0.0.0", function () { + console.info("Relay started on ", httpsServer.address()); + resolve(null); }); + }); - let httpServer = http.createServer(app); - - cron.schedule("0 * * * *", createOrRenewSSl); - - await new Promise((resolve) => { - httpServer.listen(80, "0.0.0.0", function () { - console.info("HTTP Listening on ", httpServer.address()); - resolve(null); - }); - }); - const dht = await getDHT(); - - let wsServer = new WS.Server({server: httpsServer}); - - wsServer.on("connection", (socket: any) => { - relay(dht, new Stream(false, socket)); - }); - - await new Promise((resolve) => { - httpsServer.listen(relayPort, "0.0.0.0", function () { - console.info("Relay started on ", httpsServer.address()); - resolve(null); - }); - }); - - await createOrRenewSSl(); + await createOrRenewSSl(); } async function createOrRenewSSl() { - if (sslParams.cert) { - const expires = ( - await acme.forge.readCertificateInfo(sslParams.cert as Buffer) - ).notAfter; + if (sslParams.cert) { + const expires = ( + await acme.forge.readCertificateInfo(sslParams.cert as Buffer) + ).notAfter; - let duration = intervalToDuration({start: new Date(), end: expires}); + let duration = intervalToDuration({ start: new Date(), end: expires }); - let daysLeft = (duration.months as number) * 30 + (duration.days as number); + let daysLeft = (duration.months as number) * 30 + (duration.days as number); - if (daysLeft > 30) { - return; - } + if (daysLeft > 30) { + return; } + } - const [certificateKey, certificateRequest] = await acme.forge.createCsr({ - commonName: config.str("relay-domain"), - }); + const [certificateKey, certificateRequest] = await acme.forge.createCsr({ + commonName: config.str("relay-domain"), + }); - sslParams.cert = await acmeClient.auto({ - csr: certificateRequest, - termsOfServiceAgreed: true, - challengeCreateFn: async (authz, challenge, keyAuthorization) => { - router.get( - `/.well-known/acme-challenge/${challenge.token}`, - (req, res) => { - res.send(keyAuthorization); - } - ); - }, - challengeRemoveFn: async () => { - router = express.Router(); - }, - challengePriority: ["http-01"], - }); - sslParams.key = certificateKey; - sslCtx = tls.createSecureContext(sslParams); + sslParams.cert = await acmeClient.auto({ + csr: certificateRequest, + termsOfServiceAgreed: true, + challengeCreateFn: async (authz, challenge, keyAuthorization) => { + router.get( + `/.well-known/acme-challenge/${challenge.token}`, + (req, res) => { + res.send(keyAuthorization); + } + ); + }, + challengeRemoveFn: async () => { + router = express.Router(); + }, + challengePriority: ["http-01"], + }); + sslParams.key = certificateKey; + sslCtx = tls.createSecureContext(sslParams); - console.log("SSL Certificate Updated"); + console.log("SSL Certificate Updated"); } diff --git a/src/rpc.ts b/src/rpc.ts index 08174f6..60dd2b3 100644 --- a/src/rpc.ts +++ b/src/rpc.ts @@ -1,28 +1,28 @@ import crypto from "crypto"; import jayson from "jayson/promise/index.js"; -import {pack, unpack} from "msgpackr"; -import {Mutex} from "async-mutex"; -import {createRequire} from "module"; +import { pack, unpack } from "msgpackr"; +import { Mutex } from "async-mutex"; +import { createRequire } from "module"; import NodeCache from "node-cache"; -import {get as getDHT} from "./dht.js"; -import {rpcMethods} from "./rpc/index.js"; +import { get as getDHT } from "./dht.js"; +import { rpcMethods } from "./rpc/index.js"; import PocketPKG from "@pokt-network/pocket-js"; -const {Configuration, HttpRpcProvider, PocketAAT, Pocket} = PocketPKG; +const { Configuration, HttpRpcProvider, PocketAAT, Pocket } = PocketPKG; import { - JSONRPCRequest, - JSONRPCResponseWithError, - JSONRPCResponseWithResult, + JSONRPCRequest, + JSONRPCResponseWithError, + JSONRPCResponseWithResult, } from "jayson"; -import config, {updateUsePocketGateway, usePocketGateway} from "./config.js"; -import {errorExit} from "./util.js"; +import config, { updateUsePocketGateway, usePocketGateway } from "./config.js"; +import { errorExit } from "./util.js"; const require = createRequire(import.meta.url); const stringify = require("json-stable-stringify"); const pendingRequests = new NodeCache(); const processedRequests = new NodeCache({ - stdTTL: 60 * 60 * 12, + stdTTL: 60 * 60 * 12, }); type PocketAATObject = typeof PocketAAT; @@ -32,235 +32,235 @@ let _aat: PocketAATObject; let jsonServer: jayson.Server; interface RPCRequest { - force: boolean; - chain: string; - query: string; - data: string; + force: boolean; + chain: string; + query: string; + data: string; } interface RPCResponse { - updated: number; - data: - | any - | { + updated: number; + data: + | any + | { error: string | boolean; - }; + }; } function hash(data: string): string { - return crypto.createHash("sha256").update(data).digest("hex"); + return crypto.createHash("sha256").update(data).digest("hex"); } function getRequestId(request: RPCRequest) { - const clonedRequest = Object.assign({}, request); + const clonedRequest = Object.assign({}, request); - // @ts-ignore - delete clonedRequest.force; + // @ts-ignore + delete clonedRequest.force; - return hash(stringify(clonedRequest)); + return hash(stringify(clonedRequest)); } function maybeProcessRequest(request: RPCRequest) { - if (!request.chain) { - throw new Error("RPC chain missing"); - } + if (!request.chain) { + throw new Error("RPC chain missing"); + } - if (!request.data) { - throw new Error("RPC data missing"); - } + if (!request.data) { + throw new Error("RPC data missing"); + } - return processRequest(request); + return processRequest(request); } async function processRequest(request: RPCRequest): Promise { - const reqId = getRequestId(request); + const reqId = getRequestId(request); - let lock: Mutex = pendingRequests.get(reqId) as Mutex; - const lockExists = !!lock; + let lock: Mutex = pendingRequests.get(reqId) as Mutex; + const lockExists = !!lock; - if (!lockExists) { - lock = new Mutex(); - pendingRequests.set(reqId, lock); + if (!lockExists) { + lock = new Mutex(); + pendingRequests.set(reqId, lock); + } + + if (lock.isLocked()) { + await lock.waitForUnlock(); + return processedRequests.get(reqId) as RPCResponse; + } + await lock.acquire(); + + if (!request.force && processedRequests.get(reqId)) { + return processedRequests.get(reqId) as RPCResponse; + } + + let rpcResp; + + let error; + try { + rpcResp = await processRpcRequest( + { + method: request.query, + jsonrpc: "2.0", + params: request.data, + id: 1, + } as unknown as JSONRPCRequest, + request.chain + ); + } catch (e) { + error = (e as Error).message; + } + + let dbData: RPCResponse = { + updated: Date.now(), + data: "", + }; + + if (rpcResp) { + rpcResp = rpcResp as JSONRPCResponseWithResult; + if (false === rpcResp.result) { + error = true; } - if (lock.isLocked()) { - await lock.waitForUnlock(); - return processedRequests.get(reqId) as RPCResponse; + rpcResp = rpcResp as unknown as JSONRPCResponseWithError; + + if (rpcResp.error) { + // @ts-ignore + error = rpcResp.error.message; } - await lock.acquire(); + } - if (!request.force && processedRequests.get(reqId)) { - return processedRequests.get(reqId) as RPCResponse; - } + dbData.data = error + ? { error } + : (rpcResp as unknown as JSONRPCResponseWithResult).result; - let rpcResp; + if (!processedRequests.get(reqId) || request.force) { + processedRequests.set(reqId, dbData); + } - let error; - try { - rpcResp = await processRpcRequest( - { - method: request.query, - jsonrpc: "2.0", - params: request.data, - id: 1 - } as unknown as JSONRPCRequest, - request.chain - ); - } catch (e) { - error = (e as Error).message; - } + await lock.release(); - let dbData: RPCResponse = { - updated: Date.now(), - data: "", - }; - - if (rpcResp) { - rpcResp = rpcResp as JSONRPCResponseWithResult; - if (false === rpcResp.result) { - error = true; - } - - rpcResp = rpcResp as unknown as JSONRPCResponseWithError; - - if (rpcResp.error) { - // @ts-ignore - error = rpcResp.error.message; - } - } - - dbData.data = error - ? {error} - : (rpcResp as unknown as JSONRPCResponseWithResult).result; - - if (!processedRequests.get(reqId) || request.force) { - processedRequests.set(reqId, dbData); - } - - await lock.release(); - - return dbData; + return dbData; } export function updateAat(aat: PocketAATObject): void { - _aat = aat; + _aat = aat; } export function getAat(): PocketAATObject { - return _aat; + return _aat; } export function getPocketServer(): typeof Pocket { - return pocketServer; + return pocketServer; } export async function unlockAccount( - accountPrivateKey: string, - accountPublicKey: string, - accountPassphrase: string + accountPrivateKey: string, + accountPublicKey: string, + accountPassphrase: string ): Promise { - try { - // @ts-ignore - const account = await pocketServer.keybase.importAccount( - Buffer.from(accountPrivateKey, "hex"), - accountPassphrase - ); + try { + // @ts-ignore + const account = await pocketServer.keybase.importAccount( + Buffer.from(accountPrivateKey, "hex"), + accountPassphrase + ); - if (account instanceof Error) { - // noinspection ExceptionCaughtLocallyJS - throw account; - } - - // @ts-ignore - await pocketServer.keybase.unlockAccount( - account.addressHex, - accountPassphrase, - 0 - ); - - // @ts-ignore - return await PocketAAT.from( - "0.0.1", - accountPublicKey, - accountPublicKey, - accountPrivateKey - ); - } catch (e) { - console.error(e); - process.exit(1); + if (account instanceof Error) { + // noinspection ExceptionCaughtLocallyJS + throw account; } + + // @ts-ignore + await pocketServer.keybase.unlockAccount( + account.addressHex, + accountPassphrase, + 0 + ); + + // @ts-ignore + return await PocketAAT.from( + "0.0.1", + accountPublicKey, + accountPublicKey, + accountPrivateKey + ); + } catch (e) { + console.error(e); + process.exit(1); + } } export async function processRpcRequest( - request: JSONRPCRequest, - chain: string + request: JSONRPCRequest, + chain: string ): Promise { - return new Promise((resolve) => { - jsonServer.call( - request, - {chain}, - ( - err?: JSONRPCResponseWithError | null, - result?: JSONRPCResponseWithResult - ): void => { - if (err) { - return resolve(err); - } - resolve(result); - } - ); - }); + return new Promise((resolve) => { + jsonServer.call( + request, + { chain }, + ( + err?: JSONRPCResponseWithError | null, + result?: JSONRPCResponseWithResult + ): void => { + if (err) { + return resolve(err); + } + resolve(result); + } + ); + }); } export async function start() { - if (!config.str("pocket-app-id") || !config.str("pocket-app-key")) { - const pocketHost = config.str("pocket-host"); - const pocketPort = config.uint("pocket-port"); - if (!pocketHost || !pocketPort) { - errorExit( - "Please set pocket-host and pocket-port config options if you do not have an API key set" - ); - } - - const dispatchURL = new URL( - `http://${config.str("pocket-host")}:${config.uint("pocket-port")}` - ); - const rpcProvider = new HttpRpcProvider(dispatchURL); - const configuration = new Configuration(); - // @ts-ignore - pocketServer = new Pocket([dispatchURL], rpcProvider, configuration); - updateUsePocketGateway(false); + if (!config.str("pocket-app-id") || !config.str("pocket-app-key")) { + const pocketHost = config.str("pocket-host"); + const pocketPort = config.uint("pocket-port"); + if (!pocketHost || !pocketPort) { + errorExit( + "Please set pocket-host and pocket-port config options if you do not have an API key set" + ); } - if (!usePocketGateway()) { - updateAat( - await unlockAccount( - config.str("pocket-account-private-key"), - config.str("pocket-account-public-key"), - "0" - ) - ); - } + const dispatchURL = new URL( + `http://${config.str("pocket-host")}:${config.uint("pocket-port")}` + ); + const rpcProvider = new HttpRpcProvider(dispatchURL); + const configuration = new Configuration(); + // @ts-ignore + pocketServer = new Pocket([dispatchURL], rpcProvider, configuration); + updateUsePocketGateway(false); + } - jsonServer = new jayson.Server(rpcMethods, {useContext: true}); + if (!usePocketGateway()) { + updateAat( + await unlockAccount( + config.str("pocket-account-private-key"), + config.str("pocket-account-public-key"), + "0" + ) + ); + } - (await getDHT("server")).on("connection", (socket: any) => { - socket.rawStream._ondestroy = () => false; - socket.on("data", async (data: any) => { - let request: RPCRequest; - try { - request = unpack(data) as RPCRequest; - } catch (e) { - return; - } + jsonServer = new jayson.Server(rpcMethods, { useContext: true }); - try { - socket.write(pack(await maybeProcessRequest(request))); - } catch (error) { - console.trace(error); - socket.write(pack({error})); - } - socket.end(); - }); + (await getDHT("server")).on("connection", (socket: any) => { + socket.rawStream._ondestroy = () => false; + socket.on("data", async (data: any) => { + let request: RPCRequest; + try { + request = unpack(data) as RPCRequest; + } catch (e) { + return; + } + + try { + socket.write(pack(await maybeProcessRequest(request))); + } catch (error) { + console.trace(error); + socket.write(pack({ error })); + } + socket.end(); }); + }); } diff --git a/src/rpc/algorand.ts b/src/rpc/algorand.ts index d912b37..e9d14d0 100644 --- a/src/rpc/algorand.ts +++ b/src/rpc/algorand.ts @@ -1,112 +1,112 @@ -import {maybeMapChainId, reverseMapChainId} from "../util.js"; +import { maybeMapChainId, reverseMapChainId } from "../util.js"; import minimatch from "minimatch"; // @ts-ignore import HTTPClient from "algosdk/dist/cjs/src/client/client.js"; -import {sprintf} from "sprintf-js"; -import {RpcMethodList} from "./index.js"; +import { sprintf } from "sprintf-js"; +import { RpcMethodList } from "./index.js"; import config from "../config.js"; const allowedEndpoints: { [endpoint: string]: ("GET" | "POST")[] } = { - "/v2/teal/compile": ["POST"], - "/v2/accounts/*": ["GET"], + "/v2/teal/compile": ["POST"], + "/v2/accounts/*": ["GET"], }; export function proxyRestMethod( - apiServer: string, - matchChainId: string + apiServer: string, + matchChainId: string ): Function { - return async function (args: any, context: object) { - // @ts-ignore - let chain = context.chain; - let chainId = maybeMapChainId(chain); + return async function (args: any, context: object) { + // @ts-ignore + let chain = context.chain; + let chainId = maybeMapChainId(chain); - if (!chainId) { - throw new Error("Invalid Chain"); + if (!chainId) { + throw new Error("Invalid Chain"); + } + + chainId = reverseMapChainId(chainId as string); + if (!chainId || chainId !== matchChainId) { + throw new Error("Invalid Chain"); + } + + let method = args.method ?? false; + let endpoint = args.endpoint ?? false; + let data = args.data ?? false; + let query = args.query ?? false; + let fullHeaders = args.fullHeaders ?? {}; + + fullHeaders = { ...fullHeaders, Referer: "lumeweb_dns_relay" }; + + if (method) { + method = method.toUpperCase(); + } + + if (!endpoint) { + throw new Error("Endpoint Missing"); + } + + let found = false; + + for (const theEndpoint in allowedEndpoints) { + if (minimatch(endpoint, theEndpoint)) { + found = true; + break; + } + } + + if (!found) { + throw new Error("Endpoint Invalid"); + } + + let apiUrl; + try { + apiUrl = sprintf(apiServer, chainId, config.str("pocket-app-id")); + } catch (e) { + apiUrl = apiServer; + } + + const client = new HTTPClient({}, apiUrl); + let resp; + switch (method) { + case "GET": + resp = await client.get(endpoint, query, fullHeaders); + break; + case "POST": + if (Array.isArray(data?.data)) { + data = new Uint8Array(Buffer.from(data.data)); } - chainId = reverseMapChainId(chainId as string); - if (!chainId || chainId !== matchChainId) { - throw new Error("Invalid Chain"); + resp = await client.post(endpoint, data, { ...fullHeaders }); + break; + default: + throw new Error("Method Invalid"); + } + + const getCircularReplacer = () => { + const seen = new WeakSet(); + return (key: string, value: any): any => { + if (typeof value === "object" && value !== null) { + if (seen.has(value)) { + return; + } + seen.add(value); } - - let method = args.method ?? false; - let endpoint = args.endpoint ?? false; - let data = args.data ?? false; - let query = args.query ?? false; - let fullHeaders = args.fullHeaders ?? {}; - - fullHeaders = {...fullHeaders, Referer: "lumeweb_dns_relay"}; - - if (method) { - method = method.toUpperCase(); - } - - if (!endpoint) { - throw new Error("Endpoint Missing"); - } - - let found = false; - - for (const theEndpoint in allowedEndpoints) { - if (minimatch(endpoint, theEndpoint)) { - found = true; - break; - } - } - - if (!found) { - throw new Error("Endpoint Invalid"); - } - - let apiUrl; - try { - apiUrl = sprintf(apiServer, chainId, config.str("pocket-app-id")); - } catch (e) { - apiUrl = apiServer; - } - - const client = new HTTPClient({}, apiUrl); - let resp; - switch (method) { - case "GET": - resp = await client.get(endpoint, query, fullHeaders); - break; - case "POST": - if (Array.isArray(data?.data)) { - data = new Uint8Array(Buffer.from(data.data)); - } - - resp = await client.post(endpoint, data, {...fullHeaders}); - break; - default: - throw new Error("Method Invalid"); - } - - const getCircularReplacer = () => { - const seen = new WeakSet(); - return (key: string, value: any): any => { - if (typeof value === "object" && value !== null) { - if (seen.has(value)) { - return; - } - seen.add(value); - } - return value; - }; - }; - - return JSON.parse(JSON.stringify(resp, getCircularReplacer())); + return value; + }; }; + + return JSON.parse(JSON.stringify(resp, getCircularReplacer())); + }; } export default { - algorand_rest_request: proxyRestMethod( - "http://mainnet-api.algonode.network", - "algorand-mainnet" - ), - //'algorand_rest_request': proxyRestMethod("https://%s.gateway.pokt.network/v1/lb/%s", "algorand-mainnet"), - algorand_rest_indexer_request: proxyRestMethod( - "http://mainnet-idx.algonode.network", - "algorand-mainnet-indexer" - ), + algorand_rest_request: proxyRestMethod( + "http://mainnet-api.algonode.network", + "algorand-mainnet" + ), + //'algorand_rest_request': proxyRestMethod("https://%s.gateway.pokt.network/v1/lb/%s", "algorand-mainnet"), + algorand_rest_indexer_request: proxyRestMethod( + "http://mainnet-idx.algonode.network", + "algorand-mainnet-indexer" + ), } as RpcMethodList; diff --git a/src/rpc/common.ts b/src/rpc/common.ts index a6b401f..caef806 100644 --- a/src/rpc/common.ts +++ b/src/rpc/common.ts @@ -1,106 +1,106 @@ -import {ethers} from "ethers"; -import {Pocket, PocketAAT} from "@pokt-network/pocket-js"; -import {maybeMapChainId, reverseMapChainId} from "../util.js"; -import {Connection} from "@solana/web3.js"; -import {getAat, getPocketServer} from "../rpc.js"; -import config, {usePocketGateway} from "../config.js"; +import { ethers } from "ethers"; +import { Pocket, PocketAAT } from "@pokt-network/pocket-js"; +import { maybeMapChainId, reverseMapChainId } from "../util.js"; +import { Connection } from "@solana/web3.js"; +import { getAat, getPocketServer } from "../rpc.js"; +import config, { usePocketGateway } from "../config.js"; type RpcProviderMethod = (method: string, params: Array) => Promise; const gatewayProviders: { [name: string]: RpcProviderMethod } = {}; const gatewayMethods: { - [name: string]: (chainId: string) => RpcProviderMethod; + [name: string]: (chainId: string) => RpcProviderMethod; } = { - default: (chainId: string): RpcProviderMethod => { - const provider = new ethers.providers.JsonRpcProvider({ - url: `https://${chainId}.gateway.pokt.network/v1/lb/${config.str( - "pocket-api-id" - )}`, - password: config.str("pocket-api-key"), - }); - return provider.send.bind(provider); - }, - "sol-mainnet": (chainId: string): RpcProviderMethod => { - const provider = new Connection( - `https://solana-mainnet.gateway.pokt.network/v1/lb/${config.str( - "pocket-api-id" - )}` - ); + default: (chainId: string): RpcProviderMethod => { + const provider = new ethers.providers.JsonRpcProvider({ + url: `https://${chainId}.gateway.pokt.network/v1/lb/${config.str( + "pocket-api-id" + )}`, + password: config.str("pocket-api-key"), + }); + return provider.send.bind(provider); + }, + "sol-mainnet": (chainId: string): RpcProviderMethod => { + const provider = new Connection( + `https://solana-mainnet.gateway.pokt.network/v1/lb/${config.str( + "pocket-api-id" + )}` + ); - // @ts-ignore - return provider._rpcRequest.bind(provider); - }, + // @ts-ignore + return provider._rpcRequest.bind(provider); + }, }; export function proxyRpcMethod( - method: string, - chains: string[] = [] + method: string, + chains: string[] = [] ): Function { - return async function (args: any, context: object) { - // @ts-ignore - let chain = context.chain; - let chainId = maybeMapChainId(chain); + return async function (args: any, context: object) { + // @ts-ignore + let chain = context.chain; + let chainId = maybeMapChainId(chain); - let chainMatch = true; + let chainMatch = true; - if ( - chains.length > 0 && - !chains.includes(chain) && - !chains.includes(chainId.toString()) - ) { - chainMatch = false; - } + if ( + chains.length > 0 && + !chains.includes(chain) && + !chains.includes(chainId.toString()) + ) { + chainMatch = false; + } - if (!chainId || !chainMatch) { - throw new Error("Invalid Chain"); - } + if (!chainId || !chainMatch) { + throw new Error("Invalid Chain"); + } - if (usePocketGateway()) { - chainId = reverseMapChainId(chainId as string); - if (!chainId) { - throw new Error("Invalid Chain"); - } + if (usePocketGateway()) { + chainId = reverseMapChainId(chainId as string); + if (!chainId) { + throw new Error("Invalid Chain"); + } - let provider: RpcProviderMethod | boolean = - gatewayProviders[chainId as string] || false; - if (!provider) { - provider = getRpcProvider(chainId as string); - } - gatewayProviders[chainId as string] = provider; - return await provider(method, args); - } + let provider: RpcProviderMethod | boolean = + gatewayProviders[chainId as string] || false; + if (!provider) { + provider = getRpcProvider(chainId as string); + } + gatewayProviders[chainId as string] = provider; + return await provider(method, args); + } - return await sendRelay( - JSON.stringify(args), - chainId, - getAat() as unknown as PocketAAT - ); - }; + return await sendRelay( + JSON.stringify(args), + chainId, + getAat() as unknown as PocketAAT + ); + }; } // Call this every time you want to fetch RPC data async function sendRelay( - rpcQuery: string, - blockchain: string, - pocketAAT: PocketAAT + rpcQuery: string, + blockchain: string, + pocketAAT: PocketAAT ) { - try { - return await (getPocketServer() as unknown as Pocket).sendRelay( - rpcQuery, - blockchain, - pocketAAT - ); - } catch (e) { - console.log(e); - throw e; - } + try { + return await (getPocketServer() as unknown as Pocket).sendRelay( + rpcQuery, + blockchain, + pocketAAT + ); + } catch (e) { + console.log(e); + throw e; + } } function getRpcProvider(chain: string): RpcProviderMethod { - if (chain in gatewayMethods) { - return gatewayMethods[chain](chain); - } + if (chain in gatewayMethods) { + return gatewayMethods[chain](chain); + } - return gatewayMethods.default(chain); + return gatewayMethods.default(chain); } diff --git a/src/rpc/dns.ts b/src/rpc/dns.ts index c4d9ebf..3c6b331 100644 --- a/src/rpc/dns.ts +++ b/src/rpc/dns.ts @@ -1,16 +1,16 @@ -import {isIp} from "../util.js"; -import {RpcMethodList} from "./index.js"; -import {createRequire} from "module"; +import { isIp } from "../util.js"; +import { RpcMethodList } from "./index.js"; +import { createRequire } from "module"; const require = createRequire(import.meta.url); const bns = require("bns"); -const {StubResolver, RecursiveResolver} = bns; +const { StubResolver, RecursiveResolver } = bns; const resolverOpt = { - tcp: true, - inet6: false, - edns: true, - dnssec: true, + tcp: true, + inet6: false, + edns: true, + dnssec: true, }; const globalResolver = new RecursiveResolver(resolverOpt); @@ -18,90 +18,90 @@ globalResolver.hints.setDefault(); globalResolver.open(); async function resolveNameServer(ns: string): Promise { - if (isIp(ns)) { - return ns; - } - let result = await getDnsRecords(ns, "A"); + if (isIp(ns)) { + return ns; + } + let result = await getDnsRecords(ns, "A"); - if (result.length) { - return result[0]; - } + if (result.length) { + return result[0]; + } - return false; + return false; } async function getDnsRecords( - domain: string, - type: string, - authority: boolean = false, - resolver = globalResolver + domain: string, + type: string, + authority: boolean = false, + resolver = globalResolver ): Promise { - let result; + let result; - try { - result = await resolver.lookup(domain, type); - } catch (e) { - return []; - } + try { + result = await resolver.lookup(domain, type); + } catch (e) { + return []; + } - let prop = authority ? "authority" : "answer"; + let prop = authority ? "authority" : "answer"; - if (!result || !result[prop].length) { - return []; - } + if (!result || !result[prop].length) { + return []; + } - return result[prop].map( - (item: object) => - // @ts-ignore - item.data.address ?? item.data.target ?? item.data.ns ?? null - ); + return result[prop].map( + (item: object) => + // @ts-ignore + item.data.address ?? item.data.target ?? item.data.ns ?? null + ); } export default { - dnslookup: async function (args: any) { - let dnsResults: string[] = []; - let domain = args.domain; - let ns = args.nameserver; - let dnsResolver = ns ? new StubResolver(resolverOpt) : globalResolver; - await dnsResolver.open(); + dnslookup: async function (args: any) { + let dnsResults: string[] = []; + let domain = args.domain; + let ns = args.nameserver; + let dnsResolver = ns ? new StubResolver(resolverOpt) : globalResolver; + await dnsResolver.open(); - if (ns) { - let nextNs = ns; - let prevNs = null; + if (ns) { + let nextNs = ns; + let prevNs = null; - while (nextNs) { - nextNs = await resolveNameServer(nextNs); - if (!nextNs) { - nextNs = prevNs; - } - - dnsResolver.setServers([nextNs]); - - if (nextNs === prevNs) { - break; - } - let result = await getDnsRecords(domain, "NS", true, dnsResolver); - prevNs = nextNs; - nextNs = result.length ? result[0] : false; - } + while (nextNs) { + nextNs = await resolveNameServer(nextNs); + if (!nextNs) { + nextNs = prevNs; } - for (const queryType of ["CNAME", "A"]) { - let result = await getDnsRecords(domain, queryType, false, dnsResolver); + dnsResolver.setServers([nextNs]); - if (result) { - dnsResults = dnsResults.concat(result); - } + if (nextNs === prevNs) { + break; } + let result = await getDnsRecords(domain, "NS", true, dnsResolver); + prevNs = nextNs; + nextNs = result.length ? result[0] : false; + } + } - await dnsResolver.close(); + for (const queryType of ["CNAME", "A"]) { + let result = await getDnsRecords(domain, queryType, false, dnsResolver); - dnsResults = dnsResults.filter(Boolean); + if (result) { + dnsResults = dnsResults.concat(result); + } + } - if (dnsResults.length) { - return dnsResults[0]; - } + await dnsResolver.close(); - return false; - }, + dnsResults = dnsResults.filter(Boolean); + + if (dnsResults.length) { + return dnsResults[0]; + } + + return false; + }, } as RpcMethodList; diff --git a/src/rpc/evm.ts b/src/rpc/evm.ts index 064520f..db2203a 100644 --- a/src/rpc/evm.ts +++ b/src/rpc/evm.ts @@ -1,14 +1,14 @@ -import {proxyRpcMethod} from "./common.js"; -import {RpcMethodList} from "./index.js"; +import { proxyRpcMethod } from "./common.js"; +import { RpcMethodList } from "./index.js"; const rpcMethods: RpcMethodList = {}; function proxyEvmRpcMethod(method: string): Function { - return proxyRpcMethod(method); + return proxyRpcMethod(method); } ["eth_call", "eth_chainId", "net_version"].forEach((method) => { - rpcMethods[method] = proxyEvmRpcMethod(method); + rpcMethods[method] = proxyEvmRpcMethod(method); }); export default rpcMethods; diff --git a/src/rpc/handshake.ts b/src/rpc/handshake.ts index 2886e21..82d5984 100644 --- a/src/rpc/handshake.ts +++ b/src/rpc/handshake.ts @@ -1,88 +1,88 @@ -import {RpcMethodList} from "./index.js"; +import { RpcMethodList } from "./index.js"; // @ts-ignore import rand from "random-key"; // @ts-ignore import SPVNode from "hsd/lib/node/spvnode.js"; import config from "../config.js"; -import {createRequire} from "module"; +import { createRequire } from "module"; const require = createRequire(import.meta.url); -const {NodeClient} = require("hs-client"); +const { NodeClient } = require("hs-client"); let hsdServer: SPVNode; let clientArgs = { - network: "main", - host: "127.0.0.1", - port: 12037, - apiKey: rand.generate(), + network: "main", + host: "127.0.0.1", + port: 12037, + apiKey: rand.generate(), }; if (!config.bool("hsd-use-external-node")) { - hsdServer = new SPVNode({ - config: false, - argv: false, - env: true, - noDns: true, - memory: false, - httpHost: "127.0.0.1", - apiKey: clientArgs.apiKey, - logFile: false, - logConsole: true, - logLevel: "info", - workers: true, - network: "main", - }); + hsdServer = new SPVNode({ + config: false, + argv: false, + env: true, + noDns: true, + memory: false, + httpHost: "127.0.0.1", + apiKey: clientArgs.apiKey, + logFile: false, + logConsole: true, + logLevel: "info", + workers: true, + network: "main", + }); - console.log(`HSD API KEY: ${clientArgs.apiKey}`); + console.log(`HSD API KEY: ${clientArgs.apiKey}`); - hsdServer.on("abort", async (err: any) => { - const timeout = setTimeout(() => { - console.error("Shutdown is taking a long time. Exiting."); - process.exit(3); - }, 5000); + hsdServer.on("abort", async (err: any) => { + const timeout = setTimeout(() => { + console.error("Shutdown is taking a long time. Exiting."); + process.exit(3); + }, 5000); - timeout.unref(); - - try { - console.error("Shutting down..."); - await hsdServer.close(); - clearTimeout(timeout); - console.error((err as Error).stack); - process.exit(2); - } catch (e: any) { - console.error(`Error occurred during shutdown: ${(e as Error).message}`); - process.exit(3); - } - }); + timeout.unref(); try { - await hsdServer.ensure(); - await hsdServer.open(); - await hsdServer.connect(); - - hsdServer.startSync(); + console.error("Shutting down..."); + await hsdServer.close(); + clearTimeout(timeout); + console.error((err as Error).stack); + process.exit(2); } catch (e: any) { - console.error((e as Error).stack); + console.error(`Error occurred during shutdown: ${(e as Error).message}`); + process.exit(3); } + }); + + try { + await hsdServer.ensure(); + await hsdServer.open(); + await hsdServer.connect(); + + hsdServer.startSync(); + } catch (e: any) { + console.error((e as Error).stack); + } } else { - clientArgs = { - network: config.str("hsd-network-type"), - host: config.str("hsd-host"), - port: config.uint("hsd-port"), - apiKey: config.str("hsd-api-key"), - }; + clientArgs = { + network: config.str("hsd-network-type"), + host: config.str("hsd-host"), + port: config.uint("hsd-port"), + apiKey: config.str("hsd-api-key"), + }; } const hnsClient = new NodeClient(clientArgs); export default { - getnameresource: async function (args: any, context: object) { - // @ts-ignore - if ("hns" !== context.chain) { - throw new Error("Invalid Chain"); - } + getnameresource: async function (args: any, context: object) { + // @ts-ignore + if ("hns" !== context.chain) { + throw new Error("Invalid Chain"); + } - return await hnsClient.execute("getnameresource", args); - }, + return await hnsClient.execute("getnameresource", args); + }, } as RpcMethodList; diff --git a/src/rpc/index.ts b/src/rpc/index.ts index 121bf43..3aa96ba 100644 --- a/src/rpc/index.ts +++ b/src/rpc/index.ts @@ -2,17 +2,17 @@ export type RpcMethodList = { [name: string]: Function }; export * from "./common.js"; -import {default as DnsMethods} from "./dns.js"; -import {default as EvmMethods} from "./evm.js"; -import {default as HnsMethods} from "./handshake.js"; -import {default as SolMethods} from "./solana.js"; -import {default as AlgoMethods} from "./algorand.js"; +import { default as DnsMethods } from "./dns.js"; +import { default as EvmMethods } from "./evm.js"; +import { default as HnsMethods } from "./handshake.js"; +import { default as SolMethods } from "./solana.js"; +import { default as AlgoMethods } from "./algorand.js"; export const rpcMethods: RpcMethodList = Object.assign( - {}, - DnsMethods, - EvmMethods, - HnsMethods, - SolMethods, - AlgoMethods + {}, + DnsMethods, + EvmMethods, + HnsMethods, + SolMethods, + AlgoMethods ); diff --git a/src/rpc/solana.ts b/src/rpc/solana.ts index 5878c8b..5cd5996 100644 --- a/src/rpc/solana.ts +++ b/src/rpc/solana.ts @@ -1,9 +1,9 @@ -import {proxyRpcMethod} from "./common.js"; -import {RpcMethodList} from "./index.js"; -import * as chainNetworks from "../networks.json" assert {type: "json"}; +import { proxyRpcMethod } from "./common.js"; +import { RpcMethodList } from "./index.js"; +import * as chainNetworks from "../networks.json" assert { type: "json" }; export default { - getAccountInfo: proxyRpcMethod("getAccountInfo", [ - chainNetworks["sol-mainnet"], - ]), + getAccountInfo: proxyRpcMethod("getAccountInfo", [ + chainNetworks["sol-mainnet"], + ]), } as RpcMethodList; diff --git a/src/util.ts b/src/util.ts index a35a1b6..90f4a96 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,66 +1,66 @@ -import * as chainNetworks from "./networks.json" assert {type: "json"}; -import {Buffer} from "buffer"; -import {blake2b} from "libskynet"; +import * as chainNetworks from "./networks.json" assert { type: "json" }; +import { Buffer } from "buffer"; +import { blake2b } from "libskynet"; type networks = { [net: string]: string }; export function errorExit(msg: string): void { - console.error(msg); - process.exit(1); + console.error(msg); + process.exit(1); } export function maybeMapChainId(chain: string): string | boolean { - if (chain in chainNetworks) { - return (chainNetworks as networks)[chain]; - } + if (chain in chainNetworks) { + return (chainNetworks as networks)[chain]; + } - if ( - [parseInt(chain, 16).toString(), parseInt(chain, 10).toString()].includes( - chain.toLowerCase() - ) - ) { - return chain; - } + if ( + [parseInt(chain, 16).toString(), parseInt(chain, 10).toString()].includes( + chain.toLowerCase() + ) + ) { + return chain; + } - return false; + return false; } export function reverseMapChainId(chainId: string): string | boolean { - let vals = Object.values(chainNetworks); - if (!vals.includes(chainId)) { - return false; - } + let vals = Object.values(chainNetworks); + if (!vals.includes(chainId)) { + return false; + } - return Object.keys(chainNetworks)[vals.indexOf(chainId)]; + return Object.keys(chainNetworks)[vals.indexOf(chainId)]; } export function isIp(ip: string) { - return /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test( - ip - ); + return /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test( + ip + ); } export function hashDataKey(dataKey: string): Uint8Array { - return blake2b(encodeUtf8String(dataKey)); + return blake2b(encodeUtf8String(dataKey)); } function encodeUtf8String(str: string): Uint8Array { - const byteArray = stringToUint8ArrayUtf8(str); - const encoded = new Uint8Array(8 + byteArray.length); - encoded.set(encodeNumber(byteArray.length)); - encoded.set(byteArray, 8); - return encoded; + const byteArray = stringToUint8ArrayUtf8(str); + const encoded = new Uint8Array(8 + byteArray.length); + encoded.set(encodeNumber(byteArray.length)); + encoded.set(byteArray, 8); + return encoded; } function stringToUint8ArrayUtf8(str: string): Uint8Array { - return Uint8Array.from(Buffer.from(str, "utf-8")); + return Uint8Array.from(Buffer.from(str, "utf-8")); } function encodeNumber(num: number): Uint8Array { - const encoded = new Uint8Array(8); - for (let index = 0; index < encoded.length; index++) { - encoded[index] = num & 0xff; - num = num >> 8; - } - return encoded; + const encoded = new Uint8Array(8); + for (let index = 0; index < encoded.length; index++) { + encoded[index] = num & 0xff; + num = num >> 8; + } + return encoded; }