diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index efe3952d..00000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,61 +0,0 @@ -module.exports = { - root: true, - env: { - browser: true, - es6: true, - node: true, - }, - parser: "@typescript-eslint/parser", - parserOptions: { - ecmaVersion: 10, - project: "./tsconfig.json", - sourceType: "module" - }, - plugins: [ - "@typescript-eslint", - "prettier", - "@chainsafe/eslint-plugin-node", - ], - extends: [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - ], - rules: { - "prettier/prettier": "error", - //doesnt work, it reports false errors - "constructor-super": "off", - //"@typescript-eslint/class-name-casing": "error", - "@typescript-eslint/explicit-function-return-type": ["error", { - "allowExpressions": true - }], - "@typescript-eslint/func-call-spacing": "error", - //"@typescript-eslint/interface-name-prefix": ["error", "always"], - //"@typescript-eslint/member-ordering": "error", - "@typescript-eslint/no-explicit-any": "error", - "@typescript-eslint/no-unused-vars": ["error", { - "varsIgnorePattern": "^_" - }], - "@typescript-eslint/no-use-before-define": "off", - "@typescript-eslint/semi": "error", - "@typescript-eslint/type-annotation-spacing": "error", - "camelcase": "error", - "func-call-spacing": "off", - "new-parens": "error", - "no-caller": "error", - "no-bitwise": "off", - "no-console": "warn", - "no-var": "error", - "prefer-const": "error", - "quotes": ["error", "double"], - "@chainsafe/node/file-extension-in-import": ["error", "always", {esm: true}], - "@typescript-eslint/no-floating-promises": "error", - }, - "overrides": [ - { - "files": ["**/test/**/*.ts"], - "rules": { - "@typescript-eslint/no-explicit-any": "off" - } - } - ] -}; diff --git a/.gitignore b/.gitignore index e0f68951..ae16f245 100644 --- a/.gitignore +++ b/.gitignore @@ -70,3 +70,6 @@ lib # others package-lock.json + +# benchmark +benchmark_data/ diff --git a/.mocharc.yaml b/.mocharc.yaml deleted file mode 100644 index 782a40de..00000000 --- a/.mocharc.yaml +++ /dev/null @@ -1,5 +0,0 @@ -colors: true -exit: true -extension: ["ts"] -node-option: - - loader=ts-node/esm diff --git a/.prettierrc.cjs b/.prettierrc.cjs deleted file mode 100644 index faacad34..00000000 --- a/.prettierrc.cjs +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = { - printWidth: 120, - tabWidth: 2, - useTabs: false, - semi: true, - singleQuote: false, - quoteProps: "as-needed", - trailingComma: "es5", - bracketSpacing: true, - arrowParens: "always", -}; \ No newline at end of file diff --git a/biome.jsonc b/biome.jsonc new file mode 100644 index 00000000..5df34bdc --- /dev/null +++ b/biome.jsonc @@ -0,0 +1,12 @@ +{ + "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", + "extends": [ + "@chainsafe/biomejs-config", + "@chainsafe/biomejs-config/recommended", + "@chainsafe/biomejs-config/nodejs", + "@chainsafe/biomejs-config/esm" + ], + "files": { + "includes": ["**/packages/**/*/src/**/*.ts", "**/packages/**/*/test/**/*.ts"] + } +} diff --git a/package.json b/package.json index 20b2747a..d999b26d 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "scripts": { "check-types": "pnpm -r check-types", "build": "pnpm -r build", - "lint": "pnpm -r lint", + "lint": "biome check", "prepublishOnly": "pnpm build", "publish": "pnpm publish -r --access public --no-git-check", "test": "pnpm -r test", @@ -21,24 +21,13 @@ "lint" ], "devDependencies": { - "@chainsafe/eslint-plugin-node": "^11.2.3", - "@dapplion/benchmark": "^0.2.4", - "@types/chai": "^4.2.0", - "@types/debug": "^4.1.5", - "@types/eslint": "^6.1.3", - "@types/mocha": "^8.0.3", - "@types/node": "^20.6.0", - "@typescript-eslint/eslint-plugin": "^5.27.1", - "@typescript-eslint/parser": "^5.27.1", - "chai": "^4.3.6", - "eslint": "^8.17.0", - "eslint-plugin-prettier": "^4.0.0", - "karma": "^4.3.0", - "mocha": "^10.0.0", - "nyc": "^14.1.1", - "prettier": "^2.6.2", - "ts-node": "^10.8.1", - "typescript": "^4.7.3" + "@biomejs/biome": "^2.3.14", + "@chainsafe/benchmark": "^2.0.1", + "@chainsafe/biomejs-config": "^1.0.0", + "@types/node": "^24.10.12", + "ts-node": "^10.9.2", + "typescript": "^5.9.3", + "vitest": "^4.0.18" }, "packageManager": "pnpm@10.24.0" } \ No newline at end of file diff --git a/packages/discv5/.mocharc.yaml b/packages/discv5/.mocharc.yaml deleted file mode 100644 index 782a40de..00000000 --- a/packages/discv5/.mocharc.yaml +++ /dev/null @@ -1,5 +0,0 @@ -colors: true -exit: true -extension: ["ts"] -node-option: - - loader=ts-node/esm diff --git a/packages/discv5/package.json b/packages/discv5/package.json index b01a4e90..8eb8e5a4 100644 --- a/packages/discv5/package.json +++ b/packages/discv5/package.json @@ -4,6 +4,7 @@ "description": "Discovery V5", "type": "module", "files": [ + "src", "lib" ], "exports": { @@ -40,10 +41,10 @@ "check-types": "tsc --noEmit", "build": "tsc -p tsconfig.build.json", "prepublishOnly": "pnpm build", - "lint": "eslint --color --ext .ts src/ test/", + "lint": "biome check src test", "test": "pnpm test:unit && pnpm test:e2e", - "test:unit": "mocha 'test/unit/**/*.test.ts'", - "test:e2e": "mocha 'test/e2e/**/*.test.ts'" + "test:unit": "vitest --run 'test/unit'", + "test:e2e": "vitest --run 'test/e2e'" }, "pre-push": [ "lint" @@ -67,16 +68,16 @@ "devDependencies": {}, "dependencies": { "@chainsafe/enr": "workspace:^", - "@ethereumjs/rlp": "^5.0.2", + "@ethereumjs/rlp": "^10.1.1", "@libp2p/crypto": "^5.0.1", - "@libp2p/interface": "^2.0.1", - "@libp2p/peer-id": "^5.0.1", - "@multiformats/multiaddr": "^12.1.10", - "@noble/hashes": "^1.7.0", - "@noble/secp256k1": "^2.2.2", - "debug": "^4.3.1", - "ethereum-cryptography": "^2.2.0", - "lru-cache": "^10.1.0", - "strict-event-emitter-types": "^2.0.0" + "@libp2p/interface": "^3.1.0", + "@libp2p/peer-id": "^6.0.4", + "@multiformats/multiaddr": "^13.0.1", + "@noble/hashes": "^2.0.1", + "@noble/secp256k1": "^3.0.0", + "ethereum-cryptography": "^3.2.0", + "lru-cache": "^11.2.5", + "strict-event-emitter-types": "^2.0.0", + "weald": "^1.1.1" } } diff --git a/packages/discv5/src/config/index.ts b/packages/discv5/src/config/index.ts index 9fa0215d..8ac1519a 100644 --- a/packages/discv5/src/config/index.ts +++ b/packages/discv5/src/config/index.ts @@ -1,5 +1,5 @@ -import { ISessionConfig } from "../session/index.js"; -import { ILookupConfig } from "../kademlia/index.js"; +import type {ILookupConfig} from "../kademlia/index.js"; +import type {ISessionConfig} from "../session/index.js"; export type IDiscv5Config = ISessionConfig & ILookupConfig & { @@ -20,16 +20,16 @@ export type IDiscv5Config = ISessionConfig & export const defaultConfig: IDiscv5Config = { addrVotesToUpdateEnr: 10, - requestTimeout: 1 * 1000, - requestRetries: 1, - sessionTimeout: 86400 * 1000, // 1 day - sessionEstablishTimeout: 15 * 1000, - sessionCacheCapacity: 2000, + allowUnverifiedSessions: false, + enrUpdate: true, + lookupNumResults: 16, lookupParallelism: 3, lookupRequestLimit: 3, - lookupNumResults: 16, lookupTimeout: 60 * 1000, pingInterval: 300 * 1000, - enrUpdate: true, - allowUnverifiedSessions: false, + requestRetries: 1, + requestTimeout: 1 * 1000, + sessionCacheCapacity: 2000, + sessionEstablishTimeout: 15 * 1000, + sessionTimeout: 86400 * 1000, // 1 day }; diff --git a/packages/discv5/src/kademlia/bucket.ts b/packages/discv5/src/kademlia/bucket.ts index 340a96df..06dd8715 100644 --- a/packages/discv5/src/kademlia/bucket.ts +++ b/packages/discv5/src/kademlia/bucket.ts @@ -1,10 +1,17 @@ -import { EventEmitter } from "events"; -import { ENR, NodeId } from "@chainsafe/enr"; - -import { MAX_NODES_PER_BUCKET } from "./constants.js"; -import { BucketEventEmitter, EntryStatus, IEntry, IEntryFull, InsertResult, UpdateResult } from "./types.js"; - -export class Bucket extends (EventEmitter as { new (): BucketEventEmitter }) { +import {EventEmitter} from "node:events"; +import type {ENR, NodeId} from "@chainsafe/enr"; + +import {MAX_NODES_PER_BUCKET} from "./constants.js"; +import { + type BucketEventEmitter, + EntryStatus, + type IEntry, + type IEntryFull, + InsertResult, + UpdateResult, +} from "./types.js"; + +export class Bucket extends (EventEmitter as {new (): BucketEventEmitter}) { /** * Entries ordered from least-recently connected to most-recently connected */ @@ -88,32 +95,29 @@ export class Bucket extends (EventEmitter as { new (): BucketEventEmitter }) { case EntryStatus.Connected: { if (this.nodes.length < MAX_NODES_PER_BUCKET) { this.firstConnectedIndex = this.firstConnectedIndex ?? this.nodes.length; - this.nodes.push({ value, status }); + this.nodes.push({status, value}); break; - } else { - // The bucket is full, attempt to add the node as pending - if (this.addPending(value, status)) { - return InsertResult.Pending; - } else { - return InsertResult.FailedBucketFull; - } } + // The bucket is full, attempt to add the node as pending + if (this.addPending(value, status)) { + return InsertResult.Pending; + } + return InsertResult.FailedBucketFull; } case EntryStatus.Disconnected: { if (this.nodes.length < MAX_NODES_PER_BUCKET) { if (this.firstConnectedIndex === undefined) { // No connected nodes, add to the end - this.nodes.push({ value, status }); + this.nodes.push({status, value}); } else { // add before the first connected node - this.nodes.splice(this.firstConnectedIndex, 0, { value, status }); + this.nodes.splice(this.firstConnectedIndex, 0, {status, value}); this.firstConnectedIndex++; } break; - } else { - // The bucket is full - return InsertResult.FailedBucketFull; } + // The bucket is full + return InsertResult.FailedBucketFull; } } @@ -121,7 +125,7 @@ export class Bucket extends (EventEmitter as { new (): BucketEventEmitter }) { // happen when a pending node is inserted, a node gets removed from the bucket, freeing up // space and then re-inserted here. if (isPendingNode) { - delete this.pending; + this.pending = undefined; } return InsertResult.Inserted; } @@ -138,15 +142,14 @@ export class Bucket extends (EventEmitter as { new (): BucketEventEmitter }) { if (value.seq > node.value.seq) { node.value = value; return UpdateResult.Updated; - } else { - return UpdateResult.NotModified; } - } else if (this.pending?.value.nodeId === value.nodeId) { + return UpdateResult.NotModified; + } + if (this.pending?.value.nodeId === value.nodeId) { this.pending.value = value; return UpdateResult.UpdatedPending; - } else { - return UpdateResult.FailedKeyNonExistent; } + return UpdateResult.FailedKeyNonExistent; } /** @@ -175,7 +178,7 @@ export class Bucket extends (EventEmitter as { new (): BucketEventEmitter }) { // If the least-recently connected node re-establishes its // connected status, drop the pending node. if (index === 0 && isConnected) { - delete this.pending; + this.pending = undefined; } // Reinsert the node with the desired status @@ -183,21 +186,21 @@ export class Bucket extends (EventEmitter as { new (): BucketEventEmitter }) { case InsertResult.Inserted: { if (notModified) { return UpdateResult.NotModified; - } else if (!wasConnected && isConnected) { + } + if (!wasConnected && isConnected) { return UpdateResult.UpdatedAndPromoted; - } else { - return UpdateResult.Updated; } + return UpdateResult.Updated; } default: throw new Error("Unreachable"); } - } else if (this.pending?.value.nodeId === id) { + } + if (this.pending?.value.nodeId === id) { this.pending.status = status; return UpdateResult.UpdatedPending; - } else { - return UpdateResult.FailedKeyNonExistent; } + return UpdateResult.FailedKeyNonExistent; } /** @@ -208,7 +211,7 @@ export class Bucket extends (EventEmitter as { new (): BucketEventEmitter }) { */ addPending(value: ENR, status: EntryStatus): boolean { if (!this.pending && this.firstConnectedIndex !== 0) { - this.pending = { value, status }; + this.pending = {status, value}; const first = this.nodes[0]; this.emit("pendingEviction", first.value); this.pendingTimeoutId = setTimeout(this.applyPending, this.pendingTimeout); @@ -253,10 +256,10 @@ export class Bucket extends (EventEmitter as { new (): BucketEventEmitter }) { getWithPending(id: NodeId): IEntryFull | undefined { const bucketEntry = this.get(id); if (bucketEntry) { - return { pending: false, ...bucketEntry }; + return {pending: false, ...bucketEntry}; } if (this.pending && this.pending.value.nodeId === id) { - return { pending: true, ...this.pending }; + return {pending: true, ...this.pending}; } return undefined; } @@ -297,7 +300,7 @@ export class Bucket extends (EventEmitter as { new (): BucketEventEmitter }) { case EntryStatus.Connected: { if (this.firstConnectedIndex === index && index === this.nodes.length - 1) { // It was the last connected node. - delete this.firstConnectedIndex; + this.firstConnectedIndex = undefined; } break; } diff --git a/packages/discv5/src/kademlia/index.ts b/packages/discv5/src/kademlia/index.ts index 2f6660c0..bc1ee628 100644 --- a/packages/discv5/src/kademlia/index.ts +++ b/packages/discv5/src/kademlia/index.ts @@ -1,5 +1,5 @@ -export * from "./types.js"; export * from "./constants.js"; +export * from "./kademlia.js"; export * from "./lookup.js"; +export * from "./types.js"; export * from "./util.js"; -export * from "./kademlia.js"; diff --git a/packages/discv5/src/kademlia/kademlia.ts b/packages/discv5/src/kademlia/kademlia.ts index 67034e5a..a55a76b0 100644 --- a/packages/discv5/src/kademlia/kademlia.ts +++ b/packages/discv5/src/kademlia/kademlia.ts @@ -1,11 +1,17 @@ -import { EventEmitter } from "events"; -import { NodeId, ENR } from "@chainsafe/enr"; - -import { Bucket } from "./bucket.js"; -import { EntryStatus, IEntryFull, BucketEventEmitter, IEntry, InsertResult } from "./types.js"; -import { NUM_BUCKETS, PENDING_TIMEOUT } from "./constants.js"; -import { log2Distance } from "./util.js"; -import { UpdateResult } from "./types.js"; +import {EventEmitter} from "node:events"; +import type {ENR, NodeId} from "@chainsafe/enr"; + +import {Bucket} from "./bucket.js"; +import {NUM_BUCKETS, PENDING_TIMEOUT} from "./constants.js"; +import { + type BucketEventEmitter, + type EntryStatus, + type IEntry, + type IEntryFull, + InsertResult, + UpdateResult, +} from "./types.js"; +import {log2Distance} from "./util.js"; /** * A Kademlia routing table, for storing ENRs based on their NodeIds @@ -16,7 +22,7 @@ import { UpdateResult } from "./types.js"; * take the place of the oldest disconnected entry in the bucket * or be dropped after a timeout. */ -export class KademliaRoutingTable extends (EventEmitter as { new (): BucketEventEmitter }) { +export class KademliaRoutingTable extends (EventEmitter as {new (): BucketEventEmitter}) { localId: NodeId; buckets: Bucket[]; @@ -29,11 +35,11 @@ export class KademliaRoutingTable extends (EventEmitter as { new (): BucketEvent constructor(localId: NodeId) { super(); this.localId = localId; - this.buckets = Array.from({ length: NUM_BUCKETS }, () => new Bucket(PENDING_TIMEOUT)); - this.buckets.forEach((bucket) => { + this.buckets = Array.from({length: NUM_BUCKETS}, () => new Bucket(PENDING_TIMEOUT)); + for (const bucket of this.buckets) { bucket.on("pendingEviction", (enr: ENR) => this.emit("pendingEviction", enr)); bucket.on("appliedEviction", (inserted: ENR, evicted?: ENR) => this.emit("appliedEviction", inserted, evicted)); - }); + } } get size(): number { @@ -41,11 +47,13 @@ export class KademliaRoutingTable extends (EventEmitter as { new (): BucketEvent } isEmpty(): boolean { - return this.size == 0; + return this.size === 0; } clear(): void { - this.buckets.forEach((bucket) => bucket && bucket.clear()); + for (const bucket of this.buckets) { + bucket?.clear(); + } } /** @@ -115,9 +123,8 @@ export class KademliaRoutingTable extends (EventEmitter as { new (): BucketEvent (updateResult === UpdateResult.NotModified && statusResult === UpdateResult.NotModified) ) { return updateResult; - } else { - return UpdateResult.Updated; } + return UpdateResult.Updated; } /** @@ -132,50 +139,49 @@ export class KademliaRoutingTable extends (EventEmitter as { new (): BucketEvent if (!bucket.get(id)) { return bucket.add(value, status); - } else { - // The node exists in the bucket - // Attempt to update the status - const updateStatus = bucket.updateStatus(id, status); - - // If there was a failure state, we'd return early - // but the only failure we have is a full bucket (which can't happen here) + } + // The node exists in the bucket + // Attempt to update the status + const updateStatus = bucket.updateStatus(id, status); - // Attempt to update the value - const updateValue = bucket.updateValue(value); + // If there was a failure state, we'd return early + // but the only failure we have is a full bucket (which can't happen here) - if (updateValue === UpdateResult.Updated && updateStatus === UpdateResult.Updated) { - return InsertResult.Updated; - } + // Attempt to update the value + const updateValue = bucket.updateValue(value); - if (updateValue === UpdateResult.Updated && updateStatus === UpdateResult.UpdatedAndPromoted) { - return InsertResult.UpdatedAndPromoted; - } + if (updateValue === UpdateResult.Updated && updateStatus === UpdateResult.Updated) { + return InsertResult.Updated; + } - if ( - (updateValue === UpdateResult.Updated && updateStatus === UpdateResult.NotModified) || - (updateValue === UpdateResult.Updated && updateStatus === UpdateResult.UpdatedPending) - ) { - return InsertResult.ValueUpdated; - } + if (updateValue === UpdateResult.Updated && updateStatus === UpdateResult.UpdatedAndPromoted) { + return InsertResult.UpdatedAndPromoted; + } - if (updateValue === UpdateResult.NotModified && updateStatus === UpdateResult.Updated) { - return InsertResult.StatusUpdated; - } + if ( + (updateValue === UpdateResult.Updated && updateStatus === UpdateResult.NotModified) || + (updateValue === UpdateResult.Updated && updateStatus === UpdateResult.UpdatedPending) + ) { + return InsertResult.ValueUpdated; + } - if (updateValue === UpdateResult.NotModified && updateStatus === UpdateResult.UpdatedAndPromoted) { - return InsertResult.StatusUpdatedAndPromoted; - } + if (updateValue === UpdateResult.NotModified && updateStatus === UpdateResult.Updated) { + return InsertResult.StatusUpdated; + } - if (updateValue === UpdateResult.NotModified && updateStatus === UpdateResult.NotModified) { - return InsertResult.Updated; - } + if (updateValue === UpdateResult.NotModified && updateStatus === UpdateResult.UpdatedAndPromoted) { + return InsertResult.StatusUpdatedAndPromoted; + } - if (updateValue === UpdateResult.UpdatedPending && updateStatus === UpdateResult.UpdatedPending) { - return InsertResult.UpdatedPending; - } + if (updateValue === UpdateResult.NotModified && updateStatus === UpdateResult.NotModified) { + return InsertResult.Updated; + } - throw new Error("Unreachable"); + if (updateValue === UpdateResult.UpdatedPending && updateStatus === UpdateResult.UpdatedPending) { + return InsertResult.UpdatedPending; } + + throw new Error("Unreachable"); } /** @@ -196,9 +202,9 @@ export class KademliaRoutingTable extends (EventEmitter as { new (): BucketEvent nearest(id: NodeId, limit: number): ENR[] { const results: ENR[] = []; - this.buckets.forEach((bucket) => { + for (const bucket of this.buckets) { results.push(...bucket.values()); - }); + } results.sort((a, b) => { return log2Distance(id, a.nodeId) - log2Distance(id, b.nodeId); }); @@ -211,22 +217,16 @@ export class KademliaRoutingTable extends (EventEmitter as { new (): BucketEvent } values(): ENR[] { - return this.buckets - .filter((bucket) => !bucket.isEmpty()) - .map((bucket) => bucket.values()) - .flat(); + return this.buckets.filter((bucket) => !bucket.isEmpty()).flatMap((bucket) => bucket.values()); } rawValues(): IEntry[] { - return this.buckets - .filter((bucket) => !bucket.isEmpty()) - .map((bucket) => bucket.rawValues()) - .flat(); + return this.buckets.filter((bucket) => !bucket.isEmpty()).flatMap((bucket) => bucket.rawValues()); } random(): ENR | undefined { const nonEmptyBuckets = this.buckets.filter((bucket) => !bucket.isEmpty()); - if (nonEmptyBuckets.length == 0) { + if (nonEmptyBuckets.length === 0) { return undefined; } const selectedBucket = nonEmptyBuckets[Math.floor(Math.random() * nonEmptyBuckets.length)]; diff --git a/packages/discv5/src/kademlia/lookup.ts b/packages/discv5/src/kademlia/lookup.ts index b79b793d..5e43b13e 100644 --- a/packages/discv5/src/kademlia/lookup.ts +++ b/packages/discv5/src/kademlia/lookup.ts @@ -1,9 +1,9 @@ -import { EventEmitter } from "events"; -import { ENR, NodeId } from "@chainsafe/enr"; +import {EventEmitter} from "node:events"; +import type {ENR, NodeId} from "@chainsafe/enr"; -import { createFindNodeMessage, RequestMessage } from "../message/index.js"; -import { ILookupPeer, ILookupConfig, LookupState, LookupPeerState, LookupEventEmitter } from "./types.js"; -import { distance, findNodeLog2Distances } from "./util.js"; +import {type RequestMessage, createFindNodeMessage} from "../message/index.js"; +import {type ILookupConfig, type ILookupPeer, type LookupEventEmitter, LookupPeerState, LookupState} from "./types.js"; +import {distance, findNodeLog2Distances} from "./util.js"; export function createLookupPeer(nodeId: NodeId, state: LookupPeerState): ILookupPeer { return { @@ -13,7 +13,7 @@ export function createLookupPeer(nodeId: NodeId, state: LookupPeerState): ILooku }; } -export class Lookup extends (EventEmitter as { new (): LookupEventEmitter }) { +export class Lookup extends (EventEmitter as {new (): LookupEventEmitter}) { /** * Target we're looking for */ @@ -173,11 +173,9 @@ export class Lookup extends (EventEmitter as { new (): LookupEventEmitter }) { if (this.noProgress >= this.config.lookupParallelism) { this.state = LookupState.Stalled; } - } else if (this.state === LookupState.Stalled) { - if (progress) { - this.state = LookupState.Iterating; - this.noProgress = 0; - } + } else if (this.state === LookupState.Stalled && progress) { + this.state = LookupState.Iterating; + this.noProgress = 0; } } this.nextPeer(); @@ -193,11 +191,9 @@ export class Lookup extends (EventEmitter as { new (): LookupEventEmitter }) { } const dist = distance(this.target, nodeId); const peer = this.closestPeers.get(dist); - if (peer) { - if (peer.state === LookupPeerState.Waiting) { - this.numPeersWaiting -= 1; - peer.state = LookupPeerState.Failed; - } + if (peer && peer.state === LookupPeerState.Waiting) { + this.numPeersWaiting -= 1; + peer.state = LookupPeerState.Failed; } this.nextPeer(); } @@ -219,37 +215,33 @@ export class Lookup extends (EventEmitter as { new (): LookupEventEmitter }) { if (peer.state === LookupPeerState.NotContacted) { if (atCapacity) { return; - } else { - // This peer is waiting to be (re)iterated - peer.state = LookupPeerState.Waiting; - this.numPeersWaiting += 1; - this.emit("peer", peer.nodeId); - return; } + // This peer is waiting to be (re)iterated + peer.state = LookupPeerState.Waiting; + this.numPeersWaiting += 1; + this.emit("peer", peer.nodeId); + return; } if (peer.state === LookupPeerState.Waiting) { if (atCapacity) { // The lookup is still waiting for a result from a peer and is // at capacity w.r.t. the maximum number of peers being waited on. return; - } else { - // The lookup is still waiting for a result from a peer and the - // `resultCounter` did not yet reach `numResults`. - // Therefore the lookup is not yet done, regardless of already successful - // lookups to peers farther from the target. - resultCounter = -1; } + // The lookup is still waiting for a result from a peer and the + // `resultCounter` did not yet reach `numResults`. + // Therefore the lookup is not yet done, regardless of already successful + // lookups to peers farther from the target. + resultCounter = -1; } - if (peer.state === LookupPeerState.Succeeded) { - if (resultCounter > 0) { - resultCounter += 1; - // If `numResults` successful results have been delivered for the closest peers, - // the lookup is done - if (resultCounter >= this.config.lookupNumResults) { - this.state = LookupState.Finished; - this.emit("finished", this.closestNodesByDistance()); - return; - } + if (peer.state === LookupPeerState.Succeeded && resultCounter > 0) { + resultCounter += 1; + // If `numResults` successful results have been delivered for the closest peers, + // the lookup is done + if (resultCounter >= this.config.lookupNumResults) { + this.state = LookupState.Finished; + this.emit("finished", this.closestNodesByDistance()); + return; } } // Skip over unresponsive or failed peers diff --git a/packages/discv5/src/kademlia/types.ts b/packages/discv5/src/kademlia/types.ts index aed42dd6..5a953d96 100644 --- a/packages/discv5/src/kademlia/types.ts +++ b/packages/discv5/src/kademlia/types.ts @@ -1,6 +1,6 @@ -import { EventEmitter } from "events"; -import StrictEventEmitter from "strict-event-emitter-types"; -import { ENR, NodeId } from "@chainsafe/enr"; +import type {EventEmitter} from "node:events"; +import type {ENR, NodeId} from "@chainsafe/enr"; +import type {StrictEventEmitter} from "strict-event-emitter-types"; export interface IBucketEvents { /** @@ -23,53 +23,53 @@ export type BucketEventEmitter = StrictEventEmitter /** The result of inserting an entry into a bucket. */ export enum InsertResult { /** The entry has been successfully inserted */ - Inserted, + Inserted = 0, /** * The entry is pending insertion because the relevant bucket is currently full. * * The entry is inserted after a timeout elapsed, if the status of the least-recently connected * (and currently disconnected) node in the bucket is not updated before the timeout expires. */ - Pending, + Pending = 1, /** The node existed and the status was updated */ - StatusUpdated, + StatusUpdated = 2, /** The node existed and the status was updated and the node was promoted to a connected state */ - StatusUpdatedAndPromoted, + StatusUpdatedAndPromoted = 3, /** The node existed and the value was updated. */ - ValueUpdated, + ValueUpdated = 4, /** Both the status and value were updated. */ - Updated, + Updated = 5, /** Both the status and value were promoted and the node was promoted to a connected state */ - UpdatedAndPromoted, + UpdatedAndPromoted = 6, /** The pending slot was updated. */ - UpdatedPending, + UpdatedPending = 7, /** The entry was not inserted because the relevant bucket is full. */ - FailedBucketFull, + FailedBucketFull = 8, /** Cannot update self */ - FailedInvalidSelfUpdate, + FailedInvalidSelfUpdate = 9, /** The entry already exists. */ - NodeExists, + NodeExists = 10, } /** The result of performing an update on a bucket. */ export enum UpdateResult { /** The node was updated successfully */ - Updated, + Updated = 0, /** The update promoted the node to a connected state from a disconnected state. */ - UpdatedAndPromoted, + UpdatedAndPromoted = 1, /** The pending entry was updated. */ - UpdatedPending, + UpdatedPending = 2, /** The update removed the node. The node didn't exist. */ - FailedKeyNonExistent, + FailedKeyNonExistent = 3, /** The update removed the node. The bucket was full. */ - FailedBucketFull, + FailedBucketFull = 4, /** There were no changes made to the value of the node. */ - NotModified, + NotModified = 5, } export enum EntryStatus { - Connected, - Disconnected, + Connected = 0, + Disconnected = 1, } export interface IEntry { @@ -124,7 +124,7 @@ export enum LookupState { * The query is making progress by iterating towards `numResults` closest peers * to the target with a maximum of `parallelism` peers at a time */ - Iterating, + Iterating = 0, /** * A query is stalled when it did not make progress after `parallelism` consecutive * successful results. @@ -134,7 +134,7 @@ export enum LookupState { * If the query can make progress again upon receiving the remaining results, * it switches back to `Iterating`. Otherwise it will be finished. */ - Stalled, + Stalled = 1, /** * The query is finished. * @@ -142,7 +142,7 @@ export enum LookupState { * closes peers (not counting those that failed or are unresponsive) * or because the query ran out of peers that have not yet delivered results (or failed). */ - Finished, + Finished = 2, } export interface ILookupPeer { @@ -166,17 +166,17 @@ export enum LookupPeerState { * * This is the starting state for every peer known or discovered by a lookup */ - NotContacted, + NotContacted = 0, /** * The lookup is waiting for a result from the peer */ - Waiting, + Waiting = 1, /** * Obtaining a result from the peer has failed */ - Failed, + Failed = 2, /** * A successful result from the peer has been delivered */ - Succeeded, + Succeeded = 3, } diff --git a/packages/discv5/src/kademlia/util.ts b/packages/discv5/src/kademlia/util.ts index c5421215..90188d1c 100644 --- a/packages/discv5/src/kademlia/util.ts +++ b/packages/discv5/src/kademlia/util.ts @@ -1,7 +1,6 @@ -import { bytesToBigint, NodeId } from "@chainsafe/enr"; - -import { NUM_BUCKETS } from "./constants.js"; -import { hexToBytes } from "ethereum-cryptography/utils.js"; +import {type NodeId, bytesToBigint} from "@chainsafe/enr"; +import {hexToBytes} from "ethereum-cryptography/utils.js"; +import {NUM_BUCKETS} from "./constants.js"; /** * Computes the xor distance between two NodeIds @@ -25,9 +24,8 @@ export function log2Distance(a: NodeId, b: NodeId): number { firstMatch += 3; } break; - } else { - firstMatch += 4; } + firstMatch += 4; } return NUM_BUCKETS - firstMatch; diff --git a/packages/discv5/src/keypair/index.ts b/packages/discv5/src/keypair/index.ts index 58d2a626..bddc8b17 100644 --- a/packages/discv5/src/keypair/index.ts +++ b/packages/discv5/src/keypair/index.ts @@ -1,11 +1,10 @@ -import { KeyType } from "@libp2p/interface"; +import type {KeyType} from "@libp2p/interface"; +import {ERR_TYPE_NOT_IMPLEMENTED} from "./constants.js"; +import {Secp256k1Keypair} from "./secp256k1.js"; +import type {IKeypair} from "./types.js"; -import { IKeypair } from "./types.js"; -import { ERR_TYPE_NOT_IMPLEMENTED } from "./constants.js"; -import { Secp256k1Keypair } from "./secp256k1.js"; - -export * from "./types.js"; export * from "./secp256k1.js"; +export * from "./types.js"; export function generateKeypair(type: KeyType): IKeypair { switch (type) { diff --git a/packages/discv5/src/keypair/secp256k1.ts b/packages/discv5/src/keypair/secp256k1.ts index 2626f9b8..09bc6714 100644 --- a/packages/discv5/src/keypair/secp256k1.ts +++ b/packages/discv5/src/keypair/secp256k1.ts @@ -1,10 +1,12 @@ -import { KeyType } from "@libp2p/interface"; -import { AbstractKeypair, IKeypair, IKeypairClass } from "./types.js"; -import { ERR_INVALID_KEYPAIR_TYPE } from "./constants.js"; -import { getDiscv5Crypto } from "../util/crypto.js"; -import { concatBytes } from "@noble/hashes/utils"; +import type {KeyType} from "@libp2p/interface"; +import {concatBytes} from "@noble/hashes/utils.js"; +import {getDiscv5Crypto} from "../util/crypto.js"; +import {ERR_INVALID_KEYPAIR_TYPE} from "./constants.js"; +import {AbstractKeypair, type IKeypair, type IKeypairClass} from "./types.js"; + export function secp256k1PublicKeyToCompressed(publicKey: Uint8Array): Uint8Array { if (publicKey.length === 64) { + // biome-ignore lint/style/noParameterAssign: Preexisting code publicKey = concatBytes(Uint8Array.from([4]), publicKey); } return getDiscv5Crypto().secp256k1.publicKeyConvert(publicKey, true); @@ -14,6 +16,7 @@ export function secp256k1PublicKeyToRaw(publicKey: Uint8Array): Uint8Array { return getDiscv5Crypto().secp256k1.publicKeyConvert(publicKey, false); } +// biome-ignore lint/style/useNamingConvention: additional typecheck export const Secp256k1Keypair: IKeypairClass = class Secp256k1Keypair extends AbstractKeypair implements IKeypair { readonly type: KeyType; diff --git a/packages/discv5/src/keypair/types.ts b/packages/discv5/src/keypair/types.ts index bfd73f1b..76b30f18 100644 --- a/packages/discv5/src/keypair/types.ts +++ b/packages/discv5/src/keypair/types.ts @@ -1,4 +1,4 @@ -import { KeyType } from "@libp2p/interface"; +import type {KeyType} from "@libp2p/interface"; export interface IKeypair { type: KeyType; @@ -21,11 +21,13 @@ export abstract class AbstractKeypair { readonly _privateKey?: Uint8Array; readonly _publicKey?: Uint8Array; constructor(privateKey?: Uint8Array, publicKey?: Uint8Array) { - if ((this._privateKey = privateKey) && !this.privateKeyVerify()) { + this._privateKey = privateKey; + if (this._privateKey && !this.privateKeyVerify()) { throw new Error("Invalid private key"); } - if ((this._publicKey = publicKey) && !this.publicKeyVerify()) { - throw new Error("Invalid private key"); + this._publicKey = publicKey; + if (this._publicKey && !this.publicKeyVerify()) { + throw new Error("Invalid public key"); } } get privateKey(): Uint8Array { diff --git a/packages/discv5/src/libp2p/discv5.ts b/packages/discv5/src/libp2p/discv5.ts index f2ffa59d..1aeb3d54 100644 --- a/packages/discv5/src/libp2p/discv5.ts +++ b/packages/discv5/src/libp2p/discv5.ts @@ -1,18 +1,17 @@ +import type {ENR} from "@chainsafe/enr"; import { - PeerDiscovery, - PeerDiscoveryEvents, - peerDiscoverySymbol, - PeerInfo, - PrivateKey, + type PeerDiscovery, + type PeerDiscoveryEvents, + type PeerInfo, + type PrivateKey, TypedEventEmitter, + peerDiscoverySymbol, } from "@libp2p/interface"; -import { Multiaddr, multiaddr } from "@multiformats/multiaddr"; -import { ENR } from "@chainsafe/enr"; - -import { Discv5, ENRInput, SignableENRInput } from "../service/index.js"; -import { IDiscv5Config } from "../config/index.js"; -import { MetricsRegister } from "../metrics.js"; -import { BindAddrs } from "../transport/types.js"; +import {type Multiaddr, multiaddr} from "@multiformats/multiaddr"; +import type {IDiscv5Config} from "../config/index.js"; +import type {MetricsRegister} from "../metrics.js"; +import {Discv5, type ENRInput, type SignableENRInput} from "../service/index.js"; +import type {BindAddrs} from "../transport/types.js"; // Default to 0ms between automatic searches // 0ms is 'backwards compatible' with the prior behavior (always be searching) @@ -67,27 +66,29 @@ export class Discv5Discovery extends TypedEventEmitter impl [Symbol.toStringTag] = "discv5"; [peerDiscoverySymbol] = this; - public discv5: Discv5; - public searchInterval: number; + discv5: Discv5; + searchInterval: number; private started: NodeJS.Timer | boolean; private controller: AbortController; constructor(options: IDiscv5DiscoveryOptions) { super(); this.discv5 = Discv5.create({ - enr: options.enr, - privateKey: options.privateKey, bindAddrs: { ip4: options.bindAddrs.ip4 ? multiaddr(options.bindAddrs.ip4) : undefined, ip6: options.bindAddrs.ip6 ? multiaddr(options.bindAddrs.ip6) : undefined, } as BindAddrs, config: options, + enr: options.enr, metricsRegistry: options.metricsRegistry, + privateKey: options.privateKey, }); this.searchInterval = options.searchInterval ?? DEFAULT_SEARCH_INTERVAL_MS; this.started = false; this.controller = new AbortController(); - options.bootEnrs.forEach((bootEnr) => this.discv5.addEnr(bootEnr)); + for (const bootEnr of options.bootEnrs) { + this.discv5.addEnr(bootEnr); + } } async start(): Promise { @@ -126,7 +127,7 @@ export class Discv5Discovery extends TypedEventEmitter impl try { if (this.searchInterval === Infinity) return; await sleep(this.searchInterval, this.controller.signal); - } catch (e) { + } catch { return; } } @@ -157,8 +158,7 @@ async function sleep(ms: number, signal: AbortSignal): Promise { return new Promise((resolve, reject) => { if (signal.aborted) return reject(new Error()); - // eslint-disable-next-line @typescript-eslint/no-empty-function - let onDone: () => void = () => {}; + let onDone: () => void; const timeout = setTimeout(() => { onDone(); diff --git a/packages/discv5/src/message/create.ts b/packages/discv5/src/message/create.ts index 88b3098d..17ca73e3 100644 --- a/packages/discv5/src/message/create.ts +++ b/packages/discv5/src/message/create.ts @@ -1,14 +1,14 @@ -import { randomBytes, toBytes } from "@noble/hashes/utils"; -import { SequenceNumber, ENR } from "@chainsafe/enr"; +import type {ENR, SequenceNumber} from "@chainsafe/enr"; +import {randomBytes, utf8ToBytes} from "@noble/hashes/utils.js"; import { - RequestId, - IPingMessage, + type IFindNodeMessage, + type INodesMessage, + type IPingMessage, + type ITalkReqMessage, + type ITalkRespMessage, MessageType, - IFindNodeMessage, - INodesMessage, - ITalkReqMessage, - ITalkRespMessage, + type RequestId, } from "./types.js"; export function createRequestId(): RequestId { @@ -17,41 +17,41 @@ export function createRequestId(): RequestId { export function createPingMessage(enrSeq: SequenceNumber): IPingMessage { return { - type: MessageType.PING, - id: createRequestId(), enrSeq, + id: createRequestId(), + type: MessageType.PING, }; } export function createFindNodeMessage(distances: number[]): IFindNodeMessage { return { - type: MessageType.FINDNODE, - id: createRequestId(), distances, + id: createRequestId(), + type: MessageType.FINDNODE, }; } export function createNodesMessage(id: RequestId, total: number, enrs: ENR[]): INodesMessage { return { - type: MessageType.NODES, + enrs, id, total, - enrs, + type: MessageType.NODES, }; } export function createTalkRequestMessage(request: string | Uint8Array, protocol: string | Uint8Array): ITalkReqMessage { return { - type: MessageType.TALKREQ, id: createRequestId(), - protocol: toBytes(protocol), - request: toBytes(request), + protocol: protocol instanceof Uint8Array ? protocol : utf8ToBytes(protocol), + request: request instanceof Uint8Array ? request : utf8ToBytes(request), + type: MessageType.TALKREQ, }; } export function createTalkResponseMessage(requestId: RequestId, payload: Uint8Array): ITalkRespMessage { return { - type: MessageType.TALKRESP, id: requestId, response: payload, + type: MessageType.TALKRESP, }; } diff --git a/packages/discv5/src/message/decode.ts b/packages/discv5/src/message/decode.ts index 04659a2e..3d321b81 100644 --- a/packages/discv5/src/message/decode.ts +++ b/packages/discv5/src/message/decode.ts @@ -1,20 +1,20 @@ -import * as RLP from "@ethereumjs/rlp"; -import { bytesToBigint, ENR } from "@chainsafe/enr"; +import {ENR, bytesToBigint} from "@chainsafe/enr"; +import * as Rlp from "@ethereumjs/rlp"; +import {ipFromBytes} from "../util/ip.js"; import { - IPingMessage, - IPongMessage, - IFindNodeMessage, - INodesMessage, - IRegTopicMessage, - ITicketMessage, - IRegConfirmationMessage, - ITopicQueryMessage, - Message, + type IFindNodeMessage, + type INodesMessage, + type IPingMessage, + type IPongMessage, + type IRegConfirmationMessage, + type IRegTopicMessage, + type ITalkReqMessage, + type ITalkRespMessage, + type ITicketMessage, + type ITopicQueryMessage, + type Message, MessageType, - ITalkReqMessage, - ITalkRespMessage, } from "./types.js"; -import { ipFromBytes } from "../util/ip.js"; const ERR_INVALID_MESSAGE = "invalid message"; @@ -54,19 +54,19 @@ export function decode(data: Uint8Array): Message { } function decodePing(data: Uint8Array): IPingMessage { - const rlpRaw = RLP.decode(data.slice(1)) as Uint8Array[]; + const rlpRaw = Rlp.decode(data.slice(1)) as Uint8Array[]; if (!Array.isArray(rlpRaw) || rlpRaw.length !== 2) { throw new Error(ERR_INVALID_MESSAGE); } return { - type: MessageType.PING, - id: decodeRequestId(rlpRaw), enrSeq: bytesToBigint(rlpRaw[1]), + id: decodeRequestId(rlpRaw), + type: MessageType.PING, }; } function decodePong(data: Uint8Array): IPongMessage { - const rlpRaw = RLP.decode(data.slice(1)) as Uint8Array[]; + const rlpRaw = Rlp.decode(data.slice(1)) as Uint8Array[]; if (!Array.isArray(rlpRaw) || rlpRaw.length !== 4) { throw new Error(ERR_INVALID_MESSAGE); } @@ -84,15 +84,15 @@ function decodePong(data: Uint8Array): IPongMessage { const port = rlpRaw[3].length ? Number(bytesToBigint(rlpRaw[3])) : 0; return { - type: MessageType.PONG, - id: decodeRequestId(rlpRaw), + addr: {ip, port}, enrSeq: bytesToBigint(rlpRaw[1]), - addr: { ip, port }, + id: decodeRequestId(rlpRaw), + type: MessageType.PONG, }; } function decodeFindNode(data: Uint8Array): IFindNodeMessage { - const rlpRaw = RLP.decode(data.slice(1)) as Uint8Array[]; + const rlpRaw = Rlp.decode(data.slice(1)) as Uint8Array[]; if (!Array.isArray(rlpRaw) || rlpRaw.length !== 2) { throw new Error(ERR_INVALID_MESSAGE); } @@ -101,97 +101,97 @@ function decodeFindNode(data: Uint8Array): IFindNodeMessage { } const distances = (rlpRaw[1] as Uint8Array[]).map((x) => (x.length ? Number(bytesToBigint(x)) : 0)); return { - type: MessageType.FINDNODE, - id: decodeRequestId(rlpRaw), distances, + id: decodeRequestId(rlpRaw), + type: MessageType.FINDNODE, }; } function decodeNodes(data: Uint8Array): INodesMessage { - const rlpRaw = RLP.decode(data.slice(1)) as RLP.NestedUint8Array; + const rlpRaw = Rlp.decode(data.slice(1)) as Rlp.NestedUint8Array; if (!Array.isArray(rlpRaw) || rlpRaw.length !== 3 || !Array.isArray(rlpRaw[2])) { throw new Error(ERR_INVALID_MESSAGE); } return { - type: MessageType.NODES, + enrs: rlpRaw[2].map((enrRaw) => ENR.decodeFromValues(enrRaw as Uint8Array[])), id: decodeRequestId(rlpRaw as Uint8Array[]), total: rlpRaw[1].length ? Number(bytesToBigint(rlpRaw[1] as Uint8Array)) : 0, - enrs: rlpRaw[2].map((enrRaw) => ENR.decodeFromValues(enrRaw as Uint8Array[])), + type: MessageType.NODES, }; } function decodeTalkReq(data: Uint8Array): ITalkReqMessage { - const rlpRaw = RLP.decode(data.slice(1)) as Uint8Array[]; + const rlpRaw = Rlp.decode(data.slice(1)) as Uint8Array[]; if (!Array.isArray(rlpRaw) || rlpRaw.length !== 3) { throw new Error(ERR_INVALID_MESSAGE); } return { - type: MessageType.TALKREQ, id: decodeRequestId(rlpRaw), protocol: rlpRaw[1], request: rlpRaw[2], + type: MessageType.TALKREQ, }; } function decodeTalkResp(data: Uint8Array): ITalkRespMessage { - const rlpRaw = RLP.decode(data.slice(1)) as Uint8Array[]; + const rlpRaw = Rlp.decode(data.slice(1)) as Uint8Array[]; if (!Array.isArray(rlpRaw) || rlpRaw.length !== 2) { throw new Error(ERR_INVALID_MESSAGE); } return { - type: MessageType.TALKRESP, id: decodeRequestId(rlpRaw), response: rlpRaw[1], + type: MessageType.TALKRESP, }; } function decodeRegTopic(data: Uint8Array): IRegTopicMessage { - const rlpRaw = RLP.decode(data.slice(1)) as Uint8Array[]; + const rlpRaw = Rlp.decode(data.slice(1)) as Uint8Array[]; if (!Array.isArray(rlpRaw) || rlpRaw.length !== 4 || !Array.isArray(rlpRaw[2])) { throw new Error(ERR_INVALID_MESSAGE); } return { - type: MessageType.REGTOPIC, - id: decodeRequestId(rlpRaw), - topic: rlpRaw[1], enr: ENR.decodeFromValues(rlpRaw[2] as Uint8Array[]), + id: decodeRequestId(rlpRaw), ticket: rlpRaw[3], + topic: rlpRaw[1], + type: MessageType.REGTOPIC, }; } function decodeTicket(data: Uint8Array): ITicketMessage { - const rlpRaw = RLP.decode(data.slice(1)) as Uint8Array[]; + const rlpRaw = Rlp.decode(data.slice(1)) as Uint8Array[]; if (!Array.isArray(rlpRaw) || rlpRaw.length !== 3) { throw new Error(ERR_INVALID_MESSAGE); } return { - type: MessageType.TICKET, id: decodeRequestId(rlpRaw), ticket: rlpRaw[1], + type: MessageType.TICKET, waitTime: rlpRaw[2].length ? Number(bytesToBigint(rlpRaw[2] as Uint8Array)) : 0, }; } function decodeRegConfirmation(data: Uint8Array): IRegConfirmationMessage { - const rlpRaw = RLP.decode(data.slice(1)) as Uint8Array[]; + const rlpRaw = Rlp.decode(data.slice(1)) as Uint8Array[]; if (!Array.isArray(rlpRaw) || rlpRaw.length !== 2) { throw new Error(ERR_INVALID_MESSAGE); } return { - type: MessageType.REGCONFIRMATION, id: decodeRequestId(rlpRaw), topic: rlpRaw[1], + type: MessageType.REGCONFIRMATION, }; } function decodeTopicQuery(data: Uint8Array): ITopicQueryMessage { - const rlpRaw = RLP.decode(data.slice(1)) as Uint8Array[]; + const rlpRaw = Rlp.decode(data.slice(1)) as Uint8Array[]; if (!Array.isArray(rlpRaw) || rlpRaw.length !== 2) { throw new Error(ERR_INVALID_MESSAGE); } return { - type: MessageType.TOPICQUERY, id: rlpRaw[0], topic: rlpRaw[1], + type: MessageType.TOPICQUERY, }; } diff --git a/packages/discv5/src/message/encode.ts b/packages/discv5/src/message/encode.ts index e63a6eaf..cfe5f87c 100644 --- a/packages/discv5/src/message/encode.ts +++ b/packages/discv5/src/message/encode.ts @@ -1,21 +1,21 @@ -import * as RLP from "@ethereumjs/rlp"; -import { ipToBytes } from "../util/ip.js"; -import { concatBytes } from "@noble/hashes/utils"; +import {bigintToBytes} from "@chainsafe/enr"; +import * as Rlp from "@ethereumjs/rlp"; +import {concatBytes} from "@noble/hashes/utils.js"; +import {ipToBytes} from "../util/ip.js"; import { - IPingMessage, - IPongMessage, - IFindNodeMessage, - INodesMessage, - IRegTopicMessage, - ITicketMessage, - IRegConfirmationMessage, - ITopicQueryMessage, - Message, + type IFindNodeMessage, + type INodesMessage, + type IPingMessage, + type IPongMessage, + type IRegConfirmationMessage, + type IRegTopicMessage, + type ITalkReqMessage, + type ITalkRespMessage, + type ITicketMessage, + type ITopicQueryMessage, + type Message, MessageType, - ITalkReqMessage, - ITalkRespMessage, } from "./types.js"; -import { bigintToBytes } from "@chainsafe/enr"; export function encode(message: Message): Uint8Array { switch (message.type) { @@ -43,7 +43,7 @@ export function encode(message: Message): Uint8Array { } export function encodePingMessage(m: IPingMessage): Uint8Array { - return concatBytes(Uint8Array.from([MessageType.PING]), RLP.encode([m.id, bigintToBytes(m.enrSeq)])); + return concatBytes(Uint8Array.from([MessageType.PING]), Rlp.encode([m.id, bigintToBytes(m.enrSeq)])); } export function encodePongMessage(m: IPongMessage): Uint8Array { @@ -52,44 +52,44 @@ export function encodePongMessage(m: IPongMessage): Uint8Array { } return concatBytes( Uint8Array.from([MessageType.PONG]), - RLP.encode([m.id, bigintToBytes(m.enrSeq), ipToBytes(m.addr.ip), m.addr.port]) + Rlp.encode([m.id, bigintToBytes(m.enrSeq), ipToBytes(m.addr.ip), m.addr.port]) ); } export function encodeFindNodeMessage(m: IFindNodeMessage): Uint8Array { - return concatBytes(Uint8Array.from([MessageType.FINDNODE]), RLP.encode([m.id, m.distances])); + return concatBytes(Uint8Array.from([MessageType.FINDNODE]), Rlp.encode([m.id, m.distances])); } export function encodeNodesMessage(m: INodesMessage): Uint8Array { return concatBytes( Uint8Array.from([MessageType.NODES]), - RLP.encode([m.id, m.total, m.enrs.map((enr) => enr.encodeToValues())]) + Rlp.encode([m.id, m.total, m.enrs.map((enr) => enr.encodeToValues())]) ); } export function encodeTalkReqMessage(m: ITalkReqMessage): Uint8Array { - return concatBytes(Uint8Array.from([MessageType.TALKREQ]), RLP.encode([m.id, m.protocol, m.request])); + return concatBytes(Uint8Array.from([MessageType.TALKREQ]), Rlp.encode([m.id, m.protocol, m.request])); } export function encodeTalkRespMessage(m: ITalkRespMessage): Uint8Array { - return concatBytes(Uint8Array.from([MessageType.TALKRESP]), RLP.encode([m.id, m.response])); + return concatBytes(Uint8Array.from([MessageType.TALKRESP]), Rlp.encode([m.id, m.response])); } export function encodeRegTopicMessage(m: IRegTopicMessage): Uint8Array { return concatBytes( Uint8Array.from([MessageType.REGTOPIC]), - RLP.encode([m.id, m.topic, m.enr.encodeToValues(), m.ticket]) + Rlp.encode([m.id, m.topic, m.enr.encodeToValues(), m.ticket]) ); } export function encodeTicketMessage(m: ITicketMessage): Uint8Array { - return concatBytes(Uint8Array.from([MessageType.TICKET]), RLP.encode([m.id, m.ticket, m.waitTime])); + return concatBytes(Uint8Array.from([MessageType.TICKET]), Rlp.encode([m.id, m.ticket, m.waitTime])); } export function encodeRegConfirmMessage(m: IRegConfirmationMessage): Uint8Array { - return concatBytes(Uint8Array.from([MessageType.REGCONFIRMATION]), RLP.encode([m.id, m.topic])); + return concatBytes(Uint8Array.from([MessageType.REGCONFIRMATION]), Rlp.encode([m.id, m.topic])); } export function encodeTopicQueryMessage(m: ITopicQueryMessage): Uint8Array { - return concatBytes(Uint8Array.from([MessageType.TOPICQUERY]), RLP.encode([m.id, m.topic])); + return concatBytes(Uint8Array.from([MessageType.TOPICQUERY]), Rlp.encode([m.id, m.topic])); } diff --git a/packages/discv5/src/message/index.ts b/packages/discv5/src/message/index.ts index 9a84fc75..740a14b6 100644 --- a/packages/discv5/src/message/index.ts +++ b/packages/discv5/src/message/index.ts @@ -1,5 +1,5 @@ -export * from "./types.js"; -export * from "./encode.js"; -export * from "./decode.js"; export * from "./create.js"; +export * from "./decode.js"; +export * from "./encode.js"; +export * from "./types.js"; export * from "./util.js"; diff --git a/packages/discv5/src/message/types.ts b/packages/discv5/src/message/types.ts index 14c48093..e7a303f1 100644 --- a/packages/discv5/src/message/types.ts +++ b/packages/discv5/src/message/types.ts @@ -1,5 +1,6 @@ -import { SequenceNumber, ENR } from "@chainsafe/enr"; -import { SocketAddress } from "../util/ip.js"; +/** biome-ignore-all lint/style/useNamingConvention: Preexisting code */ +import type {ENR, SequenceNumber} from "@chainsafe/enr"; +import type {SocketAddress} from "../util/ip.js"; export type RequestId = Uint8Array; diff --git a/packages/discv5/src/message/util.ts b/packages/discv5/src/message/util.ts index a8baebaf..4115f00e 100644 --- a/packages/discv5/src/message/util.ts +++ b/packages/discv5/src/message/util.ts @@ -1,4 +1,4 @@ -import { MessageType, RequestMessage, ResponseMessage } from "./types.js"; +import {MessageType, type RequestMessage, type ResponseMessage} from "./types.js"; export function requestMatchesResponse(req: RequestMessage, res: ResponseMessage): boolean { switch (req.type) { diff --git a/packages/discv5/src/metrics.ts b/packages/discv5/src/metrics.ts index bd143142..72610538 100644 --- a/packages/discv5/src/metrics.ts +++ b/packages/discv5/src/metrics.ts @@ -5,7 +5,7 @@ export interface MetricsRegister { type GaugeConfig = { name: string; help: string; -} & (NoLabels extends Labels ? { labelNames?: never } : { labelNames: [LabelKeys, ...LabelKeys[]] }); +} & (NoLabels extends Labels ? {labelNames?: never} : {labelNames: [LabelKeys, ...LabelKeys[]]}); type NoLabels = Record; type LabelsGeneric = Record; @@ -22,8 +22,8 @@ export interface IDiscv5Metrics { connectedPeerCount: Gauge; lookupCount: Gauge; - sentMessageCount: Gauge<{ type: string }>; - rcvdMessageCount: Gauge<{ type: string }>; + sentMessageCount: Gauge<{type: string}>; + rcvdMessageCount: Gauge<{type: string}>; rateLimitHitIP: Gauge; rateLimitHitTotal: Gauge; @@ -34,50 +34,49 @@ export type Metrics = ReturnType; /** * Discv5 metrics */ -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/explicit-function-return-type export function createDiscv5Metrics(register: MetricsRegister) { return { - /** Total size of the kad table */ - kadTableSize: register.gauge({ - name: "discv5_kad_table_size", - help: "Total size of the discv5 kad table", - }), - /** Total number of attempted lookups */ - lookupCount: register.gauge({ - name: "discv5_lookup_count", - help: "Total count of discv5 lookups", - }), /** Total number of active sessions */ activeSessionCount: register.gauge({ - name: "discv5_active_session_count", help: "Count of the discv5 active sessions", + name: "discv5_active_session_count", }), /** Total number of connected peers */ connectedPeerCount: register.gauge({ - name: "discv5_connected_peer_count", help: "Count of the discv5 connected peers", + name: "discv5_connected_peer_count", }), - /** Total number messages sent by message type */ - sentMessageCount: register.gauge<{ type: string }>({ - name: "discv5_sent_message_count", - help: "Count of the discv5 messages sent by message type", - labelNames: ["type"], + /** Total size of the kad table */ + kadTableSize: register.gauge({ + help: "Total size of the discv5 kad table", + name: "discv5_kad_table_size", }), - /** Total number messages received by message type */ - rcvdMessageCount: register.gauge<{ type: string }>({ - name: "discv5_rcvd_message_count", - help: "Count of the discv5 messages received by message type", - labelNames: ["type"], + /** Total number of attempted lookups */ + lookupCount: register.gauge({ + help: "Total count of discv5 lookups", + name: "discv5_lookup_count", }), /** Total count of rate limit hits by IP */ rateLimitHitIP: register.gauge({ - name: "discv5_rate_limit_hit_ip", help: "Total count of rate limit hits by IP", + name: "discv5_rate_limit_hit_ip", }), /** Total count of rate limit hits by total requests */ rateLimitHitTotal: register.gauge({ - name: "discv5_rate_limit_hit_total", help: "Total count of rate limit hits by total requests", + name: "discv5_rate_limit_hit_total", + }), + /** Total number messages received by message type */ + rcvdMessageCount: register.gauge<{type: string}>({ + help: "Count of the discv5 messages received by message type", + labelNames: ["type"], + name: "discv5_rcvd_message_count", + }), + /** Total number messages sent by message type */ + sentMessageCount: register.gauge<{type: string}>({ + help: "Count of the discv5 messages sent by message type", + labelNames: ["type"], + name: "discv5_sent_message_count", }), }; } diff --git a/packages/discv5/src/packet/create.ts b/packages/discv5/src/packet/create.ts index dc563d79..1c4b04e1 100644 --- a/packages/discv5/src/packet/create.ts +++ b/packages/discv5/src/packet/create.ts @@ -1,41 +1,41 @@ -import { randomBytes } from "@noble/hashes/utils"; -import { NodeId, SequenceNumber } from "@chainsafe/enr"; -import { ID_NONCE_SIZE, MASKING_IV_SIZE, NONCE_SIZE } from "./constants.js"; -import { encodeMessageAuthdata, encodeWhoAreYouAuthdata } from "./encode.js"; -import { IHeader, IPacket, PacketType } from "./types.js"; +import type {NodeId, SequenceNumber} from "@chainsafe/enr"; +import {randomBytes} from "@noble/hashes/utils.js"; +import {ID_NONCE_SIZE, MASKING_IV_SIZE, NONCE_SIZE} from "./constants.js"; +import {encodeMessageAuthdata, encodeWhoAreYouAuthdata} from "./encode.js"; +import {type IHeader, type IPacket, PacketType} from "./types.js"; export function createHeader(flag: PacketType, authdata: Uint8Array, nonce = randomBytes(NONCE_SIZE)): IHeader { return { - protocolId: "discv5", - version: 1, + authdata, + authdataSize: authdata.length, flag, nonce: nonce, - authdataSize: authdata.length, - authdata, + protocolId: "discv5", + version: 1, }; } export function createRandomPacket(srcId: NodeId): IPacket { - const authdata = encodeMessageAuthdata({ srcId }); + const authdata = encodeMessageAuthdata({srcId}); const header = createHeader(PacketType.Message, authdata); const maskingIv = randomBytes(MASKING_IV_SIZE); const message = randomBytes(44); return { - maskingIv, header, + maskingIv, message, }; } export function createWhoAreYouPacket(nonce: Uint8Array, enrSeq: SequenceNumber): IPacket { const idNonce = randomBytes(ID_NONCE_SIZE); - const authdata = encodeWhoAreYouAuthdata({ idNonce, enrSeq }); + const authdata = encodeWhoAreYouAuthdata({enrSeq, idNonce}); const header = createHeader(PacketType.WhoAreYou, authdata, nonce); const maskingIv = randomBytes(MASKING_IV_SIZE); const message = Buffer.alloc(0); return { - maskingIv, header, + maskingIv, message, }; } diff --git a/packages/discv5/src/packet/encode.ts b/packages/discv5/src/packet/encode.ts index 74a5202a..d1ad6c93 100644 --- a/packages/discv5/src/packet/encode.ts +++ b/packages/discv5/src/packet/encode.ts @@ -1,20 +1,23 @@ import Crypto from "node:crypto"; - -import { bytesToNumber, CodeError, numberToBytes } from "../util/index.js"; +import {bigintToBytes, bytesToBigint} from "@chainsafe/enr"; +import {bytesToHex, bytesToUtf8, concatBytes, hexToBytes, utf8ToBytes} from "ethereum-cryptography/utils.js"; +import {CodeError, bytesToNumber, numberToBytes} from "../util/index.js"; import { AUTHDATA_SIZE_SIZE, EPH_KEY_SIZE_SIZE, + ERR_INVALID_AUTHDATA_SIZE, ERR_INVALID_FLAG, ERR_INVALID_PROTOCOL_ID, ERR_INVALID_VERSION, - ERR_INVALID_AUTHDATA_SIZE, ERR_TOO_LARGE, ERR_TOO_SMALL, FLAG_SIZE, + ID_NONCE_SIZE, MASKING_IV_SIZE, MASKING_KEY_SIZE, MAX_PACKET_SIZE, MESSAGE_AUTHDATA_SIZE, + MIN_HANDSHAKE_AUTHDATA_SIZE, MIN_PACKET_SIZE, NONCE_SIZE, PROTOCOL_SIZE, @@ -22,12 +25,15 @@ import { STATIC_HEADER_SIZE, VERSION_SIZE, WHOAREYOU_AUTHDATA_SIZE, - ID_NONCE_SIZE, - MIN_HANDSHAKE_AUTHDATA_SIZE, } from "./constants.js"; -import { IHandshakeAuthdata, IHeader, IMessageAuthdata, IPacket, IWhoAreYouAuthdata, PacketType } from "./types.js"; -import { bytesToHex, concatBytes, hexToBytes, utf8ToBytes, bytesToUtf8 } from "ethereum-cryptography/utils.js"; -import { bigintToBytes, bytesToBigint } from "@chainsafe/enr"; +import { + type IHandshakeAuthdata, + type IHeader, + type IMessageAuthdata, + type IPacket, + type IWhoAreYouAuthdata, + PacketType, +} from "./types.js"; export function encodePacket(destId: string, packet: IPacket): Uint8Array { return concatBytes(packet.maskingIv, encodeHeader(destId, packet.maskingIv, packet.header), packet.message); @@ -62,8 +68,8 @@ export function decodePacket(srcId: string, data: Uint8Array): IPacket { const message = data.slice(MASKING_IV_SIZE + headerBuf.length); return { - maskingIv, header, + maskingIv, message, messageAd: concatBytes(maskingIv, headerBuf), }; @@ -111,12 +117,12 @@ export function decodeHeader(srcId: string, maskingIv: Uint8Array, data: Uint8Ar return [ { - protocolId, - version, + authdata, + authdataSize, flag, nonce, - authdataSize, - authdata, + protocolId, + version, }, Buffer.concat([staticHeaderBuf, authdata]), ]; @@ -151,8 +157,8 @@ export function decodeWhoAreYouAuthdata(data: Uint8Array): IWhoAreYouAuthdata { throw new CodeError(`Invalid authdata length: ${data.length}`, ERR_INVALID_AUTHDATA_SIZE); } return { - idNonce: data.slice(0, ID_NONCE_SIZE), enrSeq: bytesToBigint(data.slice(ID_NONCE_SIZE)), + idNonce: data.slice(0, ID_NONCE_SIZE), }; } @@ -176,12 +182,12 @@ export function decodeHandshakeAuthdata(data: Uint8Array): IHandshakeAuthdata { const ephPubkey = data.slice(34 + sigSize, 34 + sigSize + ephKeySize); const record = data.slice(34 + sigSize + ephKeySize); return { - srcId, - sigSize, ephKeySize, - idSignature, ephPubkey, + idSignature, record, + sigSize, + srcId, }; } diff --git a/packages/discv5/src/packet/index.ts b/packages/discv5/src/packet/index.ts index 09108bf6..448feaf5 100644 --- a/packages/discv5/src/packet/index.ts +++ b/packages/discv5/src/packet/index.ts @@ -1,4 +1,4 @@ export * from "./constants.js"; -export * from "./types.js"; -export * from "./encode.js"; export * from "./create.js"; +export * from "./encode.js"; +export * from "./types.js"; diff --git a/packages/discv5/src/packet/types.ts b/packages/discv5/src/packet/types.ts index dbc95385..7f2d5282 100644 --- a/packages/discv5/src/packet/types.ts +++ b/packages/discv5/src/packet/types.ts @@ -1,4 +1,4 @@ -import { NodeId } from "@chainsafe/enr"; +import type {NodeId} from "@chainsafe/enr"; // DISCV5 message packet types @@ -10,13 +10,13 @@ export enum PacketType { /** * Sent when the recipient of an ordinary message packet cannot decrypt/authenticate the packet's message */ - WhoAreYou, + WhoAreYou = 1, /** * Sent following a WHOAREYOU. * These packets establish a new session and carry handshake related data * in addition to the encrypted/authenticated message */ - Handshake, + Handshake = 2, } export interface IStaticHeader { diff --git a/packages/discv5/src/rateLimit/index.ts b/packages/discv5/src/rateLimit/index.ts index dbc99cf7..b0aa74e1 100644 --- a/packages/discv5/src/rateLimit/index.ts +++ b/packages/discv5/src/rateLimit/index.ts @@ -1,5 +1,5 @@ -import { IDiscv5Metrics } from "../metrics.js"; -import { RateLimiterGRCA, RateLimiterQuota } from "./rateLimiterGRCA.js"; +import type {IDiscv5Metrics} from "../metrics.js"; +import {RateLimiterGRCA, type RateLimiterQuota} from "./rateLimiterGRCA.js"; type IPAddress = string; @@ -28,7 +28,10 @@ export class RateLimiter implements IRateLimiter { private readonly bannedIPs = new Map(); private readonly expectedResponsesByIP = new Map(); - constructor(opts: RateLimiterOpts, private readonly metrics: IDiscv5Metrics | null) { + constructor( + opts: RateLimiterOpts, + private readonly metrics: IDiscv5Metrics | null + ) { this.rateLimiterGlobal = RateLimiterGRCA.fromQuota(opts.globalQuota); this.rateLimiterIP = RateLimiterGRCA.fromQuota(opts.byIPQuota); } diff --git a/packages/discv5/src/rateLimit/rateLimiterGRCA.ts b/packages/discv5/src/rateLimit/rateLimiterGRCA.ts index 7dc36395..a445d946 100644 --- a/packages/discv5/src/rateLimit/rateLimiterGRCA.ts +++ b/packages/discv5/src/rateLimit/rateLimiterGRCA.ts @@ -48,6 +48,7 @@ export class RateLimiterGRCA { allows(key: Key, tokens: number, msSinceStart?: number): boolean { if (msSinceStart === undefined) { + // biome-ignore lint/style/noParameterAssign: Preexisting code msSinceStart = Date.now() - this.startTimeMs; } diff --git a/packages/discv5/src/service/addrVotes.ts b/packages/discv5/src/service/addrVotes.ts index 52f84c70..47ee91bc 100644 --- a/packages/discv5/src/service/addrVotes.ts +++ b/packages/discv5/src/service/addrVotes.ts @@ -1,5 +1,5 @@ -import { NodeId } from "@chainsafe/enr"; -import { SocketAddress } from "../util/ip.js"; +import type {NodeId} from "@chainsafe/enr"; +import type {SocketAddress} from "../util/ip.js"; /** Serialized representation of the IP:port vote from the Pong message */ type VoteID = string; @@ -8,7 +8,7 @@ const MAX_VOTES = 200; export class AddrVotes { /** Bounded by `MAX_VOTES`, on new votes evicts the oldest votes */ - private readonly votes = new Map(); + private readonly votes = new Map(); /** Bounded by votes, if the vote count reaches 0, its key is deleted */ private readonly tallies = new Map(); @@ -25,7 +25,8 @@ export class AddrVotes { if (prevVote?.socketAddrStr === socketAddrStr) { // Same vote, ignore return false; - } else if (prevVote !== undefined) { + } + if (prevVote !== undefined) { // If there was a previous vote, remove from tally const prevVoteTally = (this.tallies.get(prevVote.socketAddrStr) ?? 0) - 1; if (prevVoteTally <= 0) { @@ -46,7 +47,7 @@ export class AddrVotes { // Persist vote this.tallies.set(socketAddrStr, currentTally); - this.votes.set(voter, { socketAddrStr: socketAddrStr, unixTsMs: Date.now() }); + this.votes.set(voter, {socketAddrStr: socketAddrStr, unixTsMs: Date.now()}); // If there are too many votes, remove the oldest if (this.votes.size > MAX_VOTES) { diff --git a/packages/discv5/src/service/index.ts b/packages/discv5/src/service/index.ts index eb6eb0fa..86a1c0de 100644 --- a/packages/discv5/src/service/index.ts +++ b/packages/discv5/src/service/index.ts @@ -1,2 +1,2 @@ -export * from "./types.js"; export * from "./service.js"; +export * from "./types.js"; diff --git a/packages/discv5/src/service/service.ts b/packages/discv5/src/service/service.ts index a35062e3..fe2decf9 100644 --- a/packages/discv5/src/service/service.ts +++ b/packages/discv5/src/service/service.ts @@ -1,74 +1,79 @@ -import { EventEmitter } from "events"; -import debug from "debug"; -import { randomBytes } from "@noble/hashes/utils"; -import { Multiaddr } from "@multiformats/multiaddr"; -import { PeerId, PrivateKey } from "@libp2p/interface"; +import {EventEmitter} from "node:events"; import { - createPeerIdFromPublicKey, ENR, - NodeId, MAX_RECORD_SIZE, - createNodeId, + type NodeId, SignableENR, bytesToBigint, + createNodeId, + createPeerIdFromPublicKey, } from "@chainsafe/enr"; - -import { BindAddrs, IPMode, ITransportService, UDPTransportService } from "../transport/index.js"; -import { MAX_PACKET_SIZE } from "../packet/index.js"; -import { ConnectionDirection, RequestErrorType, ResponseErrorType, SessionService } from "../session/index.js"; -import { IKeypair, createKeypair } from "../keypair/index.js"; +import type {PeerId, PrivateKey} from "@libp2p/interface"; +import type {Multiaddr} from "@multiformats/multiaddr"; +import {randomBytes} from "@noble/hashes/utils.js"; +import debug from "weald"; +import {type IDiscv5Config, defaultConfig} from "../config/index.js"; import { EntryStatus, InsertResult, KademliaRoutingTable, - log2Distance, Lookup, UpdateResult, + log2Distance, } from "../kademlia/index.js"; +import {type IKeypair, createKeypair} from "../keypair/index.js"; import { - RequestMessage, - ResponseMessage, - createPingMessage, + type IFindNodeMessage, + type INodesMessage, + type IPingMessage, + type IPongMessage, + type ITalkReqMessage, + type ITalkRespMessage, + MessageType, + type RequestId, + type RequestMessage, + type ResponseMessage, createFindNodeMessage, createNodesMessage, - MessageType, - IFindNodeMessage, - INodesMessage, - IPongMessage, - IPingMessage, - requestMatchesResponse, - ITalkReqMessage, - ITalkRespMessage, + createPingMessage, createTalkRequestMessage, createTalkResponseMessage, - RequestId, + requestMatchesResponse, } from "../message/index.js"; -import { AddrVotes } from "./addrVotes.js"; -import { CodeError } from "../util/index.js"; -import { IDiscv5Config, defaultConfig } from "../config/index.js"; -import { createNodeContact, getNodeAddress, getNodeId, INodeAddress, NodeContact } from "../session/nodeInfo.js"; +import {type IDiscv5Metrics, type MetricsRegister, createDiscv5Metrics} from "../metrics.js"; +import {MAX_PACKET_SIZE} from "../packet/index.js"; +import {RateLimiter, type RateLimiterOpts} from "../rateLimit/index.js"; +import {ConnectionDirection, RequestErrorType, ResponseErrorType, SessionService} from "../session/index.js"; import { - ConnectionStatus, - ConnectionStatusType, - Discv5EventEmitter, - ENRInput, - IActiveRequest, - INodesResponse, - PongResponse, - ResponseType, - SignableENRInput, - toResponseType, -} from "./types.js"; -import { RateLimiter, RateLimiterOpts } from "../rateLimit/index.js"; + type INodeAddress, + type NodeContact, + createNodeContact, + getNodeAddress, + getNodeId, +} from "../session/nodeInfo.js"; +import {type BindAddrs, type IPMode, type ITransportService, UDPTransportService} from "../transport/index.js"; +import {CodeError} from "../util/index.js"; import { - multiaddrFromSocketAddress, + getSocketAddressMultiaddrOnENR, + getSocketAddressOnENR, isEqualSocketAddress, + multiaddrFromSocketAddress, multiaddrToSocketAddress, setSocketAddressOnENR, - getSocketAddressOnENR, - getSocketAddressMultiaddrOnENR, } from "../util/ip.js"; -import { createDiscv5Metrics, IDiscv5Metrics, MetricsRegister } from "../metrics.js"; +import {AddrVotes} from "./addrVotes.js"; +import { + type ConnectionStatus, + ConnectionStatusType, + type Discv5EventEmitter, + type ENRInput, + type IActiveRequest, + type INodesResponse, + type PongResponse, + type ResponseType, + type SignableENRInput, + toResponseType, +} from "./types.js"; const log = debug("discv5:service"); @@ -110,11 +115,11 @@ export interface IDiscv5CreateOptions { * * Additionally, the service offers events when peers are added to the peer table or discovered via lookup. */ -export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { +export class Discv5 extends (EventEmitter as {new (): Discv5EventEmitter}) { /** * Session service that establishes sessions with peers */ - public sessionService: SessionService; + sessionService: SessionService; /** * Configuration @@ -193,11 +198,9 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { this.addrVotes = new AddrVotes(config.addrVotesToUpdateEnr); if (metrics) { this.metrics = metrics; - // eslint-disable-next-line @typescript-eslint/no-this-alias - const discv5 = this; - metrics.kadTableSize.collect = () => metrics.kadTableSize.set(discv5.kbuckets.size); - metrics.connectedPeerCount.collect = () => metrics.connectedPeerCount.set(discv5.connectedPeers.size); - metrics.activeSessionCount.collect = () => metrics.activeSessionCount.set(discv5.sessionService.sessionsSize()); + metrics.kadTableSize.collect = () => metrics.kadTableSize.set(this.kbuckets.size); + metrics.connectedPeerCount.collect = () => metrics.connectedPeerCount.set(this.connectedPeers.size); + metrics.activeSessionCount.collect = () => metrics.activeSessionCount.set(this.sessionService.sessionsSize()); metrics.lookupCount.collect = () => metrics.lookupCount.set(this.nextLookupId - 1); } this.ipMode = this.sessionService.transport.ipMode; @@ -210,18 +213,18 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { * @param privateKey the PrivateKey that identifies the enr * @param multiaddr The multiaddr which contains the network interface and port to which the UDP server binds */ - public static create(opts: IDiscv5CreateOptions): Discv5 { - const { enr, privateKey, bindAddrs, config = {}, metricsRegistry, transport } = opts; - const fullConfig = { ...defaultConfig, ...config }; + static create(opts: IDiscv5CreateOptions): Discv5 { + const {enr, privateKey, bindAddrs, config = {}, metricsRegistry, transport} = opts; + const fullConfig = {...defaultConfig, ...config}; const metrics = metricsRegistry ? createDiscv5Metrics(metricsRegistry) : undefined; - const keypair = createKeypair({ type: privateKey.type, privateKey: privateKey.raw }); + const keypair = createKeypair({privateKey: privateKey.raw, type: privateKey.type}); const decodedEnr = typeof enr === "string" ? SignableENR.decodeTxt(enr, privateKey.raw) : enr; const rateLimiter = opts.rateLimiterOpts && new RateLimiter(opts.rateLimiterOpts, metrics ?? null); const sessionService = new SessionService( fullConfig, decodedEnr, keypair, - transport ?? new UDPTransportService({ bindAddrs, nodeId: decodedEnr.nodeId, rateLimiter }) + transport ?? new UDPTransportService({bindAddrs, nodeId: decodedEnr.nodeId, rateLimiter}) ); return new Discv5(fullConfig, sessionService, metrics); } @@ -229,7 +232,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { /** * Starts the service and adds all initial bootstrap peers to be considered. */ - public async start(): Promise { + async start(): Promise { if (this.started) { log("Starting discv5 service failed -- already started"); return; @@ -249,7 +252,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { /** * Stops the service, closing any underlying networking activity. */ - public async stop(): Promise { + async stop(): Promise { if (!this.started) { log("Stopping discv5 service -- already stopped"); return; @@ -258,13 +261,17 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { this.kbuckets.off("pendingEviction", this.onPendingEviction); this.kbuckets.off("appliedEviction", this.onAppliedEviction); this.kbuckets.clear(); - this.activeLookups.forEach((lookup) => lookup.stop()); + for (const lookup of this.activeLookups.values()) { + lookup.stop(); + } this.activeLookups.clear(); this.nextLookupId = 1; this.activeRequests.clear(); this.activeNodesResponses.clear(); this.addrVotes.clear(); - this.connectedPeers.forEach((intervalId) => clearInterval(intervalId)); + for (const intervalId of this.connectedPeers.values()) { + clearInterval(intervalId); + } this.connectedPeers.clear(); this.sessionService.off("established", this.onEstablished); this.sessionService.off("request", this.handleRpcRequest); @@ -275,7 +282,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { this.started = false; } - public isStarted(): boolean { + isStarted(): boolean { return this.started; } @@ -286,12 +293,12 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { * so that they can be used immediately in following DHT operations involving one of these peers, * without having to dial them upfront. */ - public addEnr(enr: ENRInput): void { + addEnr(enr: ENRInput): void { let decodedEnr: ENR; try { decodedEnr = typeof enr === "string" ? ENR.decodeTxt(enr) : enr; decodedEnr.encode(); - } catch (e) { + } catch { log("Unable to add enr: %o", enr); return; } @@ -300,45 +307,45 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { } } - public get bindAddrs(): Multiaddr[] { + get bindAddrs(): Multiaddr[] { return this.sessionService.transport.bindAddrs; } - public get keypair(): IKeypair { + get keypair(): IKeypair { return this.sessionService.keypair; } - public get peerId(): PeerId { + get peerId(): PeerId { return createPeerIdFromPublicKey(this.keypair.type, this.keypair.publicKey); } - public get enr(): SignableENR { + get enr(): SignableENR { return this.sessionService.enr; } - public get connectedPeerCount(): number { + get connectedPeerCount(): number { return this.connectedPeers.size; } - public getKadValue(nodeId: NodeId): ENR | undefined { + getKadValue(nodeId: NodeId): ENR | undefined { return this.kbuckets.getValue(nodeId); } /** * Return all ENRs of nodes currently contained in buckets of the kad routing table */ - public kadValues(): ENR[] { + kadValues(): ENR[] { return this.kbuckets.values(); } - public async findRandomNode(): Promise { + async findRandomNode(): Promise { return await this.findNode(createNodeId(randomBytes(32))); } /** * Starts an iterative FIND_NODE lookup */ - public async findNode(target: NodeId): Promise { + async findNode(target: NodeId): Promise { const lookupId = this.nextLookupId; log("Starting a new lookup. Id: %d", lookupId); if (this.nextLookupId >= 2 ** 32) { @@ -368,7 +375,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { * * This includes ENRs from any ongoing lookups not yet in the kad table */ - public findEnr(nodeId: NodeId): ENR | undefined { + findEnr(nodeId: NodeId): ENR | undefined { // check if we know this node id in our routing table const enr = this.kbuckets.getValue(nodeId); if (enr) { @@ -387,18 +394,18 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { /** * Send FINDNODE message to remote and returns response */ - public async sendFindNode(remote: ENR | Multiaddr, distances: number[]): Promise { + async sendFindNode(remote: ENR | Multiaddr, distances: number[]): Promise { const contact = createNodeContact(remote, this.ipMode); const request = createFindNodeMessage(distances); return await new Promise((resolve, reject) => { this.sendRpcRequest({ - contact, - request, callbackPromise: { - resolve: resolve as (val: ENR[]) => void, reject, + resolve: resolve as (val: ENR[]) => void, }, + contact, + request, }); }); } @@ -406,22 +413,18 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { /** * Send TALKREQ message to dstId and returns response */ - public async sendTalkReq( - remote: ENR | Multiaddr, - payload: Uint8Array, - protocol: string | Uint8Array - ): Promise { + async sendTalkReq(remote: ENR | Multiaddr, payload: Uint8Array, protocol: string | Uint8Array): Promise { const contact = createNodeContact(remote, this.ipMode); const request = createTalkRequestMessage(payload, protocol); return await new Promise((resolve, reject) => { this.sendRpcRequest({ - contact, - request, callbackPromise: { - resolve: resolve as (val: Uint8Array) => void, reject, + resolve: resolve as (val: Uint8Array) => void, }, + contact, + request, }); }); } @@ -429,7 +432,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { /** * Send TALKRESP message to requesting node */ - public async sendTalkResp(remote: INodeAddress, requestId: RequestId, payload: Uint8Array): Promise { + async sendTalkResp(remote: INodeAddress, requestId: RequestId, payload: Uint8Array): Promise { const msg = createTalkResponseMessage(requestId, payload); this.sendRpcResponse(remote, msg); } @@ -437,25 +440,25 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { /** * Hack to get debug logs to work in browser */ - public enableLogs(): void { + enableLogs(): void { debug.enable("discv5*"); } /** * Sends a PING request to a node and returns response */ - public async sendPing(nodeAddr: ENR | Multiaddr): Promise { + async sendPing(nodeAddr: ENR | Multiaddr): Promise { const contact = createNodeContact(nodeAddr, this.ipMode); const request = createPingMessage(this.enr.seq); return await new Promise((resolve, reject) => { this.sendRpcRequest({ - contact, - request, callbackPromise: { - resolve: resolve as (val: PongResponse) => void, reject, + resolve: resolve as (val: PongResponse) => void, }, + contact, + request, }); }); } @@ -475,7 +478,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { * Request an external node's ENR */ private requestEnr(contact: NodeContact): void { - this.sendRpcRequest({ request: createFindNodeMessage([0]), contact }); + this.sendRpcRequest({contact, request: createFindNodeMessage([0])}); } /** @@ -491,8 +494,8 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { this.sendRpcRequest({ contact: createNodeContact(enr, this.ipMode), - request, lookupId, + request, }); } @@ -512,7 +515,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { log("Sending %s to node: %o", MessageType[activeRequest.request.type], nodeAddr); try { this.sessionService.sendRequest(activeRequest.contact, activeRequest.request); - this.metrics?.sentMessageCount.inc({ type: MessageType[activeRequest.request.type] }); + this.metrics?.sentMessageCount.inc({type: MessageType[activeRequest.request.type]}); } catch (e) { this.activeRequests.delete(bytesToBigint(activeRequest.request.id)); log("Error sending RPC to node: %o, :Error: %s", nodeAddr, (e as Error).message); @@ -526,7 +529,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { log("Sending %s to node: %o", MessageType[response.type], nodeAddr); try { this.sessionService.sendResponse(nodeAddr, response); - this.metrics?.sentMessageCount.inc({ type: MessageType[response.type] }); + this.metrics?.sentMessageCount.inc({type: MessageType[response.type]}); } catch (e) { log("Error sending RPC to node: %o, :Error: %s", nodeAddr, (e as Error).message); } @@ -651,16 +654,14 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { // If any of the discovered nodes are in the routing table, // and there contains an older ENR, update it. const entry = this.kbuckets.getWithPending(enr.nodeId); - if (entry) { - if (entry.value.seq < enr.seq) { - switch (this.kbuckets.update(enr)) { - case UpdateResult.FailedBucketFull: - case UpdateResult.FailedKeyNonExistent: { - clearInterval(this.connectedPeers.get(enr.nodeId) as NodeJS.Timeout); - this.connectedPeers.delete(enr.nodeId); - log("Failed to update discovered ENR. Node: %s", enr.nodeId); - continue; - } + if (entry && entry.value.seq < enr.seq) { + switch (this.kbuckets.update(enr)) { + case UpdateResult.FailedBucketFull: + case UpdateResult.FailedKeyNonExistent: { + clearInterval(this.connectedPeers.get(enr.nodeId) as NodeJS.Timeout); + this.connectedPeers.delete(enr.nodeId); + log("Failed to update discovered ENR. Node: %s", enr.nodeId); + continue; } } } @@ -700,7 +701,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { // process events from the session service private onEstablished = ( - nodeAddr: INodeAddress, + _nodeAddr: INodeAddress, enr: ENR, direction: ConnectionDirection, verified: boolean @@ -712,7 +713,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { const nodeId = enr.nodeId; log("Session established with Node: %s, Direction: %s", nodeId, ConnectionDirection[direction]); - this.connectionUpdated(nodeId, { type: ConnectionStatusType.Connected, enr, direction }); + this.connectionUpdated(nodeId, {direction, enr, type: ConnectionStatusType.Connected}); }; private handleWhoAreYouRequest = (nodeAddr: INodeAddress, nonce: Uint8Array): void => { @@ -735,22 +736,25 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { */ private handleRpcRequest = (nodeAddr: INodeAddress, request: RequestMessage): void => { const requestType = MessageType[request.type]; - this.metrics?.rcvdMessageCount.inc({ type: requestType }); + this.metrics?.rcvdMessageCount.inc({type: requestType}); try { switch (request.type) { case MessageType.PING: - return this.handlePing(nodeAddr, request as IPingMessage); + this.handlePing(nodeAddr, request as IPingMessage); + break; case MessageType.FINDNODE: - return this.handleFindNode(nodeAddr, request as IFindNodeMessage); + this.handleFindNode(nodeAddr, request as IFindNodeMessage); + break; case MessageType.TALKREQ: - return this.handleTalkReq(nodeAddr, request as ITalkReqMessage); + this.handleTalkReq(nodeAddr, request as ITalkReqMessage); + break; default: log("Received request type which is unimplemented: %s", request.type); // TODO Implement all RPC methods return; } - } catch (e) { + } catch { log("Error handling rpc request: node: %o, requestType: %s", nodeAddr, requestType); } }; @@ -758,26 +762,24 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { private handlePing(nodeAddr: INodeAddress, message: IPingMessage): void { // check if we need to update the known ENR const entry = this.kbuckets.getWithPending(nodeAddr.nodeId); - if (entry) { - if (entry.value.seq < message.enrSeq) { - this.requestEnr(createNodeContact(entry.value, this.ipMode)); - } + if (entry && entry.value.seq < message.enrSeq) { + this.requestEnr(createNodeContact(entry.value, this.ipMode)); } const ipUDP = multiaddrToSocketAddress(nodeAddr.socketAddr); const pongMessage: IPongMessage = { - type: MessageType.PONG, - id: message.id, - enrSeq: this.enr.seq, addr: ipUDP, + enrSeq: this.enr.seq, + id: message.id, + type: MessageType.PONG, }; // build the Pong response log("Sending PONG response to node: %o", nodeAddr); try { this.sessionService.sendResponse(nodeAddr, pongMessage); - this.metrics?.sentMessageCount.inc({ type: MessageType[MessageType.PONG] }); + this.metrics?.sentMessageCount.inc({type: MessageType[MessageType.PONG]}); } catch (e) { log("Failed to send Pong. Error %s", (e as Error).message); } @@ -789,7 +791,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { * the maximum packet size */ private handleFindNode(nodeAddr: INodeAddress, message: IFindNodeMessage): void { - const { id, distances } = message; + const {id, distances} = message; let nodes: ENR[] = []; for (const distance of new Set(distances)) { // filter out invalid distances @@ -809,7 +811,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { log("Sending empty NODES response to %o", nodeAddr); try { this.sessionService.sendResponse(nodeAddr, createNodesMessage(id, 1, nodes)); - this.metrics?.sentMessageCount.inc({ type: MessageType[MessageType.NODES] }); + this.metrics?.sentMessageCount.inc({type: MessageType[MessageType.NODES]}); } catch (e) { log("Failed to send a NODES response. Error: %s", (e as Error).message); } @@ -828,7 +830,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { const _nodes = nodes.slice(i, i + nodesPerPacket); try { this.sessionService.sendResponse(nodeAddr, createNodesMessage(id, total, _nodes)); - this.metrics?.sentMessageCount.inc({ type: MessageType[MessageType.NODES] }); + this.metrics?.sentMessageCount.inc({type: MessageType[MessageType.NODES]}); } catch (e) { log("Failed to send a NODES response. Error: %s", (e as Error).message); } @@ -847,7 +849,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { */ private handleRpcResponse = (nodeAddr: INodeAddress, response: ResponseMessage): void => { const responseType = MessageType[response.type]; - this.metrics?.rcvdMessageCount.inc({ type: responseType }); + this.metrics?.rcvdMessageCount.inc({type: responseType}); // verify we know of the rpc id @@ -942,7 +944,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { request: createFindNodeMessage([0]), }); } - this.connectionUpdated(nodeAddr.nodeId, { type: ConnectionStatusType.PongReceived, enr }); + this.connectionUpdated(nodeAddr.nodeId, {enr, type: ConnectionStatusType.PongReceived}); } } @@ -954,7 +956,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { activeRequest: IActiveRequest, message: INodesMessage ): boolean { - const { request, lookupId } = activeRequest; + const {request, lookupId} = activeRequest; // Currently a maximum of 16 peers can be returned. // Datagrams have a max size of 1280 and ENRs have a max size of 300 bytes. // There should be no more than 5 responses to return 16 peers @@ -970,7 +972,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { // handle the case that there is more than one response if (message.total > 1) { - const currentResponse = this.activeNodesResponses.get(bytesToBigint(message.id)) || { count: 1, enrs: [] }; + const currentResponse = this.activeNodesResponses.get(bytesToBigint(message.id)) || {count: 1, enrs: []}; this.activeNodesResponses.delete(bytesToBigint(message.id)); log("NODES response: %d of %d received, length: %d", currentResponse.count, message.total, message.enrs.length); // If there are more requests coming, store the nodes and wait for another response @@ -1001,7 +1003,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { private handleTalkResp = ( nodeAddr: INodeAddress, - activeRequest: IActiveRequest, + _activeRequest: IActiveRequest, message: ITalkRespMessage ): void => { log("Received TALKRESP message from Node: %o", nodeAddr); @@ -1017,7 +1019,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { if (!req) { return; } - const { request, contact, lookupId, callbackPromise } = req; + const {request, contact, lookupId, callbackPromise} = req; this.activeRequests.delete(bytesToBigint(request.id)); const nodeId = getNodeId(contact); @@ -1053,7 +1055,7 @@ export class Discv5 extends (EventEmitter as { new (): Discv5EventEmitter }) { } // report the node as being disconnected - this.connectionUpdated(nodeId, { type: ConnectionStatusType.Disconnected }); + this.connectionUpdated(nodeId, {type: ConnectionStatusType.Disconnected}); // If this is initiated by the user, return the error on the callback. callbackPromise?.reject(new CodeError("RPC failure", RequestErrorType[error])); diff --git a/packages/discv5/src/service/types.ts b/packages/discv5/src/service/types.ts index 8e379a87..43df1148 100644 --- a/packages/discv5/src/service/types.ts +++ b/packages/discv5/src/service/types.ts @@ -1,19 +1,19 @@ -import { EventEmitter } from "events"; -import StrictEventEmitter from "strict-event-emitter-types"; -import { Multiaddr } from "@multiformats/multiaddr"; -import { ENR, SequenceNumber, SignableENR } from "@chainsafe/enr"; +import type {EventEmitter} from "node:events"; +import type {ENR, SequenceNumber, SignableENR} from "@chainsafe/enr"; +import type {Multiaddr} from "@multiformats/multiaddr"; +import type {StrictEventEmitter} from "strict-event-emitter-types"; import { - INodesMessage, - IPongMessage, - ITalkReqMessage, - ITalkRespMessage, + type INodesMessage, + type IPongMessage, + type ITalkReqMessage, + type ITalkRespMessage, MessageType, - RequestMessage, + type RequestMessage, } from "../message/index.js"; -import { INodeAddress, NodeContact } from "../session/nodeInfo.js"; -import { ConnectionDirection } from "../session/index.js"; -import { CodeError, SocketAddress } from "../util/index.js"; +import type {ConnectionDirection} from "../session/index.js"; +import type {INodeAddress, NodeContact} from "../session/nodeInfo.js"; +import type {CodeError, SocketAddress} from "../util/index.js"; export interface IDiscv5Events { /** @@ -96,7 +96,7 @@ export type ResponseType = Uint8Array | ENR[] | PongResponse; export function toResponseType(response: IPongMessage | INodesMessage | ITalkRespMessage): ResponseType { switch (response.type) { case MessageType.PONG: - return { enrSeq: response.enrSeq, addr: response.addr }; + return {addr: response.addr, enrSeq: response.enrSeq}; case MessageType.NODES: return response.enrs; case MessageType.TALKRESP: @@ -105,9 +105,9 @@ export function toResponseType(response: IPongMessage | INodesMessage | ITalkRes } export enum ConnectionStatusType { - Connected, - PongReceived, - Disconnected, + Connected = 0, + PongReceived = 1, + Disconnected = 2, } export type ConnectionStatus = diff --git a/packages/discv5/src/session/crypto.ts b/packages/discv5/src/session/crypto.ts index 1d17a84d..d73d1040 100644 --- a/packages/discv5/src/session/crypto.ts +++ b/packages/discv5/src/session/crypto.ts @@ -1,9 +1,8 @@ import Crypto from "node:crypto"; -import { NodeId } from "@chainsafe/enr"; - -import { generateKeypair, IKeypair, createKeypair } from "../keypair/index.js"; -import { getDiscv5Crypto } from "../util/crypto.js"; -import { concatBytes, hexToBytes, utf8ToBytes } from "ethereum-cryptography/utils.js"; +import type {NodeId} from "@chainsafe/enr"; +import {concatBytes, hexToBytes, utf8ToBytes} from "ethereum-cryptography/utils.js"; +import {type IKeypair, createKeypair, generateKeypair} from "../keypair/index.js"; +import {getDiscv5Crypto} from "../util/crypto.js"; // Implementation for generating session keys in the Discv5 protocol. // Currently, Diffie-Hellman key agreement is performed with known public key types. Session keys @@ -38,7 +37,7 @@ export function generateSessionKeys( return [...deriveKey(secret, localId, remoteId, challengeData), ephemKeypair.publicKey] as [ Uint8Array, Uint8Array, - Uint8Array + Uint8Array, ]; } @@ -65,7 +64,7 @@ export function deriveKeysFromPubkey( ephemPK: Uint8Array, challengeData: Uint8Array ): [Uint8Array, Uint8Array] { - const secret = kpriv.deriveSecret(createKeypair({ type: kpriv.type, publicKey: ephemPK })); + const secret = kpriv.deriveSecret(createKeypair({publicKey: ephemPK, type: kpriv.type})); return deriveKey(secret, remoteId, localId, challengeData); } diff --git a/packages/discv5/src/session/index.ts b/packages/discv5/src/session/index.ts index b3349010..103397f0 100644 --- a/packages/discv5/src/session/index.ts +++ b/packages/discv5/src/session/index.ts @@ -1,4 +1,4 @@ -export * from "./types.js"; export * from "./crypto.js"; -export * from "./session.js"; export * from "./service.js"; +export * from "./session.js"; +export * from "./types.js"; diff --git a/packages/discv5/src/session/nodeInfo.ts b/packages/discv5/src/session/nodeInfo.ts index 9ff09144..be3e64ce 100644 --- a/packages/discv5/src/session/nodeInfo.ts +++ b/packages/discv5/src/session/nodeInfo.ts @@ -1,9 +1,9 @@ -import { Multiaddr, isMultiaddr } from "@multiformats/multiaddr"; -import { peerIdFromString } from "@libp2p/peer-id"; -import { ENR, NodeId, getV4Crypto } from "@chainsafe/enr"; -import { createKeypair, IKeypair } from "../keypair/index.js"; -import { IPMode } from "../transport/types.js"; -import { getSocketAddressMultiaddrOnENR } from "../util/ip.js"; +import {type ENR, type NodeId, getV4Crypto} from "@chainsafe/enr"; +import {peerIdFromString} from "@libp2p/peer-id"; +import {type Multiaddr, isMultiaddr} from "@multiformats/multiaddr"; +import {type IKeypair, createKeypair} from "../keypair/index.js"; +import type {IPMode} from "../transport/types.js"; +import {getSocketAddressMultiaddrOnENR, multiaddrToObject} from "../util/ip.js"; /** A representation of an unsigned contactable node. */ export interface INodeAddress { @@ -18,7 +18,7 @@ export function nodeAddressToString(nodeAddr: INodeAddress): string { // have a peer ID specified, we remove any p2p portions of the multiaddr when generating the nodeAddressString // since only the UDP socket addr is included in the session cache key (e.g. /ip4/127.0.0.1/udp/9000/p2p/Qm...) const normalizedAddr = nodeAddr.socketAddr.decapsulateCode(421); - return nodeAddr.nodeId + ":" + Buffer.from(normalizedAddr.bytes).toString("hex"); + return `${nodeAddr.nodeId}:${Buffer.from(normalizedAddr.bytes).toString("hex")}`; } /** @@ -27,13 +27,13 @@ export function nodeAddressToString(nodeAddr: INodeAddress): string { */ export enum INodeContactType { /** We know the ENR of the node we are contacting. */ - ENR, + Enr = 0, /** * We don't have an ENR, but have enough information to start a handshake. * The handshake will request the ENR at the first opportunity. * The public key can be derived from multiaddr's whose keys can be inlined. */ - Raw, + Raw = 1, } /** @@ -56,7 +56,7 @@ export type NodeContact = nodeAddress: INodeAddress; } | { - type: INodeContactType.ENR; + type: INodeContactType.Enr; publicKey: IKeypair; nodeAddress: INodeAddress; enr: ENR; @@ -69,14 +69,11 @@ export type NodeContact = */ export function createNodeContact(input: ENR | Multiaddr, ipMode: IPMode): NodeContact { if (isMultiaddr(input)) { - const options = input.toOptions(); - if (options.transport !== "udp") { - throw new Error("Multiaddr must specify a UDP port"); - } + const options = multiaddrToObject(input); if ((options.family === 4 && !ipMode.ip4) || (options.family === 6 && !ipMode.ip6)) { throw new Error("Multiaddr family not supported by IP mode"); } - const peerIdStr = input.getPeerId(); + const peerIdStr = input.getComponents().find((c) => c.code === 421)?.value; if (!peerIdStr) { throw new Error("Multiaddr must specify a peer id"); } @@ -85,31 +82,30 @@ export function createNodeContact(input: ENR | Multiaddr, ipMode: IPMode): NodeC if (!publicKey) { throw new Error("Peer ID must have a public key"); } - const keypair = createKeypair({ type: publicKey.type, publicKey: publicKey.raw }); + const keypair = createKeypair({publicKey: publicKey.raw, type: publicKey.type}); const nodeId = getV4Crypto().nodeId(keypair.publicKey); return { - type: INodeContactType.Raw, - publicKey: keypair, nodeAddress: { - socketAddr: input, nodeId, + socketAddr: input, }, + publicKey: keypair, + type: INodeContactType.Raw, }; - } else { - const socketAddr = getSocketAddressMultiaddrOnENR(input, ipMode); - if (!socketAddr) { - throw new Error("ENR has no suitable udp multiaddr given the IP mode"); - } - return { - type: INodeContactType.ENR, - publicKey: createKeypair({ type: input.keypairType, publicKey: input.publicKey }), - nodeAddress: { - socketAddr, - nodeId: input.nodeId, - }, - enr: input, - }; } + const socketAddr = getSocketAddressMultiaddrOnENR(input, ipMode); + if (!socketAddr) { + throw new Error("ENR has no suitable udp multiaddr given the IP mode"); + } + return { + enr: input, + nodeAddress: { + nodeId: input.nodeId, + socketAddr, + }, + publicKey: createKeypair({publicKey: input.publicKey, type: input.keypairType}), + type: INodeContactType.Enr, + }; } export function getNodeId(contact: NodeContact): NodeId { diff --git a/packages/discv5/src/session/service.ts b/packages/discv5/src/session/service.ts index 25a8ee53..261c1588 100644 --- a/packages/discv5/src/session/service.ts +++ b/packages/discv5/src/session/service.ts @@ -1,48 +1,57 @@ -import { EventEmitter } from "events"; -import StrictEventEmitter from "strict-event-emitter-types"; -import debug from "debug"; -import { Multiaddr } from "@multiformats/multiaddr"; -import { ENR, SignableENR } from "@chainsafe/enr"; -import { bytesToHex, equalsBytes } from "ethereum-cryptography/utils.js"; -import { IPMode, ITransportService } from "../transport/index.js"; +import {EventEmitter} from "node:events"; +import type {ENR, SignableENR} from "@chainsafe/enr"; +import type {Multiaddr} from "@multiformats/multiaddr"; +import {bytesToHex, equalsBytes} from "ethereum-cryptography/utils.js"; +import {LRUCache} from "lru-cache"; +import type {StrictEventEmitter} from "strict-event-emitter-types"; +import debug from "weald"; +import type {IKeypair} from "../keypair/index.js"; import { + type Message, + MessageType, + type RequestMessage, + type ResponseMessage, + createFindNodeMessage, + decode, + encode, + isRequestType, +} from "../message/index.js"; +import type {IDiscv5Metrics} from "../metrics.js"; +import { + type IHandshakeAuthdata, + type IMessageAuthdata, + type IPacket, + type IWhoAreYouAuthdata, PacketType, - IPacket, + createHeader, + createRandomPacket, + createWhoAreYouPacket, decodeHandshakeAuthdata, decodeMessageAuthdata, decodeWhoAreYouAuthdata, encodeChallengeData, - createHeader, encodeMessageAuthdata, - createRandomPacket, - createWhoAreYouPacket, } from "../packet/index.js"; -import { ERR_INVALID_SIG, Session } from "./session.js"; -import { IKeypair } from "../keypair/index.js"; +import type {IPMode, ITransportService} from "../transport/index.js"; +import {TimeoutMap, multiaddrToObject} from "../util/index.js"; +import {getSocketAddressMultiaddrOnENR} from "../util/ip.js"; import { - Message, - RequestMessage, - encode, - decode, - ResponseMessage, - MessageType, - createFindNodeMessage, - isRequestType, -} from "../message/index.js"; + type INodeAddress, + INodeContactType, + type NodeContact, + getNodeAddress, + nodeAddressToString, +} from "./nodeInfo.js"; +import {ERR_INVALID_SIG, Session} from "./session.js"; import { - IRequestCall, - ISessionEvents, - ISessionConfig, - IChallenge, - RequestErrorType, ConnectionDirection, - NodeAddressString, + type IChallenge, + type IRequestCall, + type ISessionConfig, + type ISessionEvents, + type NodeAddressString, + RequestErrorType, } from "./types.js"; -import { getNodeAddress, INodeAddress, INodeContactType, nodeAddressToString, NodeContact } from "./nodeInfo.js"; -import { LRUCache } from "lru-cache"; -import { TimeoutMap } from "../util/index.js"; -import { IDiscv5Metrics } from "../metrics.js"; -import { getSocketAddressMultiaddrOnENR } from "../util/ip.js"; const log = debug("discv5:sessionService"); @@ -70,19 +79,19 @@ export interface SessionServiceOpts { * to match the source, the `Session` is promoted to an established state. RPC requests are not sent * to untrusted Sessions, only responses. */ -export class SessionService extends (EventEmitter as { new (): StrictEventEmitter }) { +export class SessionService extends (EventEmitter as {new (): StrictEventEmitter}) { /** * The local ENR */ - public enr: SignableENR; + enr: SignableENR; /** * The keypair to sign the ENR and set up encrypted communication with peers */ - public keypair: IKeypair; + keypair: IKeypair; /** * The underlying packet transport */ - public transport: ITransportService; + transport: ITransportService; /** * Configuration @@ -149,20 +158,20 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte this.keypair = keypair; this.transport = transport; - this.activeRequests = new TimeoutMap(config.requestTimeout, (k, v) => + this.activeRequests = new TimeoutMap(config.requestTimeout, (_k, v) => this.handleRequestTimeout(getNodeAddress(v.contact), v) ); this.activeRequestsNonceMapping = new Map(); this.pendingRequests = new Map(); - this.activeChallenges = new LRUCache({ ttl: config.requestTimeout * 2, max: config.sessionCacheCapacity }); - this.sessions = new LRUCache({ ttl: config.sessionTimeout, max: config.sessionCacheCapacity }); + this.activeChallenges = new LRUCache({max: config.sessionCacheCapacity, ttl: config.requestTimeout * 2}); + this.sessions = new LRUCache({max: config.sessionCacheCapacity, ttl: config.sessionTimeout}); this.ipMode = this.transport.ipMode; } /** * Starts the session service, starting the underlying UDP transport service. */ - public async start(): Promise { + async start(): Promise { log(`Starting session service with node id ${this.enr.nodeId}`); this.transport.on("packet", this.processInboundPacket); await this.transport.start(); @@ -171,7 +180,7 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte /** * Stops the session service, stopping the underlying UDP transport service. */ - public async stop(): Promise { + async stop(): Promise { log("Stopping session service"); this.transport.removeListener("packet", this.processInboundPacket); await this.transport.stop(); @@ -182,14 +191,14 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte this.sessions.clear(); } - public sessionsSize(): number { + sessionsSize(): number { return this.sessions.size; } /** * Sends an RequestMessage to a node. */ - public sendRequest(contact: NodeContact, request: RequestMessage): void { + sendRequest(contact: NodeContact, request: RequestMessage): void { const nodeAddr = getNodeAddress(contact); const nodeAddrStr = nodeAddressToString(nodeAddr); @@ -211,7 +220,7 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte } const session = this.sessions.get(nodeAddrStr); - let packet, initiatingSession; + let packet: IPacket, initiatingSession: boolean; if (session) { // Encrypt the message and send packet = session.encryptMessage(this.enr.nodeId, nodeAddr.nodeId, encode(request)); @@ -227,10 +236,10 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte const call: IRequestCall = { contact, + handshakeSent: false, + initiatingSession, packet, request, - initiatingSession, - handshakeSent: false, retries: 1, }; @@ -246,7 +255,7 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte /** * Sends an RPC response */ - public sendResponse(nodeAddr: INodeAddress, response: ResponseMessage): void { + sendResponse(nodeAddr: INodeAddress, response: ResponseMessage): void { const nodeAddrStr = nodeAddressToString(nodeAddr); // Check for an established session @@ -257,7 +266,7 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte } // Encrypt the message and send - let packet; + let packet: IPacket; try { packet = session.encryptMessage(this.enr.nodeId, nodeAddr.nodeId, encode(response)); } catch (e) { @@ -272,7 +281,7 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte * This is called in response to a "whoAreYouRequest" event. * The application finds the highest known ENR for a node then we respond to the node with a WHOAREYOU packet. */ - public sendChallenge(nodeAddr: INodeAddress, nonce: Uint8Array, remoteEnr: ENR | null): void { + sendChallenge(nodeAddr: INodeAddress, nonce: Uint8Array, remoteEnr: ENR | null): void { const nodeAddrStr = nodeAddressToString(nodeAddr); // Ignore this request if the session is already established @@ -294,23 +303,26 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte this.addExpectedResponse(nodeAddr.socketAddr); this.send(nodeAddr, packet); - this.activeChallenges.set(nodeAddrStr, { data: challengeData, remoteEnr: remoteEnr ?? undefined }); + this.activeChallenges.set(nodeAddrStr, {data: challengeData, remoteEnr: remoteEnr ?? undefined}); } - public processInboundPacket = (src: Multiaddr, packet: IPacket): void => { + processInboundPacket = (src: Multiaddr, packet: IPacket): void => { switch (packet.header.flag) { case PacketType.WhoAreYou: - return this.handleChallenge(src, packet); + this.handleChallenge(src, packet); + break; case PacketType.Handshake: - return this.handleHandshake(src, packet); + this.handleHandshake(src, packet); + break; case PacketType.Message: - return this.handleMessage(src, packet); + this.handleMessage(src, packet); + break; } }; private handleChallenge(src: Multiaddr, packet: IPacket): void { // First decode the authdata - let authdata; + let authdata: IWhoAreYouAuthdata; try { authdata = decodeWhoAreYouAuthdata(packet.header.authdata); } catch (e) { @@ -336,7 +348,6 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte // Verify that the src_addresses match if (!nodeAddr.socketAddr.equals(src)) { log( - // eslint-disable-next-line max-len "Received a WHOAREYOU packet for a message with a non-expected source. Source %s, expected_source: %s message_nonce %s", src.toString(), nodeAddr.socketAddr.toString(), @@ -353,7 +364,6 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte const requestCall = this.activeRequests.get(nodeAddrStr); if (!requestCall) { log( - // eslint-disable-next-line max-len "Active request mappings are not in sync. Message_id %s, node_address %o doesn't exist in active request mapping", nonce, nodeAddr @@ -417,12 +427,12 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte // All sent requests must have an associated node_id. Therefore the following // must not panic. switch (requestCall.contact.type) { - case INodeContactType.ENR: { + case INodeContactType.Enr: { // NOTE: Here we decide if the session is outgoing or ingoing. The condition for an // outgoing session is that we originally sent a RANDOM packet (signifying we did // not have a session for a request) and the packet is not a PING (we are not // trying to update an old session that may have expired). - let connectionDirection; + let connectionDirection: ConnectionDirection; if (requestCall.initiatingSession) { if (requestCall.request.type === MessageType.PING) { connectionDirection = ConnectionDirection.Incoming; @@ -481,8 +491,8 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte * Returns true if they match */ private verifyEnr(enr: ENR, nodeAddr: INodeAddress): boolean { - const enrMultiaddrIP4 = getSocketAddressMultiaddrOnENR(enr, { ...this.ipMode, ip6: false } as IPMode); - const enrMultiaddrIP6 = getSocketAddressMultiaddrOnENR(enr, { ...this.ipMode, ip4: false } as IPMode); + const enrMultiaddrIP4 = getSocketAddressMultiaddrOnENR(enr, {...this.ipMode, ip6: false} as IPMode); + const enrMultiaddrIP6 = getSocketAddressMultiaddrOnENR(enr, {...this.ipMode, ip4: false} as IPMode); return ( enr.nodeId === nodeAddr.nodeId && (enrMultiaddrIP4?.equals(nodeAddr.socketAddr) ?? enrMultiaddrIP6?.equals(nodeAddr.socketAddr) ?? true) @@ -494,7 +504,7 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte // Needs to match an outgoing WHOAREYOU packet (so we have the required nonce to be signed). // If it doesn't we drop the packet. // This will lead to future outgoing WHOAREYOU packets if they proceed to send further encrypted packets - let authdata; + let authdata: IHandshakeAuthdata; try { authdata = decodeHandshakeAuthdata(packet.header.authdata); } catch (e) { @@ -502,8 +512,8 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte return; } const nodeAddr = { - socketAddr: src, nodeId: authdata.srcId, + socketAddr: src, }; const nodeAddrStr = nodeAddressToString(nodeAddr); @@ -547,12 +557,8 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte // decrypt the message this.handleMessage(src, { + header: createHeader(PacketType.Message, encodeMessageAuthdata({srcId: nodeAddr.nodeId}), packet.header.nonce), maskingIv: packet.maskingIv, - header: createHeader( - PacketType.Message, - encodeMessageAuthdata({ srcId: nodeAddr.nodeId }), - packet.header.nonce - ), message: packet.message, messageAd: encodeChallengeData(packet.maskingIv, packet.header), }); @@ -568,7 +574,7 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte } private handleMessage(src: Multiaddr, packet: IPacket): void { - let authdata; + let authdata: IMessageAuthdata; try { authdata = decodeMessageAuthdata(packet.header.authdata); } catch (e) { @@ -576,8 +582,8 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte return; } const nodeAddr = { - socketAddr: src, nodeId: authdata.srcId, + socketAddr: src, }; const nodeAddrStr = nodeAddressToString(nodeAddr); @@ -594,14 +600,14 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte } // attempt to decrypt and process the message - let encodedMessage; + let encodedMessage: Uint8Array; try { encodedMessage = session.decryptMessage( packet.header.nonce, packet.message, packet.messageAd || encodeChallengeData(packet.maskingIv, packet.header) ); - } catch (e) { + } catch { // We have a session but the message could not be decrypted. // It is likely the node sending this message has dropped their session. // In this case, this message is a random packet and we should reply with a WHOAREYOU. @@ -637,37 +643,35 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte // Sessions could be awaiting an ENR response. // Check if this response matches these const requestId = session.awaitingEnr; - if (requestId !== undefined) { - if (equalsBytes(requestId, message.id)) { - delete session.awaitingEnr; - if (message.type === MessageType.NODES) { - // Received the requested ENR - const enr = message.enrs.pop(); - - if (enr) { - // Verify the ENR endpoint matches observed node address - const verified = this.verifyEnr(enr, nodeAddr); - - // Drop session if invalid ENR and session service not configured to allow unverified sessions - if (!verified && !this.config.allowUnverifiedSessions) { - log("ENR contains invalid socket address. Dropping session with %o", nodeAddr); - this.failSession(nodeAddr, RequestErrorType.InvalidRemoteENR, true); - return; - } - // Notify the application - // This can occur when we try to dial a node without an - // ENR. In this case we have attempted to establish the - // connection, so this is an outgoing connection. - this.emit("established", nodeAddr, enr, ConnectionDirection.Outgoing, verified); - + if (requestId !== undefined && equalsBytes(requestId, message.id)) { + session.awaitingEnr = undefined; + if (message.type === MessageType.NODES) { + // Received the requested ENR + const enr = message.enrs.pop(); + + if (enr) { + // Verify the ENR endpoint matches observed node address + const verified = this.verifyEnr(enr, nodeAddr); + + // Drop session if invalid ENR and session service not configured to allow unverified sessions + if (!verified && !this.config.allowUnverifiedSessions) { + log("ENR contains invalid socket address. Dropping session with %o", nodeAddr); + this.failSession(nodeAddr, RequestErrorType.InvalidRemoteENR, true); return; } - } + // Notify the application + // This can occur when we try to dial a node without an + // ENR. In this case we have attempted to establish the + // connection, so this is an outgoing connection. + this.emit("established", nodeAddr, enr, ConnectionDirection.Outgoing, verified); - log("Session failed invalid ENR response"); - this.failSession(nodeAddr, RequestErrorType.InvalidRemoteENR, true); - return; + return; + } } + + log("Session failed invalid ENR response"); + this.failSession(nodeAddr, RequestErrorType.InvalidRemoteENR, true); + return; } // Handle standard responses @@ -700,27 +704,24 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte // The response matches a request // Check to see if this is a Nodes response, in which case we may require to wait for extra responses - if (response.type === MessageType.NODES) { - if (response.total > 1) { - // This is a multi-response Nodes response - if (requestCall.remainingResponses === undefined) { - // This is the first nodes response - requestCall.remainingResponses = response.total - 1; - // add back the request and send the response - this.activeRequests.set(nodeAddrStr, requestCall); - this.emit("response", nodeAddr, response); - return; - } else { - // This is not the first nodes response - requestCall.remainingResponses--; - if (requestCall.remainingResponses !== 0) { - // more responses remaining, add back the request and send the response - // add back the request and send the response - this.activeRequests.set(nodeAddrStr, requestCall); - this.emit("response", nodeAddr, response); - return; - } - } + if (response.type === MessageType.NODES && response.total > 1) { + // This is a multi-response Nodes response + if (requestCall.remainingResponses === undefined) { + // This is the first nodes response + requestCall.remainingResponses = response.total - 1; + // add back the request and send the response + this.activeRequests.set(nodeAddrStr, requestCall); + this.emit("response", nodeAddr, response); + return; + } + // This is not the first nodes response + requestCall.remainingResponses--; + if (requestCall.remainingResponses !== 0) { + // more responses remaining, add back the request and send the response + // add back the request and send the response + this.activeRequests.set(nodeAddrStr, requestCall); + this.emit("response", nodeAddr, response); + return; } } @@ -759,11 +760,11 @@ export class SessionService extends (EventEmitter as { new (): StrictEventEmitte } private removeExpectedResponse(socketAddr: Multiaddr): void { - this.transport.addExpectedResponse?.(socketAddr.toOptions().host); + this.transport.removeExpectedResponse?.(multiaddrToObject(socketAddr).host); } private addExpectedResponse(socketAddr: Multiaddr): void { - this.transport.removeExpectedResponse?.(socketAddr.toOptions().host); + this.transport.addExpectedResponse?.(multiaddrToObject(socketAddr).host); } private handleRequestTimeout(nodeAddr: INodeAddress, requestCall: IRequestCall): void { diff --git a/packages/discv5/src/session/session.ts b/packages/discv5/src/session/session.ts index 19365474..a42518f4 100644 --- a/packages/discv5/src/session/session.ts +++ b/packages/discv5/src/session/session.ts @@ -1,28 +1,19 @@ -import { NodeId, ENR } from "@chainsafe/enr"; - -import { IKeys } from "./types.js"; +import {ENR, type NodeId} from "@chainsafe/enr"; +import {randomBytes} from "@noble/hashes/utils.js"; +import {type IKeypair, createKeypair} from "../keypair/index.js"; +import type {RequestId} from "../message/index.js"; import { - IPacket, + type IPacket, + MASKING_IV_SIZE, PacketType, - encodeHandshakeAuthdata, createHeader, - MASKING_IV_SIZE, encodeChallengeData, + encodeHandshakeAuthdata, encodeMessageAuthdata, } from "../packet/index.js"; -import { - generateSessionKeys, - deriveKeysFromPubkey, - decryptMessage, - encryptMessage, - idSign, - idVerify, -} from "./crypto.js"; -import { IKeypair, createKeypair } from "../keypair/index.js"; -import { randomBytes } from "@noble/hashes/utils"; -import { RequestId } from "../message/index.js"; -import { IChallenge } from "."; -import { getNodeId, getPublicKey, NodeContact } from "./nodeInfo.js"; +import {decryptMessage, deriveKeysFromPubkey, encryptMessage, generateSessionKeys, idSign, idVerify} from "./crypto.js"; +import {type NodeContact, getNodeId, getPublicKey} from "./nodeInfo.js"; +import type {IChallenge, IKeys} from "./types.js"; // The `Session` struct handles the stages of creating and establishing a handshake with a // peer. @@ -64,7 +55,7 @@ export class Session { */ awaitingEnr?: RequestId; - constructor({ keys }: ISessionOpts) { + constructor({keys}: ISessionOpts) { this.keys = keys; } @@ -84,7 +75,7 @@ export class Session { ): [Session, ENR] { let enr: ENR; // check and verify a potential ENR update - if (enrRecord && enrRecord.length) { + if (enrRecord?.length) { const newRemoteEnr = ENR.decode(enrRecord); if (challenge.remoteEnr) { if (challenge.remoteEnr.seq < newRemoteEnr.seq) { @@ -104,7 +95,7 @@ export class Session { // verify the auth header nonce if ( !idVerify( - createKeypair({ type: enr.keypairType, publicKey: enr.publicKey }), + createKeypair({publicKey: enr.publicKey, type: enr.keypairType}), challenge.data, ephPubkey, localId, @@ -119,9 +110,9 @@ export class Session { // generate session keys const [decryptionKey, encryptionKey] = deriveKeysFromPubkey(localKey, localId, remoteId, ephPubkey, challenge.data); - const keys = { encryptionKey, decryptionKey }; + const keys = {decryptionKey, encryptionKey}; - return [new Session({ keys }), enr]; + return [new Session({keys}), enr]; } /** @@ -142,19 +133,19 @@ export class Session { getPublicKey(remoteContact), challengeData ); - const keys = { encryptionKey, decryptionKey }; + const keys = {decryptionKey, encryptionKey}; // construct nonce signature const idSignature = idSign(localKey, challengeData, ephPubkey, getNodeId(remoteContact)); // create authdata const authdata = encodeHandshakeAuthdata({ - srcId: localNodeId, - sigSize: 64, ephKeySize: 33, - idSignature, ephPubkey, + idSignature, record: updatedEnr || undefined, + sigSize: 64, + srcId: localNodeId, }); const header = createHeader(PacketType.Handshake, authdata); @@ -166,11 +157,11 @@ export class Session { return [ { - maskingIv, header, + maskingIv, message: messageCiphertext, }, - new Session({ keys }), + new Session({keys}), ]; } @@ -187,15 +178,15 @@ export class Session { * Encrypt packets with the current session key if we are awaiting a response from an * IAuthMessagePacket. */ - encryptMessage(srcId: NodeId, destId: NodeId, message: Uint8Array): IPacket { - const authdata = encodeMessageAuthdata({ srcId }); + encryptMessage(srcId: NodeId, _destId: NodeId, message: Uint8Array): IPacket { + const authdata = encodeMessageAuthdata({srcId}); const header = createHeader(PacketType.Message, authdata); const maskingIv = randomBytes(MASKING_IV_SIZE); const aad = encodeChallengeData(maskingIv, header); const ciphertext = encryptMessage(this.keys.encryptionKey, header.nonce, message, aad); return { - maskingIv, header, + maskingIv, message: ciphertext, }; } @@ -210,12 +201,12 @@ export class Session { // try with the new keys if (this.awaitingKeys) { const newKeys = this.awaitingKeys; - delete this.awaitingKeys; + this.awaitingKeys = undefined; try { const result = decryptMessage(newKeys.decryptionKey, nonce, message, aad); this.keys = newKeys; return result; - } catch (e) { + } catch { // } } diff --git a/packages/discv5/src/session/types.ts b/packages/discv5/src/session/types.ts index fd8c7e33..15298527 100644 --- a/packages/discv5/src/session/types.ts +++ b/packages/discv5/src/session/types.ts @@ -1,9 +1,8 @@ -import { Multiaddr } from "@multiformats/multiaddr"; -import { NodeId, ENR } from "@chainsafe/enr"; - -import { IPacket } from "../packet/index.js"; -import { RequestId, RequestMessage, ResponseMessage } from "../message/index.js"; -import { INodeAddress, NodeContact } from "./nodeInfo.js"; +import type {ENR, NodeId} from "@chainsafe/enr"; +import type {Multiaddr} from "@multiformats/multiaddr"; +import type {RequestId, RequestMessage, ResponseMessage} from "../message/index.js"; +import type {IPacket} from "../packet/index.js"; +import type {INodeAddress, NodeContact} from "./nodeInfo.js"; export type NodeAddressString = string; @@ -40,30 +39,30 @@ export interface ISessionConfig { export enum RequestErrorType { /** The request timed out. */ - Timeout, + Timeout = 0, /** The discovery service has not been started. */ - ServiceNotStarted, + ServiceNotStarted = 1, /** The request was sent to ourselves. */ - SelfRequest, + SelfRequest = 2, /** An invalid ENR was provided. */ - InvalidENR, + InvalidENR = 3, /** The remote's ENR was invalid. */ - InvalidRemoteENR, + InvalidRemoteENR = 4, /** The remote returned an invalid packet. */ - InvalidRemotePacket, + InvalidRemotePacket = 5, /** Failed attempting to encrypt the request. */ - Encryptionailed, + EncryptionFailed = 6, /** The multiaddr provided is invalid */ - InvalidMultiaddr, + InvalidMultiaddr = 7, } export enum ResponseErrorType { /** The responder address does not match the expected address */ - WrongAddress, + WrongAddress = 0, /** The response type does not match the expected response type */ - WrongResponseType, + WrongResponseType = 1, /** The response handler threw */ - InternalError, + InternalError = 2, } export interface IKeys { encryptionKey: Uint8Array; @@ -73,9 +72,9 @@ export interface IKeys { /** How we connected to the node. */ export enum ConnectionDirection { /** The node contacted us. */ - Incoming, + Incoming = 0, /** We contacted the node. */ - Outgoing, + Outgoing = 1, } /** A Challenge (WHOAREYOU) object used to handle and send WHOAREYOU requests. */ diff --git a/packages/discv5/src/transport/types.ts b/packages/discv5/src/transport/types.ts index 41e10619..46ee3e58 100644 --- a/packages/discv5/src/transport/types.ts +++ b/packages/discv5/src/transport/types.ts @@ -1,10 +1,10 @@ -import { EventEmitter } from "events"; -import StrictEventEmitter from "strict-event-emitter-types"; -import { Multiaddr } from "@multiformats/multiaddr"; -import { BaseENR } from "@chainsafe/enr"; +import type {EventEmitter} from "node:events"; +import type {BaseENR} from "@chainsafe/enr"; +import type {Multiaddr} from "@multiformats/multiaddr"; +import type {StrictEventEmitter} from "strict-event-emitter-types"; -import { IPacket } from "../packet/index.js"; -import { SocketAddress } from "../util/ip.js"; +import type {IPacket} from "../packet/index.js"; +import type {SocketAddress} from "../util/ip.js"; export interface ISocketAddr { port: number; diff --git a/packages/discv5/src/transport/udp.ts b/packages/discv5/src/transport/udp.ts index 3ca1a3eb..92d1f550 100644 --- a/packages/discv5/src/transport/udp.ts +++ b/packages/discv5/src/transport/udp.ts @@ -1,12 +1,13 @@ import * as dgram from "node:dgram"; -import { EventEmitter } from "events"; -import { Multiaddr, multiaddr, MultiaddrObject } from "@multiformats/multiaddr"; -import { ENR } from "@chainsafe/enr"; +import {EventEmitter} from "node:events"; -import { decodePacket, encodePacket, IPacket, MAX_PACKET_SIZE } from "../packet/index.js"; -import { BindAddrs, IPMode, IRemoteInfo, ITransportService, TransportEventEmitter } from "./types.js"; -import { IRateLimiter } from "../rateLimit/index.js"; -import { getSocketAddressOnENR, SocketAddress } from "../util/ip.js"; +import type {ENR} from "@chainsafe/enr"; +import {type Multiaddr, multiaddr} from "@multiformats/multiaddr"; + +import {type IPacket, MAX_PACKET_SIZE, decodePacket, encodePacket} from "../packet/index.js"; +import type {IRateLimiter} from "../rateLimit/index.js"; +import {type MultiaddrObject, type SocketAddress, getSocketAddressOnENR, multiaddrToObject} from "../util/ip.js"; +import type {BindAddrs, IPMode, IRemoteInfo, ITransportService, TransportEventEmitter} from "./types.js"; export type UDPTransportServiceInit = { bindAddrs: BindAddrs; @@ -24,7 +25,7 @@ type SocketOpts = { * This class is responsible for encoding outgoing Packets and decoding incoming Packets over UDP */ export class UDPTransportService - extends (EventEmitter as { new (): TransportEventEmitter }) + extends (EventEmitter as {new (): TransportEventEmitter}) implements ITransportService { readonly bindAddrs: Multiaddr[]; @@ -41,7 +42,7 @@ export class UDPTransportService private readonly srcId: string; private readonly rateLimiter?: IRateLimiter; - public constructor(init: UDPTransportServiceInit) { + constructor(init: UDPTransportServiceInit) { super(); this.srcId = init.nodeId; this.rateLimiter = init.rateLimiter; @@ -49,10 +50,7 @@ export class UDPTransportService throw new Error("Must bind with an IPv4 and/or IPv6 multiaddr"); } const toSocketOpts = (addr: Multiaddr): SocketOpts => { - const opts = addr.toOptions(); - if (opts.transport !== "udp") { - throw new Error("Local multiaddr must use UDP"); - } + const opts = multiaddrToObject(addr); return { addr, opts, @@ -60,7 +58,7 @@ export class UDPTransportService }; this.bindAddrs = []; - this.ipMode = { ip4: false, ip6: false } as unknown as IPMode; + this.ipMode = {ip4: false, ip6: false} as unknown as IPMode; if (init.bindAddrs.ip4) { this.ip4 = toSocketOpts(init.bindAddrs.ip4); @@ -80,7 +78,7 @@ export class UDPTransportService } } - public async start(): Promise { + async start(): Promise { const [socket4, socket6] = await Promise.all([ this.ip4 ? openSocket(this.ip4.opts) : undefined, this.ip6 ? openSocket(this.ip6.opts) : undefined, @@ -95,7 +93,7 @@ export class UDPTransportService } } - public async stop(): Promise { + async stop(): Promise { const socket4 = this.ip4?.socket; const socket6 = this.ip6?.socket; socket4?.off("message", this.handleIncoming); @@ -103,8 +101,8 @@ export class UDPTransportService await Promise.all([closeSocket(socket4), closeSocket(socket6)]); } - public async send(to: Multiaddr, toId: string, packet: IPacket): Promise { - const nodeAddr = to.toOptions(); + async send(to: Multiaddr, toId: string, packet: IPacket): Promise { + const nodeAddr = multiaddrToObject(to); if (nodeAddr.family === 4) { if (!this.ip4) { throw new Error("Cannot send to an IPv4 address without a bound IPv4 socket"); @@ -151,10 +149,10 @@ export class UDPTransportService async function openSocket(opts: MultiaddrObject): Promise { const socket = dgram.createSocket({ + ipv6Only: opts.family === 6, recvBufferSize: 16 * MAX_PACKET_SIZE, sendBufferSize: MAX_PACKET_SIZE, type: opts.family === 4 ? "udp4" : "udp6", - ipv6Only: opts.family === 6, }); await new Promise((resolve) => socket.bind(opts.port, opts.host, resolve as () => void)); return socket; diff --git a/packages/discv5/src/util/crypto.ts b/packages/discv5/src/util/crypto.ts index 9a07e790..1d38d269 100644 --- a/packages/discv5/src/util/crypto.ts +++ b/packages/discv5/src/util/crypto.ts @@ -1,10 +1,12 @@ -import { sha256 } from "@noble/hashes/sha256"; -import { hmac } from "@noble/hashes/hmac"; -import { expand, extract } from "@noble/hashes/hkdf"; -import { sign, verify, ProjectivePoint as Point, getPublicKey, getSharedSecret, utils, etc } from "@noble/secp256k1"; +import {expand, extract} from "@noble/hashes/hkdf.js"; +import {hmac} from "@noble/hashes/hmac.js"; +import {sha256} from "@noble/hashes/sha2.js"; +import {Point, etc, getPublicKey, getSharedSecret, hashes, sign, utils, verify} from "@noble/secp256k1"; -etc.hmacSha256Sync = (k, ...m) => hmac(sha256, k, etc.concatBytes(...m)); -export type discv5Crypto = { +hashes.hmacSha256 = (k, ...m) => hmac(sha256, k, etc.concatBytes(...m)); +hashes.sha256 = sha256; + +export type Discv5Crypto = { sha256: (data: Uint8Array) => Uint8Array; secp256k1: { publicKeyVerify: (publicKey: Uint8Array) => boolean; @@ -27,38 +29,38 @@ export type discv5Crypto = { }; }; -export const defaultCrypto: discv5Crypto = { - sha256: sha256, +export const defaultCrypto: Discv5Crypto = { + hkdf: { + expand: (hash, key, info, outputLen) => expand(hash as never, key, info, outputLen), + extract: (hash, secret, info) => extract(hash as never, secret, info), + }, secp256k1: { + deriveSecret: (privKey, pubKey) => getSharedSecret(privKey, pubKey, true), + generatePrivateKey: () => utils.randomSecretKey(), + privateKeyVerify: (pk) => { + return utils.isValidSecretKey(pk); + }, + publicKeyConvert: (pk, compress) => Point.fromBytes(pk).toBytes(compress), + publicKeyCreate: (pk) => getPublicKey(pk), publicKeyVerify: (pk) => { try { - Point.fromHex(pk).assertValidity(); + Point.fromBytes(pk).assertValidity(); return true; } catch { return false; } }, - publicKeyCreate: (pk) => getPublicKey(pk), - publicKeyConvert: (pk, compress) => Point.fromHex(pk).toRawBytes(compress), - sign: (msg, pk) => sign(msg, pk).toCompactRawBytes(), - verify: (pk, msg, sig) => verify(sig, msg, pk), - deriveSecret: (privKey, pubKey) => getSharedSecret(privKey, pubKey, true), - generatePrivateKey: () => utils.randomPrivateKey(), - privateKeyVerify: (pk) => { - return utils.isValidPrivateKey(pk); - }, - }, - hkdf: { - extract: (hash, secret, info) => extract(hash as never, secret, info), - expand: (hash, key, info, outputLen) => expand(hash as never, key, info, outputLen), + sign: (msg, pk) => sign(msg, pk, {prehash: false}), + verify: (pk, msg, sig) => verify(sig, msg, pk, {prehash: false}), }, + sha256: sha256, }; -let crypto: discv5Crypto = defaultCrypto; -export const getDiscv5Crypto = (): discv5Crypto => { +let crypto: Discv5Crypto = defaultCrypto; +export const getDiscv5Crypto = (): Discv5Crypto => { return crypto; }; -export const setDiscv5Crypto = (c: discv5Crypto): void => { +export const setDiscv5Crypto = (c: Discv5Crypto): void => { crypto = c; }; diff --git a/packages/discv5/src/util/index.ts b/packages/discv5/src/util/index.ts index a9c0a422..009be275 100644 --- a/packages/discv5/src/util/index.ts +++ b/packages/discv5/src/util/index.ts @@ -1,4 +1,4 @@ +export * from "./error.js"; +export * from "./ip.js"; export * from "./timeoutMap.js"; export * from "./toBytes.js"; -export * from "./ip.js"; -export * from "./error.js"; diff --git a/packages/discv5/src/util/ip.ts b/packages/discv5/src/util/ip.ts index 3c1648ee..15ccf630 100644 --- a/packages/discv5/src/util/ip.ts +++ b/packages/discv5/src/util/ip.ts @@ -1,26 +1,26 @@ -import { multiaddr, Multiaddr } from "@multiformats/multiaddr"; -import { BaseENR, SignableENR } from "@chainsafe/enr"; -import { IPMode } from "../transport/types.js"; +import type {BaseENR, SignableENR} from "@chainsafe/enr"; +import {type Multiaddr, multiaddr} from "@multiformats/multiaddr"; +import type {IPMode} from "../transport/types.js"; -export type IP = { type: 4 | 6; octets: Uint8Array }; +export type Ip = {type: 4 | 6; octets: Uint8Array}; export type SocketAddress = { - ip: IP; + ip: Ip; port: number; }; -export function ipFromBytes(bytes: Uint8Array): IP | undefined { +export function ipFromBytes(bytes: Uint8Array): Ip | undefined { // https://github.com/sigp/discv5/blob/517eb3f0c5e5b347d8fe6c2973e1698f89e83524/src/rpc.rs#L429 switch (bytes.length) { case 4: - return { type: 4, octets: bytes }; + return {octets: bytes, type: 4}; case 16: - return { type: 6, octets: bytes }; + return {octets: bytes, type: 6}; default: return undefined; } } -export function ipToBytes(ip: IP): Uint8Array { +export function ipToBytes(ip: Ip): Uint8Array { return ip.octets; } @@ -95,7 +95,7 @@ export function setSocketAddressOnENR(enr: SignableENR, s: SocketAddress): void // 4 32 ip4 // 41 128 ip6 // 273 16 udp -const Protocol = { +const PROTOCOL = { 4: 4, 6: 41, udp: 273, @@ -108,7 +108,7 @@ const udpProto1 = 2; export function multiaddrFromSocketAddress(s: SocketAddress): Multiaddr { // ipProto(1) + octets(4 or 16) + udpProto(2) + udpPort(2) const multiaddrBuf = new Uint8Array(s.ip.octets.length + 5); - multiaddrBuf[0] = Protocol[s.ip.type]; + multiaddrBuf[0] = PROTOCOL[s.ip.type]; multiaddrBuf.set(s.ip.octets, 1); multiaddrBuf[multiaddrBuf.length - 4] = udpProto0; multiaddrBuf[multiaddrBuf.length - 3] = udpProto1; @@ -118,18 +118,28 @@ export function multiaddrFromSocketAddress(s: SocketAddress): Multiaddr { } export function multiaddrToSocketAddress(multiaddr: Multiaddr): SocketAddress { - let ip: IP | undefined; + let ip: Ip | undefined; let port: number | undefined; - for (const tuple of multiaddr.tuples()) { - switch (tuple[0]) { - case Protocol["4"]: - ip = { type: 4, octets: tuple[1]! }; + // Force cache population of bytes property to ensure getComponents() works correctly + void multiaddr.bytes; + for (const component of multiaddr.getComponents()) { + switch (component.code) { + case PROTOCOL["4"]: + ip = { + // biome-ignore lint/style/noNonNullAssertion: guaranteed with multiaddr.bytes access above + octets: component.bytes!.slice(1), // remove varint prefix + type: 4, + }; break; - case Protocol["6"]: - ip = { type: 6, octets: tuple[1]! }; + case PROTOCOL["6"]: + ip = { + // biome-ignore lint/style/noNonNullAssertion: guaranteed with multiaddr.bytes access above + octets: component.bytes!.slice(1), // remove varint prefix + type: 6, + }; break; - case Protocol.udp: { - port = (tuple[1]![0] << 8) + tuple[1]![1]; + case PROTOCOL.udp: { + port = Number(component.value); break; } } @@ -145,3 +155,35 @@ export function multiaddrToSocketAddress(multiaddr: Multiaddr): SocketAddress { port, }; } + +export type MultiaddrObject = { + family: number; + host: string; + port: number; +}; + +export function multiaddrToObject(addr: Multiaddr): MultiaddrObject { + const components = addr.getComponents(); + const ipComponent = components.at(0); + const transportComponent = components.at(1); + if (!ipComponent || !transportComponent) { + throw new Error("Invalid multiaddr format for transport bind address"); + } + if (ipComponent.name !== "ip4" && ipComponent.name !== "ip6") { + throw new Error("Local multiaddr must use IPv4 or IPv6"); + } + if (ipComponent.value === undefined) { + throw new Error("IP component of multiaddr must have a value"); + } + if (transportComponent.name !== "udp") { + throw new Error("Local multiaddr must use UDP"); + } + if (transportComponent.value === undefined) { + throw new Error("Transport component of multiaddr must have a value"); + } + return { + family: ipComponent.name === "ip4" ? 4 : 6, + host: ipComponent.value, + port: Number(transportComponent.value), + }; +} diff --git a/packages/discv5/src/util/timeoutMap.ts b/packages/discv5/src/util/timeoutMap.ts index 166d06dd..2a6452b2 100644 --- a/packages/discv5/src/util/timeoutMap.ts +++ b/packages/discv5/src/util/timeoutMap.ts @@ -3,7 +3,7 @@ * A callback, onTimeout, can optionally be registered which will be called upon each value's timeout */ export class TimeoutMap extends Map { - public onTimeout: ((k: K, v: V) => void) | undefined; + onTimeout: ((k: K, v: V) => void) | undefined; private timeout: number; private timeouts: Map; diff --git a/packages/discv5/test/e2e/connect.test.ts b/packages/discv5/test/e2e/connect.test.ts index 038a42f9..9ffa14dc 100644 --- a/packages/discv5/test/e2e/connect.test.ts +++ b/packages/discv5/test/e2e/connect.test.ts @@ -1,15 +1,14 @@ -/* eslint-env mocha */ -import { expect } from "chai"; -import { privateKeyFromProtobuf } from "@libp2p/crypto/keys"; -import { PrivateKey } from "@libp2p/interface"; -import { multiaddr } from "@multiformats/multiaddr"; -import { SignableENR } from "@chainsafe/enr"; -import { Discv5 } from "../../src/index.js"; +import {SignableENR} from "@chainsafe/enr"; +import {privateKeyFromProtobuf} from "@libp2p/crypto/keys"; +import type {PrivateKey} from "@libp2p/interface"; +import {multiaddr} from "@multiformats/multiaddr"; +import {afterEach, describe, expect, it} from "vitest"; +import {Discv5} from "../../src/index.js"; let nodeIdx = 0; const portBase = 10000; -describe("discv5 integration test", function () { +describe("discv5 integration test", () => { const nodes: Discv5[] = []; type Node = { @@ -28,24 +27,24 @@ describe("discv5 integration test", function () { enr.setLocationMultiaddr(multiAddrUdp); const discv5 = Discv5.create({ - enr, - privateKey, - bindAddrs: { ip4: multiAddrUdp }, + bindAddrs: {ip4: multiAddrUdp}, config: { lookupTimeout: 2000, }, + enr, + privateKey, }); nodes.push(discv5); await discv5.start(); - return { privateKey, enr, discv5 }; + return {discv5, enr, privateKey}; } // 2862ae92fa59042fd4d4a3e3bddb92b33a53b72be15deafce07dfbd7c3b12812 - this.afterEach(async () => { + afterEach(async () => { for (const node of nodes) { await node.stop(); } @@ -62,7 +61,7 @@ describe("discv5 integration test", function () { expect(nodes.map((n) => n.nodeId)).to.deep.equal([node2.enr.nodeId, node1.enr.nodeId], "Should find ENR of node2"); }); - it("Send TALKREQ/TALKRESP", async function () { + it("Send TALKREQ/TALKRESP", async () => { const node0 = await getDiscv5Node(); const node1 = await getDiscv5Node(); @@ -72,13 +71,13 @@ describe("discv5 integration test", function () { try { await node0.discv5.sendTalkReq(node1.enr.toENR(), Buffer.from([0, 1, 2, 3]), "foo"); expect.fail("TALKREQ response should throw when no response is given"); - } catch (e) { + } catch { // expected } // test a TALKRESP with a response const expectedResp = Buffer.from([4, 5, 6, 7]); - node1.discv5.on("talkReqReceived", (nodeAddr, enr, request) => { + node1.discv5.on("talkReqReceived", (nodeAddr, _enr, request) => { void node1.discv5.sendTalkResp(nodeAddr, request.id, expectedResp); }); const resp = await node0.discv5.sendTalkReq(node1.enr.toENR(), Buffer.from([0, 1, 2, 3]), "foo"); @@ -99,5 +98,5 @@ function getPrivateKey(i: number): PrivateKey { "CAISIHRKcVKLTpKhQOEIPwQjH2xx/nvJWWLUCr90/NOuuZ+l", "CAISIP3n7vFWZKye7duop0nhfttFJUXTVvQfd4q0dPpURLke", ]; - return privateKeyFromProtobuf(Buffer.from(privKeysBase64[i], "base64")); + return privateKeyFromProtobuf(Buffer.from(privKeysBase64[i], "base64")) as PrivateKey; } diff --git a/packages/discv5/test/e2e/mainnetBootnodes.test.ts b/packages/discv5/test/e2e/mainnetBootnodes.test.ts index 2300742f..b64aca3d 100644 --- a/packages/discv5/test/e2e/mainnetBootnodes.test.ts +++ b/packages/discv5/test/e2e/mainnetBootnodes.test.ts @@ -1,96 +1,103 @@ -/* eslint-env mocha */ -import { expect } from "chai"; -import { generateKeyPair, privateKeyFromProtobuf } from "@libp2p/crypto/keys"; -import { multiaddr } from "@multiformats/multiaddr"; -import { ENR, SignableENR } from "@chainsafe/enr"; -import { Discv5 } from "../../src/index.js"; +import {ENR, SignableENR} from "@chainsafe/enr"; +import {generateKeyPair, privateKeyFromProtobuf} from "@libp2p/crypto/keys"; +import type {PrivateKey} from "@libp2p/interface"; +import {multiaddr} from "@multiformats/multiaddr"; +import {describe, expect, it} from "vitest"; +import {Discv5} from "../../src/index.js"; let port = 9000; -describe("discv5 integration test", function () { - this.timeout("5min"); - - const RANDOM_PRIVATE_KEY = true; // Otherwise uses a fixed private key - const bootnodesENRText = getMainnetBootnodesENRText(); - - for (const bindAddrs of [ - { - ip4: multiaddr(`/ip4/0.0.0.0/udp/${port++}`), - }, - { - ip6: multiaddr(`/ip6/::/udp/${port++}`), - }, - { - ip4: multiaddr(`/ip4/0.0.0.0/udp/${port++}`), - ip6: multiaddr(`/ip6/::/udp/${port++}`), - }, - ]) { - it(`Connect to nodes from Mainnet bootnodes: ${Object.keys(bindAddrs)}`, async function () { +describe( + "discv5 integration test", + () => { + const RANDOM_PRIVATE_KEY = true; // Otherwise uses a fixed private key + const bootnodesENRText = getMainnetBootnodesENRText(); + + for (const bindAddrs of [ + { + ip4: multiaddr(`/ip4/0.0.0.0/udp/${port++}`), + }, + { + ip6: multiaddr(`/ip6/::/udp/${port++}`), + }, + { + ip4: multiaddr(`/ip4/0.0.0.0/udp/${port++}`), + ip6: multiaddr(`/ip6/::/udp/${port++}`), + }, + ]) { // ip6 test fails in github runner - if (process.env.CI && bindAddrs.ip6) this.skip(); - - const privateKey = RANDOM_PRIVATE_KEY - ? await generateKeyPair("secp256k1") - : privateKeyFromProtobuf( - Buffer.from("080212205465237331224a07d9c7b9c458e0859f401ab49f01c971857d373a3e6f6fdf3a", "hex") - ); - - const enr = SignableENR.createFromPrivateKey(privateKey); - - const discv5 = Discv5.create({ - enr, - privateKey, - bindAddrs, - config: { - lookupTimeout: 2000, - }, - }); - - await discv5.start(); - - for (let i = 0; i < bootnodesENRText.length; i++) { - const bootEnr = ENR.decodeTxt(bootnodesENRText[i]); - discv5.addEnr(bootEnr); - console.log("BOOTNODE", bootEnr.ip, bootEnr.udp); - } - - const foundENRs: ENR[] = []; - discv5.on("discovered", (enr) => { - foundENRs.push(enr); - }); - - await discv5.findRandomNode(); - - expect(foundENRs).to.have.length.greaterThan(0, "Should found some ENRs"); - }); - } -}); + it.skipIf(process.env.CI && bindAddrs.ip6)( + `Connect to nodes from Mainnet bootnodes: ${Object.keys(bindAddrs)}`, + async () => { + const privateKey = RANDOM_PRIVATE_KEY + ? await generateKeyPair("secp256k1") + : (privateKeyFromProtobuf( + Buffer.from("080212205465237331224a07d9c7b9c458e0859f401ab49f01c971857d373a3e6f6fdf3a", "hex") + ) as PrivateKey); + + const enr = SignableENR.createFromPrivateKey(privateKey); + + const discv5 = Discv5.create({ + bindAddrs, + config: { + lookupTimeout: 2000, + }, + enr, + privateKey, + }); + + await discv5.start(); + + for (let i = 0; i < bootnodesENRText.length; i++) { + const bootEnr = ENR.decodeTxt(bootnodesENRText[i]); + discv5.addEnr(bootEnr); + console.log("BOOTNODE", bootEnr.ip, bootEnr.udp); + } + + const foundENRs: ENR[] = []; + discv5.on("discovered", (enr) => { + foundENRs.push(enr); + }); + + await discv5.findRandomNode(); + + expect(foundENRs).to.have.length.greaterThan(0, "Should found some ENRs"); + } + ); + } + }, + 5 * 60 * 1000 +); function getMainnetBootnodesENRText(): string[] { return [ // # Teku team's bootnodes - "enr:-KG4QOtcP9X1FbIMOe17QNMKqDxCpm14jcX5tiOE4_TyMrFqbmhPZHK_ZPG2Gxb1GE2xdtodOfx9-cgvNtxnRyHEmC0ghGV0aDKQ9aX9QgAAAAD__________4JpZIJ2NIJpcIQDE8KdiXNlY3AyNTZrMaEDhpehBDbZjM_L9ek699Y7vhUJ-eAdMyQW_Fil522Y0fODdGNwgiMog3VkcIIjKA", - "enr:-KG4QDyytgmE4f7AnvW-ZaUOIi9i79qX4JwjRAiXBZCU65wOfBu-3Nb5I7b_Rmg3KCOcZM_C3y5pg7EBU5XGrcLTduQEhGV0aDKQ9aX9QgAAAAD__________4JpZIJ2NIJpcIQ2_DUbiXNlY3AyNTZrMaEDKnz_-ps3UUOfHWVYaskI5kWYO_vtYMGYCQRAR3gHDouDdGNwgiMog3VkcIIjKA", + "enr:-Iu4QLm7bZGdAt9NSeJG0cEnJohWcQTQaI9wFLu3Q7eHIDfrI4cwtzvEW3F3VbG9XdFXlrHyFGeXPn9snTCQJ9bnMRABgmlkgnY0gmlwhAOTJQCJc2VjcDI1NmsxoQIZdZD6tDYpkpEfVo5bgiU8MGRjhcOmHGD2nErK0UKRrIN0Y3CCIyiDdWRwgiMo", // # 3.147.37.0 | aws-us-east-2-ohio + "enr:-Iu4QEDJ4Wa_UQNbK8Ay1hFEkXvd8psolVK6OhfTL9irqz3nbXxxWyKwEplPfkju4zduVQj6mMhUCm9R2Lc4YM5jPcIBgmlkgnY0gmlwhANrfESJc2VjcDI1NmsxoQJCYz2-nsqFpeEj6eov9HSi9QssIVIVNr0I89J1vXM9foN0Y3CCIyiDdWRwgiMo", // # 3.107.124.68 | aws-ap-southeast-2-sydney // # Prylab team's bootnodes - "enr:-Ku4QImhMc1z8yCiNJ1TyUxdcfNucje3BGwEHzodEZUan8PherEo4sF7pPHPSIB1NNuSg5fZy7qFsjmUKs2ea1Whi0EBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQOVphkDqal4QzPMksc5wnpuC3gvSC8AfbFOnZY_On34wIN1ZHCCIyg", - "enr:-Ku4QP2xDnEtUXIjzJ_DhlCRN9SN99RYQPJL92TMlSv7U5C1YnYLjwOQHgZIUXw6c-BvRg2Yc2QsZxxoS_pPRVe0yK8Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQMeFF5GrS7UZpAH2Ly84aLK-TyvH-dRo0JM1i8yygH50YN1ZHCCJxA", - "enr:-Ku4QPp9z1W4tAO8Ber_NQierYaOStqhDqQdOPY3bB3jDgkjcbk6YrEnVYIiCBbTxuar3CzS528d2iE7TdJsrL-dEKoBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQMw5fqqkw2hHC4F5HZZDPsNmPdB1Gi8JPQK7pRc9XHh-oN1ZHCCKvg", + "enr:-Ku4QImhMc1z8yCiNJ1TyUxdcfNucje3BGwEHzodEZUan8PherEo4sF7pPHPSIB1NNuSg5fZy7qFsjmUKs2ea1Whi0EBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQOVphkDqal4QzPMksc5wnpuC3gvSC8AfbFOnZY_On34wIN1ZHCCIyg", // 18.223.219.100 | aws-us-east-2-ohio + "enr:-Ku4QP2xDnEtUXIjzJ_DhlCRN9SN99RYQPJL92TMlSv7U5C1YnYLjwOQHgZIUXw6c-BvRg2Yc2QsZxxoS_pPRVe0yK8Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQMeFF5GrS7UZpAH2Ly84aLK-TyvH-dRo0JM1i8yygH50YN1ZHCCJxA", // 18.223.219.100 | aws-us-east-2-ohio + "enr:-Ku4QPp9z1W4tAO8Ber_NQierYaOStqhDqQdOPY3bB3jDgkjcbk6YrEnVYIiCBbTxuar3CzS528d2iE7TdJsrL-dEKoBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQMw5fqqkw2hHC4F5HZZDPsNmPdB1Gi8JPQK7pRc9XHh-oN1ZHCCKvg", // 18.223.219.100 | aws-us-east-2-ohio // # Lighthouse team's bootnodes - "enr:-Le4QPUXJS2BTORXxyx2Ia-9ae4YqA_JWX3ssj4E_J-3z1A-HmFGrU8BpvpqhNabayXeOZ2Nq_sbeDgtzMJpLLnXFgAChGV0aDKQtTA_KgEAAAAAIgEAAAAAAIJpZIJ2NIJpcISsaa0Zg2lwNpAkAIkHAAAAAPA8kv_-awoTiXNlY3AyNTZrMaEDHAD2JKYevx89W0CcFJFiskdcEzkH_Wdv9iW42qLK79ODdWRwgiMohHVkcDaCI4I", - "enr:-Le4QLHZDSvkLfqgEo8IWGG96h6mxwe_PsggC20CL3neLBjfXLGAQFOPSltZ7oP6ol54OvaNqO02Rnvb8YmDR274uq8ChGV0aDKQtTA_KgEAAAAAIgEAAAAAAIJpZIJ2NIJpcISLosQxg2lwNpAqAX4AAAAAAPA8kv_-ax65iXNlY3AyNTZrMaEDBJj7_dLFACaxBfaI8KZTh_SSJUjhyAyfshimvSqo22WDdWRwgiMohHVkcDaCI4I", - "enr:-Le4QH6LQrusDbAHPjU_HcKOuMeXfdEB5NJyXgHWFadfHgiySqeDyusQMvfphdYWOzuSZO9Uq2AMRJR5O4ip7OvVma8BhGV0aDKQtTA_KgEAAAAAIgEAAAAAAIJpZIJ2NIJpcISLY9ncg2lwNpAkAh8AgQIBAAAAAAAAAAmXiXNlY3AyNTZrMaECDYCZTZEksF-kmgPholqgVt8IXr-8L7Nu7YrZ7HUpgxmDdWRwgiMohHVkcDaCI4I", - "enr:-Le4QIqLuWybHNONr933Lk0dcMmAB5WgvGKRyDihy1wHDIVlNuuztX62W51voT4I8qD34GcTEOTmag1bcdZ_8aaT4NUBhGV0aDKQtTA_KgEAAAAAIgEAAAAAAIJpZIJ2NIJpcISLY04ng2lwNpAkAh8AgAIBAAAAAAAAAA-fiXNlY3AyNTZrMaEDscnRV6n1m-D9ID5UsURk0jsoKNXt1TIrj8uKOGW6iluDdWRwgiMohHVkcDaCI4I", + "enr:-Le4QPUXJS2BTORXxyx2Ia-9ae4YqA_JWX3ssj4E_J-3z1A-HmFGrU8BpvpqhNabayXeOZ2Nq_sbeDgtzMJpLLnXFgAChGV0aDKQtTA_KgEAAAAAIgEAAAAAAIJpZIJ2NIJpcISsaa0Zg2lwNpAkAIkHAAAAAPA8kv_-awoTiXNlY3AyNTZrMaEDHAD2JKYevx89W0CcFJFiskdcEzkH_Wdv9iW42qLK79ODdWRwgiMohHVkcDaCI4I", // 172.105.173.25 | linode-au-sydney + "enr:-Le4QLHZDSvkLfqgEo8IWGG96h6mxwe_PsggC20CL3neLBjfXLGAQFOPSltZ7oP6ol54OvaNqO02Rnvb8YmDR274uq8ChGV0aDKQtTA_KgEAAAAAIgEAAAAAAIJpZIJ2NIJpcISLosQxg2lwNpAqAX4AAAAAAPA8kv_-ax65iXNlY3AyNTZrMaEDBJj7_dLFACaxBfaI8KZTh_SSJUjhyAyfshimvSqo22WDdWRwgiMohHVkcDaCI4I", // 139.162.196.49 | linode-uk-london + "enr:-Le4QH6LQrusDbAHPjU_HcKOuMeXfdEB5NJyXgHWFadfHgiySqeDyusQMvfphdYWOzuSZO9Uq2AMRJR5O4ip7OvVma8BhGV0aDKQtTA_KgEAAAAAIgEAAAAAAIJpZIJ2NIJpcISLY9ncg2lwNpAkAh8AgQIBAAAAAAAAAAmXiXNlY3AyNTZrMaECDYCZTZEksF-kmgPholqgVt8IXr-8L7Nu7YrZ7HUpgxmDdWRwgiMohHVkcDaCI4I", // 139.99.217.220 | ovh-au-sydney + "enr:-Le4QIqLuWybHNONr933Lk0dcMmAB5WgvGKRyDihy1wHDIVlNuuztX62W51voT4I8qD34GcTEOTmag1bcdZ_8aaT4NUBhGV0aDKQtTA_KgEAAAAAIgEAAAAAAIJpZIJ2NIJpcISLY04ng2lwNpAkAh8AgAIBAAAAAAAAAA-fiXNlY3AyNTZrMaEDscnRV6n1m-D9ID5UsURk0jsoKNXt1TIrj8uKOGW6iluDdWRwgiMohHVkcDaCI4I", // 139.99.78.39 | ovh-singapore // # EF bootnodes - "enr:-Ku4QHqVeJ8PPICcWk1vSn_XcSkjOkNiTg6Fmii5j6vUQgvzMc9L1goFnLKgXqBJspJjIsB91LTOleFmyWWrFVATGngBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhAMRHkWJc2VjcDI1NmsxoQKLVXFOhp2uX6jeT0DvvDpPcU8FWMjQdR4wMuORMhpX24N1ZHCCIyg", - "enr:-Ku4QG-2_Md3sZIAUebGYT6g0SMskIml77l6yR-M_JXc-UdNHCmHQeOiMLbylPejyJsdAPsTHJyjJB2sYGDLe0dn8uYBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhBLY-NyJc2VjcDI1NmsxoQORcM6e19T1T9gi7jxEZjk_sjVLGFscUNqAY9obgZaxbIN1ZHCCIyg", - "enr:-Ku4QPn5eVhcoF1opaFEvg1b6JNFD2rqVkHQ8HApOKK61OIcIXD127bKWgAtbwI7pnxx6cDyk_nI88TrZKQaGMZj0q0Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhDayLMaJc2VjcDI1NmsxoQK2sBOLGcUb4AwuYzFuAVCaNHA-dy24UuEKkeFNgCVCsIN1ZHCCIyg", - "enr:-Ku4QEWzdnVtXc2Q0ZVigfCGggOVB2Vc1ZCPEc6j21NIFLODSJbvNaef1g4PxhPwl_3kax86YPheFUSLXPRs98vvYsoBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhDZBrP2Jc2VjcDI1NmsxoQM6jr8Rb1ktLEsVcKAPa08wCsKUmvoQ8khiOl_SLozf9IN1ZHCCIyg", + "enr:-Ku4QHqVeJ8PPICcWk1vSn_XcSkjOkNiTg6Fmii5j6vUQgvzMc9L1goFnLKgXqBJspJjIsB91LTOleFmyWWrFVATGngBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhAMRHkWJc2VjcDI1NmsxoQKLVXFOhp2uX6jeT0DvvDpPcU8FWMjQdR4wMuORMhpX24N1ZHCCIyg", // 3.17.30.69 | aws-us-east-2-ohio + "enr:-Ku4QG-2_Md3sZIAUebGYT6g0SMskIml77l6yR-M_JXc-UdNHCmHQeOiMLbylPejyJsdAPsTHJyjJB2sYGDLe0dn8uYBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhBLY-NyJc2VjcDI1NmsxoQORcM6e19T1T9gi7jxEZjk_sjVLGFscUNqAY9obgZaxbIN1ZHCCIyg", // # 18.216.248.220 | aws-us-east-2-ohio + "enr:-Ku4QPn5eVhcoF1opaFEvg1b6JNFD2rqVkHQ8HApOKK61OIcIXD127bKWgAtbwI7pnxx6cDyk_nI88TrZKQaGMZj0q0Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhDayLMaJc2VjcDI1NmsxoQK2sBOLGcUb4AwuYzFuAVCaNHA-dy24UuEKkeFNgCVCsIN1ZHCCIyg", // # 54.178.44.198 | aws-ap-northeast-1-tokyo + "enr:-Ku4QEWzdnVtXc2Q0ZVigfCGggOVB2Vc1ZCPEc6j21NIFLODSJbvNaef1g4PxhPwl_3kax86YPheFUSLXPRs98vvYsoBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhDZBrP2Jc2VjcDI1NmsxoQM6jr8Rb1ktLEsVcKAPa08wCsKUmvoQ8khiOl_SLozf9IN1ZHCCIyg", // # 54.65.172.253 | aws-ap-northeast-1-tokyo // # Nimbus team's bootnodes - "enr:-LK4QLU5_AeUzZEtpK8grqPo4EmX4el3ochu8vNNoXX1PrBjYfn8ksjeQ1eFtbL7ywMau9k_7BBQGmO26DHWgngkBCgBh2F0dG5ldHOI__________-EZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhAN7_O-Jc2VjcDI1NmsxoQKH1zg2Fge8Q6Zf-rLFbjGEtgvVbmDXqFVLxqquJcguFIN0Y3CCI4yDdWRwgiOM", - "enr:-LK4QLjSKc09WkFZ5Pa1UF3KPkt3ieTZ6B7F6iDL_chyniP5NVDl10aGIu-pL9mbwZ47GM3RN63eGHPsw-MTLSYcz74Bh2F0dG5ldHOI__________-EZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhDQ7fI6Jc2VjcDI1NmsxoQJDU6zzDlUDgUqFSzoIuP9bWu097k2d7X4eHoJTGhbphoN0Y3CCI4yDdWRwgiOM", + "enr:-LK4QA8FfhaAjlb_BXsXxSfiysR7R52Nhi9JBt4F8SPssu8hdE1BXQQEtVDC3qStCW60LSO7hEsVHv5zm8_6Vnjhcn0Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhAN4aBKJc2VjcDI1NmsxoQJerDhsJ-KxZ8sHySMOCmTO6sHM3iCFQ6VMvLTe948MyYN0Y3CCI4yDdWRwgiOM", // 3.120.104.18 | aws-eu-central-1-frankfurt + "enr:-LK4QKWrXTpV9T78hNG6s8AM6IO4XH9kFT91uZtFg1GcsJ6dKovDOr1jtAAFPnS2lvNltkOGA9k29BUN7lFh_sjuc9QBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhANAdd-Jc2VjcDI1NmsxoQLQa6ai7y9PMN5hpLe5HmiJSlYzMuzP7ZhwRiwHvqNXdoN0Y3CCI4yDdWRwgiOM", // 3.64.117.223 | aws-eu-central-1-frankfurt + + // # Lodestar team's bootnodes + "enr:-IS4QPi-onjNsT5xAIAenhCGTDl4z-4UOR25Uq-3TmG4V3kwB9ljLTb_Kp1wdjHNj-H8VVLRBSSWVZo3GUe3z6k0E-IBgmlkgnY0gmlwhKB3_qGJc2VjcDI1NmsxoQMvAfgB4cJXvvXeM6WbCG86CstbSxbQBSGx31FAwVtOTYN1ZHCCIyg", // 160.119.254.161 | hostafrica-southafrica + "enr:-KG4QPUf8-g_jU-KrwzG42AGt0wWM1BTnQxgZXlvCEIfTQ5hSmptkmgmMbRkpOqv6kzb33SlhPHJp7x4rLWWiVq5lSECgmlkgnY0gmlwhFPlR9KDaXA2kCoGxcAJAAAVAAAAAAAAABCJc2VjcDI1NmsxoQLdUv9Eo9sxCt0tc_CheLOWnX59yHJtkBSOL7kpxdJ6GYN1ZHCCIyiEdWRwNoIjKA", // 83.229.71.210 | kamatera-telaviv-israel ]; } diff --git a/packages/discv5/test/unit/kademlia/kademlia.test.ts b/packages/discv5/test/unit/kademlia/kademlia.test.ts index 3f8e343f..d1ef4ba9 100644 --- a/packages/discv5/test/unit/kademlia/kademlia.test.ts +++ b/packages/discv5/test/unit/kademlia/kademlia.test.ts @@ -1,10 +1,9 @@ -/* eslint-env mocha */ -import { KademliaRoutingTable } from "../../../src/kademlia/kademlia.js"; -import { expect } from "chai"; -import { ENR, createNodeId, SignableENR } from "@chainsafe/enr"; -import { EntryStatus, log2Distance } from "../../../src/kademlia/index.js"; -import { randomBytes } from "@noble/hashes/utils"; -import { generateKeypair } from "../../../src/index.js"; +import {type ENR, SignableENR, createNodeId} from "@chainsafe/enr"; +import {randomBytes} from "@noble/hashes/utils.js"; +import {describe, expect, it} from "vitest"; +import {generateKeypair} from "../../../src/index.js"; +import {EntryStatus, log2Distance} from "../../../src/kademlia/index.js"; +import {KademliaRoutingTable} from "../../../src/kademlia/kademlia.js"; describe("Kademlia routing table", () => { const nodeId = createNodeId(Buffer.alloc(32)); diff --git a/packages/discv5/test/unit/kademlia/util.test.ts b/packages/discv5/test/unit/kademlia/util.test.ts index 9ef842d3..79ccbbd1 100644 --- a/packages/discv5/test/unit/kademlia/util.test.ts +++ b/packages/discv5/test/unit/kademlia/util.test.ts @@ -1,8 +1,7 @@ -/* eslint-env mocha */ -import { expect } from "chai"; -import { randomBytes } from "@noble/hashes/utils"; -import { createNodeId } from "@chainsafe/enr"; -import { distance, log2Distance } from "../../../src/kademlia/index.js"; +import {createNodeId} from "@chainsafe/enr"; +import {randomBytes} from "@noble/hashes/utils.js"; +import {describe, expect, it} from "vitest"; +import {distance, log2Distance} from "../../../src/kademlia/index.js"; describe("Kademlia distance function", () => { it("identity", () => { diff --git a/packages/discv5/test/unit/message/codec.test.ts b/packages/discv5/test/unit/message/codec.test.ts index 7bd49dc1..36522b2e 100644 --- a/packages/discv5/test/unit/message/codec.test.ts +++ b/packages/discv5/test/unit/message/codec.test.ts @@ -1,7 +1,7 @@ -import { expect } from "chai"; -import { bigintToBytes, ENR } from "@chainsafe/enr"; -import { Message, MessageType, decode, encode } from "../../../src/message/index.js"; -import { hexToBytes } from "ethereum-cryptography/utils.js"; +import {ENR, bigintToBytes} from "@chainsafe/enr"; +import {hexToBytes} from "ethereum-cryptography/utils.js"; +import {describe, expect, it} from "vitest"; +import {type Message, MessageType, decode, encode} from "../../../src/message/index.js"; describe("message", () => { const testCases: { @@ -9,70 +9,70 @@ describe("message", () => { expected: Uint8Array; }[] = [ { + expected: hexToBytes("01c20101"), message: { - type: MessageType.PING, - id: bigintToBytes(1n), enrSeq: 1n, + id: bigintToBytes(1n), + type: MessageType.PING, }, - expected: hexToBytes("01c20101"), }, { + expected: hexToBytes("01c20100"), message: { - type: MessageType.PING, - id: bigintToBytes(1n), enrSeq: 0n, // < test 0 enrSeq + id: bigintToBytes(1n), + type: MessageType.PING, }, - expected: hexToBytes("01c20100"), }, { + expected: hexToBytes("02c90101847f00000181ff"), message: { - type: MessageType.PONG, - id: bigintToBytes(1n), + addr: {ip: {octets: new Uint8Array([127, 0, 0, 1]), type: 4}, port: 255}, // 1 byte enrSeq: 1n, - addr: { ip: { type: 4, octets: new Uint8Array([127, 0, 0, 1]) }, port: 255 }, // 1 byte + id: bigintToBytes(1n), + type: MessageType.PONG, }, - expected: hexToBytes("02c90101847f00000181ff"), }, { + expected: hexToBytes("02ca0101847f000001821388"), message: { - type: MessageType.PONG, - id: bigintToBytes(1n), + addr: {ip: {octets: new Uint8Array([127, 0, 0, 1]), type: 4}, port: 5000}, enrSeq: 1n, - addr: { ip: { type: 4, octets: new Uint8Array([127, 0, 0, 1]) }, port: 5000 }, + id: bigintToBytes(1n), + type: MessageType.PONG, }, - expected: hexToBytes("02ca0101847f000001821388"), }, { + expected: hexToBytes("02d6010190aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa821388"), message: { - type: MessageType.PONG, - id: bigintToBytes(1n), + addr: {ip: {octets: new Uint8Array(16).fill(0xaa), type: 6}, port: 5000}, // 2 bytes enrSeq: 1n, - addr: { ip: { type: 6, octets: new Uint8Array(16).fill(0xaa) }, port: 5000 }, // 2 bytes + id: bigintToBytes(1n), + type: MessageType.PONG, }, - expected: hexToBytes("02d6010190aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa821388"), }, { + expected: hexToBytes("03c401c281fa"), message: { - type: MessageType.FINDNODE, - id: bigintToBytes(1n), distances: [250], + id: bigintToBytes(1n), + type: MessageType.FINDNODE, }, - expected: hexToBytes("03c401c281fa"), }, { + expected: hexToBytes("04c30101c0"), message: { - type: MessageType.NODES, + enrs: [], id: bigintToBytes(1n), total: 1, - enrs: [], + type: MessageType.NODES, }, - expected: hexToBytes("04c30101c0"), }, { + expected: hexToBytes( + "04f8f20101f8eef875b8401ce2991c64993d7c84c29a00bdc871917551c7d330fca2dd0d69c706596dc655448f030b98a77d4001fd46ae0112ce26d613c5a6a02a81a6223cd0c4edaa53280182696482763489736563703235366b31a103ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd3138f875b840d7f1c39e376297f81d7297758c64cb37dcc5c3beea9f57f7ce9695d7d5a67553417d719539d6ae4b445946de4d99e680eb8063f29485b555d45b7df16a1850130182696482763489736563703235366b31a1030e2cb74241c0c4fc8e8166f1a79a05d5b0dd95813a74b094529f317d5c39d235" + ), message: { - type: MessageType.NODES, - id: bigintToBytes(1n), - total: 1, enrs: [ ENR.decodeTxt( "enr:-HW4QBzimRxkmT18hMKaAL3IcZF1UcfTMPyi3Q1pxwZZbcZVRI8DC5infUAB_UauARLOJtYTxaagKoGmIjzQxO2qUygBgmlkgnY0iXNlY3AyNTZrMaEDymNMrg1JrLQB2KTGtv6MVbcNEVv0AHacwUAPMljNMTg" @@ -81,13 +81,13 @@ describe("message", () => { "enr:-HW4QNfxw543Ypf4HXKXdYxkyzfcxcO-6p9X986WldfVpnVTQX1xlTnWrktEWUbeTZnmgOuAY_KUhbVV1Ft98WoYUBMBgmlkgnY0iXNlY3AyNTZrMaEDDiy3QkHAxPyOgWbxp5oF1bDdlYE6dLCUUp8xfVw50jU" ), ], + id: bigintToBytes(1n), + total: 1, + type: MessageType.NODES, }, - expected: hexToBytes( - "04f8f20101f8eef875b8401ce2991c64993d7c84c29a00bdc871917551c7d330fca2dd0d69c706596dc655448f030b98a77d4001fd46ae0112ce26d613c5a6a02a81a6223cd0c4edaa53280182696482763489736563703235366b31a103ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd3138f875b840d7f1c39e376297f81d7297758c64cb37dcc5c3beea9f57f7ce9695d7d5a67553417d719539d6ae4b445946de4d99e680eb8063f29485b555d45b7df16a1850130182696482763489736563703235366b31a1030e2cb74241c0c4fc8e8166f1a79a05d5b0dd95813a74b094529f317d5c39d235" - ), }, ]; - for (const { message, expected } of testCases) { + for (const {message, expected} of testCases) { it(`should encode/decode message type ${MessageType[message.type]}`, () => { const actual = encode(message); expect(actual).to.deep.equal(expected); @@ -105,27 +105,27 @@ describe("invalid messages", () => { expected: Error; }[] = [ { + expected: new Error("invalid port for encoding"), message: { - type: MessageType.PONG, - id: bigintToBytes(1n), - enrSeq: 1n, // Negative port is invalid. - addr: { ip: { type: 4, octets: new Uint8Array([127, 0, 0, 1]) }, port: -1 }, + addr: {ip: {octets: new Uint8Array([127, 0, 0, 1]), type: 4}, port: -1}, + enrSeq: 1n, + id: bigintToBytes(1n), + type: MessageType.PONG, }, - expected: new Error("invalid port for encoding"), }, { + expected: new Error("invalid port for encoding"), message: { - type: MessageType.PONG, - id: bigintToBytes(1n), - enrSeq: 1n, // This port is greater than 16 bits. - addr: { ip: { type: 4, octets: new Uint8Array([127, 0, 0, 1]) }, port: 65536 }, + addr: {ip: {octets: new Uint8Array([127, 0, 0, 1]), type: 4}, port: 65536}, + enrSeq: 1n, + id: bigintToBytes(1n), + type: MessageType.PONG, }, - expected: new Error("invalid port for encoding"), }, ]; - for (const { message, expected } of testCases) { + for (const {message, expected} of testCases) { it(`should fail to encode/decode message type ${MessageType[message.type]}`, () => { expect(() => { encode(message); diff --git a/packages/discv5/test/unit/rateLimit/rateLimiterGRCA.test.ts b/packages/discv5/test/unit/rateLimit/rateLimiterGRCA.test.ts index dffa99ca..d130119c 100644 --- a/packages/discv5/test/unit/rateLimit/rateLimiterGRCA.test.ts +++ b/packages/discv5/test/unit/rateLimit/rateLimiterGRCA.test.ts @@ -1,5 +1,5 @@ -import { expect } from "chai"; -import { RateLimiterGRCA } from "../../../src/rateLimit/rateLimiterGRCA.js"; +import {describe, expect, it} from "vitest"; +import {RateLimiterGRCA} from "../../../src/rateLimit/rateLimiterGRCA.js"; describe("GRCA limit", () => { const replenishAllEvery = 2000; @@ -8,9 +8,17 @@ describe("GRCA limit", () => { const testCases: { title: string; - steps: { sec: Seconds; tokens: number; allows: boolean }[]; + steps: {sec: Seconds; tokens: number; allows: boolean}[]; }[] = [ { + steps: [ + {allows: true, sec: 0.0, tokens: 4}, + {allows: false, sec: 0.1, tokens: 1}, + {allows: true, sec: 0.5, tokens: 1}, + {allows: true, sec: 1.0, tokens: 1}, + {allows: false, sec: 1.4, tokens: 1}, + {allows: true, sec: 2.0, tokens: 2}, + ], // x // used x // tokens x x @@ -19,34 +27,26 @@ describe("GRCA limit", () => { // | | | | | // 0 1 2 title: "burst of tokens", - steps: [ - { sec: 0.0, tokens: 4, allows: true }, - { sec: 0.1, tokens: 1, allows: false }, - { sec: 0.5, tokens: 1, allows: true }, - { sec: 1.0, tokens: 1, allows: true }, - { sec: 1.4, tokens: 1, allows: false }, - { sec: 2.0, tokens: 2, allows: true }, - ], }, { + steps: [ + {allows: true, sec: 0.0, tokens: 1}, + {allows: true, sec: 0.1, tokens: 1}, + {allows: true, sec: 0.2, tokens: 1}, + {allows: true, sec: 0.3, tokens: 1}, + {allows: false, sec: 0.4, tokens: 1}, + ], // if we limit to 4T per 2s, check that 4 requests worth 1 token can be sent before the // first half second, when one token will be available again. Check also that before // regaining a token, another request is rejected title: "Fill bucket with single requests", - steps: [ - { sec: 0.0, tokens: 1, allows: true }, - { sec: 0.1, tokens: 1, allows: true }, - { sec: 0.2, tokens: 1, allows: true }, - { sec: 0.3, tokens: 1, allows: true }, - { sec: 0.4, tokens: 1, allows: false }, - ], }, ]; - for (const { title, steps } of testCases) { + for (const {title, steps} of testCases) { it(title, () => { - const limiter = RateLimiterGRCA.fromQuota({ replenishAllEvery, maxTokens }); - for (const [i, { sec, tokens, allows }] of steps.entries()) { + const limiter = RateLimiterGRCA.fromQuota({maxTokens, replenishAllEvery}); + for (const [i, {sec, tokens, allows}] of steps.entries()) { expect(limiter.allows(key, tokens, sec * 1000)).equals(allows, `step ${i}`); } }); diff --git a/packages/discv5/test/unit/service/addrVotes.test.ts b/packages/discv5/test/unit/service/addrVotes.test.ts index 328aaef0..15e8ad9d 100644 --- a/packages/discv5/test/unit/service/addrVotes.test.ts +++ b/packages/discv5/test/unit/service/addrVotes.test.ts @@ -1,7 +1,7 @@ -import { expect } from "chai"; -import { createNodeId } from "@chainsafe/enr"; -import { AddrVotes } from "../../../src/service/addrVotes.js"; -import { SocketAddress } from "../../../src/util/ip.js"; +import {createNodeId} from "@chainsafe/enr"; +import {beforeEach, describe, expect, it} from "vitest"; +import {AddrVotes} from "../../../src/service/addrVotes.js"; +import type {SocketAddress} from "../../../src/util/ip.js"; describe("AddrVotes", () => { let addVotes: AddrVotes; @@ -11,7 +11,7 @@ describe("AddrVotes", () => { }); it("should return winning vote after 3 same votes", () => { - const addr: SocketAddress = { ip: { type: 4, octets: new Uint8Array([127, 0, 0, 1]) }, port: 30303 }; + const addr: SocketAddress = {ip: {octets: new Uint8Array([127, 0, 0, 1]), type: 4}, port: 30303}; const nodeId = createNodeId(Buffer.alloc(32)); expect(addVotes.addVote(nodeId, addr)).equals(false); // same vote, no effect @@ -25,8 +25,8 @@ describe("AddrVotes", () => { }); it("1 node adds 2 different vote", () => { - const addr: SocketAddress = { ip: { type: 4, octets: new Uint8Array([127, 0, 0, 1]) }, port: 30303 }; - const ipStrange: SocketAddress = { ip: addr.ip, port: 30304 }; + const addr: SocketAddress = {ip: {octets: new Uint8Array([127, 0, 0, 1]), type: 4}, port: 30303}; + const ipStrange: SocketAddress = {ip: addr.ip, port: 30304}; const nodeId = createNodeId(Buffer.alloc(32)); expect(addVotes.addVote(nodeId, addr)).equals(false); // new vote, strange one => 1st vote is deleted diff --git a/packages/discv5/test/unit/service/service.test.ts b/packages/discv5/test/unit/service/service.test.ts index 4d94f601..fb5f8671 100644 --- a/packages/discv5/test/unit/service/service.test.ts +++ b/packages/discv5/test/unit/service/service.test.ts @@ -1,19 +1,16 @@ -/* eslint-env mocha */ -import { expect } from "chai"; -import { privateKeyFromRaw } from "@libp2p/crypto/keys"; -import { multiaddr } from "@multiformats/multiaddr"; -import { SignableENR } from "@chainsafe/enr"; +import {SignableENR} from "@chainsafe/enr"; +import {generateKeyPair} from "@libp2p/crypto/keys"; +import {multiaddr} from "@multiformats/multiaddr"; +import {afterEach, beforeEach, describe, expect, it} from "vitest"; -import { Discv5 } from "../../../src/service/service.js"; -import { generateKeypair } from "../../../src/keypair/index.js"; +import {Discv5} from "../../../src/service/service.js"; describe("Discv5", async () => { - const kp0 = generateKeypair("secp256k1"); - const privateKey0 = privateKeyFromRaw(kp0.privateKey); - const enr0 = SignableENR.createV4(kp0.privateKey); + const kp0 = await generateKeyPair("secp256k1"); + const enr0 = SignableENR.createV4(kp0.raw); const mu0 = multiaddr("/ip4/127.0.0.1/udp/40000"); - const service0 = Discv5.create({ enr: enr0, privateKey: privateKey0, bindAddrs: { ip4: mu0 } }); + const service0 = Discv5.create({bindAddrs: {ip4: mu0}, enr: enr0, privateKey: kp0}); beforeEach(async () => { await service0.start(); @@ -32,33 +29,31 @@ describe("Discv5", async () => { }); it("should add new enrs", async () => { - const kp1 = generateKeypair("secp256k1"); - const enr1 = SignableENR.createV4(kp1.privateKey); + const kp1 = await generateKeyPair("secp256k1"); + const enr1 = SignableENR.createV4(kp1.raw); enr1.encode(); service0.addEnr(enr1.toENR()); expect(service0.kadValues().length).eq(1); }); - it("should complete a lookup to another node", async function () { - this.timeout(10000); - const kp1 = generateKeypair("secp256k1"); - const privateKey1 = privateKeyFromRaw(kp1.privateKey); - const enr1 = SignableENR.createV4(kp1.privateKey); + it("should complete a lookup to another node", async () => { + const kp1 = await generateKeyPair("secp256k1"); + const enr1 = SignableENR.createV4(kp1.raw); const mu1 = multiaddr("/ip4/127.0.0.1/udp/10360"); - const addr1 = mu1.tuples(); + const components1 = mu1.getComponents(); - if (!addr1[0][1] || !addr1[1][1]) { + if (!components1[0].value || !components1[1].value) { throw new Error("invalid multiaddr"); } - enr1.set("ip", addr1[0][1]); - enr1.set("udp", addr1[1][1]); + enr1.ip = components1[0].value; + enr1.udp = Number(components1[1].value); enr1.encode(); - const service1 = Discv5.create({ enr: enr1, privateKey: privateKey1, bindAddrs: { ip4: mu1 } }); + const service1 = Discv5.create({bindAddrs: {ip4: mu1}, enr: enr1, privateKey: kp1}); await service1.start(); for (let i = 0; i < 100; i++) { - const kp = generateKeypair("secp256k1"); - const enr = SignableENR.createV4(kp.privateKey); + const kp = await generateKeyPair("secp256k1"); + const enr = SignableENR.createV4(kp.raw); enr.encode(); service1.addEnr(enr.toENR()); } @@ -66,4 +61,4 @@ describe("Discv5", async () => { await service0.findNode(Buffer.alloc(32).toString("hex")); await service1.stop(); }); -}); +}, 10_000); diff --git a/packages/discv5/test/unit/session/crypto.test.ts b/packages/discv5/test/unit/session/crypto.test.ts index 01a58b9b..3e365e80 100644 --- a/packages/discv5/test/unit/session/crypto.test.ts +++ b/packages/discv5/test/unit/session/crypto.test.ts @@ -1,19 +1,17 @@ -/* eslint-env mocha */ -import { expect } from "chai"; -import { randomBytes } from "@noble/hashes/utils"; -import { getV4Crypto, SignableENR } from "@chainsafe/enr"; - +import {SignableENR, getV4Crypto} from "@chainsafe/enr"; +import {randomBytes} from "@noble/hashes/utils.js"; +import {describe, expect, it} from "vitest"; +import {createKeypair, generateKeypair} from "../../../src/keypair/index.js"; import { + decryptMessage, deriveKey, - generateSessionKeys, deriveKeysFromPubkey, + encryptMessage, + generateSessionKeys, idSign, idVerify, - encryptMessage, - decryptMessage, } from "../../../src/session/index.js"; -import { createKeypair, generateKeypair } from "../../../src/keypair/index.js"; -import { getDiscv5Crypto } from "../../../src/util/crypto.js"; +import {getDiscv5Crypto} from "../../../src/util/crypto.js"; describe("session crypto", () => { it("ecdh should produce expected secret", () => { @@ -57,7 +55,7 @@ describe("session crypto", () => { const [a1, b1, pk] = generateSessionKeys( enr1.nodeId, enr2.nodeId, - createKeypair({ type: enr2.keypairType, publicKey: enr2.publicKey }), + createKeypair({publicKey: enr2.publicKey, type: enr2.keypairType}), nonce ); const [a2, b2] = deriveKeysFromPubkey(kp2, enr2.nodeId, enr1.nodeId, pk, nonce); @@ -80,11 +78,11 @@ describe("session crypto", () => { const ephemPK = Buffer.from("039961e4c2356d61bedb83052c115d311acb3a96f5777296dcf297351130266231", "hex"); const nodeIdB = "bbbb9d047f0488c0b5a93c1c3f2d8bafc7c8ff337024a55434a0d0555de64db9"; - const actual = idSign(createKeypair({ type: "secp256k1", privateKey: localSK }), challengeData, ephemPK, nodeIdB); + const actual = idSign(createKeypair({privateKey: localSK, type: "secp256k1"}), challengeData, ephemPK, nodeIdB); expect(actual).to.deep.equal(expected); expect( idVerify( - createKeypair({ type: "secp256k1", publicKey: getV4Crypto().publicKey(localSK) }), + createKeypair({publicKey: getV4Crypto().publicKey(localSK), type: "secp256k1"}), challengeData, ephemPK, nodeIdB, diff --git a/packages/discv5/test/unit/session/service.test.ts b/packages/discv5/test/unit/session/service.test.ts index b0a802e5..80920716 100644 --- a/packages/discv5/test/unit/session/service.test.ts +++ b/packages/discv5/test/unit/session/service.test.ts @@ -1,27 +1,25 @@ -/* eslint-env mocha */ -import { expect } from "chai"; -import { Multiaddr, multiaddr } from "@multiformats/multiaddr"; -import { SignableENR } from "@chainsafe/enr"; - -import { createKeypair } from "../../../src/keypair/index.js"; -import { createWhoAreYouPacket, IPacket, PacketType } from "../../../src/packet/index.js"; -import { UDPTransportService } from "../../../src/transport/index.js"; -import { SessionService } from "../../../src/session/index.js"; -import { createFindNodeMessage } from "../../../src/message/index.js"; -import { defaultConfig } from "../../../src/config/index.js"; -import { createNodeContact } from "../../../src/session/nodeInfo.js"; -import { hexToBytes } from "ethereum-cryptography/utils.js"; +import {SignableENR} from "@chainsafe/enr"; +import {type Multiaddr, multiaddr} from "@multiformats/multiaddr"; +import {hexToBytes} from "ethereum-cryptography/utils.js"; +import {afterEach, beforeEach, describe, expect, it} from "vitest"; +import {defaultConfig} from "../../../src/config/index.js"; +import {createKeypair} from "../../../src/keypair/index.js"; +import {createFindNodeMessage} from "../../../src/message/index.js"; +import {type IPacket, PacketType, createWhoAreYouPacket} from "../../../src/packet/index.js"; +import {SessionService} from "../../../src/session/index.js"; +import {createNodeContact} from "../../../src/session/nodeInfo.js"; +import {UDPTransportService} from "../../../src/transport/index.js"; describe("session service", () => { const kp0 = createKeypair({ - type: "secp256k1", privateKey: hexToBytes("a93bedf04784c937059557c9dcb328f5f59fdb6e89295c30e918579250b7b01f"), publicKey: hexToBytes("022663242e1092ea19e6bb41d67aa69850541a623b94bbea840ddceaab39789894"), + type: "secp256k1", }); const kp1 = createKeypair({ - type: "secp256k1", privateKey: hexToBytes("bd04e55f2a1424a4e69e96aad41cf763d2468d4358472e9f851569bdf47fb24c"), publicKey: hexToBytes("03eae9945b354e9212566bc3f2740f3a62b3e1eb227dbed809f6dc2d3ea848c82e"), + type: "secp256k1", }); const addr0 = multiaddr("/ip4/127.0.0.1/udp/49020"); @@ -40,8 +38,8 @@ describe("session service", () => { let service1: SessionService; beforeEach(async () => { - transport0 = new UDPTransportService({ bindAddrs: { ip4: addr0 }, nodeId: enr0.nodeId }); - transport1 = new UDPTransportService({ bindAddrs: { ip4: addr1 }, nodeId: enr1.nodeId }); + transport0 = new UDPTransportService({bindAddrs: {ip4: addr0}, nodeId: enr0.nodeId}); + transport1 = new UDPTransportService({bindAddrs: {ip4: addr1}, nodeId: enr1.nodeId}); service0 = new SessionService(defaultConfig, enr0, kp0, transport0); service1 = new SessionService(defaultConfig, enr1, kp1, transport1); @@ -85,7 +83,7 @@ describe("session service", () => { resolve(); }) ); - service0.sendRequest(createNodeContact(enr1.toENR(), { ip4: true, ip6: true }), createFindNodeMessage([0])); + service0.sendRequest(createNodeContact(enr1.toENR(), {ip4: true, ip6: true}), createFindNodeMessage([0])); await Promise.all([receivedRandom, receivedWhoAreYou, establishedSession, receivedMsg]); }); it("receiver should drop WhoAreYou packets from destinations without existing pending requests", async () => { diff --git a/packages/discv5/test/unit/transport/udp.test.ts b/packages/discv5/test/unit/transport/udp.test.ts index 31ed3521..7ef45857 100644 --- a/packages/discv5/test/unit/transport/udp.test.ts +++ b/packages/discv5/test/unit/transport/udp.test.ts @@ -1,44 +1,42 @@ -/* eslint-env mocha */ -import { expect } from "chai"; -import { Multiaddr, multiaddr } from "@multiformats/multiaddr"; - -import { PacketType, IPacket, NONCE_SIZE, MASKING_IV_SIZE } from "../../../src/packet/index.js"; -import { UDPTransportService } from "../../../src/transport/index.js"; -import { bytesToHex } from "ethereum-cryptography/utils.js"; +import {type Multiaddr, multiaddr} from "@multiformats/multiaddr"; +import {bytesToHex} from "ethereum-cryptography/utils.js"; +import {afterAll, beforeAll, describe, expect, it} from "vitest"; +import {type IPacket, MASKING_IV_SIZE, NONCE_SIZE, PacketType} from "../../../src/packet/index.js"; +import {UDPTransportService} from "../../../src/transport/index.js"; describe("UDP4 transport", () => { const address = "127.0.0.1"; const nodeIdA = bytesToHex(new Uint8Array(32).fill(1)); const portA = 49523; const multiaddrA = multiaddr(`/ip4/${address}/udp/${portA}`); - const a = new UDPTransportService({ bindAddrs: { ip4: multiaddrA }, nodeId: nodeIdA }); + const a = new UDPTransportService({bindAddrs: {ip4: multiaddrA}, nodeId: nodeIdA}); const nodeIdB = bytesToHex(new Uint8Array(32).fill(2)); const portB = portA + 1; const multiaddrB = multiaddr(`/ip4/${address}/udp/${portB}`); - const b = new UDPTransportService({ bindAddrs: { ip4: multiaddrB }, nodeId: nodeIdB }); + const b = new UDPTransportService({bindAddrs: {ip4: multiaddrB}, nodeId: nodeIdB}); - before(async () => { + beforeAll(async () => { await a.start(); await b.start(); }); - after(async () => { + afterAll(async () => { await a.stop(); await b.stop(); }); it("should send and receive messages", async () => { const messagePacket: IPacket = { - maskingIv: new Uint8Array(MASKING_IV_SIZE), header: { - protocolId: "discv5", - version: 1, + authdata: new Uint8Array(32).fill(2), + authdataSize: 32, flag: PacketType.Message, nonce: new Uint8Array(NONCE_SIZE), - authdataSize: 32, - authdata: new Uint8Array(32).fill(2), + protocolId: "discv5", + version: 1, }, + maskingIv: new Uint8Array(MASKING_IV_SIZE), message: new Uint8Array(44).fill(1), }; const received = new Promise<[Multiaddr, IPacket]>((resolve) => @@ -58,34 +56,34 @@ describe("UDP6 transport", () => { const nodeIdA = bytesToHex(new Uint8Array(32).fill(1)); const portA = 49523; const multiaddrA = multiaddr(`/ip6/${address}/udp/${portA}`); - const a = new UDPTransportService({ bindAddrs: { ip6: multiaddrA }, nodeId: nodeIdA }); + const a = new UDPTransportService({bindAddrs: {ip6: multiaddrA}, nodeId: nodeIdA}); const nodeIdB = bytesToHex(new Uint8Array(32).fill(2)); const portB = portA + 1; const multiaddrB = multiaddr(`/ip6/${address}/udp/${portB}`); - const b = new UDPTransportService({ bindAddrs: { ip6: multiaddrB }, nodeId: nodeIdB }); + const b = new UDPTransportService({bindAddrs: {ip6: multiaddrB}, nodeId: nodeIdB}); - before(async () => { + beforeAll(async () => { await a.start(); await b.start(); }); - after(async () => { + afterAll(async () => { await a.stop(); await b.stop(); }); it("should send and receive messages", async () => { const messagePacket: IPacket = { - maskingIv: new Uint8Array(MASKING_IV_SIZE), header: { - protocolId: "discv5", - version: 1, + authdata: new Uint8Array(32).fill(2), + authdataSize: 32, flag: PacketType.Message, nonce: new Uint8Array(NONCE_SIZE), - authdataSize: 32, - authdata: new Uint8Array(32).fill(2), + protocolId: "discv5", + version: 1, }, + maskingIv: new Uint8Array(MASKING_IV_SIZE), message: new Uint8Array(44).fill(1), }; const received = new Promise<[Multiaddr, IPacket]>((resolve) => @@ -101,42 +99,42 @@ describe("UDP6 transport", () => { }); describe("UDP4+6 transport", () => { - context("with loopback addresses", () => { + describe("with loopback addresses", () => { const address4 = "127.0.0.1"; const address6 = "::1"; const nodeIdA = bytesToHex(new Uint8Array(32).fill(1)); const portA = 49523; const multiaddr4A = multiaddr(`/ip4/${address4}/udp/${portA}`); const multiaddr6A = multiaddr(`/ip6/${address6}/udp/${portA}`); - const a = new UDPTransportService({ bindAddrs: { ip4: multiaddr4A, ip6: multiaddr6A }, nodeId: nodeIdA }); + const a = new UDPTransportService({bindAddrs: {ip4: multiaddr4A, ip6: multiaddr6A}, nodeId: nodeIdA}); const nodeIdB = bytesToHex(new Uint8Array(32).fill(2)); const portB = portA + 1; const multiaddr4B = multiaddr(`/ip4/${address4}/udp/${portB}`); const multiaddr6B = multiaddr(`/ip6/${address6}/udp/${portB}`); - const b = new UDPTransportService({ bindAddrs: { ip4: multiaddr4B, ip6: multiaddr6B }, nodeId: nodeIdB }); + const b = new UDPTransportService({bindAddrs: {ip4: multiaddr4B, ip6: multiaddr6B}, nodeId: nodeIdB}); - before(async () => { + beforeAll(async () => { await a.start(); await b.start(); }); - after(async () => { + afterAll(async () => { await a.stop(); await b.stop(); }); it("should send and receive messages", async () => { const messagePacket: IPacket = { - maskingIv: new Uint8Array(MASKING_IV_SIZE), header: { - protocolId: "discv5", - version: 1, + authdata: new Uint8Array(32).fill(2), + authdataSize: 32, flag: PacketType.Message, nonce: new Uint8Array(NONCE_SIZE), - authdataSize: 32, - authdata: new Uint8Array(32).fill(2), + protocolId: "discv5", + version: 1, }, + maskingIv: new Uint8Array(MASKING_IV_SIZE), message: new Uint8Array(44).fill(1), }; async function send(multiaddr: Multiaddr, nodeId: string, packet: IPacket): Promise<[Multiaddr, IPacket]> { @@ -163,7 +161,7 @@ describe("UDP4+6 transport", () => { }); }); - context("with wildcard addresses", () => { + describe("with wildcard addresses", () => { it("should bind to the same port on both IPv4 and IPv6", async () => { const nodeId = bytesToHex(new Uint8Array(32).fill(3)); const port = 49525; @@ -171,7 +169,7 @@ describe("UDP4+6 transport", () => { const multiaddr6 = multiaddr(`/ip6/::/udp/${port}`); const transport = new UDPTransportService({ - bindAddrs: { ip4: multiaddr4, ip6: multiaddr6 }, + bindAddrs: {ip4: multiaddr4, ip6: multiaddr6}, nodeId, }); @@ -191,14 +189,14 @@ describe("UDP4+6 transport", () => { const multiaddr4A = multiaddr(`/ip4/127.0.0.1/udp/${portA}`); const multiaddr6A = multiaddr(`/ip6/::1/udp/${portA}`); const a = new UDPTransportService({ - bindAddrs: { ip4: multiaddr4A, ip6: multiaddr6A }, + bindAddrs: {ip4: multiaddr4A, ip6: multiaddr6A}, nodeId: nodeIdA, }); const multiaddr4B = multiaddr(`/ip4/127.0.0.1/udp/${portB}`); const multiaddr6B = multiaddr(`/ip6/::1/udp/${portB}`); const b = new UDPTransportService({ - bindAddrs: { ip4: multiaddr4B, ip6: multiaddr6B }, + bindAddrs: {ip4: multiaddr4B, ip6: multiaddr6B}, nodeId: nodeIdB, }); @@ -206,15 +204,15 @@ describe("UDP4+6 transport", () => { await b.start(); const messagePacket: IPacket = { - maskingIv: new Uint8Array(MASKING_IV_SIZE), header: { - protocolId: "discv5", - version: 1, + authdata: new Uint8Array(32).fill(2), + authdataSize: 32, flag: PacketType.Message, nonce: new Uint8Array(NONCE_SIZE), - authdataSize: 32, - authdata: new Uint8Array(32).fill(2), + protocolId: "discv5", + version: 1, }, + maskingIv: new Uint8Array(MASKING_IV_SIZE), message: new Uint8Array(44).fill(1), }; @@ -245,7 +243,7 @@ describe("UDP4+6 transport", () => { const multiaddr4 = multiaddr(`/ip4/127.0.0.1/udp/${ports[i]}`); const multiaddr6 = multiaddr(`/ip6/::1/udp/${ports[i]}`); const transport = new UDPTransportService({ - bindAddrs: { ip4: multiaddr4, ip6: multiaddr6 }, + bindAddrs: {ip4: multiaddr4, ip6: multiaddr6}, nodeId, }); transports.push(transport); @@ -254,15 +252,15 @@ describe("UDP4+6 transport", () => { await Promise.all(transports.map((t) => t.start())); const messagePacket: IPacket = { - maskingIv: new Uint8Array(MASKING_IV_SIZE), header: { - protocolId: "discv5", - version: 1, + authdata: new Uint8Array(32).fill(2), + authdataSize: 32, flag: PacketType.Message, nonce: new Uint8Array(NONCE_SIZE), - authdataSize: 32, - authdata: new Uint8Array(32).fill(2), + protocolId: "discv5", + version: 1, }, + maskingIv: new Uint8Array(MASKING_IV_SIZE), message: new Uint8Array(44).fill(1), }; diff --git a/packages/discv5/test/unit/util/ip.test.ts b/packages/discv5/test/unit/util/ip.test.ts index 53357329..e387714a 100644 --- a/packages/discv5/test/unit/util/ip.test.ts +++ b/packages/discv5/test/unit/util/ip.test.ts @@ -1,10 +1,10 @@ -import { multiaddr } from "@multiformats/multiaddr"; -import { expect } from "chai"; -import { SignableENR } from "@chainsafe/enr"; -import { generateKeypair } from "../../../src/index.js"; +import {SignableENR} from "@chainsafe/enr"; +import {multiaddr} from "@multiformats/multiaddr"; +import {describe, expect, it} from "vitest"; +import {generateKeypair} from "../../../src/index.js"; import { + type SocketAddress, getSocketAddressOnENR, - SocketAddress, isEqualSocketAddress, multiaddrFromSocketAddress, multiaddrToSocketAddress, @@ -13,19 +13,19 @@ import { describe("isEqualSocketAddress", () => { it("equal", () => { - const testCases: { addr1: SocketAddress; addr2: SocketAddress }[] = [ + const testCases: {addr1: SocketAddress; addr2: SocketAddress}[] = [ { addr1: { ip: { - type: 4, octets: new Uint8Array(4), + type: 4, }, port: 0, }, addr2: { ip: { - type: 4, octets: new Uint8Array(4), + type: 4, }, port: 0, }, @@ -33,15 +33,15 @@ describe("isEqualSocketAddress", () => { { addr1: { ip: { - type: 6, octets: new Uint8Array(16), + type: 6, }, port: 0, }, addr2: { ip: { - type: 6, octets: new Uint8Array(16), + type: 6, }, port: 0, }, @@ -49,39 +49,39 @@ describe("isEqualSocketAddress", () => { { addr1: { ip: { - type: 4, octets: new Uint8Array(4), + type: 4, }, port: 1, }, addr2: { ip: { - type: 4, octets: new Uint8Array(4), + type: 4, }, port: 1, }, }, ]; - for (const { addr1: ip1, addr2: ip2 } of testCases) { + for (const {addr1: ip1, addr2: ip2} of testCases) { expect(isEqualSocketAddress(ip1, ip2), `isEqualSocketAddress(${ip1}, ${ip2}) should be true`).to.be.equal(true); } }); it("not equal", () => { - const testCases: { ip1: SocketAddress; ip2: SocketAddress }[] = [ + const testCases: {ip1: SocketAddress; ip2: SocketAddress}[] = [ { ip1: { ip: { - type: 4, octets: new Uint8Array(4), + type: 4, }, port: 0, }, ip2: { ip: { - type: 6, octets: new Uint8Array(4), + type: 6, }, port: 0, }, @@ -89,15 +89,15 @@ describe("isEqualSocketAddress", () => { { ip1: { ip: { - type: 4, octets: Uint8Array.from([0, 0, 0, 0]), + type: 4, }, port: 0, }, ip2: { ip: { - type: 4, octets: Uint8Array.from([0, 0, 0, 1]), + type: 4, }, port: 0, }, @@ -105,21 +105,21 @@ describe("isEqualSocketAddress", () => { { ip1: { ip: { - type: 4, octets: new Uint8Array(4), + type: 4, }, port: 0, }, ip2: { ip: { - type: 4, octets: new Uint8Array(4), + type: 4, }, port: 1, }, }, ]; - for (const { ip1, ip2 } of testCases) { + for (const {ip1, ip2} of testCases) { expect(isEqualSocketAddress(ip1, ip2), `isEqualSocketAddress(${ip1}, ${ip2}) should be false`).to.be.equal(false); } }); @@ -129,16 +129,16 @@ describe("get/set SocketAddress on ENR", () => { it("roundtrip", () => { const addr: SocketAddress = { ip: { - type: 4, octets: Uint8Array.from([127, 0, 0, 1]), + type: 4, }, port: 53, }; const enr = SignableENR.createV4(generateKeypair("secp256k1").privateKey); - expect(getSocketAddressOnENR(enr, { ip4: true, ip6: false })).to.equal(undefined); + expect(getSocketAddressOnENR(enr, {ip4: true, ip6: false})).to.equal(undefined); setSocketAddressOnENR(enr, addr); - expect(getSocketAddressOnENR(enr, { ip4: true, ip6: false })).to.deep.equal(addr); + expect(getSocketAddressOnENR(enr, {ip4: true, ip6: false})).to.deep.equal(addr); }); }); @@ -146,8 +146,8 @@ describe("multiaddr to/from SocketAddress", () => { it("roundtrip", () => { const addr: SocketAddress = { ip: { - type: 4, octets: Uint8Array.from([127, 0, 0, 1]), + type: 4, }, port: 53, }; @@ -157,8 +157,8 @@ describe("multiaddr to/from SocketAddress", () => { it("different implementations yield same results", () => { const numTries = 50; const randPort = (): number => Math.floor(Math.random() * 65535); - const randIp4 = (): Uint8Array => Uint8Array.from({ length: 4 }, () => Math.floor(Math.random() * 255)); - const randIp6 = (): Uint8Array => Uint8Array.from({ length: 16 }, () => Math.floor(Math.random() * 255)); + const randIp4 = (): Uint8Array => Uint8Array.from({length: 4}, () => Math.floor(Math.random() * 255)); + const randIp6 = (): Uint8Array => Uint8Array.from({length: 16}, () => Math.floor(Math.random() * 255)); const ip4ToStr = (bytes: Uint8Array): string => bytes.join("."); const ip6ToStr = (bytes: Uint8Array): string => Array.from(bytes) @@ -179,8 +179,8 @@ describe("multiaddr to/from SocketAddress", () => { if (i % 2 === 0) { addr = { ip: { - type: 4, octets: randIp4(), + type: 4, }, port: randPort(), }; @@ -188,8 +188,8 @@ describe("multiaddr to/from SocketAddress", () => { } else { addr = { ip: { - type: 6, octets: randIp6(), + type: 6, }, port: randPort(), }; diff --git a/packages/discv5/test/unit/util/timeoutMap.test.ts b/packages/discv5/test/unit/util/timeoutMap.test.ts index befb2951..a4072f56 100644 --- a/packages/discv5/test/unit/util/timeoutMap.test.ts +++ b/packages/discv5/test/unit/util/timeoutMap.test.ts @@ -1,17 +1,16 @@ -/* eslint-env mocha */ -import { expect } from "chai"; +import {describe, expect, it} from "vitest"; -import { TimeoutMap } from "../../../src/util/index.js"; +import {TimeoutMap} from "../../../src/util/index.js"; describe("TimeoutMap", () => { - it("should evict items after a timeout", async function () { + it("should evict items after a timeout", async () => { const timeout = 15; const map = new TimeoutMap(timeout); map.set("foo", "bar"); await new Promise((resolve) => setTimeout(resolve, timeout + 1)); expect(map.size).to.equal(0); }); - it("should call onTimeout after a timeout", async function () { + it("should call onTimeout after a timeout", async () => { const timeout = 15; let callbackCalled = false; const map = new TimeoutMap(timeout, (k, v) => { @@ -24,7 +23,7 @@ describe("TimeoutMap", () => { expect(map.size).to.equal(0); expect(callbackCalled).to.equal(true); }); - it("should update a timeout", async function () { + it("should update a timeout", async () => { const timeout = 15; const map = new TimeoutMap(timeout); map.set("foo", "bar"); diff --git a/packages/discv5/tsconfig.json b/packages/discv5/tsconfig.json index b2a55fed..51bc338b 100644 --- a/packages/discv5/tsconfig.json +++ b/packages/discv5/tsconfig.json @@ -2,15 +2,11 @@ "include": ["src", "test"], "compilerOptions": { "target": "esnext", - "module": "esnext", - "moduleResolution": "node", + "module": "nodenext", + "moduleResolution": "nodenext", "outDir": "./lib", "strict": true, "strictNullChecks": true, - "typeRoots": [ - "../../node_modules/@types", - "../../types" - ], "esModuleInterop": true, "sourceMap": true, } diff --git a/packages/enr/.bench.yaml b/packages/enr/.bench.yaml deleted file mode 100644 index 892a0274..00000000 --- a/packages/enr/.bench.yaml +++ /dev/null @@ -1,10 +0,0 @@ -# Mocha opts -extension: ["ts"] -colors: true -node-option: - - "loader=ts-node/register" - -# benchmark opts -# threshold: 3 -# maxMs: 60_000 -# minRuns: 10 \ No newline at end of file diff --git a/packages/enr/.mocharc.yaml b/packages/enr/.mocharc.yaml deleted file mode 100644 index 782a40de..00000000 --- a/packages/enr/.mocharc.yaml +++ /dev/null @@ -1,5 +0,0 @@ -colors: true -exit: true -extension: ["ts"] -node-option: - - loader=ts-node/esm diff --git a/packages/enr/bench/index.bench.ts b/packages/enr/bench/index.bench.ts index e9800ec2..546bb07a 100644 --- a/packages/enr/bench/index.bench.ts +++ b/packages/enr/bench/index.bench.ts @@ -1,18 +1,13 @@ -import { itBench } from "@dapplion/benchmark"; -import { createSecp256k1PeerId } from "@libp2p/peer-id-factory"; +import { describe, itBench } from "@chainsafe/benchmark"; +import { generateKeyPair } from "@libp2p/crypto/keys"; import { ENR, SignableENR, - createPeerIdFromPrivateKey, - createPeerIdFromPublicKey, - createPrivateKeyFromPeerId, - createPublicKeyFromPeerId, } from "../src/index.js"; describe("ENR", async function () { - const peerId = await createSecp256k1PeerId(); - const { privateKey } = createPrivateKeyFromPeerId(peerId); - const enr = SignableENR.createV4(privateKey); + const kp = await generateKeyPair("secp256k1"); + const enr = SignableENR.createV4(kp.raw); enr.ip = "127.0.0.1"; enr.tcp = 8080; @@ -24,23 +19,9 @@ describe("ENR", async function () { }); }); -describe("createPeerIdFromPrivateKey", async function () { - const peerId = await createSecp256k1PeerId(); - const { type, privateKey } = createPrivateKeyFromPeerId(peerId); - const { publicKey } = createPublicKeyFromPeerId(peerId); - - itBench("createPeerIdFromPrivateKey", () => { - return createPeerIdFromPrivateKey(type, privateKey); - }); - itBench("createPeerIdFromPublicKey", () => { - return createPeerIdFromPublicKey(type, publicKey); - }); -}); - describe("ENR - encode/decode", async function () { - const peerId = await createSecp256k1PeerId(); - const { privateKey } = createPrivateKeyFromPeerId(peerId); - const enr = SignableENR.createV4(privateKey); + const kp = await generateKeyPair("secp256k1"); + const enr = SignableENR.createV4(kp.raw); enr.ip = "127.0.0.1"; enr.tcp = 8080; enr.udp = 8080; diff --git a/packages/enr/package.json b/packages/enr/package.json index 624830c8..542fb24f 100644 --- a/packages/enr/package.json +++ b/packages/enr/package.json @@ -4,6 +4,7 @@ "description": "Ethereum name record", "type": "module", "files": [ + "src", "lib" ], "exports": { @@ -25,10 +26,10 @@ "check-types": "tsc --noEmit", "build": "tsc -p tsconfig.build.json", "prepublishOnly": "pnpm build", - "lint": "eslint --color --ext .ts src/ test/", + "lint": "biome check src test", "test": "pnpm test:unit && pnpm test:e2e", - "test:perf": "NODE_OPTIONS='--max-old-space-size=4096 --loader=ts-node/esm' benchmark 'bench/**/*.bench.ts' --config .bench.yaml", - "test:unit": "mocha 'test/unit/**/*.test.ts'" + "test:perf": "NODE_OPTIONS='--max-old-space-size=4096 --loader=ts-node/esm' benchmark 'bench/**/*.bench.ts'", + "test:unit": "vitest --run 'test/unit'" }, "pre-push": [ "lint" @@ -49,17 +50,13 @@ "url": "https://github.com/ChainSafe/discv5/issues" }, "homepage": "https://github.com/ChainSafe/discv5#readme", - "devDependencies": { - "@types/bn.js": "^4.11.5" - }, "dependencies": { - "@ethereumjs/rlp": "^5.0.2", + "@ethereumjs/rlp": "^10.1.1", "@libp2p/crypto": "^5.0.1", - "@libp2p/interface": "^2.0.1", - "@libp2p/peer-id": "^5.0.1", - "@multiformats/multiaddr": "^12.1.10", - "@scure/base": "^1.2.1", - "ethereum-cryptography": "^2.2.0", - "uint8-varint": "^2.0.2" + "@libp2p/interface": "^3.1.0", + "@libp2p/peer-id": "^6.0.4", + "@multiformats/multiaddr": "^13.0.1", + "@scure/base": "^2.0.0", + "ethereum-cryptography": "^3.2.0" } } diff --git a/packages/enr/src/crypto.ts b/packages/enr/src/crypto.ts index 6edca3a5..25552794 100644 --- a/packages/enr/src/crypto.ts +++ b/packages/enr/src/crypto.ts @@ -1,5 +1,5 @@ -import { NodeId } from "./types.js"; import * as defaultCrypto from "./defaultCrypto.js"; +import type {NodeId} from "./types.js"; /** * In order to support different environments (eg: browser vs high performance), a pluggable crypto interface is provided diff --git a/packages/enr/src/defaultCrypto.ts b/packages/enr/src/defaultCrypto.ts index f31e18b1..e8ea8d6f 100644 --- a/packages/enr/src/defaultCrypto.ts +++ b/packages/enr/src/defaultCrypto.ts @@ -1,8 +1,7 @@ -import { keccak256 } from "ethereum-cryptography/keccak"; -import { secp256k1 } from "ethereum-cryptography/secp256k1"; - -import { createNodeId } from "./util.js"; -import { NodeId } from "./types.js"; +import {keccak256} from "ethereum-cryptography/keccak"; +import {secp256k1} from "ethereum-cryptography/secp256k1"; +import type {NodeId} from "./types.js"; +import {createNodeId} from "./util.js"; export function hash(input: Uint8Array): Uint8Array { return keccak256(input); diff --git a/packages/enr/src/enr.ts b/packages/enr/src/enr.ts index 00952636..3a1e2167 100644 --- a/packages/enr/src/enr.ts +++ b/packages/enr/src/enr.ts @@ -1,18 +1,21 @@ -import { Multiaddr, multiaddr, protocols } from "@multiformats/multiaddr"; -import * as RLP from "@ethereumjs/rlp"; -import { KeyType, PeerId, PrivateKey } from "@libp2p/interface"; -import { convertToString, convertToBytes } from "@multiformats/multiaddr/convert"; -import { encode as varintEncode } from "uint8-varint"; - -import { ERR_INVALID_ID, MAX_RECORD_SIZE } from "./constants.js"; -import { ENRKey, ENRValue, SequenceNumber, NodeId } from "./types.js"; -import { createPeerIdFromPublicKey } from "./peerId.js"; -import { bytesToBigint, fromBase64url, toBase64url, toNewUint8Array } from "./util.js"; -import { getV4Crypto } from "./crypto.js"; -import { bytesToUtf8, equalsBytes, utf8ToBytes } from "ethereum-cryptography/utils.js"; +import * as Rlp from "@ethereumjs/rlp"; +import type {KeyType, PeerId, PrivateKey} from "@libp2p/interface"; +import {type Component, type Multiaddr, multiaddr, registry} from "@multiformats/multiaddr"; +import {bytesToUtf8, equalsBytes, utf8ToBytes} from "ethereum-cryptography/utils.js"; +import {ERR_INVALID_ID, MAX_RECORD_SIZE} from "./constants.js"; +import {getV4Crypto} from "./crypto.js"; +import {createPeerIdFromPublicKey} from "./peerId.js"; +import type {ENRKey, ENRValue, NodeId, SequenceNumber} from "./types.js"; +import {bytesToBigint, fromBase64url, toBase64url, toNewUint8Array} from "./util.js"; + +const ip4 = registry.getProtocol("ip4"); +const ip6 = registry.getProtocol("ip6"); +const tcp = registry.getProtocol("tcp"); +const udp = registry.getProtocol("udp"); /** ENR identity scheme */ export enum IDScheme { + // biome-ignore lint/style/useNamingConvention: existing code v4 = "v4", } @@ -35,7 +38,7 @@ export function id(kvs: ReadonlyMap): IDScheme { if (!idBuf) throw new Error("id not found"); const id = bytesToUtf8(idBuf) as IDScheme; if (IDScheme[id] == null) { - throw new Error("Unknown enr id scheme: " + id); + throw new Error(`Unknown enr id scheme: ${id}`); } return id; } @@ -95,8 +98,7 @@ export function encodeToValues( // sort keys and flatten into [k, v, k, v, ...] const content: Array = Array.from(kvs.keys()) .sort((a, b) => a.localeCompare(b)) - .map((k) => [k, kvs.get(k)] as [ENRKey, ENRValue]) - .flat(); + .flatMap((k) => [k, kvs.get(k)] as [ENRKey, ENRValue]); content.unshift(Number(seq)); if (signature) { content.unshift(signature); @@ -105,7 +107,7 @@ export function encodeToValues( } export function encode(kvs: ReadonlyMap, seq: SequenceNumber, signature: Uint8Array): Uint8Array { - const encoded = RLP.encode(encodeToValues(kvs, seq, signature)); + const encoded = Rlp.encode(encodeToValues(kvs, seq, signature)); if (encoded.length >= MAX_RECORD_SIZE) { throw new Error("ENR must be less than 300 bytes"); } @@ -138,7 +140,7 @@ export function decodeFromValues(decoded: Uint8Array[]): ENRData { } const _id = id(kvs); - if (!verify(_id, RLP.encode(signed), publicKey(_id, kvs), signature)) { + if (!verify(_id, Rlp.encode(signed), publicKey(_id, kvs), signature)) { throw new Error("Unable to verify enr signature"); } return { @@ -148,7 +150,7 @@ export function decodeFromValues(decoded: Uint8Array[]): ENRData { }; } export function decode(encoded: Uint8Array): ENRData { - return decodeFromValues(RLP.decode(encoded) as Uint8Array[]); + return decodeFromValues(Rlp.decode(encoded) as Uint8Array[]); } export function txtToBuf(encoded: string): Uint8Array { if (!encoded.startsWith("enr:")) { @@ -165,13 +167,17 @@ export function decodeTxt(encoded: string): ENRData { /** Protocols automagically supported by this library */ export type Protocol = "udp" | "tcp" | "quic" | "udp4" | "udp6" | "tcp4" | "tcp6" | "quic4" | "quic6"; -export function getIPValue(kvs: ReadonlyMap, key: string, multifmtStr: string): string | undefined { +export function getIPValue( + kvs: ReadonlyMap, + key: string, + multifmtStr: "ip4" | "ip6" +): string | undefined { const raw = kvs.get(key); if (raw) { - return convertToString(multifmtStr, toNewUint8Array(raw)) as string; - } else { - return undefined; + const protocol = multifmtStr === "ip4" ? ip4 : ip6; + return protocol.bytesToValue?.(toNewUint8Array(raw)) as string; } + return undefined; } export function getProtocolValue(kvs: ReadonlyMap, key: string): number | undefined { @@ -181,9 +187,8 @@ export function getProtocolValue(kvs: ReadonlyMap, key: string throw new Error("Encoded protocol length should be 2"); } return (raw[0] << 8) + raw[1]; - } else { - return undefined; } + return undefined; } export function portToBuf(port: number): Uint8Array { @@ -199,37 +204,44 @@ export function parseLocationMultiaddr(ma: Multiaddr): { protoName: "udp" | "tcp" | "quic"; protoVal: Uint8Array; } { - const protoNames = ma.protoNames(); - const tuples = ma.tuples(); + // Force cache population of bytes property to ensure getComponents() works correctly + void ma.bytes; + const components = ma.getComponents(); let family: 4 | 6; let protoName: "udp" | "tcp" | "quic"; - if (protoNames[0] === "ip4") { + if (components[0].name === "ip4") { family = 4; - } else if (protoNames[0] === "ip6") { + } else if (components[0].name === "ip6") { family = 6; } else { throw new Error("Invalid multiaddr: must start with ip4 or ip6"); } - if (tuples[0][1] == null) { + // Remove varint prefix + const ip = components[0].bytes?.slice(1); + if (ip == null) { throw new Error("Invalid multiaddr: ip address is missing"); } - const ip = tuples[0][1]; - if (protoNames[1] === "udp") { + if (components[1].name === "udp") { protoName = "udp"; - } else if (protoNames[1] === "tcp") { + } else if (components[1].name === "tcp") { protoName = "tcp"; } else { throw new Error("Invalid multiaddr: must have udp or tcp protocol"); } - if (tuples[1][1] == null) { + if (components[1].value == null) { + throw new Error("Invalid multiaddr: udp or tcp port is missing"); + } + // Remove varint prefix + // Note that tcp's code is 6 (1 byte) while udp's code is 273 (2 bytes), so we slice accordingly + const protoVal = components[1].bytes?.slice(protoName === "udp" ? 2 : 1); + if (protoVal == null) { throw new Error("Invalid multiaddr: udp or tcp port is missing"); } - const protoVal = tuples[1][1]; - if (protoNames.length === 3) { - if (protoNames[2] === "quic-v1") { + if (components.length === 3) { + if (components[2].name === "quic-v1") { if (protoName !== "udp") { throw new Error("Invalid multiaddr: quic protocol must be used with udp"); } @@ -237,27 +249,27 @@ export function parseLocationMultiaddr(ma: Multiaddr): { } else { throw new Error("Invalid multiaddr: unknown protocol"); } - } else if (protoNames.length > 2) { + } else if (components.length > 2) { throw new Error("Invalid multiaddr: unknown protocol"); } - return { family, ip, protoName, protoVal }; + return {family, ip, protoName, protoVal}; } // Classes export abstract class BaseENR { /** Raw enr key-values */ - public abstract kvs: ReadonlyMap; + abstract kvs: ReadonlyMap; /** Sequence number */ - public abstract seq: SequenceNumber; - public abstract signature: Uint8Array; + abstract seq: SequenceNumber; + abstract signature: Uint8Array; // Identity methods /** Node identifier */ - public abstract nodeId: NodeId; - public abstract publicKey: Uint8Array; + abstract nodeId: NodeId; + abstract publicKey: Uint8Array; /** enr identity scheme */ get id(): IDScheme { @@ -311,49 +323,58 @@ export abstract class BaseENR { if (!ipVal) { return undefined; } - const isUdp = protocol.startsWith("udp"); const isTcp = protocol.startsWith("tcp"); const isQuic = protocol.startsWith("quic"); - let protoName, protoVal; - if (isUdp) { - protoName = "udp"; - protoVal = isIpv6 ? this.kvs.get("udp6") : this.kvs.get("udp"); - } else if (isTcp) { - protoName = "tcp"; - protoVal = isIpv6 ? this.kvs.get("tcp6") : this.kvs.get("tcp"); - } else if (isQuic) { - protoName = "udp"; - protoVal = isIpv6 ? this.kvs.get("quic6") : this.kvs.get("quic"); - } else { - return undefined; - } - if (!protoVal) { + if (!isUdp && !isTcp && !isQuic) { return undefined; } - // Create raw multiaddr buffer - // multiaddr length is: - // 1 byte for the ip protocol (ip4 or ip6) - // N bytes for the ip address - // 1 or 2 bytes for the protocol as buffer (tcp or udp) - // 2 bytes for the port - const ipMa = protocols(isIpv6 ? "ip6" : "ip4"); - const ipByteLen = ipMa.size / 8; - const protoMa = protocols(protoName); - const protoBuf = varintEncode(protoMa.code); - const maBuf = new Uint8Array(3 + ipByteLen + protoBuf.length); - maBuf[0] = ipMa.code; - maBuf.set(ipVal, 1); - maBuf.set(protoBuf, 1 + ipByteLen); - maBuf.set(protoVal, 1 + ipByteLen + protoBuf.length); - - const ma = multiaddr(maBuf); + const ipComponent: Component = { + code: isIpv6 ? ip6.code : ip4.code, + name: isIpv6 ? ip6.name : ip4.name, + value: isIpv6 ? ip6.bytesToValue?.(toNewUint8Array(ipVal)) : ip4.bytesToValue?.(toNewUint8Array(ipVal)), + }; + + if (isUdp) { + const protoVal = isIpv6 ? this.kvs.get("udp6") : this.kvs.get("udp"); + if (!protoVal) { + return undefined; + } + const protoComponent: Component = { + code: udp.code, + name: udp.name, + value: udp.bytesToValue?.(toNewUint8Array(protoVal)), + }; + return multiaddr([ipComponent, protoComponent]); + } + if (isTcp) { + const protoVal = isIpv6 ? this.kvs.get("tcp6") : this.kvs.get("tcp"); + if (!protoVal) { + return undefined; + } + const protoComponent: Component = { + code: tcp.code, + name: tcp.name, + value: tcp.bytesToValue?.(toNewUint8Array(protoVal)), + }; + return multiaddr([ipComponent, protoComponent]); + } if (isQuic) { - return ma.encapsulate("/quic-v1"); + const protoVal = isIpv6 ? this.kvs.get("quic6") : this.kvs.get("quic"); + if (!protoVal) { + return undefined; + } + const protoComponent: Component = { + code: udp.code, + name: udp.name, + value: udp.bytesToValue?.(toNewUint8Array(protoVal)), + }; + return multiaddr([ipComponent, protoComponent]).encapsulate("/quic-v1"); } - return ma; + return undefined; } + async getFullMultiaddr(protocol: Protocol): Promise { const locationMultiaddr = this.getLocationMultiaddr(protocol); if (locationMultiaddr) { @@ -367,7 +388,7 @@ export abstract class BaseENR { abstract encodeToValues(): (ENRKey | ENRValue | number)[]; abstract encode(): Uint8Array; encodeTxt(): string { - return "enr:" + toBase64url(this.encode()); + return `enr:${toBase64url(this.encode())}`; } } /** @@ -377,11 +398,13 @@ export abstract class BaseENR { * * `ENR` is used to read serialized ENRs and may not be modified once created. */ + +// biome-ignore lint/style/useNamingConvention: existing code export class ENR extends BaseENR { - public kvs: ReadonlyMap; - public seq: SequenceNumber; - public signature: Uint8Array; - public nodeId: string; + kvs: ReadonlyMap; + seq: SequenceNumber; + signature: Uint8Array; + nodeId: string; private encoded?: Uint8Array; constructor( @@ -402,16 +425,16 @@ export class ENR extends BaseENR { return new ENR(obj.kvs, obj.seq, obj.signature); } static decodeFromValues(encoded: Uint8Array[]): ENR { - const { kvs, seq, signature } = decodeFromValues(encoded); + const {kvs, seq, signature} = decodeFromValues(encoded); return new ENR(kvs, seq, signature); } static decode(encoded: Uint8Array): ENR { - const { kvs, seq, signature } = decode(encoded); + const {kvs, seq, signature} = decode(encoded); return new ENR(kvs, seq, signature, encoded); } static decodeTxt(encoded: string): ENR { const encodedBuf = txtToBuf(encoded); - const { kvs, seq, signature } = decode(encodedBuf); + const {kvs, seq, signature} = decode(encodedBuf); return new ENR(kvs, seq, signature, encodedBuf); } @@ -428,7 +451,7 @@ export class ENR extends BaseENR { } encodeToValues(): Uint8Array[] { - return RLP.decode(this.encode()) as Uint8Array[]; + return Rlp.decode(this.encode()) as Uint8Array[]; } encode(): Uint8Array { if (!this.encoded) { @@ -446,16 +469,16 @@ export class ENR extends BaseENR { * `SignableENR` is used to create and update ENRs. */ export class SignableENR extends BaseENR { - public kvs: ReadonlyMap; - public seq: SequenceNumber; - public nodeId: NodeId; - public publicKey: Uint8Array; - public privateKey: Uint8Array; + kvs: ReadonlyMap; + seq: SequenceNumber; + nodeId: NodeId; + publicKey: Uint8Array; + privateKey: Uint8Array; private _signature?: Uint8Array; constructor( - kvs: ReadonlyMap | Record = {}, - seq: SequenceNumber = 1n, + kvs: ReadonlyMap | Record, + seq: SequenceNumber, privateKey: Uint8Array, signature?: Uint8Array ) { @@ -467,10 +490,8 @@ export class SignableENR extends BaseENR { this.nodeId = nodeId(this.id, this.publicKey); this._signature = signature; - if (this.id === IDScheme.v4) { - if (!equalsBytes(getV4Crypto().publicKey(this.privateKey), this.publicKey)) { - throw new Error("Provided keypair doesn't match kv pubkey"); - } + if (this.id === IDScheme.v4 && !equalsBytes(getV4Crypto().publicKey(this.privateKey), this.publicKey)) { + throw new Error("Provided keypair doesn't match kv pubkey"); } } @@ -498,21 +519,21 @@ export class SignableENR extends BaseENR { } } static decodeFromValues(encoded: Uint8Array[], privateKey: Uint8Array): SignableENR { - const { kvs, seq, signature } = decodeFromValues(encoded); + const {kvs, seq, signature} = decodeFromValues(encoded); return new SignableENR(kvs, seq, privateKey, signature); } static decode(encoded: Uint8Array, privateKey: Uint8Array): SignableENR { - const { kvs, seq, signature } = decode(encoded); + const {kvs, seq, signature} = decode(encoded); return new SignableENR(kvs, seq, privateKey, signature); } static decodeTxt(encoded: string, privateKey: Uint8Array): SignableENR { - const { kvs, seq, signature } = decodeTxt(encoded); + const {kvs, seq, signature} = decodeTxt(encoded); return new SignableENR(kvs, seq, privateKey, signature); } get signature(): Uint8Array { if (!this._signature) { - this._signature = sign(this.id, RLP.encode(encodeToValues(this.kvs, this.seq)), this.privateKey); + this._signature = sign(this.id, Rlp.encode(encodeToValues(this.kvs, this.seq)), this.privateKey); } return this._signature; } @@ -548,7 +569,8 @@ export class SignableENR extends BaseENR { } set ip(ip: string | undefined) { if (ip) { - this.set("ip", convertToBytes("ip4", ip)); + // biome-ignore lint/style/noNonNullAssertion: known to exist + this.set("ip", ip4.valueToBytes!(ip)); } else { this.delete("ip"); } @@ -588,7 +610,8 @@ export class SignableENR extends BaseENR { } set ip6(ip: string | undefined) { if (ip) { - this.set("ip6", convertToBytes("ip6", ip)); + // biome-ignore lint/style/noNonNullAssertion: known to exist + this.set("ip6", ip6.valueToBytes!(ip)); } else { this.delete("ip6"); } @@ -624,22 +647,22 @@ export class SignableENR extends BaseENR { } } setLocationMultiaddr(multiaddr: Multiaddr): void { - const { family, ip, protoName, protoVal } = parseLocationMultiaddr(multiaddr); + const {family, ip, protoName, protoVal} = parseLocationMultiaddr(multiaddr); if (family === 4) { this.set("ip", ip); this.set(protoName, protoVal); } else { this.set("ip6", ip); - this.set(protoName + "6", protoVal); + this.set(`${protoName}6`, protoVal); } } toObject(): SignableENRData { return { kvs: this.kvs, - seq: this.seq, privateKey: this.privateKey, + seq: this.seq, }; } encodeToValues(): (string | number | Uint8Array)[] { diff --git a/packages/enr/src/index.ts b/packages/enr/src/index.ts index 95e32748..274e04d9 100644 --- a/packages/enr/src/index.ts +++ b/packages/enr/src/index.ts @@ -2,6 +2,6 @@ export * from "./constants.js"; export * from "./crypto.js"; export * as defaultCrypto from "./defaultCrypto.js"; export * from "./enr.js"; -export * from "./types.js"; export * from "./peerId.js"; +export * from "./types.js"; export * from "./util.js"; diff --git a/packages/enr/src/peerId.ts b/packages/enr/src/peerId.ts index 4af9217c..67bc4779 100644 --- a/packages/enr/src/peerId.ts +++ b/packages/enr/src/peerId.ts @@ -1,10 +1,10 @@ -import { KeyType, PeerId } from "@libp2p/interface"; -import { peerIdFromPublicKey } from "@libp2p/peer-id"; -import { publicKeyFromRaw } from "@libp2p/crypto/keys"; +import {publicKeyFromRaw} from "@libp2p/crypto/keys"; +import type {KeyType, PeerId} from "@libp2p/interface"; +import {peerIdFromPublicKey} from "@libp2p/peer-id"; export const ERR_TYPE_NOT_IMPLEMENTED = "Keypair type not implemented"; -export function createPeerIdFromPublicKey(type: KeyType, publicKey: Uint8Array): PeerId { +export function createPeerIdFromPublicKey(_type: KeyType, publicKey: Uint8Array): PeerId { const pubKey = publicKeyFromRaw(publicKey); if (pubKey.type !== "secp256k1") { throw new Error(ERR_TYPE_NOT_IMPLEMENTED); diff --git a/packages/enr/src/util.ts b/packages/enr/src/util.ts index 4d905087..696420b3 100644 --- a/packages/enr/src/util.ts +++ b/packages/enr/src/util.ts @@ -1,6 +1,6 @@ -import { NodeId } from "./types.js"; -import { bytesToHex, hexToBytes } from "ethereum-cryptography/utils"; -import { base64urlnopad } from "@scure/base"; +import {base64urlnopad} from "@scure/base"; +import {bytesToHex, hexToBytes} from "ethereum-cryptography/utils"; +import type {NodeId} from "./types.js"; // multiaddr 8.0.0 expects an Uint8Array with internal buffer starting at 0 offset export function toNewUint8Array(buf: Uint8Array): Uint8Array { const arrayBuffer = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); diff --git a/packages/enr/test/unit/enr.test.ts b/packages/enr/test/unit/enr.test.ts index ca3890ba..c822ac19 100644 --- a/packages/enr/test/unit/enr.test.ts +++ b/packages/enr/test/unit/enr.test.ts @@ -1,10 +1,9 @@ -/* eslint-env mocha */ -import { expect } from "chai"; -import { generateKeyPair } from "@libp2p/crypto/keys"; -import { multiaddr } from "@multiformats/multiaddr"; -import { BaseENR, ENR, SignableENR, getV4Crypto } from "../../src/index.js"; -import { peerIdFromString } from "@libp2p/peer-id"; -import { bytesToHex, hexToBytes, utf8ToBytes } from "ethereum-cryptography/utils.js"; +import {generateKeyPair} from "@libp2p/crypto/keys"; +import {peerIdFromString} from "@libp2p/peer-id"; +import {multiaddr} from "@multiformats/multiaddr"; +import {bytesToHex, hexToBytes, utf8ToBytes} from "ethereum-cryptography/utils.js"; +import {beforeEach, describe, expect, it} from "vitest"; +import {type BaseENR, ENR, SignableENR, getV4Crypto} from "../../src/index.js"; describe("ENR spec test vector", () => { // spec enr https://eips.ethereum.org/EIPS/eip-778 @@ -19,8 +18,8 @@ describe("ENR spec test vector", () => { const kvs = new Map( Object.entries({ id: utf8ToBytes("v4"), - secp256k1: publicKey, ip: hexToBytes("7f000001"), + secp256k1: publicKey, udp: hexToBytes((30303).toString(16)), }) ); @@ -73,71 +72,69 @@ describe("ENR multiaddr support", () => { it("should get / set UDP multiaddr", () => { const multi0 = multiaddr("/ip4/127.0.0.1/udp/30303"); - const tuples0 = multi0.tuples(); + const components0 = multi0.getComponents(); - if (!tuples0[0][1] || !tuples0[1][1]) { + if (!components0[0].value || !components0[1].value) { throw new Error("invalid multiaddr"); } // set underlying records - record.set("ip", tuples0[0][1]); - record.set("udp", tuples0[1][1]); + record.ip = components0[0].value; + record.udp = Number(components0[1].value); // and get the multiaddr - expect(record.getLocationMultiaddr("udp")!.toString()).to.equal(multi0.toString()); + expect(record.getLocationMultiaddr("udp")?.toString()).to.equal(multi0.toString()); // set the multiaddr const multi1 = multiaddr("/ip4/0.0.0.0/udp/30300"); record.setLocationMultiaddr(multi1); // and get the multiaddr - expect(record.getLocationMultiaddr("udp")!.toString()).to.equal(multi1.toString()); + expect(record.getLocationMultiaddr("udp")?.toString()).to.equal(multi1.toString()); // and get the underlying records - const tuples1 = multi1.tuples(); - expect(record.kvs.get("ip")).to.deep.equal(tuples1[0][1]); - expect(record.kvs.get("udp")).to.deep.equal(tuples1[1][1]); + const components1 = multi1.getComponents(); + expect(record.ip).to.deep.equal(components1[0].value); + expect(record.udp).to.deep.equal(Number(components1[1].value)); }); it("should get / set TCP multiaddr", () => { const multi0 = multiaddr("/ip4/127.0.0.1/tcp/30303"); - const tuples0 = multi0.tuples(); - - if (!tuples0[0][1] || !tuples0[1][1]) { + const components0 = multi0.getComponents(); + if (!components0[0].value || !components0[1].value) { throw new Error("invalid multiaddr"); } // set underlying records - record.set("ip", tuples0[0][1]); - record.set("tcp", tuples0[1][1]); + record.ip = components0[0].value; + record.tcp = Number(components0[1].value); // and get the multiaddr - expect(record.getLocationMultiaddr("tcp")!.toString()).to.equal(multi0.toString()); + expect(record.getLocationMultiaddr("tcp")?.toString()).to.equal(multi0.toString()); // set the multiaddr const multi1 = multiaddr("/ip4/0.0.0.0/tcp/30300"); record.setLocationMultiaddr(multi1); // and get the multiaddr - expect(record.getLocationMultiaddr("tcp")!.toString()).to.equal(multi1.toString()); + expect(record.getLocationMultiaddr("tcp")?.toString()).to.equal(multi1.toString()); // and get the underlying records - const tuples1 = multi1.tuples(); - expect(record.kvs.get("ip")).to.deep.equal(tuples1[0][1]); - expect(record.kvs.get("tcp")).to.deep.equal(tuples1[1][1]); + const components1 = multi1.getComponents(); + expect(record.ip).to.deep.equal(components1[0].value); + expect(record.tcp).to.deep.equal(Number(components1[1].value)); }); it("should get / set QUIC multiaddr", () => { const multi0 = multiaddr("/ip4/127.0.0.1/udp/30303/quic-v1"); - const tuples0 = multi0.tuples(); - - if (!tuples0[0][1] || !tuples0[1][1]) { + const components0 = multi0.getComponents(); + if (!components0[0].value || !components0[1].value) { throw new Error("invalid multiaddr"); } // set underlying records - record.set("ip", tuples0[0][1]); - record.set("quic", tuples0[1][1]); + record.ip = components0[0].value; + record.quic = Number(components0[1].value); // and get the multiaddr - expect(record.getLocationMultiaddr("quic")!.toString()).to.equal(multi0.toString()); + expect(record.getLocationMultiaddr("quic")?.toString()).to.equal(multi0.toString()); // set the multiaddr const multi1 = multiaddr("/ip4/0.0.0.0/udp/30300/quic-v1"); record.setLocationMultiaddr(multi1); // and get the multiaddr - expect(record.getLocationMultiaddr("quic")!.toString()).to.equal(multi1.toString()); + expect(record.getLocationMultiaddr("quic")?.toString()).to.equal(multi1.toString()); // and get the underlying records - const tuples1 = multi1.tuples(); - expect(record.kvs.get("ip")).to.deep.equal(tuples1[0][1]); - expect(record.kvs.get("quic")).to.deep.equal(tuples1[1][1]); + const components1 = multi1.getComponents(); + expect(record.ip).to.deep.equal(components1[0].value); + expect(record.quic).to.deep.equal(Number(components1[1].value)); }); describe("location multiaddr", async () => { @@ -231,7 +228,7 @@ describe("ENR multiaddr support", () => { }); }); -describe("ENR", function () { +describe("ENR", () => { describe("decodeTxt", () => { it("should encodeTxt and decodeTxt", async () => { const privateKey = await generateKeyPair("secp256k1"); @@ -241,8 +238,8 @@ describe("ENR", function () { expect(txt.slice(0, 4)).to.be.equal("enr:"); const enr2 = ENR.decodeTxt(txt); expect(bytesToHex(enr2.signature as Uint8Array)).to.be.equal(bytesToHex(enr.signature as Uint8Array)); - const mu = enr2.getLocationMultiaddr("udp")!; - expect(mu.toString()).to.be.equal("/ip4/18.223.219.100/udp/9000"); + const mu = enr2.getLocationMultiaddr("udp"); + expect(mu?.toString()).to.be.equal("/ip4/18.223.219.100/udp/9000"); }); it("should decode valid enr successfully", () => { diff --git a/packages/enr/tsconfig.json b/packages/enr/tsconfig.json index 05da08b0..51bc338b 100644 --- a/packages/enr/tsconfig.json +++ b/packages/enr/tsconfig.json @@ -2,8 +2,8 @@ "include": ["src", "test"], "compilerOptions": { "target": "esnext", - "module": "esnext", - "moduleResolution": "node", + "module": "nodenext", + "moduleResolution": "nodenext", "outDir": "./lib", "strict": true, "strictNullChecks": true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 04ff1b33..48c9a258 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,60 +8,27 @@ importers: .: devDependencies: - '@chainsafe/eslint-plugin-node': - specifier: ^11.2.3 - version: 11.2.3(eslint@8.56.0) - '@dapplion/benchmark': - specifier: ^0.2.4 - version: 0.2.4(mocha@10.2.0) - '@types/chai': - specifier: ^4.2.0 - version: 4.3.11 - '@types/debug': - specifier: ^4.1.5 - version: 4.1.12 - '@types/eslint': - specifier: ^6.1.3 - version: 6.8.1 - '@types/mocha': - specifier: ^8.0.3 - version: 8.2.3 + '@biomejs/biome': + specifier: ^2.3.14 + version: 2.3.14 + '@chainsafe/benchmark': + specifier: ^2.0.1 + version: 2.0.1 + '@chainsafe/biomejs-config': + specifier: ^1.0.0 + version: 1.0.0(@biomejs/biome@2.3.14) '@types/node': - specifier: ^20.6.0 - version: 20.11.0 - '@typescript-eslint/eslint-plugin': - specifier: ^5.27.1 - version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@4.9.5))(eslint@8.56.0)(typescript@4.9.5) - '@typescript-eslint/parser': - specifier: ^5.27.1 - version: 5.62.0(eslint@8.56.0)(typescript@4.9.5) - chai: - specifier: ^4.3.6 - version: 4.4.0 - eslint: - specifier: ^8.17.0 - version: 8.56.0 - eslint-plugin-prettier: - specifier: ^4.0.0 - version: 4.2.1(eslint@8.56.0)(prettier@2.8.8) - karma: - specifier: ^4.3.0 - version: 4.4.1 - mocha: - specifier: ^10.0.0 - version: 10.2.0 - nyc: - specifier: ^14.1.1 - version: 14.1.1 - prettier: - specifier: ^2.6.2 - version: 2.8.8 + specifier: ^24.10.12 + version: 24.10.12 ts-node: - specifier: ^10.8.1 - version: 10.9.2(@types/node@20.11.0)(typescript@4.9.5) + specifier: ^10.9.2 + version: 10.9.2(@types/node@24.10.12)(typescript@5.9.3) typescript: - specifier: ^4.7.3 - version: 4.9.5 + specifier: ^5.9.3 + version: 5.9.3 + vitest: + specifier: ^4.0.18 + version: 4.0.18(@types/node@24.10.12)(yaml@2.8.2) packages/discv5: dependencies: @@ -69,95 +36,80 @@ importers: specifier: workspace:^ version: link:../enr '@ethereumjs/rlp': - specifier: ^5.0.2 - version: 5.0.2 + specifier: ^10.1.1 + version: 10.1.1 '@libp2p/crypto': specifier: ^5.0.1 version: 5.0.1 '@libp2p/interface': - specifier: ^2.0.1 - version: 2.0.1 + specifier: ^3.1.0 + version: 3.1.0 '@libp2p/peer-id': - specifier: ^5.0.1 - version: 5.0.1 + specifier: ^6.0.4 + version: 6.0.4 '@multiformats/multiaddr': - specifier: ^12.1.10 - version: 12.3.1 + specifier: ^13.0.1 + version: 13.0.1 '@noble/hashes': - specifier: ^1.7.0 - version: 1.7.0 + specifier: ^2.0.1 + version: 2.0.1 '@noble/secp256k1': - specifier: ^2.2.2 - version: 2.2.3 - debug: - specifier: ^4.3.1 - version: 4.3.4(supports-color@8.1.1) + specifier: ^3.0.0 + version: 3.0.0 ethereum-cryptography: - specifier: ^2.2.0 - version: 2.2.1 + specifier: ^3.2.0 + version: 3.2.0 lru-cache: - specifier: ^10.1.0 - version: 10.1.0 + specifier: ^11.2.5 + version: 11.2.5 strict-event-emitter-types: specifier: ^2.0.0 version: 2.0.0 + weald: + specifier: ^1.1.1 + version: 1.1.1 packages/enr: dependencies: '@ethereumjs/rlp': - specifier: ^5.0.2 - version: 5.0.2 + specifier: ^10.1.1 + version: 10.1.1 '@libp2p/crypto': specifier: ^5.0.1 version: 5.0.1 '@libp2p/interface': - specifier: ^2.0.1 - version: 2.0.1 + specifier: ^3.1.0 + version: 3.1.0 '@libp2p/peer-id': - specifier: ^5.0.1 - version: 5.0.1 + specifier: ^6.0.4 + version: 6.0.4 '@multiformats/multiaddr': - specifier: ^12.1.10 - version: 12.3.1 + specifier: ^13.0.1 + version: 13.0.1 '@scure/base': - specifier: ^1.2.1 - version: 1.2.1 + specifier: ^2.0.0 + version: 2.0.0 ethereum-cryptography: - specifier: ^2.2.0 - version: 2.2.1 - uint8-varint: - specifier: ^2.0.2 - version: 2.0.3 - devDependencies: - '@types/bn.js': - specifier: ^4.11.5 - version: 4.11.6 + specifier: ^3.2.0 + version: 3.2.0 packages: - '@aashutoshrathi/word-wrap@1.2.6': - resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} - engines: {node: '>=0.10.0'} - - '@actions/cache@1.0.11': - resolution: {integrity: sha512-L+VCF1JpFePAzxkYtpwYDWnd0WzSU1DoNPE2cuINKpEie27ONH0Cpqt40cG8NiJW4zbZLN+kNkEDo3F2MkUuRw==} - deprecated: Please upgrade to v4 or higher. See https://github.com/actions/toolkit/discussions/1890 for more details. + '@actions/cache@4.1.0': + resolution: {integrity: sha512-z3Opg+P4Y7baq+g1dODXgdtsvPLSewr3ZKpp3U0HQR1A/vWCoJFS52XSezjdngo4SIOdR5oHtyK3a3Arar+X9A==} - '@actions/core@1.10.1': - resolution: {integrity: sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g==} + '@actions/core@1.11.1': + resolution: {integrity: sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==} '@actions/exec@1.1.1': resolution: {integrity: sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==} - '@actions/github@5.1.1': - resolution: {integrity: sha512-Nk59rMDoJaV+mHCOJPXuvB1zIbomlKS0dmSIqPGxd0enAXBnOfn4VWF+CGtRCwXZG9Epa54tZA7VIRlJDS8A6g==} + '@actions/github@6.0.1': + resolution: {integrity: sha512-xbZVcaqD4XnQAe35qSQqskb3SqIAfRyLBrHMd/8TuL7hJSz2QtbDwnNM8zWx4zO5l2fnGtseNE3MbEvD7BxVMw==} '@actions/glob@0.1.2': resolution: {integrity: sha512-SclLR7Ia5sEqjkJTPs7Sd86maMDw43p769YxBOxvPvEWuPEhpAnBsQfENOpXjFYMmhCqd127bmf+YdvJqVqR4A==} - '@actions/http-client@1.0.11': - resolution: {integrity: sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==} - '@actions/http-client@2.2.0': resolution: {integrity: sha512-q+epW0trjVUUHboliPb4UF9g2msf+w61b32tAkFEwL/IwP0DQWgbCMM0Hbe3e3WXSKz5VcUXbzJQgy8Hkra/Lg==} @@ -204,64 +156,67 @@ packages: resolution: {integrity: sha512-sM4vpsCpcCApagRW5UIjQNlNylo02my2opgp0Emi8x888hZUvJ3dN69Oq20cEGXkMUWnoCrBaB0zyS3yeB87sQ==} engines: {node: '>=14.0.0'} - '@babel/code-frame@7.23.5': - resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} - engines: {node: '>=6.9.0'} - - '@babel/generator@7.23.6': - resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-environment-visitor@7.22.20': - resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-function-name@7.23.0': - resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-hoist-variables@7.22.5': - resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-split-export-declaration@7.22.6': - resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.23.4': - resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.22.20': - resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} - engines: {node: '>=6.9.0'} - - '@babel/highlight@7.23.4': - resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.23.6': - resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==} - engines: {node: '>=6.0.0'} + '@biomejs/biome@2.3.14': + resolution: {integrity: sha512-QMT6QviX0WqXJCaiqVMiBUCr5WRQ1iFSjvOLoTk6auKukJMvnMzWucXpwZB0e8F00/1/BsS9DzcKgWH+CLqVuA==} + engines: {node: '>=14.21.3'} hasBin: true - '@babel/template@7.22.15': - resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} - engines: {node: '>=6.9.0'} + '@biomejs/cli-darwin-arm64@2.3.14': + resolution: {integrity: sha512-UJGPpvWJMkLxSRtpCAKfKh41Q4JJXisvxZL8ChN1eNW3m/WlPFJ6EFDCE7YfUb4XS8ZFi3C1dFpxUJ0Ety5n+A==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] - '@babel/traverse@7.23.7': - resolution: {integrity: sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==} - engines: {node: '>=6.9.0'} + '@biomejs/cli-darwin-x64@2.3.14': + resolution: {integrity: sha512-PNkLNQG6RLo8lG7QoWe/hhnMxJIt1tEimoXpGQjwS/dkdNiKBLPv4RpeQl8o3s1OKI3ZOR5XPiYtmbGGHAOnLA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] - '@babel/types@7.23.6': - resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==} - engines: {node: '>=6.9.0'} + '@biomejs/cli-linux-arm64-musl@2.3.14': + resolution: {integrity: sha512-LInRbXhYujtL3sH2TMCH/UBwJZsoGwfQjBrMfl84CD4hL/41C/EU5mldqf1yoFpsI0iPWuU83U+nB2TUUypWeg==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@2.3.14': + resolution: {integrity: sha512-KT67FKfzIw6DNnUNdYlBg+eU24Go3n75GWK6NwU4+yJmDYFe9i/MjiI+U/iEzKvo0g7G7MZqoyrhIYuND2w8QQ==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@2.3.14': + resolution: {integrity: sha512-KQU7EkbBBuHPW3/rAcoiVmhlPtDSGOGRPv9js7qJVpYTzjQmVR+C9Rfcz+ti8YCH+zT1J52tuBybtP4IodjxZQ==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@2.3.14': + resolution: {integrity: sha512-ZsZzQsl9U+wxFrGGS4f6UxREUlgHwmEfu1IrXlgNFrNnd5Th6lIJr8KmSzu/+meSa9f4rzFrbEW9LBBA6ScoMA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@2.3.14': + resolution: {integrity: sha512-+IKYkj/pUBbnRf1G1+RlyA3LWiDgra1xpS7H2g4BuOzzRbRB+hmlw0yFsLprHhbbt7jUzbzAbAjK/Pn0FDnh1A==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@2.3.14': + resolution: {integrity: sha512-oizCjdyQ3WJEswpb3Chdngeat56rIdSYK12JI3iI11Mt5T5EXcZ7WLuowzEaFPNJ3zmOQFliMN8QY1Pi+qsfdQ==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + + '@chainsafe/benchmark@2.0.1': + resolution: {integrity: sha512-Noecu9z6kjXWdKl9ZL/PckJxfi+Ax4/8/i4F862jo3FZcViK8LWR5Byc8pKeNC5vcDMSP73/ME3vgUovYGqwUw==} + hasBin: true - '@chainsafe/eslint-plugin-node@11.2.3': - resolution: {integrity: sha512-2iQv5JEaPcJuKP4pdawGd6iOVoUEDwx/PhsLqevwQXXz0WYwazW+p1fTF1bAcQNvZzLz4/wEBPtcVpQKNwY+jw==} - engines: {node: '>=8.10.0'} + '@chainsafe/biomejs-config@1.0.0': + resolution: {integrity: sha512-juZ0Oivc8QeF5wIUDdgOfOvAH4II8N3hHjQBdyv2PjvbTXna+gTv0kucJ9Mp7HO+nwRH58fhFh7iOMfsrSfogg==} peerDependencies: - eslint: '>=5.16.0' + '@biomejs/biome': ^2.2.0 '@chainsafe/is-ip@2.0.2': resolution: {integrity: sha512-ndGqEMG1W5WkGagaqOZHpPU172AGdxr+LD15sv3WIUvT5oCFUrG1Y0CW/v2Egwj4JXEvSibaIIIqImsm98y1nA==} @@ -269,73 +224,192 @@ packages: '@chainsafe/netmask@2.0.0': resolution: {integrity: sha512-I3Z+6SWUoaljh3TBzCnCxjlUyN8tA+NAk5L6m9IxvCf1BENQTePzPMis97CoN/iMW1St3WN+AWCCRp+TTBRiDg==} + '@colors/colors@1.5.0': + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} - '@dapplion/benchmark@0.2.4': - resolution: {integrity: sha512-57nIqyEEgEoSPzLTTgkt5NukLbZuYCg9lmNml+/QR4TcwwFugSuSPmNQTDKyqO92l8XmI8AfSxSoIioAXkJ7lw==} - hasBin: true - peerDependencies: - mocha: '>8.0.0' + '@esbuild/aix-ppc64@0.27.3': + resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] - '@eslint-community/eslint-utils@4.4.0': - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@esbuild/android-arm64@0.27.3': + resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.3': + resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.3': + resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.3': + resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.3': + resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.3': + resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.3': + resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.3': + resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.3': + resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.3': + resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.3': + resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.3': + resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.3': + resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] - '@eslint-community/regexpp@4.10.0': - resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + '@esbuild/linux-riscv64@0.27.3': + resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.3': + resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.3': + resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.3': + resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.3': + resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.3': + resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.3': + resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.3': + resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.3': + resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] - '@eslint/eslintrc@2.1.4': - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@esbuild/win32-arm64@0.27.3': + resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] - '@eslint/js@8.56.0': - resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@esbuild/win32-ia32@0.27.3': + resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] - '@ethereumjs/rlp@5.0.2': - resolution: {integrity: sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA==} + '@esbuild/win32-x64@0.27.3': + resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@ethereumjs/rlp@10.1.1': + resolution: {integrity: sha512-jbnWTEwcpoY+gE0r+wxfDG9zgiu54DcTcwnc9sX3DsqKR4l5K7x2V8mQL3Et6hURa4DuT9g7z6ukwpBLFchszg==} + engines: {node: '>=20'} hasBin: true '@fastify/busboy@2.1.0': resolution: {integrity: sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==} engines: {node: '>=14'} - '@humanwhocodes/config-array@0.11.14': - resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} - engines: {node: '>=10.10.0'} - deprecated: Use @eslint/config-array instead - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/object-schema@2.0.2': - resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} - deprecated: Use @eslint/object-schema instead - - '@jridgewell/gen-mapping@0.3.3': - resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} - engines: {node: '>=6.0.0'} + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} '@jridgewell/resolve-uri@3.1.1': resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} engines: {node: '>=6.0.0'} - '@jridgewell/set-array@1.1.2': - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} - engines: {node: '>=6.0.0'} - '@jridgewell/sourcemap-codec@1.4.15': resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - '@jridgewell/trace-mapping@0.3.20': - resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==} + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} @@ -346,11 +420,17 @@ packages: '@libp2p/crypto@5.0.1': resolution: {integrity: sha512-j7X4ISdWHnIJh752bl70z+3R4LdB8xftFU0ShOuuHg9ETTViHa3O0AK5v1HxyaSXE/uhXhfwjVH3vxn8ECQl/A==} + '@libp2p/crypto@5.1.13': + resolution: {integrity: sha512-8NN9cQP3jDn+p9+QE9ByiEoZ2lemDFf/unTgiKmS3JF93ph240EUVdbCyyEgOMfykzb0okTM4gzvwfx9osJebQ==} + '@libp2p/interface@2.0.1': resolution: {integrity: sha512-zDAgu+ZNiYZxVsmcvCeNCLMnGORwLMMI8w0k2YcHwolATsv2q7QG3KpakmyKjH4m7C0hT86lGgf1sgGobPssYA==} - '@libp2p/peer-id@5.0.1': - resolution: {integrity: sha512-HwoW7dQ/o4NQ+5PQThOzMK2OHMRicmTZxVuMjbjWcPNnNWb8x/5vwjzdEUfqXimHYdZTIpy2PMMq6Jf4zvculQ==} + '@libp2p/interface@3.1.0': + resolution: {integrity: sha512-RE7/XyvC47fQBe1cHxhMvepYKa5bFCUyFrrpj8PuM0E7JtzxU7F+Du5j4VXbg2yLDcToe0+j8mB7jvwE2AThYw==} + + '@libp2p/peer-id@6.0.4': + resolution: {integrity: sha512-Z3xK0lwwKn4bPg3ozEpPr1HxsRi2CxZdghOL+MXoFah/8uhJJHxHFA8A/jxtKn4BB8xkk6F8R5vKNIS05yaCYw==} '@multiformats/dns@1.0.6': resolution: {integrity: sha512-nt/5UqjMPtyvkG9BQYdJ4GfLK3nMqGpFZOzf4hAmIa0sJh2LlS9YKXZ4FgwBDsaHvzZqR/rUFIywIc7pkHNNuw==} @@ -358,89 +438,241 @@ packages: '@multiformats/multiaddr@12.3.1': resolution: {integrity: sha512-yoGODQY4nIj41ENJClucS8FtBoe8w682bzbKldEQr9lSlfdHqAsRC+vpJAOBpiMwPps1tHua4kxrDmvprdhoDQ==} - '@noble/curves@1.4.2': - resolution: {integrity: sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==} + '@multiformats/multiaddr@13.0.1': + resolution: {integrity: sha512-XToN915cnfr6Lr9EdGWakGJbPT0ghpg/850HvdC+zFX8XvpLZElwa8synCiwa8TuvKNnny6m8j8NVBNCxhIO3g==} + + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} + engines: {node: ^14.21.3 || >=16} '@noble/curves@1.6.0': resolution: {integrity: sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==} engines: {node: ^14.21.3 || >=16} - '@noble/hashes@1.4.0': - resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} - engines: {node: '>= 16'} + '@noble/curves@1.9.0': + resolution: {integrity: sha512-7YDlXiNMdO1YZeH6t/kvopHHbIZzlxrCV9WLqCY6QhcXOoXiNCMDqJIglZ9Yjx5+w7Dz30TITFrlTjnRg7sKEg==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@2.0.1': + resolution: {integrity: sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw==} + engines: {node: '>= 20.19.0'} '@noble/hashes@1.5.0': resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==} engines: {node: ^14.21.3 || >=16} - '@noble/hashes@1.7.0': - resolution: {integrity: sha512-HXydb0DgzTpDPwbVeDGCG1gIu7X6+AuU6Zl6av/E/KG8LMsvPntvq+w17CHRpKBmN6Ybdrt1eP3k4cj8DJa78w==} + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} engines: {node: ^14.21.3 || >=16} - '@noble/secp256k1@2.2.3': - resolution: {integrity: sha512-l7r5oEQym9Us7EAigzg30/PQAvynhMt2uoYtT3t26eGDVm9Yii5mZ5jWSWmZ/oSIR2Et0xfc6DXrG0bZ787V3w==} - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} + '@noble/hashes@2.0.1': + resolution: {integrity: sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==} + engines: {node: '>= 20.19.0'} - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} + '@noble/secp256k1@3.0.0': + resolution: {integrity: sha512-NJBaR352KyIvj3t6sgT/+7xrNyF9Xk9QlLSIqUGVUYlsnDTAUqY8LOmwpcgEx4AMJXRITQ5XEVHD+mMaPfr3mg==} - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} + '@octokit/auth-token@4.0.0': + resolution: {integrity: sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==} + engines: {node: '>= 18'} - '@octokit/auth-token@2.5.0': - resolution: {integrity: sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==} + '@octokit/core@5.2.2': + resolution: {integrity: sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==} + engines: {node: '>= 18'} - '@octokit/core@3.6.0': - resolution: {integrity: sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==} + '@octokit/endpoint@9.0.6': + resolution: {integrity: sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==} + engines: {node: '>= 18'} - '@octokit/endpoint@6.0.12': - resolution: {integrity: sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==} + '@octokit/graphql@7.1.1': + resolution: {integrity: sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==} + engines: {node: '>= 18'} - '@octokit/graphql@4.8.0': - resolution: {integrity: sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==} + '@octokit/openapi-types@20.0.0': + resolution: {integrity: sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==} - '@octokit/openapi-types@12.11.0': - resolution: {integrity: sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==} + '@octokit/openapi-types@24.2.0': + resolution: {integrity: sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==} - '@octokit/plugin-paginate-rest@2.21.3': - resolution: {integrity: sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==} + '@octokit/plugin-paginate-rest@9.2.2': + resolution: {integrity: sha512-u3KYkGF7GcZnSD/3UP0S7K5XUFT2FkOQdcfXZGZQPGv3lm4F2Xbf71lvjldr8c1H3nNbF+33cLEkWYbokGWqiQ==} + engines: {node: '>= 18'} peerDependencies: - '@octokit/core': '>=2' + '@octokit/core': '5' - '@octokit/plugin-rest-endpoint-methods@5.16.2': - resolution: {integrity: sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==} + '@octokit/plugin-rest-endpoint-methods@10.4.1': + resolution: {integrity: sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==} + engines: {node: '>= 18'} peerDependencies: - '@octokit/core': '>=3' + '@octokit/core': '5' + + '@octokit/request-error@5.1.1': + resolution: {integrity: sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==} + engines: {node: '>= 18'} - '@octokit/request-error@2.1.0': - resolution: {integrity: sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==} + '@octokit/request@8.4.1': + resolution: {integrity: sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==} + engines: {node: '>= 18'} - '@octokit/request@5.6.3': - resolution: {integrity: sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==} + '@octokit/types@12.6.0': + resolution: {integrity: sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==} - '@octokit/types@6.41.0': - resolution: {integrity: sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==} + '@octokit/types@13.10.0': + resolution: {integrity: sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==} '@opentelemetry/api@1.7.0': resolution: {integrity: sha512-AdY5wvN0P2vXBi3b29hxZgSFvdhdxPB9+f0B6s//P9Q8nibRWeA3cHm8UmLpio9ABigkVHJ5NMPk+Mz8VCCyrw==} engines: {node: '>=8.0.0'} - '@scure/base@1.1.8': - resolution: {integrity: sha512-6CyAclxj3Nb0XT7GHK6K4zK6k2xJm6E4Ft0Ohjt4WgegiFUHEtFb2CGzmPmGBwoIhrLsqNLYfLr04Y1GePrzZg==} + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@protobuf-ts/runtime-rpc@2.11.1': + resolution: {integrity: sha512-4CqqUmNA+/uMz00+d3CYKgElXO9VrEbucjnBFEjqI4GuDrEQ32MaI3q+9qPBvIGOlL4PmHXrzM32vBPWRhQKWQ==} - '@scure/base@1.2.1': - resolution: {integrity: sha512-DGmGtC8Tt63J5GfHgfl5CuAXh96VF/LD8K9Hr/Gv0J2lAoRGlPOMpqMpMbCTOoOJMZCk2Xt+DskdDyn6dEFdzQ==} + '@protobuf-ts/runtime@2.11.1': + resolution: {integrity: sha512-KuDaT1IfHkugM2pyz+FwiY80ejWrkH1pAtOBOZFuR6SXEFTsnb/jiQWQ1rCIrcKx2BtyxnxW6BWwsVSA/Ie+WQ==} - '@scure/bip32@1.4.0': - resolution: {integrity: sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==} + '@rollup/rollup-android-arm-eabi@4.57.1': + resolution: {integrity: sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==} + cpu: [arm] + os: [android] - '@scure/bip39@1.3.0': - resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==} + '@rollup/rollup-android-arm64@4.57.1': + resolution: {integrity: sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.57.1': + resolution: {integrity: sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.57.1': + resolution: {integrity: sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.57.1': + resolution: {integrity: sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.57.1': + resolution: {integrity: sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.57.1': + resolution: {integrity: sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.57.1': + resolution: {integrity: sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.57.1': + resolution: {integrity: sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.57.1': + resolution: {integrity: sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.57.1': + resolution: {integrity: sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-loong64-musl@4.57.1': + resolution: {integrity: sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.57.1': + resolution: {integrity: sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-ppc64-musl@4.57.1': + resolution: {integrity: sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.57.1': + resolution: {integrity: sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.57.1': + resolution: {integrity: sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.57.1': + resolution: {integrity: sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.57.1': + resolution: {integrity: sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.57.1': + resolution: {integrity: sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openbsd-x64@4.57.1': + resolution: {integrity: sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.57.1': + resolution: {integrity: sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.57.1': + resolution: {integrity: sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.57.1': + resolution: {integrity: sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.57.1': + resolution: {integrity: sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.57.1': + resolution: {integrity: sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==} + cpu: [x64] + os: [win32] + + '@scure/base@1.2.6': + resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + + '@scure/base@2.0.0': + resolution: {integrity: sha512-3E1kpuZginKkek01ovG8krQ0Z44E3DHPjc5S2rjJw9lZn3KSQOs8S7wqikF/AH7iRanHypj85uGyxk0XAyC37w==} + + '@scure/bip32@1.7.0': + resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==} + + '@scure/bip39@1.6.0': + resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} '@tsconfig/node10@1.0.9': resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} @@ -454,119 +686,69 @@ packages: '@tsconfig/node16@1.0.4': resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - '@types/bn.js@4.11.6': - resolution: {integrity: sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==} - - '@types/chai@4.3.11': - resolution: {integrity: sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ==} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} - '@types/debug@4.1.12': - resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} '@types/dns-packet@5.6.5': resolution: {integrity: sha512-qXOC7XLOEe43ehtWJCMnQXvgcIpv6rPmQ1jXT98Ad8A3TB1Ue50jsCbSSSyuazScEuZ/Q026vHbrOTVkmwA+7Q==} - '@types/eslint@6.8.1': - resolution: {integrity: sha512-eutiEpQ4SN7kdF8QVDPyiSSy7ZFM+werJVw6/mRxLGbG4oet6/p81WFjSIcuY9PzM+dsu25Yh5EAUmQ9aJC1gg==} - - '@types/estree@1.0.5': - resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/mocha@8.2.3': - resolution: {integrity: sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==} - - '@types/ms@0.7.34': - resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} '@types/node-fetch@2.6.10': resolution: {integrity: sha512-PPpPK6F9ALFTn59Ka3BaL+qGuipRfxNE8qVgkp0bVixeiR2c2/L+IVOiBdu9JhhT22sWnQEp6YyHGI2b2+CMcA==} - '@types/node@20.11.0': - resolution: {integrity: sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==} - - '@types/semver@7.5.6': - resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==} + '@types/node@24.10.12': + resolution: {integrity: sha512-68e+T28EbdmLSTkPgs3+UacC6rzmqrcWFPQs1C8mwJhI/r5Uxr0yEuQotczNRROd1gq30NGxee+fo0rSIxpyAw==} '@types/tunnel@0.0.3': resolution: {integrity: sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==} - '@typescript-eslint/eslint-plugin@5.62.0': - resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true + '@vitest/expect@4.0.18': + resolution: {integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==} - '@typescript-eslint/parser@5.62.0': - resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@vitest/mocker@4.0.18': + resolution: {integrity: sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==} peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0-0 peerDependenciesMeta: - typescript: + msw: + optional: true + vite: optional: true - '@typescript-eslint/scope-manager@5.62.0': - resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@vitest/pretty-format@2.1.9': + resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} - '@typescript-eslint/type-utils@5.62.0': - resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: '*' - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true + '@vitest/pretty-format@4.0.18': + resolution: {integrity: sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==} - '@typescript-eslint/types@5.62.0': - resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@vitest/runner@2.1.9': + resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==} - '@typescript-eslint/typescript-estree@5.62.0': - resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true + '@vitest/runner@4.0.18': + resolution: {integrity: sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==} - '@typescript-eslint/utils@5.62.0': - resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + '@vitest/snapshot@4.0.18': + resolution: {integrity: sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==} - '@typescript-eslint/visitor-keys@5.62.0': - resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@vitest/spy@4.0.18': + resolution: {integrity: sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==} - '@ungap/structured-clone@1.2.0': - resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + '@vitest/utils@2.1.9': + resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + + '@vitest/utils@4.0.18': + resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==} abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} - accepts@1.3.8: - resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} - engines: {node: '>= 0.6'} - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn-walk@8.3.2: resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} engines: {node: '>=0.4.0'} @@ -576,81 +758,35 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - after@0.8.2: - resolution: {integrity: sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==} - - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - - ajv@8.12.0: - resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} - - ansi-colors@4.1.1: - resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} - engines: {node: '>=6'} - - ansi-regex@4.1.1: - resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} - engines: {node: '>=6'} + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - - append-transform@1.0.0: - resolution: {integrity: sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==} - engines: {node: '>=4'} - - archy@1.0.0: - resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - - arraybuffer.slice@0.0.7: - resolution: {integrity: sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==} - - asn1@0.2.6: - resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - asn1js@3.0.5: resolution: {integrity: sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==} engines: {node: '>=12.0.0'} - assert-plus@1.0.0: - resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} - engines: {node: '>=0.8'} - - assertion-error@1.1.0: - resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} - - async-limiter@1.0.1: - resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} - - async@2.6.4: - resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -662,251 +798,73 @@ packages: aws-sdk@2.1533.0: resolution: {integrity: sha512-tnt8VMxd6WHORHYrk/RSeUa14QNTkjsCVXuRZCbk9QPX//K1k8+mNwfrV9LN/e4L1vBtjVep7V4MJsyU07ibUw==} engines: {node: '>= 10.0.0'} - - aws-sign2@0.7.0: - resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} - - aws4@1.13.2: - resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} - - backo2@1.0.2: - resolution: {integrity: sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==} + deprecated: The AWS SDK for JavaScript (v2) has reached end-of-support, and no longer receives updates. Please migrate your code to use AWS SDK for JavaScript (v3). More info https://a.co/cUPnyil balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - base64-arraybuffer@0.1.5: - resolution: {integrity: sha512-437oANT9tP582zZMwSvZGy2nmSeAb8DW2me3y+Uv1Wp2Rulr8Mqlyrv3E7MLxmsiaPSMMDmiDVzgE+e8zlMx9g==} - engines: {node: '>= 0.6.0'} - base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - base64id@1.0.0: - resolution: {integrity: sha512-rz8L+d/xByiB/vLVftPkyY215fqNrmasrcJsYkVcm4TgJNz+YXKrFaFAWibSaHkiKoSgMDCb+lipOIRQNGYesw==} - engines: {node: '>= 0.4.0'} - - bcrypt-pbkdf@1.0.2: - resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} - before-after-hook@2.2.3: resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} - better-assert@1.0.2: - resolution: {integrity: sha512-bYeph2DFlpK1XmGs6fvlLRUN29QISM3GBuUwSFsMY2XRx4AvC0WNCS57j4c/xGrK2RS24C1w3YoBOsw9fT46tQ==} - - binary-extensions@2.2.0: - resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} - engines: {node: '>=8'} - - blob@0.0.5: - resolution: {integrity: sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==} - - bluebird@3.7.2: - resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} - - body-parser@1.20.2: - resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} - - browser-stdout@1.3.1: - resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} - - buffer-alloc-unsafe@1.1.0: - resolution: {integrity: sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==} - - buffer-alloc@1.2.0: - resolution: {integrity: sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==} - - buffer-fill@1.0.0: - resolution: {integrity: sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==} - buffer@4.9.2: resolution: {integrity: sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==} buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - - caching-transform@3.0.2: - resolution: {integrity: sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==} - engines: {node: '>=6'} - call-bind@1.0.5: resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} - callsite@1.0.0: - resolution: {integrity: sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==} - - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} - - camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} - - caseless@0.12.0: - resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} - - chai@4.4.0: - resolution: {integrity: sha512-x9cHNq1uvkCdU+5xTkNh5WtgD4e4yDFCsp9jVc7N7qVeKeftv3gO/ZrviX5d+3ZfxdYnZXZYujjRInu1RogU6A==} - engines: {node: '>=4'} - - chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - check-error@1.0.3: - resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} - - chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} - engines: {node: '>= 8.10.0'} - - cliui@5.0.0: - resolution: {integrity: sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==} + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} - cliui@7.0.4: - resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} + engines: {node: 10.* || >= 12.*} cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} - color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} - color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - colors@1.4.0: - resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} - engines: {node: '>=0.1.90'} - combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} - commondir@1.0.1: - resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - - component-bind@1.0.0: - resolution: {integrity: sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw==} - - component-emitter@1.2.1: - resolution: {integrity: sha512-jPatnhd33viNplKjqXKRkGU345p263OIWzDL2wH3LGIGp5Kojo+uXizHmOADRvhGFFTnJqX3jBAKP6vvmSDKcA==} - - component-inherit@0.0.3: - resolution: {integrity: sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA==} - concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - connect@3.7.0: - resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==} - engines: {node: '>= 0.10.0'} - - content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - - convert-source-map@1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - - cookie@0.3.1: - resolution: {integrity: sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw==} - engines: {node: '>= 0.6'} - - core-util-is@1.0.2: - resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} - - cp-file@6.2.0: - resolution: {integrity: sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==} - engines: {node: '>=6'} - create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - cross-spawn@4.0.2: - resolution: {integrity: sha512-yAXz/pA1tD8Gtg2S98Ekf/sewp3Lcp3YoFKJ4Hkp5h5yLWnKVTDU0kwjKJ8NDCYcfTLfyGkzTikst+jWypT1iA==} - - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - csv-parse@4.16.3: - resolution: {integrity: sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==} - - csv-stringify@5.6.5: - resolution: {integrity: sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==} - - custom-event@1.0.1: - resolution: {integrity: sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==} - - dashdash@1.14.1: - resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} - engines: {node: '>=0.10'} - - date-format@2.1.0: - resolution: {integrity: sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==} - engines: {node: '>=4.0'} - deprecated: 2.x is no longer supported. Please upgrade to 4.x or higher. - - debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@3.1.0: - resolution: {integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + csv-parse@5.6.0: + resolution: {integrity: sha512-l3nz3euub2QMg5ouu5U09Ew9Wf6/wQ8I++ch1loQ0ljmzhmfZYrH9fflS22i/PQEvsPvxCwxgz5q7UB8K1JO4Q==} - debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + csv-stringify@6.6.0: + resolution: {integrity: sha512-YW32lKOmIBgbxtu3g5SaiqWNwa/9ISQt2EcgOq0+RAIFufFp9is6tqNnKahqE5kuKvrnYAzs28r+s6pXJR8Vcw==} - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -914,25 +872,6 @@ packages: supports-color: optional: true - decamelize@1.2.0: - resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} - engines: {node: '>=0.10.0'} - - decamelize@4.0.0: - resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} - engines: {node: '>=10'} - - deep-eql@4.1.3: - resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} - engines: {node: '>=6'} - - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - default-require-extensions@2.0.0: - resolution: {integrity: sha512-B0n2zDIXpzLzKeoEozorDSa1cHc1t0NjmxP0zuAxbizNU2MBqYJJKYXrrFdKuQliojXynrxgd7l4ahfg/+aA5g==} - engines: {node: '>=4'} - define-data-property@1.1.1: resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} engines: {node: '>= 0.4'} @@ -941,174 +880,49 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} - depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - deprecation@2.3.1: resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} - destroy@1.2.0: - resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - - di@0.0.1: - resolution: {integrity: sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==} - diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} - diff@5.0.0: - resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} - engines: {node: '>=0.3.1'} - - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - dns-packet@5.6.1: resolution: {integrity: sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==} engines: {node: '>=6'} - doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - - dom-serialize@2.2.1: - resolution: {integrity: sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==} - - ecc-jsbn@0.1.2: - resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} - - ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - - emoji-regex@7.0.3: - resolution: {integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - encodeurl@1.0.2: - resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} - engines: {node: '>= 0.8'} + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - engine.io-client@3.2.1: - resolution: {integrity: sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==} + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - engine.io-parser@2.1.3: - resolution: {integrity: sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==} - - engine.io@3.2.1: - resolution: {integrity: sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==} - - ent@2.2.0: - resolution: {integrity: sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==} - - error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - - es6-error@4.1.1: - resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} + esbuild@0.27.3: + resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} + engines: {node: '>=18'} + hasBin: true escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} - escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - eslint-plugin-es@4.1.0: - resolution: {integrity: sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==} - engines: {node: '>=8.10.0'} - peerDependencies: - eslint: '>=4.19.1' - - eslint-plugin-prettier@4.2.1: - resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} - engines: {node: '>=12.0.0'} - peerDependencies: - eslint: '>=7.28.0' - eslint-config-prettier: '*' - prettier: '>=2.0.0' - peerDependenciesMeta: - eslint-config-prettier: - optional: true - - eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - - eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-utils@2.1.0: - resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} - engines: {node: '>=6'} - - eslint-visitor-keys@1.3.0: - resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} - engines: {node: '>=4'} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint@8.56.0: - resolution: {integrity: sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. - hasBin: true - - espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - - esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - ethereum-cryptography@2.2.1: - resolution: {integrity: sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==} + ethereum-cryptography@3.2.0: + resolution: {integrity: sha512-Urr5YVsalH+Jo0sYkTkv1MyI9bLYZwW8BENZCeE1QYaTHETEYx0Nv/SVsWkSqpYrzweg6d8KMY1wTjH/1m/BIg==} + engines: {node: ^14.21.3 || >=16, npm: '>=9'} event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} - eventemitter3@4.0.7: - resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} - eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} @@ -1120,91 +934,31 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} - extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - - extsprintf@1.3.0: - resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} - engines: {'0': node >=0.6.0} + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-diff@1.3.0: - resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - - fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} - engines: {node: '>=8.6.0'} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fastq@1.16.0: - resolution: {integrity: sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==} - - file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} - - fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} - engines: {node: '>=8'} - - finalhandler@1.1.2: - resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==} - engines: {node: '>= 0.8'} - - find-cache-dir@2.1.0: - resolution: {integrity: sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==} - engines: {node: '>=6'} - - find-up@3.0.0: - resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} - engines: {node: '>=6'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - flat-cache@3.2.0: - resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} - engines: {node: ^10.12.0 || >=12.0.0} + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} - flat@5.0.2: - resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} - hasBin: true - - flatted@2.0.2: - resolution: {integrity: sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==} - - flatted@3.2.9: - resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} - - follow-redirects@1.15.4: - resolution: {integrity: sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==} - engines: {node: '>=4.0'} + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} peerDependencies: - debug: '*' + picomatch: ^3 || ^4 peerDependenciesMeta: - debug: + picomatch: optional: true for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - foreground-child@1.5.6: - resolution: {integrity: sha512-3TOY+4TKV0Ml83PXJQY+JFQaHNV38lzQDIzzXYg1kWdBLenGgoZhAs0CKgzI31vi2pWEpQMq/Yi4bpKwCPkw7g==} - - forever-agent@0.6.1: - resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} - - form-data@2.3.3: - resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} - engines: {node: '>= 0.12'} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} form-data@2.5.1: resolution: {integrity: sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==} @@ -1214,13 +968,6 @@ packages: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} - fs-extra@7.0.1: - resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} - engines: {node: '>=6 <7 || >=8'} - - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1233,75 +980,17 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-func-name@2.0.2: - resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - get-intrinsic@1.2.2: resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} - getpass@0.1.7: - resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - glob@7.2.0: - resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} - deprecated: Glob versions prior to v9 are no longer supported - - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported - - globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - - globals@13.24.0: - resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} - engines: {node: '>=8'} - - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + hasBin: true gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - - har-schema@2.0.0: - resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} - engines: {node: '>=4'} - - har-validator@5.1.5: - resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} - engines: {node: '>=6'} - deprecated: this library is no longer supported - - has-binary2@1.0.3: - resolution: {integrity: sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==} - - has-cors@1.1.0: - resolution: {integrity: sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA==} - - has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - has-property-descriptors@1.0.1: resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} @@ -1317,10 +1006,6 @@ packages: resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} engines: {node: '>= 0.4'} - hasha@3.0.0: - resolution: {integrity: sha512-w0Kz8lJFBoyaurBiNrIvxPqr/gJ6fOfSkpAPOepN3oECqGJag37xPbOv57izi/KP8auHgNYxn5fXtAb+1LsJ6w==} - engines: {node: '>=4'} - hashlru@2.3.0: resolution: {integrity: sha512-0cMsjjIC8I+D3M44pOQdsy0OHXGLVz6Z0beRuufhKa0KfaD2wGwAev6jILzXsd3/vpnNQJmWyZtIILqM1N+n5A==} @@ -1328,57 +1013,12 @@ packages: resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} engines: {node: '>= 0.4'} - he@1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} - hasBin: true - - hosted-git-info@2.8.9: - resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} - - html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - - http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} - - http-proxy@1.18.1: - resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} - engines: {node: '>=8.0.0'} - - http-signature@1.2.0: - resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} - engines: {node: '>=0.8', npm: '>=1.3.7'} - - iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - ieee754@1.1.13: resolution: {integrity: sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==} ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - ignore@5.3.0: - resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==} - engines: {node: '>= 4'} - - import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - indexof@0.0.1: - resolution: {integrity: sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==} - - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. - inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -1386,28 +1026,10 @@ packages: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} engines: {node: '>= 0.4'} - is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} - is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-fullwidth-code-point@2.0.0: - resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} - engines: {node: '>=4'} - is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} @@ -1416,81 +1038,20 @@ packages: resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} engines: {node: '>= 0.4'} - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - - is-plain-obj@2.1.0: - resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} - engines: {node: '>=8'} - - is-plain-object@5.0.0: - resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} - engines: {node: '>=0.10.0'} - - is-stream@1.1.0: - resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} - engines: {node: '>=0.10.0'} - is-typed-array@1.1.12: resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} engines: {node: '>= 0.4'} - is-typedarray@1.0.0: - resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} - - is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - isarray@2.0.1: - resolution: {integrity: sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==} - - isbinaryfile@3.0.3: - resolution: {integrity: sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==} - engines: {node: '>=0.6.0'} - isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - isstream@0.1.2: - resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} - - istanbul-lib-coverage@2.0.5: - resolution: {integrity: sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==} - engines: {node: '>=6'} - - istanbul-lib-hook@2.0.7: - resolution: {integrity: sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==} - engines: {node: '>=6'} - - istanbul-lib-instrument@3.3.0: - resolution: {integrity: sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==} - engines: {node: '>=6'} - - istanbul-lib-report@2.0.8: - resolution: {integrity: sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==} - engines: {node: '>=6'} - - istanbul-lib-source-maps@3.0.6: - resolution: {integrity: sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==} - engines: {node: '>=6'} - - istanbul-reports@2.2.7: - resolution: {integrity: sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==} - engines: {node: '>=6'} - it-pushable@3.2.3: resolution: {integrity: sha512-gzYnXYK8Y5t5b/BnJUr7glfQLO4U5vyb05gPx/TyTw+4Bv1zM9gFk4YsOrnulWefMewlphCjKkakFvj1y99Tcg==} @@ -1498,135 +1059,39 @@ packages: resolution: {integrity: sha512-6DmOs5r7ERDbvS4q8yLKENcj6Yecr7QQTqWApbZdfAUTEC947d+PEha7PCqhm//9oxaLYL7TWRekwhoXl2s6fg==} engines: {node: '>=16.0.0', npm: '>=7.0.0'} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jmespath@0.16.0: resolution: {integrity: sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==} engines: {node: '>= 0.6.0'} - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - - jsbn@0.1.1: - resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} - - jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-parse-better-errors@1.0.2: - resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - json-schema@0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - json-stringify-safe@5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - - jsonfile@4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - - jsprim@1.4.2: - resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} - engines: {node: '>=0.6.0'} - - karma@4.4.1: - resolution: {integrity: sha512-L5SIaXEYqzrh6b1wqYC42tNsFMx2PWuxky84pK9coK09MvmL7mxii3G3bZBh/0rvD27lqDd0le9jyhzvwif73A==} - engines: {node: '>= 8'} - hasBin: true - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - - load-json-file@4.0.0: - resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} - engines: {node: '>=4'} - - locate-path@3.0.0: - resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} - engines: {node: '>=6'} - - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - lodash.flattendeep@4.4.0: - resolution: {integrity: sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - - log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - - log4js@4.5.1: - resolution: {integrity: sha512-EEEgFcE9bLgaYUKuozyFfytQM2wDHtXn4tAN41pkaxpNjAykv11GVdeI4tHtmPWW4Xrgh9R/2d7XYghDVjbKKw==} - engines: {node: '>=6.0'} - deprecated: 4.x is no longer supported. Please upgrade to 6.x or higher. + log-symbols@7.0.1: + resolution: {integrity: sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==} + engines: {node: '>=18'} - loupe@2.3.7: - resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} - lru-cache@10.1.0: - resolution: {integrity: sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==} - engines: {node: 14 || >=16.14} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@4.1.5: - resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + lru-cache@11.2.5: + resolution: {integrity: sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==} + engines: {node: 20 || >=22} - lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - make-dir@2.1.0: - resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} - engines: {node: '>=6'} + main-event@1.0.1: + resolution: {integrity: sha512-NWtdGrAca/69fm6DIVd8T9rtfDII4Q8NQbIbsKQq2VzS9eqOGYs8uaNQjcuaCq/d9H/o625aOTJX2Qoxzqw0Pw==} make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - media-typer@0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} - - merge-source-map@1.1.0: - resolution: {integrity: sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} - mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} @@ -1635,63 +1100,35 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} - mime@2.6.0: - resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} - engines: {node: '>=4.0.0'} - hasBin: true - minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - minimatch@5.0.1: - resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} - engines: {node: '>=10'} - - minimist@0.0.10: - resolution: {integrity: sha512-iotkTvxc+TwOm5Ieim8VnSNvCDjCK9S8G3scJ50ZthspSxa7jx50jkhYduuAtAjvfDUwSgOwf8+If99AlOEhyw==} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} - mkdirp@0.5.6: - resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} - hasBin: true - - mocha@10.2.0: - resolution: {integrity: sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==} - engines: {node: '>= 14.0.0'} - hasBin: true - - ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + ms@3.0.0-canary.202508261828: + resolution: {integrity: sha512-NotsCoUCIUkojWCzQff4ttdCfIPoA1UGZsyQbi7KmqkNRfKCrvga8JJi2PknHymHOuor0cJSn/ylj52Cbt2IrQ==} + engines: {node: '>=18'} + multiformats@13.2.2: resolution: {integrity: sha512-RWI+nyf0q64vyOxL8LbKtjJMki0sogRL/8axvklNtiTM0iFCVtHwME9w6+0P1/v4dQvsIg8A45oT3ka1t/M/+A==} - nanoid@3.3.3: - resolution: {integrity: sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==} + multiformats@13.4.2: + resolution: {integrity: sha512-eh6eHCrRi1+POZ3dA+Dq1C6jhP1GNtr9CRINMb67OKzqW9I5DUuZM/3jLPlzhgpGeiNUlEGEbkCYChXMCc/8DQ==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - natural-compare-lite@1.4.0: - resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} - - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - negotiator@0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} - - nested-error-stacks@2.1.1: - resolution: {integrity: sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==} - node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -1701,73 +1138,16 @@ packages: encoding: optional: true - normalize-package-data@2.5.0: - resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} - - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - nyc@14.1.1: - resolution: {integrity: sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==} - engines: {node: '>=6'} - hasBin: true - - oauth-sign@0.9.0: - resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} - - object-component@0.0.3: - resolution: {integrity: sha512-S0sN3agnVh2SZNEIGc0N1X4Z5K0JeFbGBrnuZpsxuUh5XLF0BnvWkMjRXo/zGKLd/eghvNIKcx1pQkmUjXIyrA==} - - object-inspect@1.13.1: - resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} - - on-finished@2.3.0: - resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==} - engines: {node: '>= 0.8'} - - on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - optimist@0.6.1: - resolution: {integrity: sha512-snN4O4TkigujZphWLN0E//nQmm7790RYaE53DdL7ZYwee2D8DDo9/EyYiKUfN3rneWUjhJnueija3G9I2i0h3g==} - - optionator@0.9.3: - resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} - engines: {node: '>= 0.8.0'} - - os-homedir@1.0.2: - resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} - engines: {node: '>=0.10.0'} - - os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} - p-defer@4.0.0: resolution: {integrity: sha512-Vb3QRvQ0Y5XnF40ZUWW7JfLogicVh/EnA5gBIvKDJoYpeI82+1E3AlB9yOcKFS0AhHrWVnAQO39fbR0G99IVEQ==} engines: {node: '>=12'} - p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-locate@3.0.0: - resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} - engines: {node: '>=6'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - p-queue@8.0.1: resolution: {integrity: sha512-NXzu9aQJTAzbBqOt2hwsR63ea7yvxJc0PwN/zobNAudYfb1B7R08SzB4TsLeSbUCuG467NhnoT0oO6w1qRO+BA==} engines: {node: '>=18'} @@ -1776,118 +1156,54 @@ packages: resolution: {integrity: sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==} engines: {node: '>=14.16'} - p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - - package-hash@3.0.0: - resolution: {integrity: sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==} - engines: {node: '>=6'} - - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - - parse-json@4.0.0: - resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} - engines: {node: '>=4'} - - parseqs@0.0.5: - resolution: {integrity: sha512-B3Nrjw2aL7aI4TDujOzfA4NsEc4u1lVcIRE0xesutH8kjeWF70uk+W5cBlIQx04zUH9NTBvuN36Y9xLRPK6Jjw==} - - parseuri@0.0.5: - resolution: {integrity: sha512-ijhdxJu6l5Ru12jF0JvzXVPvsC+VibqeaExlNoMhWN6VQ79PGjkmc7oA4W1lp00sFkNyj0fx6ivPLdV51/UMog==} - - parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - - path-exists@3.0.0: - resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} - engines: {node: '>=4'} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} - path-type@3.0.0: - resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} - engines: {node: '>=4'} + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - pathval@1.1.1: - resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - performance-now@2.1.0: - resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} - pify@3.0.0: - resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} - engines: {node: '>=4'} + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} - pify@4.0.1: - resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} - engines: {node: '>=6'} + progress-events@1.0.0: + resolution: {integrity: sha512-zIB6QDrSbPfRg+33FZalluFIowkbV5Xh1xSuetjG+rlC5he6u2dc6VQJ0TbMdlN3R1RHdpOqxEFMKTnQ+itUwA==} + engines: {node: '>=16.0.0', npm: '>=7.0.0'} - pkg-dir@3.0.0: - resolution: {integrity: sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==} - engines: {node: '>=6'} - - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - prettier-linter-helpers@1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} - - prettier@2.8.8: - resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} - engines: {node: '>=10.13.0'} - hasBin: true - - process@0.11.10: - resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} - engines: {node: '>= 0.6.0'} - - progress-events@1.0.0: - resolution: {integrity: sha512-zIB6QDrSbPfRg+33FZalluFIowkbV5Xh1xSuetjG+rlC5he6u2dc6VQJ0TbMdlN3R1RHdpOqxEFMKTnQ+itUwA==} - engines: {node: '>=16.0.0', npm: '>=7.0.0'} + progress-events@1.0.1: + resolution: {integrity: sha512-MOzLIwhpt64KIVN64h1MwdKWiyKFNc/S6BoYKPIVUHFg0/eIEyBulhWCgn678v/4c0ri3FdGuzXymNCv02MUIw==} protons-runtime@5.5.0: resolution: {integrity: sha512-EsALjF9QsrEk6gbCx3lmfHxVN0ah7nG3cY7GySD4xf4g8cr7g543zB88Foh897Sr1RQJ9yDCUsoT1i1H/cVUFA==} - pseudomap@1.0.2: - resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} - - psl@1.15.0: - resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} + protons-runtime@5.6.0: + resolution: {integrity: sha512-/Kde+sB9DsMFrddJT/UZWe6XqvL7SL5dbag/DBCElFKhkwDj7XKt53S+mzLyaDP5OqS0wXjV5SA572uWDaT0Hg==} punycode@1.3.2: resolution: {integrity: sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==} - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - pvtsutils@1.3.5: resolution: {integrity: sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA==} @@ -1895,62 +1211,11 @@ packages: resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==} engines: {node: '>=6.0.0'} - qjobs@1.2.0: - resolution: {integrity: sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==} - engines: {node: '>=0.9'} - - qs@6.11.0: - resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} - engines: {node: '>=0.6'} - - qs@6.5.3: - resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} - engines: {node: '>=0.6'} - querystring@0.2.0: resolution: {integrity: sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==} engines: {node: '>=0.4.x'} deprecated: The querystring API is considered Legacy. new code should use the URLSearchParams API instead. - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - - range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - - raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} - engines: {node: '>= 0.8'} - - read-pkg-up@4.0.0: - resolution: {integrity: sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==} - engines: {node: '>=6'} - - read-pkg@3.0.0: - resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} - engines: {node: '>=4'} - - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - - regexpp@3.2.0: - resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} - engines: {node: '>=8'} - - release-zalgo@1.0.0: - resolution: {integrity: sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==} - engines: {node: '>=4'} - - request@2.88.2: - resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} - engines: {node: '>= 6'} - deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 - require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -1959,85 +1224,25 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} - require-main-filename@2.0.0: - resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} - - requires-port@1.0.0: - resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} - - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - - resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} - hasBin: true - - reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - rfdc@1.3.0: - resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} - - rimraf@2.7.1: - resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true - - rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - deprecated: Rimraf versions prior to v4 are no longer supported + rollup@4.57.1: + resolution: {integrity: sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sax@1.2.1: resolution: {integrity: sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==} sax@1.3.0: resolution: {integrity: sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==} - semver@5.5.1: - resolution: {integrity: sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==} - hasBin: true - - semver@5.7.2: - resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} - hasBin: true - semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} - engines: {node: '>=10'} - hasBin: true - - serialize-javascript@6.0.0: - resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} - - set-blocking@2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - set-function-length@1.1.1: resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} engines: {node: '>= 0.4'} - setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2046,144 +1251,64 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - side-channel@1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} - - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - - socket.io-adapter@1.1.2: - resolution: {integrity: sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==} - - socket.io-client@2.1.1: - resolution: {integrity: sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==} - - socket.io-parser@3.2.0: - resolution: {integrity: sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==} - - socket.io@2.1.1: - resolution: {integrity: sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - spawn-wrap@1.4.3: - resolution: {integrity: sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==} - - spdx-correct@3.2.0: - resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} - - spdx-exceptions@2.3.0: - resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} - - spdx-expression-parse@3.0.1: - resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - - spdx-license-ids@3.0.16: - resolution: {integrity: sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==} - - sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} - sshpk@1.18.0: - resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} - hasBin: true - - statuses@1.5.0: - resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} - engines: {node: '>= 0.6'} - statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - streamroller@1.0.6: - resolution: {integrity: sha512-3QC47Mhv3/aZNFpDDVO44qQb9gwB9QggMEE0sQmkTAwBVYdBRWISdsywlkfm5II1Q5y/pmrHflti/IgmIzdDBg==} - engines: {node: '>=6.0'} - deprecated: 1.x is no longer supported. Please upgrade to 3.x or higher. + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} strict-event-emitter-types@2.0.0: resolution: {integrity: sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==} - string-width@3.1.0: - resolution: {integrity: sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==} - engines: {node: '>=6'} - string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} - strip-ansi@5.2.0: - resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} - engines: {node: '>=6'} + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} - - supports-color@6.1.0: - resolution: {integrity: sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==} - engines: {node: '>=6'} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} - - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - test-exclude@5.2.3: - resolution: {integrity: sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==} - engines: {node: '>=6'} - - text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + engines: {node: '>=12'} - tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} + supports-color@10.2.2: + resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} + engines: {node: '>=18'} - to-array@0.1.4: - resolution: {integrity: sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} - tough-cookie@2.5.0: - resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} - engines: {node: '>=0.8'} + tinyrainbow@3.0.3: + resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} + engines: {node: '>=14.0.0'} tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} @@ -2208,45 +1333,17 @@ packages: tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - tsutils@3.21.0: - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - - tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} - tunnel@0.0.6: resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} - tweetnacl@0.14.5: - resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} - - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - - type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - - type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} - - typescript@4.9.5: - resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} - engines: {node: '>=4.2.0'} + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} hasBin: true - uint8-varint@2.0.3: - resolution: {integrity: sha512-seXTM8ba4uuAMDgi3UHXPdDxCBKjWWZigW+F+1ESPhOZv9ekT1qmbdzYHLSNA+u+wHj10P55dQ41y2Qh7NOqiA==} + uint8-varint@2.0.4: + resolution: {integrity: sha512-FwpTa7ZGA/f/EssWAb5/YV6pHgVF1fViKdW8cWaEarjB8t7NyofSWBdOTyFPaGuUG4gx3v1O3PQ8etsiOs3lcw==} uint8arraylist@2.4.8: resolution: {integrity: sha512-vc1PlGOzglLF0eae1M8mLRTBivsvrGsdmJ5RbK3e+QRvRLOZfZhQROTwH/OfyF3+ZVUg9/8hE8bmKP2CvP9quQ==} @@ -2254,48 +1351,22 @@ packages: uint8arrays@5.1.0: resolution: {integrity: sha512-vA6nFepEmlSKkMBnLBaUMVvAC4G3CTmO58C12y4sq6WPDOR7mOFYOi7GlrQ4djeSbP6JG9Pv9tJDM97PedRSww==} - ultron@1.1.1: - resolution: {integrity: sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==} + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - - undici@5.28.2: - resolution: {integrity: sha512-wh1pHJHnUeQV5Xa8/kyQhO7WFa8M34l026L5P/+2TYiakvGy5Rdc8jWZVyG7ieht/0WgJLEd3kcU5gKx+6GC8w==} + undici@5.29.0: + resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==} engines: {node: '>=14.0'} universal-user-agent@6.0.1: resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==} - universalify@0.1.2: - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} - engines: {node: '>= 4.0.0'} - - unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - url@0.10.3: resolution: {integrity: sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==} - useragent@2.3.0: - resolution: {integrity: sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==} - util@0.12.5: resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} - utils-merge@1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} - - uuid@3.4.0: - resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} - deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. - hasBin: true - uuid@8.0.0: resolution: {integrity: sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==} hasBin: true @@ -2307,16 +1378,82 @@ packages: v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - validate-npm-package-license@3.0.4: - resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + vite@7.3.1: + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true - verror@1.10.0: - resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} - engines: {'0': node >=0.6.0} + vitest@4.0.18: + resolution: {integrity: sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.0.18 + '@vitest/browser-preview': 4.0.18 + '@vitest/browser-webdriverio': 4.0.18 + '@vitest/ui': 4.0.18 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true - void-elements@2.0.1: - resolution: {integrity: sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==} - engines: {node: '>=0.10.0'} + weald@1.1.1: + resolution: {integrity: sha512-PaEQShzMCz8J/AD2N3dJMc1hTZWkJeLKS2NMeiVkV5KDHwgZe7qXLEzyodsT/SODxWDdXJJqocuwf3kHzcXhSQ==} webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -2324,54 +1461,31 @@ packages: whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - which-module@2.0.1: - resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} - which-typed-array@1.1.13: resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} engines: {node: '>= 0.4'} - which@1.3.1: - resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} - hasBin: true - which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true - wordwrap@0.0.3: - resolution: {integrity: sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw==} - engines: {node: '>=0.4.0'} - - workerpool@6.2.1: - resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} - - wrap-ansi@5.1.0: - resolution: {integrity: sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==} - engines: {node: '>=6'} + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - write-file-atomic@2.4.3: - resolution: {integrity: sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==} - - ws@3.3.3: - resolution: {integrity: sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - xml2js@0.5.0: resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} engines: {node: '>=4.0.0'} @@ -2380,116 +1494,76 @@ packages: resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} engines: {node: '>=4.0'} - xmlhttprequest-ssl@1.5.5: - resolution: {integrity: sha512-/bFPLUgJrfGUL10AIv4Y7/CUt6so9CLtB/oFxQSHseSDNNCdC6vwwKEqwLN6wNPBg9YWXAiMu8jkf6RPRS/75Q==} - engines: {node: '>=0.4.0'} - - y18n@4.0.3: - resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} - y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} - yallist@2.1.2: - resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} - - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - - yamlparser@0.0.2: - resolution: {integrity: sha512-Cou9FCGblEENtn1/8La5wkDM/ISMh2bzu5Wh7dYzCzA0o9jD4YGyLkUJxe84oPBGoB92f+Oy4ZjVhA8S0C2wlQ==} - - yargs-parser@13.1.2: - resolution: {integrity: sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==} - - yargs-parser@20.2.4: - resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} - engines: {node: '>=10'} - - yargs-parser@20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} + yaml@2.8.2: + resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} + engines: {node: '>= 14.6'} + hasBin: true yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} - yargs-unparser@2.0.0: - resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} - engines: {node: '>=10'} - - yargs@13.3.2: - resolution: {integrity: sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==} - - yargs@16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} - yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} - yeast@0.1.2: - resolution: {integrity: sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg==} - yn@3.1.1: resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} engines: {node: '>=6'} - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} + yoctocolors@2.1.2: + resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} + engines: {node: '>=18'} snapshots: - '@aashutoshrathi/word-wrap@1.2.6': {} - - '@actions/cache@1.0.11': + '@actions/cache@4.1.0': dependencies: - '@actions/core': 1.10.1 + '@actions/core': 1.11.1 '@actions/exec': 1.1.1 '@actions/glob': 0.1.2 - '@actions/http-client': 1.0.11 + '@actions/http-client': 2.2.0 '@actions/io': 1.1.3 + '@azure/abort-controller': 1.1.0 '@azure/ms-rest-js': 2.7.0 '@azure/storage-blob': 12.17.0 + '@protobuf-ts/runtime-rpc': 2.11.1 semver: 6.3.1 - uuid: 3.4.0 transitivePeerDependencies: - encoding - '@actions/core@1.10.1': + '@actions/core@1.11.1': dependencies: + '@actions/exec': 1.1.1 '@actions/http-client': 2.2.0 - uuid: 8.3.2 '@actions/exec@1.1.1': dependencies: '@actions/io': 1.1.3 - '@actions/github@5.1.1': + '@actions/github@6.0.1': dependencies: '@actions/http-client': 2.2.0 - '@octokit/core': 3.6.0 - '@octokit/plugin-paginate-rest': 2.21.3(@octokit/core@3.6.0) - '@octokit/plugin-rest-endpoint-methods': 5.16.2(@octokit/core@3.6.0) - transitivePeerDependencies: - - encoding + '@octokit/core': 5.2.2 + '@octokit/plugin-paginate-rest': 9.2.2(@octokit/core@5.2.2) + '@octokit/plugin-rest-endpoint-methods': 10.4.1(@octokit/core@5.2.2) + '@octokit/request': 8.4.1 + '@octokit/request-error': 5.1.1 + undici: 5.29.0 '@actions/glob@0.1.2': dependencies: - '@actions/core': 1.10.1 + '@actions/core': 1.11.1 minimatch: 3.1.2 - '@actions/http-client@1.0.11': - dependencies: - tunnel: 0.0.6 - '@actions/http-client@2.2.0': dependencies: tunnel: 0.0.6 - undici: 5.28.2 + undici: 5.29.0 '@actions/io@1.1.3': {} @@ -2573,84 +1647,63 @@ snapshots: transitivePeerDependencies: - encoding - '@babel/code-frame@7.23.5': - dependencies: - '@babel/highlight': 7.23.4 - chalk: 2.4.2 - - '@babel/generator@7.23.6': - dependencies: - '@babel/types': 7.23.6 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.20 - jsesc: 2.5.2 - - '@babel/helper-environment-visitor@7.22.20': {} - - '@babel/helper-function-name@7.23.0': - dependencies: - '@babel/template': 7.22.15 - '@babel/types': 7.23.6 + '@biomejs/biome@2.3.14': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 2.3.14 + '@biomejs/cli-darwin-x64': 2.3.14 + '@biomejs/cli-linux-arm64': 2.3.14 + '@biomejs/cli-linux-arm64-musl': 2.3.14 + '@biomejs/cli-linux-x64': 2.3.14 + '@biomejs/cli-linux-x64-musl': 2.3.14 + '@biomejs/cli-win32-arm64': 2.3.14 + '@biomejs/cli-win32-x64': 2.3.14 + + '@biomejs/cli-darwin-arm64@2.3.14': + optional: true - '@babel/helper-hoist-variables@7.22.5': - dependencies: - '@babel/types': 7.23.6 + '@biomejs/cli-darwin-x64@2.3.14': + optional: true - '@babel/helper-split-export-declaration@7.22.6': - dependencies: - '@babel/types': 7.23.6 + '@biomejs/cli-linux-arm64-musl@2.3.14': + optional: true - '@babel/helper-string-parser@7.23.4': {} + '@biomejs/cli-linux-arm64@2.3.14': + optional: true - '@babel/helper-validator-identifier@7.22.20': {} + '@biomejs/cli-linux-x64-musl@2.3.14': + optional: true - '@babel/highlight@7.23.4': - dependencies: - '@babel/helper-validator-identifier': 7.22.20 - chalk: 2.4.2 - js-tokens: 4.0.0 + '@biomejs/cli-linux-x64@2.3.14': + optional: true - '@babel/parser@7.23.6': - dependencies: - '@babel/types': 7.23.6 + '@biomejs/cli-win32-arm64@2.3.14': + optional: true - '@babel/template@7.22.15': - dependencies: - '@babel/code-frame': 7.23.5 - '@babel/parser': 7.23.6 - '@babel/types': 7.23.6 + '@biomejs/cli-win32-x64@2.3.14': + optional: true - '@babel/traverse@7.23.7': + '@chainsafe/benchmark@2.0.1': dependencies: - '@babel/code-frame': 7.23.5 - '@babel/generator': 7.23.6 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.6 - '@babel/types': 7.23.6 - debug: 4.3.4(supports-color@8.1.1) - globals: 11.12.0 + '@actions/cache': 4.1.0 + '@actions/github': 6.0.1 + '@vitest/runner': 2.1.9 + ajv: 8.17.1 + aws-sdk: 2.1533.0 + cli-table3: 0.6.5 + csv-parse: 5.6.0 + csv-stringify: 6.6.0 + debug: 4.4.3 + glob: 10.5.0 + log-symbols: 7.0.1 + yaml: 2.8.2 + yargs: 17.7.2 transitivePeerDependencies: + - encoding - supports-color - '@babel/types@7.23.6': - dependencies: - '@babel/helper-string-parser': 7.23.4 - '@babel/helper-validator-identifier': 7.22.20 - to-fast-properties: 2.0.0 - - '@chainsafe/eslint-plugin-node@11.2.3(eslint@8.56.0)': + '@chainsafe/biomejs-config@1.0.0(@biomejs/biome@2.3.14)': dependencies: - eslint: 8.56.0 - eslint-plugin-es: 4.1.0(eslint@8.56.0) - eslint-utils: 2.1.0 - ignore: 5.3.0 - is-core-module: 2.13.1 - minimatch: 3.1.2 - resolve: 1.22.8 - semver: 6.3.1 + '@biomejs/biome': 2.3.14 '@chainsafe/is-ip@2.0.2': {} @@ -2658,78 +1711,109 @@ snapshots: dependencies: '@chainsafe/is-ip': 2.0.2 + '@colors/colors@1.5.0': + optional: true + '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 - '@dapplion/benchmark@0.2.4(mocha@10.2.0)': - dependencies: - '@actions/cache': 1.0.11 - '@actions/github': 5.1.1 - ajv: 8.12.0 - aws-sdk: 2.1533.0 - csv-parse: 4.16.3 - csv-stringify: 5.6.5 - mocha: 10.2.0 - yargs: 17.7.2 - transitivePeerDependencies: - - encoding + '@esbuild/aix-ppc64@0.27.3': + optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@8.56.0)': - dependencies: - eslint: 8.56.0 - eslint-visitor-keys: 3.4.3 + '@esbuild/android-arm64@0.27.3': + optional: true - '@eslint-community/regexpp@4.10.0': {} + '@esbuild/android-arm@0.27.3': + optional: true - '@eslint/eslintrc@2.1.4': - dependencies: - ajv: 6.12.6 - debug: 4.3.4(supports-color@8.1.1) - espree: 9.6.1 - globals: 13.24.0 - ignore: 5.3.0 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color + '@esbuild/android-x64@0.27.3': + optional: true - '@eslint/js@8.56.0': {} + '@esbuild/darwin-arm64@0.27.3': + optional: true - '@ethereumjs/rlp@5.0.2': {} + '@esbuild/darwin-x64@0.27.3': + optional: true - '@fastify/busboy@2.1.0': {} + '@esbuild/freebsd-arm64@0.27.3': + optional: true - '@humanwhocodes/config-array@0.11.14': - dependencies: - '@humanwhocodes/object-schema': 2.0.2 - debug: 4.3.4(supports-color@8.1.1) - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color + '@esbuild/freebsd-x64@0.27.3': + optional: true - '@humanwhocodes/module-importer@1.0.1': {} + '@esbuild/linux-arm64@0.27.3': + optional: true - '@humanwhocodes/object-schema@2.0.2': {} + '@esbuild/linux-arm@0.27.3': + optional: true - '@jridgewell/gen-mapping@0.3.3': - dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.20 + '@esbuild/linux-ia32@0.27.3': + optional: true - '@jridgewell/resolve-uri@3.1.1': {} + '@esbuild/linux-loong64@0.27.3': + optional: true - '@jridgewell/set-array@1.1.2': {} + '@esbuild/linux-mips64el@0.27.3': + optional: true - '@jridgewell/sourcemap-codec@1.4.15': {} + '@esbuild/linux-ppc64@0.27.3': + optional: true + + '@esbuild/linux-riscv64@0.27.3': + optional: true + + '@esbuild/linux-s390x@0.27.3': + optional: true + + '@esbuild/linux-x64@0.27.3': + optional: true + + '@esbuild/netbsd-arm64@0.27.3': + optional: true + + '@esbuild/netbsd-x64@0.27.3': + optional: true + + '@esbuild/openbsd-arm64@0.27.3': + optional: true + + '@esbuild/openbsd-x64@0.27.3': + optional: true - '@jridgewell/trace-mapping@0.3.20': + '@esbuild/openharmony-arm64@0.27.3': + optional: true + + '@esbuild/sunos-x64@0.27.3': + optional: true + + '@esbuild/win32-arm64@0.27.3': + optional: true + + '@esbuild/win32-ia32@0.27.3': + optional: true + + '@esbuild/win32-x64@0.27.3': + optional: true + + '@ethereumjs/rlp@10.1.1': {} + + '@fastify/busboy@2.1.0': {} + + '@isaacs/cliui@8.0.2': dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.2 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jridgewell/resolve-uri@3.1.1': {} + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} '@jridgewell/trace-mapping@0.3.9': dependencies: @@ -2742,13 +1826,23 @@ snapshots: dependencies: '@libp2p/interface': 2.0.1 '@noble/curves': 1.6.0 - '@noble/hashes': 1.7.0 + '@noble/hashes': 1.8.0 asn1js: 3.0.5 multiformats: 13.2.2 protons-runtime: 5.5.0 uint8arraylist: 2.4.8 uint8arrays: 5.1.0 + '@libp2p/crypto@5.1.13': + dependencies: + '@libp2p/interface': 3.1.0 + '@noble/curves': 2.0.1 + '@noble/hashes': 2.0.1 + multiformats: 13.4.2 + protons-runtime: 5.6.0 + uint8arraylist: 2.4.8 + uint8arrays: 5.1.0 + '@libp2p/interface@2.0.1': dependencies: '@multiformats/multiaddr': 12.3.1 @@ -2758,11 +1852,20 @@ snapshots: progress-events: 1.0.0 uint8arraylist: 2.4.8 - '@libp2p/peer-id@5.0.1': + '@libp2p/interface@3.1.0': dependencies: - '@libp2p/crypto': 5.0.1 - '@libp2p/interface': 2.0.1 - multiformats: 13.2.2 + '@multiformats/dns': 1.0.6 + '@multiformats/multiaddr': 13.0.1 + main-event: 1.0.1 + multiformats: 13.4.2 + progress-events: 1.0.1 + uint8arraylist: 2.4.8 + + '@libp2p/peer-id@6.0.4': + dependencies: + '@libp2p/crypto': 5.1.13 + '@libp2p/interface': 3.1.0 + multiformats: 13.4.2 uint8arrays: 5.1.0 '@multiformats/dns@1.0.6': @@ -2781,117 +1884,198 @@ snapshots: '@chainsafe/netmask': 2.0.0 '@multiformats/dns': 1.0.6 multiformats: 13.2.2 - uint8-varint: 2.0.3 + uint8-varint: 2.0.4 uint8arrays: 5.1.0 - '@noble/curves@1.4.2': + '@multiformats/multiaddr@13.0.1': dependencies: - '@noble/hashes': 1.4.0 + '@chainsafe/is-ip': 2.0.2 + multiformats: 13.2.2 + uint8-varint: 2.0.4 + uint8arrays: 5.1.0 + + '@noble/ciphers@1.3.0': {} '@noble/curves@1.6.0': dependencies: '@noble/hashes': 1.5.0 - '@noble/hashes@1.4.0': {} + '@noble/curves@1.9.0': + dependencies: + '@noble/hashes': 1.8.0 - '@noble/hashes@1.5.0': {} + '@noble/curves@2.0.1': + dependencies: + '@noble/hashes': 2.0.1 - '@noble/hashes@1.7.0': {} + '@noble/hashes@1.5.0': {} - '@noble/secp256k1@2.2.3': {} + '@noble/hashes@1.8.0': {} - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 + '@noble/hashes@2.0.1': {} - '@nodelib/fs.stat@2.0.5': {} + '@noble/secp256k1@3.0.0': {} - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.16.0 + '@octokit/auth-token@4.0.0': {} - '@octokit/auth-token@2.5.0': + '@octokit/core@5.2.2': dependencies: - '@octokit/types': 6.41.0 - - '@octokit/core@3.6.0': - dependencies: - '@octokit/auth-token': 2.5.0 - '@octokit/graphql': 4.8.0 - '@octokit/request': 5.6.3 - '@octokit/request-error': 2.1.0 - '@octokit/types': 6.41.0 + '@octokit/auth-token': 4.0.0 + '@octokit/graphql': 7.1.1 + '@octokit/request': 8.4.1 + '@octokit/request-error': 5.1.1 + '@octokit/types': 13.10.0 before-after-hook: 2.2.3 universal-user-agent: 6.0.1 - transitivePeerDependencies: - - encoding - '@octokit/endpoint@6.0.12': + '@octokit/endpoint@9.0.6': dependencies: - '@octokit/types': 6.41.0 - is-plain-object: 5.0.0 + '@octokit/types': 13.10.0 universal-user-agent: 6.0.1 - '@octokit/graphql@4.8.0': + '@octokit/graphql@7.1.1': dependencies: - '@octokit/request': 5.6.3 - '@octokit/types': 6.41.0 + '@octokit/request': 8.4.1 + '@octokit/types': 13.10.0 universal-user-agent: 6.0.1 - transitivePeerDependencies: - - encoding - '@octokit/openapi-types@12.11.0': {} + '@octokit/openapi-types@20.0.0': {} + + '@octokit/openapi-types@24.2.0': {} - '@octokit/plugin-paginate-rest@2.21.3(@octokit/core@3.6.0)': + '@octokit/plugin-paginate-rest@9.2.2(@octokit/core@5.2.2)': dependencies: - '@octokit/core': 3.6.0 - '@octokit/types': 6.41.0 + '@octokit/core': 5.2.2 + '@octokit/types': 12.6.0 - '@octokit/plugin-rest-endpoint-methods@5.16.2(@octokit/core@3.6.0)': + '@octokit/plugin-rest-endpoint-methods@10.4.1(@octokit/core@5.2.2)': dependencies: - '@octokit/core': 3.6.0 - '@octokit/types': 6.41.0 - deprecation: 2.3.1 + '@octokit/core': 5.2.2 + '@octokit/types': 12.6.0 - '@octokit/request-error@2.1.0': + '@octokit/request-error@5.1.1': dependencies: - '@octokit/types': 6.41.0 + '@octokit/types': 13.10.0 deprecation: 2.3.1 once: 1.4.0 - '@octokit/request@5.6.3': + '@octokit/request@8.4.1': dependencies: - '@octokit/endpoint': 6.0.12 - '@octokit/request-error': 2.1.0 - '@octokit/types': 6.41.0 - is-plain-object: 5.0.0 - node-fetch: 2.7.0 + '@octokit/endpoint': 9.0.6 + '@octokit/request-error': 5.1.1 + '@octokit/types': 13.10.0 universal-user-agent: 6.0.1 - transitivePeerDependencies: - - encoding - '@octokit/types@6.41.0': + '@octokit/types@12.6.0': dependencies: - '@octokit/openapi-types': 12.11.0 + '@octokit/openapi-types': 20.0.0 + + '@octokit/types@13.10.0': + dependencies: + '@octokit/openapi-types': 24.2.0 '@opentelemetry/api@1.7.0': {} - '@scure/base@1.1.8': {} + '@pkgjs/parseargs@0.11.0': + optional: true + + '@protobuf-ts/runtime-rpc@2.11.1': + dependencies: + '@protobuf-ts/runtime': 2.11.1 + + '@protobuf-ts/runtime@2.11.1': {} + + '@rollup/rollup-android-arm-eabi@4.57.1': + optional: true + + '@rollup/rollup-android-arm64@4.57.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.57.1': + optional: true + + '@rollup/rollup-darwin-x64@4.57.1': + optional: true + + '@rollup/rollup-freebsd-arm64@4.57.1': + optional: true + + '@rollup/rollup-freebsd-x64@4.57.1': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.57.1': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.57.1': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.57.1': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.57.1': + optional: true - '@scure/base@1.2.1': {} + '@rollup/rollup-linux-loong64-gnu@4.57.1': + optional: true - '@scure/bip32@1.4.0': + '@rollup/rollup-linux-loong64-musl@4.57.1': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.57.1': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.57.1': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.57.1': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.57.1': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.57.1': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.57.1': + optional: true + + '@rollup/rollup-linux-x64-musl@4.57.1': + optional: true + + '@rollup/rollup-openbsd-x64@4.57.1': + optional: true + + '@rollup/rollup-openharmony-arm64@4.57.1': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.57.1': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.57.1': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.57.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.57.1': + optional: true + + '@scure/base@1.2.6': {} + + '@scure/base@2.0.0': {} + + '@scure/bip32@1.7.0': dependencies: - '@noble/curves': 1.4.2 - '@noble/hashes': 1.4.0 - '@scure/base': 1.1.8 + '@noble/curves': 1.9.0 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 - '@scure/bip39@1.3.0': + '@scure/bip39@1.6.0': dependencies: - '@noble/hashes': 1.4.0 - '@scure/base': 1.1.8 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@standard-schema/spec@1.1.0': {} '@tsconfig/node10@1.0.9': {} @@ -2901,223 +2085,120 @@ snapshots: '@tsconfig/node16@1.0.4': {} - '@types/bn.js@4.11.6': + '@types/chai@5.2.3': dependencies: - '@types/node': 20.11.0 + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 - '@types/chai@4.3.11': {} - - '@types/debug@4.1.12': - dependencies: - '@types/ms': 0.7.34 + '@types/deep-eql@4.0.2': {} '@types/dns-packet@5.6.5': dependencies: - '@types/node': 20.11.0 - - '@types/eslint@6.8.1': - dependencies: - '@types/estree': 1.0.5 - '@types/json-schema': 7.0.15 - - '@types/estree@1.0.5': {} + '@types/node': 24.10.12 - '@types/json-schema@7.0.15': {} - - '@types/mocha@8.2.3': {} - - '@types/ms@0.7.34': {} + '@types/estree@1.0.8': {} '@types/node-fetch@2.6.10': dependencies: - '@types/node': 20.11.0 + '@types/node': 24.10.12 form-data: 4.0.0 - '@types/node@20.11.0': + '@types/node@24.10.12': dependencies: - undici-types: 5.26.5 - - '@types/semver@7.5.6': {} + undici-types: 7.16.0 '@types/tunnel@0.0.3': dependencies: - '@types/node': 20.11.0 - - '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@4.9.5))(eslint@8.56.0)(typescript@4.9.5)': - dependencies: - '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@4.9.5) - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/type-utils': 5.62.0(eslint@8.56.0)(typescript@4.9.5) - '@typescript-eslint/utils': 5.62.0(eslint@8.56.0)(typescript@4.9.5) - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.56.0 - graphemer: 1.4.0 - ignore: 5.3.0 - natural-compare-lite: 1.4.0 - semver: 7.5.4 - tsutils: 3.21.0(typescript@4.9.5) - optionalDependencies: - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color + '@types/node': 24.10.12 - '@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@4.9.5)': + '@vitest/expect@4.0.18': dependencies: - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.56.0 - optionalDependencies: - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 + chai: 6.2.2 + tinyrainbow: 3.0.3 - '@typescript-eslint/scope-manager@5.62.0': + '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@24.10.12)(yaml@2.8.2))': dependencies: - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/visitor-keys': 5.62.0 + '@vitest/spy': 4.0.18 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 7.3.1(@types/node@24.10.12)(yaml@2.8.2) - '@typescript-eslint/type-utils@5.62.0(eslint@8.56.0)(typescript@4.9.5)': + '@vitest/pretty-format@2.1.9': dependencies: - '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) - '@typescript-eslint/utils': 5.62.0(eslint@8.56.0)(typescript@4.9.5) - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.56.0 - tsutils: 3.21.0(typescript@4.9.5) - optionalDependencies: - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color + tinyrainbow: 1.2.0 - '@typescript-eslint/types@5.62.0': {} + '@vitest/pretty-format@4.0.18': + dependencies: + tinyrainbow: 3.0.3 - '@typescript-eslint/typescript-estree@5.62.0(typescript@4.9.5)': + '@vitest/runner@2.1.9': dependencies: - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.3.4(supports-color@8.1.1) - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.5.4 - tsutils: 3.21.0(typescript@4.9.5) - optionalDependencies: - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color + '@vitest/utils': 2.1.9 + pathe: 1.1.2 - '@typescript-eslint/utils@5.62.0(eslint@8.56.0)(typescript@4.9.5)': - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) - '@types/json-schema': 7.0.15 - '@types/semver': 7.5.6 - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) - eslint: 8.56.0 - eslint-scope: 5.1.1 - semver: 7.5.4 - transitivePeerDependencies: - - supports-color - - typescript + '@vitest/runner@4.0.18': + dependencies: + '@vitest/utils': 4.0.18 + pathe: 2.0.3 - '@typescript-eslint/visitor-keys@5.62.0': + '@vitest/snapshot@4.0.18': dependencies: - '@typescript-eslint/types': 5.62.0 - eslint-visitor-keys: 3.4.3 + '@vitest/pretty-format': 4.0.18 + magic-string: 0.30.21 + pathe: 2.0.3 - '@ungap/structured-clone@1.2.0': {} + '@vitest/spy@4.0.18': {} - abort-controller@3.0.0: + '@vitest/utils@2.1.9': dependencies: - event-target-shim: 5.0.1 + '@vitest/pretty-format': 2.1.9 + loupe: 3.2.1 + tinyrainbow: 1.2.0 - accepts@1.3.8: + '@vitest/utils@4.0.18': dependencies: - mime-types: 2.1.35 - negotiator: 0.6.3 + '@vitest/pretty-format': 4.0.18 + tinyrainbow: 3.0.3 - acorn-jsx@5.3.2(acorn@8.11.3): + abort-controller@3.0.0: dependencies: - acorn: 8.11.3 + event-target-shim: 5.0.1 acorn-walk@8.3.2: {} acorn@8.11.3: {} - after@0.8.2: {} - - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - ajv@8.12.0: + ajv@8.17.1: dependencies: fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - uri-js: 4.4.1 - - ansi-colors@4.1.1: {} - - ansi-regex@4.1.1: {} ansi-regex@5.0.1: {} - ansi-styles@3.2.1: - dependencies: - color-convert: 1.9.3 + ansi-regex@6.2.2: {} ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - - append-transform@1.0.0: - dependencies: - default-require-extensions: 2.0.0 - - archy@1.0.0: {} + ansi-styles@6.2.3: {} arg@4.1.3: {} - argparse@1.0.10: - dependencies: - sprintf-js: 1.0.3 - - argparse@2.0.1: {} - - array-union@2.1.0: {} - - arraybuffer.slice@0.0.7: {} - - asn1@0.2.6: - dependencies: - safer-buffer: 2.1.2 - asn1js@3.0.5: dependencies: pvtsutils: 1.3.5 pvutils: 1.1.3 tslib: 2.6.2 - assert-plus@1.0.0: {} - - assertion-error@1.1.0: {} - - async-limiter@1.0.1: {} - - async@2.6.4: - dependencies: - lodash: 4.17.21 + assertion-error@2.0.1: {} asynckit@0.4.0: {} @@ -3136,53 +2217,12 @@ snapshots: uuid: 8.0.0 xml2js: 0.5.0 - aws-sign2@0.7.0: {} - - aws4@1.13.2: {} - - backo2@1.0.2: {} - balanced-match@1.0.2: {} - base64-arraybuffer@0.1.5: {} - base64-js@1.5.1: {} - base64id@1.0.0: {} - - bcrypt-pbkdf@1.0.2: - dependencies: - tweetnacl: 0.14.5 - before-after-hook@2.2.3: {} - better-assert@1.0.2: - dependencies: - callsite: 1.0.0 - - binary-extensions@2.2.0: {} - - blob@0.0.5: {} - - bluebird@3.7.2: {} - - body-parser@1.20.2: - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.11.0 - raw-body: 2.5.2 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -3192,21 +2232,6 @@ snapshots: dependencies: balanced-match: 1.0.2 - braces@3.0.2: - dependencies: - fill-range: 7.0.1 - - browser-stdout@1.3.1: {} - - buffer-alloc-unsafe@1.1.0: {} - - buffer-alloc@1.2.0: - dependencies: - buffer-alloc-unsafe: 1.1.0 - buffer-fill: 1.0.0 - - buffer-fill@1.0.0: {} - buffer@4.9.2: dependencies: base64-js: 1.5.1 @@ -3218,79 +2243,19 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 - bytes@3.1.2: {} - - caching-transform@3.0.2: - dependencies: - hasha: 3.0.0 - make-dir: 2.1.0 - package-hash: 3.0.0 - write-file-atomic: 2.4.3 - call-bind@1.0.5: dependencies: function-bind: 1.1.2 get-intrinsic: 1.2.2 set-function-length: 1.1.1 - callsite@1.0.0: {} - - callsites@3.1.0: {} - - camelcase@5.3.1: {} - - camelcase@6.3.0: {} - - caseless@0.12.0: {} - - chai@4.4.0: - dependencies: - assertion-error: 1.1.0 - check-error: 1.0.3 - deep-eql: 4.1.3 - get-func-name: 2.0.2 - loupe: 2.3.7 - pathval: 1.1.1 - type-detect: 4.0.8 - - chalk@2.4.2: - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - check-error@1.0.3: - dependencies: - get-func-name: 2.0.2 - - chokidar@3.5.3: - dependencies: - anymatch: 3.1.3 - braces: 3.0.2 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - - cliui@5.0.0: - dependencies: - string-width: 3.1.0 - strip-ansi: 5.2.0 - wrap-ansi: 5.1.0 + chai@6.2.2: {} - cliui@7.0.4: + cli-table3@0.6.5: dependencies: string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 + optionalDependencies: + '@colors/colors': 1.5.0 cliui@8.0.1: dependencies: @@ -3298,116 +2263,34 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 - color-convert@1.9.3: - dependencies: - color-name: 1.1.3 - color-convert@2.0.1: dependencies: color-name: 1.1.4 - color-name@1.1.3: {} - color-name@1.1.4: {} - colors@1.4.0: {} - combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 - commondir@1.0.1: {} - - component-bind@1.0.0: {} - - component-emitter@1.2.1: {} - - component-inherit@0.0.3: {} - concat-map@0.0.1: {} - connect@3.7.0: - dependencies: - debug: 2.6.9 - finalhandler: 1.1.2 - parseurl: 1.3.3 - utils-merge: 1.0.1 - transitivePeerDependencies: - - supports-color - - content-type@1.0.5: {} - - convert-source-map@1.9.0: {} - - cookie@0.3.1: {} - - core-util-is@1.0.2: {} - - cp-file@6.2.0: - dependencies: - graceful-fs: 4.2.11 - make-dir: 2.1.0 - nested-error-stacks: 2.1.1 - pify: 4.0.1 - safe-buffer: 5.2.1 - create-require@1.1.1: {} - cross-spawn@4.0.2: - dependencies: - lru-cache: 4.1.5 - which: 1.3.1 - - cross-spawn@7.0.3: + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 - csv-parse@4.16.3: {} + csv-parse@5.6.0: {} - csv-stringify@5.6.5: {} + csv-stringify@6.6.0: {} - custom-event@1.0.1: {} - - dashdash@1.14.1: - dependencies: - assert-plus: 1.0.0 - - date-format@2.1.0: {} - - debug@2.6.9: - dependencies: - ms: 2.0.0 - - debug@3.1.0: - dependencies: - ms: 2.0.0 - - debug@3.2.7: + debug@4.4.3: dependencies: ms: 2.1.3 - debug@4.3.4(supports-color@8.1.1): - dependencies: - ms: 2.1.2 - optionalDependencies: - supports-color: 8.1.1 - - decamelize@1.2.0: {} - - decamelize@4.0.0: {} - - deep-eql@4.1.3: - dependencies: - type-detect: 4.0.8 - - deep-is@0.1.4: {} - - default-require-extensions@2.0.0: - dependencies: - strip-bom: 3.0.0 - define-data-property@1.1.1: dependencies: get-intrinsic: 1.2.2 @@ -3416,306 +2299,91 @@ snapshots: delayed-stream@1.0.0: {} - depd@2.0.0: {} - deprecation@2.3.1: {} - destroy@1.2.0: {} - - di@0.0.1: {} - diff@4.0.2: {} - diff@5.0.0: {} - - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - dns-packet@5.6.1: dependencies: '@leichtgewicht/ip-codec': 2.0.5 - doctrine@3.0.0: - dependencies: - esutils: 2.0.3 - - dom-serialize@2.2.1: - dependencies: - custom-event: 1.0.1 - ent: 2.2.0 - extend: 3.0.2 - void-elements: 2.0.1 - - ecc-jsbn@0.1.2: - dependencies: - jsbn: 0.1.1 - safer-buffer: 2.1.2 - - ee-first@1.1.1: {} - - emoji-regex@7.0.3: {} + eastasianwidth@0.2.0: {} emoji-regex@8.0.0: {} - encodeurl@1.0.2: {} - - engine.io-client@3.2.1: - dependencies: - component-emitter: 1.2.1 - component-inherit: 0.0.3 - debug: 3.1.0 - engine.io-parser: 2.1.3 - has-cors: 1.1.0 - indexof: 0.0.1 - parseqs: 0.0.5 - parseuri: 0.0.5 - ws: 3.3.3 - xmlhttprequest-ssl: 1.5.5 - yeast: 0.1.2 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate + emoji-regex@9.2.2: {} - engine.io-parser@2.1.3: - dependencies: - after: 0.8.2 - arraybuffer.slice: 0.0.7 - base64-arraybuffer: 0.1.5 - blob: 0.0.5 - has-binary2: 1.0.3 + es-module-lexer@1.7.0: {} - engine.io@3.2.1: - dependencies: - accepts: 1.3.8 - base64id: 1.0.0 - cookie: 0.3.1 - debug: 3.1.0 - engine.io-parser: 2.1.3 - ws: 3.3.3 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - ent@2.2.0: {} - - error-ex@1.3.2: - dependencies: - is-arrayish: 0.2.1 - - es6-error@4.1.1: {} + esbuild@0.27.3: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.3 + '@esbuild/android-arm': 0.27.3 + '@esbuild/android-arm64': 0.27.3 + '@esbuild/android-x64': 0.27.3 + '@esbuild/darwin-arm64': 0.27.3 + '@esbuild/darwin-x64': 0.27.3 + '@esbuild/freebsd-arm64': 0.27.3 + '@esbuild/freebsd-x64': 0.27.3 + '@esbuild/linux-arm': 0.27.3 + '@esbuild/linux-arm64': 0.27.3 + '@esbuild/linux-ia32': 0.27.3 + '@esbuild/linux-loong64': 0.27.3 + '@esbuild/linux-mips64el': 0.27.3 + '@esbuild/linux-ppc64': 0.27.3 + '@esbuild/linux-riscv64': 0.27.3 + '@esbuild/linux-s390x': 0.27.3 + '@esbuild/linux-x64': 0.27.3 + '@esbuild/netbsd-arm64': 0.27.3 + '@esbuild/netbsd-x64': 0.27.3 + '@esbuild/openbsd-arm64': 0.27.3 + '@esbuild/openbsd-x64': 0.27.3 + '@esbuild/openharmony-arm64': 0.27.3 + '@esbuild/sunos-x64': 0.27.3 + '@esbuild/win32-arm64': 0.27.3 + '@esbuild/win32-ia32': 0.27.3 + '@esbuild/win32-x64': 0.27.3 escalade@3.1.1: {} - escape-html@1.0.3: {} - - escape-string-regexp@1.0.5: {} - - escape-string-regexp@4.0.0: {} - - eslint-plugin-es@4.1.0(eslint@8.56.0): - dependencies: - eslint: 8.56.0 - eslint-utils: 2.1.0 - regexpp: 3.2.0 - - eslint-plugin-prettier@4.2.1(eslint@8.56.0)(prettier@2.8.8): - dependencies: - eslint: 8.56.0 - prettier: 2.8.8 - prettier-linter-helpers: 1.0.0 - - eslint-scope@5.1.1: - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - - eslint-scope@7.2.2: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-utils@2.1.0: - dependencies: - eslint-visitor-keys: 1.3.0 - - eslint-visitor-keys@1.3.0: {} - - eslint-visitor-keys@3.4.3: {} - - eslint@8.56.0: - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) - '@eslint-community/regexpp': 4.10.0 - '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.56.0 - '@humanwhocodes/config-array': 0.11.14 - '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.2.0 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4(supports-color@8.1.1) - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.5.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.24.0 - graphemer: 1.4.0 - ignore: 5.3.0 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.0 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.3 - strip-ansi: 6.0.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - - espree@9.6.1: - dependencies: - acorn: 8.11.3 - acorn-jsx: 5.3.2(acorn@8.11.3) - eslint-visitor-keys: 3.4.3 - - esprima@4.0.1: {} - - esquery@1.5.0: + estree-walker@3.0.3: dependencies: - estraverse: 5.3.0 + '@types/estree': 1.0.8 - esrecurse@4.3.0: + ethereum-cryptography@3.2.0: dependencies: - estraverse: 5.3.0 - - estraverse@4.3.0: {} - - estraverse@5.3.0: {} - - esutils@2.0.3: {} - - ethereum-cryptography@2.2.1: - dependencies: - '@noble/curves': 1.4.2 - '@noble/hashes': 1.4.0 - '@scure/bip32': 1.4.0 - '@scure/bip39': 1.3.0 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.0 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 event-target-shim@5.0.1: {} - eventemitter3@4.0.7: {} - eventemitter3@5.0.1: {} events@1.1.1: {} events@3.3.0: {} - extend@3.0.2: {} - - extsprintf@1.3.0: {} + expect-type@1.3.0: {} fast-deep-equal@3.1.3: {} - fast-diff@1.3.0: {} - - fast-glob@3.3.2: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fastq@1.16.0: - dependencies: - reusify: 1.0.4 - - file-entry-cache@6.0.1: - dependencies: - flat-cache: 3.2.0 - - fill-range@7.0.1: - dependencies: - to-regex-range: 5.0.1 - - finalhandler@1.1.2: - dependencies: - debug: 2.6.9 - encodeurl: 1.0.2 - escape-html: 1.0.3 - on-finished: 2.3.0 - parseurl: 1.3.3 - statuses: 1.5.0 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - - find-cache-dir@2.1.0: - dependencies: - commondir: 1.0.1 - make-dir: 2.1.0 - pkg-dir: 3.0.0 - - find-up@3.0.0: - dependencies: - locate-path: 3.0.0 - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - flat-cache@3.2.0: - dependencies: - flatted: 3.2.9 - keyv: 4.5.4 - rimraf: 3.0.2 - - flat@5.0.2: {} - - flatted@2.0.2: {} + fast-uri@3.1.0: {} - flatted@3.2.9: {} - - follow-redirects@1.15.4: {} + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 for-each@0.3.3: dependencies: is-callable: 1.2.7 - foreground-child@1.5.6: - dependencies: - cross-spawn: 4.0.2 - signal-exit: 3.0.7 - - forever-agent@0.6.1: {} - - form-data@2.3.3: + foreground-child@3.3.1: dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 + cross-spawn: 7.0.6 + signal-exit: 4.1.0 form-data@2.5.1: dependencies: @@ -3729,14 +2397,6 @@ snapshots: combined-stream: 1.0.8 mime-types: 2.1.35 - fs-extra@7.0.1: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - - fs.realpath@1.0.0: {} - fsevents@2.3.3: optional: true @@ -3744,8 +2404,6 @@ snapshots: get-caller-file@2.0.5: {} - get-func-name@2.0.2: {} - get-intrinsic@1.2.2: dependencies: function-bind: 1.1.2 @@ -3753,76 +2411,19 @@ snapshots: has-symbols: 1.0.3 hasown: 2.0.0 - getpass@0.1.7: - dependencies: - assert-plus: 1.0.0 - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - glob@7.2.0: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - - glob@7.2.3: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - - globals@11.12.0: {} - - globals@13.24.0: - dependencies: - type-fest: 0.20.2 - - globby@11.1.0: + glob@10.5.0: dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.2 - ignore: 5.3.0 - merge2: 1.4.1 - slash: 3.0.0 + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 gopd@1.0.1: dependencies: get-intrinsic: 1.2.2 - graceful-fs@4.2.11: {} - - graphemer@1.4.0: {} - - har-schema@2.0.0: {} - - har-validator@5.1.5: - dependencies: - ajv: 6.12.6 - har-schema: 2.0.0 - - has-binary2@1.0.3: - dependencies: - isarray: 2.0.1 - - has-cors@1.1.0: {} - - has-flag@3.0.0: {} - - has-flag@4.0.0: {} - has-property-descriptors@1.0.1: dependencies: get-intrinsic: 1.2.2 @@ -3831,335 +2432,79 @@ snapshots: has-symbols@1.0.3: {} - has-tostringtag@1.0.0: - dependencies: - has-symbols: 1.0.3 - - hasha@3.0.0: - dependencies: - is-stream: 1.1.0 - - hashlru@2.3.0: {} - - hasown@2.0.0: - dependencies: - function-bind: 1.1.2 - - he@1.2.0: {} - - hosted-git-info@2.8.9: {} - - html-escaper@2.0.2: {} - - http-errors@2.0.0: - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.1 - toidentifier: 1.0.1 - - http-proxy@1.18.1: - dependencies: - eventemitter3: 4.0.7 - follow-redirects: 1.15.4 - requires-port: 1.0.0 - transitivePeerDependencies: - - debug - - http-signature@1.2.0: - dependencies: - assert-plus: 1.0.0 - jsprim: 1.4.2 - sshpk: 1.18.0 - - iconv-lite@0.4.24: - dependencies: - safer-buffer: 2.1.2 - - ieee754@1.1.13: {} - - ieee754@1.2.1: {} - - ignore@5.3.0: {} - - import-fresh@3.3.0: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - imurmurhash@0.1.4: {} - - indexof@0.0.1: {} - - inflight@1.0.6: - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - inherits@2.0.4: {} - - is-arguments@1.1.1: - dependencies: - call-bind: 1.0.5 - has-tostringtag: 1.0.0 - - is-arrayish@0.2.1: {} - - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.2.0 - - is-callable@1.2.7: {} - - is-core-module@2.13.1: - dependencies: - hasown: 2.0.0 - - is-extglob@2.1.1: {} - - is-fullwidth-code-point@2.0.0: {} - - is-fullwidth-code-point@3.0.0: {} - - is-generator-function@1.0.10: - dependencies: - has-tostringtag: 1.0.0 - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-number@7.0.0: {} - - is-path-inside@3.0.3: {} - - is-plain-obj@2.1.0: {} - - is-plain-object@5.0.0: {} - - is-stream@1.1.0: {} - - is-typed-array@1.1.12: - dependencies: - which-typed-array: 1.1.13 - - is-typedarray@1.0.0: {} - - is-unicode-supported@0.1.0: {} - - isarray@1.0.0: {} - - isarray@2.0.1: {} - - isbinaryfile@3.0.3: - dependencies: - buffer-alloc: 1.2.0 - - isexe@2.0.0: {} - - isstream@0.1.2: {} - - istanbul-lib-coverage@2.0.5: {} - - istanbul-lib-hook@2.0.7: - dependencies: - append-transform: 1.0.0 - - istanbul-lib-instrument@3.3.0: - dependencies: - '@babel/generator': 7.23.6 - '@babel/parser': 7.23.6 - '@babel/template': 7.22.15 - '@babel/traverse': 7.23.7 - '@babel/types': 7.23.6 - istanbul-lib-coverage: 2.0.5 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - istanbul-lib-report@2.0.8: - dependencies: - istanbul-lib-coverage: 2.0.5 - make-dir: 2.1.0 - supports-color: 6.1.0 - - istanbul-lib-source-maps@3.0.6: - dependencies: - debug: 4.3.4(supports-color@8.1.1) - istanbul-lib-coverage: 2.0.5 - make-dir: 2.1.0 - rimraf: 2.7.1 - source-map: 0.6.1 - transitivePeerDependencies: - - supports-color - - istanbul-reports@2.2.7: - dependencies: - html-escaper: 2.0.2 - - it-pushable@3.2.3: - dependencies: - p-defer: 4.0.0 - - it-stream-types@2.0.1: {} - - jmespath@0.16.0: {} - - js-tokens@4.0.0: {} - - js-yaml@3.14.1: - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 - - jsbn@0.1.1: {} - - jsesc@2.5.2: {} - - json-buffer@3.0.1: {} - - json-parse-better-errors@1.0.2: {} - - json-schema-traverse@0.4.1: {} + has-tostringtag@1.0.0: + dependencies: + has-symbols: 1.0.3 - json-schema-traverse@1.0.0: {} + hashlru@2.3.0: {} - json-schema@0.4.0: {} + hasown@2.0.0: + dependencies: + function-bind: 1.1.2 - json-stable-stringify-without-jsonify@1.0.1: {} + ieee754@1.1.13: {} - json-stringify-safe@5.0.1: {} + ieee754@1.2.1: {} - jsonfile@4.0.0: - optionalDependencies: - graceful-fs: 4.2.11 - - jsprim@1.4.2: - dependencies: - assert-plus: 1.0.0 - extsprintf: 1.3.0 - json-schema: 0.4.0 - verror: 1.10.0 - - karma@4.4.1: - dependencies: - bluebird: 3.7.2 - body-parser: 1.20.2 - braces: 3.0.2 - chokidar: 3.5.3 - colors: 1.4.0 - connect: 3.7.0 - di: 0.0.1 - dom-serialize: 2.2.1 - flatted: 2.0.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - http-proxy: 1.18.1 - isbinaryfile: 3.0.3 - lodash: 4.17.21 - log4js: 4.5.1 - mime: 2.6.0 - minimatch: 3.1.2 - optimist: 0.6.1 - qjobs: 1.2.0 - range-parser: 1.2.1 - rimraf: 2.7.1 - safe-buffer: 5.2.1 - socket.io: 2.1.1 - source-map: 0.6.1 - tmp: 0.0.33 - useragent: 2.3.0 - transitivePeerDependencies: - - bufferutil - - debug - - supports-color - - utf-8-validate + inherits@2.0.4: {} - keyv@4.5.4: + is-arguments@1.1.1: dependencies: - json-buffer: 3.0.1 + call-bind: 1.0.5 + has-tostringtag: 1.0.0 - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 + is-callable@1.2.7: {} - load-json-file@4.0.0: - dependencies: - graceful-fs: 4.2.11 - parse-json: 4.0.0 - pify: 3.0.0 - strip-bom: 3.0.0 + is-fullwidth-code-point@3.0.0: {} - locate-path@3.0.0: + is-generator-function@1.0.10: dependencies: - p-locate: 3.0.0 - path-exists: 3.0.0 + has-tostringtag: 1.0.0 - locate-path@6.0.0: + is-typed-array@1.1.12: dependencies: - p-locate: 5.0.0 + which-typed-array: 1.1.13 - lodash.flattendeep@4.4.0: {} + is-unicode-supported@2.1.0: {} - lodash.merge@4.6.2: {} + isarray@1.0.0: {} - lodash@4.17.21: {} + isexe@2.0.0: {} - log-symbols@4.1.0: + it-pushable@3.2.3: dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 + p-defer: 4.0.0 - log4js@4.5.1: - dependencies: - date-format: 2.1.0 - debug: 4.3.4(supports-color@8.1.1) - flatted: 2.0.2 - rfdc: 1.3.0 - streamroller: 1.0.6 - transitivePeerDependencies: - - supports-color + it-stream-types@2.0.1: {} - loupe@2.3.7: + jackspeak@3.4.3: dependencies: - get-func-name: 2.0.2 + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 - lru-cache@10.1.0: {} + jmespath@0.16.0: {} - lru-cache@4.1.5: - dependencies: - pseudomap: 1.0.2 - yallist: 2.1.2 + json-schema-traverse@1.0.0: {} - lru-cache@6.0.0: + log-symbols@7.0.1: dependencies: - yallist: 4.0.0 + is-unicode-supported: 2.1.0 + yoctocolors: 2.1.2 - make-dir@2.1.0: - dependencies: - pify: 4.0.1 - semver: 5.7.2 + loupe@3.2.1: {} - make-error@1.3.6: {} + lru-cache@10.4.3: {} - media-typer@0.3.0: {} + lru-cache@11.2.5: {} - merge-source-map@1.1.0: + magic-string@0.30.21: dependencies: - source-map: 0.6.1 + '@jridgewell/sourcemap-codec': 1.5.5 - merge2@1.4.1: {} + main-event@1.0.1: {} - micromatch@4.0.5: - dependencies: - braces: 3.0.2 - picomatch: 2.3.1 + make-error@1.3.6: {} mime-db@1.52.0: {} @@ -4167,163 +2512,38 @@ snapshots: dependencies: mime-db: 1.52.0 - mime@2.6.0: {} - minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 - minimatch@5.0.1: + minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 - minimist@0.0.10: {} - - minimist@1.2.8: {} - - mkdirp@0.5.6: - dependencies: - minimist: 1.2.8 - - mocha@10.2.0: - dependencies: - ansi-colors: 4.1.1 - browser-stdout: 1.3.1 - chokidar: 3.5.3 - debug: 4.3.4(supports-color@8.1.1) - diff: 5.0.0 - escape-string-regexp: 4.0.0 - find-up: 5.0.0 - glob: 7.2.0 - he: 1.2.0 - js-yaml: 4.1.0 - log-symbols: 4.1.0 - minimatch: 5.0.1 - ms: 2.1.3 - nanoid: 3.3.3 - serialize-javascript: 6.0.0 - strip-json-comments: 3.1.1 - supports-color: 8.1.1 - workerpool: 6.2.1 - yargs: 16.2.0 - yargs-parser: 20.2.4 - yargs-unparser: 2.0.0 - - ms@2.0.0: {} - - ms@2.1.2: {} + minipass@7.1.2: {} ms@2.1.3: {} - multiformats@13.2.2: {} - - nanoid@3.3.3: {} - - natural-compare-lite@1.4.0: {} + ms@3.0.0-canary.202508261828: {} - natural-compare@1.4.0: {} + multiformats@13.2.2: {} - negotiator@0.6.3: {} + multiformats@13.4.2: {} - nested-error-stacks@2.1.1: {} + nanoid@3.3.11: {} node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 - normalize-package-data@2.5.0: - dependencies: - hosted-git-info: 2.8.9 - resolve: 1.22.8 - semver: 5.7.2 - validate-npm-package-license: 3.0.4 - - normalize-path@3.0.0: {} - - nyc@14.1.1: - dependencies: - archy: 1.0.0 - caching-transform: 3.0.2 - convert-source-map: 1.9.0 - cp-file: 6.2.0 - find-cache-dir: 2.1.0 - find-up: 3.0.0 - foreground-child: 1.5.6 - glob: 7.2.3 - istanbul-lib-coverage: 2.0.5 - istanbul-lib-hook: 2.0.7 - istanbul-lib-instrument: 3.3.0 - istanbul-lib-report: 2.0.8 - istanbul-lib-source-maps: 3.0.6 - istanbul-reports: 2.2.7 - js-yaml: 3.14.1 - make-dir: 2.1.0 - merge-source-map: 1.1.0 - resolve-from: 4.0.0 - rimraf: 2.7.1 - signal-exit: 3.0.7 - spawn-wrap: 1.4.3 - test-exclude: 5.2.3 - uuid: 3.4.0 - yargs: 13.3.2 - yargs-parser: 13.1.2 - transitivePeerDependencies: - - supports-color - - oauth-sign@0.9.0: {} - - object-component@0.0.3: {} - - object-inspect@1.13.1: {} - - on-finished@2.3.0: - dependencies: - ee-first: 1.1.1 - - on-finished@2.4.1: - dependencies: - ee-first: 1.1.1 + obug@2.1.1: {} once@1.4.0: dependencies: wrappy: 1.0.2 - optimist@0.6.1: - dependencies: - minimist: 0.0.10 - wordwrap: 0.0.3 - - optionator@0.9.3: - dependencies: - '@aashutoshrathi/word-wrap': 1.2.6 - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - - os-homedir@1.0.2: {} - - os-tmpdir@1.0.2: {} - p-defer@4.0.0: {} - p-limit@2.3.0: - dependencies: - p-try: 2.2.0 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-locate@3.0.0: - dependencies: - p-limit: 2.3.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - p-queue@8.0.1: dependencies: eventemitter3: 5.0.1 @@ -4331,225 +2551,98 @@ snapshots: p-timeout@6.1.2: {} - p-try@2.2.0: {} - - package-hash@3.0.0: - dependencies: - graceful-fs: 4.2.11 - hasha: 3.0.0 - lodash.flattendeep: 4.4.0 - release-zalgo: 1.0.0 - - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - - parse-json@4.0.0: - dependencies: - error-ex: 1.3.2 - json-parse-better-errors: 1.0.2 - - parseqs@0.0.5: - dependencies: - better-assert: 1.0.2 - - parseuri@0.0.5: - dependencies: - better-assert: 1.0.2 - - parseurl@1.3.3: {} - - path-exists@3.0.0: {} - - path-exists@4.0.0: {} - - path-is-absolute@1.0.1: {} + package-json-from-dist@1.0.1: {} path-key@3.1.1: {} - path-parse@1.0.7: {} - - path-type@3.0.0: + path-scurry@1.11.1: dependencies: - pify: 3.0.0 - - path-type@4.0.0: {} - - pathval@1.1.1: {} - - performance-now@2.1.0: {} + lru-cache: 10.4.3 + minipass: 7.1.2 - picomatch@2.3.1: {} + pathe@1.1.2: {} - pify@3.0.0: {} + pathe@2.0.3: {} - pify@4.0.1: {} + picocolors@1.1.1: {} - pkg-dir@3.0.0: - dependencies: - find-up: 3.0.0 - - prelude-ls@1.2.1: {} + picomatch@4.0.3: {} - prettier-linter-helpers@1.0.0: + postcss@8.5.6: dependencies: - fast-diff: 1.3.0 - - prettier@2.8.8: {} + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 process@0.11.10: {} progress-events@1.0.0: {} + progress-events@1.0.1: {} + protons-runtime@5.5.0: dependencies: - uint8-varint: 2.0.3 + uint8-varint: 2.0.4 uint8arraylist: 2.4.8 uint8arrays: 5.1.0 - pseudomap@1.0.2: {} - - psl@1.15.0: + protons-runtime@5.6.0: dependencies: - punycode: 2.3.1 + uint8-varint: 2.0.4 + uint8arraylist: 2.4.8 + uint8arrays: 5.1.0 punycode@1.3.2: {} - punycode@2.3.1: {} - pvtsutils@1.3.5: dependencies: tslib: 2.6.2 pvutils@1.1.3: {} - qjobs@1.2.0: {} - - qs@6.11.0: - dependencies: - side-channel: 1.0.4 - - qs@6.5.3: {} - querystring@0.2.0: {} - queue-microtask@1.2.3: {} - - randombytes@2.1.0: - dependencies: - safe-buffer: 5.2.1 - - range-parser@1.2.1: {} - - raw-body@2.5.2: - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - - read-pkg-up@4.0.0: - dependencies: - find-up: 3.0.0 - read-pkg: 3.0.0 - - read-pkg@3.0.0: - dependencies: - load-json-file: 4.0.0 - normalize-package-data: 2.5.0 - path-type: 3.0.0 - - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 - - regexpp@3.2.0: {} - - release-zalgo@1.0.0: - dependencies: - es6-error: 4.1.1 - - request@2.88.2: - dependencies: - aws-sign2: 0.7.0 - aws4: 1.13.2 - caseless: 0.12.0 - combined-stream: 1.0.8 - extend: 3.0.2 - forever-agent: 0.6.1 - form-data: 2.3.3 - har-validator: 5.1.5 - http-signature: 1.2.0 - is-typedarray: 1.0.0 - isstream: 0.1.2 - json-stringify-safe: 5.0.1 - mime-types: 2.1.35 - oauth-sign: 0.9.0 - performance-now: 2.1.0 - qs: 6.5.3 - safe-buffer: 5.2.1 - tough-cookie: 2.5.0 - tunnel-agent: 0.6.0 - uuid: 3.4.0 - require-directory@2.1.1: {} require-from-string@2.0.2: {} - require-main-filename@2.0.0: {} - - requires-port@1.0.0: {} - - resolve-from@4.0.0: {} - - resolve@1.22.8: - dependencies: - is-core-module: 2.13.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - reusify@1.0.4: {} - - rfdc@1.3.0: {} - - rimraf@2.7.1: - dependencies: - glob: 7.2.3 - - rimraf@3.0.2: + rollup@4.57.1: dependencies: - glob: 7.2.3 - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - safe-buffer@5.1.2: {} - - safe-buffer@5.2.1: {} - - safer-buffer@2.1.2: {} + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.57.1 + '@rollup/rollup-android-arm64': 4.57.1 + '@rollup/rollup-darwin-arm64': 4.57.1 + '@rollup/rollup-darwin-x64': 4.57.1 + '@rollup/rollup-freebsd-arm64': 4.57.1 + '@rollup/rollup-freebsd-x64': 4.57.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.57.1 + '@rollup/rollup-linux-arm-musleabihf': 4.57.1 + '@rollup/rollup-linux-arm64-gnu': 4.57.1 + '@rollup/rollup-linux-arm64-musl': 4.57.1 + '@rollup/rollup-linux-loong64-gnu': 4.57.1 + '@rollup/rollup-linux-loong64-musl': 4.57.1 + '@rollup/rollup-linux-ppc64-gnu': 4.57.1 + '@rollup/rollup-linux-ppc64-musl': 4.57.1 + '@rollup/rollup-linux-riscv64-gnu': 4.57.1 + '@rollup/rollup-linux-riscv64-musl': 4.57.1 + '@rollup/rollup-linux-s390x-gnu': 4.57.1 + '@rollup/rollup-linux-x64-gnu': 4.57.1 + '@rollup/rollup-linux-x64-musl': 4.57.1 + '@rollup/rollup-openbsd-x64': 4.57.1 + '@rollup/rollup-openharmony-arm64': 4.57.1 + '@rollup/rollup-win32-arm64-msvc': 4.57.1 + '@rollup/rollup-win32-ia32-msvc': 4.57.1 + '@rollup/rollup-win32-x64-gnu': 4.57.1 + '@rollup/rollup-win32-x64-msvc': 4.57.1 + fsevents: 2.3.3 sax@1.2.1: {} sax@1.3.0: {} - semver@5.5.1: {} - - semver@5.7.2: {} - semver@6.3.1: {} - semver@7.5.4: - dependencies: - lru-cache: 6.0.0 - - serialize-javascript@6.0.0: - dependencies: - randombytes: 2.1.0 - - set-blocking@2.0.0: {} - set-function-length@1.1.1: dependencies: define-data-property: 1.1.1 @@ -4557,210 +2650,76 @@ snapshots: gopd: 1.0.1 has-property-descriptors: 1.0.1 - setprototypeof@1.2.0: {} - shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 shebang-regex@3.0.0: {} - side-channel@1.0.4: - dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 - object-inspect: 1.13.1 - - signal-exit@3.0.7: {} - - slash@3.0.0: {} - - socket.io-adapter@1.1.2: {} - - socket.io-client@2.1.1: - dependencies: - backo2: 1.0.2 - base64-arraybuffer: 0.1.5 - component-bind: 1.0.0 - component-emitter: 1.2.1 - debug: 3.1.0 - engine.io-client: 3.2.1 - has-binary2: 1.0.3 - has-cors: 1.1.0 - indexof: 0.0.1 - object-component: 0.0.3 - parseqs: 0.0.5 - parseuri: 0.0.5 - socket.io-parser: 3.2.0 - to-array: 0.1.4 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - socket.io-parser@3.2.0: - dependencies: - component-emitter: 1.2.1 - debug: 3.1.0 - isarray: 2.0.1 - transitivePeerDependencies: - - supports-color - - socket.io@2.1.1: - dependencies: - debug: 3.1.0 - engine.io: 3.2.1 - has-binary2: 1.0.3 - socket.io-adapter: 1.1.2 - socket.io-client: 2.1.1 - socket.io-parser: 3.2.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - source-map@0.6.1: {} - - spawn-wrap@1.4.3: - dependencies: - foreground-child: 1.5.6 - mkdirp: 0.5.6 - os-homedir: 1.0.2 - rimraf: 2.7.1 - signal-exit: 3.0.7 - which: 1.3.1 - - spdx-correct@3.2.0: - dependencies: - spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.16 - - spdx-exceptions@2.3.0: {} - - spdx-expression-parse@3.0.1: - dependencies: - spdx-exceptions: 2.3.0 - spdx-license-ids: 3.0.16 + siginfo@2.0.0: {} - spdx-license-ids@3.0.16: {} + signal-exit@4.1.0: {} - sprintf-js@1.0.3: {} + source-map-js@1.2.1: {} - sshpk@1.18.0: - dependencies: - asn1: 0.2.6 - assert-plus: 1.0.0 - bcrypt-pbkdf: 1.0.2 - dashdash: 1.14.1 - ecc-jsbn: 0.1.2 - getpass: 0.1.7 - jsbn: 0.1.1 - safer-buffer: 2.1.2 - tweetnacl: 0.14.5 - - statuses@1.5.0: {} + stackback@0.0.2: {} - statuses@2.0.1: {} - - streamroller@1.0.6: - dependencies: - async: 2.6.4 - date-format: 2.1.0 - debug: 3.2.7 - fs-extra: 7.0.1 - lodash: 4.17.21 - transitivePeerDependencies: - - supports-color + std-env@3.10.0: {} strict-event-emitter-types@2.0.0: {} - string-width@3.1.0: - dependencies: - emoji-regex: 7.0.3 - is-fullwidth-code-point: 2.0.0 - strip-ansi: 5.2.0 - string-width@4.2.3: dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - strip-ansi@5.2.0: + string-width@5.1.2: dependencies: - ansi-regex: 4.1.1 + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.2 strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 - strip-bom@3.0.0: {} - - strip-json-comments@3.1.1: {} - - supports-color@5.5.0: - dependencies: - has-flag: 3.0.0 - - supports-color@6.1.0: + strip-ansi@7.1.2: dependencies: - has-flag: 3.0.0 - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - supports-color@8.1.1: - dependencies: - has-flag: 4.0.0 - - supports-preserve-symlinks-flag@1.0.0: {} - - test-exclude@5.2.3: - dependencies: - glob: 7.2.3 - minimatch: 3.1.2 - read-pkg-up: 4.0.0 - require-main-filename: 2.0.0 + ansi-regex: 6.2.2 - text-table@0.2.0: {} + supports-color@10.2.2: {} - tmp@0.0.33: - dependencies: - os-tmpdir: 1.0.2 - - to-array@0.1.4: {} + tinybench@2.9.0: {} - to-fast-properties@2.0.0: {} + tinyexec@1.0.2: {} - to-regex-range@5.0.1: + tinyglobby@0.2.15: dependencies: - is-number: 7.0.0 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 - toidentifier@1.0.1: {} + tinyrainbow@1.2.0: {} - tough-cookie@2.5.0: - dependencies: - psl: 1.15.0 - punycode: 2.3.1 + tinyrainbow@3.0.3: {} tr46@0.0.3: {} - ts-node@10.9.2(@types/node@20.11.0)(typescript@4.9.5): + ts-node@10.9.2(@types/node@24.10.12)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.9 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.11.0 + '@types/node': 24.10.12 acorn: 8.11.3 acorn-walk: 8.3.2 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 4.9.5 + typescript: 5.9.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 @@ -4768,35 +2727,11 @@ snapshots: tslib@2.6.2: {} - tsutils@3.21.0(typescript@4.9.5): - dependencies: - tslib: 1.14.1 - typescript: 4.9.5 - - tunnel-agent@0.6.0: - dependencies: - safe-buffer: 5.2.1 - tunnel@0.0.6: {} - tweetnacl@0.14.5: {} - - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - type-detect@4.0.8: {} - - type-fest@0.20.2: {} - - type-is@1.6.18: - dependencies: - media-typer: 0.3.0 - mime-types: 2.1.35 - - typescript@4.9.5: {} + typescript@5.9.3: {} - uint8-varint@2.0.3: + uint8-varint@2.0.4: dependencies: uint8arraylist: 2.4.8 uint8arrays: 5.1.0 @@ -4809,37 +2744,19 @@ snapshots: dependencies: multiformats: 13.2.2 - ultron@1.1.1: {} + undici-types@7.16.0: {} - undici-types@5.26.5: {} - - undici@5.28.2: + undici@5.29.0: dependencies: '@fastify/busboy': 2.1.0 universal-user-agent@6.0.1: {} - universalify@0.1.2: {} - - unpipe@1.0.0: {} - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - url@0.10.3: dependencies: punycode: 1.3.2 querystring: 0.2.0 - useragent@2.3.0: - dependencies: - lru-cache: 4.1.5 - request: 2.88.2 - semver: 5.5.1 - tmp: 0.0.33 - yamlparser: 0.0.2 - util@0.12.5: dependencies: inherits: 2.0.4 @@ -4848,28 +2765,66 @@ snapshots: is-typed-array: 1.1.12 which-typed-array: 1.1.13 - utils-merge@1.0.1: {} - - uuid@3.4.0: {} - uuid@8.0.0: {} uuid@8.3.2: {} v8-compile-cache-lib@3.0.1: {} - validate-npm-package-license@3.0.4: - dependencies: - spdx-correct: 3.2.0 - spdx-expression-parse: 3.0.1 - - verror@1.10.0: + vite@7.3.1(@types/node@24.10.12)(yaml@2.8.2): dependencies: - assert-plus: 1.0.0 - core-util-is: 1.0.2 - extsprintf: 1.3.0 - - void-elements@2.0.1: {} + esbuild: 0.27.3 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.57.1 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 24.10.12 + fsevents: 2.3.3 + yaml: 2.8.2 + + vitest@4.0.18(@types/node@24.10.12)(yaml@2.8.2): + dependencies: + '@vitest/expect': 4.0.18 + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@24.10.12)(yaml@2.8.2)) + '@vitest/pretty-format': 4.0.18 + '@vitest/runner': 4.0.18 + '@vitest/snapshot': 4.0.18 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 + es-module-lexer: 1.7.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tinyrainbow: 3.0.3 + vite: 7.3.1(@types/node@24.10.12)(yaml@2.8.2) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 24.10.12 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + + weald@1.1.1: + dependencies: + ms: 3.0.0-canary.202508261828 + supports-color: 10.2.2 webidl-conversions@3.0.1: {} @@ -4878,8 +2833,6 @@ snapshots: tr46: 0.0.3 webidl-conversions: 3.0.1 - which-module@2.0.1: {} - which-typed-array@1.1.13: dependencies: available-typed-arrays: 1.0.5 @@ -4888,23 +2841,14 @@ snapshots: gopd: 1.0.1 has-tostringtag: 1.0.0 - which@1.3.1: - dependencies: - isexe: 2.0.0 - which@2.0.2: dependencies: isexe: 2.0.0 - wordwrap@0.0.3: {} - - workerpool@6.2.1: {} - - wrap-ansi@5.1.0: + why-is-node-running@2.3.0: dependencies: - ansi-styles: 3.2.1 - string-width: 3.1.0 - strip-ansi: 5.2.0 + siginfo: 2.0.0 + stackback: 0.0.2 wrap-ansi@7.0.0: dependencies: @@ -4912,19 +2856,13 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - wrappy@1.0.2: {} - - write-file-atomic@2.4.3: + wrap-ansi@8.1.0: dependencies: - graceful-fs: 4.2.11 - imurmurhash: 0.1.4 - signal-exit: 3.0.7 + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.1.2 - ws@3.3.3: - dependencies: - async-limiter: 1.0.1 - safe-buffer: 5.1.2 - ultron: 1.1.1 + wrappy@1.0.2: {} xml2js@0.5.0: dependencies: @@ -4933,59 +2871,12 @@ snapshots: xmlbuilder@11.0.1: {} - xmlhttprequest-ssl@1.5.5: {} - - y18n@4.0.3: {} - y18n@5.0.8: {} - yallist@2.1.2: {} - - yallist@4.0.0: {} - - yamlparser@0.0.2: {} - - yargs-parser@13.1.2: - dependencies: - camelcase: 5.3.1 - decamelize: 1.2.0 - - yargs-parser@20.2.4: {} - - yargs-parser@20.2.9: {} + yaml@2.8.2: {} yargs-parser@21.1.1: {} - yargs-unparser@2.0.0: - dependencies: - camelcase: 6.3.0 - decamelize: 4.0.0 - flat: 5.0.2 - is-plain-obj: 2.1.0 - - yargs@13.3.2: - dependencies: - cliui: 5.0.0 - find-up: 3.0.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - require-main-filename: 2.0.0 - set-blocking: 2.0.0 - string-width: 3.1.0 - which-module: 2.0.1 - y18n: 4.0.3 - yargs-parser: 13.1.2 - - yargs@16.2.0: - dependencies: - cliui: 7.0.4 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 20.2.9 - yargs@17.7.2: dependencies: cliui: 8.0.1 @@ -4996,8 +2887,6 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 - yeast@0.1.2: {} - yn@3.1.1: {} - yocto-queue@0.1.0: {} + yoctocolors@2.1.2: {} diff --git a/tsconfig.json b/tsconfig.json index 69af3464..4b4d5310 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,14 +1,10 @@ { "compilerOptions": { "target": "esnext", - "module": "esnext", - "moduleResolution": "node", + "module": "nodenext", + "moduleResolution": "nodenext", "strict": true, "strictNullChecks": true, - "typeRoots": [ - "./node_modules/@types", - "./types" - ], "esModuleInterop": true, "sourceMap": true, } diff --git a/types/bcrypto/index.d.ts b/types/bcrypto/index.d.ts deleted file mode 100644 index 624a6f81..00000000 --- a/types/bcrypto/index.d.ts +++ /dev/null @@ -1,84 +0,0 @@ -/// - -declare module "bcrypto/lib/keccak.js" { - /** - * keccak.js - Keccak/SHA3 implementation for bcrypto - * Copyright (c) 2017-2019, Christopher Jeffrey (MIT License). - * https://github.com/bcoin-org/bcrypto - * - * Parts of this software are based on emn178/js-sha3: - * Copyright (c) 2015-2017, Chen, Yi-Cyuan (MIT License). - * https://github.com/emn178/js-sha3 - * - * Parts of this software are based on rhash/RHash: - * Copyright (c) 2005-2014, Aleksey Kravchenko - * https://github.com/rhash/RHash - * - * Resources: - * https://en.wikipedia.org/wiki/SHA-3 - * https://keccak.team/specifications.html - * https://csrc.nist.gov/projects/hash-functions/sha-3-project/sha-3-standardization - * http://dx.doi.org/10.6028/NIST.FIPS.202 - * https://github.com/rhash/RHash/blob/master/librhash/sha3.c - * https://github.com/emn178/js-sha3/blob/master/src/sha3.js - */ - class Keccak { - native: number; - id: string; - size: number; - bits: number; - blockSize: number; - zero: Buffer; - ctx: Keccak; - static hash(): Keccak; - // static hmac(bits?: number, pad?: number, len?: number): HMAC; - static digest(data: Buffer, bits?: number, pad?: number, len?: number): Buffer; - static root(left: Buffer, right: Buffer, bits?: number, pad?: number, len?: number): Buffer; - static multi(x: Buffer, y: Buffer, z: Buffer, bits?: number, pad?: number, len?: number): Buffer; - static mac(data: Buffer, key: Buffer, bits?: number, pad?: number, len?: number): Buffer; - init(bits?: number): this; - update(data: Buffer): this; - final(pad: number, len?: number): Buffer; - } - - export = Keccak; -} - -declare module "bcrypto/lib/secp256k1.js" { - export function privateKeyGenerate(): Buffer; - export function privateKeyVerify(key: Buffer): boolean; - export function publicKeyCreate(key: Buffer, compress?: boolean): Buffer; - export function publicKeyConvert(pub: Buffer, compress?: boolean): Buffer; - export function publicKeyVerify(pub: Buffer): boolean; - export function sign(msg: Buffer, key: Buffer): Buffer; - export function verify(msg: Buffer, sig: Buffer, key: Buffer): boolean; - export function derive(pub: Buffer, priv: Buffer, compress?: boolean): Buffer; -} - -declare module "bcrypto/lib/hkdf.js" { - export function extract(hash: any, ikm: Buffer, salt?: Buffer): Buffer; - export function expand(hash: any, prk: Buffer, info: Buffer, length: number): Buffer; -} - -declare module "bcrypto/lib/sha256.js" { - export function digest(data: Buffer): Buffer; -} -declare module "bcrypto/lib/cipher.js" { - class CipherBase { - init(key: Buffer, iv: Buffer): this; - update(data: Buffer): Buffer; - final(): Buffer; - setAAD(data: Buffer): this; - setAuthTag(data: Buffer): this; - getAuthTag(): Buffer; - } - export class Cipher extends CipherBase { - constructor(name: string); - } - export class Decipher extends CipherBase { - constructor(name: string); - } -} -declare module "bcrypto/lib/random.js" { - export function randomBytes(size: number): Buffer; -}