From 9cd4d3b5d710a05bcf45f6bb28bf2986a3ebe324 Mon Sep 17 00:00:00 2001 From: Jim Toth Date: Mon, 27 Jul 2026 20:42:00 -0400 Subject: [PATCH 01/15] Port onto @anyone-protocol/ao-client (D15/D16/D17) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Second W4 port, following operator-registry-controller. Replaces @permaweb/aoconnect 0.0.59, the local send-aos-message.ts wrapper, and the vendored src/util/arbundles-lite (an old copy of Irys arbundles) with the shared client and the maintained @dha-team/arbundles. D17 — explicit endpoints. CU_URL is gone, replaced by a single HB_URL with NO default (nodeUrlFromEnv fails closed). Two reads reworked to the D4 design, and neither is a like-for-like swap: 1. The operator-registry read was a View-State dryrun that pulled all five registry maps and used two. The native contract exposes `scoring` for exactly this consumer, so it now asks for that slice. Note the view calls it `hardware`, not `verifiedHardware`. 2. `Last-Snapshot` does not exist on the native contract, and could not: the per-fingerprint `Details` are deliberately never persisted to state (they would add ~3.6MB per round to a tree that is re-read constantly). They exist only as the OUTPUT of Complete-Round, so getLastSnapshot now reads that message's own slot via readSlotOutput. (2) means the settle slot has to reach persistRound, which runs as a SEPARATE BullMQ job. completeRound therefore returns the slot instead of a boolean, and the existing parent/child return value carries it — the child already fed getChildrenValues(). The slot travels, not the payload: a ~3.6MB snapshot has no business in a Redis job result. persistRound keeps its Timestamp === stamp guard, and now gets it from the exact round it settled rather than re-reading whatever was latest. Contract rejections are detected properly now. A rejected write returns HTTP 200 with the reason only in its own slot output, so the old code reported success for writes that changed nothing; ao-client confirms the slot and raises AoContractError. Integration specs, 5/5 green against a local node holding the real migrated relay -rewards and operator-registry state: a round settles, the snapshot comes back from the settle slot WITH Details, and a stale round is correctly refused ("No pending round") rather than silently archiving the wrong one. Typecheck is net -1 error against baseline and introduces none. --- README.md | 2 +- operations/relay-rewards-controller-live.hcl | 5 +- operations/relay-rewards-controller-stage.hcl | 5 +- package-lock.json | 692 +++++++++++++----- package.json | 3 +- src/distribution/distribution.service.ts | 23 +- .../interfaces/operator-registry.ts | 29 +- .../operator-registry.service.spec.ts | 48 +- .../operator-registry.service.ts | 65 +- .../relay-rewards.service.spec.ts | 95 ++- src/relay-rewards/relay-rewards.service.ts | 175 +++-- src/tasks/processors/distribution-queue.ts | 21 +- src/util/arbundles-lite/Bundle.ts | 185 ----- src/util/arbundles-lite/BundleInterface.ts | 19 - src/util/arbundles-lite/BundleItem.ts | 28 - src/util/arbundles-lite/DataItem.ts | 284 ------- src/util/arbundles-lite/ar-data-base.ts | 25 - src/util/arbundles-lite/ar-data-bundle.ts | 85 --- src/util/arbundles-lite/ar-data-create.ts | 80 -- src/util/arbundles-lite/constants.ts | 53 -- src/util/arbundles-lite/deepHash.ts | 65 -- src/util/arbundles-lite/index.ts | 19 - src/util/arbundles-lite/signing/Signer.ts | 21 - .../signing/chains/ArweaveSigner.ts | 27 - .../signing/chains/ethereumSigner.ts | 34 - .../arbundles-lite/signing/chains/index.ts | 16 - src/util/arbundles-lite/signing/constants.ts | 45 -- src/util/arbundles-lite/signing/index.ts | 5 - src/util/arbundles-lite/signing/keccak256.ts | 105 --- .../arbundles-lite/signing/keys/Rsa4096Pss.ts | 35 - src/util/arbundles-lite/signing/keys/index.ts | 2 - .../arbundles-lite/signing/keys/secp256k1.ts | 42 -- src/util/arbundles-lite/tags.ts | 202 ----- src/util/arbundles-lite/types.ts | 1 - src/util/arbundles-lite/utils.ts | 81 -- src/util/create-ethereum-data-item-signer.ts | 22 - src/util/send-aos-message.ts | 113 --- 37 files changed, 844 insertions(+), 1913 deletions(-) delete mode 100644 src/util/arbundles-lite/Bundle.ts delete mode 100644 src/util/arbundles-lite/BundleInterface.ts delete mode 100644 src/util/arbundles-lite/BundleItem.ts delete mode 100644 src/util/arbundles-lite/DataItem.ts delete mode 100644 src/util/arbundles-lite/ar-data-base.ts delete mode 100644 src/util/arbundles-lite/ar-data-bundle.ts delete mode 100644 src/util/arbundles-lite/ar-data-create.ts delete mode 100644 src/util/arbundles-lite/constants.ts delete mode 100644 src/util/arbundles-lite/deepHash.ts delete mode 100644 src/util/arbundles-lite/index.ts delete mode 100644 src/util/arbundles-lite/signing/Signer.ts delete mode 100644 src/util/arbundles-lite/signing/chains/ArweaveSigner.ts delete mode 100644 src/util/arbundles-lite/signing/chains/ethereumSigner.ts delete mode 100644 src/util/arbundles-lite/signing/chains/index.ts delete mode 100644 src/util/arbundles-lite/signing/constants.ts delete mode 100644 src/util/arbundles-lite/signing/index.ts delete mode 100644 src/util/arbundles-lite/signing/keccak256.ts delete mode 100644 src/util/arbundles-lite/signing/keys/Rsa4096Pss.ts delete mode 100644 src/util/arbundles-lite/signing/keys/index.ts delete mode 100644 src/util/arbundles-lite/signing/keys/secp256k1.ts delete mode 100644 src/util/arbundles-lite/tags.ts delete mode 100644 src/util/arbundles-lite/types.ts delete mode 100644 src/util/arbundles-lite/utils.ts delete mode 100644 src/util/create-ethereum-data-item-signer.ts delete mode 100644 src/util/send-aos-message.ts diff --git a/README.md b/README.md index a122d0e..f41ca18 100644 --- a/README.md +++ b/README.md @@ -168,7 +168,7 @@ In production these are injected by Nomad + Vault + Consul KV (see | `OPERATOR_REGISTRY_PROCESS_ID` | AO process id for the operator registry | | `HODLER_CONTRACT_ADDRESS` | HODLER Ethereum contract address | | `JSON_RPC` | Ethereum JSON-RPC URL for reading the HODLER contract | -| `CU_URL` | AO Compute Unit URL used by `aoconnect` | +| `HB_URL` | Our HyperBEAM node, e.g. `https://hb.anyone.tech`. No default — the service refuses to start without it. | > **A note on `USE_HODLER`:** this flag is a leftover from the migration to the > HODLER staking model. HODLER is now the only supported path going forward, so diff --git a/operations/relay-rewards-controller-live.hcl b/operations/relay-rewards-controller-live.hcl index c42de46..e543891 100644 --- a/operations/relay-rewards-controller-live.hcl +++ b/operations/relay-rewards-controller-live.hcl @@ -47,7 +47,10 @@ job "relay-rewards-controller-live" { DO_CLEAN="true" PORT="${NOMAD_PORT_http}" NO_COLOR="1" - CU_URL="https://cu.anyone.tech" + # Our own HyperBEAM node — replaces CU_URL (D17). The edge whitelists + # `/~meta@1.0` and `^/{contract-pid}`, covering both the `~process@1.0/now/...` + # reads and the `~process@1.0/push` writes. + HB_URL="https://hb.anyone.tech" IS_LOCAL_LEADER="true" CPU_COUNT="1" CONSUL_HOST="${NOMAD_IP_http}" diff --git a/operations/relay-rewards-controller-stage.hcl b/operations/relay-rewards-controller-stage.hcl index b03bcb8..a2ff97d 100644 --- a/operations/relay-rewards-controller-stage.hcl +++ b/operations/relay-rewards-controller-stage.hcl @@ -47,7 +47,10 @@ job "relay-rewards-controller-stage" { DO_CLEAN="true" PORT="${NOMAD_PORT_http}" NO_COLOR="1" - CU_URL="https://cu-stage.anyone.tech" + # Our own HyperBEAM node — replaces CU_URL (D17). The edge whitelists + # `/~meta@1.0` and `^/{contract-pid}`, covering both the `~process@1.0/now/...` + # reads and the `~process@1.0/push` writes. + HB_URL="https://hb-stage.anyone.tech" IS_LOCAL_LEADER="true" CPU_COUNT="1" CONSUL_HOST="${NOMAD_IP_http}" diff --git a/package-lock.json b/package-lock.json index cb3193d..2db567f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,17 @@ { "name": "relay-rewards-controller", - "version": "0.1.0", + "version": "0.4.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "relay-rewards-controller", - "version": "0.1.0", + "version": "0.4.4", "license": "AGPL-3.0-only", "dependencies": { + "@anyone-protocol/ao-client": "github:anyone-protocol/ao-client#v0.1.2", "@ardrive/turbo-sdk": "^1.22.0", + "@dha-team/arbundles": "^1.0.4", "@nestjs/axios": "^4.0.1", "@nestjs/bullmq": "^11.0.1", "@nestjs/common": "^11.0.1", @@ -17,7 +19,6 @@ "@nestjs/core": "^11.0.1", "@nestjs/mongoose": "^11.0.3", "@nestjs/platform-express": "^11.0.1", - "@permaweb/aoconnect": "0.0.59", "@types/consul": "^0.40.3", "arweave": "^1.15.5", "base64url": "^3.0.1", @@ -261,6 +262,17 @@ "tslib": "^2.1.0" } }, + "node_modules/@anyone-protocol/ao-client": { + "version": "0.1.0", + "resolved": "git+ssh://git@github.com/anyone-protocol/ao-client.git#4e18519624cfc1b7e067b311e5b41e3fd684037d", + "license": "AGPL-3.0-only", + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "@dha-team/arbundles": "^1.0.3" + } + }, "node_modules/@ardrive/turbo-sdk": { "version": "1.30.0", "resolved": "https://registry.npmjs.org/@ardrive/turbo-sdk/-/turbo-sdk-1.30.0.tgz", @@ -345,7 +357,6 @@ "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", @@ -1050,30 +1061,73 @@ } }, "node_modules/@dha-team/arbundles": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@dha-team/arbundles/-/arbundles-1.0.3.tgz", - "integrity": "sha512-/XelOo5V/1o1M8VchCQ+F7N5kxwirWh5jD5zg1KECaV80Qld6aKBSgG19VLlBsRUXbRUfjM+LDRPJm9Hjfmycg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@dha-team/arbundles/-/arbundles-1.0.4.tgz", + "integrity": "sha512-T/4pv6bosp4caV32EubHTqDzLAqL6481Bsqd348JO0h+HSaMysloY/pFSLwZf9U3IvkJngIZ4njrYQUkjSkkwA==", "license": "Apache-2.0", "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/providers": "^5.7.2", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wallet": "^5.7.0", - "@noble/ed25519": "^1.6.1", - "arweave": "^1.15.7", - "base64url": "^3.0.1", - "bs58": "^4.0.1", - "keccak": "^3.0.2", - "secp256k1": "^5.0.0" + "@ethersproject/bytes": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@noble/ed25519": "1.6.1", + "arweave": "1.15.7", + "base64url": "3.0.1", + "bs58": "4.0.1", + "keccak": "3.0.2", + "secp256k1": "5.0.0" }, "optionalDependencies": { - "@randlabs/myalgo-connect": "^1.1.2", - "algosdk": "^1.13.1", - "arweave-stream-tx": "^1.1.0", - "multistream": "^4.1.0", - "tmp-promise": "^3.0.2" + "@randlabs/myalgo-connect": "1.1.2", + "algosdk": "1.13.1", + "arweave-stream-tx": "1.1.0", + "multistream": "4.1.0", + "tmp-promise": "3.0.2" + } + }, + "node_modules/@dha-team/arbundles/node_modules/@ethersproject/bytes": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@dha-team/arbundles/node_modules/@ethersproject/signing-key": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" } }, "node_modules/@dha-team/arbundles/node_modules/base-x": { @@ -1094,6 +1148,63 @@ "base-x": "^3.0.2" } }, + "node_modules/@dha-team/arbundles/node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/@dha-team/arbundles/node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.5", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", + "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", + "license": "MIT" + }, + "node_modules/@dha-team/arbundles/node_modules/keccak": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", + "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@dha-team/arbundles/node_modules/secp256k1": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-5.0.0.tgz", + "integrity": "sha512-TKWX8xvoGHrxVdqbYeZM9w+izTF4b9z3NhSaDkdn81btvuh+ivbIMGT/zQvDtTFWhRlThpoz6LEYTr7n8A5GcA==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@dha-team/arbundles/node_modules/secp256k1/node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", + "license": "MIT" + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", @@ -1329,6 +1440,33 @@ "@ethersproject/web": "^5.8.0" } }, + "node_modules/@ethersproject/abstract-provider/node_modules/@ethersproject/transactions": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", + "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0" + } + }, "node_modules/@ethersproject/abstract-signer": { "version": "5.8.0", "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.8.0.tgz", @@ -1474,9 +1612,9 @@ } }, "node_modules/@ethersproject/hash": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", - "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", "funding": [ { "type": "individual", @@ -1489,15 +1627,15 @@ ], "license": "MIT", "dependencies": { - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/base64": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/strings": "^5.8.0" + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" } }, "node_modules/@ethersproject/hdnode": { @@ -1530,6 +1668,33 @@ "@ethersproject/wordlists": "^5.8.0" } }, + "node_modules/@ethersproject/hdnode/node_modules/@ethersproject/transactions": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", + "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0" + } + }, "node_modules/@ethersproject/json-wallets": { "version": "5.8.0", "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.8.0.tgz", @@ -1561,6 +1726,33 @@ "scrypt-js": "3.0.1" } }, + "node_modules/@ethersproject/json-wallets/node_modules/@ethersproject/transactions": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", + "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0" + } + }, "node_modules/@ethersproject/keccak256": { "version": "5.8.0", "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", @@ -1656,9 +1848,9 @@ } }, "node_modules/@ethersproject/providers": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.8.0.tgz", - "integrity": "sha512-3Il3oTzEx3o6kzcg9ZzbE+oCZYyY+3Zh83sKkn4s1DZfTUjIegHnN2Cm0kbn9YFy45FDVcuCLLONhU7ny0SsCw==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", "funding": [ { "type": "individual", @@ -1671,39 +1863,39 @@ ], "license": "MIT", "dependencies": { - "@ethersproject/abstract-provider": "^5.8.0", - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/base64": "^5.8.0", - "@ethersproject/basex": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/hash": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/networks": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/random": "^5.8.0", - "@ethersproject/rlp": "^5.8.0", - "@ethersproject/sha2": "^5.8.0", - "@ethersproject/strings": "^5.8.0", - "@ethersproject/transactions": "^5.8.0", - "@ethersproject/web": "^5.8.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", "bech32": "1.1.4", - "ws": "8.18.0" + "ws": "7.4.6" } }, "node_modules/@ethersproject/providers/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", "license": "MIT", "engines": { - "node": ">=10.0.0" + "node": ">=8.3.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" + "utf-8-validate": "^5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -1821,9 +2013,9 @@ } }, "node_modules/@ethersproject/transactions": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", - "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", "funding": [ { "type": "individual", @@ -1836,21 +2028,21 @@ ], "license": "MIT", "dependencies": { - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/rlp": "^5.8.0", - "@ethersproject/signing-key": "^5.8.0" + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" } }, "node_modules/@ethersproject/wallet": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.8.0.tgz", - "integrity": "sha512-G+jnzmgg6UxurVKRKvw27h0kvG75YKXZKdlLYmAHeF32TGUzHkOFd7Zn6QHOTYRFWnfjtSSFjBowKo7vfrXzPA==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", + "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", "funding": [ { "type": "individual", @@ -1863,21 +2055,21 @@ ], "license": "MIT", "dependencies": { - "@ethersproject/abstract-provider": "^5.8.0", - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/hash": "^5.8.0", - "@ethersproject/hdnode": "^5.8.0", - "@ethersproject/json-wallets": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/random": "^5.8.0", - "@ethersproject/signing-key": "^5.8.0", - "@ethersproject/transactions": "^5.8.0", - "@ethersproject/wordlists": "^5.8.0" + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" } }, "node_modules/@ethersproject/web": { @@ -1926,6 +2118,33 @@ "@ethersproject/strings": "^5.8.0" } }, + "node_modules/@ethersproject/wordlists/node_modules/@ethersproject/hash": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", + "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, "node_modules/@fastify/busboy": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", @@ -2372,7 +2591,8 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.3.0.tgz", "integrity": "sha512-M/T6Zewn7sDaBQEqIZ8Rb+i9y8qfGmq+5SDFSf9sA2lUZTmdDLVdOiQaeDp+Q4wElZ9HG1GAX5KhDaidp6LQsQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@isaacs/balanced-match": { "version": "4.0.1", @@ -3203,7 +3423,8 @@ "optional": true, "os": [ "darwin" - ] + ], + "peer": true }, "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { "version": "3.0.3", @@ -3216,7 +3437,8 @@ "optional": true, "os": [ "darwin" - ] + ], + "peer": true }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { "version": "3.0.3", @@ -3229,7 +3451,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { "version": "3.0.3", @@ -3242,7 +3465,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { "version": "3.0.3", @@ -3255,7 +3479,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { "version": "3.0.3", @@ -3268,7 +3493,8 @@ "optional": true, "os": [ "win32" - ] + ], + "peer": true }, "node_modules/@nestjs/axios": { "version": "4.0.1", @@ -3426,7 +3652,6 @@ "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.1.6.tgz", "integrity": "sha512-krKwLLcFmeuKDqngG2N/RuZHCs2ycsKcxWIDgcm7i1lf3sQ0iG03ci+DsP/r3FcT/eJDFsIHnKtNta2LIi7PzQ==", "license": "MIT", - "peer": true, "dependencies": { "file-type": "21.0.0", "iterare": "1.2.1", @@ -3474,7 +3699,6 @@ "integrity": "sha512-a00B0BM4X+9z+t3UxJqIZlemIwCQdYoPKrMcM+ky4z3pkqqG1eTWexjs+YXpGObnLnjtMPVKWlcZHp3adDYvUw==", "hasInstallScript": true, "license": "MIT", - "peer": true, "dependencies": { "@nuxt/opencollective": "0.4.1", "fast-safe-stringify": "2.1.1", @@ -3527,7 +3751,6 @@ "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.9.tgz", "integrity": "sha512-GVd3+0lO0mJq2m1kl9hDDnVrX3Nd4oH3oDfklz0pZEVEVS0KVSp63ufHq2Lu9cyPdSBuelJr9iPm2QQ1yX+Kmw==", "license": "MIT", - "peer": true, "dependencies": { "cors": "2.8.5", "express": "5.1.0", @@ -3605,9 +3828,9 @@ } }, "node_modules/@noble/ed25519": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.7.5.tgz", - "integrity": "sha512-xuS0nwRMQBvSxDa7UxMb61xTiH3MxTgUfhyPUALVIe0FlOAz4sjELwyDRyUvqeEYfRSG9qNjFIycqLZppg4RSA==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.6.1.tgz", + "integrity": "sha512-Gptpue6qPmg7p1E5LBO5GDtXw5WMc2DVtUmu4EQequOcoCvum1dT9sY6s9M8aSJWq9YopCN4jmTOAvqMdw3q7w==", "funding": [ { "type": "individual", @@ -3705,24 +3928,6 @@ "node": ">=18" } }, - "node_modules/@permaweb/aoconnect": { - "version": "0.0.59", - "resolved": "https://registry.npmjs.org/@permaweb/aoconnect/-/aoconnect-0.0.59.tgz", - "integrity": "sha512-AgnUv50hp3BVvqWk2IOw3p9ksF2GblFwQHCIWqwTYjvdViCPlsL4gx/BefxFqbMABXQ5q2QJItMJLlPelqC2CQ==", - "dependencies": { - "@permaweb/ao-scheduler-utils": "~0.0.23", - "buffer": "^6.0.3", - "debug": "^4.3.6", - "hyper-async": "^1.1.2", - "mnemonist": "^0.39.8", - "ramda": "^0.30.1", - "warp-arbundles": "^1.0.4", - "zod": "^3.23.8" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/@pkgr/core": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", @@ -3744,13 +3949,13 @@ "optional": true }, "node_modules/@randlabs/myalgo-connect": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@randlabs/myalgo-connect/-/myalgo-connect-1.4.2.tgz", - "integrity": "sha512-K9hEyUi7G8tqOp7kWIALJLVbGCByhilcy6123WfcorxWwiE1sbQupPyIU5f3YdQK6wMjBsyTWiLW52ZBMp7sXA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@randlabs/myalgo-connect/-/myalgo-connect-1.1.2.tgz", + "integrity": "sha512-UPsdWfZmnRvEuGL83MNolSzVRDfCo4cURA5Bxi9whRcoglEte3hUgEwbxesaeCnpByvgLNYM9YBbjBb8Bh9PqQ==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@randlabs/communication-bridge": "1.0.1" + "@randlabs/communication-bridge": "^1.0.0" } }, "node_modules/@scure/base": { @@ -4101,7 +4306,6 @@ "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -4245,7 +4449,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.10.tgz", "integrity": "sha512-iAFpG6DokED3roLSP0K+ybeDdIX6Bc0Vd3mLW5uDqThPWtNos3E+EqOM11mPQHKzfWHqEBuLjIlsBQQ8CsISmQ==", "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~6.21.0" } @@ -4417,7 +4620,6 @@ "integrity": "sha512-pUXGCuHnnKw6PyYq93lLRiZm3vjuslIy7tus1lIQTYVK9bL8XBgJnCWm8a0KcTtHC84Yya1Q6rtll+duSMj0dg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.39.1", "@typescript-eslint/types": "8.39.1", @@ -4847,7 +5049,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4915,7 +5116,6 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -4969,25 +5169,74 @@ } }, "node_modules/algosdk": { - "version": "1.24.1", - "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-1.24.1.tgz", - "integrity": "sha512-9moZxdqeJ6GdE4N6fA/GlUP4LrbLZMYcYkt141J4Ss68OfEgH9qW0wBuZ3ZOKEx/xjc5bg7mLP2Gjg7nwrkmww==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-1.13.1.tgz", + "integrity": "sha512-htyJI1/zVcOzpNZVT8PHn4K0yXXTS+b7RXplc7nmFqGVThbM8+ufbnBLChxVPh3BVxqqpqS13VTsQcNArK10jg==", "license": "MIT", "optional": true, "dependencies": { "algo-msgpack-with-bigint": "^2.1.1", "buffer": "^6.0.2", - "cross-fetch": "^3.1.5", "hi-base32": "^0.5.1", "js-sha256": "^0.9.0", "js-sha3": "^0.8.0", "js-sha512": "^0.8.0", "json-bigint": "^1.0.0", + "superagent": "^6.1.0", "tweetnacl": "^1.0.3", - "vlq": "^2.0.4" + "url-parse": "^1.5.1" + } + }, + "node_modules/algosdk/node_modules/form-data": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.5.tgz", + "integrity": "sha512-j23EibVLnp4zNXGW7LjryXYa2X6U/M96yoOX+ybZxwkYajdxRNEqYY3zhh7y0i6kfISKS2jr+EJq1YTUDEv5+w==", + "license": "MIT", + "optional": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.4", + "mime-types": "^2.1.35" }, "engines": { - "node": ">=14.0.0" + "node": ">= 6" + } + }, + "node_modules/algosdk/node_modules/formidable": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", + "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==", + "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", + "license": "MIT", + "optional": true, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/algosdk/node_modules/superagent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-6.1.0.tgz", + "integrity": "sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==", + "deprecated": "Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net", + "license": "MIT", + "optional": true, + "dependencies": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.2", + "debug": "^4.1.1", + "fast-safe-stringify": "^2.0.7", + "form-data": "^3.0.0", + "formidable": "^1.2.2", + "methods": "^1.1.2", + "mime": "^2.4.6", + "qs": "^6.9.4", + "readable-stream": "^3.6.0", + "semver": "^7.3.2" + }, + "engines": { + "node": ">= 7.0.0" } }, "node_modules/ansi-colors": { @@ -5122,7 +5371,6 @@ "resolved": "https://registry.npmjs.org/arweave/-/arweave-1.15.7.tgz", "integrity": "sha512-F+Y4iWU1qea9IsKQ/YNmLsY4DHQVsaJBuhEbFxQn9cfGHOmtXE+bwo14oY8xqymsqSNf/e1PeIfLk7G7qN/hVA==", "license": "MIT", - "peer": true, "dependencies": { "arconnect": "^0.4.2", "asn1.js": "^5.4.1", @@ -5134,12 +5382,13 @@ } }, "node_modules/arweave-stream-tx": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/arweave-stream-tx/-/arweave-stream-tx-1.2.2.tgz", - "integrity": "sha512-bNt9rj0hbAEzoUZEF2s6WJbIz8nasZlZpxIw03Xm8fzb9gRiiZlZGW3lxQLjfc9Z0VRUWDzwtqoYeEoB/JDToQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arweave-stream-tx/-/arweave-stream-tx-1.1.0.tgz", + "integrity": "sha512-1BEYGFSP+FP1ACfclTjSjSTWx5PV/7a+0TwGZu+MlkmnnZTQ3hCOr5Md2Pi/T6dc69Fj+BRezSckiIhKFwTc3g==", "optional": true, "dependencies": { - "exponential-backoff": "^3.1.0" + "exponential-backoff": "^3.1.0", + "stream-chunker": "^1.2.8" }, "peerDependencies": { "arweave": "^1.10.0" @@ -5190,7 +5439,6 @@ "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", "license": "MIT", - "peer": true, "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", @@ -5613,7 +5861,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", @@ -5862,7 +6109,6 @@ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "readdirp": "^4.0.1" }, @@ -6037,6 +6283,7 @@ "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -6146,7 +6393,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", - "dev": true, + "devOptional": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6256,14 +6503,14 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/cors": { @@ -6399,6 +6646,7 @@ "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz", "integrity": "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==", "license": "MIT", + "peer": true, "dependencies": { "luxon": "^3.2.1" }, @@ -6406,16 +6654,6 @@ "node": ">=12.0.0" } }, - "node_modules/cross-fetch": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", - "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==", - "license": "MIT", - "optional": true, - "dependencies": { - "node-fetch": "^2.7.0" - } - }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -6563,6 +6801,7 @@ "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=0.10" } @@ -6582,6 +6821,7 @@ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "license": "Apache-2.0", "optional": true, + "peer": true, "engines": { "node": ">=8" } @@ -6861,7 +7101,6 @@ "integrity": "sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", @@ -6923,7 +7162,6 @@ "integrity": "sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -7389,9 +7627,9 @@ } }, "node_modules/exponential-backoff": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz", - "integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", "license": "Apache-2.0", "optional": true }, @@ -8303,9 +8541,9 @@ } }, "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -8495,6 +8733,7 @@ "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.7.0.tgz", "integrity": "sha512-NUcA93i1lukyXU+riqEyPtSEkyFq8tX90uL659J+qpCZ3rEdViB/APC58oAhIh3+bJln2hzdlZbBZsGNrlsR8g==", "license": "MIT", + "peer": true, "dependencies": { "@ioredis/commands": "^1.3.0", "cluster-key-slot": "^1.1.0", @@ -8665,6 +8904,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT", + "optional": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -8855,7 +9101,6 @@ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -10599,13 +10844,15 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/lodash.isarguments": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/lodash.memoize": { "version": "4.1.2", @@ -10734,6 +10981,7 @@ "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.1.tgz", "integrity": "sha512-RkRWjA926cTvz5rAb1BqyWkKbbjzCGchDUIKMCUvNi17j6f6j8uHGDV82Aqcqtzd+icoYpELmG3ksgGiFNNcNg==", "license": "MIT", + "peer": true, "engines": { "node": ">=12" } @@ -10851,7 +11099,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -10888,7 +11136,7 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "dev": true, + "devOptional": true, "license": "MIT", "bin": { "mime": "cli.js" @@ -11057,7 +11305,6 @@ "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.17.1.tgz", "integrity": "sha512-aodS4cacux5caoxB5ErEwRmrafIUsVRJxHnvP7URnSUnTenr32j1qBVV+KjYxryyLSisQkxglAFF69TNLeZTLg==", "license": "MIT", - "peer": true, "dependencies": { "bson": "^6.10.4", "kareem": "2.6.3", @@ -11107,6 +11354,7 @@ "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.5.tgz", "integrity": "sha512-UjkUHN0yqp9RWKy0Lplhh+wlpdt9oQBYgULZOiFhV3VclSF1JnSQWZ5r9gORQlNYaUKQoR8itv7g7z1xDDuACA==", "license": "MIT", + "peer": true, "optionalDependencies": { "msgpackr-extract": "^3.0.2" } @@ -11118,6 +11366,7 @@ "hasInstallScript": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "node-gyp-build-optional-packages": "5.2.2" }, @@ -11325,6 +11574,7 @@ "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", "license": "MIT", "optional": true, + "peer": true, "dependencies": { "detect-libc": "^2.0.1" }, @@ -11873,7 +12123,6 @@ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -11912,6 +12161,13 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT", + "optional": true + }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -12148,6 +12404,7 @@ "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", "license": "MIT", + "peer": true, "engines": { "node": ">=4" } @@ -12157,6 +12414,7 @@ "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", "license": "MIT", + "peer": true, "dependencies": { "redis-errors": "^1.0.0" }, @@ -12443,7 +12701,6 @@ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "license": "Apache-2.0", - "peer": true, "dependencies": { "tslib": "^2.1.0" } @@ -12508,7 +12765,6 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -12883,7 +13139,8 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/starknet": { "version": "6.24.1", @@ -12953,6 +13210,16 @@ "integrity": "sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==", "license": "BSD-3-Clause" }, + "node_modules/stream-chunker": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/stream-chunker/-/stream-chunker-1.2.8.tgz", + "integrity": "sha512-1j0PRZxgxJ8pPRyLlFu6Eer2imfhx1f++644xu/ZGRReDanv4frTSTWwNidtZOHJKwi86ue2KOWHFyikkQWN8w==", + "license": "MIT", + "optional": true, + "dependencies": { + "through2": "~2.0.0" + } + }, "node_modules/stream-json": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/stream-json/-/stream-json-1.9.1.tgz", @@ -13379,10 +13646,54 @@ "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==", "license": "MIT" }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/through2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT", + "optional": true + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/tmp": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", - "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.7.tgz", + "integrity": "sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==", "license": "MIT", "optional": true, "engines": { @@ -13390,9 +13701,9 @@ } }, "node_modules/tmp-promise": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", - "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.2.tgz", + "integrity": "sha512-OyCLAKU1HzBjL6Ev3gxUeraJNlbNingmi8IrHHEsYH8LTmEuhvYfqvhn2F/je+mjf4N58UmZ96OMEy1JanSCpA==", "license": "MIT", "optional": true, "dependencies": { @@ -13655,7 +13966,6 @@ "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -13882,7 +14192,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -14031,6 +14340,7 @@ "https://github.com/sponsors/ctavan" ], "license": "MIT", + "peer": true, "bin": { "uuid": "dist/bin/uuid" } @@ -14066,13 +14376,6 @@ "node": ">= 0.8" } }, - "node_modules/vlq": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vlq/-/vlq-2.0.4.tgz", - "integrity": "sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA==", - "license": "MIT", - "optional": true - }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -14147,7 +14450,6 @@ "integrity": "sha512-HU1JOuV1OavsZ+mfigY0j8d1TgQgbZ6M+J75zDkpEAwYeXjWSqrGJtgnPblJjd/mAyTNQ7ygw0MiKOn6etz8yw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -14313,7 +14615,6 @@ "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz", "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==", "license": "MIT", - "peer": true, "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", @@ -14460,7 +14761,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "license": "MIT", - "peer": true, "engines": { "node": ">=10.0.0" }, diff --git a/package.json b/package.json index b8ed76d..56ecace 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,9 @@ "test:e2e": "jest --config ./test/jest-e2e.json" }, "dependencies": { + "@anyone-protocol/ao-client": "github:anyone-protocol/ao-client#v0.1.2", "@ardrive/turbo-sdk": "^1.22.0", + "@dha-team/arbundles": "^1.0.4", "@nestjs/axios": "^4.0.1", "@nestjs/bullmq": "^11.0.1", "@nestjs/common": "^11.0.1", @@ -32,7 +34,6 @@ "@nestjs/core": "^11.0.1", "@nestjs/mongoose": "^11.0.3", "@nestjs/platform-express": "^11.0.1", - "@permaweb/aoconnect": "0.0.59", "@types/consul": "^0.40.3", "arweave": "^1.15.5", "base64url": "^3.0.1", diff --git a/src/distribution/distribution.service.ts b/src/distribution/distribution.service.ts index 35aac61..d4f697d 100644 --- a/src/distribution/distribution.service.ts +++ b/src/distribution/distribution.service.ts @@ -244,9 +244,8 @@ export class DistributionService { public async getCurrentScores(stamp: number): Promise { const relaysData = await this.fetchRelays() const { locksData, stakingData } = await this.relayRewardsService.getHodlerData() - const operatorRegistryState = await this.operatorRegistryService.getOperatorRegistryState() - const verificationData = operatorRegistryState.VerifiedFingerprintsToOperatorAddresses - const hardwareData = operatorRegistryState.VerifiedHardwareFingerprints + const { verified: verificationData, hardware: hardwareData } = + await this.operatorRegistryService.getOperatorRegistryScoring() const uptimeStreaks = await this.fetchUptimeStreaks(stamp, verificationData) await this.geoipService.cacheCheck() const { sizes, cells } = this.parseLocations(relaysData, verificationData) @@ -299,16 +298,22 @@ export class DistributionService { return this.relayRewardsService.addScores(stamp, scoresForLua) } - public async complete(stamp: number): Promise { - const result = await this.relayRewardsService.completeRound(stamp) - if (result) { + /** + * Settle the round. Returns the SLOT of the Complete-Round message (or undefined if it did + * not settle) — the round's full snapshot, including per-fingerprint Details, is that slot's + * output and exists nowhere else. persistRound needs it. + */ + public async complete(stamp: number): Promise { + const slot = await this.relayRewardsService.completeRound(stamp) + if (slot) { this.tasksService.updateDistribution(stamp, true, false) } - return result + return slot } - public async persistRound(stamp: number): Promise { - const snapshot: RoundSnapshot | undefined = await this.relayRewardsService.getLastSnapshot() + public async persistRound(stamp: number, slot: string): Promise { + const snapshot: RoundSnapshot | undefined = + await this.relayRewardsService.getLastSnapshot(slot) if (!snapshot || snapshot.Timestamp == 0) { this.logger.error('Last snapshot not found') diff --git a/src/operator-registry/interfaces/operator-registry.ts b/src/operator-registry/interfaces/operator-registry.ts index f52f497..f0b97a5 100644 --- a/src/operator-registry/interfaces/operator-registry.ts +++ b/src/operator-registry/interfaces/operator-registry.ts @@ -1,9 +1,22 @@ -export interface OperatorRegistryState { - ClaimableFingerprintsToOperatorAddresses: { [fingerprint: string]: string } - VerifiedFingerprintsToOperatorAddresses: { [fingerprint: string]: string } - BlockedOperatorAddresses: { [fingerprint: string]: boolean } - RegistrationCreditsFingerprintsToOperatorAddresses: { - [fingerprint: string]: string - } - VerifiedHardwareFingerprints: { [fingerprint: string]: boolean } +/** + * The slice of the operator-registry this service needs, as returned by that contract's + * `scoring` view. + * + * Deliberately NOT the whole registry. The legacynet `View-State` dryrun pulled all five maps + * and used two; `scoring` is the view the native contract added for exactly this consumer — + * "the exact slice the reward runners + verifier need each round". + * + * Note `hardware`, not `verifiedHardware` — the view renames it. Legacy → native: + * + * VerifiedFingerprintsToOperatorAddresses -> verified (fingerprint -> operator address) + * VerifiedHardwareFingerprints -> hardware (fingerprint -> true) + * + * Address VALUES are EIP-55 checksummed post-migration; legacynet stored `0x`+ALLCAPS. + * Fingerprint KEYS are unchanged. + */ +export interface OperatorRegistryScoring { + /** fingerprint -> operator address (claimed/verified) */ + verified: { [fingerprint: string]: string } + /** fingerprint -> true */ + hardware: { [fingerprint: string]: boolean } } diff --git a/src/operator-registry/operator-registry.service.spec.ts b/src/operator-registry/operator-registry.service.spec.ts index 07d9f3e..b7dbce7 100644 --- a/src/operator-registry/operator-registry.service.spec.ts +++ b/src/operator-registry/operator-registry.service.spec.ts @@ -1,18 +1,58 @@ +/** + * INTEGRATION test — reads a real operator-registry process on a real node. + * + * Requires: HB_URL, OPERATOR_REGISTRY_PROCESS_ID. + */ +import { Logger } from '@nestjs/common' +import { ConfigModule } from '@nestjs/config' import { Test, TestingModule } from '@nestjs/testing' +import { getAddress } from 'ethers' + import { OperatorRegistryService } from './operator-registry.service' +const HAVE_NODE = !!process.env.OPERATOR_REGISTRY_PROCESS_ID && !!process.env.HB_URL +const itNode = HAVE_NODE ? it : it.skip + describe('OperatorRegistryService', () => { + let module: TestingModule let service: OperatorRegistryService beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [OperatorRegistryService], - }).compile() - + module = await Test.createTestingModule({ + imports: [ConfigModule.forRoot({ isGlobal: true })], + providers: [OperatorRegistryService] + }) + .setLogger(new Logger()) + .compile() service = module.get(OperatorRegistryService) + service.onApplicationBootstrap() + }) + + afterEach(async () => { + await module.close() }) it('should be defined', () => { expect(service).toBeDefined() }) + + itNode('reads the scoring slice', async () => { + const scoring = await service.getOperatorRegistryScoring() + + // The `scoring` view, not the whole registry: exactly `verified` + `hardware`. + expect(Object.keys(scoring).sort()).toEqual(['hardware', 'verified']) + for (const key of ['verified', 'hardware'] as const) { + // Lua serializes an EMPTY table as a JSON array; the service normalizes those back to + // objects, so no caller ever sees an array here. + expect(Array.isArray(scoring[key])).toBe(false) + expect(typeof scoring[key]).toBe('object') + } + + const [firstVerified] = Object.values(scoring.verified) + if (firstVerified) { + // Addresses are EIP-55 post-migration, not legacynet ALLCAPS. getAddress is the oracle: + // a canonical address is its own checksum. + expect(firstVerified).toBe(getAddress(firstVerified)) + } + }, 60_000) }) diff --git a/src/operator-registry/operator-registry.service.ts b/src/operator-registry/operator-registry.service.ts index f3aeee8..1f674a2 100644 --- a/src/operator-registry/operator-registry.service.ts +++ b/src/operator-registry/operator-registry.service.ts @@ -1,21 +1,25 @@ -import { Injectable, Logger } from '@nestjs/common' -import { sendAosDryRun } from '../util/send-aos-message' -import _ from 'lodash' +import { Injectable, Logger, OnApplicationBootstrap } from '@nestjs/common' import { ConfigService } from '@nestjs/config' -import { OperatorRegistryState } from './interfaces/operator-registry' +import { AoClient, createAoClient, nodeUrlFromEnv } from '@anyone-protocol/ao-client' + +import { OperatorRegistryScoring } from './interfaces/operator-registry' @Injectable() -export class OperatorRegistryService { +export class OperatorRegistryService implements OnApplicationBootstrap { private readonly logger = new Logger(OperatorRegistryService.name) private isLive?: string private readonly operatorRegistryProcessId: string + private readonly hbUrl: string + + private ao!: AoClient constructor( private readonly config: ConfigService<{ IS_LIVE: string OPERATOR_REGISTRY_PROCESS_ID: string + HB_URL: string }> ) { this.isLive = config.get('IS_LIVE', { infer: true }) @@ -26,32 +30,55 @@ export class OperatorRegistryService { const operatorRegistryPid = this.config.get( 'OPERATOR_REGISTRY_PROCESS_ID', - { - infer: true, - } + { infer: true } ) if (operatorRegistryPid != undefined) { this.operatorRegistryProcessId = operatorRegistryPid } else { this.logger.error('Missing operator registry process id') } + + // Fail closed, no default. Replaces CU_URL. The outage that forced this migration was + // caused by endpoints nobody had set explicitly. + this.hbUrl = nodeUrlFromEnv({ + HB_URL: config.get('HB_URL', { infer: true }) + }) } - public async getOperatorRegistryState(): Promise { - const { result } = await sendAosDryRun({ - processId: this.operatorRegistryProcessId, - tags: [{ name: 'Action', value: 'View-State' }], + onApplicationBootstrap() { + // Reads only — this service never writes to the operator registry, so no signer. + this.ao = createAoClient({ + url: this.hbUrl, + logger: { + debug: (m, ...meta) => this.logger.debug(m, ...meta), + warn: (m, ...meta) => this.logger.warn(m, ...meta), + error: (m, ...meta) => this.logger.error(m, ...meta) + } }) - const state = JSON.parse(result.Messages[0].Data) + this.logger.log(`Reading operator registry from node ${this.hbUrl}`) + } + + /** + * The verified/hardware slice used to score a round. + * + * This was a `View-State` dryrun that pulled all five registry maps to use two. The native + * contract exposes `scoring` for precisely this, so we ask for the slice instead. + */ + public async getOperatorRegistryScoring(): Promise { + const scoring = await this.ao.readView( + this.operatorRegistryProcessId, + 'scoring' + ) - for (const prop in state) { - // NB: Lua returns empty tables as JSON arrays, so we normalize them to - // empty objects as when they are populated they will also be objects - if (Array.isArray(state[prop]) && state[prop].length < 1) { - state[prop] = {} + // NB: Lua returns empty tables as JSON arrays, so we normalize them to empty objects as + // when they are populated they will also be objects. Still true of the native + // contract: an empty registry serves {"verified":[],"hardware":[]}. + for (const prop in scoring) { + if (Array.isArray(scoring[prop]) && scoring[prop].length < 1) { + scoring[prop] = {} as any } } - return state + return scoring } } diff --git a/src/relay-rewards/relay-rewards.service.spec.ts b/src/relay-rewards/relay-rewards.service.spec.ts index c30f809..5803fa6 100644 --- a/src/relay-rewards/relay-rewards.service.spec.ts +++ b/src/relay-rewards/relay-rewards.service.spec.ts @@ -1,18 +1,105 @@ +/** + * INTEGRATION test — talks to a real HyperBEAM node holding a real relay-rewards process. + * No mocks: the point is to prove ans104 signing, the ACL, and the settle-slot read path + * actually work end to end. + * + * Requires: + * HB_URL e.g. http://localhost:8734 + * RELAY_REWARDS_PROCESS_ID a process spawned from a relay-rewards module + * RELAY_REWARDS_CONTROLLER_KEY an EVM key holding owner/admin on that process + * IS_LIVE=true the write paths no-op otherwise, by design + * + * To stand one up locally see smart-contracts/ao/scripts/run-e2e.ts, which publishes the + * pure-source module into a node container and spawns it with the migration seed. + */ +import { Logger } from '@nestjs/common' +import { ConfigModule } from '@nestjs/config' import { Test, TestingModule } from '@nestjs/testing' + import { RelayRewardsService } from './relay-rewards.service' +const HAVE_NODE = !!process.env.RELAY_REWARDS_PROCESS_ID && !!process.env.HB_URL +const itNode = HAVE_NODE ? it : it.skip + describe('RelayRewardsService', () => { + let module: TestingModule let service: RelayRewardsService beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [RelayRewardsService], - }).compile() - + module = await Test.createTestingModule({ + imports: [ConfigModule.forRoot({ isGlobal: true })], + providers: [RelayRewardsService] + }) + .setLogger(new Logger()) + .compile() service = module.get(RelayRewardsService) + await service.onApplicationBootstrap() + }) + + afterEach(async () => { + await module.close() }) it('should be defined', () => { expect(service).toBeDefined() }) + + itNode( + 'settles a round and reads the full snapshot back from the settle slot', + async () => { + // A round must be newer than the seeded PreviousRound, so derive the stamp from the + // contract rather than the wall clock. + const status: any = await (service as any).ao.readView( + process.env.RELAY_REWARDS_PROCESS_ID, + 'status' + ) + const stamp = Number(status.lastRoundTimestamp) + 3_600_000 + + const fingerprint = 'A'.repeat(40) + const address = '0x' + '1'.repeat(40) + const added = await service.addScores(stamp, { + [fingerprint]: { + Fingerprint: fingerprint, + Address: address, + Network: 10_000, + IsHardware: false, + UptimeStreak: 14, + ExitBonus: false, + FamilySize: 0, + LocationSize: 0 + } + } as any) + expect(added).toBe(true) + + const slot = await service.completeRound(stamp) + // completeRound now yields the SLOT, not a boolean — the snapshot lives in its output. + expect(slot).toBeDefined() + + const snapshot = await service.getLastSnapshot(slot!) + expect(snapshot).toBeDefined() + expect(snapshot!.Timestamp).toBe(stamp) + expect(snapshot!.Period).toBeGreaterThan(0) + expect(snapshot!.Configuration).toBeDefined() + expect(snapshot!.Summary?.Rewards?.Total).toBeDefined() + + // Details are the whole reason this reads the slot rather than state — the contract + // never persists them. Losing them silently would still produce a "valid" snapshot. + expect(snapshot!.Details).toBeDefined() + expect(snapshot!.Details[fingerprint]).toBeDefined() + }, + 180_000 + ) + + itNode('reports a round it did not settle rather than guessing', async () => { + // A stamp at/behind the previous round cannot settle; completeRound must yield undefined + // so persistRound skips instead of archiving someone else's round. + const status: any = await (service as any).ao.readView( + process.env.RELAY_REWARDS_PROCESS_ID, + 'status' + ) + const stale = Number(status.lastRoundTimestamp) + + const slot = await service.completeRound(stale) + expect(slot).toBeUndefined() + }, 120_000) }) diff --git a/src/relay-rewards/relay-rewards.service.ts b/src/relay-rewards/relay-rewards.service.ts index a029e86..4cc0a5c 100644 --- a/src/relay-rewards/relay-rewards.service.ts +++ b/src/relay-rewards/relay-rewards.service.ts @@ -1,15 +1,13 @@ import { Injectable, Logger } from '@nestjs/common' -import { - AosSigningFunction, - sendAosDryRun, - sendAosMessage -} from '../util/send-aos-message' -import { - createEthereumDataItemSigner -} from '../util/create-ethereum-data-item-signer' import { ethers, Wallet } from 'ethers' import _ from 'lodash' -import { EthereumSigner } from '../util/arbundles-lite' +import { EthereumSigner } from '@dha-team/arbundles' +import { + AoClient, + AoContractError, + createAoClient, + nodeUrlFromEnv +} from '@anyone-protocol/ao-client' import { ConfigService } from '@nestjs/config' import { AddScoresData } from 'src/distribution/dto/add-scores' import RoundSnapshot from 'src/distribution/dto/round-snapshot' @@ -24,8 +22,9 @@ export class RelayRewardsService { private readonly relayRewardsProcessId: string private readonly relayRewardsControllerKey: string private readonly hodlerContract: ethers.Contract + private readonly hbUrl: string - private signer!: AosSigningFunction + private ao!: AoClient private readonly useHodler: boolean @@ -37,6 +36,7 @@ export class RelayRewardsService { HODLER_CONTRACT_ADDRESS: string JSON_RPC: string USE_HODLER: string + HB_URL: string }> ) { this.isLive = config.get('IS_LIVE', { infer: true }) @@ -79,13 +79,37 @@ export class RelayRewardsService { if (relayRewardsKey != undefined) { this.relayRewardsControllerKey = relayRewardsKey } else this.logger.error('Missing relay rewards controller key') + + // Fail closed, no default. Replaces CU_URL. + this.hbUrl = nodeUrlFromEnv({ + HB_URL: this.config.get('HB_URL', { infer: true }) + }) } async onApplicationBootstrap(): Promise { - this.signer = await createEthereumDataItemSigner(new EthereumSigner(this.relayRewardsControllerKey)) + this.ao = createAoClient({ + url: this.hbUrl, + signer: new EthereumSigner(this.relayRewardsControllerKey), + logger: { + debug: (m, ...meta) => this.logger.debug(m, ...meta), + warn: (m, ...meta) => this.logger.warn(m, ...meta), + error: (m, ...meta) => this.logger.error(m, ...meta) + } + }) const wallet = new Wallet(this.relayRewardsControllerKey) const address = await wallet.getAddress() - this.logger.log(`Bootstrapped with signer address ${address}`) + this.logger.log(`Bootstrapped with signer address ${address} against node ${this.hbUrl}`) + + // Surface an unreachable node at boot rather than mid-round. Warn, do not throw: a blip + // during a rolling deploy should not crash-loop the service. + try { + this.logger.log(`Node operator address: ${await this.ao.fetchNodeAddress()}`) + } catch (error) { + this.logger.warn( + `Could not reach the HyperBEAM node at ${this.hbUrl} during bootstrap`, + error.stack + ) + } } public async getHodlerData(): Promise<{ @@ -132,87 +156,104 @@ export class RelayRewardsService { return { stakingData, locksData } } - public async getLastSnapshot(): Promise { + /** + * The completed round's full snapshot — Timestamp, Period, Summary, Configuration and the + * per-fingerprint `Details`. + * + * This was a `Last-Snapshot` dryrun. That action does not exist on the native contract, and + * it could not: `Details` are deliberately NEVER persisted to state (they would add ~3.6MB + * per round to a state tree that is re-read constantly). They exist only as the OUTPUT of + * the `Complete-Round` message, so this reads that message's own slot. + * + * The slot therefore has to travel from whoever sent Complete-Round. It is threaded through + * the BullMQ parent/child return value rather than the payload itself, precisely because the + * payload is large and Redis is a poor place to put it. + */ + public async getLastSnapshot(slot: string): Promise { try { - const { result } = await sendAosDryRun({ - processId: this.relayRewardsProcessId, - tags: [ { name: 'Action', value: 'Last-Snapshot' } ] - }) + const output = await this.ao.readSlotOutput(this.relayRewardsProcessId, slot) - if (!result.Error) { - if (!result.Messages) { - this.logger.warn(`No messages found for Last-Snapshot [${JSON.stringify(result)}]`) - } - const data: RoundSnapshot = JSON.parse(result.Messages[0].Data) - - return data - } else { - this.logger.error(`Failed fetching Last-Snapshot: ${result.Error}`) - } + return JSON.parse(output) as RoundSnapshot } catch (error) { - this.logger.error(`Exception in getLastSnapshot: ${error.message}`, error.stack) + this.logger.error( + `Exception reading the round snapshot from slot ${slot}: ${error.message}`, + error.stack + ) } } public async addScores(stamp: number, scores: AddScoresData): Promise { - if (this.isLive === 'true') { - try { - const { messageId, result } = await sendAosMessage({ - processId: this.relayRewardsProcessId, - signer: this.signer as any, // NB: types, lol - tags: [ - { name: 'Action', value: 'Add-Scores' }, - { name: 'Round-Timestamp', value: stamp.toString() }, - ], - data: JSON.stringify({ - Scores: scores, - }), - }) - - if (!result.Error) { - this.logger.log(`[${stamp}] Add-Scores ${Object.keys(scores).length}: ${messageId ?? 'no-message-id'}`) - - return true - } else { - this.logger.error(`Failed storing ${Object.keys(scores).length} scores for ${stamp}: ${result.Error}`) - } - } catch (error) { + if (this.isLive !== 'true') { + this.logger.warn(`NOT LIVE: Not adding ${scores.length} scores to distribution contract `) + + return false + } + + try { + const { id } = await this.ao.sendMessage({ + processId: this.relayRewardsProcessId, + action: 'Add-Scores', + // Tag names must be lowercase for the ans104 signature round-trip; the node + // presents them title-cased to the contract (`ctx.tags['Round-Timestamp']`). + tags: [{ name: 'round-timestamp', value: stamp.toString() }], + data: JSON.stringify({ Scores: scores }) + }) + + this.logger.log(`[${stamp}] Add-Scores ${Object.keys(scores).length}: ${id}`) + + return true + } catch (error) { + if (error instanceof AoContractError) { + this.logger.error( + `Failed storing ${Object.keys(scores).length} scores for ${stamp}: ${error.reason}` + ) + } else { this.logger.error(`Exception in addScores: ${error.message}`, error.stack) } - } else { - this.logger.warn(`NOT LIVE: Not adding ${scores.length} scores to distribution contract `) } return false } - public async completeRound(stamp: number): Promise { + /** + * Settle the round. Returns the SLOT of the Complete-Round message, which is where the full + * snapshot (incl. Details) lives — see getLastSnapshot. `undefined` means the round did not + * settle. + */ + public async completeRound(stamp: number): Promise { if (this.isLive !== 'true') { this.logger.warn(`NOT LIVE: Not sending the Complete-Round message`) - return false + return undefined } try { - const { messageId, result } = await sendAosMessage({ + const { id, slot } = await this.ao.sendMessage({ processId: this.relayRewardsProcessId, - signer: this.signer as any, // NB: types, lol - tags: [ - { name: 'Action', value: 'Complete-Round' }, - { name: 'Round-Timestamp', value: stamp.toString() }, - ], + action: 'Complete-Round', + tags: [{ name: 'round-timestamp', value: stamp.toString() }] }) - if (!result.Error) { - this.logger.log(`[${stamp}] Complete-Round: ${messageId ?? 'no-message-id'}`) + if (slot === null) { + // The contract accepted it (sendMessage would have thrown otherwise), but without a + // slot we cannot retrieve Details later. Report the round as not settled rather than + // let persistence silently archive nothing. + this.logger.error(`[${stamp}] Complete-Round returned no slot; cannot persist the round`) - return true - } else { - this.logger.error(`Failed Complete-Round for ${stamp}: ${result.Error}`) + return undefined } + + this.logger.log(`[${stamp}] Complete-Round: ${id} (slot ${slot})`) + + return slot } catch (error) { - this.logger.error('Exception in distribute: ${error.message}', error.stack) + if (error instanceof AoContractError) { + this.logger.error(`Failed Complete-Round for ${stamp}: ${error.reason}`) + } else { + this.logger.error(`Exception in completeRound: ${error.message}`, error.stack) + } } - return false + + return undefined } } diff --git a/src/tasks/processors/distribution-queue.ts b/src/tasks/processors/distribution-queue.ts index 405354b..ea3f920 100644 --- a/src/tasks/processors/distribution-queue.ts +++ b/src/tasks/processors/distribution-queue.ts @@ -22,7 +22,7 @@ export class DistributionQueue extends WorkerHost { super() } - async process(job: Job): Promise { + async process(job: Job): Promise { this.logger.debug(`Dequeueing ${job.name} [${job.id}]`) switch (job.name) { @@ -106,7 +106,9 @@ export class DistributionQueue extends WorkerHost { return { result: false, stamp: 0, scored: [] } } - async completeDistributionHandler(job: Job<{ stamp: number; total: number }, boolean, string>): Promise { + // Resolves to the Complete-Round SLOT, which persistDistributionHandler reads the round + // snapshot from; undefined when the round did not settle. + async completeDistributionHandler(job: Job<{ stamp: number; total: number }, string | undefined, string>): Promise { return job.getChildrenValues().then( jobValues => { const jobsData = Object.values(jobValues) @@ -131,29 +133,32 @@ export class DistributionQueue extends WorkerHost { } if (processed.length > 0) { + // The settle SLOT, not a boolean: the round snapshot lives in that slot's output + // and persistDistributionHandler cannot find it otherwise. Undefined = not settled. return this.distribution.complete(job.data.stamp) } else { - return false + return undefined } }, error => { this.logger.error(`Exception while completing distribution: ${error.message}`, error.stack) - return false + return undefined } ) } async persistDistributionHandler(job: Job<{ stamp: number }, boolean, string>): Promise { try { - const isComplete = Object.values(await job.getChildrenValues())[0] ?? false - if (!isComplete) { + // The child returns the Complete-Round SLOT (undefined if the round did not settle). + const settleSlot = Object.values(await job.getChildrenValues())[0] as string | undefined + if (!settleSlot) { this.logger.warn( `Round was not marked as complete. Skipping persisting of distribution summary [${job.data.stamp}]` ) return false } - this.logger.log(`Persisting distribution summary [${job.data.stamp}]`) - return this.distribution.persistRound(job.data.stamp) + this.logger.log(`Persisting distribution summary [${job.data.stamp}] from slot ${settleSlot}`) + return this.distribution.persistRound(job.data.stamp, settleSlot) } catch (err) { this.logger.error(`Exception persisting distribution summary [${job.data.stamp}]`, err.stack) } diff --git a/src/util/arbundles-lite/Bundle.ts b/src/util/arbundles-lite/Bundle.ts deleted file mode 100644 index 94da229..0000000 --- a/src/util/arbundles-lite/Bundle.ts +++ /dev/null @@ -1,185 +0,0 @@ -import base64url from 'base64url' -import { byteArrayToLong } from './utils' -import DataItem from './DataItem' -import type Arweave from 'arweave' -import type { BundleInterface } from './BundleInterface' -import type { JWKInterface } from 'arweave/node/lib/wallet' -import { createHash } from 'crypto' -import type { CreateTransactionInterface, Transaction } from './utils' - -const HEADER_START = 32 - -export class Bundle implements BundleInterface { - public length: number - public items: DataItem[] - protected binary: Buffer - - constructor(binary: Buffer) { - this.binary = binary - this.length = this.getDataItemCount() - this.items = this.getItems() - } - - public getRaw(): Buffer { - return this.binary - } - - /** - * Get a DataItem by index (`number`) or by txId (`string`) - * @param index - */ - public get(index: number | string): DataItem { - if (typeof index === 'number') { - if (index >= this.length) { - throw new RangeError('Index out of range') - } - - return this.getByIndex(index) - } else { - return this.getById(index) - } - } - - public getSizes(): number[] { - const ids: number[] = [] - for (let i = HEADER_START; i < HEADER_START + 64 * this.length; i += 64) { - ids.push(byteArrayToLong(this.binary.subarray(i, i + 32))) - } - - return ids - } - - public getIds(): string[] { - const ids: string[] = [] - for (let i = HEADER_START; i < HEADER_START + 64 * this.length; i += 64) { - const bundleId = this.binary.subarray(i + 32, i + 64) - if (bundleId.length === 0) { - throw new Error("Invalid bundle, id specified in headers doesn't exist") - } - ids.push(base64url.encode(bundleId)) - } - - return ids - } - - public getIdBy(index: number): string { - if (index > this.length - 1) { - throw new RangeError('Index of bundle out of range') - } - - const start = 64 + 64 * index - return base64url.encode(this.binary.subarray(start, start + 32)) - } - - public async toTransaction( - attributes: Partial>, - arweave: Arweave, - jwk: JWKInterface - ): Promise { - const tx = await arweave.createTransaction({ data: this.binary, ...attributes }, jwk) - tx.addTag('Bundle-Format', 'binary') - tx.addTag('Bundle-Version', '2.0.0') - return tx - } - - public async verify(): Promise { - for (const item of this.items) { - const valid = await item.isValid() - const expected = base64url(createHash('sha256').update(item.rawSignature).digest()) - if (!(valid && item.id === expected)) { - return false - } - } - - return true - } - - private getOffset(id: Uint8Array): { startOffset: number; size: number } { - let offset = 0 - for (let i = HEADER_START; i < HEADER_START + 64 * this.length; i += 64) { - const _offset = byteArrayToLong(this.binary.subarray(i, i + 32)) - offset += _offset - const _id = this.binary.subarray(i + 32, i + 64) - - if (Buffer.compare(_id, id) === 0) { - return { startOffset: offset, size: _offset } - } - } - - return { startOffset: -1, size: -1 } - } - - // TODO: Test this - /** - * UNSAFE! Assumes index < length - * @param index - * @private - */ - private getByIndex(index: number): DataItem { - let offset = 0 - const bundleStart = this.getBundleStart() - let counter = 0 - let _offset, _id - for (let i = HEADER_START; i < HEADER_START + 64 * this.length; i += 64) { - _offset = byteArrayToLong(this.binary.subarray(i, i + 32)) - if (counter++ === index) { - _id = this.binary.subarray(i + 32, i + 64) - break - } - offset += _offset - } - const dataItemStart = bundleStart + offset - const slice = this.binary.subarray(dataItemStart, dataItemStart + _offset) - const item = new DataItem(slice) - item.rawId = _id - return item - } - - private getById(id: string): DataItem { - const _id = base64url.toBuffer(id) - - const offset = this.getOffset(_id) - if (offset.startOffset === -1) { - throw new Error('Transaction not found') - } - - const bundleStart = this.getBundleStart() - const dataItemStart = bundleStart + offset.startOffset - return new DataItem(this.binary.subarray(dataItemStart, dataItemStart + offset.size)) - } - - private getDataItemCount(): number { - return byteArrayToLong(this.binary.subarray(0, 32)) - } - - private getBundleStart(): number { - return 32 + 64 * this.length - } - - private getItems(): DataItem[] { - const items = new Array(this.length) - let offset = 0 - const bundleStart = this.getBundleStart() - - let counter = 0 - for (let i = HEADER_START; i < HEADER_START + 64 * this.length; i += 64) { - const _offset = byteArrayToLong(this.binary.subarray(i, i + 32)) - const _id = this.binary.subarray(i + 32, i + 64) - if (_id.length === 0) { - throw new Error("Invalid bundle, id specified in headers doesn't exist") - } - const dataItemStart = bundleStart + offset - const bytes = this.binary.subarray(dataItemStart, dataItemStart + _offset) - - offset += _offset - - const item = new DataItem(bytes) - item.rawId = _id - items[counter] = item - - counter++ - } - return items - } -} -export default Bundle diff --git a/src/util/arbundles-lite/BundleInterface.ts b/src/util/arbundles-lite/BundleInterface.ts deleted file mode 100644 index bdf7423..0000000 --- a/src/util/arbundles-lite/BundleInterface.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { BundleItem } from './BundleItem' -import type Arweave from 'arweave' -import type { JWKInterface } from 'arweave/node/lib/wallet' -import type { CreateTransactionInterface, Transaction } from './utils' - -type ResolvesTo = T | Promise | ((...args: any[]) => Promise) - -export interface BundleInterface { - readonly length: ResolvesTo - readonly items: BundleItem[] | AsyncGenerator - get(index: number | string): BundleItem | Promise - getIds(): string[] | Promise - getRaw(): ResolvesTo - toTransaction( - attributes: Partial, - arweave: Arweave, - jwk: JWKInterface - ): Promise -} diff --git a/src/util/arbundles-lite/BundleItem.ts b/src/util/arbundles-lite/BundleItem.ts deleted file mode 100644 index bef77e1..0000000 --- a/src/util/arbundles-lite/BundleItem.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { Signer } from './signing/index' -import type { Buffer } from 'buffer' - -type ResolvesTo = T | Promise | ((...args: any[]) => Promise) - -export abstract class BundleItem { - readonly signatureType: ResolvesTo - readonly rawSignature: ResolvesTo - readonly signature: ResolvesTo - readonly signatureLength: ResolvesTo - readonly rawOwner: ResolvesTo - readonly owner: ResolvesTo - readonly ownerLength: ResolvesTo - readonly rawTarget: ResolvesTo - readonly target: ResolvesTo - readonly rawAnchor: ResolvesTo - readonly anchor: ResolvesTo - readonly rawTags: ResolvesTo - readonly tags: ResolvesTo<{ name: string; value: string }[]> - readonly rawData: ResolvesTo - readonly data: ResolvesTo - abstract sign(signer: Signer): Promise - abstract isValid(): Promise - /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ - static async verify(..._: any[]): Promise { - throw new Error('You must implement `verify`') - } -} diff --git a/src/util/arbundles-lite/DataItem.ts b/src/util/arbundles-lite/DataItem.ts deleted file mode 100644 index 76567ba..0000000 --- a/src/util/arbundles-lite/DataItem.ts +++ /dev/null @@ -1,284 +0,0 @@ -import { byteArrayToLong } from './utils' -import base64url from 'base64url' -import { Buffer } from 'buffer' -import { sign } from './ar-data-bundle' -import type { BundleItem } from './BundleItem' -import type { Signer } from './signing' -import { indexToType } from './signing' -import getSignatureData from './ar-data-base' -import { SIG_CONFIG, SignatureConfig } from './constants' -import { getCryptoDriver } from './utils' -import { deserializeTags } from './tags' -import { createHash } from 'crypto' -import type { Base64URLString } from './types' - -export const MIN_BINARY_SIZE = 80 -export const MAX_TAG_BYTES = 4096 - -export class DataItem implements BundleItem { - private readonly binary: Buffer - private _id: Buffer - - constructor(binary: Buffer) { - this.binary = binary - } - - static isDataItem(obj: any): obj is DataItem { - return obj.binary !== undefined - } - - get signatureType(): SignatureConfig { - const signatureTypeVal: number = byteArrayToLong(this.binary.subarray(0, 2)) - if (SignatureConfig?.[signatureTypeVal] !== undefined) { - return signatureTypeVal - } - throw new Error('Unknown signature type: ' + signatureTypeVal) - } - - async isValid(): Promise { - return DataItem.verify(this.binary) - } - - get id(): Base64URLString { - return base64url.encode(this.rawId) - } - - set id(id: string) { - this._id = base64url.toBuffer(id) - } - - get rawId(): Buffer { - return createHash('sha256').update(this.rawSignature).digest() - } - - set rawId(id: Buffer) { - this._id = id - } - - get rawSignature(): Buffer { - return this.binary.subarray(2, 2 + this.signatureLength) - } - - get signature(): Base64URLString { - return base64url.encode(this.rawSignature) - } - - set rawOwner(pubkey: Buffer) { - if (pubkey.byteLength != this.ownerLength) - throw new Error(`Expected raw owner (pubkey) to be ${this.ownerLength} bytes, got ${pubkey.byteLength} bytes.`) - this.binary.set(pubkey, 2 + this.signatureLength) - } - - get rawOwner(): Buffer { - return this.binary.subarray(2 + this.signatureLength, 2 + this.signatureLength + this.ownerLength) - } - - get signatureLength(): number { - return SIG_CONFIG[this.signatureType].sigLength - } - - get owner(): Base64URLString { - return base64url.encode(this.rawOwner) - } - - get ownerLength(): number { - return SIG_CONFIG[this.signatureType].pubLength - } - - get rawTarget(): Buffer { - const targetStart = this.getTargetStart() - const isPresent = this.binary[targetStart] == 1 - return isPresent ? this.binary.subarray(targetStart + 1, targetStart + 33) : Buffer.alloc(0) - } - - get target(): Base64URLString { - return base64url.encode(this.rawTarget) - } - - get rawAnchor(): Buffer { - const anchorStart = this.getAnchorStart() - const isPresent = this.binary[anchorStart] == 1 - - return isPresent ? this.binary.subarray(anchorStart + 1, anchorStart + 33) : Buffer.alloc(0) - } - - get anchor(): Base64URLString { - return base64url.encode(this.rawAnchor) /* .toString(); */ - } - - get rawTags(): Buffer { - const tagsStart = this.getTagsStart() - const tagsSize = byteArrayToLong(this.binary.subarray(tagsStart + 8, tagsStart + 16)) - return this.binary.subarray(tagsStart + 16, tagsStart + 16 + tagsSize) - } - - get tags(): { name: string; value: string }[] { - const tagsStart = this.getTagsStart() - const tagsCount = byteArrayToLong(this.binary.subarray(tagsStart, tagsStart + 8)) - if (tagsCount == 0) { - return [] - } - - const tagsSize = byteArrayToLong(this.binary.subarray(tagsStart + 8, tagsStart + 16)) - - return deserializeTags(Buffer.from(this.binary.subarray(tagsStart + 16, tagsStart + 16 + tagsSize))) - } - - get tagsB64Url(): { name: Base64URLString; value: Base64URLString }[] { - const _tags = this.tags - return _tags.map(t => ({ - name: base64url.encode(t.name), - value: base64url.encode(t.value), - })) - } - - getStartOfData(): number { - const tagsStart = this.getTagsStart() - - const numberOfTagBytesArray = this.binary.subarray(tagsStart + 8, tagsStart + 16) - const numberOfTagBytes = byteArrayToLong(numberOfTagBytesArray) - return tagsStart + 16 + numberOfTagBytes - } - - get rawData(): Buffer { - const tagsStart = this.getTagsStart() - - const numberOfTagBytesArray = this.binary.subarray(tagsStart + 8, tagsStart + 16) - const numberOfTagBytes = byteArrayToLong(numberOfTagBytesArray) - const dataStart = tagsStart + 16 + numberOfTagBytes - - return this.binary.subarray(dataStart, this.binary.length) - } - - get data(): Base64URLString { - return base64url.encode(this.rawData) - } - - /** - * UNSAFE!! - * DO NOT MUTATE THE BINARY ARRAY. THIS WILL CAUSE UNDEFINED BEHAVIOUR. - */ - getRaw(): Buffer { - return this.binary - } - - public async sign(signer: Signer): Promise { - this._id = await sign(this, signer) - return this.rawId - } - - public async setSignature(signature: Buffer): Promise { - this.binary.set(signature, 2) - this._id = Buffer.from(await getCryptoDriver().hash(signature)) - } - - public isSigned(): boolean { - return (this._id?.length ?? 0) > 0 - } - - /** - * Returns a JSON representation of a DataItem - */ - - public toJSON(): { - owner: string - data: string - signature: string - target: string - tags: { name: Base64URLString; value: Base64URLString }[] - } { - return { - signature: this.signature, - owner: this.owner, - target: this.target, - tags: this.tags.map(t => ({ - name: base64url.encode(t.name), - value: base64url.encode(t.value), - })), - data: this.data, - } - } - - /** - * Verifies a `Buffer` and checks it fits the format of a DataItem - * - * A binary is valid iff: - * - the tags are encoded correctly - */ - static async verify(buffer: Buffer): Promise { - if (buffer.byteLength < MIN_BINARY_SIZE) { - return false - } - const item = new DataItem(buffer) - const sigType = item.signatureType - const tagsStart = item.getTagsStart() - - const numberOfTags = byteArrayToLong(buffer.subarray(tagsStart, tagsStart + 8)) - const numberOfTagBytesArray = buffer.subarray(tagsStart + 8, tagsStart + 16) - const numberOfTagBytes = byteArrayToLong(numberOfTagBytesArray) - - if (numberOfTagBytes > MAX_TAG_BYTES) return false - - if (numberOfTags > 0) { - try { - const tags: { name: string; value: string }[] = deserializeTags( - Buffer.from(buffer.subarray(tagsStart + 16, tagsStart + 16 + numberOfTagBytes)) - ) - - if (tags.length !== numberOfTags) { - return false - } - /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ - } catch (e) { - return false - } - } - - const Signer = indexToType[sigType] - - const signatureData = await getSignatureData(item) - return await Signer.verify(item.rawOwner, signatureData, item.rawSignature) - } - - public async getSignatureData(): Promise { - return getSignatureData(this) - } - - /** - * Returns the start byte of the tags section (number of tags) - * - * @private - */ - private getTagsStart(): number { - const targetStart = this.getTargetStart() - const targetPresent = this.binary[targetStart] == 1 - let tagsStart = targetStart + (targetPresent ? 33 : 1) - const anchorPresent = this.binary[tagsStart] == 1 - tagsStart += anchorPresent ? 33 : 1 - - return tagsStart - } - - /** - * Returns the start byte of the tags section (number of tags) - * - * @private - */ - private getTargetStart(): number { - return 2 + this.signatureLength + this.ownerLength - } - - /** - * Returns the start byte of the tags section (number of tags) - * - * @private - */ - private getAnchorStart(): number { - let anchorStart = this.getTargetStart() + 1 - const targetPresent = this.binary[this.getTargetStart()] == 1 - anchorStart += targetPresent ? 32 : 0 - - return anchorStart - } -} -export default DataItem diff --git a/src/util/arbundles-lite/ar-data-base.ts b/src/util/arbundles-lite/ar-data-base.ts deleted file mode 100644 index 59ead64..0000000 --- a/src/util/arbundles-lite/ar-data-base.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type DataItem from './DataItem' -import { deepHash, stringToBuffer } from './utils' -/** - * Options for creation of a DataItem - */ -export interface DataItemCreateOptions { - target?: string - anchor?: string - tags?: { name: string; value: string }[] -} - -async function getSignatureData(item: DataItem): Promise { - return deepHash([ - stringToBuffer('dataitem'), - stringToBuffer('1'), - stringToBuffer(item.signatureType.toString()), - item.rawOwner, - item.rawTarget, - item.rawAnchor, - item.rawTags, - item.rawData, - ]) -} - -export default getSignatureData diff --git a/src/util/arbundles-lite/ar-data-bundle.ts b/src/util/arbundles-lite/ar-data-bundle.ts deleted file mode 100644 index c6ede15..0000000 --- a/src/util/arbundles-lite/ar-data-bundle.ts +++ /dev/null @@ -1,85 +0,0 @@ -import getSignatureData from './ar-data-base' -import { longTo32ByteArray } from './utils' -import type DataItem from './DataItem' -import Bundle from './Bundle' -import type { Signer } from './signing/Signer' -import { getCryptoDriver } from './utils' - -/** - * Unbundles a transaction into an Array of DataItems. - * - * Takes either a json string or object. Will throw if given an invalid json - * string but otherwise, it will return an empty array if - * - * a) the json object is the wrong format - * b) the object contains no valid DataItems. - * - * It will verify all DataItems and discard ones that don't pass verification. - * - * @param txData - */ -export function unbundleData(txData: Buffer): Bundle { - return new Bundle(txData) -} - -/** - * Verifies all data items and returns a json object with an items array. - * Throws if any of the data items fail verification. - * - * @param dataItems - * @param signer - */ -export async function bundleAndSignData(dataItems: DataItem[], signer: Signer): Promise { - const headers = new Uint8Array(64 * dataItems.length) - - const binaries = await Promise.all( - dataItems.map(async (d, index) => { - // Sign DataItem - const id = d.isSigned() ? d.rawId : await sign(d, signer) - // Create header array - const header = new Uint8Array(64) - // Set offset - header.set(longTo32ByteArray(d.getRaw().byteLength), 0) - // Set id - header.set(id, 32) - // Add header to array of headers - headers.set(header, 64 * index) - // Convert to array for flattening - return d.getRaw() - }) - ).then(a => { - return Buffer.concat(a) - }) - - const buffer = Buffer.concat([Buffer.from(longTo32ByteArray(dataItems.length)), Buffer.from(headers), binaries]) - - return new Bundle(buffer) -} - -/** - * Signs a single - * - * @param item - * @param signer - * @returns signings - signature and id in byte-arrays - */ -export async function getSignatureAndId(item: DataItem, signer: Signer): Promise<{ signature: Buffer; id: Buffer }> { - const signatureData = await getSignatureData(item) - - const signatureBytes = await signer.sign(signatureData) - const idBytes = await getCryptoDriver().hash(signatureBytes) - - return { signature: Buffer.from(signatureBytes), id: Buffer.from(idBytes) } -} - -/** - * Signs and returns item id - * - * @param item - * @param jwk - */ -export async function sign(item: DataItem, signer: Signer): Promise { - const { signature, id } = await getSignatureAndId(item, signer) - item.getRaw().set(signature, 2) - return id -} diff --git a/src/util/arbundles-lite/ar-data-create.ts b/src/util/arbundles-lite/ar-data-create.ts deleted file mode 100644 index 2cb021f..0000000 --- a/src/util/arbundles-lite/ar-data-create.ts +++ /dev/null @@ -1,80 +0,0 @@ -import type { DataItemCreateOptions } from './ar-data-base' - -import base64url from 'base64url' -import { longTo8ByteArray, shortTo2ByteArray } from './utils' -import DataItem from './DataItem' -import type { Tag } from './tags' -import { serializeTags } from './tags' -import type { Signer } from './signing/index' - -/** - * This will create a single DataItem in binary format (Uint8Array) - * - * @param data - * @param opts - Options involved in creating data items - * @param signer - */ -export function createData(data: string | Uint8Array, signer: Signer, opts?: DataItemCreateOptions): DataItem { - // TODO: Add asserts - // Parse all values to a buffer and - const _owner = signer.publicKey - - const _target = opts?.target ? base64url.toBuffer(opts.target) : null - const target_length = 1 + (_target?.byteLength ?? 0) - const _anchor = opts?.anchor ? Buffer.from(opts.anchor) : null - const anchor_length = 1 + (_anchor?.byteLength ?? 0) - const _tags = (opts?.tags?.length ?? 0) > 0 ? serializeTags(opts?.tags as Tag[]) : null - const tags_length = 16 + (_tags ? _tags.byteLength : 0) - const _data = typeof data === 'string' ? Buffer.from(data) : Buffer.from(data) - const data_length = _data.byteLength - - // See [https://github.com/joshbenaron/arweave-standards/blob/ans104/ans/ANS-104.md#13-dataitem-format] - const length = - 2 + signer.signatureLength + signer.ownerLength + target_length + anchor_length + tags_length + data_length - // Create array with set length - const bytes = Buffer.alloc(length) - - bytes.set(shortTo2ByteArray(signer.signatureType), 0) - // Push bytes for `signature` - bytes.set(new Uint8Array(signer.signatureLength).fill(0), 2) - // // Push bytes for `id` - // bytes.set(EMPTY_ARRAY, 32); - // Push bytes for `owner` - - if (_owner.byteLength !== signer.ownerLength) - throw new Error(`Owner must be ${signer.ownerLength} bytes, but was incorrectly ${_owner.byteLength}`) - bytes.set(_owner, 2 + signer.signatureLength) - - const position = 2 + signer.signatureLength + signer.ownerLength - // Push `presence byte` and push `target` if present - // 64 + OWNER_LENGTH - bytes[position] = _target ? 1 : 0 - if (_target) { - if (_target.byteLength !== 32) throw new Error(`Target must be 32 bytes but was incorrectly ${_target.byteLength}`) - bytes.set(_target, position + 1) - } - - // Push `presence byte` and push `anchor` if present - // 64 + OWNER_LENGTH - const anchor_start = position + target_length - let tags_start = anchor_start + 1 - bytes[anchor_start] = _anchor ? 1 : 0 - if (_anchor) { - tags_start += _anchor.byteLength - if (_anchor.byteLength !== 32) throw new Error('Anchor must be 32 bytes') - bytes.set(_anchor, anchor_start + 1) - } - - bytes.set(longTo8ByteArray(opts?.tags?.length ?? 0), tags_start) - const bytesCount = longTo8ByteArray(_tags?.byteLength ?? 0) - bytes.set(bytesCount, tags_start + 8) - if (_tags) { - bytes.set(_tags, tags_start + 16) - } - - const data_start = tags_start + tags_length - - bytes.set(_data, data_start) - - return new DataItem(bytes) -} diff --git a/src/util/arbundles-lite/constants.ts b/src/util/arbundles-lite/constants.ts deleted file mode 100644 index 029d919..0000000 --- a/src/util/arbundles-lite/constants.ts +++ /dev/null @@ -1,53 +0,0 @@ -export enum SignatureConfig { - ARWEAVE = 1, - ED25519, - ETHEREUM, - SOLANA, - INJECTEDAPTOS = 5, - MULTIAPTOS = 6, - TYPEDETHEREUM = 7, -} - -export interface SignatureMeta { - sigLength: number - pubLength: number - sigName: string -} - -export const SIG_CONFIG: Record = { - [SignatureConfig.ARWEAVE]: { - sigLength: 512, - pubLength: 512, - sigName: 'arweave', - }, - [SignatureConfig.ED25519]: { - sigLength: 64, - pubLength: 32, - sigName: 'ed25519', - }, - [SignatureConfig.ETHEREUM]: { - sigLength: 65, - pubLength: 65, - sigName: 'ethereum', - }, - [SignatureConfig.SOLANA]: { - sigLength: 64, - pubLength: 32, - sigName: 'solana', - }, - [SignatureConfig.INJECTEDAPTOS]: { - sigLength: 64, - pubLength: 32, - sigName: 'injectedAptos', - }, - [SignatureConfig.MULTIAPTOS]: { - sigLength: 64 * 32 + 4, // max 32 64 byte signatures, +4 for 32-bit bitmap - pubLength: 32 * 32 + 1, // max 64 32 byte keys, +1 for 8-bit threshold value - sigName: 'multiAptos', - }, - [SignatureConfig.TYPEDETHEREUM]: { - sigLength: 65, - pubLength: 42, - sigName: 'typedEthereum', - }, -} diff --git a/src/util/arbundles-lite/deepHash.ts b/src/util/arbundles-lite/deepHash.ts deleted file mode 100644 index b617693..0000000 --- a/src/util/arbundles-lite/deepHash.ts +++ /dev/null @@ -1,65 +0,0 @@ -// In TypeScript 3.7, could be written as a single type: -// `type DeepHashChunk = Uint8Array | DeepHashChunk[];` -import { getCryptoDriver, concatBuffers, stringToBuffer } from './utils' -import { createHash } from 'crypto' - -export type DeepHashChunk = Uint8Array | AsyncIterable | DeepHashChunks -export type DeepHashChunks = DeepHashChunk[] - -export async function deepHash(data: DeepHashChunk): Promise { - if (typeof data[Symbol.asyncIterator as keyof AsyncIterable] === 'function') { - const _data = data as AsyncIterable - - const context = createHash('sha384') - - let length = 0 - - for await (const chunk of _data) { - length += chunk.byteLength - context.update(chunk) - } - - const tag = concatBuffers([stringToBuffer('blob'), stringToBuffer(length.toString())]) - - const taggedHash = concatBuffers([await getCryptoDriver().hash(tag, 'SHA-384'), context.digest()]) - - return await getCryptoDriver().hash(taggedHash, 'SHA-384') - } else if (Array.isArray(data)) { - const tag = concatBuffers([stringToBuffer('list'), stringToBuffer(data.length.toString())]) - - return await deepHashChunks(data, await getCryptoDriver().hash(tag, 'SHA-384')) - } - - const _data = data as Uint8Array - - const tag = concatBuffers([stringToBuffer('blob'), stringToBuffer(_data.byteLength.toString())]) - - const taggedHash = concatBuffers([ - await getCryptoDriver().hash(tag, 'SHA-384'), - await getCryptoDriver().hash(_data, 'SHA-384'), - ]) - - return await getCryptoDriver().hash(taggedHash, 'SHA-384') -} - -export async function deepHashChunks(chunks: DeepHashChunks, acc: Uint8Array): Promise { - if (chunks.length < 1) { - return acc - } - - const hashPair = concatBuffers([acc, await deepHash(chunks[0])]) - const newAcc = await getCryptoDriver().hash(hashPair, 'SHA-384') - return await deepHashChunks(chunks.slice(1), newAcc) -} - -export async function hashStream(stream: AsyncIterable): Promise { - const context = createHash('sha384') - - for await (const chunk of stream) { - context.update(chunk) - } - - return context.digest() -} - -export default deepHash diff --git a/src/util/arbundles-lite/index.ts b/src/util/arbundles-lite/index.ts deleted file mode 100644 index 370d00c..0000000 --- a/src/util/arbundles-lite/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * This stuff is copied from arbundles: - * https://github.com/Irys-xyz/arbundles - * Thanks! - */ -export * from './signing' -export * from './ar-data-base' -export * from './ar-data-bundle' -export * from './ar-data-create' -export * from './Bundle' -export * from './BundleInterface' -export * from './BundleItem' -export * from './constants' -export * from './DataItem' -// export * from "./error"; -// export * from "./interface-jwk"; -export * from './tags' -export * from './utils' -// export * from "$/utils"; diff --git a/src/util/arbundles-lite/signing/Signer.ts b/src/util/arbundles-lite/signing/Signer.ts deleted file mode 100644 index 6ae850b..0000000 --- a/src/util/arbundles-lite/signing/Signer.ts +++ /dev/null @@ -1,21 +0,0 @@ -export abstract class Signer { - readonly publicKey: Buffer - readonly signatureType: number - readonly signatureLength: number - readonly ownerLength: number - readonly pem?: string | Buffer - - abstract sign(message: Uint8Array, _opts?: any): Promise | Uint8Array - static verify( - /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ - _pk: string | Buffer, - /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ - _message: Uint8Array, - /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ - _signature: Uint8Array, - /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ - _opts?: any - ): boolean { - throw new Error('You must implement verify method on child') - } -} diff --git a/src/util/arbundles-lite/signing/chains/ArweaveSigner.ts b/src/util/arbundles-lite/signing/chains/ArweaveSigner.ts deleted file mode 100644 index e4d9b45..0000000 --- a/src/util/arbundles-lite/signing/chains/ArweaveSigner.ts +++ /dev/null @@ -1,27 +0,0 @@ -import Rsa4096Pss from '../keys/Rsa4096Pss' -import type { JWKInterface } from 'arweave/node/lib/wallet' -// import { jwkTopem } from 'arweave/node/lib/crypto/node-driver' -import base64url from 'base64url' -import { getCryptoDriver } from '../../utils' - -export default class ArweaveSigner extends Rsa4096Pss { - protected jwk: JWKInterface - - constructor(jwk: JWKInterface) { - super(getCryptoDriver().jwkToPem(jwk), jwk.n) - this.jwk = jwk - } - - get publicKey(): Buffer { - if (!this.pk) throw new Error('ArweaveSigner - pk is undefined') - return base64url.toBuffer(this.pk) - } - - sign(message: Uint8Array): Uint8Array { - return getCryptoDriver().sign(this.jwk, message) as any - } - - static async verify(pk: string, message: Uint8Array, signature: Uint8Array): Promise { - return await getCryptoDriver().verify(pk, message, signature) - } -} diff --git a/src/util/arbundles-lite/signing/chains/ethereumSigner.ts b/src/util/arbundles-lite/signing/chains/ethereumSigner.ts deleted file mode 100644 index 022e93b..0000000 --- a/src/util/arbundles-lite/signing/chains/ethereumSigner.ts +++ /dev/null @@ -1,34 +0,0 @@ -import Secp256k1 from '../keys/secp256k1' -import * as secp256k1 from 'secp256k1' -import base64url from 'base64url' -import { Wallet, toBeArray, hashMessage } from 'ethers' - -export default class EthereumSigner extends Secp256k1 { - public get publicKey(): Buffer { - return Buffer.from(this.pk, 'hex') - } - - constructor(key: string) { - if (key.startsWith('0x')) key = key.slice(2) - const b = Buffer.from(key, 'hex') - const pub = secp256k1.publicKeyCreate(b, false) - super(key, Buffer.from(pub)) - } - - async sign(message: Uint8Array): Promise { - const wallet = new Wallet(this._key) - return wallet.signMessage(message).then(r => Buffer.from(r.slice(2), 'hex')) as any - // below doesn't work due to lacking correct v derivation. - // return Buffer.from(joinSignature(Buffer.from(secp256k1.ecdsaSign(arrayify(hashMessage(message)), this.key).signature)).slice(2), "hex"); - } - - static async verify(pk: string | Buffer, message: Uint8Array, signature: Uint8Array): Promise { - // const address = ethers.utils.computeAddress(pk); - // return ethers.utils.verifyMessage(message, signature) === address; - return secp256k1.ecdsaVerify( - signature.length === 65 ? signature.slice(0, -1) : signature, - toBeArray(hashMessage(message)), - typeof pk === 'string' ? base64url.toBuffer(pk) : pk - ) - } -} diff --git a/src/util/arbundles-lite/signing/chains/index.ts b/src/util/arbundles-lite/signing/chains/index.ts deleted file mode 100644 index d730e27..0000000 --- a/src/util/arbundles-lite/signing/chains/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -export { default as ArweaveSigner } from './ArweaveSigner' -// export { default as InjectedSolanaSigner } from "./injectedSolanaSigner"; -// export * from "./injectedEthereumSigner"; -// export { default as SolanaSigner } from "./SolanaSigner"; -// export { default as PolygonSigner } from "./PolygonSigner"; -// export { default as NearSigner } from "./NearSigner"; -export { default as EthereumSigner } from './ethereumSigner' -// export { default as AlgorandSigner } from "./AlgorandSigner"; -// export { default as HexInjectedSolanaSigner } from "./HexInjectedSolanaSigner"; -// export { default as HexSolanaSigner } from "./HexSolanaSigner"; -// export { default as AptosSigner } from "./AptosSigner"; -// export { default as InjectedAptosSigner } from "./InjectedAptosSigner"; -// export { default as MultiSignatureAptosSigner } from "./multiSignatureAptos"; -// export { default as TypedEthereumSigner } from "./TypedEthereumSigner"; -// export * from "./InjectedTypedEthereumSigner"; -// export { default as ArconnectSigner } from "./arconnectSigner"; diff --git a/src/util/arbundles-lite/signing/constants.ts b/src/util/arbundles-lite/signing/constants.ts deleted file mode 100644 index f101a73..0000000 --- a/src/util/arbundles-lite/signing/constants.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { Signer } from './Signer' -// import Curve25519 from "./keys/curve25519"; - -import { - ArweaveSigner, - EthereumSigner, - // HexInjectedSolanaSigner, - // InjectedAptosSigner, - // MultiSignatureAptosSigner, - // TypedEthereumSigner, -} from './chains/index' - -export type IndexToType = Record< - number, - { - new (...args): Signer - readonly signatureLength: number - readonly ownerLength: number - verify(pk: string | Uint8Array, message: Uint8Array, signature: Uint8Array): Promise - } -> - -export const indexToType: IndexToType = { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error - 1: ArweaveSigner, - // // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // // @ts-expect-error - // 2: Curve25519, - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error - 3: EthereumSigner, - // // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // // @ts-expect-error - // 4: HexInjectedSolanaSigner, - // // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // // @ts-expect-error - // 5: InjectedAptosSigner, - // // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // // @ts-expect-error - // 6: MultiSignatureAptosSigner, - // // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // // @ts-expect-error - // 7: TypedEthereumSigner, -} diff --git a/src/util/arbundles-lite/signing/index.ts b/src/util/arbundles-lite/signing/index.ts deleted file mode 100644 index 21ab563..0000000 --- a/src/util/arbundles-lite/signing/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './Signer' -export * from './constants' -export * from './keys/index' -export * from './chains/index' -export * from './keccak256' // TODO: just use ethers bundled ver diff --git a/src/util/arbundles-lite/signing/keccak256.ts b/src/util/arbundles-lite/signing/keccak256.ts deleted file mode 100644 index cc279c5..0000000 --- a/src/util/arbundles-lite/signing/keccak256.ts +++ /dev/null @@ -1,105 +0,0 @@ -import BN from 'bn.js' -import { Buffer } from 'buffer' -import createKeccakHash from 'keccak' - -export function keccak256(value: Buffer | BN | string | number) { - value = toBuffer(value) - return createKeccakHash('keccak256') - .update(value as Buffer) - .digest() -} - -function toBuffer(value: any) { - if (!Buffer.isBuffer(value)) { - if (Array.isArray(value)) { - value = Buffer.from(value) - } else if (typeof value === 'string') { - if (isHexString(value)) { - value = Buffer.from(padToEven(stripHexPrefix(value)), 'hex') - } else { - value = Buffer.from(value) - } - } else if (typeof value === 'number') { - value = intToBuffer(value) - } else if (value === null || value === undefined) { - value = Buffer.allocUnsafe(0) - } else if (BN.isBN(value)) { - value = value.toArrayLike(Buffer) - } else if (value.toArray) { - // converts a BN to a Buffer - value = Buffer.from(value.toArray()) - } else { - throw new Error('invalid type') - } - } - - return value -} - -function isHexString(value: any, length?: number) { - if (typeof value !== 'string' || !value.match(/^0x[0-9A-Fa-f]*$/)) { - return false - } - - if (length && value.length !== 2 + 2 * length) { - return false - } - - return true -} - -function padToEven(value: any) { - if (typeof value !== 'string') { - throw new Error(`while padding to even, value must be string, is currently ${typeof value}, while padToEven.`) - } - - if (value.length % 2) { - value = `0${value}` - } - - return value -} - -function stripHexPrefix(value: any) { - if (typeof value !== 'string') { - return value - } - - return isHexPrefixed(value) ? value.slice(2) : value -} - -function isHexPrefixed(value: any) { - if (typeof value !== 'string') { - throw new Error( - "value must be type 'string', is currently type " + typeof value + ', while checking isHexPrefixed.' - ) - } - - return value.startsWith('0x') -} - -function intToBuffer(i: number) { - const hex = intToHex(i) - return Buffer.from(padToEven(hex.slice(2)), 'hex') -} - -function intToHex(i: number) { - const hex = i.toString(16) - return `0x${hex}` -} - -if (typeof window !== 'undefined') { - ;(window as any).keccak256 = keccak256 -} - -export default keccak256 - -export const exportForTesting = { - intToBuffer, - intToHex, - isHexPrefixed, - stripHexPrefix, - padToEven, - isHexString, - toBuffer, -} diff --git a/src/util/arbundles-lite/signing/keys/Rsa4096Pss.ts b/src/util/arbundles-lite/signing/keys/Rsa4096Pss.ts deleted file mode 100644 index 8b3aecf..0000000 --- a/src/util/arbundles-lite/signing/keys/Rsa4096Pss.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { Signer } from '../Signer' -import { getCryptoDriver } from '../../utils' -import base64url from 'base64url' -import { SIG_CONFIG } from '../../constants' -import { constants, createSign, verify } from 'crypto' - -export default class Rsa4096Pss implements Signer { - readonly signatureType: number = 1 - readonly ownerLength: number = SIG_CONFIG[1].pubLength - readonly signatureLength: number = SIG_CONFIG[1].sigLength - private readonly _publicKey: Buffer - public get publicKey(): Buffer { - return this._publicKey - } - - constructor( - private _key: string, - public pk?: string - ) { - if (!pk) { - this.pk = getCryptoDriver().getPublicKey(JSON.parse(_key)) - } - } - - sign(message: Uint8Array): Uint8Array { - return createSign('sha256').update(message).sign({ - key: this._key, - padding: constants.RSA_PKCS1_PSS_PADDING, - }) - } - - static async verify(pk: string | Buffer, message: Uint8Array, signature: Uint8Array): Promise { - return verify('rsa-pss', message, Buffer.isBuffer(pk) ? base64url.encode(pk) : pk, signature) - } -} diff --git a/src/util/arbundles-lite/signing/keys/index.ts b/src/util/arbundles-lite/signing/keys/index.ts deleted file mode 100644 index de67fba..0000000 --- a/src/util/arbundles-lite/signing/keys/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default as Rsa4096 } from './Rsa4096Pss' -export { default as secp256k1 } from './secp256k1' diff --git a/src/util/arbundles-lite/signing/keys/secp256k1.ts b/src/util/arbundles-lite/signing/keys/secp256k1.ts deleted file mode 100644 index 1b0e2b4..0000000 --- a/src/util/arbundles-lite/signing/keys/secp256k1.ts +++ /dev/null @@ -1,42 +0,0 @@ -import type { Signer } from '../Signer' -import base64url from 'base64url' -import secp256k1 from 'secp256k1' -import { SignatureConfig, SIG_CONFIG } from '../../constants' -import keccak256 from '../keccak256' - -export default class Secp256k1 implements Signer { - readonly ownerLength: number = SIG_CONFIG[SignatureConfig.ETHEREUM].pubLength - readonly signatureLength: number = SIG_CONFIG[SignatureConfig.ETHEREUM].sigLength - readonly signatureType: SignatureConfig = SignatureConfig.ETHEREUM - public readonly pk: string - - constructor( - protected _key: string, - pk: Buffer - ) { - this.pk = pk.toString('hex') - } - - public get publicKey(): Buffer { - throw new Error('You must implement `publicKey`') - } - - public get key(): Uint8Array { - return Buffer.from(this._key, 'hex') - } - - static async verify(pk: string | Buffer, message: Uint8Array, signature: Uint8Array): Promise { - let p = pk - if (typeof pk === 'string') p = base64url.toBuffer(pk) - let verified = false - try { - verified = secp256k1.ecdsaVerify(signature, keccak256(Buffer.from(message)), p as Buffer) - /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ - } catch (e) {} - return verified - } - - async sign(message: Uint8Array): Promise { - return secp256k1.ecdsaSign(keccak256(Buffer.from(message)), Buffer.from(this.key)).signature - } -} diff --git a/src/util/arbundles-lite/tags.ts b/src/util/arbundles-lite/tags.ts deleted file mode 100644 index bb3fe3a..0000000 --- a/src/util/arbundles-lite/tags.ts +++ /dev/null @@ -1,202 +0,0 @@ -import { MAX_TAG_BYTES } from './DataItem' - -export interface Tag { - name: string - value: string -} - -export class AVSCTap { - protected buf: Buffer - protected pos: number - - constructor(buf = Buffer.alloc(MAX_TAG_BYTES), pos = 0) { - this.buf = buf - this.pos = pos - } - - public writeTags(tags: Tag[]): void { - if (!Array.isArray(tags)) { - throw new Error('input must be array') - } - - const n = tags.length - let i - if (n) { - this.writeLong(n) - for (i = 0; i < n; i++) { - // for this use case, assume tags/strings. - const tag = tags[i] - if (typeof tag?.name !== 'string' || typeof tag?.value !== 'string') - throw new Error(`Invalid tag format for ${tag}, expected {name:string, value: string}`) - this.writeString(tag.name) - this.writeString(tag.value) - // this.itemsType._write(tap, val[i]); - } - } - this.writeLong(0) - } - - public toBuffer(): Buffer { - const buffer = Buffer.alloc(this.pos) - if (this.pos > this.buf.length) throw new Error(`Too many tag bytes (${this.pos} > ${this.buf.length})`) - this.buf.copy(buffer, 0, 0, this.pos) - return buffer - } - - protected writeLong(n: number): void { - const buf = this.buf - let f, m - - if (n >= -1073741824 && n < 1073741824) { - // Won't overflow, we can use integer arithmetic. - m = n >= 0 ? n << 1 : (~n << 1) | 1 - do { - buf[this.pos] = m & 0x7f - m >>= 7 - } while (m && (buf[this.pos++] |= 0x80)) - } else { - // We have to use slower floating arithmetic. - f = n >= 0 ? n * 2 : -n * 2 - 1 - do { - buf[this.pos] = f & 0x7f - f /= 128 - } while (f >= 1 && (buf[this.pos++] |= 0x80)) - } - this.pos++ - this.buf = buf - } - - // for some reason using setters/getters with ++ doesn't work right. - // set pos(newPos: number) { - // const d = newPos + 1 - this.buf.length; - // if (d > 0) this.buf = Buffer.concat([this.buf, Buffer.alloc(d)]); - // this._pos = newPos; - // } - - // get pos(): number { - // return this._pos; - // } - - // protected safeRead(position): number { - // return position > this.buf.length ? 0 : this.buf[position]; - // } - // protected safeWrite(position, value): Buffer { - // if (position > this.buf.length) this.buf = Buffer.concat([this.buf, Buffer.alloc(1)]); - // this.buf[position] = value; - // return this.buf; - // } - - protected writeString(s: string): void { - const len = Buffer.byteLength(s) - const buf = this.buf - this.writeLong(len) - let pos = this.pos - this.pos += len - if (this.pos > buf.length) { - return - } - if (len > 64) { - // this._writeUtf8(s, len); - this.buf.write(s, this.pos - len, len, 'utf8') - } else { - let i, l, c1, c2 - for (i = 0, l = len; i < l; i++) { - c1 = s.charCodeAt(i) - if (c1 < 0x80) { - buf[pos++] = c1 - } else if (c1 < 0x800) { - buf[pos++] = (c1 >> 6) | 0xc0 - buf[pos++] = (c1 & 0x3f) | 0x80 - } else if ((c1 & 0xfc00) === 0xd800 && ((c2 = s.charCodeAt(i + 1)) & 0xfc00) === 0xdc00) { - c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff) - i++ - buf[pos++] = (c1 >> 18) | 0xf0 - buf[pos++] = ((c1 >> 12) & 0x3f) | 0x80 - buf[pos++] = ((c1 >> 6) & 0x3f) | 0x80 - buf[pos++] = (c1 & 0x3f) | 0x80 - } else { - buf[pos++] = (c1 >> 12) | 0xe0 - buf[pos++] = ((c1 >> 6) & 0x3f) | 0x80 - buf[pos++] = (c1 & 0x3f) | 0x80 - } - } - } - this.buf = buf - } - - protected readLong(): number { - let n = 0 - let k = 0 - const buf = this.buf - let b, h, f, fk - - do { - b = buf[this.pos++] - h = b & 0x80 - n |= (b & 0x7f) << k - k += 7 - } while (h && k < 28) - - if (h) { - // Switch to float arithmetic, otherwise we might overflow. - f = n - fk = 268435456 // 2 ** 28. - do { - b = buf[this.pos++] - f += (b & 0x7f) * fk - fk *= 128 - } while (b & 0x80) - return (f % 2 ? -(f + 1) : f) / 2 - } - - return (n >> 1) ^ -(n & 1) - } - - protected skipLong(): void { - const buf = this.buf - while (buf[this.pos++] & 0x80) {} - } - - public readTags(): Tag[] { - // var items = this.itemsType; - const val: Tag[] = [] - let n - while ((n = this.readLong())) { - if (n < 0) { - n = -n - this.skipLong() // Skip size. - } - while (n--) { - const name = this.readString() - const value = this.readString() - val.push(/* items._read(tap) */ { name, value }) - } - } - return val - } - - protected readString(): string { - const len = this.readLong() - const pos = this.pos - const buf = this.buf - this.pos += len - if (this.pos > buf.length) { - // return undefined; - throw new Error('TAP Position out of range') - } - return this.buf.slice(pos, pos + len).toString() - } -} - -export function serializeTags(tags: Tag[]): Buffer { - if (tags?.length === 0) { - return Buffer.allocUnsafe(0) - } - const tap = new AVSCTap() - tap.writeTags(tags) - return tap.toBuffer() -} -export function deserializeTags(tagsBuffer: Buffer): Tag[] { - const tap = new AVSCTap(tagsBuffer) - return tap.readTags() -} diff --git a/src/util/arbundles-lite/types.ts b/src/util/arbundles-lite/types.ts deleted file mode 100644 index b1b0be4..0000000 --- a/src/util/arbundles-lite/types.ts +++ /dev/null @@ -1 +0,0 @@ -export type Base64URLString = string diff --git a/src/util/arbundles-lite/utils.ts b/src/util/arbundles-lite/utils.ts deleted file mode 100644 index d5d0088..0000000 --- a/src/util/arbundles-lite/utils.ts +++ /dev/null @@ -1,81 +0,0 @@ -export function longToNByteArray(N: number, long: number): Uint8Array { - const byteArray = new Uint8Array(N) - if (long < 0) throw new Error('Array is unsigned, cannot represent -ve numbers') - if (long > 2 ** (N * 8) - 1) throw new Error(`Number ${long} is too large for an array of ${N} bytes`) - for (let index = 0; index < byteArray.length; index++) { - const byte = long & 0xff - byteArray[index] = byte - long = (long - byte) / 256 - } - return byteArray -} - -export function longTo8ByteArray(long: number): Uint8Array { - return longToNByteArray(8, long) -} - -export function shortTo2ByteArray(short: number): Uint8Array { - return longToNByteArray(2, short) -} - -export function longTo16ByteArray(long: number): Uint8Array { - return longToNByteArray(16, long) -} - -export function longTo32ByteArray(long: number): Uint8Array { - return longToNByteArray(32, long) -} - -export function byteArrayToLong(byteArray: Uint8Array): number { - let value = 0 - for (let i = byteArray.length - 1; i >= 0; i--) { - value = value * 256 + byteArray[i] - } - return value -} - -import { createPublicKey } from 'crypto' -import { default as nodeDriver } from 'arweave/node/lib/crypto/node-driver' -import type { JWKInterface } from 'arweave/node/lib/wallet' -export { stringToBuffer, concatBuffers } from 'arweave/node/lib/utils' -export { default as Transaction } from 'arweave/node/lib/transaction' -export { deepHash } from './deepHash' -// export type { CreateTransactionInterface } from 'arweave/node'//"@irys/arweave/common/arweave"; -export { default as Arweave } from 'arweave/node' -import { Tag } from 'arweave/node/lib/transaction' - -export interface CreateTransactionInterface { - format: number - last_tx: string - owner: string - tags: Tag[] - target: string - quantity: string - data: string | Uint8Array | ArrayBuffer - data_size: string - data_root: string - reward: string -} - -// hack as ESM won't unpack .default CJS imports, so we do so dynamically - -const driver: typeof nodeDriver = nodeDriver['default'] ? nodeDriver['default'] : nodeDriver -export class CryptoDriver extends driver { - public getPublicKey(jwk: JWKInterface): string { - return createPublicKey({ - key: this.jwkToPem(jwk), - type: 'pkcs1', - format: 'pem', - }) - .export({ - format: 'pem', - type: 'pkcs1', - }) - .toString() - } -} - -let driverInstance: CryptoDriver -export function getCryptoDriver(): CryptoDriver { - return (driverInstance ??= new CryptoDriver()) -} diff --git a/src/util/create-ethereum-data-item-signer.ts b/src/util/create-ethereum-data-item-signer.ts deleted file mode 100644 index d6804f3..0000000 --- a/src/util/create-ethereum-data-item-signer.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { createData, Signer } from './arbundles-lite' - -export async function createEthereumDataItemSigner(signer: Signer) { - return ({ - data, - tags, - target, - anchor, - }: { - data: string | Uint8Array - tags: any[] - target?: string - anchor?: string - }) => { - const dataItem = createData(data, signer, { tags, target, anchor }) - - return dataItem.sign(signer).then(async () => ({ - id: await dataItem.id, - raw: await dataItem.getRaw(), - })) - } -} diff --git a/src/util/send-aos-message.ts b/src/util/send-aos-message.ts deleted file mode 100644 index 4cba32a..0000000 --- a/src/util/send-aos-message.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { Logger } from '@nestjs/common' -import { message as aoMessage, result as aoResult, dryrun as aoDryRun, createDataItemSigner } from '@permaweb/aoconnect' - -export type SendAosBaseOptions = { - processId: string - data?: string - tags?: { name: string; value: string }[] -} -export type SendAosDryRunOptions = SendAosBaseOptions -export type SendAosMessageOptions = SendAosBaseOptions & { - signer: ReturnType -} - -export type AosSigningFunction = ({ - data, - tags, - target, - anchor, -}: { - data: string | Uint8Array - tags: any[] - target?: string - anchor?: string -}) => Promise<{ - id: string - raw: Buffer -}> - -export async function sendAosDryRun({ processId, data, tags }: SendAosDryRunOptions, retries = 3) { - const logger = new Logger('util/sendAosDryRun') - let attempts = 0 - let lastError: Error | undefined - - while (attempts < retries) { - try { - logger.debug(`Sending AO DryRun to process ${processId}`) - - return { - result: await aoDryRun({ - process: processId, - tags, - data, - }), - } - } catch (error) { - logger.error(`Error sending AO DryRun to process ${processId}`, error) - - if (error.message.includes('500')) { - logger.debug( - `Retrying sending AO DryRun to process ${processId}`, - JSON.stringify({ attempts, retries, error: error.message }, undefined, 2) - ) - - // NB: Sleep between each attempt with exponential backoff - await new Promise(resolve => setTimeout(resolve, 2 ** attempts * 2000)) - - attempts++ - lastError = error - } else { - throw error - } - } - } - - throw lastError -} - -export async function sendAosMessage({ processId, data, tags, signer }: SendAosMessageOptions, retries = 3) { - const logger = new Logger('util/sendAosMessage') - let attempts = 0 - let lastError: Error | undefined - - while (attempts < retries) { - try { - logger.debug(`Sending AO Message to process ${processId}`) - - const messageId = await aoMessage({ - process: processId, - tags, - data, - signer, - }) - - logger.debug(`Fetching AO Message result ${messageId} from process ${processId}`) - const result = await aoResult({ - message: messageId, - process: processId, - }) - logger.debug(`Got AO Message result ${messageId} from process ${processId}`) - - return { messageId, result } - } catch (error) { - logger.error(`Error sending AO Message to process ${processId}`, error) - - if (error.message.includes('500')) { - logger.debug( - `Retrying sending AO Message to process ${processId}`, - JSON.stringify({ attempts, retries, error: error.message }, undefined, 2) - ) - - // NB: Sleep between each attempt with exponential backoff - await new Promise(resolve => setTimeout(resolve, 2 ** attempts * 2000)) - - attempts++ - lastError = error - } else { - throw error - } - } - } - - throw lastError -} From 3c4dca710e5b5f42f96c81942c5e56d244346560 Mon Sep 17 00:00:00 2001 From: Jim Toth Date: Tue, 28 Jul 2026 15:10:27 -0400 Subject: [PATCH 02/15] Drop the unused arweave dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Declared as a direct dependency but never imported — the Arweave interaction all goes through the bundling service, which used the Turbo SDK. No effect on `npm audit`: arweave stays in the tree transitively via @ardrive/turbo-sdk and @dha-team/arbundles. This is declaration hygiene, so the manifest says what the service actually uses. --- package-lock.json | 1 - package.json | 1 - 2 files changed, 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2db567f..c288962 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,6 @@ "@nestjs/mongoose": "^11.0.3", "@nestjs/platform-express": "^11.0.1", "@types/consul": "^0.40.3", - "arweave": "^1.15.5", "base64url": "^3.0.1", "bn.js": "^5.2.1", "consul": "^2.0.1", diff --git a/package.json b/package.json index 56ecace..b8c3f6f 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,6 @@ "@nestjs/mongoose": "^11.0.3", "@nestjs/platform-express": "^11.0.1", "@types/consul": "^0.40.3", - "arweave": "^1.15.5", "base64url": "^3.0.1", "bn.js": "^5.2.1", "consul": "^2.0.1", From a25c40d9d25a5df39b2879de48688f02a0cb9eb1 Mon Sep 17 00:00:00 2001 From: Jim Toth Date: Tue, 28 Jul 2026 15:23:30 -0400 Subject: [PATCH 03/15] Replace @ardrive/turbo-sdk with a direct ANS-104 upload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ArDrive left Arweave, and the SDK was doing very little here — sign a data item, POST it — while costing a great deal. What it dragged in, all of it now gone from the tree: * @permaweb/aoconnect 0.0.57, bundled inside the SDK. Older than any pin this migration removed, and it carries third-party default endpoints. So the "aoconnect removed from every service" claim was true of our code and false of the dependency tree. * The entire Solana payment stack — @solana/spl-token, @solana/buffer-layout-utils, bigint-buffer — inherited purely to upload to Arweave. `npm audit` drops from 66/67/65 to 53/54/52 across the three. The wire format is the one publish-module.ts already proved: POST the raw signed item to `/~bundler@1.0/tx`. That path is served both by up.arweave.net — it is HyperBEAM's own default `bundler_ans104` target, see dev_arweave.erl post_tx/4 — and by our own node. So moving to self-hosted bundling later is a BUNDLER_NODE change, not a rewrite; the commented-out line above it in each HCL records the two prerequisites (edge-allow /~bundler@1.0/tx, faff-allow-list the signer). BUNDLER_GATEWAY and BUNDLER_NETWORK are dropped — both existed only to configure Turbo. The three copies of this service had drifted into three distinct implementations differing by one line; they are byte-identical again. --- operations/relay-rewards-controller-live.hcl | 7 +- operations/relay-rewards-controller-stage.hcl | 7 +- package-lock.json | 1260 +---------------- package.json | 1 - src/bundling/bundling.service.ts | 100 +- 5 files changed, 111 insertions(+), 1264 deletions(-) diff --git a/operations/relay-rewards-controller-live.hcl b/operations/relay-rewards-controller-live.hcl index e543891..edb9428 100644 --- a/operations/relay-rewards-controller-live.hcl +++ b/operations/relay-rewards-controller-live.hcl @@ -38,9 +38,9 @@ job "relay-rewards-controller-live" { REDIS_MODE="sentinel" REDIS_MASTER_NAME="relay-rewards-controller-live-redis-master" USE_HODLER = "true" - BUNDLER_GATEWAY="https://ar.anyone.tech" - # BUNDLER_NODE="https://ar.anyone.tech/bundler" - BUNDLER_NODE="https://upload.ardrive.io" + # Our own node once /~bundler@1.0/tx is edge-allowed + the signer is faff-allow-listed: + # BUNDLER_NODE="https://hb.anyone.tech" + BUNDLER_NODE="https://up.arweave.net" GEODATADIR="/geo-ip-db/data" GEOTMPDIR="/geo-ip-db/tmp" ROUND_PERIOD_SECONDS="3600" @@ -69,7 +69,6 @@ job "relay-rewards-controller-live" { {{with secret "kv/live-protocol/relay-rewards-controller-live"}} RELAY_REWARDS_CONTROLLER_KEY="{{.Data.data.RELAY_REWARDS_CONTROLLER_KEY}}" - BUNDLER_NETWORK="{{.Data.data.BUNDLER_NETWORK}}" BUNDLER_CONTROLLER_KEY="{{.Data.data.RELAY_REWARDS_CONTROLLER_KEY}}" JSON_RPC="{{.Data.data.JSON_RPC}}" diff --git a/operations/relay-rewards-controller-stage.hcl b/operations/relay-rewards-controller-stage.hcl index a2ff97d..26818bf 100644 --- a/operations/relay-rewards-controller-stage.hcl +++ b/operations/relay-rewards-controller-stage.hcl @@ -38,9 +38,9 @@ job "relay-rewards-controller-stage" { REDIS_MODE="sentinel" REDIS_MASTER_NAME="relay-rewards-controller-stage-redis-master" USE_HODLER = "true" - BUNDLER_GATEWAY="https://ar.anyone.tech" - # BUNDLER_NODE="https://ar.anyone.tech/bundler" - BUNDLER_NODE="https://upload.ardrive.io" + # Our own node once /~bundler@1.0/tx is edge-allowed + the signer is faff-allow-listed: + # BUNDLER_NODE="https://hb.anyone.tech" + BUNDLER_NODE="https://up.arweave.net" GEODATADIR="/geo-ip-db/data" GEOTMPDIR="/geo-ip-db/tmp" ROUND_PERIOD_SECONDS="900" @@ -69,7 +69,6 @@ job "relay-rewards-controller-stage" { {{with secret "kv/stage-protocol/relay-rewards-controller-stage"}} RELAY_REWARDS_CONTROLLER_KEY="{{.Data.data.RELAY_REWARDS_CONTROLLER_KEY}}" - BUNDLER_NETWORK="{{.Data.data.BUNDLER_NETWORK}}" BUNDLER_CONTROLLER_KEY="{{.Data.data.RELAY_REWARDS_CONTROLLER_KEY}}" JSON_RPC="{{.Data.data.JSON_RPC}}" diff --git a/package-lock.json b/package-lock.json index c288962..5881df8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,6 @@ "license": "AGPL-3.0-only", "dependencies": { "@anyone-protocol/ao-client": "github:anyone-protocol/ao-client#v0.1.2", - "@ardrive/turbo-sdk": "^1.22.0", "@dha-team/arbundles": "^1.0.4", "@nestjs/axios": "^4.0.1", "@nestjs/bullmq": "^11.0.1", @@ -272,59 +271,6 @@ "@dha-team/arbundles": "^1.0.3" } }, - "node_modules/@ardrive/turbo-sdk": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/@ardrive/turbo-sdk/-/turbo-sdk-1.30.0.tgz", - "integrity": "sha512-jx3HRxXLsID/cSv9BDLEbg1aVOHc/9m5Drg/SulaiKGLJT+XPaqI+KmcDVS55nwaOU1q+L/6b7VOFXVT5G6JNw==", - "license": "Apache-2.0", - "dependencies": { - "@cosmjs/proto-signing": "^0.33.1", - "@cosmjs/stargate": "^0.33.1", - "@dha-team/arbundles": "^1.0.1", - "@ethersproject/signing-key": "^5.7.0", - "@permaweb/aoconnect": "0.0.57", - "@solana/web3.js": "^1.91.7", - "arweave": "^1.15.1", - "axios": "^1.9.0", - "axios-retry": "^3.7.0", - "bignumber.js": "^9.1.2", - "bs58": "^5.0.0", - "commander": "^12.1.0", - "ethers": "^6.12.0", - "eventemitter3": "^5.0.1", - "mime-types": "^2.1.35", - "plimit-lit": "^3.0.1", - "prompts": "^2.4.2", - "starknet": "^6.11.0", - "tweetnacl": "^1.0.3", - "winston": "^3.14.1" - }, - "bin": { - "turbo": "lib/esm/cli/cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@ardrive/turbo-sdk/node_modules/@permaweb/aoconnect": { - "version": "0.0.57", - "resolved": "https://registry.npmjs.org/@permaweb/aoconnect/-/aoconnect-0.0.57.tgz", - "integrity": "sha512-l1+47cZuQ8pOIMOdRXymcegCmefXjqR8Bc2MY6jIzWv9old/tG6mfCue2W1QviGyhjP3zEVQgr7YofkY2lq35Q==", - "dependencies": { - "@permaweb/ao-scheduler-utils": "~0.0.20", - "buffer": "^6.0.3", - "debug": "^4.3.5", - "hyper-async": "^1.1.2", - "mnemonist": "^0.39.8", - "ramda": "^0.30.1", - "warp-arbundles": "^1.0.4", - "zod": "^3.23.8" - }, - "engines": { - "node": ">=18", - "yarn": "please-use-npm" - } - }, "node_modules/@babel/code-frame": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", @@ -796,15 +742,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/runtime": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.2.tgz", - "integrity": "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/template": { "version": "7.27.2", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", @@ -871,159 +808,6 @@ "node": ">=0.1.90" } }, - "node_modules/@cosmjs/amino": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.33.1.tgz", - "integrity": "sha512-WfWiBf2EbIWpwKG9AOcsIIkR717SY+JdlXM/SL/bI66BdrhniAF+/ZNis9Vo9HF6lP2UU5XrSmFA4snAvEgdrg==", - "license": "Apache-2.0", - "dependencies": { - "@cosmjs/crypto": "^0.33.1", - "@cosmjs/encoding": "^0.33.1", - "@cosmjs/math": "^0.33.1", - "@cosmjs/utils": "^0.33.1" - } - }, - "node_modules/@cosmjs/crypto": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.33.1.tgz", - "integrity": "sha512-U4kGIj/SNBzlb2FGgA0sMR0MapVgJUg8N+oIAiN5+vl4GZ3aefmoL1RDyTrFS/7HrB+M+MtHsxC0tvEu4ic/zA==", - "license": "Apache-2.0", - "dependencies": { - "@cosmjs/encoding": "^0.33.1", - "@cosmjs/math": "^0.33.1", - "@cosmjs/utils": "^0.33.1", - "@noble/hashes": "^1", - "bn.js": "^5.2.0", - "elliptic": "^6.6.1", - "libsodium-wrappers-sumo": "^0.7.11" - } - }, - "node_modules/@cosmjs/encoding": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.33.1.tgz", - "integrity": "sha512-nuNxf29fUcQE14+1p//VVQDwd1iau5lhaW/7uMz7V2AH3GJbFJoJVaKvVyZvdFk+Cnu+s3wCqgq4gJkhRCJfKw==", - "license": "Apache-2.0", - "dependencies": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - } - }, - "node_modules/@cosmjs/json-rpc": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.33.1.tgz", - "integrity": "sha512-T6VtWzecpmuTuMRGZWuBYHsMF/aznWCYUt/cGMWNSz7DBPipVd0w774PKpxXzpEbyt5sr61NiuLXc+Az15S/Cw==", - "license": "Apache-2.0", - "dependencies": { - "@cosmjs/stream": "^0.33.1", - "xstream": "^11.14.0" - } - }, - "node_modules/@cosmjs/math": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.33.1.tgz", - "integrity": "sha512-ytGkWdKFCPiiBU5eqjHNd59djPpIsOjbr2CkNjlnI1Zmdj+HDkSoD9MUGpz9/RJvRir5IvsXqdE05x8EtoQkJA==", - "license": "Apache-2.0", - "dependencies": { - "bn.js": "^5.2.0" - } - }, - "node_modules/@cosmjs/proto-signing": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.33.1.tgz", - "integrity": "sha512-Sv4W+MxX+0LVnd+2rU4Fw1HRsmMwSVSYULj7pRkij3wnPwUlTVoJjmKFgKz13ooIlfzPrz/dnNjGp/xnmXChFQ==", - "license": "Apache-2.0", - "dependencies": { - "@cosmjs/amino": "^0.33.1", - "@cosmjs/crypto": "^0.33.1", - "@cosmjs/encoding": "^0.33.1", - "@cosmjs/math": "^0.33.1", - "@cosmjs/utils": "^0.33.1", - "cosmjs-types": "^0.9.0" - } - }, - "node_modules/@cosmjs/socket": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.33.1.tgz", - "integrity": "sha512-KzAeorten6Vn20sMiM6NNWfgc7jbyVo4Zmxev1FXa5EaoLCZy48cmT3hJxUJQvJP/lAy8wPGEjZ/u4rmF11x9A==", - "license": "Apache-2.0", - "dependencies": { - "@cosmjs/stream": "^0.33.1", - "isomorphic-ws": "^4.0.1", - "ws": "^7", - "xstream": "^11.14.0" - } - }, - "node_modules/@cosmjs/socket/node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@cosmjs/stargate": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.33.1.tgz", - "integrity": "sha512-CnJ1zpSiaZgkvhk+9aTp5IPmgWn2uo+cNEBN8VuD9sD6BA0V4DMjqe251cNFLiMhkGtiE5I/WXFERbLPww3k8g==", - "license": "Apache-2.0", - "dependencies": { - "@cosmjs/amino": "^0.33.1", - "@cosmjs/encoding": "^0.33.1", - "@cosmjs/math": "^0.33.1", - "@cosmjs/proto-signing": "^0.33.1", - "@cosmjs/stream": "^0.33.1", - "@cosmjs/tendermint-rpc": "^0.33.1", - "@cosmjs/utils": "^0.33.1", - "cosmjs-types": "^0.9.0" - } - }, - "node_modules/@cosmjs/stream": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.33.1.tgz", - "integrity": "sha512-bMUvEENjeQPSTx+YRzVsWT1uFIdHRcf4brsc14SOoRQ/j5rOJM/aHfsf/BmdSAnYbdOQ3CMKj/8nGAQ7xUdn7w==", - "license": "Apache-2.0", - "dependencies": { - "xstream": "^11.14.0" - } - }, - "node_modules/@cosmjs/tendermint-rpc": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.33.1.tgz", - "integrity": "sha512-22klDFq2MWnf//C8+rZ5/dYatr6jeGT+BmVbutXYfAK9fmODbtFcumyvB6uWaEORWfNukl8YK1OLuaWezoQvxA==", - "license": "Apache-2.0", - "dependencies": { - "@cosmjs/crypto": "^0.33.1", - "@cosmjs/encoding": "^0.33.1", - "@cosmjs/json-rpc": "^0.33.1", - "@cosmjs/math": "^0.33.1", - "@cosmjs/socket": "^0.33.1", - "@cosmjs/stream": "^0.33.1", - "@cosmjs/utils": "^0.33.1", - "axios": "^1.6.0", - "readonly-date": "^1.0.0", - "xstream": "^11.14.0" - } - }, - "node_modules/@cosmjs/utils": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.33.1.tgz", - "integrity": "sha512-UnLHDY6KMmC+UXf3Ufyh+onE19xzEXjT4VZ504Acmk4PXxqyvG4cCPprlKUFnGUX7f0z8Or9MAOHXBx41uHBcg==", - "license": "Apache-2.0" - }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -2144,15 +1928,6 @@ "@ethersproject/strings": "^5.8.0" } }, - "node_modules/@fastify/busboy": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", - "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", - "license": "MIT", - "engines": { - "node": ">=14" - } - }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -3811,21 +3586,6 @@ } } }, - "node_modules/@noble/curves": { - "version": "1.9.6", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.6.tgz", - "integrity": "sha512-GIKz/j99FRthB8icyJQA51E8Uk5hXmdyThjgQXRKiv9h0zeRlzSCLIzFw6K1LotZ3XuB7yzlf76qk7uBmTdFqA==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.8.0" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@noble/ed25519": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.6.1.tgz", @@ -3842,6 +3602,7 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "dev": true, "license": "MIT", "engines": { "node": "^14.21.3 || >=16" @@ -3914,19 +3675,6 @@ "@noble/hashes": "^1.1.5" } }, - "node_modules/@permaweb/ao-scheduler-utils": { - "version": "0.0.27", - "resolved": "https://registry.npmjs.org/@permaweb/ao-scheduler-utils/-/ao-scheduler-utils-0.0.27.tgz", - "integrity": "sha512-KvdSDf/J65zCy7ymo9WfxNIv57Qy3omdL6uD6v66cV6h2KTUnyjhQJ6QqlXz8C5uIn9Zjm3Bu03NIjUKrwut2g==", - "dependencies": { - "lru-cache": "^10.2.2", - "ramda": "^0.30.0", - "zod": "^3.23.5" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/@pkgr/core": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", @@ -3957,67 +3705,6 @@ "@randlabs/communication-bridge": "^1.0.0" } }, - "node_modules/@scure/base": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.1.tgz", - "integrity": "sha512-DGmGtC8Tt63J5GfHgfl5CuAXh96VF/LD8K9Hr/Gv0J2lAoRGlPOMpqMpMbCTOoOJMZCk2Xt+DskdDyn6dEFdzQ==", - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/starknet": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@scure/starknet/-/starknet-1.1.0.tgz", - "integrity": "sha512-83g3M6Ix2qRsPN4wqLDqiRZ2GBNbjVWfboJE/9UjfG+MHr6oDSu/CWgy8hsBSJejr09DkkL+l0Ze4KVrlCIdtQ==", - "license": "MIT", - "dependencies": { - "@noble/curves": "~1.7.0", - "@noble/hashes": "~1.6.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/starknet/node_modules/@noble/curves": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.7.0.tgz", - "integrity": "sha512-UTMhXK9SeDhFJVrHeUJ5uZlI6ajXg10O6Ddocf9S6GjbSBVZsJo88HzKwXznNfGpMTRDyJkqMjNDPYgf0qFWnw==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.6.0" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/starknet/node_modules/@noble/curves/node_modules/@noble/hashes": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.6.0.tgz", - "integrity": "sha512-YUULf0Uk4/mAA89w+k3+yUYh6NrEvxZa5T6SY3wlMvE2chHkxFUUIDI8/XW1QSC357iA5pSnqt7XEhvFOqmDyQ==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/starknet/node_modules/@noble/hashes": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.6.1.tgz", - "integrity": "sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -4045,127 +3732,6 @@ "@sinonjs/commons": "^3.0.0" } }, - "node_modules/@solana/buffer-layout": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz", - "integrity": "sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==", - "license": "MIT", - "dependencies": { - "buffer": "~6.0.3" - }, - "engines": { - "node": ">=5.10" - } - }, - "node_modules/@solana/codecs-core": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.3.0.tgz", - "integrity": "sha512-oG+VZzN6YhBHIoSKgS5ESM9VIGzhWjEHEGNPSibiDTxFhsFWxNaz8LbMDPjBUE69r9wmdGLkrQ+wVPbnJcZPvw==", - "license": "MIT", - "dependencies": { - "@solana/errors": "2.3.0" - }, - "engines": { - "node": ">=20.18.0" - }, - "peerDependencies": { - "typescript": ">=5.3.3" - } - }, - "node_modules/@solana/codecs-numbers": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.3.0.tgz", - "integrity": "sha512-jFvvwKJKffvG7Iz9dmN51OGB7JBcy2CJ6Xf3NqD/VP90xak66m/Lg48T01u5IQ/hc15mChVHiBm+HHuOFDUrQg==", - "license": "MIT", - "dependencies": { - "@solana/codecs-core": "2.3.0", - "@solana/errors": "2.3.0" - }, - "engines": { - "node": ">=20.18.0" - }, - "peerDependencies": { - "typescript": ">=5.3.3" - } - }, - "node_modules/@solana/errors": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-2.3.0.tgz", - "integrity": "sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==", - "license": "MIT", - "dependencies": { - "chalk": "^5.4.1", - "commander": "^14.0.0" - }, - "bin": { - "errors": "bin/cli.mjs" - }, - "engines": { - "node": ">=20.18.0" - }, - "peerDependencies": { - "typescript": ">=5.3.3" - } - }, - "node_modules/@solana/errors/node_modules/commander": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.0.tgz", - "integrity": "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==", - "license": "MIT", - "engines": { - "node": ">=20" - } - }, - "node_modules/@solana/web3.js": { - "version": "1.98.4", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.98.4.tgz", - "integrity": "sha512-vv9lfnvjUsRiq//+j5pBdXig0IQdtzA0BRZ3bXEP4KaIyF1CcaydWqgyzQgfZMNIsWNWmG+AUHwPy4AHOD6gpw==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.25.0", - "@noble/curves": "^1.4.2", - "@noble/hashes": "^1.4.0", - "@solana/buffer-layout": "^4.0.1", - "@solana/codecs-numbers": "^2.1.0", - "agentkeepalive": "^4.5.0", - "bn.js": "^5.2.1", - "borsh": "^0.7.0", - "bs58": "^4.0.1", - "buffer": "6.0.3", - "fast-stable-stringify": "^1.0.0", - "jayson": "^4.1.1", - "node-fetch": "^2.7.0", - "rpc-websockets": "^9.0.2", - "superstruct": "^2.0.2" - } - }, - "node_modules/@solana/web3.js/node_modules/base-x": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", - "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==", - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/@solana/web3.js/node_modules/bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "license": "MIT", - "dependencies": { - "base-x": "^3.0.2" - } - }, - "node_modules/@swc/helpers": { - "version": "0.5.17", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", - "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.8.0" - } - }, "node_modules/@tokenizer/inflate": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.2.7.tgz", @@ -4278,6 +3844,7 @@ "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" @@ -4536,12 +4103,6 @@ "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==", "license": "MIT" }, - "node_modules/@types/uuid": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", - "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", - "license": "MIT" - }, "node_modules/@types/webidl-conversions": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", @@ -4557,15 +4118,6 @@ "@types/webidl-conversions": "*" } }, - "node_modules/@types/ws": { - "version": "7.4.7", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", - "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/yargs": { "version": "17.0.33", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", @@ -4993,21 +4545,6 @@ "dev": true, "license": "Apache-2.0" }, - "node_modules/abi-wan-kanabi": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/abi-wan-kanabi/-/abi-wan-kanabi-2.2.4.tgz", - "integrity": "sha512-0aA81FScmJCPX+8UvkXLki3X1+yPQuWxEkqXBVKltgPAK79J+NB+Lp5DouMXa7L6f+zcRlIA/6XO7BN/q9fnvg==", - "license": "ISC", - "dependencies": { - "ansicolors": "^0.3.2", - "cardinal": "^2.1.1", - "fs-extra": "^10.0.0", - "yargs": "^17.7.2" - }, - "bin": { - "generate": "dist/generate.js" - } - }, "node_modules/accepts": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", @@ -5097,18 +4634,6 @@ "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", "license": "MIT" }, - "node_modules/agentkeepalive": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", - "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", - "license": "MIT", - "dependencies": { - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, "node_modules/ajv": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", @@ -5268,6 +4793,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -5286,12 +4812,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/ansicolors": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", - "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", - "license": "MIT" - }, "node_modules/ansis": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.2.0.tgz", @@ -5438,22 +4958,13 @@ "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", "license": "MIT", + "peer": true, "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, - "node_modules/axios-retry": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.9.1.tgz", - "integrity": "sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.15.4", - "is-retry-allowed": "^2.2.0" - } - }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -5639,12 +5150,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, - "node_modules/base-x": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.1.tgz", - "integrity": "sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw==", - "license": "MIT" - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -5782,35 +5287,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/borsh": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz", - "integrity": "sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==", - "license": "Apache-2.0", - "dependencies": { - "bn.js": "^5.2.0", - "bs58": "^4.0.0", - "text-encoding-utf-8": "^1.0.2" - } - }, - "node_modules/borsh/node_modules/base-x": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", - "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==", - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/borsh/node_modules/bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "license": "MIT", - "dependencies": { - "base-x": "^3.0.2" - } - }, "node_modules/brace-expansion": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", @@ -5887,15 +5363,6 @@ "node": ">= 6" } }, - "node_modules/bs58": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", - "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", - "license": "MIT", - "dependencies": { - "base-x": "^4.0.0" - } - }, "node_modules/bser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", @@ -5934,6 +5401,7 @@ } ], "license": "MIT", + "optional": true, "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -6060,31 +5528,6 @@ ], "license": "CC-BY-4.0" }, - "node_modules/cardinal": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", - "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", - "license": "MIT", - "dependencies": { - "ansicolors": "~0.3.2", - "redeyed": "~2.1.0" - }, - "bin": { - "cdl": "bin/cdl.js" - } - }, - "node_modules/chalk": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.5.0.tgz", - "integrity": "sha512-1tm8DTaJhPBG3bIkVeZt1iZM9GfSX2lzOeDVZH9R9ffRHpmHvxZ/QhgQH/aDTkswQVt+YHdXAdS/In/30OjCbg==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", @@ -6207,6 +5650,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", @@ -6221,6 +5665,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -6236,6 +5681,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -6248,12 +5694,14 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, "license": "MIT" }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -6362,15 +5810,6 @@ "node": ">= 0.8" } }, - "node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, "node_modules/comment-json": { "version": "4.2.5", "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.5.tgz", @@ -6552,12 +5991,6 @@ } } }, - "node_modules/cosmjs-types": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.9.0.tgz", - "integrity": "sha512-MN/yUe6mkJwHnCFfsNPeCfXVhyxHYW6c/xDUzrSbBycYzw++XvWDMJArXp2pLdgD6FQ8DW79vkPjeNKVrXaHeQ==", - "license": "Apache-2.0" - }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -6740,52 +6173,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delay": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", - "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -6958,6 +6345,7 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, "license": "MIT" }, "node_modules/enabled": { @@ -7051,25 +6439,11 @@ "node": ">= 0.4" } }, - "node_modules/es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "license": "MIT" - }, - "node_modules/es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", - "license": "MIT", - "dependencies": { - "es6-promise": "^4.0.3" - } - }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -7388,6 +6762,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", @@ -7552,12 +6927,6 @@ } } }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "license": "MIT" - }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -7695,14 +7064,6 @@ "node": ">= 0.6" } }, - "node_modules/eyes": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", - "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==", - "engines": { - "node": "> 0.1.90" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -7767,12 +7128,6 @@ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", "license": "MIT" }, - "node_modules/fast-stable-stringify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz", - "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==", - "license": "MIT" - }, "node_modules/fast-uri": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", @@ -7825,16 +7180,6 @@ "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", "license": "MIT" }, - "node_modules/fetch-cookie": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-3.0.1.tgz", - "integrity": "sha512-ZGXe8Y5Z/1FWqQ9q/CrJhkUD73DyBU9VF0hBQmEO/wPHe4A9PKTjplFDLeFX8aOsYypZUcX5Ji/eByn3VCVO3Q==", - "license": "Unlicense", - "dependencies": { - "set-cookie-parser": "^2.4.8", - "tough-cookie": "^4.0.0" - } - }, "node_modules/fflate": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", @@ -7957,6 +7302,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=4.0" }, @@ -8127,6 +7473,7 @@ "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", @@ -8255,6 +7602,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" @@ -8387,22 +7735,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "license": "MIT", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -8419,6 +7751,7 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, "license": "ISC" }, "node_modules/graphemer": { @@ -8490,18 +7823,6 @@ "node": ">=8" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -8606,21 +7927,6 @@ "node": ">=10.17.0" } }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.0.0" - } - }, - "node_modules/hyper-async": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/hyper-async/-/hyper-async-1.1.2.tgz", - "integrity": "sha512-cnpOgKa+5FZOaccTtjduac1FrZuSc38/ftCp3vYJdUMt+7c+uvGDKLDK4MTNK8D3aFjIeveVrPcSgUPvzZLopg==", - "license": "MIT" - }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -8812,6 +8118,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -8866,18 +8173,6 @@ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", "license": "MIT" }, - "node_modules/is-retry-allowed": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", - "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -8917,25 +8212,6 @@ "dev": true, "license": "ISC" }, - "node_modules/isomorphic-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", - "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", - "license": "MIT", - "dependencies": { - "node-fetch": "^2.6.1", - "whatwg-fetch": "^3.4.1" - } - }, - "node_modules/isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", - "license": "MIT", - "peerDependencies": { - "ws": "*" - } - }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -9009,89 +8285,21 @@ "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/iterare": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/iterare/-/iterare-1.2.1.tgz", - "integrity": "sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==", - "license": "ISC", - "engines": { - "node": ">=6" - } - }, - "node_modules/jayson": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/jayson/-/jayson-4.2.0.tgz", - "integrity": "sha512-VfJ9t1YLwacIubLhONk0KFeosUBwstRWQ0IRT1KDjEjnVnSOVHC3uwugyV7L0c7R9lpVyrUGT2XWiBA1UTtpyg==", - "license": "MIT", - "dependencies": { - "@types/connect": "^3.4.33", - "@types/node": "^12.12.54", - "@types/ws": "^7.4.4", - "commander": "^2.20.3", - "delay": "^5.0.0", - "es6-promisify": "^5.0.0", - "eyes": "^0.1.8", - "isomorphic-ws": "^4.0.1", - "json-stringify-safe": "^5.0.1", - "stream-json": "^1.9.1", - "uuid": "^8.3.2", - "ws": "^7.5.10" - }, - "bin": { - "jayson": "bin/jayson.js" + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/jayson/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "license": "MIT" - }, - "node_modules/jayson/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "license": "MIT" - }, - "node_modules/jayson/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/jayson/node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "license": "MIT", + "node_modules/iterare": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/iterare/-/iterare-1.2.1.tgz", + "integrity": "sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==", + "license": "ISC", "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "node": ">=6" } }, "node_modules/jest": { @@ -10642,12 +9850,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "license": "ISC" - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -10672,6 +9874,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, "license": "MIT", "dependencies": { "universalify": "^2.0.0" @@ -10718,6 +9921,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -10762,21 +9966,6 @@ "node": ">= 0.8.0" } }, - "node_modules/libsodium-sumo": { - "version": "0.7.15", - "resolved": "https://registry.npmjs.org/libsodium-sumo/-/libsodium-sumo-0.7.15.tgz", - "integrity": "sha512-5tPmqPmq8T8Nikpm1Nqj0hBHvsLFCXvdhBFV7SGOitQPZAA6jso8XoL0r4L7vmfKXr486fiQInvErHtEvizFMw==", - "license": "ISC" - }, - "node_modules/libsodium-wrappers-sumo": { - "version": "0.7.15", - "resolved": "https://registry.npmjs.org/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.7.15.tgz", - "integrity": "sha512-aSWY8wKDZh5TC7rMvEdTHoyppVq/1dTSAeAR7H6pzd6QRT3vQWcT5pGwCotLcpPEOLXX6VvqihSPkpEhYAjANA==", - "license": "ISC", - "dependencies": { - "libsodium-sumo": "^0.7.15" - } - }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -10963,18 +10152,6 @@ "node": ">=0.1.90" } }, - "node_modules/lossless-json": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lossless-json/-/lossless-json-4.1.1.tgz", - "integrity": "sha512-HusN80C0ohtT9kOHQH7EuUaqzRQsnekpa+2ot8OzvW0iC08dq/YtM/7uKwwajldQsCrHyC8q9fz3t3L+TmDltA==", - "license": "MIT" - }, - "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "license": "ISC" - }, "node_modules/luxon": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.1.tgz", @@ -11234,15 +10411,6 @@ "mkdirp": "bin/cmd.js" } }, - "node_modules/mnemonist": { - "version": "0.39.8", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.8.tgz", - "integrity": "sha512-vyWo2K3fjrUw8YeeZ1zF0fy6Mu59RHokURlld8ymdUPjMlD9EC9ov1/YPqTgqRvUN9nTr3Gqfz29LYAmu0PHPQ==", - "license": "MIT", - "dependencies": { - "obliterator": "^2.0.1" - } - }, "node_modules/mongodb": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.18.0.tgz", @@ -11514,48 +10682,6 @@ "lodash": "^4.17.21" } }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/node-gyp-build": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", @@ -11641,21 +10767,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/obliterator": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.5.tgz", - "integrity": "sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==", - "license": "MIT" - }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -11839,12 +10950,6 @@ "node": ">=6" } }, - "node_modules/pako": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", - "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", - "license": "(MIT AND Zlib)" - }, "node_modules/papi": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/papi/-/papi-1.1.2.tgz", @@ -12084,18 +11189,6 @@ "node": ">=8" } }, - "node_modules/plimit-lit": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/plimit-lit/-/plimit-lit-3.0.1.tgz", - "integrity": "sha512-EyTTdP5LMX6WbHihG8R9w6DS+c3pyMpeKooOFuGDCyuVBogQjYNtoYwKLRD6hM1+VkHzGcfIuyLoWi6l5JA3iA==", - "license": "MIT", - "dependencies": { - "queue-lit": "^3.0.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/pluralize": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", @@ -12171,6 +11264,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, "license": "MIT", "dependencies": { "kleur": "^3.0.3", @@ -12197,19 +11291,8 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, - "node_modules/psl": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", - "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", "license": "MIT", - "dependencies": { - "punycode": "^2.3.1" - }, - "funding": { - "url": "https://github.com/sponsors/lupomontero" - } + "peer": true }, "node_modules/punycode": { "version": "2.3.1", @@ -12256,16 +11339,8 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "license": "MIT" - }, - "node_modules/queue-lit": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/queue-lit/-/queue-lit-3.0.0.tgz", - "integrity": "sha512-iyVL2X5G58kICVGLW/nseYmdHxBoAp2Gav16H23NPtIllyEJ+UheHlYZqBjO+lJHRYoZRSrX7chH8tMrH9MB/A==", "license": "MIT", - "engines": { - "node": ">=18" - } + "optional": true }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -12288,16 +11363,6 @@ ], "license": "MIT" }, - "node_modules/ramda": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", - "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/ramda" - } - }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -12383,21 +11448,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/readonly-date": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/readonly-date/-/readonly-date-1.0.0.tgz", - "integrity": "sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ==", - "license": "Apache-2.0" - }, - "node_modules/redeyed": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", - "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", - "license": "MIT", - "dependencies": { - "esprima": "~4.0.0" - } - }, "node_modules/redis-errors": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", @@ -12441,6 +11491,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -12460,7 +11511,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/resolve": { "version": "1.22.10", @@ -12630,47 +11682,6 @@ "node": ">= 18" } }, - "node_modules/rpc-websockets": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-9.1.3.tgz", - "integrity": "sha512-I+kNjW0udB4Fetr3vvtRuYZJS0PcSPyyvBcH5sDdoV8DFs5E4W2pTr7aiMlKfPxANTClP9RlqCPolj9dd5MsEA==", - "license": "LGPL-3.0-only", - "dependencies": { - "@swc/helpers": "^0.5.11", - "@types/uuid": "^8.3.4", - "@types/ws": "^8.2.2", - "buffer": "^6.0.3", - "eventemitter3": "^5.0.1", - "uuid": "^8.3.2", - "ws": "^8.5.0" - }, - "funding": { - "type": "paypal", - "url": "https://paypal.me/kozjak" - }, - "optionalDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - } - }, - "node_modules/rpc-websockets/node_modules/@types/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/rpc-websockets/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -12899,12 +11910,6 @@ "node": ">= 18" } }, - "node_modules/set-cookie-parser": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", - "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", - "license": "MIT" - }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -13044,6 +12049,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, "license": "MIT" }, "node_modules/slash": { @@ -13141,59 +12147,6 @@ "license": "MIT", "peer": true }, - "node_modules/starknet": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/starknet/-/starknet-6.24.1.tgz", - "integrity": "sha512-g7tiCt73berhcNi41otlN3T3kxZnIvZhMi8WdC21Y6GC6zoQgbI2z1t7JAZF9c4xZiomlanwVnurcpyfEdyMpg==", - "license": "MIT", - "dependencies": { - "@noble/curves": "1.7.0", - "@noble/hashes": "1.6.0", - "@scure/base": "1.2.1", - "@scure/starknet": "1.1.0", - "abi-wan-kanabi": "^2.2.3", - "fetch-cookie": "~3.0.0", - "isomorphic-fetch": "~3.0.0", - "lossless-json": "^4.0.1", - "pako": "^2.0.4", - "starknet-types-07": "npm:@starknet-io/types-js@^0.7.10", - "ts-mixer": "^6.0.3" - } - }, - "node_modules/starknet-types-07": { - "name": "@starknet-io/types-js", - "version": "0.7.10", - "resolved": "https://registry.npmjs.org/@starknet-io/types-js/-/types-js-0.7.10.tgz", - "integrity": "sha512-1VtCqX4AHWJlRRSYGSn+4X1mqolI1Tdq62IwzoU2vUuEE72S1OlEeGhpvd6XsdqXcfHmVzYfj8k1XtKBQqwo9w==", - "license": "MIT" - }, - "node_modules/starknet/node_modules/@noble/curves": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.7.0.tgz", - "integrity": "sha512-UTMhXK9SeDhFJVrHeUJ5uZlI6ajXg10O6Ddocf9S6GjbSBVZsJo88HzKwXznNfGpMTRDyJkqMjNDPYgf0qFWnw==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.6.0" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/starknet/node_modules/@noble/hashes": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.6.0.tgz", - "integrity": "sha512-YUULf0Uk4/mAA89w+k3+yUYh6NrEvxZa5T6SY3wlMvE2chHkxFUUIDI8/XW1QSC357iA5pSnqt7XEhvFOqmDyQ==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/statuses": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", @@ -13203,12 +12156,6 @@ "node": ">= 0.8" } }, - "node_modules/stream-chain": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz", - "integrity": "sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==", - "license": "BSD-3-Clause" - }, "node_modules/stream-chunker": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/stream-chunker/-/stream-chunker-1.2.8.tgz", @@ -13219,15 +12166,6 @@ "through2": "~2.0.0" } }, - "node_modules/stream-json": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/stream-json/-/stream-json-1.9.1.tgz", - "integrity": "sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==", - "license": "BSD-3-Clause", - "dependencies": { - "stream-chain": "^2.2.5" - } - }, "node_modules/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", @@ -13263,6 +12201,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -13277,6 +12216,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -13355,15 +12295,6 @@ "node": ">=14.18.0" } }, - "node_modules/superstruct": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-2.0.2.tgz", - "integrity": "sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==", - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/supertest": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.1.4.tgz", @@ -13634,11 +12565,6 @@ "node": "*" } }, - "node_modules/text-encoding-utf-8": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", - "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" - }, "node_modules/text-hex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", @@ -13755,30 +12681,6 @@ "url": "https://github.com/sponsors/Borewit" } }, - "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", - "license": "BSD-3-Clause", - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/tr46": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", @@ -13953,12 +12855,6 @@ "dev": true, "license": "MIT" }, - "node_modules/ts-mixer": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz", - "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==", - "license": "MIT" - }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -14107,7 +13003,8 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "license": "Unlicense" + "license": "Unlicense", + "optional": true }, "node_modules/type-check": { "version": "0.4.0", @@ -14190,6 +13087,7 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -14237,18 +13135,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/undici": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz", - "integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==", - "license": "MIT", - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, - "engines": { - "node": ">=14.0" - } - }, "node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", @@ -14259,6 +13145,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, "license": "MIT", "engines": { "node": ">= 10.0.0" @@ -14319,6 +13206,7 @@ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "license": "MIT", + "optional": true, "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -14385,31 +13273,6 @@ "makeerror": "1.0.12" } }, - "node_modules/warp-arbundles": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/warp-arbundles/-/warp-arbundles-1.0.4.tgz", - "integrity": "sha512-KeRac/EJ7VOK+v5+PSMh2SrzpCKOAFnJICLlqZWt6qPkDCzVwcrNE5wFxOlEk5U170ewMDAB3e86UHUblevXpw==", - "license": "ISC", - "dependencies": { - "arweave": "^1.13.7", - "base64url": "^3.0.1", - "buffer": "^6.0.3", - "warp-isomorphic": "^1.0.7" - } - }, - "node_modules/warp-isomorphic": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/warp-isomorphic/-/warp-isomorphic-1.0.7.tgz", - "integrity": "sha512-fXHbUXwdYqPm9fRPz8mjv5ndPco09aMQuTe4kXfymzOq8V6F3DLsg9cIafxvjms9/mc6eijzkLBJ63yjEENEjA==", - "license": "MIT", - "dependencies": { - "buffer": "^6.0.3", - "undici": "^5.19.1" - }, - "engines": { - "node": ">=16.8.0" - } - }, "node_modules/watchpack": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", @@ -14574,12 +13437,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/whatwg-fetch": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", - "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", - "license": "MIT" - }, "node_modules/whatwg-url": { "version": "14.2.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", @@ -14776,25 +13633,6 @@ } } }, - "node_modules/xstream": { - "version": "11.14.0", - "resolved": "https://registry.npmjs.org/xstream/-/xstream-11.14.0.tgz", - "integrity": "sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw==", - "license": "MIT", - "dependencies": { - "globalthis": "^1.0.1", - "symbol-observable": "^2.0.3" - } - }, - "node_modules/xstream/node_modules/symbol-observable": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-2.0.3.tgz", - "integrity": "sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA==", - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -14808,6 +13646,7 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, "license": "ISC", "engines": { "node": ">=10" @@ -14824,6 +13663,7 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, "license": "MIT", "dependencies": { "cliui": "^8.0.1", @@ -14842,6 +13682,7 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, "license": "ISC", "engines": { "node": ">=12" @@ -14892,15 +13733,6 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } } } } diff --git a/package.json b/package.json index b8c3f6f..a3861ba 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,6 @@ }, "dependencies": { "@anyone-protocol/ao-client": "github:anyone-protocol/ao-client#v0.1.2", - "@ardrive/turbo-sdk": "^1.22.0", "@dha-team/arbundles": "^1.0.4", "@nestjs/axios": "^4.0.1", "@nestjs/bullmq": "^11.0.1", diff --git a/src/bundling/bundling.service.ts b/src/bundling/bundling.service.ts index 0b8557d..51064aa 100644 --- a/src/bundling/bundling.service.ts +++ b/src/bundling/bundling.service.ts @@ -1,22 +1,34 @@ -import { - EthereumSigner, - TurboAuthenticatedClient, - TurboFactory -} from '@ardrive/turbo-sdk' +import { createData, EthereumSigner } from '@dha-team/arbundles' import { Injectable, Logger } from '@nestjs/common' import { ConfigService } from '@nestjs/config' +import { Wallet } from 'ethers' +/** + * Publishes data to Arweave as a signed ANS-104 DataItem. + * + * Replaces @ardrive/turbo-sdk. ArDrive left Arweave, and the SDK was doing very little + * for us here — sign an item, POST it — while dragging in a Solana payment stack + * (@solana/spl-token -> bigint-buffer, a critical advisory) and its own bundled copy of + * @permaweb/aoconnect 0.0.57, which is older than any pin this migration removed and + * carries third-party default endpoints. + * + * The wire format is the same one publish-module.ts proved: POST the raw signed item to + * `/~bundler@1.0/tx`. That path is served BOTH by up.arweave.net (it is + * HyperBEAM's own default `bundler_ans104` target — see dev_arweave.erl post_tx/4) and by + * our own node, so moving to self-hosted bundling later is a BUNDLER_NODE config change, + * not a code change. + */ @Injectable() export class BundlingService { private readonly logger = new Logger(BundlingService.name) - private readonly bundler: TurboAuthenticatedClient + private readonly signer: EthereumSigner + private readonly bundlerNode: string constructor( readonly config: ConfigService<{ BUNDLER_CONTROLLER_KEY: string BUNDLER_NODE: string - BUNDLER_NETWORK: string }> ) { this.logger.log('Initializing bundling service') @@ -33,49 +45,55 @@ export class BundlingService { if (!bundlerNode) { throw new Error('BUNDLER_NODE is not set!') } + this.bundlerNode = bundlerNode.replace(/\/+$/, '') - const bundlerGateway = config.get( - 'BUNDLER_GATEWAY', - { infer: true } - ) - if (!bundlerNode) { - throw new Error('BUNDLER_GATEWAY is not set!') - } - - const bundlerNetwork = config.get( - 'BUNDLER_NETWORK', - { infer: true } - ) - if (!bundlerNetwork) { - throw new Error('BUNDLER_NETWORK is not set!') - } + // arbundles wants the raw hex; a 0x prefix silently produces a different key. + this.signer = new EthereumSigner(bundlerControllerKey.replace(/^0x/, '')) - const signer = new EthereumSigner(bundlerControllerKey) - this.bundler = TurboFactory.authenticated({ - signer, - gatewayUrl: bundlerGateway, - uploadServiceConfig: { url: bundlerNode } - }) - this.bundler.signer.getNativeAddress().then((address) => { - this.logger.log(`Bundler controller address: ${address}`) - }) - this.logger.log( - `Initialized bundling service` + - ` [${bundlerGateway}, ${bundlerNode}, ${bundlerNetwork}]` + `Initialized bundling service [${this.bundlerNode}]` + + ` as ${new Wallet(bundlerControllerKey).address}` ) } async upload( - data: Buffer, + data: string | Buffer, dataItemOpts: { tags?: { name: string, value: string }[] } - ) { - const signed = await this.bundler.signer.signDataItem({ - fileSizeFactory: () => data.length, - fileStreamFactory: () => Buffer.from(data), - dataItemOpts + ): Promise<{ id: string }> { + const item = createData( + typeof data === 'string' ? data : Buffer.from(data), + this.signer, + { tags: dataItemOpts.tags } + ) + await item.sign(this.signer) + + const response = await fetch(`${this.bundlerNode}/~bundler@1.0/tx`, { + method: 'POST', + headers: { + 'Content-Type': 'application/ans104', + 'codec-device': 'ans104@1.0', + // Required. Without it a HyperBEAM bundler answers with the Hyperbuddy HTML UI + // and HTTP 200, which reads as success and is not. + 'Accept': 'application/json' + }, + // getRaw() hands back a Node Buffer, which does not satisfy BodyInit under the DOM + // lib types even though it is a Uint8Array at runtime. + body: new Uint8Array(item.getRaw()), + signal: AbortSignal.timeout(300_000) }) - return this.bundler.uploadSignedDataItem(signed) + const body = (await response.text()).replace(/\s+/g, ' ') + if (!response.ok || !body.includes('"id"')) { + // A 400 against our own node almost always means this signer is not on the + // bundler's faff allow-list, which is config rather than a code fault. + throw new Error( + `Bundler refused item ${item.id} with HTTP ${response.status}: ` + + body.slice(0, 200) + ) + } + + // The id that settles on Arweave is the SIGNED item id — NOT any id the node may + // report from its local cache. Callers persist this as the summary tx. + return { id: item.id } } } From c5bf127e84afe428e6d1eb07c389b28d2784014a Mon Sep 17 00:00:00 2001 From: Jim Toth Date: Tue, 28 Jul 2026 15:52:32 -0400 Subject: [PATCH 04/15] npm audit fix Non-breaking advisory fixes only; no direct dependency changed, lockfile only. Production vulnerabilities 37 -> 22 (high 13 -> 8). Tracked with `npm audit --omit=dev`: the all-inclusive headline moves the wrong way because the tree now resolves fully and the growth is dev-only tooling (jest, eslint, the Nest CLI) that never ships. Build clean. --- package-lock.json | 1749 ++++++++++++++++++++++----------------------- 1 file changed, 873 insertions(+), 876 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5881df8..5d2072a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -64,36 +64,22 @@ } }, "node_modules/@adraffy/ens-normalize": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", - "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.1.tgz", + "integrity": "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==", "license": "MIT" }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@angular-devkit/core": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.15.tgz", - "integrity": "sha512-pU2RZYX6vhd7uLSdLwPnuBcr0mXJSjp3EgOXKsrlQFQZevc+Qs+2JdXgIElnOT/aDqtRtriDmLlSbtdE8n3ZbA==", + "version": "19.2.27", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.27.tgz", + "integrity": "sha512-3amNzoCVSKd7ah6l6lBQL4onwwJvqvam7FMoQBILrxtW5LB5ezh8gMSPuA4zJjKjoRzf9uoWdlzqv/84I52xZA==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "8.17.1", + "ajv": "8.18.0", "ajv-formats": "3.0.1", "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", + "picomatch": "4.0.4", "rxjs": "7.8.1", "source-map": "0.7.4" }, @@ -122,13 +108,13 @@ } }, "node_modules/@angular-devkit/schematics": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.15.tgz", - "integrity": "sha512-kNOJ+3vekJJCQKWihNmxBkarJzNW09kP5a9E1SRNiQVNOUEeSwcRR0qYotM65nx821gNzjjhJXnAZ8OazWldrg==", + "version": "19.2.27", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.27.tgz", + "integrity": "sha512-/PZmyAlb2NGWPikRRuiWLdfHQd8Wrx6lX4HqvTcaDhlU43M3T0ud4PH2T3QDp7BzHYY92xtD8iPxX2asg67G1A==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "19.2.15", + "@angular-devkit/core": "19.2.27", "jsonc-parser": "3.3.1", "magic-string": "0.30.17", "ora": "5.4.1", @@ -141,14 +127,14 @@ } }, "node_modules/@angular-devkit/schematics-cli": { - "version": "19.2.19", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-19.2.19.tgz", - "integrity": "sha512-7q9UY6HK6sccL9F3cqGRUwKhM7b/XfD2YcVaZ2WD7VMaRlRm85v6mRjSrfKIAwxcQU0UK27kMc79NIIqaHjzxA==", + "version": "19.2.27", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-19.2.27.tgz", + "integrity": "sha512-wHYH6SVXVykhLzovUHtYor3Nl4SpIiITi7r9DQDaKYUD4hpRBx25W6N9eGuakT9Vd5tV/x6wmvQFWQZQwFB7eA==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "19.2.19", - "@angular-devkit/schematics": "19.2.19", + "@angular-devkit/core": "19.2.27", + "@angular-devkit/schematics": "19.2.27", "@inquirer/prompts": "7.3.2", "ansi-colors": "4.1.3", "symbol-observable": "4.0.0", @@ -163,53 +149,6 @@ "yarn": ">= 1.13.0" } }, - "node_modules/@angular-devkit/schematics-cli/node_modules/@angular-devkit/core": { - "version": "19.2.19", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.19.tgz", - "integrity": "sha512-JbLL+4IMLMBgjLZlnPG4lYDfz4zGrJ/s6Aoon321NJKuw1Kb1k5KpFu9dUY0BqLIe8xPQ2UJBpI+xXdK5MXMHQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.17.1", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^4.0.0" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/@angular-devkit/schematics": { - "version": "19.2.19", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.19.tgz", - "integrity": "sha512-J4Jarr0SohdrHcb40gTL4wGPCQ952IMWF1G/MSAQfBAPvA9ZKApYhpxcY7PmehVePve+ujpus1dGsJ7dPxz8Kg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "19.2.19", - "jsonc-parser": "3.3.1", - "magic-string": "0.30.17", - "ora": "5.4.1", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, "node_modules/@angular-devkit/schematics-cli/node_modules/@inquirer/prompts": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.3.2.tgz", @@ -240,16 +179,6 @@ } } }, - "node_modules/@angular-devkit/schematics-cli/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, "node_modules/@angular-devkit/schematics/node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -272,13 +201,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", + "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -287,9 +216,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", - "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", "dev": true, "license": "MIT", "engines": { @@ -297,22 +226,22 @@ } }, "node_modules/@babel/core": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", - "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.0", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.27.3", - "@babel/helpers": "^7.27.6", - "@babel/parser": "^7.28.0", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.0", - "@babel/types": "^7.28.0", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -338,14 +267,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", - "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.0", - "@babel/types": "^7.28.0", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -355,14 +284,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -371,16 +300,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -392,9 +311,9 @@ } }, "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", "dev": true, "license": "MIT", "engines": { @@ -402,29 +321,29 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", - "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.27.3" + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -444,9 +363,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", "dev": true, "license": "MIT", "engines": { @@ -454,9 +373,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", "dev": true, "license": "MIT", "engines": { @@ -464,9 +383,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", "dev": true, "license": "MIT", "engines": { @@ -474,27 +393,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.2.tgz", - "integrity": "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.2" + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", - "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.28.0" + "@babel/types": "^7.29.7" }, "bin": { "parser": "bin/babel-parser.js" @@ -743,33 +662,33 @@ } }, "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", - "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.0", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.0", + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", "debug": "^4.3.1" }, "engines": { @@ -777,14 +696,14 @@ } }, "node_modules/@babel/types": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", - "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -797,6 +716,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@borewit/text-codec": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.2.tgz", + "integrity": "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -1033,9 +962,9 @@ } }, "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -1044,9 +973,9 @@ } }, "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -1104,9 +1033,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", "dependencies": { @@ -1121,9 +1050,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -1149,9 +1078,9 @@ "license": "MIT" }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -2362,35 +2291,12 @@ } }, "node_modules/@ioredis/commands": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.3.0.tgz", - "integrity": "sha512-M/T6Zewn7sDaBQEqIZ8Rb+i9y8qfGmq+5SDFSf9sA2lUZTmdDLVdOiQaeDp+Q4wElZ9HG1GAX5KhDaidp6LQsQ==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.10.0.tgz", + "integrity": "sha512-UmeW7z4LfctwoQ5wkhVzgq8tXkreED2xZGpX+Bg+zA+WJFZCT6c062AfCK/Dfk81xZnnwdhJCUMkitihRaoC2Q==", "license": "MIT", "peer": true }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" - } - }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -2433,9 +2339,9 @@ } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.0.tgz", + "integrity": "sha512-ttBQIIQPDeLjpPOohtUdXuXUVoA2uIB6fEH9HyJ7234s5mBJ5wTx20njxplLZQgLaOfpmPQA7X2t5AX6tIPbog==", "dev": true, "license": "MIT", "dependencies": { @@ -2825,9 +2731,9 @@ } }, "node_modules/@jest/reporters/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -2895,9 +2801,9 @@ } }, "node_modules/@jest/reporters/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -3129,6 +3035,17 @@ "@jridgewell/trace-mapping": "^0.3.24" } }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", @@ -3178,18 +3095,18 @@ } }, "node_modules/@mongodb-js/saslprep": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.3.0.tgz", - "integrity": "sha512-zlayKCsIjYb7/IdfqxorK5+xUMyi4vOKcFy10wKJYc63NSdKI8mNME+uJqfatkPmOSMMUiojrL58IePKBm3gvQ==", + "version": "1.4.13", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.13.tgz", + "integrity": "sha512-E3Sv4eCYAlKYUTx8S3ioQcDUscOif+8zZ5OnW1IzJ+Tt+EO+ke8mn+Y3FX6N1H79picwbdOavVOb1jPi2EOyrg==", "license": "MIT", "dependencies": { "sparse-bitfield": "^3.0.3" } }, "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", - "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.4.tgz", + "integrity": "sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ==", "cpu": [ "arm64" ], @@ -3201,9 +3118,9 @@ "peer": true }, "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", - "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.4.tgz", + "integrity": "sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w==", "cpu": [ "x64" ], @@ -3215,9 +3132,9 @@ "peer": true }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", - "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.4.tgz", + "integrity": "sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw==", "cpu": [ "arm" ], @@ -3229,9 +3146,9 @@ "peer": true }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", - "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.4.tgz", + "integrity": "sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw==", "cpu": [ "arm64" ], @@ -3243,9 +3160,9 @@ "peer": true }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", - "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.4.tgz", + "integrity": "sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ==", "cpu": [ "x64" ], @@ -3257,9 +3174,9 @@ "peer": true }, "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", - "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.4.tgz", + "integrity": "sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ==", "cpu": [ "x64" ], @@ -3310,15 +3227,15 @@ } }, "node_modules/@nestjs/cli": { - "version": "11.0.14", - "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-11.0.14.tgz", - "integrity": "sha512-YwP03zb5VETTwelXU+AIzMVbEZKk/uxJL+z9pw0mdG9ogAtqZ6/mpmIM4nEq/NU8D0a7CBRLcMYUmWW/55pfqw==", + "version": "11.0.24", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-11.0.24.tgz", + "integrity": "sha512-aIHxQLSYtXShifA3zwWIeznEsZnNa3Iz2QRykFj+sl9IcbERBHr5nH87FRgywM+He3NxoF5WazHfR8FsmVeWxw==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "19.2.19", - "@angular-devkit/schematics": "19.2.19", - "@angular-devkit/schematics-cli": "19.2.19", + "@angular-devkit/core": "19.2.27", + "@angular-devkit/schematics": "19.2.27", + "@angular-devkit/schematics-cli": "19.2.27", "@inquirer/prompts": "7.10.1", "@nestjs/schematics": "^11.0.1", "ansis": "4.2.0", @@ -3326,13 +3243,13 @@ "cli-table3": "0.6.5", "commander": "4.1.1", "fork-ts-checker-webpack-plugin": "9.1.0", - "glob": "13.0.0", + "glob": "13.0.6", "node-emoji": "1.11.0", "ora": "5.4.1", "tsconfig-paths": "4.2.0", "tsconfig-paths-webpack-plugin": "4.2.0", "typescript": "5.9.3", - "webpack": "5.103.0", + "webpack": "5.106.2", "webpack-node-externals": "3.0.0" }, "bin": { @@ -3342,7 +3259,7 @@ "node": ">= 20.11" }, "peerDependencies": { - "@swc/cli": "^0.1.62 || ^0.3.0 || ^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0", + "@swc/cli": "^0.1.62 || ^0.3.0 || ^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0 || ^0.8.0", "@swc/core": "^1.3.62" }, "peerDependenciesMeta": { @@ -3354,53 +3271,6 @@ } } }, - "node_modules/@nestjs/cli/node_modules/@angular-devkit/core": { - "version": "19.2.19", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.19.tgz", - "integrity": "sha512-JbLL+4IMLMBgjLZlnPG4lYDfz4zGrJ/s6Aoon321NJKuw1Kb1k5KpFu9dUY0BqLIe8xPQ2UJBpI+xXdK5MXMHQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.17.1", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^4.0.0" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@nestjs/cli/node_modules/@angular-devkit/schematics": { - "version": "19.2.19", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.19.tgz", - "integrity": "sha512-J4Jarr0SohdrHcb40gTL4wGPCQ952IMWF1G/MSAQfBAPvA9ZKApYhpxcY7PmehVePve+ujpus1dGsJ7dPxz8Kg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "19.2.19", - "jsonc-parser": "3.3.1", - "magic-string": "0.30.17", - "ora": "5.4.1", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, "node_modules/@nestjs/cli/node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -3411,25 +3281,15 @@ "node": ">= 6" } }, - "node_modules/@nestjs/cli/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, "node_modules/@nestjs/common": { - "version": "11.1.6", - "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.1.6.tgz", - "integrity": "sha512-krKwLLcFmeuKDqngG2N/RuZHCs2ycsKcxWIDgcm7i1lf3sQ0iG03ci+DsP/r3FcT/eJDFsIHnKtNta2LIi7PzQ==", + "version": "11.1.28", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.1.28.tgz", + "integrity": "sha512-bRImsxibie+AM7xjdwcrm/gr5YeacI65kSBNzTufa1Ib5iwziaY/lqMtRh9THq6pbV4e1HP9aI2ZxGUumnmaoQ==", "license": "MIT", "dependencies": { - "file-type": "21.0.0", + "file-type": "21.3.4", "iterare": "1.2.1", - "load-esm": "1.0.2", + "load-esm": "1.0.3", "tslib": "2.8.1", "uid": "2.0.2" }, @@ -3453,14 +3313,14 @@ } }, "node_modules/@nestjs/config": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-4.0.2.tgz", - "integrity": "sha512-McMW6EXtpc8+CwTUwFdg6h7dYcBUpH5iUILCclAsa+MbCEvC9ZKu4dCHRlJqALuhjLw97pbQu62l4+wRwGeZqA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-4.0.4.tgz", + "integrity": "sha512-CJPjNitr0bAufSEnRe2N+JbnVmMmDoo6hvKCPzXgZoGwJSmp/dZPk9f/RMbuD/+Q1ZJPjwsRpq0vxna++Knwow==", "license": "MIT", "dependencies": { - "dotenv": "16.4.7", - "dotenv-expand": "12.0.1", - "lodash": "4.17.21" + "dotenv": "17.4.1", + "dotenv-expand": "12.0.3", + "lodash": "4.18.1" }, "peerDependencies": { "@nestjs/common": "^10.0.0 || ^11.0.0", @@ -3468,16 +3328,14 @@ } }, "node_modules/@nestjs/core": { - "version": "11.1.9", - "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-11.1.9.tgz", - "integrity": "sha512-a00B0BM4X+9z+t3UxJqIZlemIwCQdYoPKrMcM+ky4z3pkqqG1eTWexjs+YXpGObnLnjtMPVKWlcZHp3adDYvUw==", - "hasInstallScript": true, + "version": "11.1.28", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-11.1.28.tgz", + "integrity": "sha512-06m63xIRj8+l8uOeh/8LnYupGubkyu4f+bPKIadaSui6vK9KpXgoz7HveT1yOVLcEt0M0oCOEW5EuEXZkEmBBQ==", "license": "MIT", "dependencies": { - "@nuxt/opencollective": "0.4.1", "fast-safe-stringify": "2.1.1", "iterare": "1.2.1", - "path-to-regexp": "8.3.0", + "path-to-regexp": "8.4.2", "tslib": "2.8.1", "uid": "2.0.2" }, @@ -3521,15 +3379,15 @@ } }, "node_modules/@nestjs/platform-express": { - "version": "11.1.9", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.9.tgz", - "integrity": "sha512-GVd3+0lO0mJq2m1kl9hDDnVrX3Nd4oH3oDfklz0pZEVEVS0KVSp63ufHq2Lu9cyPdSBuelJr9iPm2QQ1yX+Kmw==", + "version": "11.1.28", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.28.tgz", + "integrity": "sha512-hU+9Sz4m+onHrR5AmelI59QKmY/Re546bPnygnpqqeQdHDiJpBgjWbL4t6Jr73CBpS60cpyng7WzjgphNB9iwA==", "license": "MIT", "dependencies": { - "cors": "2.8.5", - "express": "5.1.0", - "multer": "2.0.2", - "path-to-regexp": "8.3.0", + "cors": "2.8.6", + "express": "5.2.1", + "multer": "2.2.0", + "path-to-regexp": "8.4.2", "tslib": "2.8.1" }, "funding": { @@ -3542,20 +3400,83 @@ } }, "node_modules/@nestjs/schematics": { - "version": "11.0.7", - "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-11.0.7.tgz", - "integrity": "sha512-t8dNYYMwEeEsrlwc2jbkfwCfXczq4AeNEgx1KVQuJ6wYibXk0ZbXbPdfp8scnEAaQv1grpncNV5gWgzi7ZwbvQ==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-11.1.0.tgz", + "integrity": "sha512-lVxGZ46tcdItFMoXr6vyKWlnOsm1SZm/GUqAEDvy2RL4Q4O+3bkziAhrO7Y8JLssFUUvNFEGqAizI52WAxhjDw==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "19.2.15", - "@angular-devkit/schematics": "19.2.15", - "comment-json": "4.2.5", + "@angular-devkit/core": "19.2.24", + "@angular-devkit/schematics": "19.2.24", + "comment-json": "5.0.0", "jsonc-parser": "3.3.1", "pluralize": "8.0.0" }, "peerDependencies": { + "prettier": "^3.0.0", "typescript": ">=4.8.2" + }, + "peerDependenciesMeta": { + "prettier": { + "optional": true + } + } + }, + "node_modules/@nestjs/schematics/node_modules/@angular-devkit/core": { + "version": "19.2.24", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.24.tgz", + "integrity": "sha512-Kd49warf6U/EyWe5BszF/eebN3zQ3bk7tgfEljAw8q/rX95UUtriJubWvp6pgzHfzBA4jwq8f+QiNZB8eBEXPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "8.18.0", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.4", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@nestjs/schematics/node_modules/@angular-devkit/schematics": { + "version": "19.2.24", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.24.tgz", + "integrity": "sha512-lnw+ZM1Io+cJAkReC0NPDjqObL8NtKzKIkdgEEKC8CUmkhurYhedbicN8Y8NYHgG1uLd2GozW3+/QqPRZaN+Lw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "19.2.24", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.17", + "ora": "5.4.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@nestjs/schematics/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" } }, "node_modules/@nestjs/testing": { @@ -3649,22 +3570,6 @@ "node": ">= 8" } }, - "node_modules/@nuxt/opencollective": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.4.1.tgz", - "integrity": "sha512-GXD3wy50qYbxCJ652bDrDzgMr3NFEkIS374+IgFQKkCvk9yiYcLvX2XDYr7UyQxf4wK0e+yqDYRubZ0DtOxnmQ==", - "license": "MIT", - "dependencies": { - "consola": "^3.2.3" - }, - "bin": { - "opencollective": "bin/opencollective.js" - }, - "engines": { - "node": "^14.18.0 || >=16.10.0", - "npm": ">=5.10.0" - } - }, "node_modules/@paralleldrive/cuid2": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.2.2.tgz", @@ -3733,14 +3638,13 @@ } }, "node_modules/@tokenizer/inflate": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.2.7.tgz", - "integrity": "sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz", + "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==", "license": "MIT", "dependencies": { - "debug": "^4.4.0", - "fflate": "^0.8.2", - "token-types": "^6.0.0" + "debug": "^4.4.3", + "token-types": "^6.1.1" }, "engines": { "node": ">=18" @@ -4568,21 +4472,25 @@ } }, "node_modules/accepts/node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "license": "MIT", "dependencies": { "mime-db": "^1.54.0" }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", "dev": true, "license": "MIT", "bin": { @@ -4634,10 +4542,23 @@ "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", "license": "MIT" }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", "dependencies": { @@ -4837,9 +4758,9 @@ } }, "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { @@ -4933,9 +4854,9 @@ } }, "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "version": "4.12.5", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", + "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", "license": "MIT" }, "node_modules/async": { @@ -4954,15 +4875,16 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", - "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.18.1.tgz", + "integrity": "sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==", "license": "MIT", "peer": true, "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", - "proxy-from-env": "^1.1.0" + "follow-redirects": "^1.16.0", + "form-data": "^4.0.5", + "https-proxy-agent": "^5.0.1", + "proxy-from-env": "^2.1.0" } }, "node_modules/babel-jest": { @@ -5180,13 +5102,16 @@ } }, "node_modules/baseline-browser-mapping": { - "version": "2.8.32", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.32.tgz", - "integrity": "sha512-OPz5aBThlyLFgxyhdwf/s2+8ab3OvT7AdTNvKHBwpXomIYeXqpUUuT8LrdtxZSsWJ4R4CU1un4XGh5Ez3nlTpw==", + "version": "2.11.6", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.6.tgz", + "integrity": "sha512-69D/imtToCsIcAl8WBS2YaRwA4jO/j0HhU+hELqMEu9f54MoUtI6+XH5mrKU8rEFNEk/Ui1I2MK4/JkWacclGw==", "dev": true, "license": "Apache-2.0", "bin": { - "baseline-browser-mapping": "dist/cli.js" + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/bech32": { @@ -5242,26 +5167,26 @@ } }, "node_modules/bn.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", - "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.5.tgz", + "integrity": "sha512-Vq886eXykuP5E6HcKSSStP3bJgrE6In5WKxVUvJ8XGpWWYs2xZHWqUwzCtGgEtBcxyd57KBFDPFoUfNzdaHCNg==", "license": "MIT" }, "node_modules/body-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.1.tgz", - "integrity": "sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", + "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", "license": "MIT", "dependencies": { "bytes": "^3.1.2", - "content-type": "^1.0.5", + "content-type": "^2.0.0", "debug": "^4.4.3", - "http-errors": "^2.0.0", - "iconv-lite": "^0.7.0", + "http-errors": "^2.0.1", + "iconv-lite": "^0.7.2", "on-finished": "^2.4.1", - "qs": "^6.14.0", - "raw-body": "^3.0.1", - "type-is": "^2.0.1" + "qs": "^6.15.2", + "raw-body": "^3.0.2", + "type-is": "^2.1.0" }, "engines": { "node": ">=18" @@ -5271,10 +5196,23 @@ "url": "https://opencollective.com/express" } }, + "node_modules/body-parser/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/body-parser/node_modules/iconv-lite": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", - "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -5317,9 +5255,9 @@ "license": "MIT" }, "node_modules/browserslist": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz", - "integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==", + "version": "4.28.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.7.tgz", + "integrity": "sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==", "dev": true, "funding": [ { @@ -5337,11 +5275,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.8.25", - "caniuse-lite": "^1.0.30001754", - "electron-to-chromium": "^1.5.249", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.1.4" + "baseline-browser-mapping": "^2.10.44", + "caniuse-lite": "^1.0.30001806", + "electron-to-chromium": "^1.5.393", + "node-releases": "^2.0.51", + "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" @@ -5423,19 +5361,29 @@ "license": "MIT" }, "node_modules/bullmq": { - "version": "5.56.10", - "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.56.10.tgz", - "integrity": "sha512-rhmVJo7yAZLKb05TRT9MNMvRqnCUBNW915D8Wn4O/MvjvNMbzDvNjvSaPZzdxxXlRH4GjbtIh0Waeff2LKF+Lg==", + "version": "5.81.2", + "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.81.2.tgz", + "integrity": "sha512-Hi9GaVCC6HE9bQP65j/FNv1aL1fcEukTF99ezS5pl1Ud+joCFpNWiPCV45mWdkEmpuacS0XJdMMFGKPIHCwoPg==", "license": "MIT", "peer": true, "dependencies": { - "cron-parser": "^4.9.0", - "ioredis": "^5.4.1", - "msgpackr": "^1.11.2", - "node-abort-controller": "^3.1.1", - "semver": "^7.5.4", - "tslib": "^2.0.0", - "uuid": "^9.0.0" + "cron-parser": "4.9.0", + "ioredis": "5.11.1", + "msgpackr": "2.0.4", + "node-abort-controller": "3.1.1", + "semver": "7.8.5", + "tslib": "2.8.1" + }, + "engines": { + "node": ">=12.22.0" + }, + "peerDependencies": { + "redis": ">=5.0.0" + }, + "peerDependenciesMeta": { + "redis": { + "optional": true + } } }, "node_modules/busboy": { @@ -5508,9 +5456,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001757", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001757.tgz", - "integrity": "sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==", + "version": "1.0.30001806", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz", + "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==", "dev": true, "funding": [ { @@ -5726,9 +5674,9 @@ } }, "node_modules/cluster-key-slot": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", - "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.1.tgz", + "integrity": "sha512-rwHwUfXL40Chm1r08yrhU3qpUvdVlgkKNeyeGPOxnW8/SyVDvgRaed/Uz54AqWNaTCAThlj6QAs3TZcKI0xDEw==", "license": "Apache-2.0", "peer": true, "engines": { @@ -5810,18 +5758,22 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, "node_modules/comment-json": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.5.tgz", - "integrity": "sha512-bKw/r35jR3HGt5PEPm1ljsQQGyCrR8sFGNiN5L+ykDHdpO8Smxkrkla9Yi6NkQyUrb8V54PGhfMs6NrIwtxtdw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-5.0.0.tgz", + "integrity": "sha512-uiqLcOiVDJtBP8WGkZHEP+FZIhTzP1dxvn59EfoYUi9gqupjrBWVQkO2atDrbnKPwLeotFYDsuNb26uBMqB+hw==", "dev": true, "license": "MIT", "dependencies": { "array-timsort": "^1.0.3", - "core-util-is": "^1.0.3", - "esprima": "^4.0.1", - "has-own-prop": "^2.0.0", - "repeat-string": "^1.6.1" + "esprima": "^4.0.1" }, "engines": { "node": ">= 6" @@ -5858,15 +5810,6 @@ "typedarray": "^0.0.6" } }, - "node_modules/consola": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", - "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", - "license": "MIT", - "engines": { - "node": "^14.18.0 || >=16.10.0" - } - }, "node_modules/consul": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/consul/-/consul-2.0.1.tgz", @@ -5878,29 +5821,17 @@ "uuid": "^10.0.0" } }, - "node_modules/consul/node_modules/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/content-disposition": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", - "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", + "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/content-type": { @@ -5948,13 +5879,13 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "devOptional": true, - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", "license": "MIT", "dependencies": { "object-assign": "^4", @@ -5962,6 +5893,10 @@ }, "engines": { "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/cosmiconfig": { @@ -6234,9 +6169,9 @@ } }, "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", + "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -6254,9 +6189,9 @@ } }, "node_modules/dotenv": { - "version": "16.4.7", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", - "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", + "version": "17.4.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.1.tgz", + "integrity": "sha512-k8DaKGP6r1G30Lx8V4+pCsLzKr8vLmV2paqEj1Y55GdAgJuIqpRp5FfajGF8KtwMxCz9qJc6wUIJnm053d/WCw==", "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -6266,9 +6201,9 @@ } }, "node_modules/dotenv-expand": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-12.0.1.tgz", - "integrity": "sha512-LaKRbou8gt0RNID/9RoI+J2rvXsBRPMV7p+ElHlPhcSARbCPDYcYG2s1TIzAfWv4YSgyY5taidWzzs31lNV3yQ==", + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-12.0.3.tgz", + "integrity": "sha512-uc47g4b+4k/M/SeaW1y4OApx+mtLWl92l5LMPP0GNXctZqELk+YGgOPIIC5elYmUH4OuoK3JLhuRUYegeySiFA==", "license": "BSD-2-Clause", "dependencies": { "dotenv": "^16.4.5" @@ -6280,6 +6215,18 @@ "url": "https://dotenvx.com" } }, + "node_modules/dotenv-expand/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -6301,9 +6248,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.262", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.262.tgz", - "integrity": "sha512-NlAsMteRHek05jRUxUR0a5jpjYq9ykk6+kO0yRaMi5moe7u0fVIOeQ3Y30A8dIiWFBNUoQGi1ljb1i5VtS9WQQ==", + "version": "1.5.397", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.397.tgz", + "integrity": "sha512-khGTy9U9x02KEtsKM8vx5A62BsRmcOsIgDpWr1ImE32Ax8GxHGPHZf+Eu9H8zOOyHJnB0jTbseyTHbq2XCT8yw==", "dev": true, "license": "ISC" }, @@ -6323,9 +6270,9 @@ } }, "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "version": "4.12.5", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", + "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", "license": "MIT" }, "node_modules/emittery": { @@ -6364,14 +6311,14 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.18.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", - "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "version": "5.24.4", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.4.tgz", + "integrity": "sha512-GVoi+ICHocoOIU7qVVM48wOJziRsqrsyqlI0Ce0LdowRn6v3bcH2zUa9kp85ncx0nwIb9/HOCOLS3fdThDG/XQ==", "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "tapable": "^2.3.3" }, "engines": { "node": ">=10.13.0" @@ -6406,9 +6353,9 @@ } }, "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz", + "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==", "dev": true, "license": "MIT" }, @@ -6604,9 +6551,9 @@ } }, "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", "dependencies": { @@ -6637,9 +6584,9 @@ } }, "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -6715,9 +6662,9 @@ "license": "MIT" }, "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -6828,9 +6775,9 @@ } }, "node_modules/ethers": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.15.0.tgz", - "integrity": "sha512-Kf/3ZW54L4UT0pZtsY/rf+EkBU7Qi5nnhonjUb8yTXcxH3cdcWrV2cRyk0Xk/4jK6OoHhxxZHriyhje20If2hQ==", + "version": "6.17.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.17.0.tgz", + "integrity": "sha512-BpyrpIPJ3ydEVow8zGaz1DuPS7YU8DcWxuBnY9a0UA/lvAPwrMr+EPXsfrul628SRaekPNeIM4UFh/91GWZang==", "funding": [ { "type": "individual", @@ -6843,13 +6790,13 @@ ], "license": "MIT", "dependencies": { - "@adraffy/ens-normalize": "1.10.1", + "@adraffy/ens-normalize": "1.11.1", "@noble/curves": "1.2.0", "@noble/hashes": "1.3.2", "@types/node": "22.7.5", "aes-js": "4.0.0-beta.5", "tslib": "2.7.0", - "ws": "8.17.1" + "ws": "8.21.0" }, "engines": { "node": ">=14.0.0" @@ -6906,27 +6853,6 @@ "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "license": "MIT" }, - "node_modules/ethers/node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -7002,18 +6928,19 @@ "optional": true }, "node_modules/express": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", - "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", "dependencies": { "accepts": "^2.0.0", - "body-parser": "^2.2.0", + "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", + "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", @@ -7053,15 +6980,19 @@ } }, "node_modules/express/node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "license": "MIT", "dependencies": { "mime-db": "^1.54.0" }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/fast-deep-equal": { @@ -7129,9 +7060,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz", + "integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==", "dev": true, "funding": [ { @@ -7180,12 +7111,6 @@ "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", "license": "MIT" }, - "node_modules/fflate": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", - "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", - "license": "MIT" - }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -7200,14 +7125,14 @@ } }, "node_modules/file-type": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.0.0.tgz", - "integrity": "sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg==", + "version": "21.3.4", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.4.tgz", + "integrity": "sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==", "license": "MIT", "dependencies": { - "@tokenizer/inflate": "^0.2.7", - "strtok3": "^10.2.2", - "token-types": "^6.0.0", + "@tokenizer/inflate": "^0.4.1", + "strtok3": "^10.3.4", + "token-types": "^6.1.1", "uint8array-extras": "^1.4.0" }, "engines": { @@ -7231,9 +7156,9 @@ } }, "node_modules/finalhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", - "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", "license": "MIT", "dependencies": { "debug": "^4.4.0", @@ -7244,7 +7169,11 @@ "statuses": "^2.0.1" }, "engines": { - "node": ">= 0.8" + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/find-up": { @@ -7279,9 +7208,9 @@ } }, "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.3.tgz", + "integrity": "sha512-/zipXxyO6rGvuNGDiULY9MvEGSkb2gaG4GGH4ygMi0ZZzyMHdUZBmntJmx5x1G2VuPytCwGN4xsJP6cw+sK+vQ==", "dev": true, "license": "ISC" }, @@ -7292,9 +7221,9 @@ "license": "MIT" }, "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", "funding": [ { "type": "individual", @@ -7357,9 +7286,9 @@ } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -7405,9 +7334,9 @@ "license": "MIT" }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -7418,16 +7347,16 @@ } }, "node_modules/form-data": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", + "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" + "hasown": "^2.0.4", + "mime-types": "^2.1.35" }, "engines": { "node": ">= 6" @@ -7669,18 +7598,18 @@ } }, "node_modules/glob": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", - "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "minimatch": "^10.1.1", - "minipass": "^7.1.2", - "path-scurry": "^2.0.0" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -7706,17 +7635,40 @@ "dev": true, "license": "BSD-2-Clause" }, + "node_modules/glob/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz", + "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, "node_modules/glob/node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.8" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -7773,9 +7725,9 @@ } }, "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7813,16 +7765,6 @@ "node": ">=8" } }, - "node_modules/has-own-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", - "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -7917,6 +7859,20 @@ "url": "https://opencollective.com/express" } }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "peer": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -8034,21 +7990,19 @@ "license": "ISC" }, "node_modules/ioredis": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.7.0.tgz", - "integrity": "sha512-NUcA93i1lukyXU+riqEyPtSEkyFq8tX90uL659J+qpCZ3rEdViB/APC58oAhIh3+bJln2hzdlZbBZsGNrlsR8g==", + "version": "5.11.1", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.11.1.tgz", + "integrity": "sha512-ehuGcf94bQXhfagULNXrJdfnWO38v070jxSx/qE87Kjzmu2fU7ro5EFAb+OPituLqgfyuQaym5DlrNydW2sJ9A==", "license": "MIT", "peer": true, "dependencies": { - "@ioredis/commands": "^1.3.0", - "cluster-key-slot": "^1.1.0", - "debug": "^4.3.4", - "denque": "^2.1.0", - "lodash.defaults": "^4.2.0", - "lodash.isarguments": "^3.1.0", - "redis-errors": "^1.2.0", - "redis-parser": "^3.0.0", - "standard-as-callback": "^2.1.0" + "@ioredis/commands": "1.10.0", + "cluster-key-slot": "1.1.1", + "debug": "4.4.3", + "denque": "2.1.0", + "redis-errors": "1.2.0", + "redis-parser": "3.0.0", + "standard-as-callback": "2.1.0" }, "engines": { "node": ">=12.22.0" @@ -8579,9 +8533,9 @@ } }, "node_modules/jest-config/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -8649,9 +8603,9 @@ } }, "node_modules/jest-config/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -9313,9 +9267,9 @@ } }, "node_modules/jest-runtime/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -9383,9 +9337,9 @@ } }, "node_modules/jest-runtime/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -9552,9 +9506,9 @@ "license": "MIT" }, "node_modules/jest-util/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { @@ -9781,10 +9735,20 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", + "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -9974,9 +9938,9 @@ "license": "MIT" }, "node_modules/load-esm": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/load-esm/-/load-esm-1.0.2.tgz", - "integrity": "sha512-nVAvWk/jeyrWyXEAs84mpQCYccxRqgKY4OznLuJhJCa0XsPSfdOIr2zvBZEj3IHEHbX97jjscKRRV539bW0Gpw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/load-esm/-/load-esm-1.0.3.tgz", + "integrity": "sha512-v5xlu8eHD1+6r8EHTg6hfmO97LN8ugKtiXcy5e6oN72iD2r6u0RPfLl6fxM+7Wnh2ZRq15o0russMst44WauPA==", "funding": [ { "type": "github", @@ -10023,25 +9987,11 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "license": "MIT" }, - "node_modules/lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", - "license": "MIT", - "peer": true - }, - "node_modules/lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", - "license": "MIT", - "peer": true - }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -10152,6 +10102,16 @@ "node": ">=0.1.90" } }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, "node_modules/luxon": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.1.tgz", @@ -10215,12 +10175,16 @@ } }, "node_modules/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.1.tgz", + "integrity": "sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==", "license": "MIT", "engines": { "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/memfs": { @@ -10296,9 +10260,9 @@ } }, "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { @@ -10384,42 +10348,31 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "license": "MIT", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/mongodb": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.18.0.tgz", - "integrity": "sha512-fO5ttN9VC8P0F5fqtQmclAkgXZxbIkYRTUi1j8JO6IYwvamkhtYDilJr35jOPELR49zqCJgXZWwCtW7B+TM8vQ==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.20.0.tgz", + "integrity": "sha512-Tl6MEIU3K4Rq3TSHd+sZQqRBoGlFsOgNrH5ltAcFBV62Re3Fd+FcaVf8uSEQFOJ51SDowDVttBTONMfoYWrWlQ==", "license": "Apache-2.0", "dependencies": { - "@mongodb-js/saslprep": "^1.1.9", + "@mongodb-js/saslprep": "^1.3.0", "bson": "^6.10.4", - "mongodb-connection-string-url": "^3.0.0" + "mongodb-connection-string-url": "^3.0.2" }, "engines": { "node": ">=16.20.1" @@ -10430,7 +10383,7 @@ "gcp-metadata": "^5.2.0", "kerberos": "^2.0.1", "mongodb-client-encryption": ">=6.0.0 <7", - "snappy": "^7.2.2", + "snappy": "^7.3.2", "socks": "^2.7.1" }, "peerDependenciesMeta": { @@ -10468,14 +10421,14 @@ } }, "node_modules/mongoose": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.17.1.tgz", - "integrity": "sha512-aodS4cacux5caoxB5ErEwRmrafIUsVRJxHnvP7URnSUnTenr32j1qBVV+KjYxryyLSisQkxglAFF69TNLeZTLg==", + "version": "8.24.2", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.24.2.tgz", + "integrity": "sha512-5+H3MSHNJCcr9M+lVplekrZ4/Dyn3N1dOpvgn9gMwvHJhunc4G8SQcBVd/btBQoVdspVNPjx8Pw03YWBv6uTJg==", "license": "MIT", "dependencies": { "bson": "^6.10.4", "kareem": "2.6.3", - "mongodb": "~6.18.0", + "mongodb": "~6.20.0", "mpath": "0.9.0", "mquery": "5.0.0", "ms": "2.1.3", @@ -10517,19 +10470,19 @@ "license": "MIT" }, "node_modules/msgpackr": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.5.tgz", - "integrity": "sha512-UjkUHN0yqp9RWKy0Lplhh+wlpdt9oQBYgULZOiFhV3VclSF1JnSQWZ5r9gORQlNYaUKQoR8itv7g7z1xDDuACA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-2.0.4.tgz", + "integrity": "sha512-o1C5KRmuRt+apqMr1HuGSqWStZoRBUpEsCsl15uM9VdAF1qHLtvMOU2En747EnTyEl6c4pzPewRMFF31s1CNbA==", "license": "MIT", "peer": true, "optionalDependencies": { - "msgpackr-extract": "^3.0.2" + "msgpackr-extract": "^3.0.4" } }, "node_modules/msgpackr-extract": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", - "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.4.tgz", + "integrity": "sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==", "hasInstallScript": true, "license": "MIT", "optional": true, @@ -10541,30 +10494,31 @@ "download-msgpackr-prebuilds": "bin/download-prebuilds.js" }, "optionalDependencies": { - "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4" } }, "node_modules/multer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/multer/-/multer-2.0.2.tgz", - "integrity": "sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/multer/-/multer-2.2.0.tgz", + "integrity": "sha512-6rdyFg2kLrMh9Jee7/BMPuV9lEAd7lLW2YUpF9/YxR7njyoUwwQ0ZPh3TaIY50Sw6vlyD2HW3wGOkTS4P79xrQ==", "license": "MIT", "dependencies": { "append-field": "^1.0.0", "busboy": "^1.6.0", "concat-stream": "^2.0.0", - "mkdirp": "^0.5.6", - "object-assign": "^4.1.1", - "type-is": "^1.6.18", - "xtend": "^4.0.2" + "type-is": "^1.6.18" }, "engines": { "node": ">= 10.16.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/multer/node_modules/media-typer": { @@ -10717,11 +10671,14 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "version": "2.0.51", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz", + "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/normalize-path": { "version": "3.0.0", @@ -11038,9 +10995,9 @@ "license": "MIT" }, "node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -11048,16 +11005,16 @@ "minipass": "^7.1.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "11.2.4", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", - "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -11065,9 +11022,9 @@ } }, "node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", "license": "MIT", "funding": { "type": "opencollective", @@ -11098,9 +11055,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -11288,11 +11245,14 @@ } }, "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", "license": "MIT", - "peer": true + "peer": true, + "engines": { + "node": ">=10" + } }, "node_modules/punycode": { "version": "2.3.1", @@ -11321,12 +11281,13 @@ "license": "MIT" }, "node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.1.0" + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" }, "engines": { "node": ">=0.6" @@ -11363,23 +11324,17 @@ ], "license": "MIT" }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz", + "integrity": "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==", "license": "MIT", "engines": { "node": ">= 0.6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/raw-body": { @@ -11398,9 +11353,9 @@ } }, "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", - "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -11477,16 +11432,6 @@ "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", "license": "Apache-2.0" }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -11624,9 +11569,9 @@ } }, "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -11655,9 +11600,9 @@ } }, "node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -11770,9 +11715,9 @@ } }, "node_modules/schema-utils/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", "dependencies": { @@ -11831,9 +11776,9 @@ "license": "MIT" }, "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -11843,25 +11788,29 @@ } }, "node_modules/send": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", - "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", "license": "MIT", "dependencies": { - "debug": "^4.3.5", + "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "mime-types": "^3.0.1", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", - "statuses": "^2.0.1" + "statuses": "^2.0.2" }, "engines": { "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/send/node_modules/mime-db": { @@ -11874,31 +11823,25 @@ } }, "node_modules/send/node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "license": "MIT", "dependencies": { "mime-db": "^1.54.0" }, "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", "license": "MIT", "dependencies": { "encodeurl": "^2.0.0", @@ -11908,6 +11851,10 @@ }, "engines": { "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/setprototypeof": { @@ -11940,14 +11887,14 @@ } }, "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, @@ -11959,13 +11906,13 @@ } }, "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "object-inspect": "^1.13.4" }, "engines": { "node": ">= 0.4" @@ -12259,9 +12206,9 @@ } }, "node_modules/strtok3": { - "version": "10.3.4", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.4.tgz", - "integrity": "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==", + "version": "10.3.5", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.5.tgz", + "integrity": "sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==", "license": "MIT", "dependencies": { "@tokenizer/token": "^0.3.0" @@ -12361,9 +12308,9 @@ } }, "node_modules/tapable": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", - "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", "dev": true, "license": "MIT", "engines": { @@ -12375,14 +12322,14 @@ } }, "node_modules/terser": { - "version": "5.43.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", - "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", + "version": "5.49.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.49.0.tgz", + "integrity": "sha512-SNiDnXyHSrxVcIOtVbULzcTmniUiwcV7Nwdyj1twVubeTmbjoa8p69KKDpfkdoOavuM4/GRm1+ykI8qqnavHoA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.14.0", + "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -12394,16 +12341,15 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.14", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", - "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.6.1.tgz", + "integrity": "sha512-201R5j+sJpK8nFWwKVyNfZot8FaJbLZDq5evriVzbV1wDtSXDjRUDRfJzHpAaxFDMEhsZL1QkeqM61wgsS3KaQ==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", "schema-utils": "^4.3.0", - "serialize-javascript": "^6.0.2", "terser": "^5.31.1" }, "engines": { @@ -12417,12 +12363,39 @@ "webpack": "^5.1.0" }, "peerDependenciesMeta": { + "@minify-html/node": { + "optional": true + }, "@swc/core": { "optional": true }, + "@swc/css": { + "optional": true + }, + "@swc/html": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "cssnano": { + "optional": true + }, + "csso": { + "optional": true + }, "esbuild": { "optional": true }, + "html-minifier-terser": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "postcss": { + "optional": true + }, "uglify-js": { "optional": true } @@ -12462,9 +12435,9 @@ } }, "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", - "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "dev": true, "license": "MIT", "dependencies": { @@ -12497,13 +12470,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "license": "MIT" - }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -12520,9 +12486,9 @@ } }, "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -12553,9 +12519,9 @@ } }, "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -12665,11 +12631,12 @@ } }, "node_modules/token-types": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.0.4.tgz", - "integrity": "sha512-MD9MjpVNhVyH4fyd5rKphjvt/1qj+PtQUz65aFqAZA6XniWAuSFRjLk3e2VALEFlh9OwBpXUN7rfeqSnT/Fmkw==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz", + "integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==", "license": "MIT", "dependencies": { + "@borewit/text-codec": "^0.2.1", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" }, @@ -13043,17 +13010,34 @@ } }, "node_modules/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", + "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", "license": "MIT", "dependencies": { - "content-type": "^1.0.5", + "content-type": "^2.0.0", "media-typer": "^1.1.0", "mime-types": "^3.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/type-is/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/type-is/node_modules/mime-db": { @@ -13066,15 +13050,19 @@ } }, "node_modules/type-is/node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "license": "MIT", "dependencies": { "mime-db": "^1.54.0" }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/typedarray": { @@ -13124,9 +13112,9 @@ } }, "node_modules/uint8array-extras": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.4.1.tgz", - "integrity": "sha512-+NWHrac9dvilNgme+gP4YrBSumsaMZP0fNBtXXFIf33RLLKEcBUKaQZ7ULUbS0sBfcjxIZ4V96OTRkCbM7hxpw==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", "license": "MIT", "engines": { "node": ">=18" @@ -13161,9 +13149,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", - "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { @@ -13219,15 +13207,15 @@ "license": "MIT" }, "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], "license": "MIT", - "peer": true, "bin": { "uuid": "dist/bin/uuid" } @@ -13274,13 +13262,12 @@ } }, "node_modules/watchpack": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", - "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.2.tgz", + "integrity": "sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==", "dev": true, "license": "MIT", "dependencies": { - "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" }, "engines": { @@ -13307,9 +13294,9 @@ } }, "node_modules/webpack": { - "version": "5.103.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.103.0.tgz", - "integrity": "sha512-HU1JOuV1OavsZ+mfigY0j8d1TgQgbZ6M+J75zDkpEAwYeXjWSqrGJtgnPblJjd/mAyTNQ7ygw0MiKOn6etz8yw==", + "version": "5.106.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.106.2.tgz", + "integrity": "sha512-wGN3qcrBQIFmQ/c0AiOAQBvrZ5lmY8vbbMv4Mxfgzqd/B6+9pXtLo73WuS1dSGXM5QYY3hZnIbvx+K1xxe6FyA==", "dev": true, "license": "MIT", "dependencies": { @@ -13319,25 +13306,24 @@ "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.15.0", + "acorn": "^8.16.0", "acorn-import-phases": "^1.0.3", - "browserslist": "^4.26.3", + "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.3", - "es-module-lexer": "^1.2.1", + "enhanced-resolve": "^5.20.0", + "es-module-lexer": "^2.0.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.3.1", - "mime-types": "^2.1.27", + "mime-db": "^1.54.0", "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", - "terser-webpack-plugin": "^5.3.11", - "watchpack": "^2.4.4", - "webpack-sources": "^3.3.3" + "terser-webpack-plugin": "^5.3.17", + "watchpack": "^2.5.1", + "webpack-sources": "^3.3.4" }, "bin": { "webpack": "bin/webpack.js" @@ -13366,9 +13352,9 @@ } }, "node_modules/webpack-sources": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", - "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.1.tgz", + "integrity": "sha512-jyuiGJdtvY434z5bUZrjz67v76/ePNvFZTp9Mdz29IlH4+GPsgyGjiv0fKI+M7BdkU6ADjulUcKAd3tUK3WlEw==", "dev": true, "license": "MIT", "engines": { @@ -13417,6 +13403,16 @@ "node": ">=4.0" } }, + "node_modules/webpack/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/webpack/node_modules/schema-utils": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", @@ -13613,9 +13609,9 @@ "license": "ISC" }, "node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -13638,6 +13634,7 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "license": "MIT", + "optional": true, "engines": { "node": ">=0.4" } From aa0dc845184c6135e463778cf4d7bbfebb2b9ea1 Mon Sep 17 00:00:00 2001 From: Jim Toth Date: Tue, 28 Jul 2026 16:22:40 -0400 Subject: [PATCH 05/15] Override elliptic and secp256k1 to their patched versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clears all 3 production criticals. These came from @dha-team/arbundles, which pins the EOL @ethersproject v5 line; arbundles 1.0.4 is already latest and the advisory range is `*`, so there was no upgrade to take — npm's suggested "fix" is a downgrade to 1.0.3. But the advisories are version-exact and both packages already ship fixes: elliptic critical hits <=6.6.0, patched in 6.6.1 secp256k1 high hits exactly 5.0.0, patched in 5.0.1 Both were installed twice — the patched version hoisted at the root, and a vulnerable copy nested under arbundles that its ethersproject chain resolved to. An override collapses them onto the patched ones, so this needs no change to arbundles or to ethers (our own code is already on v6.17). Verified rather than assumed: these are the ECDSA signing primitives, so a clean build proves nothing. The integration specs were run against a real node holding real migrated state, exercising ANS-104 signed writes end to end — operator registry 5/5 (registration credits, operator certificates) and relay rewards 3/3 (settles a round, reads the snapshot back from the settle slot). One low remains in elliptic with range <=6.6.1, i.e. unfixed at latest. --- package-lock.json | 42 ------------------------------------------ package.json | 4 ++++ 2 files changed, 4 insertions(+), 42 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5d2072a..89bf1a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -860,27 +860,6 @@ "base-x": "^3.0.2" } }, - "node_modules/@dha-team/arbundles/node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/@dha-team/arbundles/node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.5", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.5.tgz", - "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", - "license": "MIT" - }, "node_modules/@dha-team/arbundles/node_modules/keccak": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", @@ -896,27 +875,6 @@ "node": ">=10.0.0" } }, - "node_modules/@dha-team/arbundles/node_modules/secp256k1": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-5.0.0.tgz", - "integrity": "sha512-TKWX8xvoGHrxVdqbYeZM9w+izTF4b9z3NhSaDkdn81btvuh+ivbIMGT/zQvDtTFWhRlThpoz6LEYTr7n8A5GcA==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "elliptic": "^6.5.4", - "node-addon-api": "^5.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@dha-team/arbundles/node_modules/secp256k1/node_modules/node-addon-api": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", - "license": "MIT" - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", diff --git a/package.json b/package.json index a3861ba..4ca9ac5 100644 --- a/package.json +++ b/package.json @@ -93,5 +93,9 @@ ], "coverageDirectory": "../coverage", "testEnvironment": "node" + }, + "overrides": { + "elliptic": "^6.6.1", + "secp256k1": "^5.0.1" } } From 38404c2f7bee775a26aae32807928f7f84872648 Mon Sep 17 00:00:00 2001 From: Jim Toth Date: Tue, 28 Jul 2026 17:06:56 -0400 Subject: [PATCH 06/15] Drop unused geoip-lite and override ws to a patched 7.x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Declared but imported nowhere. GeoIpService does not use it — it fetches /fingerprint-map/ from api-service over HTTP, so the geolocation data comes from there, not from a local database. It was the single largest source of production advisories left in this service. It pulls rimraf 2 -> glob 7 -> minimatch 3 -> brace-expansion 1, and every high in that chain came from it. Its spec baseline is unchanged: 4 failed / 1 passed before and after, the failures being pre-existing and requiring a live api-service at ANYONE_API_URL. --- Clears the last production highs. @dha-team/arbundles pulls @ethersproject/providers 5.7.2, which pins ws 7.4.6 — inside the advisory range 7.0.0 - 7.5.10 for two DoS reports. Same nested-vs-hoisted shape as elliptic and secp256k1: a safe ws 8.21.0 sits hoisted for ethers v6 while the vulnerable 7.4.6 sits nested. The override is SCOPED to @ethersproject/providers so ethers v6 keeps ws 8; forcing ws 7 globally would break it. 7.5.13 is the patched 7.x line, so ethersproject stays on a compatible major. This also clears the aggregate advisories on @dha-team/arbundles and @ethersproject/providers themselves, which were flagged only by way of their vulnerable leaves. With elliptic, secp256k1 and now ws all patched, nothing is left — so the cluster was never actually blocked on arbundles leaving ethersproject v5, as previously recorded. Worth stating plainly: these are DoS bugs in WebSocket frame handling, and nothing on this path opens a WebSocket — arbundles pulls @ethersproject/providers for wallet and provider types, and no WebSocketProvider is ever constructed. This is noise reduction, not risk reduction. Verified against a real node holding real migrated state: the operator-registry integration spec passes 5/5 including ANS-104 signed writes. --- package-lock.json | 227 ++-------------------------------------------- package.json | 6 +- 2 files changed, 14 insertions(+), 219 deletions(-) diff --git a/package-lock.json b/package-lock.json index 89bf1a8..de55be9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,6 @@ "consul": "^2.0.1", "date-fns": "^4.1.0", "ethers": "^6.13.4", - "geoip-lite": "^1.4.10", "h3-js": "^4.1.0", "keccak": "^3.0.4", "lodash": "^4.17.21", @@ -1556,9 +1555,9 @@ } }, "node_modules/@ethersproject/providers/node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "version": "7.5.13", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.13.tgz", + "integrity": "sha512-rsKI6xDBFVf4r/x8XyChGK04QR/XHroxs/jUcoWvtEZM8TPU/X/uIY9B1CsSzYws9ZJb/6bbBu7dPhFW00CAoA==", "license": "MIT", "engines": { "node": ">=8.3.0" @@ -4817,15 +4816,6 @@ "integrity": "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==", "license": "MIT" }, - "node_modules/async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "license": "MIT", - "dependencies": { - "lodash": "^4.17.14" - } - }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -5028,6 +5018,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, "license": "MIT" }, "node_modules/base64-js": { @@ -5303,15 +5294,6 @@ "ieee754": "^1.2.1" } }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -5751,6 +5733,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, "license": "MIT" }, "node_modules/concat-stream": { @@ -7054,15 +7037,6 @@ "bser": "2.1.1" } }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" - } - }, "node_modules/fecha": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", @@ -7382,6 +7356,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, "license": "ISC" }, "node_modules/fsevents": { @@ -7418,73 +7393,6 @@ "node": ">=6.9.0" } }, - "node_modules/geoip-lite": { - "version": "1.4.10", - "resolved": "https://registry.npmjs.org/geoip-lite/-/geoip-lite-1.4.10.tgz", - "integrity": "sha512-4N69uhpS3KFd97m00wiFEefwa+L+HT5xZbzPhwu+sDawStg6UN/dPwWtUfkQuZkGIY1Cj7wDVp80IsqNtGMi2w==", - "license": "Apache-2.0", - "dependencies": { - "async": "2.1 - 2.6.4", - "chalk": "4.1 - 4.1.2", - "iconv-lite": "0.4.13 - 0.6.3", - "ip-address": "5.8.9 - 5.9.4", - "lazy": "1.0.11", - "rimraf": "2.5.2 - 2.7.1", - "yauzl": "2.9.2 - 2.10.0" - }, - "engines": { - "node": ">=10.3.0" - } - }, - "node_modules/geoip-lite/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/geoip-lite/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/geoip-lite/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/geoip-lite/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -7718,6 +7626,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -7841,18 +7750,6 @@ "node": ">=10.17.0" } }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -7935,6 +7832,7 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "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.", + "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -7970,20 +7868,6 @@ "url": "https://opencollective.com/ioredis" } }, - "node_modules/ip-address": { - "version": "5.9.4", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-5.9.4.tgz", - "integrity": "sha512-dHkI3/YNJq4b/qQaz+c8LuarD3pY24JqZWfjB8aZx1gtpc2MDILu9L9jpZe1sHpzo/yWFweQVn+U//FhazUxmw==", - "license": "MIT", - "dependencies": { - "jsbn": "1.1.0", - "lodash": "^4.17.15", - "sprintf-js": "1.1.2" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -9715,12 +9599,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "license": "MIT" - }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -9855,15 +9733,6 @@ "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", "license": "MIT" }, - "node_modules/lazy": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz", - "integrity": "sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA==", - "license": "MIT", - "engines": { - "node": ">=0.2.0" - } - }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -10930,6 +10799,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -10999,12 +10869,6 @@ "node": ">=8" } }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "license": "MIT" - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -11513,62 +11377,6 @@ "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/router": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", @@ -12007,12 +11815,6 @@ "memory-pager": "^1.0.2" } }, - "node_modules/sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "license": "BSD-3-Clause" - }, "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", @@ -12218,6 +12020,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -13643,16 +13446,6 @@ "node": ">=12" } }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/package.json b/package.json index 4ca9ac5..6a0fcd6 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,6 @@ "consul": "^2.0.1", "date-fns": "^4.1.0", "ethers": "^6.13.4", - "geoip-lite": "^1.4.10", "h3-js": "^4.1.0", "keccak": "^3.0.4", "lodash": "^4.17.21", @@ -96,6 +95,9 @@ }, "overrides": { "elliptic": "^6.6.1", - "secp256k1": "^5.0.1" + "secp256k1": "^5.0.1", + "@ethersproject/providers": { + "ws": "^7.5.13" + } } } From da07a629063333f626944638ed93777239138af0 Mon Sep 17 00:00:00 2001 From: Jim Toth Date: Sun, 9 Aug 2026 04:52:17 -0400 Subject: [PATCH 07/15] Bump ao-client to v0.1.3 --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index de55be9..8bfb3e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.4.4", "license": "AGPL-3.0-only", "dependencies": { - "@anyone-protocol/ao-client": "github:anyone-protocol/ao-client#v0.1.2", + "@anyone-protocol/ao-client": "github:anyone-protocol/ao-client#v0.1.3", "@dha-team/arbundles": "^1.0.4", "@nestjs/axios": "^4.0.1", "@nestjs/bullmq": "^11.0.1", @@ -189,8 +189,8 @@ } }, "node_modules/@anyone-protocol/ao-client": { - "version": "0.1.0", - "resolved": "git+ssh://git@github.com/anyone-protocol/ao-client.git#4e18519624cfc1b7e067b311e5b41e3fd684037d", + "version": "0.1.3", + "resolved": "git+ssh://git@github.com/anyone-protocol/ao-client.git#3fc04052c7d76691d8345adcb24f6b5bf99d6988", "license": "AGPL-3.0-only", "engines": { "node": ">=20" diff --git a/package.json b/package.json index 6a0fcd6..896279c 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "test:e2e": "jest --config ./test/jest-e2e.json" }, "dependencies": { - "@anyone-protocol/ao-client": "github:anyone-protocol/ao-client#v0.1.2", + "@anyone-protocol/ao-client": "github:anyone-protocol/ao-client#v0.1.3", "@dha-team/arbundles": "^1.0.4", "@nestjs/axios": "^4.0.1", "@nestjs/bullmq": "^11.0.1", From 1762e860124ff4e6ab07cc6c333fe67bcda7151c Mon Sep 17 00:00:00 2001 From: Jim Toth Date: Tue, 11 Aug 2026 00:11:05 -0400 Subject: [PATCH 08/15] Allow this workflow to be triggered manually --- .github/workflows/release-action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release-action.yml b/.github/workflows/release-action.yml index 2d2cbb8..e0a0363 100644 --- a/.github/workflows/release-action.yml +++ b/.github/workflows/release-action.yml @@ -5,6 +5,7 @@ on: branches: main tags: - v* + workflow_dispatch: env: IMAGE_NAME: relay-rewards-controller From e67588d7e5c9441dca9a4f13d43f2a7d0c245c58 Mon Sep 17 00:00:00 2001 From: Jim Toth Date: Tue, 11 Aug 2026 00:18:33 -0400 Subject: [PATCH 09/15] Build and publish only; deploy is a separate step --- .github/workflows/release-action.yml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/.github/workflows/release-action.yml b/.github/workflows/release-action.yml index e0a0363..bde3eef 100644 --- a/.github/workflows/release-action.yml +++ b/.github/workflows/release-action.yml @@ -46,20 +46,3 @@ jobs: docker tag $IMAGE_NAME $IMAGE_ID:${GITHUB_SHA} docker push $IMAGE_ID:${GITHUB_SHA} - - - name: Deploy new version - env: - NOMAD_CACERT: admin-ui-ca.crt - NOMAD_TOKEN: ${{ secrets.NOMAD_TOKEN_RELAY_REWARDS_CONTROLLER_DEPLOY }} - NOMAD_ADDR: ${{ secrets.NOMAD_ADDR }} - run: | - curl -L https://releases.hashicorp.com/nomad/1.10.2/nomad_1.10.2_linux_amd64.zip -o nomad.zip - unzip nomad.zip - - if grep -q "stage" deploy-vars.json; then - sed -i "s/\[\[ .commit_sha \]\]/${GITHUB_SHA}/g" operations/relay-rewards-controller-stage.hcl - ./nomad job run operations/relay-rewards-controller-stage.hcl - else - sed -i "s/\[\[ .commit_sha \]\]/${GITHUB_SHA}/g" operations/relay-rewards-controller-live.hcl - ./nomad job run operations/relay-rewards-controller-live.hcl - fi From e949d20837e161076d594fa1911c633d2a818a6b Mon Sep 17 00:00:00 2001 From: Jim Toth Date: Tue, 11 Aug 2026 00:21:17 -0400 Subject: [PATCH 10/15] Take the image tag from a nomad variable --- operations/relay-rewards-controller-live.hcl | 9 +++++++-- operations/relay-rewards-controller-stage.hcl | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/operations/relay-rewards-controller-live.hcl b/operations/relay-rewards-controller-live.hcl index edb9428..ceb8169 100644 --- a/operations/relay-rewards-controller-live.hcl +++ b/operations/relay-rewards-controller-live.hcl @@ -1,3 +1,8 @@ +variable "commit_sha" { + type = string + description = "The git commit SHA to use for the runtime image tag" +} + job "relay-rewards-controller-live" { datacenters = ["ator-fin"] type = "service" @@ -28,13 +33,13 @@ job "relay-rewards-controller-live" { driver = "docker" config { network_mode = "host" - image = "ghcr.io/anyone-protocol/relay-rewards-controller:[[ .commit_sha ]]" + image = "ghcr.io/anyone-protocol/relay-rewards-controller:${var.commit_sha}" force_pull = true } env { IS_LIVE="true" - VERSION="[[ .commit_sha ]]" + VERSION = var.commit_sha REDIS_MODE="sentinel" REDIS_MASTER_NAME="relay-rewards-controller-live-redis-master" USE_HODLER = "true" diff --git a/operations/relay-rewards-controller-stage.hcl b/operations/relay-rewards-controller-stage.hcl index 26818bf..bf62999 100644 --- a/operations/relay-rewards-controller-stage.hcl +++ b/operations/relay-rewards-controller-stage.hcl @@ -1,3 +1,8 @@ +variable "commit_sha" { + type = string + description = "The git commit SHA to use for the runtime image tag" +} + job "relay-rewards-controller-stage" { datacenters = ["ator-fin"] type = "service" @@ -28,13 +33,13 @@ job "relay-rewards-controller-stage" { driver = "docker" config { network_mode = "host" - image = "ghcr.io/anyone-protocol/relay-rewards-controller:[[ .commit_sha ]]" + image = "ghcr.io/anyone-protocol/relay-rewards-controller:${var.commit_sha}" force_pull = true } env { IS_LIVE="true" - VERSION="[[ .commit_sha ]]" + VERSION = var.commit_sha REDIS_MODE="sentinel" REDIS_MASTER_NAME="relay-rewards-controller-stage-redis-master" USE_HODLER = "true" From 043964bb6b0dc5ff303f3e4e237486762895f33f Mon Sep 17 00:00:00 2001 From: Jim Toth Date: Wed, 12 Aug 2026 05:33:17 -0400 Subject: [PATCH 11/15] Probe the JSON-RPC endpoint at boot, and fail over when a backup exists A single hardcoded endpoint fails at use time rather than boot, so a stale key surfaces as a distribution error and can go unnoticed for weeks. This checks reachability at startup and says which host is live. JSON_RPC_BACKUP is optional: with one endpoint this is a health check that warns, with two it also fails over. --- src/evm-provider/evm-provider.module.ts | 11 ++ src/evm-provider/evm-provider.service.ts | 122 +++++++++++++++++++++ src/relay-rewards/relay-rewards.module.ts | 4 +- src/relay-rewards/relay-rewards.service.ts | 90 +++++++++++---- 4 files changed, 203 insertions(+), 24 deletions(-) create mode 100644 src/evm-provider/evm-provider.module.ts create mode 100644 src/evm-provider/evm-provider.service.ts diff --git a/src/evm-provider/evm-provider.module.ts b/src/evm-provider/evm-provider.module.ts new file mode 100644 index 0000000..c523a79 --- /dev/null +++ b/src/evm-provider/evm-provider.module.ts @@ -0,0 +1,11 @@ +import { Logger, Module } from '@nestjs/common' +import { ConfigModule } from '@nestjs/config' + +import { EvmProviderService } from './evm-provider.service' + +@Module({ + imports: [ConfigModule], + providers: [EvmProviderService, Logger], + exports: [EvmProviderService] +}) +export class EvmProviderModule {} diff --git a/src/evm-provider/evm-provider.service.ts b/src/evm-provider/evm-provider.service.ts new file mode 100644 index 0000000..ce52f63 --- /dev/null +++ b/src/evm-provider/evm-provider.service.ts @@ -0,0 +1,122 @@ +import { Injectable, Logger, OnApplicationBootstrap } from '@nestjs/common' +import { ConfigService } from '@nestjs/config' +import { ethers } from 'ethers' + +/** Host only, for log lines — never the key in the path. */ +const hostOf = (url: string) => { + try { return new URL(url).host } catch { return 'unparseable url' } +} + +const DefaultEvmProviderServiceConfig = { + JSON_RPC: '', + JSON_RPC_BACKUP: '' +} + +/** + * The JSON-RPC endpoint, checked at bootstrap, with an OPTIONAL second one. + * + * This exists because a single endpoint fails at USE time, not boot. A stale Infura key here + * started the controller cleanly and then threw `401 invalid project id` out of the distribution + * job, which reads like a distribution bug — and the same key had already been silently failing + * for ~26 days, which is why stage completed no rounds between 2026-06-13 and the migration. + * Probing at startup turns both of those into one obvious line. + * + * `JSON_RPC_BACKUP` is optional on purpose: spare provider keys are not always available, and a + * missing backup must not stop the service. With one endpoint this is a health check that warns; + * with two it also fails over. Which vendor is which is a jobspec decision, so nothing here + * names them — the log prints the host instead. + * + * It deliberately does NOT throw when the endpoint is unreachable. Reads will still fail the way + * they do today, but the reason is stated once at boot rather than inferred from a stack trace, + * and a provider blip cannot crash-loop the controller. + */ +@Injectable() +export class EvmProviderService implements OnApplicationBootstrap { + private readonly logger = new Logger(EvmProviderService.name) + + public readonly config: typeof DefaultEvmProviderServiceConfig = + DefaultEvmProviderServiceConfig + + private currentJsonRpcProvider?: ethers.JsonRpcProvider + private backupJsonRpcProvider?: ethers.JsonRpcProvider + + constructor(config: ConfigService) { + this.config.JSON_RPC = config.get('JSON_RPC', { infer: true }) + this.config.JSON_RPC_BACKUP = + config.get('JSON_RPC_BACKUP', { infer: true }) || '' + } + + async onApplicationBootstrap() { + if (!this.config.JSON_RPC) { + // Not fatal here: whether an RPC endpoint is required at all depends on USE_HODLER, and + // that decision belongs to the service that needs it. + this.logger.warn('JSON_RPC is not set — no EVM provider will be available') + + return + } + + const primary = new ethers.JsonRpcProvider(this.config.JSON_RPC) + const primaryName = `primary (${hostOf(this.config.JSON_RPC)})` + const primaryOk = await this.checkProvider(primaryName, primary) + + if (!this.config.JSON_RPC_BACKUP) { + this.currentJsonRpcProvider = primary + this.logger.warn( + `No JSON_RPC_BACKUP configured — running on ${primaryName} with NO failover` + + `${primaryOk ? '' : ', and it is NOT reachable right now'}` + ) + + return + } + + const secondary = new ethers.JsonRpcProvider(this.config.JSON_RPC_BACKUP) + const secondaryName = `secondary (${hostOf(this.config.JSON_RPC_BACKUP)})` + const secondaryOk = await this.checkProvider(secondaryName, secondary) + + // Prefer the primary, but do not insist on it — a dead primary with a healthy secondary is + // a degraded service, not a stopped one. + if (primaryOk || !secondaryOk) { + this.currentJsonRpcProvider = primary + this.backupJsonRpcProvider = secondaryOk ? secondary : undefined + if (primaryOk) { + this.logger.log(`Using ${primaryName}, ${secondaryName} standing by`) + } else { + this.logger.error( + `NEITHER JSON-RPC provider is reachable (${primaryName}, ${secondaryName}). ` + + `Continuing on ${primaryName}; EVM reads will fail until one recovers.` + ) + } + } else { + this.currentJsonRpcProvider = secondary + this.logger.warn( + `${primaryName} is unavailable — running on ${secondaryName} with NO failover` + ) + } + } + + /** Reachability, not credits: an auth failure and an outage both surface as a throw here. */ + private async checkProvider(name: string, provider: ethers.JsonRpcProvider) { + try { + const blockNumber = await provider.getBlockNumber() + this.logger.log(`${name} JSON-RPC provider is live at block ${blockNumber}`) + + return true + } catch (error) { + this.logger.error( + `${name} JSON-RPC provider is NOT usable: ` + + `${error instanceof Error ? error.message : error}` + ) + + return false + } + } + + async getCurrentJsonRpcProvider() { + return this.currentJsonRpcProvider + } + + /** `undefined` whenever there is no usable second endpoint — callers must handle that. */ + async getBackupJsonRpcProvider() { + return this.backupJsonRpcProvider + } +} diff --git a/src/relay-rewards/relay-rewards.module.ts b/src/relay-rewards/relay-rewards.module.ts index deea997..3b6a562 100644 --- a/src/relay-rewards/relay-rewards.module.ts +++ b/src/relay-rewards/relay-rewards.module.ts @@ -3,8 +3,10 @@ import { RelayRewardsService } from './relay-rewards.service' import { ConfigModule } from '@nestjs/config' import { HttpModule } from '@nestjs/axios' +import { EvmProviderModule } from '../evm-provider/evm-provider.module' + @Module({ - imports: [ConfigModule, HttpModule], + imports: [ConfigModule, HttpModule, EvmProviderModule], providers: [RelayRewardsService, Logger], exports: [RelayRewardsService], }) diff --git a/src/relay-rewards/relay-rewards.service.ts b/src/relay-rewards/relay-rewards.service.ts index 4cc0a5c..5bda01b 100644 --- a/src/relay-rewards/relay-rewards.service.ts +++ b/src/relay-rewards/relay-rewards.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Logger } from '@nestjs/common' +import { Injectable, Logger, OnApplicationBootstrap } from '@nestjs/common' import { ethers, Wallet } from 'ethers' import _ from 'lodash' import { EthereumSigner } from '@dha-team/arbundles' @@ -12,16 +12,19 @@ import { ConfigService } from '@nestjs/config' import { AddScoresData } from 'src/distribution/dto/add-scores' import RoundSnapshot from 'src/distribution/dto/round-snapshot' import { hodlerABI } from './abi/hodler' +import { EvmProviderService } from '../evm-provider/evm-provider.service' @Injectable() -export class RelayRewardsService { +export class RelayRewardsService implements OnApplicationBootstrap { private readonly logger = new Logger(RelayRewardsService.name) private isLive?: string private readonly relayRewardsProcessId: string private readonly relayRewardsControllerKey: string - private readonly hodlerContract: ethers.Contract + private hodlerContract?: ethers.Contract + private backupHodlerContract?: ethers.Contract + private readonly hodlerAddress?: string private readonly hbUrl: string private ao!: AoClient @@ -37,7 +40,8 @@ export class RelayRewardsService { JSON_RPC: string USE_HODLER: string HB_URL: string - }> + }>, + private readonly evmProvider: EvmProviderService ) { this.isLive = config.get('IS_LIVE', { infer: true }) @@ -46,23 +50,11 @@ export class RelayRewardsService { this.logger.log(`Initializing relay rewards service (IS_LIVE: ${this.isLive}, USE_HODLER: ${this.useHodler})`) if (this.useHodler) { - const jsonRpc = this.config.get('JSON_RPC', { infer: true }) - if (!jsonRpc) { - this.logger.error('Missing JSON RPC URL') - throw new Error('Missing JSON RPC URL') + this.hodlerAddress = this.config.get('HODLER_CONTRACT_ADDRESS', { infer: true }) + if (!this.hodlerAddress) { + this.logger.error('Missing HODLER contract address') + throw new Error('Missing HODLER contract address') } - const provider = new ethers.JsonRpcProvider(jsonRpc) - - const hodlerAddress = this.config.get('HODLER_CONTRACT_ADDRESS', { infer: true }) - this.hodlerContract = new ethers.Contract( - hodlerAddress, - hodlerABI, - provider - ) - - if (!this.hodlerContract) { - this.logger.error('Failed to initialize HODLER contract') - } else this.logger.log(`HODLER contract initialized at address: ${hodlerAddress}`) } const relayRewardsPid = this.config.get('RELAY_REWARDS_PROCESS_ID', { @@ -110,6 +102,50 @@ export class RelayRewardsService { error.stack ) } + + if (this.useHodler) { + const provider = await this.evmProvider.getCurrentJsonRpcProvider() + const backup = await this.evmProvider.getBackupJsonRpcProvider() + if (!provider) { + this.logger.error('USE_HODLER is true but no EVM provider is configured') + throw new Error('Missing JSON RPC URL') + } + + this.hodlerContract = + new ethers.Contract(this.hodlerAddress!, hodlerABI, provider) + if (backup) { + this.backupHodlerContract = + new ethers.Contract(this.hodlerAddress!, hodlerABI, backup) + } + this.logger.log( + `HODLER contract initialized at address: ${this.hodlerAddress}` + + `${backup ? ' (with backup provider)' : ' (NO backup provider)'}` + ) + } + } + + /** + * Run a hodler read against the current provider, once more against the backup on failure. + * + * The bootstrap probe only proves an endpoint was alive THEN; this covers one that dies + * between bootstrap and use. Mirrors the retry in operator-registry-controller's hardware + * verification. + */ + private async withHodlerFallback( + label: string, + call: (contract: ethers.Contract) => Promise + ): Promise { + try { + return await call(this.hodlerContract!) + } catch (error) { + if (!this.backupHodlerContract) { throw error } + this.logger.warn( + `${label} failed on the current JSON-RPC provider, retrying on the backup: ` + + `${error instanceof Error ? error.message : error}` + ) + + return await call(this.backupHodlerContract) + } } public async getHodlerData(): Promise<{ @@ -124,11 +160,16 @@ export class RelayRewardsService { return { locksData, stakingData } } - const keys = await this.hodlerContract.getHodlerKeys() + const keys = await this.withHodlerFallback( + 'getHodlerKeys', c => c.getHodlerKeys() + ) for (const key of keys) { const hodlerAddress = ethers.getAddress(key) - const locks: { fingerprint: string, operator: string, amount: string }[] = await this.hodlerContract.getLocks(hodlerAddress) + const locks: { fingerprint: string, operator: string, amount: string }[] = + await this.withHodlerFallback( + `getLocks(${hodlerAddress})`, c => c.getLocks(hodlerAddress) + ) locks.forEach((lock) => { if (!locksData[lock.fingerprint]) { locksData[lock.fingerprint] = [] @@ -139,7 +180,10 @@ export class RelayRewardsService { } }) - const stakes: { operator: string, amount: string }[] = await this.hodlerContract.getStakes(hodlerAddress) + const stakes: { operator: string, amount: string }[] = + await this.withHodlerFallback( + `getStakes(${hodlerAddress})`, c => c.getStakes(hodlerAddress) + ) stakes.forEach((stake) => { const operatorAddress = ethers.getAddress(stake.operator) if (operatorAddress && operatorAddress.length > 0) { From 92aa70c98be4b9ba7a08daf4cdecd129d3320fcf Mon Sep 17 00:00:00 2001 From: Jim Toth Date: Wed, 12 Aug 2026 06:08:59 -0400 Subject: [PATCH 12/15] Batch Add-Scores by bytes rather than a fixed count 420 per message encoded a legacynet limit; the constraint now is the uploader's 5 MiB item cap, so budget against that instead. A live-sized round fits in one message, which cuts store growth 5.2x by taking a round from 16 slots to 2, and makes the round atomic: batches can no longer partially land and settle short. Also maps src/ imports for jest, without which the distribution spec could not load at all. --- package.json | 3 + src/distribution/distribution.service.spec.ts | 62 ++++++++++++++- src/distribution/distribution.service.ts | 78 ++++++++++++++----- 3 files changed, 122 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 896279c..e7c9e80 100644 --- a/package.json +++ b/package.json @@ -84,6 +84,9 @@ ], "rootDir": "src", "testRegex": ".*\\.spec\\.ts$", + "moduleNameMapper": { + "^src/(.*)$": "/$1" + }, "transform": { "^.+\\.(t|j)s$": "ts-jest" }, diff --git a/src/distribution/distribution.service.spec.ts b/src/distribution/distribution.service.spec.ts index 8b3793a..c4e470f 100644 --- a/src/distribution/distribution.service.spec.ts +++ b/src/distribution/distribution.service.spec.ts @@ -8,10 +8,14 @@ describe('DistributionService', () => { let module: TestingModule beforeEach(async () => { + // DistributionService takes nine collaborators; auto-mock the ones a unit test does not + // exercise, rather than hand-wiring Mongoose model tokens for tests that never touch them. module = await Test.createTestingModule({ imports: [ConfigModule.forRoot()], providers: [DistributionService], - }).compile() + }) + .useMocker(() => ({})) + .compile() service = module.get(DistributionService) }) @@ -26,6 +30,62 @@ describe('DistributionService', () => { expect(service).toBeDefined() }) + // groupScoreJobs batches by BYTES against the uploader's 5 MiB item cap. These are cheap and + // pure, and the failure they guard against is silent: a batch that overshoots the cap is + // rejected at upload, and a round that splits when it need not costs slots and store. + describe('groupScoreJobs', () => { + const CAP = 5 * 1024 * 1024 + const BUDGET = Math.floor(CAP * 0.8) + const score = (i: number) => ({ + Fingerprint: i.toString(16).toUpperCase().padStart(40, '0'), + Address: '0x' + i.toString(16).padStart(40, '0'), + Network: 1300, IsHardware: true, ExitBonus: false, + UptimeStreak: 3, FamilySize: 0, LocationSize: 1, + }) + // What addScores actually serializes, so the assertions measure the real wire payload. + const wireBytes = (batch: ReturnType[]) => { + const map: Record = {} + batch.forEach(s => (map[s.Fingerprint] = s)) + return JSON.stringify({ Scores: map }).length + } + + it('puts a live-sized round in ONE message', () => { + const groups = service.groupScoreJobs( + Array.from({ length: 6010 }, (_, i) => score(i + 1)) as any + ) + expect(groups).toHaveLength(1) + expect(groups[0]).toHaveLength(6010) + expect(wireBytes(groups[0] as any)).toBeLessThan(BUDGET) + }) + + it('keeps every batch under the budget once splitting is needed', () => { + const groups = service.groupScoreJobs( + Array.from({ length: 40000 }, (_, i) => score(i + 1)) as any + ) + expect(groups.length).toBeGreaterThan(1) + for (const g of groups) { + expect(wireBytes(g as any)).toBeLessThanOrEqual(BUDGET) + expect(wireBytes(g as any)).toBeLessThan(CAP) // the constraint that actually matters + } + }) + + it('loses no scores and preserves order when it splits', () => { + const input = Array.from({ length: 40000 }, (_, i) => score(i + 1)) + const flat = service.groupScoreJobs(input as any).flat() + expect(flat).toHaveLength(input.length) + expect(flat.map((s: any) => s.Fingerprint)).toEqual(input.map(s => s.Fingerprint)) + }) + + it('emits no empty groups, including for empty input', () => { + expect(service.groupScoreJobs([])).toEqual([]) + for (const g of service.groupScoreJobs( + Array.from({ length: 40000 }, (_, i) => score(i + 1)) as any + )) { + expect(g.length).toBeGreaterThan(0) + } + }) + }) + // Skipped tests are part of implemented spec, but skipped for now as expensive testing of logs/e2e it.skip('should attempt to retry failed transactions for a distribution.', () => {}) it.skip('should not finalize the distribution until all transactions succeed.', () => {}) diff --git a/src/distribution/distribution.service.ts b/src/distribution/distribution.service.ts index d4f697d..83a4ff4 100644 --- a/src/distribution/distribution.service.ts +++ b/src/distribution/distribution.service.ts @@ -28,7 +28,30 @@ export class DistributionService { private isLive?: string - private static readonly scoresPerBatch = 420 + /** + * Batch `Add-Scores` by BYTES, not by a fixed count. + * + * The constraint that actually exists is the uploader's item size limit: the node pushes every + * scheduled message to Arweave via up.arweave.net, which caps an item at 5 MiB. The old + * `scoresPerBatch = 420` predates this stack and encoded a legacynet limit instead, so it split + * a round into ~15 messages that no longer need splitting. + * + * That split is not free. Each message is its own slot, and every slot writes state-sized data: + * measured at live cardinality, one message per round cut store growth from 167 MiB to 32 MiB + * per round (5.2x) with no change in wall clock, because the per-relay cost is keccak in the + * contract and does not care how the scores arrive. + * + * It also makes a round ATOMIC. With N batches, some can land and one can fail, and + * `Complete-Round` will happily settle the incomplete set: relays whose batch went missing are + * silently under-rewarded. One message either lands or does not. + * + * Budgeted at 80% of the cap so tags, the ans104 envelope and any growth between rounds have + * room. At today's ~260 B/relay that is ~16,100 relays in one message, against 6,010 live. + */ + private static readonly ITEM_SIZE_LIMIT = 5 * 1024 * 1024 + private static readonly maxBatchBytes = Math.floor( + DistributionService.ITEM_SIZE_LIMIT * 0.8 + ) private readonly useHodler: boolean constructor( @@ -59,28 +82,43 @@ export class DistributionService { } public groupScoreJobs(data: ScoreData[]): ScoreData[][] { - const result = data.reduce((curr, score): ScoreData[][] => { - if (curr.length == 0) { - curr.push([score]) - } else { - if (curr[curr.length - 1].length < DistributionService.scoresPerBatch) { - const last = curr.pop() - if (last != undefined) { - last.push(score) - curr.push(last) - } else { - this.logger.error('Last element not found, this should not happen') - } - } else { - curr.push([score]) - } + // Mirror what addScores actually puts on the wire: {"Scores":{"":{...},...}} + const ENVELOPE = '{"Scores":{}}'.length + // "": {...} plus the separating comma + const entrySize = (s: ScoreData) => + s.Fingerprint.length + JSON.stringify(s).length + 4 + + const groups: ScoreData[][] = [] + let current: ScoreData[] = [] + let bytes = ENVELOPE + + for (const score of data) { + const size = entrySize(score) + // Never emit an empty group: a single score wider than the budget still has to go, since + // there is nothing left to split. It would fail at upload, loudly, rather than silently here. + if (current.length > 0 && bytes + size > DistributionService.maxBatchBytes) { + groups.push(current) + current = [] + bytes = ENVELOPE } - return curr - }, []) + current.push(score) + bytes += size + } + if (current.length > 0) { + groups.push(current) + } - this.logger.debug(`Created ${result.length} groups out of ${data.length}`) + const budgetKB = Math.round(DistributionService.maxBatchBytes / 1024) + const largest = groups.reduce( + (max, g) => Math.max(max, g.reduce((b, s) => b + entrySize(s), ENVELOPE)), + 0 + ) + this.logger.log( + `Grouped ${data.length} scores into ${groups.length} message(s), ` + + `largest ${Math.round(largest / 1024)}KB of a ${budgetKB}KB budget` + ) - return result + return groups } private async fetchRelays(): Promise { From 3d76b0d8c5645c2234b73a12fc5ef718072562ea Mon Sep 17 00:00:00 2001 From: Jim Toth Date: Wed, 12 Aug 2026 07:00:19 -0400 Subject: [PATCH 13/15] Guard the bundler item size, retry transient uploads, and stop sending the fingerprint twice The bundler refuses items over 5 MiB and nothing in the path said how close we were: the relay summary is already ~62% of the cap at 6,010 relays. Reject oversized items before spending a signature and a 300s POST, and warn from 80%. Retry the POST for conditions that can clear, but not for a 4xx or a size rejection, which are config and deterministic. The item is signed once and keeps its id, so re-posting is idempotent. The fingerprint was sent as both the map key and a field inside the value, which the contract never reads. One definition of the wire shape now serves the sender and the batcher, so their sizes cannot drift. --- src/bundling/bundling.service.spec.ts | 58 ++++++++++ src/bundling/bundling.service.ts | 105 +++++++++++++++--- src/distribution/distribution.service.spec.ts | 19 +++- src/distribution/distribution.service.ts | 26 ++++- 4 files changed, 186 insertions(+), 22 deletions(-) create mode 100644 src/bundling/bundling.service.spec.ts diff --git a/src/bundling/bundling.service.spec.ts b/src/bundling/bundling.service.spec.ts new file mode 100644 index 0000000..0cfbeb7 --- /dev/null +++ b/src/bundling/bundling.service.spec.ts @@ -0,0 +1,58 @@ +import { ConfigService } from '@nestjs/config' + +import { BundlingService } from './bundling.service' + +/** + * The bundler refuses items over 5 MiB. This guard is the only thing in the path that says so + * before we spend a signature and a 300s POST on an item that cannot be accepted. + * + * It matters because we are already close: the relay `distribution/summary` measures ~541 B per + * scored relay, which puts 6,010 relays at ~62% of the cap and the ceiling near 9,691. + */ +describe('BundlingService size guard', () => { + const CAP = 5 * 1024 * 1024 + // A marked throwaway test key. Never used to sign anything but these local assertions. + const TEST_KEY = + '0123456789012345678901234567890123456789012345678901234567890123' + + const service = () => + new BundlingService( + new ConfigService({ + BUNDLER_CONTROLLER_KEY: TEST_KEY, + BUNDLER_NODE: 'http://localhost:1' + }) as any + ) + + it('refuses an item over the cap, naming the size and the limit', async () => { + await expect( + service().upload(Buffer.alloc(CAP + 1), { tags: [] }) + ).rejects.toThrow(/over the 5MiB bundler limit/) + }) + + it('refuses before signing or posting, so the failure is fast and self-explaining', async () => { + // The bundler node points at a closed port: if the guard did not fire first, this would + // surface as a connection error instead of the size message. + await expect( + service().upload(Buffer.alloc(CAP + 1), { tags: [] }) + ).rejects.toThrow(/cannot be uploaded as a single item/) + }) + + // These two DO reach the network (the guard's job is to let them past), and the bundler node + // points at a closed port, so they fail on transport after the retries back off. The + // assertion is on WHICH error: anything but the size guard means the guard passed it on. + const failureFrom = async (bytes: number) => { + const error = await service() + .upload(Buffer.alloc(bytes), { tags: [] }) + .then(() => null, (e: Error) => e) + + return String(error?.message ?? '') + } + + it('lets an item just under the cap through to the network', async () => { + expect(await failureFrom(CAP - 1024)).not.toMatch(/bundler limit/) + }, 30_000) + + it('passes a realistic live-sized summary (6,010 relays at ~541 B)', async () => { + expect(await failureFrom(541 * 6010)).not.toMatch(/bundler limit/) + }, 30_000) +}) diff --git a/src/bundling/bundling.service.ts b/src/bundling/bundling.service.ts index 51064aa..34f9b91 100644 --- a/src/bundling/bundling.service.ts +++ b/src/bundling/bundling.service.ts @@ -56,10 +56,42 @@ export class BundlingService { ) } + /** + * up.arweave.net rejects a data item over 5 MiB. Nothing else in the path notices how close we + * are, so this is where it gets said. + * + * This is not hypothetical headroom: the relay `distribution/summary` measured 541 B per scored + * relay, so 6,010 relays is already ~62% of the cap and the ceiling is ~9,691. The seed carries + * 9,750 lifetime fingerprints. Crossing it does not lose rewards (those settle on-chain in + * `Complete-Round`) but it does lose that round's published archive, and today the only trace + * would be one error line. + */ + private static readonly ITEM_SIZE_LIMIT = 5 * 1024 * 1024 + private static readonly WARN_AT = 0.8 + async upload( data: string | Buffer, dataItemOpts: { tags?: { name: string, value: string }[] } ): Promise<{ id: string }> { + const size = typeof data === 'string' ? Buffer.byteLength(data) : data.length + const pct = Math.round((size / BundlingService.ITEM_SIZE_LIMIT) * 100) + if (size > BundlingService.ITEM_SIZE_LIMIT) { + // Fail here rather than burn a signature and a 300s POST on an item the bundler will + // refuse, and name the real cause instead of leaving an opaque HTTP error. + throw new Error( + `Item is ${Math.round(size / 1024)}KB, over the ${ + BundlingService.ITEM_SIZE_LIMIT / 1024 / 1024 + }MiB bundler limit (${pct}%). It cannot be uploaded as a single item.` + ) + } + if (size > BundlingService.ITEM_SIZE_LIMIT * BundlingService.WARN_AT) { + this.logger.warn( + `Item is ${Math.round(size / 1024)}KB, ${pct}% of the bundler's ` + + `${BundlingService.ITEM_SIZE_LIMIT / 1024 / 1024}MiB limit. ` + + `Uploads will start failing as this grows.` + ) + } + const item = createData( typeof data === 'string' ? data : Buffer.from(data), this.signer, @@ -67,29 +99,68 @@ export class BundlingService { ) await item.sign(this.signer) - const response = await fetch(`${this.bundlerNode}/~bundler@1.0/tx`, { - method: 'POST', - headers: { - 'Content-Type': 'application/ans104', - 'codec-device': 'ans104@1.0', - // Required. Without it a HyperBEAM bundler answers with the Hyperbuddy HTML UI - // and HTTP 200, which reads as success and is not. - 'Accept': 'application/json' - }, - // getRaw() hands back a Node Buffer, which does not satisfy BodyInit under the DOM - // lib types even though it is a Uint8Array at runtime. - body: new Uint8Array(item.getRaw()), - signal: AbortSignal.timeout(300_000) - }) + // Retry the POST, not the signing: the item is signed once and keeps its id, so re-posting + // it is idempotent. Only worth doing for conditions that can clear on their own. A 4xx is + // config (typically this signer missing from the bundler's faff allow-list) and a size + // rejection is deterministic, so both fail on the first attempt rather than three times + // slower. Round cadence is 15 minutes, so a few seconds of backoff costs nothing and turns + // a transient blip into a round that still gets archived. + const ATTEMPTS = 3 + let lastError: Error | undefined + + for (let attempt = 1; attempt <= ATTEMPTS; attempt++) { + let response: Response + try { + response = await fetch(`${this.bundlerNode}/~bundler@1.0/tx`, { + method: 'POST', + headers: { + 'Content-Type': 'application/ans104', + 'codec-device': 'ans104@1.0', + // Required. Without it a HyperBEAM bundler answers with the Hyperbuddy HTML UI + // and HTTP 200, which reads as success and is not. + 'Accept': 'application/json' + }, + // getRaw() hands back a Node Buffer, which does not satisfy BodyInit under the DOM + // lib types even though it is a Uint8Array at runtime. + body: new Uint8Array(item.getRaw()), + signal: AbortSignal.timeout(300_000) + }) + } catch (error) { + // Network failure or timeout: no response at all, always worth another try. + lastError = error instanceof Error ? error : new Error(String(error)) + if (attempt < ATTEMPTS) { + this.logger.warn( + `Bundler POST for item ${item.id} failed (attempt ${attempt}/${ATTEMPTS}): ` + + `${lastError.message}. Retrying.` + ) + await new Promise(r => setTimeout(r, attempt * 2000)) + continue + } + throw lastError + } + + const body = (await response.text()).replace(/\s+/g, ' ') + if (response.ok && body.includes('"id"')) { + if (attempt > 1) { + this.logger.log(`Bundler accepted item ${item.id} on attempt ${attempt}`) + } + break + } - const body = (await response.text()).replace(/\s+/g, ' ') - if (!response.ok || !body.includes('"id"')) { // A 400 against our own node almost always means this signer is not on the // bundler's faff allow-list, which is config rather than a code fault. - throw new Error( + lastError = new Error( `Bundler refused item ${item.id} with HTTP ${response.status}: ` + body.slice(0, 200) ) + const worthRetrying = response.status >= 500 || response.status === 429 + if (!worthRetrying || attempt === ATTEMPTS) { + throw lastError + } + this.logger.warn( + `${lastError.message} (attempt ${attempt}/${ATTEMPTS}). Retrying.` + ) + await new Promise(r => setTimeout(r, attempt * 2000)) } // The id that settles on Arweave is the SIGNED item id — NOT any id the node may diff --git a/src/distribution/distribution.service.spec.ts b/src/distribution/distribution.service.spec.ts index c4e470f..553f1cc 100644 --- a/src/distribution/distribution.service.spec.ts +++ b/src/distribution/distribution.service.spec.ts @@ -42,10 +42,11 @@ describe('DistributionService', () => { Network: 1300, IsHardware: true, ExitBonus: false, UptimeStreak: 3, FamilySize: 0, LocationSize: 1, }) - // What addScores actually serializes, so the assertions measure the real wire payload. + // What addScores actually serializes, so the assertions measure the real wire payload: + // fingerprint as the KEY only, never repeated inside the value. const wireBytes = (batch: ReturnType[]) => { const map: Record = {} - batch.forEach(s => (map[s.Fingerprint] = s)) + batch.forEach(({ Fingerprint, ...rest }) => (map[Fingerprint] = rest)) return JSON.stringify({ Scores: map }).length } @@ -76,6 +77,20 @@ describe('DistributionService', () => { expect(flat.map((s: any) => s.Fingerprint)).toEqual(input.map(s => s.Fingerprint)) }) + it('estimates the batch size as the wire payload, not the input objects', () => { + const batch = Array.from({ length: 500 }, (_, i) => score(i + 1)) + const groups = service.groupScoreJobs(batch as any) + expect(groups).toHaveLength(1) + // The estimate must track the SENT shape. If it measured the input objects it would count + // the Fingerprint twice and over-reserve by ~57 B per relay. + const sent = wireBytes(groups[0] as any) + const withDuplicate = JSON.stringify({ + Scores: Object.fromEntries(batch.map(s => [s.Fingerprint, s])) + }).length + expect(sent).toBeLessThan(withDuplicate) + expect((withDuplicate - sent) / batch.length).toBeGreaterThan(50) + }) + it('emits no empty groups, including for empty input', () => { expect(service.groupScoreJobs([])).toEqual([]) for (const g of service.groupScoreJobs( diff --git a/src/distribution/distribution.service.ts b/src/distribution/distribution.service.ts index 83a4ff4..0bb0c76 100644 --- a/src/distribution/distribution.service.ts +++ b/src/distribution/distribution.service.ts @@ -81,12 +81,30 @@ export class DistributionService { ) } + /** + * The value `Add-Scores` puts on the wire for one relay: everything except `Fingerprint`, + * which is already the map key. + * + * Sending it twice cost ~57 B per relay, ~335 KB on a live round, for a field the contract + * never reads from the value (it takes the fingerprint from the key and validates that). The + * `Omit` on AddScoresData always claimed this shape; assigning the whole object did not + * trigger an excess-property check, so the claim was silently false. + * + * Shared with the batcher so its size estimate cannot drift from what is actually sent. + */ + private static wireValue( + { Fingerprint, ...rest }: ScoreData + ): Omit { + return rest + } + public groupScoreJobs(data: ScoreData[]): ScoreData[][] { // Mirror what addScores actually puts on the wire: {"Scores":{"":{...},...}} const ENVELOPE = '{"Scores":{}}'.length - // "": {...} plus the separating comma + // "":{...} plus quotes, colon and the separating comma const entrySize = (s: ScoreData) => - s.Fingerprint.length + JSON.stringify(s).length + 4 + s.Fingerprint.length + + JSON.stringify(DistributionService.wireValue(s)).length + 4 const groups: ScoreData[][] = [] let current: ScoreData[] = [] @@ -331,7 +349,9 @@ export class DistributionService { public async addScores(stamp: number, scores: ScoreData[]): Promise { const scoresForLua: AddScoresData = {} - scores.forEach(score => (scoresForLua[score.Fingerprint] = score)) + scores.forEach(score => { + scoresForLua[score.Fingerprint] = DistributionService.wireValue(score) + }) return this.relayRewardsService.addScores(stamp, scoresForLua) } From 4704118124afb4f174e7ab6112c1c8e7ee96f178 Mon Sep 17 00:00:00 2001 From: Jim Toth Date: Wed, 12 Aug 2026 07:29:08 -0400 Subject: [PATCH 14/15] Give the relay rewards spec the EVM provider module it now depends on --- src/relay-rewards/relay-rewards.service.spec.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/relay-rewards/relay-rewards.service.spec.ts b/src/relay-rewards/relay-rewards.service.spec.ts index 5803fa6..cee8d0e 100644 --- a/src/relay-rewards/relay-rewards.service.spec.ts +++ b/src/relay-rewards/relay-rewards.service.spec.ts @@ -16,6 +16,7 @@ import { Logger } from '@nestjs/common' import { ConfigModule } from '@nestjs/config' import { Test, TestingModule } from '@nestjs/testing' +import { EvmProviderModule } from '../evm-provider/evm-provider.module' import { RelayRewardsService } from './relay-rewards.service' const HAVE_NODE = !!process.env.RELAY_REWARDS_PROCESS_ID && !!process.env.HB_URL @@ -26,8 +27,11 @@ describe('RelayRewardsService', () => { let service: RelayRewardsService beforeEach(async () => { + // EvmProviderModule is real rather than mocked: RelayRewardsService resolves its Hodler + // contract from it during onApplicationBootstrap, so a stub would skip the wiring this + // test exists to exercise. With USE_HODLER unset it probes nothing and stays quiet. module = await Test.createTestingModule({ - imports: [ConfigModule.forRoot({ isGlobal: true })], + imports: [ConfigModule.forRoot({ isGlobal: true }), EvmProviderModule], providers: [RelayRewardsService] }) .setLogger(new Logger()) From e57f65ba7c6dda940396a0fcd97ecef7c17ebc28 Mon Sep 17 00:00:00 2001 From: Jim Toth Date: Thu, 3 Sep 2026 21:23:45 -0400 Subject: [PATCH 15/15] match stage round period to live at 3600s --- operations/relay-rewards-controller-stage.hcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operations/relay-rewards-controller-stage.hcl b/operations/relay-rewards-controller-stage.hcl index bf62999..35ee979 100644 --- a/operations/relay-rewards-controller-stage.hcl +++ b/operations/relay-rewards-controller-stage.hcl @@ -48,7 +48,7 @@ job "relay-rewards-controller-stage" { BUNDLER_NODE="https://up.arweave.net" GEODATADIR="/geo-ip-db/data" GEOTMPDIR="/geo-ip-db/tmp" - ROUND_PERIOD_SECONDS="900" + ROUND_PERIOD_SECONDS="3600" DO_CLEAN="true" PORT="${NOMAD_PORT_http}" NO_COLOR="1"