From 555eafcd0fb1fa8764288827cbaa63ef6bd2ff8f Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 8 May 2025 11:53:58 -0400 Subject: [PATCH 001/303] chore(deps-dev): bump react-refresh from 0.14.2 to 0.17.0 --- demos/taco-demo/package.json | 2 +- demos/taco-nft-demo/package.json | 2 +- pnpm-lock.yaml | 22 +++++++++++----------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/demos/taco-demo/package.json b/demos/taco-demo/package.json index e69859f93..8b674202d 100644 --- a/demos/taco-demo/package.json +++ b/demos/taco-demo/package.json @@ -34,7 +34,7 @@ "esbuild-loader": "^2.21.0", "html-webpack-plugin": "^5.6.3", "process": "^0.11.10", - "react-refresh": "^0.14.2", + "react-refresh": "^0.17.0", "rimraf": "^5.0.10", "stream-browserify": "^3.0.0", "typescript": "^4.9.5", diff --git a/demos/taco-nft-demo/package.json b/demos/taco-nft-demo/package.json index 95b7acbf5..a3cadb6f1 100644 --- a/demos/taco-nft-demo/package.json +++ b/demos/taco-nft-demo/package.json @@ -31,7 +31,7 @@ "copy-webpack-plugin": "^12.0.2", "esbuild-loader": "^2.21.0", "html-webpack-plugin": "^5.6.3", - "react-refresh": "^0.14.2", + "react-refresh": "^0.17.0", "rimraf": "^5.0.10", "stream-browserify": "^3.0.0", "typescript": "^4.9.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7393a03f0..5f414cbc0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -145,7 +145,7 @@ importers: devDependencies: '@pmmmwh/react-refresh-webpack-plugin': specifier: ^0.5.15 - version: 0.5.15(react-refresh@0.14.2)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4)) + version: 0.5.15(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4)) '@types/react': specifier: ^18.3.20 version: 18.3.20 @@ -171,8 +171,8 @@ importers: specifier: ^0.11.10 version: 0.11.10 react-refresh: - specifier: ^0.14.2 - version: 0.14.2 + specifier: ^0.17.0 + version: 0.17.0 rimraf: specifier: ^5.0.10 version: 5.0.10 @@ -230,7 +230,7 @@ importers: devDependencies: '@pmmmwh/react-refresh-webpack-plugin': specifier: ^0.5.15 - version: 0.5.15(react-refresh@0.14.2)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4)) + version: 0.5.15(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4)) '@types/react': specifier: ^18.3.20 version: 18.3.20 @@ -250,8 +250,8 @@ importers: specifier: ^5.6.3 version: 5.6.3(webpack@5.98.0(webpack-cli@5.1.4)) react-refresh: - specifier: ^0.14.2 - version: 0.14.2 + specifier: ^0.17.0 + version: 0.17.0 rimraf: specifier: ^5.0.10 version: 5.0.10 @@ -7706,8 +7706,8 @@ packages: resolution: {integrity: sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==} engines: {node: '>=0.10.0'} - react-refresh@0.14.2: - resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} + react-refresh@0.17.0: + resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} engines: {node: '>=0.10.0'} react-scripts@5.0.1: @@ -11580,14 +11580,14 @@ snapshots: type-fest: 0.21.3 webpack-dev-server: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.98.0) - '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.14.2)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4))': + '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4))': dependencies: ansi-html: 0.0.9 core-js-pure: 3.41.0 error-stack-parser: 2.1.4 html-entities: 2.5.3 loader-utils: 2.0.4 - react-refresh: 0.14.2 + react-refresh: 0.17.0 schema-utils: 4.3.0 source-map: 0.7.4 webpack: 5.98.0(webpack-cli@5.1.4) @@ -18127,7 +18127,7 @@ snapshots: react-refresh@0.11.0: {} - react-refresh@0.14.2: {} + react-refresh@0.17.0: {} react-scripts@5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(@types/babel__core@7.20.5)(bufferutil@4.0.9)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(type-fest@0.21.3)(typescript@5.8.2)(utf-8-validate@5.0.10): dependencies: From 9ccd94aa9ee8833857139c6637308fe5df28ebf4 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 8 May 2025 11:59:41 -0400 Subject: [PATCH 002/303] chore(deps): bump dotenv from 16.3.1 to 16.5.0 --- examples/taco/nodejs/package.json | 2 +- packages/taco/package.json | 2 +- pnpm-lock.yaml | 14 ++++++++++---- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/examples/taco/nodejs/package.json b/examples/taco/nodejs/package.json index 8fca0d054..b76b20a3e 100644 --- a/examples/taco/nodejs/package.json +++ b/examples/taco/nodejs/package.json @@ -12,7 +12,7 @@ "dependencies": { "@nucypher/taco": "workspace:*", "@nucypher/taco-auth": "workspace:*", - "dotenv": "^16.4.7", + "dotenv": "^16.5.0", "ethers": "^5.8.0" } } diff --git a/packages/taco/package.json b/packages/taco/package.json index 1a3a675e5..39fcf9f7e 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -52,7 +52,7 @@ "devDependencies": { "@nucypher/test-utils": "workspace:*", "@types/semver": "^7.7.0", - "dotenv": "^16.4.7", + "dotenv": "^16.5.0", "glob": "^11.0.1", "modified-zod2md": "0.1.5-modified.4" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5f414cbc0..e806c8078 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -420,8 +420,8 @@ importers: specifier: workspace:* version: link:../../../packages/taco-auth dotenv: - specifier: ^16.4.7 - version: 16.4.7 + specifier: ^16.5.0 + version: 16.5.0 ethers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -590,8 +590,8 @@ importers: specifier: ^7.7.0 version: 7.7.0 dotenv: - specifier: ^16.4.7 - version: 16.4.7 + specifier: ^16.5.0 + version: 16.5.0 glob: specifier: ^11.0.1 version: 11.0.1 @@ -4606,6 +4606,10 @@ packages: resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} engines: {node: '>=12'} + dotenv@16.5.0: + resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} + engines: {node: '>=12'} + dotgitignore@2.1.0: resolution: {integrity: sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==} engines: {node: '>=6'} @@ -14184,6 +14188,8 @@ snapshots: dotenv@16.4.7: {} + dotenv@16.5.0: {} + dotgitignore@2.1.0: dependencies: find-up: 3.0.0 From b2e3a35529fd829a63848d113c17c2f0ba144278 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 8 May 2025 12:03:40 -0400 Subject: [PATCH 003/303] chore(deps-dev): bump @pmmmwh/react-refresh-webpack-plugin from 0.5.15 to 0.6.0 --- demos/taco-demo/package.json | 2 +- demos/taco-nft-demo/package.json | 2 +- pnpm-lock.yaml | 44 +++++++++++++++++++++++++++----- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/demos/taco-demo/package.json b/demos/taco-demo/package.json index 8b674202d..43169b64f 100644 --- a/demos/taco-demo/package.json +++ b/demos/taco-demo/package.json @@ -25,7 +25,7 @@ "react-spinners": "^0.14.1" }, "devDependencies": { - "@pmmmwh/react-refresh-webpack-plugin": "^0.5.15", + "@pmmmwh/react-refresh-webpack-plugin": "^0.6.0", "@types/react": "^18.3.20", "@types/react-copy-to-clipboard": "^5.0.7", "@types/react-dom": "^18.3.5", diff --git a/demos/taco-nft-demo/package.json b/demos/taco-nft-demo/package.json index a3cadb6f1..fb6318061 100644 --- a/demos/taco-nft-demo/package.json +++ b/demos/taco-nft-demo/package.json @@ -24,7 +24,7 @@ "react-spinners": "^0.14.1" }, "devDependencies": { - "@pmmmwh/react-refresh-webpack-plugin": "^0.5.15", + "@pmmmwh/react-refresh-webpack-plugin": "^0.6.0", "@types/react": "^18.3.20", "@types/react-copy-to-clipboard": "^5.0.7", "@types/react-dom": "^18.3.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e806c8078..6fa072f93 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -144,8 +144,8 @@ importers: version: 0.14.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) devDependencies: '@pmmmwh/react-refresh-webpack-plugin': - specifier: ^0.5.15 - version: 0.5.15(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4)) + specifier: ^0.6.0 + version: 0.6.0(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4)) '@types/react': specifier: ^18.3.20 version: 18.3.20 @@ -229,8 +229,8 @@ importers: version: 0.14.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) devDependencies: '@pmmmwh/react-refresh-webpack-plugin': - specifier: ^0.5.15 - version: 0.5.15(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4)) + specifier: ^0.6.0 + version: 0.6.0(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4)) '@types/react': specifier: ^18.3.20 version: 18.3.20 @@ -2432,6 +2432,32 @@ packages: webpack-plugin-serve: optional: true + '@pmmmwh/react-refresh-webpack-plugin@0.6.0': + resolution: {integrity: sha512-AAc+QWfZ1KQ/e1C6OHWVlxU+ks6zFGOA44IJUlvju7RlDS8nsX6poPFOIlsg/rTofO9vKov12+WCjMhKkRKD5g==} + engines: {node: '>=18.12'} + peerDependencies: + '@types/webpack': 5.x + react-refresh: '>=0.10.0 <1.0.0' + sockjs-client: ^1.4.0 + type-fest: '>=0.17.0 <5.0.0' + webpack: ^5.0.0 + webpack-dev-server: ^4.8.0 || 5.x + webpack-hot-middleware: 2.x + webpack-plugin-serve: 1.x + peerDependenciesMeta: + '@types/webpack': + optional: true + sockjs-client: + optional: true + type-fest: + optional: true + webpack-dev-server: + optional: true + webpack-hot-middleware: + optional: true + webpack-plugin-serve: + optional: true + '@randlabs/communication-bridge@1.0.1': resolution: {integrity: sha512-CzS0U8IFfXNK7QaJFE4pjbxDGfPjbXBEsEaCn9FN15F+ouSAEUQkva3Gl66hrkBZOGexKFEWMwUHIDKpZ2hfVg==} @@ -3357,6 +3383,9 @@ packages: resolution: {integrity: sha512-9moZxdqeJ6GdE4N6fA/GlUP4LrbLZMYcYkt141J4Ss68OfEgH9qW0wBuZ3ZOKEx/xjc5bg7mLP2Gjg7nwrkmww==} engines: {node: '>=14.0.0'} + anser@2.3.2: + resolution: {integrity: sha512-PMqBCBvrOVDRqLGooQb+z+t1Q0PiPyurUQeZRR5uHBOVZcW8B04KMmnT12USnhpNX2wCPagWzLVppQMUG3u0Dw==} + ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -11584,13 +11613,12 @@ snapshots: type-fest: 0.21.3 webpack-dev-server: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.98.0) - '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4))': + '@pmmmwh/react-refresh-webpack-plugin@0.6.0(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4))': dependencies: - ansi-html: 0.0.9 + anser: 2.3.2 core-js-pure: 3.41.0 error-stack-parser: 2.1.4 html-entities: 2.5.3 - loader-utils: 2.0.4 react-refresh: 0.17.0 schema-utils: 4.3.0 source-map: 0.7.4 @@ -12688,6 +12716,8 @@ snapshots: transitivePeerDependencies: - encoding + anser@2.3.2: {} + ansi-colors@4.1.3: {} ansi-escapes@4.3.2: From 590398aca82eb47c5b6492d624a7804a9ddd395f Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 8 May 2025 12:06:42 -0400 Subject: [PATCH 004/303] chore(deps): bump next from 14.2.10 to 14.2.26 --- examples/taco/nextjs/package.json | 2 +- pnpm-lock.yaml | 133 +++++++++++++++++++++++++++++- 2 files changed, 132 insertions(+), 3 deletions(-) diff --git a/examples/taco/nextjs/package.json b/examples/taco/nextjs/package.json index c27f7a2b0..9593b5d33 100644 --- a/examples/taco/nextjs/package.json +++ b/examples/taco/nextjs/package.json @@ -20,7 +20,7 @@ "eslint": "8.57.0", "eslint-config-next": "14.0.4", "ethers": "^5.8.0", - "next": "14.2.10", + "next": "14.2.26", "react": "18.3.1", "react-dom": "18.3.1", "typescript": "5.2.2" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6fa072f93..9683fd01e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -399,8 +399,8 @@ importers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) next: - specifier: 14.2.10 - version: 14.2.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 14.2.26 + version: 14.2.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: 18.3.1 version: 18.3.1 @@ -2297,6 +2297,9 @@ packages: '@next/env@14.2.10': resolution: {integrity: sha512-dZIu93Bf5LUtluBXIv4woQw2cZVZ2DJTjax5/5DOs3lzEOeKLy7GxRSr4caK9/SCPdaW6bCgpye6+n4Dh9oJPw==} + '@next/env@14.2.26': + resolution: {integrity: sha512-vO//GJ/YBco+H7xdQhzJxF7ub3SUwft76jwaeOyVVQFHCi5DCnkP16WHB+JBylo4vOKPoZBlR94Z8xBxNBdNJA==} + '@next/eslint-plugin-next@14.0.4': resolution: {integrity: sha512-U3qMNHmEZoVmHA0j/57nRfi3AscXNvkOnxDmle/69Jz/G0o/gWjXTDdlgILZdrxQ0Lw/jv2mPW8PGy0EGIHXhQ==} @@ -2306,54 +2309,108 @@ packages: cpu: [arm64] os: [darwin] + '@next/swc-darwin-arm64@14.2.26': + resolution: {integrity: sha512-zDJY8gsKEseGAxG+C2hTMT0w9Nk9N1Sk1qV7vXYz9MEiyRoF5ogQX2+vplyUMIfygnjn9/A04I6yrUTRTuRiyQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + '@next/swc-darwin-x64@14.2.10': resolution: {integrity: sha512-Y0TC+FXbFUQ2MQgimJ/7Ina2mXIKhE7F+GUe1SgnzRmwFY3hX2z8nyVCxE82I2RicspdkZnSWMn4oTjIKz4uzA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] + '@next/swc-darwin-x64@14.2.26': + resolution: {integrity: sha512-U0adH5ryLfmTDkahLwG9sUQG2L0a9rYux8crQeC92rPhi3jGQEY47nByQHrVrt3prZigadwj/2HZ1LUUimuSbg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + '@next/swc-linux-arm64-gnu@14.2.10': resolution: {integrity: sha512-ZfQ7yOy5zyskSj9rFpa0Yd7gkrBnJTkYVSya95hX3zeBG9E55Z6OTNPn1j2BTFWvOVVj65C3T+qsjOyVI9DQpA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + '@next/swc-linux-arm64-gnu@14.2.26': + resolution: {integrity: sha512-SINMl1I7UhfHGM7SoRiw0AbwnLEMUnJ/3XXVmhyptzriHbWvPPbbm0OEVG24uUKhuS1t0nvN/DBvm5kz6ZIqpg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + '@next/swc-linux-arm64-musl@14.2.10': resolution: {integrity: sha512-n2i5o3y2jpBfXFRxDREr342BGIQCJbdAUi/K4q6Env3aSx8erM9VuKXHw5KNROK9ejFSPf0LhoSkU/ZiNdacpQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + '@next/swc-linux-arm64-musl@14.2.26': + resolution: {integrity: sha512-s6JaezoyJK2DxrwHWxLWtJKlqKqTdi/zaYigDXUJ/gmx/72CrzdVZfMvUc6VqnZ7YEvRijvYo+0o4Z9DencduA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + '@next/swc-linux-x64-gnu@14.2.10': resolution: {integrity: sha512-GXvajAWh2woTT0GKEDlkVhFNxhJS/XdDmrVHrPOA83pLzlGPQnixqxD8u3bBB9oATBKB//5e4vpACnx5Vaxdqg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + '@next/swc-linux-x64-gnu@14.2.26': + resolution: {integrity: sha512-FEXeUQi8/pLr/XI0hKbe0tgbLmHFRhgXOUiPScz2hk0hSmbGiU8aUqVslj/6C6KA38RzXnWoJXo4FMo6aBxjzg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + '@next/swc-linux-x64-musl@14.2.10': resolution: {integrity: sha512-opFFN5B0SnO+HTz4Wq4HaylXGFV+iHrVxd3YvREUX9K+xfc4ePbRrxqOuPOFjtSuiVouwe6uLeDtabjEIbkmDA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + '@next/swc-linux-x64-musl@14.2.26': + resolution: {integrity: sha512-BUsomaO4d2DuXhXhgQCVt2jjX4B4/Thts8nDoIruEJkhE5ifeQFtvW5c9JkdOtYvE5p2G0hcwQ0UbRaQmQwaVg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + '@next/swc-win32-arm64-msvc@14.2.10': resolution: {integrity: sha512-9NUzZuR8WiXTvv+EiU/MXdcQ1XUvFixbLIMNQiVHuzs7ZIFrJDLJDaOF1KaqttoTujpcxljM/RNAOmw1GhPPQQ==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] + '@next/swc-win32-arm64-msvc@14.2.26': + resolution: {integrity: sha512-5auwsMVzT7wbB2CZXQxDctpWbdEnEW/e66DyXO1DcgHxIyhP06awu+rHKshZE+lPLIGiwtjo7bsyeuubewwxMw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + '@next/swc-win32-ia32-msvc@14.2.10': resolution: {integrity: sha512-fr3aEbSd1GeW3YUMBkWAu4hcdjZ6g4NBl1uku4gAn661tcxd1bHs1THWYzdsbTRLcCKLjrDZlNp6j2HTfrw+Bg==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] + '@next/swc-win32-ia32-msvc@14.2.26': + resolution: {integrity: sha512-GQWg/Vbz9zUGi9X80lOeGsz1rMH/MtFO/XqigDznhhhTfDlDoynCM6982mPCbSlxJ/aveZcKtTlwfAjwhyxDpg==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + '@next/swc-win32-x64-msvc@14.2.10': resolution: {integrity: sha512-UjeVoRGKNL2zfbcQ6fscmgjBAS/inHBh63mjIlfPg/NG8Yn2ztqylXt5qilYb6hoHIwaU2ogHknHWWmahJjgZQ==} engines: {node: '>= 10'} cpu: [x64] os: [win32] + '@next/swc-win32-x64-msvc@14.2.26': + resolution: {integrity: sha512-2rdB3T1/Gp7bv1eQTTm9d1Y1sv9UuJ2LAwOE0Pe2prHKe32UNscj7YS13fRB37d0GAiGNR+Y7ZcW8YjDI8Ns0w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} @@ -6767,6 +6824,24 @@ packages: sass: optional: true + next@14.2.26: + resolution: {integrity: sha512-b81XSLihMwCfwiUVRRja3LphLo4uBBMZEzBBWMaISbKTwOmq3wPknIETy/8000tr7Gq4WmbuFYPS7jOYIf+ZJw==} + engines: {node: '>=18.17.0'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + react: ^18.2.0 + react-dom: ^18.2.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + sass: + optional: true + nice-try@1.0.5: resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} @@ -11492,6 +11567,8 @@ snapshots: '@next/env@14.2.10': {} + '@next/env@14.2.26': {} + '@next/eslint-plugin-next@14.0.4': dependencies: glob: 7.1.7 @@ -11499,30 +11576,57 @@ snapshots: '@next/swc-darwin-arm64@14.2.10': optional: true + '@next/swc-darwin-arm64@14.2.26': + optional: true + '@next/swc-darwin-x64@14.2.10': optional: true + '@next/swc-darwin-x64@14.2.26': + optional: true + '@next/swc-linux-arm64-gnu@14.2.10': optional: true + '@next/swc-linux-arm64-gnu@14.2.26': + optional: true + '@next/swc-linux-arm64-musl@14.2.10': optional: true + '@next/swc-linux-arm64-musl@14.2.26': + optional: true + '@next/swc-linux-x64-gnu@14.2.10': optional: true + '@next/swc-linux-x64-gnu@14.2.26': + optional: true + '@next/swc-linux-x64-musl@14.2.10': optional: true + '@next/swc-linux-x64-musl@14.2.26': + optional: true + '@next/swc-win32-arm64-msvc@14.2.10': optional: true + '@next/swc-win32-arm64-msvc@14.2.26': + optional: true + '@next/swc-win32-ia32-msvc@14.2.10': optional: true + '@next/swc-win32-ia32-msvc@14.2.26': + optional: true + '@next/swc-win32-x64-msvc@14.2.10': optional: true + '@next/swc-win32-x64-msvc@14.2.26': + optional: true + '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': dependencies: eslint-scope: 5.1.1 @@ -17181,6 +17285,31 @@ snapshots: - '@babel/core' - babel-plugin-macros + next@14.2.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@next/env': 14.2.26 + '@swc/helpers': 0.5.5 + busboy: 1.6.0 + caniuse-lite: 1.0.30001707 + graceful-fs: 4.2.11 + postcss: 8.4.31 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + styled-jsx: 5.1.1(react@18.3.1) + optionalDependencies: + '@next/swc-darwin-arm64': 14.2.26 + '@next/swc-darwin-x64': 14.2.26 + '@next/swc-linux-arm64-gnu': 14.2.26 + '@next/swc-linux-arm64-musl': 14.2.26 + '@next/swc-linux-x64-gnu': 14.2.26 + '@next/swc-linux-x64-musl': 14.2.26 + '@next/swc-win32-arm64-msvc': 14.2.26 + '@next/swc-win32-ia32-msvc': 14.2.26 + '@next/swc-win32-x64-msvc': 14.2.26 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + nice-try@1.0.5: {} no-case@3.0.4: From 172206d73575c39bf600a8cea8451197cf8410e8 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 2 Jul 2025 14:38:13 -0400 Subject: [PATCH 005/303] Bump @vitest/coverage-v8 from 3.1.1 to 3.2.4 --- package.json | 2 +- pnpm-lock.yaml | 53 ++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 37ac6d4a4..c993ecf15 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "@types/node": "^20.17.28", "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", - "@vitest/coverage-v8": "^3.0.9", + "@vitest/coverage-v8": "^3.2.4", "bundlemon": "^2.1.0", "eslint": "^8.57.1", "eslint-config-prettier": "^9.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9683fd01e..04bfdbf62 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,8 +38,8 @@ importers: specifier: ^6.21.0 version: 6.21.0(eslint@8.57.1)(typescript@5.8.2) '@vitest/coverage-v8': - specifier: ^3.0.9 - version: 3.1.1(vitest@3.0.9(@types/node@20.17.28)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0)) + specifier: ^3.2.4 + version: 3.2.4(vitest@3.0.9(@types/node@20.17.28)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0)) bundlemon: specifier: ^2.1.0 version: 2.1.0 @@ -3235,11 +3235,11 @@ packages: ethers: ^5 react: '*' - '@vitest/coverage-v8@3.1.1': - resolution: {integrity: sha512-MgV6D2dhpD6Hp/uroUoAIvFqA8AuvXEFBC2eepG3WFc1pxTfdk1LEqqkWoWhjz+rytoqrnUUCdf6Lzco3iHkLQ==} + '@vitest/coverage-v8@3.2.4': + resolution: {integrity: sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==} peerDependencies: - '@vitest/browser': 3.1.1 - vitest: 3.1.1 + '@vitest/browser': 3.2.4 + vitest: 3.2.4 peerDependenciesMeta: '@vitest/browser': optional: true @@ -3603,6 +3603,9 @@ packages: ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + ast-v8-to-istanbul@0.3.3: + resolution: {integrity: sha512-MuXMrSLVVoA6sYN/6Hke18vMzrT4TZNbZIj/hvh0fnYFpO+/kFXcLIaiPwXXWaQUPg4yJD8fj+lfJ7/1EBconw==} + async-function@1.0.0: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} @@ -4501,6 +4504,15 @@ packages: supports-color: optional: true + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decamelize-keys@1.1.1: resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} engines: {node: '>=0.10.0'} @@ -6285,6 +6297,9 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true @@ -8363,6 +8378,9 @@ packages: std-env@3.8.1: resolution: {integrity: sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==} + std-env@3.9.0: + resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} @@ -12561,18 +12579,19 @@ snapshots: - node-fetch - supports-color - '@vitest/coverage-v8@3.1.1(vitest@3.0.9(@types/node@20.17.28)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0))': + '@vitest/coverage-v8@3.2.4(vitest@3.0.9(@types/node@20.17.28)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 - debug: 4.4.0 + ast-v8-to-istanbul: 0.3.3 + debug: 4.4.1 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 istanbul-reports: 3.1.7 magic-string: 0.30.17 magicast: 0.3.5 - std-env: 3.8.1 + std-env: 3.9.0 test-exclude: 7.0.1 tinyrainbow: 2.0.0 vitest: 3.0.9(@types/node@20.17.28)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0) @@ -13024,6 +13043,12 @@ snapshots: ast-types-flow@0.0.8: {} + ast-v8-to-istanbul@0.3.3: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + estree-walker: 3.0.3 + js-tokens: 9.0.1 + async-function@1.0.0: {} async-retry@1.3.3: @@ -14137,6 +14162,10 @@ snapshots: dependencies: ms: 2.1.3 + debug@4.4.1: + dependencies: + ms: 2.1.3 + decamelize-keys@1.1.1: dependencies: decamelize: 1.2.0 @@ -16297,7 +16326,7 @@ snapshots: istanbul-lib-source-maps@5.0.6: dependencies: '@jridgewell/trace-mapping': 0.3.25 - debug: 4.4.0 + debug: 4.4.1 istanbul-lib-coverage: 3.2.2 transitivePeerDependencies: - supports-color @@ -16784,6 +16813,8 @@ snapshots: js-tokens@4.0.0: {} + js-tokens@9.0.1: {} + js-yaml@3.14.1: dependencies: argparse: 1.0.10 @@ -19027,6 +19058,8 @@ snapshots: std-env@3.8.1: {} + std-env@3.9.0: {} + stop-iteration-iterator@1.1.0: dependencies: es-errors: 1.3.0 From 0c37b3d1c2565fe78be5d352218e1a53a33ca63e Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 2 Jul 2025 14:44:01 -0400 Subject: [PATCH 006/303] Bump eslint-plugin-unused-imports from 3.2.0 to 4.1.4 --- package.json | 2 +- pnpm-lock.yaml | 22 +++++++--------------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index c993ecf15..30a9c3d36 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "eslint-plugin-import": "^2.31.0", "eslint-plugin-no-only-tests": "^3.3.0", "eslint-plugin-simple-import-sort": "^10.0.0", - "eslint-plugin-unused-imports": "^3.2.0", + "eslint-plugin-unused-imports": "^4.1.4", "gh-pages": "^6.3.0", "npm-run-all": "^4.1.5", "prettier": "^3.5.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 04bfdbf62..30c628784 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,8 +65,8 @@ importers: specifier: ^10.0.0 version: 10.0.0(eslint@8.57.1) eslint-plugin-unused-imports: - specifier: ^3.2.0 - version: 3.2.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1) + specifier: ^4.1.4 + version: 4.1.4(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1) gh-pages: specifier: ^6.3.0 version: 6.3.0 @@ -5043,20 +5043,15 @@ packages: peerDependencies: eslint: ^7.5.0 || ^8.0.0 - eslint-plugin-unused-imports@3.2.0: - resolution: {integrity: sha512-6uXyn6xdINEpxE1MtDjxQsyXB37lfyO2yKGVVgtD7WEWQGORSOZjgrD6hBhvGv4/SO+TOlS+UnC6JppRqbuwGQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-plugin-unused-imports@4.1.4: + resolution: {integrity: sha512-YptD6IzQjDardkl0POxnnRBhU1OEePMV0nd6siHaRBbd+lyh6NAhFEobiznKU7kTsSsDeSD62Pe7kAM1b7dAZQ==} peerDependencies: - '@typescript-eslint/eslint-plugin': 6 - 7 - eslint: '8' + '@typescript-eslint/eslint-plugin': ^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0 + eslint: ^9.0.0 || ^8.0.0 peerDependenciesMeta: '@typescript-eslint/eslint-plugin': optional: true - eslint-rule-composer@0.3.0: - resolution: {integrity: sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==} - engines: {node: '>=4.0.0'} - eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} @@ -15056,15 +15051,12 @@ snapshots: - supports-color - typescript - eslint-plugin-unused-imports@3.2.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1): + eslint-plugin-unused-imports@4.1.4(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1): dependencies: eslint: 8.57.1 - eslint-rule-composer: 0.3.0 optionalDependencies: '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2) - eslint-rule-composer@0.3.0: {} - eslint-scope@5.1.1: dependencies: esrecurse: 4.3.0 From 405e5c001d7cf266b83aaf59744e933b10999093 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 2 Jul 2025 14:50:11 -0400 Subject: [PATCH 007/303] Bump next from 14.2.10 to 15.3.4 --- examples/pre/nextjs/package.json | 2 +- examples/taco/nextjs/next-env.d.ts | 2 +- examples/taco/nextjs/package.json | 2 +- pnpm-lock.yaml | 541 ++++++++++++++++++----------- 4 files changed, 345 insertions(+), 202 deletions(-) diff --git a/examples/pre/nextjs/package.json b/examples/pre/nextjs/package.json index bc50d2318..59d5b8bb5 100644 --- a/examples/pre/nextjs/package.json +++ b/examples/pre/nextjs/package.json @@ -17,7 +17,7 @@ "eslint": "8.57.0", "eslint-config-next": "14.0.4", "ethers": "^5.8.0", - "next": "14.2.10", + "next": "15.3.4", "react": "18.3.1", "react-dom": "18.3.1" } diff --git a/examples/taco/nextjs/next-env.d.ts b/examples/taco/nextjs/next-env.d.ts index 40c3d6809..1b3be0840 100644 --- a/examples/taco/nextjs/next-env.d.ts +++ b/examples/taco/nextjs/next-env.d.ts @@ -2,4 +2,4 @@ /// // NOTE: This file should not be edited -// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. +// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/examples/taco/nextjs/package.json b/examples/taco/nextjs/package.json index 9593b5d33..775346f22 100644 --- a/examples/taco/nextjs/package.json +++ b/examples/taco/nextjs/package.json @@ -20,7 +20,7 @@ "eslint": "8.57.0", "eslint-config-next": "14.0.4", "ethers": "^5.8.0", - "next": "14.2.26", + "next": "15.3.4", "react": "18.3.1", "react-dom": "18.3.1", "typescript": "5.2.2" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 30c628784..f279c5176 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -295,8 +295,8 @@ importers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) next: - specifier: 14.2.10 - version: 14.2.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 15.3.4 + version: 15.3.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: 18.3.1 version: 18.3.1 @@ -399,8 +399,8 @@ importers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) next: - specifier: 14.2.26 - version: 14.2.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 15.3.4 + version: 15.3.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: 18.3.1 version: 18.3.1 @@ -1564,6 +1564,9 @@ packages: '@emnapi/runtime@1.4.0': resolution: {integrity: sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw==} + '@emnapi/runtime@1.4.3': + resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} + '@emnapi/wasi-threads@1.0.1': resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==} @@ -2118,6 +2121,122 @@ packages: resolution: {integrity: sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==} engines: {node: '>=6.9.0'} + '@img/sharp-darwin-arm64@0.34.2': + resolution: {integrity: sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.2': + resolution: {integrity: sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.1.0': + resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.1.0': + resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.1.0': + resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.1.0': + resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-ppc64@1.1.0': + resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.1.0': + resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.1.0': + resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.1.0': + resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.1.0': + resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.34.2': + resolution: {integrity: sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.34.2': + resolution: {integrity: sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-s390x@0.34.2': + resolution: {integrity: sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.34.2': + resolution: {integrity: sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.34.2': + resolution: {integrity: sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.34.2': + resolution: {integrity: sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.34.2': + resolution: {integrity: sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.2': + resolution: {integrity: sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.2': + resolution: {integrity: sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.2': + resolution: {integrity: sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + '@irys/arweave@0.0.2': resolution: {integrity: sha512-ddE5h4qXbl0xfGlxrtBIwzflaxZUDlDs43TuT0u1OMfyobHul4AA1VEX72Rpzw2bOh4vzoytSqA1jCM7x9YtHg==} @@ -2294,119 +2413,56 @@ packages: '@near-js/utils@0.0.4': resolution: {integrity: sha512-mPUEPJbTCMicGitjEGvQqOe8AS7O4KkRCxqd0xuE/X6gXF1jz1pYMZn4lNUeUz2C84YnVSGLAM0o9zcN6Y4hiA==} - '@next/env@14.2.10': - resolution: {integrity: sha512-dZIu93Bf5LUtluBXIv4woQw2cZVZ2DJTjax5/5DOs3lzEOeKLy7GxRSr4caK9/SCPdaW6bCgpye6+n4Dh9oJPw==} - - '@next/env@14.2.26': - resolution: {integrity: sha512-vO//GJ/YBco+H7xdQhzJxF7ub3SUwft76jwaeOyVVQFHCi5DCnkP16WHB+JBylo4vOKPoZBlR94Z8xBxNBdNJA==} + '@next/env@15.3.4': + resolution: {integrity: sha512-ZkdYzBseS6UjYzz6ylVKPOK+//zLWvD6Ta+vpoye8cW11AjiQjGYVibF0xuvT4L0iJfAPfZLFidaEzAOywyOAQ==} '@next/eslint-plugin-next@14.0.4': resolution: {integrity: sha512-U3qMNHmEZoVmHA0j/57nRfi3AscXNvkOnxDmle/69Jz/G0o/gWjXTDdlgILZdrxQ0Lw/jv2mPW8PGy0EGIHXhQ==} - '@next/swc-darwin-arm64@14.2.10': - resolution: {integrity: sha512-V3z10NV+cvMAfxQUMhKgfQnPbjw+Ew3cnr64b0lr8MDiBJs3eLnM6RpGC46nhfMZsiXgQngCJKWGTC/yDcgrDQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@next/swc-darwin-arm64@14.2.26': - resolution: {integrity: sha512-zDJY8gsKEseGAxG+C2hTMT0w9Nk9N1Sk1qV7vXYz9MEiyRoF5ogQX2+vplyUMIfygnjn9/A04I6yrUTRTuRiyQ==} + '@next/swc-darwin-arm64@15.3.4': + resolution: {integrity: sha512-z0qIYTONmPRbwHWvpyrFXJd5F9YWLCsw3Sjrzj2ZvMYy9NPQMPZ1NjOJh4ojr4oQzcGYwgJKfidzehaNa1BpEg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@14.2.10': - resolution: {integrity: sha512-Y0TC+FXbFUQ2MQgimJ/7Ina2mXIKhE7F+GUe1SgnzRmwFY3hX2z8nyVCxE82I2RicspdkZnSWMn4oTjIKz4uzA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@next/swc-darwin-x64@14.2.26': - resolution: {integrity: sha512-U0adH5ryLfmTDkahLwG9sUQG2L0a9rYux8crQeC92rPhi3jGQEY47nByQHrVrt3prZigadwj/2HZ1LUUimuSbg==} + '@next/swc-darwin-x64@15.3.4': + resolution: {integrity: sha512-Z0FYJM8lritw5Wq+vpHYuCIzIlEMjewG2aRkc3Hi2rcbULknYL/xqfpBL23jQnCSrDUGAo/AEv0Z+s2bff9Zkw==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@14.2.10': - resolution: {integrity: sha512-ZfQ7yOy5zyskSj9rFpa0Yd7gkrBnJTkYVSya95hX3zeBG9E55Z6OTNPn1j2BTFWvOVVj65C3T+qsjOyVI9DQpA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-arm64-gnu@14.2.26': - resolution: {integrity: sha512-SINMl1I7UhfHGM7SoRiw0AbwnLEMUnJ/3XXVmhyptzriHbWvPPbbm0OEVG24uUKhuS1t0nvN/DBvm5kz6ZIqpg==} + '@next/swc-linux-arm64-gnu@15.3.4': + resolution: {integrity: sha512-l8ZQOCCg7adwmsnFm8m5q9eIPAHdaB2F3cxhufYtVo84pymwKuWfpYTKcUiFcutJdp9xGHC+F1Uq3xnFU1B/7g==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@14.2.10': - resolution: {integrity: sha512-n2i5o3y2jpBfXFRxDREr342BGIQCJbdAUi/K4q6Env3aSx8erM9VuKXHw5KNROK9ejFSPf0LhoSkU/ZiNdacpQ==} + '@next/swc-linux-arm64-musl@15.3.4': + resolution: {integrity: sha512-wFyZ7X470YJQtpKot4xCY3gpdn8lE9nTlldG07/kJYexCUpX1piX+MBfZdvulo+t1yADFVEuzFfVHfklfEx8kw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@14.2.26': - resolution: {integrity: sha512-s6JaezoyJK2DxrwHWxLWtJKlqKqTdi/zaYigDXUJ/gmx/72CrzdVZfMvUc6VqnZ7YEvRijvYo+0o4Z9DencduA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-x64-gnu@14.2.10': - resolution: {integrity: sha512-GXvajAWh2woTT0GKEDlkVhFNxhJS/XdDmrVHrPOA83pLzlGPQnixqxD8u3bBB9oATBKB//5e4vpACnx5Vaxdqg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-linux-x64-gnu@14.2.26': - resolution: {integrity: sha512-FEXeUQi8/pLr/XI0hKbe0tgbLmHFRhgXOUiPScz2hk0hSmbGiU8aUqVslj/6C6KA38RzXnWoJXo4FMo6aBxjzg==} + '@next/swc-linux-x64-gnu@15.3.4': + resolution: {integrity: sha512-gEbH9rv9o7I12qPyvZNVTyP/PWKqOp8clvnoYZQiX800KkqsaJZuOXkWgMa7ANCCh/oEN2ZQheh3yH8/kWPSEg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@14.2.10': - resolution: {integrity: sha512-opFFN5B0SnO+HTz4Wq4HaylXGFV+iHrVxd3YvREUX9K+xfc4ePbRrxqOuPOFjtSuiVouwe6uLeDtabjEIbkmDA==} + '@next/swc-linux-x64-musl@15.3.4': + resolution: {integrity: sha512-Cf8sr0ufuC/nu/yQ76AnarbSAXcwG/wj+1xFPNbyNo8ltA6kw5d5YqO8kQuwVIxk13SBdtgXrNyom3ZosHAy4A==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@14.2.26': - resolution: {integrity: sha512-BUsomaO4d2DuXhXhgQCVt2jjX4B4/Thts8nDoIruEJkhE5ifeQFtvW5c9JkdOtYvE5p2G0hcwQ0UbRaQmQwaVg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-win32-arm64-msvc@14.2.10': - resolution: {integrity: sha512-9NUzZuR8WiXTvv+EiU/MXdcQ1XUvFixbLIMNQiVHuzs7ZIFrJDLJDaOF1KaqttoTujpcxljM/RNAOmw1GhPPQQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@next/swc-win32-arm64-msvc@14.2.26': - resolution: {integrity: sha512-5auwsMVzT7wbB2CZXQxDctpWbdEnEW/e66DyXO1DcgHxIyhP06awu+rHKshZE+lPLIGiwtjo7bsyeuubewwxMw==} + '@next/swc-win32-arm64-msvc@15.3.4': + resolution: {integrity: sha512-ay5+qADDN3rwRbRpEhTOreOn1OyJIXS60tg9WMYTWCy3fB6rGoyjLVxc4dR9PYjEdR2iDYsaF5h03NA+XuYPQQ==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-ia32-msvc@14.2.10': - resolution: {integrity: sha512-fr3aEbSd1GeW3YUMBkWAu4hcdjZ6g4NBl1uku4gAn661tcxd1bHs1THWYzdsbTRLcCKLjrDZlNp6j2HTfrw+Bg==} - engines: {node: '>= 10'} - cpu: [ia32] - os: [win32] - - '@next/swc-win32-ia32-msvc@14.2.26': - resolution: {integrity: sha512-GQWg/Vbz9zUGi9X80lOeGsz1rMH/MtFO/XqigDznhhhTfDlDoynCM6982mPCbSlxJ/aveZcKtTlwfAjwhyxDpg==} - engines: {node: '>= 10'} - cpu: [ia32] - os: [win32] - - '@next/swc-win32-x64-msvc@14.2.10': - resolution: {integrity: sha512-UjeVoRGKNL2zfbcQ6fscmgjBAS/inHBh63mjIlfPg/NG8Yn2ztqylXt5qilYb6hoHIwaU2ogHknHWWmahJjgZQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - - '@next/swc-win32-x64-msvc@14.2.26': - resolution: {integrity: sha512-2rdB3T1/Gp7bv1eQTTm9d1Y1sv9UuJ2LAwOE0Pe2prHKe32UNscj7YS13fRB37d0GAiGNR+Y7ZcW8YjDI8Ns0w==} + '@next/swc-win32-x64-msvc@15.3.4': + resolution: {integrity: sha512-4kDt31Bc9DGyYs41FTL1/kNpDeHyha2TC0j5sRRoKCyrhNcfZ/nRQkAUlF27mETwm8QyHqIjHJitfcza2Iykfg==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -2776,9 +2832,6 @@ packages: '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} - '@swc/helpers@0.5.5': - resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} - '@szmarczak/http-timer@4.0.6': resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} engines: {node: '>=10'} @@ -4053,6 +4106,13 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + colord@2.9.3: resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} @@ -4608,6 +4668,10 @@ packages: resolution: {integrity: sha512-Mc7QhQ8s+cLrnUfU/Ji94vG/r8M26m8f++vyres4ZoojaRDpZ1eSIh/EpzLNwlWuvzSZ3UbDFspjFvTDXe6e/g==} engines: {node: '>=12.20'} + detect-libc@2.0.4: + resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} + engines: {node: '>=8'} + detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -5839,6 +5903,9 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + is-async-function@2.1.1: resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} engines: {node: '>= 0.4'} @@ -6816,38 +6883,23 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - next@14.2.10: - resolution: {integrity: sha512-sDDExXnh33cY3RkS9JuFEKaS4HmlWmDKP1VJioucCG6z5KuA008DPsDZOzi8UfqEk3Ii+2NCQSJrfbEWtZZfww==} - engines: {node: '>=18.17.0'} + next@15.3.4: + resolution: {integrity: sha512-mHKd50C+mCjam/gcnwqL1T1vPx/XQNFlXqFIVdgQdVAFY9iIQtY0IfaVflEYzKiqjeA7B0cYYMaCrmAYFjs4rA==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 '@playwright/test': ^1.41.2 - react: ^18.2.0 - react-dom: ^18.2.0 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 sass: ^1.3.0 peerDependenciesMeta: '@opentelemetry/api': optional: true '@playwright/test': optional: true - sass: - optional: true - - next@14.2.26: - resolution: {integrity: sha512-b81XSLihMwCfwiUVRRja3LphLo4uBBMZEzBBWMaISbKTwOmq3wPknIETy/8000tr7Gq4WmbuFYPS7jOYIf+ZJw==} - engines: {node: '>=18.17.0'} - hasBin: true - peerDependencies: - '@opentelemetry/api': ^1.1.0 - '@playwright/test': ^1.41.2 - react: ^18.2.0 - react-dom: ^18.2.0 - sass: ^1.3.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - '@playwright/test': + babel-plugin-react-compiler: optional: true sass: optional: true @@ -8153,6 +8205,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + send@0.19.0: resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} engines: {node: '>= 0.8.0'} @@ -8197,6 +8254,10 @@ packages: resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} engines: {node: '>=8'} + sharp@0.34.2: + resolution: {integrity: sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@1.2.0: resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} engines: {node: '>=0.10.0'} @@ -8246,6 +8307,9 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -8494,13 +8558,13 @@ packages: peerDependencies: webpack: ^5.0.0 - styled-jsx@5.1.1: - resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} engines: {node: '>= 12.0.0'} peerDependencies: '@babel/core': '*' babel-plugin-macros: '*' - react: '>= 16.8.0 || 17.x.x || ^18.0.0-0' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' peerDependenciesMeta: '@babel/core': optional: true @@ -10657,6 +10721,11 @@ snapshots: tslib: 2.8.1 optional: true + '@emnapi/runtime@1.4.3': + dependencies: + tslib: 2.8.1 + optional: true + '@emnapi/wasi-threads@1.0.1': dependencies: tslib: 2.8.1 @@ -11179,6 +11248,87 @@ snapshots: '@hutson/parse-repository-url@3.0.2': {} + '@img/sharp-darwin-arm64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.1.0 + optional: true + + '@img/sharp-darwin-x64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.1.0 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.1.0': + optional: true + + '@img/sharp-libvips-darwin-x64@1.1.0': + optional: true + + '@img/sharp-libvips-linux-arm64@1.1.0': + optional: true + + '@img/sharp-libvips-linux-arm@1.1.0': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.1.0': + optional: true + + '@img/sharp-libvips-linux-s390x@1.1.0': + optional: true + + '@img/sharp-libvips-linux-x64@1.1.0': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.1.0': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.1.0': + optional: true + + '@img/sharp-linux-arm64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.1.0 + optional: true + + '@img/sharp-linux-arm@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.1.0 + optional: true + + '@img/sharp-linux-s390x@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.1.0 + optional: true + + '@img/sharp-linux-x64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.1.0 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + optional: true + + '@img/sharp-wasm32@0.34.2': + dependencies: + '@emnapi/runtime': 1.4.3 + optional: true + + '@img/sharp-win32-arm64@0.34.2': + optional: true + + '@img/sharp-win32-ia32@0.34.2': + optional: true + + '@img/sharp-win32-x64@0.34.2': + optional: true + '@irys/arweave@0.0.2': dependencies: asn1.js: 5.4.1 @@ -11578,66 +11728,34 @@ snapshots: depd: 2.0.0 mustache: 4.2.0 - '@next/env@14.2.10': {} - - '@next/env@14.2.26': {} + '@next/env@15.3.4': {} '@next/eslint-plugin-next@14.0.4': dependencies: glob: 7.1.7 - '@next/swc-darwin-arm64@14.2.10': + '@next/swc-darwin-arm64@15.3.4': optional: true - '@next/swc-darwin-arm64@14.2.26': + '@next/swc-darwin-x64@15.3.4': optional: true - '@next/swc-darwin-x64@14.2.10': + '@next/swc-linux-arm64-gnu@15.3.4': optional: true - '@next/swc-darwin-x64@14.2.26': + '@next/swc-linux-arm64-musl@15.3.4': optional: true - '@next/swc-linux-arm64-gnu@14.2.10': + '@next/swc-linux-x64-gnu@15.3.4': optional: true - '@next/swc-linux-arm64-gnu@14.2.26': + '@next/swc-linux-x64-musl@15.3.4': optional: true - '@next/swc-linux-arm64-musl@14.2.10': + '@next/swc-win32-arm64-msvc@15.3.4': optional: true - '@next/swc-linux-arm64-musl@14.2.26': - optional: true - - '@next/swc-linux-x64-gnu@14.2.10': - optional: true - - '@next/swc-linux-x64-gnu@14.2.26': - optional: true - - '@next/swc-linux-x64-musl@14.2.10': - optional: true - - '@next/swc-linux-x64-musl@14.2.26': - optional: true - - '@next/swc-win32-arm64-msvc@14.2.10': - optional: true - - '@next/swc-win32-arm64-msvc@14.2.26': - optional: true - - '@next/swc-win32-ia32-msvc@14.2.10': - optional: true - - '@next/swc-win32-ia32-msvc@14.2.26': - optional: true - - '@next/swc-win32-x64-msvc@14.2.10': - optional: true - - '@next/swc-win32-x64-msvc@14.2.26': + '@next/swc-win32-x64-msvc@15.3.4': optional: true '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': @@ -12008,11 +12126,6 @@ snapshots: dependencies: tslib: 2.8.1 - '@swc/helpers@0.5.5': - dependencies: - '@swc/counter': 0.1.3 - tslib: 2.8.1 - '@szmarczak/http-timer@4.0.6': dependencies: defer-to-connect: 2.0.1 @@ -13611,6 +13724,18 @@ snapshots: color-name@1.1.4: {} + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + optional: true + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + optional: true + colord@2.9.3: {} colorette@2.0.20: {} @@ -14250,6 +14375,9 @@ snapshots: detect-indent@7.0.1: {} + detect-libc@2.0.4: + optional: true + detect-newline@3.1.0: {} detect-newline@4.0.1: {} @@ -16112,6 +16240,9 @@ snapshots: is-arrayish@0.2.1: {} + is-arrayish@0.3.2: + optional: true + is-async-function@2.1.1: dependencies: async-function: 1.0.0 @@ -17283,52 +17414,27 @@ snapshots: neo-async@2.6.2: {} - next@14.2.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@next/env': 14.2.10 - '@swc/helpers': 0.5.5 - busboy: 1.6.0 - caniuse-lite: 1.0.30001707 - graceful-fs: 4.2.11 - postcss: 8.4.31 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - styled-jsx: 5.1.1(react@18.3.1) - optionalDependencies: - '@next/swc-darwin-arm64': 14.2.10 - '@next/swc-darwin-x64': 14.2.10 - '@next/swc-linux-arm64-gnu': 14.2.10 - '@next/swc-linux-arm64-musl': 14.2.10 - '@next/swc-linux-x64-gnu': 14.2.10 - '@next/swc-linux-x64-musl': 14.2.10 - '@next/swc-win32-arm64-msvc': 14.2.10 - '@next/swc-win32-ia32-msvc': 14.2.10 - '@next/swc-win32-x64-msvc': 14.2.10 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - - next@14.2.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next@15.3.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@next/env': 14.2.26 - '@swc/helpers': 0.5.5 + '@next/env': 15.3.4 + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.15 busboy: 1.6.0 caniuse-lite: 1.0.30001707 - graceful-fs: 4.2.11 postcss: 8.4.31 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - styled-jsx: 5.1.1(react@18.3.1) + styled-jsx: 5.1.6(react@18.3.1) optionalDependencies: - '@next/swc-darwin-arm64': 14.2.26 - '@next/swc-darwin-x64': 14.2.26 - '@next/swc-linux-arm64-gnu': 14.2.26 - '@next/swc-linux-arm64-musl': 14.2.26 - '@next/swc-linux-x64-gnu': 14.2.26 - '@next/swc-linux-x64-musl': 14.2.26 - '@next/swc-win32-arm64-msvc': 14.2.26 - '@next/swc-win32-ia32-msvc': 14.2.26 - '@next/swc-win32-x64-msvc': 14.2.26 + '@next/swc-darwin-arm64': 15.3.4 + '@next/swc-darwin-x64': 15.3.4 + '@next/swc-linux-arm64-gnu': 15.3.4 + '@next/swc-linux-arm64-musl': 15.3.4 + '@next/swc-linux-x64-gnu': 15.3.4 + '@next/swc-linux-x64-musl': 15.3.4 + '@next/swc-win32-arm64-msvc': 15.3.4 + '@next/swc-win32-x64-msvc': 15.3.4 + sharp: 0.34.2 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -18765,6 +18871,9 @@ snapshots: semver@7.7.1: {} + semver@7.7.2: + optional: true + send@0.19.0: dependencies: debug: 2.6.9 @@ -18847,6 +18956,35 @@ snapshots: dependencies: kind-of: 6.0.3 + sharp@0.34.2: + dependencies: + color: 4.2.3 + detect-libc: 2.0.4 + semver: 7.7.2 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.2 + '@img/sharp-darwin-x64': 0.34.2 + '@img/sharp-libvips-darwin-arm64': 1.1.0 + '@img/sharp-libvips-darwin-x64': 1.1.0 + '@img/sharp-libvips-linux-arm': 1.1.0 + '@img/sharp-libvips-linux-arm64': 1.1.0 + '@img/sharp-libvips-linux-ppc64': 1.1.0 + '@img/sharp-libvips-linux-s390x': 1.1.0 + '@img/sharp-libvips-linux-x64': 1.1.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + '@img/sharp-linux-arm': 0.34.2 + '@img/sharp-linux-arm64': 0.34.2 + '@img/sharp-linux-s390x': 0.34.2 + '@img/sharp-linux-x64': 0.34.2 + '@img/sharp-linuxmusl-arm64': 0.34.2 + '@img/sharp-linuxmusl-x64': 0.34.2 + '@img/sharp-wasm32': 0.34.2 + '@img/sharp-win32-arm64': 0.34.2 + '@img/sharp-win32-ia32': 0.34.2 + '@img/sharp-win32-x64': 0.34.2 + optional: true + shebang-command@1.2.0: dependencies: shebang-regex: 1.0.0 @@ -18902,6 +19040,11 @@ snapshots: signal-exit@4.1.0: {} + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + optional: true + sisteransi@1.0.5: {} siwe@3.0.0(ethers@5.8.0): @@ -19197,7 +19340,7 @@ snapshots: dependencies: webpack: 5.98.0 - styled-jsx@5.1.1(react@18.3.1): + styled-jsx@5.1.6(react@18.3.1): dependencies: client-only: 0.0.1 react: 18.3.1 From 55d7dc776227fe7bb869aadd3d107014a7027619 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 2 Jul 2025 15:11:02 -0400 Subject: [PATCH 008/303] Bump webpack-dev-server from 4.15.2 to 5.2.2 Bump copy-webpack-plugin from 12.0.2 to 13.0.0 Bump webpack from 5.98.0 to 5.99.9 Bump webpack-cli from 5.1.4 to 6.0.1 --- demos/taco-demo/package.json | 8 +- demos/taco-nft-demo/package.json | 8 +- examples/pre/webpack-5/package.json | 8 +- examples/taco/webpack-5/package.json | 8 +- pnpm-lock.yaml | 675 +++++++++++++++++---------- 5 files changed, 436 insertions(+), 271 deletions(-) diff --git a/demos/taco-demo/package.json b/demos/taco-demo/package.json index 43169b64f..6ce20fe4c 100644 --- a/demos/taco-demo/package.json +++ b/demos/taco-demo/package.json @@ -29,7 +29,7 @@ "@types/react": "^18.3.20", "@types/react-copy-to-clipboard": "^5.0.7", "@types/react-dom": "^18.3.5", - "copy-webpack-plugin": "^12.0.2", + "copy-webpack-plugin": "^13.0.0", "crypto-browserify": "^3.12.1", "esbuild-loader": "^2.21.0", "html-webpack-plugin": "^5.6.3", @@ -39,8 +39,8 @@ "stream-browserify": "^3.0.0", "typescript": "^4.9.5", "vm-browserify": "^1.1.2", - "webpack": "^5.98.0", - "webpack-cli": "^5.1.4", - "webpack-dev-server": "^4.15.2" + "webpack": "^5.99.9", + "webpack-cli": "^6.0.1", + "webpack-dev-server": "^5.2.2" } } diff --git a/demos/taco-nft-demo/package.json b/demos/taco-nft-demo/package.json index fb6318061..75e62e3e1 100644 --- a/demos/taco-nft-demo/package.json +++ b/demos/taco-nft-demo/package.json @@ -28,15 +28,15 @@ "@types/react": "^18.3.20", "@types/react-copy-to-clipboard": "^5.0.7", "@types/react-dom": "^18.3.5", - "copy-webpack-plugin": "^12.0.2", + "copy-webpack-plugin": "^13.0.0", "esbuild-loader": "^2.21.0", "html-webpack-plugin": "^5.6.3", "react-refresh": "^0.17.0", "rimraf": "^5.0.10", "stream-browserify": "^3.0.0", "typescript": "^4.9.5", - "webpack": "^5.98.0", - "webpack-cli": "^5.1.4", - "webpack-dev-server": "^4.15.2" + "webpack": "^5.99.9", + "webpack-cli": "^6.0.1", + "webpack-dev-server": "^5.2.2" } } diff --git a/examples/pre/webpack-5/package.json b/examples/pre/webpack-5/package.json index b257e9135..bd659a83a 100644 --- a/examples/pre/webpack-5/package.json +++ b/examples/pre/webpack-5/package.json @@ -15,11 +15,11 @@ "@nucypher/pre": "workspace:*" }, "devDependencies": { - "copy-webpack-plugin": "^12.0.2", + "copy-webpack-plugin": "^13.0.0", "esbuild-loader": "^2.21.0", "ethers": "^5.8.0", - "webpack": "^5.98.0", - "webpack-cli": "^5.1.4", - "webpack-dev-server": "^4.15.2" + "webpack": "^5.99.9", + "webpack-cli": "^6.0.1", + "webpack-dev-server": "^5.2.2" } } diff --git a/examples/taco/webpack-5/package.json b/examples/taco/webpack-5/package.json index 35fc00075..5f231f408 100644 --- a/examples/taco/webpack-5/package.json +++ b/examples/taco/webpack-5/package.json @@ -16,11 +16,11 @@ "@nucypher/taco-auth": "workspace:*" }, "devDependencies": { - "copy-webpack-plugin": "^12.0.2", + "copy-webpack-plugin": "^13.0.0", "esbuild-loader": "^2.21.0", - "webpack": "^5.98.0", - "webpack-cli": "^5.1.4", - "webpack-dev-server": "^4.15.2" + "webpack": "^5.99.9", + "webpack-cli": "^6.0.1", + "webpack-dev-server": "^5.2.2" }, "peerDependencies": { "ethers": "^5.7.2" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f279c5176..04bf7c255 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -129,7 +129,7 @@ importers: version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) file-loader: specifier: ^6.2.0 - version: 6.2.0(webpack@5.98.0(webpack-cli@5.1.4)) + version: 6.2.0(webpack@5.99.9(webpack-cli@6.0.1)) react: specifier: ^18.3.1 version: 18.3.1 @@ -145,7 +145,7 @@ importers: devDependencies: '@pmmmwh/react-refresh-webpack-plugin': specifier: ^0.6.0 - version: 0.6.0(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4)) + version: 0.6.0(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9))(webpack@5.99.9(webpack-cli@6.0.1)) '@types/react': specifier: ^18.3.20 version: 18.3.20 @@ -156,17 +156,17 @@ importers: specifier: ^18.3.5 version: 18.3.5(@types/react@18.3.20) copy-webpack-plugin: - specifier: ^12.0.2 - version: 12.0.2(webpack@5.98.0(webpack-cli@5.1.4)) + specifier: ^13.0.0 + version: 13.0.0(webpack@5.99.9(webpack-cli@6.0.1)) crypto-browserify: specifier: ^3.12.1 version: 3.12.1 esbuild-loader: specifier: ^2.21.0 - version: 2.21.0(webpack@5.98.0(webpack-cli@5.1.4)) + version: 2.21.0(webpack@5.99.9(webpack-cli@6.0.1)) html-webpack-plugin: specifier: ^5.6.3 - version: 5.6.3(webpack@5.98.0(webpack-cli@5.1.4)) + version: 5.6.3(webpack@5.99.9(webpack-cli@6.0.1)) process: specifier: ^0.11.10 version: 0.11.10 @@ -186,14 +186,14 @@ importers: specifier: ^1.1.2 version: 1.1.2 webpack: - specifier: ^5.98.0 - version: 5.98.0(webpack-cli@5.1.4) + specifier: ^5.99.9 + version: 5.99.9(webpack-cli@6.0.1) webpack-cli: - specifier: ^5.1.4 - version: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.98.0) + specifier: ^6.0.1 + version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) webpack-dev-server: - specifier: ^4.15.2 - version: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0) + specifier: ^5.2.2 + version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) demos/taco-nft-demo: dependencies: @@ -214,7 +214,7 @@ importers: version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) file-loader: specifier: ^6.2.0 - version: 6.2.0(webpack@5.98.0(webpack-cli@5.1.4)) + version: 6.2.0(webpack@5.99.9(webpack-cli@6.0.1)) react: specifier: ^18.3.1 version: 18.3.1 @@ -230,7 +230,7 @@ importers: devDependencies: '@pmmmwh/react-refresh-webpack-plugin': specifier: ^0.6.0 - version: 0.6.0(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4)) + version: 0.6.0(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9))(webpack@5.99.9(webpack-cli@6.0.1)) '@types/react': specifier: ^18.3.20 version: 18.3.20 @@ -241,14 +241,14 @@ importers: specifier: ^18.3.5 version: 18.3.5(@types/react@18.3.20) copy-webpack-plugin: - specifier: ^12.0.2 - version: 12.0.2(webpack@5.98.0(webpack-cli@5.1.4)) + specifier: ^13.0.0 + version: 13.0.0(webpack@5.99.9(webpack-cli@6.0.1)) esbuild-loader: specifier: ^2.21.0 - version: 2.21.0(webpack@5.98.0(webpack-cli@5.1.4)) + version: 2.21.0(webpack@5.99.9(webpack-cli@6.0.1)) html-webpack-plugin: specifier: ^5.6.3 - version: 5.6.3(webpack@5.98.0(webpack-cli@5.1.4)) + version: 5.6.3(webpack@5.99.9(webpack-cli@6.0.1)) react-refresh: specifier: ^0.17.0 version: 0.17.0 @@ -262,14 +262,14 @@ importers: specifier: ^4.9.5 version: 4.9.5 webpack: - specifier: ^5.98.0 - version: 5.98.0(webpack-cli@5.1.4) + specifier: ^5.99.9 + version: 5.99.9(webpack-cli@6.0.1) webpack-cli: - specifier: ^5.1.4 - version: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.98.0) + specifier: ^6.0.1 + version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) webpack-dev-server: - specifier: ^4.15.2 - version: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0) + specifier: ^5.2.2 + version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) examples/pre/nextjs: dependencies: @@ -351,23 +351,23 @@ importers: version: link:../../../packages/pre devDependencies: copy-webpack-plugin: - specifier: ^12.0.2 - version: 12.0.2(webpack@5.98.0(webpack-cli@5.1.4)) + specifier: ^13.0.0 + version: 13.0.0(webpack@5.99.9(webpack-cli@6.0.1)) esbuild-loader: specifier: ^2.21.0 - version: 2.21.0(webpack@5.98.0(webpack-cli@5.1.4)) + version: 2.21.0(webpack@5.99.9(webpack-cli@6.0.1)) ethers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) webpack: - specifier: ^5.98.0 - version: 5.98.0(webpack-cli@5.1.4) + specifier: ^5.99.9 + version: 5.99.9(webpack-cli@6.0.1) webpack-cli: - specifier: ^5.1.4 - version: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.98.0) + specifier: ^6.0.1 + version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) webpack-dev-server: - specifier: ^4.15.2 - version: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0) + specifier: ^5.2.2 + version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) examples/taco/nextjs: dependencies: @@ -473,20 +473,20 @@ importers: version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) devDependencies: copy-webpack-plugin: - specifier: ^12.0.2 - version: 12.0.2(webpack@5.98.0(webpack-cli@5.1.4)) + specifier: ^13.0.0 + version: 13.0.0(webpack@5.99.9(webpack-cli@6.0.1)) esbuild-loader: specifier: ^2.21.0 - version: 2.21.0(webpack@5.98.0(webpack-cli@5.1.4)) + version: 2.21.0(webpack@5.99.9(webpack-cli@6.0.1)) webpack: - specifier: ^5.98.0 - version: 5.98.0(webpack-cli@5.1.4) + specifier: ^5.99.9 + version: 5.99.9(webpack-cli@6.0.1) webpack-cli: - specifier: ^5.1.4 - version: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.98.0) + specifier: ^6.0.1 + version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) webpack-dev-server: - specifier: ^4.15.2 - version: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0) + specifier: ^5.2.2 + version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) packages/pre: dependencies: @@ -1554,9 +1554,9 @@ packages: peerDependencies: postcss-selector-parser: ^6.0.10 - '@discoveryjs/json-ext@0.5.7': - resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} - engines: {node: '>=10.0.0'} + '@discoveryjs/json-ext@0.6.3': + resolution: {integrity: sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==} + engines: {node: '>=14.17.0'} '@emnapi/core@1.4.0': resolution: {integrity: sha512-H+N/FqT07NmLmt6OFFtDfwe8PNygprzBikrEMyQfgqSmT0vzE515Pz7R8izwB9q/zsH/MA64AKoul3sA6/CzVg==} @@ -2355,6 +2355,24 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@jsonjoy.com/base64@1.1.2': + resolution: {integrity: sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pack@1.2.0': + resolution: {integrity: sha512-io1zEbbYcElht3tdlqEOFxZ0dMTYrHz9iMf0gqn1pPjZFTCgM5R4R5IMA20Chb2UPYYsxjzs8CgZ7Nb5n2K2rA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/util@1.6.0': + resolution: {integrity: sha512-sw/RMbehRhN68WRtcKCpQOPfnH6lLP4GJfqzi3iYej8tnzpZUDr6UkZYJjcjjC0FWEJOJbyM3PTIwxucUmDG2A==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + '@leichtgewicht/ip-codec@2.0.5': resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} @@ -2727,10 +2745,6 @@ packages: resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} engines: {node: '>=10'} - '@sindresorhus/merge-streams@2.3.0': - resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} - engines: {node: '>=18'} - '@sinonjs/commons@1.8.6': resolution: {integrity: sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==} @@ -3035,6 +3049,9 @@ packages: '@types/retry@0.12.0': resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} + '@types/retry@0.12.2': + resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} + '@types/semver@7.7.0': resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==} @@ -3371,26 +3388,26 @@ packages: '@webassemblyjs/wast-printer@1.14.1': resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} - '@webpack-cli/configtest@2.1.1': - resolution: {integrity: sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==} - engines: {node: '>=14.15.0'} + '@webpack-cli/configtest@3.0.1': + resolution: {integrity: sha512-u8d0pJ5YFgneF/GuvEiDA61Tf1VDomHHYMjv/wc9XzYj7nopltpG96nXN5dJRstxZhcNpV1g+nT6CydO7pHbjA==} + engines: {node: '>=18.12.0'} peerDependencies: - webpack: 5.x.x - webpack-cli: 5.x.x + webpack: ^5.82.0 + webpack-cli: 6.x.x - '@webpack-cli/info@2.0.2': - resolution: {integrity: sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==} - engines: {node: '>=14.15.0'} + '@webpack-cli/info@3.0.1': + resolution: {integrity: sha512-coEmDzc2u/ffMvuW9aCjoRzNSPDl/XLuhPdlFRpT9tZHmJ/039az33CE7uH+8s0uL1j5ZNtfdv0HkfaKRBGJsQ==} + engines: {node: '>=18.12.0'} peerDependencies: - webpack: 5.x.x - webpack-cli: 5.x.x + webpack: ^5.82.0 + webpack-cli: 6.x.x - '@webpack-cli/serve@2.0.5': - resolution: {integrity: sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==} - engines: {node: '>=14.15.0'} + '@webpack-cli/serve@3.0.1': + resolution: {integrity: sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg==} + engines: {node: '>=18.12.0'} peerDependencies: - webpack: 5.x.x - webpack-cli: 5.x.x + webpack: ^5.82.0 + webpack-cli: 6.x.x webpack-dev-server: '*' peerDependenciesMeta: webpack-dev-server: @@ -3912,6 +3929,10 @@ packages: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + bundle-require@4.2.1: resolution: {integrity: sha512-7Q/6vkyYAwOmQNRw75x+4yRtZCZJXUDmHHlFdkiV0wgv/reNjtJwpu1jPJ0w2kbEpIM0uoKI3S4/f39dU7AjSA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -4131,10 +4152,6 @@ packages: resolution: {integrity: sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==} engines: {node: '>=8.0.0'} - commander@10.0.1: - resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} - engines: {node: '>=14'} - commander@12.1.0: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} @@ -4296,8 +4313,8 @@ packages: copy-to-clipboard@3.3.3: resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} - copy-webpack-plugin@12.0.2: - resolution: {integrity: sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==} + copy-webpack-plugin@13.0.0: + resolution: {integrity: sha512-FgR/h5a6hzJqATDGd9YG41SeDViH+0bkHn6WNXCi5zKAZkeESeSxLySSsFLHqLEVCh0E+rITmCf0dusXWYukeQ==} engines: {node: '>= 18.12.0'} peerDependencies: webpack: ^5.1.0 @@ -4610,6 +4627,14 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + default-browser-id@5.0.0: + resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} + engines: {node: '>=18'} + + default-browser@5.2.1: + resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} + engines: {node: '>=18'} + default-gateway@6.0.3: resolution: {integrity: sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==} engines: {node: '>= 10'} @@ -4629,6 +4654,10 @@ packages: resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} engines: {node: '>=8'} + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} @@ -5607,10 +5636,6 @@ packages: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} - globby@14.1.0: - resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} - engines: {node: '>=18'} - gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} @@ -5774,6 +5799,15 @@ packages: '@types/express': optional: true + http-proxy-middleware@2.0.9: + resolution: {integrity: sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/express': ^4.17.13 + peerDependenciesMeta: + '@types/express': + optional: true + http-proxy@1.18.1: resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} engines: {node: '>=8.0.0'} @@ -5797,6 +5831,10 @@ packages: humanize-ms@1.2.1: resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + hyperdyperid@1.2.0: + resolution: {integrity: sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==} + engines: {node: '>=10.18'} + iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -5825,10 +5863,6 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - ignore@7.0.3: - resolution: {integrity: sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==} - engines: {node: '>= 4'} - immer@9.0.21: resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==} @@ -5946,6 +5980,11 @@ packages: engines: {node: '>=8'} hasBin: true + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -5970,6 +6009,11 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + is-interactive@1.0.0: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} @@ -5981,6 +6025,10 @@ packages: is-module@1.0.0: resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + is-network-error@1.1.0: + resolution: {integrity: sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==} + engines: {node: '>=16'} + is-number-object@1.1.1: resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} engines: {node: '>= 0.4'} @@ -6101,6 +6149,10 @@ packages: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} @@ -6686,6 +6738,10 @@ packages: resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==} engines: {node: '>= 4.0.0'} + memfs@4.17.2: + resolution: {integrity: sha512-NgYhCOWgovOXSzvYgUW0LQ7Qy72rWQMGGFJDoWg4G30RHd3z77VbYdtJ4fembJXBy8pMIUA31XNAupobOQlwdg==} + engines: {node: '>= 4.0.0'} + memorystream@0.3.1: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} @@ -7035,6 +7091,10 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} + open@10.1.2: + resolution: {integrity: sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==} + engines: {node: '>=18'} + open@8.4.2: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} @@ -7106,6 +7166,10 @@ packages: resolution: {integrity: sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==} engines: {node: '>=8'} + p-retry@6.2.1: + resolution: {integrity: sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==} + engines: {node: '>=16.17'} + p-try@1.0.0: resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} engines: {node: '>=4'} @@ -7198,10 +7262,6 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - path-type@6.0.0: - resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} - engines: {node: '>=18'} - pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -8099,6 +8159,10 @@ packages: rpc-websockets@9.1.1: resolution: {integrity: sha512-1IXGM/TfPT6nfYMIXkJdzn+L4JEsmb0FL1O2OBjaH03V3yuUDdKFulGLMFG6ErV+8pZ5HVC0limve01RyO+saA==} + run-applescript@7.0.0: + resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} + engines: {node: '>=18'} + run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} @@ -8178,6 +8242,10 @@ packages: resolution: {integrity: sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==} engines: {node: '>= 10.13.0'} + schema-utils@4.3.2: + resolution: {integrity: sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==} + engines: {node: '>= 10.13.0'} + scrypt-js@3.0.1: resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} @@ -8326,10 +8394,6 @@ packages: resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} engines: {node: '>=12'} - slash@5.1.0: - resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} - engines: {node: '>=14.16'} - sockjs@0.3.24: resolution: {integrity: sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==} @@ -8701,6 +8765,12 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + thingies@1.21.0: + resolution: {integrity: sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==} + engines: {node: '>=10.18'} + peerDependencies: + tslib: ^2 + throat@6.0.2: resolution: {integrity: sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==} @@ -8780,6 +8850,12 @@ packages: resolution: {integrity: sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==} engines: {node: '>=8'} + tree-dump@1.0.3: + resolution: {integrity: sha512-il+Cv80yVHFBwokQSfd4bldvr1Md951DpgAGfmhydt04L+YzHgubm2tQ7zueWDcGENKHq0ZvGFR/hjvNXilHEg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + trim-newlines@3.0.1: resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} engines: {node: '>=8'} @@ -8998,10 +9074,6 @@ packages: resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} engines: {node: '>=4'} - unicorn-magic@0.3.0: - resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} - engines: {node: '>=18'} - unique-string@2.0.0: resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} engines: {node: '>=8'} @@ -9198,18 +9270,15 @@ packages: resolution: {integrity: sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==} engines: {node: '>=10.4'} - webpack-cli@5.1.4: - resolution: {integrity: sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==} - engines: {node: '>=14.15.0'} + webpack-cli@6.0.1: + resolution: {integrity: sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==} + engines: {node: '>=18.12.0'} hasBin: true peerDependencies: - '@webpack-cli/generators': '*' - webpack: 5.x.x + webpack: ^5.82.0 webpack-bundle-analyzer: '*' webpack-dev-server: '*' peerDependenciesMeta: - '@webpack-cli/generators': - optional: true webpack-bundle-analyzer: optional: true webpack-dev-server: @@ -9221,6 +9290,15 @@ packages: peerDependencies: webpack: ^4.0.0 || ^5.0.0 + webpack-dev-middleware@7.4.2: + resolution: {integrity: sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==} + engines: {node: '>= 18.12.0'} + peerDependencies: + webpack: ^5.0.0 + peerDependenciesMeta: + webpack: + optional: true + webpack-dev-server@4.15.2: resolution: {integrity: sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==} engines: {node: '>= 12.13.0'} @@ -9234,15 +9312,28 @@ packages: webpack-cli: optional: true + webpack-dev-server@5.2.2: + resolution: {integrity: sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==} + engines: {node: '>= 18.12.0'} + hasBin: true + peerDependencies: + webpack: ^5.0.0 + webpack-cli: '*' + peerDependenciesMeta: + webpack: + optional: true + webpack-cli: + optional: true + webpack-manifest-plugin@4.1.1: resolution: {integrity: sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow==} engines: {node: '>=12.22.0'} peerDependencies: webpack: ^4.44.2 || ^5.47.0 - webpack-merge@5.10.0: - resolution: {integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==} - engines: {node: '>=10.0.0'} + webpack-merge@6.0.1: + resolution: {integrity: sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==} + engines: {node: '>=18.0.0'} webpack-sources@1.4.3: resolution: {integrity: sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==} @@ -9255,8 +9346,8 @@ packages: resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} engines: {node: '>=10.13.0'} - webpack@5.98.0: - resolution: {integrity: sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==} + webpack@5.99.9: + resolution: {integrity: sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -10708,7 +10799,7 @@ snapshots: dependencies: postcss-selector-parser: 6.1.2 - '@discoveryjs/json-ext@0.5.7': {} + '@discoveryjs/json-ext@0.6.3': {} '@emnapi/core@1.4.0': dependencies: @@ -11605,6 +11696,22 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@jsonjoy.com/base64@1.1.2(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/json-pack@1.2.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/base64': 1.1.2(tslib@2.8.1) + '@jsonjoy.com/util': 1.6.0(tslib@2.8.1) + hyperdyperid: 1.2.0 + thingies: 1.21.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/util@1.6.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + '@leichtgewicht/ip-codec@2.0.5': {} '@manypkg/find-root@1.1.0': @@ -11833,7 +11940,7 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.11.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.98.0))(webpack@5.98.0)': + '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.11.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.99.9))(webpack@5.99.9)': dependencies: ansi-html: 0.0.9 core-js-pure: 3.41.0 @@ -11843,12 +11950,12 @@ snapshots: react-refresh: 0.11.0 schema-utils: 4.3.0 source-map: 0.7.4 - webpack: 5.98.0 + webpack: 5.99.9 optionalDependencies: type-fest: 0.21.3 - webpack-dev-server: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.98.0) + webpack-dev-server: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.99.9) - '@pmmmwh/react-refresh-webpack-plugin@0.6.0(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4))': + '@pmmmwh/react-refresh-webpack-plugin@0.6.0(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9))(webpack@5.99.9(webpack-cli@6.0.1))': dependencies: anser: 2.3.2 core-js-pure: 3.41.0 @@ -11857,10 +11964,10 @@ snapshots: react-refresh: 0.17.0 schema-utils: 4.3.0 source-map: 0.7.4 - webpack: 5.98.0(webpack-cli@5.1.4) + webpack: 5.99.9(webpack-cli@6.0.1) optionalDependencies: type-fest: 0.21.3 - webpack-dev-server: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0) + webpack-dev-server: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) '@randlabs/communication-bridge@1.0.1': optional: true @@ -11985,8 +12092,6 @@ snapshots: '@sindresorhus/is@4.6.0': {} - '@sindresorhus/merge-streams@2.3.0': {} - '@sinonjs/commons@1.8.6': dependencies: type-detect: 4.0.8 @@ -12181,11 +12286,11 @@ snapshots: '@types/body-parser@1.19.5': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.13.14 + '@types/node': 20.17.28 '@types/bonjour@3.5.13': dependencies: - '@types/node': 22.13.14 + '@types/node': 20.17.28 '@types/cacheable-request@6.0.3': dependencies: @@ -12197,7 +12302,7 @@ snapshots: '@types/connect-history-api-fallback@1.5.4': dependencies: '@types/express-serve-static-core': 5.0.6 - '@types/node': 22.13.14 + '@types/node': 20.17.28 '@types/connect@3.4.38': dependencies: @@ -12233,14 +12338,14 @@ snapshots: '@types/express-serve-static-core@4.19.6': dependencies: - '@types/node': 22.13.14 + '@types/node': 20.17.28 '@types/qs': 6.9.18 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 '@types/express-serve-static-core@5.0.6': dependencies: - '@types/node': 22.13.14 + '@types/node': 20.17.28 '@types/qs': 6.9.18 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 @@ -12264,7 +12369,7 @@ snapshots: '@types/http-proxy@1.17.16': dependencies: - '@types/node': 22.13.14 + '@types/node': 20.17.28 '@types/istanbul-lib-coverage@2.0.6': {} @@ -12292,7 +12397,7 @@ snapshots: '@types/node-forge@1.3.11': dependencies: - '@types/node': 22.13.14 + '@types/node': 20.17.28 '@types/node@11.11.6': {} @@ -12356,12 +12461,14 @@ snapshots: '@types/retry@0.12.0': {} + '@types/retry@0.12.2': {} + '@types/semver@7.7.0': {} '@types/send@0.17.4': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.13.14 + '@types/node': 20.17.28 '@types/serve-index@1.9.4': dependencies: @@ -12370,12 +12477,12 @@ snapshots: '@types/serve-static@1.15.7': dependencies: '@types/http-errors': 2.0.4 - '@types/node': 22.13.14 + '@types/node': 20.17.28 '@types/send': 0.17.4 '@types/sockjs@0.3.36': dependencies: - '@types/node': 22.13.14 + '@types/node': 20.17.28 '@types/stack-utils@2.0.3': {} @@ -12391,7 +12498,7 @@ snapshots: '@types/ws@8.18.0': dependencies: - '@types/node': 22.13.14 + '@types/node': 20.17.28 '@types/yargs-parser@21.0.3': {} @@ -12830,22 +12937,22 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@xtuc/long': 4.2.2 - '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4(webpack-dev-server@4.15.2)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4))': + '@webpack-cli/configtest@3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9))(webpack@5.99.9(webpack-cli@6.0.1))': dependencies: - webpack: 5.98.0(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.98.0) + webpack: 5.99.9(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) - '@webpack-cli/info@2.0.2(webpack-cli@5.1.4(webpack-dev-server@4.15.2)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4))': + '@webpack-cli/info@3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9))(webpack@5.99.9(webpack-cli@6.0.1))': dependencies: - webpack: 5.98.0(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.98.0) + webpack: 5.99.9(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) - '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4(webpack-dev-server@4.15.2)(webpack@5.98.0))(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4))': + '@webpack-cli/serve@3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9))(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9))(webpack@5.99.9(webpack-cli@6.0.1))': dependencies: - webpack: 5.98.0(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.98.0) + webpack: 5.99.9(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) optionalDependencies: - webpack-dev-server: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0) + webpack-dev-server: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) '@xtuc/ieee754@1.2.0': {} @@ -12895,7 +13002,7 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.4.0 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -13214,14 +13321,14 @@ snapshots: transitivePeerDependencies: - supports-color - babel-loader@8.4.1(@babel/core@7.26.10)(webpack@5.98.0): + babel-loader@8.4.1(@babel/core@7.26.10)(webpack@5.99.9): dependencies: '@babel/core': 7.26.10 find-cache-dir: 3.3.2 loader-utils: 2.0.4 make-dir: 3.1.0 schema-utils: 2.7.1 - webpack: 5.98.0 + webpack: 5.99.9 babel-plugin-istanbul@6.1.1: dependencies: @@ -13521,6 +13628,10 @@ snapshots: builtin-modules@3.3.0: {} + bundle-name@4.1.0: + dependencies: + run-applescript: 7.0.0 + bundle-require@4.2.1(esbuild@0.19.12): dependencies: esbuild: 0.19.12 @@ -13758,8 +13869,6 @@ snapshots: table-layout: 1.0.2 typical: 5.2.0 - commander@10.0.1: {} - commander@12.1.0: {} commander@13.1.0: {} @@ -13964,15 +14073,14 @@ snapshots: dependencies: toggle-selection: 1.0.6 - copy-webpack-plugin@12.0.2(webpack@5.98.0(webpack-cli@5.1.4)): + copy-webpack-plugin@13.0.0(webpack@5.99.9(webpack-cli@6.0.1)): dependencies: - fast-glob: 3.3.3 glob-parent: 6.0.2 - globby: 14.1.0 normalize-path: 3.0.0 schema-utils: 4.3.0 serialize-javascript: 6.0.2 - webpack: 5.98.0(webpack-cli@5.1.4) + tinyglobby: 0.2.12 + webpack: 5.99.9(webpack-cli@6.0.1) core-js-compat@3.41.0: dependencies: @@ -14093,7 +14201,7 @@ snapshots: postcss: 8.5.3 postcss-selector-parser: 6.1.2 - css-loader@6.11.0(webpack@5.98.0): + css-loader@6.11.0(webpack@5.99.9): dependencies: icss-utils: 5.1.0(postcss@8.5.3) postcss: 8.5.3 @@ -14104,9 +14212,9 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.7.1 optionalDependencies: - webpack: 5.98.0 + webpack: 5.99.9 - css-minimizer-webpack-plugin@3.4.1(webpack@5.98.0): + css-minimizer-webpack-plugin@3.4.1(webpack@5.99.9): dependencies: cssnano: 5.1.15(postcss@8.5.3) jest-worker: 27.5.1 @@ -14114,7 +14222,7 @@ snapshots: schema-utils: 4.3.0 serialize-javascript: 6.0.2 source-map: 0.6.1 - webpack: 5.98.0 + webpack: 5.99.9 css-prefers-color-scheme@6.0.3(postcss@8.5.3): dependencies: @@ -14330,6 +14438,13 @@ snapshots: deepmerge@4.3.1: {} + default-browser-id@5.0.0: {} + + default-browser@5.2.1: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.0 + default-gateway@6.0.3: dependencies: execa: 5.1.1 @@ -14348,6 +14463,8 @@ snapshots: define-lazy-prop@2.0.0: {} + define-lazy-prop@3.0.0: {} + define-properties@1.2.1: dependencies: define-data-property: 1.1.4 @@ -14676,14 +14793,14 @@ snapshots: dependencies: es6-promise: 4.2.8 - esbuild-loader@2.21.0(webpack@5.98.0(webpack-cli@5.1.4)): + esbuild-loader@2.21.0(webpack@5.99.9(webpack-cli@6.0.1)): dependencies: esbuild: 0.16.17 joycon: 3.1.1 json5: 2.2.3 loader-utils: 2.0.4 tapable: 2.2.1 - webpack: 5.98.0(webpack-cli@5.1.4) + webpack: 5.99.9(webpack-cli@6.0.1) webpack-sources: 1.4.3 esbuild@0.16.17: @@ -15199,7 +15316,7 @@ snapshots: eslint-visitor-keys@3.4.3: {} - eslint-webpack-plugin@3.2.0(eslint@8.57.1)(webpack@5.98.0): + eslint-webpack-plugin@3.2.0(eslint@8.57.1)(webpack@5.99.9): dependencies: '@types/eslint': 8.56.12 eslint: 8.57.1 @@ -15207,7 +15324,7 @@ snapshots: micromatch: 4.0.8 normalize-path: 3.0.0 schema-utils: 4.3.0 - webpack: 5.98.0 + webpack: 5.99.9 eslint@8.57.0: dependencies: @@ -15511,17 +15628,17 @@ snapshots: dependencies: flat-cache: 3.2.0 - file-loader@6.2.0(webpack@5.98.0(webpack-cli@5.1.4)): + file-loader@6.2.0(webpack@5.99.9(webpack-cli@6.0.1)): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.98.0(webpack-cli@5.1.4) + webpack: 5.99.9(webpack-cli@6.0.1) - file-loader@6.2.0(webpack@5.98.0): + file-loader@6.2.0(webpack@5.99.9): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.98.0 + webpack: 5.99.9 file-uri-to-path@1.0.0: {} @@ -15618,7 +15735,7 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.1)(typescript@5.8.2)(webpack@5.98.0): + fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.1)(typescript@5.8.2)(webpack@5.99.9): dependencies: '@babel/code-frame': 7.26.2 '@types/json-schema': 7.0.15 @@ -15634,7 +15751,7 @@ snapshots: semver: 7.7.1 tapable: 1.1.3 typescript: 5.8.2 - webpack: 5.98.0 + webpack: 5.99.9 optionalDependencies: eslint: 8.57.1 @@ -15889,15 +16006,6 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 - globby@14.1.0: - dependencies: - '@sindresorhus/merge-streams': 2.3.0 - fast-glob: 3.3.3 - ignore: 7.0.3 - path-type: 6.0.0 - slash: 5.1.0 - unicorn-magic: 0.3.0 - gopd@1.2.0: {} got@11.8.6: @@ -16018,7 +16126,7 @@ snapshots: relateurl: 0.2.7 terser: 5.39.0 - html-webpack-plugin@5.6.3(webpack@5.98.0(webpack-cli@5.1.4)): + html-webpack-plugin@5.6.3(webpack@5.99.9(webpack-cli@6.0.1)): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -16026,9 +16134,9 @@ snapshots: pretty-error: 4.0.0 tapable: 2.2.1 optionalDependencies: - webpack: 5.98.0(webpack-cli@5.1.4) + webpack: 5.99.9(webpack-cli@6.0.1) - html-webpack-plugin@5.6.3(webpack@5.98.0): + html-webpack-plugin@5.6.3(webpack@5.99.9): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -16036,7 +16144,7 @@ snapshots: pretty-error: 4.0.0 tapable: 2.2.1 optionalDependencies: - webpack: 5.98.0 + webpack: 5.99.9 htmlparser2@6.1.0: dependencies: @@ -16078,7 +16186,7 @@ snapshots: dependencies: '@tootallnate/once': 1.1.2 agent-base: 6.0.2 - debug: 4.4.0 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -16094,6 +16202,18 @@ snapshots: transitivePeerDependencies: - debug + http-proxy-middleware@2.0.9(@types/express@4.17.21): + dependencies: + '@types/http-proxy': 1.17.16 + http-proxy: 1.18.1 + is-glob: 4.0.3 + is-plain-obj: 3.0.0 + micromatch: 4.0.8 + optionalDependencies: + '@types/express': 4.17.21 + transitivePeerDependencies: + - debug + http-proxy@1.18.1: dependencies: eventemitter3: 4.0.7 @@ -16110,7 +16230,7 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.4.0 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -16122,6 +16242,8 @@ snapshots: dependencies: ms: 2.1.3 + hyperdyperid@1.2.0: {} + iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 @@ -16144,8 +16266,6 @@ snapshots: ignore@5.3.2: {} - ignore@7.0.3: {} - immer@9.0.21: {} import-fresh@3.3.1: @@ -16287,6 +16407,8 @@ snapshots: is-docker@2.2.1: {} + is-docker@3.0.0: {} + is-extglob@2.1.1: {} is-finalizationregistry@1.1.1: @@ -16308,12 +16430,18 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + is-interactive@1.0.0: {} is-map@2.0.3: {} is-module@1.0.0: {} + is-network-error@1.1.0: {} + is-number-object@1.1.1: dependencies: call-bound: 1.0.4 @@ -16408,6 +16536,10 @@ snapshots: dependencies: is-docker: 2.2.1 + is-wsl@3.1.0: + dependencies: + is-inside-container: 1.0.0 + isarray@1.0.0: {} isarray@2.0.5: {} @@ -16440,7 +16572,7 @@ snapshots: istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.4.0 + debug: 4.4.1 istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -17243,6 +17375,13 @@ snapshots: dependencies: fs-monkey: 1.0.6 + memfs@4.17.2: + dependencies: + '@jsonjoy.com/json-pack': 1.2.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.6.0(tslib@2.8.1) + tree-dump: 1.0.3(tslib@2.8.1) + tslib: 2.8.1 + memorystream@0.3.1: {} meow@8.1.2: @@ -17297,11 +17436,11 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.9.2(webpack@5.98.0): + mini-css-extract-plugin@2.9.2(webpack@5.99.9): dependencies: schema-utils: 4.3.0 tapable: 2.2.1 - webpack: 5.98.0 + webpack: 5.99.9 minimalistic-assert@1.0.1: {} @@ -17579,6 +17718,13 @@ snapshots: dependencies: mimic-fn: 2.1.0 + open@10.1.2: + dependencies: + default-browser: 5.2.1 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + is-wsl: 3.1.0 + open@8.4.2: dependencies: define-lazy-prop: 2.0.0 @@ -17666,6 +17812,12 @@ snapshots: '@types/retry': 0.12.0 retry: 0.13.1 + p-retry@6.2.1: + dependencies: + '@types/retry': 0.12.2 + is-network-error: 1.1.0 + retry: 0.13.1 + p-try@1.0.0: {} p-try@2.2.0: {} @@ -17749,8 +17901,6 @@ snapshots: path-type@4.0.0: {} - path-type@6.0.0: {} - pathe@2.0.3: {} pathval@2.0.0: {} @@ -17949,13 +18099,13 @@ snapshots: postcss: 8.5.3 ts-node: 10.9.2(@types/node@20.17.28)(typescript@5.8.2) - postcss-loader@6.2.1(postcss@8.5.3)(webpack@5.98.0): + postcss-loader@6.2.1(postcss@8.5.3)(webpack@5.99.9): dependencies: cosmiconfig: 7.1.0 klona: 2.0.6 postcss: 8.5.3 semver: 7.7.1 - webpack: 5.98.0 + webpack: 5.99.9 postcss-logical@5.0.4(postcss@8.5.3): dependencies: @@ -18371,7 +18521,7 @@ snapshots: prop-types: 15.8.1 react: 18.3.1 - react-dev-utils@12.0.1(eslint@8.57.1)(typescript@5.8.2)(webpack@5.98.0): + react-dev-utils@12.0.1(eslint@8.57.1)(typescript@5.8.2)(webpack@5.99.9): dependencies: '@babel/code-frame': 7.26.2 address: 1.2.2 @@ -18382,7 +18532,7 @@ snapshots: escape-string-regexp: 4.0.0 filesize: 8.0.7 find-up: 5.0.0 - fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.1)(typescript@5.8.2)(webpack@5.98.0) + fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.1)(typescript@5.8.2)(webpack@5.99.9) global-modules: 2.0.0 globby: 11.1.0 gzip-size: 6.0.0 @@ -18397,7 +18547,7 @@ snapshots: shell-quote: 1.8.2 strip-ansi: 6.0.1 text-table: 0.2.0 - webpack: 5.98.0 + webpack: 5.99.9 optionalDependencies: typescript: 5.8.2 transitivePeerDependencies: @@ -18426,53 +18576,53 @@ snapshots: react-scripts@5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(@types/babel__core@7.20.5)(bufferutil@4.0.9)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(type-fest@0.21.3)(typescript@5.8.2)(utf-8-validate@5.0.10): dependencies: '@babel/core': 7.26.10 - '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(react-refresh@0.11.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.98.0))(webpack@5.98.0) + '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(react-refresh@0.11.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.99.9))(webpack@5.99.9) '@svgr/webpack': 5.5.0 babel-jest: 27.5.1(@babel/core@7.26.10) - babel-loader: 8.4.1(@babel/core@7.26.10)(webpack@5.98.0) + babel-loader: 8.4.1(@babel/core@7.26.10)(webpack@5.99.9) babel-plugin-named-asset-import: 0.3.8(@babel/core@7.26.10) babel-preset-react-app: 10.1.0 bfj: 7.1.0 browserslist: 4.24.4 camelcase: 6.3.0 case-sensitive-paths-webpack-plugin: 2.4.0 - css-loader: 6.11.0(webpack@5.98.0) - css-minimizer-webpack-plugin: 3.4.1(webpack@5.98.0) + css-loader: 6.11.0(webpack@5.99.9) + css-minimizer-webpack-plugin: 3.4.1(webpack@5.99.9) dotenv: 10.0.0 dotenv-expand: 5.1.0 eslint: 8.57.1 eslint-config-react-app: 7.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10))(typescript@5.8.2) - eslint-webpack-plugin: 3.2.0(eslint@8.57.1)(webpack@5.98.0) - file-loader: 6.2.0(webpack@5.98.0) + eslint-webpack-plugin: 3.2.0(eslint@8.57.1)(webpack@5.99.9) + file-loader: 6.2.0(webpack@5.99.9) fs-extra: 10.1.0 - html-webpack-plugin: 5.6.3(webpack@5.98.0) + html-webpack-plugin: 5.6.3(webpack@5.99.9) identity-obj-proxy: 3.0.0 jest: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10) jest-resolve: 27.5.1 jest-watch-typeahead: 1.1.0(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10)) - mini-css-extract-plugin: 2.9.2(webpack@5.98.0) + mini-css-extract-plugin: 2.9.2(webpack@5.99.9) postcss: 8.5.3 postcss-flexbugs-fixes: 5.0.2(postcss@8.5.3) - postcss-loader: 6.2.1(postcss@8.5.3)(webpack@5.98.0) + postcss-loader: 6.2.1(postcss@8.5.3)(webpack@5.99.9) postcss-normalize: 10.0.1(browserslist@4.24.4)(postcss@8.5.3) postcss-preset-env: 7.8.3(postcss@8.5.3) prompts: 2.4.2 react: 18.3.1 react-app-polyfill: 3.0.0 - react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.8.2)(webpack@5.98.0) + react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.8.2)(webpack@5.99.9) react-refresh: 0.11.0 resolve: 1.22.10 resolve-url-loader: 4.0.0 - sass-loader: 12.6.0(webpack@5.98.0) + sass-loader: 12.6.0(webpack@5.99.9) semver: 7.7.1 - source-map-loader: 3.0.2(webpack@5.98.0) - style-loader: 3.3.4(webpack@5.98.0) + source-map-loader: 3.0.2(webpack@5.99.9) + style-loader: 3.3.4(webpack@5.99.9) tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2)) - terser-webpack-plugin: 5.3.14(webpack@5.98.0) - webpack: 5.98.0 - webpack-dev-server: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.98.0) - webpack-manifest-plugin: 4.1.1(webpack@5.98.0) - workbox-webpack-plugin: 6.6.0(@types/babel__core@7.20.5)(webpack@5.98.0) + terser-webpack-plugin: 5.3.14(webpack@5.99.9) + webpack: 5.99.9 + webpack-dev-server: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.99.9) + webpack-manifest-plugin: 4.1.1(webpack@5.99.9) + workbox-webpack-plugin: 6.6.0(@types/babel__core@7.20.5)(webpack@5.99.9) optionalDependencies: fsevents: 2.3.3 typescript: 5.8.2 @@ -18772,6 +18922,8 @@ snapshots: bufferutil: 4.0.9 utf-8-validate: 5.0.10 + run-applescript@7.0.0: {} + run-async@2.4.1: {} run-parallel@1.2.0: @@ -18809,11 +18961,11 @@ snapshots: sanitize.css@13.0.0: {} - sass-loader@12.6.0(webpack@5.98.0): + sass-loader@12.6.0(webpack@5.99.9): dependencies: klona: 2.0.6 neo-async: 2.6.2 - webpack: 5.98.0 + webpack: 5.99.9 sax@1.2.4: {} @@ -18850,6 +19002,13 @@ snapshots: ajv-formats: 2.1.1(ajv@8.17.1) ajv-keywords: 5.1.0(ajv@8.17.1) + schema-utils@4.3.2: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) + scrypt-js@3.0.1: {} secp256k1@5.0.1: @@ -19057,8 +19216,6 @@ snapshots: slash@4.0.0: {} - slash@5.1.0: {} - sockjs@0.3.24: dependencies: faye-websocket: 0.11.4 @@ -19082,12 +19239,12 @@ snapshots: source-map-js@1.2.1: {} - source-map-loader@3.0.2(webpack@5.98.0): + source-map-loader@3.0.2(webpack@5.99.9): dependencies: abab: 2.0.6 iconv-lite: 0.6.3 source-map-js: 1.2.1 - webpack: 5.98.0 + webpack: 5.99.9 source-map-support@0.5.21: dependencies: @@ -19125,7 +19282,7 @@ snapshots: spdy-transport@3.0.0: dependencies: - debug: 4.4.0 + debug: 4.4.1 detect-node: 2.1.0 hpack.js: 2.1.6 obuf: 1.1.2 @@ -19136,7 +19293,7 @@ snapshots: spdy@4.0.2: dependencies: - debug: 4.4.0 + debug: 4.4.1 handle-thing: 2.0.1 http-deceiver: 1.2.7 select-hose: 2.0.0 @@ -19336,9 +19493,9 @@ snapshots: dependencies: escape-string-regexp: 1.0.5 - style-loader@3.3.4(webpack@5.98.0): + style-loader@3.3.4(webpack@5.99.9): dependencies: - webpack: 5.98.0 + webpack: 5.99.9 styled-jsx@5.1.6(react@18.3.1): dependencies: @@ -19466,23 +19623,23 @@ snapshots: ansi-escapes: 4.3.2 supports-hyperlinks: 2.3.0 - terser-webpack-plugin@5.3.14(webpack@5.98.0(webpack-cli@5.1.4)): + terser-webpack-plugin@5.3.14(webpack@5.99.9(webpack-cli@6.0.1)): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 4.3.0 serialize-javascript: 6.0.2 terser: 5.39.0 - webpack: 5.98.0(webpack-cli@5.1.4) + webpack: 5.99.9(webpack-cli@6.0.1) - terser-webpack-plugin@5.3.14(webpack@5.98.0): + terser-webpack-plugin@5.3.14(webpack@5.99.9): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 4.3.0 serialize-javascript: 6.0.2 terser: 5.39.0 - webpack: 5.98.0 + webpack: 5.99.9 terser@5.39.0: dependencies: @@ -19517,6 +19674,10 @@ snapshots: dependencies: any-promise: 1.3.0 + thingies@1.21.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + throat@6.0.2: {} through2@2.0.5: @@ -19588,6 +19749,10 @@ snapshots: dependencies: punycode: 2.3.1 + tree-dump@1.0.3(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + trim-newlines@3.0.1: {} trim-repeated@1.0.0: @@ -19800,8 +19965,6 @@ snapshots: unicode-property-aliases-ecmascript@2.1.0: {} - unicorn-magic@0.3.0: {} - unique-string@2.0.0: dependencies: crypto-random-string: 2.0.0 @@ -20071,44 +20234,46 @@ snapshots: webidl-conversions@6.1.0: {} - webpack-cli@5.1.4(webpack-dev-server@4.15.2)(webpack@5.98.0): + webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9): dependencies: - '@discoveryjs/json-ext': 0.5.7 - '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4(webpack-dev-server@4.15.2)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4)) - '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4(webpack-dev-server@4.15.2)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4)) - '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4(webpack-dev-server@4.15.2)(webpack@5.98.0))(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0))(webpack@5.98.0(webpack-cli@5.1.4)) + '@discoveryjs/json-ext': 0.6.3 + '@webpack-cli/configtest': 3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9))(webpack@5.99.9(webpack-cli@6.0.1)) + '@webpack-cli/info': 3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9))(webpack@5.99.9(webpack-cli@6.0.1)) + '@webpack-cli/serve': 3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9))(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9))(webpack@5.99.9(webpack-cli@6.0.1)) colorette: 2.0.20 - commander: 10.0.1 + commander: 12.1.0 cross-spawn: 7.0.6 envinfo: 7.14.0 fastest-levenshtein: 1.0.16 import-local: 3.2.0 interpret: 3.1.1 rechoir: 0.8.0 - webpack: 5.98.0(webpack-cli@5.1.4) - webpack-merge: 5.10.0 + webpack: 5.99.9(webpack-cli@6.0.1) + webpack-merge: 6.0.1 optionalDependencies: - webpack-dev-server: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0) + webpack-dev-server: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) - webpack-dev-middleware@5.3.4(webpack@5.98.0(webpack-cli@5.1.4)): + webpack-dev-middleware@5.3.4(webpack@5.99.9): dependencies: colorette: 2.0.20 memfs: 3.5.3 mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.3.0 - webpack: 5.98.0(webpack-cli@5.1.4) + webpack: 5.99.9 - webpack-dev-middleware@5.3.4(webpack@5.98.0): + webpack-dev-middleware@7.4.2(webpack@5.99.9(webpack-cli@6.0.1)): dependencies: colorette: 2.0.20 - memfs: 3.5.3 + memfs: 4.17.2 mime-types: 2.1.35 + on-finished: 2.4.1 range-parser: 1.2.1 schema-utils: 4.3.0 - webpack: 5.98.0 + optionalDependencies: + webpack: 5.99.9(webpack-cli@6.0.1) - webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@5.1.4)(webpack@5.98.0): + webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.99.9): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -20138,22 +20303,22 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 5.3.4(webpack@5.98.0(webpack-cli@5.1.4)) + webpack-dev-middleware: 5.3.4(webpack@5.99.9) ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - webpack: 5.98.0(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.98.0) + webpack: 5.99.9 transitivePeerDependencies: - bufferutil - debug - supports-color - utf-8-validate - webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.98.0): + webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 '@types/express': 4.17.21 + '@types/express-serve-static-core': 4.19.6 '@types/serve-index': 1.9.4 '@types/serve-static': 1.15.7 '@types/sockjs': 0.3.36 @@ -20164,38 +20329,36 @@ snapshots: colorette: 2.0.20 compression: 1.8.0 connect-history-api-fallback: 2.0.0 - default-gateway: 6.0.3 express: 4.21.2 graceful-fs: 4.2.11 - html-entities: 2.5.3 - http-proxy-middleware: 2.0.7(@types/express@4.17.21) + http-proxy-middleware: 2.0.9(@types/express@4.17.21) ipaddr.js: 2.2.0 launch-editor: 2.10.0 - open: 8.4.2 - p-retry: 4.6.2 - rimraf: 3.0.2 + open: 10.1.2 + p-retry: 6.2.1 schema-utils: 4.3.0 selfsigned: 2.4.1 serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 5.3.4(webpack@5.98.0) + webpack-dev-middleware: 7.4.2(webpack@5.99.9(webpack-cli@6.0.1)) ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - webpack: 5.98.0 + webpack: 5.99.9(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) transitivePeerDependencies: - bufferutil - debug - supports-color - utf-8-validate - webpack-manifest-plugin@4.1.1(webpack@5.98.0): + webpack-manifest-plugin@4.1.1(webpack@5.99.9): dependencies: tapable: 2.2.1 - webpack: 5.98.0 + webpack: 5.99.9 webpack-sources: 2.3.1 - webpack-merge@5.10.0: + webpack-merge@6.0.1: dependencies: clone-deep: 4.0.1 flat: 5.0.2 @@ -20213,10 +20376,11 @@ snapshots: webpack-sources@3.2.3: {} - webpack@5.98.0: + webpack@5.99.9: dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.7 + '@types/json-schema': 7.0.15 '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 @@ -20233,9 +20397,9 @@ snapshots: loader-runner: 4.3.0 mime-types: 2.1.35 neo-async: 2.6.2 - schema-utils: 4.3.0 + schema-utils: 4.3.2 tapable: 2.2.1 - terser-webpack-plugin: 5.3.14(webpack@5.98.0) + terser-webpack-plugin: 5.3.14(webpack@5.99.9) watchpack: 2.4.2 webpack-sources: 3.2.3 transitivePeerDependencies: @@ -20243,10 +20407,11 @@ snapshots: - esbuild - uglify-js - webpack@5.98.0(webpack-cli@5.1.4): + webpack@5.99.9(webpack-cli@6.0.1): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.7 + '@types/json-schema': 7.0.15 '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 @@ -20263,13 +20428,13 @@ snapshots: loader-runner: 4.3.0 mime-types: 2.1.35 neo-async: 2.6.2 - schema-utils: 4.3.0 + schema-utils: 4.3.2 tapable: 2.2.1 - terser-webpack-plugin: 5.3.14(webpack@5.98.0(webpack-cli@5.1.4)) + terser-webpack-plugin: 5.3.14(webpack@5.99.9(webpack-cli@6.0.1)) watchpack: 2.4.2 webpack-sources: 3.2.3 optionalDependencies: - webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.98.0) + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) transitivePeerDependencies: - '@swc/core' - esbuild @@ -20487,12 +20652,12 @@ snapshots: workbox-sw@6.6.0: {} - workbox-webpack-plugin@6.6.0(@types/babel__core@7.20.5)(webpack@5.98.0): + workbox-webpack-plugin@6.6.0(@types/babel__core@7.20.5)(webpack@5.99.9): dependencies: fast-json-stable-stringify: 2.1.0 pretty-bytes: 5.6.0 upath: 1.2.0 - webpack: 5.98.0 + webpack: 5.99.9 webpack-sources: 1.4.3 workbox-build: 6.6.0(@types/babel__core@7.20.5) transitivePeerDependencies: From ee970a1dcaf5f6ea87b63e7f8f52073b27612ee6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Sep 2025 07:13:46 +0000 Subject: [PATCH 009/303] Bump actions/checkout from 4 to 5 Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/lynx.yml | 2 +- .github/workflows/main.yml | 2 +- .github/workflows/mainnet.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/tapir.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/lynx.yml b/.github/workflows/lynx.yml index 16a9b4f28..0dda49320 100644 --- a/.github/workflows/lynx.yml +++ b/.github/workflows/lynx.yml @@ -25,7 +25,7 @@ jobs: os: [ubuntu-latest] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: pnpm/action-setup@v4 with: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c9d560a82..7c24f96b3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,7 +12,7 @@ jobs: node: ['18.x', '20.x', '22.x'] os: [ubuntu-latest] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: pnpm/action-setup@v4 with: diff --git a/.github/workflows/mainnet.yml b/.github/workflows/mainnet.yml index cc52462f3..d6c5ec860 100644 --- a/.github/workflows/mainnet.yml +++ b/.github/workflows/mainnet.yml @@ -23,7 +23,7 @@ jobs: os: [ubuntu-latest] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: pnpm/action-setup@v4 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fa55a0060..1ec57b994 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,7 @@ jobs: name: Publish NPM package using changesets runs-on: 'ubuntu-latest' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: pnpm/action-setup@v4 with: version: 9 diff --git a/.github/workflows/tapir.yml b/.github/workflows/tapir.yml index dd207b0d7..66523f192 100644 --- a/.github/workflows/tapir.yml +++ b/.github/workflows/tapir.yml @@ -27,7 +27,7 @@ jobs: os: [ubuntu-latest] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: pnpm/action-setup@v4 with: From 0b15566c11c5d7c10e3fc56a8441fd2d086dd069 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Aug 2025 17:35:12 +0000 Subject: [PATCH 010/303] Bump bundlemon from 2.1.0 to 3.1.0 Bumps [bundlemon](https://github.com/LironEr/bundlemon) from 2.1.0 to 3.1.0. - [Release notes](https://github.com/LironEr/bundlemon/releases) - [Commits](https://github.com/LironEr/bundlemon/compare/bundlemon@2.1.0...bundlemon@v3.1.0) --- updated-dependencies: - dependency-name: bundlemon dependency-version: 3.1.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package.json | 2 +- pnpm-lock.yaml | 950 ++++++++++++++++++++++++++++++------------------- 2 files changed, 592 insertions(+), 360 deletions(-) diff --git a/package.json b/package.json index 30a9c3d36..701b84bd7 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", "@vitest/coverage-v8": "^3.2.4", - "bundlemon": "^2.1.0", + "bundlemon": "^3.1.0", "eslint": "^8.57.1", "eslint-config-prettier": "^9.1.0", "eslint-config-typestrict": "^1.0.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 04bf7c255..eeb2174de 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,8 +41,8 @@ importers: specifier: ^3.2.4 version: 3.2.4(vitest@3.0.9(@types/node@20.17.28)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0)) bundlemon: - specifier: ^2.1.0 - version: 2.1.0 + specifier: ^3.1.0 + version: 3.1.0(typescript@5.8.2) eslint: specifier: ^8.57.1 version: 8.57.1 @@ -66,7 +66,7 @@ importers: version: 10.0.0(eslint@8.57.1) eslint-plugin-unused-imports: specifier: ^4.1.4 - version: 4.1.4(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1) + version: 4.2.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1) gh-pages: specifier: ^6.3.0 version: 6.3.0 @@ -129,7 +129,7 @@ importers: version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) file-loader: specifier: ^6.2.0 - version: 6.2.0(webpack@5.99.9(webpack-cli@6.0.1)) + version: 6.2.0(webpack@5.101.3(webpack-cli@6.0.1)) react: specifier: ^18.3.1 version: 18.3.1 @@ -145,7 +145,7 @@ importers: devDependencies: '@pmmmwh/react-refresh-webpack-plugin': specifier: ^0.6.0 - version: 0.6.0(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9))(webpack@5.99.9(webpack-cli@6.0.1)) + version: 0.6.1(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3))(webpack@5.101.3(webpack-cli@6.0.1)) '@types/react': specifier: ^18.3.20 version: 18.3.20 @@ -157,16 +157,16 @@ importers: version: 18.3.5(@types/react@18.3.20) copy-webpack-plugin: specifier: ^13.0.0 - version: 13.0.0(webpack@5.99.9(webpack-cli@6.0.1)) + version: 13.0.1(webpack@5.101.3(webpack-cli@6.0.1)) crypto-browserify: specifier: ^3.12.1 version: 3.12.1 esbuild-loader: specifier: ^2.21.0 - version: 2.21.0(webpack@5.99.9(webpack-cli@6.0.1)) + version: 2.21.0(webpack@5.101.3(webpack-cli@6.0.1)) html-webpack-plugin: specifier: ^5.6.3 - version: 5.6.3(webpack@5.99.9(webpack-cli@6.0.1)) + version: 5.6.3(webpack@5.101.3(webpack-cli@6.0.1)) process: specifier: ^0.11.10 version: 0.11.10 @@ -187,13 +187,13 @@ importers: version: 1.1.2 webpack: specifier: ^5.99.9 - version: 5.99.9(webpack-cli@6.0.1) + version: 5.101.3(webpack-cli@6.0.1) webpack-cli: specifier: ^6.0.1 - version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) + version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3) webpack-dev-server: specifier: ^5.2.2 - version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) + version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3) demos/taco-nft-demo: dependencies: @@ -214,7 +214,7 @@ importers: version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) file-loader: specifier: ^6.2.0 - version: 6.2.0(webpack@5.99.9(webpack-cli@6.0.1)) + version: 6.2.0(webpack@5.101.3(webpack-cli@6.0.1)) react: specifier: ^18.3.1 version: 18.3.1 @@ -230,7 +230,7 @@ importers: devDependencies: '@pmmmwh/react-refresh-webpack-plugin': specifier: ^0.6.0 - version: 0.6.0(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9))(webpack@5.99.9(webpack-cli@6.0.1)) + version: 0.6.1(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3))(webpack@5.101.3(webpack-cli@6.0.1)) '@types/react': specifier: ^18.3.20 version: 18.3.20 @@ -242,13 +242,13 @@ importers: version: 18.3.5(@types/react@18.3.20) copy-webpack-plugin: specifier: ^13.0.0 - version: 13.0.0(webpack@5.99.9(webpack-cli@6.0.1)) + version: 13.0.1(webpack@5.101.3(webpack-cli@6.0.1)) esbuild-loader: specifier: ^2.21.0 - version: 2.21.0(webpack@5.99.9(webpack-cli@6.0.1)) + version: 2.21.0(webpack@5.101.3(webpack-cli@6.0.1)) html-webpack-plugin: specifier: ^5.6.3 - version: 5.6.3(webpack@5.99.9(webpack-cli@6.0.1)) + version: 5.6.3(webpack@5.101.3(webpack-cli@6.0.1)) react-refresh: specifier: ^0.17.0 version: 0.17.0 @@ -263,13 +263,13 @@ importers: version: 4.9.5 webpack: specifier: ^5.99.9 - version: 5.99.9(webpack-cli@6.0.1) + version: 5.101.3(webpack-cli@6.0.1) webpack-cli: specifier: ^6.0.1 - version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) + version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3) webpack-dev-server: specifier: ^5.2.2 - version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) + version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3) examples/pre/nextjs: dependencies: @@ -352,22 +352,22 @@ importers: devDependencies: copy-webpack-plugin: specifier: ^13.0.0 - version: 13.0.0(webpack@5.99.9(webpack-cli@6.0.1)) + version: 13.0.1(webpack@5.101.3(webpack-cli@6.0.1)) esbuild-loader: specifier: ^2.21.0 - version: 2.21.0(webpack@5.99.9(webpack-cli@6.0.1)) + version: 2.21.0(webpack@5.101.3(webpack-cli@6.0.1)) ethers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) webpack: specifier: ^5.99.9 - version: 5.99.9(webpack-cli@6.0.1) + version: 5.101.3(webpack-cli@6.0.1) webpack-cli: specifier: ^6.0.1 - version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) + version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3) webpack-dev-server: specifier: ^5.2.2 - version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) + version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3) examples/taco/nextjs: dependencies: @@ -421,7 +421,7 @@ importers: version: link:../../../packages/taco-auth dotenv: specifier: ^16.5.0 - version: 16.5.0 + version: 16.6.1 ethers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -474,19 +474,19 @@ importers: devDependencies: copy-webpack-plugin: specifier: ^13.0.0 - version: 13.0.0(webpack@5.99.9(webpack-cli@6.0.1)) + version: 13.0.1(webpack@5.101.3(webpack-cli@6.0.1)) esbuild-loader: specifier: ^2.21.0 - version: 2.21.0(webpack@5.99.9(webpack-cli@6.0.1)) + version: 2.21.0(webpack@5.101.3(webpack-cli@6.0.1)) webpack: specifier: ^5.99.9 - version: 5.99.9(webpack-cli@6.0.1) + version: 5.101.3(webpack-cli@6.0.1) webpack-cli: specifier: ^6.0.1 - version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) + version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3) webpack-dev-server: specifier: ^5.2.2 - version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) + version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3) packages/pre: dependencies: @@ -551,7 +551,7 @@ importers: version: 0.2.6 cz-conventional-changelog: specifier: ^3.3.0 - version: 3.3.0(@types/node@22.13.14)(typescript@5.8.2) + version: 3.3.0(@types/node@24.1.0)(typescript@5.8.2) standard-version: specifier: ^9.5.0 version: 9.5.0 @@ -591,7 +591,7 @@ importers: version: 7.7.0 dotenv: specifier: ^16.5.0 - version: 16.5.0 + version: 16.6.1 glob: specifier: ^11.0.1 version: 11.0.1 @@ -637,7 +637,7 @@ importers: version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) vitest: specifier: ^3.0.9 - version: 3.0.9(@types/node@22.13.14)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0) + version: 3.0.9(@types/node@24.1.0)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0) packages: @@ -683,6 +683,10 @@ packages: resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + '@babel/compat-data@7.26.8': resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} engines: {node: '>=6.9.0'} @@ -773,6 +777,10 @@ packages: resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.25.9': resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} @@ -823,6 +831,7 @@ packages: '@babel/plugin-proposal-class-properties@7.18.6': resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead. peerDependencies: '@babel/core': ^7.0.0-0 @@ -835,24 +844,28 @@ packages: '@babel/plugin-proposal-nullish-coalescing-operator@7.18.6': resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead. peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-proposal-numeric-separator@7.18.6': resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead. peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-proposal-optional-chaining@7.21.0': resolution: {integrity: sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead. peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-proposal-private-methods@7.18.6': resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead. peerDependencies: '@babel/core': ^7.0.0-0 @@ -865,6 +878,7 @@ packages: '@babel/plugin-proposal-private-property-in-object@7.21.11': resolution: {integrity: sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead. peerDependencies: '@babel/core': ^7.0.0-0 @@ -1358,6 +1372,10 @@ packages: resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==} engines: {node: '>=6.9.0'} + '@babel/runtime@7.28.2': + resolution: {integrity: sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==} + engines: {node: '>=6.9.0'} + '@babel/template@7.27.0': resolution: {integrity: sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==} engines: {node: '>=6.9.0'} @@ -1564,8 +1582,8 @@ packages: '@emnapi/runtime@1.4.0': resolution: {integrity: sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw==} - '@emnapi/runtime@1.4.3': - resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} + '@emnapi/runtime@1.5.0': + resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==} '@emnapi/wasi-threads@1.0.1': resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==} @@ -2105,10 +2123,12 @@ packages: '@humanwhocodes/config-array@0.11.14': resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead '@humanwhocodes/config-array@0.13.0': resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} @@ -2116,123 +2136,130 @@ packages: '@humanwhocodes/object-schema@2.0.3': resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead '@hutson/parse-repository-url@3.0.2': resolution: {integrity: sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==} engines: {node: '>=6.9.0'} - '@img/sharp-darwin-arm64@0.34.2': - resolution: {integrity: sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==} + '@img/sharp-darwin-arm64@0.34.3': + resolution: {integrity: sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [darwin] - '@img/sharp-darwin-x64@0.34.2': - resolution: {integrity: sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==} + '@img/sharp-darwin-x64@0.34.3': + resolution: {integrity: sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.1.0': - resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==} + '@img/sharp-libvips-darwin-arm64@1.2.0': + resolution: {integrity: sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ==} cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.1.0': - resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==} + '@img/sharp-libvips-darwin-x64@1.2.0': + resolution: {integrity: sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg==} cpu: [x64] os: [darwin] - '@img/sharp-libvips-linux-arm64@1.1.0': - resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==} + '@img/sharp-libvips-linux-arm64@1.2.0': + resolution: {integrity: sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA==} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linux-arm@1.1.0': - resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==} + '@img/sharp-libvips-linux-arm@1.2.0': + resolution: {integrity: sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw==} cpu: [arm] os: [linux] - '@img/sharp-libvips-linux-ppc64@1.1.0': - resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==} + '@img/sharp-libvips-linux-ppc64@1.2.0': + resolution: {integrity: sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ==} cpu: [ppc64] os: [linux] - '@img/sharp-libvips-linux-s390x@1.1.0': - resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==} + '@img/sharp-libvips-linux-s390x@1.2.0': + resolution: {integrity: sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw==} cpu: [s390x] os: [linux] - '@img/sharp-libvips-linux-x64@1.1.0': - resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==} + '@img/sharp-libvips-linux-x64@1.2.0': + resolution: {integrity: sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg==} cpu: [x64] os: [linux] - '@img/sharp-libvips-linuxmusl-arm64@1.1.0': - resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==} + '@img/sharp-libvips-linuxmusl-arm64@1.2.0': + resolution: {integrity: sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q==} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linuxmusl-x64@1.1.0': - resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==} + '@img/sharp-libvips-linuxmusl-x64@1.2.0': + resolution: {integrity: sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q==} cpu: [x64] os: [linux] - '@img/sharp-linux-arm64@0.34.2': - resolution: {integrity: sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==} + '@img/sharp-linux-arm64@0.34.3': + resolution: {integrity: sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linux-arm@0.34.2': - resolution: {integrity: sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==} + '@img/sharp-linux-arm@0.34.3': + resolution: {integrity: sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] - '@img/sharp-linux-s390x@0.34.2': - resolution: {integrity: sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==} + '@img/sharp-linux-ppc64@0.34.3': + resolution: {integrity: sha512-GLtbLQMCNC5nxuImPR2+RgrviwKwVql28FWZIW1zWruy6zLgA5/x2ZXk3mxj58X/tszVF69KK0Is83V8YgWhLA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + + '@img/sharp-linux-s390x@0.34.3': + resolution: {integrity: sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] - '@img/sharp-linux-x64@0.34.2': - resolution: {integrity: sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==} + '@img/sharp-linux-x64@0.34.3': + resolution: {integrity: sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-linuxmusl-arm64@0.34.2': - resolution: {integrity: sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==} + '@img/sharp-linuxmusl-arm64@0.34.3': + resolution: {integrity: sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linuxmusl-x64@0.34.2': - resolution: {integrity: sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==} + '@img/sharp-linuxmusl-x64@0.34.3': + resolution: {integrity: sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-wasm32@0.34.2': - resolution: {integrity: sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==} + '@img/sharp-wasm32@0.34.3': + resolution: {integrity: sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [wasm32] - '@img/sharp-win32-arm64@0.34.2': - resolution: {integrity: sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==} + '@img/sharp-win32-arm64@0.34.3': + resolution: {integrity: sha512-MjnHPnbqMXNC2UgeLJtX4XqoVHHlZNd+nPt1kRPmj63wURegwBhZlApELdtxM2OIZDRv/DFtLcNhVbd1z8GYXQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [win32] - '@img/sharp-win32-ia32@0.34.2': - resolution: {integrity: sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==} + '@img/sharp-win32-ia32@0.34.3': + resolution: {integrity: sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ia32] os: [win32] - '@img/sharp-win32-x64@0.34.2': - resolution: {integrity: sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==} + '@img/sharp-win32-x64@0.34.3': + resolution: {integrity: sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [win32] @@ -2247,6 +2274,7 @@ packages: '@irys/sdk@0.1.24': resolution: {integrity: sha512-8vpgd4o/B1KaChPDgSBcLjAJapi16t/6wlV0SIPEJefbPdDKVuPyK36N3SlFeMkYexrBdqQOkLomHxBaWs0pLA==} engines: {node: '>=16.10.0'} + deprecated: 'Arweave support is deprecated - We recommend migrating to the Irys datachain: https://migrate-to.irys.xyz/' hasBin: true '@isaacs/cliui@8.0.2': @@ -2352,6 +2380,9 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.30': + resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} + '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} @@ -2361,14 +2392,32 @@ packages: peerDependencies: tslib: '2' - '@jsonjoy.com/json-pack@1.2.0': - resolution: {integrity: sha512-io1zEbbYcElht3tdlqEOFxZ0dMTYrHz9iMf0gqn1pPjZFTCgM5R4R5IMA20Chb2UPYYsxjzs8CgZ7Nb5n2K2rA==} + '@jsonjoy.com/buffers@1.0.0': + resolution: {integrity: sha512-NDigYR3PHqCnQLXYyoLbnEdzMMvzeiCWo1KOut7Q0CoIqg9tUAPKJ1iq/2nFhc5kZtexzutNY0LFjdwWL3Dw3Q==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/util@1.6.0': - resolution: {integrity: sha512-sw/RMbehRhN68WRtcKCpQOPfnH6lLP4GJfqzi3iYej8tnzpZUDr6UkZYJjcjjC0FWEJOJbyM3PTIwxucUmDG2A==} + '@jsonjoy.com/codegen@1.0.0': + resolution: {integrity: sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pack@1.11.0': + resolution: {integrity: sha512-nLqSTAYwpk+5ZQIoVp7pfd/oSKNWlEdvTq2LzVA4r2wtWZg6v+5u0VgBOaDJuUfNOuw/4Ysq6glN5QKSrOCgrA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pointer@1.0.2': + resolution: {integrity: sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/util@1.9.0': + resolution: {integrity: sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -2563,8 +2612,8 @@ packages: webpack-plugin-serve: optional: true - '@pmmmwh/react-refresh-webpack-plugin@0.6.0': - resolution: {integrity: sha512-AAc+QWfZ1KQ/e1C6OHWVlxU+ks6zFGOA44IJUlvju7RlDS8nsX6poPFOIlsg/rTofO9vKov12+WCjMhKkRKD5g==} + '@pmmmwh/react-refresh-webpack-plugin@0.6.1': + resolution: {integrity: sha512-95DXXJxNkpYu+sqmpDp7vbw9JCyiNpHuCsvuMuOgVFrKQlwEIn9Y1+NNIQJq+zFL+eWyxw6htthB5CtdwJupNA==} engines: {node: '>=18.12'} peerDependencies: '@types/webpack': 5.x @@ -2933,6 +2982,9 @@ packages: '@types/estree@1.0.7': resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/express-serve-static-core@4.19.6': resolution: {integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==} @@ -2975,8 +3027,8 @@ packages: '@types/keyv@3.1.4': resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} - '@types/lodash@4.17.16': - resolution: {integrity: sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==} + '@types/lodash@4.17.20': + resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==} '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} @@ -3002,6 +3054,9 @@ packages: '@types/node@22.13.14': resolution: {integrity: sha512-Zs/Ollc1SJ8nKUAgc7ivOEdIBM8JAKgrqqUYi2J997JuKO7/tpQC+WCetQ1sypiKCQWHdvdg9wBNpUPEWZae7w==} + '@types/node@24.1.0': + resolution: {integrity: sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==} + '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -3425,6 +3480,7 @@ packages: abab@2.0.6: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} + deprecated: Use your platform's native atob() and btoa() methods instead accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} @@ -3433,6 +3489,12 @@ packages: acorn-globals@6.0.0: resolution: {integrity: sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==} + acorn-import-phases@1.0.4: + resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} + engines: {node: '>=10.13.0'} + peerDependencies: + acorn: ^8.14.0 + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -3456,6 +3518,11 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + add-stream@1.0.0: resolution: {integrity: sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==} @@ -3673,8 +3740,8 @@ packages: ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} - ast-v8-to-istanbul@0.3.3: - resolution: {integrity: sha512-MuXMrSLVVoA6sYN/6Hke18vMzrT4TZNbZIj/hvh0fnYFpO+/kFXcLIaiPwXXWaQUPg4yJD8fj+lfJ7/1EBconw==} + ast-v8-to-istanbul@0.3.5: + resolution: {integrity: sha512-9SdXjNheSiE8bALAQCQQuT6fgQaoxJh7IRYrRGZ8/9nv8WhJeC1aXAwN8TbaOssGOukUvyvnkgD9+Yuykvl1aA==} async-function@1.0.0: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} @@ -3708,8 +3775,13 @@ packages: resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} engines: {node: '>=4'} - axios-retry@3.9.1: - resolution: {integrity: sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w==} + axios-retry@4.5.0: + resolution: {integrity: sha512-aR99oXhpEDGo0UuAlYcn2iGRds30k366Zfa05XWScR9QaQD4JYiP3/1Qt1u7YlefUOK+cn0CcwoL1oefavQUlQ==} + peerDependencies: + axios: 0.x || 1.x + + axios@1.11.0: + resolution: {integrity: sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==} axios@1.8.4: resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==} @@ -3820,6 +3892,9 @@ packages: bignumber.js@9.1.2: resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} + bignumber.js@9.3.1: + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -3939,13 +4014,13 @@ packages: peerDependencies: esbuild: '>=0.17' - bundlemon-utils@1.2.1: - resolution: {integrity: sha512-ydFZrI68L5j6hB9y88XGlbOp2lEwZHsDZl31ljHoi+wKE32glbuXMU0d0vQJLiR7Eq6uS0nDNYSmeoFHiV9R2g==} - engines: {node: '>=14.16'} + bundlemon-utils@2.0.1: + resolution: {integrity: sha512-7wxHoOlzICvQyMRfVqoBpnM5pJt1JdcUxsYPNiFx3RlVmUEANh2xdEyoyTsVCqzeJC3rn+AbPuiermBwA3szAQ==} + engines: {node: '>=18'} - bundlemon@2.1.0: - resolution: {integrity: sha512-zvsN7VDNeCtGIR+XUXobjxCSmnsUBqVe5ap2hMQnZOumfKAUJ6WVn/tnJOmt7TJfkXHeUKGi2sHARl7qrL+WDg==} - engines: {node: '>=14.16'} + bundlemon@3.1.0: + resolution: {integrity: sha512-8PAomH/fzAD/aXUKmphKmPm4Tl2L7mo51AAalO0EVAZE0cik58AM2x0CVdw4jutD069U2rSyRQstxHo2NEr+9Q==} + engines: {node: '>=18'} hasBin: true busboy@1.6.0: @@ -4152,6 +4227,10 @@ packages: resolution: {integrity: sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==} engines: {node: '>=8.0.0'} + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + commander@12.1.0: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} @@ -4175,10 +4254,6 @@ packages: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} - commander@9.5.0: - resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} - engines: {node: ^12.20.0 || >=14} - commitizen@4.3.1: resolution: {integrity: sha512-gwAPAVTy/j5YcOOebcCRIijn+mSjWJC+IYKivTu6aG8Ei/scoXgfsMRnuAk6b0GRste2J4NGxVdMN3ZpfNaVaw==} engines: {node: '>= 12'} @@ -4313,8 +4388,8 @@ packages: copy-to-clipboard@3.3.3: resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} - copy-webpack-plugin@13.0.0: - resolution: {integrity: sha512-FgR/h5a6hzJqATDGd9YG41SeDViH+0bkHn6WNXCi5zKAZkeESeSxLySSsFLHqLEVCh0E+rITmCf0dusXWYukeQ==} + copy-webpack-plugin@13.0.1: + resolution: {integrity: sha512-J+YV3WfhY6W/Xf9h+J1znYuqTye2xkBUIGyTPWuBAT27qajBa5mR4f8WBmfDY3YjRftT2kqZZiLi1qf0H+UOFw==} engines: {node: '>= 18.12.0'} peerDependencies: webpack: ^5.1.0 @@ -4347,6 +4422,15 @@ packages: resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} engines: {node: '>=10'} + cosmiconfig@8.3.6: + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + cosmiconfig@9.0.0: resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} engines: {node: '>=14'} @@ -4768,6 +4852,7 @@ packages: domexception@2.0.1: resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==} engines: {node: '>=8'} + deprecated: Use your platform's native DOMException instead domhandler@4.3.1: resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} @@ -4797,8 +4882,8 @@ packages: resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} engines: {node: '>=12'} - dotenv@16.5.0: - resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} dotgitignore@2.1.0: @@ -4861,8 +4946,8 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} - end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} enhanced-resolve@5.18.1: resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} @@ -5136,8 +5221,8 @@ packages: peerDependencies: eslint: ^7.5.0 || ^8.0.0 - eslint-plugin-unused-imports@4.1.4: - resolution: {integrity: sha512-YptD6IzQjDardkl0POxnnRBhU1OEePMV0nd6siHaRBbd+lyh6NAhFEobiznKU7kTsSsDeSD62Pe7kAM1b7dAZQ==} + eslint-plugin-unused-imports@4.2.0: + resolution: {integrity: sha512-hLbJ2/wnjKq4kGA9AUaExVFIbNzyxYdVo49QZmKCnhk5pc9wcYRbfgLHvWJ8tnsdcseGhoUAddm9gn/lt+d74w==} peerDependencies: '@typescript-eslint/eslint-plugin': ^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0 eslint: ^9.0.0 || ^8.0.0 @@ -5171,11 +5256,13 @@ packages: eslint@8.57.0: resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true eslint@8.57.1: resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true espree@9.6.1: @@ -5411,6 +5498,15 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + follow-redirects@1.15.9: resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} engines: {node: '>=4.0'} @@ -5442,14 +5538,18 @@ packages: vue-template-compiler: optional: true - form-data@3.0.3: - resolution: {integrity: sha512-q5YBMeWy6E2Un0nMGWMgI65MAKtaylxfNJGJxpGh45YDciZB4epbWpaAfImil6CPAPTYB4sh0URQNDRIZG5F2w==} + form-data@3.0.4: + resolution: {integrity: sha512-f0cRzm6dkyVYV3nPoooP8XlccPQukegwhAnpoLcXy+X+A8KfpGOoXwDr9FLZd3wzgLaBGQBE3lY93Zm/i1JvIQ==} engines: {node: '>= 6'} form-data@4.0.2: resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} engines: {node: '>= 6'} + form-data@4.0.4: + resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + engines: {node: '>= 6'} + forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -5582,6 +5682,12 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob-to-regex.js@1.0.1: + resolution: {integrity: sha512-CG/iEvgQqfzoVsMUbxSJcwbG2JwyZ3naEqPkeltwl0BSS8Bp83k3xlGms+0QdWFUAwV+uvo80wNswKF6FWEkKg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} @@ -5596,9 +5702,11 @@ packages: glob@7.1.7: resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} + deprecated: Glob versions prior to v9 are no longer supported glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported global-directory@4.0.1: resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} @@ -5765,8 +5873,8 @@ packages: htmlparser2@6.1.0: resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} - http-cache-semantics@4.1.1: - resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} http-deceiver@1.2.7: resolution: {integrity: sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==} @@ -5888,6 +5996,7 @@ packages: inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. inherits@2.0.3: resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} @@ -6608,6 +6717,7 @@ packages: lodash.isequal@4.5.0: resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. lodash.ismatch@4.4.0: resolution: {integrity: sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==} @@ -6738,8 +6848,8 @@ packages: resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==} engines: {node: '>= 4.0.0'} - memfs@4.17.2: - resolution: {integrity: sha512-NgYhCOWgovOXSzvYgUW0LQ7Qy72rWQMGGFJDoWg4G30RHd3z77VbYdtJ4fembJXBy8pMIUA31XNAupobOQlwdg==} + memfs@4.38.2: + resolution: {integrity: sha512-FpWsVHpAkoSh/LfY1BgAl72BVd374ooMRtDi2VqzBycX4XEfvC0XKACCe0C9VRZoYq5viuoyTv6lYXZ/Q7TrLQ==} engines: {node: '>= 4.0.0'} memorystream@0.3.1: @@ -7091,8 +7201,8 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} - open@10.1.2: - resolution: {integrity: sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==} + open@10.2.0: + resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} engines: {node: '>=18'} open@8.4.2: @@ -7839,8 +7949,8 @@ packages: public-encrypt@4.0.3: resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} - pump@3.0.2: - resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} + pump@3.0.3: + resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} @@ -7849,6 +7959,10 @@ packages: q@1.5.1: resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==} engines: {node: '>=0.6.0', teleport: '>=0.2.0'} + deprecated: |- + You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other. + + (For a CapTP with native promises, see @endo/eventual-send and @endo/captp) qs@6.13.0: resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} @@ -7864,6 +7978,7 @@ packages: querystring@0.2.1: resolution: {integrity: sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==} engines: {node: '>=0.4.x'} + deprecated: The querystring API is considered Legacy. new code should use the URLSearchParams API instead. querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} @@ -8132,6 +8247,7 @@ packages: rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true rimraf@5.0.10: @@ -8143,6 +8259,7 @@ packages: rollup-plugin-terser@7.0.2: resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser peerDependencies: rollup: ^2.0.0 @@ -8322,8 +8439,8 @@ packages: resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} engines: {node: '>=8'} - sharp@0.34.2: - resolution: {integrity: sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==} + sharp@0.34.3: + resolution: {integrity: sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} shebang-command@1.2.0: @@ -8431,9 +8548,11 @@ packages: source-map@0.8.0-beta.0: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} engines: {node: '>= 8'} + deprecated: The work that was done in this beta branch won't be included in future versions sourcemap-codec@1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead spawndamnit@3.0.1: resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} @@ -8471,6 +8590,7 @@ packages: stable@0.1.8: resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} + deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} @@ -8579,6 +8699,7 @@ packages: stringify-package@1.0.1: resolution: {integrity: sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==} + deprecated: This module is not used anymore, and has been replaced by @npmcli/package-json strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} @@ -8676,6 +8797,7 @@ packages: svgo@1.3.2: resolution: {integrity: sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==} engines: {node: '>=4.0.0'} + deprecated: This SVGO version is no longer supported. Upgrade to v2.x.x. hasBin: true svgo@2.8.0: @@ -8765,8 +8887,8 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - thingies@1.21.0: - resolution: {integrity: sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==} + thingies@2.5.0: + resolution: {integrity: sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw==} engines: {node: '>=10.18'} peerDependencies: tslib: ^2 @@ -9058,6 +9180,9 @@ packages: undici-types@6.20.0: resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + undici-types@7.8.0: + resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} + unicode-canonical-property-names-ecmascript@2.0.1: resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} engines: {node: '>=4'} @@ -9238,6 +9363,7 @@ packages: w3c-hr-time@1.0.2: resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} + deprecated: Use your platform's native performance.now() and performance.timeOrigin. w3c-xmlserializer@2.0.0: resolution: {integrity: sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==} @@ -9342,12 +9468,12 @@ packages: resolution: {integrity: sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==} engines: {node: '>=10.13.0'} - webpack-sources@3.2.3: - resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + webpack-sources@3.3.3: + resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==} engines: {node: '>=10.13.0'} - webpack@5.99.9: - resolution: {integrity: sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==} + webpack@5.101.3: + resolution: {integrity: sha512-7b0dTKR3Ed//AD/6kkx/o7duS8H3f1a4w3BYpIriX4BzIhjkn4teo05cptsxvLesHFKK5KObnadmCHBwGc+51A==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -9442,6 +9568,7 @@ packages: workbox-cacheable-response@6.6.0: resolution: {integrity: sha512-JfhJUSQDwsF1Xv3EV1vWzSsCOZn4mQ38bWEBR3LdvOxSPgB65gAM6cS2CX8rkkKHRgiLrN7Wxoyu+TuH67kHrw==} + deprecated: workbox-background-sync@6.6.0 workbox-core@6.6.0: resolution: {integrity: sha512-GDtFRF7Yg3DD859PMbPAYPeJyg5gJYXuBQAC+wyrWuuXgpfoOrIQIvFRZnQ7+czTIQjIr1DhLEGFzZanAT/3bQ==} @@ -9451,6 +9578,7 @@ packages: workbox-google-analytics@6.6.0: resolution: {integrity: sha512-p4DJa6OldXWd6M9zRl0H6vB9lkrmqYFkRQ2xEiNdBFp9U0LhsGO7hsBscVEyH9H2/3eZZt8c97NB2FD9U2NJ+Q==} + deprecated: It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained workbox-navigation-preload@6.6.0: resolution: {integrity: sha512-utNEWG+uOfXdaZmvhshrh7KzhDu/1iMHyQOV6Aqup8Mm78D286ugu5k9MFD9SzBT5TcwgwSORVvInaXWbvKz9Q==} @@ -9539,6 +9667,10 @@ packages: utf-8-validate: optional: true + wsl-utils@0.1.0: + resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} + engines: {node: '>=18'} + xml-name-validator@3.0.0: resolution: {integrity: sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==} @@ -9650,6 +9782,12 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + '@babel/compat-data@7.26.8': {} '@babel/core@7.26.10': @@ -9789,6 +9927,8 @@ snapshots: '@babel/helper-validator-identifier@7.25.9': {} + '@babel/helper-validator-identifier@7.27.1': {} + '@babel/helper-validator-option@7.25.9': {} '@babel/helper-wrap-function@7.25.9': @@ -10500,6 +10640,8 @@ snapshots: dependencies: regenerator-runtime: 0.14.1 + '@babel/runtime@7.28.2': {} + '@babel/template@7.27.0': dependencies: '@babel/code-frame': 7.26.2 @@ -10682,7 +10824,7 @@ snapshots: '@commitlint/execute-rule@19.8.0': optional: true - '@commitlint/load@19.8.0(@types/node@22.13.14)(typescript@5.8.2)': + '@commitlint/load@19.8.0(@types/node@24.1.0)(typescript@5.8.2)': dependencies: '@commitlint/config-validator': 19.8.0 '@commitlint/execute-rule': 19.8.0 @@ -10690,7 +10832,7 @@ snapshots: '@commitlint/types': 19.8.0 chalk: 5.4.1 cosmiconfig: 9.0.0(typescript@5.8.2) - cosmiconfig-typescript-loader: 6.1.0(@types/node@22.13.14)(cosmiconfig@9.0.0(typescript@5.8.2))(typescript@5.8.2) + cosmiconfig-typescript-loader: 6.1.0(@types/node@24.1.0)(cosmiconfig@9.0.0(typescript@5.8.2))(typescript@5.8.2) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -10812,7 +10954,7 @@ snapshots: tslib: 2.8.1 optional: true - '@emnapi/runtime@1.4.3': + '@emnapi/runtime@1.5.0': dependencies: tslib: 2.8.1 optional: true @@ -11339,92 +11481,97 @@ snapshots: '@hutson/parse-repository-url@3.0.2': {} - '@img/sharp-darwin-arm64@0.34.2': + '@img/sharp-darwin-arm64@0.34.3': optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.1.0 + '@img/sharp-libvips-darwin-arm64': 1.2.0 optional: true - '@img/sharp-darwin-x64@0.34.2': + '@img/sharp-darwin-x64@0.34.3': optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.1.0 + '@img/sharp-libvips-darwin-x64': 1.2.0 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.0': optional: true - '@img/sharp-libvips-darwin-arm64@1.1.0': + '@img/sharp-libvips-darwin-x64@1.2.0': optional: true - '@img/sharp-libvips-darwin-x64@1.1.0': + '@img/sharp-libvips-linux-arm64@1.2.0': optional: true - '@img/sharp-libvips-linux-arm64@1.1.0': + '@img/sharp-libvips-linux-arm@1.2.0': optional: true - '@img/sharp-libvips-linux-arm@1.1.0': + '@img/sharp-libvips-linux-ppc64@1.2.0': optional: true - '@img/sharp-libvips-linux-ppc64@1.1.0': + '@img/sharp-libvips-linux-s390x@1.2.0': optional: true - '@img/sharp-libvips-linux-s390x@1.1.0': + '@img/sharp-libvips-linux-x64@1.2.0': optional: true - '@img/sharp-libvips-linux-x64@1.1.0': + '@img/sharp-libvips-linuxmusl-arm64@1.2.0': optional: true - '@img/sharp-libvips-linuxmusl-arm64@1.1.0': + '@img/sharp-libvips-linuxmusl-x64@1.2.0': optional: true - '@img/sharp-libvips-linuxmusl-x64@1.1.0': + '@img/sharp-linux-arm64@0.34.3': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.0 optional: true - '@img/sharp-linux-arm64@0.34.2': + '@img/sharp-linux-arm@0.34.3': optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.1.0 + '@img/sharp-libvips-linux-arm': 1.2.0 optional: true - '@img/sharp-linux-arm@0.34.2': + '@img/sharp-linux-ppc64@0.34.3': optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.1.0 + '@img/sharp-libvips-linux-ppc64': 1.2.0 optional: true - '@img/sharp-linux-s390x@0.34.2': + '@img/sharp-linux-s390x@0.34.3': optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.1.0 + '@img/sharp-libvips-linux-s390x': 1.2.0 optional: true - '@img/sharp-linux-x64@0.34.2': + '@img/sharp-linux-x64@0.34.3': optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.1.0 + '@img/sharp-libvips-linux-x64': 1.2.0 optional: true - '@img/sharp-linuxmusl-arm64@0.34.2': + '@img/sharp-linuxmusl-arm64@0.34.3': optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.0 optional: true - '@img/sharp-linuxmusl-x64@0.34.2': + '@img/sharp-linuxmusl-x64@0.34.3': optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + '@img/sharp-libvips-linuxmusl-x64': 1.2.0 optional: true - '@img/sharp-wasm32@0.34.2': + '@img/sharp-wasm32@0.34.3': dependencies: - '@emnapi/runtime': 1.4.3 + '@emnapi/runtime': 1.5.0 optional: true - '@img/sharp-win32-arm64@0.34.2': + '@img/sharp-win32-arm64@0.34.3': optional: true - '@img/sharp-win32-ia32@0.34.2': + '@img/sharp-win32-ia32@0.34.3': optional: true - '@img/sharp-win32-x64@0.34.2': + '@img/sharp-win32-x64@0.34.3': optional: true '@irys/arweave@0.0.2': dependencies: asn1.js: 5.4.1 async-retry: 1.3.3 - axios: 1.8.4 + axios: 1.11.0 base64-js: 1.5.1 bignumber.js: 9.1.2 transitivePeerDependencies: @@ -11691,6 +11838,11 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping@0.3.30': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping@0.3.9': dependencies: '@jridgewell/resolve-uri': 3.1.2 @@ -11700,23 +11852,42 @@ snapshots: dependencies: tslib: 2.8.1 - '@jsonjoy.com/json-pack@1.2.0(tslib@2.8.1)': + '@jsonjoy.com/buffers@1.0.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/codegen@1.0.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/json-pack@1.11.0(tslib@2.8.1)': dependencies: '@jsonjoy.com/base64': 1.1.2(tslib@2.8.1) - '@jsonjoy.com/util': 1.6.0(tslib@2.8.1) + '@jsonjoy.com/buffers': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/json-pointer': 1.0.2(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) hyperdyperid: 1.2.0 - thingies: 1.21.0(tslib@2.8.1) + thingies: 2.5.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pointer@1.0.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/util@1.6.0(tslib@2.8.1)': + '@jsonjoy.com/util@1.9.0(tslib@2.8.1)': dependencies: + '@jsonjoy.com/buffers': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) tslib: 2.8.1 '@leichtgewicht/ip-codec@2.0.5': {} '@manypkg/find-root@1.1.0': dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.28.2 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 @@ -11940,7 +12111,7 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.11.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.99.9))(webpack@5.99.9)': + '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.11.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.101.3))(webpack@5.101.3)': dependencies: ansi-html: 0.0.9 core-js-pure: 3.41.0 @@ -11950,12 +12121,12 @@ snapshots: react-refresh: 0.11.0 schema-utils: 4.3.0 source-map: 0.7.4 - webpack: 5.99.9 + webpack: 5.101.3 optionalDependencies: type-fest: 0.21.3 - webpack-dev-server: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.99.9) + webpack-dev-server: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.101.3) - '@pmmmwh/react-refresh-webpack-plugin@0.6.0(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9))(webpack@5.99.9(webpack-cli@6.0.1))': + '@pmmmwh/react-refresh-webpack-plugin@0.6.1(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3))(webpack@5.101.3(webpack-cli@6.0.1))': dependencies: anser: 2.3.2 core-js-pure: 3.41.0 @@ -11964,10 +12135,10 @@ snapshots: react-refresh: 0.17.0 schema-utils: 4.3.0 source-map: 0.7.4 - webpack: 5.99.9(webpack-cli@6.0.1) + webpack: 5.101.3(webpack-cli@6.0.1) optionalDependencies: type-fest: 0.21.3 - webpack-dev-server: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) + webpack-dev-server: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3) '@randlabs/communication-bridge@1.0.1': optional: true @@ -12318,7 +12489,7 @@ snapshots: '@types/eslint-scope@3.7.7': dependencies: '@types/eslint': 9.6.1 - '@types/estree': 1.0.7 + '@types/estree': 1.0.8 '@types/eslint@8.56.12': dependencies: @@ -12327,7 +12498,7 @@ snapshots: '@types/eslint@9.6.1': dependencies: - '@types/estree': 1.0.7 + '@types/estree': 1.0.8 '@types/json-schema': 7.0.15 '@types/estree@0.0.39': {} @@ -12336,6 +12507,8 @@ snapshots: '@types/estree@1.0.7': {} + '@types/estree@1.0.8': {} + '@types/express-serve-static-core@4.19.6': dependencies: '@types/node': 20.17.28 @@ -12389,7 +12562,7 @@ snapshots: dependencies: '@types/node': 20.17.28 - '@types/lodash@4.17.16': {} + '@types/lodash@4.17.20': {} '@types/mime@1.3.5': {} @@ -12415,6 +12588,11 @@ snapshots: dependencies: undici-types: 6.20.0 + '@types/node@24.1.0': + dependencies: + undici-types: 7.8.0 + optional: true + '@types/normalize-package-data@2.4.4': {} '@types/parse-json@4.0.2': {} @@ -12798,7 +12976,7 @@ snapshots: dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 - ast-v8-to-istanbul: 0.3.3 + ast-v8-to-istanbul: 0.3.5 debug: 4.4.1 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 @@ -12828,13 +13006,13 @@ snapshots: optionalDependencies: vite: 6.2.3(@types/node@20.17.28)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) - '@vitest/mocker@3.0.9(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))': + '@vitest/mocker@3.0.9(vite@6.2.3(@types/node@24.1.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))': dependencies: '@vitest/spy': 3.0.9 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) + vite: 6.2.3(@types/node@24.1.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) '@vitest/pretty-format@3.0.9': dependencies: @@ -12937,22 +13115,22 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@xtuc/long': 4.2.2 - '@webpack-cli/configtest@3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9))(webpack@5.99.9(webpack-cli@6.0.1))': + '@webpack-cli/configtest@3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3))(webpack@5.101.3(webpack-cli@6.0.1))': dependencies: - webpack: 5.99.9(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) + webpack: 5.101.3(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3) - '@webpack-cli/info@3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9))(webpack@5.99.9(webpack-cli@6.0.1))': + '@webpack-cli/info@3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3))(webpack@5.101.3(webpack-cli@6.0.1))': dependencies: - webpack: 5.99.9(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) + webpack: 5.101.3(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3) - '@webpack-cli/serve@3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9))(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9))(webpack@5.99.9(webpack-cli@6.0.1))': + '@webpack-cli/serve@3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3))(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3))(webpack@5.101.3(webpack-cli@6.0.1))': dependencies: - webpack: 5.99.9(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) + webpack: 5.101.3(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3) optionalDependencies: - webpack-dev-server: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) + webpack-dev-server: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3) '@xtuc/ieee754@1.2.0': {} @@ -12975,6 +13153,10 @@ snapshots: acorn: 7.4.1 acorn-walk: 7.2.0 + acorn-import-phases@1.0.4(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn-jsx@5.3.2(acorn@8.14.1): dependencies: acorn: 8.14.1 @@ -12989,6 +13171,8 @@ snapshots: acorn@8.14.1: {} + acorn@8.15.0: {} + add-stream@1.0.0: {} address@1.2.2: {} @@ -13002,7 +13186,7 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.4.1 + debug: 4.4.0 transitivePeerDependencies: - supports-color @@ -13236,7 +13420,7 @@ snapshots: arconnect: 0.4.2 asn1.js: 5.4.1 base64-js: 1.5.1 - bignumber.js: 9.1.2 + bignumber.js: 9.3.1 optional: true asap@2.0.6: {} @@ -13258,9 +13442,9 @@ snapshots: ast-types-flow@0.0.8: {} - ast-v8-to-istanbul@0.3.3: + ast-v8-to-istanbul@0.3.5: dependencies: - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/trace-mapping': 0.3.30 estree-walker: 3.0.3 js-tokens: 9.0.1 @@ -13292,11 +13476,19 @@ snapshots: axe-core@4.10.3: {} - axios-retry@3.9.1: + axios-retry@4.5.0(axios@1.11.0): dependencies: - '@babel/runtime': 7.27.0 + axios: 1.11.0 is-retry-allowed: 2.2.0 + axios@1.11.0: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.4 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + axios@1.8.4: dependencies: follow-redirects: 1.15.9 @@ -13321,14 +13513,14 @@ snapshots: transitivePeerDependencies: - supports-color - babel-loader@8.4.1(@babel/core@7.26.10)(webpack@5.99.9): + babel-loader@8.4.1(@babel/core@7.26.10)(webpack@5.101.3): dependencies: '@babel/core': 7.26.10 find-cache-dir: 3.3.2 loader-utils: 2.0.4 make-dir: 3.1.0 schema-utils: 2.7.1 - webpack: 5.99.9 + webpack: 5.101.3 babel-plugin-istanbul@6.1.1: dependencies: @@ -13466,6 +13658,9 @@ snapshots: bignumber.js@9.1.2: {} + bignumber.js@9.3.1: + optional: true + binary-extensions@2.3.0: {} bindings@1.5.0: @@ -13637,25 +13832,26 @@ snapshots: esbuild: 0.19.12 load-tsconfig: 0.2.5 - bundlemon-utils@1.2.1: + bundlemon-utils@2.0.1: dependencies: bytes: 3.1.2 - bundlemon@2.1.0: + bundlemon@3.1.0(typescript@5.8.2): dependencies: - axios: 1.8.4 - axios-retry: 3.9.1 + axios: 1.11.0 + axios-retry: 4.5.0(axios@1.11.0) brotli-size: 4.0.0 - bundlemon-utils: 1.2.1 + bundlemon-utils: 2.0.1 bytes: 3.1.2 chalk: 4.1.2 - commander: 9.5.0 - cosmiconfig: 7.1.0 + commander: 11.1.0 + cosmiconfig: 8.3.6(typescript@5.8.2) gzip-size: 6.0.0 micromatch: 4.0.8 yup: 0.32.11 transitivePeerDependencies: - debug + - typescript busboy@1.6.0: dependencies: @@ -13671,7 +13867,7 @@ snapshots: dependencies: clone-response: 1.0.3 get-stream: 5.2.0 - http-cache-semantics: 4.1.1 + http-cache-semantics: 4.2.0 keyv: 4.5.4 lowercase-keys: 2.0.0 normalize-url: 6.1.0 @@ -13869,6 +14065,8 @@ snapshots: table-layout: 1.0.2 typical: 5.2.0 + commander@11.1.0: {} + commander@12.1.0: {} commander@13.1.0: {} @@ -13881,12 +14079,10 @@ snapshots: commander@8.3.0: {} - commander@9.5.0: {} - - commitizen@4.3.1(@types/node@22.13.14)(typescript@5.8.2): + commitizen@4.3.1(@types/node@24.1.0)(typescript@5.8.2): dependencies: cachedir: 2.3.0 - cz-conventional-changelog: 3.3.0(@types/node@22.13.14)(typescript@5.8.2) + cz-conventional-changelog: 3.3.0(@types/node@24.1.0)(typescript@5.8.2) dedent: 0.7.0 detect-indent: 6.1.0 find-node-modules: 2.1.3 @@ -14073,14 +14269,14 @@ snapshots: dependencies: toggle-selection: 1.0.6 - copy-webpack-plugin@13.0.0(webpack@5.99.9(webpack-cli@6.0.1)): + copy-webpack-plugin@13.0.1(webpack@5.101.3(webpack-cli@6.0.1)): dependencies: glob-parent: 6.0.2 normalize-path: 3.0.0 schema-utils: 4.3.0 serialize-javascript: 6.0.2 tinyglobby: 0.2.12 - webpack: 5.99.9(webpack-cli@6.0.1) + webpack: 5.101.3(webpack-cli@6.0.1) core-js-compat@3.41.0: dependencies: @@ -14092,9 +14288,9 @@ snapshots: core-util-is@1.0.3: {} - cosmiconfig-typescript-loader@6.1.0(@types/node@22.13.14)(cosmiconfig@9.0.0(typescript@5.8.2))(typescript@5.8.2): + cosmiconfig-typescript-loader@6.1.0(@types/node@24.1.0)(cosmiconfig@9.0.0(typescript@5.8.2))(typescript@5.8.2): dependencies: - '@types/node': 22.13.14 + '@types/node': 24.1.0 cosmiconfig: 9.0.0(typescript@5.8.2) jiti: 2.4.2 typescript: 5.8.2 @@ -14116,6 +14312,15 @@ snapshots: path-type: 4.0.0 yaml: 1.10.2 + cosmiconfig@8.3.6(typescript@5.8.2): + dependencies: + import-fresh: 3.3.1 + js-yaml: 4.1.0 + parse-json: 5.2.0 + path-type: 4.0.0 + optionalDependencies: + typescript: 5.8.2 + cosmiconfig@9.0.0(typescript@5.8.2): dependencies: env-paths: 2.2.1 @@ -14201,7 +14406,7 @@ snapshots: postcss: 8.5.3 postcss-selector-parser: 6.1.2 - css-loader@6.11.0(webpack@5.99.9): + css-loader@6.11.0(webpack@5.101.3): dependencies: icss-utils: 5.1.0(postcss@8.5.3) postcss: 8.5.3 @@ -14212,9 +14417,9 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.7.1 optionalDependencies: - webpack: 5.99.9 + webpack: 5.101.3 - css-minimizer-webpack-plugin@3.4.1(webpack@5.99.9): + css-minimizer-webpack-plugin@3.4.1(webpack@5.101.3): dependencies: cssnano: 5.1.15(postcss@8.5.3) jest-worker: 27.5.1 @@ -14222,7 +14427,7 @@ snapshots: schema-utils: 4.3.0 serialize-javascript: 6.0.2 source-map: 0.6.1 - webpack: 5.99.9 + webpack: 5.101.3 css-prefers-color-scheme@6.0.3(postcss@8.5.3): dependencies: @@ -14334,16 +14539,16 @@ snapshots: csv-stringify: 5.6.5 stream-transform: 2.1.3 - cz-conventional-changelog@3.3.0(@types/node@22.13.14)(typescript@5.8.2): + cz-conventional-changelog@3.3.0(@types/node@24.1.0)(typescript@5.8.2): dependencies: chalk: 2.4.2 - commitizen: 4.3.1(@types/node@22.13.14)(typescript@5.8.2) + commitizen: 4.3.1(@types/node@24.1.0)(typescript@5.8.2) conventional-commit-types: 3.0.0 lodash.map: 4.6.0 longest: 2.0.1 word-wrap: 1.2.5 optionalDependencies: - '@commitlint/load': 19.8.0(@types/node@22.13.14)(typescript@5.8.2) + '@commitlint/load': 19.8.0(@types/node@24.1.0)(typescript@5.8.2) transitivePeerDependencies: - '@types/node' - typescript @@ -14591,7 +14796,7 @@ snapshots: dotenv@16.4.7: {} - dotenv@16.5.0: {} + dotenv@16.6.1: {} dotgitignore@2.1.0: dependencies: @@ -14644,7 +14849,7 @@ snapshots: encodeurl@2.0.0: {} - end-of-stream@1.4.4: + end-of-stream@1.4.5: dependencies: once: 1.4.0 @@ -14793,14 +14998,14 @@ snapshots: dependencies: es6-promise: 4.2.8 - esbuild-loader@2.21.0(webpack@5.99.9(webpack-cli@6.0.1)): + esbuild-loader@2.21.0(webpack@5.101.3(webpack-cli@6.0.1)): dependencies: esbuild: 0.16.17 joycon: 3.1.1 json5: 2.2.3 loader-utils: 2.0.4 tapable: 2.2.1 - webpack: 5.99.9(webpack-cli@6.0.1) + webpack: 5.101.3(webpack-cli@6.0.1) webpack-sources: 1.4.3 esbuild@0.16.17: @@ -15296,7 +15501,7 @@ snapshots: - supports-color - typescript - eslint-plugin-unused-imports@4.1.4(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1): + eslint-plugin-unused-imports@4.2.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1): dependencies: eslint: 8.57.1 optionalDependencies: @@ -15316,7 +15521,7 @@ snapshots: eslint-visitor-keys@3.4.3: {} - eslint-webpack-plugin@3.2.0(eslint@8.57.1)(webpack@5.99.9): + eslint-webpack-plugin@3.2.0(eslint@8.57.1)(webpack@5.101.3): dependencies: '@types/eslint': 8.56.12 eslint: 8.57.1 @@ -15324,7 +15529,7 @@ snapshots: micromatch: 4.0.8 normalize-path: 3.0.0 schema-utils: 4.3.0 - webpack: 5.99.9 + webpack: 5.101.3 eslint@8.57.0: dependencies: @@ -15628,17 +15833,17 @@ snapshots: dependencies: flat-cache: 3.2.0 - file-loader@6.2.0(webpack@5.99.9(webpack-cli@6.0.1)): + file-loader@6.2.0(webpack@5.101.3(webpack-cli@6.0.1)): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.99.9(webpack-cli@6.0.1) + webpack: 5.101.3(webpack-cli@6.0.1) - file-loader@6.2.0(webpack@5.99.9): + file-loader@6.2.0(webpack@5.101.3): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.99.9 + webpack: 5.101.3 file-uri-to-path@1.0.0: {} @@ -15724,6 +15929,8 @@ snapshots: flatted@3.3.3: {} + follow-redirects@1.15.11: {} + follow-redirects@1.15.9: {} for-each@0.3.5: @@ -15735,7 +15942,7 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.1)(typescript@5.8.2)(webpack@5.99.9): + fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.1)(typescript@5.8.2)(webpack@5.101.3): dependencies: '@babel/code-frame': 7.26.2 '@types/json-schema': 7.0.15 @@ -15751,15 +15958,16 @@ snapshots: semver: 7.7.1 tapable: 1.1.3 typescript: 5.8.2 - webpack: 5.99.9 + webpack: 5.101.3 optionalDependencies: eslint: 8.57.1 - form-data@3.0.3: + form-data@3.0.4: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 es-set-tostringtag: 2.1.0 + hasown: 2.0.2 mime-types: 2.1.35 form-data@4.0.2: @@ -15769,6 +15977,14 @@ snapshots: es-set-tostringtag: 2.1.0 mime-types: 2.1.35 + form-data@4.0.4: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + forwarded@0.2.0: {} fraction.js@4.3.7: {} @@ -15863,7 +16079,7 @@ snapshots: get-stream@5.2.0: dependencies: - pump: 3.0.2 + pump: 3.0.3 get-stream@6.0.1: {} @@ -15919,6 +16135,10 @@ snapshots: dependencies: is-glob: 4.0.3 + glob-to-regex.js@1.0.1(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + glob-to-regexp@0.4.1: {} glob@10.4.5: @@ -16126,7 +16346,7 @@ snapshots: relateurl: 0.2.7 terser: 5.39.0 - html-webpack-plugin@5.6.3(webpack@5.99.9(webpack-cli@6.0.1)): + html-webpack-plugin@5.6.3(webpack@5.101.3(webpack-cli@6.0.1)): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -16134,9 +16354,9 @@ snapshots: pretty-error: 4.0.0 tapable: 2.2.1 optionalDependencies: - webpack: 5.99.9(webpack-cli@6.0.1) + webpack: 5.101.3(webpack-cli@6.0.1) - html-webpack-plugin@5.6.3(webpack@5.99.9): + html-webpack-plugin@5.6.3(webpack@5.101.3): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -16144,7 +16364,7 @@ snapshots: pretty-error: 4.0.0 tapable: 2.2.1 optionalDependencies: - webpack: 5.99.9 + webpack: 5.101.3 htmlparser2@6.1.0: dependencies: @@ -16153,7 +16373,7 @@ snapshots: domutils: 2.8.0 entities: 2.2.0 - http-cache-semantics@4.1.1: {} + http-cache-semantics@4.2.0: {} http-deceiver@1.2.7: {} @@ -16186,7 +16406,7 @@ snapshots: dependencies: '@tootallnate/once': 1.1.2 agent-base: 6.0.2 - debug: 4.4.1 + debug: 4.4.0 transitivePeerDependencies: - supports-color @@ -16217,7 +16437,7 @@ snapshots: http-proxy@1.18.1: dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.9 + follow-redirects: 1.15.11 requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -16230,7 +16450,7 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.4.1 + debug: 4.4.0 transitivePeerDependencies: - supports-color @@ -16572,7 +16792,7 @@ snapshots: istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.4.1 + debug: 4.4.0 istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -16830,7 +17050,7 @@ snapshots: jest-message-util@28.1.3: dependencies: - '@babel/code-frame': 7.26.2 + '@babel/code-frame': 7.27.1 '@jest/types': 28.1.3 '@types/stack-utils': 2.0.3 chalk: 4.1.2 @@ -17090,7 +17310,7 @@ snapshots: decimal.js: 10.5.0 domexception: 2.0.1 escodegen: 2.1.0 - form-data: 3.0.3 + form-data: 3.0.4 html-encoding-sniffer: 2.0.1 http-proxy-agent: 4.0.1 https-proxy-agent: 5.0.1 @@ -17375,10 +17595,12 @@ snapshots: dependencies: fs-monkey: 1.0.6 - memfs@4.17.2: + memfs@4.38.2: dependencies: - '@jsonjoy.com/json-pack': 1.2.0(tslib@2.8.1) - '@jsonjoy.com/util': 1.6.0(tslib@2.8.1) + '@jsonjoy.com/json-pack': 1.11.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + glob-to-regex.js: 1.0.1(tslib@2.8.1) + thingies: 2.5.0(tslib@2.8.1) tree-dump: 1.0.3(tslib@2.8.1) tslib: 2.8.1 @@ -17436,11 +17658,11 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.9.2(webpack@5.99.9): + mini-css-extract-plugin@2.9.2(webpack@5.101.3): dependencies: schema-utils: 4.3.0 tapable: 2.2.1 - webpack: 5.99.9 + webpack: 5.101.3 minimalistic-assert@1.0.1: {} @@ -17573,7 +17795,7 @@ snapshots: '@next/swc-linux-x64-musl': 15.3.4 '@next/swc-win32-arm64-msvc': 15.3.4 '@next/swc-win32-x64-msvc': 15.3.4 - sharp: 0.34.2 + sharp: 0.34.3 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -17718,12 +17940,12 @@ snapshots: dependencies: mimic-fn: 2.1.0 - open@10.1.2: + open@10.2.0: dependencies: default-browser: 5.2.1 define-lazy-prop: 3.0.0 is-inside-container: 1.0.0 - is-wsl: 3.1.0 + wsl-utils: 0.1.0 open@8.4.2: dependencies: @@ -17853,7 +18075,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.26.2 + '@babel/code-frame': 7.27.1 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -18099,13 +18321,13 @@ snapshots: postcss: 8.5.3 ts-node: 10.9.2(@types/node@20.17.28)(typescript@5.8.2) - postcss-loader@6.2.1(postcss@8.5.3)(webpack@5.99.9): + postcss-loader@6.2.1(postcss@8.5.3)(webpack@5.101.3): dependencies: cosmiconfig: 7.1.0 klona: 2.0.6 postcss: 8.5.3 semver: 7.7.1 - webpack: 5.99.9 + webpack: 5.101.3 postcss-logical@5.0.4(postcss@8.5.3): dependencies: @@ -18455,9 +18677,9 @@ snapshots: randombytes: 2.1.0 safe-buffer: 5.2.1 - pump@3.0.2: + pump@3.0.3: dependencies: - end-of-stream: 1.4.4 + end-of-stream: 1.4.5 once: 1.4.0 punycode@2.3.1: {} @@ -18521,7 +18743,7 @@ snapshots: prop-types: 15.8.1 react: 18.3.1 - react-dev-utils@12.0.1(eslint@8.57.1)(typescript@5.8.2)(webpack@5.99.9): + react-dev-utils@12.0.1(eslint@8.57.1)(typescript@5.8.2)(webpack@5.101.3): dependencies: '@babel/code-frame': 7.26.2 address: 1.2.2 @@ -18532,7 +18754,7 @@ snapshots: escape-string-regexp: 4.0.0 filesize: 8.0.7 find-up: 5.0.0 - fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.1)(typescript@5.8.2)(webpack@5.99.9) + fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.1)(typescript@5.8.2)(webpack@5.101.3) global-modules: 2.0.0 globby: 11.1.0 gzip-size: 6.0.0 @@ -18547,7 +18769,7 @@ snapshots: shell-quote: 1.8.2 strip-ansi: 6.0.1 text-table: 0.2.0 - webpack: 5.99.9 + webpack: 5.101.3 optionalDependencies: typescript: 5.8.2 transitivePeerDependencies: @@ -18576,53 +18798,53 @@ snapshots: react-scripts@5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(@types/babel__core@7.20.5)(bufferutil@4.0.9)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(type-fest@0.21.3)(typescript@5.8.2)(utf-8-validate@5.0.10): dependencies: '@babel/core': 7.26.10 - '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(react-refresh@0.11.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.99.9))(webpack@5.99.9) + '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(react-refresh@0.11.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.101.3))(webpack@5.101.3) '@svgr/webpack': 5.5.0 babel-jest: 27.5.1(@babel/core@7.26.10) - babel-loader: 8.4.1(@babel/core@7.26.10)(webpack@5.99.9) + babel-loader: 8.4.1(@babel/core@7.26.10)(webpack@5.101.3) babel-plugin-named-asset-import: 0.3.8(@babel/core@7.26.10) babel-preset-react-app: 10.1.0 bfj: 7.1.0 browserslist: 4.24.4 camelcase: 6.3.0 case-sensitive-paths-webpack-plugin: 2.4.0 - css-loader: 6.11.0(webpack@5.99.9) - css-minimizer-webpack-plugin: 3.4.1(webpack@5.99.9) + css-loader: 6.11.0(webpack@5.101.3) + css-minimizer-webpack-plugin: 3.4.1(webpack@5.101.3) dotenv: 10.0.0 dotenv-expand: 5.1.0 eslint: 8.57.1 eslint-config-react-app: 7.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10))(typescript@5.8.2) - eslint-webpack-plugin: 3.2.0(eslint@8.57.1)(webpack@5.99.9) - file-loader: 6.2.0(webpack@5.99.9) + eslint-webpack-plugin: 3.2.0(eslint@8.57.1)(webpack@5.101.3) + file-loader: 6.2.0(webpack@5.101.3) fs-extra: 10.1.0 - html-webpack-plugin: 5.6.3(webpack@5.99.9) + html-webpack-plugin: 5.6.3(webpack@5.101.3) identity-obj-proxy: 3.0.0 jest: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10) jest-resolve: 27.5.1 jest-watch-typeahead: 1.1.0(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10)) - mini-css-extract-plugin: 2.9.2(webpack@5.99.9) + mini-css-extract-plugin: 2.9.2(webpack@5.101.3) postcss: 8.5.3 postcss-flexbugs-fixes: 5.0.2(postcss@8.5.3) - postcss-loader: 6.2.1(postcss@8.5.3)(webpack@5.99.9) + postcss-loader: 6.2.1(postcss@8.5.3)(webpack@5.101.3) postcss-normalize: 10.0.1(browserslist@4.24.4)(postcss@8.5.3) postcss-preset-env: 7.8.3(postcss@8.5.3) prompts: 2.4.2 react: 18.3.1 react-app-polyfill: 3.0.0 - react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.8.2)(webpack@5.99.9) + react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.8.2)(webpack@5.101.3) react-refresh: 0.11.0 resolve: 1.22.10 resolve-url-loader: 4.0.0 - sass-loader: 12.6.0(webpack@5.99.9) + sass-loader: 12.6.0(webpack@5.101.3) semver: 7.7.1 - source-map-loader: 3.0.2(webpack@5.99.9) - style-loader: 3.3.4(webpack@5.99.9) + source-map-loader: 3.0.2(webpack@5.101.3) + style-loader: 3.3.4(webpack@5.101.3) tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2)) - terser-webpack-plugin: 5.3.14(webpack@5.99.9) - webpack: 5.99.9 - webpack-dev-server: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.99.9) - webpack-manifest-plugin: 4.1.1(webpack@5.99.9) - workbox-webpack-plugin: 6.6.0(@types/babel__core@7.20.5)(webpack@5.99.9) + terser-webpack-plugin: 5.3.14(webpack@5.101.3) + webpack: 5.101.3 + webpack-dev-server: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.101.3) + webpack-manifest-plugin: 4.1.1(webpack@5.101.3) + workbox-webpack-plugin: 6.6.0(@types/babel__core@7.20.5)(webpack@5.101.3) optionalDependencies: fsevents: 2.3.3 typescript: 5.8.2 @@ -18762,7 +18984,7 @@ snapshots: regenerator-transform@0.15.2: dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.28.2 regex-parser@2.3.1: {} @@ -18961,11 +19183,11 @@ snapshots: sanitize.css@13.0.0: {} - sass-loader@12.6.0(webpack@5.99.9): + sass-loader@12.6.0(webpack@5.101.3): dependencies: klona: 2.0.6 neo-async: 2.6.2 - webpack: 5.99.9 + webpack: 5.101.3 sax@1.2.4: {} @@ -19115,33 +19337,34 @@ snapshots: dependencies: kind-of: 6.0.3 - sharp@0.34.2: + sharp@0.34.3: dependencies: color: 4.2.3 detect-libc: 2.0.4 semver: 7.7.2 optionalDependencies: - '@img/sharp-darwin-arm64': 0.34.2 - '@img/sharp-darwin-x64': 0.34.2 - '@img/sharp-libvips-darwin-arm64': 1.1.0 - '@img/sharp-libvips-darwin-x64': 1.1.0 - '@img/sharp-libvips-linux-arm': 1.1.0 - '@img/sharp-libvips-linux-arm64': 1.1.0 - '@img/sharp-libvips-linux-ppc64': 1.1.0 - '@img/sharp-libvips-linux-s390x': 1.1.0 - '@img/sharp-libvips-linux-x64': 1.1.0 - '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 - '@img/sharp-libvips-linuxmusl-x64': 1.1.0 - '@img/sharp-linux-arm': 0.34.2 - '@img/sharp-linux-arm64': 0.34.2 - '@img/sharp-linux-s390x': 0.34.2 - '@img/sharp-linux-x64': 0.34.2 - '@img/sharp-linuxmusl-arm64': 0.34.2 - '@img/sharp-linuxmusl-x64': 0.34.2 - '@img/sharp-wasm32': 0.34.2 - '@img/sharp-win32-arm64': 0.34.2 - '@img/sharp-win32-ia32': 0.34.2 - '@img/sharp-win32-x64': 0.34.2 + '@img/sharp-darwin-arm64': 0.34.3 + '@img/sharp-darwin-x64': 0.34.3 + '@img/sharp-libvips-darwin-arm64': 1.2.0 + '@img/sharp-libvips-darwin-x64': 1.2.0 + '@img/sharp-libvips-linux-arm': 1.2.0 + '@img/sharp-libvips-linux-arm64': 1.2.0 + '@img/sharp-libvips-linux-ppc64': 1.2.0 + '@img/sharp-libvips-linux-s390x': 1.2.0 + '@img/sharp-libvips-linux-x64': 1.2.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.0 + '@img/sharp-libvips-linuxmusl-x64': 1.2.0 + '@img/sharp-linux-arm': 0.34.3 + '@img/sharp-linux-arm64': 0.34.3 + '@img/sharp-linux-ppc64': 0.34.3 + '@img/sharp-linux-s390x': 0.34.3 + '@img/sharp-linux-x64': 0.34.3 + '@img/sharp-linuxmusl-arm64': 0.34.3 + '@img/sharp-linuxmusl-x64': 0.34.3 + '@img/sharp-wasm32': 0.34.3 + '@img/sharp-win32-arm64': 0.34.3 + '@img/sharp-win32-ia32': 0.34.3 + '@img/sharp-win32-x64': 0.34.3 optional: true shebang-command@1.2.0: @@ -19239,12 +19462,12 @@ snapshots: source-map-js@1.2.1: {} - source-map-loader@3.0.2(webpack@5.99.9): + source-map-loader@3.0.2(webpack@5.101.3): dependencies: abab: 2.0.6 iconv-lite: 0.6.3 source-map-js: 1.2.1 - webpack: 5.99.9 + webpack: 5.101.3 source-map-support@0.5.21: dependencies: @@ -19282,7 +19505,7 @@ snapshots: spdy-transport@3.0.0: dependencies: - debug: 4.4.1 + debug: 4.4.0 detect-node: 2.1.0 hpack.js: 2.1.6 obuf: 1.1.2 @@ -19293,7 +19516,7 @@ snapshots: spdy@4.0.2: dependencies: - debug: 4.4.1 + debug: 4.4.0 handle-thing: 2.0.1 http-deceiver: 1.2.7 select-hose: 2.0.0 @@ -19493,9 +19716,9 @@ snapshots: dependencies: escape-string-regexp: 1.0.5 - style-loader@3.3.4(webpack@5.99.9): + style-loader@3.3.4(webpack@5.101.3): dependencies: - webpack: 5.99.9 + webpack: 5.101.3 styled-jsx@5.1.6(react@18.3.1): dependencies: @@ -19623,23 +19846,23 @@ snapshots: ansi-escapes: 4.3.2 supports-hyperlinks: 2.3.0 - terser-webpack-plugin@5.3.14(webpack@5.99.9(webpack-cli@6.0.1)): + terser-webpack-plugin@5.3.14(webpack@5.101.3(webpack-cli@6.0.1)): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 4.3.0 serialize-javascript: 6.0.2 terser: 5.39.0 - webpack: 5.99.9(webpack-cli@6.0.1) + webpack: 5.101.3(webpack-cli@6.0.1) - terser-webpack-plugin@5.3.14(webpack@5.99.9): + terser-webpack-plugin@5.3.14(webpack@5.101.3): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 4.3.0 serialize-javascript: 6.0.2 terser: 5.39.0 - webpack: 5.99.9 + webpack: 5.101.3 terser@5.39.0: dependencies: @@ -19674,7 +19897,7 @@ snapshots: dependencies: any-promise: 1.3.0 - thingies@1.21.0(tslib@2.8.1): + thingies@2.5.0(tslib@2.8.1): dependencies: tslib: 2.8.1 @@ -19954,6 +20177,9 @@ snapshots: undici-types@6.20.0: {} + undici-types@7.8.0: + optional: true + unicode-canonical-property-names-ecmascript@2.0.1: {} unicode-match-property-ecmascript@2.0.0: @@ -20070,13 +20296,13 @@ snapshots: - tsx - yaml - vite-node@3.0.9(@types/node@22.13.14)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0): + vite-node@3.0.9(@types/node@24.1.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0): dependencies: cac: 6.7.14 debug: 4.4.0 es-module-lexer: 1.6.0 pathe: 2.0.3 - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) + vite: 6.2.3(@types/node@24.1.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) transitivePeerDependencies: - '@types/node' - jiti @@ -20103,13 +20329,13 @@ snapshots: terser: 5.39.0 yaml: 2.7.0 - vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0): + vite@6.2.3(@types/node@24.1.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0): dependencies: esbuild: 0.25.1 postcss: 8.5.3 rollup: 4.37.0 optionalDependencies: - '@types/node': 22.13.14 + '@types/node': 24.1.0 fsevents: 2.3.3 jiti: 2.4.2 terser: 5.39.0 @@ -20154,10 +20380,10 @@ snapshots: - tsx - yaml - vitest@3.0.9(@types/node@22.13.14)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0): + vitest@3.0.9(@types/node@24.1.0)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0): dependencies: '@vitest/expect': 3.0.9 - '@vitest/mocker': 3.0.9(vite@6.2.3(@types/node@22.13.14)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0)) + '@vitest/mocker': 3.0.9(vite@6.2.3(@types/node@24.1.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0)) '@vitest/pretty-format': 3.0.9 '@vitest/runner': 3.0.9 '@vitest/snapshot': 3.0.9 @@ -20173,11 +20399,11 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.0.2 tinyrainbow: 2.0.0 - vite: 6.2.3(@types/node@22.13.14)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) - vite-node: 3.0.9(@types/node@22.13.14)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) + vite: 6.2.3(@types/node@24.1.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) + vite-node: 3.0.9(@types/node@24.1.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.13.14 + '@types/node': 24.1.0 jsdom: 16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - jiti @@ -20234,12 +20460,12 @@ snapshots: webidl-conversions@6.1.0: {} - webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9): + webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3): dependencies: '@discoveryjs/json-ext': 0.6.3 - '@webpack-cli/configtest': 3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9))(webpack@5.99.9(webpack-cli@6.0.1)) - '@webpack-cli/info': 3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9))(webpack@5.99.9(webpack-cli@6.0.1)) - '@webpack-cli/serve': 3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9))(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9))(webpack@5.99.9(webpack-cli@6.0.1)) + '@webpack-cli/configtest': 3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3))(webpack@5.101.3(webpack-cli@6.0.1)) + '@webpack-cli/info': 3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3))(webpack@5.101.3(webpack-cli@6.0.1)) + '@webpack-cli/serve': 3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3))(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3))(webpack@5.101.3(webpack-cli@6.0.1)) colorette: 2.0.20 commander: 12.1.0 cross-spawn: 7.0.6 @@ -20248,32 +20474,32 @@ snapshots: import-local: 3.2.0 interpret: 3.1.1 rechoir: 0.8.0 - webpack: 5.99.9(webpack-cli@6.0.1) + webpack: 5.101.3(webpack-cli@6.0.1) webpack-merge: 6.0.1 optionalDependencies: - webpack-dev-server: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) + webpack-dev-server: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3) - webpack-dev-middleware@5.3.4(webpack@5.99.9): + webpack-dev-middleware@5.3.4(webpack@5.101.3): dependencies: colorette: 2.0.20 memfs: 3.5.3 mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.3.0 - webpack: 5.99.9 + webpack: 5.101.3 - webpack-dev-middleware@7.4.2(webpack@5.99.9(webpack-cli@6.0.1)): + webpack-dev-middleware@7.4.2(webpack@5.101.3(webpack-cli@6.0.1)): dependencies: colorette: 2.0.20 - memfs: 4.17.2 + memfs: 4.38.2 mime-types: 2.1.35 on-finished: 2.4.1 range-parser: 1.2.1 schema-utils: 4.3.0 optionalDependencies: - webpack: 5.99.9(webpack-cli@6.0.1) + webpack: 5.101.3(webpack-cli@6.0.1) - webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.99.9): + webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.101.3): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -20303,17 +20529,17 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 5.3.4(webpack@5.99.9) + webpack-dev-middleware: 5.3.4(webpack@5.101.3) ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - webpack: 5.99.9 + webpack: 5.101.3 transitivePeerDependencies: - bufferutil - debug - supports-color - utf-8-validate - webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9): + webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -20334,28 +20560,28 @@ snapshots: http-proxy-middleware: 2.0.9(@types/express@4.17.21) ipaddr.js: 2.2.0 launch-editor: 2.10.0 - open: 10.1.2 + open: 10.2.0 p-retry: 6.2.1 schema-utils: 4.3.0 selfsigned: 2.4.1 serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.2(webpack@5.99.9(webpack-cli@6.0.1)) + webpack-dev-middleware: 7.4.2(webpack@5.101.3(webpack-cli@6.0.1)) ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - webpack: 5.99.9(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) + webpack: 5.101.3(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3) transitivePeerDependencies: - bufferutil - debug - supports-color - utf-8-validate - webpack-manifest-plugin@4.1.1(webpack@5.99.9): + webpack-manifest-plugin@4.1.1(webpack@5.101.3): dependencies: tapable: 2.2.1 - webpack: 5.99.9 + webpack: 5.101.3 webpack-sources: 2.3.1 webpack-merge@6.0.1: @@ -20374,17 +20600,18 @@ snapshots: source-list-map: 2.0.1 source-map: 0.6.1 - webpack-sources@3.2.3: {} + webpack-sources@3.3.3: {} - webpack@5.99.9: + webpack@5.101.3: dependencies: '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.7 + '@types/estree': 1.0.8 '@types/json-schema': 7.0.15 '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.14.1 + acorn: 8.15.0 + acorn-import-phases: 1.0.4(acorn@8.15.0) browserslist: 4.24.4 chrome-trace-event: 1.0.4 enhanced-resolve: 5.18.1 @@ -20399,23 +20626,24 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.2 tapable: 2.2.1 - terser-webpack-plugin: 5.3.14(webpack@5.99.9) + terser-webpack-plugin: 5.3.14(webpack@5.101.3) watchpack: 2.4.2 - webpack-sources: 3.2.3 + webpack-sources: 3.3.3 transitivePeerDependencies: - '@swc/core' - esbuild - uglify-js - webpack@5.99.9(webpack-cli@6.0.1): + webpack@5.101.3(webpack-cli@6.0.1): dependencies: '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.7 + '@types/estree': 1.0.8 '@types/json-schema': 7.0.15 '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.14.1 + acorn: 8.15.0 + acorn-import-phases: 1.0.4(acorn@8.15.0) browserslist: 4.24.4 chrome-trace-event: 1.0.4 enhanced-resolve: 5.18.1 @@ -20430,11 +20658,11 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.2 tapable: 2.2.1 - terser-webpack-plugin: 5.3.14(webpack@5.99.9(webpack-cli@6.0.1)) + terser-webpack-plugin: 5.3.14(webpack@5.101.3(webpack-cli@6.0.1)) watchpack: 2.4.2 - webpack-sources: 3.2.3 + webpack-sources: 3.3.3 optionalDependencies: - webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3) transitivePeerDependencies: - '@swc/core' - esbuild @@ -20652,12 +20880,12 @@ snapshots: workbox-sw@6.6.0: {} - workbox-webpack-plugin@6.6.0(@types/babel__core@7.20.5)(webpack@5.99.9): + workbox-webpack-plugin@6.6.0(@types/babel__core@7.20.5)(webpack@5.101.3): dependencies: fast-json-stable-stringify: 2.1.0 pretty-bytes: 5.6.0 upath: 1.2.0 - webpack: 5.99.9 + webpack: 5.101.3 webpack-sources: 1.4.3 workbox-build: 6.6.0(@types/babel__core@7.20.5) transitivePeerDependencies: @@ -20711,6 +20939,10 @@ snapshots: bufferutil: 4.0.9 utf-8-validate: 5.0.10 + wsl-utils@0.1.0: + dependencies: + is-wsl: 3.1.0 + xml-name-validator@3.0.0: {} xmlchars@2.2.0: {} @@ -20745,8 +20977,8 @@ snapshots: yup@0.32.11: dependencies: - '@babel/runtime': 7.27.0 - '@types/lodash': 4.17.16 + '@babel/runtime': 7.28.2 + '@types/lodash': 4.17.20 lodash: 4.17.21 lodash-es: 4.17.21 nanoclone: 0.2.1 From c1fd08f997f5995547a4ddaaef443d4ef9e62bef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Aug 2025 17:37:37 +0000 Subject: [PATCH 011/303] Bump axios from 1.8.4 to 1.11.0 Bumps [axios](https://github.com/axios/axios) from 1.8.4 to 1.11.0. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.8.4...v1.11.0) --- updated-dependencies: - dependency-name: axios dependency-version: 1.11.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- packages/shared/package.json | 2 +- packages/test-utils/package.json | 2 +- pnpm-lock.yaml | 54 ++++++++++---------------------- 3 files changed, 18 insertions(+), 40 deletions(-) diff --git a/packages/shared/package.json b/packages/shared/package.json index 1cdc44bc8..79d0d3ea1 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -44,7 +44,7 @@ "@ethersproject/providers": "^5.8.0", "@nucypher/nucypher-contracts": "^0.25.0", "@nucypher/nucypher-core": "^0.14.5", - "axios": "^1.8.4", + "axios": "^1.11.0", "deep-equal": "^2.2.3", "ethers": "^5.8.0", "qs": "^6.14.0", diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index cea78cb70..1295e2594 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -32,7 +32,7 @@ "@nucypher/nucypher-core": "^0.14.5", "@nucypher/shared": "workspace:*", "@nucypher/taco-auth": "workspace:*", - "axios": "^1.8.4", + "axios": "^1.11.0", "ethers": "^5.8.0", "vitest": "^3.0.9" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eeb2174de..64c9d09a2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -519,8 +519,8 @@ importers: specifier: ^0.14.5 version: 0.14.5 axios: - specifier: ^1.8.4 - version: 1.8.4 + specifier: ^1.11.0 + version: 1.11.0 deep-equal: specifier: ^2.2.3 version: 2.2.3 @@ -630,8 +630,8 @@ importers: specifier: workspace:* version: link:../taco-auth axios: - specifier: ^1.8.4 - version: 1.8.4 + specifier: ^1.11.0 + version: 1.11.0 ethers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -683,10 +683,6 @@ packages: resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} - '@babel/code-frame@7.27.1': - resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} - engines: {node: '>=6.9.0'} - '@babel/compat-data@7.26.8': resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} engines: {node: '>=6.9.0'} @@ -777,10 +773,6 @@ packages: resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} - engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.25.9': resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} @@ -1372,10 +1364,6 @@ packages: resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.28.2': - resolution: {integrity: sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==} - engines: {node: '>=6.9.0'} - '@babel/template@7.27.0': resolution: {integrity: sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==} engines: {node: '>=6.9.0'} @@ -3027,8 +3015,8 @@ packages: '@types/keyv@3.1.4': resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} - '@types/lodash@4.17.20': - resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==} + '@types/lodash@4.17.16': + resolution: {integrity: sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==} '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} @@ -9782,12 +9770,6 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/code-frame@7.27.1': - dependencies: - '@babel/helper-validator-identifier': 7.27.1 - js-tokens: 4.0.0 - picocolors: 1.1.1 - '@babel/compat-data@7.26.8': {} '@babel/core@7.26.10': @@ -9927,8 +9909,6 @@ snapshots: '@babel/helper-validator-identifier@7.25.9': {} - '@babel/helper-validator-identifier@7.27.1': {} - '@babel/helper-validator-option@7.25.9': {} '@babel/helper-wrap-function@7.25.9': @@ -10640,8 +10620,6 @@ snapshots: dependencies: regenerator-runtime: 0.14.1 - '@babel/runtime@7.28.2': {} - '@babel/template@7.27.0': dependencies: '@babel/code-frame': 7.26.2 @@ -11580,7 +11558,7 @@ snapshots: '@irys/query@0.0.8': dependencies: async-retry: 1.3.3 - axios: 1.8.4 + axios: 1.11.0 transitivePeerDependencies: - debug @@ -11887,7 +11865,7 @@ snapshots: '@manypkg/find-root@1.1.0': dependencies: - '@babel/runtime': 7.28.2 + '@babel/runtime': 7.27.0 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 @@ -12072,7 +12050,7 @@ snapshots: '@ethersproject/providers': 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@nucypher/nucypher-contracts': 0.25.0 '@nucypher/nucypher-core': 0.14.5 - axios: 1.8.4 + axios: 1.11.0 deep-equal: 2.2.3 ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) qs: 6.14.0 @@ -12542,7 +12520,7 @@ snapshots: '@types/http-proxy@1.17.16': dependencies: - '@types/node': 20.17.28 + '@types/node': 22.13.14 '@types/istanbul-lib-coverage@2.0.6': {} @@ -12562,7 +12540,7 @@ snapshots: dependencies: '@types/node': 20.17.28 - '@types/lodash@4.17.20': {} + '@types/lodash@4.17.16': {} '@types/mime@1.3.5': {} @@ -17050,7 +17028,7 @@ snapshots: jest-message-util@28.1.3: dependencies: - '@babel/code-frame': 7.27.1 + '@babel/code-frame': 7.26.2 '@jest/types': 28.1.3 '@types/stack-utils': 2.0.3 chalk: 4.1.2 @@ -18075,7 +18053,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.27.1 + '@babel/code-frame': 7.26.2 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -18984,7 +18962,7 @@ snapshots: regenerator-transform@0.15.2: dependencies: - '@babel/runtime': 7.28.2 + '@babel/runtime': 7.27.0 regex-parser@2.3.1: {} @@ -20977,8 +20955,8 @@ snapshots: yup@0.32.11: dependencies: - '@babel/runtime': 7.28.2 - '@types/lodash': 4.17.20 + '@babel/runtime': 7.27.0 + '@types/lodash': 4.17.16 lodash: 4.17.21 lodash-es: 4.17.21 nanoclone: 0.2.1 From edee1f89727eb25d43b2bb295c65a3355107fb0d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 20:44:03 +0000 Subject: [PATCH 012/303] Bump @types/node from 20.11.30 to 24.3.0 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.30 to 24.3.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 24.3.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- examples/pre/nextjs/package.json | 2 +- examples/pre/react/package.json | 2 +- examples/taco/nextjs/package.json | 2 +- examples/taco/react/package.json | 2 +- package.json | 2 +- pnpm-lock.yaml | 372 ++++++++++-------------------- 6 files changed, 126 insertions(+), 256 deletions(-) diff --git a/examples/pre/nextjs/package.json b/examples/pre/nextjs/package.json index 59d5b8bb5..d9a266493 100644 --- a/examples/pre/nextjs/package.json +++ b/examples/pre/nextjs/package.json @@ -11,7 +11,7 @@ }, "dependencies": { "@nucypher/pre": "workspace:*", - "@types/node": "20.11.30", + "@types/node": "24.3.0", "@types/react": "18.3.5", "@types/react-dom": "18.3.0", "eslint": "8.57.0", diff --git a/examples/pre/react/package.json b/examples/pre/react/package.json index d1cbd298c..653567731 100644 --- a/examples/pre/react/package.json +++ b/examples/pre/react/package.json @@ -29,7 +29,7 @@ "react-dom": "^18.3.1" }, "devDependencies": { - "@types/node": "^20.17.28", + "@types/node": "^24.3.0", "@types/react": "^18.3.20", "@types/react-dom": "^18.3.5", "react-scripts": "^5.0.1" diff --git a/examples/taco/nextjs/package.json b/examples/taco/nextjs/package.json index 775346f22..98718953b 100644 --- a/examples/taco/nextjs/package.json +++ b/examples/taco/nextjs/package.json @@ -14,7 +14,7 @@ "@nucypher/shared": "workspace:*", "@nucypher/taco": "workspace:*", "@nucypher/taco-auth": "workspace:*", - "@types/node": "20.11.30", + "@types/node": "24.3.0", "@types/react": "18.3.5", "@types/react-dom": "18.3.0", "eslint": "8.57.0", diff --git a/examples/taco/react/package.json b/examples/taco/react/package.json index 860a6cc63..0cfdf1338 100644 --- a/examples/taco/react/package.json +++ b/examples/taco/react/package.json @@ -30,7 +30,7 @@ "react-dom": "^18.3.1" }, "devDependencies": { - "@types/node": "^20.17.28", + "@types/node": "^24.3.0", "@types/react": "^18.3.20", "@types/react-dom": "^18.3.5", "react-scripts": "^5.0.1" diff --git a/package.json b/package.json index 701b84bd7..e5c742053 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ }, "devDependencies": { "@skypack/package-check": "^0.2.2", - "@types/node": "^20.17.28", + "@types/node": "^24.3.0", "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", "@vitest/coverage-v8": "^3.2.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 64c9d09a2..558fd750b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,8 +29,8 @@ importers: specifier: ^0.2.2 version: 0.2.2 '@types/node': - specifier: ^20.17.28 - version: 20.17.28 + specifier: ^24.3.0 + version: 24.3.0 '@typescript-eslint/eslint-plugin': specifier: ^6.21.0 version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2) @@ -39,7 +39,7 @@ importers: version: 6.21.0(eslint@8.57.1)(typescript@5.8.2) '@vitest/coverage-v8': specifier: ^3.2.4 - version: 3.2.4(vitest@3.0.9(@types/node@20.17.28)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0)) + version: 3.2.4(vitest@3.0.9(@types/node@24.3.0)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0)) bundlemon: specifier: ^3.1.0 version: 3.1.0(typescript@5.8.2) @@ -84,7 +84,7 @@ importers: version: 2.15.1 ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@20.17.28)(typescript@5.8.2) + version: 10.9.2(@types/node@24.3.0)(typescript@5.8.2) ts-unused-exports: specifier: ^10.1.0 version: 10.1.0(typescript@5.8.2) @@ -105,7 +105,7 @@ importers: version: 5.8.2 vitest: specifier: ^3.0.9 - version: 3.0.9(@types/node@20.17.28)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0) + version: 3.0.9(@types/node@24.3.0)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0) demos/taco-demo: dependencies: @@ -277,8 +277,8 @@ importers: specifier: workspace:* version: link:../../../packages/pre '@types/node': - specifier: 20.11.30 - version: 20.11.30 + specifier: 24.3.0 + version: 24.3.0 '@types/react': specifier: 18.3.5 version: 18.3.5 @@ -332,8 +332,8 @@ importers: version: 18.3.1(react@18.3.1) devDependencies: '@types/node': - specifier: ^20.17.28 - version: 20.17.28 + specifier: ^24.3.0 + version: 24.3.0 '@types/react': specifier: ^18.3.20 version: 18.3.20 @@ -342,7 +342,7 @@ importers: version: 18.3.5(@types/react@18.3.20) react-scripts: specifier: ^5.0.1 - version: 5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(@types/babel__core@7.20.5)(bufferutil@4.0.9)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(type-fest@0.21.3)(typescript@5.8.2)(utf-8-validate@5.0.10) + version: 5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(@types/babel__core@7.20.5)(bufferutil@4.0.9)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(type-fest@0.21.3)(typescript@5.8.2)(utf-8-validate@5.0.10) examples/pre/webpack-5: dependencies: @@ -381,8 +381,8 @@ importers: specifier: workspace:* version: link:../../../packages/taco-auth '@types/node': - specifier: 20.11.30 - version: 20.11.30 + specifier: 24.3.0 + version: 24.3.0 '@types/react': specifier: 18.3.5 version: 18.3.5 @@ -448,8 +448,8 @@ importers: version: 18.3.1(react@18.3.1) devDependencies: '@types/node': - specifier: ^20.17.28 - version: 20.17.28 + specifier: ^24.3.0 + version: 24.3.0 '@types/react': specifier: ^18.3.20 version: 18.3.20 @@ -458,7 +458,7 @@ importers: version: 18.3.5(@types/react@18.3.20) react-scripts: specifier: ^5.0.1 - version: 5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(@types/babel__core@7.20.5)(bufferutil@4.0.9)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(type-fest@0.21.3)(typescript@5.8.2)(utf-8-validate@5.0.10) + version: 5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(@types/babel__core@7.20.5)(bufferutil@4.0.9)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(type-fest@0.21.3)(typescript@5.8.2)(utf-8-validate@5.0.10) examples/taco/webpack-5: dependencies: @@ -551,7 +551,7 @@ importers: version: 0.2.6 cz-conventional-changelog: specifier: ^3.3.0 - version: 3.3.0(@types/node@24.1.0)(typescript@5.8.2) + version: 3.3.0(@types/node@24.3.0)(typescript@5.8.2) standard-version: specifier: ^9.5.0 version: 9.5.0 @@ -637,7 +637,7 @@ importers: version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) vitest: specifier: ^3.0.9 - version: 3.0.9(@types/node@24.1.0)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0) + version: 3.0.9(@types/node@24.3.0)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0) packages: @@ -3033,17 +3033,8 @@ packages: '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - '@types/node@20.11.30': - resolution: {integrity: sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==} - - '@types/node@20.17.28': - resolution: {integrity: sha512-DHlH/fNL6Mho38jTy7/JT7sn2wnXI+wULR6PV4gy4VHLVvnrV/d3pHAMQHhc4gjdLmK2ZiPoMxzp6B3yRajLSQ==} - - '@types/node@22.13.14': - resolution: {integrity: sha512-Zs/Ollc1SJ8nKUAgc7ivOEdIBM8JAKgrqqUYi2J997JuKO7/tpQC+WCetQ1sypiKCQWHdvdg9wBNpUPEWZae7w==} - - '@types/node@24.1.0': - resolution: {integrity: sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==} + '@types/node@24.3.0': + resolution: {integrity: sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -5486,15 +5477,6 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - follow-redirects@1.15.11: - resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - follow-redirects@1.15.9: resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} engines: {node: '>=4.0'} @@ -5526,8 +5508,8 @@ packages: vue-template-compiler: optional: true - form-data@3.0.4: - resolution: {integrity: sha512-f0cRzm6dkyVYV3nPoooP8XlccPQukegwhAnpoLcXy+X+A8KfpGOoXwDr9FLZd3wzgLaBGQBE3lY93Zm/i1JvIQ==} + form-data@3.0.3: + resolution: {integrity: sha512-q5YBMeWy6E2Un0nMGWMgI65MAKtaylxfNJGJxpGh45YDciZB4epbWpaAfImil6CPAPTYB4sh0URQNDRIZG5F2w==} engines: {node: '>= 6'} form-data@4.0.2: @@ -9159,17 +9141,8 @@ packages: underscore@1.12.1: resolution: {integrity: sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==} - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - - undici-types@6.19.8: - resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - - undici-types@6.20.0: - resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} - - undici-types@7.8.0: - resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} + undici-types@7.10.0: + resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} unicode-canonical-property-names-ecmascript@2.0.1: resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} @@ -10802,7 +10775,7 @@ snapshots: '@commitlint/execute-rule@19.8.0': optional: true - '@commitlint/load@19.8.0(@types/node@24.1.0)(typescript@5.8.2)': + '@commitlint/load@19.8.0(@types/node@24.3.0)(typescript@5.8.2)': dependencies: '@commitlint/config-validator': 19.8.0 '@commitlint/execute-rule': 19.8.0 @@ -10810,7 +10783,7 @@ snapshots: '@commitlint/types': 19.8.0 chalk: 5.4.1 cosmiconfig: 9.0.0(typescript@5.8.2) - cosmiconfig-typescript-loader: 6.1.0(@types/node@24.1.0)(cosmiconfig@9.0.0(typescript@5.8.2))(typescript@5.8.2) + cosmiconfig-typescript-loader: 6.1.0(@types/node@24.3.0)(cosmiconfig@9.0.0(typescript@5.8.2))(typescript@5.8.2) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -11620,7 +11593,7 @@ snapshots: '@jest/console@27.5.1': dependencies: '@jest/types': 27.5.1 - '@types/node': 20.17.28 + '@types/node': 24.3.0 chalk: 4.1.2 jest-message-util: 27.5.1 jest-util: 27.5.1 @@ -11629,27 +11602,27 @@ snapshots: '@jest/console@28.1.3': dependencies: '@jest/types': 28.1.3 - '@types/node': 20.17.28 + '@types/node': 24.3.0 chalk: 4.1.2 jest-message-util: 28.1.3 jest-util: 28.1.3 slash: 3.0.0 - '@jest/core@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10)': + '@jest/core@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10)': dependencies: '@jest/console': 27.5.1 '@jest/reporters': 27.5.1 '@jest/test-result': 27.5.1 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 20.17.28 + '@types/node': 24.3.0 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.8.1 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 27.5.1 - jest-config: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10) + jest-config: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10) jest-haste-map: 27.5.1 jest-message-util: 27.5.1 jest-regex-util: 27.5.1 @@ -11676,14 +11649,14 @@ snapshots: dependencies: '@jest/fake-timers': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 20.17.28 + '@types/node': 24.3.0 jest-mock: 27.5.1 '@jest/fake-timers@27.5.1': dependencies: '@jest/types': 27.5.1 '@sinonjs/fake-timers': 8.1.0 - '@types/node': 20.17.28 + '@types/node': 24.3.0 jest-message-util: 27.5.1 jest-mock: 27.5.1 jest-util: 27.5.1 @@ -11701,7 +11674,7 @@ snapshots: '@jest/test-result': 27.5.1 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 20.17.28 + '@types/node': 24.3.0 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -11781,7 +11754,7 @@ snapshots: dependencies: '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.17.28 + '@types/node': 24.3.0 '@types/yargs': 16.0.9 chalk: 4.1.2 @@ -11790,7 +11763,7 @@ snapshots: '@jest/schemas': 28.1.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.17.28 + '@types/node': 24.3.0 '@types/yargs': 17.0.33 chalk: 4.1.2 @@ -12435,31 +12408,31 @@ snapshots: '@types/body-parser@1.19.5': dependencies: '@types/connect': 3.4.38 - '@types/node': 20.17.28 + '@types/node': 24.3.0 '@types/bonjour@3.5.13': dependencies: - '@types/node': 20.17.28 + '@types/node': 24.3.0 '@types/cacheable-request@6.0.3': dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 20.17.28 + '@types/node': 24.3.0 '@types/responselike': 1.0.3 '@types/connect-history-api-fallback@1.5.4': dependencies: '@types/express-serve-static-core': 5.0.6 - '@types/node': 20.17.28 + '@types/node': 24.3.0 '@types/connect@3.4.38': dependencies: - '@types/node': 22.13.14 + '@types/node': 24.3.0 '@types/conventional-commits-parser@5.0.1': dependencies: - '@types/node': 22.13.14 + '@types/node': 24.3.0 optional: true '@types/deep-equal@1.0.4': {} @@ -12489,14 +12462,14 @@ snapshots: '@types/express-serve-static-core@4.19.6': dependencies: - '@types/node': 20.17.28 + '@types/node': 24.3.0 '@types/qs': 6.9.18 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 '@types/express-serve-static-core@5.0.6': dependencies: - '@types/node': 20.17.28 + '@types/node': 24.3.0 '@types/qs': 6.9.18 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 @@ -12510,7 +12483,7 @@ snapshots: '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 20.17.28 + '@types/node': 24.3.0 '@types/html-minifier-terser@6.1.0': {} @@ -12520,7 +12493,7 @@ snapshots: '@types/http-proxy@1.17.16': dependencies: - '@types/node': 22.13.14 + '@types/node': 24.3.0 '@types/istanbul-lib-coverage@2.0.6': {} @@ -12538,7 +12511,7 @@ snapshots: '@types/keyv@3.1.4': dependencies: - '@types/node': 20.17.28 + '@types/node': 24.3.0 '@types/lodash@4.17.16': {} @@ -12548,28 +12521,15 @@ snapshots: '@types/node-forge@1.3.11': dependencies: - '@types/node': 20.17.28 + '@types/node': 24.3.0 '@types/node@11.11.6': {} '@types/node@12.20.55': {} - '@types/node@20.11.30': + '@types/node@24.3.0': dependencies: - undici-types: 5.26.5 - - '@types/node@20.17.28': - dependencies: - undici-types: 6.19.8 - - '@types/node@22.13.14': - dependencies: - undici-types: 6.20.0 - - '@types/node@24.1.0': - dependencies: - undici-types: 7.8.0 - optional: true + undici-types: 7.10.0 '@types/normalize-package-data@2.4.4': {} @@ -12609,11 +12569,11 @@ snapshots: '@types/resolve@1.17.1': dependencies: - '@types/node': 20.17.28 + '@types/node': 24.3.0 '@types/responselike@1.0.3': dependencies: - '@types/node': 20.17.28 + '@types/node': 24.3.0 '@types/retry@0.12.0': {} @@ -12624,7 +12584,7 @@ snapshots: '@types/send@0.17.4': dependencies: '@types/mime': 1.3.5 - '@types/node': 20.17.28 + '@types/node': 24.3.0 '@types/serve-index@1.9.4': dependencies: @@ -12633,12 +12593,12 @@ snapshots: '@types/serve-static@1.15.7': dependencies: '@types/http-errors': 2.0.4 - '@types/node': 20.17.28 + '@types/node': 24.3.0 '@types/send': 0.17.4 '@types/sockjs@0.3.36': dependencies: - '@types/node': 20.17.28 + '@types/node': 24.3.0 '@types/stack-utils@2.0.3': {} @@ -12650,11 +12610,11 @@ snapshots: '@types/ws@7.4.7': dependencies: - '@types/node': 12.20.55 + '@types/node': 24.3.0 '@types/ws@8.18.0': dependencies: - '@types/node': 20.17.28 + '@types/node': 24.3.0 '@types/yargs-parser@21.0.3': {} @@ -12950,7 +12910,7 @@ snapshots: - node-fetch - supports-color - '@vitest/coverage-v8@3.2.4(vitest@3.0.9(@types/node@20.17.28)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0))': + '@vitest/coverage-v8@3.2.4(vitest@3.0.9(@types/node@24.3.0)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -12965,7 +12925,7 @@ snapshots: std-env: 3.9.0 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.0.9(@types/node@20.17.28)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0) + vitest: 3.0.9(@types/node@24.3.0)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0) transitivePeerDependencies: - supports-color @@ -12976,21 +12936,13 @@ snapshots: chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.0.9(vite@6.2.3(@types/node@20.17.28)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))': + '@vitest/mocker@3.0.9(vite@6.2.3(@types/node@24.3.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))': dependencies: '@vitest/spy': 3.0.9 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.2.3(@types/node@20.17.28)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) - - '@vitest/mocker@3.0.9(vite@6.2.3(@types/node@24.1.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))': - dependencies: - '@vitest/spy': 3.0.9 - estree-walker: 3.0.3 - magic-string: 0.30.17 - optionalDependencies: - vite: 6.2.3(@types/node@24.1.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) + vite: 6.2.3(@types/node@24.3.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) '@vitest/pretty-format@3.0.9': dependencies: @@ -13461,7 +13413,7 @@ snapshots: axios@1.11.0: dependencies: - follow-redirects: 1.15.11 + follow-redirects: 1.15.9 form-data: 4.0.4 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -14057,10 +14009,10 @@ snapshots: commander@8.3.0: {} - commitizen@4.3.1(@types/node@24.1.0)(typescript@5.8.2): + commitizen@4.3.1(@types/node@24.3.0)(typescript@5.8.2): dependencies: cachedir: 2.3.0 - cz-conventional-changelog: 3.3.0(@types/node@24.1.0)(typescript@5.8.2) + cz-conventional-changelog: 3.3.0(@types/node@24.3.0)(typescript@5.8.2) dedent: 0.7.0 detect-indent: 6.1.0 find-node-modules: 2.1.3 @@ -14266,9 +14218,9 @@ snapshots: core-util-is@1.0.3: {} - cosmiconfig-typescript-loader@6.1.0(@types/node@24.1.0)(cosmiconfig@9.0.0(typescript@5.8.2))(typescript@5.8.2): + cosmiconfig-typescript-loader@6.1.0(@types/node@24.3.0)(cosmiconfig@9.0.0(typescript@5.8.2))(typescript@5.8.2): dependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.0 cosmiconfig: 9.0.0(typescript@5.8.2) jiti: 2.4.2 typescript: 5.8.2 @@ -14517,16 +14469,16 @@ snapshots: csv-stringify: 5.6.5 stream-transform: 2.1.3 - cz-conventional-changelog@3.3.0(@types/node@24.1.0)(typescript@5.8.2): + cz-conventional-changelog@3.3.0(@types/node@24.3.0)(typescript@5.8.2): dependencies: chalk: 2.4.2 - commitizen: 4.3.1(@types/node@24.1.0)(typescript@5.8.2) + commitizen: 4.3.1(@types/node@24.3.0)(typescript@5.8.2) conventional-commit-types: 3.0.0 lodash.map: 4.6.0 longest: 2.0.1 word-wrap: 1.2.5 optionalDependencies: - '@commitlint/load': 19.8.0(@types/node@24.1.0)(typescript@5.8.2) + '@commitlint/load': 19.8.0(@types/node@24.3.0)(typescript@5.8.2) transitivePeerDependencies: - '@types/node' - typescript @@ -15134,7 +15086,7 @@ snapshots: dependencies: eslint: 8.57.1 - eslint-config-react-app@7.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10))(typescript@5.8.2): + eslint-config-react-app@7.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10))(typescript@5.8.2): dependencies: '@babel/core': 7.26.10 '@babel/eslint-parser': 7.27.0(@babel/core@7.26.10)(eslint@8.57.1) @@ -15146,7 +15098,7 @@ snapshots: eslint: 8.57.1 eslint-plugin-flowtype: 8.0.3(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(eslint@8.57.1) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1) - eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10))(typescript@5.8.2) + eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10))(typescript@5.8.2) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) eslint-plugin-react: 7.37.4(eslint@8.57.1) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) @@ -15360,13 +15312,13 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10))(typescript@5.8.2): + eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10))(typescript@5.8.2): dependencies: '@typescript-eslint/experimental-utils': 5.62.0(eslint@8.57.1)(typescript@5.8.2) eslint: 8.57.1 optionalDependencies: '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2) - jest: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10) + jest: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10) transitivePeerDependencies: - supports-color - typescript @@ -15907,8 +15859,6 @@ snapshots: flatted@3.3.3: {} - follow-redirects@1.15.11: {} - follow-redirects@1.15.9: {} for-each@0.3.5: @@ -15940,12 +15890,11 @@ snapshots: optionalDependencies: eslint: 8.57.1 - form-data@3.0.4: + form-data@3.0.3: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 es-set-tostringtag: 2.1.0 - hasown: 2.0.2 mime-types: 2.1.35 form-data@4.0.2: @@ -16415,7 +16364,7 @@ snapshots: http-proxy@1.18.1: dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.11 + follow-redirects: 1.15.9 requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -16844,7 +16793,7 @@ snapshots: '@jest/environment': 27.5.1 '@jest/test-result': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 20.17.28 + '@types/node': 24.3.0 chalk: 4.1.2 co: 4.6.0 dedent: 0.7.0 @@ -16863,16 +16812,16 @@ snapshots: transitivePeerDependencies: - supports-color - jest-cli@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10): + jest-cli@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10): dependencies: - '@jest/core': 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10) + '@jest/core': 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10) '@jest/test-result': 27.5.1 '@jest/types': 27.5.1 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 import-local: 3.2.0 - jest-config: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10) + jest-config: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10) jest-util: 27.5.1 jest-validate: 27.5.1 prompts: 2.4.2 @@ -16884,7 +16833,7 @@ snapshots: - ts-node - utf-8-validate - jest-config@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10): + jest-config@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10): dependencies: '@babel/core': 7.26.10 '@jest/test-sequencer': 27.5.1 @@ -16911,7 +16860,7 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - ts-node: 10.9.2(@types/node@20.17.28)(typescript@5.8.2) + ts-node: 10.9.2(@types/node@24.3.0)(typescript@5.8.2) transitivePeerDependencies: - bufferutil - canvas @@ -16942,7 +16891,7 @@ snapshots: '@jest/environment': 27.5.1 '@jest/fake-timers': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 20.17.28 + '@types/node': 24.3.0 jest-mock: 27.5.1 jest-util: 27.5.1 jsdom: 16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -16957,7 +16906,7 @@ snapshots: '@jest/environment': 27.5.1 '@jest/fake-timers': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 20.17.28 + '@types/node': 24.3.0 jest-mock: 27.5.1 jest-util: 27.5.1 @@ -16967,7 +16916,7 @@ snapshots: dependencies: '@jest/types': 27.5.1 '@types/graceful-fs': 4.1.9 - '@types/node': 20.17.28 + '@types/node': 24.3.0 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -16986,7 +16935,7 @@ snapshots: '@jest/source-map': 27.5.1 '@jest/test-result': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 20.17.28 + '@types/node': 24.3.0 chalk: 4.1.2 co: 4.6.0 expect: 27.5.1 @@ -17041,7 +16990,7 @@ snapshots: jest-mock@27.5.1: dependencies: '@jest/types': 27.5.1 - '@types/node': 20.17.28 + '@types/node': 24.3.0 jest-pnp-resolver@1.2.3(jest-resolve@27.5.1): optionalDependencies: @@ -17079,7 +17028,7 @@ snapshots: '@jest/test-result': 27.5.1 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 20.17.28 + '@types/node': 24.3.0 chalk: 4.1.2 emittery: 0.8.1 graceful-fs: 4.2.11 @@ -17130,7 +17079,7 @@ snapshots: jest-serializer@27.5.1: dependencies: - '@types/node': 20.17.28 + '@types/node': 24.3.0 graceful-fs: 4.2.11 jest-snapshot@27.5.1: @@ -17163,7 +17112,7 @@ snapshots: jest-util@27.5.1: dependencies: '@jest/types': 27.5.1 - '@types/node': 20.17.28 + '@types/node': 24.3.0 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -17172,7 +17121,7 @@ snapshots: jest-util@28.1.3: dependencies: '@jest/types': 28.1.3 - '@types/node': 20.17.28 + '@types/node': 24.3.0 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -17187,11 +17136,11 @@ snapshots: leven: 3.1.0 pretty-format: 27.5.1 - jest-watch-typeahead@1.1.0(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10)): + jest-watch-typeahead@1.1.0(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10)): dependencies: ansi-escapes: 4.3.2 chalk: 4.1.2 - jest: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10) + jest: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10) jest-regex-util: 28.0.2 jest-watcher: 28.1.3 slash: 4.0.0 @@ -17202,7 +17151,7 @@ snapshots: dependencies: '@jest/test-result': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 20.17.28 + '@types/node': 24.3.0 ansi-escapes: 4.3.2 chalk: 4.1.2 jest-util: 27.5.1 @@ -17212,7 +17161,7 @@ snapshots: dependencies: '@jest/test-result': 28.1.3 '@jest/types': 28.1.3 - '@types/node': 20.17.28 + '@types/node': 24.3.0 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.10.2 @@ -17221,27 +17170,27 @@ snapshots: jest-worker@26.6.2: dependencies: - '@types/node': 20.17.28 + '@types/node': 24.3.0 merge-stream: 2.0.0 supports-color: 7.2.0 jest-worker@27.5.1: dependencies: - '@types/node': 22.13.14 + '@types/node': 24.3.0 merge-stream: 2.0.0 supports-color: 8.1.1 jest-worker@28.1.3: dependencies: - '@types/node': 20.17.28 + '@types/node': 24.3.0 merge-stream: 2.0.0 supports-color: 8.1.1 - jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10): + jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10): dependencies: - '@jest/core': 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10) + '@jest/core': 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10) import-local: 3.2.0 - jest-cli: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10) + jest-cli: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - canvas @@ -17288,7 +17237,7 @@ snapshots: decimal.js: 10.5.0 domexception: 2.0.1 escodegen: 2.1.0 - form-data: 3.0.4 + form-data: 3.0.3 html-encoding-sniffer: 2.0.1 http-proxy-agent: 4.0.1 https-proxy-agent: 5.0.1 @@ -18291,13 +18240,13 @@ snapshots: postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-load-config@4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2)): + postcss-load-config@4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2)): dependencies: lilconfig: 3.1.3 yaml: 2.7.0 optionalDependencies: postcss: 8.5.3 - ts-node: 10.9.2(@types/node@20.17.28)(typescript@5.8.2) + ts-node: 10.9.2(@types/node@24.3.0)(typescript@5.8.2) postcss-loader@6.2.1(postcss@8.5.3)(webpack@5.101.3): dependencies: @@ -18773,7 +18722,7 @@ snapshots: react-refresh@0.17.0: {} - react-scripts@5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(@types/babel__core@7.20.5)(bufferutil@4.0.9)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(type-fest@0.21.3)(typescript@5.8.2)(utf-8-validate@5.0.10): + react-scripts@5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(@types/babel__core@7.20.5)(bufferutil@4.0.9)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(type-fest@0.21.3)(typescript@5.8.2)(utf-8-validate@5.0.10): dependencies: '@babel/core': 7.26.10 '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(react-refresh@0.11.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.101.3))(webpack@5.101.3) @@ -18791,15 +18740,15 @@ snapshots: dotenv: 10.0.0 dotenv-expand: 5.1.0 eslint: 8.57.1 - eslint-config-react-app: 7.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10))(typescript@5.8.2) + eslint-config-react-app: 7.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10))(typescript@5.8.2) eslint-webpack-plugin: 3.2.0(eslint@8.57.1)(webpack@5.101.3) file-loader: 6.2.0(webpack@5.101.3) fs-extra: 10.1.0 html-webpack-plugin: 5.6.3(webpack@5.101.3) identity-obj-proxy: 3.0.0 - jest: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10) + jest: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10) jest-resolve: 27.5.1 - jest-watch-typeahead: 1.1.0(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2))(utf-8-validate@5.0.10)) + jest-watch-typeahead: 1.1.0(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10)) mini-css-extract-plugin: 2.9.2(webpack@5.101.3) postcss: 8.5.3 postcss-flexbugs-fixes: 5.0.2(postcss@8.5.3) @@ -18817,7 +18766,7 @@ snapshots: semver: 7.7.1 source-map-loader: 3.0.2(webpack@5.101.3) style-loader: 3.3.4(webpack@5.101.3) - tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2)) + tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2)) terser-webpack-plugin: 5.3.14(webpack@5.101.3) webpack: 5.101.3 webpack-dev-server: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.101.3) @@ -19777,7 +19726,7 @@ snapshots: typical: 5.2.0 wordwrapjs: 4.0.1 - tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2)): + tailwindcss@3.4.17(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -19796,7 +19745,7 @@ snapshots: postcss: 8.5.3 postcss-import: 15.1.0(postcss@8.5.3) postcss-js: 4.0.1(postcss@8.5.3) - postcss-load-config: 4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2)) + postcss-load-config: 4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2)) postcss-nested: 6.2.0(postcss@8.5.3) postcss-selector-parser: 6.1.2 resolve: 1.22.10 @@ -19983,14 +19932,14 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-node@10.9.2(@types/node@20.17.28)(typescript@5.8.2): + ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.17.28 + '@types/node': 24.3.0 acorn: 8.14.1 acorn-walk: 8.3.4 arg: 4.1.3 @@ -20149,14 +20098,7 @@ snapshots: underscore@1.12.1: {} - undici-types@5.26.5: {} - - undici-types@6.19.8: {} - - undici-types@6.20.0: {} - - undici-types@7.8.0: - optional: true + undici-types@7.10.0: {} unicode-canonical-property-names-ecmascript@2.0.1: {} @@ -20253,34 +20195,13 @@ snapshots: vary@1.1.2: {} - vite-node@3.0.9(@types/node@20.17.28)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0): - dependencies: - cac: 6.7.14 - debug: 4.4.0 - es-module-lexer: 1.6.0 - pathe: 2.0.3 - vite: 6.2.3(@types/node@20.17.28)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) - transitivePeerDependencies: - - '@types/node' - - jiti - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - - vite-node@3.0.9(@types/node@24.1.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0): + vite-node@3.0.9(@types/node@24.3.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0): dependencies: cac: 6.7.14 debug: 4.4.0 es-module-lexer: 1.6.0 pathe: 2.0.3 - vite: 6.2.3(@types/node@24.1.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) + vite: 6.2.3(@types/node@24.3.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) transitivePeerDependencies: - '@types/node' - jiti @@ -20295,73 +20216,22 @@ snapshots: - tsx - yaml - vite@6.2.3(@types/node@20.17.28)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0): + vite@6.2.3(@types/node@24.3.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0): dependencies: esbuild: 0.25.1 postcss: 8.5.3 rollup: 4.37.0 optionalDependencies: - '@types/node': 20.17.28 + '@types/node': 24.3.0 fsevents: 2.3.3 jiti: 2.4.2 terser: 5.39.0 yaml: 2.7.0 - vite@6.2.3(@types/node@24.1.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0): - dependencies: - esbuild: 0.25.1 - postcss: 8.5.3 - rollup: 4.37.0 - optionalDependencies: - '@types/node': 24.1.0 - fsevents: 2.3.3 - jiti: 2.4.2 - terser: 5.39.0 - yaml: 2.7.0 - - vitest@3.0.9(@types/node@20.17.28)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0): - dependencies: - '@vitest/expect': 3.0.9 - '@vitest/mocker': 3.0.9(vite@6.2.3(@types/node@20.17.28)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0)) - '@vitest/pretty-format': 3.0.9 - '@vitest/runner': 3.0.9 - '@vitest/snapshot': 3.0.9 - '@vitest/spy': 3.0.9 - '@vitest/utils': 3.0.9 - chai: 5.2.0 - debug: 4.4.0 - expect-type: 1.2.0 - magic-string: 0.30.17 - pathe: 2.0.3 - std-env: 3.8.1 - tinybench: 2.9.0 - tinyexec: 0.3.2 - tinypool: 1.0.2 - tinyrainbow: 2.0.0 - vite: 6.2.3(@types/node@20.17.28)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) - vite-node: 3.0.9(@types/node@20.17.28)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 20.17.28 - jsdom: 16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - transitivePeerDependencies: - - jiti - - less - - lightningcss - - msw - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - - vitest@3.0.9(@types/node@24.1.0)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0): + vitest@3.0.9(@types/node@24.3.0)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0): dependencies: '@vitest/expect': 3.0.9 - '@vitest/mocker': 3.0.9(vite@6.2.3(@types/node@24.1.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0)) + '@vitest/mocker': 3.0.9(vite@6.2.3(@types/node@24.3.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0)) '@vitest/pretty-format': 3.0.9 '@vitest/runner': 3.0.9 '@vitest/snapshot': 3.0.9 @@ -20377,11 +20247,11 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.0.2 tinyrainbow: 2.0.0 - vite: 6.2.3(@types/node@24.1.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) - vite-node: 3.0.9(@types/node@24.1.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) + vite: 6.2.3(@types/node@24.3.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) + vite-node: 3.0.9(@types/node@24.3.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.0 jsdom: 16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - jiti From 556bbeaf1340c262c8d5c6b88c7e6305a2e6ea29 Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Tue, 3 Jun 2025 15:58:58 +0200 Subject: [PATCH 013/303] add WalletAllowlistCondition --- .../taco/examples/wallet-allowlist-example.ts | 56 +++++ .../taco/schema-docs/condition-schemas.md | 14 ++ packages/taco/src/conditions/base/index.ts | 1 + .../src/conditions/base/wallet-allowlist.ts | 27 +++ .../taco/src/conditions/condition-factory.ts | 7 + .../taco/src/conditions/predefined/index.ts | 1 + .../conditions/predefined/wallet-allowlist.ts | 29 +++ .../schemas/export-for-zod-doc-gen.ts | 2 + packages/taco/src/conditions/schemas/index.ts | 16 ++ packages/taco/src/conditions/schemas/utils.ts | 3 + .../conditions/schemas/wallet-allowlist.ts | 38 +++ .../conditions/base/wallet-allowlist.test.ts | 227 ++++++++++++++++++ packages/taco/test/test-utils.ts | 14 ++ 13 files changed, 435 insertions(+) create mode 100644 packages/taco/examples/wallet-allowlist-example.ts create mode 100644 packages/taco/src/conditions/base/wallet-allowlist.ts create mode 100644 packages/taco/src/conditions/predefined/wallet-allowlist.ts create mode 100644 packages/taco/src/conditions/schemas/index.ts create mode 100644 packages/taco/src/conditions/schemas/wallet-allowlist.ts create mode 100644 packages/taco/test/conditions/base/wallet-allowlist.test.ts diff --git a/packages/taco/examples/wallet-allowlist-example.ts b/packages/taco/examples/wallet-allowlist-example.ts new file mode 100644 index 000000000..0ed584327 --- /dev/null +++ b/packages/taco/examples/wallet-allowlist-example.ts @@ -0,0 +1,56 @@ +/** + * Example demonstrating how to use the WalletAllowlistCondition + * + * This is a gas-free, off-chain condition that grants decryption permissions + * to a predefined list of wallet addresses. + */ + +async function walletAllowlistExample() { + // Import the relevant modules + const taco = await import('../src/index'); + const { predefined } = await import('../src/conditions'); + + console.log('Wallet Allowlist Example'); + + // Create a simple condition allowing specific wallet addresses to decrypt + // Addresses must be in checksummed format + // The condition is satisfied when the requester proves control of one of the + // specified addresses (through wallet signature verification handled by auth providers) + const walletCondition = new predefined.walletAllowlist.WalletOwnership({ + addresses: [ + '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', + '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', + '0x0000000000000000000000000000000000000001', + ], + }); + + // View the condition's object representation - what gets stored on-chain + console.log('Wallet Allowlist Condition:', walletCondition.toObj()); + + // In a real app, you would encrypt data with this condition + // const encrypter = await taco.conditions.getEncrypter({ + // conditions: walletCondition, + // }); + // const ciphertext = await encrypter.encrypt('secret data'); + + // Check if a specific address is in the allowlist + const addresses = walletCondition.toObj().addresses; + const addressToCheck = '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77'; + const isAllowed = addresses.some( + (addr: string) => addr.toLowerCase() === addressToCheck.toLowerCase() + ); + + console.log(`Is address ${addressToCheck} allowed? ${isAllowed}`); + + // Check a non-allowed address + const nonAllowedAddress = '0x0000000000000000000000000000000000000099'; + const isNonAllowedAddressAllowed = addresses.some( + (addr: string) => addr.toLowerCase() === nonAllowedAddress.toLowerCase() + ); + + console.log( + `Is address ${nonAllowedAddress} allowed? ${isNonAllowedAddressAllowed}` + ); +} + +walletAllowlistExample().catch(console.error); diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index 93b1c76a5..6a7623665 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -6,6 +6,7 @@ _Union of the following possible types:_ - [RpcCondition](#rpccondition) - [TimeCondition](#timecondition) +- [WalletAllowlistCondition](#walletallowlistcondition) - [ContractCondition](#contractcondition) - [CompoundCondition](#compoundcondition) - [JsonApiCondition](#jsonapicondition) @@ -255,6 +256,19 @@ _Object containing the following properties:_ _(\*) Required._ +## WalletAllowlistCondition + +A condition that is satisfied when the requester proves control of one of the specified wallet addresses by signing a message. + +_Object containing the following properties:_ + +| Property | Description | Type | +| :----------------------- | :------------------------------------------------------------------------- | :---------------------------------- | +| **`conditionType`** (\*) | | `'wallet-allowlist'` | +| **`addresses`** (\*) | List of wallet addresses allowed to decrypt. Matching is case-insensitive. | `Array` (_min: 1, max: 10_) | + +_(\*) Required._ + ## More resources For more information, please refer to the TACo documentation: diff --git a/packages/taco/src/conditions/base/index.ts b/packages/taco/src/conditions/base/index.ts index 6de843d86..6de86b400 100644 --- a/packages/taco/src/conditions/base/index.ts +++ b/packages/taco/src/conditions/base/index.ts @@ -1,6 +1,7 @@ // Exporting classes here instead of their respective schema files to // avoid circular dependency on Condition class. +export * as walletAllowlist from './wallet-allowlist'; export * as contract from './contract'; export * as jsonApi from './json-api'; export * as jsonRpc from './json-rpc'; diff --git a/packages/taco/src/conditions/base/wallet-allowlist.ts b/packages/taco/src/conditions/base/wallet-allowlist.ts new file mode 100644 index 000000000..9de2df933 --- /dev/null +++ b/packages/taco/src/conditions/base/wallet-allowlist.ts @@ -0,0 +1,27 @@ +import { Condition } from '../condition'; +import { + WalletAllowlistConditionProps, + walletAllowlistConditionSchema, + WalletAllowlistConditionType, +} from '../schemas/wallet-allowlist'; +import { OmitConditionType } from '../shared'; +export { WalletAllowlistConditionProps, WalletAllowlistConditionType }; + +/** + * A condition that checks if a wallet address is in a list of allowed addresses. + */ +export class WalletAllowlistCondition extends Condition { + constructor(value: OmitConditionType) { + super(walletAllowlistConditionSchema, { + conditionType: WalletAllowlistConditionType, + ...value, + }); + } + + /** + * This condition requires wallet authentication to verify addresses + */ + override requiresAuthentication(): boolean { + return true; + } +} diff --git a/packages/taco/src/conditions/condition-factory.ts b/packages/taco/src/conditions/condition-factory.ts index ab84ae909..43335bec9 100644 --- a/packages/taco/src/conditions/condition-factory.ts +++ b/packages/taco/src/conditions/condition-factory.ts @@ -20,6 +20,11 @@ import { TimeConditionProps, TimeConditionType, } from './base/time'; +import { + WalletAllowlistCondition, + WalletAllowlistConditionProps, + WalletAllowlistConditionType, +} from './base/wallet-allowlist'; import { CompoundCondition, CompoundConditionProps, @@ -56,6 +61,8 @@ export class ConditionFactory { return new JsonRpcCondition(props as JsonRpcConditionProps); case JWTConditionType: return new JWTCondition(props as JWTConditionProps); + case WalletAllowlistConditionType: + return new WalletAllowlistCondition(props as WalletAllowlistConditionProps); // Logical Conditions case CompoundConditionType: return new CompoundCondition(props as CompoundConditionProps); diff --git a/packages/taco/src/conditions/predefined/index.ts b/packages/taco/src/conditions/predefined/index.ts index 7d29ceb02..cc565a42d 100644 --- a/packages/taco/src/conditions/predefined/index.ts +++ b/packages/taco/src/conditions/predefined/index.ts @@ -1,2 +1,3 @@ +export * as walletAllowlist from './wallet-allowlist'; export * as erc20 from './erc20'; export * as erc721 from './erc721'; diff --git a/packages/taco/src/conditions/predefined/wallet-allowlist.ts b/packages/taco/src/conditions/predefined/wallet-allowlist.ts new file mode 100644 index 000000000..4d9b9ea59 --- /dev/null +++ b/packages/taco/src/conditions/predefined/wallet-allowlist.ts @@ -0,0 +1,29 @@ +import { WalletAllowlistCondition } from '../base/wallet-allowlist'; +import { + WalletAllowlistConditionProps, + WalletAllowlistFields, +} from '../schemas/wallet-allowlist'; + +// Default values (currently none) +export const WalletAllowlistDefaults = {}; + +/** + * A condition that grants decryption permissions to specific wallet addresses. + * The condition is satisfied when the requester can prove they control one of + * the specified addresses. + * + * The requester must prove control of one of the specified addresses (handled by + * upstream authentication providers such as EIP-4361 or EIP-1271). + * + * This is a gas-free condition as it doesn't require any on-chain transactions. + */ +export class WalletOwnership extends WalletAllowlistCondition { + constructor( + value: Pick< + WalletAllowlistConditionProps, + WalletAllowlistFields + >, + ) { + super({ ...WalletAllowlistDefaults, ...value }); + } +} diff --git a/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts b/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts index 36e6cfa24..8f2d8a706 100755 --- a/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts +++ b/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts @@ -19,3 +19,5 @@ export * from './return-value-test'; export * from './rpc'; export * from './sequential'; export * from './time'; +// ts-unused-exports:disable-next-line - this comment line is added to prevent lint from changing or objecting the export order. +export * from './wallet-allowlist'; diff --git a/packages/taco/src/conditions/schemas/index.ts b/packages/taco/src/conditions/schemas/index.ts new file mode 100644 index 000000000..81202cd93 --- /dev/null +++ b/packages/taco/src/conditions/schemas/index.ts @@ -0,0 +1,16 @@ +// Export all schemas + +export * from './common'; +export * from './compound'; +export * from './context'; +export * from './contract'; +export * from './wallet-allowlist'; +export * from './if-then-else'; +export * from './json-api'; +export * from './json-rpc'; +export * from './jwt'; +export * from './return-value-test'; +export * from './rpc'; +export * from './sequential'; +export * from './time'; +export * from './utils'; diff --git a/packages/taco/src/conditions/schemas/utils.ts b/packages/taco/src/conditions/schemas/utils.ts index abd14f36b..f0d3d1936 100644 --- a/packages/taco/src/conditions/schemas/utils.ts +++ b/packages/taco/src/conditions/schemas/utils.ts @@ -2,6 +2,7 @@ import { z } from 'zod'; import { compoundConditionSchema } from '../compound-condition'; + import { contractConditionSchema } from './contract'; import { ifThenElseConditionSchema } from './if-then-else'; import { jsonApiConditionSchema } from './json-api'; @@ -10,11 +11,13 @@ import { jwtConditionSchema } from './jwt'; import { rpcConditionSchema } from './rpc'; import { sequentialConditionSchema } from './sequential'; import { timeConditionSchema } from './time'; +import { walletAllowlistConditionSchema } from './wallet-allowlist'; export const anyConditionSchema: z.ZodSchema = z.lazy(() => z.union([ rpcConditionSchema, timeConditionSchema, + walletAllowlistConditionSchema, contractConditionSchema, compoundConditionSchema, jsonApiConditionSchema, diff --git a/packages/taco/src/conditions/schemas/wallet-allowlist.ts b/packages/taco/src/conditions/schemas/wallet-allowlist.ts new file mode 100644 index 000000000..6bb6c942c --- /dev/null +++ b/packages/taco/src/conditions/schemas/wallet-allowlist.ts @@ -0,0 +1,38 @@ +import { EthAddressSchema } from '@nucypher/shared'; +import { ethers } from 'ethers'; +import { z } from 'zod'; + +import { baseConditionSchema } from './common'; + +export const WalletAllowlistConditionType = 'wallet-allowlist'; + +export const walletAllowlistConditionSchema = baseConditionSchema + .extend({ + conditionType: z.literal(WalletAllowlistConditionType), + addresses: z + .array(EthAddressSchema) + .min(1, 'At least one address must be provided') + .max(10, 'Maximum of 10 addresses allowed') + // Ensure all addresses are valid Ethereum addresses with proper checksum + .refine((addrs) => { + try { + return addrs.every((addr) => { + // Then verify it has the correct checksum (comparing to canonical form) + return addr === ethers.utils.getAddress(addr); + }); + } catch (e) { + // If any error occurs during validation, fail the validation + return false; + } + }, 'All addresses must be properly checksummed') + .describe( + 'List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form. Matching is case-sensitive.', + ), + }) + .strict(); + +export type WalletAllowlistConditionProps = z.infer< + typeof walletAllowlistConditionSchema +>; + +export type WalletAllowlistFields = 'addresses'; diff --git a/packages/taco/test/conditions/base/wallet-allowlist.test.ts b/packages/taco/test/conditions/base/wallet-allowlist.test.ts new file mode 100644 index 000000000..b3d81b906 --- /dev/null +++ b/packages/taco/test/conditions/base/wallet-allowlist.test.ts @@ -0,0 +1,227 @@ +import { describe, expect, it } from 'vitest'; + +import { + WalletAllowlistCondition, + WalletAllowlistConditionProps, +} from '../../../src/conditions/base/wallet-allowlist'; +import { + walletAllowlistConditionSchema, + WalletAllowlistConditionType, +} from '../../../src/conditions/schemas/wallet-allowlist'; +import { testWalletAllowlistConditionObj } from '../../test-utils'; + +describe('WalletAllowlistCondition', () => { + describe('validate', () => { + it('accepts valid condition object', () => { + const result = WalletAllowlistCondition.validate( + walletAllowlistConditionSchema, + testWalletAllowlistConditionObj, + ); + + expect(result.error).toBeUndefined(); + expect(result.data).toEqual(testWalletAllowlistConditionObj); + }); + + it('fills in conditionType if missing', () => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { conditionType: _, ...withoutType } = + testWalletAllowlistConditionObj; + const condition = new WalletAllowlistCondition(withoutType); + + expect(condition.toObj().conditionType).toBe( + WalletAllowlistConditionType, + ); + }); + + it('rejects unknown fields', () => { + const conditionObj = { + ...testWalletAllowlistConditionObj, + unknownField: 'unknown', + } as unknown as WalletAllowlistConditionProps; + + const result = WalletAllowlistCondition.validate( + walletAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + // The error format for unknown fields is just a top-level _errors array + expect(result.error?.format()).toMatchObject({ + _errors: ["Unrecognized key(s) in object: 'unknownField'"], + }); + }); + + it('rejects empty addresses array', () => { + const conditionObj = { + ...testWalletAllowlistConditionObj, + addresses: [], + }; + + const result = WalletAllowlistCondition.validate( + walletAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + addresses: { + _errors: ['At least one address must be provided'], + }, + }); + }); + + it('rejects too many addresses (more than 10)', () => { + const tooManyAddresses = Array(11).fill( + '0x1234567890123456789012345678901234567890', + ); + const conditionObj = { + ...testWalletAllowlistConditionObj, + addresses: tooManyAddresses, + }; + + const result = WalletAllowlistCondition.validate( + walletAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + addresses: { + _errors: ['Maximum of 10 addresses allowed'], + }, + }); + }); + + it('accepts single address', () => { + const conditionObj = { + ...testWalletAllowlistConditionObj, + addresses: ['0x1234567890123456789012345678901234567890'], + }; + + const result = WalletAllowlistCondition.validate( + walletAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeUndefined(); + expect(result.data).toBeDefined(); + }); + + it('checks for valid ethereum addresses', () => { + const conditionObj = { + ...testWalletAllowlistConditionObj, + addresses: ['not-an-ethereum-address'], + }; + + const result = WalletAllowlistCondition.validate( + walletAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + addresses: { + 0: { + _errors: ['Invalid Ethereum address'], + }, + }, + }); + }); + + it('rejects non-array addresses', () => { + const conditionObj = { + ...testWalletAllowlistConditionObj, + addresses: 'single-address' as unknown as string[], + }; + + const result = WalletAllowlistCondition.validate( + walletAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + addresses: { + _errors: ['Expected array, received string'], + }, + }); + }); + + it('rejects non-checksummed addresses', () => { + // This is a valid address but with mixed case that doesn't match checksum format + // 0xE247A45c287191d435A8a5D72A7C8dc030451E9F (correct checksum) + // vs + // 0xe247a45c287191d435A8a5D72A7C8dc030451E9F (incorrect checksum) + const conditionObj = { + ...testWalletAllowlistConditionObj, + // Mixed case that doesn't follow checksum format + addresses: ['0xe247a45c287191d435A8a5D72A7C8dc030451E9F'], + }; + + const result = WalletAllowlistCondition.validate( + walletAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + addresses: { + _errors: ['All addresses must be properly checksummed'], + }, + }); + }); + }); + + describe('constructor', () => { + it('creates a condition from a valid object', () => { + const condition = new WalletAllowlistCondition( + testWalletAllowlistConditionObj, + ); + expect(condition).toBeDefined(); + }); + + it('fails to create a condition from an invalid object', () => { + const invalidCondition = () => { + // This will throw at runtime when validation occurs + return new WalletAllowlistCondition({ + ...testWalletAllowlistConditionObj, + addresses: [] as string[], // Empty array will fail validation + }); + }; + + // The error is wrapped in a general Error with message containing the Zod validation error + expect(invalidCondition).toThrow(/Invalid condition/); + }); + + it('retains the original addresses order', () => { + const addresses = [ + '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', + '0x0000000000000000000000000000000000000001', + '0x0000000000000000000000000000000000000002', + ]; + + const conditionObj = { + ...testWalletAllowlistConditionObj, + addresses, + }; + const condition = new WalletAllowlistCondition(conditionObj); + + expect(condition.toObj().addresses).toEqual(addresses); + }); + }); + + describe('requiresAuthentication', () => { + it('returns true', () => { + const condition = new WalletAllowlistCondition( + testWalletAllowlistConditionObj, + ); + expect(condition.requiresAuthentication()).toBe(true); + }); + }); +}); diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 5beac4443..1abe7b256 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -69,6 +69,10 @@ import { JsonRpcConditionProps, JsonRpcConditionType, } from '../src/conditions/schemas/json-rpc'; +import { + WalletAllowlistConditionProps, + WalletAllowlistConditionType, +} from '../src/conditions/schemas/wallet-allowlist'; import { SequentialConditionProps, SequentialConditionType, @@ -294,6 +298,16 @@ export const testRpcConditionObj: RpcConditionProps = { returnValueTest: testRpcReturnValueTest, }; +export const testWalletAllowlistConditionObj: WalletAllowlistConditionProps = + { + conditionType: WalletAllowlistConditionType, + addresses: [ + '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', + '0x0000000000000000000000000000000000000001', + '0x0000000000000000000000000000000000000002', + ], + }; + export const testContractConditionObj: ContractConditionProps = { conditionType: ContractConditionType, contractAddress: '0x0000000000000000000000000000000000000000', From 481dd5abf4dad778e2fd0a00a19fb8131e82cbaf Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Wed, 4 Jun 2025 10:09:03 +0200 Subject: [PATCH 014/303] updated the schema doc and removed an unnecessary class --- .../taco/examples/wallet-allowlist-example.ts | 56 ------------------- .../taco/schema-docs/condition-schemas.md | 10 ++-- .../taco/src/conditions/predefined/index.ts | 1 - .../conditions/predefined/wallet-allowlist.ts | 29 ---------- 4 files changed, 4 insertions(+), 92 deletions(-) delete mode 100644 packages/taco/examples/wallet-allowlist-example.ts delete mode 100644 packages/taco/src/conditions/predefined/wallet-allowlist.ts diff --git a/packages/taco/examples/wallet-allowlist-example.ts b/packages/taco/examples/wallet-allowlist-example.ts deleted file mode 100644 index 0ed584327..000000000 --- a/packages/taco/examples/wallet-allowlist-example.ts +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Example demonstrating how to use the WalletAllowlistCondition - * - * This is a gas-free, off-chain condition that grants decryption permissions - * to a predefined list of wallet addresses. - */ - -async function walletAllowlistExample() { - // Import the relevant modules - const taco = await import('../src/index'); - const { predefined } = await import('../src/conditions'); - - console.log('Wallet Allowlist Example'); - - // Create a simple condition allowing specific wallet addresses to decrypt - // Addresses must be in checksummed format - // The condition is satisfied when the requester proves control of one of the - // specified addresses (through wallet signature verification handled by auth providers) - const walletCondition = new predefined.walletAllowlist.WalletOwnership({ - addresses: [ - '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', - '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', - '0x0000000000000000000000000000000000000001', - ], - }); - - // View the condition's object representation - what gets stored on-chain - console.log('Wallet Allowlist Condition:', walletCondition.toObj()); - - // In a real app, you would encrypt data with this condition - // const encrypter = await taco.conditions.getEncrypter({ - // conditions: walletCondition, - // }); - // const ciphertext = await encrypter.encrypt('secret data'); - - // Check if a specific address is in the allowlist - const addresses = walletCondition.toObj().addresses; - const addressToCheck = '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77'; - const isAllowed = addresses.some( - (addr: string) => addr.toLowerCase() === addressToCheck.toLowerCase() - ); - - console.log(`Is address ${addressToCheck} allowed? ${isAllowed}`); - - // Check a non-allowed address - const nonAllowedAddress = '0x0000000000000000000000000000000000000099'; - const isNonAllowedAddressAllowed = addresses.some( - (addr: string) => addr.toLowerCase() === nonAllowedAddress.toLowerCase() - ); - - console.log( - `Is address ${nonAllowedAddress} allowed? ${isNonAllowedAddressAllowed}` - ); -} - -walletAllowlistExample().catch(console.error); diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index 6a7623665..4de877227 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -258,14 +258,12 @@ _(\*) Required._ ## WalletAllowlistCondition -A condition that is satisfied when the requester proves control of one of the specified wallet addresses by signing a message. - _Object containing the following properties:_ -| Property | Description | Type | -| :----------------------- | :------------------------------------------------------------------------- | :---------------------------------- | -| **`conditionType`** (\*) | | `'wallet-allowlist'` | -| **`addresses`** (\*) | List of wallet addresses allowed to decrypt. Matching is case-insensitive. | `Array` (_min: 1, max: 10_) | +| Property | Description | Type | +| :----------------------- | :------------------------------------------------------------------------------------------------------------------------- | :---------------------------------- | +| **`conditionType`** (\*) | | `'wallet-allowlist'` | +| **`addresses`** (\*) | List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form. Matching is case-sensitive. | `Array` (_min: 1, max: 10_) | _(\*) Required._ diff --git a/packages/taco/src/conditions/predefined/index.ts b/packages/taco/src/conditions/predefined/index.ts index cc565a42d..7d29ceb02 100644 --- a/packages/taco/src/conditions/predefined/index.ts +++ b/packages/taco/src/conditions/predefined/index.ts @@ -1,3 +1,2 @@ -export * as walletAllowlist from './wallet-allowlist'; export * as erc20 from './erc20'; export * as erc721 from './erc721'; diff --git a/packages/taco/src/conditions/predefined/wallet-allowlist.ts b/packages/taco/src/conditions/predefined/wallet-allowlist.ts deleted file mode 100644 index 4d9b9ea59..000000000 --- a/packages/taco/src/conditions/predefined/wallet-allowlist.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { WalletAllowlistCondition } from '../base/wallet-allowlist'; -import { - WalletAllowlistConditionProps, - WalletAllowlistFields, -} from '../schemas/wallet-allowlist'; - -// Default values (currently none) -export const WalletAllowlistDefaults = {}; - -/** - * A condition that grants decryption permissions to specific wallet addresses. - * The condition is satisfied when the requester can prove they control one of - * the specified addresses. - * - * The requester must prove control of one of the specified addresses (handled by - * upstream authentication providers such as EIP-4361 or EIP-1271). - * - * This is a gas-free condition as it doesn't require any on-chain transactions. - */ -export class WalletOwnership extends WalletAllowlistCondition { - constructor( - value: Pick< - WalletAllowlistConditionProps, - WalletAllowlistFields - >, - ) { - super({ ...WalletAllowlistDefaults, ...value }); - } -} From 30adf1364dfc544b28c9c72d8711824eb2938d63 Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Wed, 4 Jun 2025 10:36:02 +0200 Subject: [PATCH 015/303] add simple creation example and an integration test --- packages/taco/examples/conditions.ts | 22 +++++++ .../integration-test/encrypt-decrypt.test.ts | 64 ++++++++++++++++++- 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/packages/taco/examples/conditions.ts b/packages/taco/examples/conditions.ts index 3ac71b0e0..c242e3073 100644 --- a/packages/taco/examples/conditions.ts +++ b/packages/taco/examples/conditions.ts @@ -124,3 +124,25 @@ console.assert( !myContractCallCondition.requiresAuthentication(), 'ContractCondition does not require a signer', ); + +// Wallet Allowlist Condition Example +const walletAllowlistCondition = new conditions.base.walletAllowlist.WalletAllowlistCondition({ + addresses: [ + '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', + '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', + '0x0000000000000000000000000000000000000001', + ], +}); + +console.assert( + walletAllowlistCondition.requiresAuthentication(), + 'WalletAllowlistCondition requires authentication', +); + +// You can check if an address is allowed with the condition's toObj method +const addressToCheck = '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77'; +const addresses = walletAllowlistCondition.toObj().addresses; +const isAllowed = addresses.some( + (addr: string) => addr.toLowerCase() === addressToCheck.toLowerCase(), +); +console.log(`Is address ${addressToCheck} allowed? ${isAllowed}`); diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index db1482940..1c439c347 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -25,6 +25,9 @@ const DOMAIN = 'lynx'; const RITUAL_ID = 27; const CHAIN_ID = 80002; +// The wallet address of our consumer (derived from CONSUMER_PRIVATE_KEY) +const CONSUMER_ADDRESS = '0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed'; + describe.skipIf(!process.env.RUNNING_IN_CI)( 'Taco Encrypt/Decrypt Integration Test', () => { @@ -49,7 +52,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( } }); - test('should encrypt and decrypt a message with large condition values', async (value) => { + test('should encrypt and decrypt a message with RPC balance condition less than UINT256_MAX', async (value) => { // Create test message const messageString = 'This is a secret 🤐'; const message = toBytes(messageString); @@ -128,5 +131,64 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( // Verify decryption expect(decryptedMessageString).toEqual(messageString); }, 15000); // 15s timeout + + test('should encrypt and decrypt according to wallet allowlist condition', async () => { + // Create test message + const messageString = + 'This message should only be accessible to allowed wallet addresses'; + const message = toBytes(messageString); + + // Create wallet allowlist condition with consumer address in the list + const walletAllowlistCondition = + new conditions.base.walletAllowlist.WalletAllowlistCondition({ + addresses: [ + CONSUMER_ADDRESS, + '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', // Some other address + '0x0000000000000000000000000000000000000001', // Another address + ], + }); + + // Verify that the condition requires authentication + expect(walletAllowlistCondition.requiresAuthentication()).toBe(true); + + // Encrypt message with the wallet allowlist condition + const messageKit = await encrypt( + provider, + DOMAIN, + message, + walletAllowlistCondition, + RITUAL_ID, + encryptorSigner, + ); + + const encryptedBytes = messageKit.toBytes(); + + // Prepare for decryption + const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); + const conditionContext = + conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); + + // Add auth provider for the consumer wallet + const authProvider = new EIP4361AuthProvider(provider, consumerSigner, { + domain: 'localhost', + uri: 'http://localhost:3000', + }); + conditionContext.addAuthProvider( + USER_ADDRESS_PARAM_DEFAULT, + authProvider, + ); + + // Decrypt message + const decryptedBytes = await decrypt( + provider, + DOMAIN, + messageKitFromBytes, + conditionContext, + ); + const decryptedMessageString = fromBytes(decryptedBytes); + + // Verify decryption was successful + expect(decryptedMessageString).toEqual(messageString); + }, 15000); // 15s timeout }, ); From e52b353710103c52f250a45b071fa02926a02b2b Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Thu, 5 Jun 2025 04:06:50 +0200 Subject: [PATCH 016/303] allow up to 25 in the wallet allowlist condition --- packages/taco/schema-docs/condition-schemas.md | 2 +- packages/taco/src/conditions/schemas/wallet-allowlist.ts | 2 +- packages/taco/test/conditions/base/wallet-allowlist.test.ts | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index 4de877227..94230bed3 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -263,7 +263,7 @@ _Object containing the following properties:_ | Property | Description | Type | | :----------------------- | :------------------------------------------------------------------------------------------------------------------------- | :---------------------------------- | | **`conditionType`** (\*) | | `'wallet-allowlist'` | -| **`addresses`** (\*) | List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form. Matching is case-sensitive. | `Array` (_min: 1, max: 10_) | +| **`addresses`** (\*) | List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form. Matching is case-sensitive. | `Array` (_min: 1, max: 25_) | _(\*) Required._ diff --git a/packages/taco/src/conditions/schemas/wallet-allowlist.ts b/packages/taco/src/conditions/schemas/wallet-allowlist.ts index 6bb6c942c..f6c2e8091 100644 --- a/packages/taco/src/conditions/schemas/wallet-allowlist.ts +++ b/packages/taco/src/conditions/schemas/wallet-allowlist.ts @@ -12,7 +12,7 @@ export const walletAllowlistConditionSchema = baseConditionSchema addresses: z .array(EthAddressSchema) .min(1, 'At least one address must be provided') - .max(10, 'Maximum of 10 addresses allowed') + .max(25, 'Maximum of 25 addresses allowed') // Ensure all addresses are valid Ethereum addresses with proper checksum .refine((addrs) => { try { diff --git a/packages/taco/test/conditions/base/wallet-allowlist.test.ts b/packages/taco/test/conditions/base/wallet-allowlist.test.ts index b3d81b906..c60947c6f 100644 --- a/packages/taco/test/conditions/base/wallet-allowlist.test.ts +++ b/packages/taco/test/conditions/base/wallet-allowlist.test.ts @@ -72,8 +72,8 @@ describe('WalletAllowlistCondition', () => { }); }); - it('rejects too many addresses (more than 10)', () => { - const tooManyAddresses = Array(11).fill( + it('rejects too many addresses (more than 25)', () => { + const tooManyAddresses = Array(26).fill( '0x1234567890123456789012345678901234567890', ); const conditionObj = { @@ -90,7 +90,7 @@ describe('WalletAllowlistCondition', () => { expect(result.data).toBeUndefined(); expect(result.error?.format()).toMatchObject({ addresses: { - _errors: ['Maximum of 10 addresses allowed'], + _errors: ['Maximum of 25 addresses allowed'], }, }); }); From c3fa2f30432c5033661baf8dcc5dc86e9eb191aa Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Thu, 5 Jun 2025 05:53:26 +0200 Subject: [PATCH 017/303] skip an integration test till it is ready --- packages/taco/integration-test/encrypt-decrypt.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index 1c439c347..d984cc911 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -132,7 +132,8 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( expect(decryptedMessageString).toEqual(messageString); }, 15000); // 15s timeout - test('should encrypt and decrypt according to wallet allowlist condition', async () => { + // TODO: Unskip this test when wallet allowlist condition is implemented and running at the nodes as per https://github.com/nucypher/nucypher/issues/3600 + test.skip('should encrypt and decrypt according to wallet allowlist condition', async () => { // Create test message const messageString = 'This message should only be accessible to allowed wallet addresses'; From f7cbd442fb68f46a4cef334d6b9c233d1fe88028 Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Thu, 5 Jun 2025 06:07:03 +0200 Subject: [PATCH 018/303] tiny enhancement --- packages/taco/examples/conditions.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/taco/examples/conditions.ts b/packages/taco/examples/conditions.ts index c242e3073..ecc886719 100644 --- a/packages/taco/examples/conditions.ts +++ b/packages/taco/examples/conditions.ts @@ -126,13 +126,14 @@ console.assert( ); // Wallet Allowlist Condition Example -const walletAllowlistCondition = new conditions.base.walletAllowlist.WalletAllowlistCondition({ - addresses: [ - '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', - '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', - '0x0000000000000000000000000000000000000001', - ], -}); +const walletAllowlistCondition = + new conditions.base.walletAllowlist.WalletAllowlistCondition({ + addresses: [ + '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', + '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', + '0x0000000000000000000000000000000000000001', + ], + }); console.assert( walletAllowlistCondition.requiresAuthentication(), @@ -142,7 +143,6 @@ console.assert( // You can check if an address is allowed with the condition's toObj method const addressToCheck = '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77'; const addresses = walletAllowlistCondition.toObj().addresses; -const isAllowed = addresses.some( - (addr: string) => addr.toLowerCase() === addressToCheck.toLowerCase(), -); +// This would be checked by taco nodes after validating the wallet signature provided by encryptor (the value of the variable `addressToCheck`). +const isAllowed = addresses.includes(addressToCheck); console.log(`Is address ${addressToCheck} allowed? ${isAllowed}`); From ab437f4500cbcec590a0675d2833e31400a6444e Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Fri, 6 Jun 2025 00:55:09 +0200 Subject: [PATCH 019/303] rename WalletAllowlist to AddressAllowlist --- packages/taco/examples/conditions.ts | 10 +- .../integration-test/encrypt-decrypt.test.ts | 8 +- .../taco/schema-docs/condition-schemas.md | 46 ++-- .../src/conditions/base/address-allowlist.ts | 27 +++ packages/taco/src/conditions/base/index.ts | 2 +- .../src/conditions/base/wallet-allowlist.ts | 27 --- .../taco/src/conditions/condition-factory.ts | 16 +- ...llet-allowlist.ts => address-allowlist.ts} | 12 +- .../schemas/export-for-zod-doc-gen.ts | 2 +- packages/taco/src/conditions/schemas/index.ts | 2 +- packages/taco/src/conditions/schemas/utils.ts | 5 +- .../conditions/base/address-allowlist.test.ts | 165 +++++++++++++ .../conditions/base/wallet-allowlist.test.ts | 227 ------------------ packages/taco/test/test-utils.ts | 12 +- 14 files changed, 254 insertions(+), 307 deletions(-) create mode 100644 packages/taco/src/conditions/base/address-allowlist.ts delete mode 100644 packages/taco/src/conditions/base/wallet-allowlist.ts rename packages/taco/src/conditions/schemas/{wallet-allowlist.ts => address-allowlist.ts} (74%) create mode 100644 packages/taco/test/conditions/base/address-allowlist.test.ts delete mode 100644 packages/taco/test/conditions/base/wallet-allowlist.test.ts diff --git a/packages/taco/examples/conditions.ts b/packages/taco/examples/conditions.ts index ecc886719..2921c27e8 100644 --- a/packages/taco/examples/conditions.ts +++ b/packages/taco/examples/conditions.ts @@ -126,8 +126,8 @@ console.assert( ); // Wallet Allowlist Condition Example -const walletAllowlistCondition = - new conditions.base.walletAllowlist.WalletAllowlistCondition({ +const addressAllowlistCondition = + new conditions.base.addressAllowlist.AddressAllowlistCondition({ addresses: [ '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', @@ -136,13 +136,13 @@ const walletAllowlistCondition = }); console.assert( - walletAllowlistCondition.requiresAuthentication(), - 'WalletAllowlistCondition requires authentication', + addressAllowlistCondition.requiresAuthentication(), + 'AddressAllowlistCondition requires authentication', ); // You can check if an address is allowed with the condition's toObj method const addressToCheck = '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77'; -const addresses = walletAllowlistCondition.toObj().addresses; +const addresses = addressAllowlistCondition.toObj().addresses; // This would be checked by taco nodes after validating the wallet signature provided by encryptor (the value of the variable `addressToCheck`). const isAllowed = addresses.includes(addressToCheck); console.log(`Is address ${addressToCheck} allowed? ${isAllowed}`); diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index d984cc911..a51d6f318 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -140,8 +140,8 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const message = toBytes(messageString); // Create wallet allowlist condition with consumer address in the list - const walletAllowlistCondition = - new conditions.base.walletAllowlist.WalletAllowlistCondition({ + const addressAllowlistCondition = + new conditions.base.addressAllowlist.AddressAllowlistCondition({ addresses: [ CONSUMER_ADDRESS, '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', // Some other address @@ -150,14 +150,14 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( }); // Verify that the condition requires authentication - expect(walletAllowlistCondition.requiresAuthentication()).toBe(true); + expect(addressAllowlistCondition.requiresAuthentication()).toBe(true); // Encrypt message with the wallet allowlist condition const messageKit = await encrypt( provider, DOMAIN, message, - walletAllowlistCondition, + addressAllowlistCondition, RITUAL_ID, encryptorSigner, ); diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index 94230bed3..d98b82a92 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -6,7 +6,7 @@ _Union of the following possible types:_ - [RpcCondition](#rpccondition) - [TimeCondition](#timecondition) -- [WalletAllowlistCondition](#walletallowlistcondition) +- [AddressAllowlistCondition](#walletallowlistcondition) - [ContractCondition](#contractcondition) - [CompoundCondition](#compoundcondition) - [JsonApiCondition](#jsonapicondition) @@ -17,7 +17,8 @@ _Union of the following possible types:_ ## UserAddress -This is a context variable that will be replaced at decryption time. It represents the Ethereum address of the requester attempting decryption. +This is a context variable that will be replaced at decryption time. It +represents the Ethereum address of the requester attempting decryption. _Literal `':userAddress'` value._ @@ -51,15 +52,20 @@ _String._ _Union of the following possible types:_ -- [PlainString](#plainstring), `boolean`, `number` (_int, ≥-9007199254740991, ≤9007199254740991_) _or_ `bigint` (_≤115792089237316195423570985008687907853269984665640564039457584007913129639935, ≥-57896044618658097711785492504343953926634992332820282019728792003956564819968_) +- [PlainString](#plainstring), `boolean`, `number` (_int, ≥-9007199254740991, + ≤9007199254740991_) _or_ `bigint` + (_≤115792089237316195423570985008687907853269984665640564039457584007913129639935, + ≥-57896044618658097711785492504343953926634992332820282019728792003956564819968_) - [ContextParam](#contextparam) -- _Array of [BlockchainParamOrContextParam](#blockchainparamorcontextparam) items_ +- _Array of [BlockchainParamOrContextParam](#blockchainparamorcontextparam) + items_ ## ContextParam -A Context Parameter i.e. a placeholder used within conditions and specified at the encryption time, whose value is provided at decryption time. +A Context Parameter i.e. a placeholder used within conditions and specified at +the encryption time, whose value is provided at decryption time. -_String which matches the regular expression `/^:[a-zA-Z_][a-zA-Z0-9_]*$/`._ +_String which matches the regular expression `/^:[a-zA-Z_][a-zA-Z0-9_]\*$/`.\_ ## ParamOrContextParam @@ -73,11 +79,11 @@ _Union of the following possible types:_ _Object containing the following properties:_ -| Property | Type | Default | -| :------------------ | :------------------------------------------------------------------------ | :----------- | -| `conditionType` | `'compound'` | `'compound'` | -| **`operator`** (\*) | `'and' \| 'or' \| 'not'` | | -| **`operands`** (\*) | _Array of at least 1 and at most 5 [AnyCondition](#anycondition) items_ | | +| Property | Type | Default | +| :------------------ | :---------------------------------------------------------------------- | :----------- | +| `conditionType` | `'compound'` | `'compound'` | +| **`operator`** (\*) | `'and' \| 'or' \| 'not'` | | +| **`operands`** (\*) | _Array of at least 1 and at most 5 [AnyCondition](#anycondition) items_ | | _(\*) Required._ @@ -207,7 +213,8 @@ _(\*) Required._ ## RpcCondition -RPC Condition for calling [Ethereum JSON RPC APIs](https://ethereum.github.io/execution-apis/api-documentation/) +RPC Condition for calling +[Ethereum JSON RPC APIs](https://ethereum.github.io/execution-apis/api-documentation/) _Object containing the following properties:_ @@ -236,10 +243,10 @@ _(\*) Required._ _Object containing the following properties:_ -| Property | Type | Default | -| :---------------------------- | :---------------------------------------------------------------------------------- | :------------- | -| `conditionType` | `'sequential'` | `'sequential'` | -| **`conditionVariables`** (\*) | _Array of at least 2 and at most 5 [ConditionVariable](#conditionvariable) items_ | | +| Property | Type | Default | +| :---------------------------- | :-------------------------------------------------------------------------------- | :------------- | +| `conditionType` | `'sequential'` | `'sequential'` | +| **`conditionVariables`** (\*) | _Array of at least 2 and at most 5 [ConditionVariable](#conditionvariable) items_ | | _(\*) Required._ @@ -256,13 +263,13 @@ _Object containing the following properties:_ _(\*) Required._ -## WalletAllowlistCondition +## AddressAllowlistCondition _Object containing the following properties:_ | Property | Description | Type | | :----------------------- | :------------------------------------------------------------------------------------------------------------------------- | :---------------------------------- | -| **`conditionType`** (\*) | | `'wallet-allowlist'` | +| **`conditionType`** (\*) | | `'address-allowlist'` | | **`addresses`** (\*) | List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form. Matching is case-sensitive. | `Array` (_min: 1, max: 25_) | _(\*) Required._ @@ -272,4 +279,5 @@ _(\*) Required._ For more information, please refer to the TACo documentation: https://docs.taco.build/. -Visit the TACo Playground to see the condition schemas in action: https://playground.taco.build/. +Visit the TACo Playground to see the condition schemas in action: +https://playground.taco.build/. diff --git a/packages/taco/src/conditions/base/address-allowlist.ts b/packages/taco/src/conditions/base/address-allowlist.ts new file mode 100644 index 000000000..baa126c70 --- /dev/null +++ b/packages/taco/src/conditions/base/address-allowlist.ts @@ -0,0 +1,27 @@ +import { Condition } from '../condition'; +import { + AddressAllowlistConditionProps, + addressAllowlistConditionSchema, + AddressAllowlistConditionType, +} from '../schemas/address-allowlist'; +import { OmitConditionType } from '../shared'; +export { AddressAllowlistConditionProps, AddressAllowlistConditionType }; + +/** + * A condition that checks if a wallet address is in a list of allowed addresses. + */ +export class AddressAllowlistCondition extends Condition { + constructor(value: OmitConditionType) { + super(addressAllowlistConditionSchema, { + conditionType: AddressAllowlistConditionType, + ...value, + }); + } + + /** + * This condition requires wallet authentication to verify addresses + */ + override requiresAuthentication(): boolean { + return true; + } +} diff --git a/packages/taco/src/conditions/base/index.ts b/packages/taco/src/conditions/base/index.ts index 6de86b400..cc6a33328 100644 --- a/packages/taco/src/conditions/base/index.ts +++ b/packages/taco/src/conditions/base/index.ts @@ -1,7 +1,7 @@ // Exporting classes here instead of their respective schema files to // avoid circular dependency on Condition class. -export * as walletAllowlist from './wallet-allowlist'; +export * as addressAllowlist from './address-allowlist'; export * as contract from './contract'; export * as jsonApi from './json-api'; export * as jsonRpc from './json-rpc'; diff --git a/packages/taco/src/conditions/base/wallet-allowlist.ts b/packages/taco/src/conditions/base/wallet-allowlist.ts deleted file mode 100644 index 9de2df933..000000000 --- a/packages/taco/src/conditions/base/wallet-allowlist.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Condition } from '../condition'; -import { - WalletAllowlistConditionProps, - walletAllowlistConditionSchema, - WalletAllowlistConditionType, -} from '../schemas/wallet-allowlist'; -import { OmitConditionType } from '../shared'; -export { WalletAllowlistConditionProps, WalletAllowlistConditionType }; - -/** - * A condition that checks if a wallet address is in a list of allowed addresses. - */ -export class WalletAllowlistCondition extends Condition { - constructor(value: OmitConditionType) { - super(walletAllowlistConditionSchema, { - conditionType: WalletAllowlistConditionType, - ...value, - }); - } - - /** - * This condition requires wallet authentication to verify addresses - */ - override requiresAuthentication(): boolean { - return true; - } -} diff --git a/packages/taco/src/conditions/condition-factory.ts b/packages/taco/src/conditions/condition-factory.ts index 43335bec9..190e0a30c 100644 --- a/packages/taco/src/conditions/condition-factory.ts +++ b/packages/taco/src/conditions/condition-factory.ts @@ -1,3 +1,8 @@ +import { + AddressAllowlistCondition, + AddressAllowlistConditionProps, + AddressAllowlistConditionType, +} from './base/address-allowlist'; import { ContractCondition, ContractConditionProps, @@ -20,11 +25,6 @@ import { TimeConditionProps, TimeConditionType, } from './base/time'; -import { - WalletAllowlistCondition, - WalletAllowlistConditionProps, - WalletAllowlistConditionType, -} from './base/wallet-allowlist'; import { CompoundCondition, CompoundConditionProps, @@ -61,8 +61,10 @@ export class ConditionFactory { return new JsonRpcCondition(props as JsonRpcConditionProps); case JWTConditionType: return new JWTCondition(props as JWTConditionProps); - case WalletAllowlistConditionType: - return new WalletAllowlistCondition(props as WalletAllowlistConditionProps); + case AddressAllowlistConditionType: + return new AddressAllowlistCondition( + props as AddressAllowlistConditionProps, + ); // Logical Conditions case CompoundConditionType: return new CompoundCondition(props as CompoundConditionProps); diff --git a/packages/taco/src/conditions/schemas/wallet-allowlist.ts b/packages/taco/src/conditions/schemas/address-allowlist.ts similarity index 74% rename from packages/taco/src/conditions/schemas/wallet-allowlist.ts rename to packages/taco/src/conditions/schemas/address-allowlist.ts index f6c2e8091..4b4761162 100644 --- a/packages/taco/src/conditions/schemas/wallet-allowlist.ts +++ b/packages/taco/src/conditions/schemas/address-allowlist.ts @@ -4,11 +4,11 @@ import { z } from 'zod'; import { baseConditionSchema } from './common'; -export const WalletAllowlistConditionType = 'wallet-allowlist'; +export const AddressAllowlistConditionType = 'address-allowlist'; -export const walletAllowlistConditionSchema = baseConditionSchema +export const addressAllowlistConditionSchema = baseConditionSchema .extend({ - conditionType: z.literal(WalletAllowlistConditionType), + conditionType: z.literal(AddressAllowlistConditionType), addresses: z .array(EthAddressSchema) .min(1, 'At least one address must be provided') @@ -31,8 +31,8 @@ export const walletAllowlistConditionSchema = baseConditionSchema }) .strict(); -export type WalletAllowlistConditionProps = z.infer< - typeof walletAllowlistConditionSchema +export type AddressAllowlistConditionProps = z.infer< + typeof addressAllowlistConditionSchema >; -export type WalletAllowlistFields = 'addresses'; +export type AddressAllowlistFields = 'addresses'; diff --git a/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts b/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts index 8f2d8a706..7fff168cc 100755 --- a/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts +++ b/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts @@ -20,4 +20,4 @@ export * from './rpc'; export * from './sequential'; export * from './time'; // ts-unused-exports:disable-next-line - this comment line is added to prevent lint from changing or objecting the export order. -export * from './wallet-allowlist'; +export * from './address-allowlist'; diff --git a/packages/taco/src/conditions/schemas/index.ts b/packages/taco/src/conditions/schemas/index.ts index 81202cd93..017edce1f 100644 --- a/packages/taco/src/conditions/schemas/index.ts +++ b/packages/taco/src/conditions/schemas/index.ts @@ -1,10 +1,10 @@ // Export all schemas +export * from './address-allowlist'; export * from './common'; export * from './compound'; export * from './context'; export * from './contract'; -export * from './wallet-allowlist'; export * from './if-then-else'; export * from './json-api'; export * from './json-rpc'; diff --git a/packages/taco/src/conditions/schemas/utils.ts b/packages/taco/src/conditions/schemas/utils.ts index f0d3d1936..61ecfb610 100644 --- a/packages/taco/src/conditions/schemas/utils.ts +++ b/packages/taco/src/conditions/schemas/utils.ts @@ -2,7 +2,7 @@ import { z } from 'zod'; import { compoundConditionSchema } from '../compound-condition'; - +import { addressAllowlistConditionSchema } from './address-allowlist'; import { contractConditionSchema } from './contract'; import { ifThenElseConditionSchema } from './if-then-else'; import { jsonApiConditionSchema } from './json-api'; @@ -11,13 +11,12 @@ import { jwtConditionSchema } from './jwt'; import { rpcConditionSchema } from './rpc'; import { sequentialConditionSchema } from './sequential'; import { timeConditionSchema } from './time'; -import { walletAllowlistConditionSchema } from './wallet-allowlist'; export const anyConditionSchema: z.ZodSchema = z.lazy(() => z.union([ rpcConditionSchema, timeConditionSchema, - walletAllowlistConditionSchema, + addressAllowlistConditionSchema, contractConditionSchema, compoundConditionSchema, jsonApiConditionSchema, diff --git a/packages/taco/test/conditions/base/address-allowlist.test.ts b/packages/taco/test/conditions/base/address-allowlist.test.ts new file mode 100644 index 000000000..100c942a9 --- /dev/null +++ b/packages/taco/test/conditions/base/address-allowlist.test.ts @@ -0,0 +1,165 @@ +import { describe, expect, it } from 'vitest'; + +import { + AddressAllowlistCondition, + AddressAllowlistConditionProps, +} from '../../../src/conditions/base/address-allowlist'; +import { + addressAllowlistConditionSchema, + AddressAllowlistConditionType, +} from '../../../src/conditions/schemas/address-allowlist'; +import { testAddressAllowlistConditionObj } from '../../test-utils'; + +describe('AddressAllowlistCondition', () => { + describe('validate', () => { + it('accepts valid condition object', () => { + const result = AddressAllowlistCondition.validate( + addressAllowlistConditionSchema, + testAddressAllowlistConditionObj, + ); + + expect(result.error).toBeUndefined(); + expect(result.data).toEqual(testAddressAllowlistConditionObj); + }); + + it('fills in conditionType if missing', () => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { conditionType: _, ...withoutType } = + testAddressAllowlistConditionObj; + const condition = new AddressAllowlistCondition(withoutType); + + expect(condition.toObj().conditionType).toBe( + AddressAllowlistConditionType, + ); + }); + + it('rejects unknown fields', () => { + const conditionObj = { + ...testAddressAllowlistConditionObj, + unknownField: 'unknown', + } as unknown as AddressAllowlistConditionProps; + + const result = AddressAllowlistCondition.validate( + addressAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + // The error format for unknown fields is just a top-level _errors array + expect(result.error?.format()).toMatchObject({ + _errors: ["Unrecognized key(s) in object: 'unknownField'"], + }); + }); + + it('requires addresses to be present', () => { + const conditionObj = { + ...testAddressAllowlistConditionObj, + addresses: undefined, + } as unknown as AddressAllowlistConditionProps; + + const result = AddressAllowlistCondition.validate( + addressAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toHaveProperty('addresses'); + }); + + it('requires addresses to be an array', () => { + const conditionObj = { + ...testAddressAllowlistConditionObj, + addresses: 'not-an-array', + } as unknown as AddressAllowlistConditionProps; + + const result = AddressAllowlistCondition.validate( + addressAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.message).toContain('Expected array'); + }); + + it('requires at least one address', () => { + const conditionObj = { + ...testAddressAllowlistConditionObj, + addresses: [], + } as unknown as AddressAllowlistConditionProps; + + const result = AddressAllowlistCondition.validate( + addressAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.message).toContain('At least one address must be provided'); + }); + + it('requires addresses to be valid Ethereum addresses', () => { + const conditionObj = { + ...testAddressAllowlistConditionObj, + addresses: ['not-an-eth-address'], + } as unknown as AddressAllowlistConditionProps; + + const result = AddressAllowlistCondition.validate( + addressAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.message).toContain('Invalid Ethereum address'); + }); + + it('requires addresses to be checksummed', () => { + const conditionObj = { + ...testAddressAllowlistConditionObj, + // Lowercase version of a valid address + addresses: ['0x1e988ba4692e52bc50b375bcc8585b95c48aad77'], + } as unknown as AddressAllowlistConditionProps; + + const result = AddressAllowlistCondition.validate( + addressAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.message).toContain('All addresses must be properly checksummed'); + }); + }); + + describe('constructor', () => { + it('creates a condition from a valid object', () => { + const condition = new AddressAllowlistCondition( + testAddressAllowlistConditionObj, + ); + expect(condition.toObj()).toEqual(testAddressAllowlistConditionObj); + }); + + it('throws an error for invalid condition', () => { + const invalidCondition = () => { + return new AddressAllowlistCondition({ + addresses: [], + }); + }; + + // The error is wrapped in a general Error with message containing the Zod validation error + expect(invalidCondition).toThrow(/Invalid condition/); + }); + }); + + describe('requiresAuthentication', () => { + it('returns true', () => { + const condition = new AddressAllowlistCondition( + testAddressAllowlistConditionObj, + ); + expect(condition.requiresAuthentication()).toBe(true); + }); + }); +}); diff --git a/packages/taco/test/conditions/base/wallet-allowlist.test.ts b/packages/taco/test/conditions/base/wallet-allowlist.test.ts deleted file mode 100644 index c60947c6f..000000000 --- a/packages/taco/test/conditions/base/wallet-allowlist.test.ts +++ /dev/null @@ -1,227 +0,0 @@ -import { describe, expect, it } from 'vitest'; - -import { - WalletAllowlistCondition, - WalletAllowlistConditionProps, -} from '../../../src/conditions/base/wallet-allowlist'; -import { - walletAllowlistConditionSchema, - WalletAllowlistConditionType, -} from '../../../src/conditions/schemas/wallet-allowlist'; -import { testWalletAllowlistConditionObj } from '../../test-utils'; - -describe('WalletAllowlistCondition', () => { - describe('validate', () => { - it('accepts valid condition object', () => { - const result = WalletAllowlistCondition.validate( - walletAllowlistConditionSchema, - testWalletAllowlistConditionObj, - ); - - expect(result.error).toBeUndefined(); - expect(result.data).toEqual(testWalletAllowlistConditionObj); - }); - - it('fills in conditionType if missing', () => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { conditionType: _, ...withoutType } = - testWalletAllowlistConditionObj; - const condition = new WalletAllowlistCondition(withoutType); - - expect(condition.toObj().conditionType).toBe( - WalletAllowlistConditionType, - ); - }); - - it('rejects unknown fields', () => { - const conditionObj = { - ...testWalletAllowlistConditionObj, - unknownField: 'unknown', - } as unknown as WalletAllowlistConditionProps; - - const result = WalletAllowlistCondition.validate( - walletAllowlistConditionSchema, - conditionObj, - ); - - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - // The error format for unknown fields is just a top-level _errors array - expect(result.error?.format()).toMatchObject({ - _errors: ["Unrecognized key(s) in object: 'unknownField'"], - }); - }); - - it('rejects empty addresses array', () => { - const conditionObj = { - ...testWalletAllowlistConditionObj, - addresses: [], - }; - - const result = WalletAllowlistCondition.validate( - walletAllowlistConditionSchema, - conditionObj, - ); - - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error?.format()).toMatchObject({ - addresses: { - _errors: ['At least one address must be provided'], - }, - }); - }); - - it('rejects too many addresses (more than 25)', () => { - const tooManyAddresses = Array(26).fill( - '0x1234567890123456789012345678901234567890', - ); - const conditionObj = { - ...testWalletAllowlistConditionObj, - addresses: tooManyAddresses, - }; - - const result = WalletAllowlistCondition.validate( - walletAllowlistConditionSchema, - conditionObj, - ); - - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error?.format()).toMatchObject({ - addresses: { - _errors: ['Maximum of 25 addresses allowed'], - }, - }); - }); - - it('accepts single address', () => { - const conditionObj = { - ...testWalletAllowlistConditionObj, - addresses: ['0x1234567890123456789012345678901234567890'], - }; - - const result = WalletAllowlistCondition.validate( - walletAllowlistConditionSchema, - conditionObj, - ); - - expect(result.error).toBeUndefined(); - expect(result.data).toBeDefined(); - }); - - it('checks for valid ethereum addresses', () => { - const conditionObj = { - ...testWalletAllowlistConditionObj, - addresses: ['not-an-ethereum-address'], - }; - - const result = WalletAllowlistCondition.validate( - walletAllowlistConditionSchema, - conditionObj, - ); - - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error?.format()).toMatchObject({ - addresses: { - 0: { - _errors: ['Invalid Ethereum address'], - }, - }, - }); - }); - - it('rejects non-array addresses', () => { - const conditionObj = { - ...testWalletAllowlistConditionObj, - addresses: 'single-address' as unknown as string[], - }; - - const result = WalletAllowlistCondition.validate( - walletAllowlistConditionSchema, - conditionObj, - ); - - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error?.format()).toMatchObject({ - addresses: { - _errors: ['Expected array, received string'], - }, - }); - }); - - it('rejects non-checksummed addresses', () => { - // This is a valid address but with mixed case that doesn't match checksum format - // 0xE247A45c287191d435A8a5D72A7C8dc030451E9F (correct checksum) - // vs - // 0xe247a45c287191d435A8a5D72A7C8dc030451E9F (incorrect checksum) - const conditionObj = { - ...testWalletAllowlistConditionObj, - // Mixed case that doesn't follow checksum format - addresses: ['0xe247a45c287191d435A8a5D72A7C8dc030451E9F'], - }; - - const result = WalletAllowlistCondition.validate( - walletAllowlistConditionSchema, - conditionObj, - ); - - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error?.format()).toMatchObject({ - addresses: { - _errors: ['All addresses must be properly checksummed'], - }, - }); - }); - }); - - describe('constructor', () => { - it('creates a condition from a valid object', () => { - const condition = new WalletAllowlistCondition( - testWalletAllowlistConditionObj, - ); - expect(condition).toBeDefined(); - }); - - it('fails to create a condition from an invalid object', () => { - const invalidCondition = () => { - // This will throw at runtime when validation occurs - return new WalletAllowlistCondition({ - ...testWalletAllowlistConditionObj, - addresses: [] as string[], // Empty array will fail validation - }); - }; - - // The error is wrapped in a general Error with message containing the Zod validation error - expect(invalidCondition).toThrow(/Invalid condition/); - }); - - it('retains the original addresses order', () => { - const addresses = [ - '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', - '0x0000000000000000000000000000000000000001', - '0x0000000000000000000000000000000000000002', - ]; - - const conditionObj = { - ...testWalletAllowlistConditionObj, - addresses, - }; - const condition = new WalletAllowlistCondition(conditionObj); - - expect(condition.toObj().addresses).toEqual(addresses); - }); - }); - - describe('requiresAuthentication', () => { - it('returns true', () => { - const condition = new WalletAllowlistCondition( - testWalletAllowlistConditionObj, - ); - expect(condition.requiresAuthentication()).toBe(true); - }); - }); -}); diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 1abe7b256..7124ea9fc 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -36,6 +36,10 @@ import { import { ethers } from 'ethers'; import { MockInstance, vi } from 'vitest'; +import { + AddressAllowlistConditionProps, + AddressAllowlistConditionType, +} from '../src/conditions/base/address-allowlist'; import { ContractConditionProps, ContractConditionType, @@ -69,10 +73,6 @@ import { JsonRpcConditionProps, JsonRpcConditionType, } from '../src/conditions/schemas/json-rpc'; -import { - WalletAllowlistConditionProps, - WalletAllowlistConditionType, -} from '../src/conditions/schemas/wallet-allowlist'; import { SequentialConditionProps, SequentialConditionType, @@ -298,9 +298,9 @@ export const testRpcConditionObj: RpcConditionProps = { returnValueTest: testRpcReturnValueTest, }; -export const testWalletAllowlistConditionObj: WalletAllowlistConditionProps = +export const testAddressAllowlistConditionObj: AddressAllowlistConditionProps = { - conditionType: WalletAllowlistConditionType, + conditionType: AddressAllowlistConditionType, addresses: [ '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', '0x0000000000000000000000000000000000000001', From 0d6057390a7c65417c4cd73d5eaca6701f11b062 Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Mon, 9 Jun 2025 22:52:10 +0200 Subject: [PATCH 020/303] Apply suggestions from code review Co-authored-by: Manuel Montenegro --- packages/taco/examples/conditions.ts | 3 +-- packages/taco/integration-test/encrypt-decrypt.test.ts | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/taco/examples/conditions.ts b/packages/taco/examples/conditions.ts index 2921c27e8..992f69940 100644 --- a/packages/taco/examples/conditions.ts +++ b/packages/taco/examples/conditions.ts @@ -125,7 +125,7 @@ console.assert( 'ContractCondition does not require a signer', ); -// Wallet Allowlist Condition Example +// Address Allowlist Condition Example const addressAllowlistCondition = new conditions.base.addressAllowlist.AddressAllowlistCondition({ addresses: [ @@ -145,4 +145,3 @@ const addressToCheck = '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77'; const addresses = addressAllowlistCondition.toObj().addresses; // This would be checked by taco nodes after validating the wallet signature provided by encryptor (the value of the variable `addressToCheck`). const isAllowed = addresses.includes(addressToCheck); -console.log(`Is address ${addressToCheck} allowed? ${isAllowed}`); diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index a51d6f318..902755fa5 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -25,8 +25,8 @@ const DOMAIN = 'lynx'; const RITUAL_ID = 27; const CHAIN_ID = 80002; -// The wallet address of our consumer (derived from CONSUMER_PRIVATE_KEY) -const CONSUMER_ADDRESS = '0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed'; +// The wallet address of our consumer +const CONSUMER_ADDRESS = ethers.utils.computeAddress(CONSUMER_PRIVATE_KEY); describe.skipIf(!process.env.RUNNING_IN_CI)( 'Taco Encrypt/Decrypt Integration Test', From 9e810c698e3e14323e00685fcd164dccf6735eb8 Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Tue, 10 Jun 2025 23:49:02 +0200 Subject: [PATCH 021/303] add `userAddress` to `addressAllowlistConditionSchema` --- packages/taco/examples/conditions.ts | 1 + packages/taco/src/conditions/base/address-allowlist.ts | 7 ------- .../taco/src/conditions/schemas/address-allowlist.ts | 5 +++-- .../taco/test/conditions/base/address-allowlist.test.ts | 9 +++++++-- packages/taco/test/test-utils.ts | 1 + 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/taco/examples/conditions.ts b/packages/taco/examples/conditions.ts index 992f69940..ddffae177 100644 --- a/packages/taco/examples/conditions.ts +++ b/packages/taco/examples/conditions.ts @@ -128,6 +128,7 @@ console.assert( // Address Allowlist Condition Example const addressAllowlistCondition = new conditions.base.addressAllowlist.AddressAllowlistCondition({ + userAddress: ':userAddress', addresses: [ '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', diff --git a/packages/taco/src/conditions/base/address-allowlist.ts b/packages/taco/src/conditions/base/address-allowlist.ts index baa126c70..cebe2cb6d 100644 --- a/packages/taco/src/conditions/base/address-allowlist.ts +++ b/packages/taco/src/conditions/base/address-allowlist.ts @@ -17,11 +17,4 @@ export class AddressAllowlistCondition extends Condition { ...value, }); } - - /** - * This condition requires wallet authentication to verify addresses - */ - override requiresAuthentication(): boolean { - return true; - } } diff --git a/packages/taco/src/conditions/schemas/address-allowlist.ts b/packages/taco/src/conditions/schemas/address-allowlist.ts index 4b4761162..1f657bd86 100644 --- a/packages/taco/src/conditions/schemas/address-allowlist.ts +++ b/packages/taco/src/conditions/schemas/address-allowlist.ts @@ -2,13 +2,14 @@ import { EthAddressSchema } from '@nucypher/shared'; import { ethers } from 'ethers'; import { z } from 'zod'; -import { baseConditionSchema } from './common'; +import { baseConditionSchema, UserAddressSchema } from './common'; export const AddressAllowlistConditionType = 'address-allowlist'; export const addressAllowlistConditionSchema = baseConditionSchema .extend({ conditionType: z.literal(AddressAllowlistConditionType), + userAddress: UserAddressSchema, addresses: z .array(EthAddressSchema) .min(1, 'At least one address must be provided') @@ -35,4 +36,4 @@ export type AddressAllowlistConditionProps = z.infer< typeof addressAllowlistConditionSchema >; -export type AddressAllowlistFields = 'addresses'; +export type AddressAllowlistFields = 'addresses' | 'userAddress'; diff --git a/packages/taco/test/conditions/base/address-allowlist.test.ts b/packages/taco/test/conditions/base/address-allowlist.test.ts index 100c942a9..b2a9a82a4 100644 --- a/packages/taco/test/conditions/base/address-allowlist.test.ts +++ b/packages/taco/test/conditions/base/address-allowlist.test.ts @@ -97,7 +97,9 @@ describe('AddressAllowlistCondition', () => { expect(result.error).toBeDefined(); expect(result.data).toBeUndefined(); - expect(result.error?.message).toContain('At least one address must be provided'); + expect(result.error?.message).toContain( + 'At least one address must be provided', + ); }); it('requires addresses to be valid Ethereum addresses', () => { @@ -130,7 +132,9 @@ describe('AddressAllowlistCondition', () => { expect(result.error).toBeDefined(); expect(result.data).toBeUndefined(); - expect(result.error?.message).toContain('All addresses must be properly checksummed'); + expect(result.error?.message).toContain( + 'All addresses must be properly checksummed', + ); }); }); @@ -145,6 +149,7 @@ describe('AddressAllowlistCondition', () => { it('throws an error for invalid condition', () => { const invalidCondition = () => { return new AddressAllowlistCondition({ + userAddress: ':userAddress', addresses: [], }); }; diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 7124ea9fc..d32548b3c 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -301,6 +301,7 @@ export const testRpcConditionObj: RpcConditionProps = { export const testAddressAllowlistConditionObj: AddressAllowlistConditionProps = { conditionType: AddressAllowlistConditionType, + userAddress: ':userAddress', addresses: [ '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', '0x0000000000000000000000000000000000000001', From 49d165e436e971355725535c31dc994abe4f188c Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Fri, 20 Jun 2025 23:01:37 +0200 Subject: [PATCH 022/303] add and use EthAddressSchemaStrict and few other small edits --- packages/shared/src/schemas.ts | 16 ++++++ .../integration-test/encrypt-decrypt.test.ts | 1 + .../taco/schema-docs/condition-schemas.md | 51 ++++++++----------- .../conditions/schemas/address-allowlist.ts | 19 +------ packages/taco/src/conditions/schemas/index.ts | 16 ------ .../conditions/base/address-allowlist.test.ts | 2 +- 6 files changed, 42 insertions(+), 63 deletions(-) delete mode 100644 packages/taco/src/conditions/schemas/index.ts diff --git a/packages/shared/src/schemas.ts b/packages/shared/src/schemas.ts index 37dfa2653..a2e0dd07c 100644 --- a/packages/shared/src/schemas.ts +++ b/packages/shared/src/schemas.ts @@ -9,10 +9,26 @@ const isAddress = (address: string) => { } }; +const isAddressStrict = (address: string) => { + try { + // Verify the address was checksummed to prevent passing an address that has a typo + return address === ethers.utils.getAddress(address); + } catch (e) { + // If any error occurs during validation, fail the validation + return false; + } +}; + export const EthAddressSchema = z .string() .refine(isAddress, { message: 'Invalid Ethereum address' }); +export const EthAddressSchemaStrict = z + .string() + .refine(isAddressStrict, { + message: 'Invalid Ethereum address - it must be valid and checksummed', + }); + const BLOCK_HASH_REGEXP = new RegExp('^0x[a-fA-F0-9]{64}$'); const BlockNumber = z.number().int().nonnegative(); const BlockHash = z.string().regex(BLOCK_HASH_REGEXP, 'Invalid block hash'); diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index 902755fa5..5dd257a98 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -142,6 +142,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( // Create wallet allowlist condition with consumer address in the list const addressAllowlistCondition = new conditions.base.addressAllowlist.AddressAllowlistCondition({ + userAddress: ':userAddress', addresses: [ CONSUMER_ADDRESS, '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', // Some other address diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index d98b82a92..5a41354ac 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -6,7 +6,7 @@ _Union of the following possible types:_ - [RpcCondition](#rpccondition) - [TimeCondition](#timecondition) -- [AddressAllowlistCondition](#walletallowlistcondition) +- [AddressAllowlistCondition](#addressallowlistcondition) - [ContractCondition](#contractcondition) - [CompoundCondition](#compoundcondition) - [JsonApiCondition](#jsonapicondition) @@ -17,8 +17,7 @@ _Union of the following possible types:_ ## UserAddress -This is a context variable that will be replaced at decryption time. It -represents the Ethereum address of the requester attempting decryption. +This is a context variable that will be replaced at decryption time. It represents the Ethereum address of the requester attempting decryption. _Literal `':userAddress'` value._ @@ -52,20 +51,15 @@ _String._ _Union of the following possible types:_ -- [PlainString](#plainstring), `boolean`, `number` (_int, ≥-9007199254740991, - ≤9007199254740991_) _or_ `bigint` - (_≤115792089237316195423570985008687907853269984665640564039457584007913129639935, - ≥-57896044618658097711785492504343953926634992332820282019728792003956564819968_) +- [PlainString](#plainstring), `boolean`, `number` (_int, ≥-9007199254740991, ≤9007199254740991_) _or_ `bigint` (_≤115792089237316195423570985008687907853269984665640564039457584007913129639935, ≥-57896044618658097711785492504343953926634992332820282019728792003956564819968_) - [ContextParam](#contextparam) -- _Array of [BlockchainParamOrContextParam](#blockchainparamorcontextparam) - items_ +- _Array of [BlockchainParamOrContextParam](#blockchainparamorcontextparam) items_ ## ContextParam -A Context Parameter i.e. a placeholder used within conditions and specified at -the encryption time, whose value is provided at decryption time. +A Context Parameter i.e. a placeholder used within conditions and specified at the encryption time, whose value is provided at decryption time. -_String which matches the regular expression `/^:[a-zA-Z_][a-zA-Z0-9_]\*$/`.\_ +_String which matches the regular expression `/^:[a-zA-Z_][a-zA-Z0-9_]*$/`._ ## ParamOrContextParam @@ -79,11 +73,11 @@ _Union of the following possible types:_ _Object containing the following properties:_ -| Property | Type | Default | -| :------------------ | :---------------------------------------------------------------------- | :----------- | -| `conditionType` | `'compound'` | `'compound'` | -| **`operator`** (\*) | `'and' \| 'or' \| 'not'` | | -| **`operands`** (\*) | _Array of at least 1 and at most 5 [AnyCondition](#anycondition) items_ | | +| Property | Type | Default | +| :------------------ | :------------------------------------------------------------------------ | :----------- | +| `conditionType` | `'compound'` | `'compound'` | +| **`operator`** (\*) | `'and' \| 'or' \| 'not'` | | +| **`operands`** (\*) | _Array of at least 1 and at most 5 [AnyCondition](#anycondition) items_ | | _(\*) Required._ @@ -213,8 +207,7 @@ _(\*) Required._ ## RpcCondition -RPC Condition for calling -[Ethereum JSON RPC APIs](https://ethereum.github.io/execution-apis/api-documentation/) +RPC Condition for calling [Ethereum JSON RPC APIs](https://ethereum.github.io/execution-apis/api-documentation/) _Object containing the following properties:_ @@ -243,10 +236,10 @@ _(\*) Required._ _Object containing the following properties:_ -| Property | Type | Default | -| :---------------------------- | :-------------------------------------------------------------------------------- | :------------- | -| `conditionType` | `'sequential'` | `'sequential'` | -| **`conditionVariables`** (\*) | _Array of at least 2 and at most 5 [ConditionVariable](#conditionvariable) items_ | | +| Property | Type | Default | +| :---------------------------- | :---------------------------------------------------------------------------------- | :------------- | +| `conditionType` | `'sequential'` | `'sequential'` | +| **`conditionVariables`** (\*) | _Array of at least 2 and at most 5 [ConditionVariable](#conditionvariable) items_ | | _(\*) Required._ @@ -267,10 +260,11 @@ _(\*) Required._ _Object containing the following properties:_ -| Property | Description | Type | -| :----------------------- | :------------------------------------------------------------------------------------------------------------------------- | :---------------------------------- | -| **`conditionType`** (\*) | | `'address-allowlist'` | -| **`addresses`** (\*) | List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form. Matching is case-sensitive. | `Array` (_min: 1, max: 25_) | +| Property | Description | Type | +| :----------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------- | +| **`conditionType`** (\*) | | `'address-allowlist'` | +| **`userAddress`** (\*) | This is a context variable that will be replaced at decryption time. It represents the Ethereum address of the requester attempting decryption. | [UserAddress](#useraddress) | +| **`addresses`** (\*) | List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form. Matching is case-sensitive. | `Array` (_min: 1, max: 25_) | _(\*) Required._ @@ -279,5 +273,4 @@ _(\*) Required._ For more information, please refer to the TACo documentation: https://docs.taco.build/. -Visit the TACo Playground to see the condition schemas in action: -https://playground.taco.build/. +Visit the TACo Playground to see the condition schemas in action: https://playground.taco.build/. diff --git a/packages/taco/src/conditions/schemas/address-allowlist.ts b/packages/taco/src/conditions/schemas/address-allowlist.ts index 1f657bd86..50a16aeeb 100644 --- a/packages/taco/src/conditions/schemas/address-allowlist.ts +++ b/packages/taco/src/conditions/schemas/address-allowlist.ts @@ -1,5 +1,4 @@ -import { EthAddressSchema } from '@nucypher/shared'; -import { ethers } from 'ethers'; +import { EthAddressSchemaStrict } from '@nucypher/shared'; import { z } from 'zod'; import { baseConditionSchema, UserAddressSchema } from './common'; @@ -11,21 +10,9 @@ export const addressAllowlistConditionSchema = baseConditionSchema conditionType: z.literal(AddressAllowlistConditionType), userAddress: UserAddressSchema, addresses: z - .array(EthAddressSchema) + .array(EthAddressSchemaStrict) .min(1, 'At least one address must be provided') .max(25, 'Maximum of 25 addresses allowed') - // Ensure all addresses are valid Ethereum addresses with proper checksum - .refine((addrs) => { - try { - return addrs.every((addr) => { - // Then verify it has the correct checksum (comparing to canonical form) - return addr === ethers.utils.getAddress(addr); - }); - } catch (e) { - // If any error occurs during validation, fail the validation - return false; - } - }, 'All addresses must be properly checksummed') .describe( 'List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form. Matching is case-sensitive.', ), @@ -35,5 +22,3 @@ export const addressAllowlistConditionSchema = baseConditionSchema export type AddressAllowlistConditionProps = z.infer< typeof addressAllowlistConditionSchema >; - -export type AddressAllowlistFields = 'addresses' | 'userAddress'; diff --git a/packages/taco/src/conditions/schemas/index.ts b/packages/taco/src/conditions/schemas/index.ts deleted file mode 100644 index 017edce1f..000000000 --- a/packages/taco/src/conditions/schemas/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -// Export all schemas - -export * from './address-allowlist'; -export * from './common'; -export * from './compound'; -export * from './context'; -export * from './contract'; -export * from './if-then-else'; -export * from './json-api'; -export * from './json-rpc'; -export * from './jwt'; -export * from './return-value-test'; -export * from './rpc'; -export * from './sequential'; -export * from './time'; -export * from './utils'; diff --git a/packages/taco/test/conditions/base/address-allowlist.test.ts b/packages/taco/test/conditions/base/address-allowlist.test.ts index b2a9a82a4..e3bac2fc9 100644 --- a/packages/taco/test/conditions/base/address-allowlist.test.ts +++ b/packages/taco/test/conditions/base/address-allowlist.test.ts @@ -133,7 +133,7 @@ describe('AddressAllowlistCondition', () => { expect(result.error).toBeDefined(); expect(result.data).toBeUndefined(); expect(result.error?.message).toContain( - 'All addresses must be properly checksummed', + 'Invalid Ethereum address - it must be valid and checksummed', ); }); }); From 8cf61960d95068f8269467bfa3786600df8968dc Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Mon, 23 Jun 2025 07:24:39 +0200 Subject: [PATCH 023/303] enhance the schema docs a bit --- packages/taco/schema-docs/condition-schemas.md | 8 +++++--- packages/taco/src/conditions/schemas/address-allowlist.ts | 5 ++++- packages/taco/src/conditions/schemas/common.ts | 6 +++++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index 5a41354ac..ea648d3e8 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -25,9 +25,9 @@ _Literal `':userAddress'` value._ _Object containing the following properties:_ -| Property | Type | -| :----------------------- | :------- | -| **`conditionType`** (\*) | `string` | +| Property | Description | Type | +| :----------------------- | :------------------------------------------------------------------------------------------------- | :------- | +| **`conditionType`** (\*) | This value is set automatically at every sub-class constructor when a new object is being created. | `string` | _(\*) Required._ @@ -258,6 +258,8 @@ _(\*) Required._ ## AddressAllowlistCondition +Address Allowlist Condition for allowing decryption for specific wallet addresses. It may not be very handy on its own, but when combined with other conditions, it can be very useful. + _Object containing the following properties:_ | Property | Description | Type | diff --git a/packages/taco/src/conditions/schemas/address-allowlist.ts b/packages/taco/src/conditions/schemas/address-allowlist.ts index 50a16aeeb..84a543586 100644 --- a/packages/taco/src/conditions/schemas/address-allowlist.ts +++ b/packages/taco/src/conditions/schemas/address-allowlist.ts @@ -17,7 +17,10 @@ export const addressAllowlistConditionSchema = baseConditionSchema 'List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form. Matching is case-sensitive.', ), }) - .strict(); + .strict() + .describe( + 'Address Allowlist Condition for allowing decryption for specific wallet addresses. It may not be very handy on its own, but when combined with other conditions, it can be very useful.', + ); export type AddressAllowlistConditionProps = z.infer< typeof addressAllowlistConditionSchema diff --git a/packages/taco/src/conditions/schemas/common.ts b/packages/taco/src/conditions/schemas/common.ts index 6669e4d30..4131d1190 100644 --- a/packages/taco/src/conditions/schemas/common.ts +++ b/packages/taco/src/conditions/schemas/common.ts @@ -27,7 +27,11 @@ export const UserAddressSchema = z ); export const baseConditionSchema = z.object({ - conditionType: z.string(), + conditionType: z + .string() + .describe( + 'This value is set automatically at every sub-class constructor when a new object is being created.', + ), }); // Source: https://github.com/colinhacks/zod/issues/831#issuecomment-1063481764 From d9ecadea99c70769c45963c644a88066f5aa22f8 Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Mon, 23 Jun 2025 08:44:42 +0200 Subject: [PATCH 024/303] add a test --- .../conditions/schemas/address-allowlist.ts | 2 +- .../conditions/base/address-allowlist.test.ts | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/taco/src/conditions/schemas/address-allowlist.ts b/packages/taco/src/conditions/schemas/address-allowlist.ts index 84a543586..0d68496ae 100644 --- a/packages/taco/src/conditions/schemas/address-allowlist.ts +++ b/packages/taco/src/conditions/schemas/address-allowlist.ts @@ -12,7 +12,7 @@ export const addressAllowlistConditionSchema = baseConditionSchema addresses: z .array(EthAddressSchemaStrict) .min(1, 'At least one address must be provided') - .max(25, 'Maximum of 25 addresses allowed') + .max(25, 'A maximum of 25 addresses is allowed') .describe( 'List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form. Matching is case-sensitive.', ), diff --git a/packages/taco/test/conditions/base/address-allowlist.test.ts b/packages/taco/test/conditions/base/address-allowlist.test.ts index e3bac2fc9..102f1d19a 100644 --- a/packages/taco/test/conditions/base/address-allowlist.test.ts +++ b/packages/taco/test/conditions/base/address-allowlist.test.ts @@ -102,6 +102,29 @@ describe('AddressAllowlistCondition', () => { ); }); + it('enforces a maximum of 25 addresses', () => { + // Create an array of 26 valid Ethereum addresses + const tooManyAddresses = Array(26) + .fill(0) + .map((_, i) => `0x${(i + 10).toString().padStart(40, '0')}`); + + const conditionObj = { + ...testAddressAllowlistConditionObj, + addresses: tooManyAddresses, + } as unknown as AddressAllowlistConditionProps; + + const result = AddressAllowlistCondition.validate( + addressAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.message).toContain( + 'A maximum of 25 addresses is allowed', + ); + }); + it('requires addresses to be valid Ethereum addresses', () => { const conditionObj = { ...testAddressAllowlistConditionObj, From e4e9a44258995d1d56604888f5c3678e34fa0fa0 Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Thu, 26 Jun 2025 13:37:05 +0200 Subject: [PATCH 025/303] few edits in response to MR reviews --- packages/taco/examples/conditions.ts | 7 ++++--- packages/taco/schema-docs/condition-schemas.md | 8 ++++---- packages/taco/src/conditions/schemas/address-allowlist.ts | 2 +- packages/taco/src/conditions/schemas/common.ts | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/taco/examples/conditions.ts b/packages/taco/examples/conditions.ts index ddffae177..f1ed65f53 100644 --- a/packages/taco/examples/conditions.ts +++ b/packages/taco/examples/conditions.ts @@ -112,7 +112,7 @@ const myContractCallCondition = new conditions.base.contract.ContractCondition({ method: 'myFunctionAbi', // `myMethodAbi.name` parameters: [':userAddress', ':myCustomParam'], // `myMethodAbi.inputs` functionAbi: myFunctionAbi, - contractAddress: '0x0...1', + contractAddress: '0x0000000000000000000000000000000000000001', chain: ChainId.SEPOLIA, returnValueTest: { comparator: '>', @@ -121,8 +121,8 @@ const myContractCallCondition = new conditions.base.contract.ContractCondition({ }); console.assert( - !myContractCallCondition.requiresAuthentication(), - 'ContractCondition does not require a signer', + myContractCallCondition.requiresAuthentication(), + 'ContractCondition requires a signer', ); // Address Allowlist Condition Example @@ -146,3 +146,4 @@ const addressToCheck = '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77'; const addresses = addressAllowlistCondition.toObj().addresses; // This would be checked by taco nodes after validating the wallet signature provided by encryptor (the value of the variable `addressToCheck`). const isAllowed = addresses.includes(addressToCheck); +console.assert(isAllowed, 'Address should be allowed but it is not.'); diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index ea648d3e8..906127fba 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -25,9 +25,9 @@ _Literal `':userAddress'` value._ _Object containing the following properties:_ -| Property | Description | Type | -| :----------------------- | :------------------------------------------------------------------------------------------------- | :------- | -| **`conditionType`** (\*) | This value is set automatically at every sub-class constructor when a new object is being created. | `string` | +| Property | Description | Type | +| :----------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------- | +| **`conditionType`** (\*) | A unique identifier that indicates the condition variant in its serialized form. It is set automatically at every sub-class constructor when a new object is being created. | `string` | _(\*) Required._ @@ -258,7 +258,7 @@ _(\*) Required._ ## AddressAllowlistCondition -Address Allowlist Condition for allowing decryption for specific wallet addresses. It may not be very handy on its own, but when combined with other conditions, it can be very useful. +Address Allowlist Condition for allowing decryption for specific wallet addresses. It is very handy when combined with other conditions. _Object containing the following properties:_ diff --git a/packages/taco/src/conditions/schemas/address-allowlist.ts b/packages/taco/src/conditions/schemas/address-allowlist.ts index 0d68496ae..0c4f1d3fd 100644 --- a/packages/taco/src/conditions/schemas/address-allowlist.ts +++ b/packages/taco/src/conditions/schemas/address-allowlist.ts @@ -19,7 +19,7 @@ export const addressAllowlistConditionSchema = baseConditionSchema }) .strict() .describe( - 'Address Allowlist Condition for allowing decryption for specific wallet addresses. It may not be very handy on its own, but when combined with other conditions, it can be very useful.', + 'Address Allowlist Condition for allowing decryption for specific wallet addresses. It is very handy when combined with other conditions.', ); export type AddressAllowlistConditionProps = z.infer< diff --git a/packages/taco/src/conditions/schemas/common.ts b/packages/taco/src/conditions/schemas/common.ts index 4131d1190..fc64ae2e7 100644 --- a/packages/taco/src/conditions/schemas/common.ts +++ b/packages/taco/src/conditions/schemas/common.ts @@ -30,7 +30,7 @@ export const baseConditionSchema = z.object({ conditionType: z .string() .describe( - 'This value is set automatically at every sub-class constructor when a new object is being created.', + 'A unique identifier that indicates the condition variant in its serialized form. It is set automatically at every sub-class constructor when a new object is being created.', ), }); From 38d6d6d779cb17025410d226c095533deaea9bcb Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Sat, 5 Jul 2025 01:15:45 +0200 Subject: [PATCH 026/303] Update packages/taco/src/conditions/schemas/address-allowlist.ts Co-authored-by: Derek Pierre --- packages/taco/src/conditions/schemas/address-allowlist.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco/src/conditions/schemas/address-allowlist.ts b/packages/taco/src/conditions/schemas/address-allowlist.ts index 0c4f1d3fd..d240f3c00 100644 --- a/packages/taco/src/conditions/schemas/address-allowlist.ts +++ b/packages/taco/src/conditions/schemas/address-allowlist.ts @@ -14,7 +14,7 @@ export const addressAllowlistConditionSchema = baseConditionSchema .min(1, 'At least one address must be provided') .max(25, 'A maximum of 25 addresses is allowed') .describe( - 'List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form. Matching is case-sensitive.', + 'List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form.', ), }) .strict() From 574dcad64e930efb83ca2f22a995219980188c80 Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Sat, 5 Jul 2025 01:24:56 +0200 Subject: [PATCH 027/303] unskip address allowlist condition as it is available now at nucypher --- packages/taco/integration-test/encrypt-decrypt.test.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index 5dd257a98..7b63626de 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -109,10 +109,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( USER_ADDRESS_PARAM_DEFAULT, ) ) { - const authProvider = new EIP4361AuthProvider(provider, consumerSigner, { - domain: 'localhost', - uri: 'http://localhost:3000', - }); + const authProvider = new EIP4361AuthProvider(provider, consumerSigner); conditionContext.addAuthProvider( USER_ADDRESS_PARAM_DEFAULT, authProvider, @@ -132,8 +129,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( expect(decryptedMessageString).toEqual(messageString); }, 15000); // 15s timeout - // TODO: Unskip this test when wallet allowlist condition is implemented and running at the nodes as per https://github.com/nucypher/nucypher/issues/3600 - test.skip('should encrypt and decrypt according to wallet allowlist condition', async () => { + test('should encrypt and decrypt according to wallet allowlist condition', async () => { // Create test message const messageString = 'This message should only be accessible to allowed wallet addresses'; From 410efff1f582105db3e27109d2f0c4e12f56fea9 Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Sat, 5 Jul 2025 01:39:29 +0200 Subject: [PATCH 028/303] update the generated schema docs --- packages/taco/schema-docs/condition-schemas.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index 906127fba..4603e4114 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -266,7 +266,7 @@ _Object containing the following properties:_ | :----------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------- | | **`conditionType`** (\*) | | `'address-allowlist'` | | **`userAddress`** (\*) | This is a context variable that will be replaced at decryption time. It represents the Ethereum address of the requester attempting decryption. | [UserAddress](#useraddress) | -| **`addresses`** (\*) | List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form. Matching is case-sensitive. | `Array` (_min: 1, max: 25_) | +| **`addresses`** (\*) | List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form. | `Array` (_min: 1, max: 25_) | _(\*) Required._ From 9d7b541b324ccb3c7a0e5bb9cdcbbda1388caf77 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 30 May 2025 13:07:58 +0100 Subject: [PATCH 029/303] Add basic stub functions and types for TACo signing --- packages/taco/src/index.ts | 1 + packages/taco/src/sign.ts | 27 +++++++++++++++++++++++++++ packages/taco/src/types.ts | 29 +++++++++++++++++++++++++++++ packages/taco/src/utils.ts | 10 ++++++++++ 4 files changed, 67 insertions(+) create mode 100644 packages/taco/src/sign.ts diff --git a/packages/taco/src/index.ts b/packages/taco/src/index.ts index 698685a1b..69ef03f93 100644 --- a/packages/taco/src/index.ts +++ b/packages/taco/src/index.ts @@ -12,3 +12,4 @@ export { export * as conditions from './conditions'; export { decrypt, encrypt, encryptWithPublicKey } from './taco'; +export { sign191, signUserOp } from './sign'; diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts new file mode 100644 index 000000000..d28259e18 --- /dev/null +++ b/packages/taco/src/sign.ts @@ -0,0 +1,27 @@ +import { Domain } from '@nucypher/shared'; + +import { SignResult, SigningOptions, UserOperation } from './types'; +import { aggregateSignatures, verifyThreshold } from './utils'; + + +// Core signing functions +export async function sign191( + payload: Uint8Array | string, + cohortId: number, + domain: Domain, + options: SigningOptions = { optimistic: true, returnAggregated: true } +): Promise { + throw new Error("Not implemented"); +} + +export async function signUserOp( + userOp: UserOperation, + chainId: number, + accountSpec: "zerodev" | "kernel" | "metamask" | "safe" | string, + entryPointVersion: "v0.6" | "v0.7" | "v0.8", + cohortId: number, + domain: Domain, + options: SigningOptions = { optimistic: true, returnAggregated: true } +): Promise { + throw new Error("Not implemented"); +} \ No newline at end of file diff --git a/packages/taco/src/types.ts b/packages/taco/src/types.ts index 406bf6910..30a89502a 100644 --- a/packages/taco/src/types.ts +++ b/packages/taco/src/types.ts @@ -3,3 +3,32 @@ export { Conditions as CoreConditions, Context as CoreContext, } from '@nucypher/nucypher-core'; + +// Signing types +export type SignResult = { + digest: string; // Final hash signed by the node + aggregatedSignature: string; // Combined signature from all signers + signingResults: { // Individual signing results from each participant + [ursulaAddress: string]: [signerAddress: string, signatureB64: string] + }; + type: string; // Signature type (e.g. "eip712", "userOp:zerodev") +}; + +export type SigningOptions = { + optimistic?: boolean; // Whether to proceed with signing even if some nodes are unavailable + returnAggregated?: boolean; // Whether to return the aggregated signature +}; + +export type UserOperation = { + sender: string; + nonce: string; + initCode: string; + callData: string; + callGasLimit: string; + verificationGasLimit: string; + preVerificationGas: string; + maxFeePerGas: string; + maxPriorityFeePerGas: string; + paymasterAndData: string; + signature: string; +}; diff --git a/packages/taco/src/utils.ts b/packages/taco/src/utils.ts index 32cc94e9b..c384ec58b 100644 --- a/packages/taco/src/utils.ts +++ b/packages/taco/src/utils.ts @@ -49,3 +49,13 @@ export const toJSON = (obj: unknown) => JSON.stringify(obj, sortedSerializingReplacer); export const fromJSON = (json: string) => JSON.parse(json, customTypeReceiver); + +export function aggregateSignatures(signatures: string[]): string { + // TODO: Implement signature aggregation logic + throw new Error("Not implemented"); +} + +export function verifyThreshold(signatures: string[], threshold: number): boolean { + // TODO: Implement threshold verification logic + throw new Error("Not implemented"); +} From f643b04d3053b2ad942b353e9b673dd8fd37490f Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 2 Jun 2025 13:30:16 +0100 Subject: [PATCH 030/303] Add new types and functions to `porter.ts` --- packages/shared/src/porter.ts | 117 ++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index 0a13050d3..b857b757d 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -152,6 +152,49 @@ export type TacoDecryptResult = { errors: Record; }; +// Signing types +type PostSign191Request = { + readonly payload: Base64EncodedBytes; + readonly cohort_id: number; + readonly optimistic?: boolean; + readonly return_aggregated?: boolean; +}; + +type PostSignUserOpRequest = { + readonly user_op: { + readonly sender: string; + readonly nonce: string; + readonly init_code: string; + readonly call_data: string; + readonly call_gas_limit: string; + readonly verification_gas_limit: string; + readonly pre_verification_gas: string; + readonly max_fee_per_gas: string; + readonly max_priority_fee_per_gas: string; + readonly paymaster_and_data: string; + readonly signature: string; + }; + readonly chain_id: number; + readonly account_spec: string; + readonly entry_point_version: string; + readonly cohort_id: number; + readonly optimistic?: boolean; + readonly return_aggregated?: boolean; +}; + +type SignResponse = { + readonly result: { + readonly digest: HexEncodedBytes; + readonly aggregated_signature: HexEncodedBytes; + readonly signing_results: Record< + ChecksumAddress, + [ChecksumAddress, Base64EncodedBytes] + >; + readonly type: string; + }; + readonly version: string; +}; + export class PorterClient { readonly porterUrls: URL[]; @@ -284,4 +327,78 @@ export class PorterClient { > = Object.fromEntries(decryptionResponses); return { encryptedResponses, errors }; } + + public async sign191( + payload: Uint8Array, + cohortId: number, + optimistic: boolean = true, + returnAggregated: boolean = true, + ): Promise { + const data: PostSign191Request = { + payload: toBase64(payload), + cohort_id: cohortId, + optimistic, + return_aggregated: returnAggregated, + }; + + const resp: AxiosResponse = await this.tryAndCall({ + url: '/sign191', + method: 'post', + data, + }); + + return resp.data.result; + } + + public async signUserOp( + userOp: { + sender: string; + nonce: string; + initCode: string; + callData: string; + callGasLimit: string; + verificationGasLimit: string; + preVerificationGas: string; + maxFeePerGas: string; + maxPriorityFeePerGas: string; + paymasterAndData: string; + signature: string; + }, + chainId: number, + accountSpec: string, + entryPointVersion: string, + cohortId: number, + optimistic: boolean = true, + returnAggregated: boolean = true, + ): Promise { + const data: PostSignUserOpRequest = { + user_op: { + sender: userOp.sender, + nonce: userOp.nonce, + init_code: userOp.initCode, + call_data: userOp.callData, + call_gas_limit: userOp.callGasLimit, + verification_gas_limit: userOp.verificationGasLimit, + pre_verification_gas: userOp.preVerificationGas, + max_fee_per_gas: userOp.maxFeePerGas, + max_priority_fee_per_gas: userOp.maxPriorityFeePerGas, + paymaster_and_data: userOp.paymasterAndData, + signature: userOp.signature, + }, + chain_id: chainId, + account_spec: accountSpec, + entry_point_version: entryPointVersion, + cohort_id: cohortId, + optimistic, + return_aggregated: returnAggregated, + }; + + const resp: AxiosResponse = await this.tryAndCall({ + url: '/sign_user_op', + method: 'post', + data, + }); + + return resp.data.result; + } } From fe5d6ffb35fa97dfd72ea5f5eac51052c1386546 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 2 Jun 2025 13:30:32 +0100 Subject: [PATCH 031/303] Use new porter types and functions in signing api --- packages/taco/src/sign.ts | 46 ++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index d28259e18..c3adc2afd 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -1,8 +1,6 @@ -import { Domain } from '@nucypher/shared'; - -import { SignResult, SigningOptions, UserOperation } from './types'; -import { aggregateSignatures, verifyThreshold } from './utils'; +import { Domain, PorterClient } from '@nucypher/shared'; +import { SigningOptions, SignResult, UserOperation } from './types'; // Core signing functions export async function sign191( @@ -11,7 +9,26 @@ export async function sign191( domain: Domain, options: SigningOptions = { optimistic: true, returnAggregated: true } ): Promise { - throw new Error("Not implemented"); + const porter = new PorterClient(domain); + + // Convert string payload to Uint8Array if needed + const payloadBytes = typeof payload === 'string' + ? new TextEncoder().encode(payload) + : payload; + + const result = await porter.sign191( + payloadBytes, + cohortId, + options.optimistic, + options.returnAggregated + ); + + return { + digest: result.digest, + aggregatedSignature: result.aggregated_signature, + signingResults: result.signing_results, + type: result.type + }; } export async function signUserOp( @@ -23,5 +40,22 @@ export async function signUserOp( domain: Domain, options: SigningOptions = { optimistic: true, returnAggregated: true } ): Promise { - throw new Error("Not implemented"); + const porter = new PorterClient(domain); + + const result = await porter.signUserOp( + userOp, + chainId, + accountSpec, + entryPointVersion, + cohortId, + options.optimistic, + options.returnAggregated + ); + + return { + digest: result.digest, + aggregatedSignature: result.aggregated_signature, + signingResults: result.signing_results, + type: result.type + }; } \ No newline at end of file From 7b2ed3f5a26af60dcc4bf43d3c9f8eb5508f9f8f Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 2 Jun 2025 13:35:59 +0100 Subject: [PATCH 032/303] Add tests for porter signing endpoints --- packages/shared/test/porter.test.ts | 154 +++++++++++++++++++++++++++- 1 file changed, 151 insertions(+), 3 deletions(-) diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index 13fb992da..70ee58439 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -2,14 +2,14 @@ import { fakeUrsulas } from '@nucypher/test-utils'; import axios, { HttpStatusCode } from 'axios'; import { MockInstance, beforeAll, describe, expect, it, vi } from 'vitest'; import { - GetUrsulasResult, - PorterClient, - Ursula, domains, + GetUrsulasResult, getPorterUris, getPorterUrisFromSource, initialize, + PorterClient, toHexString, + Ursula, } from '../src'; const fakePorterUris = [ @@ -49,6 +49,62 @@ const mockGetUrsulas = (ursulas: Ursula[] = fakeUrsulas()): MockInstance => { }); }; +const mockSign191 = (success: boolean = true): MockInstance => { + const fakeSignResponse = { + result: { + digest: '0x1234', + aggregated_signature: '0x5678', + signing_results: { + '0x1234': ['0x5678', '0x90ab'], + '0xabcd': ['0xefgh', '0xijkl'], + }, + type: 'eip191', + }, + version: '5.2.0', + }; + + return vi.spyOn(axios, 'request').mockImplementation(async (config) => { + if (config.url === '/sign191') { + if (success) { + return Promise.resolve({ + status: HttpStatusCode.Ok, + data: fakeSignResponse, + }); + } + return Promise.resolve({ status: HttpStatusCode.BadRequest, data: '' }); + } + throw new Error('Unexpected endpoint'); + }); +}; + +const mockSignUserOp = (success: boolean = true): MockInstance => { + const fakeSignResponse = { + result: { + digest: '0x1234', + aggregated_signature: '0x5678', + signing_results: { + '0x1234': ['0x5678', '0x90ab'], + '0xabcd': ['0xefgh', '0xijkl'], + }, + type: 'userOp:zerodev', + }, + version: '5.2.0', + }; + + return vi.spyOn(axios, 'request').mockImplementation(async (config) => { + if (config.url === '/sign_user_op') { + if (success) { + return Promise.resolve({ + status: HttpStatusCode.Ok, + data: fakeSignResponse, + }); + } + return Promise.resolve({ status: HttpStatusCode.BadRequest, data: '' }); + } + throw new Error('Unexpected endpoint'); + }); +}; + describe('getPorterUris', () => { beforeAll(async () => { await initialize(); @@ -117,3 +173,95 @@ describe('PorterClient', () => { ); }); }); + +describe('PorterClient Signing', () => { + beforeAll(async () => { + await initialize(); + }); + + describe('sign191', () => { + it('should successfully sign a message', async () => { + mockSign191(true); + const porterClient = new PorterClient(fakePorterUris[2]); + const payload = new TextEncoder().encode('Hello, TACo!'); + const result = await porterClient.sign191(payload, 5, true, true); + + expect(result).toEqual({ + digest: '0x1234', + aggregated_signature: '0x5678', + signing_results: { + '0x1234': ['0x5678', '0x90ab'], + '0xabcd': ['0xefgh', '0xijkl'], + }, + type: 'eip191', + }); + }); + + it('should handle signing failures', async () => { + mockSign191(false); + const porterClient = new PorterClient(fakePorterUris[2]); + const payload = new TextEncoder().encode('Hello, TACo!'); + + await expect( + porterClient.sign191(payload, 5, true, true) + ).rejects.toThrow('Porter returned bad response: 400 - '); + }); + }); + + describe('signUserOp', () => { + const mockUserOp = { + sender: '0x1234', + nonce: '0x1', + initCode: '0x', + callData: '0xabc', + callGasLimit: '0x20000', + verificationGasLimit: '0x15000', + preVerificationGas: '0x1000', + maxFeePerGas: '0xabc', + maxPriorityFeePerGas: '0x123', + paymasterAndData: '0x', + signature: '0x', + }; + + it('should successfully sign a UserOperation', async () => { + mockSignUserOp(true); + const porterClient = new PorterClient(fakePorterUris[2]); + const result = await porterClient.signUserOp( + mockUserOp, + 8453, + 'zerodev', + 'v0.8', + 5, + true, + true + ); + + expect(result).toEqual({ + digest: '0x1234', + aggregated_signature: '0x5678', + signing_results: { + '0x1234': ['0x5678', '0x90ab'], + '0xabcd': ['0xefgh', '0xijkl'], + }, + type: 'userOp:zerodev', + }); + }); + + it('should handle UserOperation signing failures', async () => { + mockSignUserOp(false); + const porterClient = new PorterClient(fakePorterUris[2]); + + await expect( + porterClient.signUserOp( + mockUserOp, + 8453, + 'zerodev', + 'v0.8', + 5, + true, + true + ) + ).rejects.toThrow('Porter returned bad response: 400 - '); + }); + }); +}); From ac9b8fb8d305652ce0c210898f78dc0e32b66fe6 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 5 Jun 2025 08:41:45 +0100 Subject: [PATCH 033/303] Fix linting errors --- packages/shared/test/porter.test.ts | 5 +++-- packages/taco/src/utils.ts | 10 ---------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index 70ee58439..0620cad50 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -1,11 +1,12 @@ import { fakeUrsulas } from '@nucypher/test-utils'; import axios, { HttpStatusCode } from 'axios'; -import { MockInstance, beforeAll, describe, expect, it, vi } from 'vitest'; +import { beforeAll, describe, expect, it, MockInstance, vi } from 'vitest'; + import { domains, - GetUrsulasResult, getPorterUris, getPorterUrisFromSource, + GetUrsulasResult, initialize, PorterClient, toHexString, diff --git a/packages/taco/src/utils.ts b/packages/taco/src/utils.ts index c384ec58b..32cc94e9b 100644 --- a/packages/taco/src/utils.ts +++ b/packages/taco/src/utils.ts @@ -49,13 +49,3 @@ export const toJSON = (obj: unknown) => JSON.stringify(obj, sortedSerializingReplacer); export const fromJSON = (json: string) => JSON.parse(json, customTypeReceiver); - -export function aggregateSignatures(signatures: string[]): string { - // TODO: Implement signature aggregation logic - throw new Error("Not implemented"); -} - -export function verifyThreshold(signatures: string[], threshold: number): boolean { - // TODO: Implement threshold verification logic - throw new Error("Not implemented"); -} From 98922e4caadb165730e35d7acfe1b750ff36733b Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 5 Jun 2025 09:16:02 +0100 Subject: [PATCH 034/303] Add tests for signing --- packages/taco/test/tao-sign.test.ts | 233 ++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 packages/taco/test/tao-sign.test.ts diff --git a/packages/taco/test/tao-sign.test.ts b/packages/taco/test/tao-sign.test.ts new file mode 100644 index 000000000..e8c9ff60a --- /dev/null +++ b/packages/taco/test/tao-sign.test.ts @@ -0,0 +1,233 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { PorterClient } from '@nucypher/shared'; +import { fakePorterUri } from '@nucypher/test-utils'; + +import { sign191, signUserOp } from '../src/sign'; +import { UserOperation } from '../src/types'; + +describe('TACo Signing', () => { + let sign191Mock: ReturnType; + let signUserOpMock: ReturnType; + + beforeEach(() => { + sign191Mock = vi.fn(); + signUserOpMock = vi.fn(); + vi.spyOn(PorterClient.prototype, 'sign191').mockImplementation(sign191Mock); + vi.spyOn(PorterClient.prototype, 'signUserOp').mockImplementation(signUserOpMock); + }); + + describe('sign191', () => { + const message = 'Hello, TACo!'; + const cohortId = 5; + const domain = fakePorterUri; + + it('should sign a string message', async () => { + const expectedResult = { + digest: '0x123', + aggregated_signature: '0x456', + signing_results: { + '0x789': ['0xabc', '0xdef'], + }, + type: 'eip191', + }; + + sign191Mock.mockResolvedValue(expectedResult); + + const result = await sign191(message, cohortId, domain); + + expect(sign191Mock).toHaveBeenCalledWith( + expect.any(Uint8Array), + cohortId, + true, + true + ); + expect(result).toEqual({ + digest: expectedResult.digest, + aggregatedSignature: expectedResult.aggregated_signature, + signingResults: expectedResult.signing_results, + type: expectedResult.type, + }); + }); + + it('should sign a Uint8Array message', async () => { + const messageBytes = new TextEncoder().encode(message); + const expectedResult = { + digest: '0x123', + aggregated_signature: '0x456', + signing_results: { + '0x789': ['0xabc', '0xdef'], + }, + type: 'eip191', + }; + + sign191Mock.mockResolvedValue(expectedResult); + + const result = await sign191(messageBytes, cohortId, domain); + + expect(sign191Mock).toHaveBeenCalledWith( + messageBytes, + cohortId, + true, + true + ); + expect(result).toEqual({ + digest: expectedResult.digest, + aggregatedSignature: expectedResult.aggregated_signature, + signingResults: expectedResult.signing_results, + type: expectedResult.type, + }); + }); + + it('should handle custom signing options', async () => { + const options = { optimistic: false, returnAggregated: false }; + const expectedResult = { + digest: '0x123', + aggregated_signature: '0x456', + signing_results: { + '0x789': ['0xabc', '0xdef'], + }, + type: 'eip191', + }; + + sign191Mock.mockResolvedValue(expectedResult); + + await sign191(message, cohortId, domain, options); + + expect(sign191Mock).toHaveBeenCalledWith( + expect.any(Uint8Array), + cohortId, + false, + false + ); + }); + }); + + describe('signUserOp', () => { + const userOp: UserOperation = { + sender: '0x123', + nonce: '0x1', + initCode: '0x', + callData: '0x', + callGasLimit: '0x1', + verificationGasLimit: '0x1', + preVerificationGas: '0x1', + maxFeePerGas: '0x1', + maxPriorityFeePerGas: '0x1', + paymasterAndData: '0x', + signature: '0x', + }; + const chainId = 1; + const cohortId = 5; + const domain = fakePorterUri; + + it('should sign a user operation with zerodev account', async () => { + const expectedResult = { + digest: '0x123', + aggregated_signature: '0x456', + signing_results: { + '0x789': ['0xabc', '0xdef'], + }, + type: 'eip191', + }; + + signUserOpMock.mockResolvedValue(expectedResult); + + const result = await signUserOp( + userOp, + chainId, + 'zerodev', + 'v0.6', + cohortId, + domain + ); + + expect(signUserOpMock).toHaveBeenCalledWith( + userOp, + chainId, + 'zerodev', + 'v0.6', + cohortId, + true, + true + ); + expect(result).toEqual({ + digest: expectedResult.digest, + aggregatedSignature: expectedResult.aggregated_signature, + signingResults: expectedResult.signing_results, + type: expectedResult.type, + }); + }); + + it('should sign a user operation with kernel account', async () => { + const expectedResult = { + digest: '0x123', + aggregated_signature: '0x456', + signing_results: { + '0x789': ['0xabc', '0xdef'], + }, + type: 'eip191', + }; + + signUserOpMock.mockResolvedValue(expectedResult); + + const result = await signUserOp( + userOp, + chainId, + 'kernel', + 'v0.7', + cohortId, + domain + ); + + expect(signUserOpMock).toHaveBeenCalledWith( + userOp, + chainId, + 'kernel', + 'v0.7', + cohortId, + true, + true + ); + expect(result).toEqual({ + digest: expectedResult.digest, + aggregatedSignature: expectedResult.aggregated_signature, + signingResults: expectedResult.signing_results, + type: expectedResult.type, + }); + }); + + it('should handle custom signing options', async () => { + const options = { optimistic: false, returnAggregated: false }; + const expectedResult = { + digest: '0x123', + aggregated_signature: '0x456', + signing_results: { + '0x789': ['0xabc', '0xdef'], + }, + type: 'eip191', + }; + + signUserOpMock.mockResolvedValue(expectedResult); + + await signUserOp( + userOp, + chainId, + 'safe', + 'v0.8', + cohortId, + domain, + options + ); + + expect(signUserOpMock).toHaveBeenCalledWith( + userOp, + chainId, + 'safe', + 'v0.8', + cohortId, + false, + false + ); + }); + }); +}); From a88510808d9b8cd6c8fd7ae1039f717c16cb8b28 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 6 Jun 2025 11:09:20 +0100 Subject: [PATCH 035/303] Refactor mock signing as per Copilot code review --- packages/shared/test/porter.test.ts | 57 ++++++++--------------------- 1 file changed, 16 insertions(+), 41 deletions(-) diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index 0620cad50..1f1502a4b 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -50,26 +50,26 @@ const mockGetUrsulas = (ursulas: Ursula[] = fakeUrsulas()): MockInstance => { }); }; -const mockSign191 = (success: boolean = true): MockInstance => { - const fakeSignResponse = { - result: { - digest: '0x1234', - aggregated_signature: '0x5678', - signing_results: { - '0x1234': ['0x5678', '0x90ab'], - '0xabcd': ['0xefgh', '0xijkl'], - }, - type: 'eip191', +const createMockSignResponse = (type: string) => ({ + result: { + digest: '0x1234', + aggregated_signature: '0x5678', + signing_results: { + '0x1234': ['0x5678', '0x90ab'], + '0xabcd': ['0xefgh', '0xijkl'], }, - version: '5.2.0', - }; + type, + }, + version: '5.2.0', +}); +const createMockSignImplementation = (endpoint: string, type: string) => (success: boolean = true): MockInstance => { return vi.spyOn(axios, 'request').mockImplementation(async (config) => { - if (config.url === '/sign191') { + if (config.url === endpoint) { if (success) { return Promise.resolve({ status: HttpStatusCode.Ok, - data: fakeSignResponse, + data: createMockSignResponse(type), }); } return Promise.resolve({ status: HttpStatusCode.BadRequest, data: '' }); @@ -78,33 +78,8 @@ const mockSign191 = (success: boolean = true): MockInstance => { }); }; -const mockSignUserOp = (success: boolean = true): MockInstance => { - const fakeSignResponse = { - result: { - digest: '0x1234', - aggregated_signature: '0x5678', - signing_results: { - '0x1234': ['0x5678', '0x90ab'], - '0xabcd': ['0xefgh', '0xijkl'], - }, - type: 'userOp:zerodev', - }, - version: '5.2.0', - }; - - return vi.spyOn(axios, 'request').mockImplementation(async (config) => { - if (config.url === '/sign_user_op') { - if (success) { - return Promise.resolve({ - status: HttpStatusCode.Ok, - data: fakeSignResponse, - }); - } - return Promise.resolve({ status: HttpStatusCode.BadRequest, data: '' }); - } - throw new Error('Unexpected endpoint'); - }); -}; +const mockSign191 = createMockSignImplementation('/sign191', 'eip191'); +const mockSignUserOp = createMockSignImplementation('/sign_user_op', 'userOp:zerodev'); describe('getPorterUris', () => { beforeAll(async () => { From c8862ff1d33782f054285a7ace90f6f962957c07 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 6 Jun 2025 11:30:59 +0100 Subject: [PATCH 036/303] Add signing types and build out porter signing methods --- packages/shared/src/porter.ts | 145 +++++++++++++++++----------------- 1 file changed, 73 insertions(+), 72 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index b857b757d..159f2ba32 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -153,48 +153,44 @@ export type TacoDecryptResult = { }; // Signing types -type PostSign191Request = { - readonly payload: Base64EncodedBytes; +type SignRequest = { + readonly payload?: Base64EncodedBytes; + readonly packed_user_op?: string; + readonly signature_type: string; + readonly aa_version?: string; readonly cohort_id: number; - readonly optimistic?: boolean; - readonly return_aggregated?: boolean; -}; - -type PostSignUserOpRequest = { - readonly user_op: { - readonly sender: string; - readonly nonce: string; - readonly init_code: string; - readonly call_data: string; - readonly call_gas_limit: string; - readonly verification_gas_limit: string; - readonly pre_verification_gas: string; - readonly max_fee_per_gas: string; - readonly max_priority_fee_per_gas: string; - readonly paymaster_and_data: string; - readonly signature: string; - }; - readonly chain_id: number; - readonly account_spec: string; - readonly entry_point_version: string; - readonly cohort_id: number; - readonly optimistic?: boolean; - readonly return_aggregated?: boolean; + readonly chain_id?: number; + readonly context?: Record; }; type SignResponse = { readonly result: { readonly digest: HexEncodedBytes; - readonly aggregated_signature: HexEncodedBytes; - readonly signing_results: Record< - ChecksumAddress, - [ChecksumAddress, Base64EncodedBytes] - >; - readonly type: string; + readonly signing_results: Record; }; readonly version: string; }; +type SignResult = { + digest: string; + aggregatedSignature: string; + signingResults: { [ursulaAddress: string]: [string, string] }; + type: string; +}; + +function aggregatePorterSignatures( + signaturesWithAddress: { [checksumAddress: string]: [string, string] } +): string { + const sortedSignaturePairs = Object.entries(signaturesWithAddress) + .sort(([_, [addr1]], [__, [addr2]]) => + addr1.toLowerCase().localeCompare(addr2.toLowerCase()) + ); + + const sortedSignatures = sortedSignaturePairs.map(([_, [__, signature]]) => signature); + const combined = sortedSignatures.join(''); + return combined; +} + export class PorterClient { readonly porterUrls: URL[]; @@ -333,12 +329,11 @@ export class PorterClient { cohortId: number, optimistic: boolean = true, returnAggregated: boolean = true, - ): Promise { - const data: PostSign191Request = { + ): Promise { + const data: SignRequest = { payload: toBase64(payload), + signature_type: 'eip191', cohort_id: cohortId, - optimistic, - return_aggregated: returnAggregated, }; const resp: AxiosResponse = await this.tryAndCall({ @@ -347,58 +342,64 @@ export class PorterClient { data, }); - return resp.data.result; + const signingResults: { [ursulaAddress: string]: [string, string] } = {}; + for (const [ursulaAddress, [signerAddress, signatureB64]] of Object.entries( + resp.data.result.signing_results + )) { + signingResults[ursulaAddress] = [signerAddress, signatureB64]; + } + + return { + digest: resp.data.result.digest, + aggregatedSignature: aggregatePorterSignatures(signingResults), + signingResults, + type: 'eip191' + }; } public async signUserOp( - userOp: { - sender: string; - nonce: string; - initCode: string; - callData: string; - callGasLimit: string; - verificationGasLimit: string; - preVerificationGas: string; - maxFeePerGas: string; - maxPriorityFeePerGas: string; - paymasterAndData: string; - signature: string; - }, + packedUserOp: Record, chainId: number, accountSpec: string, entryPointVersion: string, cohortId: number, optimistic: boolean = true, returnAggregated: boolean = true, - ): Promise { - const data: PostSignUserOpRequest = { - user_op: { - sender: userOp.sender, - nonce: userOp.nonce, - init_code: userOp.initCode, - call_data: userOp.callData, - call_gas_limit: userOp.callGasLimit, - verification_gas_limit: userOp.verificationGasLimit, - pre_verification_gas: userOp.preVerificationGas, - max_fee_per_gas: userOp.maxFeePerGas, - max_priority_fee_per_gas: userOp.maxPriorityFeePerGas, - paymaster_and_data: userOp.paymasterAndData, - signature: userOp.signature, - }, - chain_id: chainId, - account_spec: accountSpec, - entry_point_version: entryPointVersion, + context: Record = {}, + ): Promise { + const data: SignRequest = { + signature_type: 'packedUserOp', + aa_version: 'mdt', + packed_user_op: JSON.stringify(packedUserOp), cohort_id: cohortId, - optimistic, - return_aggregated: returnAggregated, + chain_id: chainId, + context, }; const resp: AxiosResponse = await this.tryAndCall({ - url: '/sign_user_op', + url: '/sign', method: 'post', data, }); - return resp.data.result; + const signingResults: { [ursulaAddress: string]: [string, string] } = {}; + let messageHash = ''; + + for (const [ursulaAddress, [signerAddress, signatureB64]] of Object.entries( + resp.data.result.signing_results + )) { + const decodedData = JSON.parse( + new TextDecoder().decode(fromBase64(signatureB64)) + ); + messageHash = decodedData.message_hash; + signingResults[ursulaAddress] = [signerAddress, decodedData.signature]; + } + + return { + digest: messageHash, + aggregatedSignature: aggregatePorterSignatures(signingResults), + signingResults, + type: `userOp:${accountSpec}` + }; } } From e7dfa71c2a97b32d5f964eca6415855602817b89 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 6 Jun 2025 11:41:49 +0100 Subject: [PATCH 037/303] Add signingOptions type and fix tests --- packages/shared/src/porter.ts | 32 ++++++++----- packages/shared/test/porter.test.ts | 69 ++++++++++++++++++----------- 2 files changed, 64 insertions(+), 37 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index 159f2ba32..e5fc0e356 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -153,14 +153,21 @@ export type TacoDecryptResult = { }; // Signing types +type SigningOptions = { + optimistic?: boolean; // Whether to return first signatures received or wait for all signatures + returnAggregated?: boolean; // Whether to return the aggregated signature +}; + type SignRequest = { - readonly payload?: Base64EncodedBytes; - readonly packed_user_op?: string; + readonly payload?: Base64EncodedBytes | undefined; + readonly packed_user_op?: string | undefined; readonly signature_type: string; - readonly aa_version?: string; + readonly aa_version?: string | undefined; readonly cohort_id: number; - readonly chain_id?: number; - readonly context?: Record; + readonly chain_id?: number | undefined; + readonly context?: Record | undefined; + readonly optimistic?: boolean | undefined; + readonly return_aggregated?: boolean | undefined; }; type SignResponse = { @@ -327,13 +334,14 @@ export class PorterClient { public async sign191( payload: Uint8Array, cohortId: number, - optimistic: boolean = true, - returnAggregated: boolean = true, + options: SigningOptions = { optimistic: true, returnAggregated: true } ): Promise { const data: SignRequest = { payload: toBase64(payload), signature_type: 'eip191', cohort_id: cohortId, + optimistic: options.optimistic, + return_aggregated: options.returnAggregated, }; const resp: AxiosResponse = await this.tryAndCall({ @@ -346,7 +354,10 @@ export class PorterClient { for (const [ursulaAddress, [signerAddress, signatureB64]] of Object.entries( resp.data.result.signing_results )) { - signingResults[ursulaAddress] = [signerAddress, signatureB64]; + const decodedData = JSON.parse( + new TextDecoder().decode(fromBase64(signatureB64)) + ); + signingResults[ursulaAddress] = [signerAddress, decodedData.signature]; } return { @@ -363,8 +374,7 @@ export class PorterClient { accountSpec: string, entryPointVersion: string, cohortId: number, - optimistic: boolean = true, - returnAggregated: boolean = true, + options: SigningOptions = { optimistic: true, returnAggregated: true }, context: Record = {}, ): Promise { const data: SignRequest = { @@ -374,6 +384,8 @@ export class PorterClient { cohort_id: cohortId, chain_id: chainId, context, + optimistic: options.optimistic, + return_aggregated: options.returnAggregated, }; const resp: AxiosResponse = await this.tryAndCall({ diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index 1f1502a4b..7158afae2 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -11,6 +11,7 @@ import { PorterClient, toHexString, Ursula, + toBase64, } from '../src'; const fakePorterUris = [ @@ -53,12 +54,16 @@ const mockGetUrsulas = (ursulas: Ursula[] = fakeUrsulas()): MockInstance => { const createMockSignResponse = (type: string) => ({ result: { digest: '0x1234', - aggregated_signature: '0x5678', signing_results: { - '0x1234': ['0x5678', '0x90ab'], - '0xabcd': ['0xefgh', '0xijkl'], - }, - type, + '0x1234': ['0x5678', toBase64(new TextEncoder().encode(JSON.stringify({ + message_hash: '0x1234', + signature: '0x90ab' + })))], + '0xabcd': ['0xefgh', toBase64(new TextEncoder().encode(JSON.stringify({ + message_hash: '0x1234', + signature: '0xijkl' + })))] + } }, version: '5.2.0', }); @@ -79,7 +84,7 @@ const createMockSignImplementation = (endpoint: string, type: string) => (succes }; const mockSign191 = createMockSignImplementation('/sign191', 'eip191'); -const mockSignUserOp = createMockSignImplementation('/sign_user_op', 'userOp:zerodev'); +const mockSignUserOp = createMockSignImplementation('/sign', 'userOp:zerodev'); describe('getPorterUris', () => { beforeAll(async () => { @@ -160,12 +165,15 @@ describe('PorterClient Signing', () => { mockSign191(true); const porterClient = new PorterClient(fakePorterUris[2]); const payload = new TextEncoder().encode('Hello, TACo!'); - const result = await porterClient.sign191(payload, 5, true, true); + const result = await porterClient.sign191(payload, 5, { + optimistic: true, + returnAggregated: true + }); expect(result).toEqual({ digest: '0x1234', - aggregated_signature: '0x5678', - signing_results: { + aggregatedSignature: '0x90ab0xijkl', // Combined signatures in sorted order + signingResults: { '0x1234': ['0x5678', '0x90ab'], '0xabcd': ['0xefgh', '0xijkl'], }, @@ -179,23 +187,26 @@ describe('PorterClient Signing', () => { const payload = new TextEncoder().encode('Hello, TACo!'); await expect( - porterClient.sign191(payload, 5, true, true) + porterClient.sign191(payload, 5, { + optimistic: true, + returnAggregated: true + }) ).rejects.toThrow('Porter returned bad response: 400 - '); }); }); describe('signUserOp', () => { - const mockUserOp = { + const mockPackedUserOp = { sender: '0x1234', nonce: '0x1', - initCode: '0x', - callData: '0xabc', - callGasLimit: '0x20000', - verificationGasLimit: '0x15000', - preVerificationGas: '0x1000', - maxFeePerGas: '0xabc', - maxPriorityFeePerGas: '0x123', - paymasterAndData: '0x', + init_code: '0x', + call_data: '0xabc', + call_gas_limit: '0x20000', + verification_gas_limit: '0x15000', + pre_verification_gas: '0x1000', + max_fee_per_gas: '0xabc', + max_priority_fee_per_gas: '0x123', + paymaster_and_data: '0x', signature: '0x', }; @@ -203,19 +214,21 @@ describe('PorterClient Signing', () => { mockSignUserOp(true); const porterClient = new PorterClient(fakePorterUris[2]); const result = await porterClient.signUserOp( - mockUserOp, + mockPackedUserOp, 8453, 'zerodev', 'v0.8', 5, - true, - true + { + optimistic: true, + returnAggregated: true + } ); expect(result).toEqual({ digest: '0x1234', - aggregated_signature: '0x5678', - signing_results: { + aggregatedSignature: '0x90ab0xijkl', // Combined signatures in sorted order + signingResults: { '0x1234': ['0x5678', '0x90ab'], '0xabcd': ['0xefgh', '0xijkl'], }, @@ -229,13 +242,15 @@ describe('PorterClient Signing', () => { await expect( porterClient.signUserOp( - mockUserOp, + mockPackedUserOp, 8453, 'zerodev', 'v0.8', 5, - true, - true + { + optimistic: true, + returnAggregated: true + } ) ).rejects.toThrow('Porter returned bad response: 400 - '); }); From 2021e2cb9037ef0051373950054929aefc136e56 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 6 Jun 2025 12:17:19 +0100 Subject: [PATCH 038/303] Fix tests and CamelCase --- packages/taco/src/sign.ts | 14 +- packages/taco/test/tao-sign.test.ts | 239 +++++++++++++++------------- 2 files changed, 138 insertions(+), 115 deletions(-) diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index c3adc2afd..cfa04af20 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -19,14 +19,13 @@ export async function sign191( const result = await porter.sign191( payloadBytes, cohortId, - options.optimistic, - options.returnAggregated + options ); return { digest: result.digest, - aggregatedSignature: result.aggregated_signature, - signingResults: result.signing_results, + aggregatedSignature: result.aggregatedSignature, + signingResults: result.signingResults, type: result.type }; } @@ -48,14 +47,13 @@ export async function signUserOp( accountSpec, entryPointVersion, cohortId, - options.optimistic, - options.returnAggregated + options ); return { digest: result.digest, - aggregatedSignature: result.aggregated_signature, - signingResults: result.signing_results, + aggregatedSignature: result.aggregatedSignature, + signingResults: result.signingResults, type: result.type }; } \ No newline at end of file diff --git a/packages/taco/test/tao-sign.test.ts b/packages/taco/test/tao-sign.test.ts index e8c9ff60a..b26009d80 100644 --- a/packages/taco/test/tao-sign.test.ts +++ b/packages/taco/test/tao-sign.test.ts @@ -3,7 +3,6 @@ import { PorterClient } from '@nucypher/shared'; import { fakePorterUri } from '@nucypher/test-utils'; import { sign191, signUserOp } from '../src/sign'; -import { UserOperation } from '../src/types'; describe('TACo Signing', () => { let sign191Mock: ReturnType; @@ -17,126 +16,137 @@ describe('TACo Signing', () => { }); describe('sign191', () => { - const message = 'Hello, TACo!'; - const cohortId = 5; - const domain = fakePorterUri; - it('should sign a string message', async () => { - const expectedResult = { - digest: '0x123', - aggregated_signature: '0x456', - signing_results: { - '0x789': ['0xabc', '0xdef'], + const message = 'Hello, TACo!'; + const cohortId = 5; + const domain = fakePorterUri; + + sign191Mock.mockResolvedValue({ + digest: '0x1234', + aggregatedSignature: '0x90ab0xijkl', + signingResults: { + '0x1234': ['0x5678', '0x90ab'], + '0xabcd': ['0xefgh', '0xijkl'], }, type: 'eip191', - }; - - sign191Mock.mockResolvedValue(expectedResult); + }); const result = await sign191(message, cohortId, domain); expect(sign191Mock).toHaveBeenCalledWith( expect.any(Uint8Array), cohortId, - true, - true + { optimistic: true, returnAggregated: true } ); + expect(result).toEqual({ - digest: expectedResult.digest, - aggregatedSignature: expectedResult.aggregated_signature, - signingResults: expectedResult.signing_results, - type: expectedResult.type, + digest: '0x1234', + aggregatedSignature: '0x90ab0xijkl', + signingResults: { + '0x1234': ['0x5678', '0x90ab'], + '0xabcd': ['0xefgh', '0xijkl'], + }, + type: 'eip191', }); }); it('should sign a Uint8Array message', async () => { - const messageBytes = new TextEncoder().encode(message); - const expectedResult = { - digest: '0x123', - aggregated_signature: '0x456', - signing_results: { - '0x789': ['0xabc', '0xdef'], + const messageBytes = new TextEncoder().encode('Hello, TACo!'); + const cohortId = 5; + const domain = fakePorterUri; + + sign191Mock.mockResolvedValue({ + digest: '0x1234', + aggregatedSignature: '0x90ab0xijkl', + signingResults: { + '0x1234': ['0x5678', '0x90ab'], + '0xabcd': ['0xefgh', '0xijkl'], }, type: 'eip191', - }; - - sign191Mock.mockResolvedValue(expectedResult); + }); const result = await sign191(messageBytes, cohortId, domain); expect(sign191Mock).toHaveBeenCalledWith( messageBytes, cohortId, - true, - true + { optimistic: true, returnAggregated: true } ); + expect(result).toEqual({ - digest: expectedResult.digest, - aggregatedSignature: expectedResult.aggregated_signature, - signingResults: expectedResult.signing_results, - type: expectedResult.type, + digest: '0x1234', + aggregatedSignature: '0x90ab0xijkl', + signingResults: { + '0x1234': ['0x5678', '0x90ab'], + '0xabcd': ['0xefgh', '0xijkl'], + }, + type: 'eip191', }); }); it('should handle custom signing options', async () => { + const message = 'Hello, TACo!'; + const cohortId = 5; + const domain = fakePorterUri; const options = { optimistic: false, returnAggregated: false }; - const expectedResult = { - digest: '0x123', - aggregated_signature: '0x456', - signing_results: { - '0x789': ['0xabc', '0xdef'], + + sign191Mock.mockResolvedValue({ + digest: '0x1234', + aggregatedSignature: '0x90ab0xijkl', + signingResults: { + '0x1234': ['0x5678', '0x90ab'], + '0xabcd': ['0xefgh', '0xijkl'], }, type: 'eip191', - }; - - sign191Mock.mockResolvedValue(expectedResult); + }); await sign191(message, cohortId, domain, options); expect(sign191Mock).toHaveBeenCalledWith( expect.any(Uint8Array), cohortId, - false, - false + options ); }); }); describe('signUserOp', () => { - const userOp: UserOperation = { + const userOp = { sender: '0x123', nonce: '0x1', initCode: '0x', - callData: '0x', - callGasLimit: '0x1', - verificationGasLimit: '0x1', - preVerificationGas: '0x1', - maxFeePerGas: '0x1', - maxPriorityFeePerGas: '0x1', + callData: '0xabc', + callGasLimit: '0x20000', + verificationGasLimit: '0x15000', + preVerificationGas: '0x1000', + maxFeePerGas: '0xabc', + maxPriorityFeePerGas: '0x123', paymasterAndData: '0x', signature: '0x', }; - const chainId = 1; - const cohortId = 5; - const domain = fakePorterUri; it('should sign a user operation with zerodev account', async () => { - const expectedResult = { - digest: '0x123', - aggregated_signature: '0x456', - signing_results: { - '0x789': ['0xabc', '0xdef'], - }, - type: 'eip191', - }; + const chainId = 1; + const accountSpec = 'zerodev'; + const entryPointVersion = 'v0.6'; + const cohortId = 5; + const domain = fakePorterUri; - signUserOpMock.mockResolvedValue(expectedResult); + signUserOpMock.mockResolvedValue({ + digest: '0x1234', + aggregatedSignature: '0x90ab0xijkl', + signingResults: { + '0x1234': ['0x5678', '0x90ab'], + '0xabcd': ['0xefgh', '0xijkl'], + }, + type: 'userOp:zerodev', + }); const result = await signUserOp( userOp, chainId, - 'zerodev', - 'v0.6', + accountSpec, + entryPointVersion, cohortId, domain ); @@ -144,37 +154,45 @@ describe('TACo Signing', () => { expect(signUserOpMock).toHaveBeenCalledWith( userOp, chainId, - 'zerodev', - 'v0.6', + accountSpec, + entryPointVersion, cohortId, - true, - true + { optimistic: true, returnAggregated: true } ); + expect(result).toEqual({ - digest: expectedResult.digest, - aggregatedSignature: expectedResult.aggregated_signature, - signingResults: expectedResult.signing_results, - type: expectedResult.type, + digest: '0x1234', + aggregatedSignature: '0x90ab0xijkl', + signingResults: { + '0x1234': ['0x5678', '0x90ab'], + '0xabcd': ['0xefgh', '0xijkl'], + }, + type: 'userOp:zerodev', }); }); it('should sign a user operation with kernel account', async () => { - const expectedResult = { - digest: '0x123', - aggregated_signature: '0x456', - signing_results: { - '0x789': ['0xabc', '0xdef'], - }, - type: 'eip191', - }; + const chainId = 1; + const accountSpec = 'kernel'; + const entryPointVersion = 'v0.7'; + const cohortId = 5; + const domain = fakePorterUri; - signUserOpMock.mockResolvedValue(expectedResult); + signUserOpMock.mockResolvedValue({ + digest: '0x1234', + aggregatedSignature: '0x90ab0xijkl', + signingResults: { + '0x1234': ['0x5678', '0x90ab'], + '0xabcd': ['0xefgh', '0xijkl'], + }, + type: 'userOp:kernel', + }); const result = await signUserOp( userOp, chainId, - 'kernel', - 'v0.7', + accountSpec, + entryPointVersion, cohortId, domain ); @@ -182,38 +200,46 @@ describe('TACo Signing', () => { expect(signUserOpMock).toHaveBeenCalledWith( userOp, chainId, - 'kernel', - 'v0.7', + accountSpec, + entryPointVersion, cohortId, - true, - true + { optimistic: true, returnAggregated: true } ); + expect(result).toEqual({ - digest: expectedResult.digest, - aggregatedSignature: expectedResult.aggregated_signature, - signingResults: expectedResult.signing_results, - type: expectedResult.type, + digest: '0x1234', + aggregatedSignature: '0x90ab0xijkl', + signingResults: { + '0x1234': ['0x5678', '0x90ab'], + '0xabcd': ['0xefgh', '0xijkl'], + }, + type: 'userOp:kernel', }); }); it('should handle custom signing options', async () => { + const chainId = 1; + const accountSpec = 'safe'; + const entryPointVersion = 'v0.8'; + const cohortId = 5; + const domain = fakePorterUri; const options = { optimistic: false, returnAggregated: false }; - const expectedResult = { - digest: '0x123', - aggregated_signature: '0x456', - signing_results: { - '0x789': ['0xabc', '0xdef'], - }, - type: 'eip191', - }; - signUserOpMock.mockResolvedValue(expectedResult); + signUserOpMock.mockResolvedValue({ + digest: '0x1234', + aggregatedSignature: '0x90ab0xijkl', + signingResults: { + '0x1234': ['0x5678', '0x90ab'], + '0xabcd': ['0xefgh', '0xijkl'], + }, + type: 'userOp:safe', + }); await signUserOp( userOp, chainId, - 'safe', - 'v0.8', + accountSpec, + entryPointVersion, cohortId, domain, options @@ -222,11 +248,10 @@ describe('TACo Signing', () => { expect(signUserOpMock).toHaveBeenCalledWith( userOp, chainId, - 'safe', - 'v0.8', + accountSpec, + entryPointVersion, cohortId, - false, - false + options ); }); }); From 8ef0df2bce16ee2a7fa2d606363109d8b2e73380 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 6 Jun 2025 12:22:12 +0100 Subject: [PATCH 039/303] Fix linting --- packages/shared/src/porter.ts | 6 +++--- packages/taco/test/tao-sign.test.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index e5fc0e356..bb0f951d7 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -189,11 +189,11 @@ function aggregatePorterSignatures( signaturesWithAddress: { [checksumAddress: string]: [string, string] } ): string { const sortedSignaturePairs = Object.entries(signaturesWithAddress) - .sort(([_, [addr1]], [__, [addr2]]) => + .sort(([, [addr1]], [, [addr2]]) => addr1.toLowerCase().localeCompare(addr2.toLowerCase()) ); - const sortedSignatures = sortedSignaturePairs.map(([_, [__, signature]]) => signature); + const sortedSignatures = sortedSignaturePairs.map(([, [, signature]]) => signature); const combined = sortedSignatures.join(''); return combined; } @@ -414,4 +414,4 @@ export class PorterClient { type: `userOp:${accountSpec}` }; } -} +} \ No newline at end of file diff --git a/packages/taco/test/tao-sign.test.ts b/packages/taco/test/tao-sign.test.ts index b26009d80..47ab1bf4f 100644 --- a/packages/taco/test/tao-sign.test.ts +++ b/packages/taco/test/tao-sign.test.ts @@ -1,6 +1,6 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest'; import { PorterClient } from '@nucypher/shared'; import { fakePorterUri } from '@nucypher/test-utils'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; import { sign191, signUserOp } from '../src/sign'; From b9aa4bf1704f7255ae7a6ccfc71987b7eb3edfc9 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 10 Jun 2025 11:11:31 +0100 Subject: [PATCH 040/303] Rename file and allow Porter uri to be passed to signing function --- packages/taco/src/sign.ts | 36 +++++++++---------- .../{tao-sign.test.ts => taco-sign.test.ts} | 31 +++++++++------- 2 files changed, 35 insertions(+), 32 deletions(-) rename packages/taco/test/{tao-sign.test.ts => taco-sign.test.ts} (90%) diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index cfa04af20..bf7f496bd 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -1,4 +1,4 @@ -import { Domain, PorterClient } from '@nucypher/shared'; +import { Domain, getPorterUris, PorterClient } from '@nucypher/shared'; import { SigningOptions, SignResult, UserOperation } from './types'; @@ -7,9 +7,13 @@ export async function sign191( payload: Uint8Array | string, cohortId: number, domain: Domain, - options: SigningOptions = { optimistic: true, returnAggregated: true } + options: SigningOptions = { optimistic: true, returnAggregated: true }, + porterUris?: string[] ): Promise { - const porter = new PorterClient(domain); + const porterUrisFull: string[] = porterUris + ? porterUris + : await getPorterUris(domain); + const porter = new PorterClient(porterUrisFull); // Convert string payload to Uint8Array if needed const payloadBytes = typeof payload === 'string' @@ -19,15 +23,10 @@ export async function sign191( const result = await porter.sign191( payloadBytes, cohortId, - options + options, ); - return { - digest: result.digest, - aggregatedSignature: result.aggregatedSignature, - signingResults: result.signingResults, - type: result.type - }; + return result; } export async function signUserOp( @@ -37,9 +36,13 @@ export async function signUserOp( entryPointVersion: "v0.6" | "v0.7" | "v0.8", cohortId: number, domain: Domain, - options: SigningOptions = { optimistic: true, returnAggregated: true } + options: SigningOptions = { optimistic: true, returnAggregated: true }, + porterUris?: string[] ): Promise { - const porter = new PorterClient(domain); + const porterUrisFull: string[] = porterUris + ? porterUris + : await getPorterUris(domain); + const porter = new PorterClient(porterUrisFull); const result = await porter.signUserOp( userOp, @@ -47,13 +50,8 @@ export async function signUserOp( accountSpec, entryPointVersion, cohortId, - options + options, ); - return { - digest: result.digest, - aggregatedSignature: result.aggregatedSignature, - signingResults: result.signingResults, - type: result.type - }; + return result; } \ No newline at end of file diff --git a/packages/taco/test/tao-sign.test.ts b/packages/taco/test/taco-sign.test.ts similarity index 90% rename from packages/taco/test/tao-sign.test.ts rename to packages/taco/test/taco-sign.test.ts index 47ab1bf4f..a32f76bea 100644 --- a/packages/taco/test/tao-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -19,7 +19,7 @@ describe('TACo Signing', () => { it('should sign a string message', async () => { const message = 'Hello, TACo!'; const cohortId = 5; - const domain = fakePorterUri; + const porterUris = [fakePorterUri]; sign191Mock.mockResolvedValue({ digest: '0x1234', @@ -31,7 +31,7 @@ describe('TACo Signing', () => { type: 'eip191', }); - const result = await sign191(message, cohortId, domain); + const result = await sign191(message, cohortId, 'lynx', undefined, porterUris); expect(sign191Mock).toHaveBeenCalledWith( expect.any(Uint8Array), @@ -53,7 +53,7 @@ describe('TACo Signing', () => { it('should sign a Uint8Array message', async () => { const messageBytes = new TextEncoder().encode('Hello, TACo!'); const cohortId = 5; - const domain = fakePorterUri; + const porterUris = [fakePorterUri]; sign191Mock.mockResolvedValue({ digest: '0x1234', @@ -65,7 +65,7 @@ describe('TACo Signing', () => { type: 'eip191', }); - const result = await sign191(messageBytes, cohortId, domain); + const result = await sign191(messageBytes, cohortId, 'lynx', undefined, porterUris); expect(sign191Mock).toHaveBeenCalledWith( messageBytes, @@ -87,7 +87,7 @@ describe('TACo Signing', () => { it('should handle custom signing options', async () => { const message = 'Hello, TACo!'; const cohortId = 5; - const domain = fakePorterUri; + const porterUris = [fakePorterUri]; const options = { optimistic: false, returnAggregated: false }; sign191Mock.mockResolvedValue({ @@ -100,7 +100,7 @@ describe('TACo Signing', () => { type: 'eip191', }); - await sign191(message, cohortId, domain, options); + await sign191(message, cohortId, 'lynx', options, porterUris); expect(sign191Mock).toHaveBeenCalledWith( expect.any(Uint8Array), @@ -130,7 +130,7 @@ describe('TACo Signing', () => { const accountSpec = 'zerodev'; const entryPointVersion = 'v0.6'; const cohortId = 5; - const domain = fakePorterUri; + const porterUris = [fakePorterUri]; signUserOpMock.mockResolvedValue({ digest: '0x1234', @@ -148,7 +148,9 @@ describe('TACo Signing', () => { accountSpec, entryPointVersion, cohortId, - domain + 'lynx', + undefined, + porterUris ); expect(signUserOpMock).toHaveBeenCalledWith( @@ -176,7 +178,7 @@ describe('TACo Signing', () => { const accountSpec = 'kernel'; const entryPointVersion = 'v0.7'; const cohortId = 5; - const domain = fakePorterUri; + const porterUris = [fakePorterUri]; signUserOpMock.mockResolvedValue({ digest: '0x1234', @@ -194,7 +196,9 @@ describe('TACo Signing', () => { accountSpec, entryPointVersion, cohortId, - domain + 'lynx', + undefined, + porterUris ); expect(signUserOpMock).toHaveBeenCalledWith( @@ -222,7 +226,7 @@ describe('TACo Signing', () => { const accountSpec = 'safe'; const entryPointVersion = 'v0.8'; const cohortId = 5; - const domain = fakePorterUri; + const porterUris = [fakePorterUri]; const options = { optimistic: false, returnAggregated: false }; signUserOpMock.mockResolvedValue({ @@ -241,8 +245,9 @@ describe('TACo Signing', () => { accountSpec, entryPointVersion, cohortId, - domain, - options + 'lynx', + options, + porterUris ); expect(signUserOpMock).toHaveBeenCalledWith( From f23c4c46e33533d4300d4d8439b9553e80fb1c11 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 10 Jun 2025 11:26:38 +0100 Subject: [PATCH 041/303] Combine parameters for user op versioning --- packages/shared/src/porter.ts | 17 +++++------------ packages/shared/test/porter.test.ts | 8 +++----- packages/taco/src/sign.ts | 6 ++---- packages/taco/test/taco-sign.test.ts | 27 +++++++++------------------ 4 files changed, 19 insertions(+), 39 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index bb0f951d7..8fb1217b9 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -188,14 +188,8 @@ type SignResult = { function aggregatePorterSignatures( signaturesWithAddress: { [checksumAddress: string]: [string, string] } ): string { - const sortedSignaturePairs = Object.entries(signaturesWithAddress) - .sort(([, [addr1]], [, [addr2]]) => - addr1.toLowerCase().localeCompare(addr2.toLowerCase()) - ); - - const sortedSignatures = sortedSignaturePairs.map(([, [, signature]]) => signature); - const combined = sortedSignatures.join(''); - return combined; + const signatures = Object.values(signaturesWithAddress).map(([, signature]) => signature); + return signatures.join(''); } export class PorterClient { @@ -371,15 +365,14 @@ export class PorterClient { public async signUserOp( packedUserOp: Record, chainId: number, - accountSpec: string, - entryPointVersion: string, + aaVersion: string, cohortId: number, options: SigningOptions = { optimistic: true, returnAggregated: true }, context: Record = {}, ): Promise { const data: SignRequest = { signature_type: 'packedUserOp', - aa_version: 'mdt', + aa_version: aaVersion, packed_user_op: JSON.stringify(packedUserOp), cohort_id: cohortId, chain_id: chainId, @@ -411,7 +404,7 @@ export class PorterClient { digest: messageHash, aggregatedSignature: aggregatePorterSignatures(signingResults), signingResults, - type: `userOp:${accountSpec}` + type: aaVersion }; } } \ No newline at end of file diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index 7158afae2..cb38a71a1 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -216,8 +216,7 @@ describe('PorterClient Signing', () => { const result = await porterClient.signUserOp( mockPackedUserOp, 8453, - 'zerodev', - 'v0.8', + 'zerodev:v0.6', 5, { optimistic: true, @@ -232,7 +231,7 @@ describe('PorterClient Signing', () => { '0x1234': ['0x5678', '0x90ab'], '0xabcd': ['0xefgh', '0xijkl'], }, - type: 'userOp:zerodev', + type: 'zerodev:v0.6', }); }); @@ -244,8 +243,7 @@ describe('PorterClient Signing', () => { porterClient.signUserOp( mockPackedUserOp, 8453, - 'zerodev', - 'v0.8', + 'zerodev:v0.6', 5, { optimistic: true, diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index bf7f496bd..f65b0c971 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -32,8 +32,7 @@ export async function sign191( export async function signUserOp( userOp: UserOperation, chainId: number, - accountSpec: "zerodev" | "kernel" | "metamask" | "safe" | string, - entryPointVersion: "v0.6" | "v0.7" | "v0.8", + aaVersion: "zerodev:v0.6" | "kernel:v0.7" | "safe:v0.8" | "metamask:v0.6" | string, cohortId: number, domain: Domain, options: SigningOptions = { optimistic: true, returnAggregated: true }, @@ -47,8 +46,7 @@ export async function signUserOp( const result = await porter.signUserOp( userOp, chainId, - accountSpec, - entryPointVersion, + aaVersion, cohortId, options, ); diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index a32f76bea..f17e63192 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -127,8 +127,7 @@ describe('TACo Signing', () => { it('should sign a user operation with zerodev account', async () => { const chainId = 1; - const accountSpec = 'zerodev'; - const entryPointVersion = 'v0.6'; + const aaVersion = 'zerodev:v0.6'; const cohortId = 5; const porterUris = [fakePorterUri]; @@ -145,8 +144,7 @@ describe('TACo Signing', () => { const result = await signUserOp( userOp, chainId, - accountSpec, - entryPointVersion, + aaVersion, cohortId, 'lynx', undefined, @@ -156,8 +154,7 @@ describe('TACo Signing', () => { expect(signUserOpMock).toHaveBeenCalledWith( userOp, chainId, - accountSpec, - entryPointVersion, + aaVersion, cohortId, { optimistic: true, returnAggregated: true } ); @@ -175,8 +172,7 @@ describe('TACo Signing', () => { it('should sign a user operation with kernel account', async () => { const chainId = 1; - const accountSpec = 'kernel'; - const entryPointVersion = 'v0.7'; + const aaVersion = 'kernel:v0.7'; const cohortId = 5; const porterUris = [fakePorterUri]; @@ -193,8 +189,7 @@ describe('TACo Signing', () => { const result = await signUserOp( userOp, chainId, - accountSpec, - entryPointVersion, + aaVersion, cohortId, 'lynx', undefined, @@ -204,8 +199,7 @@ describe('TACo Signing', () => { expect(signUserOpMock).toHaveBeenCalledWith( userOp, chainId, - accountSpec, - entryPointVersion, + aaVersion, cohortId, { optimistic: true, returnAggregated: true } ); @@ -223,8 +217,7 @@ describe('TACo Signing', () => { it('should handle custom signing options', async () => { const chainId = 1; - const accountSpec = 'safe'; - const entryPointVersion = 'v0.8'; + const aaVersion = 'safe:v0.8'; const cohortId = 5; const porterUris = [fakePorterUri]; const options = { optimistic: false, returnAggregated: false }; @@ -242,8 +235,7 @@ describe('TACo Signing', () => { await signUserOp( userOp, chainId, - accountSpec, - entryPointVersion, + aaVersion, cohortId, 'lynx', options, @@ -253,8 +245,7 @@ describe('TACo Signing', () => { expect(signUserOpMock).toHaveBeenCalledWith( userOp, chainId, - accountSpec, - entryPointVersion, + aaVersion, cohortId, options ); From 89918b8fb70b212c39497b546bde3bb2a170a3f6 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 10 Jun 2025 11:30:19 +0100 Subject: [PATCH 042/303] Update UserOp type to match official 4337 spec --- packages/shared/test/porter.test.ts | 20 ++++++++++++-------- packages/taco/src/types.ts | 26 +++++++++++++++----------- packages/taco/test/taco-sign.test.ts | 8 ++++++-- 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index cb38a71a1..08d937f4a 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -199,14 +199,18 @@ describe('PorterClient Signing', () => { const mockPackedUserOp = { sender: '0x1234', nonce: '0x1', - init_code: '0x', - call_data: '0xabc', - call_gas_limit: '0x20000', - verification_gas_limit: '0x15000', - pre_verification_gas: '0x1000', - max_fee_per_gas: '0xabc', - max_priority_fee_per_gas: '0x123', - paymaster_and_data: '0x', + factory: '0x0', + factoryData: '0x', + callData: '0xabc', + callGasLimit: '0x20000', + verificationGasLimit: '0x15000', + preVerificationGas: '0x1000', + maxFeePerGas: '0xabc', + maxPriorityFeePerGas: '0x123', + paymaster: '0x0', + paymasterVerificationGasLimit: '0x0', + paymasterPostOpGasLimit: '0x0', + paymasterData: '0x', signature: '0x', }; diff --git a/packages/taco/src/types.ts b/packages/taco/src/types.ts index 30a89502a..4e12a2299 100644 --- a/packages/taco/src/types.ts +++ b/packages/taco/src/types.ts @@ -20,15 +20,19 @@ export type SigningOptions = { }; export type UserOperation = { - sender: string; - nonce: string; - initCode: string; - callData: string; - callGasLimit: string; - verificationGasLimit: string; - preVerificationGas: string; - maxFeePerGas: string; - maxPriorityFeePerGas: string; - paymasterAndData: string; - signature: string; + sender: string; // The Account making the UserOperation + nonce: string; // Anti-replay parameter + factory: string; // Account Factory for new Accounts OR 0x7702 flag for EIP-7702 Accounts, otherwise address(0) + factoryData: string; // data for the Account Factory if factory is provided OR EIP-7702 initialization data, or empty array + callData: string; // The data to pass to the sender during the main execution call + callGasLimit: string; // The amount of gas to allocate the main execution call + verificationGasLimit: string; // The amount of gas to allocate for the verification step + preVerificationGas: string; // Extra gas to pay the bundler + maxFeePerGas: string; // Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) + maxPriorityFeePerGas: string; // Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) + paymaster: string; // Address of paymaster contract, (or empty, if the sender pays for gas by itself) + paymasterVerificationGasLimit: string; // The amount of gas to allocate for the paymaster validation code (only if paymaster exists) + paymasterPostOpGasLimit: string; // The amount of gas to allocate for the paymaster post-operation code (only if paymaster exists) + paymasterData: string; // Data for paymaster (only if paymaster exists) + signature: string; // Data passed into the sender to verify authorization }; diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index f17e63192..2e002fa2e 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -114,14 +114,18 @@ describe('TACo Signing', () => { const userOp = { sender: '0x123', nonce: '0x1', - initCode: '0x', + factory: '0x0', + factoryData: '0x', callData: '0xabc', callGasLimit: '0x20000', verificationGasLimit: '0x15000', preVerificationGas: '0x1000', maxFeePerGas: '0xabc', maxPriorityFeePerGas: '0x123', - paymasterAndData: '0x', + paymaster: '0x0', + paymasterVerificationGasLimit: '0x0', + paymasterPostOpGasLimit: '0x0', + paymasterData: '0x', signature: '0x', }; From 917f2df688a6717f50cf00a57eb580c3cb26aba5 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 10 Jun 2025 11:50:12 +0100 Subject: [PATCH 043/303] Add error handling plus tests for signing functions --- packages/shared/src/porter.ts | 34 ++++++--- packages/shared/test/porter.test.ts | 111 +++++++++++++++++++++++++--- 2 files changed, 126 insertions(+), 19 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index 8fb1217b9..c33dae68e 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -182,6 +182,7 @@ type SignResult = { digest: string; aggregatedSignature: string; signingResults: { [ursulaAddress: string]: [string, string] }; + errors: Record; type: string; }; @@ -345,19 +346,27 @@ export class PorterClient { }); const signingResults: { [ursulaAddress: string]: [string, string] } = {}; + const errors: Record = {}; + for (const [ursulaAddress, [signerAddress, signatureB64]] of Object.entries( resp.data.result.signing_results )) { - const decodedData = JSON.parse( - new TextDecoder().decode(fromBase64(signatureB64)) - ); - signingResults[ursulaAddress] = [signerAddress, decodedData.signature]; + try { + const decodedData = JSON.parse( + new TextDecoder().decode(fromBase64(signatureB64)) + ); + signingResults[ursulaAddress] = [signerAddress, decodedData.signature]; + } catch (e: unknown) { + const errorMessage = e instanceof Error ? e.message : 'Unknown error'; + errors[ursulaAddress] = `Failed to decode signature: ${errorMessage}`; + } } return { digest: resp.data.result.digest, aggregatedSignature: aggregatePorterSignatures(signingResults), signingResults, + errors, type: 'eip191' }; } @@ -388,22 +397,29 @@ export class PorterClient { }); const signingResults: { [ursulaAddress: string]: [string, string] } = {}; + const errors: Record = {}; let messageHash = ''; for (const [ursulaAddress, [signerAddress, signatureB64]] of Object.entries( resp.data.result.signing_results )) { - const decodedData = JSON.parse( - new TextDecoder().decode(fromBase64(signatureB64)) - ); - messageHash = decodedData.message_hash; - signingResults[ursulaAddress] = [signerAddress, decodedData.signature]; + try { + const decodedData = JSON.parse( + new TextDecoder().decode(fromBase64(signatureB64)) + ); + messageHash = decodedData.message_hash; + signingResults[ursulaAddress] = [signerAddress, decodedData.signature]; + } catch (e: unknown) { + const errorMessage = e instanceof Error ? e.message : 'Unknown error'; + errors[ursulaAddress] = `Failed to decode signature: ${errorMessage}`; + } } return { digest: messageHash, aggregatedSignature: aggregatePorterSignatures(signingResults), signingResults, + errors, type: aaVersion }; } diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index 08d937f4a..4a66d6560 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -9,9 +9,9 @@ import { GetUrsulasResult, initialize, PorterClient, + toBase64, toHexString, Ursula, - toBase64, } from '../src'; const fakePorterUris = [ @@ -51,10 +51,16 @@ const mockGetUrsulas = (ursulas: Ursula[] = fakeUrsulas()): MockInstance => { }); }; -const createMockSignResponse = (type: string) => ({ +const createMockSignResponse = (type: string, errorCase?: boolean) => ({ result: { digest: '0x1234', - signing_results: { + signing_results: errorCase ? { + '0x1234': ['0x5678', 'invalid-base64'], + '0xabcd': ['0xefgh', toBase64(new TextEncoder().encode(JSON.stringify({ + message_hash: '0x1234', + signature: '0xijkl' + })))] + } : { '0x1234': ['0x5678', toBase64(new TextEncoder().encode(JSON.stringify({ message_hash: '0x1234', signature: '0x90ab' @@ -68,13 +74,13 @@ const createMockSignResponse = (type: string) => ({ version: '5.2.0', }); -const createMockSignImplementation = (endpoint: string, type: string) => (success: boolean = true): MockInstance => { +const createMockSignImplementation = (endpoint: string, type: string) => (success: boolean = true, errorCase?: boolean): MockInstance => { return vi.spyOn(axios, 'request').mockImplementation(async (config) => { if (config.url === endpoint) { if (success) { return Promise.resolve({ status: HttpStatusCode.Ok, - data: createMockSignResponse(type), + data: createMockSignResponse(type, errorCase), }); } return Promise.resolve({ status: HttpStatusCode.BadRequest, data: '' }); @@ -164,11 +170,14 @@ describe('PorterClient Signing', () => { it('should successfully sign a message', async () => { mockSign191(true); const porterClient = new PorterClient(fakePorterUris[2]); - const payload = new TextEncoder().encode('Hello, TACo!'); - const result = await porterClient.sign191(payload, 5, { - optimistic: true, - returnAggregated: true - }); + const result = await porterClient.sign191( + new TextEncoder().encode('test message'), + 5, + { + optimistic: true, + returnAggregated: true + } + ); expect(result).toEqual({ digest: '0x1234', @@ -177,6 +186,7 @@ describe('PorterClient Signing', () => { '0x1234': ['0x5678', '0x90ab'], '0xabcd': ['0xefgh', '0xijkl'], }, + errors: {}, type: 'eip191', }); }); @@ -235,6 +245,7 @@ describe('PorterClient Signing', () => { '0x1234': ['0x5678', '0x90ab'], '0xabcd': ['0xefgh', '0xijkl'], }, + errors: {}, type: 'zerodev:v0.6', }); }); @@ -256,5 +267,85 @@ describe('PorterClient Signing', () => { ) ).rejects.toThrow('Porter returned bad response: 400 - '); }); + + it('should handle signature decoding errors in UserOperation signing', async () => { + // Mock a response with invalid base64 signature + mockSignUserOp(true, true); + const porterClient = new PorterClient(fakePorterUris[2]); + const result = await porterClient.signUserOp( + mockPackedUserOp, + 8453, + 'zerodev:v0.6', + 5, + { + optimistic: true, + returnAggregated: true + } + ); + + expect(result).toEqual({ + digest: '0x1234', + aggregatedSignature: '0xijkl', // Only valid signature included + signingResults: { + '0xabcd': ['0xefgh', '0xijkl'], + }, + errors: { + '0x1234': 'Failed to decode signature: Invalid character', + }, + type: 'zerodev:v0.6', + }); + }); + + it('should handle signature decoding errors in sign191', async () => { + // Mock a response with invalid base64 signature + mockSign191(true, true); + const porterClient = new PorterClient(fakePorterUris[2]); + const result = await porterClient.sign191( + new TextEncoder().encode('test message'), + 5, + { + optimistic: true, + returnAggregated: true + } + ); + + expect(result).toEqual({ + digest: '0x1234', + aggregatedSignature: '0xijkl', // Only valid signature included + signingResults: { + '0xabcd': ['0xefgh', '0xijkl'], + }, + errors: { + '0x1234': 'Failed to decode signature: Invalid character', + }, + type: 'eip191', + }); + }); + + it('should handle non-Error objects in signature decoding', async () => { + // Mock a response that will cause a non-Error to be thrown + mockSign191(true, true); + const porterClient = new PorterClient(fakePorterUris[2]); + const result = await porterClient.sign191( + new TextEncoder().encode('test message'), + 5, + { + optimistic: true, + returnAggregated: true + } + ); + + expect(result).toEqual({ + digest: '0x1234', + aggregatedSignature: '0xijkl', // Only valid signature included + signingResults: { + '0xabcd': ['0xefgh', '0xijkl'], + }, + errors: { + '0x1234': 'Failed to decode signature: Invalid character', + }, + type: 'eip191', + }); + }); }); }); From 8a1585553586fab84ad21ef04b282146c84961d1 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 13 Jun 2025 13:51:00 +0100 Subject: [PATCH 044/303] Add reserved conext variable for signing condition --- packages/taco/src/conditions/context/context.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/taco/src/conditions/context/context.ts b/packages/taco/src/conditions/context/context.ts index c22993ac8..26a2046bd 100644 --- a/packages/taco/src/conditions/context/context.ts +++ b/packages/taco/src/conditions/context/context.ts @@ -55,7 +55,9 @@ const EXPECTED_AUTH_PROVIDER_TYPES: Record = { ], }; -export const RESERVED_CONTEXT_PARAMS = [USER_ADDRESS_PARAM_DEFAULT]; +const INTERNAL_SIGNING_CONDITION = ':signingConditionObject'; + +export const RESERVED_CONTEXT_PARAMS = [USER_ADDRESS_PARAM_DEFAULT, INTERNAL_SIGNING_CONDITION]; export class ConditionContext { public requestedContextParameters: Set; From 8f03d0b6c872e40169660e389948a0c847411d05 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 16 Jun 2025 09:43:39 +0200 Subject: [PATCH 045/303] Add integration test for signing --- packages/taco/integration-test/sign.test.ts | 102 ++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 packages/taco/integration-test/sign.test.ts diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts new file mode 100644 index 000000000..d9b06cdba --- /dev/null +++ b/packages/taco/integration-test/sign.test.ts @@ -0,0 +1,102 @@ +import { Domain, getPorterUris } from '@nucypher/shared'; +import { ethers } from 'ethers'; +import { beforeAll, describe, expect, test } from 'vitest'; + +import { initialize } from '../src'; +import { sign191, signUserOp } from '../src/sign'; +import { UserOperation } from '../src/types'; + +const RPC_PROVIDER_URL = 'https://rpc-amoy.polygon.technology'; +const SIGNER_PRIVATE_KEY = '0x900edb9e8214b2353f82aa195e915128f419a92cfb8bbc0f4784f10ef4112b86'; +const DOMAIN = 'lynx'; +const RITUAL_ID = 27; +const CHAIN_ID = 80002; + +describe('Taco Sign Integration Test', () => { + let provider: ethers.providers.JsonRpcProvider; + let signer: ethers.Wallet; + + beforeAll(async () => { + provider = new ethers.providers.JsonRpcProvider(RPC_PROVIDER_URL); + signer = new ethers.Wallet(SIGNER_PRIVATE_KEY, provider); + + // Initialize the library + await initialize(); + + // Verify network connection + const network = await provider.getNetwork(); + if (network.chainId !== CHAIN_ID) { + throw new Error( + `Provider connected to wrong network. Expected ${CHAIN_ID}, got ${network.chainId}`, + ); + } + }); + + test('should sign a message using sign191', async () => { + // Create test message + const message = 'This is a test message to sign'; + + // Get porter URIs + const porterUris = await getPorterUris(DOMAIN as Domain); + + // Sign message + const signResult = await sign191( + message, + RITUAL_ID, + DOMAIN as Domain, + { optimistic: true, returnAggregated: true }, + porterUris + ); + + // Verify sign result + expect(signResult).toBeDefined(); + expect(signResult.digest).toBeDefined(); + expect(signResult.aggregatedSignature).toBeDefined(); + expect(signResult.signingResults).toBeDefined(); + expect(signResult.type).toBe('eip191'); + expect(Object.keys(signResult.signingResults).length).toBeGreaterThan(0); + }, 15000); + + test('should sign a user operation', async () => { + // Create a sample user operation with all required fields + const userOp: UserOperation = { + sender: signer.address, + nonce: '0x0', + factory: '0x', + factoryData: '0x', + callData: '0x', + callGasLimit: '0x0', + verificationGasLimit: '0x0', + preVerificationGas: '0x0', + maxFeePerGas: '0x0', + maxPriorityFeePerGas: '0x0', + paymaster: '0x', + paymasterVerificationGasLimit: '0x0', + paymasterPostOpGasLimit: '0x0', + paymasterData: '0x', + signature: '0x' + }; + + // Get porter URIs + const porterUris = await getPorterUris(DOMAIN as Domain); + + // Sign user operation + const signResult = await signUserOp( + userOp, + CHAIN_ID, + 'zerodev:v0.6', + RITUAL_ID, + DOMAIN as Domain, + { optimistic: true, returnAggregated: true }, + porterUris + ); + + // Verify sign result + expect(signResult).toBeDefined(); + expect(signResult.digest).toBeDefined(); + expect(signResult.aggregatedSignature).toBeDefined(); + expect(signResult.signingResults).toBeDefined(); + expect(signResult.type).toBe('zerodev:v0.6'); + expect(Object.keys(signResult.signingResults).length).toBeGreaterThan(0); + }, 15000); +}); \ No newline at end of file From 0855f65fc21e7899b51bb554767af867b81e4f44 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 18 Jun 2025 10:54:38 +0200 Subject: [PATCH 046/303] Begins adding new agent for SigningCoordinator contract --- .../contracts/agents/signingCoordinator.ts | 48 + .../ethers-typechain/SigningCoordinator.ts | 2749 +++++++++++++++++ .../src/contracts/ethers-typechain/index.ts | 1 + packages/shared/src/porter.ts | 21 +- 4 files changed, 2807 insertions(+), 12 deletions(-) create mode 100644 packages/shared/src/contracts/agents/signingCoordinator.ts create mode 100644 packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts diff --git a/packages/shared/src/contracts/agents/signingCoordinator.ts b/packages/shared/src/contracts/agents/signingCoordinator.ts new file mode 100644 index 000000000..39203dc0c --- /dev/null +++ b/packages/shared/src/contracts/agents/signingCoordinator.ts @@ -0,0 +1,48 @@ +import { getContract } from '@nucypher/nucypher-contracts'; +import { ethers } from 'ethers'; + +import { Domain } from '../../porter'; +import { SigningCoordinator__factory } from '../ethers-typechain'; +import { SigningCoordinator } from '../ethers-typechain/SigningCoordinator'; + +export type SigningParticipant = { + provider: string; + operator: string; + signature: string; +}; + +export class SigningCoordinatorAgent { + public static async getParticipants( + provider: ethers.providers.Provider, + domain: Domain, + ritualId: number, + ): Promise { + const coordinator = await this.connectReadOnly(provider, domain); + const participants = await coordinator[ + 'getSigners(uint32)' + ](ritualId); + + return participants.map((participant) => { + return { + operator: participant.operator, + }; + }); + } + + private static async connectReadOnly( + provider: ethers.providers.Provider, + domain: Domain, + ) { + return await this.connect(provider, domain); + } + + private static async connect( + provider: ethers.providers.Provider, + domain: Domain, + signer?: ethers.Signer, + ): Promise { + const network = await provider.getNetwork(); + const contractAddress = getContract(domain, network.chainId, 'SigningCoordinator'); + return SigningCoordinator__factory.connect(contractAddress, signer ?? provider); + } +} diff --git a/packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts b/packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts new file mode 100644 index 000000000..aba6ce957 --- /dev/null +++ b/packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts @@ -0,0 +1,2749 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + EventFragment, + FunctionFragment, + Result, +} from '@ethersproject/abi'; +import type { Listener, Provider } from '@ethersproject/providers'; +import type { + BaseContract, + BigNumber, + BigNumberish, + BytesLike, + CallOverrides, + ContractTransaction, + Overrides, + PopulatedTransaction, + Signer, + utils, +} from 'ethers'; +import type { + OnEvent, + TypedEvent, + TypedEventFilter, + TypedListener, +} from './common'; + +export declare namespace BLS12381 { + export type G2PointStruct = { + word0: BytesLike; + word1: BytesLike; + word2: BytesLike; + }; + + export type G2PointStructOutput = [string, string, string] & { + word0: string; + word1: string; + word2: string; + }; + + export type G1PointStruct = { word0: BytesLike; word1: BytesLike }; + + export type G1PointStructOutput = [string, string] & { + word0: string; + word1: string; + }; +} + +export declare namespace SigningCoordinator { + export type ParticipantStruct = { + provider: string; + aggregated: boolean; + transcript: BytesLike; + decryptionRequestStaticKey: BytesLike; + }; + + export type ParticipantStructOutput = [string, boolean, string, string] & { + provider: string; + aggregated: boolean; + transcript: string; + decryptionRequestStaticKey: string; + }; +} + +export interface SigningCoordinatorInterface extends utils.Interface { + functions: { + 'DEFAULT_ADMIN_ROLE()': FunctionFragment; + 'FEE_MODEL_MANAGER_ROLE()': FunctionFragment; + 'TREASURY_ROLE()': FunctionFragment; + 'acceptDefaultAdminTransfer()': FunctionFragment; + 'application()': FunctionFragment; + 'approveFeeModel(address)': FunctionFragment; + 'beginDefaultAdminTransfer(address)': FunctionFragment; + 'cancelDefaultAdminTransfer()': FunctionFragment; + 'changeDefaultAdminDelay(uint48)': FunctionFragment; + 'cohortFingerprint(address[])': FunctionFragment; + 'defaultAdmin()': FunctionFragment; + 'defaultAdminDelay()': FunctionFragment; + 'defaultAdminDelayIncreaseWait()': FunctionFragment; + 'expectedTranscriptSize(uint16,uint16)': FunctionFragment; + 'extendRitual(uint32,uint32)': FunctionFragment; + 'feeModelsRegistry(address)': FunctionFragment; + 'getAccessController(uint32)': FunctionFragment; + 'getAuthority(uint32)': FunctionFragment; + 'getFeeModel(uint32)': FunctionFragment; + 'getInitiator(uint32)': FunctionFragment; + 'getParticipant(uint32,address,bool)': FunctionFragment; + 'getParticipantFromProvider(uint32,address)': FunctionFragment; + 'getParticipants(uint32)': FunctionFragment; + 'getParticipants(uint32,uint256,uint256,bool)': FunctionFragment; + 'getProviderPublicKey(address,uint256)': FunctionFragment; + 'getProviders(uint32)': FunctionFragment; + 'getPublicKeyFromRitualId(uint32)': FunctionFragment; + 'getRitualIdFromPublicKey((bytes32,bytes16))': FunctionFragment; + 'getRitualState(uint32)': FunctionFragment; + 'getRoleAdmin(bytes32)': FunctionFragment; + 'getThresholdForRitualSize(uint16)': FunctionFragment; + 'getTimestamps(uint32)': FunctionFragment; + 'grantRole(bytes32,address)': FunctionFragment; + 'hasRole(bytes32,address)': FunctionFragment; + 'initialize(uint32,uint16,address)': FunctionFragment; + 'initializeNumberOfRituals()': FunctionFragment; + 'initiateRitual(address,address[],address,uint32,address)': FunctionFragment; + 'isEncryptionAuthorized(uint32,bytes,bytes)': FunctionFragment; + 'isParticipant(uint32,address)': FunctionFragment; + 'isProviderKeySet(address)': FunctionFragment; + 'isProviderPublicKeySet(address)': FunctionFragment; + 'isRitualActive(uint32)': FunctionFragment; + 'maxDkgSize()': FunctionFragment; + 'numberOfRituals()': FunctionFragment; + 'owner()': FunctionFragment; + 'pendingDefaultAdmin()': FunctionFragment; + 'pendingDefaultAdminDelay()': FunctionFragment; + 'postAggregation(uint32,bytes,(bytes32,bytes16),bytes)': FunctionFragment; + 'postTranscript(uint32,bytes)': FunctionFragment; + 'publishTranscript(uint32,bytes)': FunctionFragment; + 'reinitializeDefaultAdmin(address)': FunctionFragment; + 'renounceRole(bytes32,address)': FunctionFragment; + 'revokeRole(bytes32,address)': FunctionFragment; + 'rituals(uint256)': FunctionFragment; + 'rollbackDefaultAdminDelay()': FunctionFragment; + 'setMaxDkgSize(uint16)': FunctionFragment; + 'setProviderPublicKey((bytes32,bytes32,bytes32))': FunctionFragment; + 'setReimbursementPool(address)': FunctionFragment; + 'setTimeout(uint32)': FunctionFragment; + 'supportsInterface(bytes4)': FunctionFragment; + 'timeout()': FunctionFragment; + 'transferRitualAuthority(uint32,address)': FunctionFragment; + 'withdrawAllTokens(address)': FunctionFragment; + }; + + getFunction( + nameOrSignatureOrTopic: + | 'DEFAULT_ADMIN_ROLE' + | 'FEE_MODEL_MANAGER_ROLE' + | 'TREASURY_ROLE' + | 'acceptDefaultAdminTransfer' + | 'application' + | 'approveFeeModel' + | 'beginDefaultAdminTransfer' + | 'cancelDefaultAdminTransfer' + | 'changeDefaultAdminDelay' + | 'cohortFingerprint' + | 'defaultAdmin' + | 'defaultAdminDelay' + | 'defaultAdminDelayIncreaseWait' + | 'expectedTranscriptSize' + | 'extendRitual' + | 'feeModelsRegistry' + | 'getAccessController' + | 'getAuthority' + | 'getFeeModel' + | 'getInitiator' + | 'getParticipant' + | 'getParticipantFromProvider' + | 'getParticipants(uint32)' + | 'getParticipants(uint32,uint256,uint256,bool)' + | 'getProviderPublicKey' + | 'getProviders' + | 'getPublicKeyFromRitualId' + | 'getRitualIdFromPublicKey' + | 'getRitualState' + | 'getRoleAdmin' + | 'getThresholdForRitualSize' + | 'getTimestamps' + | 'grantRole' + | 'hasRole' + | 'initialize' + | 'initializeNumberOfRituals' + | 'initiateRitual' + | 'isEncryptionAuthorized' + | 'isParticipant' + | 'isProviderKeySet' + | 'isProviderPublicKeySet' + | 'isRitualActive' + | 'maxDkgSize' + | 'numberOfRituals' + | 'owner' + | 'pendingDefaultAdmin' + | 'pendingDefaultAdminDelay' + | 'postAggregation' + | 'postTranscript' + | 'publishTranscript' + | 'reinitializeDefaultAdmin' + | 'renounceRole' + | 'revokeRole' + | 'rituals' + | 'rollbackDefaultAdminDelay' + | 'setMaxDkgSize' + | 'setProviderPublicKey' + | 'setReimbursementPool' + | 'setTimeout' + | 'supportsInterface' + | 'timeout' + | 'transferRitualAuthority' + | 'withdrawAllTokens', + ): FunctionFragment; + + encodeFunctionData( + functionFragment: 'DEFAULT_ADMIN_ROLE', + values?: undefined, + ): string; + encodeFunctionData( + functionFragment: 'FEE_MODEL_MANAGER_ROLE', + values?: undefined, + ): string; + encodeFunctionData( + functionFragment: 'TREASURY_ROLE', + values?: undefined, + ): string; + encodeFunctionData( + functionFragment: 'acceptDefaultAdminTransfer', + values?: undefined, + ): string; + encodeFunctionData( + functionFragment: 'application', + values?: undefined, + ): string; + encodeFunctionData( + functionFragment: 'approveFeeModel', + values: [string], + ): string; + encodeFunctionData( + functionFragment: 'beginDefaultAdminTransfer', + values: [string], + ): string; + encodeFunctionData( + functionFragment: 'cancelDefaultAdminTransfer', + values?: undefined, + ): string; + encodeFunctionData( + functionFragment: 'changeDefaultAdminDelay', + values: [BigNumberish], + ): string; + encodeFunctionData( + functionFragment: 'cohortFingerprint', + values: [string[]], + ): string; + encodeFunctionData( + functionFragment: 'defaultAdmin', + values?: undefined, + ): string; + encodeFunctionData( + functionFragment: 'defaultAdminDelay', + values?: undefined, + ): string; + encodeFunctionData( + functionFragment: 'defaultAdminDelayIncreaseWait', + values?: undefined, + ): string; + encodeFunctionData( + functionFragment: 'expectedTranscriptSize', + values: [BigNumberish, BigNumberish], + ): string; + encodeFunctionData( + functionFragment: 'extendRitual', + values: [BigNumberish, BigNumberish], + ): string; + encodeFunctionData( + functionFragment: 'feeModelsRegistry', + values: [string], + ): string; + encodeFunctionData( + functionFragment: 'getAccessController', + values: [BigNumberish], + ): string; + encodeFunctionData( + functionFragment: 'getAuthority', + values: [BigNumberish], + ): string; + encodeFunctionData( + functionFragment: 'getFeeModel', + values: [BigNumberish], + ): string; + encodeFunctionData( + functionFragment: 'getInitiator', + values: [BigNumberish], + ): string; + encodeFunctionData( + functionFragment: 'getParticipant', + values: [BigNumberish, string, boolean], + ): string; + encodeFunctionData( + functionFragment: 'getParticipantFromProvider', + values: [BigNumberish, string], + ): string; + encodeFunctionData( + functionFragment: 'getParticipants(uint32)', + values: [BigNumberish], + ): string; + encodeFunctionData( + functionFragment: 'getParticipants(uint32,uint256,uint256,bool)', + values: [BigNumberish, BigNumberish, BigNumberish, boolean], + ): string; + encodeFunctionData( + functionFragment: 'getProviderPublicKey', + values: [string, BigNumberish], + ): string; + encodeFunctionData( + functionFragment: 'getProviders', + values: [BigNumberish], + ): string; + encodeFunctionData( + functionFragment: 'getPublicKeyFromRitualId', + values: [BigNumberish], + ): string; + encodeFunctionData( + functionFragment: 'getRitualIdFromPublicKey', + values: [BLS12381.G1PointStruct], + ): string; + encodeFunctionData( + functionFragment: 'getRitualState', + values: [BigNumberish], + ): string; + encodeFunctionData( + functionFragment: 'getRoleAdmin', + values: [BytesLike], + ): string; + encodeFunctionData( + functionFragment: 'getThresholdForRitualSize', + values: [BigNumberish], + ): string; + encodeFunctionData( + functionFragment: 'getTimestamps', + values: [BigNumberish], + ): string; + encodeFunctionData( + functionFragment: 'grantRole', + values: [BytesLike, string], + ): string; + encodeFunctionData( + functionFragment: 'hasRole', + values: [BytesLike, string], + ): string; + encodeFunctionData( + functionFragment: 'initialize', + values: [BigNumberish, BigNumberish, string], + ): string; + encodeFunctionData( + functionFragment: 'initializeNumberOfRituals', + values?: undefined, + ): string; + encodeFunctionData( + functionFragment: 'initiateRitual', + values: [string, string[], string, BigNumberish, string], + ): string; + encodeFunctionData( + functionFragment: 'isEncryptionAuthorized', + values: [BigNumberish, BytesLike, BytesLike], + ): string; + encodeFunctionData( + functionFragment: 'isParticipant', + values: [BigNumberish, string], + ): string; + encodeFunctionData( + functionFragment: 'isProviderKeySet', + values: [string], + ): string; + encodeFunctionData( + functionFragment: 'isProviderPublicKeySet', + values: [string], + ): string; + encodeFunctionData( + functionFragment: 'isRitualActive', + values: [BigNumberish], + ): string; + encodeFunctionData( + functionFragment: 'maxDkgSize', + values?: undefined, + ): string; + encodeFunctionData( + functionFragment: 'numberOfRituals', + values?: undefined, + ): string; + encodeFunctionData(functionFragment: 'owner', values?: undefined): string; + encodeFunctionData( + functionFragment: 'pendingDefaultAdmin', + values?: undefined, + ): string; + encodeFunctionData( + functionFragment: 'pendingDefaultAdminDelay', + values?: undefined, + ): string; + encodeFunctionData( + functionFragment: 'postAggregation', + values: [BigNumberish, BytesLike, BLS12381.G1PointStruct, BytesLike], + ): string; + encodeFunctionData( + functionFragment: 'postTranscript', + values: [BigNumberish, BytesLike], + ): string; + encodeFunctionData( + functionFragment: 'publishTranscript', + values: [BigNumberish, BytesLike], + ): string; + encodeFunctionData( + functionFragment: 'reinitializeDefaultAdmin', + values: [string], + ): string; + encodeFunctionData( + functionFragment: 'renounceRole', + values: [BytesLike, string], + ): string; + encodeFunctionData( + functionFragment: 'revokeRole', + values: [BytesLike, string], + ): string; + encodeFunctionData( + functionFragment: 'rituals', + values: [BigNumberish], + ): string; + encodeFunctionData( + functionFragment: 'rollbackDefaultAdminDelay', + values?: undefined, + ): string; + encodeFunctionData( + functionFragment: 'setMaxDkgSize', + values: [BigNumberish], + ): string; + encodeFunctionData( + functionFragment: 'setProviderPublicKey', + values: [BLS12381.G2PointStruct], + ): string; + encodeFunctionData( + functionFragment: 'setReimbursementPool', + values: [string], + ): string; + encodeFunctionData( + functionFragment: 'setTimeout', + values: [BigNumberish], + ): string; + encodeFunctionData( + functionFragment: 'supportsInterface', + values: [BytesLike], + ): string; + encodeFunctionData(functionFragment: 'timeout', values?: undefined): string; + encodeFunctionData( + functionFragment: 'transferRitualAuthority', + values: [BigNumberish, string], + ): string; + encodeFunctionData( + functionFragment: 'withdrawAllTokens', + values: [string], + ): string; + + decodeFunctionResult( + functionFragment: 'DEFAULT_ADMIN_ROLE', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'FEE_MODEL_MANAGER_ROLE', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'TREASURY_ROLE', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'acceptDefaultAdminTransfer', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'application', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'approveFeeModel', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'beginDefaultAdminTransfer', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'cancelDefaultAdminTransfer', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'changeDefaultAdminDelay', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'cohortFingerprint', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'defaultAdmin', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'defaultAdminDelay', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'defaultAdminDelayIncreaseWait', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'expectedTranscriptSize', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'extendRitual', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'feeModelsRegistry', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'getAccessController', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'getAuthority', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'getFeeModel', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'getInitiator', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'getParticipant', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'getParticipantFromProvider', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'getParticipants(uint32)', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'getParticipants(uint32,uint256,uint256,bool)', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'getProviderPublicKey', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'getProviders', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'getPublicKeyFromRitualId', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'getRitualIdFromPublicKey', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'getRitualState', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'getRoleAdmin', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'getThresholdForRitualSize', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'getTimestamps', + data: BytesLike, + ): Result; + decodeFunctionResult(functionFragment: 'grantRole', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'hasRole', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'initialize', data: BytesLike): Result; + decodeFunctionResult( + functionFragment: 'initializeNumberOfRituals', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'initiateRitual', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'isEncryptionAuthorized', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'isParticipant', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'isProviderKeySet', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'isProviderPublicKeySet', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'isRitualActive', + data: BytesLike, + ): Result; + decodeFunctionResult(functionFragment: 'maxDkgSize', data: BytesLike): Result; + decodeFunctionResult( + functionFragment: 'numberOfRituals', + data: BytesLike, + ): Result; + decodeFunctionResult(functionFragment: 'owner', data: BytesLike): Result; + decodeFunctionResult( + functionFragment: 'pendingDefaultAdmin', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'pendingDefaultAdminDelay', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'postAggregation', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'postTranscript', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'publishTranscript', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'reinitializeDefaultAdmin', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'renounceRole', + data: BytesLike, + ): Result; + decodeFunctionResult(functionFragment: 'revokeRole', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'rituals', data: BytesLike): Result; + decodeFunctionResult( + functionFragment: 'rollbackDefaultAdminDelay', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'setMaxDkgSize', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'setProviderPublicKey', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'setReimbursementPool', + data: BytesLike, + ): Result; + decodeFunctionResult(functionFragment: 'setTimeout', data: BytesLike): Result; + decodeFunctionResult( + functionFragment: 'supportsInterface', + data: BytesLike, + ): Result; + decodeFunctionResult(functionFragment: 'timeout', data: BytesLike): Result; + decodeFunctionResult( + functionFragment: 'transferRitualAuthority', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'withdrawAllTokens', + data: BytesLike, + ): Result; + + events: { + 'AggregationPosted(uint32,address,bytes32)': EventFragment; + 'DefaultAdminDelayChangeCanceled()': EventFragment; + 'DefaultAdminDelayChangeScheduled(uint48,uint48)': EventFragment; + 'DefaultAdminTransferCanceled()': EventFragment; + 'DefaultAdminTransferScheduled(address,uint48)': EventFragment; + 'EndRitual(uint32,bool)': EventFragment; + 'FeeModelApproved(address)': EventFragment; + 'Initialized(uint64)': EventFragment; + 'MaxDkgSizeChanged(uint16,uint16)': EventFragment; + 'ParticipantPublicKeySet(uint32,address,(bytes32,bytes32,bytes32))': EventFragment; + 'ReimbursementPoolSet(address)': EventFragment; + 'RitualAuthorityTransferred(uint32,address,address)': EventFragment; + 'RitualExtended(uint32,uint32)': EventFragment; + 'RoleAdminChanged(bytes32,bytes32,bytes32)': EventFragment; + 'RoleGranted(bytes32,address,address)': EventFragment; + 'RoleRevoked(bytes32,address,address)': EventFragment; + 'StartAggregationRound(uint32)': EventFragment; + 'StartRitual(uint32,address,address[])': EventFragment; + 'TimeoutChanged(uint32,uint32)': EventFragment; + 'TranscriptPosted(uint32,address,bytes32)': EventFragment; + }; + + getEvent(nameOrSignatureOrTopic: 'AggregationPosted'): EventFragment; + getEvent( + nameOrSignatureOrTopic: 'DefaultAdminDelayChangeCanceled', + ): EventFragment; + getEvent( + nameOrSignatureOrTopic: 'DefaultAdminDelayChangeScheduled', + ): EventFragment; + getEvent( + nameOrSignatureOrTopic: 'DefaultAdminTransferCanceled', + ): EventFragment; + getEvent( + nameOrSignatureOrTopic: 'DefaultAdminTransferScheduled', + ): EventFragment; + getEvent(nameOrSignatureOrTopic: 'EndRitual'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'FeeModelApproved'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'Initialized'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'MaxDkgSizeChanged'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'ParticipantPublicKeySet'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'ReimbursementPoolSet'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'RitualAuthorityTransferred'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'RitualExtended'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'RoleAdminChanged'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'RoleGranted'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'RoleRevoked'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'StartAggregationRound'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'StartRitual'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'TimeoutChanged'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'TranscriptPosted'): EventFragment; +} + +export interface AggregationPostedEventObject { + ritualId: number; + node: string; + aggregatedTranscriptDigest: string; +} +export type AggregationPostedEvent = TypedEvent< + [number, string, string], + AggregationPostedEventObject +>; + +export type AggregationPostedEventFilter = + TypedEventFilter; + +export interface DefaultAdminDelayChangeCanceledEventObject {} +export type DefaultAdminDelayChangeCanceledEvent = TypedEvent< + [], + DefaultAdminDelayChangeCanceledEventObject +>; + +export type DefaultAdminDelayChangeCanceledEventFilter = + TypedEventFilter; + +export interface DefaultAdminDelayChangeScheduledEventObject { + newDelay: number; + effectSchedule: number; +} +export type DefaultAdminDelayChangeScheduledEvent = TypedEvent< + [number, number], + DefaultAdminDelayChangeScheduledEventObject +>; + +export type DefaultAdminDelayChangeScheduledEventFilter = + TypedEventFilter; + +export interface DefaultAdminTransferCanceledEventObject {} +export type DefaultAdminTransferCanceledEvent = TypedEvent< + [], + DefaultAdminTransferCanceledEventObject +>; + +export type DefaultAdminTransferCanceledEventFilter = + TypedEventFilter; + +export interface DefaultAdminTransferScheduledEventObject { + newAdmin: string; + acceptSchedule: number; +} +export type DefaultAdminTransferScheduledEvent = TypedEvent< + [string, number], + DefaultAdminTransferScheduledEventObject +>; + +export type DefaultAdminTransferScheduledEventFilter = + TypedEventFilter; + +export interface EndRitualEventObject { + ritualId: number; + successful: boolean; +} +export type EndRitualEvent = TypedEvent< + [number, boolean], + EndRitualEventObject +>; + +export type EndRitualEventFilter = TypedEventFilter; + +export interface FeeModelApprovedEventObject { + feeModel: string; +} +export type FeeModelApprovedEvent = TypedEvent< + [string], + FeeModelApprovedEventObject +>; + +export type FeeModelApprovedEventFilter = + TypedEventFilter; + +export interface InitializedEventObject { + version: BigNumber; +} +export type InitializedEvent = TypedEvent<[BigNumber], InitializedEventObject>; + +export type InitializedEventFilter = TypedEventFilter; + +export interface MaxDkgSizeChangedEventObject { + oldSize: number; + newSize: number; +} +export type MaxDkgSizeChangedEvent = TypedEvent< + [number, number], + MaxDkgSizeChangedEventObject +>; + +export type MaxDkgSizeChangedEventFilter = + TypedEventFilter; + +export interface ParticipantPublicKeySetEventObject { + ritualId: number; + participant: string; + publicKey: BLS12381.G2PointStructOutput; +} +export type ParticipantPublicKeySetEvent = TypedEvent< + [number, string, BLS12381.G2PointStructOutput], + ParticipantPublicKeySetEventObject +>; + +export type ParticipantPublicKeySetEventFilter = + TypedEventFilter; + +export interface ReimbursementPoolSetEventObject { + pool: string; +} +export type ReimbursementPoolSetEvent = TypedEvent< + [string], + ReimbursementPoolSetEventObject +>; + +export type ReimbursementPoolSetEventFilter = + TypedEventFilter; + +export interface RitualAuthorityTransferredEventObject { + ritualId: number; + previousAuthority: string; + newAuthority: string; +} +export type RitualAuthorityTransferredEvent = TypedEvent< + [number, string, string], + RitualAuthorityTransferredEventObject +>; + +export type RitualAuthorityTransferredEventFilter = + TypedEventFilter; + +export interface RitualExtendedEventObject { + ritualId: number; + endTimestamp: number; +} +export type RitualExtendedEvent = TypedEvent< + [number, number], + RitualExtendedEventObject +>; + +export type RitualExtendedEventFilter = TypedEventFilter; + +export interface RoleAdminChangedEventObject { + role: string; + previousAdminRole: string; + newAdminRole: string; +} +export type RoleAdminChangedEvent = TypedEvent< + [string, string, string], + RoleAdminChangedEventObject +>; + +export type RoleAdminChangedEventFilter = + TypedEventFilter; + +export interface RoleGrantedEventObject { + role: string; + account: string; + sender: string; +} +export type RoleGrantedEvent = TypedEvent< + [string, string, string], + RoleGrantedEventObject +>; + +export type RoleGrantedEventFilter = TypedEventFilter; + +export interface RoleRevokedEventObject { + role: string; + account: string; + sender: string; +} +export type RoleRevokedEvent = TypedEvent< + [string, string, string], + RoleRevokedEventObject +>; + +export type RoleRevokedEventFilter = TypedEventFilter; + +export interface StartAggregationRoundEventObject { + ritualId: number; +} +export type StartAggregationRoundEvent = TypedEvent< + [number], + StartAggregationRoundEventObject +>; + +export type StartAggregationRoundEventFilter = + TypedEventFilter; + +export interface StartRitualEventObject { + ritualId: number; + authority: string; + participants: string[]; +} +export type StartRitualEvent = TypedEvent< + [number, string, string[]], + StartRitualEventObject +>; + +export type StartRitualEventFilter = TypedEventFilter; + +export interface TimeoutChangedEventObject { + oldTimeout: number; + newTimeout: number; +} +export type TimeoutChangedEvent = TypedEvent< + [number, number], + TimeoutChangedEventObject +>; + +export type TimeoutChangedEventFilter = TypedEventFilter; + +export interface TranscriptPostedEventObject { + ritualId: number; + node: string; + transcriptDigest: string; +} +export type TranscriptPostedEvent = TypedEvent< + [number, string, string], + TranscriptPostedEventObject +>; + +export type TranscriptPostedEventFilter = + TypedEventFilter; + +export interface Coordinator extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this; + attach(addressOrName: string): this; + deployed(): Promise; + + interface: CoordinatorInterface; + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined, + ): Promise>; + + listeners( + eventFilter?: TypedEventFilter, + ): Array>; + listeners(eventName?: string): Array; + removeAllListeners( + eventFilter: TypedEventFilter, + ): this; + removeAllListeners(eventName?: string): this; + off: OnEvent; + on: OnEvent; + once: OnEvent; + removeListener: OnEvent; + + functions: { + DEFAULT_ADMIN_ROLE(overrides?: CallOverrides): Promise<[string]>; + + FEE_MODEL_MANAGER_ROLE(overrides?: CallOverrides): Promise<[string]>; + + TREASURY_ROLE(overrides?: CallOverrides): Promise<[string]>; + + acceptDefaultAdminTransfer( + overrides?: Overrides & { from?: string }, + ): Promise; + + application(overrides?: CallOverrides): Promise<[string]>; + + approveFeeModel( + feeModel: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + beginDefaultAdminTransfer( + newAdmin: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + cancelDefaultAdminTransfer( + overrides?: Overrides & { from?: string }, + ): Promise; + + changeDefaultAdminDelay( + newDelay: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + cohortFingerprint( + nodes: string[], + overrides?: CallOverrides, + ): Promise<[string]>; + + defaultAdmin(overrides?: CallOverrides): Promise<[string]>; + + defaultAdminDelay(overrides?: CallOverrides): Promise<[number]>; + + defaultAdminDelayIncreaseWait(overrides?: CallOverrides): Promise<[number]>; + + expectedTranscriptSize( + dkgSize: BigNumberish, + threshold: BigNumberish, + overrides?: CallOverrides, + ): Promise<[BigNumber]>; + + extendRitual( + ritualId: BigNumberish, + duration: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + feeModelsRegistry( + arg0: string, + overrides?: CallOverrides, + ): Promise<[boolean]>; + + getAccessController( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise<[string]>; + + getAuthority( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise<[string]>; + + getFeeModel( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise<[string]>; + + getInitiator( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise<[string]>; + + getParticipant( + ritualId: BigNumberish, + provider: string, + transcript: boolean, + overrides?: CallOverrides, + ): Promise<[Coordinator.ParticipantStructOutput]>; + + getParticipantFromProvider( + ritualId: BigNumberish, + provider: string, + overrides?: CallOverrides, + ): Promise<[Coordinator.ParticipantStructOutput]>; + + 'getParticipants(uint32)'( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise<[Coordinator.ParticipantStructOutput[]]>; + + 'getParticipants(uint32,uint256,uint256,bool)'( + ritualId: BigNumberish, + startIndex: BigNumberish, + maxParticipants: BigNumberish, + includeTranscript: boolean, + overrides?: CallOverrides, + ): Promise<[Coordinator.ParticipantStructOutput[]]>; + + getProviderPublicKey( + provider: string, + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise<[BLS12381.G2PointStructOutput]>; + + getProviders( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise<[string[]]>; + + getPublicKeyFromRitualId( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise<[BLS12381.G1PointStructOutput]>; + + getRitualIdFromPublicKey( + dkgPublicKey: BLS12381.G1PointStruct, + overrides?: CallOverrides, + ): Promise<[number] & { ritualId: number }>; + + getRitualState( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise<[number]>; + + getRoleAdmin(role: BytesLike, overrides?: CallOverrides): Promise<[string]>; + + getThresholdForRitualSize( + size: BigNumberish, + overrides?: CallOverrides, + ): Promise<[number]>; + + getTimestamps( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise< + [number, number] & { initTimestamp: number; endTimestamp: number } + >; + + grantRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + hasRole( + role: BytesLike, + account: string, + overrides?: CallOverrides, + ): Promise<[boolean]>; + + initialize( + _timeout: BigNumberish, + _maxDkgSize: BigNumberish, + _admin: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + initializeNumberOfRituals( + overrides?: Overrides & { from?: string }, + ): Promise; + + initiateRitual( + feeModel: string, + providers: string[], + authority: string, + duration: BigNumberish, + accessController: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + isEncryptionAuthorized( + arg0: BigNumberish, + arg1: BytesLike, + arg2: BytesLike, + overrides?: CallOverrides, + ): Promise<[boolean]>; + + isParticipant( + ritualId: BigNumberish, + provider: string, + overrides?: CallOverrides, + ): Promise<[boolean]>; + + isProviderKeySet( + provider: string, + overrides?: CallOverrides, + ): Promise<[boolean]>; + + isProviderPublicKeySet( + arg0: string, + overrides?: CallOverrides, + ): Promise<[boolean]>; + + isRitualActive( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise<[boolean]>; + + maxDkgSize(overrides?: CallOverrides): Promise<[number]>; + + numberOfRituals(overrides?: CallOverrides): Promise<[BigNumber]>; + + owner(overrides?: CallOverrides): Promise<[string]>; + + pendingDefaultAdmin( + overrides?: CallOverrides, + ): Promise<[string, number] & { newAdmin: string; schedule: number }>; + + pendingDefaultAdminDelay( + overrides?: CallOverrides, + ): Promise<[number, number] & { newDelay: number; schedule: number }>; + + postAggregation( + ritualId: BigNumberish, + aggregatedTranscript: BytesLike, + dkgPublicKey: BLS12381.G1PointStruct, + decryptionRequestStaticKey: BytesLike, + overrides?: Overrides & { from?: string }, + ): Promise; + + postTranscript( + arg0: BigNumberish, + arg1: BytesLike, + overrides?: Overrides & { from?: string }, + ): Promise; + + publishTranscript( + ritualId: BigNumberish, + transcript: BytesLike, + overrides?: Overrides & { from?: string }, + ): Promise; + + reinitializeDefaultAdmin( + newDefaultAdmin: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + renounceRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + revokeRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + rituals( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise< + [ + string, + number, + number, + number, + number, + string, + number, + number, + boolean, + string, + BLS12381.G1PointStructOutput, + string, + string, + ] & { + initiator: string; + initTimestamp: number; + endTimestamp: number; + totalTranscripts: number; + totalAggregations: number; + authority: string; + dkgSize: number; + threshold: number; + aggregationMismatch: boolean; + accessController: string; + publicKey: BLS12381.G1PointStructOutput; + aggregatedTranscript: string; + feeModel: string; + } + >; + + rollbackDefaultAdminDelay( + overrides?: Overrides & { from?: string }, + ): Promise; + + setMaxDkgSize( + newSize: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + setProviderPublicKey( + publicKey: BLS12381.G2PointStruct, + overrides?: Overrides & { from?: string }, + ): Promise; + + setReimbursementPool( + pool: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + setTimeout( + newTimeout: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + supportsInterface( + interfaceId: BytesLike, + overrides?: CallOverrides, + ): Promise<[boolean]>; + + timeout(overrides?: CallOverrides): Promise<[number]>; + + transferRitualAuthority( + ritualId: BigNumberish, + newAuthority: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + withdrawAllTokens( + token: string, + overrides?: Overrides & { from?: string }, + ): Promise; + }; + + DEFAULT_ADMIN_ROLE(overrides?: CallOverrides): Promise; + + FEE_MODEL_MANAGER_ROLE(overrides?: CallOverrides): Promise; + + TREASURY_ROLE(overrides?: CallOverrides): Promise; + + acceptDefaultAdminTransfer( + overrides?: Overrides & { from?: string }, + ): Promise; + + application(overrides?: CallOverrides): Promise; + + approveFeeModel( + feeModel: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + beginDefaultAdminTransfer( + newAdmin: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + cancelDefaultAdminTransfer( + overrides?: Overrides & { from?: string }, + ): Promise; + + changeDefaultAdminDelay( + newDelay: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + cohortFingerprint( + nodes: string[], + overrides?: CallOverrides, + ): Promise; + + defaultAdmin(overrides?: CallOverrides): Promise; + + defaultAdminDelay(overrides?: CallOverrides): Promise; + + defaultAdminDelayIncreaseWait(overrides?: CallOverrides): Promise; + + expectedTranscriptSize( + dkgSize: BigNumberish, + threshold: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + extendRitual( + ritualId: BigNumberish, + duration: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + feeModelsRegistry(arg0: string, overrides?: CallOverrides): Promise; + + getAccessController( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getAuthority( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getFeeModel( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getInitiator( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getParticipant( + ritualId: BigNumberish, + provider: string, + transcript: boolean, + overrides?: CallOverrides, + ): Promise; + + getParticipantFromProvider( + ritualId: BigNumberish, + provider: string, + overrides?: CallOverrides, + ): Promise; + + 'getParticipants(uint32)'( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + 'getParticipants(uint32,uint256,uint256,bool)'( + ritualId: BigNumberish, + startIndex: BigNumberish, + maxParticipants: BigNumberish, + includeTranscript: boolean, + overrides?: CallOverrides, + ): Promise; + + getProviderPublicKey( + provider: string, + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getProviders( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getPublicKeyFromRitualId( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getRitualIdFromPublicKey( + dkgPublicKey: BLS12381.G1PointStruct, + overrides?: CallOverrides, + ): Promise; + + getRitualState( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getRoleAdmin(role: BytesLike, overrides?: CallOverrides): Promise; + + getThresholdForRitualSize( + size: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getTimestamps( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise< + [number, number] & { initTimestamp: number; endTimestamp: number } + >; + + grantRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + hasRole( + role: BytesLike, + account: string, + overrides?: CallOverrides, + ): Promise; + + initialize( + _timeout: BigNumberish, + _maxDkgSize: BigNumberish, + _admin: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + initializeNumberOfRituals( + overrides?: Overrides & { from?: string }, + ): Promise; + + initiateRitual( + feeModel: string, + providers: string[], + authority: string, + duration: BigNumberish, + accessController: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + isEncryptionAuthorized( + arg0: BigNumberish, + arg1: BytesLike, + arg2: BytesLike, + overrides?: CallOverrides, + ): Promise; + + isParticipant( + ritualId: BigNumberish, + provider: string, + overrides?: CallOverrides, + ): Promise; + + isProviderKeySet( + provider: string, + overrides?: CallOverrides, + ): Promise; + + isProviderPublicKeySet( + arg0: string, + overrides?: CallOverrides, + ): Promise; + + isRitualActive( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + maxDkgSize(overrides?: CallOverrides): Promise; + + numberOfRituals(overrides?: CallOverrides): Promise; + + owner(overrides?: CallOverrides): Promise; + + pendingDefaultAdmin( + overrides?: CallOverrides, + ): Promise<[string, number] & { newAdmin: string; schedule: number }>; + + pendingDefaultAdminDelay( + overrides?: CallOverrides, + ): Promise<[number, number] & { newDelay: number; schedule: number }>; + + postAggregation( + ritualId: BigNumberish, + aggregatedTranscript: BytesLike, + dkgPublicKey: BLS12381.G1PointStruct, + decryptionRequestStaticKey: BytesLike, + overrides?: Overrides & { from?: string }, + ): Promise; + + postTranscript( + arg0: BigNumberish, + arg1: BytesLike, + overrides?: Overrides & { from?: string }, + ): Promise; + + publishTranscript( + ritualId: BigNumberish, + transcript: BytesLike, + overrides?: Overrides & { from?: string }, + ): Promise; + + reinitializeDefaultAdmin( + newDefaultAdmin: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + renounceRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + revokeRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + rituals( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise< + [ + string, + number, + number, + number, + number, + string, + number, + number, + boolean, + string, + BLS12381.G1PointStructOutput, + string, + string, + ] & { + initiator: string; + initTimestamp: number; + endTimestamp: number; + totalTranscripts: number; + totalAggregations: number; + authority: string; + dkgSize: number; + threshold: number; + aggregationMismatch: boolean; + accessController: string; + publicKey: BLS12381.G1PointStructOutput; + aggregatedTranscript: string; + feeModel: string; + } + >; + + rollbackDefaultAdminDelay( + overrides?: Overrides & { from?: string }, + ): Promise; + + setMaxDkgSize( + newSize: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + setProviderPublicKey( + publicKey: BLS12381.G2PointStruct, + overrides?: Overrides & { from?: string }, + ): Promise; + + setReimbursementPool( + pool: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + setTimeout( + newTimeout: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + supportsInterface( + interfaceId: BytesLike, + overrides?: CallOverrides, + ): Promise; + + timeout(overrides?: CallOverrides): Promise; + + transferRitualAuthority( + ritualId: BigNumberish, + newAuthority: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + withdrawAllTokens( + token: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + callStatic: { + DEFAULT_ADMIN_ROLE(overrides?: CallOverrides): Promise; + + FEE_MODEL_MANAGER_ROLE(overrides?: CallOverrides): Promise; + + TREASURY_ROLE(overrides?: CallOverrides): Promise; + + acceptDefaultAdminTransfer(overrides?: CallOverrides): Promise; + + application(overrides?: CallOverrides): Promise; + + approveFeeModel(feeModel: string, overrides?: CallOverrides): Promise; + + beginDefaultAdminTransfer( + newAdmin: string, + overrides?: CallOverrides, + ): Promise; + + cancelDefaultAdminTransfer(overrides?: CallOverrides): Promise; + + changeDefaultAdminDelay( + newDelay: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + cohortFingerprint( + nodes: string[], + overrides?: CallOverrides, + ): Promise; + + defaultAdmin(overrides?: CallOverrides): Promise; + + defaultAdminDelay(overrides?: CallOverrides): Promise; + + defaultAdminDelayIncreaseWait(overrides?: CallOverrides): Promise; + + expectedTranscriptSize( + dkgSize: BigNumberish, + threshold: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + extendRitual( + ritualId: BigNumberish, + duration: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + feeModelsRegistry( + arg0: string, + overrides?: CallOverrides, + ): Promise; + + getAccessController( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getAuthority( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getFeeModel( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getInitiator( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getParticipant( + ritualId: BigNumberish, + provider: string, + transcript: boolean, + overrides?: CallOverrides, + ): Promise; + + getParticipantFromProvider( + ritualId: BigNumberish, + provider: string, + overrides?: CallOverrides, + ): Promise; + + 'getParticipants(uint32)'( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + 'getParticipants(uint32,uint256,uint256,bool)'( + ritualId: BigNumberish, + startIndex: BigNumberish, + maxParticipants: BigNumberish, + includeTranscript: boolean, + overrides?: CallOverrides, + ): Promise; + + getProviderPublicKey( + provider: string, + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getProviders( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getPublicKeyFromRitualId( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getRitualIdFromPublicKey( + dkgPublicKey: BLS12381.G1PointStruct, + overrides?: CallOverrides, + ): Promise; + + getRitualState( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getRoleAdmin(role: BytesLike, overrides?: CallOverrides): Promise; + + getThresholdForRitualSize( + size: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getTimestamps( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise< + [number, number] & { initTimestamp: number; endTimestamp: number } + >; + + grantRole( + role: BytesLike, + account: string, + overrides?: CallOverrides, + ): Promise; + + hasRole( + role: BytesLike, + account: string, + overrides?: CallOverrides, + ): Promise; + + initialize( + _timeout: BigNumberish, + _maxDkgSize: BigNumberish, + _admin: string, + overrides?: CallOverrides, + ): Promise; + + initializeNumberOfRituals(overrides?: CallOverrides): Promise; + + initiateRitual( + feeModel: string, + providers: string[], + authority: string, + duration: BigNumberish, + accessController: string, + overrides?: CallOverrides, + ): Promise; + + isEncryptionAuthorized( + arg0: BigNumberish, + arg1: BytesLike, + arg2: BytesLike, + overrides?: CallOverrides, + ): Promise; + + isParticipant( + ritualId: BigNumberish, + provider: string, + overrides?: CallOverrides, + ): Promise; + + isProviderKeySet( + provider: string, + overrides?: CallOverrides, + ): Promise; + + isProviderPublicKeySet( + arg0: string, + overrides?: CallOverrides, + ): Promise; + + isRitualActive( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + maxDkgSize(overrides?: CallOverrides): Promise; + + numberOfRituals(overrides?: CallOverrides): Promise; + + owner(overrides?: CallOverrides): Promise; + + pendingDefaultAdmin( + overrides?: CallOverrides, + ): Promise<[string, number] & { newAdmin: string; schedule: number }>; + + pendingDefaultAdminDelay( + overrides?: CallOverrides, + ): Promise<[number, number] & { newDelay: number; schedule: number }>; + + postAggregation( + ritualId: BigNumberish, + aggregatedTranscript: BytesLike, + dkgPublicKey: BLS12381.G1PointStruct, + decryptionRequestStaticKey: BytesLike, + overrides?: CallOverrides, + ): Promise; + + postTranscript( + arg0: BigNumberish, + arg1: BytesLike, + overrides?: CallOverrides, + ): Promise; + + publishTranscript( + ritualId: BigNumberish, + transcript: BytesLike, + overrides?: CallOverrides, + ): Promise; + + reinitializeDefaultAdmin( + newDefaultAdmin: string, + overrides?: CallOverrides, + ): Promise; + + renounceRole( + role: BytesLike, + account: string, + overrides?: CallOverrides, + ): Promise; + + revokeRole( + role: BytesLike, + account: string, + overrides?: CallOverrides, + ): Promise; + + rituals( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise< + [ + string, + number, + number, + number, + number, + string, + number, + number, + boolean, + string, + BLS12381.G1PointStructOutput, + string, + string, + ] & { + initiator: string; + initTimestamp: number; + endTimestamp: number; + totalTranscripts: number; + totalAggregations: number; + authority: string; + dkgSize: number; + threshold: number; + aggregationMismatch: boolean; + accessController: string; + publicKey: BLS12381.G1PointStructOutput; + aggregatedTranscript: string; + feeModel: string; + } + >; + + rollbackDefaultAdminDelay(overrides?: CallOverrides): Promise; + + setMaxDkgSize( + newSize: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + setProviderPublicKey( + publicKey: BLS12381.G2PointStruct, + overrides?: CallOverrides, + ): Promise; + + setReimbursementPool( + pool: string, + overrides?: CallOverrides, + ): Promise; + + setTimeout( + newTimeout: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + supportsInterface( + interfaceId: BytesLike, + overrides?: CallOverrides, + ): Promise; + + timeout(overrides?: CallOverrides): Promise; + + transferRitualAuthority( + ritualId: BigNumberish, + newAuthority: string, + overrides?: CallOverrides, + ): Promise; + + withdrawAllTokens(token: string, overrides?: CallOverrides): Promise; + }; + + filters: { + 'AggregationPosted(uint32,address,bytes32)'( + ritualId?: BigNumberish | null, + node?: string | null, + aggregatedTranscriptDigest?: null, + ): AggregationPostedEventFilter; + AggregationPosted( + ritualId?: BigNumberish | null, + node?: string | null, + aggregatedTranscriptDigest?: null, + ): AggregationPostedEventFilter; + + 'DefaultAdminDelayChangeCanceled()'(): DefaultAdminDelayChangeCanceledEventFilter; + DefaultAdminDelayChangeCanceled(): DefaultAdminDelayChangeCanceledEventFilter; + + 'DefaultAdminDelayChangeScheduled(uint48,uint48)'( + newDelay?: null, + effectSchedule?: null, + ): DefaultAdminDelayChangeScheduledEventFilter; + DefaultAdminDelayChangeScheduled( + newDelay?: null, + effectSchedule?: null, + ): DefaultAdminDelayChangeScheduledEventFilter; + + 'DefaultAdminTransferCanceled()'(): DefaultAdminTransferCanceledEventFilter; + DefaultAdminTransferCanceled(): DefaultAdminTransferCanceledEventFilter; + + 'DefaultAdminTransferScheduled(address,uint48)'( + newAdmin?: string | null, + acceptSchedule?: null, + ): DefaultAdminTransferScheduledEventFilter; + DefaultAdminTransferScheduled( + newAdmin?: string | null, + acceptSchedule?: null, + ): DefaultAdminTransferScheduledEventFilter; + + 'EndRitual(uint32,bool)'( + ritualId?: BigNumberish | null, + successful?: null, + ): EndRitualEventFilter; + EndRitual( + ritualId?: BigNumberish | null, + successful?: null, + ): EndRitualEventFilter; + + 'FeeModelApproved(address)'(feeModel?: null): FeeModelApprovedEventFilter; + FeeModelApproved(feeModel?: null): FeeModelApprovedEventFilter; + + 'Initialized(uint64)'(version?: null): InitializedEventFilter; + Initialized(version?: null): InitializedEventFilter; + + 'MaxDkgSizeChanged(uint16,uint16)'( + oldSize?: null, + newSize?: null, + ): MaxDkgSizeChangedEventFilter; + MaxDkgSizeChanged( + oldSize?: null, + newSize?: null, + ): MaxDkgSizeChangedEventFilter; + + 'ParticipantPublicKeySet(uint32,address,(bytes32,bytes32,bytes32))'( + ritualId?: BigNumberish | null, + participant?: string | null, + publicKey?: null, + ): ParticipantPublicKeySetEventFilter; + ParticipantPublicKeySet( + ritualId?: BigNumberish | null, + participant?: string | null, + publicKey?: null, + ): ParticipantPublicKeySetEventFilter; + + 'ReimbursementPoolSet(address)'( + pool?: string | null, + ): ReimbursementPoolSetEventFilter; + ReimbursementPoolSet(pool?: string | null): ReimbursementPoolSetEventFilter; + + 'RitualAuthorityTransferred(uint32,address,address)'( + ritualId?: BigNumberish | null, + previousAuthority?: string | null, + newAuthority?: string | null, + ): RitualAuthorityTransferredEventFilter; + RitualAuthorityTransferred( + ritualId?: BigNumberish | null, + previousAuthority?: string | null, + newAuthority?: string | null, + ): RitualAuthorityTransferredEventFilter; + + 'RitualExtended(uint32,uint32)'( + ritualId?: BigNumberish | null, + endTimestamp?: null, + ): RitualExtendedEventFilter; + RitualExtended( + ritualId?: BigNumberish | null, + endTimestamp?: null, + ): RitualExtendedEventFilter; + + 'RoleAdminChanged(bytes32,bytes32,bytes32)'( + role?: BytesLike | null, + previousAdminRole?: BytesLike | null, + newAdminRole?: BytesLike | null, + ): RoleAdminChangedEventFilter; + RoleAdminChanged( + role?: BytesLike | null, + previousAdminRole?: BytesLike | null, + newAdminRole?: BytesLike | null, + ): RoleAdminChangedEventFilter; + + 'RoleGranted(bytes32,address,address)'( + role?: BytesLike | null, + account?: string | null, + sender?: string | null, + ): RoleGrantedEventFilter; + RoleGranted( + role?: BytesLike | null, + account?: string | null, + sender?: string | null, + ): RoleGrantedEventFilter; + + 'RoleRevoked(bytes32,address,address)'( + role?: BytesLike | null, + account?: string | null, + sender?: string | null, + ): RoleRevokedEventFilter; + RoleRevoked( + role?: BytesLike | null, + account?: string | null, + sender?: string | null, + ): RoleRevokedEventFilter; + + 'StartAggregationRound(uint32)'( + ritualId?: BigNumberish | null, + ): StartAggregationRoundEventFilter; + StartAggregationRound( + ritualId?: BigNumberish | null, + ): StartAggregationRoundEventFilter; + + 'StartRitual(uint32,address,address[])'( + ritualId?: BigNumberish | null, + authority?: string | null, + participants?: null, + ): StartRitualEventFilter; + StartRitual( + ritualId?: BigNumberish | null, + authority?: string | null, + participants?: null, + ): StartRitualEventFilter; + + 'TimeoutChanged(uint32,uint32)'( + oldTimeout?: null, + newTimeout?: null, + ): TimeoutChangedEventFilter; + TimeoutChanged( + oldTimeout?: null, + newTimeout?: null, + ): TimeoutChangedEventFilter; + + 'TranscriptPosted(uint32,address,bytes32)'( + ritualId?: BigNumberish | null, + node?: string | null, + transcriptDigest?: null, + ): TranscriptPostedEventFilter; + TranscriptPosted( + ritualId?: BigNumberish | null, + node?: string | null, + transcriptDigest?: null, + ): TranscriptPostedEventFilter; + }; + + estimateGas: { + DEFAULT_ADMIN_ROLE(overrides?: CallOverrides): Promise; + + FEE_MODEL_MANAGER_ROLE(overrides?: CallOverrides): Promise; + + TREASURY_ROLE(overrides?: CallOverrides): Promise; + + acceptDefaultAdminTransfer( + overrides?: Overrides & { from?: string }, + ): Promise; + + application(overrides?: CallOverrides): Promise; + + approveFeeModel( + feeModel: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + beginDefaultAdminTransfer( + newAdmin: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + cancelDefaultAdminTransfer( + overrides?: Overrides & { from?: string }, + ): Promise; + + changeDefaultAdminDelay( + newDelay: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + cohortFingerprint( + nodes: string[], + overrides?: CallOverrides, + ): Promise; + + defaultAdmin(overrides?: CallOverrides): Promise; + + defaultAdminDelay(overrides?: CallOverrides): Promise; + + defaultAdminDelayIncreaseWait( + overrides?: CallOverrides, + ): Promise; + + expectedTranscriptSize( + dkgSize: BigNumberish, + threshold: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + extendRitual( + ritualId: BigNumberish, + duration: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + feeModelsRegistry( + arg0: string, + overrides?: CallOverrides, + ): Promise; + + getAccessController( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getAuthority( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getFeeModel( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getInitiator( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getParticipant( + ritualId: BigNumberish, + provider: string, + transcript: boolean, + overrides?: CallOverrides, + ): Promise; + + getParticipantFromProvider( + ritualId: BigNumberish, + provider: string, + overrides?: CallOverrides, + ): Promise; + + 'getParticipants(uint32)'( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + 'getParticipants(uint32,uint256,uint256,bool)'( + ritualId: BigNumberish, + startIndex: BigNumberish, + maxParticipants: BigNumberish, + includeTranscript: boolean, + overrides?: CallOverrides, + ): Promise; + + getProviderPublicKey( + provider: string, + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getProviders( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getPublicKeyFromRitualId( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getRitualIdFromPublicKey( + dkgPublicKey: BLS12381.G1PointStruct, + overrides?: CallOverrides, + ): Promise; + + getRitualState( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getRoleAdmin( + role: BytesLike, + overrides?: CallOverrides, + ): Promise; + + getThresholdForRitualSize( + size: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getTimestamps( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + grantRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + hasRole( + role: BytesLike, + account: string, + overrides?: CallOverrides, + ): Promise; + + initialize( + _timeout: BigNumberish, + _maxDkgSize: BigNumberish, + _admin: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + initializeNumberOfRituals( + overrides?: Overrides & { from?: string }, + ): Promise; + + initiateRitual( + feeModel: string, + providers: string[], + authority: string, + duration: BigNumberish, + accessController: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + isEncryptionAuthorized( + arg0: BigNumberish, + arg1: BytesLike, + arg2: BytesLike, + overrides?: CallOverrides, + ): Promise; + + isParticipant( + ritualId: BigNumberish, + provider: string, + overrides?: CallOverrides, + ): Promise; + + isProviderKeySet( + provider: string, + overrides?: CallOverrides, + ): Promise; + + isProviderPublicKeySet( + arg0: string, + overrides?: CallOverrides, + ): Promise; + + isRitualActive( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + maxDkgSize(overrides?: CallOverrides): Promise; + + numberOfRituals(overrides?: CallOverrides): Promise; + + owner(overrides?: CallOverrides): Promise; + + pendingDefaultAdmin(overrides?: CallOverrides): Promise; + + pendingDefaultAdminDelay(overrides?: CallOverrides): Promise; + + postAggregation( + ritualId: BigNumberish, + aggregatedTranscript: BytesLike, + dkgPublicKey: BLS12381.G1PointStruct, + decryptionRequestStaticKey: BytesLike, + overrides?: Overrides & { from?: string }, + ): Promise; + + postTranscript( + arg0: BigNumberish, + arg1: BytesLike, + overrides?: Overrides & { from?: string }, + ): Promise; + + publishTranscript( + ritualId: BigNumberish, + transcript: BytesLike, + overrides?: Overrides & { from?: string }, + ): Promise; + + reinitializeDefaultAdmin( + newDefaultAdmin: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + renounceRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + revokeRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + rituals( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + rollbackDefaultAdminDelay( + overrides?: Overrides & { from?: string }, + ): Promise; + + setMaxDkgSize( + newSize: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + setProviderPublicKey( + publicKey: BLS12381.G2PointStruct, + overrides?: Overrides & { from?: string }, + ): Promise; + + setReimbursementPool( + pool: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + setTimeout( + newTimeout: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + supportsInterface( + interfaceId: BytesLike, + overrides?: CallOverrides, + ): Promise; + + timeout(overrides?: CallOverrides): Promise; + + transferRitualAuthority( + ritualId: BigNumberish, + newAuthority: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + withdrawAllTokens( + token: string, + overrides?: Overrides & { from?: string }, + ): Promise; + }; + + populateTransaction: { + DEFAULT_ADMIN_ROLE( + overrides?: CallOverrides, + ): Promise; + + FEE_MODEL_MANAGER_ROLE( + overrides?: CallOverrides, + ): Promise; + + TREASURY_ROLE(overrides?: CallOverrides): Promise; + + acceptDefaultAdminTransfer( + overrides?: Overrides & { from?: string }, + ): Promise; + + application(overrides?: CallOverrides): Promise; + + approveFeeModel( + feeModel: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + beginDefaultAdminTransfer( + newAdmin: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + cancelDefaultAdminTransfer( + overrides?: Overrides & { from?: string }, + ): Promise; + + changeDefaultAdminDelay( + newDelay: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + cohortFingerprint( + nodes: string[], + overrides?: CallOverrides, + ): Promise; + + defaultAdmin(overrides?: CallOverrides): Promise; + + defaultAdminDelay(overrides?: CallOverrides): Promise; + + defaultAdminDelayIncreaseWait( + overrides?: CallOverrides, + ): Promise; + + expectedTranscriptSize( + dkgSize: BigNumberish, + threshold: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + extendRitual( + ritualId: BigNumberish, + duration: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + feeModelsRegistry( + arg0: string, + overrides?: CallOverrides, + ): Promise; + + getAccessController( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getAuthority( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getFeeModel( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getInitiator( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getParticipant( + ritualId: BigNumberish, + provider: string, + transcript: boolean, + overrides?: CallOverrides, + ): Promise; + + getParticipantFromProvider( + ritualId: BigNumberish, + provider: string, + overrides?: CallOverrides, + ): Promise; + + 'getParticipants(uint32)'( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + 'getParticipants(uint32,uint256,uint256,bool)'( + ritualId: BigNumberish, + startIndex: BigNumberish, + maxParticipants: BigNumberish, + includeTranscript: boolean, + overrides?: CallOverrides, + ): Promise; + + getProviderPublicKey( + provider: string, + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getProviders( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getPublicKeyFromRitualId( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getRitualIdFromPublicKey( + dkgPublicKey: BLS12381.G1PointStruct, + overrides?: CallOverrides, + ): Promise; + + getRitualState( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getRoleAdmin( + role: BytesLike, + overrides?: CallOverrides, + ): Promise; + + getThresholdForRitualSize( + size: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + getTimestamps( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + grantRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + hasRole( + role: BytesLike, + account: string, + overrides?: CallOverrides, + ): Promise; + + initialize( + _timeout: BigNumberish, + _maxDkgSize: BigNumberish, + _admin: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + initializeNumberOfRituals( + overrides?: Overrides & { from?: string }, + ): Promise; + + initiateRitual( + feeModel: string, + providers: string[], + authority: string, + duration: BigNumberish, + accessController: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + isEncryptionAuthorized( + arg0: BigNumberish, + arg1: BytesLike, + arg2: BytesLike, + overrides?: CallOverrides, + ): Promise; + + isParticipant( + ritualId: BigNumberish, + provider: string, + overrides?: CallOverrides, + ): Promise; + + isProviderKeySet( + provider: string, + overrides?: CallOverrides, + ): Promise; + + isProviderPublicKeySet( + arg0: string, + overrides?: CallOverrides, + ): Promise; + + isRitualActive( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + maxDkgSize(overrides?: CallOverrides): Promise; + + numberOfRituals(overrides?: CallOverrides): Promise; + + owner(overrides?: CallOverrides): Promise; + + pendingDefaultAdmin( + overrides?: CallOverrides, + ): Promise; + + pendingDefaultAdminDelay( + overrides?: CallOverrides, + ): Promise; + + postAggregation( + ritualId: BigNumberish, + aggregatedTranscript: BytesLike, + dkgPublicKey: BLS12381.G1PointStruct, + decryptionRequestStaticKey: BytesLike, + overrides?: Overrides & { from?: string }, + ): Promise; + + postTranscript( + arg0: BigNumberish, + arg1: BytesLike, + overrides?: Overrides & { from?: string }, + ): Promise; + + publishTranscript( + ritualId: BigNumberish, + transcript: BytesLike, + overrides?: Overrides & { from?: string }, + ): Promise; + + reinitializeDefaultAdmin( + newDefaultAdmin: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + renounceRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + revokeRole( + role: BytesLike, + account: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + rituals( + ritualId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + + rollbackDefaultAdminDelay( + overrides?: Overrides & { from?: string }, + ): Promise; + + setMaxDkgSize( + newSize: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + setProviderPublicKey( + publicKey: BLS12381.G2PointStruct, + overrides?: Overrides & { from?: string }, + ): Promise; + + setReimbursementPool( + pool: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + setTimeout( + newTimeout: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; + + supportsInterface( + interfaceId: BytesLike, + overrides?: CallOverrides, + ): Promise; + + timeout(overrides?: CallOverrides): Promise; + + transferRitualAuthority( + ritualId: BigNumberish, + newAuthority: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + withdrawAllTokens( + token: string, + overrides?: Overrides & { from?: string }, + ): Promise; + }; +} diff --git a/packages/shared/src/contracts/ethers-typechain/index.ts b/packages/shared/src/contracts/ethers-typechain/index.ts index e0b86d8c9..0571c6f5d 100644 --- a/packages/shared/src/contracts/ethers-typechain/index.ts +++ b/packages/shared/src/contracts/ethers-typechain/index.ts @@ -2,6 +2,7 @@ /* tslint:disable */ /* eslint-disable */ export type { Coordinator } from './Coordinator'; +export type { SigningCoordinator } from './SigningCoordinator'; export * as factories from './factories'; export { Coordinator__factory } from './factories/Coordinator__factory'; export { GlobalAllowList__factory } from './factories/GlobalAllowList__factory'; diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index c33dae68e..3a4c160e3 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -158,13 +158,12 @@ type SigningOptions = { returnAggregated?: boolean; // Whether to return the aggregated signature }; -type SignRequest = { - readonly payload?: Base64EncodedBytes | undefined; - readonly packed_user_op?: string | undefined; +type SignUserOpRequest = { + readonly user_op: string; readonly signature_type: string; - readonly aa_version?: string | undefined; + readonly aa_version: string; readonly cohort_id: number; - readonly chain_id?: number | undefined; + readonly chain_id: number; readonly context?: Record | undefined; readonly optimistic?: boolean | undefined; readonly return_aggregated?: boolean | undefined; @@ -340,7 +339,7 @@ export class PorterClient { }; const resp: AxiosResponse = await this.tryAndCall({ - url: '/sign191', + url: '/sign', method: 'post', data, }); @@ -372,22 +371,20 @@ export class PorterClient { } public async signUserOp( - packedUserOp: Record, + userOp: Record, chainId: number, aaVersion: string, cohortId: number, options: SigningOptions = { optimistic: true, returnAggregated: true }, context: Record = {}, ): Promise { - const data: SignRequest = { - signature_type: 'packedUserOp', + const data: SignUserOpRequest = { aa_version: aaVersion, - packed_user_op: JSON.stringify(packedUserOp), + user_op: JSON.stringify(userOp), cohort_id: cohortId, chain_id: chainId, context, - optimistic: options.optimistic, - return_aggregated: options.returnAggregated, + signature_type: 'userop', }; const resp: AxiosResponse = await this.tryAndCall({ From 76652c104a530b36f9b592d2b0f84f17fa2c2908 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 18 Jun 2025 11:50:27 +0200 Subject: [PATCH 047/303] Add SigningCoordinator artifacts after running `pnpm typechain` --- .../ethers-typechain/SigningCoordinator.ts | 2015 +++++------------ .../factories/SigningCoordinator__factory.ts | 1233 ++++++++++ .../ethers-typechain/factories/index.ts | 1 + .../src/contracts/ethers-typechain/index.ts | 3 +- 4 files changed, 1782 insertions(+), 1470 deletions(-) create mode 100644 packages/shared/src/contracts/ethers-typechain/factories/SigningCoordinator__factory.ts diff --git a/packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts b/packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts index aba6ce957..549518b1d 100644 --- a/packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts +++ b/packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts @@ -26,175 +26,112 @@ import type { TypedListener, } from './common'; -export declare namespace BLS12381 { - export type G2PointStruct = { - word0: BytesLike; - word1: BytesLike; - word2: BytesLike; - }; - - export type G2PointStructOutput = [string, string, string] & { - word0: string; - word1: string; - word2: string; - }; - - export type G1PointStruct = { word0: BytesLike; word1: BytesLike }; - - export type G1PointStructOutput = [string, string] & { - word0: string; - word1: string; - }; -} - export declare namespace SigningCoordinator { - export type ParticipantStruct = { + export type SigningCohortParticipantStruct = { provider: string; - aggregated: boolean; - transcript: BytesLike; - decryptionRequestStaticKey: BytesLike; + operator: string; + signature: BytesLike; }; - export type ParticipantStructOutput = [string, boolean, string, string] & { - provider: string; - aggregated: boolean; - transcript: string; - decryptionRequestStaticKey: string; - }; + export type SigningCohortParticipantStructOutput = [ + string, + string, + string, + ] & { provider: string; operator: string; signature: string }; } export interface SigningCoordinatorInterface extends utils.Interface { functions: { 'DEFAULT_ADMIN_ROLE()': FunctionFragment; - 'FEE_MODEL_MANAGER_ROLE()': FunctionFragment; - 'TREASURY_ROLE()': FunctionFragment; + 'INITIATOR_ROLE()': FunctionFragment; 'acceptDefaultAdminTransfer()': FunctionFragment; 'application()': FunctionFragment; - 'approveFeeModel(address)': FunctionFragment; 'beginDefaultAdminTransfer(address)': FunctionFragment; 'cancelDefaultAdminTransfer()': FunctionFragment; 'changeDefaultAdminDelay(uint48)': FunctionFragment; - 'cohortFingerprint(address[])': FunctionFragment; 'defaultAdmin()': FunctionFragment; 'defaultAdminDelay()': FunctionFragment; 'defaultAdminDelayIncreaseWait()': FunctionFragment; - 'expectedTranscriptSize(uint16,uint16)': FunctionFragment; - 'extendRitual(uint32,uint32)': FunctionFragment; - 'feeModelsRegistry(address)': FunctionFragment; - 'getAccessController(uint32)': FunctionFragment; - 'getAuthority(uint32)': FunctionFragment; - 'getFeeModel(uint32)': FunctionFragment; - 'getInitiator(uint32)': FunctionFragment; - 'getParticipant(uint32,address,bool)': FunctionFragment; - 'getParticipantFromProvider(uint32,address)': FunctionFragment; - 'getParticipants(uint32)': FunctionFragment; - 'getParticipants(uint32,uint256,uint256,bool)': FunctionFragment; - 'getProviderPublicKey(address,uint256)': FunctionFragment; - 'getProviders(uint32)': FunctionFragment; - 'getPublicKeyFromRitualId(uint32)': FunctionFragment; - 'getRitualIdFromPublicKey((bytes32,bytes16))': FunctionFragment; - 'getRitualState(uint32)': FunctionFragment; + 'deployAdditionalChainForSigningMultisig(uint256,uint32)': FunctionFragment; + 'getChains(uint32)': FunctionFragment; + 'getCondition(uint32,uint256)': FunctionFragment; 'getRoleAdmin(bytes32)': FunctionFragment; - 'getThresholdForRitualSize(uint16)': FunctionFragment; - 'getTimestamps(uint32)': FunctionFragment; + 'getSigner(uint32,address)': FunctionFragment; + 'getSigners(uint32)': FunctionFragment; + 'getSigningCohortConditions(uint32,uint256)': FunctionFragment; + 'getSigningCohortDataHash(uint32)': FunctionFragment; + 'getSigningCohortState(uint32)': FunctionFragment; + 'getSigningCoordinatorChild(uint256)': FunctionFragment; 'grantRole(bytes32,address)': FunctionFragment; 'hasRole(bytes32,address)': FunctionFragment; - 'initialize(uint32,uint16,address)': FunctionFragment; - 'initializeNumberOfRituals()': FunctionFragment; - 'initiateRitual(address,address[],address,uint32,address)': FunctionFragment; - 'isEncryptionAuthorized(uint32,bytes,bytes)': FunctionFragment; - 'isParticipant(uint32,address)': FunctionFragment; - 'isProviderKeySet(address)': FunctionFragment; - 'isProviderPublicKeySet(address)': FunctionFragment; - 'isRitualActive(uint32)': FunctionFragment; - 'maxDkgSize()': FunctionFragment; - 'numberOfRituals()': FunctionFragment; + 'initialize(uint32,uint16,address,address)': FunctionFragment; + 'initiateSigningCohort(uint256,address,address[],uint16,uint32)': FunctionFragment; + 'isCohortActive(uint32)': FunctionFragment; + 'isSigner(uint32,address)': FunctionFragment; + 'maxCohortSize()': FunctionFragment; + 'numberOfSigningCohorts()': FunctionFragment; 'owner()': FunctionFragment; 'pendingDefaultAdmin()': FunctionFragment; 'pendingDefaultAdminDelay()': FunctionFragment; - 'postAggregation(uint32,bytes,(bytes32,bytes16),bytes)': FunctionFragment; - 'postTranscript(uint32,bytes)': FunctionFragment; - 'publishTranscript(uint32,bytes)': FunctionFragment; - 'reinitializeDefaultAdmin(address)': FunctionFragment; + 'postSigningCohortSignature(uint32,bytes)': FunctionFragment; 'renounceRole(bytes32,address)': FunctionFragment; 'revokeRole(bytes32,address)': FunctionFragment; - 'rituals(uint256)': FunctionFragment; 'rollbackDefaultAdminDelay()': FunctionFragment; + 'setDispatcher(address)': FunctionFragment; 'setMaxDkgSize(uint16)': FunctionFragment; - 'setProviderPublicKey((bytes32,bytes32,bytes32))': FunctionFragment; - 'setReimbursementPool(address)': FunctionFragment; + 'setSigningCohortConditions(uint32,uint256,bytes)': FunctionFragment; 'setTimeout(uint32)': FunctionFragment; + 'signingCohorts(uint32)': FunctionFragment; + 'signingCoordinatorDispatcher()': FunctionFragment; 'supportsInterface(bytes4)': FunctionFragment; 'timeout()': FunctionFragment; - 'transferRitualAuthority(uint32,address)': FunctionFragment; - 'withdrawAllTokens(address)': FunctionFragment; }; getFunction( nameOrSignatureOrTopic: | 'DEFAULT_ADMIN_ROLE' - | 'FEE_MODEL_MANAGER_ROLE' - | 'TREASURY_ROLE' + | 'INITIATOR_ROLE' | 'acceptDefaultAdminTransfer' | 'application' - | 'approveFeeModel' | 'beginDefaultAdminTransfer' | 'cancelDefaultAdminTransfer' | 'changeDefaultAdminDelay' - | 'cohortFingerprint' | 'defaultAdmin' | 'defaultAdminDelay' | 'defaultAdminDelayIncreaseWait' - | 'expectedTranscriptSize' - | 'extendRitual' - | 'feeModelsRegistry' - | 'getAccessController' - | 'getAuthority' - | 'getFeeModel' - | 'getInitiator' - | 'getParticipant' - | 'getParticipantFromProvider' - | 'getParticipants(uint32)' - | 'getParticipants(uint32,uint256,uint256,bool)' - | 'getProviderPublicKey' - | 'getProviders' - | 'getPublicKeyFromRitualId' - | 'getRitualIdFromPublicKey' - | 'getRitualState' + | 'deployAdditionalChainForSigningMultisig' + | 'getChains' + | 'getCondition' | 'getRoleAdmin' - | 'getThresholdForRitualSize' - | 'getTimestamps' + | 'getSigner' + | 'getSigners' + | 'getSigningCohortConditions' + | 'getSigningCohortDataHash' + | 'getSigningCohortState' + | 'getSigningCoordinatorChild' | 'grantRole' | 'hasRole' | 'initialize' - | 'initializeNumberOfRituals' - | 'initiateRitual' - | 'isEncryptionAuthorized' - | 'isParticipant' - | 'isProviderKeySet' - | 'isProviderPublicKeySet' - | 'isRitualActive' - | 'maxDkgSize' - | 'numberOfRituals' + | 'initiateSigningCohort' + | 'isCohortActive' + | 'isSigner' + | 'maxCohortSize' + | 'numberOfSigningCohorts' | 'owner' | 'pendingDefaultAdmin' | 'pendingDefaultAdminDelay' - | 'postAggregation' - | 'postTranscript' - | 'publishTranscript' - | 'reinitializeDefaultAdmin' + | 'postSigningCohortSignature' | 'renounceRole' | 'revokeRole' - | 'rituals' | 'rollbackDefaultAdminDelay' + | 'setDispatcher' | 'setMaxDkgSize' - | 'setProviderPublicKey' - | 'setReimbursementPool' + | 'setSigningCohortConditions' | 'setTimeout' + | 'signingCohorts' + | 'signingCoordinatorDispatcher' | 'supportsInterface' - | 'timeout' - | 'transferRitualAuthority' - | 'withdrawAllTokens', + | 'timeout', ): FunctionFragment; encodeFunctionData( @@ -202,11 +139,7 @@ export interface SigningCoordinatorInterface extends utils.Interface { values?: undefined, ): string; encodeFunctionData( - functionFragment: 'FEE_MODEL_MANAGER_ROLE', - values?: undefined, - ): string; - encodeFunctionData( - functionFragment: 'TREASURY_ROLE', + functionFragment: 'INITIATOR_ROLE', values?: undefined, ): string; encodeFunctionData( @@ -217,10 +150,6 @@ export interface SigningCoordinatorInterface extends utils.Interface { functionFragment: 'application', values?: undefined, ): string; - encodeFunctionData( - functionFragment: 'approveFeeModel', - values: [string], - ): string; encodeFunctionData( functionFragment: 'beginDefaultAdminTransfer', values: [string], @@ -233,10 +162,6 @@ export interface SigningCoordinatorInterface extends utils.Interface { functionFragment: 'changeDefaultAdminDelay', values: [BigNumberish], ): string; - encodeFunctionData( - functionFragment: 'cohortFingerprint', - values: [string[]], - ): string; encodeFunctionData( functionFragment: 'defaultAdmin', values?: undefined, @@ -250,79 +175,43 @@ export interface SigningCoordinatorInterface extends utils.Interface { values?: undefined, ): string; encodeFunctionData( - functionFragment: 'expectedTranscriptSize', - values: [BigNumberish, BigNumberish], - ): string; - encodeFunctionData( - functionFragment: 'extendRitual', + functionFragment: 'deployAdditionalChainForSigningMultisig', values: [BigNumberish, BigNumberish], ): string; encodeFunctionData( - functionFragment: 'feeModelsRegistry', - values: [string], - ): string; - encodeFunctionData( - functionFragment: 'getAccessController', + functionFragment: 'getChains', values: [BigNumberish], ): string; encodeFunctionData( - functionFragment: 'getAuthority', - values: [BigNumberish], - ): string; - encodeFunctionData( - functionFragment: 'getFeeModel', - values: [BigNumberish], - ): string; - encodeFunctionData( - functionFragment: 'getInitiator', - values: [BigNumberish], + functionFragment: 'getCondition', + values: [BigNumberish, BigNumberish], ): string; encodeFunctionData( - functionFragment: 'getParticipant', - values: [BigNumberish, string, boolean], + functionFragment: 'getRoleAdmin', + values: [BytesLike], ): string; encodeFunctionData( - functionFragment: 'getParticipantFromProvider', + functionFragment: 'getSigner', values: [BigNumberish, string], ): string; encodeFunctionData( - functionFragment: 'getParticipants(uint32)', - values: [BigNumberish], - ): string; - encodeFunctionData( - functionFragment: 'getParticipants(uint32,uint256,uint256,bool)', - values: [BigNumberish, BigNumberish, BigNumberish, boolean], - ): string; - encodeFunctionData( - functionFragment: 'getProviderPublicKey', - values: [string, BigNumberish], - ): string; - encodeFunctionData( - functionFragment: 'getProviders', - values: [BigNumberish], - ): string; - encodeFunctionData( - functionFragment: 'getPublicKeyFromRitualId', + functionFragment: 'getSigners', values: [BigNumberish], ): string; encodeFunctionData( - functionFragment: 'getRitualIdFromPublicKey', - values: [BLS12381.G1PointStruct], + functionFragment: 'getSigningCohortConditions', + values: [BigNumberish, BigNumberish], ): string; encodeFunctionData( - functionFragment: 'getRitualState', + functionFragment: 'getSigningCohortDataHash', values: [BigNumberish], ): string; encodeFunctionData( - functionFragment: 'getRoleAdmin', - values: [BytesLike], - ): string; - encodeFunctionData( - functionFragment: 'getThresholdForRitualSize', + functionFragment: 'getSigningCohortState', values: [BigNumberish], ): string; encodeFunctionData( - functionFragment: 'getTimestamps', + functionFragment: 'getSigningCoordinatorChild', values: [BigNumberish], ): string; encodeFunctionData( @@ -335,42 +224,26 @@ export interface SigningCoordinatorInterface extends utils.Interface { ): string; encodeFunctionData( functionFragment: 'initialize', - values: [BigNumberish, BigNumberish, string], - ): string; - encodeFunctionData( - functionFragment: 'initializeNumberOfRituals', - values?: undefined, + values: [BigNumberish, BigNumberish, string, string], ): string; encodeFunctionData( - functionFragment: 'initiateRitual', - values: [string, string[], string, BigNumberish, string], + functionFragment: 'initiateSigningCohort', + values: [BigNumberish, string, string[], BigNumberish, BigNumberish], ): string; encodeFunctionData( - functionFragment: 'isEncryptionAuthorized', - values: [BigNumberish, BytesLike, BytesLike], + functionFragment: 'isCohortActive', + values: [BigNumberish], ): string; encodeFunctionData( - functionFragment: 'isParticipant', + functionFragment: 'isSigner', values: [BigNumberish, string], ): string; encodeFunctionData( - functionFragment: 'isProviderKeySet', - values: [string], - ): string; - encodeFunctionData( - functionFragment: 'isProviderPublicKeySet', - values: [string], - ): string; - encodeFunctionData( - functionFragment: 'isRitualActive', - values: [BigNumberish], - ): string; - encodeFunctionData( - functionFragment: 'maxDkgSize', + functionFragment: 'maxCohortSize', values?: undefined, ): string; encodeFunctionData( - functionFragment: 'numberOfRituals', + functionFragment: 'numberOfSigningCohorts', values?: undefined, ): string; encodeFunctionData(functionFragment: 'owner', values?: undefined): string; @@ -383,21 +256,9 @@ export interface SigningCoordinatorInterface extends utils.Interface { values?: undefined, ): string; encodeFunctionData( - functionFragment: 'postAggregation', - values: [BigNumberish, BytesLike, BLS12381.G1PointStruct, BytesLike], - ): string; - encodeFunctionData( - functionFragment: 'postTranscript', + functionFragment: 'postSigningCohortSignature', values: [BigNumberish, BytesLike], ): string; - encodeFunctionData( - functionFragment: 'publishTranscript', - values: [BigNumberish, BytesLike], - ): string; - encodeFunctionData( - functionFragment: 'reinitializeDefaultAdmin', - values: [string], - ): string; encodeFunctionData( functionFragment: 'renounceRole', values: [BytesLike, string], @@ -406,54 +267,46 @@ export interface SigningCoordinatorInterface extends utils.Interface { functionFragment: 'revokeRole', values: [BytesLike, string], ): string; - encodeFunctionData( - functionFragment: 'rituals', - values: [BigNumberish], - ): string; encodeFunctionData( functionFragment: 'rollbackDefaultAdminDelay', values?: undefined, ): string; encodeFunctionData( - functionFragment: 'setMaxDkgSize', - values: [BigNumberish], + functionFragment: 'setDispatcher', + values: [string], ): string; encodeFunctionData( - functionFragment: 'setProviderPublicKey', - values: [BLS12381.G2PointStruct], + functionFragment: 'setMaxDkgSize', + values: [BigNumberish], ): string; encodeFunctionData( - functionFragment: 'setReimbursementPool', - values: [string], + functionFragment: 'setSigningCohortConditions', + values: [BigNumberish, BigNumberish, BytesLike], ): string; encodeFunctionData( functionFragment: 'setTimeout', values: [BigNumberish], ): string; encodeFunctionData( - functionFragment: 'supportsInterface', - values: [BytesLike], + functionFragment: 'signingCohorts', + values: [BigNumberish], ): string; - encodeFunctionData(functionFragment: 'timeout', values?: undefined): string; encodeFunctionData( - functionFragment: 'transferRitualAuthority', - values: [BigNumberish, string], + functionFragment: 'signingCoordinatorDispatcher', + values?: undefined, ): string; encodeFunctionData( - functionFragment: 'withdrawAllTokens', - values: [string], + functionFragment: 'supportsInterface', + values: [BytesLike], ): string; + encodeFunctionData(functionFragment: 'timeout', values?: undefined): string; decodeFunctionResult( functionFragment: 'DEFAULT_ADMIN_ROLE', data: BytesLike, ): Result; decodeFunctionResult( - functionFragment: 'FEE_MODEL_MANAGER_ROLE', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'TREASURY_ROLE', + functionFragment: 'INITIATOR_ROLE', data: BytesLike, ): Result; decodeFunctionResult( @@ -464,10 +317,6 @@ export interface SigningCoordinatorInterface extends utils.Interface { functionFragment: 'application', data: BytesLike, ): Result; - decodeFunctionResult( - functionFragment: 'approveFeeModel', - data: BytesLike, - ): Result; decodeFunctionResult( functionFragment: 'beginDefaultAdminTransfer', data: BytesLike, @@ -480,10 +329,6 @@ export interface SigningCoordinatorInterface extends utils.Interface { functionFragment: 'changeDefaultAdminDelay', data: BytesLike, ): Result; - decodeFunctionResult( - functionFragment: 'cohortFingerprint', - data: BytesLike, - ): Result; decodeFunctionResult( functionFragment: 'defaultAdmin', data: BytesLike, @@ -497,115 +342,54 @@ export interface SigningCoordinatorInterface extends utils.Interface { data: BytesLike, ): Result; decodeFunctionResult( - functionFragment: 'expectedTranscriptSize', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'extendRitual', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'feeModelsRegistry', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'getAccessController', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'getAuthority', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'getFeeModel', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'getInitiator', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'getParticipant', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'getParticipantFromProvider', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'getParticipants(uint32)', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'getParticipants(uint32,uint256,uint256,bool)', + functionFragment: 'deployAdditionalChainForSigningMultisig', data: BytesLike, ): Result; + decodeFunctionResult(functionFragment: 'getChains', data: BytesLike): Result; decodeFunctionResult( - functionFragment: 'getProviderPublicKey', + functionFragment: 'getCondition', data: BytesLike, ): Result; decodeFunctionResult( - functionFragment: 'getProviders', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'getPublicKeyFromRitualId', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'getRitualIdFromPublicKey', + functionFragment: 'getRoleAdmin', data: BytesLike, ): Result; + decodeFunctionResult(functionFragment: 'getSigner', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'getSigners', data: BytesLike): Result; decodeFunctionResult( - functionFragment: 'getRitualState', + functionFragment: 'getSigningCohortConditions', data: BytesLike, ): Result; decodeFunctionResult( - functionFragment: 'getRoleAdmin', + functionFragment: 'getSigningCohortDataHash', data: BytesLike, ): Result; decodeFunctionResult( - functionFragment: 'getThresholdForRitualSize', + functionFragment: 'getSigningCohortState', data: BytesLike, ): Result; decodeFunctionResult( - functionFragment: 'getTimestamps', + functionFragment: 'getSigningCoordinatorChild', data: BytesLike, ): Result; decodeFunctionResult(functionFragment: 'grantRole', data: BytesLike): Result; decodeFunctionResult(functionFragment: 'hasRole', data: BytesLike): Result; decodeFunctionResult(functionFragment: 'initialize', data: BytesLike): Result; decodeFunctionResult( - functionFragment: 'initializeNumberOfRituals', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'initiateRitual', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'isEncryptionAuthorized', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'isParticipant', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'isProviderKeySet', + functionFragment: 'initiateSigningCohort', data: BytesLike, ): Result; decodeFunctionResult( - functionFragment: 'isProviderPublicKeySet', + functionFragment: 'isCohortActive', data: BytesLike, ): Result; + decodeFunctionResult(functionFragment: 'isSigner', data: BytesLike): Result; decodeFunctionResult( - functionFragment: 'isRitualActive', + functionFragment: 'maxCohortSize', data: BytesLike, ): Result; - decodeFunctionResult(functionFragment: 'maxDkgSize', data: BytesLike): Result; decodeFunctionResult( - functionFragment: 'numberOfRituals', + functionFragment: 'numberOfSigningCohorts', data: BytesLike, ): Result; decodeFunctionResult(functionFragment: 'owner', data: BytesLike): Result; @@ -618,19 +402,7 @@ export interface SigningCoordinatorInterface extends utils.Interface { data: BytesLike, ): Result; decodeFunctionResult( - functionFragment: 'postAggregation', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'postTranscript', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'publishTranscript', - data: BytesLike, - ): Result; - decodeFunctionResult( - functionFragment: 'reinitializeDefaultAdmin', + functionFragment: 'postSigningCohortSignature', data: BytesLike, ): Result; decodeFunctionResult( @@ -638,62 +410,55 @@ export interface SigningCoordinatorInterface extends utils.Interface { data: BytesLike, ): Result; decodeFunctionResult(functionFragment: 'revokeRole', data: BytesLike): Result; - decodeFunctionResult(functionFragment: 'rituals', data: BytesLike): Result; decodeFunctionResult( functionFragment: 'rollbackDefaultAdminDelay', data: BytesLike, ): Result; decodeFunctionResult( - functionFragment: 'setMaxDkgSize', + functionFragment: 'setDispatcher', data: BytesLike, ): Result; decodeFunctionResult( - functionFragment: 'setProviderPublicKey', + functionFragment: 'setMaxDkgSize', data: BytesLike, ): Result; decodeFunctionResult( - functionFragment: 'setReimbursementPool', + functionFragment: 'setSigningCohortConditions', data: BytesLike, ): Result; decodeFunctionResult(functionFragment: 'setTimeout', data: BytesLike): Result; decodeFunctionResult( - functionFragment: 'supportsInterface', + functionFragment: 'signingCohorts', data: BytesLike, ): Result; - decodeFunctionResult(functionFragment: 'timeout', data: BytesLike): Result; decodeFunctionResult( - functionFragment: 'transferRitualAuthority', + functionFragment: 'signingCoordinatorDispatcher', data: BytesLike, ): Result; decodeFunctionResult( - functionFragment: 'withdrawAllTokens', + functionFragment: 'supportsInterface', data: BytesLike, ): Result; + decodeFunctionResult(functionFragment: 'timeout', data: BytesLike): Result; events: { - 'AggregationPosted(uint32,address,bytes32)': EventFragment; 'DefaultAdminDelayChangeCanceled()': EventFragment; 'DefaultAdminDelayChangeScheduled(uint48,uint48)': EventFragment; 'DefaultAdminTransferCanceled()': EventFragment; 'DefaultAdminTransferScheduled(address,uint48)': EventFragment; - 'EndRitual(uint32,bool)': EventFragment; - 'FeeModelApproved(address)': EventFragment; + 'DispatcherChanged(address,address)': EventFragment; 'Initialized(uint64)': EventFragment; - 'MaxDkgSizeChanged(uint16,uint16)': EventFragment; - 'ParticipantPublicKeySet(uint32,address,(bytes32,bytes32,bytes32))': EventFragment; - 'ReimbursementPoolSet(address)': EventFragment; - 'RitualAuthorityTransferred(uint32,address,address)': EventFragment; - 'RitualExtended(uint32,uint32)': EventFragment; + 'InitiateSigningCohort(uint32,uint256,address,address[])': EventFragment; + 'MaxCohortSizeChanged(uint16,uint16)': EventFragment; 'RoleAdminChanged(bytes32,bytes32,bytes32)': EventFragment; 'RoleGranted(bytes32,address,address)': EventFragment; 'RoleRevoked(bytes32,address,address)': EventFragment; - 'StartAggregationRound(uint32)': EventFragment; - 'StartRitual(uint32,address,address[])': EventFragment; + 'SigningCohortConditionsSet(uint32,uint256,bytes)': EventFragment; + 'SigningCohortDeployed(uint32,uint256)': EventFragment; + 'SigningCohortSignaturePosted(uint32,address,bytes)': EventFragment; 'TimeoutChanged(uint32,uint32)': EventFragment; - 'TranscriptPosted(uint32,address,bytes32)': EventFragment; }; - getEvent(nameOrSignatureOrTopic: 'AggregationPosted'): EventFragment; getEvent( nameOrSignatureOrTopic: 'DefaultAdminDelayChangeCanceled', ): EventFragment; @@ -706,35 +471,20 @@ export interface SigningCoordinatorInterface extends utils.Interface { getEvent( nameOrSignatureOrTopic: 'DefaultAdminTransferScheduled', ): EventFragment; - getEvent(nameOrSignatureOrTopic: 'EndRitual'): EventFragment; - getEvent(nameOrSignatureOrTopic: 'FeeModelApproved'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'DispatcherChanged'): EventFragment; getEvent(nameOrSignatureOrTopic: 'Initialized'): EventFragment; - getEvent(nameOrSignatureOrTopic: 'MaxDkgSizeChanged'): EventFragment; - getEvent(nameOrSignatureOrTopic: 'ParticipantPublicKeySet'): EventFragment; - getEvent(nameOrSignatureOrTopic: 'ReimbursementPoolSet'): EventFragment; - getEvent(nameOrSignatureOrTopic: 'RitualAuthorityTransferred'): EventFragment; - getEvent(nameOrSignatureOrTopic: 'RitualExtended'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'InitiateSigningCohort'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'MaxCohortSizeChanged'): EventFragment; getEvent(nameOrSignatureOrTopic: 'RoleAdminChanged'): EventFragment; getEvent(nameOrSignatureOrTopic: 'RoleGranted'): EventFragment; getEvent(nameOrSignatureOrTopic: 'RoleRevoked'): EventFragment; - getEvent(nameOrSignatureOrTopic: 'StartAggregationRound'): EventFragment; - getEvent(nameOrSignatureOrTopic: 'StartRitual'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'SigningCohortConditionsSet'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'SigningCohortDeployed'): EventFragment; + getEvent( + nameOrSignatureOrTopic: 'SigningCohortSignaturePosted', + ): EventFragment; getEvent(nameOrSignatureOrTopic: 'TimeoutChanged'): EventFragment; - getEvent(nameOrSignatureOrTopic: 'TranscriptPosted'): EventFragment; -} - -export interface AggregationPostedEventObject { - ritualId: number; - node: string; - aggregatedTranscriptDigest: string; } -export type AggregationPostedEvent = TypedEvent< - [number, string, string], - AggregationPostedEventObject ->; - -export type AggregationPostedEventFilter = - TypedEventFilter; export interface DefaultAdminDelayChangeCanceledEventObject {} export type DefaultAdminDelayChangeCanceledEvent = TypedEvent< @@ -778,27 +528,17 @@ export type DefaultAdminTransferScheduledEvent = TypedEvent< export type DefaultAdminTransferScheduledEventFilter = TypedEventFilter; -export interface EndRitualEventObject { - ritualId: number; - successful: boolean; -} -export type EndRitualEvent = TypedEvent< - [number, boolean], - EndRitualEventObject ->; - -export type EndRitualEventFilter = TypedEventFilter; - -export interface FeeModelApprovedEventObject { - feeModel: string; +export interface DispatcherChangedEventObject { + oldDispatcher: string; + newDispatcher: string; } -export type FeeModelApprovedEvent = TypedEvent< - [string], - FeeModelApprovedEventObject +export type DispatcherChangedEvent = TypedEvent< + [string, string], + DispatcherChangedEventObject >; -export type FeeModelApprovedEventFilter = - TypedEventFilter; +export type DispatcherChangedEventFilter = + TypedEventFilter; export interface InitializedEventObject { version: BigNumber; @@ -807,65 +547,31 @@ export type InitializedEvent = TypedEvent<[BigNumber], InitializedEventObject>; export type InitializedEventFilter = TypedEventFilter; -export interface MaxDkgSizeChangedEventObject { - oldSize: number; - newSize: number; -} -export type MaxDkgSizeChangedEvent = TypedEvent< - [number, number], - MaxDkgSizeChangedEventObject ->; - -export type MaxDkgSizeChangedEventFilter = - TypedEventFilter; - -export interface ParticipantPublicKeySetEventObject { - ritualId: number; - participant: string; - publicKey: BLS12381.G2PointStructOutput; -} -export type ParticipantPublicKeySetEvent = TypedEvent< - [number, string, BLS12381.G2PointStructOutput], - ParticipantPublicKeySetEventObject ->; - -export type ParticipantPublicKeySetEventFilter = - TypedEventFilter; - -export interface ReimbursementPoolSetEventObject { - pool: string; -} -export type ReimbursementPoolSetEvent = TypedEvent< - [string], - ReimbursementPoolSetEventObject ->; - -export type ReimbursementPoolSetEventFilter = - TypedEventFilter; - -export interface RitualAuthorityTransferredEventObject { - ritualId: number; - previousAuthority: string; - newAuthority: string; +export interface InitiateSigningCohortEventObject { + cohortId: number; + chainId: BigNumber; + authority: string; + participants: string[]; } -export type RitualAuthorityTransferredEvent = TypedEvent< - [number, string, string], - RitualAuthorityTransferredEventObject +export type InitiateSigningCohortEvent = TypedEvent< + [number, BigNumber, string, string[]], + InitiateSigningCohortEventObject >; -export type RitualAuthorityTransferredEventFilter = - TypedEventFilter; +export type InitiateSigningCohortEventFilter = + TypedEventFilter; -export interface RitualExtendedEventObject { - ritualId: number; - endTimestamp: number; +export interface MaxCohortSizeChangedEventObject { + oldSize: number; + newSize: number; } -export type RitualExtendedEvent = TypedEvent< +export type MaxCohortSizeChangedEvent = TypedEvent< [number, number], - RitualExtendedEventObject + MaxCohortSizeChangedEventObject >; -export type RitualExtendedEventFilter = TypedEventFilter; +export type MaxCohortSizeChangedEventFilter = + TypedEventFilter; export interface RoleAdminChangedEventObject { role: string; @@ -904,28 +610,43 @@ export type RoleRevokedEvent = TypedEvent< export type RoleRevokedEventFilter = TypedEventFilter; -export interface StartAggregationRoundEventObject { - ritualId: number; +export interface SigningCohortConditionsSetEventObject { + cohortId: number; + chainId: BigNumber; + conditions: string; } -export type StartAggregationRoundEvent = TypedEvent< - [number], - StartAggregationRoundEventObject +export type SigningCohortConditionsSetEvent = TypedEvent< + [number, BigNumber, string], + SigningCohortConditionsSetEventObject >; -export type StartAggregationRoundEventFilter = - TypedEventFilter; +export type SigningCohortConditionsSetEventFilter = + TypedEventFilter; -export interface StartRitualEventObject { - ritualId: number; - authority: string; - participants: string[]; +export interface SigningCohortDeployedEventObject { + cohortId: number; + chainId: BigNumber; +} +export type SigningCohortDeployedEvent = TypedEvent< + [number, BigNumber], + SigningCohortDeployedEventObject +>; + +export type SigningCohortDeployedEventFilter = + TypedEventFilter; + +export interface SigningCohortSignaturePostedEventObject { + cohortId: number; + provider: string; + signature: string; } -export type StartRitualEvent = TypedEvent< - [number, string, string[]], - StartRitualEventObject +export type SigningCohortSignaturePostedEvent = TypedEvent< + [number, string, string], + SigningCohortSignaturePostedEventObject >; -export type StartRitualEventFilter = TypedEventFilter; +export type SigningCohortSignaturePostedEventFilter = + TypedEventFilter; export interface TimeoutChangedEventObject { oldTimeout: number; @@ -938,25 +659,12 @@ export type TimeoutChangedEvent = TypedEvent< export type TimeoutChangedEventFilter = TypedEventFilter; -export interface TranscriptPostedEventObject { - ritualId: number; - node: string; - transcriptDigest: string; -} -export type TranscriptPostedEvent = TypedEvent< - [number, string, string], - TranscriptPostedEventObject ->; - -export type TranscriptPostedEventFilter = - TypedEventFilter; - -export interface Coordinator extends BaseContract { +export interface SigningCoordinator extends BaseContract { connect(signerOrProvider: Signer | Provider | string): this; attach(addressOrName: string): this; deployed(): Promise; - interface: CoordinatorInterface; + interface: SigningCoordinatorInterface; queryFilter( event: TypedEventFilter, @@ -980,9 +688,7 @@ export interface Coordinator extends BaseContract { functions: { DEFAULT_ADMIN_ROLE(overrides?: CallOverrides): Promise<[string]>; - FEE_MODEL_MANAGER_ROLE(overrides?: CallOverrides): Promise<[string]>; - - TREASURY_ROLE(overrides?: CallOverrides): Promise<[string]>; + INITIATOR_ROLE(overrides?: CallOverrides): Promise<[string]>; acceptDefaultAdminTransfer( overrides?: Overrides & { from?: string }, @@ -990,11 +696,6 @@ export interface Coordinator extends BaseContract { application(overrides?: CallOverrides): Promise<[string]>; - approveFeeModel( - feeModel: string, - overrides?: Overrides & { from?: string }, - ): Promise; - beginDefaultAdminTransfer( newAdmin: string, overrides?: Overrides & { from?: string }, @@ -1009,119 +710,62 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - cohortFingerprint( - nodes: string[], - overrides?: CallOverrides, - ): Promise<[string]>; - defaultAdmin(overrides?: CallOverrides): Promise<[string]>; defaultAdminDelay(overrides?: CallOverrides): Promise<[number]>; defaultAdminDelayIncreaseWait(overrides?: CallOverrides): Promise<[number]>; - expectedTranscriptSize( - dkgSize: BigNumberish, - threshold: BigNumberish, - overrides?: CallOverrides, - ): Promise<[BigNumber]>; - - extendRitual( - ritualId: BigNumberish, - duration: BigNumberish, + deployAdditionalChainForSigningMultisig( + chainId: BigNumberish, + cohortId: BigNumberish, overrides?: Overrides & { from?: string }, ): Promise; - feeModelsRegistry( - arg0: string, - overrides?: CallOverrides, - ): Promise<[boolean]>; - - getAccessController( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise<[string]>; - - getAuthority( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise<[string]>; - - getFeeModel( - ritualId: BigNumberish, + getChains( + cohortId: BigNumberish, overrides?: CallOverrides, - ): Promise<[string]>; + ): Promise<[BigNumber[]]>; - getInitiator( - ritualId: BigNumberish, + getCondition( + cohortId: BigNumberish, + chainId: BigNumberish, overrides?: CallOverrides, ): Promise<[string]>; - getParticipant( - ritualId: BigNumberish, - provider: string, - transcript: boolean, - overrides?: CallOverrides, - ): Promise<[Coordinator.ParticipantStructOutput]>; - - getParticipantFromProvider( - ritualId: BigNumberish, - provider: string, - overrides?: CallOverrides, - ): Promise<[Coordinator.ParticipantStructOutput]>; - - 'getParticipants(uint32)'( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise<[Coordinator.ParticipantStructOutput[]]>; - - 'getParticipants(uint32,uint256,uint256,bool)'( - ritualId: BigNumberish, - startIndex: BigNumberish, - maxParticipants: BigNumberish, - includeTranscript: boolean, - overrides?: CallOverrides, - ): Promise<[Coordinator.ParticipantStructOutput[]]>; + getRoleAdmin(role: BytesLike, overrides?: CallOverrides): Promise<[string]>; - getProviderPublicKey( + getSigner( + cohortId: BigNumberish, provider: string, - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise<[BLS12381.G2PointStructOutput]>; - - getProviders( - ritualId: BigNumberish, overrides?: CallOverrides, - ): Promise<[string[]]>; + ): Promise<[SigningCoordinator.SigningCohortParticipantStructOutput]>; - getPublicKeyFromRitualId( - ritualId: BigNumberish, + getSigners( + cohortId: BigNumberish, overrides?: CallOverrides, - ): Promise<[BLS12381.G1PointStructOutput]>; + ): Promise<[SigningCoordinator.SigningCohortParticipantStructOutput[]]>; - getRitualIdFromPublicKey( - dkgPublicKey: BLS12381.G1PointStruct, + getSigningCohortConditions( + cohortId: BigNumberish, + chainId: BigNumberish, overrides?: CallOverrides, - ): Promise<[number] & { ritualId: number }>; + ): Promise<[string]>; - getRitualState( - ritualId: BigNumberish, + getSigningCohortDataHash( + cohortId: BigNumberish, overrides?: CallOverrides, - ): Promise<[number]>; - - getRoleAdmin(role: BytesLike, overrides?: CallOverrides): Promise<[string]>; + ): Promise<[string]>; - getThresholdForRitualSize( - size: BigNumberish, + getSigningCohortState( + cohortId: BigNumberish, overrides?: CallOverrides, ): Promise<[number]>; - getTimestamps( - ritualId: BigNumberish, + getSigningCoordinatorChild( + chainId: BigNumberish, overrides?: CallOverrides, - ): Promise< - [number, number] & { initTimestamp: number; endTimestamp: number } - >; + ): Promise<[string]>; grantRole( role: BytesLike, @@ -1138,54 +782,34 @@ export interface Coordinator extends BaseContract { initialize( _timeout: BigNumberish, _maxDkgSize: BigNumberish, + _signingCoordinatorDispatcher: string, _admin: string, overrides?: Overrides & { from?: string }, ): Promise; - initializeNumberOfRituals( - overrides?: Overrides & { from?: string }, - ): Promise; - - initiateRitual( - feeModel: string, - providers: string[], + initiateSigningCohort( + chainId: BigNumberish, authority: string, + providers: string[], + threshold: BigNumberish, duration: BigNumberish, - accessController: string, overrides?: Overrides & { from?: string }, ): Promise; - isEncryptionAuthorized( - arg0: BigNumberish, - arg1: BytesLike, - arg2: BytesLike, + isCohortActive( + cohortId: BigNumberish, overrides?: CallOverrides, ): Promise<[boolean]>; - isParticipant( - ritualId: BigNumberish, + isSigner( + cohortId: BigNumberish, provider: string, overrides?: CallOverrides, ): Promise<[boolean]>; - isProviderKeySet( - provider: string, - overrides?: CallOverrides, - ): Promise<[boolean]>; - - isProviderPublicKeySet( - arg0: string, - overrides?: CallOverrides, - ): Promise<[boolean]>; - - isRitualActive( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise<[boolean]>; + maxCohortSize(overrides?: CallOverrides): Promise<[number]>; - maxDkgSize(overrides?: CallOverrides): Promise<[number]>; - - numberOfRituals(overrides?: CallOverrides): Promise<[BigNumber]>; + numberOfSigningCohorts(overrides?: CallOverrides): Promise<[BigNumber]>; owner(overrides?: CallOverrides): Promise<[string]>; @@ -1197,28 +821,9 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise<[number, number] & { newDelay: number; schedule: number }>; - postAggregation( - ritualId: BigNumberish, - aggregatedTranscript: BytesLike, - dkgPublicKey: BLS12381.G1PointStruct, - decryptionRequestStaticKey: BytesLike, - overrides?: Overrides & { from?: string }, - ): Promise; - - postTranscript( - arg0: BigNumberish, - arg1: BytesLike, - overrides?: Overrides & { from?: string }, - ): Promise; - - publishTranscript( - ritualId: BigNumberish, - transcript: BytesLike, - overrides?: Overrides & { from?: string }, - ): Promise; - - reinitializeDefaultAdmin( - newDefaultAdmin: string, + postSigningCohortSignature( + cohortId: BigNumberish, + signature: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; @@ -1234,57 +839,24 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - rituals( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise< - [ - string, - number, - number, - number, - number, - string, - number, - number, - boolean, - string, - BLS12381.G1PointStructOutput, - string, - string, - ] & { - initiator: string; - initTimestamp: number; - endTimestamp: number; - totalTranscripts: number; - totalAggregations: number; - authority: string; - dkgSize: number; - threshold: number; - aggregationMismatch: boolean; - accessController: string; - publicKey: BLS12381.G1PointStructOutput; - aggregatedTranscript: string; - feeModel: string; - } - >; - rollbackDefaultAdminDelay( overrides?: Overrides & { from?: string }, ): Promise; - setMaxDkgSize( - newSize: BigNumberish, + setDispatcher( + dispatcher: string, overrides?: Overrides & { from?: string }, ): Promise; - setProviderPublicKey( - publicKey: BLS12381.G2PointStruct, + setMaxDkgSize( + newSize: BigNumberish, overrides?: Overrides & { from?: string }, ): Promise; - setReimbursementPool( - pool: string, + setSigningCohortConditions( + cohortId: BigNumberish, + chainId: BigNumberish, + conditions: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; @@ -1293,30 +865,34 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; + signingCohorts( + arg0: BigNumberish, + overrides?: CallOverrides, + ): Promise< + [string, number, number, string, number, number, number] & { + initiator: string; + initTimestamp: number; + endTimestamp: number; + authority: string; + totalSignatures: number; + numSigners: number; + threshold: number; + } + >; + + signingCoordinatorDispatcher(overrides?: CallOverrides): Promise<[string]>; + supportsInterface( interfaceId: BytesLike, overrides?: CallOverrides, ): Promise<[boolean]>; timeout(overrides?: CallOverrides): Promise<[number]>; - - transferRitualAuthority( - ritualId: BigNumberish, - newAuthority: string, - overrides?: Overrides & { from?: string }, - ): Promise; - - withdrawAllTokens( - token: string, - overrides?: Overrides & { from?: string }, - ): Promise; }; DEFAULT_ADMIN_ROLE(overrides?: CallOverrides): Promise; - FEE_MODEL_MANAGER_ROLE(overrides?: CallOverrides): Promise; - - TREASURY_ROLE(overrides?: CallOverrides): Promise; + INITIATOR_ROLE(overrides?: CallOverrides): Promise; acceptDefaultAdminTransfer( overrides?: Overrides & { from?: string }, @@ -1324,11 +900,6 @@ export interface Coordinator extends BaseContract { application(overrides?: CallOverrides): Promise; - approveFeeModel( - feeModel: string, - overrides?: Overrides & { from?: string }, - ): Promise; - beginDefaultAdminTransfer( newAdmin: string, overrides?: Overrides & { from?: string }, @@ -1343,116 +914,62 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - cohortFingerprint( - nodes: string[], - overrides?: CallOverrides, - ): Promise; - defaultAdmin(overrides?: CallOverrides): Promise; defaultAdminDelay(overrides?: CallOverrides): Promise; defaultAdminDelayIncreaseWait(overrides?: CallOverrides): Promise; - expectedTranscriptSize( - dkgSize: BigNumberish, - threshold: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - extendRitual( - ritualId: BigNumberish, - duration: BigNumberish, + deployAdditionalChainForSigningMultisig( + chainId: BigNumberish, + cohortId: BigNumberish, overrides?: Overrides & { from?: string }, ): Promise; - feeModelsRegistry(arg0: string, overrides?: CallOverrides): Promise; - - getAccessController( - ritualId: BigNumberish, + getChains( + cohortId: BigNumberish, overrides?: CallOverrides, - ): Promise; - - getAuthority( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - getFeeModel( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; + ): Promise; - getInitiator( - ritualId: BigNumberish, + getCondition( + cohortId: BigNumberish, + chainId: BigNumberish, overrides?: CallOverrides, ): Promise; - getParticipant( - ritualId: BigNumberish, - provider: string, - transcript: boolean, - overrides?: CallOverrides, - ): Promise; - - getParticipantFromProvider( - ritualId: BigNumberish, - provider: string, - overrides?: CallOverrides, - ): Promise; - - 'getParticipants(uint32)'( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - 'getParticipants(uint32,uint256,uint256,bool)'( - ritualId: BigNumberish, - startIndex: BigNumberish, - maxParticipants: BigNumberish, - includeTranscript: boolean, - overrides?: CallOverrides, - ): Promise; + getRoleAdmin(role: BytesLike, overrides?: CallOverrides): Promise; - getProviderPublicKey( + getSigner( + cohortId: BigNumberish, provider: string, - ritualId: BigNumberish, overrides?: CallOverrides, - ): Promise; + ): Promise; - getProviders( - ritualId: BigNumberish, + getSigners( + cohortId: BigNumberish, overrides?: CallOverrides, - ): Promise; + ): Promise; - getPublicKeyFromRitualId( - ritualId: BigNumberish, + getSigningCohortConditions( + cohortId: BigNumberish, + chainId: BigNumberish, overrides?: CallOverrides, - ): Promise; - - getRitualIdFromPublicKey( - dkgPublicKey: BLS12381.G1PointStruct, - overrides?: CallOverrides, - ): Promise; + ): Promise; - getRitualState( - ritualId: BigNumberish, + getSigningCohortDataHash( + cohortId: BigNumberish, overrides?: CallOverrides, - ): Promise; - - getRoleAdmin(role: BytesLike, overrides?: CallOverrides): Promise; + ): Promise; - getThresholdForRitualSize( - size: BigNumberish, + getSigningCohortState( + cohortId: BigNumberish, overrides?: CallOverrides, ): Promise; - getTimestamps( - ritualId: BigNumberish, + getSigningCoordinatorChild( + chainId: BigNumberish, overrides?: CallOverrides, - ): Promise< - [number, number] & { initTimestamp: number; endTimestamp: number } - >; + ): Promise; grantRole( role: BytesLike, @@ -1469,54 +986,34 @@ export interface Coordinator extends BaseContract { initialize( _timeout: BigNumberish, _maxDkgSize: BigNumberish, + _signingCoordinatorDispatcher: string, _admin: string, overrides?: Overrides & { from?: string }, ): Promise; - initializeNumberOfRituals( - overrides?: Overrides & { from?: string }, - ): Promise; - - initiateRitual( - feeModel: string, - providers: string[], + initiateSigningCohort( + chainId: BigNumberish, authority: string, + providers: string[], + threshold: BigNumberish, duration: BigNumberish, - accessController: string, overrides?: Overrides & { from?: string }, ): Promise; - isEncryptionAuthorized( - arg0: BigNumberish, - arg1: BytesLike, - arg2: BytesLike, + isCohortActive( + cohortId: BigNumberish, overrides?: CallOverrides, ): Promise; - isParticipant( - ritualId: BigNumberish, + isSigner( + cohortId: BigNumberish, provider: string, overrides?: CallOverrides, ): Promise; - isProviderKeySet( - provider: string, - overrides?: CallOverrides, - ): Promise; + maxCohortSize(overrides?: CallOverrides): Promise; - isProviderPublicKeySet( - arg0: string, - overrides?: CallOverrides, - ): Promise; - - isRitualActive( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - maxDkgSize(overrides?: CallOverrides): Promise; - - numberOfRituals(overrides?: CallOverrides): Promise; + numberOfSigningCohorts(overrides?: CallOverrides): Promise; owner(overrides?: CallOverrides): Promise; @@ -1528,28 +1025,9 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise<[number, number] & { newDelay: number; schedule: number }>; - postAggregation( - ritualId: BigNumberish, - aggregatedTranscript: BytesLike, - dkgPublicKey: BLS12381.G1PointStruct, - decryptionRequestStaticKey: BytesLike, - overrides?: Overrides & { from?: string }, - ): Promise; - - postTranscript( - arg0: BigNumberish, - arg1: BytesLike, - overrides?: Overrides & { from?: string }, - ): Promise; - - publishTranscript( - ritualId: BigNumberish, - transcript: BytesLike, - overrides?: Overrides & { from?: string }, - ): Promise; - - reinitializeDefaultAdmin( - newDefaultAdmin: string, + postSigningCohortSignature( + cohortId: BigNumberish, + signature: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; @@ -1565,57 +1043,24 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - rituals( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise< - [ - string, - number, - number, - number, - number, - string, - number, - number, - boolean, - string, - BLS12381.G1PointStructOutput, - string, - string, - ] & { - initiator: string; - initTimestamp: number; - endTimestamp: number; - totalTranscripts: number; - totalAggregations: number; - authority: string; - dkgSize: number; - threshold: number; - aggregationMismatch: boolean; - accessController: string; - publicKey: BLS12381.G1PointStructOutput; - aggregatedTranscript: string; - feeModel: string; - } - >; - rollbackDefaultAdminDelay( overrides?: Overrides & { from?: string }, ): Promise; - setMaxDkgSize( - newSize: BigNumberish, + setDispatcher( + dispatcher: string, overrides?: Overrides & { from?: string }, ): Promise; - setProviderPublicKey( - publicKey: BLS12381.G2PointStruct, + setMaxDkgSize( + newSize: BigNumberish, overrides?: Overrides & { from?: string }, ): Promise; - setReimbursementPool( - pool: string, + setSigningCohortConditions( + cohortId: BigNumberish, + chainId: BigNumberish, + conditions: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; @@ -1624,6 +1069,23 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; + signingCohorts( + arg0: BigNumberish, + overrides?: CallOverrides, + ): Promise< + [string, number, number, string, number, number, number] & { + initiator: string; + initTimestamp: number; + endTimestamp: number; + authority: string; + totalSignatures: number; + numSigners: number; + threshold: number; + } + >; + + signingCoordinatorDispatcher(overrides?: CallOverrides): Promise; + supportsInterface( interfaceId: BytesLike, overrides?: CallOverrides, @@ -1631,30 +1093,15 @@ export interface Coordinator extends BaseContract { timeout(overrides?: CallOverrides): Promise; - transferRitualAuthority( - ritualId: BigNumberish, - newAuthority: string, - overrides?: Overrides & { from?: string }, - ): Promise; - - withdrawAllTokens( - token: string, - overrides?: Overrides & { from?: string }, - ): Promise; - callStatic: { DEFAULT_ADMIN_ROLE(overrides?: CallOverrides): Promise; - FEE_MODEL_MANAGER_ROLE(overrides?: CallOverrides): Promise; - - TREASURY_ROLE(overrides?: CallOverrides): Promise; + INITIATOR_ROLE(overrides?: CallOverrides): Promise; acceptDefaultAdminTransfer(overrides?: CallOverrides): Promise; application(overrides?: CallOverrides): Promise; - approveFeeModel(feeModel: string, overrides?: CallOverrides): Promise; - beginDefaultAdminTransfer( newAdmin: string, overrides?: CallOverrides, @@ -1667,119 +1114,62 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; - cohortFingerprint( - nodes: string[], - overrides?: CallOverrides, - ): Promise; - defaultAdmin(overrides?: CallOverrides): Promise; defaultAdminDelay(overrides?: CallOverrides): Promise; defaultAdminDelayIncreaseWait(overrides?: CallOverrides): Promise; - expectedTranscriptSize( - dkgSize: BigNumberish, - threshold: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - extendRitual( - ritualId: BigNumberish, - duration: BigNumberish, + deployAdditionalChainForSigningMultisig( + chainId: BigNumberish, + cohortId: BigNumberish, overrides?: CallOverrides, ): Promise; - feeModelsRegistry( - arg0: string, - overrides?: CallOverrides, - ): Promise; - - getAccessController( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - getAuthority( - ritualId: BigNumberish, + getChains( + cohortId: BigNumberish, overrides?: CallOverrides, - ): Promise; + ): Promise; - getFeeModel( - ritualId: BigNumberish, + getCondition( + cohortId: BigNumberish, + chainId: BigNumberish, overrides?: CallOverrides, ): Promise; - getInitiator( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - getParticipant( - ritualId: BigNumberish, - provider: string, - transcript: boolean, - overrides?: CallOverrides, - ): Promise; - - getParticipantFromProvider( - ritualId: BigNumberish, - provider: string, - overrides?: CallOverrides, - ): Promise; - - 'getParticipants(uint32)'( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - 'getParticipants(uint32,uint256,uint256,bool)'( - ritualId: BigNumberish, - startIndex: BigNumberish, - maxParticipants: BigNumberish, - includeTranscript: boolean, - overrides?: CallOverrides, - ): Promise; + getRoleAdmin(role: BytesLike, overrides?: CallOverrides): Promise; - getProviderPublicKey( + getSigner( + cohortId: BigNumberish, provider: string, - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - getProviders( - ritualId: BigNumberish, overrides?: CallOverrides, - ): Promise; + ): Promise; - getPublicKeyFromRitualId( - ritualId: BigNumberish, + getSigners( + cohortId: BigNumberish, overrides?: CallOverrides, - ): Promise; + ): Promise; - getRitualIdFromPublicKey( - dkgPublicKey: BLS12381.G1PointStruct, + getSigningCohortConditions( + cohortId: BigNumberish, + chainId: BigNumberish, overrides?: CallOverrides, - ): Promise; + ): Promise; - getRitualState( - ritualId: BigNumberish, + getSigningCohortDataHash( + cohortId: BigNumberish, overrides?: CallOverrides, - ): Promise; - - getRoleAdmin(role: BytesLike, overrides?: CallOverrides): Promise; + ): Promise; - getThresholdForRitualSize( - size: BigNumberish, + getSigningCohortState( + cohortId: BigNumberish, overrides?: CallOverrides, ): Promise; - getTimestamps( - ritualId: BigNumberish, + getSigningCoordinatorChild( + chainId: BigNumberish, overrides?: CallOverrides, - ): Promise< - [number, number] & { initTimestamp: number; endTimestamp: number } - >; + ): Promise; grantRole( role: BytesLike, @@ -1796,52 +1186,34 @@ export interface Coordinator extends BaseContract { initialize( _timeout: BigNumberish, _maxDkgSize: BigNumberish, + _signingCoordinatorDispatcher: string, _admin: string, overrides?: CallOverrides, ): Promise; - initializeNumberOfRituals(overrides?: CallOverrides): Promise; - - initiateRitual( - feeModel: string, - providers: string[], + initiateSigningCohort( + chainId: BigNumberish, authority: string, + providers: string[], + threshold: BigNumberish, duration: BigNumberish, - accessController: string, overrides?: CallOverrides, ): Promise; - isEncryptionAuthorized( - arg0: BigNumberish, - arg1: BytesLike, - arg2: BytesLike, - overrides?: CallOverrides, - ): Promise; - - isParticipant( - ritualId: BigNumberish, - provider: string, + isCohortActive( + cohortId: BigNumberish, overrides?: CallOverrides, ): Promise; - isProviderKeySet( + isSigner( + cohortId: BigNumberish, provider: string, overrides?: CallOverrides, ): Promise; - isProviderPublicKeySet( - arg0: string, - overrides?: CallOverrides, - ): Promise; - - isRitualActive( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; + maxCohortSize(overrides?: CallOverrides): Promise; - maxDkgSize(overrides?: CallOverrides): Promise; - - numberOfRituals(overrides?: CallOverrides): Promise; + numberOfSigningCohorts(overrides?: CallOverrides): Promise; owner(overrides?: CallOverrides): Promise; @@ -1853,28 +1225,9 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise<[number, number] & { newDelay: number; schedule: number }>; - postAggregation( - ritualId: BigNumberish, - aggregatedTranscript: BytesLike, - dkgPublicKey: BLS12381.G1PointStruct, - decryptionRequestStaticKey: BytesLike, - overrides?: CallOverrides, - ): Promise; - - postTranscript( - arg0: BigNumberish, - arg1: BytesLike, - overrides?: CallOverrides, - ): Promise; - - publishTranscript( - ritualId: BigNumberish, - transcript: BytesLike, - overrides?: CallOverrides, - ): Promise; - - reinitializeDefaultAdmin( - newDefaultAdmin: string, + postSigningCohortSignature( + cohortId: BigNumberish, + signature: BytesLike, overrides?: CallOverrides, ): Promise; @@ -1890,55 +1243,19 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; - rituals( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise< - [ - string, - number, - number, - number, - number, - string, - number, - number, - boolean, - string, - BLS12381.G1PointStructOutput, - string, - string, - ] & { - initiator: string; - initTimestamp: number; - endTimestamp: number; - totalTranscripts: number; - totalAggregations: number; - authority: string; - dkgSize: number; - threshold: number; - aggregationMismatch: boolean; - accessController: string; - publicKey: BLS12381.G1PointStructOutput; - aggregatedTranscript: string; - feeModel: string; - } - >; - rollbackDefaultAdminDelay(overrides?: CallOverrides): Promise; + setDispatcher(dispatcher: string, overrides?: CallOverrides): Promise; + setMaxDkgSize( newSize: BigNumberish, overrides?: CallOverrides, ): Promise; - setProviderPublicKey( - publicKey: BLS12381.G2PointStruct, - overrides?: CallOverrides, - ): Promise; - - setReimbursementPool( - pool: string, + setSigningCohortConditions( + cohortId: BigNumberish, + chainId: BigNumberish, + conditions: BytesLike, overrides?: CallOverrides, ): Promise; @@ -1947,34 +1264,32 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + signingCohorts( + arg0: BigNumberish, + overrides?: CallOverrides, + ): Promise< + [string, number, number, string, number, number, number] & { + initiator: string; + initTimestamp: number; + endTimestamp: number; + authority: string; + totalSignatures: number; + numSigners: number; + threshold: number; + } + >; + + signingCoordinatorDispatcher(overrides?: CallOverrides): Promise; + supportsInterface( interfaceId: BytesLike, overrides?: CallOverrides, ): Promise; timeout(overrides?: CallOverrides): Promise; - - transferRitualAuthority( - ritualId: BigNumberish, - newAuthority: string, - overrides?: CallOverrides, - ): Promise; - - withdrawAllTokens(token: string, overrides?: CallOverrides): Promise; }; filters: { - 'AggregationPosted(uint32,address,bytes32)'( - ritualId?: BigNumberish | null, - node?: string | null, - aggregatedTranscriptDigest?: null, - ): AggregationPostedEventFilter; - AggregationPosted( - ritualId?: BigNumberish | null, - node?: string | null, - aggregatedTranscriptDigest?: null, - ): AggregationPostedEventFilter; - 'DefaultAdminDelayChangeCanceled()'(): DefaultAdminDelayChangeCanceledEventFilter; DefaultAdminDelayChangeCanceled(): DefaultAdminDelayChangeCanceledEventFilter; @@ -1999,65 +1314,39 @@ export interface Coordinator extends BaseContract { acceptSchedule?: null, ): DefaultAdminTransferScheduledEventFilter; - 'EndRitual(uint32,bool)'( - ritualId?: BigNumberish | null, - successful?: null, - ): EndRitualEventFilter; - EndRitual( - ritualId?: BigNumberish | null, - successful?: null, - ): EndRitualEventFilter; - - 'FeeModelApproved(address)'(feeModel?: null): FeeModelApprovedEventFilter; - FeeModelApproved(feeModel?: null): FeeModelApprovedEventFilter; + 'DispatcherChanged(address,address)'( + oldDispatcher?: null, + newDispatcher?: null, + ): DispatcherChangedEventFilter; + DispatcherChanged( + oldDispatcher?: null, + newDispatcher?: null, + ): DispatcherChangedEventFilter; 'Initialized(uint64)'(version?: null): InitializedEventFilter; Initialized(version?: null): InitializedEventFilter; - 'MaxDkgSizeChanged(uint16,uint16)'( + 'InitiateSigningCohort(uint32,uint256,address,address[])'( + cohortId?: BigNumberish | null, + chainId?: null, + authority?: string | null, + participants?: null, + ): InitiateSigningCohortEventFilter; + InitiateSigningCohort( + cohortId?: BigNumberish | null, + chainId?: null, + authority?: string | null, + participants?: null, + ): InitiateSigningCohortEventFilter; + + 'MaxCohortSizeChanged(uint16,uint16)'( oldSize?: null, newSize?: null, - ): MaxDkgSizeChangedEventFilter; - MaxDkgSizeChanged( + ): MaxCohortSizeChangedEventFilter; + MaxCohortSizeChanged( oldSize?: null, newSize?: null, - ): MaxDkgSizeChangedEventFilter; - - 'ParticipantPublicKeySet(uint32,address,(bytes32,bytes32,bytes32))'( - ritualId?: BigNumberish | null, - participant?: string | null, - publicKey?: null, - ): ParticipantPublicKeySetEventFilter; - ParticipantPublicKeySet( - ritualId?: BigNumberish | null, - participant?: string | null, - publicKey?: null, - ): ParticipantPublicKeySetEventFilter; - - 'ReimbursementPoolSet(address)'( - pool?: string | null, - ): ReimbursementPoolSetEventFilter; - ReimbursementPoolSet(pool?: string | null): ReimbursementPoolSetEventFilter; - - 'RitualAuthorityTransferred(uint32,address,address)'( - ritualId?: BigNumberish | null, - previousAuthority?: string | null, - newAuthority?: string | null, - ): RitualAuthorityTransferredEventFilter; - RitualAuthorityTransferred( - ritualId?: BigNumberish | null, - previousAuthority?: string | null, - newAuthority?: string | null, - ): RitualAuthorityTransferredEventFilter; - - 'RitualExtended(uint32,uint32)'( - ritualId?: BigNumberish | null, - endTimestamp?: null, - ): RitualExtendedEventFilter; - RitualExtended( - ritualId?: BigNumberish | null, - endTimestamp?: null, - ): RitualExtendedEventFilter; + ): MaxCohortSizeChangedEventFilter; 'RoleAdminChanged(bytes32,bytes32,bytes32)'( role?: BytesLike | null, @@ -2092,23 +1381,36 @@ export interface Coordinator extends BaseContract { sender?: string | null, ): RoleRevokedEventFilter; - 'StartAggregationRound(uint32)'( - ritualId?: BigNumberish | null, - ): StartAggregationRoundEventFilter; - StartAggregationRound( - ritualId?: BigNumberish | null, - ): StartAggregationRoundEventFilter; - - 'StartRitual(uint32,address,address[])'( - ritualId?: BigNumberish | null, - authority?: string | null, - participants?: null, - ): StartRitualEventFilter; - StartRitual( - ritualId?: BigNumberish | null, - authority?: string | null, - participants?: null, - ): StartRitualEventFilter; + 'SigningCohortConditionsSet(uint32,uint256,bytes)'( + cohortId?: BigNumberish | null, + chainId?: null, + conditions?: null, + ): SigningCohortConditionsSetEventFilter; + SigningCohortConditionsSet( + cohortId?: BigNumberish | null, + chainId?: null, + conditions?: null, + ): SigningCohortConditionsSetEventFilter; + + 'SigningCohortDeployed(uint32,uint256)'( + cohortId?: BigNumberish | null, + chainId?: null, + ): SigningCohortDeployedEventFilter; + SigningCohortDeployed( + cohortId?: BigNumberish | null, + chainId?: null, + ): SigningCohortDeployedEventFilter; + + 'SigningCohortSignaturePosted(uint32,address,bytes)'( + cohortId?: BigNumberish | null, + provider?: string | null, + signature?: null, + ): SigningCohortSignaturePostedEventFilter; + SigningCohortSignaturePosted( + cohortId?: BigNumberish | null, + provider?: string | null, + signature?: null, + ): SigningCohortSignaturePostedEventFilter; 'TimeoutChanged(uint32,uint32)'( oldTimeout?: null, @@ -2118,25 +1420,12 @@ export interface Coordinator extends BaseContract { oldTimeout?: null, newTimeout?: null, ): TimeoutChangedEventFilter; - - 'TranscriptPosted(uint32,address,bytes32)'( - ritualId?: BigNumberish | null, - node?: string | null, - transcriptDigest?: null, - ): TranscriptPostedEventFilter; - TranscriptPosted( - ritualId?: BigNumberish | null, - node?: string | null, - transcriptDigest?: null, - ): TranscriptPostedEventFilter; }; estimateGas: { DEFAULT_ADMIN_ROLE(overrides?: CallOverrides): Promise; - FEE_MODEL_MANAGER_ROLE(overrides?: CallOverrides): Promise; - - TREASURY_ROLE(overrides?: CallOverrides): Promise; + INITIATOR_ROLE(overrides?: CallOverrides): Promise; acceptDefaultAdminTransfer( overrides?: Overrides & { from?: string }, @@ -2144,11 +1433,6 @@ export interface Coordinator extends BaseContract { application(overrides?: CallOverrides): Promise; - approveFeeModel( - feeModel: string, - overrides?: Overrides & { from?: string }, - ): Promise; - beginDefaultAdminTransfer( newAdmin: string, overrides?: Overrides & { from?: string }, @@ -2163,11 +1447,6 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - cohortFingerprint( - nodes: string[], - overrides?: CallOverrides, - ): Promise; - defaultAdmin(overrides?: CallOverrides): Promise; defaultAdminDelay(overrides?: CallOverrides): Promise; @@ -2176,107 +1455,57 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; - expectedTranscriptSize( - dkgSize: BigNumberish, - threshold: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - extendRitual( - ritualId: BigNumberish, - duration: BigNumberish, + deployAdditionalChainForSigningMultisig( + chainId: BigNumberish, + cohortId: BigNumberish, overrides?: Overrides & { from?: string }, ): Promise; - feeModelsRegistry( - arg0: string, + getChains( + cohortId: BigNumberish, overrides?: CallOverrides, ): Promise; - getAccessController( - ritualId: BigNumberish, + getCondition( + cohortId: BigNumberish, + chainId: BigNumberish, overrides?: CallOverrides, ): Promise; - getAuthority( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - getFeeModel( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - getInitiator( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - getParticipant( - ritualId: BigNumberish, - provider: string, - transcript: boolean, - overrides?: CallOverrides, - ): Promise; - - getParticipantFromProvider( - ritualId: BigNumberish, - provider: string, - overrides?: CallOverrides, - ): Promise; - - 'getParticipants(uint32)'( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - 'getParticipants(uint32,uint256,uint256,bool)'( - ritualId: BigNumberish, - startIndex: BigNumberish, - maxParticipants: BigNumberish, - includeTranscript: boolean, + getRoleAdmin( + role: BytesLike, overrides?: CallOverrides, ): Promise; - getProviderPublicKey( + getSigner( + cohortId: BigNumberish, provider: string, - ritualId: BigNumberish, overrides?: CallOverrides, ): Promise; - getProviders( - ritualId: BigNumberish, + getSigners( + cohortId: BigNumberish, overrides?: CallOverrides, ): Promise; - getPublicKeyFromRitualId( - ritualId: BigNumberish, + getSigningCohortConditions( + cohortId: BigNumberish, + chainId: BigNumberish, overrides?: CallOverrides, ): Promise; - getRitualIdFromPublicKey( - dkgPublicKey: BLS12381.G1PointStruct, - overrides?: CallOverrides, - ): Promise; - - getRitualState( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - getRoleAdmin( - role: BytesLike, + getSigningCohortDataHash( + cohortId: BigNumberish, overrides?: CallOverrides, ): Promise; - getThresholdForRitualSize( - size: BigNumberish, + getSigningCohortState( + cohortId: BigNumberish, overrides?: CallOverrides, ): Promise; - getTimestamps( - ritualId: BigNumberish, + getSigningCoordinatorChild( + chainId: BigNumberish, overrides?: CallOverrides, ): Promise; @@ -2295,54 +1524,34 @@ export interface Coordinator extends BaseContract { initialize( _timeout: BigNumberish, _maxDkgSize: BigNumberish, + _signingCoordinatorDispatcher: string, _admin: string, overrides?: Overrides & { from?: string }, ): Promise; - initializeNumberOfRituals( - overrides?: Overrides & { from?: string }, - ): Promise; - - initiateRitual( - feeModel: string, - providers: string[], + initiateSigningCohort( + chainId: BigNumberish, authority: string, + providers: string[], + threshold: BigNumberish, duration: BigNumberish, - accessController: string, overrides?: Overrides & { from?: string }, ): Promise; - isEncryptionAuthorized( - arg0: BigNumberish, - arg1: BytesLike, - arg2: BytesLike, + isCohortActive( + cohortId: BigNumberish, overrides?: CallOverrides, ): Promise; - isParticipant( - ritualId: BigNumberish, + isSigner( + cohortId: BigNumberish, provider: string, overrides?: CallOverrides, ): Promise; - isProviderKeySet( - provider: string, - overrides?: CallOverrides, - ): Promise; + maxCohortSize(overrides?: CallOverrides): Promise; - isProviderPublicKeySet( - arg0: string, - overrides?: CallOverrides, - ): Promise; - - isRitualActive( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - maxDkgSize(overrides?: CallOverrides): Promise; - - numberOfRituals(overrides?: CallOverrides): Promise; + numberOfSigningCohorts(overrides?: CallOverrides): Promise; owner(overrides?: CallOverrides): Promise; @@ -2350,28 +1559,9 @@ export interface Coordinator extends BaseContract { pendingDefaultAdminDelay(overrides?: CallOverrides): Promise; - postAggregation( - ritualId: BigNumberish, - aggregatedTranscript: BytesLike, - dkgPublicKey: BLS12381.G1PointStruct, - decryptionRequestStaticKey: BytesLike, - overrides?: Overrides & { from?: string }, - ): Promise; - - postTranscript( - arg0: BigNumberish, - arg1: BytesLike, - overrides?: Overrides & { from?: string }, - ): Promise; - - publishTranscript( - ritualId: BigNumberish, - transcript: BytesLike, - overrides?: Overrides & { from?: string }, - ): Promise; - - reinitializeDefaultAdmin( - newDefaultAdmin: string, + postSigningCohortSignature( + cohortId: BigNumberish, + signature: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; @@ -2387,27 +1577,24 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - rituals( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - rollbackDefaultAdminDelay( overrides?: Overrides & { from?: string }, ): Promise; - setMaxDkgSize( - newSize: BigNumberish, + setDispatcher( + dispatcher: string, overrides?: Overrides & { from?: string }, ): Promise; - setProviderPublicKey( - publicKey: BLS12381.G2PointStruct, + setMaxDkgSize( + newSize: BigNumberish, overrides?: Overrides & { from?: string }, ): Promise; - setReimbursementPool( - pool: string, + setSigningCohortConditions( + cohortId: BigNumberish, + chainId: BigNumberish, + conditions: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; @@ -2416,23 +1603,19 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - supportsInterface( - interfaceId: BytesLike, + signingCohorts( + arg0: BigNumberish, overrides?: CallOverrides, ): Promise; - timeout(overrides?: CallOverrides): Promise; + signingCoordinatorDispatcher(overrides?: CallOverrides): Promise; - transferRitualAuthority( - ritualId: BigNumberish, - newAuthority: string, - overrides?: Overrides & { from?: string }, + supportsInterface( + interfaceId: BytesLike, + overrides?: CallOverrides, ): Promise; - withdrawAllTokens( - token: string, - overrides?: Overrides & { from?: string }, - ): Promise; + timeout(overrides?: CallOverrides): Promise; }; populateTransaction: { @@ -2440,11 +1623,7 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; - FEE_MODEL_MANAGER_ROLE( - overrides?: CallOverrides, - ): Promise; - - TREASURY_ROLE(overrides?: CallOverrides): Promise; + INITIATOR_ROLE(overrides?: CallOverrides): Promise; acceptDefaultAdminTransfer( overrides?: Overrides & { from?: string }, @@ -2452,11 +1631,6 @@ export interface Coordinator extends BaseContract { application(overrides?: CallOverrides): Promise; - approveFeeModel( - feeModel: string, - overrides?: Overrides & { from?: string }, - ): Promise; - beginDefaultAdminTransfer( newAdmin: string, overrides?: Overrides & { from?: string }, @@ -2471,11 +1645,6 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - cohortFingerprint( - nodes: string[], - overrides?: CallOverrides, - ): Promise; - defaultAdmin(overrides?: CallOverrides): Promise; defaultAdminDelay(overrides?: CallOverrides): Promise; @@ -2484,107 +1653,57 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; - expectedTranscriptSize( - dkgSize: BigNumberish, - threshold: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - extendRitual( - ritualId: BigNumberish, - duration: BigNumberish, + deployAdditionalChainForSigningMultisig( + chainId: BigNumberish, + cohortId: BigNumberish, overrides?: Overrides & { from?: string }, ): Promise; - feeModelsRegistry( - arg0: string, - overrides?: CallOverrides, - ): Promise; - - getAccessController( - ritualId: BigNumberish, + getChains( + cohortId: BigNumberish, overrides?: CallOverrides, ): Promise; - getAuthority( - ritualId: BigNumberish, + getCondition( + cohortId: BigNumberish, + chainId: BigNumberish, overrides?: CallOverrides, ): Promise; - getFeeModel( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - getInitiator( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - getParticipant( - ritualId: BigNumberish, - provider: string, - transcript: boolean, - overrides?: CallOverrides, - ): Promise; - - getParticipantFromProvider( - ritualId: BigNumberish, - provider: string, - overrides?: CallOverrides, - ): Promise; - - 'getParticipants(uint32)'( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - 'getParticipants(uint32,uint256,uint256,bool)'( - ritualId: BigNumberish, - startIndex: BigNumberish, - maxParticipants: BigNumberish, - includeTranscript: boolean, + getRoleAdmin( + role: BytesLike, overrides?: CallOverrides, ): Promise; - getProviderPublicKey( + getSigner( + cohortId: BigNumberish, provider: string, - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - getProviders( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - getPublicKeyFromRitualId( - ritualId: BigNumberish, overrides?: CallOverrides, ): Promise; - getRitualIdFromPublicKey( - dkgPublicKey: BLS12381.G1PointStruct, + getSigners( + cohortId: BigNumberish, overrides?: CallOverrides, ): Promise; - getRitualState( - ritualId: BigNumberish, + getSigningCohortConditions( + cohortId: BigNumberish, + chainId: BigNumberish, overrides?: CallOverrides, ): Promise; - getRoleAdmin( - role: BytesLike, + getSigningCohortDataHash( + cohortId: BigNumberish, overrides?: CallOverrides, ): Promise; - getThresholdForRitualSize( - size: BigNumberish, + getSigningCohortState( + cohortId: BigNumberish, overrides?: CallOverrides, ): Promise; - getTimestamps( - ritualId: BigNumberish, + getSigningCoordinatorChild( + chainId: BigNumberish, overrides?: CallOverrides, ): Promise; @@ -2603,55 +1722,37 @@ export interface Coordinator extends BaseContract { initialize( _timeout: BigNumberish, _maxDkgSize: BigNumberish, + _signingCoordinatorDispatcher: string, _admin: string, overrides?: Overrides & { from?: string }, ): Promise; - initializeNumberOfRituals( - overrides?: Overrides & { from?: string }, - ): Promise; - - initiateRitual( - feeModel: string, - providers: string[], + initiateSigningCohort( + chainId: BigNumberish, authority: string, + providers: string[], + threshold: BigNumberish, duration: BigNumberish, - accessController: string, overrides?: Overrides & { from?: string }, ): Promise; - isEncryptionAuthorized( - arg0: BigNumberish, - arg1: BytesLike, - arg2: BytesLike, + isCohortActive( + cohortId: BigNumberish, overrides?: CallOverrides, ): Promise; - isParticipant( - ritualId: BigNumberish, + isSigner( + cohortId: BigNumberish, provider: string, overrides?: CallOverrides, ): Promise; - isProviderKeySet( - provider: string, - overrides?: CallOverrides, - ): Promise; + maxCohortSize(overrides?: CallOverrides): Promise; - isProviderPublicKeySet( - arg0: string, + numberOfSigningCohorts( overrides?: CallOverrides, ): Promise; - isRitualActive( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - - maxDkgSize(overrides?: CallOverrides): Promise; - - numberOfRituals(overrides?: CallOverrides): Promise; - owner(overrides?: CallOverrides): Promise; pendingDefaultAdmin( @@ -2662,28 +1763,9 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; - postAggregation( - ritualId: BigNumberish, - aggregatedTranscript: BytesLike, - dkgPublicKey: BLS12381.G1PointStruct, - decryptionRequestStaticKey: BytesLike, - overrides?: Overrides & { from?: string }, - ): Promise; - - postTranscript( - arg0: BigNumberish, - arg1: BytesLike, - overrides?: Overrides & { from?: string }, - ): Promise; - - publishTranscript( - ritualId: BigNumberish, - transcript: BytesLike, - overrides?: Overrides & { from?: string }, - ): Promise; - - reinitializeDefaultAdmin( - newDefaultAdmin: string, + postSigningCohortSignature( + cohortId: BigNumberish, + signature: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; @@ -2699,27 +1781,24 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - rituals( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - rollbackDefaultAdminDelay( overrides?: Overrides & { from?: string }, ): Promise; - setMaxDkgSize( - newSize: BigNumberish, + setDispatcher( + dispatcher: string, overrides?: Overrides & { from?: string }, ): Promise; - setProviderPublicKey( - publicKey: BLS12381.G2PointStruct, + setMaxDkgSize( + newSize: BigNumberish, overrides?: Overrides & { from?: string }, ): Promise; - setReimbursementPool( - pool: string, + setSigningCohortConditions( + cohortId: BigNumberish, + chainId: BigNumberish, + conditions: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; @@ -2728,22 +1807,20 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - supportsInterface( - interfaceId: BytesLike, + signingCohorts( + arg0: BigNumberish, overrides?: CallOverrides, ): Promise; - timeout(overrides?: CallOverrides): Promise; - - transferRitualAuthority( - ritualId: BigNumberish, - newAuthority: string, - overrides?: Overrides & { from?: string }, + signingCoordinatorDispatcher( + overrides?: CallOverrides, ): Promise; - withdrawAllTokens( - token: string, - overrides?: Overrides & { from?: string }, + supportsInterface( + interfaceId: BytesLike, + overrides?: CallOverrides, ): Promise; + + timeout(overrides?: CallOverrides): Promise; }; } diff --git a/packages/shared/src/contracts/ethers-typechain/factories/SigningCoordinator__factory.ts b/packages/shared/src/contracts/ethers-typechain/factories/SigningCoordinator__factory.ts new file mode 100644 index 000000000..31fb08fbc --- /dev/null +++ b/packages/shared/src/contracts/ethers-typechain/factories/SigningCoordinator__factory.ts @@ -0,0 +1,1233 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import type { Provider } from '@ethersproject/providers'; +import { Contract, Signer, utils } from 'ethers'; +import type { + SigningCoordinator, + SigningCoordinatorInterface, +} from '../SigningCoordinator'; + +const _abi = [ + { + type: 'constructor', + stateMutability: 'nonpayable', + inputs: [ + { + name: '_application', + type: 'address', + internalType: 'contract TACoApplication', + }, + ], + }, + { + type: 'error', + name: 'AccessControlBadConfirmation', + inputs: [], + }, + { + type: 'error', + name: 'AccessControlEnforcedDefaultAdminDelay', + inputs: [ + { + name: 'schedule', + type: 'uint48', + internalType: 'uint48', + }, + ], + }, + { + type: 'error', + name: 'AccessControlEnforcedDefaultAdminRules', + inputs: [], + }, + { + type: 'error', + name: 'AccessControlInvalidDefaultAdmin', + inputs: [ + { + name: 'defaultAdmin', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'AccessControlUnauthorizedAccount', + inputs: [ + { + name: 'account', + type: 'address', + internalType: 'address', + }, + { + name: 'neededRole', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + }, + { + type: 'error', + name: 'ECDSAInvalidSignature', + inputs: [], + }, + { + type: 'error', + name: 'ECDSAInvalidSignatureLength', + inputs: [ + { + name: 'length', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + { + type: 'error', + name: 'ECDSAInvalidSignatureS', + inputs: [ + { + name: 's', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + }, + { + type: 'error', + name: 'InvalidInitialization', + inputs: [], + }, + { + type: 'error', + name: 'NotInitializing', + inputs: [], + }, + { + type: 'error', + name: 'SafeCastOverflowedUintDowncast', + inputs: [ + { + name: 'bits', + type: 'uint8', + internalType: 'uint8', + }, + { + name: 'value', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + { + type: 'event', + name: 'DefaultAdminDelayChangeCanceled', + inputs: [], + anonymous: false, + }, + { + type: 'event', + name: 'DefaultAdminDelayChangeScheduled', + inputs: [ + { + name: 'newDelay', + type: 'uint48', + internalType: 'uint48', + indexed: false, + }, + { + name: 'effectSchedule', + type: 'uint48', + internalType: 'uint48', + indexed: false, + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'DefaultAdminTransferCanceled', + inputs: [], + anonymous: false, + }, + { + type: 'event', + name: 'DefaultAdminTransferScheduled', + inputs: [ + { + name: 'newAdmin', + type: 'address', + internalType: 'address', + indexed: true, + }, + { + name: 'acceptSchedule', + type: 'uint48', + internalType: 'uint48', + indexed: false, + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'DispatcherChanged', + inputs: [ + { + name: 'oldDispatcher', + type: 'address', + internalType: 'address', + indexed: false, + }, + { + name: 'newDispatcher', + type: 'address', + internalType: 'address', + indexed: false, + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Initialized', + inputs: [ + { + name: 'version', + type: 'uint64', + internalType: 'uint64', + indexed: false, + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'InitiateSigningCohort', + inputs: [ + { + name: 'cohortId', + type: 'uint32', + internalType: 'uint32', + indexed: true, + }, + { + name: 'chainId', + type: 'uint256', + internalType: 'uint256', + indexed: false, + }, + { + name: 'authority', + type: 'address', + internalType: 'address', + indexed: true, + }, + { + name: 'participants', + type: 'address[]', + internalType: 'address[]', + indexed: false, + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'MaxCohortSizeChanged', + inputs: [ + { + name: 'oldSize', + type: 'uint16', + internalType: 'uint16', + indexed: false, + }, + { + name: 'newSize', + type: 'uint16', + internalType: 'uint16', + indexed: false, + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RoleAdminChanged', + inputs: [ + { + name: 'role', + type: 'bytes32', + internalType: 'bytes32', + indexed: true, + }, + { + name: 'previousAdminRole', + type: 'bytes32', + internalType: 'bytes32', + indexed: true, + }, + { + name: 'newAdminRole', + type: 'bytes32', + internalType: 'bytes32', + indexed: true, + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RoleGranted', + inputs: [ + { + name: 'role', + type: 'bytes32', + internalType: 'bytes32', + indexed: true, + }, + { + name: 'account', + type: 'address', + internalType: 'address', + indexed: true, + }, + { + name: 'sender', + type: 'address', + internalType: 'address', + indexed: true, + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RoleRevoked', + inputs: [ + { + name: 'role', + type: 'bytes32', + internalType: 'bytes32', + indexed: true, + }, + { + name: 'account', + type: 'address', + internalType: 'address', + indexed: true, + }, + { + name: 'sender', + type: 'address', + internalType: 'address', + indexed: true, + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'SigningCohortConditionsSet', + inputs: [ + { + name: 'cohortId', + type: 'uint32', + internalType: 'uint32', + indexed: true, + }, + { + name: 'chainId', + type: 'uint256', + internalType: 'uint256', + indexed: false, + }, + { + name: 'conditions', + type: 'bytes', + internalType: 'bytes', + indexed: false, + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'SigningCohortDeployed', + inputs: [ + { + name: 'cohortId', + type: 'uint32', + internalType: 'uint32', + indexed: true, + }, + { + name: 'chainId', + type: 'uint256', + internalType: 'uint256', + indexed: false, + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'SigningCohortSignaturePosted', + inputs: [ + { + name: 'cohortId', + type: 'uint32', + internalType: 'uint32', + indexed: true, + }, + { + name: 'provider', + type: 'address', + internalType: 'address', + indexed: true, + }, + { + name: 'signature', + type: 'bytes', + internalType: 'bytes', + indexed: false, + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'TimeoutChanged', + inputs: [ + { + name: 'oldTimeout', + type: 'uint32', + internalType: 'uint32', + indexed: false, + }, + { + name: 'newTimeout', + type: 'uint32', + internalType: 'uint32', + indexed: false, + }, + ], + anonymous: false, + }, + { + type: 'function', + name: 'DEFAULT_ADMIN_ROLE', + stateMutability: 'view', + inputs: [], + outputs: [ + { + name: '', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + }, + { + type: 'function', + name: 'INITIATOR_ROLE', + stateMutability: 'view', + inputs: [], + outputs: [ + { + name: '', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + }, + { + type: 'function', + name: 'acceptDefaultAdminTransfer', + stateMutability: 'nonpayable', + inputs: [], + outputs: [], + }, + { + type: 'function', + name: 'application', + stateMutability: 'view', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'contract TACoApplication', + }, + ], + }, + { + type: 'function', + name: 'beginDefaultAdminTransfer', + stateMutability: 'nonpayable', + inputs: [ + { + name: 'newAdmin', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + }, + { + type: 'function', + name: 'cancelDefaultAdminTransfer', + stateMutability: 'nonpayable', + inputs: [], + outputs: [], + }, + { + type: 'function', + name: 'changeDefaultAdminDelay', + stateMutability: 'nonpayable', + inputs: [ + { + name: 'newDelay', + type: 'uint48', + internalType: 'uint48', + }, + ], + outputs: [], + }, + { + type: 'function', + name: 'defaultAdmin', + stateMutability: 'view', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'function', + name: 'defaultAdminDelay', + stateMutability: 'view', + inputs: [], + outputs: [ + { + name: '', + type: 'uint48', + internalType: 'uint48', + }, + ], + }, + { + type: 'function', + name: 'defaultAdminDelayIncreaseWait', + stateMutability: 'view', + inputs: [], + outputs: [ + { + name: '', + type: 'uint48', + internalType: 'uint48', + }, + ], + }, + { + type: 'function', + name: 'deployAdditionalChainForSigningMultisig', + stateMutability: 'nonpayable', + inputs: [ + { + name: 'chainId', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'cohortId', + type: 'uint32', + internalType: 'uint32', + }, + ], + outputs: [], + }, + { + type: 'function', + name: 'getChains', + stateMutability: 'view', + inputs: [ + { + name: 'cohortId', + type: 'uint32', + internalType: 'uint32', + }, + ], + outputs: [ + { + name: '', + type: 'uint256[]', + internalType: 'uint256[]', + }, + ], + }, + { + type: 'function', + name: 'getCondition', + stateMutability: 'view', + inputs: [ + { + name: 'cohortId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'chainId', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: '', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'function', + name: 'getRoleAdmin', + stateMutability: 'view', + inputs: [ + { + name: 'role', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + outputs: [ + { + name: '', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + }, + { + type: 'function', + name: 'getSigner', + stateMutability: 'view', + inputs: [ + { + name: 'cohortId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'provider', + type: 'address', + internalType: 'address', + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + components: [ + { + name: 'provider', + type: 'address', + internalType: 'address', + }, + { + name: 'operator', + type: 'address', + internalType: 'address', + }, + { + name: 'signature', + type: 'bytes', + internalType: 'bytes', + }, + ], + internalType: 'struct SigningCoordinator.SigningCohortParticipant', + }, + ], + }, + { + type: 'function', + name: 'getSigners', + stateMutability: 'view', + inputs: [ + { + name: 'cohortId', + type: 'uint32', + internalType: 'uint32', + }, + ], + outputs: [ + { + name: '', + type: 'tuple[]', + components: [ + { + name: 'provider', + type: 'address', + internalType: 'address', + }, + { + name: 'operator', + type: 'address', + internalType: 'address', + }, + { + name: 'signature', + type: 'bytes', + internalType: 'bytes', + }, + ], + internalType: 'struct SigningCoordinator.SigningCohortParticipant[]', + }, + ], + }, + { + type: 'function', + name: 'getSigningCohortConditions', + stateMutability: 'view', + inputs: [ + { + name: 'cohortId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'chainId', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: '', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'function', + name: 'getSigningCohortDataHash', + stateMutability: 'view', + inputs: [ + { + name: 'cohortId', + type: 'uint32', + internalType: 'uint32', + }, + ], + outputs: [ + { + name: '', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + }, + { + type: 'function', + name: 'getSigningCohortState', + stateMutability: 'view', + inputs: [ + { + name: 'cohortId', + type: 'uint32', + internalType: 'uint32', + }, + ], + outputs: [ + { + name: '', + type: 'uint8', + internalType: 'enum SigningCoordinator.SigningCohortState', + }, + ], + }, + { + type: 'function', + name: 'getSigningCoordinatorChild', + stateMutability: 'view', + inputs: [ + { + name: 'chainId', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'function', + name: 'grantRole', + stateMutability: 'nonpayable', + inputs: [ + { + name: 'role', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'account', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + }, + { + type: 'function', + name: 'hasRole', + stateMutability: 'view', + inputs: [ + { + name: 'role', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'account', + type: 'address', + internalType: 'address', + }, + ], + outputs: [ + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + type: 'function', + name: 'initialize', + stateMutability: 'nonpayable', + inputs: [ + { + name: '_timeout', + type: 'uint32', + internalType: 'uint32', + }, + { + name: '_maxDkgSize', + type: 'uint16', + internalType: 'uint16', + }, + { + name: '_signingCoordinatorDispatcher', + type: 'address', + internalType: 'contract SigningCoordinatorDispatcher', + }, + { + name: '_admin', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + }, + { + type: 'function', + name: 'initiateSigningCohort', + stateMutability: 'nonpayable', + inputs: [ + { + name: 'chainId', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'authority', + type: 'address', + internalType: 'address', + }, + { + name: 'providers', + type: 'address[]', + internalType: 'address[]', + }, + { + name: 'threshold', + type: 'uint16', + internalType: 'uint16', + }, + { + name: 'duration', + type: 'uint32', + internalType: 'uint32', + }, + ], + outputs: [ + { + name: '', + type: 'uint32', + internalType: 'uint32', + }, + ], + }, + { + type: 'function', + name: 'isCohortActive', + stateMutability: 'view', + inputs: [ + { + name: 'cohortId', + type: 'uint32', + internalType: 'uint32', + }, + ], + outputs: [ + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + type: 'function', + name: 'isSigner', + stateMutability: 'view', + inputs: [ + { + name: 'cohortId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'provider', + type: 'address', + internalType: 'address', + }, + ], + outputs: [ + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + type: 'function', + name: 'maxCohortSize', + stateMutability: 'view', + inputs: [], + outputs: [ + { + name: '', + type: 'uint16', + internalType: 'uint16', + }, + ], + }, + { + type: 'function', + name: 'numberOfSigningCohorts', + stateMutability: 'view', + inputs: [], + outputs: [ + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + { + type: 'function', + name: 'owner', + stateMutability: 'view', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'function', + name: 'pendingDefaultAdmin', + stateMutability: 'view', + inputs: [], + outputs: [ + { + name: 'newAdmin', + type: 'address', + internalType: 'address', + }, + { + name: 'schedule', + type: 'uint48', + internalType: 'uint48', + }, + ], + }, + { + type: 'function', + name: 'pendingDefaultAdminDelay', + stateMutability: 'view', + inputs: [], + outputs: [ + { + name: 'newDelay', + type: 'uint48', + internalType: 'uint48', + }, + { + name: 'schedule', + type: 'uint48', + internalType: 'uint48', + }, + ], + }, + { + type: 'function', + name: 'postSigningCohortSignature', + stateMutability: 'nonpayable', + inputs: [ + { + name: 'cohortId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'signature', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + }, + { + type: 'function', + name: 'renounceRole', + stateMutability: 'nonpayable', + inputs: [ + { + name: 'role', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'account', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + }, + { + type: 'function', + name: 'revokeRole', + stateMutability: 'nonpayable', + inputs: [ + { + name: 'role', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'account', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + }, + { + type: 'function', + name: 'rollbackDefaultAdminDelay', + stateMutability: 'nonpayable', + inputs: [], + outputs: [], + }, + { + type: 'function', + name: 'setDispatcher', + stateMutability: 'nonpayable', + inputs: [ + { + name: 'dispatcher', + type: 'address', + internalType: 'contract SigningCoordinatorDispatcher', + }, + ], + outputs: [], + }, + { + type: 'function', + name: 'setMaxDkgSize', + stateMutability: 'nonpayable', + inputs: [ + { + name: 'newSize', + type: 'uint16', + internalType: 'uint16', + }, + ], + outputs: [], + }, + { + type: 'function', + name: 'setSigningCohortConditions', + stateMutability: 'nonpayable', + inputs: [ + { + name: 'cohortId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'chainId', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'conditions', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + }, + { + type: 'function', + name: 'setTimeout', + stateMutability: 'nonpayable', + inputs: [ + { + name: 'newTimeout', + type: 'uint32', + internalType: 'uint32', + }, + ], + outputs: [], + }, + { + type: 'function', + name: 'signingCohorts', + stateMutability: 'view', + inputs: [ + { + name: '', + type: 'uint32', + internalType: 'uint32', + }, + ], + outputs: [ + { + name: 'initiator', + type: 'address', + internalType: 'address', + }, + { + name: 'initTimestamp', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'endTimestamp', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'authority', + type: 'address', + internalType: 'address', + }, + { + name: 'totalSignatures', + type: 'uint16', + internalType: 'uint16', + }, + { + name: 'numSigners', + type: 'uint16', + internalType: 'uint16', + }, + { + name: 'threshold', + type: 'uint16', + internalType: 'uint16', + }, + ], + }, + { + type: 'function', + name: 'signingCoordinatorDispatcher', + stateMutability: 'view', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'contract SigningCoordinatorDispatcher', + }, + ], + }, + { + type: 'function', + name: 'supportsInterface', + stateMutability: 'view', + inputs: [ + { + name: 'interfaceId', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + outputs: [ + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + type: 'function', + name: 'timeout', + stateMutability: 'view', + inputs: [], + outputs: [ + { + name: '', + type: 'uint32', + internalType: 'uint32', + }, + ], + }, +] as const; + +export class SigningCoordinator__factory { + static readonly abi = _abi; + static createInterface(): SigningCoordinatorInterface { + return new utils.Interface(_abi) as SigningCoordinatorInterface; + } + static connect( + address: string, + signerOrProvider: Signer | Provider, + ): SigningCoordinator { + return new Contract(address, _abi, signerOrProvider) as SigningCoordinator; + } +} diff --git a/packages/shared/src/contracts/ethers-typechain/factories/index.ts b/packages/shared/src/contracts/ethers-typechain/factories/index.ts index 8187c7c16..2ee6b4d9d 100644 --- a/packages/shared/src/contracts/ethers-typechain/factories/index.ts +++ b/packages/shared/src/contracts/ethers-typechain/factories/index.ts @@ -3,4 +3,5 @@ /* eslint-disable */ export { Coordinator__factory } from './Coordinator__factory'; export { GlobalAllowList__factory } from './GlobalAllowList__factory'; +export { SigningCoordinator__factory } from './SigningCoordinator__factory'; export { SubscriptionManager__factory } from './SubscriptionManager__factory'; diff --git a/packages/shared/src/contracts/ethers-typechain/index.ts b/packages/shared/src/contracts/ethers-typechain/index.ts index 0571c6f5d..df379c575 100644 --- a/packages/shared/src/contracts/ethers-typechain/index.ts +++ b/packages/shared/src/contracts/ethers-typechain/index.ts @@ -2,10 +2,11 @@ /* tslint:disable */ /* eslint-disable */ export type { Coordinator } from './Coordinator'; -export type { SigningCoordinator } from './SigningCoordinator'; export * as factories from './factories'; export { Coordinator__factory } from './factories/Coordinator__factory'; export { GlobalAllowList__factory } from './factories/GlobalAllowList__factory'; +export { SigningCoordinator__factory } from './factories/SigningCoordinator__factory'; export { SubscriptionManager__factory } from './factories/SubscriptionManager__factory'; export type { GlobalAllowList } from './GlobalAllowList'; +export type { SigningCoordinator } from './SigningCoordinator'; export type { SubscriptionManager } from './SubscriptionManager'; From b906891ba2269e4eadf2df18e365a1a48fbf90cc Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 18 Jun 2025 17:48:07 +0200 Subject: [PATCH 048/303] Update SigningCoordinatorAgent --- packages/shared/src/contracts/agents/index.ts | 1 + .../contracts/agents/signingCoordinator.ts | 23 ++++++++---- .../ethers-typechain/SigningCoordinator.ts | 35 +++++++++++++++++++ .../factories/SigningCoordinator__factory.ts | 19 ++++++++++ 4 files changed, 71 insertions(+), 7 deletions(-) diff --git a/packages/shared/src/contracts/agents/index.ts b/packages/shared/src/contracts/agents/index.ts index 61e29c0e6..cb6bbf88d 100644 --- a/packages/shared/src/contracts/agents/index.ts +++ b/packages/shared/src/contracts/agents/index.ts @@ -1,3 +1,4 @@ export * from './coordinator'; export * from './global-allow-list'; export * from './subscription-manager'; +export * from './signingCoordinator'; \ No newline at end of file diff --git a/packages/shared/src/contracts/agents/signingCoordinator.ts b/packages/shared/src/contracts/agents/signingCoordinator.ts index 39203dc0c..7a51ec64f 100644 --- a/packages/shared/src/contracts/agents/signingCoordinator.ts +++ b/packages/shared/src/contracts/agents/signingCoordinator.ts @@ -5,9 +5,9 @@ import { Domain } from '../../porter'; import { SigningCoordinator__factory } from '../ethers-typechain'; import { SigningCoordinator } from '../ethers-typechain/SigningCoordinator'; -export type SigningParticipant = { - provider: string; +type SignerInfo = { operator: string; + provider: string; signature: string; }; @@ -16,19 +16,28 @@ export class SigningCoordinatorAgent { provider: ethers.providers.Provider, domain: Domain, ritualId: number, - ): Promise { + ): Promise { const coordinator = await this.connectReadOnly(provider, domain); - const participants = await coordinator[ - 'getSigners(uint32)' - ](ritualId); + const participants = await coordinator.getSigners(ritualId); - return participants.map((participant) => { + return participants.map((participant: SigningCoordinator.SigningCohortParticipantStructOutput) => { return { operator: participant.operator, + provider: participant.provider, + signature: participant.signature, }; }); } +// public static async getThreshold( +// provider: ethers.providers.Provider, +// domain: Domain, +// cohortId: number, +// ): Promise { +// const coordinator = await this.connectReadOnly(provider, domain); +// return await coordinator.getThreshold(cohortId); +// } + private static async connectReadOnly( provider: ethers.providers.Provider, domain: Domain, diff --git a/packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts b/packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts index 549518b1d..88b784c1f 100644 --- a/packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts +++ b/packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts @@ -57,6 +57,7 @@ export interface SigningCoordinatorInterface extends utils.Interface { 'getCondition(uint32,uint256)': FunctionFragment; 'getRoleAdmin(bytes32)': FunctionFragment; 'getSigner(uint32,address)': FunctionFragment; + 'getThreshold(uint32)': FunctionFragment; 'getSigners(uint32)': FunctionFragment; 'getSigningCohortConditions(uint32,uint256)': FunctionFragment; 'getSigningCohortDataHash(uint32)': FunctionFragment; @@ -104,6 +105,7 @@ export interface SigningCoordinatorInterface extends utils.Interface { | 'getCondition' | 'getRoleAdmin' | 'getSigner' + | 'getThreshold' | 'getSigners' | 'getSigningCohortConditions' | 'getSigningCohortDataHash' @@ -194,6 +196,10 @@ export interface SigningCoordinatorInterface extends utils.Interface { functionFragment: 'getSigner', values: [BigNumberish, string], ): string; + encodeFunctionData( + functionFragment: 'getThreshold', + values: [BigNumberish], + ): string; encodeFunctionData( functionFragment: 'getSigners', values: [BigNumberish], @@ -355,6 +361,10 @@ export interface SigningCoordinatorInterface extends utils.Interface { data: BytesLike, ): Result; decodeFunctionResult(functionFragment: 'getSigner', data: BytesLike): Result; + decodeFunctionResult( + functionFragment: 'getThreshold', + data: BytesLike, + ): Result; decodeFunctionResult(functionFragment: 'getSigners', data: BytesLike): Result; decodeFunctionResult( functionFragment: 'getSigningCohortConditions', @@ -741,6 +751,11 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise<[SigningCoordinator.SigningCohortParticipantStructOutput]>; + getThreshold( + cohortId: BigNumberish, + overrides?: CallOverrides, + ): Promise<[number]>; + getSigners( cohortId: BigNumberish, overrides?: CallOverrides, @@ -945,6 +960,11 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + getThreshold( + cohortId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + getSigners( cohortId: BigNumberish, overrides?: CallOverrides, @@ -1145,6 +1165,11 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + getThreshold( + cohortId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + getSigners( cohortId: BigNumberish, overrides?: CallOverrides, @@ -1483,6 +1508,11 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + getThreshold( + cohortId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + getSigners( cohortId: BigNumberish, overrides?: CallOverrides, @@ -1681,6 +1711,11 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + getThreshold( + cohortId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + getSigners( cohortId: BigNumberish, overrides?: CallOverrides, diff --git a/packages/shared/src/contracts/ethers-typechain/factories/SigningCoordinator__factory.ts b/packages/shared/src/contracts/ethers-typechain/factories/SigningCoordinator__factory.ts index 31fb08fbc..f0546ac66 100644 --- a/packages/shared/src/contracts/ethers-typechain/factories/SigningCoordinator__factory.ts +++ b/packages/shared/src/contracts/ethers-typechain/factories/SigningCoordinator__factory.ts @@ -656,6 +656,25 @@ const _abi = [ }, ], }, + { + type: 'function', + name: 'getThreshold', + stateMutability: 'view', + inputs: [ + { + name: 'cohortId', + type: 'uint32', + internalType: 'uint32', + }, + ], + outputs: [ + { + name: '', + type: 'uint16', + internalType: 'uint16', + }, + ], + }, { type: 'function', name: 'getSigners', From 9f2b26a7808047921c2aea55f64ff9455e8d8be0 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 18 Jun 2025 17:52:32 +0200 Subject: [PATCH 049/303] Remove 191 from sdk (for now) --- packages/shared/src/porter.ts | 44 --------- packages/shared/test/porter.test.ts | 91 ------------------ packages/taco/integration-test/sign.test.ts | 27 +----- packages/taco/src/index.ts | 2 +- packages/taco/src/sign.ts | 27 ------ packages/taco/test/taco-sign.test.ts | 100 +------------------- 6 files changed, 3 insertions(+), 288 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index 3a4c160e3..09c854092 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -325,50 +325,6 @@ export class PorterClient { return { encryptedResponses, errors }; } - public async sign191( - payload: Uint8Array, - cohortId: number, - options: SigningOptions = { optimistic: true, returnAggregated: true } - ): Promise { - const data: SignRequest = { - payload: toBase64(payload), - signature_type: 'eip191', - cohort_id: cohortId, - optimistic: options.optimistic, - return_aggregated: options.returnAggregated, - }; - - const resp: AxiosResponse = await this.tryAndCall({ - url: '/sign', - method: 'post', - data, - }); - - const signingResults: { [ursulaAddress: string]: [string, string] } = {}; - const errors: Record = {}; - - for (const [ursulaAddress, [signerAddress, signatureB64]] of Object.entries( - resp.data.result.signing_results - )) { - try { - const decodedData = JSON.parse( - new TextDecoder().decode(fromBase64(signatureB64)) - ); - signingResults[ursulaAddress] = [signerAddress, decodedData.signature]; - } catch (e: unknown) { - const errorMessage = e instanceof Error ? e.message : 'Unknown error'; - errors[ursulaAddress] = `Failed to decode signature: ${errorMessage}`; - } - } - - return { - digest: resp.data.result.digest, - aggregatedSignature: aggregatePorterSignatures(signingResults), - signingResults, - errors, - type: 'eip191' - }; - } public async signUserOp( userOp: Record, diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index 4a66d6560..7079d97dc 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -89,7 +89,6 @@ const createMockSignImplementation = (endpoint: string, type: string) => (succes }); }; -const mockSign191 = createMockSignImplementation('/sign191', 'eip191'); const mockSignUserOp = createMockSignImplementation('/sign', 'userOp:zerodev'); describe('getPorterUris', () => { @@ -166,44 +165,6 @@ describe('PorterClient Signing', () => { await initialize(); }); - describe('sign191', () => { - it('should successfully sign a message', async () => { - mockSign191(true); - const porterClient = new PorterClient(fakePorterUris[2]); - const result = await porterClient.sign191( - new TextEncoder().encode('test message'), - 5, - { - optimistic: true, - returnAggregated: true - } - ); - - expect(result).toEqual({ - digest: '0x1234', - aggregatedSignature: '0x90ab0xijkl', // Combined signatures in sorted order - signingResults: { - '0x1234': ['0x5678', '0x90ab'], - '0xabcd': ['0xefgh', '0xijkl'], - }, - errors: {}, - type: 'eip191', - }); - }); - - it('should handle signing failures', async () => { - mockSign191(false); - const porterClient = new PorterClient(fakePorterUris[2]); - const payload = new TextEncoder().encode('Hello, TACo!'); - - await expect( - porterClient.sign191(payload, 5, { - optimistic: true, - returnAggregated: true - }) - ).rejects.toThrow('Porter returned bad response: 400 - '); - }); - }); describe('signUserOp', () => { const mockPackedUserOp = { @@ -295,57 +256,5 @@ describe('PorterClient Signing', () => { type: 'zerodev:v0.6', }); }); - - it('should handle signature decoding errors in sign191', async () => { - // Mock a response with invalid base64 signature - mockSign191(true, true); - const porterClient = new PorterClient(fakePorterUris[2]); - const result = await porterClient.sign191( - new TextEncoder().encode('test message'), - 5, - { - optimistic: true, - returnAggregated: true - } - ); - - expect(result).toEqual({ - digest: '0x1234', - aggregatedSignature: '0xijkl', // Only valid signature included - signingResults: { - '0xabcd': ['0xefgh', '0xijkl'], - }, - errors: { - '0x1234': 'Failed to decode signature: Invalid character', - }, - type: 'eip191', - }); - }); - - it('should handle non-Error objects in signature decoding', async () => { - // Mock a response that will cause a non-Error to be thrown - mockSign191(true, true); - const porterClient = new PorterClient(fakePorterUris[2]); - const result = await porterClient.sign191( - new TextEncoder().encode('test message'), - 5, - { - optimistic: true, - returnAggregated: true - } - ); - - expect(result).toEqual({ - digest: '0x1234', - aggregatedSignature: '0xijkl', // Only valid signature included - signingResults: { - '0xabcd': ['0xefgh', '0xijkl'], - }, - errors: { - '0x1234': 'Failed to decode signature: Invalid character', - }, - type: 'eip191', - }); - }); }); }); diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index d9b06cdba..3d77ffc12 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -3,7 +3,7 @@ import { ethers } from 'ethers'; import { beforeAll, describe, expect, test } from 'vitest'; import { initialize } from '../src'; -import { sign191, signUserOp } from '../src/sign'; +import { signUserOp } from '../src/sign'; import { UserOperation } from '../src/types'; const RPC_PROVIDER_URL = 'https://rpc-amoy.polygon.technology'; @@ -32,31 +32,6 @@ describe('Taco Sign Integration Test', () => { } }); - test('should sign a message using sign191', async () => { - // Create test message - const message = 'This is a test message to sign'; - - // Get porter URIs - const porterUris = await getPorterUris(DOMAIN as Domain); - - // Sign message - const signResult = await sign191( - message, - RITUAL_ID, - DOMAIN as Domain, - { optimistic: true, returnAggregated: true }, - porterUris - ); - - // Verify sign result - expect(signResult).toBeDefined(); - expect(signResult.digest).toBeDefined(); - expect(signResult.aggregatedSignature).toBeDefined(); - expect(signResult.signingResults).toBeDefined(); - expect(signResult.type).toBe('eip191'); - expect(Object.keys(signResult.signingResults).length).toBeGreaterThan(0); - }, 15000); - test('should sign a user operation', async () => { // Create a sample user operation with all required fields const userOp: UserOperation = { diff --git a/packages/taco/src/index.ts b/packages/taco/src/index.ts index 69ef03f93..6a83abc24 100644 --- a/packages/taco/src/index.ts +++ b/packages/taco/src/index.ts @@ -12,4 +12,4 @@ export { export * as conditions from './conditions'; export { decrypt, encrypt, encryptWithPublicKey } from './taco'; -export { sign191, signUserOp } from './sign'; +export { signUserOp } from './sign'; diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index f65b0c971..63014fe15 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -2,33 +2,6 @@ import { Domain, getPorterUris, PorterClient } from '@nucypher/shared'; import { SigningOptions, SignResult, UserOperation } from './types'; -// Core signing functions -export async function sign191( - payload: Uint8Array | string, - cohortId: number, - domain: Domain, - options: SigningOptions = { optimistic: true, returnAggregated: true }, - porterUris?: string[] -): Promise { - const porterUrisFull: string[] = porterUris - ? porterUris - : await getPorterUris(domain); - const porter = new PorterClient(porterUrisFull); - - // Convert string payload to Uint8Array if needed - const payloadBytes = typeof payload === 'string' - ? new TextEncoder().encode(payload) - : payload; - - const result = await porter.sign191( - payloadBytes, - cohortId, - options, - ); - - return result; -} - export async function signUserOp( userOp: UserOperation, chainId: number, diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index 2e002fa2e..1586cb444 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -2,114 +2,16 @@ import { PorterClient } from '@nucypher/shared'; import { fakePorterUri } from '@nucypher/test-utils'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { sign191, signUserOp } from '../src/sign'; +import { signUserOp } from '../src/sign'; describe('TACo Signing', () => { - let sign191Mock: ReturnType; let signUserOpMock: ReturnType; beforeEach(() => { - sign191Mock = vi.fn(); signUserOpMock = vi.fn(); - vi.spyOn(PorterClient.prototype, 'sign191').mockImplementation(sign191Mock); vi.spyOn(PorterClient.prototype, 'signUserOp').mockImplementation(signUserOpMock); }); - describe('sign191', () => { - it('should sign a string message', async () => { - const message = 'Hello, TACo!'; - const cohortId = 5; - const porterUris = [fakePorterUri]; - - sign191Mock.mockResolvedValue({ - digest: '0x1234', - aggregatedSignature: '0x90ab0xijkl', - signingResults: { - '0x1234': ['0x5678', '0x90ab'], - '0xabcd': ['0xefgh', '0xijkl'], - }, - type: 'eip191', - }); - - const result = await sign191(message, cohortId, 'lynx', undefined, porterUris); - - expect(sign191Mock).toHaveBeenCalledWith( - expect.any(Uint8Array), - cohortId, - { optimistic: true, returnAggregated: true } - ); - - expect(result).toEqual({ - digest: '0x1234', - aggregatedSignature: '0x90ab0xijkl', - signingResults: { - '0x1234': ['0x5678', '0x90ab'], - '0xabcd': ['0xefgh', '0xijkl'], - }, - type: 'eip191', - }); - }); - - it('should sign a Uint8Array message', async () => { - const messageBytes = new TextEncoder().encode('Hello, TACo!'); - const cohortId = 5; - const porterUris = [fakePorterUri]; - - sign191Mock.mockResolvedValue({ - digest: '0x1234', - aggregatedSignature: '0x90ab0xijkl', - signingResults: { - '0x1234': ['0x5678', '0x90ab'], - '0xabcd': ['0xefgh', '0xijkl'], - }, - type: 'eip191', - }); - - const result = await sign191(messageBytes, cohortId, 'lynx', undefined, porterUris); - - expect(sign191Mock).toHaveBeenCalledWith( - messageBytes, - cohortId, - { optimistic: true, returnAggregated: true } - ); - - expect(result).toEqual({ - digest: '0x1234', - aggregatedSignature: '0x90ab0xijkl', - signingResults: { - '0x1234': ['0x5678', '0x90ab'], - '0xabcd': ['0xefgh', '0xijkl'], - }, - type: 'eip191', - }); - }); - - it('should handle custom signing options', async () => { - const message = 'Hello, TACo!'; - const cohortId = 5; - const porterUris = [fakePorterUri]; - const options = { optimistic: false, returnAggregated: false }; - - sign191Mock.mockResolvedValue({ - digest: '0x1234', - aggregatedSignature: '0x90ab0xijkl', - signingResults: { - '0x1234': ['0x5678', '0x90ab'], - '0xabcd': ['0xefgh', '0xijkl'], - }, - type: 'eip191', - }); - - await sign191(message, cohortId, 'lynx', options, porterUris); - - expect(sign191Mock).toHaveBeenCalledWith( - expect.any(Uint8Array), - cohortId, - options - ); - }); - }); - describe('signUserOp', () => { const userOp = { sender: '0x123', From 914ad08078c9acd79057b9bd9a60266a82f4726d Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 19 Jun 2025 12:02:40 +0200 Subject: [PATCH 050/303] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(shared):?= =?UTF-8?q?=20update=20porter=20and=20signing=20coordinator=20APIs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update PorterClient.signUserOp method to accept signingRequests and threshold parameters - Remove deprecated SignUserOpRequest type and simplify API structure - Uncomment and fix SigningCoordinatorAgent.getThreshold method - Rename ritualId parameter to cohortId for consistency - Remove 'type' field from SignResult interface - Add console.log for options debugging (TODO: implement options usage) --- .../contracts/agents/signingCoordinator.ts | 20 +++++----- packages/shared/src/porter.ts | 37 +++++-------------- 2 files changed, 20 insertions(+), 37 deletions(-) diff --git a/packages/shared/src/contracts/agents/signingCoordinator.ts b/packages/shared/src/contracts/agents/signingCoordinator.ts index 7a51ec64f..89ae7dadb 100644 --- a/packages/shared/src/contracts/agents/signingCoordinator.ts +++ b/packages/shared/src/contracts/agents/signingCoordinator.ts @@ -15,10 +15,10 @@ export class SigningCoordinatorAgent { public static async getParticipants( provider: ethers.providers.Provider, domain: Domain, - ritualId: number, + cohortId: number, ): Promise { const coordinator = await this.connectReadOnly(provider, domain); - const participants = await coordinator.getSigners(ritualId); + const participants = await coordinator.getSigners(cohortId); return participants.map((participant: SigningCoordinator.SigningCohortParticipantStructOutput) => { return { @@ -29,14 +29,14 @@ export class SigningCoordinatorAgent { }); } -// public static async getThreshold( -// provider: ethers.providers.Provider, -// domain: Domain, -// cohortId: number, -// ): Promise { -// const coordinator = await this.connectReadOnly(provider, domain); -// return await coordinator.getThreshold(cohortId); -// } + public static async getThreshold( + provider: ethers.providers.Provider, + domain: Domain, + cohortId: number, + ): Promise { + const coordinator = await this.connectReadOnly(provider, domain); + return await coordinator.getThreshold(cohortId); + } private static async connectReadOnly( provider: ethers.providers.Provider, diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index 09c854092..93bd5398f 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -158,23 +158,11 @@ type SigningOptions = { returnAggregated?: boolean; // Whether to return the aggregated signature }; -type SignUserOpRequest = { - readonly user_op: string; - readonly signature_type: string; - readonly aa_version: string; - readonly cohort_id: number; - readonly chain_id: number; - readonly context?: Record | undefined; - readonly optimistic?: boolean | undefined; - readonly return_aggregated?: boolean | undefined; -}; - type SignResponse = { readonly result: { readonly digest: HexEncodedBytes; readonly signing_results: Record; }; - readonly version: string; }; type SignResult = { @@ -182,7 +170,6 @@ type SignResult = { aggregatedSignature: string; signingResults: { [ursulaAddress: string]: [string, string] }; errors: Record; - type: string; }; function aggregatePorterSignatures( @@ -327,26 +314,23 @@ export class PorterClient { public async signUserOp( - userOp: Record, - chainId: number, - aaVersion: string, - cohortId: number, + signingRequests: Record, + threshold: number, options: SigningOptions = { optimistic: true, returnAggregated: true }, - context: Record = {}, ): Promise { - const data: SignUserOpRequest = { - aa_version: aaVersion, - user_op: JSON.stringify(userOp), - cohort_id: cohortId, - chain_id: chainId, - context, - signature_type: 'userop', + + console.log(options); + //TODO use options + + const params: Record = { + signing_requests: signingRequests, + threshold: threshold }; const resp: AxiosResponse = await this.tryAndCall({ url: '/sign', method: 'post', - data, + params, }); const signingResults: { [ursulaAddress: string]: [string, string] } = {}; @@ -373,7 +357,6 @@ export class PorterClient { aggregatedSignature: aggregatePorterSignatures(signingResults), signingResults, errors, - type: aaVersion }; } } \ No newline at end of file From 91536f755bd803b21cbfc29d86f15df8f2bd813f Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 19 Jun 2025 12:02:56 +0200 Subject: [PATCH 051/303] =?UTF-8?q?=E2=9C=A8=20feat(taco):=20enhance=20sig?= =?UTF-8?q?nUserOp=20with=20signing=20coordinator=20integration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add provider parameter to signUserOp function for blockchain interaction - Integrate SigningCoordinatorAgent to fetch participants and threshold dynamically - Add optional ConditionContext parameter for enhanced signing context - Update aaVersion type to support new signing formats (mdt, 0.8.0) - Build signing requests from user operation and distribute to signers - Implement proper signing workflow with coordinator agent --- packages/taco/src/sign.ts | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 63014fe15..66eddf218 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -1,14 +1,19 @@ import { Domain, getPorterUris, PorterClient } from '@nucypher/shared'; +import { SigningCoordinatorAgent } from '@nucypher/shared'; +import { ethers } from 'ethers'; +import { ConditionContext } from './conditions/context'; import { SigningOptions, SignResult, UserOperation } from './types'; export async function signUserOp( + provider: ethers.providers.Provider, userOp: UserOperation, chainId: number, - aaVersion: "zerodev:v0.6" | "kernel:v0.7" | "safe:v0.8" | "metamask:v0.6" | string, + aaVersion: "mdt" | "0.8.0" | string, cohortId: number, domain: Domain, options: SigningOptions = { optimistic: true, returnAggregated: true }, + context?: ConditionContext, porterUris?: string[] ): Promise { const porterUrisFull: string[] = porterUris @@ -16,11 +21,25 @@ export async function signUserOp( : await getPorterUris(domain); const porter = new PorterClient(porterUrisFull); - const result = await porter.signUserOp( + const signers = await SigningCoordinatorAgent.getParticipants(provider, domain, cohortId); + const threshold = await SigningCoordinatorAgent.getThreshold(provider, domain, cohortId); + + const signingRequest = { userOp, + cohortId, chainId, aaVersion, - cohortId, + context + }; + + const signingRequests: Record = Object.fromEntries( + signers.map((signer) => [signer.operator, JSON.stringify(signingRequest)]), + ); + + // Build signing request for the user operation + const result = await porter.signUserOp( + signingRequests, + threshold, options, ); From cc04ae3e3d4c1ae3524e0ba021874d4658122678 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 19 Jun 2025 12:03:12 +0200 Subject: [PATCH 052/303] =?UTF-8?q?=E2=9C=85=20test(shared):=20update=20po?= =?UTF-8?q?rter=20tests=20for=20new=20API=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update PorterClient.signUserOp test calls to use new signature (signingRequests, threshold, options) - Remove 'type' field expectations from test results to match updated API - Fix test data structure to align with new signing request format - Update mock implementations to handle simplified API parameters - All porter tests now pass with the updated API structure --- packages/shared/test/porter.test.ts | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index 7079d97dc..db40a524d 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -189,10 +189,11 @@ describe('PorterClient Signing', () => { mockSignUserOp(true); const porterClient = new PorterClient(fakePorterUris[2]); const result = await porterClient.signUserOp( - mockPackedUserOp, - 8453, - 'zerodev:v0.6', - 5, + { + '0x1234': JSON.stringify(mockPackedUserOp), + '0xabcd': JSON.stringify(mockPackedUserOp) + }, + 2, { optimistic: true, returnAggregated: true @@ -207,7 +208,6 @@ describe('PorterClient Signing', () => { '0xabcd': ['0xefgh', '0xijkl'], }, errors: {}, - type: 'zerodev:v0.6', }); }); @@ -217,10 +217,11 @@ describe('PorterClient Signing', () => { await expect( porterClient.signUserOp( - mockPackedUserOp, - 8453, - 'zerodev:v0.6', - 5, + { + '0x1234': JSON.stringify(mockPackedUserOp), + '0xabcd': JSON.stringify(mockPackedUserOp) + }, + 2, { optimistic: true, returnAggregated: true @@ -234,10 +235,11 @@ describe('PorterClient Signing', () => { mockSignUserOp(true, true); const porterClient = new PorterClient(fakePorterUris[2]); const result = await porterClient.signUserOp( - mockPackedUserOp, - 8453, - 'zerodev:v0.6', - 5, + { + '0x1234': JSON.stringify(mockPackedUserOp), + '0xabcd': JSON.stringify(mockPackedUserOp) + }, + 2, { optimistic: true, returnAggregated: true @@ -253,7 +255,6 @@ describe('PorterClient Signing', () => { errors: { '0x1234': 'Failed to decode signature: Invalid character', }, - type: 'zerodev:v0.6', }); }); }); From f296aaab0524a5604cbe0133f8f518177bf6dfb2 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 19 Jun 2025 12:03:29 +0200 Subject: [PATCH 053/303] =?UTF-8?q?=E2=9C=85=20test(taco):=20fix=20signing?= =?UTF-8?q?=20tests=20for=20updated=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update signUserOp test calls to include provider parameter as first argument - Add comprehensive mocks for SigningCoordinatorAgent methods (getParticipants, getThreshold) - Fix test expectations to match new porter API that takes signing requests and threshold - Remove 'type' field assertions from test results to align with updated response format - Skip integration test temporarily due to SigningCoordinator contract deployment requirements - All unit tests now pass with the enhanced signing functionality --- packages/taco/integration-test/sign.test.ts | 5 +- packages/taco/test/taco-sign.test.ts | 90 ++++++++++++++++----- 2 files changed, 75 insertions(+), 20 deletions(-) diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index 3d77ffc12..51d53a81a 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -32,7 +32,7 @@ describe('Taco Sign Integration Test', () => { } }); - test('should sign a user operation', async () => { + test.skip('should sign a user operation', async () => { // Create a sample user operation with all required fields const userOp: UserOperation = { sender: signer.address, @@ -57,12 +57,14 @@ describe('Taco Sign Integration Test', () => { // Sign user operation const signResult = await signUserOp( + provider, userOp, CHAIN_ID, 'zerodev:v0.6', RITUAL_ID, DOMAIN as Domain, { optimistic: true, returnAggregated: true }, + undefined, porterUris ); @@ -71,7 +73,6 @@ describe('Taco Sign Integration Test', () => { expect(signResult.digest).toBeDefined(); expect(signResult.aggregatedSignature).toBeDefined(); expect(signResult.signingResults).toBeDefined(); - expect(signResult.type).toBe('zerodev:v0.6'); expect(Object.keys(signResult.signingResults).length).toBeGreaterThan(0); }, 15000); }); \ No newline at end of file diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index 1586cb444..35cb566d2 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -1,15 +1,24 @@ -import { PorterClient } from '@nucypher/shared'; +import { PorterClient, SigningCoordinatorAgent } from '@nucypher/shared'; import { fakePorterUri } from '@nucypher/test-utils'; import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { ethers } from 'ethers'; import { signUserOp } from '../src/sign'; describe('TACo Signing', () => { let signUserOpMock: ReturnType; + let mockProvider: ethers.providers.Provider; beforeEach(() => { signUserOpMock = vi.fn(); + mockProvider = {} as ethers.providers.Provider; + vi.spyOn(PorterClient.prototype, 'signUserOp').mockImplementation(signUserOpMock); + vi.spyOn(SigningCoordinatorAgent, 'getParticipants').mockResolvedValue([ + { operator: '0x1234', provider: '0x5678', signature: '0x90ab' }, + { operator: '0xabcd', provider: '0xefgh', signature: '0xijkl' } + ]); + vi.spyOn(SigningCoordinatorAgent, 'getThreshold').mockResolvedValue(2); }); describe('signUserOp', () => { @@ -44,24 +53,39 @@ describe('TACo Signing', () => { '0x1234': ['0x5678', '0x90ab'], '0xabcd': ['0xefgh', '0xijkl'], }, - type: 'userOp:zerodev', + errors: {}, }); const result = await signUserOp( + mockProvider, userOp, chainId, aaVersion, cohortId, 'lynx', + { optimistic: true, returnAggregated: true }, undefined, porterUris ); expect(signUserOpMock).toHaveBeenCalledWith( - userOp, - chainId, - aaVersion, - cohortId, + { + '0x1234': JSON.stringify({ + userOp, + cohortId, + chainId, + aaVersion, + context: undefined + }), + '0xabcd': JSON.stringify({ + userOp, + cohortId, + chainId, + aaVersion, + context: undefined + }) + }, + 2, { optimistic: true, returnAggregated: true } ); @@ -72,7 +96,7 @@ describe('TACo Signing', () => { '0x1234': ['0x5678', '0x90ab'], '0xabcd': ['0xefgh', '0xijkl'], }, - type: 'userOp:zerodev', + errors: {}, }); }); @@ -89,24 +113,39 @@ describe('TACo Signing', () => { '0x1234': ['0x5678', '0x90ab'], '0xabcd': ['0xefgh', '0xijkl'], }, - type: 'userOp:kernel', + errors: {}, }); const result = await signUserOp( + mockProvider, userOp, chainId, aaVersion, cohortId, 'lynx', + { optimistic: true, returnAggregated: true }, undefined, porterUris ); expect(signUserOpMock).toHaveBeenCalledWith( - userOp, - chainId, - aaVersion, - cohortId, + { + '0x1234': JSON.stringify({ + userOp, + cohortId, + chainId, + aaVersion, + context: undefined + }), + '0xabcd': JSON.stringify({ + userOp, + cohortId, + chainId, + aaVersion, + context: undefined + }) + }, + 2, { optimistic: true, returnAggregated: true } ); @@ -117,7 +156,7 @@ describe('TACo Signing', () => { '0x1234': ['0x5678', '0x90ab'], '0xabcd': ['0xefgh', '0xijkl'], }, - type: 'userOp:kernel', + errors: {}, }); }); @@ -135,24 +174,39 @@ describe('TACo Signing', () => { '0x1234': ['0x5678', '0x90ab'], '0xabcd': ['0xefgh', '0xijkl'], }, - type: 'userOp:safe', + errors: {}, }); await signUserOp( + mockProvider, userOp, chainId, aaVersion, cohortId, 'lynx', options, + undefined, porterUris ); expect(signUserOpMock).toHaveBeenCalledWith( - userOp, - chainId, - aaVersion, - cohortId, + { + '0x1234': JSON.stringify({ + userOp, + cohortId, + chainId, + aaVersion, + context: undefined + }), + '0xabcd': JSON.stringify({ + userOp, + cohortId, + chainId, + aaVersion, + context: undefined + }) + }, + 2, options ); }); From 67f8d49e5b676a49bbf80fc2566620bdaadad1ad Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 19 Jun 2025 12:11:04 +0200 Subject: [PATCH 054/303] =?UTF-8?q?=F0=9F=92=84=20style(taco):=20clean=20u?= =?UTF-8?q?p=20imports=20and=20remove=20deprecated=20type=20field?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Reorder imports in sign.ts and test files for consistency - Remove 'type' field from SignResult type definition to match updated API - Apply prettier formatting to import statements --- packages/taco/src/sign.ts | 2 +- packages/taco/src/types.ts | 1 - packages/taco/test/taco-sign.test.ts | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 66eddf218..e19d0335f 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -1,8 +1,8 @@ import { Domain, getPorterUris, PorterClient } from '@nucypher/shared'; import { SigningCoordinatorAgent } from '@nucypher/shared'; import { ethers } from 'ethers'; -import { ConditionContext } from './conditions/context'; +import { ConditionContext } from './conditions/context'; import { SigningOptions, SignResult, UserOperation } from './types'; export async function signUserOp( diff --git a/packages/taco/src/types.ts b/packages/taco/src/types.ts index 4e12a2299..9cf2fdd0d 100644 --- a/packages/taco/src/types.ts +++ b/packages/taco/src/types.ts @@ -11,7 +11,6 @@ export type SignResult = { signingResults: { // Individual signing results from each participant [ursulaAddress: string]: [signerAddress: string, signatureB64: string] }; - type: string; // Signature type (e.g. "eip712", "userOp:zerodev") }; export type SigningOptions = { diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index 35cb566d2..63276c1a2 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -1,7 +1,7 @@ import { PorterClient, SigningCoordinatorAgent } from '@nucypher/shared'; import { fakePorterUri } from '@nucypher/test-utils'; -import { beforeEach, describe, expect, it, vi } from 'vitest'; import { ethers } from 'ethers'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; import { signUserOp } from '../src/sign'; From d25701fe8cb98217fc60de35ee61fae13b7ecb6e Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 20 Jun 2025 13:16:33 +0200 Subject: [PATCH 055/303] =?UTF-8?q?=F0=9F=90=9B=20fix(shared):=20prevent?= =?UTF-8?q?=20aggregated=20signature=20return=20when=20errors=20occur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - modify SignResult.aggregatedSignature type to allow undefined - only return aggregated signature when no signature decoding errors exist - export SignResult and SigningOptions types to enable sharing across packages - remove debug console.log statement and TODO comment --- packages/shared/src/porter.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index 93bd5398f..d8f408478 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -153,7 +153,7 @@ export type TacoDecryptResult = { }; // Signing types -type SigningOptions = { +export type SigningOptions = { optimistic?: boolean; // Whether to return first signatures received or wait for all signatures returnAggregated?: boolean; // Whether to return the aggregated signature }; @@ -165,9 +165,9 @@ type SignResponse = { }; }; -type SignResult = { +export type SignResult = { digest: string; - aggregatedSignature: string; + aggregatedSignature: string | undefined; signingResults: { [ursulaAddress: string]: [string, string] }; errors: Record; }; @@ -319,9 +319,6 @@ export class PorterClient { options: SigningOptions = { optimistic: true, returnAggregated: true }, ): Promise { - console.log(options); - //TODO use options - const params: Record = { signing_requests: signingRequests, threshold: threshold @@ -352,9 +349,14 @@ export class PorterClient { } } + // Only return aggregated signature if there are no errors + const aggregatedSignature = Object.keys(errors).length === 0 + ? aggregatePorterSignatures(signingResults) + : undefined; + return { digest: messageHash, - aggregatedSignature: aggregatePorterSignatures(signingResults), + aggregatedSignature, signingResults, errors, }; From 77abb413c2d575dd9acb1e0fbffa465d1dadeba2 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 20 Jun 2025 13:16:49 +0200 Subject: [PATCH 056/303] =?UTF-8?q?=E2=9C=85=20test(shared):=20update=20po?= =?UTF-8?q?rter=20test=20to=20expect=20undefined=20aggregated=20signature?= =?UTF-8?q?=20on=20errors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - change test expectation for signature decoding errors to expect undefined aggregatedSignature - remove unused parameters in mock functions for cleaner test setup --- packages/shared/test/porter.test.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index db40a524d..672959cfa 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -51,7 +51,7 @@ const mockGetUrsulas = (ursulas: Ursula[] = fakeUrsulas()): MockInstance => { }); }; -const createMockSignResponse = (type: string, errorCase?: boolean) => ({ +const createMockSignResponse = (errorCase?: boolean) => ({ result: { digest: '0x1234', signing_results: errorCase ? { @@ -71,16 +71,15 @@ const createMockSignResponse = (type: string, errorCase?: boolean) => ({ })))] } }, - version: '5.2.0', }); -const createMockSignImplementation = (endpoint: string, type: string) => (success: boolean = true, errorCase?: boolean): MockInstance => { +const createMockSignImplementation = (endpoint: string) => (success: boolean = true, errorCase?: boolean): MockInstance => { return vi.spyOn(axios, 'request').mockImplementation(async (config) => { if (config.url === endpoint) { if (success) { return Promise.resolve({ status: HttpStatusCode.Ok, - data: createMockSignResponse(type, errorCase), + data: createMockSignResponse(errorCase), }); } return Promise.resolve({ status: HttpStatusCode.BadRequest, data: '' }); @@ -89,7 +88,7 @@ const createMockSignImplementation = (endpoint: string, type: string) => (succes }); }; -const mockSignUserOp = createMockSignImplementation('/sign', 'userOp:zerodev'); +const mockSignUserOp = createMockSignImplementation('/sign'); describe('getPorterUris', () => { beforeAll(async () => { @@ -248,7 +247,7 @@ describe('PorterClient Signing', () => { expect(result).toEqual({ digest: '0x1234', - aggregatedSignature: '0xijkl', // Only valid signature included + aggregatedSignature: undefined, // No aggregated signature when errors occur signingResults: { '0xabcd': ['0xefgh', '0xijkl'], }, From a732f3d959420384fdab8748daf196929685d6a9 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 20 Jun 2025 13:17:02 +0200 Subject: [PATCH 057/303] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(taco):=20?= =?UTF-8?q?remove=20duplicate=20types=20by=20importing=20from=20shared=20p?= =?UTF-8?q?ackage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - remove duplicated SignResult and SigningOptions type definitions - add comment noting types are now imported from @nucypher/shared - improve code formatting and consistency --- packages/taco/src/types.ts | 44 ++++++++++++++------------------------ 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/packages/taco/src/types.ts b/packages/taco/src/types.ts index 9cf2fdd0d..388a3eb1c 100644 --- a/packages/taco/src/types.ts +++ b/packages/taco/src/types.ts @@ -4,34 +4,22 @@ export { Context as CoreContext, } from '@nucypher/nucypher-core'; -// Signing types -export type SignResult = { - digest: string; // Final hash signed by the node - aggregatedSignature: string; // Combined signature from all signers - signingResults: { // Individual signing results from each participant - [ursulaAddress: string]: [signerAddress: string, signatureB64: string] - }; -}; - -export type SigningOptions = { - optimistic?: boolean; // Whether to proceed with signing even if some nodes are unavailable - returnAggregated?: boolean; // Whether to return the aggregated signature -}; +// Note: SignResult and SigningOptions are now imported from @nucypher/shared to avoid duplication export type UserOperation = { - sender: string; // The Account making the UserOperation - nonce: string; // Anti-replay parameter - factory: string; // Account Factory for new Accounts OR 0x7702 flag for EIP-7702 Accounts, otherwise address(0) - factoryData: string; // data for the Account Factory if factory is provided OR EIP-7702 initialization data, or empty array - callData: string; // The data to pass to the sender during the main execution call - callGasLimit: string; // The amount of gas to allocate the main execution call - verificationGasLimit: string; // The amount of gas to allocate for the verification step - preVerificationGas: string; // Extra gas to pay the bundler - maxFeePerGas: string; // Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) - maxPriorityFeePerGas: string; // Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) - paymaster: string; // Address of paymaster contract, (or empty, if the sender pays for gas by itself) - paymasterVerificationGasLimit: string; // The amount of gas to allocate for the paymaster validation code (only if paymaster exists) - paymasterPostOpGasLimit: string; // The amount of gas to allocate for the paymaster post-operation code (only if paymaster exists) - paymasterData: string; // Data for paymaster (only if paymaster exists) - signature: string; // Data passed into the sender to verify authorization + sender: string; // The Account making the UserOperation + nonce: string; // Anti-replay parameter + factory: string; // Account Factory for new Accounts OR 0x7702 flag for EIP-7702 Accounts, otherwise address(0) + factoryData: string; // data for the Account Factory if factory is provided OR EIP-7702 initialization data, or empty array + callData: string; // The data to pass to the sender during the main execution call + callGasLimit: string; // The amount of gas to allocate the main execution call + verificationGasLimit: string; // The amount of gas to allocate for the verification step + preVerificationGas: string; // Extra gas to pay the bundler + maxFeePerGas: string; // Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) + maxPriorityFeePerGas: string; // Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) + paymaster: string; // Address of paymaster contract, (or empty, if the sender pays for gas by itself) + paymasterVerificationGasLimit: string; // The amount of gas to allocate for the paymaster validation code (only if paymaster exists) + paymasterPostOpGasLimit: string; // The amount of gas to allocate for the paymaster post-operation code (only if paymaster exists) + paymasterData: string; // Data for paymaster (only if paymaster exists) + signature: string; // Data passed into the sender to verify authorization }; From 8bf65c6741554192115fa3c1f8a637287d218053 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 20 Jun 2025 13:17:14 +0200 Subject: [PATCH 058/303] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(taco):=20?= =?UTF-8?q?import=20shared=20types=20and=20improve=20code=20formatting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - import SignResult and SigningOptions from @nucypher/shared instead of local types - consolidate multiple imports from shared package into single import statement - improve code formatting and add missing trailing comma --- packages/taco/src/sign.ts | 40 ++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index e19d0335f..11edac3ed 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -1,47 +1,57 @@ -import { Domain, getPorterUris, PorterClient } from '@nucypher/shared'; -import { SigningCoordinatorAgent } from '@nucypher/shared'; +import { + Domain, + getPorterUris, + PorterClient, + SigningCoordinatorAgent, + SigningOptions, + SignResult, +} from '@nucypher/shared'; import { ethers } from 'ethers'; import { ConditionContext } from './conditions/context'; -import { SigningOptions, SignResult, UserOperation } from './types'; +import { UserOperation } from './types'; export async function signUserOp( provider: ethers.providers.Provider, userOp: UserOperation, chainId: number, - aaVersion: "mdt" | "0.8.0" | string, + aaVersion: 'mdt' | '0.8.0' | string, cohortId: number, domain: Domain, options: SigningOptions = { optimistic: true, returnAggregated: true }, context?: ConditionContext, - porterUris?: string[] + porterUris?: string[], ): Promise { const porterUrisFull: string[] = porterUris ? porterUris : await getPorterUris(domain); const porter = new PorterClient(porterUrisFull); - const signers = await SigningCoordinatorAgent.getParticipants(provider, domain, cohortId); - const threshold = await SigningCoordinatorAgent.getThreshold(provider, domain, cohortId); + const signers = await SigningCoordinatorAgent.getParticipants( + provider, + domain, + cohortId, + ); + const threshold = await SigningCoordinatorAgent.getThreshold( + provider, + domain, + cohortId, + ); const signingRequest = { userOp, cohortId, chainId, aaVersion, - context + context, }; - + const signingRequests: Record = Object.fromEntries( signers.map((signer) => [signer.operator, JSON.stringify(signingRequest)]), ); // Build signing request for the user operation - const result = await porter.signUserOp( - signingRequests, - threshold, - options, - ); + const result = await porter.signUserOp(signingRequests, threshold, options); return result; -} \ No newline at end of file +} From b4e09ab0f577ed0a37bfad218662c24aabe793b7 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 20 Jun 2025 13:17:30 +0200 Subject: [PATCH 059/303] =?UTF-8?q?=E2=9C=85=20test(taco):=20consolidate?= =?UTF-8?q?=20and=20update=20signing=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - remove duplicate test case for different account types - standardize on EIP-4337 0.8.0 account abstraction version - streamline test descriptions for clarity --- packages/taco/test/taco-sign.test.ts | 66 ++-------------------------- 1 file changed, 3 insertions(+), 63 deletions(-) diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index 63276c1a2..b59af3437 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -40,69 +40,9 @@ describe('TACo Signing', () => { signature: '0x', }; - it('should sign a user operation with zerodev account', async () => { + it('should sign a user operation with a 0.8.0 account', async () => { const chainId = 1; - const aaVersion = 'zerodev:v0.6'; - const cohortId = 5; - const porterUris = [fakePorterUri]; - - signUserOpMock.mockResolvedValue({ - digest: '0x1234', - aggregatedSignature: '0x90ab0xijkl', - signingResults: { - '0x1234': ['0x5678', '0x90ab'], - '0xabcd': ['0xefgh', '0xijkl'], - }, - errors: {}, - }); - - const result = await signUserOp( - mockProvider, - userOp, - chainId, - aaVersion, - cohortId, - 'lynx', - { optimistic: true, returnAggregated: true }, - undefined, - porterUris - ); - - expect(signUserOpMock).toHaveBeenCalledWith( - { - '0x1234': JSON.stringify({ - userOp, - cohortId, - chainId, - aaVersion, - context: undefined - }), - '0xabcd': JSON.stringify({ - userOp, - cohortId, - chainId, - aaVersion, - context: undefined - }) - }, - 2, - { optimistic: true, returnAggregated: true } - ); - - expect(result).toEqual({ - digest: '0x1234', - aggregatedSignature: '0x90ab0xijkl', - signingResults: { - '0x1234': ['0x5678', '0x90ab'], - '0xabcd': ['0xefgh', '0xijkl'], - }, - errors: {}, - }); - }); - - it('should sign a user operation with kernel account', async () => { - const chainId = 1; - const aaVersion = 'kernel:v0.7'; + const aaVersion = '0.8.0'; const cohortId = 5; const porterUris = [fakePorterUri]; @@ -162,7 +102,7 @@ describe('TACo Signing', () => { it('should handle custom signing options', async () => { const chainId = 1; - const aaVersion = 'safe:v0.8'; + const aaVersion = '0.8.0'; const cohortId = 5; const porterUris = [fakePorterUri]; const options = { optimistic: false, returnAggregated: false }; From e57597a3bd8c16c019098fc7683611dd46e184f2 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 20 Jun 2025 13:17:44 +0200 Subject: [PATCH 060/303] =?UTF-8?q?=F0=9F=94=A7=20chore(taco):=20update=20?= =?UTF-8?q?integration=20test=20configuration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - change domain from lynx to TESTNET for consistency - update ritual ID and chain ID for correct test environment - standardize on EIP-4337 0.8.0 account abstraction version - conditionally skip integration tests when not in CI environment --- packages/taco/integration-test/sign.test.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index 51d53a81a..a70b282ec 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -8,11 +8,11 @@ import { UserOperation } from '../src/types'; const RPC_PROVIDER_URL = 'https://rpc-amoy.polygon.technology'; const SIGNER_PRIVATE_KEY = '0x900edb9e8214b2353f82aa195e915128f419a92cfb8bbc0f4784f10ef4112b86'; -const DOMAIN = 'lynx'; -const RITUAL_ID = 27; -const CHAIN_ID = 80002; +const DOMAIN = 'TESTNET'; +const RITUAL_ID = 2; +const CHAIN_ID = 11155111; -describe('Taco Sign Integration Test', () => { +describe.skipIf(!process.env.RUNNING_IN_CI)('Taco Sign Integration Test', () => { let provider: ethers.providers.JsonRpcProvider; let signer: ethers.Wallet; @@ -32,7 +32,7 @@ describe('Taco Sign Integration Test', () => { } }); - test.skip('should sign a user operation', async () => { + test('should sign a user operation', async () => { // Create a sample user operation with all required fields const userOp: UserOperation = { sender: signer.address, @@ -60,7 +60,7 @@ describe('Taco Sign Integration Test', () => { provider, userOp, CHAIN_ID, - 'zerodev:v0.6', + '0.8.0', RITUAL_ID, DOMAIN as Domain, { optimistic: true, returnAggregated: true }, From 1f7b76b3f2169dd54f34e5305de5581952ead2ec Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 20 Jun 2025 14:00:19 +0200 Subject: [PATCH 061/303] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(taco):=20?= =?UTF-8?q?reorder=20signUserOp=20parameters=20and=20update=20porter=20opt?= =?UTF-8?q?ions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - reorder signUserOp function parameters for better logical grouping - move domain and cohortId before chainId and userOp - update parameter order: (provider, domain, cohortId, chainId, userOp, aaVersion, options, context, porterUris) - fix test calls to match new parameter order in unit tests and integration tests - add console.log for debugging porter signUserOp options usage --- packages/shared/src/porter.ts | 2 ++ packages/taco/integration-test/sign.test.ts | 6 +++--- packages/taco/src/sign.ts | 6 +++--- packages/taco/test/taco-sign.test.ts | 12 ++++++------ 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index d8f408478..1a85d2da6 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -319,6 +319,8 @@ export class PorterClient { options: SigningOptions = { optimistic: true, returnAggregated: true }, ): Promise { + console.log({ options}) + const params: Record = { signing_requests: signingRequests, threshold: threshold diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index a70b282ec..9ffb84662 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -58,11 +58,11 @@ describe.skipIf(!process.env.RUNNING_IN_CI)('Taco Sign Integration Test', () => // Sign user operation const signResult = await signUserOp( provider, - userOp, + DOMAIN as Domain, + RITUAL_ID, CHAIN_ID, + userOp, '0.8.0', - RITUAL_ID, - DOMAIN as Domain, { optimistic: true, returnAggregated: true }, undefined, porterUris diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 11edac3ed..1789ff977 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -13,11 +13,11 @@ import { UserOperation } from './types'; export async function signUserOp( provider: ethers.providers.Provider, - userOp: UserOperation, + domain: Domain, + cohortId: number, chainId: number, + userOp: UserOperation, aaVersion: 'mdt' | '0.8.0' | string, - cohortId: number, - domain: Domain, options: SigningOptions = { optimistic: true, returnAggregated: true }, context?: ConditionContext, porterUris?: string[], diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index b59af3437..91d18a7a8 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -58,11 +58,11 @@ describe('TACo Signing', () => { const result = await signUserOp( mockProvider, - userOp, + 'lynx', + cohortId, chainId, + userOp, aaVersion, - cohortId, - 'lynx', { optimistic: true, returnAggregated: true }, undefined, porterUris @@ -119,11 +119,11 @@ describe('TACo Signing', () => { await signUserOp( mockProvider, - userOp, + 'lynx', + cohortId, chainId, + userOp, aaVersion, - cohortId, - 'lynx', options, undefined, porterUris From 47f0c86bca9d563339bc84de455d2d5f65111317 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 20 Jun 2025 14:06:23 +0200 Subject: [PATCH 062/303] Fix RPC provider url in integration test, amoy -> sepolia --- packages/taco/integration-test/sign.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index 9ffb84662..7cf4438f8 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -6,9 +6,9 @@ import { initialize } from '../src'; import { signUserOp } from '../src/sign'; import { UserOperation } from '../src/types'; -const RPC_PROVIDER_URL = 'https://rpc-amoy.polygon.technology'; +const RPC_PROVIDER_URL = 'https://ethereum-sepolia-rpc.publicnode.com'; const SIGNER_PRIVATE_KEY = '0x900edb9e8214b2353f82aa195e915128f419a92cfb8bbc0f4784f10ef4112b86'; -const DOMAIN = 'TESTNET'; +const DOMAIN = 'lynx'; const RITUAL_ID = 2; const CHAIN_ID = 11155111; From 782df9f3f14fff1d07743f3dc70fdabce9f66628 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 20 Jun 2025 14:58:28 +0200 Subject: [PATCH 063/303] Update nucypher-contracts dependency to point at github --- packages/shared/package.json | 2 +- pnpm-lock.yaml | 8210 ++++++++++++++++++---------------- 2 files changed, 4409 insertions(+), 3803 deletions(-) diff --git a/packages/shared/package.json b/packages/shared/package.json index 79d0d3ea1..09d1e5686 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -42,7 +42,7 @@ "dependencies": { "@ethersproject/abi": "^5.8.0", "@ethersproject/providers": "^5.8.0", - "@nucypher/nucypher-contracts": "^0.25.0", + "@nucypher/nucypher-contracts": "git+https://github.com/nucypher/nucypher-contracts.git#signing", "@nucypher/nucypher-core": "^0.14.5", "axios": "^1.11.0", "deep-equal": "^2.2.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 558fd750b..08bb44467 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,13 +17,13 @@ importers: dependencies: '@changesets/cli': specifier: ^2.28.1 - version: 2.28.1 + version: 2.30.0(@types/node@24.3.0) '@nucypher/nucypher-core': specifier: ^0.14.5 version: 0.14.5 ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) devDependencies: '@skypack/package-check': specifier: ^0.2.2 @@ -33,31 +33,31 @@ importers: version: 24.3.0 '@typescript-eslint/eslint-plugin': specifier: ^6.21.0 - version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2) + version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) '@typescript-eslint/parser': specifier: ^6.21.0 - version: 6.21.0(eslint@8.57.1)(typescript@5.8.2) + version: 6.21.0(eslint@8.57.1)(typescript@5.9.3) '@vitest/coverage-v8': specifier: ^3.2.4 - version: 3.2.4(vitest@3.0.9(@types/node@24.3.0)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0)) + version: 3.2.4(vitest@3.2.4(@types/node@24.3.0)(jiti@2.6.1)(jsdom@16.7.0(bufferutil@4.1.0))(terser@5.46.1)) bundlemon: specifier: ^3.1.0 - version: 3.1.0(typescript@5.8.2) + version: 3.1.0(typescript@5.9.3) eslint: specifier: ^8.57.1 version: 8.57.1 eslint-config-prettier: specifier: ^9.1.0 - version: 9.1.0(eslint@8.57.1) + version: 9.1.2(eslint@8.57.1) eslint-config-typestrict: specifier: ^1.0.5 - version: 1.0.5(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint-plugin-sonarjs@0.23.0(eslint@8.57.1)) + version: 1.0.5(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3))(eslint-plugin-sonarjs@4.0.2(eslint@8.57.1)) eslint-plugin-eslint-comments: specifier: ^3.2.0 version: 3.2.0(eslint@8.57.1) eslint-plugin-import: specifier: ^2.31.0 - version: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1) + version: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) eslint-plugin-no-only-tests: specifier: ^3.3.0 version: 3.3.0 @@ -66,7 +66,7 @@ importers: version: 10.0.0(eslint@8.57.1) eslint-plugin-unused-imports: specifier: ^4.1.4 - version: 4.2.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1) + version: 4.4.1(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) gh-pages: specifier: ^6.3.0 version: 6.3.0 @@ -75,67 +75,67 @@ importers: version: 4.1.5 prettier: specifier: ^3.5.3 - version: 3.5.3 + version: 3.8.2 prettier-plugin-organize-imports: specifier: ^3.2.4 - version: 3.2.4(prettier@3.5.3)(typescript@5.8.2) + version: 3.2.4(prettier@3.8.2)(typescript@5.9.3) sort-package-json: specifier: ^2.15.1 version: 2.15.1 ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@24.3.0)(typescript@5.8.2) + version: 10.9.2(@types/node@24.3.0)(typescript@5.9.3) ts-unused-exports: specifier: ^10.1.0 - version: 10.1.0(typescript@5.8.2) + version: 10.1.0(typescript@5.9.3) typedoc: specifier: ^0.25.13 - version: 0.25.13(typescript@5.8.2) + version: 0.25.13(typescript@5.9.3) typedoc-plugin-coverage: specifier: ^2.2.0 - version: 2.2.0(typedoc@0.25.13(typescript@5.8.2)) + version: 2.2.0(typedoc@0.25.13(typescript@5.9.3)) typedoc-plugin-missing-exports: specifier: ^2.3.0 - version: 2.3.0(typedoc@0.25.13(typescript@5.8.2)) + version: 2.3.0(typedoc@0.25.13(typescript@5.9.3)) typedoc-plugin-zod: specifier: ^1.4.0 - version: 1.4.0(typedoc@0.25.13(typescript@5.8.2)) + version: 1.4.3(typedoc@0.25.13(typescript@5.9.3)) typescript: specifier: ^5.8.2 - version: 5.8.2 + version: 5.9.3 vitest: specifier: ^3.0.9 - version: 3.0.9(@types/node@24.3.0)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0) + version: 3.2.4(@types/node@24.3.0)(jiti@2.6.1)(jsdom@16.7.0(bufferutil@4.1.0))(terser@5.46.1) demos/taco-demo: dependencies: '@irys/sdk': specifier: ^0.1.24 - version: 0.1.24(arweave@1.15.0)(bufferutil@4.0.9)(got@11.8.6)(utf-8-validate@5.0.10) + version: 0.1.24(@types/node@24.3.0)(arweave@1.15.7)(bufferutil@4.1.0)(got@11.8.6)(typescript@4.9.5)(utf-8-validate@6.0.6) '@nucypher/taco': specifier: ^0.6.0 - version: 0.6.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 0.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@nucypher/taco-auth': specifier: ^0.3.0 - version: 0.3.0(bufferutil@4.0.9)(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + version: 0.3.0(bufferutil@4.1.0)(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(utf-8-validate@6.0.6) '@usedapp/core': specifier: ^1.2.16 - version: 1.2.16(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(node-fetch@2.7.0)(react@18.3.1) + version: 1.2.16(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(node-fetch@2.7.0)(react@18.3.1) buffer: specifier: ^6.0.3 version: 6.0.3 ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) file-loader: specifier: ^6.2.0 - version: 6.2.0(webpack@5.101.3(webpack-cli@6.0.1)) + version: 6.2.0(webpack@5.106.1) react: specifier: ^18.3.1 version: 18.3.1 react-copy-to-clipboard: specifier: ^5.1.0 - version: 5.1.0(react@18.3.1) + version: 5.1.1(react@18.3.1) react-dom: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) @@ -145,28 +145,28 @@ importers: devDependencies: '@pmmmwh/react-refresh-webpack-plugin': specifier: ^0.6.0 - version: 0.6.1(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3))(webpack@5.101.3(webpack-cli@6.0.1)) + version: 0.6.2(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.3)(webpack@5.106.1) '@types/react': specifier: ^18.3.20 - version: 18.3.20 + version: 18.3.28 '@types/react-copy-to-clipboard': specifier: ^5.0.7 version: 5.0.7 '@types/react-dom': specifier: ^18.3.5 - version: 18.3.5(@types/react@18.3.20) + version: 18.3.7(@types/react@18.3.28) copy-webpack-plugin: specifier: ^13.0.0 - version: 13.0.1(webpack@5.101.3(webpack-cli@6.0.1)) + version: 13.0.1(webpack@5.106.1) crypto-browserify: specifier: ^3.12.1 version: 3.12.1 esbuild-loader: specifier: ^2.21.0 - version: 2.21.0(webpack@5.101.3(webpack-cli@6.0.1)) + version: 2.21.0(webpack@5.106.1) html-webpack-plugin: specifier: ^5.6.3 - version: 5.6.3(webpack@5.101.3(webpack-cli@6.0.1)) + version: 5.6.6(webpack@5.106.1) process: specifier: ^0.11.10 version: 0.11.10 @@ -187,40 +187,40 @@ importers: version: 1.1.2 webpack: specifier: ^5.99.9 - version: 5.101.3(webpack-cli@6.0.1) + version: 5.106.1(webpack-cli@6.0.1) webpack-cli: specifier: ^6.0.1 - version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3) + version: 6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1) webpack-dev-server: specifier: ^5.2.2 - version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3) + version: 5.2.3(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack-cli@6.0.1)(webpack@5.106.1) demos/taco-nft-demo: dependencies: '@nucypher/taco': specifier: ^0.6.0 - version: 0.6.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 0.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@nucypher/taco-auth': specifier: ^0.3.0 - version: 0.3.0(bufferutil@4.0.9)(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + version: 0.3.0(bufferutil@4.1.0)(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(utf-8-validate@6.0.6) '@usedapp/core': specifier: ^1.2.16 - version: 1.2.16(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(node-fetch@2.7.0)(react@18.3.1) + version: 1.2.16(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(node-fetch@2.7.0)(react@18.3.1) buffer: specifier: ^6.0.3 version: 6.0.3 ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) file-loader: specifier: ^6.2.0 - version: 6.2.0(webpack@5.101.3(webpack-cli@6.0.1)) + version: 6.2.0(webpack@5.106.1) react: specifier: ^18.3.1 version: 18.3.1 react-copy-to-clipboard: specifier: ^5.1.0 - version: 5.1.0(react@18.3.1) + version: 5.1.1(react@18.3.1) react-dom: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) @@ -230,25 +230,25 @@ importers: devDependencies: '@pmmmwh/react-refresh-webpack-plugin': specifier: ^0.6.0 - version: 0.6.1(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3))(webpack@5.101.3(webpack-cli@6.0.1)) + version: 0.6.2(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.3)(webpack@5.106.1) '@types/react': specifier: ^18.3.20 - version: 18.3.20 + version: 18.3.28 '@types/react-copy-to-clipboard': specifier: ^5.0.7 version: 5.0.7 '@types/react-dom': specifier: ^18.3.5 - version: 18.3.5(@types/react@18.3.20) + version: 18.3.7(@types/react@18.3.28) copy-webpack-plugin: specifier: ^13.0.0 - version: 13.0.1(webpack@5.101.3(webpack-cli@6.0.1)) + version: 13.0.1(webpack@5.106.1) esbuild-loader: specifier: ^2.21.0 - version: 2.21.0(webpack@5.101.3(webpack-cli@6.0.1)) + version: 2.21.0(webpack@5.106.1) html-webpack-plugin: specifier: ^5.6.3 - version: 5.6.3(webpack@5.101.3(webpack-cli@6.0.1)) + version: 5.6.6(webpack@5.106.1) react-refresh: specifier: ^0.17.0 version: 0.17.0 @@ -263,13 +263,13 @@ importers: version: 4.9.5 webpack: specifier: ^5.99.9 - version: 5.101.3(webpack-cli@6.0.1) + version: 5.106.1(webpack-cli@6.0.1) webpack-cli: specifier: ^6.0.1 - version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3) + version: 6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1) webpack-dev-server: specifier: ^5.2.2 - version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3) + version: 5.2.3(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack-cli@6.0.1)(webpack@5.106.1) examples/pre/nextjs: dependencies: @@ -290,10 +290,10 @@ importers: version: 8.57.0 eslint-config-next: specifier: 14.0.4 - version: 14.0.4(eslint@8.57.0)(typescript@5.8.2) + version: 14.0.4(eslint@8.57.0)(typescript@5.9.3) ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) next: specifier: 15.3.4 version: 15.3.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -311,10 +311,10 @@ importers: version: link:../../../packages/pre dotenv: specifier: ^16.4.7 - version: 16.4.7 + version: 16.6.1 ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) examples/pre/react: dependencies: @@ -323,7 +323,7 @@ importers: version: link:../../../packages/pre ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) react: specifier: ^18.3.1 version: 18.3.1 @@ -336,13 +336,13 @@ importers: version: 24.3.0 '@types/react': specifier: ^18.3.20 - version: 18.3.20 + version: 18.3.28 '@types/react-dom': specifier: ^18.3.5 - version: 18.3.5(@types/react@18.3.20) + version: 18.3.7(@types/react@18.3.28) react-scripts: specifier: ^5.0.1 - version: 5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(@types/babel__core@7.20.5)(bufferutil@4.0.9)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(type-fest@0.21.3)(typescript@5.8.2)(utf-8-validate@5.0.10) + version: 5.0.1(@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0))(@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0))(@types/babel__core@7.20.5)(bufferutil@4.1.0)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3))(type-fest@0.21.3)(typescript@5.9.3) examples/pre/webpack-5: dependencies: @@ -352,22 +352,22 @@ importers: devDependencies: copy-webpack-plugin: specifier: ^13.0.0 - version: 13.0.1(webpack@5.101.3(webpack-cli@6.0.1)) + version: 13.0.1(webpack@5.106.1) esbuild-loader: specifier: ^2.21.0 - version: 2.21.0(webpack@5.101.3(webpack-cli@6.0.1)) + version: 2.21.0(webpack@5.106.1) ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) webpack: specifier: ^5.99.9 - version: 5.101.3(webpack-cli@6.0.1) + version: 5.106.1(webpack-cli@6.0.1) webpack-cli: specifier: ^6.0.1 - version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3) + version: 6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1) webpack-dev-server: specifier: ^5.2.2 - version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3) + version: 5.2.3(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack-cli@6.0.1)(webpack@5.106.1) examples/taco/nextjs: dependencies: @@ -397,7 +397,7 @@ importers: version: 14.0.4(eslint@8.57.0)(typescript@5.2.2) ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) next: specifier: 15.3.4 version: 15.3.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -424,7 +424,7 @@ importers: version: 16.6.1 ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) examples/taco/react: dependencies: @@ -439,7 +439,7 @@ importers: version: link:../../../packages/taco-auth ethers: specifier: ^5.7.2 - version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) react: specifier: ^18.3.1 version: 18.3.1 @@ -452,13 +452,13 @@ importers: version: 24.3.0 '@types/react': specifier: ^18.3.20 - version: 18.3.20 + version: 18.3.28 '@types/react-dom': specifier: ^18.3.5 - version: 18.3.5(@types/react@18.3.20) + version: 18.3.7(@types/react@18.3.28) react-scripts: specifier: ^5.0.1 - version: 5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(@types/babel__core@7.20.5)(bufferutil@4.0.9)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(type-fest@0.21.3)(typescript@5.8.2)(utf-8-validate@5.0.10) + version: 5.0.1(@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0))(@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0))(@types/babel__core@7.20.5)(bufferutil@4.1.0)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3))(type-fest@0.21.3)(typescript@5.9.3) examples/taco/webpack-5: dependencies: @@ -470,23 +470,23 @@ importers: version: link:../../../packages/taco-auth ethers: specifier: ^5.7.2 - version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) devDependencies: copy-webpack-plugin: specifier: ^13.0.0 - version: 13.0.1(webpack@5.101.3(webpack-cli@6.0.1)) + version: 13.0.1(webpack@5.106.1) esbuild-loader: specifier: ^2.21.0 - version: 2.21.0(webpack@5.101.3(webpack-cli@6.0.1)) + version: 2.21.0(webpack@5.106.1) webpack: specifier: ^5.99.9 - version: 5.101.3(webpack-cli@6.0.1) + version: 5.106.1(webpack-cli@6.0.1) webpack-cli: specifier: ^6.0.1 - version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3) + version: 6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1) webpack-dev-server: specifier: ^5.2.2 - version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3) + version: 5.2.3(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack-cli@6.0.1)(webpack@5.106.1) packages/pre: dependencies: @@ -498,7 +498,7 @@ importers: version: link:../shared ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) devDependencies: '@nucypher/test-utils': specifier: workspace:* @@ -511,53 +511,55 @@ importers: version: 5.8.0 '@ethersproject/providers': specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@nucypher/nucypher-contracts': - specifier: ^0.25.0 - version: 0.25.0 + specifier: git+https://github.com/nucypher/nucypher-contracts.git#signing + version: https://codeload.github.com/nucypher/nucypher-contracts/tar.gz/7a7bf2207436688d5835d54bdf71f51ce527907f '@nucypher/nucypher-core': specifier: ^0.14.5 version: 0.14.5 axios: specifier: ^1.11.0 - version: 1.11.0 + version: 1.15.0 deep-equal: specifier: ^2.2.3 version: 2.2.3 ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) qs: specifier: ^6.14.0 - version: 6.14.0 + version: 6.15.1 zod: specifier: ^3.24.2 - version: 3.24.2 + version: 3.25.76 devDependencies: '@nucypher/test-utils': specifier: workspace:* version: link:../test-utils '@typechain/ethers-v5': specifier: ^11.1.2 - version: 11.1.2(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.8.2))(typescript@5.8.2) + version: 11.1.2(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(typechain@8.3.2(typescript@5.9.3))(typescript@5.9.3) '@types/deep-equal': specifier: ^1.0.4 version: 1.0.4 '@types/qs': specifier: ^6.9.18 - version: 6.9.18 + version: 6.15.0 '@types/tmp': specifier: ^0.2.6 version: 0.2.6 cz-conventional-changelog: specifier: ^3.3.0 - version: 3.3.0(@types/node@24.3.0)(typescript@5.8.2) + version: 3.3.0(@types/node@24.3.0)(typescript@5.9.3) standard-version: specifier: ^9.5.0 version: 9.5.0 typechain: specifier: ^8.3.2 - version: 8.3.2(typescript@5.8.2) + version: 8.3.2(typescript@5.9.3) + + packages/shared/dist/es: {} packages/taco: dependencies: @@ -575,29 +577,29 @@ importers: version: link:../taco-auth ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) semver: specifier: ^7.7.1 - version: 7.7.1 + version: 7.7.4 zod: specifier: ^3.24.2 - version: 3.24.2 + version: 3.25.76 devDependencies: '@nucypher/test-utils': specifier: workspace:* version: link:../test-utils '@types/semver': specifier: ^7.7.0 - version: 7.7.0 + version: 7.7.1 dotenv: specifier: ^16.5.0 version: 16.6.1 glob: specifier: ^11.0.1 - version: 11.0.1 + version: 11.1.0 modified-zod2md: specifier: 0.1.5-modified.4 - version: 0.1.5-modified.4(zod@3.24.2) + version: 0.1.5-modified.4(zod@3.25.76) packages/taco-auth: dependencies: @@ -609,15 +611,19 @@ importers: version: link:../shared siwe: specifier: ^3.0.0 - version: 3.0.0(ethers@5.8.0) + version: 3.0.0(ethers@5.8.0(bufferutil@4.1.0)) zod: specifier: ^3.24.2 - version: 3.24.2 + version: 3.25.76 devDependencies: '@nucypher/test-utils': specifier: workspace:* version: link:../test-utils + packages/taco-auth/dist/es: {} + + packages/taco/dist/es: {} + packages/test-utils: dependencies: '@nucypher/nucypher-core': @@ -631,13 +637,13 @@ importers: version: link:../taco-auth axios: specifier: ^1.11.0 - version: 1.11.0 + version: 1.15.0 ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) vitest: specifier: ^3.0.9 - version: 3.0.9(@types/node@24.3.0)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0) + version: 3.2.4(@types/node@24.3.0)(jiti@2.6.1)(jsdom@16.7.0(bufferutil@4.1.0))(terser@5.46.1) packages: @@ -649,173 +655,179 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@apideck/better-ajv-errors@0.3.6': - resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==} + '@apideck/better-ajv-errors@0.3.7': + resolution: {integrity: sha512-TajUJwGWbDwkCx/CZi7tRE8PVB7simCvKJfHUsSdvps+aTM/PDPP4gkLmKnc+x3CE//y9i/nj74GqdL/hwk7Iw==} engines: {node: '>=10'} peerDependencies: ajv: '>=8' - '@aptos-labs/aptos-cli@1.0.2': - resolution: {integrity: sha512-PYPsd0Kk3ynkxNfe3S4fanI3DiUICCoh4ibQderbvjPFL5A0oK6F4lPEO2t0MDsQySTk2t4vh99Xjy6Bd9y+aQ==} + '@aptos-labs/aptos-cli@1.1.1': + resolution: {integrity: sha512-sB7CokCM6s76SLJmccysbnFR+MDik6udKfj2+9ZsmTLV0/t73veIeCDKbvWJmbW267ibx4HiGbPI7L+1+yjEbQ==} hasBin: true - '@aptos-labs/aptos-client@1.1.0': - resolution: {integrity: sha512-rkGVjQufVONAwnMcjIbdPRmJnAoqBFxd8IXVUBJIVlDXkPgjW+Vj0P3z31CxDFE4mVBN6Wpu30BeBzCW/+IDPQ==} + '@aptos-labs/aptos-client@1.2.0': + resolution: {integrity: sha512-pBlIAT/W+Qa0TOr/318U8r0Gxw/jfyRLcvDGMEXgcVrPqO9Qhwsmozw6LPPIZ963FB7smwIaMeexWFDs3zijcg==} engines: {node: '>=15.10.0'} + deprecated: This version is deprecated. Please upgrade to version 2.1.0 or later. peerDependencies: - axios: ^1.8.0 + axios: ^1.8.4 got: ^11.8.6 - '@aptos-labs/aptos-dynamic-transaction-composer@0.1.3': - resolution: {integrity: sha512-bJl+Zq5QbhpcPIJakAkl9tnT3T02mxCYhZThQDhUmjsOZ5wMRlKJ0P7aaq1dmlybSHkVj7vRgOy2t86/NDKKng==} + '@aptos-labs/aptos-dynamic-transaction-composer@0.1.6': + resolution: {integrity: sha512-reIq7g/J02nRT6XILCX51zA9n7n0lwxZQB56fVaE2D3WB5Lt6qgw71ITlt2mvng/x/r8gY7bYyyUhKAx4hMuBw==} '@aptos-labs/script-composer-pack@0.0.9': resolution: {integrity: sha512-Y3kA1rgF65HETgoTn2omDymsgO+fnZouPLrKJZ9sbxTGdOekIIHtGee3A2gk84eCqa02ZKBumZmP+IDCXRtU/g==} - '@aptos-labs/ts-sdk@1.37.1': - resolution: {integrity: sha512-l3kmbADrUPNEdnzt6Q4ehYJjky2jiSSRfpPtprctZSvAR/vXfKore1X07FQcx/LCZV9dIccw39zSgh9HBLUaIg==} + '@aptos-labs/ts-sdk@1.39.0': + resolution: {integrity: sha512-VFEWZsqb8Mto8XbLK8lDRdUvyHjp+geiwFxRzRcQK6HftMGB4bYuEsOI2Vy6u/TqkUft8DvmpV5yX027R5/SMQ==} engines: {node: '>=20.0.0'} + deprecated: This version is deprecated, please upgrade to 5.2.1, or the latest version '@astronautlabs/jsonpath@1.1.2': resolution: {integrity: sha512-FqL/muoreH7iltYC1EB5Tvox5E8NSOOPGkgns4G+qxRKl6k5dxEVljUjB5NcKESzkqwnUqWjSZkL61XGYOuV+A==} - '@babel/code-frame@7.26.2': - resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.26.8': - resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} engines: {node: '>=6.9.0'} - '@babel/core@7.26.10': - resolution: {integrity: sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==} + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} engines: {node: '>=6.9.0'} - '@babel/eslint-parser@7.27.0': - resolution: {integrity: sha512-dtnzmSjXfgL/HDgMcmsLSzyGbEosi4DrGWoCNfuI+W4IkVJw6izpTe7LtOdwAXnkDqw5yweboYCTkM2rQizCng==} + '@babel/eslint-parser@7.28.6': + resolution: {integrity: sha512-QGmsKi2PBO/MHSQk+AAgA9R6OHQr+VqnniFE0eMWZcVcfBZoA2dKn2hUsl3Csg/Plt9opRUWdY7//VXsrIlEiA==} engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} peerDependencies: '@babel/core': ^7.11.0 eslint: ^7.5.0 || ^8.0.0 || ^9.0.0 - '@babel/generator@7.27.0': - resolution: {integrity: sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==} + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.25.9': - resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.27.0': - resolution: {integrity: sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==} + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} engines: {node: '>=6.9.0'} - '@babel/helper-create-class-features-plugin@7.27.0': - resolution: {integrity: sha512-vSGCvMecvFCd/BdpGlhpXYNhhC4ccxyvQWpbGL4CWbvfEoLFWUZuSuf7s9Aw70flgQF+6vptvgK2IfOnKlRmBg==} + '@babel/helper-create-class-features-plugin@7.28.6': + resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-create-regexp-features-plugin@7.27.0': - resolution: {integrity: sha512-fO8l08T76v48BhpNRW/nQ0MxfnSdoSKUJBMjubOAYffsVuGG5qOfMq7N6Es7UJvi7Y8goXXo07EfcHZXDPuELQ==} + '@babel/helper-create-regexp-features-plugin@7.28.5': + resolution: {integrity: sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-define-polyfill-provider@0.6.4': - resolution: {integrity: sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw==} + '@babel/helper-define-polyfill-provider@0.6.8': + resolution: {integrity: sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - '@babel/helper-member-expression-to-functions@7.25.9': - resolution: {integrity: sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==} + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.28.5': + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.25.9': - resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.26.0': - resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-optimise-call-expression@7.25.9': - resolution: {integrity: sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==} + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.26.5': - resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} engines: {node: '>=6.9.0'} - '@babel/helper-remap-async-to-generator@7.25.9': - resolution: {integrity: sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==} + '@babel/helper-remap-async-to-generator@7.27.1': + resolution: {integrity: sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-replace-supers@7.26.5': - resolution: {integrity: sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==} + '@babel/helper-replace-supers@7.28.6': + resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-skip-transparent-expression-wrappers@7.25.9': - resolution: {integrity: sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==} + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.25.9': - resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.25.9': - resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.25.9': - resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helper-wrap-function@7.25.9': - resolution: {integrity: sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==} + '@babel/helper-wrap-function@7.28.6': + resolution: {integrity: sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.27.0': - resolution: {integrity: sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==} + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.27.0': - resolution: {integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==} + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9': - resolution: {integrity: sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==} + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5': + resolution: {integrity: sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.9': - resolution: {integrity: sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==} + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1': + resolution: {integrity: sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.9': - resolution: {integrity: sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==} + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1': + resolution: {integrity: sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.9': - resolution: {integrity: sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==} + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1': + resolution: {integrity: sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.13.0 - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.9': - resolution: {integrity: sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==} + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6': + resolution: {integrity: sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -827,8 +839,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-proposal-decorators@7.25.9': - resolution: {integrity: sha512-smkNLL/O1ezy9Nhy4CNosc4Va+1wo5w4gzSZeLe6y6dM4mmHfYOCPolXQPHQxonZCF+ZyebxN9vqOolkYrSn5g==} + '@babel/plugin-proposal-decorators@7.29.0': + resolution: {integrity: sha512-CVBVv3VY/XRMxRYq5dwr2DS7/MvqPm23cOCjbwNnVrfOqcWlnefua1uUs0sjdKOGjvPUG633o07uWzJq4oI6dA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -895,26 +907,26 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-decorators@7.25.9': - resolution: {integrity: sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==} + '@babel/plugin-syntax-decorators@7.28.6': + resolution: {integrity: sha512-71EYI0ONURHJBL4rSFXnITXqXrrY8q4P0q006DPfN+Rk+ASM+++IBXem/ruokgBZR8YNEWZ8R6B+rCb8VcUTqA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-flow@7.26.0': - resolution: {integrity: sha512-B+O2DnPc0iG+YXFqOxv2WNuNU97ToWjOomUQ78DouOENWUaM5sVrmet9mcomUGQFwpJd//gvUagXBSdzO1fRKg==} + '@babel/plugin-syntax-flow@7.28.6': + resolution: {integrity: sha512-D+OrJumc9McXNEBI/JmFnc/0uCM2/Y3PEBG3gfV3QIYkKv5pvnpzFrl1kYCrcHJP8nOeFB/SHi1IHz29pNGuew==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-assertions@7.26.0': - resolution: {integrity: sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==} + '@babel/plugin-syntax-import-assertions@7.28.6': + resolution: {integrity: sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-attributes@7.26.0': - resolution: {integrity: sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==} + '@babel/plugin-syntax-import-attributes@7.28.6': + resolution: {integrity: sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -929,8 +941,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-jsx@7.25.9': - resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} + '@babel/plugin-syntax-jsx@7.28.6': + resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -977,8 +989,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-typescript@7.25.9': - resolution: {integrity: sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==} + '@babel/plugin-syntax-typescript@7.28.6': + resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -989,356 +1001,362 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-arrow-functions@7.25.9': - resolution: {integrity: sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==} + '@babel/plugin-transform-arrow-functions@7.27.1': + resolution: {integrity: sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-generator-functions@7.26.8': - resolution: {integrity: sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==} + '@babel/plugin-transform-async-generator-functions@7.29.0': + resolution: {integrity: sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-to-generator@7.25.9': - resolution: {integrity: sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==} + '@babel/plugin-transform-async-to-generator@7.28.6': + resolution: {integrity: sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoped-functions@7.26.5': - resolution: {integrity: sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==} + '@babel/plugin-transform-block-scoped-functions@7.27.1': + resolution: {integrity: sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoping@7.27.0': - resolution: {integrity: sha512-u1jGphZ8uDI2Pj/HJj6YQ6XQLZCNjOlprjxB5SVz6rq2T6SwAR+CdrWK0CP7F+9rDVMXdB0+r6Am5G5aobOjAQ==} + '@babel/plugin-transform-block-scoping@7.28.6': + resolution: {integrity: sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-properties@7.25.9': - resolution: {integrity: sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==} + '@babel/plugin-transform-class-properties@7.28.6': + resolution: {integrity: sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-static-block@7.26.0': - resolution: {integrity: sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==} + '@babel/plugin-transform-class-static-block@7.28.6': + resolution: {integrity: sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 - '@babel/plugin-transform-classes@7.25.9': - resolution: {integrity: sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==} + '@babel/plugin-transform-classes@7.28.6': + resolution: {integrity: sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-computed-properties@7.25.9': - resolution: {integrity: sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==} + '@babel/plugin-transform-computed-properties@7.28.6': + resolution: {integrity: sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-destructuring@7.25.9': - resolution: {integrity: sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==} + '@babel/plugin-transform-destructuring@7.28.5': + resolution: {integrity: sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-dotall-regex@7.25.9': - resolution: {integrity: sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==} + '@babel/plugin-transform-dotall-regex@7.28.6': + resolution: {integrity: sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-duplicate-keys@7.25.9': - resolution: {integrity: sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==} + '@babel/plugin-transform-duplicate-keys@7.27.1': + resolution: {integrity: sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.9': - resolution: {integrity: sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==} + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-dynamic-import@7.25.9': - resolution: {integrity: sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==} + '@babel/plugin-transform-dynamic-import@7.27.1': + resolution: {integrity: sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-exponentiation-operator@7.26.3': - resolution: {integrity: sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==} + '@babel/plugin-transform-explicit-resource-management@7.28.6': + resolution: {integrity: sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-export-namespace-from@7.25.9': - resolution: {integrity: sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==} + '@babel/plugin-transform-exponentiation-operator@7.28.6': + resolution: {integrity: sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-flow-strip-types@7.26.5': - resolution: {integrity: sha512-eGK26RsbIkYUns3Y8qKl362juDDYK+wEdPGHGrhzUl6CewZFo55VZ7hg+CyMFU4dd5QQakBN86nBMpRsFpRvbQ==} + '@babel/plugin-transform-export-namespace-from@7.27.1': + resolution: {integrity: sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-for-of@7.26.9': - resolution: {integrity: sha512-Hry8AusVm8LW5BVFgiyUReuoGzPUpdHQQqJY5bZnbbf+ngOHWuCuYFKw/BqaaWlvEUrF91HMhDtEaI1hZzNbLg==} + '@babel/plugin-transform-flow-strip-types@7.27.1': + resolution: {integrity: sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-function-name@7.25.9': - resolution: {integrity: sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==} + '@babel/plugin-transform-for-of@7.27.1': + resolution: {integrity: sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-json-strings@7.25.9': - resolution: {integrity: sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==} + '@babel/plugin-transform-function-name@7.27.1': + resolution: {integrity: sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-literals@7.25.9': - resolution: {integrity: sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==} + '@babel/plugin-transform-json-strings@7.28.6': + resolution: {integrity: sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-logical-assignment-operators@7.25.9': - resolution: {integrity: sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==} + '@babel/plugin-transform-literals@7.27.1': + resolution: {integrity: sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-member-expression-literals@7.25.9': - resolution: {integrity: sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==} + '@babel/plugin-transform-logical-assignment-operators@7.28.6': + resolution: {integrity: sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-amd@7.25.9': - resolution: {integrity: sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==} + '@babel/plugin-transform-member-expression-literals@7.27.1': + resolution: {integrity: sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-commonjs@7.26.3': - resolution: {integrity: sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==} + '@babel/plugin-transform-modules-amd@7.27.1': + resolution: {integrity: sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-systemjs@7.25.9': - resolution: {integrity: sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==} + '@babel/plugin-transform-modules-commonjs@7.28.6': + resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-umd@7.25.9': - resolution: {integrity: sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==} + '@babel/plugin-transform-modules-systemjs@7.29.0': + resolution: {integrity: sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-named-capturing-groups-regex@7.25.9': - resolution: {integrity: sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==} + '@babel/plugin-transform-modules-umd@7.27.1': + resolution: {integrity: sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-new-target@7.25.9': - resolution: {integrity: sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==} + '@babel/plugin-transform-new-target@7.27.1': + resolution: {integrity: sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-nullish-coalescing-operator@7.26.6': - resolution: {integrity: sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==} + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6': + resolution: {integrity: sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-numeric-separator@7.25.9': - resolution: {integrity: sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==} + '@babel/plugin-transform-numeric-separator@7.28.6': + resolution: {integrity: sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-rest-spread@7.25.9': - resolution: {integrity: sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==} + '@babel/plugin-transform-object-rest-spread@7.28.6': + resolution: {integrity: sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-super@7.25.9': - resolution: {integrity: sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==} + '@babel/plugin-transform-object-super@7.27.1': + resolution: {integrity: sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-catch-binding@7.25.9': - resolution: {integrity: sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==} + '@babel/plugin-transform-optional-catch-binding@7.28.6': + resolution: {integrity: sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-chaining@7.25.9': - resolution: {integrity: sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==} + '@babel/plugin-transform-optional-chaining@7.28.6': + resolution: {integrity: sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-parameters@7.25.9': - resolution: {integrity: sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==} + '@babel/plugin-transform-parameters@7.27.7': + resolution: {integrity: sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-methods@7.25.9': - resolution: {integrity: sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==} + '@babel/plugin-transform-private-methods@7.28.6': + resolution: {integrity: sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-property-in-object@7.25.9': - resolution: {integrity: sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==} + '@babel/plugin-transform-private-property-in-object@7.28.6': + resolution: {integrity: sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-property-literals@7.25.9': - resolution: {integrity: sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==} + '@babel/plugin-transform-property-literals@7.27.1': + resolution: {integrity: sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-constant-elements@7.25.9': - resolution: {integrity: sha512-Ncw2JFsJVuvfRsa2lSHiC55kETQVLSnsYGQ1JDDwkUeWGTL/8Tom8aLTnlqgoeuopWrbbGndrc9AlLYrIosrow==} + '@babel/plugin-transform-react-constant-elements@7.27.1': + resolution: {integrity: sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-display-name@7.25.9': - resolution: {integrity: sha512-KJfMlYIUxQB1CJfO3e0+h0ZHWOTLCPP115Awhaz8U0Zpq36Gl/cXlpoyMRnUWlhNUBAzldnCiAZNvCDj7CrKxQ==} + '@babel/plugin-transform-react-display-name@7.28.0': + resolution: {integrity: sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx-development@7.25.9': - resolution: {integrity: sha512-9mj6rm7XVYs4mdLIpbZnHOYdpW42uoiBCTVowg7sP1thUOiANgMb4UtpRivR0pp5iL+ocvUv7X4mZgFRpJEzGw==} + '@babel/plugin-transform-react-jsx-development@7.27.1': + resolution: {integrity: sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx@7.25.9': - resolution: {integrity: sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw==} + '@babel/plugin-transform-react-jsx@7.28.6': + resolution: {integrity: sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-pure-annotations@7.25.9': - resolution: {integrity: sha512-KQ/Takk3T8Qzj5TppkS1be588lkbTp5uj7w6a0LeQaTMSckU/wK0oJ/pih+T690tkgI5jfmg2TqDJvd41Sj1Cg==} + '@babel/plugin-transform-react-pure-annotations@7.27.1': + resolution: {integrity: sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regenerator@7.27.0': - resolution: {integrity: sha512-LX/vCajUJQDqE7Aum/ELUMZAY19+cDpghxrnyt5I1tV6X5PyC86AOoWXWFYFeIvauyeSA6/ktn4tQVn/3ZifsA==} + '@babel/plugin-transform-regenerator@7.29.0': + resolution: {integrity: sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regexp-modifiers@7.26.0': - resolution: {integrity: sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==} + '@babel/plugin-transform-regexp-modifiers@7.28.6': + resolution: {integrity: sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/plugin-transform-reserved-words@7.25.9': - resolution: {integrity: sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==} + '@babel/plugin-transform-reserved-words@7.27.1': + resolution: {integrity: sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-runtime@7.26.10': - resolution: {integrity: sha512-NWaL2qG6HRpONTnj4JvDU6th4jYeZOJgu3QhmFTCihib0ermtOJqktA5BduGm3suhhVe9EMP9c9+mfJ/I9slqw==} + '@babel/plugin-transform-runtime@7.29.0': + resolution: {integrity: sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-shorthand-properties@7.25.9': - resolution: {integrity: sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==} + '@babel/plugin-transform-shorthand-properties@7.27.1': + resolution: {integrity: sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-spread@7.25.9': - resolution: {integrity: sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==} + '@babel/plugin-transform-spread@7.28.6': + resolution: {integrity: sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-sticky-regex@7.25.9': - resolution: {integrity: sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==} + '@babel/plugin-transform-sticky-regex@7.27.1': + resolution: {integrity: sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-template-literals@7.26.8': - resolution: {integrity: sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q==} + '@babel/plugin-transform-template-literals@7.27.1': + resolution: {integrity: sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typeof-symbol@7.27.0': - resolution: {integrity: sha512-+LLkxA9rKJpNoGsbLnAgOCdESl73vwYn+V6b+5wHbrE7OGKVDPHIQvbFSzqE6rwqaCw2RE+zdJrlLkcf8YOA0w==} + '@babel/plugin-transform-typeof-symbol@7.27.1': + resolution: {integrity: sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.27.0': - resolution: {integrity: sha512-fRGGjO2UEGPjvEcyAZXRXAS8AfdaQoq7HnxAbJoAoW10B9xOKesmmndJv+Sym2a+9FHWZ9KbyyLCe9s0Sn5jtg==} + '@babel/plugin-transform-typescript@7.28.6': + resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-escapes@7.25.9': - resolution: {integrity: sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==} + '@babel/plugin-transform-unicode-escapes@7.27.1': + resolution: {integrity: sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-property-regex@7.25.9': - resolution: {integrity: sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==} + '@babel/plugin-transform-unicode-property-regex@7.28.6': + resolution: {integrity: sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-regex@7.25.9': - resolution: {integrity: sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==} + '@babel/plugin-transform-unicode-regex@7.27.1': + resolution: {integrity: sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-sets-regex@7.25.9': - resolution: {integrity: sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==} + '@babel/plugin-transform-unicode-sets-regex@7.28.6': + resolution: {integrity: sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/preset-env@7.26.9': - resolution: {integrity: sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ==} + '@babel/preset-env@7.29.2': + resolution: {integrity: sha512-DYD23veRYGvBFhcTY1iUvJnDNpuqNd/BzBwCvzOTKUnJjKg5kpUBh3/u9585Agdkgj+QuygG7jLfOPWMa2KVNw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1348,32 +1366,32 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 - '@babel/preset-react@7.26.3': - resolution: {integrity: sha512-Nl03d6T9ky516DGK2YMxrTqvnpUW63TnJMOMonj+Zae0JiPC5BC9xPMSL6L8fiSpA5vP88qfygavVQvnLp+6Cw==} + '@babel/preset-react@7.28.5': + resolution: {integrity: sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/preset-typescript@7.27.0': - resolution: {integrity: sha512-vxaPFfJtHhgeOVXRKuHpHPAOgymmy8V8I65T1q53R7GCZlefKeCaTyDs3zOPHTTbmquvNlQYC5klEvWsBAtrBQ==} + '@babel/preset-typescript@7.28.5': + resolution: {integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.27.0': - resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==} + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} engines: {node: '>=6.9.0'} - '@babel/template@7.27.0': - resolution: {integrity: sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==} + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.27.0': - resolution: {integrity: sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==} + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} engines: {node: '>=6.9.0'} - '@babel/types@7.27.0': - resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==} + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@0.2.3': @@ -1383,21 +1401,21 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@changesets/apply-release-plan@7.0.10': - resolution: {integrity: sha512-wNyeIJ3yDsVspYvHnEz1xQDq18D9ifed3lI+wxRQRK4pArUcuHgCTrHv0QRnnwjhVCQACxZ+CBih3wgOct6UXw==} + '@changesets/apply-release-plan@7.1.0': + resolution: {integrity: sha512-yq8ML3YS7koKQ/9bk1PqO0HMzApIFNwjlwCnwFEXMzNe8NpzeeYYKCmnhWJGkN8g7E51MnWaSbqRcTcdIxUgnQ==} - '@changesets/assemble-release-plan@6.0.6': - resolution: {integrity: sha512-Frkj8hWJ1FRZiY3kzVCKzS0N5mMwWKwmv9vpam7vt8rZjLL1JMthdh6pSDVSPumHPshTTkKZ0VtNbE0cJHZZUg==} + '@changesets/assemble-release-plan@6.0.9': + resolution: {integrity: sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==} '@changesets/changelog-git@0.2.1': resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} - '@changesets/cli@2.28.1': - resolution: {integrity: sha512-PiIyGRmSc6JddQJe/W1hRPjiN4VrMvb2VfQ6Uydy2punBioQrsxppyG5WafinKcW1mT0jOe/wU4k9Zy5ff21AA==} + '@changesets/cli@2.30.0': + resolution: {integrity: sha512-5D3Nk2JPqMI1wK25pEymeWRSlSMdo5QOGlyfrKg0AOufrUcjEE3RQgaCpHoBiM31CSNrtSgdJ0U6zL1rLDDfBA==} hasBin: true - '@changesets/config@3.1.1': - resolution: {integrity: sha512-bd+3Ap2TKXxljCggI0mKPfzCQKeV/TU4yO2h2C6vAihIo8tzseAn2e7klSuiyYYXvgu53zMN1OeYMIQkaQoWnA==} + '@changesets/config@3.1.3': + resolution: {integrity: sha512-vnXjcey8YgBn2L1OPWd3ORs0bGC4LoYcK/ubpgvzNVr53JXV5GiTVj7fWdMRsoKUH7hhhMAQnsJUqLr21EncNw==} '@changesets/errors@0.2.0': resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} @@ -1405,26 +1423,26 @@ packages: '@changesets/get-dependents-graph@2.1.3': resolution: {integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==} - '@changesets/get-release-plan@4.0.8': - resolution: {integrity: sha512-MM4mq2+DQU1ZT7nqxnpveDMTkMBLnwNX44cX7NSxlXmr7f8hO6/S2MXNiXG54uf/0nYnefv0cfy4Czf/ZL/EKQ==} + '@changesets/get-release-plan@4.0.15': + resolution: {integrity: sha512-Q04ZaRPuEVZtA+auOYgFaVQQSA98dXiVe/yFaZfY7hoSmQICHGvP0TF4u3EDNHWmmCS4ekA/XSpKlSM2PyTS2g==} '@changesets/get-version-range-type@0.4.0': resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} - '@changesets/git@3.0.2': - resolution: {integrity: sha512-r1/Kju9Y8OxRRdvna+nxpQIsMsRQn9dhhAZt94FLDeu0Hij2hnOozW8iqnHBgvu+KdnJppCveQwK4odwfw/aWQ==} + '@changesets/git@3.0.4': + resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==} '@changesets/logger@0.1.1': resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} - '@changesets/parse@0.4.1': - resolution: {integrity: sha512-iwksMs5Bf/wUItfcg+OXrEpravm5rEd9Bf4oyIPL4kVTmJQ7PNDSd6MDYkpSJR1pn7tz/k8Zf2DhTCqX08Ou+Q==} + '@changesets/parse@0.4.3': + resolution: {integrity: sha512-ZDmNc53+dXdWEv7fqIUSgRQOLYoUom5Z40gmLgmATmYR9NbL6FJJHwakcCpzaeCy+1D0m0n7mT4jj2B/MQPl7A==} '@changesets/pre@2.0.2': resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} - '@changesets/read@0.6.3': - resolution: {integrity: sha512-9H4p/OuJ3jXEUTjaVGdQEhBdqoT2cO5Ts95JTFsQyawmKzpL8FnIeJSyhTDPW1MBRDnwZlHFEM9SpPwJDY5wIg==} + '@changesets/read@0.6.7': + resolution: {integrity: sha512-D1G4AUYGrBEk8vj8MGwf75k9GpN6XL3wg8i42P2jZZwFLXnlr2Pn7r9yuQNbaMCarP7ZQWNJbV6XLeysAIMhTA==} '@changesets/should-skip-package@0.1.2': resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} @@ -1443,24 +1461,24 @@ packages: peerDependencies: commander: ~12.1.0 - '@commitlint/config-validator@19.8.0': - resolution: {integrity: sha512-+r5ZvD/0hQC3w5VOHJhGcCooiAVdynFlCe2d6I9dU+PvXdV3O+fU4vipVg+6hyLbQUuCH82mz3HnT/cBQTYYuA==} + '@commitlint/config-validator@20.5.0': + resolution: {integrity: sha512-T/Uh6iJUzyx7j35GmHWdIiGRQB+ouZDk0pwAaYq4SXgB54KZhFdJ0vYmxiW6AMYICTIWuyMxDBl1jK74oFp/Gw==} engines: {node: '>=v18'} - '@commitlint/execute-rule@19.8.0': - resolution: {integrity: sha512-fuLeI+EZ9x2v/+TXKAjplBJWI9CNrHnyi5nvUQGQt4WRkww/d95oVRsc9ajpt4xFrFmqMZkd/xBQHZDvALIY7A==} + '@commitlint/execute-rule@20.0.0': + resolution: {integrity: sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==} engines: {node: '>=v18'} - '@commitlint/load@19.8.0': - resolution: {integrity: sha512-4rvmm3ff81Sfb+mcWT5WKlyOa+Hd33WSbirTVUer0wjS1Hv/Hzr07Uv1ULIV9DkimZKNyOwXn593c+h8lsDQPQ==} + '@commitlint/load@20.5.0': + resolution: {integrity: sha512-sLhhYTL/KxeOTZjjabKDhwidGZan84XKK1+XFkwDYL/4883kIajcz/dZFAhBJmZPtL8+nBx6bnkzA95YxPeDPw==} engines: {node: '>=v18'} - '@commitlint/resolve-extends@19.8.0': - resolution: {integrity: sha512-CLanRQwuG2LPfFVvrkTrBR/L/DMy3+ETsgBqW1OvRxmzp/bbVJW0Xw23LnnExgYcsaFtos967lul1CsbsnJlzQ==} + '@commitlint/resolve-extends@20.5.0': + resolution: {integrity: sha512-3SHPWUW2v0tyspCTcfSsYml0gses92l6TlogwzvM2cbxDgmhSRc+fldDjvGkCXJrjSM87BBaWYTPWwwyASZRrg==} engines: {node: '>=v18'} - '@commitlint/types@19.8.0': - resolution: {integrity: sha512-LRjP623jPyf3Poyfb0ohMj8I3ORyBDOwXAgxxVPbSD0unJuW2mJWeiRfaQinjtccMqC5Wy1HOMfa4btKjbNxbg==} + '@commitlint/types@20.5.0': + resolution: {integrity: sha512-ZJoS8oSq2CAZEpc/YI9SulLrdiIyXeHb/OGqGrkUP6Q7YV+0ouNAa7GjqRdXeQPncHQIDz/jbCTlHScvYvO/gA==} engines: {node: '>=v18'} '@cspotcode/source-map-support@0.8.1': @@ -1564,17 +1582,14 @@ packages: resolution: {integrity: sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==} engines: {node: '>=14.17.0'} - '@emnapi/core@1.4.0': - resolution: {integrity: sha512-H+N/FqT07NmLmt6OFFtDfwe8PNygprzBikrEMyQfgqSmT0vzE515Pz7R8izwB9q/zsH/MA64AKoul3sA6/CzVg==} + '@emnapi/core@1.9.2': + resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} - '@emnapi/runtime@1.4.0': - resolution: {integrity: sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw==} + '@emnapi/runtime@1.9.2': + resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==} - '@emnapi/runtime@1.5.0': - resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==} - - '@emnapi/wasi-threads@1.0.1': - resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==} + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} '@esbuild/aix-ppc64@0.19.12': resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} @@ -1582,8 +1597,8 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.25.1': - resolution: {integrity: sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==} + '@esbuild/aix-ppc64@0.27.7': + resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] @@ -1600,8 +1615,8 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.25.1': - resolution: {integrity: sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==} + '@esbuild/android-arm64@0.27.7': + resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -1618,8 +1633,8 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.25.1': - resolution: {integrity: sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==} + '@esbuild/android-arm@0.27.7': + resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} engines: {node: '>=18'} cpu: [arm] os: [android] @@ -1636,8 +1651,8 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.25.1': - resolution: {integrity: sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==} + '@esbuild/android-x64@0.27.7': + resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} engines: {node: '>=18'} cpu: [x64] os: [android] @@ -1654,8 +1669,8 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.25.1': - resolution: {integrity: sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==} + '@esbuild/darwin-arm64@0.27.7': + resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] @@ -1672,8 +1687,8 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.25.1': - resolution: {integrity: sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==} + '@esbuild/darwin-x64@0.27.7': + resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] @@ -1690,8 +1705,8 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.25.1': - resolution: {integrity: sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==} + '@esbuild/freebsd-arm64@0.27.7': + resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] @@ -1708,8 +1723,8 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.1': - resolution: {integrity: sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==} + '@esbuild/freebsd-x64@0.27.7': + resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] @@ -1726,8 +1741,8 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.25.1': - resolution: {integrity: sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==} + '@esbuild/linux-arm64@0.27.7': + resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} engines: {node: '>=18'} cpu: [arm64] os: [linux] @@ -1744,8 +1759,8 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.25.1': - resolution: {integrity: sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==} + '@esbuild/linux-arm@0.27.7': + resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} engines: {node: '>=18'} cpu: [arm] os: [linux] @@ -1762,8 +1777,8 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.25.1': - resolution: {integrity: sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==} + '@esbuild/linux-ia32@0.27.7': + resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -1780,8 +1795,8 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.25.1': - resolution: {integrity: sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==} + '@esbuild/linux-loong64@0.27.7': + resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} engines: {node: '>=18'} cpu: [loong64] os: [linux] @@ -1798,8 +1813,8 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.25.1': - resolution: {integrity: sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==} + '@esbuild/linux-mips64el@0.27.7': + resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] @@ -1816,8 +1831,8 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.25.1': - resolution: {integrity: sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==} + '@esbuild/linux-ppc64@0.27.7': + resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] @@ -1834,8 +1849,8 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.25.1': - resolution: {integrity: sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==} + '@esbuild/linux-riscv64@0.27.7': + resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] @@ -1852,8 +1867,8 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.25.1': - resolution: {integrity: sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==} + '@esbuild/linux-s390x@0.27.7': + resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] @@ -1870,14 +1885,14 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.25.1': - resolution: {integrity: sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==} + '@esbuild/linux-x64@0.27.7': + resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.1': - resolution: {integrity: sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==} + '@esbuild/netbsd-arm64@0.27.7': + resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] @@ -1894,14 +1909,14 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.1': - resolution: {integrity: sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==} + '@esbuild/netbsd-x64@0.27.7': + resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.1': - resolution: {integrity: sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==} + '@esbuild/openbsd-arm64@0.27.7': + resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] @@ -1918,12 +1933,18 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.1': - resolution: {integrity: sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==} + '@esbuild/openbsd-x64@0.27.7': + resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/openharmony-arm64@0.27.7': + resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.16.17': resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==} engines: {node: '>=12'} @@ -1936,8 +1957,8 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.25.1': - resolution: {integrity: sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==} + '@esbuild/sunos-x64@0.27.7': + resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] @@ -1954,8 +1975,8 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.25.1': - resolution: {integrity: sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==} + '@esbuild/win32-arm64@0.27.7': + resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] @@ -1972,8 +1993,8 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.25.1': - resolution: {integrity: sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==} + '@esbuild/win32-ia32@0.27.7': + resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] @@ -1990,20 +2011,20 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.25.1': - resolution: {integrity: sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==} + '@esbuild/win32-x64@0.27.7': + resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.5.1': - resolution: {integrity: sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==} + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} '@eslint/eslintrc@2.1.4': @@ -2130,128 +2151,168 @@ packages: resolution: {integrity: sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==} engines: {node: '>=6.9.0'} - '@img/sharp-darwin-arm64@0.34.3': - resolution: {integrity: sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==} + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [darwin] - '@img/sharp-darwin-x64@0.34.3': - resolution: {integrity: sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA==} + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.2.0': - resolution: {integrity: sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ==} + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.2.0': - resolution: {integrity: sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg==} + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} cpu: [x64] os: [darwin] - '@img/sharp-libvips-linux-arm64@1.2.0': - resolution: {integrity: sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA==} + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} cpu: [arm64] os: [linux] + libc: [glibc] - '@img/sharp-libvips-linux-arm@1.2.0': - resolution: {integrity: sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw==} + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} cpu: [arm] os: [linux] + libc: [glibc] - '@img/sharp-libvips-linux-ppc64@1.2.0': - resolution: {integrity: sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ==} + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} cpu: [ppc64] os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + libc: [glibc] - '@img/sharp-libvips-linux-s390x@1.2.0': - resolution: {integrity: sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw==} + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} cpu: [s390x] os: [linux] + libc: [glibc] - '@img/sharp-libvips-linux-x64@1.2.0': - resolution: {integrity: sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg==} + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} cpu: [x64] os: [linux] + libc: [glibc] - '@img/sharp-libvips-linuxmusl-arm64@1.2.0': - resolution: {integrity: sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q==} + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} cpu: [arm64] os: [linux] + libc: [musl] - '@img/sharp-libvips-linuxmusl-x64@1.2.0': - resolution: {integrity: sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q==} + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} cpu: [x64] os: [linux] + libc: [musl] - '@img/sharp-linux-arm64@0.34.3': - resolution: {integrity: sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA==} + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [glibc] - '@img/sharp-linux-arm@0.34.3': - resolution: {integrity: sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A==} + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] + libc: [glibc] - '@img/sharp-linux-ppc64@0.34.3': - resolution: {integrity: sha512-GLtbLQMCNC5nxuImPR2+RgrviwKwVql28FWZIW1zWruy6zLgA5/x2ZXk3mxj58X/tszVF69KK0Is83V8YgWhLA==} + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ppc64] os: [linux] + libc: [glibc] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] - '@img/sharp-linux-s390x@0.34.3': - resolution: {integrity: sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ==} + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] + libc: [glibc] - '@img/sharp-linux-x64@0.34.3': - resolution: {integrity: sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ==} + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [glibc] - '@img/sharp-linuxmusl-arm64@0.34.3': - resolution: {integrity: sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ==} + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [musl] - '@img/sharp-linuxmusl-x64@0.34.3': - resolution: {integrity: sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ==} + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [musl] - '@img/sharp-wasm32@0.34.3': - resolution: {integrity: sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg==} + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [wasm32] - '@img/sharp-win32-arm64@0.34.3': - resolution: {integrity: sha512-MjnHPnbqMXNC2UgeLJtX4XqoVHHlZNd+nPt1kRPmj63wURegwBhZlApELdtxM2OIZDRv/DFtLcNhVbd1z8GYXQ==} + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [win32] - '@img/sharp-win32-ia32@0.34.3': - resolution: {integrity: sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw==} + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ia32] os: [win32] - '@img/sharp-win32-x64@0.34.3': - resolution: {integrity: sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g==} + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [win32] + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@irys/arweave@0.0.2': resolution: {integrity: sha512-ddE5h4qXbl0xfGlxrtBIwzflaxZUDlDs43TuT0u1OMfyobHul4AA1VEX72Rpzw2bOh4vzoytSqA1jCM7x9YtHg==} @@ -2269,6 +2330,10 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@isaacs/cliui@9.0.0': + resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==} + engines: {node: '>=18'} + '@istanbuljs/load-nyc-config@1.1.0': resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} engines: {node: '>=8'} @@ -2347,29 +2412,24 @@ packages: resolution: {integrity: sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - '@jridgewell/gen-mapping@0.3.8': - resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} - engines: {node: '>=6.0.0'} + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - - '@jridgewell/source-map@0.3.6': - resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} - - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.30': - resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} @@ -2380,8 +2440,20 @@ packages: peerDependencies: tslib: '2' - '@jsonjoy.com/buffers@1.0.0': - resolution: {integrity: sha512-NDigYR3PHqCnQLXYyoLbnEdzMMvzeiCWo1KOut7Q0CoIqg9tUAPKJ1iq/2nFhc5kZtexzutNY0LFjdwWL3Dw3Q==} + '@jsonjoy.com/base64@17.67.0': + resolution: {integrity: sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/buffers@1.2.1': + resolution: {integrity: sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/buffers@17.67.0': + resolution: {integrity: sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -2392,8 +2464,68 @@ packages: peerDependencies: tslib: '2' - '@jsonjoy.com/json-pack@1.11.0': - resolution: {integrity: sha512-nLqSTAYwpk+5ZQIoVp7pfd/oSKNWlEdvTq2LzVA4r2wtWZg6v+5u0VgBOaDJuUfNOuw/4Ysq6glN5QKSrOCgrA==} + '@jsonjoy.com/codegen@17.67.0': + resolution: {integrity: sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-core@4.57.1': + resolution: {integrity: sha512-YrEi/ZPmgc+GfdO0esBF04qv8boK9Dg9WpRQw/+vM8Qt3nnVIJWIa8HwZ/LXVZ0DB11XUROM8El/7yYTJX+WtA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-fsa@4.57.1': + resolution: {integrity: sha512-ooEPvSW/HQDivPDPZMibHGKZf/QS4WRir1czGZmXmp3MsQqLECZEpN0JobrD8iV9BzsuwdIv+PxtWX9WpPLsIA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node-builtins@4.57.1': + resolution: {integrity: sha512-XHkFKQ5GSH3uxm8c3ZYXVrexGdscpWKIcMWKFQpMpMJc8gA3AwOMBJXJlgpdJqmrhPyQXxaY9nbkNeYpacC0Og==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node-to-fsa@4.57.1': + resolution: {integrity: sha512-pqGHyWWzNck4jRfaGV39hkqpY5QjRUQ/nRbNT7FYbBa0xf4bDG+TE1Gt2KWZrSkrkZZDE3qZUjYMbjwSliX6pg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node-utils@4.57.1': + resolution: {integrity: sha512-vp+7ZzIB8v43G+GLXTS4oDUSQmhAsRz532QmmWBbdYA20s465JvwhkSFvX9cVTqRRAQg+vZ7zWDaIEh0lFe2gw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node@4.57.1': + resolution: {integrity: sha512-3YaKhP8gXEKN+2O49GLNfNb5l2gbnCFHyAaybbA2JkkbQP3dpdef7WcUaHAulg/c5Dg4VncHsA3NWAUSZMR5KQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-print@4.57.1': + resolution: {integrity: sha512-Ynct7ZJmfk6qoXDOKfpovNA36ITUx8rChLmRQtW08J73VOiuNsU8PB6d/Xs7fxJC2ohWR3a5AqyjmLojfrw5yw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-snapshot@4.57.1': + resolution: {integrity: sha512-/oG8xBNFMbDXTq9J7vepSA1kerS5vpgd3p5QZSPd+nX59uwodGJftI51gDYyHRpP57P3WCQf7LHtBYPqwUg2Bg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pack@1.21.0': + resolution: {integrity: sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pack@17.67.0': + resolution: {integrity: sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -2404,12 +2536,24 @@ packages: peerDependencies: tslib: '2' + '@jsonjoy.com/json-pointer@17.67.0': + resolution: {integrity: sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + '@jsonjoy.com/util@1.9.0': resolution: {integrity: sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' + '@jsonjoy.com/util@17.67.0': + resolution: {integrity: sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + '@leichtgewicht/ip-codec@2.0.5': resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} @@ -2423,8 +2567,8 @@ packages: resolution: {integrity: sha512-sFpN+TX13E9fdBDh9lvQeZdJn4qYoRb/6QF2oZZK/Pn559IhCFacPMU1rMuqyXoFQF3JSJfii2l98B87QDPeCQ==} engines: {node: '>=14.0.0'} - '@napi-rs/wasm-runtime@0.2.7': - resolution: {integrity: sha512-5yximcFK5FNompXfJFoWanu5l8v1hNGqNHh9du1xETp9HWk/B/PzvchX55WYOPaIeNglG8++68AAiauBAtbnzw==} + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} '@near-js/crypto@0.0.3': resolution: {integrity: sha512-3WC2A1a1cH8Cqrx+0iDjp1ASEEhxN/KHEMENYb0KZH6Hp5bXIY7Akt4quC7JlgJS5ESvEiLa40tS5h0zAhBWGw==} @@ -2491,24 +2635,28 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@next/swc-linux-arm64-musl@15.3.4': resolution: {integrity: sha512-wFyZ7X470YJQtpKot4xCY3gpdn8lE9nTlldG07/kJYexCUpX1piX+MBfZdvulo+t1yADFVEuzFfVHfklfEx8kw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] '@next/swc-linux-x64-gnu@15.3.4': resolution: {integrity: sha512-gEbH9rv9o7I12qPyvZNVTyP/PWKqOp8clvnoYZQiX800KkqsaJZuOXkWgMa7ANCCh/oEN2ZQheh3yH8/kWPSEg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@next/swc-linux-x64-musl@15.3.4': resolution: {integrity: sha512-Cf8sr0ufuC/nu/yQ76AnarbSAXcwG/wj+1xFPNbyNo8ltA6kw5d5YqO8kQuwVIxk13SBdtgXrNyom3ZosHAy4A==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] '@next/swc-win32-arm64-msvc@15.3.4': resolution: {integrity: sha512-ay5+qADDN3rwRbRpEhTOreOn1OyJIXS60tg9WMYTWCy3fB6rGoyjLVxc4dR9PYjEdR2iDYsaF5h03NA+XuYPQQ==} @@ -2525,15 +2673,19 @@ packages: '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} - '@noble/curves@1.8.1': - resolution: {integrity: sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==} + '@noble/curves@1.9.7': + resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} engines: {node: ^14.21.3 || >=16} - '@noble/ed25519@1.7.3': - resolution: {integrity: sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==} + '@noble/ed25519@1.7.5': + resolution: {integrity: sha512-xuS0nwRMQBvSxDa7UxMb61xTiH3MxTgUfhyPUALVIe0FlOAz4sjELwyDRyUvqeEYfRSG9qNjFIycqLZppg4RSA==} + + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} - '@noble/hashes@1.7.1': - resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==} + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} engines: {node: ^14.21.3 || >=16} '@nodelib/fs.scandir@2.1.5': @@ -2555,6 +2707,10 @@ packages: '@nucypher/nucypher-contracts@0.25.0': resolution: {integrity: sha512-4fRPKY6RzkXY1Zv2O0auJZsvP6z7tuj+Fsy83yJvADqFwRuIJfSlwgSgLwISX6q838SRG/Ve2i+sMLZRaVJfYw==} + '@nucypher/nucypher-contracts@https://codeload.github.com/nucypher/nucypher-contracts/tar.gz/7a7bf2207436688d5835d54bdf71f51ce527907f': + resolution: {tarball: https://codeload.github.com/nucypher/nucypher-contracts/tar.gz/7a7bf2207436688d5835d54bdf71f51ce527907f} + version: 0.26.0-alpha.3 + '@nucypher/nucypher-core@0.14.5': resolution: {integrity: sha512-Q3kBuJL0qtTtnxrM5DEQauQUvDlXmwubm9u1h7gbyLhs+aZNC9WDyjEUbE43+uahlHu4k1hKEMxD1gjV165ChA==} @@ -2570,12 +2726,46 @@ packages: resolution: {integrity: sha512-LehkMgoM7VDgqg3kqvMX8PFOiVgyFMVAqsbdbcffj31z2tf7C0q8RBinj61YDaLotx++py6us6M+T2cJAywnaA==} engines: {node: '>=18', pnpm: '>=8.0.0'} + '@peculiar/asn1-cms@2.6.1': + resolution: {integrity: sha512-vdG4fBF6Lkirkcl53q6eOdn3XYKt+kJTG59edgRZORlg/3atWWEReRCx5rYE1ZzTTX6vLK5zDMjHh7vbrcXGtw==} + + '@peculiar/asn1-csr@2.6.1': + resolution: {integrity: sha512-WRWnKfIocHyzFYQTka8O/tXCiBquAPSrRjXbOkHbO4qdmS6loffCEGs+rby6WxxGdJCuunnhS2duHURhjyio6w==} + + '@peculiar/asn1-ecc@2.6.1': + resolution: {integrity: sha512-+Vqw8WFxrtDIN5ehUdvlN2m73exS2JVG0UAyfVB31gIfor3zWEAQPD+K9ydCxaj3MLen9k0JhKpu9LqviuCE1g==} + + '@peculiar/asn1-pfx@2.6.1': + resolution: {integrity: sha512-nB5jVQy3MAAWvq0KY0R2JUZG8bO/bTLpnwyOzXyEh/e54ynGTatAR+csOnXkkVD9AFZ2uL8Z7EV918+qB1qDvw==} + + '@peculiar/asn1-pkcs8@2.6.1': + resolution: {integrity: sha512-JB5iQ9Izn5yGMw3ZG4Nw3Xn/hb/G38GYF3lf7WmJb8JZUydhVGEjK/ZlFSWhnlB7K/4oqEs8HnfFIKklhR58Tw==} + + '@peculiar/asn1-pkcs9@2.6.1': + resolution: {integrity: sha512-5EV8nZoMSxeWmcxWmmcolg22ojZRgJg+Y9MX2fnE2bGRo5KQLqV5IL9kdSQDZxlHz95tHvIq9F//bvL1OeNILw==} + + '@peculiar/asn1-rsa@2.6.1': + resolution: {integrity: sha512-1nVMEh46SElUt5CB3RUTV4EG/z7iYc7EoaDY5ECwganibQPkZ/Y2eMsTKB/LeyrUJ+W/tKoD9WUqIy8vB+CEdA==} + + '@peculiar/asn1-schema@2.6.0': + resolution: {integrity: sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==} + + '@peculiar/asn1-x509-attr@2.6.1': + resolution: {integrity: sha512-tlW6cxoHwgcQghnJwv3YS+9OO1737zgPogZ+CgWRUK4roEwIPzRH4JEiG770xe5HX2ATfCpmX60gurfWIF9dcQ==} + + '@peculiar/asn1-x509@2.6.1': + resolution: {integrity: sha512-O9jT5F1A2+t3r7C4VT7LYGXqkGLK7Kj1xFpz7U0isPrubwU5PbDoyYtx6MiGst29yq7pXN5vZbQFKRCP+lLZlA==} + + '@peculiar/x509@1.14.3': + resolution: {integrity: sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==} + engines: {node: '>=20.0.0'} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@pmmmwh/react-refresh-webpack-plugin@0.5.15': - resolution: {integrity: sha512-LFWllMA55pzB9D34w/wXUCf8+c+IYKuJDgxiZ3qMhl64KRMBHYM1I3VdGaD2BV5FNPV2/S2596bppxHbv2ZydQ==} + '@pmmmwh/react-refresh-webpack-plugin@0.5.17': + resolution: {integrity: sha512-tXDyE1/jzFsHXjhRZQ3hMl0IVhYe5qula43LDWIhVfjp9G/nT5OQY5AORVOrkEGAUltBJOfOWeETbmhm6kHhuQ==} engines: {node: '>= 10.13'} peerDependencies: '@types/webpack': 4.x || 5.x @@ -2600,14 +2790,14 @@ packages: webpack-plugin-serve: optional: true - '@pmmmwh/react-refresh-webpack-plugin@0.6.1': - resolution: {integrity: sha512-95DXXJxNkpYu+sqmpDp7vbw9JCyiNpHuCsvuMuOgVFrKQlwEIn9Y1+NNIQJq+zFL+eWyxw6htthB5CtdwJupNA==} + '@pmmmwh/react-refresh-webpack-plugin@0.6.2': + resolution: {integrity: sha512-IhIAD5n4XvGHuL9nAgWfsBR0TdxtjrUWETYKCBHxauYXEv+b+ctEbs9neEgPC7Ecgzv4bpZTBwesAoGDeFymzA==} engines: {node: '>=18.12'} peerDependencies: '@types/webpack': 5.x react-refresh: '>=0.10.0 <1.0.0' sockjs-client: ^1.4.0 - type-fest: '>=0.17.0 <5.0.0' + type-fest: '>=0.17.0 <6.0.0' webpack: ^5.0.0 webpack-dev-server: ^4.8.0 || 5.x webpack-hot-middleware: 2.x @@ -2660,120 +2850,162 @@ packages: peerDependencies: rollup: ^1.20.0||^2.0.0 - '@rollup/rollup-android-arm-eabi@4.37.0': - resolution: {integrity: sha512-l7StVw6WAa8l3vA1ov80jyetOAEo1FtHvZDbzXDO/02Sq/QVvqlHkYoFwDJPIMj0GKiistsBudfx5tGFnwYWDQ==} + '@rollup/rollup-android-arm-eabi@4.60.1': + resolution: {integrity: sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.37.0': - resolution: {integrity: sha512-6U3SlVyMxezt8Y+/iEBcbp945uZjJwjZimu76xoG7tO1av9VO691z8PkhzQ85ith2I8R2RddEPeSfcbyPfD4hA==} + '@rollup/rollup-android-arm64@4.60.1': + resolution: {integrity: sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.37.0': - resolution: {integrity: sha512-+iTQ5YHuGmPt10NTzEyMPbayiNTcOZDWsbxZYR1ZnmLnZxG17ivrPSWFO9j6GalY0+gV3Jtwrrs12DBscxnlYA==} + '@rollup/rollup-darwin-arm64@4.60.1': + resolution: {integrity: sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.37.0': - resolution: {integrity: sha512-m8W2UbxLDcmRKVjgl5J/k4B8d7qX2EcJve3Sut7YGrQoPtCIQGPH5AMzuFvYRWZi0FVS0zEY4c8uttPfX6bwYQ==} + '@rollup/rollup-darwin-x64@4.60.1': + resolution: {integrity: sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.37.0': - resolution: {integrity: sha512-FOMXGmH15OmtQWEt174v9P1JqqhlgYge/bUjIbiVD1nI1NeJ30HYT9SJlZMqdo1uQFyt9cz748F1BHghWaDnVA==} + '@rollup/rollup-freebsd-arm64@4.60.1': + resolution: {integrity: sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.37.0': - resolution: {integrity: sha512-SZMxNttjPKvV14Hjck5t70xS3l63sbVwl98g3FlVVx2YIDmfUIy29jQrsw06ewEYQ8lQSuY9mpAPlmgRD2iSsA==} + '@rollup/rollup-freebsd-x64@4.60.1': + resolution: {integrity: sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.37.0': - resolution: {integrity: sha512-hhAALKJPidCwZcj+g+iN+38SIOkhK2a9bqtJR+EtyxrKKSt1ynCBeqrQy31z0oWU6thRZzdx53hVgEbRkuI19w==} + '@rollup/rollup-linux-arm-gnueabihf@4.60.1': + resolution: {integrity: sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==} cpu: [arm] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.37.0': - resolution: {integrity: sha512-jUb/kmn/Gd8epbHKEqkRAxq5c2EwRt0DqhSGWjPFxLeFvldFdHQs/n8lQ9x85oAeVb6bHcS8irhTJX2FCOd8Ag==} + '@rollup/rollup-linux-arm-musleabihf@4.60.1': + resolution: {integrity: sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==} cpu: [arm] os: [linux] + libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.37.0': - resolution: {integrity: sha512-oNrJxcQT9IcbcmKlkF+Yz2tmOxZgG9D9GRq+1OE6XCQwCVwxixYAa38Z8qqPzQvzt1FCfmrHX03E0pWoXm1DqA==} + '@rollup/rollup-linux-arm64-gnu@4.60.1': + resolution: {integrity: sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==} cpu: [arm64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.37.0': - resolution: {integrity: sha512-pfxLBMls+28Ey2enpX3JvjEjaJMBX5XlPCZNGxj4kdJyHduPBXtxYeb8alo0a7bqOoWZW2uKynhHxF/MWoHaGQ==} + '@rollup/rollup-linux-arm64-musl@4.60.1': + resolution: {integrity: sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==} cpu: [arm64] os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.60.1': + resolution: {integrity: sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==} + cpu: [loong64] + os: [linux] + libc: [glibc] - '@rollup/rollup-linux-loongarch64-gnu@4.37.0': - resolution: {integrity: sha512-yCE0NnutTC/7IGUq/PUHmoeZbIwq3KRh02e9SfFh7Vmc1Z7atuJRYWhRME5fKgT8aS20mwi1RyChA23qSyRGpA==} + '@rollup/rollup-linux-loong64-musl@4.60.1': + resolution: {integrity: sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==} cpu: [loong64] os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.60.1': + resolution: {integrity: sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==} + cpu: [ppc64] + os: [linux] + libc: [glibc] - '@rollup/rollup-linux-powerpc64le-gnu@4.37.0': - resolution: {integrity: sha512-NxcICptHk06E2Lh3a4Pu+2PEdZ6ahNHuK7o6Np9zcWkrBMuv21j10SQDJW3C9Yf/A/P7cutWoC/DptNLVsZ0VQ==} + '@rollup/rollup-linux-ppc64-musl@4.60.1': + resolution: {integrity: sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==} cpu: [ppc64] os: [linux] + libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.37.0': - resolution: {integrity: sha512-PpWwHMPCVpFZLTfLq7EWJWvrmEuLdGn1GMYcm5MV7PaRgwCEYJAwiN94uBuZev0/J/hFIIJCsYw4nLmXA9J7Pw==} + '@rollup/rollup-linux-riscv64-gnu@4.60.1': + resolution: {integrity: sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==} cpu: [riscv64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.37.0': - resolution: {integrity: sha512-DTNwl6a3CfhGTAOYZ4KtYbdS8b+275LSLqJVJIrPa5/JuIufWWZ/QFvkxp52gpmguN95eujrM68ZG+zVxa8zHA==} + '@rollup/rollup-linux-riscv64-musl@4.60.1': + resolution: {integrity: sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==} cpu: [riscv64] os: [linux] + libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.37.0': - resolution: {integrity: sha512-hZDDU5fgWvDdHFuExN1gBOhCuzo/8TMpidfOR+1cPZJflcEzXdCy1LjnklQdW8/Et9sryOPJAKAQRw8Jq7Tg+A==} + '@rollup/rollup-linux-s390x-gnu@4.60.1': + resolution: {integrity: sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==} cpu: [s390x] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.37.0': - resolution: {integrity: sha512-pKivGpgJM5g8dwj0ywBwe/HeVAUSuVVJhUTa/URXjxvoyTT/AxsLTAbkHkDHG7qQxLoW2s3apEIl26uUe08LVQ==} + '@rollup/rollup-linux-x64-gnu@4.60.1': + resolution: {integrity: sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==} cpu: [x64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.37.0': - resolution: {integrity: sha512-E2lPrLKE8sQbY/2bEkVTGDEk4/49UYRVWgj90MY8yPjpnGBQ+Xi1Qnr7b7UIWw1NOggdFQFOLZ8+5CzCiz143w==} + '@rollup/rollup-linux-x64-musl@4.60.1': + resolution: {integrity: sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==} cpu: [x64] os: [linux] + libc: [musl] + + '@rollup/rollup-openbsd-x64@4.60.1': + resolution: {integrity: sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.60.1': + resolution: {integrity: sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==} + cpu: [arm64] + os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.37.0': - resolution: {integrity: sha512-Jm7biMazjNzTU4PrQtr7VS8ibeys9Pn29/1bm4ph7CP2kf21950LgN+BaE2mJ1QujnvOc6p54eWWiVvn05SOBg==} + '@rollup/rollup-win32-arm64-msvc@4.60.1': + resolution: {integrity: sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.37.0': - resolution: {integrity: sha512-e3/1SFm1OjefWICB2Ucstg2dxYDkDTZGDYgwufcbsxTHyqQps1UQf33dFEChBNmeSsTOyrjw2JJq0zbG5GF6RA==} + '@rollup/rollup-win32-ia32-msvc@4.60.1': + resolution: {integrity: sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.37.0': - resolution: {integrity: sha512-LWbXUBwn/bcLx2sSsqy7pK5o+Nr+VCoRoAohfJ5C/aBio9nfJmGQqHAhU6pwxV/RmyTk5AqdySma7uwWGlmeuA==} + '@rollup/rollup-win32-x64-gnu@4.60.1': + resolution: {integrity: sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.60.1': + resolution: {integrity: sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==} cpu: [x64] os: [win32] '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - '@rushstack/eslint-patch@1.11.0': - resolution: {integrity: sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==} + '@rushstack/eslint-patch@1.16.1': + resolution: {integrity: sha512-TvZbIpeKqGQQ7X0zSCvPH9riMSFQFSggnfBjFZ1mEoILW+UuXCKwOoPcgjMwiUtRqFZ8jWhPJc4um14vC6I4ag==} - '@scure/base@1.2.4': - resolution: {integrity: sha512-5Yy9czTO47mqz+/J8GM6GIId4umdCk1wc1q8rKERQulIoc8VP9pzDcghv10Tl2E7R96ZUx/PhND3ESYUQX8NuQ==} + '@scure/base@1.2.6': + resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} - '@scure/bip32@1.6.2': - resolution: {integrity: sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==} + '@scure/bip32@1.7.0': + resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==} - '@scure/bip39@1.5.4': - resolution: {integrity: sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==} + '@scure/bip39@1.6.0': + resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} + + '@simple-libs/stream-utils@1.2.0': + resolution: {integrity: sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==} + engines: {node: '>=18'} '@sinclair/typebox@0.24.51': resolution: {integrity: sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==} @@ -2796,8 +3028,27 @@ packages: resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} engines: {node: '>=5.10'} - '@solana/web3.js@1.98.0': - resolution: {integrity: sha512-nz3Q5OeyGFpFCR+erX2f6JPt3sKhzhYcSycBCSPkWjzSVDh/Rr1FqTVMRe58FKO16/ivTUcuJjeS5MyBvpkbzA==} + '@solana/codecs-core@2.3.0': + resolution: {integrity: sha512-oG+VZzN6YhBHIoSKgS5ESM9VIGzhWjEHEGNPSibiDTxFhsFWxNaz8LbMDPjBUE69r9wmdGLkrQ+wVPbnJcZPvw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-numbers@2.3.0': + resolution: {integrity: sha512-jFvvwKJKffvG7Iz9dmN51OGB7JBcy2CJ6Xf3NqD/VP90xak66m/Lg48T01u5IQ/hc15mChVHiBm+HHuOFDUrQg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/errors@2.3.0': + resolution: {integrity: sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==} + engines: {node: '>=20.18.0'} + hasBin: true + peerDependencies: + typescript: '>=5.3.3' + + '@solana/web3.js@1.98.4': + resolution: {integrity: sha512-vv9lfnvjUsRiq//+j5pBdXig0IQdtzA0BRZ3bXEP4KaIyF1CcaydWqgyzQgfZMNIsWNWmG+AUHwPy4AHOD6gpw==} '@spruceid/siwe-parser@3.0.0': resolution: {integrity: sha512-Y92k63ilw/8jH9Ry4G2e7lQd0jZAvb0d/Q7ssSD0D9mp/Zt2aCXIc3g0ny9yhplpAx1QXHsMz/JJptHK/zDGdw==} @@ -2814,8 +3065,8 @@ packages: '@stablelib/wipe@1.0.1': resolution: {integrity: sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==} - '@supercharge/promise-pool@3.2.0': - resolution: {integrity: sha512-pj0cAALblTZBPtMltWOlZTQSLT07jIaFNeM8TWoJD1cQMgDB9mcMlVMoetiB35OzNJpqQ2b+QEtwiR9f20mADg==} + '@supercharge/promise-pool@3.3.0': + resolution: {integrity: sha512-qGzCltMN05ohRRQAXB8TPWt+0Coz9Va266gr9nYN1qc/f/EIaup3VRg7b59mtRaeKTRcxreF20l/udCM/gOqNg==} engines: {node: '>=8'} '@surma/rollup-plugin-off-main-thread@2.2.3': @@ -2883,6 +3134,9 @@ packages: '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + '@swc/helpers@0.5.21': + resolution: {integrity: sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==} + '@szmarczak/http-timer@4.0.6': resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} engines: {node: '>=10'} @@ -2891,12 +3145,8 @@ packages: resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} engines: {node: '>= 6'} - '@trysound/sax@0.2.0': - resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} - engines: {node: '>=10.13.0'} - - '@tsconfig/node10@1.0.11': - resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + '@tsconfig/node10@1.0.12': + resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==} '@tsconfig/node12@1.0.11': resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} @@ -2907,8 +3157,8 @@ packages: '@tsconfig/node16@1.0.4': resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - '@tybys/wasm-util@0.9.0': - resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} '@typechain/ethers-v5@11.1.2': resolution: {integrity: sha512-ID6pqWkao54EuUQa0P5RgjvfA3MYqxUQKpbGKERbsjBW5Ra7EIXvbMlPp2pcP5IAdUkyMCFYsP2SN5q7mPdLDQ==} @@ -2922,17 +3172,17 @@ packages: '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - '@types/babel__generator@7.6.8': - resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} '@types/babel__template@7.4.4': resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - '@types/babel__traverse@7.20.7': - resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} - '@types/body-parser@1.19.5': - resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + '@types/body-parser@1.19.6': + resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} '@types/bonjour@3.5.13': resolution: {integrity: sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==} @@ -2940,14 +3190,17 @@ packages: '@types/cacheable-request@6.0.3': resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + '@types/connect-history-api-fallback@1.5.4': resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==} '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - '@types/conventional-commits-parser@5.0.1': - resolution: {integrity: sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==} + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} '@types/deep-equal@1.0.4': resolution: {integrity: sha512-tqdiS4otQP4KmY0PR3u6KbZ5EWvhNdUoS/jc93UuK23C220lOZ/9TvjfxdPcKvqwwDVtmtSCrnr0p/2dirAxkA==} @@ -2964,23 +3217,14 @@ packages: '@types/estree@0.0.39': resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} - '@types/estree@1.0.6': - resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} - - '@types/estree@1.0.7': - resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} - '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - '@types/express-serve-static-core@4.19.6': - resolution: {integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==} - - '@types/express-serve-static-core@5.0.6': - resolution: {integrity: sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==} + '@types/express-serve-static-core@4.19.8': + resolution: {integrity: sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==} - '@types/express@4.17.21': - resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + '@types/express@4.17.25': + resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} '@types/graceful-fs@4.1.9': resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} @@ -2988,14 +3232,14 @@ packages: '@types/html-minifier-terser@6.1.0': resolution: {integrity: sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==} - '@types/http-cache-semantics@4.0.4': - resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + '@types/http-cache-semantics@4.2.0': + resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} - '@types/http-errors@2.0.4': - resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + '@types/http-errors@2.0.5': + resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} - '@types/http-proxy@1.17.16': - resolution: {integrity: sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==} + '@types/http-proxy@1.17.17': + resolution: {integrity: sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==} '@types/istanbul-lib-coverage@2.0.6': resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} @@ -3015,8 +3259,8 @@ packages: '@types/keyv@3.1.4': resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} - '@types/lodash@4.17.16': - resolution: {integrity: sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==} + '@types/lodash@4.17.24': + resolution: {integrity: sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==} '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} @@ -3024,8 +3268,8 @@ packages: '@types/minimist@1.2.5': resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} - '@types/node-forge@1.3.11': - resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} + '@types/node-forge@1.3.14': + resolution: {integrity: sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==} '@types/node@11.11.6': resolution: {integrity: sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==} @@ -3045,14 +3289,14 @@ packages: '@types/prettier@2.7.3': resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} - '@types/prop-types@15.7.14': - resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} + '@types/prop-types@15.7.15': + resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} '@types/q@1.5.8': resolution: {integrity: sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==} - '@types/qs@6.9.18': - resolution: {integrity: sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==} + '@types/qs@6.15.0': + resolution: {integrity: sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==} '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} @@ -3063,13 +3307,13 @@ packages: '@types/react-dom@18.3.0': resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==} - '@types/react-dom@18.3.5': - resolution: {integrity: sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==} + '@types/react-dom@18.3.7': + resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} peerDependencies: '@types/react': ^18.0.0 - '@types/react@18.3.20': - resolution: {integrity: sha512-IPaCZN7PShZK/3t6Q87pfTkRm6oLTd4vztyoj+cbHUF1g3FfVb2tFIL79uCRKEfv16AhqDMBywP2VW3KIZUvcg==} + '@types/react@18.3.28': + resolution: {integrity: sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==} '@types/react@18.3.5': resolution: {integrity: sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA==} @@ -3086,17 +3330,20 @@ packages: '@types/retry@0.12.2': resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} - '@types/semver@7.7.0': - resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==} + '@types/semver@7.7.1': + resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} - '@types/send@0.17.4': - resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + '@types/send@0.17.6': + resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==} + + '@types/send@1.2.1': + resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} '@types/serve-index@1.9.4': resolution: {integrity: sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==} - '@types/serve-static@1.15.7': - resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} + '@types/serve-static@1.15.10': + resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} '@types/sockjs@0.3.36': resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==} @@ -3110,23 +3357,23 @@ packages: '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} - '@types/uuid@8.3.4': - resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==} + '@types/uuid@10.0.0': + resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} '@types/ws@7.4.7': resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} - '@types/ws@8.18.0': - resolution: {integrity: sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw==} + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - '@types/yargs@16.0.9': - resolution: {integrity: sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==} + '@types/yargs@16.0.11': + resolution: {integrity: sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==} - '@types/yargs@17.0.33': - resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} + '@types/yargs@17.0.35': + resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} '@typescript-eslint/eslint-plugin@5.62.0': resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==} @@ -3253,82 +3500,110 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - '@uniswap/token-lists@1.0.0-beta.34': - resolution: {integrity: sha512-Hc3TfrFaupg0M84e/Zv7BoF+fmMWDV15mZ5s8ZQt2qZxUcNw2GQW+L6L/2k74who31G+p1m3GRYbJpAo7d1pqA==} + '@uniswap/token-lists@1.0.0-beta.35': + resolution: {integrity: sha512-v43brw8Fx+D904fOCXL5kTU75cIPH40U/WTKB96K1gxOibk2jVsxW3AULBE5Buj5dJpeVwj/l6TNgB6QPw7lJg==} engines: {node: '>=10'} - '@unrs/resolver-binding-darwin-arm64@1.3.2': - resolution: {integrity: sha512-ddnlXgRi0Fog5+7U5Q1qY62wl95Q1lB4tXQX1UIA9YHmRCHN2twaQW0/4tDVGCvTVEU3xEayU7VemEr7GcBYUw==} + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.11.1': + resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} cpu: [arm64] os: [darwin] - '@unrs/resolver-binding-darwin-x64@1.3.2': - resolution: {integrity: sha512-tnl9xoEeg503jis+LW5cuq4hyLGQyqaoBL8VdPSqcewo/FL1C8POHbzl+AL25TidWYJD+R6bGUTE381kA1sT9w==} + '@unrs/resolver-binding-darwin-x64@1.11.1': + resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} cpu: [x64] os: [darwin] - '@unrs/resolver-binding-freebsd-x64@1.3.2': - resolution: {integrity: sha512-zyPn9LFCCjhKPeCtECZaiMUgkYN/VpLb4a9Xv7QriJmTaQxsuDtXqOHifrzUXIhorJTyS+5MOKDuNL0X9I4EHA==} + '@unrs/resolver-binding-freebsd-x64@1.11.1': + resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} cpu: [x64] os: [freebsd] - '@unrs/resolver-binding-linux-arm-gnueabihf@1.3.2': - resolution: {integrity: sha512-UWx56Wh59Ro69fe+Wfvld4E1n9KG0e3zeouWLn8eSasyi/yVH/7ZW3CLTVFQ81oMKSpXwr5u6RpzttDXZKiO4g==} + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} cpu: [arm] os: [linux] - '@unrs/resolver-binding-linux-arm-musleabihf@1.3.2': - resolution: {integrity: sha512-VYGQXsOEJtfaoY2fOm8Z9ii5idFaHFYlrq3yMFZPaFKo8ufOXYm8hnfru7qetbM9MX116iWaPC0ZX5sK+1Dr+g==} + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} cpu: [arm] os: [linux] - '@unrs/resolver-binding-linux-arm64-gnu@1.3.2': - resolution: {integrity: sha512-3zP420zxJfYPD1rGp2/OTIBxF8E3+/6VqCG+DEO6kkDgBiloa7Y8pw1o7N9BfgAC+VC8FPZsFXhV2lpx+lLRMQ==} + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} cpu: [arm64] os: [linux] + libc: [glibc] - '@unrs/resolver-binding-linux-arm64-musl@1.3.2': - resolution: {integrity: sha512-ZWjSleUgr88H4Kei7yT4PlPqySTuWN1OYDDcdbmMCtLWFly3ed+rkrcCb3gvqXdDbYrGOtzv3g2qPEN+WWNv5Q==} + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} cpu: [arm64] os: [linux] + libc: [musl] - '@unrs/resolver-binding-linux-ppc64-gnu@1.3.2': - resolution: {integrity: sha512-p+5OvYJ2UOlpjes3WfBlxyvQok2u26hLyPxLFHkYlfzhZW0juhvBf/tvewz1LDFe30M7zL9cF4OOO5dcvtk+cw==} + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} cpu: [ppc64] os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} + cpu: [riscv64] + os: [linux] + libc: [musl] - '@unrs/resolver-binding-linux-s390x-gnu@1.3.2': - resolution: {integrity: sha512-yweY7I6SqNn3kvj6vE4PQRo7j8Oz6+NiUhmgciBNAUOuI3Jq0bnW29hbHJdxZRSN1kYkQnSkbbA1tT8VnK816w==} + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} cpu: [s390x] os: [linux] + libc: [glibc] - '@unrs/resolver-binding-linux-x64-gnu@1.3.2': - resolution: {integrity: sha512-fNIvtzJcGN9hzWTIayrTSk2+KHQrqKbbY+I88xMVMOFV9t4AXha4veJdKaIuuks+2JNr6GuuNdsL7+exywZ32w==} + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} cpu: [x64] os: [linux] + libc: [glibc] - '@unrs/resolver-binding-linux-x64-musl@1.3.2': - resolution: {integrity: sha512-OaFEw8WAjiwBGxutQgkWhoAGB5BQqZJ8Gjt/mW+m6DWNjimcxU22uWCuEtfw1CIwLlKPOzsgH0429fWmZcTGkg==} + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} cpu: [x64] os: [linux] + libc: [musl] - '@unrs/resolver-binding-wasm32-wasi@1.3.2': - resolution: {integrity: sha512-u+sumtO7M0AGQ9bNQrF4BHNpUyxo23FM/yXZfmVAicTQ+mXtG06O7pm5zQUw3Mr4jRs2I84uh4O0hd8bdouuvQ==} + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@unrs/resolver-binding-win32-arm64-msvc@1.3.2': - resolution: {integrity: sha512-ZAJKy95vmDIHsRFuPNqPQRON8r2mSMf3p9DoX+OMOhvu2c8OXGg8MvhGRf3PNg45ozRrPdXDnngURKgaFfpGoQ==} + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} cpu: [arm64] os: [win32] - '@unrs/resolver-binding-win32-ia32-msvc@1.3.2': - resolution: {integrity: sha512-nQG4YFAS2BLoKVQFK/FrWJvFATI5DQUWQrcPcsWG9Ve5BLLHZuPOrJ2SpAJwLXQrRv6XHSFAYGI8wQpBg/CiFA==} + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} cpu: [ia32] os: [win32] - '@unrs/resolver-binding-win32-x64-msvc@1.3.2': - resolution: {integrity: sha512-XBWpUP0mHya6yGBwNefhyEa6V7HgYKCxEAY4qhTm/PcAQyBPNmjj97VZJOJkVdUsyuuii7xmq0pXWX/c2aToHQ==} + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} cpu: [x64] os: [win32] @@ -3348,34 +3623,34 @@ packages: '@vitest/browser': optional: true - '@vitest/expect@3.0.9': - resolution: {integrity: sha512-5eCqRItYgIML7NNVgJj6TVCmdzE7ZVgJhruW0ziSQV4V7PvLkDL1bBkBdcTs/VuIz0IxPb5da1IDSqc1TR9eig==} + '@vitest/expect@3.2.4': + resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} - '@vitest/mocker@3.0.9': - resolution: {integrity: sha512-ryERPIBOnvevAkTq+L1lD+DTFBRcjueL9lOUfXsLfwP92h4e+Heb+PjiqS3/OURWPtywfafK0kj++yDFjWUmrA==} + '@vitest/mocker@3.2.4': + resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} peerDependencies: msw: ^2.4.9 - vite: ^5.0.0 || ^6.0.0 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 peerDependenciesMeta: msw: optional: true vite: optional: true - '@vitest/pretty-format@3.0.9': - resolution: {integrity: sha512-OW9F8t2J3AwFEwENg3yMyKWweF7oRJlMyHOMIhO5F3n0+cgQAJZBjNgrF8dLwFTEXl5jUqBLXd9QyyKv8zEcmA==} + '@vitest/pretty-format@3.2.4': + resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} - '@vitest/runner@3.0.9': - resolution: {integrity: sha512-NX9oUXgF9HPfJSwl8tUZCMP1oGx2+Sf+ru6d05QjzQz4OwWg0psEzwY6VexP2tTHWdOkhKHUIZH+fS6nA7jfOw==} + '@vitest/runner@3.2.4': + resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} - '@vitest/snapshot@3.0.9': - resolution: {integrity: sha512-AiLUiuZ0FuA+/8i19mTYd+re5jqjEc2jZbgJ2up0VY0Ddyyxg/uUtBDpIFAy4uzKaQxOW8gMgBdAJJ2ydhu39A==} + '@vitest/snapshot@3.2.4': + resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} - '@vitest/spy@3.0.9': - resolution: {integrity: sha512-/CcK2UDl0aQ2wtkp3YVWldrpLRNCfVcIOFGlVGKO4R5eajsH393Z1yiXLVQ7vWsj26JOEjeZI0x5sm5P4OGUNQ==} + '@vitest/spy@3.2.4': + resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} - '@vitest/utils@3.0.9': - resolution: {integrity: sha512-ilHM5fHhZ89MCp5aAaM9uhfl1c2JdxVxl3McqsdVyVNN6JffnEen8UMCdRTzOhGXNQGo5GNL9QugHrz727Wnng==} + '@vitest/utils@3.2.4': + resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -3483,8 +3758,8 @@ packages: resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} engines: {node: '>=0.4.0'} - acorn-walk@8.3.4: - resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + acorn-walk@8.3.5: + resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} engines: {node: '>=0.4.0'} acorn@7.4.1: @@ -3492,13 +3767,8 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - acorn@8.14.1: - resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} - engines: {node: '>=0.4.0'} - hasBin: true - - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} engines: {node: '>=0.4.0'} hasBin: true @@ -3542,11 +3812,11 @@ packages: peerDependencies: ajv: ^8.8.2 - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@6.14.0: + resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} - ajv@8.17.1: - resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + ajv@8.18.0: + resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} algo-msgpack-with-bigint@2.1.1: resolution: {integrity: sha512-F1tGh056XczEaEAqu7s+hlZUDWwOBT70Eq0lfMpBP2YguSQVyxRbprLq5rELXKQOyOaixTWYhMeMQMzP0U5FoQ==} @@ -3556,8 +3826,8 @@ packages: resolution: {integrity: sha512-9moZxdqeJ6GdE4N6fA/GlUP4LrbLZMYcYkt141J4Ss68OfEgH9qW0wBuZ3ZOKEx/xjc5bg7mLP2Gjg7nwrkmww==} engines: {node: '>=14.0.0'} - anser@2.3.2: - resolution: {integrity: sha512-PMqBCBvrOVDRqLGooQb+z+t1Q0PiPyurUQeZRR5uHBOVZcW8B04KMmnT12USnhpNX2wCPagWzLVppQMUG3u0Dw==} + anser@2.3.5: + resolution: {integrity: sha512-vcZjxvvVoxTeR5XBNJB38oTu/7eDCZlwdz32N1eNgpyPF7j/Z7Idf+CUwQOkKKpJ7RJyjxgLHCM7vdIK0iCNMQ==} ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} @@ -3581,8 +3851,8 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.1.0: - resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} engines: {node: '>=12'} ansi-sequence-parser@1.1.3: @@ -3600,8 +3870,8 @@ packages: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} any-promise@1.3.0: @@ -3654,8 +3924,8 @@ packages: array-ify@1.0.0: resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} - array-includes@3.1.8: - resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + array-includes@3.1.9: + resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} engines: {node: '>= 0.4'} array-union@2.1.0: @@ -3699,8 +3969,8 @@ packages: peerDependencies: arweave: ^1.10.0 - arweave@1.15.0: - resolution: {integrity: sha512-sYfq2yJwkJLthRADsfHygNP+L7fTCyprTjOLYnpP8zaqwywddoNO3UpTk6XGjEiyyU3WfxoFLRLpzx+llZx1WA==} + arweave@1.15.7: + resolution: {integrity: sha512-F+Y4iWU1qea9IsKQ/YNmLsY4DHQVsaJBuhEbFxQn9cfGHOmtXE+bwo14oY8xqymsqSNf/e1PeIfLk7G7qN/hVA==} engines: {node: '>=18'} asap@2.0.6: @@ -3712,6 +3982,10 @@ packages: asn1.js@5.4.1: resolution: {integrity: sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==} + asn1js@3.0.7: + resolution: {integrity: sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ==} + engines: {node: '>=12.0.0'} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -3719,8 +3993,8 @@ packages: ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} - ast-v8-to-istanbul@0.3.5: - resolution: {integrity: sha512-9SdXjNheSiE8bALAQCQQuT6fgQaoxJh7IRYrRGZ8/9nv8WhJeC1aXAwN8TbaOssGOukUvyvnkgD9+Yuykvl1aA==} + ast-v8-to-istanbul@0.3.12: + resolution: {integrity: sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g==} async-function@1.0.0: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} @@ -3739,8 +4013,8 @@ packages: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} - autoprefixer@10.4.21: - resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==} + autoprefixer@10.4.27: + resolution: {integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: @@ -3750,8 +4024,8 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axe-core@4.10.3: - resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} + axe-core@4.11.2: + resolution: {integrity: sha512-byD6KPdvo72y/wj2T/4zGEvvlis+PsZsn/yPS3pEO+sFpcrqRpX/TJCxvVaEsNeMrfQbCr7w163YqoD9IYwHXw==} engines: {node: '>=4'} axios-retry@4.5.0: @@ -3759,11 +4033,8 @@ packages: peerDependencies: axios: 0.x || 1.x - axios@1.11.0: - resolution: {integrity: sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==} - - axios@1.8.4: - resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==} + axios@1.15.0: + resolution: {integrity: sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==} axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} @@ -3799,28 +4070,33 @@ packages: peerDependencies: '@babel/core': ^7.1.0 - babel-plugin-polyfill-corejs2@0.4.13: - resolution: {integrity: sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g==} + babel-plugin-polyfill-corejs2@0.4.17: + resolution: {integrity: sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-corejs3@0.13.0: + resolution: {integrity: sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-corejs3@0.11.1: - resolution: {integrity: sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==} + babel-plugin-polyfill-corejs3@0.14.2: + resolution: {integrity: sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-regenerator@0.6.4: - resolution: {integrity: sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw==} + babel-plugin-polyfill-regenerator@0.6.8: + resolution: {integrity: sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 babel-plugin-transform-react-remove-prop-types@0.4.24: resolution: {integrity: sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==} - babel-preset-current-node-syntax@1.1.0: - resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} + babel-preset-current-node-syntax@1.2.0: + resolution: {integrity: sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==} peerDependencies: - '@babel/core': ^7.0.0 + '@babel/core': ^7.0.0 || ^8.0.0-0 babel-preset-jest@27.5.1: resolution: {integrity: sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==} @@ -3834,6 +4110,10 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + base-x@3.0.11: resolution: {integrity: sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==} @@ -3847,6 +4127,11 @@ packages: resolution: {integrity: sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==} engines: {node: '>=6.0.0'} + baseline-browser-mapping@2.10.17: + resolution: {integrity: sha512-HdrkN8eVG2CXxeifv/VdJ4A4RSra1DTW8dc/hdxzhGHN8QePs6gKaWM9pHPcpCoxYZJuOZ8drHmbdpLHjCYjLA==} + engines: {node: '>=6.0.0'} + hasBin: true + batch@0.6.1: resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} @@ -3864,13 +4149,6 @@ packages: big.js@5.2.2: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} - bigint-buffer@1.1.5: - resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} - engines: {node: '>= 10.0.0'} - - bignumber.js@9.1.2: - resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} - bignumber.js@9.3.1: resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} @@ -3878,9 +4156,6 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - bip39-light@1.0.7: resolution: {integrity: sha512-WDTmLRQUsiioBdTs9BmSEmkJza+8xfJmptsNJjxnoq3EydSa/ZBXT6rm66KoT3PJIRYMnhSKNR7S9YL1l7R40Q==} @@ -3893,14 +4168,17 @@ packages: bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} - bn.js@4.12.1: - resolution: {integrity: sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==} + bn.js@4.12.3: + resolution: {integrity: sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==} bn.js@5.2.1: resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} - body-parser@1.20.3: - resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} + bn.js@5.2.3: + resolution: {integrity: sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==} + + body-parser@1.20.4: + resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} bonjour-service@1.3.0: @@ -3909,14 +4187,22 @@ packages: boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + boolbase@2.0.0: + resolution: {integrity: sha512-DkVaaQHymRhpYEYo9x1oo7Q7B0Y6KJUsjm3c9eTyFDby4MHLBTwZ6ZDWBel5zrYxj1WsZgC5oLpiz+93MluXeA==} + engines: {node: '>=20.19.0'} + borsh@0.7.0: resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + brace-expansion@1.1.13: + resolution: {integrity: sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==} + + brace-expansion@2.0.3: + resolution: {integrity: sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==} - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + brace-expansion@5.0.5: + resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} + engines: {node: 18 || 20 || >=22} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} @@ -3945,12 +4231,12 @@ packages: resolution: {integrity: sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==} engines: {node: '>= 0.10'} - browserify-sign@4.2.3: - resolution: {integrity: sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==} - engines: {node: '>= 0.12'} + browserify-sign@4.2.5: + resolution: {integrity: sha512-C2AUdAJg6rlM2W5QMp2Q4KGQMVBwR1lIimTsUnutJ8bMpW5B52pGpR2gEnNBNwijumDo5FojQ0L9JrXA8m4YEw==} + engines: {node: '>= 0.10'} - browserslist@4.24.4: - resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -3975,8 +4261,8 @@ packages: buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - bufferutil@4.0.9: - resolution: {integrity: sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==} + bufferutil@4.1.0: + resolution: {integrity: sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw==} engines: {node: '>=6.14.2'} builtin-modules@3.3.0: @@ -4010,6 +4296,10 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} + bytestreamjs@2.0.1: + resolution: {integrity: sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==} + engines: {node: '>=6.0.0'} + cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -4030,8 +4320,8 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} - call-bind@1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} engines: {node: '>= 0.4'} call-bound@1.0.4: @@ -4064,16 +4354,16 @@ packages: caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - caniuse-lite@1.0.30001707: - resolution: {integrity: sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==} + caniuse-lite@1.0.30001787: + resolution: {integrity: sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg==} case-sensitive-paths-webpack-plugin@2.4.0: resolution: {integrity: sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==} engines: {node: '>=4'} - chai@5.2.0: - resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} - engines: {node: '>=12'} + chai@5.3.3: + resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} + engines: {node: '>=18'} chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} @@ -4083,8 +4373,8 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - chalk@5.4.1: - resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} char-regex@1.0.2: @@ -4098,8 +4388,11 @@ packages: chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - check-error@2.1.1: - resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + chardet@2.1.1: + resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} + + check-error@2.1.3: + resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} engines: {node: '>= 16'} check-types@11.2.3: @@ -4117,8 +4410,8 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - cipher-base@1.0.6: - resolution: {integrity: sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==} + cipher-base@1.0.7: + resolution: {integrity: sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==} engines: {node: '>= 0.10'} cjs-module-lexer@1.4.3: @@ -4165,8 +4458,8 @@ packages: resolution: {integrity: sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==} engines: {node: '>= 4.0'} - collect-v8-coverage@1.0.2: - resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + collect-v8-coverage@1.0.3: + resolution: {integrity: sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==} color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -4181,13 +4474,6 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - color-string@1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} - - color@4.2.3: - resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} - engines: {node: '>=12.5.0'} - colord@2.9.3: resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} @@ -4218,6 +4504,10 @@ packages: resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} engines: {node: '>=18'} + commander@14.0.3: + resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} + engines: {node: '>=20'} + commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -4252,8 +4542,8 @@ packages: resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} engines: {node: '>= 0.6'} - compression@1.8.0: - resolution: {integrity: sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==} + compression@1.8.1: + resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==} engines: {node: '>= 0.8.0'} concat-map@0.0.1: @@ -4346,6 +4636,11 @@ packages: engines: {node: '>=10'} hasBin: true + conventional-commits-parser@6.4.0: + resolution: {integrity: sha512-tvRg7FIBNlyPzjdG8wWRlPHQJJHI7DylhtRGeU9Lq+JuoPh5BKpPRX83ZdLrvXuOSu5Eo/e7SzOQhU4Hd2Miuw==} + engines: {node: '>=18'} + hasBin: true + conventional-recommended-bump@6.1.0: resolution: {integrity: sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==} engines: {node: '>=10'} @@ -4357,11 +4652,11 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - cookie-signature@1.0.6: - resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + cookie-signature@1.0.7: + resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} - cookie@0.7.1: - resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} copy-to-clipboard@3.3.3: @@ -4373,20 +4668,20 @@ packages: peerDependencies: webpack: ^5.1.0 - core-js-compat@3.41.0: - resolution: {integrity: sha512-RFsU9LySVue9RTwdDVX/T0e2Y6jRYWXERKElIjpuEOEnxaXffI0X7RUwVzfYLfzuLXSNJDYoRYUAmRUcyln20A==} + core-js-compat@3.49.0: + resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} - core-js-pure@3.41.0: - resolution: {integrity: sha512-71Gzp96T9YPk63aUvE5Q5qP+DryB4ZloUZPSOebGM88VNw8VNfvdA7z6kGA8iGOTEzAomsRidp4jXSmUIJsL+Q==} + core-js-pure@3.49.0: + resolution: {integrity: sha512-XM4RFka59xATyJv/cS3O3Kml72hQXUeGRuuTmMYFxwzc9/7C8OYTaIR/Ji+Yt8DXzsFLNhat15cE/JP15HrCgw==} - core-js@3.41.0: - resolution: {integrity: sha512-SJ4/EHwS36QMJd6h/Rg+GyR4A5xE0FSI3eZ+iBVpfqf1x0eTSg1smWLHrA+2jQThZSh97fmSgFSU8B61nxosxA==} + core-js@3.49.0: + resolution: {integrity: sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==} core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - cosmiconfig-typescript-loader@6.1.0: - resolution: {integrity: sha512-tJ1w35ZRUiM5FeTzT7DtYWAFFv37ZLqSRkGi2oeCK1gPhvaWjkAtfXvLmvE1pRfxxp9aQo6ba/Pvg1dKj05D4g==} + cosmiconfig-typescript-loader@6.3.0: + resolution: {integrity: sha512-Akr82WH1Wfqatyiqpj8HDkO2o2KmJRu1FhKfSNJP3K4IdXwHfEyL7MOb62i1AGQVLtIQM+iCE9CGOtrfhR+mmA==} engines: {node: '>=v18'} peerDependencies: '@types/node': '*' @@ -4410,8 +4705,8 @@ packages: typescript: optional: true - cosmiconfig@9.0.0: - resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + cosmiconfig@9.0.1: + resolution: {integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==} engines: {node: '>=14'} peerDependencies: typescript: '>=4.9.5' @@ -4529,8 +4824,8 @@ packages: resolution: {integrity: sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==} engines: {node: '>= 6'} - css-what@6.1.0: - resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} engines: {node: '>= 6'} cssdb@7.11.2: @@ -4573,8 +4868,8 @@ packages: resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} engines: {node: '>=8'} - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} csv-generate@3.4.3: resolution: {integrity: sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==} @@ -4635,17 +4930,8 @@ packages: supports-color: optional: true - debug@4.4.0: - resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -4661,8 +4947,8 @@ packages: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} - decimal.js@10.5.0: - resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==} + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} decompress-response@6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} @@ -4690,12 +4976,12 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} - default-browser-id@5.0.0: - resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} engines: {node: '>=18'} - default-browser@5.2.1: - resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} + default-browser@5.5.0: + resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} engines: {node: '>=18'} default-gateway@6.0.3: @@ -4756,12 +5042,12 @@ packages: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} - detect-indent@7.0.1: - resolution: {integrity: sha512-Mc7QhQ8s+cLrnUfU/Ji94vG/r8M26m8f++vyres4ZoojaRDpZ1eSIh/EpzLNwlWuvzSZ3UbDFspjFvTDXe6e/g==} + detect-indent@7.0.2: + resolution: {integrity: sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==} engines: {node: '>=12.20'} - detect-libc@2.0.4: - resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} detect-newline@3.1.0: @@ -4787,8 +5073,8 @@ packages: resolution: {integrity: sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} - diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + diff@4.0.4: + resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==} engines: {node: '>=0.3.1'} diffie-hellman@5.0.3: @@ -4857,10 +5143,6 @@ packages: resolution: {integrity: sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==} engines: {node: '>=10'} - dotenv@16.4.7: - resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} - engines: {node: '>=12'} - dotenv@16.6.1: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} @@ -4890,8 +5172,8 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electron-to-chromium@1.5.128: - resolution: {integrity: sha512-bo1A4HH/NS522Ws0QNFIzyPcyUUNV/yyy70Ho1xqfGYzPUme2F/xr4tlEOuM6/A538U1vDA7a4XfCd1CKRegKQ==} + electron-to-chromium@1.5.334: + resolution: {integrity: sha512-mgjZAz7Jyx1SRCwEpy9wefDS7GvNPazLthHg8eQMJ76wBdGQQDW33TCrUTvQ4wzpmOrv2zrFoD3oNufMdyMpog==} elliptic@6.6.1: resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} @@ -4917,10 +5199,6 @@ packages: resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} engines: {node: '>= 4'} - encodeurl@1.0.2: - resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} - engines: {node: '>= 0.8'} - encodeurl@2.0.0: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} @@ -4928,8 +5206,8 @@ packages: end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - enhanced-resolve@5.18.1: - resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + enhanced-resolve@5.20.1: + resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} engines: {node: '>=10.13.0'} enquirer@2.4.1: @@ -4943,19 +5221,19 @@ packages: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} - envinfo@7.14.0: - resolution: {integrity: sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==} + envinfo@7.21.0: + resolution: {integrity: sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==} engines: {node: '>=4'} hasBin: true - error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} error-stack-parser@2.1.4: resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} - es-abstract@1.23.9: - resolution: {integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==} + es-abstract@1.24.2: + resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==} engines: {node: '>= 0.4'} es-array-method-boxes-properly@1.0.0: @@ -4972,12 +5250,15 @@ packages: es-get-iterator@1.1.3: resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} - es-iterator-helpers@1.2.1: - resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} + es-iterator-helpers@1.3.2: + resolution: {integrity: sha512-HVLACW1TppGYjJ8H6/jqH/pqOtKRw6wMlrB23xfExmFWxFquAIWCmwoLsOyN96K4a5KbmOf5At9ZUO3GZbetAw==} engines: {node: '>= 0.4'} - es-module-lexer@1.6.0: - resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + es-module-lexer@2.0.0: + resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} @@ -5016,8 +5297,8 @@ packages: engines: {node: '>=12'} hasBin: true - esbuild@0.25.1: - resolution: {integrity: sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==} + esbuild@0.27.7: + resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} engines: {node: '>=18'} hasBin: true @@ -5059,8 +5340,8 @@ packages: typescript: optional: true - eslint-config-prettier@9.1.0: - resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + eslint-config-prettier@9.1.2: + resolution: {integrity: sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==} hasBin: true peerDependencies: eslint: '>=7.0.0' @@ -5081,11 +5362,11 @@ packages: '@typescript-eslint/eslint-plugin': ^5 eslint-plugin-sonarjs: '*' - eslint-import-resolver-node@0.3.9: - resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + eslint-import-resolver-node@0.3.10: + resolution: {integrity: sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==} - eslint-import-resolver-typescript@3.10.0: - resolution: {integrity: sha512-aV3/dVsT0/H9BtpNwbaqvl+0xGMRGzncLyhm793NFGvbwGGvzyAykqWZ8oZlZuGwuHkwJjhWJkG1cM3ynvd2pQ==} + eslint-import-resolver-typescript@3.10.1: + resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -5097,8 +5378,8 @@ packages: eslint-plugin-import-x: optional: true - eslint-module-utils@2.12.0: - resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} + eslint-module-utils@2.12.1: + resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -5132,8 +5413,8 @@ packages: '@babel/plugin-transform-react-jsx': ^7.14.9 eslint: ^8.1.0 - eslint-plugin-import@2.31.0: - resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} + eslint-plugin-import@2.32.0: + resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -5177,8 +5458,8 @@ packages: peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - eslint-plugin-react@7.37.4: - resolution: {integrity: sha512-BGP0jRmfYyvOyvMoRX/uoUeW+GqNj9y16bPQzqAHf3AYII/tDs+jMN0dBVkl88/OZwNGwrVFxE7riHsXVfy/LQ==} + eslint-plugin-react@7.37.5: + resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} engines: {node: '>=4'} peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 @@ -5188,11 +5469,10 @@ packages: peerDependencies: eslint: '>=5.0.0' - eslint-plugin-sonarjs@0.23.0: - resolution: {integrity: sha512-z44T3PBf9W7qQ/aR+NmofOTyg6HLhSEZOPD4zhStqBpLoMp8GYhFksuUBnCxbnf1nfISpKBVkQhiBLFI/F4Wlg==} - engines: {node: '>=14'} + eslint-plugin-sonarjs@4.0.2: + resolution: {integrity: sha512-BTcT1zr1iTbmJtVlcesISwnXzh+9uhf9LEOr+RRNf4kR8xA0HQTPft4oiyOCzCOGKkpSJxjR8ZYF6H7VPyplyw==} peerDependencies: - eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint: ^8.0.0 || ^9.0.0 || ^10.0.0 eslint-plugin-testing-library@5.11.1: resolution: {integrity: sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw==} @@ -5200,11 +5480,11 @@ packages: peerDependencies: eslint: ^7.5.0 || ^8.0.0 - eslint-plugin-unused-imports@4.2.0: - resolution: {integrity: sha512-hLbJ2/wnjKq4kGA9AUaExVFIbNzyxYdVo49QZmKCnhk5pc9wcYRbfgLHvWJ8tnsdcseGhoUAddm9gn/lt+d74w==} + eslint-plugin-unused-imports@4.4.1: + resolution: {integrity: sha512-oZGYUz1X3sRMGUB+0cZyK2VcvRX5lm/vB56PgNNcU+7ficUCKm66oZWKUubXWnOuPjQ8PvmXtCViXBMONPe7tQ==} peerDependencies: '@typescript-eslint/eslint-plugin': ^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0 - eslint: ^9.0.0 || ^8.0.0 + eslint: ^10.0.0 || ^9.0.0 || ^8.0.0 peerDependenciesMeta: '@typescript-eslint/eslint-plugin': optional: true @@ -5248,8 +5528,8 @@ packages: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - esprima@1.2.2: - resolution: {integrity: sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==} + esprima@1.2.5: + resolution: {integrity: sha512-S9VbPDU0adFErpDai3qDkjq8+G05ONtKzcyNrPKg/ZKa+tf879nX2KexNU95b31UoTJjRLInNBHHHjFPoCd7lQ==} engines: {node: '>=0.4.0'} hasBin: true @@ -5258,8 +5538,8 @@ packages: engines: {node: '>=4'} hasBin: true - esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} esrecurse@4.3.0: @@ -5294,8 +5574,8 @@ packages: eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} - eventemitter3@5.0.1: - resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} @@ -5316,19 +5596,19 @@ packages: resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==} engines: {node: '>=0.10.0'} - expect-type@1.2.0: - resolution: {integrity: sha512-80F22aiJ3GLyVnS/B3HzgR6RelZVumzj9jkL0Rhz4h0xYbNW9PjlQz5h3J/SShErbXBc295vseR4/MIbVmUbeA==} + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} expect@27.5.1: resolution: {integrity: sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} - exponential-backoff@3.1.2: - resolution: {integrity: sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==} + exponential-backoff@3.1.3: + resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} - express@4.21.2: - resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} + express@4.22.1: + resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==} engines: {node: '>= 0.10.0'} extendable-error@0.1.7: @@ -5358,15 +5638,15 @@ packages: fast-stable-stringify@1.0.0: resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} - fast-uri@3.0.6: - resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} fastest-levenshtein@1.0.16: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} engines: {node: '>= 4.9.1'} - fastq@1.19.1: - resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} faye-websocket@0.11.4: resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} @@ -5375,8 +5655,9 @@ packages: fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} - fdir@6.4.3: - resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -5406,11 +5687,8 @@ packages: peerDependencies: webpack: ^4.0.0 || ^5.0.0 - file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - - filelist@1.0.4: - resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + filelist@1.0.6: + resolution: {integrity: sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==} filename-reserved-regex@2.0.0: resolution: {integrity: sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==} @@ -5428,8 +5706,8 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - finalhandler@1.3.1: - resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} + finalhandler@1.3.2: + resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} engines: {node: '>= 0.8'} find-cache-dir@3.3.2: @@ -5474,11 +5752,11 @@ packages: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} - follow-redirects@1.15.9: - resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -5508,24 +5786,20 @@ packages: vue-template-compiler: optional: true - form-data@3.0.3: - resolution: {integrity: sha512-q5YBMeWy6E2Un0nMGWMgI65MAKtaylxfNJGJxpGh45YDciZB4epbWpaAfImil6CPAPTYB4sh0URQNDRIZG5F2w==} - engines: {node: '>= 6'} - - form-data@4.0.2: - resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} + form-data@3.0.4: + resolution: {integrity: sha512-f0cRzm6dkyVYV3nPoooP8XlccPQukegwhAnpoLcXy+X+A8KfpGOoXwDr9FLZd3wzgLaBGQBE3lY93Zm/i1JvIQ==} engines: {node: '>= 6'} - form-data@4.0.4: - resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} engines: {node: '>= 6'} forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} - fraction.js@4.3.7: - resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + fraction.js@5.3.4: + resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} @@ -5535,8 +5809,8 @@ packages: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} - fs-extra@11.3.0: - resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==} + fs-extra@11.3.4: + resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==} engines: {node: '>=14.14'} fs-extra@7.0.1: @@ -5551,8 +5825,8 @@ packages: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} - fs-monkey@1.0.6: - resolution: {integrity: sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==} + fs-monkey@1.1.0: + resolution: {integrity: sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw==} fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -5569,9 +5843,16 @@ packages: resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} engines: {node: '>= 0.4'} + functional-red-black-tree@1.0.1: + resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} + functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -5616,8 +5897,8 @@ packages: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} - get-tsconfig@4.10.0: - resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} + get-tsconfig@4.13.7: + resolution: {integrity: sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==} gh-pages@6.3.0: resolution: {integrity: sha512-Ot5lU6jK0Eb+sszG8pciXdjMXdBJ5wODvgjR+imihTqsUWF2K6dJ9HST55lgqcs8wWcw6o6wAsUzfcYRhJPXbA==} @@ -5630,6 +5911,7 @@ packages: git-raw-commits@2.0.11: resolution: {integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==} engines: {node: '>=10'} + deprecated: This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead. hasBin: true git-remote-origin-url@2.0.0: @@ -5639,6 +5921,7 @@ packages: git-semver-tags@4.1.1: resolution: {integrity: sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==} engines: {node: '>=10'} + deprecated: This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead. hasBin: true gitconfiglocal@1.0.0: @@ -5652,8 +5935,8 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob-to-regex.js@1.0.1: - resolution: {integrity: sha512-CG/iEvgQqfzoVsMUbxSJcwbG2JwyZ3naEqPkeltwl0BSS8Bp83k3xlGms+0QdWFUAwV+uvo80wNswKF6FWEkKg==} + glob-to-regex.js@1.2.0: + resolution: {integrity: sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -5661,22 +5944,24 @@ packages: glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true - glob@11.0.1: - resolution: {integrity: sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==} + glob@11.1.0: + resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==} engines: {node: 20 || >=22} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true glob@7.1.7: resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me global-directory@4.0.1: resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} @@ -5698,14 +5983,14 @@ packages: resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} engines: {node: '>=6'} - globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - globals@13.24.0: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} + globals@17.4.0: + resolution: {integrity: sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==} + engines: {node: '>=18'} + globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} @@ -5735,8 +6020,8 @@ packages: handle-thing@2.0.1: resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} - handlebars@4.7.8: - resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + handlebars@4.7.9: + resolution: {integrity: sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==} engines: {node: '>=0.4.7'} hasBin: true @@ -5778,6 +6063,10 @@ packages: resolution: {integrity: sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==} engines: {node: '>= 0.10'} + hash-base@3.1.2: + resolution: {integrity: sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==} + engines: {node: '>= 0.8'} + hash.js@1.1.7: resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} @@ -5817,8 +6106,8 @@ packages: resolution: {integrity: sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==} engines: {node: '>=10'} - html-entities@2.5.3: - resolution: {integrity: sha512-D3AfvN7SjhTgBSA8L1BN4FpPzuEd06uy4lHwSoRWr0lndi9BKaNzPLKGOWZ2ocSGguozr08TTb2jhCLHaemruw==} + html-entities@2.6.0: + resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==} html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} @@ -5828,8 +6117,8 @@ packages: engines: {node: '>=12'} hasBin: true - html-webpack-plugin@5.6.3: - resolution: {integrity: sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg==} + html-webpack-plugin@5.6.6: + resolution: {integrity: sha512-bLjW01UTrvoWTJQL5LsMRo1SypHW80FTm12OJRSnr3v6YHNhfe+1r0MYUZJMACxnCHURVnBWRwAsWs2yPU9Ezw==} engines: {node: '>=10.13.0'} peerDependencies: '@rspack/core': 0.x || 1.x @@ -5849,34 +6138,21 @@ packages: http-deceiver@1.2.7: resolution: {integrity: sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==} - http-errors@1.6.3: - resolution: {integrity: sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==} - engines: {node: '>= 0.6'} - http-errors@1.8.1: resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==} engines: {node: '>= 0.6'} - http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} engines: {node: '>= 0.8'} - http-parser-js@0.5.9: - resolution: {integrity: sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw==} + http-parser-js@0.5.10: + resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==} http-proxy-agent@4.0.1: resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==} engines: {node: '>= 6'} - http-proxy-middleware@2.0.7: - resolution: {integrity: sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==} - engines: {node: '>=12.0.0'} - peerDependencies: - '@types/express': ^4.17.13 - peerDependenciesMeta: - '@types/express': - optional: true - http-proxy-middleware@2.0.9: resolution: {integrity: sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==} engines: {node: '>=12.0.0'} @@ -5898,8 +6174,8 @@ packages: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} - human-id@4.1.1: - resolution: {integrity: sha512-3gKm/gCSUipeLsRYZbbdA1BD83lBoWUkZ7G9VFrhWPAU76KwYo5KR8V28bpoPm/ygy0x5/GCbpRQdY7VLYCoIg==} + human-id@4.1.3: + resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} hasBin: true human-signals@2.1.0: @@ -5921,6 +6197,10 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + icss-utils@5.1.0: resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} engines: {node: ^10 || ^12 || >= 14} @@ -5953,8 +6233,8 @@ packages: engines: {node: '>=8'} hasBin: true - import-meta-resolve@4.1.0: - resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} @@ -5968,9 +6248,6 @@ packages: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. - inherits@2.0.3: - resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} - inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -5985,8 +6262,8 @@ packages: resolution: {integrity: sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==} engines: {node: '>=12.0.0'} - inquirer@8.2.6: - resolution: {integrity: sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==} + inquirer@8.2.7: + resolution: {integrity: sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==} engines: {node: '>=12.0.0'} internal-slot@1.1.0: @@ -6001,8 +6278,8 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} - ipaddr.js@2.2.0: - resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==} + ipaddr.js@2.3.0: + resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} engines: {node: '>= 10'} is-arguments@1.2.0: @@ -6016,9 +6293,6 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-arrayish@0.3.2: - resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} - is-async-function@2.1.1: resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} engines: {node: '>= 0.4'} @@ -6080,8 +6354,8 @@ packages: resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} engines: {node: '>=6'} - is-generator-function@1.1.0: - resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} engines: {node: '>= 0.4'} is-glob@4.0.3: @@ -6104,8 +6378,12 @@ packages: is-module@1.0.0: resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} - is-network-error@1.1.0: - resolution: {integrity: sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==} + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-network-error@1.3.1: + resolution: {integrity: sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==} engines: {node: '>=16'} is-number-object@1.1.1: @@ -6228,8 +6506,8 @@ packages: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} - is-wsl@3.1.0: - resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} engines: {node: '>=16'} isarray@1.0.0: @@ -6270,8 +6548,8 @@ packages: resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} engines: {node: '>=10'} - istanbul-reports@3.1.7: - resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} engines: {node: '>=8'} iterator.prototype@1.1.5: @@ -6281,17 +6559,17 @@ packages: jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - jackspeak@4.1.0: - resolution: {integrity: sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==} + jackspeak@4.2.3: + resolution: {integrity: sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==} engines: {node: 20 || >=22} - jake@10.9.2: - resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} + jake@10.9.4: + resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} engines: {node: '>=10'} hasBin: true - jayson@4.1.3: - resolution: {integrity: sha512-LtXh5aYZodBZ9Fc3j6f2w+MTNcnxteMOrb+QgIouguGOulWi0lieEkOUg+HkjjFs0DGoWDds6bi4E9hpNFLulQ==} + jayson@4.3.0: + resolution: {integrity: sha512-AauzHcUcqs8OBnCHOkJY280VaTiCm57AbuO7lqzcw7JapGj50BisE3xhksye4zlTSR1+1tAz67wLTl8tEH1obQ==} engines: {node: '>=8'} hasBin: true @@ -6467,16 +6745,16 @@ packages: resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true - jiti@2.4.2: - resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} - js-base64@3.7.7: - resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} + js-base64@3.7.8: + resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==} js-sha256@0.9.0: resolution: {integrity: sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==} @@ -6487,18 +6765,21 @@ packages: js-sha512@0.8.0: resolution: {integrity: sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==} + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} js-tokens@9.0.1: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} hasBin: true - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true jsdom@16.7.0: @@ -6510,11 +6791,6 @@ packages: canvas: optional: true - jsesc@3.0.2: - resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} - engines: {node: '>=6'} - hasBin: true - jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -6538,9 +6814,6 @@ packages: json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - json-schema@0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -6562,20 +6835,24 @@ packages: jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} jsonparse@1.3.1: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} engines: {'0': node >= 0.2.0} - jsonpath@1.1.1: - resolution: {integrity: sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==} + jsonpath@1.3.0: + resolution: {integrity: sha512-0kjkYHJBkAy50Z5QzArZ7udmvxrJzkpKYW27fiF//BrMY7TQibYLl+FYIXN2BiYmwMIVzSfD8aDRj6IzgBX2/w==} jsonpointer@5.0.1: resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} engines: {node: '>=0.10.0'} + jsx-ast-utils-x@0.1.0: + resolution: {integrity: sha512-eQQBjBnsVtGacsG9uJNB8qOr3yA8rga4wAaGG1qRcBzSIvfhERLrWxMAM1hp5fcS6Abo8M4+bUBTekYR0qTPQw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + jsx-ast-utils@3.3.5: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} @@ -6614,8 +6891,8 @@ packages: resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} engines: {node: '>=0.10'} - launch-editor@2.10.0: - resolution: {integrity: sha512-D7dBRJo/qcGX9xlvt/6wUYzQxjh5G1RvZPgPv8vi4KRU99DVQL/oW7tnVOCCTm2HGeo3C5HvGE5Yrh6UBoZ0vA==} + launch-editor@2.13.2: + resolution: {integrity: sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==} leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} @@ -6648,8 +6925,8 @@ packages: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - loader-runner@4.3.0: - resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} + loader-runner@4.3.1: + resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} engines: {node: '>=6.11.5'} loader-utils@2.0.4: @@ -6676,8 +6953,8 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} - lodash-es@4.17.21: - resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + lodash-es@4.18.1: + resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} @@ -6692,9 +6969,6 @@ packages: lodash.ismatch@4.4.0: resolution: {integrity: sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==} - lodash.isplainobject@4.0.6: - resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} - lodash.map@4.6.0: resolution: {integrity: sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==} @@ -6722,6 +6996,9 @@ packages: lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} @@ -6734,8 +7011,8 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true - loupe@3.1.3: - resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} @@ -6747,8 +7024,8 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.1.0: - resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==} + lru-cache@11.3.3: + resolution: {integrity: sha512-JvNw9Y81y33E+BEYPr0U7omo+U9AySnsMsEiXgwT6yqd31VQWTLNQqmT4ou5eqPFUrTfIDFta2wKhB1hyohtAQ==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -6764,8 +7041,8 @@ packages: magic-string@0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} - magic-string@0.30.17: - resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} magicast@0.3.5: resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} @@ -6818,14 +7095,19 @@ packages: resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==} engines: {node: '>= 4.0.0'} - memfs@4.38.2: - resolution: {integrity: sha512-FpWsVHpAkoSh/LfY1BgAl72BVd374ooMRtDi2VqzBycX4XEfvC0XKACCe0C9VRZoYq5viuoyTv6lYXZ/Q7TrLQ==} - engines: {node: '>= 4.0.0'} + memfs@4.57.1: + resolution: {integrity: sha512-WvzrWPwMQT+PtbX2Et64R4qXKK0fj/8pO85MrUCzymX3twwCiJCdvntW3HdhG1teLJcHDDLIKx5+c3HckWYZtQ==} + peerDependencies: + tslib: '2' memorystream@0.3.1: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} + meow@13.2.0: + resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} + engines: {node: '>=18'} + meow@8.1.2: resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==} engines: {node: '>=10'} @@ -6867,6 +7149,10 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} @@ -6888,8 +7174,8 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - mini-css-extract-plugin@2.9.2: - resolution: {integrity: sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==} + mini-css-extract-plugin@2.10.2: + resolution: {integrity: sha512-AOSS0IdEB95ayVkxn5oGzNQwqAi2J0Jb/kKm43t7H73s8+f5873g0yuj0PNvK4dO75mu5DHg4nlgp4k6Kga8eg==} engines: {node: '>= 12.13.0'} peerDependencies: webpack: ^5.0.0 @@ -6900,23 +7186,23 @@ packages: minimalistic-crypto-utils@1.0.1: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} - minimatch@10.0.1: - resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} - engines: {node: 20 || >=22} + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} - minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} engines: {node: '>=10'} minimatch@9.0.3: resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} engines: {node: '>=16 || 14 >=14.17'} - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} engines: {node: '>=16 || 14 >=14.17'} minimist-options@4.1.0: @@ -6929,8 +7215,8 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} mixme@0.5.10: @@ -6996,6 +7282,11 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + napi-postinstall@0.3.4: + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} @@ -7022,6 +7313,7 @@ packages: next@15.3.4: resolution: {integrity: sha512-mHKd50C+mCjam/gcnwqL1T1vPx/XQNFlXqFIVdgQdVAFY9iIQtY0IfaVflEYzKiqjeA7B0cYYMaCrmAYFjs4rA==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + deprecated: This version has a security vulnerability. Please upgrade to a patched version. See https://nextjs.org/blog/CVE-2025-66478 for more details. hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 @@ -7052,6 +7344,10 @@ packages: node-addon-api@5.1.0: resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} + node-exports-info@1.6.0: + resolution: {integrity: sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==} + engines: {node: '>= 0.4'} + node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -7061,8 +7357,8 @@ packages: encoding: optional: true - node-forge@1.3.1: - resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + node-forge@1.4.0: + resolution: {integrity: sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==} engines: {node: '>= 6.13.0'} node-gyp-build@4.8.4: @@ -7072,8 +7368,8 @@ packages: node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - node-releases@2.0.19: - resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + node-releases@2.0.37: + resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==} normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -7086,10 +7382,6 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - normalize-range@0.1.2: - resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} - engines: {node: '>=0.10.0'} - normalize-url@6.1.0: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} engines: {node: '>=10'} @@ -7106,8 +7398,12 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - nwsapi@2.2.20: - resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==} + nth-check@3.0.1: + resolution: {integrity: sha512-GX0gsdbGVCgnRgbeGaubfjpBXyYRWOOCVeYh08bSQvDZqxz5ndXs1OTfAt/h36G1xvI94YIspsI0sVFqAV9+RQ==} + engines: {node: '>=20.19.0'} + + nwsapi@2.2.23: + resolution: {integrity: sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==} object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} @@ -7141,9 +7437,9 @@ packages: resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} engines: {node: '>= 0.4'} - object.getownpropertydescriptors@2.1.8: - resolution: {integrity: sha512-qkHIGe4q0lSYMv0XI4SsBTJz3WaURhLvd0lKSgtVuOsJ2krg4SgMw3PIRQFMp07yi++UR3se2mkcLqsBNpBb/A==} - engines: {node: '>= 0.8'} + object.getownpropertydescriptors@2.1.9: + resolution: {integrity: sha512-mt8YM6XwsTTovI+kdZdHSxoyF2DI59up034orlC9NfweclcWOt7CVascNNLp6U+bjFVCVCIh9PwS76tDM/rH8g==} + engines: {node: '>= 0.4'} object.groupby@1.0.3: resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} @@ -7160,8 +7456,8 @@ packages: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} - on-headers@1.0.2: - resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} + on-headers@1.1.0: + resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==} engines: {node: '>= 0.8'} once@1.4.0: @@ -7271,8 +7567,8 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} - parse-asn1@5.1.7: - resolution: {integrity: sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==} + parse-asn1@5.1.9: + resolution: {integrity: sha512-fIYNuZ/HastSb80baGOuPRo1O9cf4baWw5WsAp7dBuUzeTD/BoaG8sVTdlPFksBE2lF21dN+A1AnrpIjSWqHHg==} engines: {node: '>= 0.10'} parse-json@4.0.0: @@ -7324,12 +7620,12 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} - path-scurry@2.0.0: - resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} - engines: {node: 20 || >=22} + path-scurry@2.0.2: + resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} + engines: {node: 18 || 20 || >=22} - path-to-regexp@0.1.12: - resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + path-to-regexp@0.1.13: + resolution: {integrity: sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==} path-to-regexp@2.4.0: resolution: {integrity: sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==} @@ -7345,13 +7641,13 @@ packages: pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - pathval@2.0.0: - resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + pathval@2.0.1: + resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} engines: {node: '>= 14.16'} - pbkdf2@3.1.2: - resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} - engines: {node: '>=0.12'} + pbkdf2@3.1.5: + resolution: {integrity: sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==} + engines: {node: '>= 0.10'} performance-now@2.1.0: resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} @@ -7362,12 +7658,12 @@ packages: picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} engines: {node: '>=8.6'} - picomatch@4.0.2: - resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} pidtree@0.3.1: @@ -7399,6 +7695,10 @@ packages: resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==} engines: {node: '>=8'} + pkijs@3.4.0: + resolution: {integrity: sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw==} + engines: {node: '>=16.0.0'} + poseidon-lite@0.2.1: resolution: {integrity: sha512-xIr+G6HeYfOhCuswdqcFpSX47SPhm0EpisWJ6h7fHlWwaVIvH3dLnejpatrtw6Xc6HaLrpq05y7VRfvDmDGIog==} @@ -7565,8 +7865,8 @@ packages: peerDependencies: postcss: ^8.0.0 - postcss-js@4.0.1: - resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + postcss-js@4.1.0: + resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: postcss: ^8.4.21 @@ -7577,16 +7877,22 @@ packages: peerDependencies: postcss: ^8.2 - postcss-load-config@4.0.2: - resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} - engines: {node: '>= 14'} + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} peerDependencies: + jiti: '>=1.21.0' postcss: '>=8.0.9' - ts-node: '>=9.0.0' + tsx: ^4.8.1 + yaml: ^2.4.2 peerDependenciesMeta: + jiti: + optional: true postcss: optional: true - ts-node: + tsx: + optional: true + yaml: optional: true postcss-loader@6.2.1: @@ -7809,8 +8115,8 @@ packages: resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} engines: {node: '>=4'} - postcss-selector-parser@7.1.0: - resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} + postcss-selector-parser@7.1.1: + resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} engines: {node: '>=4'} postcss-svgo@5.1.0: @@ -7836,8 +8142,8 @@ packages: resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} - postcss@8.5.3: - resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + postcss@8.5.9: + resolution: {integrity: sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.1.2: @@ -7866,8 +8172,8 @@ packages: engines: {node: '>=10.13.0'} hasBin: true - prettier@3.5.3: - resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} + prettier@3.8.2: + resolution: {integrity: sha512-8c3mgTe0ASwWAJK+78dpviD+A8EqhndQPUBpNUIPt6+xWlIigCwfN01lWr9MAede4uqXGTEKeQWTvzb3vjia0Q==} engines: {node: '>=14'} hasBin: true @@ -7910,8 +8216,9 @@ packages: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} psl@1.15.0: resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} @@ -7919,13 +8226,20 @@ packages: public-encrypt@4.0.3: resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} - pump@3.0.3: - resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + pvtsutils@1.3.6: + resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} + + pvutils@1.1.5: + resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} + engines: {node: '>=16.0.0'} + q@1.5.1: resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==} engines: {node: '>=0.6.0', teleport: '>=0.2.0'} @@ -7934,16 +8248,16 @@ packages: (For a CapTP with native promises, see @endo/eventual-send and @endo/captp) - qs@6.13.0: - resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} + qs@6.14.2: + resolution: {integrity: sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==} engines: {node: '>=0.6'} - qs@6.14.0: - resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + qs@6.15.1: + resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} engines: {node: '>=0.6'} - quansync@0.2.10: - resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==} + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} querystring@0.2.1: resolution: {integrity: sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==} @@ -7977,18 +8291,18 @@ packages: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} - raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + raw-body@2.5.3: + resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} engines: {node: '>= 0.8'} react-app-polyfill@3.0.0: resolution: {integrity: sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==} engines: {node: '>=14'} - react-copy-to-clipboard@5.1.0: - resolution: {integrity: sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A==} + react-copy-to-clipboard@5.1.1: + resolution: {integrity: sha512-s+HrzLyJBxrpGTYXF15dTgMjAJpEPZT/Yp6NytAtZMRngejxt6Pt5WrfFxLAcsqUDU6sY1Jz6tyHwIicE1U2Xg==} peerDependencies: - react: ^15.3.0 || 16 || 17 || 18 + react: '>=15.3.0' react-dev-utils@12.0.1: resolution: {integrity: sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==} @@ -8097,12 +8411,19 @@ packages: resolution: {integrity: sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==} engines: {node: '>=6'} + refa@0.12.1: + resolution: {integrity: sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + reflect-metadata@0.2.2: + resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + reflect.getprototypeof@1.0.10: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} - regenerate-unicode-properties@10.2.0: - resolution: {integrity: sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==} + regenerate-unicode-properties@10.2.2: + resolution: {integrity: sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==} engines: {node: '>=4'} regenerate@1.4.2: @@ -8111,28 +8432,26 @@ packages: regenerator-runtime@0.13.11: resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} - regenerator-runtime@0.14.1: - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - - regenerator-transform@0.15.2: - resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} - regex-parser@2.3.1: resolution: {integrity: sha512-yXLRqatcCuKtVHsWrNg0JL3l1zGfdXeEvDa0bdu4tCDQw0RpMDZsqbkyRTUnKMR0tXF627V2oEWjBEaEdqTwtQ==} + regexp-ast-analysis@0.7.1: + resolution: {integrity: sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + regexp.prototype.flags@1.5.4: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} - regexpu-core@6.2.0: - resolution: {integrity: sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==} + regexpu-core@6.4.0: + resolution: {integrity: sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==} engines: {node: '>=4'} regjsgen@0.8.0: resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} - regjsparser@0.12.0: - resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==} + regjsparser@0.13.1: + resolution: {integrity: sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==} hasBin: true relateurl@0.2.7: @@ -8191,13 +8510,14 @@ packages: resolution: {integrity: sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==} engines: {node: '>=10'} - resolve@1.22.10: - resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} engines: {node: '>= 0.4'} hasBin: true - resolve@2.0.0-next.5: - resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + resolve@2.0.0-next.6: + resolution: {integrity: sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==} + engines: {node: '>= 0.4'} hasBin: true responselike@2.0.1: @@ -8224,8 +8544,9 @@ packages: resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} hasBin: true - ripemd160@2.0.2: - resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} + ripemd160@2.0.3: + resolution: {integrity: sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==} + engines: {node: '>= 0.8'} rollup-plugin-terser@7.0.2: resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} @@ -8233,21 +8554,21 @@ packages: peerDependencies: rollup: ^2.0.0 - rollup@2.79.2: - resolution: {integrity: sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==} + rollup@2.80.0: + resolution: {integrity: sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ==} engines: {node: '>=10.0.0'} hasBin: true - rollup@4.37.0: - resolution: {integrity: sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg==} + rollup@4.60.1: + resolution: {integrity: sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - rpc-websockets@9.1.1: - resolution: {integrity: sha512-1IXGM/TfPT6nfYMIXkJdzn+L4JEsmb0FL1O2OBjaH03V3yuUDdKFulGLMFG6ErV+8pZ5HVC0limve01RyO+saA==} + rpc-websockets@9.3.8: + resolution: {integrity: sha512-7r+fm4tSJmLf9GvZfL1DJ1SJwpagpp6AazqM0FUaeV7CA+7+NYINSk1syWa4tU/6OF2CyBicLtzENGmXRJH6wQ==} - run-applescript@7.0.0: - resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} engines: {node: '>=18'} run-async@2.4.1: @@ -8306,6 +8627,10 @@ packages: sax@1.2.4: resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} + sax@1.6.0: + resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + engines: {node: '>=11.0.0'} + saxes@5.0.1: resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==} engines: {node: '>=10'} @@ -8325,17 +8650,17 @@ packages: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} engines: {node: '>= 10.13.0'} - schema-utils@4.3.0: - resolution: {integrity: sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==} - engines: {node: '>= 10.13.0'} - - schema-utils@4.3.2: - resolution: {integrity: sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==} + schema-utils@4.3.3: + resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} engines: {node: '>= 10.13.0'} scrypt-js@3.0.1: resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} + scslre@0.3.0: + resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==} + engines: {node: ^14.0.0 || >=16.0.0} + secp256k1@5.0.1: resolution: {integrity: sha512-lDFs9AAIaWP9UCdtWrotXWWF9t8PWgQDcxqgAnpM9rMqxb3Oaq2J0thzPVSxBwdJgyQtkU/sYtFtbM1RSt/iYA==} engines: {node: '>=18.0.0'} @@ -8347,6 +8672,10 @@ packages: resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} engines: {node: '>=10'} + selfsigned@5.5.0: + resolution: {integrity: sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==} + engines: {node: '>=18'} + semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -8355,18 +8684,13 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.7.1: - resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} - engines: {node: '>=10'} - hasBin: true - - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} engines: {node: '>=10'} hasBin: true - send@0.19.0: - resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} + send@0.19.2: + resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} engines: {node: '>= 0.8.0'} serialize-javascript@4.0.0: @@ -8375,12 +8699,12 @@ packages: serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - serve-index@1.9.1: - resolution: {integrity: sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==} + serve-index@1.9.2: + resolution: {integrity: sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ==} engines: {node: '>= 0.8.0'} - serve-static@1.16.2: - resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} + serve-static@1.16.3: + resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} engines: {node: '>= 0.8.0'} set-function-length@1.2.2: @@ -8395,22 +8719,20 @@ packages: resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} engines: {node: '>= 0.4'} - setprototypeof@1.1.0: - resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} - setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - sha.js@2.4.11: - resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} + sha.js@2.4.12: + resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} + engines: {node: '>= 0.10'} hasBin: true shallow-clone@3.0.1: resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} engines: {node: '>=8'} - sharp@0.34.3: - resolution: {integrity: sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg==} + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} shebang-command@1.2.0: @@ -8429,15 +8751,15 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shell-quote@1.8.2: - resolution: {integrity: sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==} + shell-quote@1.8.3: + resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} engines: {node: '>= 0.4'} shiki@0.14.7: resolution: {integrity: sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==} - side-channel-list@1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} engines: {node: '>= 0.4'} side-channel-map@1.0.1: @@ -8462,9 +8784,6 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - simple-swizzle@0.2.2: - resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} - sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -8511,9 +8830,9 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - source-map@0.7.4: - resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} - engines: {node: '>= 8'} + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} source-map@0.8.0-beta.0: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} @@ -8536,8 +8855,8 @@ packages: spdx-expression-parse@3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - spdx-license-ids@3.0.21: - resolution: {integrity: sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==} + spdx-license-ids@3.0.23: + resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} spdy-transport@3.0.0: resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} @@ -8580,19 +8899,19 @@ packages: static-eval@2.0.2: resolution: {integrity: sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==} + static-eval@2.1.1: + resolution: {integrity: sha512-MgWpQ/ZjGieSVB3eOJVs4OA2LT/q1vx98KPCTTQPzq/aLr0YUXTsgryTXr4SLfR0ZfUUCiedM9n/ABeDIyy4mA==} + statuses@1.5.0: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} - statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} - std-env@3.8.1: - resolution: {integrity: sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==} - - std-env@3.9.0: - resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} @@ -8601,6 +8920,12 @@ packages: stream-browserify@3.0.0: resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} + stream-chain@2.2.5: + resolution: {integrity: sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==} + + stream-json@1.9.1: + resolution: {integrity: sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==} + stream-transform@2.1.3: resolution: {integrity: sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==} @@ -8675,8 +9000,8 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} engines: {node: '>=12'} strip-bom@3.0.0: @@ -8703,6 +9028,9 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + strip-literal@3.1.0: + resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} + strip-outer@1.0.1: resolution: {integrity: sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==} engines: {node: '>=0.10.0'} @@ -8732,8 +9060,8 @@ packages: peerDependencies: postcss: ^8.2.15 - sucrase@3.35.0: - resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} engines: {node: '>=16 || 14 >=14.17'} hasBin: true @@ -8770,8 +9098,8 @@ packages: deprecated: This SVGO version is no longer supported. Upgrade to v2.x.x. hasBin: true - svgo@2.8.0: - resolution: {integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==} + svgo@2.8.2: + resolution: {integrity: sha512-TyzE4NVGLUFy+H/Uy4N6c3G0HEeprsVfge6Lmq+0FdQQ/zqoVYB62IsBZORsiL+o96s6ff/V6/3UQo/C0cgCAA==} engines: {node: '>=10.13.0'} hasBin: true @@ -8782,8 +9110,8 @@ packages: resolution: {integrity: sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==} engines: {node: '>=8.0.0'} - tailwindcss@3.4.17: - resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} + tailwindcss@3.4.19: + resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==} engines: {node: '>=14.0.0'} hasBin: true @@ -8791,8 +9119,8 @@ packages: resolution: {integrity: sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==} engines: {node: '>=6'} - tapable@2.2.1: - resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + tapable@2.3.2: + resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==} engines: {node: '>=6'} temp-dir@2.0.0: @@ -8811,8 +9139,8 @@ packages: resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} engines: {node: '>=8'} - terser-webpack-plugin@5.3.14: - resolution: {integrity: sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==} + terser-webpack-plugin@5.4.0: + resolution: {integrity: sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' @@ -8827,8 +9155,8 @@ packages: uglify-js: optional: true - terser@5.39.0: - resolution: {integrity: sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==} + terser@5.46.1: + resolution: {integrity: sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==} engines: {node: '>=10'} hasBin: true @@ -8836,8 +9164,8 @@ packages: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} - test-exclude@7.0.1: - resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} + test-exclude@7.0.2: + resolution: {integrity: sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw==} engines: {node: '>=18'} text-encoding-utf-8@1.0.2: @@ -8857,8 +9185,8 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - thingies@2.5.0: - resolution: {integrity: sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw==} + thingies@2.6.0: + resolution: {integrity: sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==} engines: {node: '>=10.18'} peerDependencies: tslib: ^2 @@ -8884,20 +9212,20 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - tinyglobby@0.2.12: - resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} + tinyglobby@0.2.16: + resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} engines: {node: '>=12.0.0'} - tinypool@1.0.2: - resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} engines: {node: ^18.0.0 || >=20.0.0} tinyrainbow@2.0.0: resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} engines: {node: '>=14.0.0'} - tinyspy@3.0.2: - resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + tinyspy@4.0.4: + resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} engines: {node: '>=14.0.0'} tmp-promise@3.0.3: @@ -8907,13 +9235,17 @@ packages: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} - tmp@0.2.3: - resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} + tmp@0.2.5: + resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} engines: {node: '>=14.14'} tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + to-buffer@1.2.2: + resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} + engines: {node: '>= 0.4'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -8942,8 +9274,8 @@ packages: resolution: {integrity: sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==} engines: {node: '>=8'} - tree-dump@1.0.3: - resolution: {integrity: sha512-il+Cv80yVHFBwokQSfd4bldvr1Md951DpgAGfmhydt04L+YzHgubm2tQ7zueWDcGENKHq0ZvGFR/hjvNXilHEg==} + tree-dump@1.1.0: + resolution: {integrity: sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -8965,6 +9297,12 @@ packages: peerDependencies: typescript: '>=4.2.0' + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + ts-command-line-args@2.5.1: resolution: {integrity: sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==} hasBin: true @@ -9012,6 +9350,10 @@ packages: peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + tsyringe@4.10.0: + resolution: {integrity: sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==} + engines: {node: '>= 6.0.0'} + tweetnacl@1.0.3: resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} @@ -9094,8 +9436,8 @@ packages: peerDependencies: typedoc: 0.24.x || 0.25.x - typedoc-plugin-zod@1.4.0: - resolution: {integrity: sha512-Mr4hoEfjIR1xjp0RqtEyfba03NDUE4jLvgErg0VQz9L60eCVLcUrV0x+71+B7rykDMexrTx0I9Yk6SS0PuSbKw==} + typedoc-plugin-zod@1.4.3: + resolution: {integrity: sha512-j3kb4dGGK5OegtiIOH4F4etYdqq2lh+sTx6sABTmptPJJm8qx9XHyNlzfLYqW86ZVfL0hFR3+B/Ij9YXQw9TsA==} peerDependencies: typedoc: 0.23.x || 0.24.x || 0.25.x || 0.26.x || 0.27.x || 0.28.x @@ -9116,8 +9458,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - typescript@5.8.2: - resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} hasBin: true @@ -9138,8 +9480,8 @@ packages: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} - underscore@1.12.1: - resolution: {integrity: sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==} + underscore@1.13.6: + resolution: {integrity: sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==} undici-types@7.10.0: resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} @@ -9152,12 +9494,12 @@ packages: resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} engines: {node: '>=4'} - unicode-match-property-value-ecmascript@2.2.0: - resolution: {integrity: sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==} + unicode-match-property-value-ecmascript@2.2.1: + resolution: {integrity: sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==} engines: {node: '>=4'} - unicode-property-aliases-ecmascript@2.1.0: - resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + unicode-property-aliases-ecmascript@2.2.0: + resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==} engines: {node: '>=4'} unique-string@2.0.0: @@ -9183,15 +9525,15 @@ packages: unquote@1.1.1: resolution: {integrity: sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==} - unrs-resolver@1.3.2: - resolution: {integrity: sha512-ZKQBC351Ubw0PY8xWhneIfb6dygTQeUHtCcNGd0QB618zabD/WbFMYdRyJ7xeVT+6G82K5v/oyZO0QSHFtbIuw==} + unrs-resolver@1.11.1: + resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} upath@1.2.0: resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} engines: {node: '>=4'} - update-browserslist-db@1.1.3: - resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -9202,8 +9544,8 @@ packages: url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} - utf-8-validate@5.0.10: - resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + utf-8-validate@6.0.6: + resolution: {integrity: sha512-q3l3P9UtEEiAHcsgsqTgf9PPjctrDWoIXW3NpOHFdRDbLvu4DLIcxHangJ4RLrWkBcKjmcs/6NkerI8T/rE4LA==} engines: {node: '>=6.14.2'} util-deprecate@1.0.2: @@ -9219,6 +9561,10 @@ packages: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true @@ -9237,24 +9583,24 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - vite-node@3.0.9: - resolution: {integrity: sha512-w3Gdx7jDcuT9cNn9jExXgOyKmf5UOTb6WMHz8LGAm54eS1Elf5OuBhCxl6zJxGhEeIkgsE1WbHuoL0mj/UXqXg==} + vite-node@3.2.4: + resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true - vite@6.2.3: - resolution: {integrity: sha512-IzwM54g4y9JA/xAeBPNaDXiBF8Jsgl3VBQ2YQ/wOY6fyW3xMdSoltIV3Bo59DErdqdE6RxUfv8W69DvUorE4Eg==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + vite@7.3.2: + resolution: {integrity: sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==} + engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@types/node': ^20.19.0 || >=22.12.0 jiti: '>=1.21.0' - less: '*' + less: ^4.0.0 lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 terser: ^5.16.0 tsx: ^4.8.1 yaml: ^2.4.2 @@ -9282,16 +9628,16 @@ packages: yaml: optional: true - vitest@3.0.9: - resolution: {integrity: sha512-BbcFDqNyBlfSpATmTtXOAOj71RNKDDvjBM/uPfnxxVGrG+FSH2RQIwgeEngTaTkuU/h0ScFvf+tRcKfYXzBybQ==} + vitest@3.2.4: + resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/debug': ^4.1.12 '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': 3.0.9 - '@vitest/ui': 3.0.9 + '@vitest/browser': 3.2.4 + '@vitest/ui': 3.2.4 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -9333,8 +9679,8 @@ packages: walker@1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} - watchpack@2.4.2: - resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} + watchpack@2.5.1: + resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} engines: {node: '>=10.13.0'} wbuf@1.7.3: @@ -9377,8 +9723,8 @@ packages: peerDependencies: webpack: ^4.0.0 || ^5.0.0 - webpack-dev-middleware@7.4.2: - resolution: {integrity: sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==} + webpack-dev-middleware@7.4.5: + resolution: {integrity: sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA==} engines: {node: '>= 18.12.0'} peerDependencies: webpack: ^5.0.0 @@ -9399,8 +9745,8 @@ packages: webpack-cli: optional: true - webpack-dev-server@5.2.2: - resolution: {integrity: sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==} + webpack-dev-server@5.2.3: + resolution: {integrity: sha512-9Gyu2F7+bg4Vv+pjbovuYDhHX+mqdqITykfzdM9UyKqKHlsE5aAjRhR+oOEfXW5vBeu8tarzlJFIZva4ZjAdrQ==} engines: {node: '>= 18.12.0'} hasBin: true peerDependencies: @@ -9429,12 +9775,12 @@ packages: resolution: {integrity: sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==} engines: {node: '>=10.13.0'} - webpack-sources@3.3.3: - resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==} + webpack-sources@3.3.4: + resolution: {integrity: sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==} engines: {node: '>=10.13.0'} - webpack@5.101.3: - resolution: {integrity: sha512-7b0dTKR3Ed//AD/6kkx/o7duS8H3f1a4w3BYpIriX4BzIhjkn4teo05cptsxvLesHFKK5KObnadmCHBwGc+51A==} + webpack@5.106.1: + resolution: {integrity: sha512-EW8af29ak8Oaf4T8k8YsajjrDBDYgnKZ5er6ljWFJsXABfTNowQfvHLftwcepVgdz+IoLSdEAbBiM9DFXoll9w==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -9453,6 +9799,7 @@ packages: whatwg-encoding@1.0.5: resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation whatwg-fetch@3.6.20: resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==} @@ -9485,8 +9832,8 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} - which-typed-array@1.1.19: - resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} engines: {node: '>= 0.4'} which@1.3.1: @@ -9616,8 +9963,8 @@ packages: utf-8-validate: optional: true - ws@8.18.1: - resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==} + ws@8.20.0: + resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -9652,15 +9999,10 @@ packages: yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - yaml@1.10.2: - resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + yaml@1.10.3: + resolution: {integrity: sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==} engines: {node: '>= 6'} - yaml@2.7.0: - resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==} - engines: {node: '>= 14'} - hasBin: true - yargs-parser@20.2.9: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'} @@ -9681,8 +10023,8 @@ packages: resolution: {integrity: sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==} engines: {node: '>=10'} - zod@3.24.2: - resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} snapshots: @@ -9690,43 +10032,42 @@ snapshots: '@ampproject/remapping@2.3.0': dependencies: - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 - '@apideck/better-ajv-errors@0.3.6(ajv@8.17.1)': + '@apideck/better-ajv-errors@0.3.7(ajv@8.18.0)': dependencies: - ajv: 8.17.1 - json-schema: 0.4.0 + ajv: 8.18.0 jsonpointer: 5.0.1 leven: 3.1.0 - '@aptos-labs/aptos-cli@1.0.2': + '@aptos-labs/aptos-cli@1.1.1': dependencies: commander: 12.1.0 - '@aptos-labs/aptos-client@1.1.0(axios@1.8.4)(got@11.8.6)': + '@aptos-labs/aptos-client@1.2.0(axios@1.15.0)(got@11.8.6)': dependencies: - axios: 1.8.4 + axios: 1.15.0 got: 11.8.6 - '@aptos-labs/aptos-dynamic-transaction-composer@0.1.3': {} + '@aptos-labs/aptos-dynamic-transaction-composer@0.1.6': {} '@aptos-labs/script-composer-pack@0.0.9': dependencies: - '@aptos-labs/aptos-dynamic-transaction-composer': 0.1.3 + '@aptos-labs/aptos-dynamic-transaction-composer': 0.1.6 - '@aptos-labs/ts-sdk@1.37.1(axios@1.8.4)(got@11.8.6)': + '@aptos-labs/ts-sdk@1.39.0(axios@1.15.0)(got@11.8.6)': dependencies: - '@aptos-labs/aptos-cli': 1.0.2 - '@aptos-labs/aptos-client': 1.1.0(axios@1.8.4)(got@11.8.6) + '@aptos-labs/aptos-cli': 1.1.1 + '@aptos-labs/aptos-client': 1.2.0(axios@1.15.0)(got@11.8.6) '@aptos-labs/script-composer-pack': 0.0.9 - '@noble/curves': 1.8.1 - '@noble/hashes': 1.7.1 - '@scure/bip32': 1.6.2 - '@scure/bip39': 1.5.4 - eventemitter3: 5.0.1 - form-data: 4.0.2 - js-base64: 3.7.7 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + eventemitter3: 5.0.4 + form-data: 4.0.5 + js-base64: 3.7.8 jwt-decode: 4.0.0 poseidon-lite: 0.2.1 transitivePeerDependencies: @@ -9737,894 +10078,909 @@ snapshots: dependencies: static-eval: 2.0.2 - '@babel/code-frame@7.26.2': + '@babel/code-frame@7.29.0': dependencies: - '@babel/helper-validator-identifier': 7.25.9 + '@babel/helper-validator-identifier': 7.28.5 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.26.8': {} + '@babel/compat-data@7.29.0': {} - '@babel/core@7.26.10': + '@babel/core@7.29.0': dependencies: - '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.27.0 - '@babel/helper-compilation-targets': 7.27.0 - '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.10) - '@babel/helpers': 7.27.0 - '@babel/parser': 7.27.0 - '@babel/template': 7.27.0 - '@babel/traverse': 7.27.0 - '@babel/types': 7.27.0 + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.0 + debug: 4.4.3 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/eslint-parser@7.27.0(@babel/core@7.26.10)(eslint@8.57.1)': + '@babel/eslint-parser@7.28.6(@babel/core@7.29.0)(eslint@8.57.1)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.29.0 '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 eslint: 8.57.1 eslint-visitor-keys: 2.1.0 semver: 6.3.1 - '@babel/generator@7.27.0': + '@babel/generator@7.29.1': dependencies: - '@babel/parser': 7.27.0 - '@babel/types': 7.27.0 - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 - '@babel/helper-annotate-as-pure@7.25.9': + '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/types': 7.27.0 + '@babel/types': 7.29.0 - '@babel/helper-compilation-targets@7.27.0': + '@babel/helper-compilation-targets@7.28.6': dependencies: - '@babel/compat-data': 7.26.8 - '@babel/helper-validator-option': 7.25.9 - browserslist: 4.24.4 + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.2 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.27.0(@babel/core@7.26.10)': + '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-member-expression-to-functions': 7.25.9 - '@babel/helper-optimise-call-expression': 7.25.9 - '@babel/helper-replace-supers': 7.26.5(@babel/core@7.26.10) - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - '@babel/traverse': 7.27.0 + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.29.0 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-create-regexp-features-plugin@7.27.0(@babel/core@7.26.10)': + '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-annotate-as-pure': 7.25.9 - regexpu-core: 6.2.0 + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + regexpu-core: 6.4.0 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.4(@babel/core@7.26.10)': + '@babel/helper-define-polyfill-provider@0.6.8(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-compilation-targets': 7.27.0 - '@babel/helper-plugin-utils': 7.26.5 - debug: 4.4.0 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + debug: 4.4.3 lodash.debounce: 4.0.8 - resolve: 1.22.10 + resolve: 1.22.11 transitivePeerDependencies: - supports-color - '@babel/helper-member-expression-to-functions@7.25.9': + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.28.5': dependencies: - '@babel/traverse': 7.27.0 - '@babel/types': 7.27.0 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/helper-module-imports@7.25.9': + '@babel/helper-module-imports@7.28.6': dependencies: - '@babel/traverse': 7.27.0 - '@babel/types': 7.27.0 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.10)': + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-module-imports': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.27.0 + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/helper-optimise-call-expression@7.25.9': + '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.27.0 + '@babel/types': 7.29.0 - '@babel/helper-plugin-utils@7.26.5': {} + '@babel/helper-plugin-utils@7.28.6': {} - '@babel/helper-remap-async-to-generator@7.25.9(@babel/core@7.26.10)': + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-wrap-function': 7.25.9 - '@babel/traverse': 7.27.0 + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-wrap-function': 7.28.6 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.26.5(@babel/core@7.26.10)': + '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-member-expression-to-functions': 7.25.9 - '@babel/helper-optimise-call-expression': 7.25.9 - '@babel/traverse': 7.27.0 + '@babel/core': 7.29.0 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/helper-skip-transparent-expression-wrappers@7.25.9': + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: - '@babel/traverse': 7.27.0 - '@babel/types': 7.27.0 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/helper-string-parser@7.25.9': {} + '@babel/helper-string-parser@7.27.1': {} - '@babel/helper-validator-identifier@7.25.9': {} + '@babel/helper-validator-identifier@7.28.5': {} - '@babel/helper-validator-option@7.25.9': {} + '@babel/helper-validator-option@7.27.1': {} - '@babel/helper-wrap-function@7.25.9': + '@babel/helper-wrap-function@7.28.6': dependencies: - '@babel/template': 7.27.0 - '@babel/traverse': 7.27.0 - '@babel/types': 7.27.0 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/helpers@7.27.0': + '@babel/helpers@7.29.2': dependencies: - '@babel/template': 7.27.0 - '@babel/types': 7.27.0 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 - '@babel/parser@7.27.0': + '@babel/parser@7.29.2': dependencies: - '@babel/types': 7.27.0 + '@babel/types': 7.29.0 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/traverse': 7.27.0 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - '@babel/plugin-transform-optional-chaining': 7.25.9(@babel/core@7.26.10) + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/traverse': 7.27.0 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.26.10)': + '@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-create-class-features-plugin': 7.27.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-decorators@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-proposal-decorators@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-create-class-features-plugin': 7.27.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-decorators': 7.25.9(@babel/core@7.26.10) + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-decorators': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.26.10)': + '@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.26.10) + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.29.0) - '@babel/plugin-proposal-numeric-separator@7.18.6(@babel/core@7.26.10)': + '@babel/plugin-proposal-numeric-separator@7.18.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.26.10) + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.29.0) - '@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.26.10)': + '@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.26.10) + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.26.10)': + '@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-create-class-features-plugin': 7.27.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.26.10)': + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.29.0 - '@babel/plugin-proposal-private-property-in-object@7.21.11(@babel/core@7.26.10)': + '@babel/plugin-proposal-private-property-in-object@7.21.11(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-create-class-features-plugin': 7.27.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.26.10) + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.26.10)': + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.26.10)': + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.26.10)': + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.26.10)': + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-decorators@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-syntax-decorators@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10)': + '@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-import-assertions@7.26.0(@babel/core@7.26.10)': + '@babel/plugin-syntax-import-assertions@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@7.26.10)': + '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.26.10)': + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.26.10)': + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.26.10)': + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.26.10)': + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.26.10)': + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.26.10)': + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.26.10)': + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.26.10)': + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.26.10)': + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.26.10)': + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.26.10)': + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-create-regexp-features-plugin': 7.27.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-arrow-functions@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-async-generator-functions@7.26.8(@babel/core@7.26.10)': + '@babel/plugin-transform-async-generator-functions@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.26.10) - '@babel/traverse': 7.27.0 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-async-to-generator@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-module-imports': 7.25.9 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.26.10) + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-block-scoped-functions@7.26.5(@babel/core@7.26.10)': + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-block-scoping@7.27.0(@babel/core@7.26.10)': + '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-class-properties@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-create-class-features-plugin': 7.27.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-static-block@7.26.0(@babel/core@7.26.10)': + '@babel/plugin-transform-class-static-block@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-create-class-features-plugin': 7.27.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-classes@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-classes@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-compilation-targets': 7.27.0 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-replace-supers': 7.26.5(@babel/core@7.26.10) - '@babel/traverse': 7.27.0 - globals: 11.12.0 + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-globals': 7.28.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-computed-properties@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/template': 7.27.0 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/template': 7.28.6 - '@babel/plugin-transform-destructuring@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-dotall-regex@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-dotall-regex@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-create-regexp-features-plugin': 7.27.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-duplicate-keys@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-create-regexp-features-plugin': 7.27.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-dynamic-import@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-explicit-resource-management@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-exponentiation-operator@7.26.3(@babel/core@7.26.10)': + '@babel/plugin-transform-exponentiation-operator@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-export-namespace-from@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-flow-strip-types@7.26.5(@babel/core@7.26.10)': + '@babel/plugin-transform-flow-strip-types@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-flow': 7.26.0(@babel/core@7.26.10) + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-flow': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-for-of@7.26.9(@babel/core@7.26.10)': + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-function-name@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-compilation-targets': 7.27.0 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/traverse': 7.27.0 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-json-strings@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-json-strings@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-literals@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-logical-assignment-operators@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-logical-assignment-operators@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-member-expression-literals@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-modules-amd@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.26.3(@babel/core@7.26.10)': + '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-systemjs@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-modules-systemjs@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.27.0 + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-umd@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-named-capturing-groups-regex@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-create-regexp-features-plugin': 7.27.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-new-target@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-nullish-coalescing-operator@7.26.6(@babel/core@7.26.10)': + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-numeric-separator@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-object-rest-spread@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-compilation-targets': 7.27.0 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.26.10) + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-object-super@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-replace-supers': 7.26.5(@babel/core@7.26.10) + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-optional-catch-binding@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-optional-chaining@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-parameters@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-private-methods@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-create-class-features-plugin': 7.27.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-property-in-object@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-create-class-features-plugin': 7.27.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-property-literals@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-constant-elements@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-display-name@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-jsx-development@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.10) + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-module-imports': 7.25.9 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.10) - '@babel/types': 7.27.0 + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-pure-annotations@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-regenerator@7.27.0(@babel/core@7.26.10)': + '@babel/plugin-transform-regenerator@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - regenerator-transform: 0.15.2 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-regexp-modifiers@7.26.0(@babel/core@7.26.10)': + '@babel/plugin-transform-regexp-modifiers@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-create-regexp-features-plugin': 7.27.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-reserved-words@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-runtime@7.26.10(@babel/core@7.26.10)': + '@babel/plugin-transform-runtime@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-module-imports': 7.25.9 - '@babel/helper-plugin-utils': 7.26.5 - babel-plugin-polyfill-corejs2: 0.4.13(@babel/core@7.26.10) - babel-plugin-polyfill-corejs3: 0.11.1(@babel/core@7.26.10) - babel-plugin-polyfill-regenerator: 0.6.4(@babel/core@7.26.10) + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.0) semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-shorthand-properties@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-spread@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-spread@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-sticky-regex@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-template-literals@7.26.8(@babel/core@7.26.10)': + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-typeof-symbol@7.27.0(@babel/core@7.26.10)': + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-typescript@7.27.0(@babel/core@7.26.10)': + '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-create-class-features-plugin': 7.27.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.10) + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-unicode-escapes@7.25.9(@babel/core@7.26.10)': - dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - - '@babel/plugin-transform-unicode-property-regex@7.25.9(@babel/core@7.26.10)': - dependencies: - '@babel/core': 7.26.10 - '@babel/helper-create-regexp-features-plugin': 7.27.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 - - '@babel/plugin-transform-unicode-regex@7.25.9(@babel/core@7.26.10)': - dependencies: - '@babel/core': 7.26.10 - '@babel/helper-create-regexp-features-plugin': 7.27.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 - - '@babel/plugin-transform-unicode-sets-regex@7.25.9(@babel/core@7.26.10)': - dependencies: - '@babel/core': 7.26.10 - '@babel/helper-create-regexp-features-plugin': 7.27.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 - - '@babel/preset-env@7.26.9(@babel/core@7.26.10)': - dependencies: - '@babel/compat-data': 7.26.8 - '@babel/core': 7.26.10 - '@babel/helper-compilation-targets': 7.27.0 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-validator-option': 7.25.9 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.26.10) - '@babel/plugin-syntax-import-assertions': 7.26.0(@babel/core@7.26.10) - '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.26.10) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.26.10) - '@babel/plugin-transform-arrow-functions': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-async-generator-functions': 7.26.8(@babel/core@7.26.10) - '@babel/plugin-transform-async-to-generator': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-block-scoped-functions': 7.26.5(@babel/core@7.26.10) - '@babel/plugin-transform-block-scoping': 7.27.0(@babel/core@7.26.10) - '@babel/plugin-transform-class-properties': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-class-static-block': 7.26.0(@babel/core@7.26.10) - '@babel/plugin-transform-classes': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-computed-properties': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-destructuring': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-dotall-regex': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-duplicate-keys': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-dynamic-import': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-exponentiation-operator': 7.26.3(@babel/core@7.26.10) - '@babel/plugin-transform-export-namespace-from': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-for-of': 7.26.9(@babel/core@7.26.10) - '@babel/plugin-transform-function-name': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-json-strings': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-literals': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-logical-assignment-operators': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-member-expression-literals': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-modules-amd': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-modules-commonjs': 7.26.3(@babel/core@7.26.10) - '@babel/plugin-transform-modules-systemjs': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-modules-umd': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-named-capturing-groups-regex': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-new-target': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-nullish-coalescing-operator': 7.26.6(@babel/core@7.26.10) - '@babel/plugin-transform-numeric-separator': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-object-rest-spread': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-object-super': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-optional-catch-binding': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-optional-chaining': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-private-methods': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-private-property-in-object': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-property-literals': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-regenerator': 7.27.0(@babel/core@7.26.10) - '@babel/plugin-transform-regexp-modifiers': 7.26.0(@babel/core@7.26.10) - '@babel/plugin-transform-reserved-words': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-shorthand-properties': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-spread': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-sticky-regex': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-template-literals': 7.26.8(@babel/core@7.26.10) - '@babel/plugin-transform-typeof-symbol': 7.27.0(@babel/core@7.26.10) - '@babel/plugin-transform-unicode-escapes': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-unicode-property-regex': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-unicode-regex': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-unicode-sets-regex': 7.25.9(@babel/core@7.26.10) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.26.10) - babel-plugin-polyfill-corejs2: 0.4.13(@babel/core@7.26.10) - babel-plugin-polyfill-corejs3: 0.11.1(@babel/core@7.26.10) - babel-plugin-polyfill-regenerator: 0.6.4(@babel/core@7.26.10) - core-js-compat: 3.41.0 + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-property-regex@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-sets-regex@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/preset-env@7.29.2(@babel/core@7.29.0)': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0) + '@babel/plugin-syntax-import-assertions': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-async-generator-functions': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-computed-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-dotall-regex': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-explicit-resource-management': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-exponentiation-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-json-strings': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-logical-assignment-operators': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-systemjs': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-rest-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-optional-catch-binding': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-regenerator': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-regexp-modifiers': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-property-regex': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-sets-regex': 7.28.6(@babel/core@7.29.0) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.0) + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.14.2(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.26.10)': + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/types': 7.27.0 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/types': 7.29.0 esutils: 2.0.3 - '@babel/preset-react@7.26.3(@babel/core@7.26.10)': + '@babel/preset-react@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-validator-option': 7.25.9 - '@babel/plugin-transform-react-display-name': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-react-jsx-development': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-react-pure-annotations': 7.25.9(@babel/core@7.26.10) + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/preset-typescript@7.27.0(@babel/core@7.26.10)': + '@babel/preset-typescript@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-validator-option': 7.25.9 - '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-modules-commonjs': 7.26.3(@babel/core@7.26.10) - '@babel/plugin-transform-typescript': 7.27.0(@babel/core@7.26.10) + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/runtime@7.27.0': - dependencies: - regenerator-runtime: 0.14.1 + '@babel/runtime@7.29.2': {} - '@babel/template@7.27.0': + '@babel/template@7.28.6': dependencies: - '@babel/code-frame': 7.26.2 - '@babel/parser': 7.27.0 - '@babel/types': 7.27.0 + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 - '@babel/traverse@7.27.0': + '@babel/traverse@7.29.0': dependencies: - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.27.0 - '@babel/parser': 7.27.0 - '@babel/template': 7.27.0 - '@babel/types': 7.27.0 - debug: 4.4.0 - globals: 11.12.0 + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 transitivePeerDependencies: - supports-color - '@babel/types@7.27.0': + '@babel/types@7.29.0': dependencies: - '@babel/helper-string-parser': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 '@bcoe/v8-coverage@0.2.3': {} '@bcoe/v8-coverage@1.0.2': {} - '@changesets/apply-release-plan@7.0.10': + '@changesets/apply-release-plan@7.1.0': dependencies: - '@changesets/config': 3.1.1 + '@changesets/config': 3.1.3 '@changesets/get-version-range-type': 0.4.0 - '@changesets/git': 3.0.2 + '@changesets/git': 3.0.4 '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 @@ -10634,57 +10990,58 @@ snapshots: outdent: 0.5.0 prettier: 2.8.8 resolve-from: 5.0.0 - semver: 7.7.1 + semver: 7.7.4 - '@changesets/assemble-release-plan@6.0.6': + '@changesets/assemble-release-plan@6.0.9': dependencies: '@changesets/errors': 0.2.0 '@changesets/get-dependents-graph': 2.1.3 '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 - semver: 7.7.1 + semver: 7.7.4 '@changesets/changelog-git@0.2.1': dependencies: '@changesets/types': 6.1.0 - '@changesets/cli@2.28.1': + '@changesets/cli@2.30.0(@types/node@24.3.0)': dependencies: - '@changesets/apply-release-plan': 7.0.10 - '@changesets/assemble-release-plan': 6.0.6 + '@changesets/apply-release-plan': 7.1.0 + '@changesets/assemble-release-plan': 6.0.9 '@changesets/changelog-git': 0.2.1 - '@changesets/config': 3.1.1 + '@changesets/config': 3.1.3 '@changesets/errors': 0.2.0 '@changesets/get-dependents-graph': 2.1.3 - '@changesets/get-release-plan': 4.0.8 - '@changesets/git': 3.0.2 + '@changesets/get-release-plan': 4.0.15 + '@changesets/git': 3.0.4 '@changesets/logger': 0.1.1 '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.3 + '@changesets/read': 0.6.7 '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@changesets/write': 0.4.0 + '@inquirer/external-editor': 1.0.3(@types/node@24.3.0) '@manypkg/get-packages': 1.1.3 ansi-colors: 4.1.3 - ci-info: 3.9.0 enquirer: 2.4.1 - external-editor: 3.1.0 fs-extra: 7.0.1 mri: 1.2.0 - p-limit: 2.3.0 package-manager-detector: 0.2.11 picocolors: 1.1.1 resolve-from: 5.0.0 - semver: 7.7.1 + semver: 7.7.4 spawndamnit: 3.0.1 term-size: 2.2.1 + transitivePeerDependencies: + - '@types/node' - '@changesets/config@3.1.1': + '@changesets/config@3.1.3': dependencies: '@changesets/errors': 0.2.0 '@changesets/get-dependents-graph': 2.1.3 '@changesets/logger': 0.1.1 + '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 @@ -10699,20 +11056,20 @@ snapshots: '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 picocolors: 1.1.1 - semver: 7.7.1 + semver: 7.7.4 - '@changesets/get-release-plan@4.0.8': + '@changesets/get-release-plan@4.0.15': dependencies: - '@changesets/assemble-release-plan': 6.0.6 - '@changesets/config': 3.1.1 + '@changesets/assemble-release-plan': 6.0.9 + '@changesets/config': 3.1.3 '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.3 + '@changesets/read': 0.6.7 '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 '@changesets/get-version-range-type@0.4.0': {} - '@changesets/git@3.0.2': + '@changesets/git@3.0.4': dependencies: '@changesets/errors': 0.2.0 '@manypkg/get-packages': 1.1.3 @@ -10724,10 +11081,10 @@ snapshots: dependencies: picocolors: 1.1.1 - '@changesets/parse@0.4.1': + '@changesets/parse@0.4.3': dependencies: '@changesets/types': 6.1.0 - js-yaml: 3.14.1 + js-yaml: 4.1.1 '@changesets/pre@2.0.2': dependencies: @@ -10736,11 +11093,11 @@ snapshots: '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 - '@changesets/read@0.6.3': + '@changesets/read@0.6.7': dependencies: - '@changesets/git': 3.0.2 + '@changesets/git': 3.0.4 '@changesets/logger': 0.1.1 - '@changesets/parse': 0.4.1 + '@changesets/parse': 0.4.3 '@changesets/types': 6.1.0 fs-extra: 7.0.1 p-filter: 2.1.0 @@ -10759,53 +11116,52 @@ snapshots: dependencies: '@changesets/types': 6.1.0 fs-extra: 7.0.1 - human-id: 4.1.1 + human-id: 4.1.3 prettier: 2.8.8 '@commander-js/extra-typings@12.1.0(commander@12.1.0)': dependencies: commander: 12.1.0 - '@commitlint/config-validator@19.8.0': + '@commitlint/config-validator@20.5.0': dependencies: - '@commitlint/types': 19.8.0 - ajv: 8.17.1 + '@commitlint/types': 20.5.0 + ajv: 8.18.0 optional: true - '@commitlint/execute-rule@19.8.0': + '@commitlint/execute-rule@20.0.0': optional: true - '@commitlint/load@19.8.0(@types/node@24.3.0)(typescript@5.8.2)': + '@commitlint/load@20.5.0(@types/node@24.3.0)(typescript@5.9.3)': dependencies: - '@commitlint/config-validator': 19.8.0 - '@commitlint/execute-rule': 19.8.0 - '@commitlint/resolve-extends': 19.8.0 - '@commitlint/types': 19.8.0 - chalk: 5.4.1 - cosmiconfig: 9.0.0(typescript@5.8.2) - cosmiconfig-typescript-loader: 6.1.0(@types/node@24.3.0)(cosmiconfig@9.0.0(typescript@5.8.2))(typescript@5.8.2) - lodash.isplainobject: 4.0.6 - lodash.merge: 4.6.2 - lodash.uniq: 4.5.0 + '@commitlint/config-validator': 20.5.0 + '@commitlint/execute-rule': 20.0.0 + '@commitlint/resolve-extends': 20.5.0 + '@commitlint/types': 20.5.0 + cosmiconfig: 9.0.1(typescript@5.9.3) + cosmiconfig-typescript-loader: 6.3.0(@types/node@24.3.0)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3) + is-plain-obj: 4.1.0 + lodash.mergewith: 4.6.2 + picocolors: 1.1.1 transitivePeerDependencies: - '@types/node' - typescript optional: true - '@commitlint/resolve-extends@19.8.0': + '@commitlint/resolve-extends@20.5.0': dependencies: - '@commitlint/config-validator': 19.8.0 - '@commitlint/types': 19.8.0 + '@commitlint/config-validator': 20.5.0 + '@commitlint/types': 20.5.0 global-directory: 4.0.1 - import-meta-resolve: 4.1.0 + import-meta-resolve: 4.2.0 lodash.mergewith: 4.6.2 resolve-from: 5.0.0 optional: true - '@commitlint/types@19.8.0': + '@commitlint/types@20.5.0': dependencies: - '@types/conventional-commits-parser': 5.0.1 - chalk: 5.4.1 + conventional-commits-parser: 6.4.0 + picocolors: 1.1.1 optional: true '@cspotcode/source-map-support@0.8.1': @@ -10814,79 +11170,79 @@ snapshots: '@csstools/normalize.css@12.1.1': {} - '@csstools/postcss-cascade-layers@1.1.1(postcss@8.5.3)': + '@csstools/postcss-cascade-layers@1.1.1(postcss@8.5.9)': dependencies: '@csstools/selector-specificity': 2.2.0(postcss-selector-parser@6.1.2) - postcss: 8.5.3 + postcss: 8.5.9 postcss-selector-parser: 6.1.2 - '@csstools/postcss-color-function@1.1.1(postcss@8.5.3)': + '@csstools/postcss-color-function@1.1.1(postcss@8.5.9)': dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.3) - postcss: 8.5.3 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.9) + postcss: 8.5.9 postcss-value-parser: 4.2.0 - '@csstools/postcss-font-format-keywords@1.0.1(postcss@8.5.3)': + '@csstools/postcss-font-format-keywords@1.0.1(postcss@8.5.9)': dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - '@csstools/postcss-hwb-function@1.0.2(postcss@8.5.3)': + '@csstools/postcss-hwb-function@1.0.2(postcss@8.5.9)': dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - '@csstools/postcss-ic-unit@1.0.1(postcss@8.5.3)': + '@csstools/postcss-ic-unit@1.0.1(postcss@8.5.9)': dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.3) - postcss: 8.5.3 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.9) + postcss: 8.5.9 postcss-value-parser: 4.2.0 - '@csstools/postcss-is-pseudo-class@2.0.7(postcss@8.5.3)': + '@csstools/postcss-is-pseudo-class@2.0.7(postcss@8.5.9)': dependencies: '@csstools/selector-specificity': 2.2.0(postcss-selector-parser@6.1.2) - postcss: 8.5.3 + postcss: 8.5.9 postcss-selector-parser: 6.1.2 - '@csstools/postcss-nested-calc@1.0.0(postcss@8.5.3)': + '@csstools/postcss-nested-calc@1.0.0(postcss@8.5.9)': dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - '@csstools/postcss-normalize-display-values@1.0.1(postcss@8.5.3)': + '@csstools/postcss-normalize-display-values@1.0.1(postcss@8.5.9)': dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - '@csstools/postcss-oklab-function@1.1.1(postcss@8.5.3)': + '@csstools/postcss-oklab-function@1.1.1(postcss@8.5.9)': dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.3) - postcss: 8.5.3 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.9) + postcss: 8.5.9 postcss-value-parser: 4.2.0 - '@csstools/postcss-progressive-custom-properties@1.3.0(postcss@8.5.3)': + '@csstools/postcss-progressive-custom-properties@1.3.0(postcss@8.5.9)': dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - '@csstools/postcss-stepped-value-functions@1.0.1(postcss@8.5.3)': + '@csstools/postcss-stepped-value-functions@1.0.1(postcss@8.5.9)': dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - '@csstools/postcss-text-decoration-shorthand@1.0.0(postcss@8.5.3)': + '@csstools/postcss-text-decoration-shorthand@1.0.0(postcss@8.5.9)': dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - '@csstools/postcss-trigonometric-functions@1.0.2(postcss@8.5.3)': + '@csstools/postcss-trigonometric-functions@1.0.2(postcss@8.5.9)': dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - '@csstools/postcss-unset-value@1.0.2(postcss@8.5.3)': + '@csstools/postcss-unset-value@1.0.2(postcss@8.5.9)': dependencies: - postcss: 8.5.3 + postcss: 8.5.9 '@csstools/selector-specificity@2.2.0(postcss-selector-parser@6.1.2)': dependencies: @@ -10894,23 +11250,18 @@ snapshots: '@discoveryjs/json-ext@0.6.3': {} - '@emnapi/core@1.4.0': - dependencies: - '@emnapi/wasi-threads': 1.0.1 - tslib: 2.8.1 - optional: true - - '@emnapi/runtime@1.4.0': + '@emnapi/core@1.9.2': dependencies: + '@emnapi/wasi-threads': 1.2.1 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.5.0': + '@emnapi/runtime@1.9.2': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.0.1': + '@emnapi/wasi-threads@1.2.1': dependencies: tslib: 2.8.1 optional: true @@ -10918,7 +11269,7 @@ snapshots: '@esbuild/aix-ppc64@0.19.12': optional: true - '@esbuild/aix-ppc64@0.25.1': + '@esbuild/aix-ppc64@0.27.7': optional: true '@esbuild/android-arm64@0.16.17': @@ -10927,7 +11278,7 @@ snapshots: '@esbuild/android-arm64@0.19.12': optional: true - '@esbuild/android-arm64@0.25.1': + '@esbuild/android-arm64@0.27.7': optional: true '@esbuild/android-arm@0.16.17': @@ -10936,7 +11287,7 @@ snapshots: '@esbuild/android-arm@0.19.12': optional: true - '@esbuild/android-arm@0.25.1': + '@esbuild/android-arm@0.27.7': optional: true '@esbuild/android-x64@0.16.17': @@ -10945,7 +11296,7 @@ snapshots: '@esbuild/android-x64@0.19.12': optional: true - '@esbuild/android-x64@0.25.1': + '@esbuild/android-x64@0.27.7': optional: true '@esbuild/darwin-arm64@0.16.17': @@ -10954,7 +11305,7 @@ snapshots: '@esbuild/darwin-arm64@0.19.12': optional: true - '@esbuild/darwin-arm64@0.25.1': + '@esbuild/darwin-arm64@0.27.7': optional: true '@esbuild/darwin-x64@0.16.17': @@ -10963,7 +11314,7 @@ snapshots: '@esbuild/darwin-x64@0.19.12': optional: true - '@esbuild/darwin-x64@0.25.1': + '@esbuild/darwin-x64@0.27.7': optional: true '@esbuild/freebsd-arm64@0.16.17': @@ -10972,7 +11323,7 @@ snapshots: '@esbuild/freebsd-arm64@0.19.12': optional: true - '@esbuild/freebsd-arm64@0.25.1': + '@esbuild/freebsd-arm64@0.27.7': optional: true '@esbuild/freebsd-x64@0.16.17': @@ -10981,7 +11332,7 @@ snapshots: '@esbuild/freebsd-x64@0.19.12': optional: true - '@esbuild/freebsd-x64@0.25.1': + '@esbuild/freebsd-x64@0.27.7': optional: true '@esbuild/linux-arm64@0.16.17': @@ -10990,7 +11341,7 @@ snapshots: '@esbuild/linux-arm64@0.19.12': optional: true - '@esbuild/linux-arm64@0.25.1': + '@esbuild/linux-arm64@0.27.7': optional: true '@esbuild/linux-arm@0.16.17': @@ -10999,7 +11350,7 @@ snapshots: '@esbuild/linux-arm@0.19.12': optional: true - '@esbuild/linux-arm@0.25.1': + '@esbuild/linux-arm@0.27.7': optional: true '@esbuild/linux-ia32@0.16.17': @@ -11008,7 +11359,7 @@ snapshots: '@esbuild/linux-ia32@0.19.12': optional: true - '@esbuild/linux-ia32@0.25.1': + '@esbuild/linux-ia32@0.27.7': optional: true '@esbuild/linux-loong64@0.16.17': @@ -11017,7 +11368,7 @@ snapshots: '@esbuild/linux-loong64@0.19.12': optional: true - '@esbuild/linux-loong64@0.25.1': + '@esbuild/linux-loong64@0.27.7': optional: true '@esbuild/linux-mips64el@0.16.17': @@ -11026,7 +11377,7 @@ snapshots: '@esbuild/linux-mips64el@0.19.12': optional: true - '@esbuild/linux-mips64el@0.25.1': + '@esbuild/linux-mips64el@0.27.7': optional: true '@esbuild/linux-ppc64@0.16.17': @@ -11035,7 +11386,7 @@ snapshots: '@esbuild/linux-ppc64@0.19.12': optional: true - '@esbuild/linux-ppc64@0.25.1': + '@esbuild/linux-ppc64@0.27.7': optional: true '@esbuild/linux-riscv64@0.16.17': @@ -11044,7 +11395,7 @@ snapshots: '@esbuild/linux-riscv64@0.19.12': optional: true - '@esbuild/linux-riscv64@0.25.1': + '@esbuild/linux-riscv64@0.27.7': optional: true '@esbuild/linux-s390x@0.16.17': @@ -11053,7 +11404,7 @@ snapshots: '@esbuild/linux-s390x@0.19.12': optional: true - '@esbuild/linux-s390x@0.25.1': + '@esbuild/linux-s390x@0.27.7': optional: true '@esbuild/linux-x64@0.16.17': @@ -11062,10 +11413,10 @@ snapshots: '@esbuild/linux-x64@0.19.12': optional: true - '@esbuild/linux-x64@0.25.1': + '@esbuild/linux-x64@0.27.7': optional: true - '@esbuild/netbsd-arm64@0.25.1': + '@esbuild/netbsd-arm64@0.27.7': optional: true '@esbuild/netbsd-x64@0.16.17': @@ -11074,10 +11425,10 @@ snapshots: '@esbuild/netbsd-x64@0.19.12': optional: true - '@esbuild/netbsd-x64@0.25.1': + '@esbuild/netbsd-x64@0.27.7': optional: true - '@esbuild/openbsd-arm64@0.25.1': + '@esbuild/openbsd-arm64@0.27.7': optional: true '@esbuild/openbsd-x64@0.16.17': @@ -11086,7 +11437,10 @@ snapshots: '@esbuild/openbsd-x64@0.19.12': optional: true - '@esbuild/openbsd-x64@0.25.1': + '@esbuild/openbsd-x64@0.27.7': + optional: true + + '@esbuild/openharmony-arm64@0.27.7': optional: true '@esbuild/sunos-x64@0.16.17': @@ -11095,7 +11449,7 @@ snapshots: '@esbuild/sunos-x64@0.19.12': optional: true - '@esbuild/sunos-x64@0.25.1': + '@esbuild/sunos-x64@0.27.7': optional: true '@esbuild/win32-arm64@0.16.17': @@ -11104,7 +11458,7 @@ snapshots: '@esbuild/win32-arm64@0.19.12': optional: true - '@esbuild/win32-arm64@0.25.1': + '@esbuild/win32-arm64@0.27.7': optional: true '@esbuild/win32-ia32@0.16.17': @@ -11113,7 +11467,7 @@ snapshots: '@esbuild/win32-ia32@0.19.12': optional: true - '@esbuild/win32-ia32@0.25.1': + '@esbuild/win32-ia32@0.27.7': optional: true '@esbuild/win32-x64@0.16.17': @@ -11122,31 +11476,31 @@ snapshots: '@esbuild/win32-x64@0.19.12': optional: true - '@esbuild/win32-x64@0.25.1': + '@esbuild/win32-x64@0.27.7': optional: true - '@eslint-community/eslint-utils@4.5.1(eslint@8.57.0)': + '@eslint-community/eslint-utils@4.9.1(eslint@8.57.0)': dependencies: eslint: 8.57.0 eslint-visitor-keys: 3.4.3 - '@eslint-community/eslint-utils@4.5.1(eslint@8.57.1)': + '@eslint-community/eslint-utils@4.9.1(eslint@8.57.1)': dependencies: eslint: 8.57.1 eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.12.1': {} + '@eslint-community/regexpp@4.12.2': {} '@eslint/eslintrc@2.1.4': dependencies: - ajv: 6.12.6 - debug: 4.4.0 + ajv: 6.14.0 + debug: 4.4.3 espree: 9.6.1 globals: 13.24.0 ignore: 5.3.2 import-fresh: 3.3.1 - js-yaml: 4.1.0 - minimatch: 3.1.2 + js-yaml: 4.1.1 + minimatch: 3.1.5 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color @@ -11206,7 +11560,7 @@ snapshots: dependencies: '@ethersproject/bytes': 5.8.0 '@ethersproject/logger': 5.8.0 - bn.js: 5.2.1 + bn.js: 5.2.3 '@ethersproject/bytes@5.8.0': dependencies: @@ -11292,7 +11646,7 @@ snapshots: dependencies: '@ethersproject/logger': 5.8.0 - '@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@ethersproject/providers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: '@ethersproject/abstract-provider': 5.8.0 '@ethersproject/abstract-signer': 5.8.0 @@ -11313,7 +11667,7 @@ snapshots: '@ethersproject/transactions': 5.8.0 '@ethersproject/web': 5.8.0 bech32: 1.1.4 - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -11339,7 +11693,7 @@ snapshots: '@ethersproject/bytes': 5.8.0 '@ethersproject/logger': 5.8.0 '@ethersproject/properties': 5.8.0 - bn.js: 5.2.1 + bn.js: 5.2.3 elliptic: 6.6.1 hash.js: 1.1.7 @@ -11413,16 +11767,16 @@ snapshots: '@humanwhocodes/config-array@0.11.14': dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.4.0 - minimatch: 3.1.2 + debug: 4.4.3 + minimatch: 3.1.5 transitivePeerDependencies: - supports-color '@humanwhocodes/config-array@0.13.0': dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.4.0 - minimatch: 3.1.2 + debug: 4.4.3 + minimatch: 3.1.5 transitivePeerDependencies: - supports-color @@ -11432,160 +11786,182 @@ snapshots: '@hutson/parse-repository-url@3.0.2': {} - '@img/sharp-darwin-arm64@0.34.3': + '@img/colour@1.1.0': + optional: true + + '@img/sharp-darwin-arm64@0.34.5': optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.2.0 + '@img/sharp-libvips-darwin-arm64': 1.2.4 optional: true - '@img/sharp-darwin-x64@0.34.3': + '@img/sharp-darwin-x64@0.34.5': optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.2.0 + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': optional: true - '@img/sharp-libvips-darwin-arm64@1.2.0': + '@img/sharp-libvips-linux-arm64@1.2.4': optional: true - '@img/sharp-libvips-darwin-x64@1.2.0': + '@img/sharp-libvips-linux-arm@1.2.4': optional: true - '@img/sharp-libvips-linux-arm64@1.2.0': + '@img/sharp-libvips-linux-ppc64@1.2.4': optional: true - '@img/sharp-libvips-linux-arm@1.2.0': + '@img/sharp-libvips-linux-riscv64@1.2.4': optional: true - '@img/sharp-libvips-linux-ppc64@1.2.0': + '@img/sharp-libvips-linux-s390x@1.2.4': optional: true - '@img/sharp-libvips-linux-s390x@1.2.0': + '@img/sharp-libvips-linux-x64@1.2.4': optional: true - '@img/sharp-libvips-linux-x64@1.2.0': + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': optional: true - '@img/sharp-libvips-linuxmusl-arm64@1.2.0': + '@img/sharp-libvips-linuxmusl-x64@1.2.4': optional: true - '@img/sharp-libvips-linuxmusl-x64@1.2.0': + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 optional: true - '@img/sharp-linux-arm64@0.34.3': + '@img/sharp-linux-arm@0.34.5': optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.2.0 + '@img/sharp-libvips-linux-arm': 1.2.4 optional: true - '@img/sharp-linux-arm@0.34.3': + '@img/sharp-linux-ppc64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.2.0 + '@img/sharp-libvips-linux-ppc64': 1.2.4 optional: true - '@img/sharp-linux-ppc64@0.34.3': + '@img/sharp-linux-riscv64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linux-ppc64': 1.2.0 + '@img/sharp-libvips-linux-riscv64': 1.2.4 optional: true - '@img/sharp-linux-s390x@0.34.3': + '@img/sharp-linux-s390x@0.34.5': optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.2.0 + '@img/sharp-libvips-linux-s390x': 1.2.4 optional: true - '@img/sharp-linux-x64@0.34.3': + '@img/sharp-linux-x64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.2.0 + '@img/sharp-libvips-linux-x64': 1.2.4 optional: true - '@img/sharp-linuxmusl-arm64@0.34.3': + '@img/sharp-linuxmusl-arm64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.2.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 optional: true - '@img/sharp-linuxmusl-x64@0.34.3': + '@img/sharp-linuxmusl-x64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.2.0 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 optional: true - '@img/sharp-wasm32@0.34.3': + '@img/sharp-wasm32@0.34.5': dependencies: - '@emnapi/runtime': 1.5.0 + '@emnapi/runtime': 1.9.2 optional: true - '@img/sharp-win32-arm64@0.34.3': + '@img/sharp-win32-arm64@0.34.5': optional: true - '@img/sharp-win32-ia32@0.34.3': + '@img/sharp-win32-ia32@0.34.5': optional: true - '@img/sharp-win32-x64@0.34.3': + '@img/sharp-win32-x64@0.34.5': optional: true + '@inquirer/external-editor@1.0.3(@types/node@24.3.0)': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.2 + optionalDependencies: + '@types/node': 24.3.0 + '@irys/arweave@0.0.2': dependencies: asn1.js: 5.4.1 async-retry: 1.3.3 - axios: 1.11.0 + axios: 1.15.0 base64-js: 1.5.1 - bignumber.js: 9.1.2 + bignumber.js: 9.3.1 transitivePeerDependencies: - debug '@irys/query@0.0.8': dependencies: async-retry: 1.3.3 - axios: 1.11.0 + axios: 1.15.0 transitivePeerDependencies: - debug - '@irys/sdk@0.1.24(arweave@1.15.0)(bufferutil@4.0.9)(got@11.8.6)(utf-8-validate@5.0.10)': + '@irys/sdk@0.1.24(@types/node@24.3.0)(arweave@1.15.7)(bufferutil@4.1.0)(got@11.8.6)(typescript@4.9.5)(utf-8-validate@6.0.6)': dependencies: - '@aptos-labs/ts-sdk': 1.37.1(axios@1.8.4)(got@11.8.6) + '@aptos-labs/ts-sdk': 1.39.0(axios@1.15.0)(got@11.8.6) '@ethersproject/bignumber': 5.8.0 '@ethersproject/contracts': 5.8.0 - '@ethersproject/providers': 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@ethersproject/providers': 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@ethersproject/wallet': 5.8.0 '@irys/query': 0.0.8 '@near-js/crypto': 0.0.3 '@near-js/keystores-browser': 0.0.3 '@near-js/providers': 0.0.4 '@near-js/transactions': 0.1.1 - '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@supercharge/promise-pool': 3.2.0 + '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@4.9.5)(utf-8-validate@6.0.6) + '@supercharge/promise-pool': 3.3.0 algosdk: 1.24.1 - arbundles: 0.10.1(arweave@1.15.0)(bufferutil@4.0.9)(utf-8-validate@5.0.10) + arbundles: 0.10.1(arweave@1.15.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6) async-retry: 1.3.3 - axios: 1.8.4 + axios: 1.15.0 base64url: 3.0.1 - bignumber.js: 9.1.2 + bignumber.js: 9.3.1 bs58: 5.0.0 commander: 8.3.0 csv: 5.5.3 - inquirer: 8.2.6 + inquirer: 8.2.7(@types/node@24.3.0) js-sha256: 0.9.0 mime-types: 2.1.35 near-seed-phrase: 0.2.1 tslib: 2.8.1 transitivePeerDependencies: + - '@types/node' - arweave - bufferutil - debug - encoding - got + - typescript - utf-8-validate '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 + strip-ansi: 7.2.0 strip-ansi-cjs: strip-ansi@6.0.1 wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@isaacs/cliui@9.0.0': {} + '@istanbuljs/load-nyc-config@1.1.0': dependencies: camelcase: 5.3.1 find-up: 4.1.0 get-package-type: 0.1.0 - js-yaml: 3.14.1 + js-yaml: 3.14.2 resolve-from: 5.0.0 '@istanbuljs/schema@0.1.3': {} @@ -11608,7 +11984,7 @@ snapshots: jest-util: 28.1.3 slash: 3.0.0 - '@jest/core@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10)': + '@jest/core@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3))': dependencies: '@jest/console': 27.5.1 '@jest/reporters': 27.5.1 @@ -11622,13 +11998,13 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 27.5.1 - jest-config: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10) + jest-config: 27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)) jest-haste-map: 27.5.1 jest-message-util: 27.5.1 jest-regex-util: 27.5.1 jest-resolve: 27.5.1 jest-resolve-dependencies: 27.5.1 - jest-runner: 27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + jest-runner: 27.5.1(bufferutil@4.1.0) jest-runtime: 27.5.1 jest-snapshot: 27.5.1 jest-util: 27.5.1 @@ -11676,7 +12052,7 @@ snapshots: '@jest/types': 27.5.1 '@types/node': 24.3.0 chalk: 4.1.2 - collect-v8-coverage: 1.0.2 + collect-v8-coverage: 1.0.3 exit: 0.1.2 glob: 7.2.3 graceful-fs: 4.2.11 @@ -11684,7 +12060,7 @@ snapshots: istanbul-lib-instrument: 5.2.1 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.7 + istanbul-reports: 3.2.0 jest-haste-map: 27.5.1 jest-resolve: 27.5.1 jest-util: 27.5.1 @@ -11712,14 +12088,14 @@ snapshots: '@jest/console': 27.5.1 '@jest/types': 27.5.1 '@types/istanbul-lib-coverage': 2.0.6 - collect-v8-coverage: 1.0.2 + collect-v8-coverage: 1.0.3 '@jest/test-result@28.1.3': dependencies: '@jest/console': 28.1.3 '@jest/types': 28.1.3 '@types/istanbul-lib-coverage': 2.0.6 - collect-v8-coverage: 1.0.2 + collect-v8-coverage: 1.0.3 '@jest/test-sequencer@27.5.1': dependencies: @@ -11732,7 +12108,7 @@ snapshots: '@jest/transform@27.5.1': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.29.0 '@jest/types': 27.5.1 babel-plugin-istanbul: 6.1.1 chalk: 4.1.2 @@ -11755,7 +12131,7 @@ snapshots: '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 '@types/node': 24.3.0 - '@types/yargs': 16.0.9 + '@types/yargs': 16.0.11 chalk: 4.1.2 '@jest/types@28.1.3': @@ -11764,46 +12140,51 @@ snapshots: '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 '@types/node': 24.3.0 - '@types/yargs': 17.0.33 + '@types/yargs': 17.0.35 chalk: 4.1.2 - '@jridgewell/gen-mapping@0.3.8': + '@jridgewell/gen-mapping@0.3.13': dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/set-array@1.2.1': {} + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/source-map@0.3.6': + '@jridgewell/remapping@2.3.5': dependencies: - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/trace-mapping@0.3.25': + '@jridgewell/source-map@0.3.11': dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/trace-mapping@0.3.30': + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping@0.3.9': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 '@jsonjoy.com/base64@1.1.2(tslib@2.8.1)': dependencies: tslib: 2.8.1 - '@jsonjoy.com/buffers@1.0.0(tslib@2.8.1)': + '@jsonjoy.com/base64@17.67.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/buffers@1.2.1(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/buffers@17.67.0(tslib@2.8.1)': dependencies: tslib: 2.8.1 @@ -11811,15 +12192,88 @@ snapshots: dependencies: tslib: 2.8.1 - '@jsonjoy.com/json-pack@1.11.0(tslib@2.8.1)': + '@jsonjoy.com/codegen@17.67.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/fs-core@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-fsa@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-core': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-builtins@4.57.1(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-to-fsa@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-fsa': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-utils@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-core': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.1(tslib@2.8.1) + glob-to-regex.js: 1.2.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-print@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-snapshot@4.57.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/json-pack': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pack@1.21.0(tslib@2.8.1)': dependencies: '@jsonjoy.com/base64': 1.1.2(tslib@2.8.1) - '@jsonjoy.com/buffers': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/buffers': 1.2.1(tslib@2.8.1) '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) '@jsonjoy.com/json-pointer': 1.0.2(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) hyperdyperid: 1.2.0 - thingies: 2.5.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pack@17.67.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/base64': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/codegen': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/json-pointer': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) + hyperdyperid: 1.2.0 + thingies: 2.6.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 '@jsonjoy.com/json-pointer@1.0.2(tslib@2.8.1)': @@ -11828,24 +12282,35 @@ snapshots: '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) tslib: 2.8.1 + '@jsonjoy.com/json-pointer@17.67.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) + tslib: 2.8.1 + '@jsonjoy.com/util@1.9.0(tslib@2.8.1)': dependencies: - '@jsonjoy.com/buffers': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/buffers': 1.2.1(tslib@2.8.1) '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) tslib: 2.8.1 + '@jsonjoy.com/util@17.67.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/codegen': 17.67.0(tslib@2.8.1) + tslib: 2.8.1 + '@leichtgewicht/ip-codec@2.0.5': {} '@manypkg/find-root@1.1.0': dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.29.2 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 '@manypkg/get-packages@1.1.3': dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.29.2 '@changesets/types': 4.1.0 '@manypkg/find-root': 1.1.0 fs-extra: 8.1.0 @@ -11854,11 +12319,11 @@ snapshots: '@metamask/detect-provider@2.0.0': {} - '@napi-rs/wasm-runtime@0.2.7': + '@napi-rs/wasm-runtime@0.2.12': dependencies: - '@emnapi/core': 1.4.0 - '@emnapi/runtime': 1.4.0 - '@tybys/wasm-util': 0.9.0 + '@emnapi/core': 1.9.2 + '@emnapi/runtime': 1.9.2 + '@tybys/wasm-util': 0.10.1 optional: true '@near-js/crypto@0.0.3': @@ -11991,13 +12456,15 @@ snapshots: dependencies: eslint-scope: 5.1.1 - '@noble/curves@1.8.1': + '@noble/curves@1.9.7': dependencies: - '@noble/hashes': 1.7.1 + '@noble/hashes': 1.8.0 + + '@noble/ed25519@1.7.5': {} - '@noble/ed25519@1.7.3': {} + '@noble/hashes@1.4.0': {} - '@noble/hashes@1.7.1': {} + '@noble/hashes@1.8.0': {} '@nodelib/fs.scandir@2.1.5': dependencies: @@ -12009,87 +12476,179 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.1 + fastq: 1.20.1 '@nolyfill/is-core-module@1.0.39': {} '@nucypher/nucypher-contracts@0.25.0': {} + '@nucypher/nucypher-contracts@https://codeload.github.com/nucypher/nucypher-contracts/tar.gz/7a7bf2207436688d5835d54bdf71f51ce527907f': {} + '@nucypher/nucypher-core@0.14.5': {} - '@nucypher/shared@0.5.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@nucypher/shared@0.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: '@ethersproject/abi': 5.8.0 - '@ethersproject/providers': 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@ethersproject/providers': 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@nucypher/nucypher-contracts': 0.25.0 '@nucypher/nucypher-core': 0.14.5 - axios: 1.11.0 + axios: 1.15.0 deep-equal: 2.2.3 - ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - qs: 6.14.0 - zod: 3.24.2 + ethers: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + qs: 6.15.1 + zod: 3.25.76 transitivePeerDependencies: - bufferutil - debug - utf-8-validate - '@nucypher/taco-auth@0.3.0(bufferutil@4.0.9)(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + '@nucypher/taco-auth@0.3.0(bufferutil@4.1.0)(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(utf-8-validate@6.0.6)': dependencies: '@ethersproject/abstract-signer': 5.8.0 - '@nucypher/shared': 0.5.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - siwe: 3.0.0(ethers@5.8.0) - zod: 3.24.2 + '@nucypher/shared': 0.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + siwe: 3.0.0(ethers@5.8.0(bufferutil@4.1.0)) + zod: 3.25.76 transitivePeerDependencies: - bufferutil - debug - ethers - utf-8-validate - '@nucypher/taco@0.6.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@nucypher/taco@0.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: '@astronautlabs/jsonpath': 1.1.2 '@nucypher/nucypher-core': 0.14.5 - '@nucypher/shared': 0.5.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@nucypher/taco-auth': 0.3.0(bufferutil@4.0.9)(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - semver: 7.7.1 - zod: 3.24.2 + '@nucypher/shared': 0.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@nucypher/taco-auth': 0.3.0(bufferutil@4.1.0)(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(utf-8-validate@6.0.6) + ethers: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + semver: 7.7.4 + zod: 3.25.76 transitivePeerDependencies: - bufferutil - debug - utf-8-validate + '@peculiar/asn1-cms@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + '@peculiar/asn1-x509-attr': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-csr@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-ecc@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-pfx@2.6.1': + dependencies: + '@peculiar/asn1-cms': 2.6.1 + '@peculiar/asn1-pkcs8': 2.6.1 + '@peculiar/asn1-rsa': 2.6.1 + '@peculiar/asn1-schema': 2.6.0 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-pkcs8@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-pkcs9@2.6.1': + dependencies: + '@peculiar/asn1-cms': 2.6.1 + '@peculiar/asn1-pfx': 2.6.1 + '@peculiar/asn1-pkcs8': 2.6.1 + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + '@peculiar/asn1-x509-attr': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-rsa@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-schema@2.6.0': + dependencies: + asn1js: 3.0.7 + pvtsutils: 1.3.6 + tslib: 2.8.1 + + '@peculiar/asn1-x509-attr@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 + + '@peculiar/asn1-x509@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + asn1js: 3.0.7 + pvtsutils: 1.3.6 + tslib: 2.8.1 + + '@peculiar/x509@1.14.3': + dependencies: + '@peculiar/asn1-cms': 2.6.1 + '@peculiar/asn1-csr': 2.6.1 + '@peculiar/asn1-ecc': 2.6.1 + '@peculiar/asn1-pkcs9': 2.6.1 + '@peculiar/asn1-rsa': 2.6.1 + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + pvtsutils: 1.3.6 + reflect-metadata: 0.2.2 + tslib: 2.8.1 + tsyringe: 4.10.0 + '@pkgjs/parseargs@0.11.0': optional: true - '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.11.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.101.3))(webpack@5.101.3)': + '@pmmmwh/react-refresh-webpack-plugin@0.5.17(react-refresh@0.11.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.1.0)(webpack@5.106.1))(webpack@5.106.1)': dependencies: ansi-html: 0.0.9 - core-js-pure: 3.41.0 + core-js-pure: 3.49.0 error-stack-parser: 2.1.4 - html-entities: 2.5.3 + html-entities: 2.6.0 loader-utils: 2.0.4 react-refresh: 0.11.0 - schema-utils: 4.3.0 - source-map: 0.7.4 - webpack: 5.101.3 + schema-utils: 4.3.3 + source-map: 0.7.6 + webpack: 5.106.1(webpack-cli@6.0.1) optionalDependencies: type-fest: 0.21.3 - webpack-dev-server: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.101.3) + webpack-dev-server: 4.15.2(bufferutil@4.1.0)(webpack@5.106.1) - '@pmmmwh/react-refresh-webpack-plugin@0.6.1(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3))(webpack@5.101.3(webpack-cli@6.0.1))': + '@pmmmwh/react-refresh-webpack-plugin@0.6.2(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.3)(webpack@5.106.1)': dependencies: - anser: 2.3.2 - core-js-pure: 3.41.0 + anser: 2.3.5 + core-js-pure: 3.49.0 error-stack-parser: 2.1.4 - html-entities: 2.5.3 + html-entities: 2.6.0 react-refresh: 0.17.0 - schema-utils: 4.3.0 - source-map: 0.7.4 - webpack: 5.101.3(webpack-cli@6.0.1) + schema-utils: 4.3.3 + source-map: 0.7.6 + webpack: 5.106.1(webpack-cli@6.0.1) optionalDependencies: type-fest: 0.21.3 - webpack-dev-server: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3) + webpack-dev-server: 5.2.3(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack-cli@6.0.1)(webpack@5.106.1) '@randlabs/communication-bridge@1.0.1': optional: true @@ -12099,116 +12658,134 @@ snapshots: '@randlabs/communication-bridge': 1.0.1 optional: true - '@rollup/plugin-babel@5.3.1(@babel/core@7.26.10)(@types/babel__core@7.20.5)(rollup@2.79.2)': + '@rollup/plugin-babel@5.3.1(@babel/core@7.29.0)(@types/babel__core@7.20.5)(rollup@2.80.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-module-imports': 7.25.9 - '@rollup/pluginutils': 3.1.0(rollup@2.79.2) - rollup: 2.79.2 + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@rollup/pluginutils': 3.1.0(rollup@2.80.0) + rollup: 2.80.0 optionalDependencies: '@types/babel__core': 7.20.5 transitivePeerDependencies: - supports-color - '@rollup/plugin-node-resolve@11.2.1(rollup@2.79.2)': + '@rollup/plugin-node-resolve@11.2.1(rollup@2.80.0)': dependencies: - '@rollup/pluginutils': 3.1.0(rollup@2.79.2) + '@rollup/pluginutils': 3.1.0(rollup@2.80.0) '@types/resolve': 1.17.1 builtin-modules: 3.3.0 deepmerge: 4.3.1 is-module: 1.0.0 - resolve: 1.22.10 - rollup: 2.79.2 + resolve: 1.22.11 + rollup: 2.80.0 - '@rollup/plugin-replace@2.4.2(rollup@2.79.2)': + '@rollup/plugin-replace@2.4.2(rollup@2.80.0)': dependencies: - '@rollup/pluginutils': 3.1.0(rollup@2.79.2) + '@rollup/pluginutils': 3.1.0(rollup@2.80.0) magic-string: 0.25.9 - rollup: 2.79.2 + rollup: 2.80.0 - '@rollup/pluginutils@3.1.0(rollup@2.79.2)': + '@rollup/pluginutils@3.1.0(rollup@2.80.0)': dependencies: '@types/estree': 0.0.39 estree-walker: 1.0.1 - picomatch: 2.3.1 - rollup: 2.79.2 + picomatch: 2.3.2 + rollup: 2.80.0 + + '@rollup/rollup-android-arm-eabi@4.60.1': + optional: true + + '@rollup/rollup-android-arm64@4.60.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.60.1': + optional: true + + '@rollup/rollup-darwin-x64@4.60.1': + optional: true - '@rollup/rollup-android-arm-eabi@4.37.0': + '@rollup/rollup-freebsd-arm64@4.60.1': optional: true - '@rollup/rollup-android-arm64@4.37.0': + '@rollup/rollup-freebsd-x64@4.60.1': optional: true - '@rollup/rollup-darwin-arm64@4.37.0': + '@rollup/rollup-linux-arm-gnueabihf@4.60.1': optional: true - '@rollup/rollup-darwin-x64@4.37.0': + '@rollup/rollup-linux-arm-musleabihf@4.60.1': optional: true - '@rollup/rollup-freebsd-arm64@4.37.0': + '@rollup/rollup-linux-arm64-gnu@4.60.1': optional: true - '@rollup/rollup-freebsd-x64@4.37.0': + '@rollup/rollup-linux-arm64-musl@4.60.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.37.0': + '@rollup/rollup-linux-loong64-gnu@4.60.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.37.0': + '@rollup/rollup-linux-loong64-musl@4.60.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.37.0': + '@rollup/rollup-linux-ppc64-gnu@4.60.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.37.0': + '@rollup/rollup-linux-ppc64-musl@4.60.1': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.37.0': + '@rollup/rollup-linux-riscv64-gnu@4.60.1': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.37.0': + '@rollup/rollup-linux-riscv64-musl@4.60.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.37.0': + '@rollup/rollup-linux-s390x-gnu@4.60.1': optional: true - '@rollup/rollup-linux-riscv64-musl@4.37.0': + '@rollup/rollup-linux-x64-gnu@4.60.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.37.0': + '@rollup/rollup-linux-x64-musl@4.60.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.37.0': + '@rollup/rollup-openbsd-x64@4.60.1': optional: true - '@rollup/rollup-linux-x64-musl@4.37.0': + '@rollup/rollup-openharmony-arm64@4.60.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.37.0': + '@rollup/rollup-win32-arm64-msvc@4.60.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.37.0': + '@rollup/rollup-win32-ia32-msvc@4.60.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.37.0': + '@rollup/rollup-win32-x64-gnu@4.60.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.60.1': optional: true '@rtsao/scc@1.1.0': {} - '@rushstack/eslint-patch@1.11.0': {} + '@rushstack/eslint-patch@1.16.1': {} - '@scure/base@1.2.4': {} + '@scure/base@1.2.6': {} - '@scure/bip32@1.6.2': + '@scure/bip32@1.7.0': dependencies: - '@noble/curves': 1.8.1 - '@noble/hashes': 1.7.1 - '@scure/base': 1.2.4 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 - '@scure/bip39@1.5.4': + '@scure/bip39@1.6.0': dependencies: - '@noble/hashes': 1.7.1 - '@scure/base': 1.2.4 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@simple-libs/stream-utils@1.2.0': + optional: true '@sinclair/typebox@0.24.51': {} @@ -12231,31 +12808,49 @@ snapshots: dependencies: buffer: 6.0.3 - '@solana/web3.js@1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@solana/codecs-core@2.3.0(typescript@4.9.5)': + dependencies: + '@solana/errors': 2.3.0(typescript@4.9.5) + typescript: 4.9.5 + + '@solana/codecs-numbers@2.3.0(typescript@4.9.5)': + dependencies: + '@solana/codecs-core': 2.3.0(typescript@4.9.5) + '@solana/errors': 2.3.0(typescript@4.9.5) + typescript: 4.9.5 + + '@solana/errors@2.3.0(typescript@4.9.5)': + dependencies: + chalk: 5.6.2 + commander: 14.0.3 + typescript: 4.9.5 + + '@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@4.9.5)(utf-8-validate@6.0.6)': dependencies: - '@babel/runtime': 7.27.0 - '@noble/curves': 1.8.1 - '@noble/hashes': 1.7.1 + '@babel/runtime': 7.29.2 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 '@solana/buffer-layout': 4.0.1 + '@solana/codecs-numbers': 2.3.0(typescript@4.9.5) agentkeepalive: 4.6.0 - bigint-buffer: 1.1.5 - bn.js: 5.2.1 + bn.js: 5.2.3 borsh: 0.7.0 bs58: 4.0.1 buffer: 6.0.3 fast-stable-stringify: 1.0.0 - jayson: 4.1.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + jayson: 4.3.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) node-fetch: 2.7.0 - rpc-websockets: 9.1.1 + rpc-websockets: 9.3.8 superstruct: 2.0.2 transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate '@spruceid/siwe-parser@3.0.0': dependencies: - '@noble/hashes': 1.7.1 + '@noble/hashes': 1.8.0 apg-js: 4.4.0 '@stablelib/binary@1.0.1': @@ -12271,7 +12866,7 @@ snapshots: '@stablelib/wipe@1.0.1': {} - '@supercharge/promise-pool@3.2.0': {} + '@supercharge/promise-pool@3.3.0': {} '@surma/rollup-plugin-off-main-thread@2.2.3': dependencies: @@ -12317,11 +12912,11 @@ snapshots: '@svgr/hast-util-to-babel-ast@5.5.0': dependencies: - '@babel/types': 7.27.0 + '@babel/types': 7.29.0 '@svgr/plugin-jsx@5.5.0': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.29.0 '@svgr/babel-preset': 5.5.0 '@svgr/hast-util-to-babel-ast': 5.5.0 svg-parser: 2.0.4 @@ -12336,10 +12931,10 @@ snapshots: '@svgr/webpack@5.5.0': dependencies: - '@babel/core': 7.26.10 - '@babel/plugin-transform-react-constant-elements': 7.25.9(@babel/core@7.26.10) - '@babel/preset-env': 7.26.9(@babel/core@7.26.10) - '@babel/preset-react': 7.26.3(@babel/core@7.26.10) + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.29.0) + '@babel/preset-env': 7.29.2(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) '@svgr/core': 5.5.0 '@svgr/plugin-jsx': 5.5.0 '@svgr/plugin-svgo': 5.5.0 @@ -12353,15 +12948,17 @@ snapshots: dependencies: tslib: 2.8.1 + '@swc/helpers@0.5.21': + dependencies: + tslib: 2.8.1 + '@szmarczak/http-timer@4.0.6': dependencies: defer-to-connect: 2.0.1 '@tootallnate/once@1.1.2': {} - '@trysound/sax@0.2.0': {} - - '@tsconfig/node10@1.0.11': {} + '@tsconfig/node10@1.0.12': {} '@tsconfig/node12@1.0.11': {} @@ -12369,43 +12966,43 @@ snapshots: '@tsconfig/node16@1.0.4': {} - '@tybys/wasm-util@0.9.0': + '@tybys/wasm-util@0.10.1': dependencies: tslib: 2.8.1 optional: true - '@typechain/ethers-v5@11.1.2(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.8.2))(typescript@5.8.2)': + '@typechain/ethers-v5@11.1.2(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(typechain@8.3.2(typescript@5.9.3))(typescript@5.9.3)': dependencies: '@ethersproject/abi': 5.8.0 - '@ethersproject/providers': 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - lodash: 4.17.21 - ts-essentials: 7.0.3(typescript@5.8.2) - typechain: 8.3.2(typescript@5.8.2) - typescript: 5.8.2 + '@ethersproject/providers': 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ethers: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + lodash: 4.18.1 + ts-essentials: 7.0.3(typescript@5.9.3) + typechain: 8.3.2(typescript@5.9.3) + typescript: 5.9.3 '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.27.0 - '@babel/types': 7.27.0 - '@types/babel__generator': 7.6.8 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.7 + '@types/babel__traverse': 7.28.0 - '@types/babel__generator@7.6.8': + '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.27.0 + '@babel/types': 7.29.0 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.27.0 - '@babel/types': 7.27.0 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 - '@types/babel__traverse@7.20.7': + '@types/babel__traverse@7.28.0': dependencies: - '@babel/types': 7.27.0 + '@babel/types': 7.29.0 - '@types/body-parser@1.19.5': + '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 '@types/node': 24.3.0 @@ -12416,24 +13013,26 @@ snapshots: '@types/cacheable-request@6.0.3': dependencies: - '@types/http-cache-semantics': 4.0.4 + '@types/http-cache-semantics': 4.2.0 '@types/keyv': 3.1.4 '@types/node': 24.3.0 '@types/responselike': 1.0.3 + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + '@types/connect-history-api-fallback@1.5.4': dependencies: - '@types/express-serve-static-core': 5.0.6 + '@types/express-serve-static-core': 4.19.8 '@types/node': 24.3.0 '@types/connect@3.4.38': dependencies: '@types/node': 24.3.0 - '@types/conventional-commits-parser@5.0.1': - dependencies: - '@types/node': 24.3.0 - optional: true + '@types/deep-eql@4.0.2': {} '@types/deep-equal@1.0.4': {} @@ -12444,7 +13043,7 @@ snapshots: '@types/eslint@8.56.12': dependencies: - '@types/estree': 1.0.7 + '@types/estree': 1.0.8 '@types/json-schema': 7.0.15 '@types/eslint@9.6.1': @@ -12454,32 +13053,21 @@ snapshots: '@types/estree@0.0.39': {} - '@types/estree@1.0.6': {} - - '@types/estree@1.0.7': {} - '@types/estree@1.0.8': {} - '@types/express-serve-static-core@4.19.6': - dependencies: - '@types/node': 24.3.0 - '@types/qs': 6.9.18 - '@types/range-parser': 1.2.7 - '@types/send': 0.17.4 - - '@types/express-serve-static-core@5.0.6': + '@types/express-serve-static-core@4.19.8': dependencies: '@types/node': 24.3.0 - '@types/qs': 6.9.18 + '@types/qs': 6.15.0 '@types/range-parser': 1.2.7 - '@types/send': 0.17.4 + '@types/send': 1.2.1 - '@types/express@4.17.21': + '@types/express@4.17.25': dependencies: - '@types/body-parser': 1.19.5 - '@types/express-serve-static-core': 4.19.6 - '@types/qs': 6.9.18 - '@types/serve-static': 1.15.7 + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 4.19.8 + '@types/qs': 6.15.0 + '@types/serve-static': 1.15.10 '@types/graceful-fs@4.1.9': dependencies: @@ -12487,11 +13075,11 @@ snapshots: '@types/html-minifier-terser@6.1.0': {} - '@types/http-cache-semantics@4.0.4': {} + '@types/http-cache-semantics@4.2.0': {} - '@types/http-errors@2.0.4': {} + '@types/http-errors@2.0.5': {} - '@types/http-proxy@1.17.16': + '@types/http-proxy@1.17.17': dependencies: '@types/node': 24.3.0 @@ -12513,13 +13101,13 @@ snapshots: dependencies: '@types/node': 24.3.0 - '@types/lodash@4.17.16': {} + '@types/lodash@4.17.24': {} '@types/mime@1.3.5': {} '@types/minimist@1.2.5': {} - '@types/node-forge@1.3.11': + '@types/node-forge@1.3.14': dependencies: '@types/node': 24.3.0 @@ -12537,35 +13125,35 @@ snapshots: '@types/prettier@2.7.3': {} - '@types/prop-types@15.7.14': {} + '@types/prop-types@15.7.15': {} '@types/q@1.5.8': {} - '@types/qs@6.9.18': {} + '@types/qs@6.15.0': {} '@types/range-parser@1.2.7': {} '@types/react-copy-to-clipboard@5.0.7': dependencies: - '@types/react': 18.3.20 + '@types/react': 18.3.28 '@types/react-dom@18.3.0': dependencies: - '@types/react': 18.3.5 + '@types/react': 18.3.28 - '@types/react-dom@18.3.5(@types/react@18.3.20)': + '@types/react-dom@18.3.7(@types/react@18.3.28)': dependencies: - '@types/react': 18.3.20 + '@types/react': 18.3.28 - '@types/react@18.3.20': + '@types/react@18.3.28': dependencies: - '@types/prop-types': 15.7.14 - csstype: 3.1.3 + '@types/prop-types': 15.7.15 + csstype: 3.2.3 '@types/react@18.3.5': dependencies: - '@types/prop-types': 15.7.14 - csstype: 3.1.3 + '@types/prop-types': 15.7.15 + csstype: 3.2.3 '@types/resolve@1.17.1': dependencies: @@ -12579,22 +13167,26 @@ snapshots: '@types/retry@0.12.2': {} - '@types/semver@7.7.0': {} + '@types/semver@7.7.1': {} - '@types/send@0.17.4': + '@types/send@0.17.6': dependencies: '@types/mime': 1.3.5 '@types/node': 24.3.0 + '@types/send@1.2.1': + dependencies: + '@types/node': 24.3.0 + '@types/serve-index@1.9.4': dependencies: - '@types/express': 4.17.21 + '@types/express': 4.17.25 - '@types/serve-static@1.15.7': + '@types/serve-static@1.15.10': dependencies: - '@types/http-errors': 2.0.4 + '@types/http-errors': 2.0.5 '@types/node': 24.3.0 - '@types/send': 0.17.4 + '@types/send': 0.17.6 '@types/sockjs@0.3.36': dependencies: @@ -12606,82 +13198,82 @@ snapshots: '@types/trusted-types@2.0.7': {} - '@types/uuid@8.3.4': {} + '@types/uuid@10.0.0': {} '@types/ws@7.4.7': dependencies: '@types/node': 24.3.0 - '@types/ws@8.18.0': + '@types/ws@8.18.1': dependencies: '@types/node': 24.3.0 '@types/yargs-parser@21.0.3': {} - '@types/yargs@16.0.9': + '@types/yargs@16.0.11': dependencies: '@types/yargs-parser': 21.0.3 - '@types/yargs@17.0.33': + '@types/yargs@17.0.35': dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2)': + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3)': dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.8.2) + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.9.3) '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.1)(typescript@5.8.2) - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.8.2) - debug: 4.4.0 + '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.9.3) + debug: 4.4.3 eslint: 8.57.1 graphemer: 1.4.0 ignore: 5.3.2 natural-compare-lite: 1.4.0 - semver: 7.7.1 - tsutils: 3.21.0(typescript@5.8.2) + semver: 7.7.4 + tsutils: 3.21.0(typescript@5.9.3) optionalDependencies: - typescript: 5.8.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2)': + '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3)': dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.8.2) + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.3) '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.1)(typescript@5.8.2) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.8.2) + '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.9.3) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 + debug: 4.4.3 eslint: 8.57.1 graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - semver: 7.7.1 - ts-api-utils: 1.4.3(typescript@5.8.2) + semver: 7.7.4 + ts-api-utils: 1.4.3(typescript@5.9.3) optionalDependencies: - typescript: 5.8.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/experimental-utils@5.62.0(eslint@8.57.1)(typescript@5.8.2)': + '@typescript-eslint/experimental-utils@5.62.0(eslint@8.57.1)(typescript@5.9.3)': dependencies: - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.8.2) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.9.3) eslint: 8.57.1 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2)': + '@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.8.2) - debug: 4.4.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.9.3) + debug: 4.4.3 eslint: 8.57.1 optionalDependencies: - typescript: 5.8.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -12691,36 +13283,36 @@ snapshots: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.2.2) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 + debug: 4.4.3 eslint: 8.57.0 optionalDependencies: typescript: 5.2.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.8.2)': + '@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.8.2) + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.9.3) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 + debug: 4.4.3 eslint: 8.57.0 optionalDependencies: - typescript: 5.8.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2)': + '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.8.2) + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.9.3) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 + debug: 4.4.3 eslint: 8.57.1 optionalDependencies: - typescript: 5.8.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -12734,27 +13326,27 @@ snapshots: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 - '@typescript-eslint/type-utils@5.62.0(eslint@8.57.1)(typescript@5.8.2)': + '@typescript-eslint/type-utils@5.62.0(eslint@8.57.1)(typescript@5.9.3)': dependencies: - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.8.2) - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.8.2) - debug: 4.4.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.9.3) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.9.3) + debug: 4.4.3 eslint: 8.57.1 - tsutils: 3.21.0(typescript@5.8.2) + tsutils: 3.21.0(typescript@5.9.3) optionalDependencies: - typescript: 5.8.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@6.21.0(eslint@8.57.1)(typescript@5.8.2)': + '@typescript-eslint/type-utils@6.21.0(eslint@8.57.1)(typescript@5.9.3)': dependencies: - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.8.2) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.8.2) - debug: 4.4.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.9.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.9.3) + debug: 4.4.3 eslint: 8.57.1 - ts-api-utils: 1.4.3(typescript@5.8.2) + ts-api-utils: 1.4.3(typescript@5.9.3) optionalDependencies: - typescript: 5.8.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -12762,17 +13354,17 @@ snapshots: '@typescript-eslint/types@6.21.0': {} - '@typescript-eslint/typescript-estree@5.62.0(typescript@5.8.2)': + '@typescript-eslint/typescript-estree@5.62.0(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.4.0 + debug: 4.4.3 globby: 11.1.0 is-glob: 4.0.3 - semver: 7.7.1 - tsutils: 3.21.0(typescript@5.8.2) + semver: 7.7.4 + tsutils: 3.21.0(typescript@5.9.3) optionalDependencies: - typescript: 5.8.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -12780,57 +13372,57 @@ snapshots: dependencies: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 + debug: 4.4.3 globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 - semver: 7.7.1 + semver: 7.7.4 ts-api-utils: 1.4.3(typescript@5.2.2) optionalDependencies: typescript: 5.2.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@6.21.0(typescript@5.8.2)': + '@typescript-eslint/typescript-estree@6.21.0(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 + debug: 4.4.3 globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 - semver: 7.7.1 - ts-api-utils: 1.4.3(typescript@5.8.2) + semver: 7.7.4 + ts-api-utils: 1.4.3(typescript@5.9.3) optionalDependencies: - typescript: 5.8.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@5.8.2)': + '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@8.57.1) + '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) '@types/json-schema': 7.0.15 - '@types/semver': 7.7.0 + '@types/semver': 7.7.1 '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.8.2) + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.9.3) eslint: 8.57.1 eslint-scope: 5.1.1 - semver: 7.7.1 + semver: 7.7.4 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/utils@6.21.0(eslint@8.57.1)(typescript@5.8.2)': + '@typescript-eslint/utils@6.21.0(eslint@8.57.1)(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@8.57.1) + '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) '@types/json-schema': 7.0.15 - '@types/semver': 7.7.0 + '@types/semver': 7.7.1 '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.8.2) + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.9.3) eslint: 8.57.1 - semver: 7.7.1 + semver: 7.7.4 transitivePeerDependencies: - supports-color - typescript @@ -12847,60 +13439,72 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@uniswap/token-lists@1.0.0-beta.34': {} + '@uniswap/token-lists@1.0.0-beta.35': {} - '@unrs/resolver-binding-darwin-arm64@1.3.2': + '@unrs/resolver-binding-android-arm-eabi@1.11.1': optional: true - '@unrs/resolver-binding-darwin-x64@1.3.2': + '@unrs/resolver-binding-android-arm64@1.11.1': optional: true - '@unrs/resolver-binding-freebsd-x64@1.3.2': + '@unrs/resolver-binding-darwin-arm64@1.11.1': optional: true - '@unrs/resolver-binding-linux-arm-gnueabihf@1.3.2': + '@unrs/resolver-binding-darwin-x64@1.11.1': optional: true - '@unrs/resolver-binding-linux-arm-musleabihf@1.3.2': + '@unrs/resolver-binding-freebsd-x64@1.11.1': optional: true - '@unrs/resolver-binding-linux-arm64-gnu@1.3.2': + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': optional: true - '@unrs/resolver-binding-linux-arm64-musl@1.3.2': + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': optional: true - '@unrs/resolver-binding-linux-ppc64-gnu@1.3.2': + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': optional: true - '@unrs/resolver-binding-linux-s390x-gnu@1.3.2': + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': optional: true - '@unrs/resolver-binding-linux-x64-gnu@1.3.2': + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': optional: true - '@unrs/resolver-binding-linux-x64-musl@1.3.2': + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': optional: true - '@unrs/resolver-binding-wasm32-wasi@1.3.2': + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': dependencies: - '@napi-rs/wasm-runtime': 0.2.7 + '@napi-rs/wasm-runtime': 0.2.12 optional: true - '@unrs/resolver-binding-win32-arm64-msvc@1.3.2': + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': optional: true - '@unrs/resolver-binding-win32-ia32-msvc@1.3.2': + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': optional: true - '@unrs/resolver-binding-win32-x64-msvc@1.3.2': + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': optional: true - '@usedapp/core@1.2.16(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(node-fetch@2.7.0)(react@18.3.1)': + '@usedapp/core@1.2.16(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(node-fetch@2.7.0)(react@18.3.1)': dependencies: '@metamask/detect-provider': 2.0.0 - '@uniswap/token-lists': 1.0.0-beta.34 - ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@uniswap/token-lists': 1.0.0-beta.35 + ethers: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) fetch-mock: 9.11.0(node-fetch@2.7.0) lodash.merge: 4.6.2 lodash.pickby: 4.6.0 @@ -12910,63 +13514,65 @@ snapshots: - node-fetch - supports-color - '@vitest/coverage-v8@3.2.4(vitest@3.0.9(@types/node@24.3.0)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0))': + '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/node@24.3.0)(jiti@2.6.1)(jsdom@16.7.0(bufferutil@4.1.0))(terser@5.46.1))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 - ast-v8-to-istanbul: 0.3.5 - debug: 4.4.1 + ast-v8-to-istanbul: 0.3.12 + debug: 4.4.3 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 - istanbul-reports: 3.1.7 - magic-string: 0.30.17 + istanbul-reports: 3.2.0 + magic-string: 0.30.21 magicast: 0.3.5 - std-env: 3.9.0 - test-exclude: 7.0.1 + std-env: 3.10.0 + test-exclude: 7.0.2 tinyrainbow: 2.0.0 - vitest: 3.0.9(@types/node@24.3.0)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0) + vitest: 3.2.4(@types/node@24.3.0)(jiti@2.6.1)(jsdom@16.7.0(bufferutil@4.1.0))(terser@5.46.1) transitivePeerDependencies: - supports-color - '@vitest/expect@3.0.9': + '@vitest/expect@3.2.4': dependencies: - '@vitest/spy': 3.0.9 - '@vitest/utils': 3.0.9 - chai: 5.2.0 + '@types/chai': 5.2.3 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.0.9(vite@6.2.3(@types/node@24.3.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))': + '@vitest/mocker@3.2.4(vite@7.3.2(@types/node@24.3.0)(jiti@2.6.1)(terser@5.46.1))': dependencies: - '@vitest/spy': 3.0.9 + '@vitest/spy': 3.2.4 estree-walker: 3.0.3 - magic-string: 0.30.17 + magic-string: 0.30.21 optionalDependencies: - vite: 6.2.3(@types/node@24.3.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) + vite: 7.3.2(@types/node@24.3.0)(jiti@2.6.1)(terser@5.46.1) - '@vitest/pretty-format@3.0.9': + '@vitest/pretty-format@3.2.4': dependencies: tinyrainbow: 2.0.0 - '@vitest/runner@3.0.9': + '@vitest/runner@3.2.4': dependencies: - '@vitest/utils': 3.0.9 + '@vitest/utils': 3.2.4 pathe: 2.0.3 + strip-literal: 3.1.0 - '@vitest/snapshot@3.0.9': + '@vitest/snapshot@3.2.4': dependencies: - '@vitest/pretty-format': 3.0.9 - magic-string: 0.30.17 + '@vitest/pretty-format': 3.2.4 + magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@3.0.9': + '@vitest/spy@3.2.4': dependencies: - tinyspy: 3.0.2 + tinyspy: 4.0.4 - '@vitest/utils@3.0.9': + '@vitest/utils@3.2.4': dependencies: - '@vitest/pretty-format': 3.0.9 - loupe: 3.1.3 + '@vitest/pretty-format': 3.2.4 + loupe: 3.2.1 tinyrainbow: 2.0.0 '@webassemblyjs/ast@1.14.1': @@ -13045,22 +13651,22 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@xtuc/long': 4.2.2 - '@webpack-cli/configtest@3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3))(webpack@5.101.3(webpack-cli@6.0.1))': + '@webpack-cli/configtest@3.0.1(webpack-cli@6.0.1)(webpack@5.106.1)': dependencies: - webpack: 5.101.3(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3) + webpack: 5.106.1(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1) - '@webpack-cli/info@3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3))(webpack@5.101.3(webpack-cli@6.0.1))': + '@webpack-cli/info@3.0.1(webpack-cli@6.0.1)(webpack@5.106.1)': dependencies: - webpack: 5.101.3(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3) + webpack: 5.106.1(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1) - '@webpack-cli/serve@3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3))(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3))(webpack@5.101.3(webpack-cli@6.0.1))': + '@webpack-cli/serve@3.0.1(webpack-cli@6.0.1)(webpack-dev-server@5.2.3)(webpack@5.106.1)': dependencies: - webpack: 5.101.3(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3) + webpack: 5.106.1(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1) optionalDependencies: - webpack-dev-server: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3) + webpack-dev-server: 5.2.3(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack-cli@6.0.1)(webpack@5.106.1) '@xtuc/ieee754@1.2.0': {} @@ -13083,25 +13689,23 @@ snapshots: acorn: 7.4.1 acorn-walk: 7.2.0 - acorn-import-phases@1.0.4(acorn@8.15.0): + acorn-import-phases@1.0.4(acorn@8.16.0): dependencies: - acorn: 8.15.0 + acorn: 8.16.0 - acorn-jsx@5.3.2(acorn@8.14.1): + acorn-jsx@5.3.2(acorn@8.16.0): dependencies: - acorn: 8.14.1 + acorn: 8.16.0 acorn-walk@7.2.0: {} - acorn-walk@8.3.4: + acorn-walk@8.3.5: dependencies: - acorn: 8.14.1 + acorn: 8.16.0 acorn@7.4.1: {} - acorn@8.14.1: {} - - acorn@8.15.0: {} + acorn@8.16.0: {} add-stream@1.0.0: {} @@ -13116,7 +13720,7 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.4.0 + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -13124,30 +13728,30 @@ snapshots: dependencies: humanize-ms: 1.2.1 - ajv-formats@2.1.1(ajv@8.17.1): + ajv-formats@2.1.1(ajv@8.18.0): optionalDependencies: - ajv: 8.17.1 + ajv: 8.18.0 - ajv-keywords@3.5.2(ajv@6.12.6): + ajv-keywords@3.5.2(ajv@6.14.0): dependencies: - ajv: 6.12.6 + ajv: 6.14.0 - ajv-keywords@5.1.0(ajv@8.17.1): + ajv-keywords@5.1.0(ajv@8.18.0): dependencies: - ajv: 8.17.1 + ajv: 8.18.0 fast-deep-equal: 3.1.3 - ajv@6.12.6: + ajv@6.14.0: dependencies: fast-deep-equal: 3.1.3 fast-json-stable-stringify: 2.1.0 json-schema-traverse: 0.4.1 uri-js: 4.4.1 - ajv@8.17.1: + ajv@8.18.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.0.6 + fast-uri: 3.1.0 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 @@ -13168,7 +13772,7 @@ snapshots: transitivePeerDependencies: - encoding - anser@2.3.2: {} + anser@2.3.5: {} ansi-colors@4.1.3: {} @@ -13182,7 +13786,7 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.1.0: {} + ansi-regex@6.2.2: {} ansi-sequence-parser@1.1.3: {} @@ -13196,27 +13800,27 @@ snapshots: ansi-styles@5.2.0: {} - ansi-styles@6.2.1: {} + ansi-styles@6.2.3: {} any-promise@1.3.0: {} anymatch@3.1.3: dependencies: normalize-path: 3.0.0 - picomatch: 2.3.1 + picomatch: 2.3.2 apg-js@4.4.0: {} - arbundles@0.10.1(arweave@1.15.0)(bufferutil@4.0.9)(utf-8-validate@5.0.10): + arbundles@0.10.1(arweave@1.15.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@ethersproject/bytes': 5.8.0 '@ethersproject/hash': 5.8.0 - '@ethersproject/providers': 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@ethersproject/providers': 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@ethersproject/signing-key': 5.8.0 '@ethersproject/transactions': 5.8.0 '@ethersproject/wallet': 5.8.0 '@irys/arweave': 0.0.2 - '@noble/ed25519': 1.7.3 + '@noble/ed25519': 1.7.5 base64url: 3.0.1 bs58: 4.0.1 keccak: 3.0.4 @@ -13224,7 +13828,7 @@ snapshots: optionalDependencies: '@randlabs/myalgo-connect': 1.4.2 algosdk: 1.24.1 - arweave-stream-tx: 1.2.2(arweave@1.15.0) + arweave-stream-tx: 1.2.2(arweave@1.15.7) multistream: 4.1.0 tmp-promise: 3.0.3 transitivePeerDependencies: @@ -13236,7 +13840,7 @@ snapshots: arconnect@0.4.2: dependencies: - arweave: 1.15.0 + arweave: 1.15.7 optional: true arg@4.1.3: {} @@ -13264,56 +13868,58 @@ snapshots: array-ify@1.0.0: {} - array-includes@3.1.8: + array-includes@3.1.9: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 + call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 es-object-atoms: 1.1.1 get-intrinsic: 1.3.0 is-string: 1.1.1 + math-intrinsics: 1.1.0 array-union@2.1.0: {} array.prototype.findlast@1.2.5: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 es-errors: 1.3.0 es-object-atoms: 1.1.1 es-shim-unscopables: 1.1.0 array.prototype.findlastindex@1.2.6: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 es-errors: 1.3.0 es-object-atoms: 1.1.1 es-shim-unscopables: 1.1.0 array.prototype.flat@1.3.3: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 es-shim-unscopables: 1.1.0 array.prototype.flatmap@1.3.3: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 es-shim-unscopables: 1.1.0 array.prototype.reduce@1.0.8: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 es-array-method-boxes-properly: 1.0.0 es-errors: 1.3.0 es-object-atoms: 1.1.1 @@ -13321,31 +13927,31 @@ snapshots: array.prototype.tosorted@1.1.4: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 es-errors: 1.3.0 es-shim-unscopables: 1.1.0 arraybuffer.prototype.slice@1.0.4: dependencies: array-buffer-byte-length: 1.0.2 - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 es-errors: 1.3.0 get-intrinsic: 1.3.0 is-array-buffer: 3.0.5 arrify@1.0.1: {} - arweave-stream-tx@1.2.2(arweave@1.15.0): + arweave-stream-tx@1.2.2(arweave@1.15.7): dependencies: - arweave: 1.15.0 - exponential-backoff: 3.1.2 + arweave: 1.15.7 + exponential-backoff: 3.1.3 optional: true - arweave@1.15.0: + arweave@1.15.7: dependencies: arconnect: 0.4.2 asn1.js: 5.4.1 @@ -13357,26 +13963,32 @@ snapshots: asn1.js@4.10.1: dependencies: - bn.js: 4.12.1 + bn.js: 4.12.3 inherits: 2.0.4 minimalistic-assert: 1.0.1 asn1.js@5.4.1: dependencies: - bn.js: 4.12.1 + bn.js: 4.12.3 inherits: 2.0.4 minimalistic-assert: 1.0.1 safer-buffer: 2.1.2 + asn1js@3.0.7: + dependencies: + pvtsutils: 1.3.6 + pvutils: 1.1.5 + tslib: 2.8.1 + assertion-error@2.0.1: {} ast-types-flow@0.0.8: {} - ast-v8-to-istanbul@0.3.5: + ast-v8-to-istanbul@0.3.12: dependencies: - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 estree-walker: 3.0.3 - js-tokens: 9.0.1 + js-tokens: 10.0.0 async-function@1.0.0: {} @@ -13390,71 +14002,62 @@ snapshots: at-least-node@1.0.0: {} - autoprefixer@10.4.21(postcss@8.5.3): + autoprefixer@10.4.27(postcss@8.5.9): dependencies: - browserslist: 4.24.4 - caniuse-lite: 1.0.30001707 - fraction.js: 4.3.7 - normalize-range: 0.1.2 + browserslist: 4.28.2 + caniuse-lite: 1.0.30001787 + fraction.js: 5.3.4 picocolors: 1.1.1 - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.1.0 - axe-core@4.10.3: {} + axe-core@4.11.2: {} - axios-retry@4.5.0(axios@1.11.0): + axios-retry@4.5.0(axios@1.15.0): dependencies: - axios: 1.11.0 + axios: 1.15.0 is-retry-allowed: 2.2.0 - axios@1.11.0: - dependencies: - follow-redirects: 1.15.9 - form-data: 4.0.4 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - - axios@1.8.4: + axios@1.15.0: dependencies: - follow-redirects: 1.15.9 - form-data: 4.0.2 - proxy-from-env: 1.1.0 + follow-redirects: 1.15.11 + form-data: 4.0.5 + proxy-from-env: 2.1.0 transitivePeerDependencies: - debug axobject-query@4.1.0: {} - babel-jest@27.5.1(@babel/core@7.26.10): + babel-jest@27.5.1(@babel/core@7.29.0): dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.29.0 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 '@types/babel__core': 7.20.5 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 27.5.1(@babel/core@7.26.10) + babel-preset-jest: 27.5.1(@babel/core@7.29.0) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 transitivePeerDependencies: - supports-color - babel-loader@8.4.1(@babel/core@7.26.10)(webpack@5.101.3): + babel-loader@8.4.1(@babel/core@7.29.0)(webpack@5.106.1): dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.29.0 find-cache-dir: 3.3.2 loader-utils: 2.0.4 make-dir: 3.1.0 schema-utils: 2.7.1 - webpack: 5.101.3 + webpack: 5.106.1(webpack-cli@6.0.1) babel-plugin-istanbul@6.1.1: dependencies: - '@babel/helper-plugin-utils': 7.26.5 + '@babel/helper-plugin-utils': 7.28.6 '@istanbuljs/load-nyc-config': 1.1.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-instrument: 5.2.1 @@ -13464,89 +14067,97 @@ snapshots: babel-plugin-jest-hoist@27.5.1: dependencies: - '@babel/template': 7.27.0 - '@babel/types': 7.27.0 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 '@types/babel__core': 7.20.5 - '@types/babel__traverse': 7.20.7 + '@types/babel__traverse': 7.28.0 babel-plugin-macros@3.1.0: dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.29.2 cosmiconfig: 7.1.0 - resolve: 1.22.10 + resolve: 1.22.11 - babel-plugin-named-asset-import@0.3.8(@babel/core@7.26.10): + babel-plugin-named-asset-import@0.3.8(@babel/core@7.29.0): dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.29.0 - babel-plugin-polyfill-corejs2@0.4.13(@babel/core@7.26.10): + babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.0): dependencies: - '@babel/compat-data': 7.26.8 - '@babel/core': 7.26.10 - '@babel/helper-define-polyfill-provider': 0.6.4(@babel/core@7.26.10) + '@babel/compat-data': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) semver: 6.3.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.11.1(@babel/core@7.26.10): + babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.14.2(@babel/core@7.29.0): dependencies: - '@babel/core': 7.26.10 - '@babel/helper-define-polyfill-provider': 0.6.4(@babel/core@7.26.10) - core-js-compat: 3.41.0 + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.4(@babel/core@7.26.10): + babel-plugin-polyfill-regenerator@0.6.8(@babel/core@7.29.0): dependencies: - '@babel/core': 7.26.10 - '@babel/helper-define-polyfill-provider': 0.6.4(@babel/core@7.26.10) + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) transitivePeerDependencies: - supports-color babel-plugin-transform-react-remove-prop-types@0.4.24: {} - babel-preset-current-node-syntax@1.1.0(@babel/core@7.26.10): - dependencies: - '@babel/core': 7.26.10 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.26.10) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.26.10) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.26.10) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.26.10) - '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.26.10) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.26.10) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.26.10) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.26.10) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.26.10) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.26.10) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.26.10) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.26.10) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.26.10) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.26.10) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.26.10) - - babel-preset-jest@27.5.1(@babel/core@7.26.10): - dependencies: - '@babel/core': 7.26.10 + babel-preset-current-node-syntax@1.2.0(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.29.0) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.29.0) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.29.0) + '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.29.0) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.29.0) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.29.0) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.29.0) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.29.0) + + babel-preset-jest@27.5.1(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 babel-plugin-jest-hoist: 27.5.1 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.26.10) + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) babel-preset-react-app@10.1.0: dependencies: - '@babel/core': 7.26.10 - '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.26.10) - '@babel/plugin-proposal-decorators': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.26.10) - '@babel/plugin-proposal-numeric-separator': 7.18.6(@babel/core@7.26.10) - '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.26.10) - '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.26.10) - '@babel/plugin-proposal-private-property-in-object': 7.21.11(@babel/core@7.26.10) - '@babel/plugin-transform-flow-strip-types': 7.26.5(@babel/core@7.26.10) - '@babel/plugin-transform-react-display-name': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-runtime': 7.26.10(@babel/core@7.26.10) - '@babel/preset-env': 7.26.9(@babel/core@7.26.10) - '@babel/preset-react': 7.26.3(@babel/core@7.26.10) - '@babel/preset-typescript': 7.27.0(@babel/core@7.26.10) - '@babel/runtime': 7.27.0 + '@babel/core': 7.29.0 + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-proposal-numeric-separator': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.29.0) + '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.11(@babel/core@7.29.0) + '@babel/plugin-transform-flow-strip-types': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.29.0) + '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) + '@babel/preset-env': 7.29.2(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + '@babel/runtime': 7.29.2 babel-plugin-macros: 3.1.0 babel-plugin-transform-react-remove-prop-types: 0.4.24 transitivePeerDependencies: @@ -13554,6 +14165,8 @@ snapshots: balanced-match@1.0.2: {} + balanced-match@4.0.4: {} + base-x@3.0.11: dependencies: safe-buffer: 5.2.1 @@ -13564,6 +14177,8 @@ snapshots: base64url@3.0.1: {} + baseline-browser-mapping@2.10.17: {} + batch@0.6.1: {} bech32@1.1.4: {} @@ -13577,36 +14192,25 @@ snapshots: bluebird: 3.7.2 check-types: 11.2.3 hoopy: 0.1.4 - jsonpath: 1.1.1 + jsonpath: 1.3.0 tryer: 1.0.1 big.js@5.2.2: {} - bigint-buffer@1.1.5: - dependencies: - bindings: 1.5.0 - - bignumber.js@9.1.2: {} - - bignumber.js@9.3.1: - optional: true + bignumber.js@9.3.1: {} binary-extensions@2.3.0: {} - bindings@1.5.0: - dependencies: - file-uri-to-path: 1.0.0 - bip39-light@1.0.7: dependencies: create-hash: 1.2.0 - pbkdf2: 3.1.2 + pbkdf2: 3.1.5 bip39@3.0.2: dependencies: '@types/node': 11.11.6 create-hash: 1.2.0 - pbkdf2: 3.1.2 + pbkdf2: 3.1.5 randombytes: 2.1.0 bl@4.1.0: @@ -13617,22 +14221,24 @@ snapshots: bluebird@3.7.2: {} - bn.js@4.12.1: {} + bn.js@4.12.3: {} bn.js@5.2.1: {} - body-parser@1.20.3: + bn.js@5.2.3: {} + + body-parser@1.20.4: dependencies: bytes: 3.1.2 content-type: 1.0.5 debug: 2.6.9 depd: 2.0.0 destroy: 1.2.0 - http-errors: 2.0.0 + http-errors: 2.0.1 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.13.0 - raw-body: 2.5.2 + qs: 6.14.2 + raw-body: 2.5.3 type-is: 1.6.18 unpipe: 1.0.0 transitivePeerDependencies: @@ -13645,21 +14251,27 @@ snapshots: boolbase@1.0.0: {} + boolbase@2.0.0: {} + borsh@0.7.0: dependencies: bn.js: 5.2.1 bs58: 4.0.1 text-encoding-utf-8: 1.0.2 - brace-expansion@1.1.11: + brace-expansion@1.1.13: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.0.1: + brace-expansion@2.0.3: dependencies: balanced-match: 1.0.2 + brace-expansion@5.0.5: + dependencies: + balanced-match: 4.0.4 + braces@3.0.3: dependencies: fill-range: 7.1.1 @@ -13675,7 +14287,7 @@ snapshots: browserify-aes@1.2.0: dependencies: buffer-xor: 1.0.3 - cipher-base: 1.0.6 + cipher-base: 1.0.7 create-hash: 1.2.0 evp_bytestokey: 1.0.3 inherits: 2.0.4 @@ -13689,36 +14301,36 @@ snapshots: browserify-des@1.0.2: dependencies: - cipher-base: 1.0.6 + cipher-base: 1.0.7 des.js: 1.1.0 inherits: 2.0.4 safe-buffer: 5.2.1 browserify-rsa@4.1.1: dependencies: - bn.js: 5.2.1 + bn.js: 5.2.3 randombytes: 2.1.0 safe-buffer: 5.2.1 - browserify-sign@4.2.3: + browserify-sign@4.2.5: dependencies: - bn.js: 5.2.1 + bn.js: 5.2.3 browserify-rsa: 4.1.1 create-hash: 1.2.0 create-hmac: 1.1.7 elliptic: 6.6.1 - hash-base: 3.0.5 inherits: 2.0.4 - parse-asn1: 5.1.7 + parse-asn1: 5.1.9 readable-stream: 2.3.8 safe-buffer: 5.2.1 - browserslist@4.24.4: + browserslist@4.28.2: dependencies: - caniuse-lite: 1.0.30001707 - electron-to-chromium: 1.5.128 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.24.4) + baseline-browser-mapping: 2.10.17 + caniuse-lite: 1.0.30001787 + electron-to-chromium: 1.5.334 + node-releases: 2.0.37 + update-browserslist-db: 1.2.3(browserslist@4.28.2) bs58@4.0.1: dependencies: @@ -13746,7 +14358,7 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 - bufferutil@4.0.9: + bufferutil@4.1.0: dependencies: node-gyp-build: 4.8.4 optional: true @@ -13755,7 +14367,7 @@ snapshots: bundle-name@4.1.0: dependencies: - run-applescript: 7.0.0 + run-applescript: 7.1.0 bundle-require@4.2.1(esbuild@0.19.12): dependencies: @@ -13766,16 +14378,16 @@ snapshots: dependencies: bytes: 3.1.2 - bundlemon@3.1.0(typescript@5.8.2): + bundlemon@3.1.0(typescript@5.9.3): dependencies: - axios: 1.11.0 - axios-retry: 4.5.0(axios@1.11.0) + axios: 1.15.0 + axios-retry: 4.5.0(axios@1.15.0) brotli-size: 4.0.0 bundlemon-utils: 2.0.1 bytes: 3.1.2 chalk: 4.1.2 commander: 11.1.0 - cosmiconfig: 8.3.6(typescript@5.8.2) + cosmiconfig: 8.3.6(typescript@5.9.3) gzip-size: 6.0.0 micromatch: 4.0.8 yup: 0.32.11 @@ -13789,6 +14401,8 @@ snapshots: bytes@3.1.2: {} + bytestreamjs@2.0.1: {} + cac@6.7.14: {} cacheable-lookup@5.0.4: {} @@ -13810,7 +14424,7 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 - call-bind@1.0.8: + call-bind@1.0.9: dependencies: call-bind-apply-helpers: 1.0.2 es-define-property: 1.0.1 @@ -13843,22 +14457,22 @@ snapshots: caniuse-api@3.0.0: dependencies: - browserslist: 4.24.4 - caniuse-lite: 1.0.30001707 + browserslist: 4.28.2 + caniuse-lite: 1.0.30001787 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 - caniuse-lite@1.0.30001707: {} + caniuse-lite@1.0.30001787: {} case-sensitive-paths-webpack-plugin@2.4.0: {} - chai@5.2.0: + chai@5.3.3: dependencies: assertion-error: 2.0.1 - check-error: 2.1.1 + check-error: 2.1.3 deep-eql: 5.0.2 - loupe: 3.1.3 - pathval: 2.0.0 + loupe: 3.2.1 + pathval: 2.0.1 chalk@2.4.2: dependencies: @@ -13871,8 +14485,7 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 - chalk@5.4.1: - optional: true + chalk@5.6.2: {} char-regex@1.0.2: {} @@ -13880,7 +14493,9 @@ snapshots: chardet@0.7.0: {} - check-error@2.1.1: {} + chardet@2.1.1: {} + + check-error@2.1.3: {} check-types@11.2.3: {} @@ -13900,10 +14515,11 @@ snapshots: ci-info@3.9.0: {} - cipher-base@1.0.6: + cipher-base@1.0.7: dependencies: inherits: 2.0.4 safe-buffer: 5.2.1 + to-buffer: 1.2.2 cjs-module-lexer@1.4.3: {} @@ -13947,7 +14563,7 @@ snapshots: chalk: 2.4.2 q: 1.5.1 - collect-v8-coverage@1.0.2: {} + collect-v8-coverage@1.0.3: {} color-convert@1.9.3: dependencies: @@ -13961,18 +14577,6 @@ snapshots: color-name@1.1.4: {} - color-string@1.9.1: - dependencies: - color-name: 1.1.4 - simple-swizzle: 0.2.2 - optional: true - - color@4.2.3: - dependencies: - color-convert: 2.0.1 - color-string: 1.9.1 - optional: true - colord@2.9.3: {} colorette@2.0.20: {} @@ -14001,6 +14605,8 @@ snapshots: commander@13.1.0: {} + commander@14.0.3: {} + commander@2.20.3: {} commander@4.1.1: {} @@ -14009,10 +14615,10 @@ snapshots: commander@8.3.0: {} - commitizen@4.3.1(@types/node@24.3.0)(typescript@5.8.2): + commitizen@4.3.1(@types/node@24.3.0)(typescript@5.9.3): dependencies: cachedir: 2.3.0 - cz-conventional-changelog: 3.3.0(@types/node@24.3.0)(typescript@5.8.2) + cz-conventional-changelog: 3.3.0(@types/node@24.3.0)(typescript@5.9.3) dedent: 0.7.0 detect-indent: 6.1.0 find-node-modules: 2.1.3 @@ -14042,13 +14648,13 @@ snapshots: dependencies: mime-db: 1.54.0 - compression@1.8.0: + compression@1.8.1: dependencies: bytes: 3.1.2 compressible: 2.0.18 debug: 2.6.9 negotiator: 0.6.4 - on-headers: 1.0.2 + on-headers: 1.1.0 safe-buffer: 5.2.1 vary: 1.1.2 transitivePeerDependencies: @@ -14091,7 +14697,7 @@ snapshots: conventional-changelog-conventionalcommits@4.6.3: dependencies: compare-func: 2.0.0 - lodash: 4.17.21 + lodash: 4.18.1 q: 1.5.1 conventional-changelog-core@4.2.4: @@ -14104,7 +14710,7 @@ snapshots: git-raw-commits: 2.0.11 git-remote-origin-url: 2.0.0 git-semver-tags: 4.1.1 - lodash: 4.17.21 + lodash: 4.18.1 normalize-package-data: 3.0.3 q: 1.5.1 read-pkg: 3.0.0 @@ -14138,9 +14744,9 @@ snapshots: dependencies: conventional-commits-filter: 2.0.7 dateformat: 3.0.3 - handlebars: 4.7.8 + handlebars: 4.7.9 json-stringify-safe: 5.0.1 - lodash: 4.17.21 + lodash: 4.18.1 meow: 8.1.2 semver: 6.3.1 split: 1.0.1 @@ -14171,11 +14777,17 @@ snapshots: dependencies: JSONStream: 1.3.5 is-text-path: 1.0.1 - lodash: 4.17.21 + lodash: 4.18.1 meow: 8.1.2 split2: 3.2.2 through2: 4.0.2 + conventional-commits-parser@6.4.0: + dependencies: + '@simple-libs/stream-utils': 1.2.0 + meow: 13.2.0 + optional: true + conventional-recommended-bump@6.1.0: dependencies: concat-stream: 2.0.0 @@ -14191,39 +14803,39 @@ snapshots: convert-source-map@2.0.0: {} - cookie-signature@1.0.6: {} + cookie-signature@1.0.7: {} - cookie@0.7.1: {} + cookie@0.7.2: {} copy-to-clipboard@3.3.3: dependencies: toggle-selection: 1.0.6 - copy-webpack-plugin@13.0.1(webpack@5.101.3(webpack-cli@6.0.1)): + copy-webpack-plugin@13.0.1(webpack@5.106.1): dependencies: glob-parent: 6.0.2 normalize-path: 3.0.0 - schema-utils: 4.3.0 + schema-utils: 4.3.3 serialize-javascript: 6.0.2 - tinyglobby: 0.2.12 - webpack: 5.101.3(webpack-cli@6.0.1) + tinyglobby: 0.2.16 + webpack: 5.106.1(webpack-cli@6.0.1) - core-js-compat@3.41.0: + core-js-compat@3.49.0: dependencies: - browserslist: 4.24.4 + browserslist: 4.28.2 - core-js-pure@3.41.0: {} + core-js-pure@3.49.0: {} - core-js@3.41.0: {} + core-js@3.49.0: {} core-util-is@1.0.3: {} - cosmiconfig-typescript-loader@6.1.0(@types/node@24.3.0)(cosmiconfig@9.0.0(typescript@5.8.2))(typescript@5.8.2): + cosmiconfig-typescript-loader@6.3.0(@types/node@24.3.0)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3): dependencies: '@types/node': 24.3.0 - cosmiconfig: 9.0.0(typescript@5.8.2) - jiti: 2.4.2 - typescript: 5.8.2 + cosmiconfig: 9.0.1(typescript@5.9.3) + jiti: 2.6.1 + typescript: 5.9.3 optional: true cosmiconfig@6.0.0: @@ -14232,7 +14844,7 @@ snapshots: import-fresh: 3.3.1 parse-json: 5.2.0 path-type: 4.0.0 - yaml: 1.10.2 + yaml: 1.10.3 cosmiconfig@7.1.0: dependencies: @@ -14240,48 +14852,48 @@ snapshots: import-fresh: 3.3.1 parse-json: 5.2.0 path-type: 4.0.0 - yaml: 1.10.2 + yaml: 1.10.3 - cosmiconfig@8.3.6(typescript@5.8.2): + cosmiconfig@8.3.6(typescript@5.9.3): dependencies: import-fresh: 3.3.1 - js-yaml: 4.1.0 + js-yaml: 4.1.1 parse-json: 5.2.0 path-type: 4.0.0 optionalDependencies: - typescript: 5.8.2 + typescript: 5.9.3 - cosmiconfig@9.0.0(typescript@5.8.2): + cosmiconfig@9.0.1(typescript@5.9.3): dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 - js-yaml: 4.1.0 + js-yaml: 4.1.1 parse-json: 5.2.0 optionalDependencies: - typescript: 5.8.2 + typescript: 5.9.3 optional: true create-ecdh@4.0.4: dependencies: - bn.js: 4.12.1 + bn.js: 4.12.3 elliptic: 6.6.1 create-hash@1.2.0: dependencies: - cipher-base: 1.0.6 + cipher-base: 1.0.7 inherits: 2.0.4 md5.js: 1.3.5 - ripemd160: 2.0.2 - sha.js: 2.4.11 + ripemd160: 2.0.3 + sha.js: 2.4.12 create-hmac@1.1.7: dependencies: - cipher-base: 1.0.6 + cipher-base: 1.0.7 create-hash: 1.2.0 inherits: 2.0.4 - ripemd160: 2.0.2 + ripemd160: 2.0.3 safe-buffer: 5.2.1 - sha.js: 2.4.11 + sha.js: 2.4.12 create-require@1.1.1: {} @@ -14308,60 +14920,60 @@ snapshots: crypto-browserify@3.12.1: dependencies: browserify-cipher: 1.0.1 - browserify-sign: 4.2.3 + browserify-sign: 4.2.5 create-ecdh: 4.0.4 create-hash: 1.2.0 create-hmac: 1.1.7 diffie-hellman: 5.0.3 hash-base: 3.0.5 inherits: 2.0.4 - pbkdf2: 3.1.2 + pbkdf2: 3.1.5 public-encrypt: 4.0.3 randombytes: 2.1.0 randomfill: 1.0.4 crypto-random-string@2.0.0: {} - css-blank-pseudo@3.0.3(postcss@8.5.3): + css-blank-pseudo@3.0.3(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-selector-parser: 6.1.2 - css-declaration-sorter@6.4.1(postcss@8.5.3): + css-declaration-sorter@6.4.1(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 - css-has-pseudo@3.0.4(postcss@8.5.3): + css-has-pseudo@3.0.4(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-selector-parser: 6.1.2 - css-loader@6.11.0(webpack@5.101.3): + css-loader@6.11.0(webpack@5.106.1): dependencies: - icss-utils: 5.1.0(postcss@8.5.3) - postcss: 8.5.3 - postcss-modules-extract-imports: 3.1.0(postcss@8.5.3) - postcss-modules-local-by-default: 4.2.0(postcss@8.5.3) - postcss-modules-scope: 3.2.1(postcss@8.5.3) - postcss-modules-values: 4.0.0(postcss@8.5.3) + icss-utils: 5.1.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.9) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.9) + postcss-modules-scope: 3.2.1(postcss@8.5.9) + postcss-modules-values: 4.0.0(postcss@8.5.9) postcss-value-parser: 4.2.0 - semver: 7.7.1 + semver: 7.7.4 optionalDependencies: - webpack: 5.101.3 + webpack: 5.106.1(webpack-cli@6.0.1) - css-minimizer-webpack-plugin@3.4.1(webpack@5.101.3): + css-minimizer-webpack-plugin@3.4.1(webpack@5.106.1): dependencies: - cssnano: 5.1.15(postcss@8.5.3) + cssnano: 5.1.15(postcss@8.5.9) jest-worker: 27.5.1 - postcss: 8.5.3 - schema-utils: 4.3.0 + postcss: 8.5.9 + schema-utils: 4.3.3 serialize-javascript: 6.0.2 source-map: 0.6.1 - webpack: 5.101.3 + webpack: 5.106.1(webpack-cli@6.0.1) - css-prefers-color-scheme@6.0.3(postcss@8.5.3): + css-prefers-color-scheme@6.0.3(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 css-select-base-adapter@0.1.1: {} @@ -14370,12 +14982,12 @@ snapshots: boolbase: 1.0.0 css-what: 3.4.2 domutils: 1.7.0 - nth-check: 2.1.1 + nth-check: 3.0.1 css-select@4.3.0: dependencies: boolbase: 1.0.0 - css-what: 6.1.0 + css-what: 6.2.2 domhandler: 4.3.1 domutils: 2.8.0 nth-check: 2.1.1 @@ -14392,55 +15004,55 @@ snapshots: css-what@3.4.2: {} - css-what@6.1.0: {} + css-what@6.2.2: {} cssdb@7.11.2: {} cssesc@3.0.0: {} - cssnano-preset-default@5.2.14(postcss@8.5.3): - dependencies: - css-declaration-sorter: 6.4.1(postcss@8.5.3) - cssnano-utils: 3.1.0(postcss@8.5.3) - postcss: 8.5.3 - postcss-calc: 8.2.4(postcss@8.5.3) - postcss-colormin: 5.3.1(postcss@8.5.3) - postcss-convert-values: 5.1.3(postcss@8.5.3) - postcss-discard-comments: 5.1.2(postcss@8.5.3) - postcss-discard-duplicates: 5.1.0(postcss@8.5.3) - postcss-discard-empty: 5.1.1(postcss@8.5.3) - postcss-discard-overridden: 5.1.0(postcss@8.5.3) - postcss-merge-longhand: 5.1.7(postcss@8.5.3) - postcss-merge-rules: 5.1.4(postcss@8.5.3) - postcss-minify-font-values: 5.1.0(postcss@8.5.3) - postcss-minify-gradients: 5.1.1(postcss@8.5.3) - postcss-minify-params: 5.1.4(postcss@8.5.3) - postcss-minify-selectors: 5.2.1(postcss@8.5.3) - postcss-normalize-charset: 5.1.0(postcss@8.5.3) - postcss-normalize-display-values: 5.1.0(postcss@8.5.3) - postcss-normalize-positions: 5.1.1(postcss@8.5.3) - postcss-normalize-repeat-style: 5.1.1(postcss@8.5.3) - postcss-normalize-string: 5.1.0(postcss@8.5.3) - postcss-normalize-timing-functions: 5.1.0(postcss@8.5.3) - postcss-normalize-unicode: 5.1.1(postcss@8.5.3) - postcss-normalize-url: 5.1.0(postcss@8.5.3) - postcss-normalize-whitespace: 5.1.1(postcss@8.5.3) - postcss-ordered-values: 5.1.3(postcss@8.5.3) - postcss-reduce-initial: 5.1.2(postcss@8.5.3) - postcss-reduce-transforms: 5.1.0(postcss@8.5.3) - postcss-svgo: 5.1.0(postcss@8.5.3) - postcss-unique-selectors: 5.1.1(postcss@8.5.3) - - cssnano-utils@3.1.0(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - - cssnano@5.1.15(postcss@8.5.3): - dependencies: - cssnano-preset-default: 5.2.14(postcss@8.5.3) + cssnano-preset-default@5.2.14(postcss@8.5.9): + dependencies: + css-declaration-sorter: 6.4.1(postcss@8.5.9) + cssnano-utils: 3.1.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-calc: 8.2.4(postcss@8.5.9) + postcss-colormin: 5.3.1(postcss@8.5.9) + postcss-convert-values: 5.1.3(postcss@8.5.9) + postcss-discard-comments: 5.1.2(postcss@8.5.9) + postcss-discard-duplicates: 5.1.0(postcss@8.5.9) + postcss-discard-empty: 5.1.1(postcss@8.5.9) + postcss-discard-overridden: 5.1.0(postcss@8.5.9) + postcss-merge-longhand: 5.1.7(postcss@8.5.9) + postcss-merge-rules: 5.1.4(postcss@8.5.9) + postcss-minify-font-values: 5.1.0(postcss@8.5.9) + postcss-minify-gradients: 5.1.1(postcss@8.5.9) + postcss-minify-params: 5.1.4(postcss@8.5.9) + postcss-minify-selectors: 5.2.1(postcss@8.5.9) + postcss-normalize-charset: 5.1.0(postcss@8.5.9) + postcss-normalize-display-values: 5.1.0(postcss@8.5.9) + postcss-normalize-positions: 5.1.1(postcss@8.5.9) + postcss-normalize-repeat-style: 5.1.1(postcss@8.5.9) + postcss-normalize-string: 5.1.0(postcss@8.5.9) + postcss-normalize-timing-functions: 5.1.0(postcss@8.5.9) + postcss-normalize-unicode: 5.1.1(postcss@8.5.9) + postcss-normalize-url: 5.1.0(postcss@8.5.9) + postcss-normalize-whitespace: 5.1.1(postcss@8.5.9) + postcss-ordered-values: 5.1.3(postcss@8.5.9) + postcss-reduce-initial: 5.1.2(postcss@8.5.9) + postcss-reduce-transforms: 5.1.0(postcss@8.5.9) + postcss-svgo: 5.1.0(postcss@8.5.9) + postcss-unique-selectors: 5.1.1(postcss@8.5.9) + + cssnano-utils@3.1.0(postcss@8.5.9): + dependencies: + postcss: 8.5.9 + + cssnano@5.1.15(postcss@8.5.9): + dependencies: + cssnano-preset-default: 5.2.14(postcss@8.5.9) lilconfig: 2.1.0 - postcss: 8.5.3 - yaml: 1.10.2 + postcss: 8.5.9 + yaml: 1.10.3 csso@4.2.0: dependencies: @@ -14454,7 +15066,7 @@ snapshots: dependencies: cssom: 0.3.8 - csstype@3.1.3: {} + csstype@3.2.3: {} csv-generate@3.4.3: {} @@ -14469,16 +15081,16 @@ snapshots: csv-stringify: 5.6.5 stream-transform: 2.1.3 - cz-conventional-changelog@3.3.0(@types/node@24.3.0)(typescript@5.8.2): + cz-conventional-changelog@3.3.0(@types/node@24.3.0)(typescript@5.9.3): dependencies: chalk: 2.4.2 - commitizen: 4.3.1(@types/node@24.3.0)(typescript@5.8.2) + commitizen: 4.3.1(@types/node@24.3.0)(typescript@5.9.3) conventional-commit-types: 3.0.0 lodash.map: 4.6.0 longest: 2.0.1 word-wrap: 1.2.5 optionalDependencies: - '@commitlint/load': 19.8.0(@types/node@24.3.0)(typescript@5.8.2) + '@commitlint/load': 20.5.0(@types/node@24.3.0)(typescript@5.9.3) transitivePeerDependencies: - '@types/node' - typescript @@ -14521,11 +15133,7 @@ snapshots: dependencies: ms: 2.1.3 - debug@4.4.0: - dependencies: - ms: 2.1.3 - - debug@4.4.1: + debug@4.4.3: dependencies: ms: 2.1.3 @@ -14536,7 +15144,7 @@ snapshots: decamelize@1.2.0: {} - decimal.js@10.5.0: {} + decimal.js@10.6.0: {} decompress-response@6.0.0: dependencies: @@ -14549,7 +15157,7 @@ snapshots: deep-equal@2.2.3: dependencies: array-buffer-byte-length: 1.0.2 - call-bind: 1.0.8 + call-bind: 1.0.9 es-get-iterator: 1.1.3 get-intrinsic: 1.3.0 is-arguments: 1.2.0 @@ -14565,7 +15173,7 @@ snapshots: side-channel: 1.1.0 which-boxed-primitive: 1.1.1 which-collection: 1.0.2 - which-typed-array: 1.1.19 + which-typed-array: 1.1.20 deep-extend@0.6.0: {} @@ -14573,12 +15181,12 @@ snapshots: deepmerge@4.3.1: {} - default-browser-id@5.0.0: {} + default-browser-id@5.0.1: {} - default-browser@5.2.1: + default-browser@5.5.0: dependencies: bundle-name: 4.1.0 - default-browser-id: 5.0.0 + default-browser-id: 5.0.1 default-gateway@6.0.3: dependencies: @@ -14625,9 +15233,9 @@ snapshots: detect-indent@6.1.0: {} - detect-indent@7.0.1: {} + detect-indent@7.0.2: {} - detect-libc@2.0.4: + detect-libc@2.1.2: optional: true detect-newline@3.1.0: {} @@ -14647,11 +15255,11 @@ snapshots: diff-sequences@27.5.1: {} - diff@4.0.2: {} + diff@4.0.4: {} diffie-hellman@5.0.3: dependencies: - bn.js: 4.12.1 + bn.js: 4.12.3 miller-rabin: 4.0.1 randombytes: 2.1.0 @@ -14724,14 +15332,12 @@ snapshots: dotenv@10.0.0: {} - dotenv@16.4.7: {} - dotenv@16.6.1: {} dotgitignore@2.1.0: dependencies: find-up: 3.0.0 - minimatch: 3.1.2 + minimatch: 3.1.5 dunder-proto@1.0.1: dependencies: @@ -14749,13 +15355,13 @@ snapshots: ejs@3.1.10: dependencies: - jake: 10.9.2 + jake: 10.9.4 - electron-to-chromium@1.5.128: {} + electron-to-chromium@1.5.334: {} elliptic@6.6.1: dependencies: - bn.js: 4.12.1 + bn.js: 4.12.3 brorand: 1.1.0 hash.js: 1.1.7 hmac-drbg: 1.0.1 @@ -14775,18 +15381,16 @@ snapshots: emojis-list@3.0.0: {} - encodeurl@1.0.2: {} - encodeurl@2.0.0: {} end-of-stream@1.4.5: dependencies: once: 1.4.0 - enhanced-resolve@5.18.1: + enhanced-resolve@5.20.1: dependencies: graceful-fs: 4.2.11 - tapable: 2.2.1 + tapable: 2.3.2 enquirer@2.4.1: dependencies: @@ -14798,9 +15402,9 @@ snapshots: env-paths@2.2.1: optional: true - envinfo@7.14.0: {} + envinfo@7.21.0: {} - error-ex@1.3.2: + error-ex@1.3.4: dependencies: is-arrayish: 0.2.1 @@ -14808,12 +15412,12 @@ snapshots: dependencies: stackframe: 1.3.4 - es-abstract@1.23.9: + es-abstract@1.24.2: dependencies: array-buffer-byte-length: 1.0.2 arraybuffer.prototype.slice: 1.0.4 available-typed-arrays: 1.0.7 - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 data-view-buffer: 1.0.2 data-view-byte-length: 1.0.2 @@ -14837,7 +15441,9 @@ snapshots: is-array-buffer: 3.0.5 is-callable: 1.2.7 is-data-view: 1.0.2 + is-negative-zero: 2.0.3 is-regex: 1.2.1 + is-set: 2.0.3 is-shared-array-buffer: 1.0.4 is-string: 1.1.1 is-typed-array: 1.1.15 @@ -14852,6 +15458,7 @@ snapshots: safe-push-apply: 1.0.0 safe-regex-test: 1.1.0 set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 string.prototype.trim: 1.2.10 string.prototype.trimend: 1.0.9 string.prototype.trimstart: 1.0.8 @@ -14860,7 +15467,7 @@ snapshots: typed-array-byte-offset: 1.0.4 typed-array-length: 1.0.7 unbox-primitive: 1.1.0 - which-typed-array: 1.1.19 + which-typed-array: 1.1.20 es-array-method-boxes-properly@1.0.0: {} @@ -14870,7 +15477,7 @@ snapshots: es-get-iterator@1.1.3: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 get-intrinsic: 1.3.0 has-symbols: 1.1.0 is-arguments: 1.2.0 @@ -14880,12 +15487,12 @@ snapshots: isarray: 2.0.5 stop-iteration-iterator: 1.1.0 - es-iterator-helpers@1.2.1: + es-iterator-helpers@1.3.2: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 es-errors: 1.3.0 es-set-tostringtag: 2.1.0 function-bind: 1.1.2 @@ -14897,9 +15504,11 @@ snapshots: has-symbols: 1.1.0 internal-slot: 1.1.0 iterator.prototype: 1.1.5 - safe-array-concat: 1.1.3 + math-intrinsics: 1.1.0 - es-module-lexer@1.6.0: {} + es-module-lexer@1.7.0: {} + + es-module-lexer@2.0.0: {} es-object-atoms@1.1.1: dependencies: @@ -14928,14 +15537,14 @@ snapshots: dependencies: es6-promise: 4.2.8 - esbuild-loader@2.21.0(webpack@5.101.3(webpack-cli@6.0.1)): + esbuild-loader@2.21.0(webpack@5.106.1): dependencies: esbuild: 0.16.17 joycon: 3.1.1 json5: 2.2.3 loader-utils: 2.0.4 - tapable: 2.2.1 - webpack: 5.101.3(webpack-cli@6.0.1) + tapable: 2.3.2 + webpack: 5.106.1(webpack-cli@6.0.1) webpack-sources: 1.4.3 esbuild@0.16.17: @@ -14989,33 +15598,34 @@ snapshots: '@esbuild/win32-ia32': 0.19.12 '@esbuild/win32-x64': 0.19.12 - esbuild@0.25.1: + esbuild@0.27.7: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.1 - '@esbuild/android-arm': 0.25.1 - '@esbuild/android-arm64': 0.25.1 - '@esbuild/android-x64': 0.25.1 - '@esbuild/darwin-arm64': 0.25.1 - '@esbuild/darwin-x64': 0.25.1 - '@esbuild/freebsd-arm64': 0.25.1 - '@esbuild/freebsd-x64': 0.25.1 - '@esbuild/linux-arm': 0.25.1 - '@esbuild/linux-arm64': 0.25.1 - '@esbuild/linux-ia32': 0.25.1 - '@esbuild/linux-loong64': 0.25.1 - '@esbuild/linux-mips64el': 0.25.1 - '@esbuild/linux-ppc64': 0.25.1 - '@esbuild/linux-riscv64': 0.25.1 - '@esbuild/linux-s390x': 0.25.1 - '@esbuild/linux-x64': 0.25.1 - '@esbuild/netbsd-arm64': 0.25.1 - '@esbuild/netbsd-x64': 0.25.1 - '@esbuild/openbsd-arm64': 0.25.1 - '@esbuild/openbsd-x64': 0.25.1 - '@esbuild/sunos-x64': 0.25.1 - '@esbuild/win32-arm64': 0.25.1 - '@esbuild/win32-ia32': 0.25.1 - '@esbuild/win32-x64': 0.25.1 + '@esbuild/aix-ppc64': 0.27.7 + '@esbuild/android-arm': 0.27.7 + '@esbuild/android-arm64': 0.27.7 + '@esbuild/android-x64': 0.27.7 + '@esbuild/darwin-arm64': 0.27.7 + '@esbuild/darwin-x64': 0.27.7 + '@esbuild/freebsd-arm64': 0.27.7 + '@esbuild/freebsd-x64': 0.27.7 + '@esbuild/linux-arm': 0.27.7 + '@esbuild/linux-arm64': 0.27.7 + '@esbuild/linux-ia32': 0.27.7 + '@esbuild/linux-loong64': 0.27.7 + '@esbuild/linux-mips64el': 0.27.7 + '@esbuild/linux-ppc64': 0.27.7 + '@esbuild/linux-riscv64': 0.27.7 + '@esbuild/linux-s390x': 0.27.7 + '@esbuild/linux-x64': 0.27.7 + '@esbuild/netbsd-arm64': 0.27.7 + '@esbuild/netbsd-x64': 0.27.7 + '@esbuild/openbsd-arm64': 0.27.7 + '@esbuild/openbsd-x64': 0.27.7 + '@esbuild/openharmony-arm64': 0.27.7 + '@esbuild/sunos-x64': 0.27.7 + '@esbuild/win32-arm64': 0.27.7 + '@esbuild/win32-ia32': 0.27.7 + '@esbuild/win32-x64': 0.27.7 escalade@3.2.0: {} @@ -15047,14 +15657,14 @@ snapshots: eslint-config-next@14.0.4(eslint@8.57.0)(typescript@5.2.2): dependencies: '@next/eslint-plugin-next': 14.0.4 - '@rushstack/eslint-patch': 1.11.0 + '@rushstack/eslint-patch': 1.16.1 '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.2.2) eslint: 8.57.0 - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.0) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.2.2))(eslint-import-resolver-typescript@3.10.0)(eslint@8.57.0) + eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.0) - eslint-plugin-react: 7.37.4(eslint@8.57.0) + eslint-plugin-react: 7.37.5(eslint@8.57.0) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.0) optionalDependencies: typescript: 5.2.2 @@ -15063,48 +15673,48 @@ snapshots: - eslint-plugin-import-x - supports-color - eslint-config-next@14.0.4(eslint@8.57.0)(typescript@5.8.2): + eslint-config-next@14.0.4(eslint@8.57.0)(typescript@5.9.3): dependencies: '@next/eslint-plugin-next': 14.0.4 - '@rushstack/eslint-patch': 1.11.0 - '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.8.2) + '@rushstack/eslint-patch': 1.16.1 + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.9.3) eslint: 8.57.0 - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.0) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.0) + eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.0) - eslint-plugin-react: 7.37.4(eslint@8.57.0) + eslint-plugin-react: 7.37.5(eslint@8.57.0) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.0) optionalDependencies: - typescript: 5.8.2 + typescript: 5.9.3 transitivePeerDependencies: - eslint-import-resolver-webpack - eslint-plugin-import-x - supports-color - eslint-config-prettier@9.1.0(eslint@8.57.1): + eslint-config-prettier@9.1.2(eslint@8.57.1): dependencies: eslint: 8.57.1 - eslint-config-react-app@7.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10))(typescript@5.8.2): + eslint-config-react-app@7.0.1(@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0))(@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)))(typescript@5.9.3): dependencies: - '@babel/core': 7.26.10 - '@babel/eslint-parser': 7.27.0(@babel/core@7.26.10)(eslint@8.57.1) - '@rushstack/eslint-patch': 1.11.0 - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2) - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.8.2) + '@babel/core': 7.29.0 + '@babel/eslint-parser': 7.28.6(@babel/core@7.29.0)(eslint@8.57.1) + '@rushstack/eslint-patch': 1.16.1 + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.9.3) babel-preset-react-app: 10.1.0 confusing-browser-globals: 1.0.11 eslint: 8.57.1 - eslint-plugin-flowtype: 8.0.3(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(eslint@8.57.1) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1) - eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10))(typescript@5.8.2) + eslint-plugin-flowtype: 8.0.3(@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0))(@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0))(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) + eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)))(typescript@5.9.3) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) - eslint-plugin-react: 7.37.4(eslint@8.57.1) + eslint-plugin-react: 7.37.5(eslint@8.57.1) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) - eslint-plugin-testing-library: 5.11.1(eslint@8.57.1)(typescript@5.8.2) + eslint-plugin-testing-library: 5.11.1(eslint@8.57.1)(typescript@5.9.3) optionalDependencies: - typescript: 5.8.2 + typescript: 5.9.3 transitivePeerDependencies: - '@babel/plugin-syntax-flow' - '@babel/plugin-transform-react-jsx' @@ -15113,72 +15723,62 @@ snapshots: - jest - supports-color - eslint-config-typestrict@1.0.5(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint-plugin-sonarjs@0.23.0(eslint@8.57.1)): + eslint-config-typestrict@1.0.5(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3))(eslint-plugin-sonarjs@4.0.2(eslint@8.57.1)): dependencies: - '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2) - eslint-plugin-sonarjs: 0.23.0(eslint@8.57.1) + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + eslint-plugin-sonarjs: 4.0.2(eslint@8.57.1) - eslint-import-resolver-node@0.3.9: + eslint-import-resolver-node@0.3.10: dependencies: debug: 3.2.7 is-core-module: 2.16.1 - resolve: 1.22.10 + resolve: 2.0.0-next.6 transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.0): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.0): dependencies: '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.0 + debug: 4.4.3 eslint: 8.57.0 - get-tsconfig: 4.10.0 + get-tsconfig: 4.13.7 is-bun-module: 2.0.0 stable-hash: 0.0.5 - tinyglobby: 0.2.12 - unrs-resolver: 1.3.2 + tinyglobby: 0.2.16 + unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): + eslint-module-utils@2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.8.2) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.9.3) eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.2.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.0))(eslint@8.57.0): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.2.2) - eslint: 8.57.0 - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.0) + eslint-import-resolver-node: 0.3.10 transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): + eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.8.2) + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.3) eslint: 8.57.0 - eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.0) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): + eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.8.2) + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.3) eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-node: 0.3.10 transitivePeerDependencies: - supports-color @@ -15188,59 +15788,30 @@ snapshots: eslint: 8.57.1 ignore: 5.3.2 - eslint-plugin-flowtype@8.0.3(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(eslint@8.57.1): + eslint-plugin-flowtype@8.0.3(@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0))(@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0))(eslint@8.57.1): dependencies: - '@babel/plugin-syntax-flow': 7.26.0(@babel/core@7.26.10) - '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.10) + '@babel/plugin-syntax-flow': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) eslint: 8.57.1 - lodash: 4.17.21 + lodash: 4.18.1 string-natural-compare: 3.0.1 - eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 - array-includes: 3.1.8 + array-includes: 3.1.9 array.prototype.findlastindex: 1.2.6 array.prototype.flat: 1.3.3 array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) - hasown: 2.0.2 - is-core-module: 2.16.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.1 - semver: 6.3.1 - string.prototype.trimend: 1.0.9 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.8.2) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.2.2))(eslint-import-resolver-typescript@3.10.0)(eslint@8.57.0): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.8 - array.prototype.findlastindex: 1.2.6 - array.prototype.flat: 1.3.3 - array.prototype.flatmap: 1.3.3 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 8.57.0 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.2.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.0))(eslint@8.57.0) + eslint-import-resolver-node: 0.3.10 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 - minimatch: 3.1.2 + minimatch: 3.1.5 object.fromentries: 2.0.8 object.groupby: 1.0.3 object.values: 1.2.1 @@ -15248,28 +15819,28 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.2.2) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.9.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0): dependencies: '@rtsao/scc': 1.1.0 - array-includes: 3.1.8 + array-includes: 3.1.9 array.prototype.findlastindex: 1.2.6 array.prototype.flat: 1.3.3 array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 eslint: 8.57.0 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + eslint-import-resolver-node: 0.3.10 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 - minimatch: 3.1.2 + minimatch: 3.1.5 object.fromentries: 2.0.8 object.groupby: 1.0.3 object.values: 1.2.1 @@ -15277,28 +15848,28 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.8.2) + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 - array-includes: 3.1.8 + array-includes: 3.1.9 array.prototype.findlastindex: 1.2.6 array.prototype.flat: 1.3.3 array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) + eslint-import-resolver-node: 0.3.10 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 - minimatch: 3.1.2 + minimatch: 3.1.5 object.fromentries: 2.0.8 object.groupby: 1.0.3 object.values: 1.2.1 @@ -15306,19 +15877,19 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.8.2) + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10))(typescript@5.8.2): + eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)))(typescript@5.9.3): dependencies: - '@typescript-eslint/experimental-utils': 5.62.0(eslint@8.57.1)(typescript@5.8.2) + '@typescript-eslint/experimental-utils': 5.62.0(eslint@8.57.1)(typescript@5.9.3) eslint: 8.57.1 optionalDependencies: - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2) - jest: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10) + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + jest: 27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)) transitivePeerDependencies: - supports-color - typescript @@ -15326,10 +15897,10 @@ snapshots: eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.0): dependencies: aria-query: 5.3.2 - array-includes: 3.1.8 + array-includes: 3.1.9 array.prototype.flatmap: 1.3.3 ast-types-flow: 0.0.8 - axe-core: 4.10.3 + axe-core: 4.11.2 axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 @@ -15337,7 +15908,7 @@ snapshots: hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 - minimatch: 3.1.2 + minimatch: 3.1.5 object.fromentries: 2.0.8 safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 @@ -15345,10 +15916,10 @@ snapshots: eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1): dependencies: aria-query: 5.3.2 - array-includes: 3.1.8 + array-includes: 3.1.9 array.prototype.flatmap: 1.3.3 ast-types-flow: 0.0.8 - axe-core: 4.10.3 + axe-core: 4.11.2 axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 @@ -15356,7 +15927,7 @@ snapshots: hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 - minimatch: 3.1.2 + minimatch: 3.1.5 object.fromentries: 2.0.8 safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 @@ -15371,46 +15942,46 @@ snapshots: dependencies: eslint: 8.57.0 - eslint-plugin-react@7.37.4(eslint@8.57.0): + eslint-plugin-react@7.37.5(eslint@8.57.0): dependencies: - array-includes: 3.1.8 + array-includes: 3.1.9 array.prototype.findlast: 1.2.5 array.prototype.flatmap: 1.3.3 array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 - es-iterator-helpers: 1.2.1 + es-iterator-helpers: 1.3.2 eslint: 8.57.0 estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 - minimatch: 3.1.2 + minimatch: 3.1.5 object.entries: 1.1.9 object.fromentries: 2.0.8 object.values: 1.2.1 prop-types: 15.8.1 - resolve: 2.0.0-next.5 + resolve: 2.0.0-next.6 semver: 6.3.1 string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-react@7.37.4(eslint@8.57.1): + eslint-plugin-react@7.37.5(eslint@8.57.1): dependencies: - array-includes: 3.1.8 + array-includes: 3.1.9 array.prototype.findlast: 1.2.5 array.prototype.flatmap: 1.3.3 array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 - es-iterator-helpers: 1.2.1 + es-iterator-helpers: 1.3.2 eslint: 8.57.1 estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 - minimatch: 3.1.2 + minimatch: 3.1.5 object.entries: 1.1.9 object.fromentries: 2.0.8 object.values: 1.2.1 prop-types: 15.8.1 - resolve: 2.0.0-next.5 + resolve: 2.0.0-next.6 semver: 6.3.1 string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 @@ -15419,23 +15990,35 @@ snapshots: dependencies: eslint: 8.57.1 - eslint-plugin-sonarjs@0.23.0(eslint@8.57.1): + eslint-plugin-sonarjs@4.0.2(eslint@8.57.1): dependencies: + '@eslint-community/regexpp': 4.12.2 + builtin-modules: 3.3.0 + bytes: 3.1.2 eslint: 8.57.1 + functional-red-black-tree: 1.0.1 + globals: 17.4.0 + jsx-ast-utils-x: 0.1.0 + lodash.merge: 4.6.2 + minimatch: 10.2.5 + scslre: 0.3.0 + semver: 7.7.4 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 - eslint-plugin-testing-library@5.11.1(eslint@8.57.1)(typescript@5.8.2): + eslint-plugin-testing-library@5.11.1(eslint@8.57.1)(typescript@5.9.3): dependencies: - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.8.2) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.9.3) eslint: 8.57.1 transitivePeerDependencies: - supports-color - typescript - eslint-plugin-unused-imports@4.2.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1): + eslint-plugin-unused-imports@4.4.1(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1): dependencies: eslint: 8.57.1 optionalDependencies: - '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2) + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) eslint-scope@5.1.1: dependencies: @@ -15451,36 +16034,36 @@ snapshots: eslint-visitor-keys@3.4.3: {} - eslint-webpack-plugin@3.2.0(eslint@8.57.1)(webpack@5.101.3): + eslint-webpack-plugin@3.2.0(eslint@8.57.1)(webpack@5.106.1): dependencies: '@types/eslint': 8.56.12 eslint: 8.57.1 jest-worker: 28.1.3 micromatch: 4.0.8 normalize-path: 3.0.0 - schema-utils: 4.3.0 - webpack: 5.101.3 + schema-utils: 4.3.3 + webpack: 5.106.1(webpack-cli@6.0.1) eslint@8.57.0: dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@8.57.0) - '@eslint-community/regexpp': 4.12.1 + '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.0) + '@eslint-community/regexpp': 4.12.2 '@eslint/eslintrc': 2.1.4 '@eslint/js': 8.57.0 '@humanwhocodes/config-array': 0.11.14 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 '@ungap/structured-clone': 1.3.0 - ajv: 6.12.6 + ajv: 6.14.0 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.0 + debug: 4.4.3 doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 - esquery: 1.6.0 + esquery: 1.7.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 6.0.1 @@ -15492,11 +16075,11 @@ snapshots: imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 - js-yaml: 4.1.0 + js-yaml: 4.1.1 json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 lodash.merge: 4.6.2 - minimatch: 3.1.2 + minimatch: 3.1.5 natural-compare: 1.4.0 optionator: 0.9.4 strip-ansi: 6.0.1 @@ -15506,24 +16089,24 @@ snapshots: eslint@8.57.1: dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@8.57.1) - '@eslint-community/regexpp': 4.12.1 + '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) + '@eslint-community/regexpp': 4.12.2 '@eslint/eslintrc': 2.1.4 '@eslint/js': 8.57.1 '@humanwhocodes/config-array': 0.13.0 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 '@ungap/structured-clone': 1.3.0 - ajv: 6.12.6 + ajv: 6.14.0 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.0 + debug: 4.4.3 doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 - esquery: 1.6.0 + esquery: 1.7.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 6.0.1 @@ -15535,11 +16118,11 @@ snapshots: imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 - js-yaml: 4.1.0 + js-yaml: 4.1.1 json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 lodash.merge: 4.6.2 - minimatch: 3.1.2 + minimatch: 3.1.5 natural-compare: 1.4.0 optionator: 0.9.4 strip-ansi: 6.0.1 @@ -15549,15 +16132,15 @@ snapshots: espree@9.6.1: dependencies: - acorn: 8.14.1 - acorn-jsx: 5.3.2(acorn@8.14.1) + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) eslint-visitor-keys: 3.4.3 - esprima@1.2.2: {} + esprima@1.2.5: {} esprima@4.0.1: {} - esquery@1.6.0: + esquery@1.7.0: dependencies: estraverse: 5.3.0 @@ -15573,13 +16156,13 @@ snapshots: estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.7 + '@types/estree': 1.0.8 esutils@2.0.3: {} etag@1.8.1: {} - ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): + ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@ethersproject/abi': 5.8.0 '@ethersproject/abstract-provider': 5.8.0 @@ -15599,7 +16182,7 @@ snapshots: '@ethersproject/networks': 5.8.0 '@ethersproject/pbkdf2': 5.8.0 '@ethersproject/properties': 5.8.0 - '@ethersproject/providers': 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@ethersproject/providers': 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@ethersproject/random': 5.8.0 '@ethersproject/rlp': 5.8.0 '@ethersproject/sha2': 5.8.0 @@ -15617,7 +16200,7 @@ snapshots: eventemitter3@4.0.7: {} - eventemitter3@5.0.1: {} + eventemitter3@5.0.4: {} events@3.3.0: {} @@ -15644,7 +16227,7 @@ snapshots: dependencies: homedir-polyfill: 1.0.3 - expect-type@1.2.0: {} + expect-type@1.3.0: {} expect@27.5.1: dependencies: @@ -15653,39 +16236,39 @@ snapshots: jest-matcher-utils: 27.5.1 jest-message-util: 27.5.1 - exponential-backoff@3.1.2: + exponential-backoff@3.1.3: optional: true - express@4.21.2: + express@4.22.1: dependencies: accepts: 1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.3 + body-parser: 1.20.4 content-disposition: 0.5.4 content-type: 1.0.5 - cookie: 0.7.1 - cookie-signature: 1.0.6 + cookie: 0.7.2 + cookie-signature: 1.0.7 debug: 2.6.9 depd: 2.0.0 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 1.3.1 + finalhandler: 1.3.2 fresh: 0.5.2 - http-errors: 2.0.0 + http-errors: 2.0.1 merge-descriptors: 1.0.3 methods: 1.1.2 on-finished: 2.4.1 parseurl: 1.3.3 - path-to-regexp: 0.1.12 + path-to-regexp: 0.1.13 proxy-addr: 2.0.7 - qs: 6.13.0 + qs: 6.14.2 range-parser: 1.2.1 safe-buffer: 5.2.1 - send: 0.19.0 - serve-static: 1.16.2 + send: 0.19.2 + serve-static: 1.16.3 setprototypeof: 1.2.0 - statuses: 2.0.1 + statuses: 2.0.2 type-is: 1.6.18 utils-merge: 1.0.1 vary: 1.1.2 @@ -15718,11 +16301,11 @@ snapshots: fast-stable-stringify@1.0.0: {} - fast-uri@3.0.6: {} + fast-uri@3.1.0: {} fastest-levenshtein@1.0.16: {} - fastq@1.19.1: + fastq@1.20.1: dependencies: reusify: 1.1.0 @@ -15734,16 +16317,16 @@ snapshots: dependencies: bser: 2.1.1 - fdir@6.4.3(picomatch@4.0.2): + fdir@6.5.0(picomatch@4.0.4): optionalDependencies: - picomatch: 4.0.2 + picomatch: 4.0.4 fetch-mock@9.11.0(node-fetch@2.7.0): dependencies: - '@babel/core': 7.26.10 - '@babel/runtime': 7.27.0 - core-js: 3.41.0 - debug: 4.4.0 + '@babel/core': 7.29.0 + '@babel/runtime': 7.29.2 + core-js: 3.49.0 + debug: 4.4.3 glob-to-regexp: 0.4.1 is-subset: 0.1.1 lodash.isequal: 4.5.0 @@ -15763,23 +16346,15 @@ snapshots: dependencies: flat-cache: 3.2.0 - file-loader@6.2.0(webpack@5.101.3(webpack-cli@6.0.1)): - dependencies: - loader-utils: 2.0.4 - schema-utils: 3.3.0 - webpack: 5.101.3(webpack-cli@6.0.1) - - file-loader@6.2.0(webpack@5.101.3): + file-loader@6.2.0(webpack@5.106.1): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.101.3 + webpack: 5.106.1(webpack-cli@6.0.1) - file-uri-to-path@1.0.0: {} - - filelist@1.0.4: + filelist@1.0.6: dependencies: - minimatch: 5.1.6 + minimatch: 5.1.9 filename-reserved-regex@2.0.0: {} @@ -15795,14 +16370,14 @@ snapshots: dependencies: to-regex-range: 5.0.1 - finalhandler@1.3.1: + finalhandler@1.3.2: dependencies: debug: 2.6.9 encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 parseurl: 1.3.3 - statuses: 2.0.1 + statuses: 2.0.2 unpipe: 1.0.0 transitivePeerDependencies: - supports-color @@ -15851,15 +16426,15 @@ snapshots: flat-cache@3.2.0: dependencies: - flatted: 3.3.3 + flatted: 3.4.2 keyv: 4.5.4 rimraf: 3.0.2 flat@5.0.2: {} - flatted@3.3.3: {} + flatted@3.4.2: {} - follow-redirects@1.15.9: {} + follow-redirects@1.15.11: {} for-each@0.3.5: dependencies: @@ -15870,9 +16445,9 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.1)(typescript@5.8.2)(webpack@5.101.3): + fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.1)(typescript@5.9.3)(webpack@5.106.1): dependencies: - '@babel/code-frame': 7.26.2 + '@babel/code-frame': 7.29.0 '@types/json-schema': 7.0.15 chalk: 4.1.2 chokidar: 3.6.0 @@ -15881,30 +16456,24 @@ snapshots: fs-extra: 9.1.0 glob: 7.2.3 memfs: 3.5.3 - minimatch: 3.1.2 + minimatch: 3.1.5 schema-utils: 2.7.0 - semver: 7.7.1 + semver: 7.7.4 tapable: 1.1.3 - typescript: 5.8.2 - webpack: 5.101.3 + typescript: 5.9.3 + webpack: 5.106.1(webpack-cli@6.0.1) optionalDependencies: eslint: 8.57.1 - form-data@3.0.3: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - es-set-tostringtag: 2.1.0 - mime-types: 2.1.35 - - form-data@4.0.2: + form-data@3.0.4: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 es-set-tostringtag: 2.1.0 + hasown: 2.0.2 mime-types: 2.1.35 - form-data@4.0.4: + form-data@4.0.5: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 @@ -15914,20 +16483,20 @@ snapshots: forwarded@0.2.0: {} - fraction.js@4.3.7: {} + fraction.js@5.3.4: {} fresh@0.5.2: {} fs-extra@10.1.0: dependencies: graceful-fs: 4.2.11 - jsonfile: 6.1.0 + jsonfile: 6.2.0 universalify: 2.0.1 - fs-extra@11.3.0: + fs-extra@11.3.4: dependencies: graceful-fs: 4.2.11 - jsonfile: 6.1.0 + jsonfile: 6.2.0 universalify: 2.0.1 fs-extra@7.0.1: @@ -15946,10 +16515,10 @@ snapshots: dependencies: at-least-node: 1.0.0 graceful-fs: 4.2.11 - jsonfile: 6.1.0 + jsonfile: 6.2.0 universalify: 2.0.1 - fs-monkey@1.0.6: {} + fs-monkey@1.1.0: {} fs.realpath@1.0.0: {} @@ -15960,15 +16529,19 @@ snapshots: function.prototype.name@1.1.8: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 functions-have-names: 1.2.3 hasown: 2.0.2 is-callable: 1.2.7 + functional-red-black-tree@1.0.1: {} + functions-have-names@1.2.3: {} + generator-function@2.0.1: {} + gensync@1.0.0-beta.2: {} get-caller-file@2.0.5: {} @@ -16006,7 +16579,7 @@ snapshots: get-stream@5.2.0: dependencies: - pump: 3.0.3 + pump: 3.0.4 get-stream@6.0.1: {} @@ -16016,7 +16589,7 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 - get-tsconfig@4.10.0: + get-tsconfig@4.13.7: dependencies: resolve-pkg-maps: 1.0.0 @@ -16027,7 +16600,7 @@ snapshots: email-addresses: 5.0.0 filenamify: 4.3.0 find-cache-dir: 3.3.2 - fs-extra: 11.3.0 + fs-extra: 11.3.4 globby: 11.1.0 git-hooks-list@3.2.0: {} @@ -16035,7 +16608,7 @@ snapshots: git-raw-commits@2.0.11: dependencies: dargs: 7.0.0 - lodash: 4.17.21 + lodash: 4.18.1 meow: 8.1.2 split2: 3.2.2 through2: 4.0.2 @@ -16062,36 +16635,36 @@ snapshots: dependencies: is-glob: 4.0.3 - glob-to-regex.js@1.0.1(tslib@2.8.1): + glob-to-regex.js@1.2.0(tslib@2.8.1): dependencies: tslib: 2.8.1 glob-to-regexp@0.4.1: {} - glob@10.4.5: + glob@10.5.0: dependencies: foreground-child: 3.3.1 jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 + minimatch: 9.0.9 + minipass: 7.1.3 package-json-from-dist: 1.0.1 path-scurry: 1.11.1 - glob@11.0.1: + glob@11.1.0: dependencies: foreground-child: 3.3.1 - jackspeak: 4.1.0 - minimatch: 10.0.1 - minipass: 7.1.2 + jackspeak: 4.2.3 + minimatch: 10.2.5 + minipass: 7.1.3 package-json-from-dist: 1.0.1 - path-scurry: 2.0.0 + path-scurry: 2.0.2 glob@7.1.7: dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.1.2 + minimatch: 3.1.5 once: 1.4.0 path-is-absolute: 1.0.1 @@ -16100,7 +16673,7 @@ snapshots: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.1.2 + minimatch: 3.1.5 once: 1.4.0 path-is-absolute: 1.0.1 @@ -16133,12 +16706,12 @@ snapshots: kind-of: 6.0.3 which: 1.3.1 - globals@11.12.0: {} - globals@13.24.0: dependencies: type-fest: 0.20.2 + globals@17.4.0: {} + globalthis@1.0.4: dependencies: define-properties: 1.2.1 @@ -16179,7 +16752,7 @@ snapshots: handle-thing@2.0.1: {} - handlebars@4.7.8: + handlebars@4.7.9: dependencies: minimist: 1.2.8 neo-async: 2.6.2 @@ -16217,6 +16790,13 @@ snapshots: inherits: 2.0.4 safe-buffer: 5.2.1 + hash-base@3.1.2: + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 + hash.js@1.1.7: dependencies: inherits: 2.0.4 @@ -16259,7 +16839,7 @@ snapshots: dependencies: whatwg-encoding: 1.0.5 - html-entities@2.5.3: {} + html-entities@2.6.0: {} html-escaper@2.0.2: {} @@ -16271,27 +16851,17 @@ snapshots: he: 1.2.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.39.0 + terser: 5.46.1 - html-webpack-plugin@5.6.3(webpack@5.101.3(webpack-cli@6.0.1)): + html-webpack-plugin@5.6.6(webpack@5.106.1): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 - lodash: 4.17.21 - pretty-error: 4.0.0 - tapable: 2.2.1 - optionalDependencies: - webpack: 5.101.3(webpack-cli@6.0.1) - - html-webpack-plugin@5.6.3(webpack@5.101.3): - dependencies: - '@types/html-minifier-terser': 6.1.0 - html-minifier-terser: 6.1.0 - lodash: 4.17.21 + lodash: 4.18.1 pretty-error: 4.0.0 - tapable: 2.2.1 + tapable: 2.3.2 optionalDependencies: - webpack: 5.101.3 + webpack: 5.106.1(webpack-cli@6.0.1) htmlparser2@6.1.0: dependencies: @@ -16304,13 +16874,6 @@ snapshots: http-deceiver@1.2.7: {} - http-errors@1.6.3: - dependencies: - depd: 1.1.2 - inherits: 2.0.3 - setprototypeof: 1.1.0 - statuses: 1.5.0 - http-errors@1.8.1: dependencies: depd: 1.1.2 @@ -16319,52 +16882,40 @@ snapshots: statuses: 1.5.0 toidentifier: 1.0.1 - http-errors@2.0.0: + http-errors@2.0.1: dependencies: depd: 2.0.0 inherits: 2.0.4 setprototypeof: 1.2.0 - statuses: 2.0.1 + statuses: 2.0.2 toidentifier: 1.0.1 - http-parser-js@0.5.9: {} + http-parser-js@0.5.10: {} http-proxy-agent@4.0.1: dependencies: '@tootallnate/once': 1.1.2 agent-base: 6.0.2 - debug: 4.4.0 + debug: 4.4.3 transitivePeerDependencies: - supports-color - http-proxy-middleware@2.0.7(@types/express@4.17.21): - dependencies: - '@types/http-proxy': 1.17.16 - http-proxy: 1.18.1 - is-glob: 4.0.3 - is-plain-obj: 3.0.0 - micromatch: 4.0.8 - optionalDependencies: - '@types/express': 4.17.21 - transitivePeerDependencies: - - debug - - http-proxy-middleware@2.0.9(@types/express@4.17.21): + http-proxy-middleware@2.0.9(@types/express@4.17.25): dependencies: - '@types/http-proxy': 1.17.16 + '@types/http-proxy': 1.17.17 http-proxy: 1.18.1 is-glob: 4.0.3 is-plain-obj: 3.0.0 micromatch: 4.0.8 optionalDependencies: - '@types/express': 4.17.21 + '@types/express': 4.17.25 transitivePeerDependencies: - debug http-proxy@1.18.1: dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.9 + follow-redirects: 1.15.11 requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -16377,11 +16928,11 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.4.0 + debug: 4.4.3 transitivePeerDependencies: - supports-color - human-id@4.1.1: {} + human-id@4.1.3: {} human-signals@2.1.0: {} @@ -16399,9 +16950,13 @@ snapshots: dependencies: safer-buffer: 2.1.2 - icss-utils@5.1.0(postcss@8.5.3): + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + + icss-utils@5.1.0(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 idb@7.1.1: {} @@ -16425,7 +16980,7 @@ snapshots: pkg-dir: 4.2.0 resolve-cwd: 3.0.0 - import-meta-resolve@4.1.0: + import-meta-resolve@4.2.0: optional: true imurmurhash@0.1.4: {} @@ -16437,8 +16992,6 @@ snapshots: once: 1.4.0 wrappy: 1.0.2 - inherits@2.0.3: {} - inherits@2.0.4: {} ini@1.3.8: {} @@ -16464,15 +17017,15 @@ snapshots: through: 2.3.8 wrap-ansi: 7.0.0 - inquirer@8.2.6: + inquirer@8.2.7(@types/node@24.3.0): dependencies: + '@inquirer/external-editor': 1.0.3(@types/node@24.3.0) ansi-escapes: 4.3.2 chalk: 4.1.2 cli-cursor: 3.1.0 cli-width: 3.0.0 - external-editor: 3.1.0 figures: 3.2.0 - lodash: 4.17.21 + lodash: 4.18.1 mute-stream: 0.0.8 ora: 5.4.1 run-async: 2.4.1 @@ -16481,6 +17034,8 @@ snapshots: strip-ansi: 6.0.1 through: 2.3.8 wrap-ansi: 6.2.0 + transitivePeerDependencies: + - '@types/node' internal-slot@1.1.0: dependencies: @@ -16492,7 +17047,7 @@ snapshots: ipaddr.js@1.9.1: {} - ipaddr.js@2.2.0: {} + ipaddr.js@2.3.0: {} is-arguments@1.2.0: dependencies: @@ -16501,15 +17056,12 @@ snapshots: is-array-buffer@3.0.5: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 get-intrinsic: 1.3.0 is-arrayish@0.2.1: {} - is-arrayish@0.3.2: - optional: true - is-async-function@2.1.1: dependencies: async-function: 1.0.0 @@ -16533,7 +17085,7 @@ snapshots: is-bun-module@2.0.0: dependencies: - semver: 7.7.1 + semver: 7.7.4 is-callable@1.2.7: {} @@ -16566,9 +17118,10 @@ snapshots: is-generator-fn@2.1.0: {} - is-generator-function@1.1.0: + is-generator-function@1.1.2: dependencies: call-bound: 1.0.4 + generator-function: 2.0.1 get-proto: 1.0.1 has-tostringtag: 1.0.2 safe-regex-test: 1.1.0 @@ -16587,7 +17140,9 @@ snapshots: is-module@1.0.0: {} - is-network-error@1.1.0: {} + is-negative-zero@2.0.3: {} + + is-network-error@1.3.1: {} is-number-object@1.1.1: dependencies: @@ -16658,7 +17213,7 @@ snapshots: is-typed-array@1.1.15: dependencies: - which-typed-array: 1.1.19 + which-typed-array: 1.1.20 is-typedarray@1.0.0: {} @@ -16683,7 +17238,7 @@ snapshots: dependencies: is-docker: 2.2.1 - is-wsl@3.1.0: + is-wsl@3.1.1: dependencies: is-inside-container: 1.0.0 @@ -16695,16 +17250,16 @@ snapshots: isobject@3.0.1: {} - isomorphic-ws@4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + isomorphic-ws@4.0.1(ws@7.5.10(bufferutil@4.1.0)(utf-8-validate@6.0.6)): dependencies: - ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 7.5.10(bufferutil@4.1.0)(utf-8-validate@6.0.6) istanbul-lib-coverage@3.2.2: {} istanbul-lib-instrument@5.2.1: dependencies: - '@babel/core': 7.26.10 - '@babel/parser': 7.27.0 + '@babel/core': 7.29.0 + '@babel/parser': 7.29.2 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -16719,7 +17274,7 @@ snapshots: istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.4.0 + debug: 4.4.3 istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -16727,13 +17282,13 @@ snapshots: istanbul-lib-source-maps@5.0.6: dependencies: - '@jridgewell/trace-mapping': 0.3.25 - debug: 4.4.1 + '@jridgewell/trace-mapping': 0.3.31 + debug: 4.4.3 istanbul-lib-coverage: 3.2.2 transitivePeerDependencies: - supports-color - istanbul-reports@3.1.7: + istanbul-reports@3.2.0: dependencies: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 @@ -16753,31 +17308,30 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 - jackspeak@4.1.0: + jackspeak@4.2.3: dependencies: - '@isaacs/cliui': 8.0.2 + '@isaacs/cliui': 9.0.0 - jake@10.9.2: + jake@10.9.4: dependencies: async: 3.2.6 - chalk: 4.1.2 - filelist: 1.0.4 - minimatch: 3.1.2 + filelist: 1.0.6 + picocolors: 1.1.1 - jayson@4.1.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): + jayson@4.3.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@types/connect': 3.4.38 '@types/node': 12.20.55 '@types/ws': 7.4.7 - JSONStream: 1.3.5 commander: 2.20.3 delay: 5.0.0 es6-promisify: 5.0.0 eyes: 0.1.8 - isomorphic-ws: 4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + isomorphic-ws: 4.0.1(ws@7.5.10(bufferutil@4.1.0)(utf-8-validate@6.0.6)) json-stringify-safe: 5.0.1 + stream-json: 1.9.1 uuid: 8.3.2 - ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 7.5.10(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -16812,16 +17366,16 @@ snapshots: transitivePeerDependencies: - supports-color - jest-cli@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10): + jest-cli@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)): dependencies: - '@jest/core': 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10) + '@jest/core': 27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)) '@jest/test-result': 27.5.1 '@jest/types': 27.5.1 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 import-local: 3.2.0 - jest-config: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10) + jest-config: 27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)) jest-util: 27.5.1 jest-validate: 27.5.1 prompts: 2.4.2 @@ -16833,25 +17387,25 @@ snapshots: - ts-node - utf-8-validate - jest-config@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10): + jest-config@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)): dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.29.0 '@jest/test-sequencer': 27.5.1 '@jest/types': 27.5.1 - babel-jest: 27.5.1(@babel/core@7.26.10) + babel-jest: 27.5.1(@babel/core@7.29.0) chalk: 4.1.2 ci-info: 3.9.0 deepmerge: 4.3.1 glob: 7.2.3 graceful-fs: 4.2.11 jest-circus: 27.5.1 - jest-environment-jsdom: 27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + jest-environment-jsdom: 27.5.1(bufferutil@4.1.0) jest-environment-node: 27.5.1 jest-get-type: 27.5.1 jest-jasmine2: 27.5.1 jest-regex-util: 27.5.1 jest-resolve: 27.5.1 - jest-runner: 27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + jest-runner: 27.5.1(bufferutil@4.1.0) jest-util: 27.5.1 jest-validate: 27.5.1 micromatch: 4.0.8 @@ -16860,7 +17414,7 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - ts-node: 10.9.2(@types/node@24.3.0)(typescript@5.8.2) + ts-node: 10.9.2(@types/node@24.3.0)(typescript@5.9.3) transitivePeerDependencies: - bufferutil - canvas @@ -16886,7 +17440,7 @@ snapshots: jest-util: 27.5.1 pretty-format: 27.5.1 - jest-environment-jsdom@27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): + jest-environment-jsdom@27.5.1(bufferutil@4.1.0): dependencies: '@jest/environment': 27.5.1 '@jest/fake-timers': 27.5.1 @@ -16894,7 +17448,7 @@ snapshots: '@types/node': 24.3.0 jest-mock: 27.5.1 jest-util: 27.5.1 - jsdom: 16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + jsdom: 16.7.0(bufferutil@4.1.0) transitivePeerDependencies: - bufferutil - canvas @@ -16965,7 +17519,7 @@ snapshots: jest-message-util@27.5.1: dependencies: - '@babel/code-frame': 7.26.2 + '@babel/code-frame': 7.29.0 '@jest/types': 27.5.1 '@types/stack-utils': 2.0.3 chalk: 4.1.2 @@ -16977,7 +17531,7 @@ snapshots: jest-message-util@28.1.3: dependencies: - '@babel/code-frame': 7.26.2 + '@babel/code-frame': 7.29.0 '@jest/types': 28.1.3 '@types/stack-utils': 2.0.3 chalk: 4.1.2 @@ -17017,11 +17571,11 @@ snapshots: jest-pnp-resolver: 1.2.3(jest-resolve@27.5.1) jest-util: 27.5.1 jest-validate: 27.5.1 - resolve: 1.22.10 + resolve: 1.22.11 resolve.exports: 1.1.1 slash: 3.0.0 - jest-runner@27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): + jest-runner@27.5.1(bufferutil@4.1.0): dependencies: '@jest/console': 27.5.1 '@jest/environment': 27.5.1 @@ -17033,7 +17587,7 @@ snapshots: emittery: 0.8.1 graceful-fs: 4.2.11 jest-docblock: 27.5.1 - jest-environment-jsdom: 27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + jest-environment-jsdom: 27.5.1(bufferutil@4.1.0) jest-environment-node: 27.5.1 jest-haste-map: 27.5.1 jest-leak-detector: 27.5.1 @@ -17061,7 +17615,7 @@ snapshots: '@jest/types': 27.5.1 chalk: 4.1.2 cjs-module-lexer: 1.4.3 - collect-v8-coverage: 1.0.2 + collect-v8-coverage: 1.0.3 execa: 5.1.1 glob: 7.2.3 graceful-fs: 4.2.11 @@ -17084,16 +17638,16 @@ snapshots: jest-snapshot@27.5.1: dependencies: - '@babel/core': 7.26.10 - '@babel/generator': 7.27.0 - '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.10) - '@babel/traverse': 7.27.0 - '@babel/types': 7.27.0 + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 - '@types/babel__traverse': 7.20.7 + '@types/babel__traverse': 7.28.0 '@types/prettier': 2.7.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.26.10) + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) chalk: 4.1.2 expect: 27.5.1 graceful-fs: 4.2.11 @@ -17105,7 +17659,7 @@ snapshots: jest-util: 27.5.1 natural-compare: 1.4.0 pretty-format: 27.5.1 - semver: 7.7.1 + semver: 7.7.4 transitivePeerDependencies: - supports-color @@ -17116,7 +17670,7 @@ snapshots: chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 - picomatch: 2.3.1 + picomatch: 2.3.2 jest-util@28.1.3: dependencies: @@ -17125,7 +17679,7 @@ snapshots: chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 - picomatch: 2.3.1 + picomatch: 2.3.2 jest-validate@27.5.1: dependencies: @@ -17136,16 +17690,16 @@ snapshots: leven: 3.1.0 pretty-format: 27.5.1 - jest-watch-typeahead@1.1.0(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10)): + jest-watch-typeahead@1.1.0(jest@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3))): dependencies: ansi-escapes: 4.3.2 chalk: 4.1.2 - jest: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10) + jest: 27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)) jest-regex-util: 28.0.2 jest-watcher: 28.1.3 slash: 4.0.0 string-length: 5.0.1 - strip-ansi: 7.1.0 + strip-ansi: 7.2.0 jest-watcher@27.5.1: dependencies: @@ -17186,11 +17740,11 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10): + jest@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)): dependencies: - '@jest/core': 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10) + '@jest/core': 27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)) import-local: 3.2.0 - jest-cli: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10) + jest-cli: 27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)) transitivePeerDependencies: - bufferutil - canvas @@ -17200,12 +17754,12 @@ snapshots: jiti@1.21.7: {} - jiti@2.4.2: + jiti@2.6.1: optional: true joycon@3.1.1: {} - js-base64@3.7.7: {} + js-base64@3.7.8: {} js-sha256@0.9.0: {} @@ -17213,36 +17767,38 @@ snapshots: js-sha512@0.8.0: {} + js-tokens@10.0.0: {} + js-tokens@4.0.0: {} js-tokens@9.0.1: {} - js-yaml@3.14.1: + js-yaml@3.14.2: dependencies: argparse: 1.0.10 esprima: 4.0.1 - js-yaml@4.1.0: + js-yaml@4.1.1: dependencies: argparse: 2.0.1 - jsdom@16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): + jsdom@16.7.0(bufferutil@4.1.0): dependencies: abab: 2.0.6 - acorn: 8.14.1 + acorn: 8.16.0 acorn-globals: 6.0.0 cssom: 0.4.4 cssstyle: 2.3.0 data-urls: 2.0.0 - decimal.js: 10.5.0 + decimal.js: 10.6.0 domexception: 2.0.1 escodegen: 2.1.0 - form-data: 3.0.3 + form-data: 3.0.4 html-encoding-sniffer: 2.0.1 http-proxy-agent: 4.0.1 https-proxy-agent: 5.0.1 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.20 + nwsapi: 2.2.23 parse5: 6.0.1 saxes: 5.0.1 symbol-tree: 3.2.4 @@ -17253,20 +17809,18 @@ snapshots: whatwg-encoding: 1.0.5 whatwg-mimetype: 2.3.0 whatwg-url: 8.7.0 - ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 7.5.10(bufferutil@4.1.0)(utf-8-validate@6.0.6) xml-name-validator: 3.0.0 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - jsesc@3.0.2: {} - jsesc@3.1.0: {} json-bigint@1.0.0: dependencies: - bignumber.js: 9.1.2 + bignumber.js: 9.3.1 json-buffer@3.0.1: {} @@ -17278,8 +17832,6 @@ snapshots: json-schema-traverse@1.0.0: {} - json-schema@0.4.0: {} - json-stable-stringify-without-jsonify@1.0.1: {} json-stringify-safe@5.0.1: {} @@ -17296,7 +17848,7 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 - jsonfile@6.1.0: + jsonfile@6.2.0: dependencies: universalify: 2.0.1 optionalDependencies: @@ -17304,17 +17856,19 @@ snapshots: jsonparse@1.3.1: {} - jsonpath@1.1.1: + jsonpath@1.3.0: dependencies: - esprima: 1.2.2 - static-eval: 2.0.2 - underscore: 1.12.1 + esprima: 1.2.5 + static-eval: 2.1.1 + underscore: 1.13.6 jsonpointer@5.0.1: {} + jsx-ast-utils-x@0.1.0: {} + jsx-ast-utils@3.3.5: dependencies: - array-includes: 3.1.8 + array-includes: 3.1.9 array.prototype.flat: 1.3.3 object.assign: 4.1.7 object.values: 1.2.1 @@ -17345,10 +17899,10 @@ snapshots: dependencies: language-subtag-registry: 0.3.23 - launch-editor@2.10.0: + launch-editor@2.13.2: dependencies: picocolors: 1.1.1 - shell-quote: 1.8.2 + shell-quote: 1.8.3 leven@3.1.0: {} @@ -17377,7 +17931,7 @@ snapshots: load-tsconfig@0.2.5: {} - loader-runner@4.3.0: {} + loader-runner@4.3.1: {} loader-utils@2.0.4: dependencies: @@ -17405,7 +17959,7 @@ snapshots: dependencies: p-locate: 5.0.0 - lodash-es@4.17.21: {} + lodash-es@4.18.1: {} lodash.camelcase@4.3.0: {} @@ -17415,9 +17969,6 @@ snapshots: lodash.ismatch@4.4.0: {} - lodash.isplainobject@4.0.6: - optional: true - lodash.map@4.6.0: {} lodash.memoize@4.1.2: {} @@ -17437,6 +17988,8 @@ snapshots: lodash@4.17.21: {} + lodash@4.18.1: {} + log-symbols@4.1.0: dependencies: chalk: 4.1.2 @@ -17448,7 +18001,7 @@ snapshots: dependencies: js-tokens: 4.0.0 - loupe@3.1.3: {} + loupe@3.2.1: {} lower-case@2.0.2: dependencies: @@ -17458,7 +18011,7 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.1.0: {} + lru-cache@11.3.3: {} lru-cache@5.1.1: dependencies: @@ -17474,14 +18027,14 @@ snapshots: dependencies: sourcemap-codec: 1.4.8 - magic-string@0.30.17: + magic-string@0.30.21: dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 magicast@0.3.5: dependencies: - '@babel/parser': 7.27.0 - '@babel/types': 7.27.0 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 source-map-js: 1.2.1 make-dir@3.1.0: @@ -17490,7 +18043,7 @@ snapshots: make-dir@4.0.0: dependencies: - semver: 7.7.1 + semver: 7.7.4 make-error@1.3.6: {} @@ -17520,19 +18073,30 @@ snapshots: memfs@3.5.3: dependencies: - fs-monkey: 1.0.6 + fs-monkey: 1.1.0 - memfs@4.38.2: + memfs@4.57.1(tslib@2.8.1): dependencies: - '@jsonjoy.com/json-pack': 1.11.0(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-to-fsa': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) - glob-to-regex.js: 1.0.1(tslib@2.8.1) - thingies: 2.5.0(tslib@2.8.1) - tree-dump: 1.0.3(tslib@2.8.1) + glob-to-regex.js: 1.2.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 memorystream@0.3.1: {} + meow@13.2.0: + optional: true + meow@8.1.2: dependencies: '@types/minimist': 1.2.5 @@ -17560,11 +18124,11 @@ snapshots: micromatch@4.0.8: dependencies: braces: 3.0.3 - picomatch: 2.3.1 + picomatch: 2.3.2 miller-rabin@4.0.1: dependencies: - bn.js: 4.12.1 + bn.js: 4.12.3 brorand: 1.1.0 mime-db@1.52.0: {} @@ -17575,6 +18139,10 @@ snapshots: dependencies: mime-db: 1.52.0 + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + mime@1.6.0: {} mimic-fn@2.1.0: {} @@ -17585,35 +18153,35 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.9.2(webpack@5.101.3): + mini-css-extract-plugin@2.10.2(webpack@5.106.1): dependencies: - schema-utils: 4.3.0 - tapable: 2.2.1 - webpack: 5.101.3 + schema-utils: 4.3.3 + tapable: 2.3.2 + webpack: 5.106.1(webpack-cli@6.0.1) minimalistic-assert@1.0.1: {} minimalistic-crypto-utils@1.0.1: {} - minimatch@10.0.1: + minimatch@10.2.5: dependencies: - brace-expansion: 2.0.1 + brace-expansion: 5.0.5 - minimatch@3.1.2: + minimatch@3.1.5: dependencies: - brace-expansion: 1.1.11 + brace-expansion: 1.1.13 - minimatch@5.1.6: + minimatch@5.1.9: dependencies: - brace-expansion: 2.0.1 + brace-expansion: 2.0.3 minimatch@9.0.3: dependencies: - brace-expansion: 2.0.1 + brace-expansion: 2.0.3 - minimatch@9.0.5: + minimatch@9.0.9: dependencies: - brace-expansion: 2.0.1 + brace-expansion: 2.0.3 minimist-options@4.1.0: dependencies: @@ -17625,7 +18193,7 @@ snapshots: minimist@1.2.8: {} - minipass@7.1.2: {} + minipass@7.1.3: {} mixme@0.5.10: {} @@ -17635,14 +18203,14 @@ snapshots: mkdirp@1.0.4: {} - modified-zod2md@0.1.5-modified.4(zod@3.24.2): + modified-zod2md@0.1.5-modified.4(zod@3.25.76): dependencies: '@commander-js/extra-typings': 12.1.0(commander@12.1.0) bundle-require: 4.2.1(esbuild@0.19.12) commander: 12.1.0 esbuild: 0.19.12 modified-zod2md: 'link:' - zod: 3.24.2 + zod: 3.25.76 modify-values@1.0.1: {} @@ -17679,6 +18247,8 @@ snapshots: nanoid@3.3.4: {} + napi-postinstall@0.3.4: {} + natural-compare-lite@1.4.0: {} natural-compare@1.4.0: {} @@ -17708,7 +18278,7 @@ snapshots: '@swc/counter': 0.1.3 '@swc/helpers': 0.5.15 busboy: 1.6.0 - caniuse-lite: 1.0.30001707 + caniuse-lite: 1.0.30001787 postcss: 8.4.31 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -17722,7 +18292,7 @@ snapshots: '@next/swc-linux-x64-musl': 15.3.4 '@next/swc-win32-arm64-msvc': 15.3.4 '@next/swc-win32-x64-msvc': 15.3.4 - sharp: 0.34.3 + sharp: 0.34.5 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -17738,22 +18308,29 @@ snapshots: node-addon-api@5.1.0: {} + node-exports-info@1.6.0: + dependencies: + array.prototype.flatmap: 1.3.3 + es-errors: 1.3.0 + object.entries: 1.1.9 + semver: 6.3.1 + node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 - node-forge@1.3.1: {} + node-forge@1.4.0: {} node-gyp-build@4.8.4: {} node-int64@0.4.0: {} - node-releases@2.0.19: {} + node-releases@2.0.37: {} normalize-package-data@2.5.0: dependencies: hosted-git-info: 2.8.9 - resolve: 1.22.10 + resolve: 1.22.11 semver: 5.7.2 validate-npm-package-license: 3.0.4 @@ -17761,13 +18338,11 @@ snapshots: dependencies: hosted-git-info: 4.1.0 is-core-module: 2.16.1 - semver: 7.7.1 + semver: 7.7.4 validate-npm-package-license: 3.0.4 normalize-path@3.0.0: {} - normalize-range@0.1.2: {} - normalize-url@6.1.0: {} npm-run-all@4.1.5: @@ -17776,10 +18351,10 @@ snapshots: chalk: 2.4.2 cross-spawn: 6.0.6 memorystream: 0.3.1 - minimatch: 3.1.2 + minimatch: 3.1.5 pidtree: 0.3.1 read-pkg: 3.0.0 - shell-quote: 1.8.2 + shell-quote: 1.8.3 string.prototype.padend: 3.1.6 npm-run-path@4.0.1: @@ -17790,7 +18365,11 @@ snapshots: dependencies: boolbase: 1.0.0 - nwsapi@2.2.20: {} + nth-check@3.0.1: + dependencies: + boolbase: 2.0.0 + + nwsapi@2.2.23: {} object-assign@4.1.1: {} @@ -17800,14 +18379,14 @@ snapshots: object-is@1.1.6: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 object-keys@1.1.1: {} object.assign@4.1.7: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 es-object-atoms: 1.1.1 @@ -17816,37 +18395,37 @@ snapshots: object.entries@1.1.9: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 es-object-atoms: 1.1.1 object.fromentries@2.0.8: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 es-object-atoms: 1.1.1 - object.getownpropertydescriptors@2.1.8: + object.getownpropertydescriptors@2.1.9: dependencies: array.prototype.reduce: 1.0.8 - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 es-object-atoms: 1.1.1 gopd: 1.2.0 safe-array-concat: 1.1.3 object.groupby@1.0.3: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 object.values@1.2.1: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 es-object-atoms: 1.1.1 @@ -17857,7 +18436,7 @@ snapshots: dependencies: ee-first: 1.1.1 - on-headers@1.0.2: {} + on-headers@1.1.0: {} once@1.4.0: dependencies: @@ -17869,7 +18448,7 @@ snapshots: open@10.2.0: dependencies: - default-browser: 5.2.1 + default-browser: 5.5.0 define-lazy-prop: 3.0.0 is-inside-container: 1.0.0 wsl-utils: 0.1.0 @@ -17964,7 +18543,7 @@ snapshots: p-retry@6.2.1: dependencies: '@types/retry': 0.12.2 - is-network-error: 1.1.0 + is-network-error: 1.3.1 retry: 0.13.1 p-try@1.0.0: {} @@ -17975,7 +18554,7 @@ snapshots: package-manager-detector@0.2.11: dependencies: - quansync: 0.2.10 + quansync: 0.2.11 param-case@3.0.4: dependencies: @@ -17986,24 +18565,23 @@ snapshots: dependencies: callsites: 3.1.0 - parse-asn1@5.1.7: + parse-asn1@5.1.9: dependencies: asn1.js: 4.10.1 browserify-aes: 1.2.0 evp_bytestokey: 1.0.3 - hash-base: 3.0.5 - pbkdf2: 3.1.2 + pbkdf2: 3.1.5 safe-buffer: 5.2.1 parse-json@4.0.0: dependencies: - error-ex: 1.3.2 + error-ex: 1.3.4 json-parse-better-errors: 1.0.2 parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.26.2 - error-ex: 1.3.2 + '@babel/code-frame': 7.29.0 + error-ex: 1.3.4 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -18033,14 +18611,14 @@ snapshots: path-scurry@1.11.1: dependencies: lru-cache: 10.4.3 - minipass: 7.1.2 + minipass: 7.1.3 - path-scurry@2.0.0: + path-scurry@2.0.2: dependencies: - lru-cache: 11.1.0 - minipass: 7.1.2 + lru-cache: 11.3.3 + minipass: 7.1.3 - path-to-regexp@0.1.12: {} + path-to-regexp@0.1.13: {} path-to-regexp@2.4.0: {} @@ -18052,15 +18630,16 @@ snapshots: pathe@2.0.3: {} - pathval@2.0.0: {} + pathval@2.0.1: {} - pbkdf2@3.1.2: + pbkdf2@3.1.5: dependencies: create-hash: 1.2.0 create-hmac: 1.1.7 - ripemd160: 2.0.2 + ripemd160: 2.0.3 safe-buffer: 5.2.1 - sha.js: 2.4.11 + sha.js: 2.4.12 + to-buffer: 1.2.2 performance-now@2.1.0: {} @@ -18068,9 +18647,9 @@ snapshots: picocolors@1.1.1: {} - picomatch@2.3.1: {} + picomatch@2.3.2: {} - picomatch@4.0.2: {} + picomatch@4.0.4: {} pidtree@0.3.1: {} @@ -18090,404 +18669,412 @@ snapshots: dependencies: find-up: 3.0.0 + pkijs@3.4.0: + dependencies: + '@noble/hashes': 1.4.0 + asn1js: 3.0.7 + bytestreamjs: 2.0.1 + pvtsutils: 1.3.6 + pvutils: 1.1.5 + tslib: 2.8.1 + poseidon-lite@0.2.1: {} possible-typed-array-names@1.1.0: {} - postcss-attribute-case-insensitive@5.0.2(postcss@8.5.3): + postcss-attribute-case-insensitive@5.0.2(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-selector-parser: 6.1.2 - postcss-browser-comments@4.0.0(browserslist@4.24.4)(postcss@8.5.3): + postcss-browser-comments@4.0.0(browserslist@4.28.2)(postcss@8.5.9): dependencies: - browserslist: 4.24.4 - postcss: 8.5.3 + browserslist: 4.28.2 + postcss: 8.5.9 - postcss-calc@8.2.4(postcss@8.5.3): + postcss-calc@8.2.4(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-selector-parser: 6.1.2 postcss-value-parser: 4.2.0 - postcss-clamp@4.1.0(postcss@8.5.3): + postcss-clamp@4.1.0(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-color-functional-notation@4.2.4(postcss@8.5.3): + postcss-color-functional-notation@4.2.4(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-color-hex-alpha@8.0.4(postcss@8.5.3): + postcss-color-hex-alpha@8.0.4(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-color-rebeccapurple@7.1.1(postcss@8.5.3): + postcss-color-rebeccapurple@7.1.1(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-colormin@5.3.1(postcss@8.5.3): + postcss-colormin@5.3.1(postcss@8.5.9): dependencies: - browserslist: 4.24.4 + browserslist: 4.28.2 caniuse-api: 3.0.0 colord: 2.9.3 - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-convert-values@5.1.3(postcss@8.5.3): + postcss-convert-values@5.1.3(postcss@8.5.9): dependencies: - browserslist: 4.24.4 - postcss: 8.5.3 + browserslist: 4.28.2 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-custom-media@8.0.2(postcss@8.5.3): + postcss-custom-media@8.0.2(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-custom-properties@12.1.11(postcss@8.5.3): + postcss-custom-properties@12.1.11(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-custom-selectors@6.0.3(postcss@8.5.3): + postcss-custom-selectors@6.0.3(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-selector-parser: 6.1.2 - postcss-dir-pseudo-class@6.0.5(postcss@8.5.3): + postcss-dir-pseudo-class@6.0.5(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-selector-parser: 6.1.2 - postcss-discard-comments@5.1.2(postcss@8.5.3): + postcss-discard-comments@5.1.2(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 - postcss-discard-duplicates@5.1.0(postcss@8.5.3): + postcss-discard-duplicates@5.1.0(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 - postcss-discard-empty@5.1.1(postcss@8.5.3): + postcss-discard-empty@5.1.1(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 - postcss-discard-overridden@5.1.0(postcss@8.5.3): + postcss-discard-overridden@5.1.0(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 - postcss-double-position-gradients@3.1.2(postcss@8.5.3): + postcss-double-position-gradients@3.1.2(postcss@8.5.9): dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.3) - postcss: 8.5.3 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.9) + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-env-function@4.0.6(postcss@8.5.3): + postcss-env-function@4.0.6(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-flexbugs-fixes@5.0.2(postcss@8.5.3): + postcss-flexbugs-fixes@5.0.2(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 - postcss-focus-visible@6.0.4(postcss@8.5.3): + postcss-focus-visible@6.0.4(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-selector-parser: 6.1.2 - postcss-focus-within@5.0.4(postcss@8.5.3): + postcss-focus-within@5.0.4(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-selector-parser: 6.1.2 - postcss-font-variant@5.0.0(postcss@8.5.3): + postcss-font-variant@5.0.0(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 - postcss-gap-properties@3.0.5(postcss@8.5.3): + postcss-gap-properties@3.0.5(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 - postcss-image-set-function@4.0.7(postcss@8.5.3): + postcss-image-set-function@4.0.7(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-import@15.1.0(postcss@8.5.3): + postcss-import@15.1.0(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 read-cache: 1.0.0 - resolve: 1.22.10 + resolve: 1.22.11 - postcss-initial@4.0.1(postcss@8.5.3): + postcss-initial@4.0.1(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 - postcss-js@4.0.1(postcss@8.5.3): + postcss-js@4.1.0(postcss@8.5.9): dependencies: camelcase-css: 2.0.1 - postcss: 8.5.3 + postcss: 8.5.9 - postcss-lab-function@4.2.1(postcss@8.5.3): + postcss-lab-function@4.2.1(postcss@8.5.9): dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.3) - postcss: 8.5.3 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.9) + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-load-config@4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2)): + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.9): dependencies: lilconfig: 3.1.3 - yaml: 2.7.0 optionalDependencies: - postcss: 8.5.3 - ts-node: 10.9.2(@types/node@24.3.0)(typescript@5.8.2) + jiti: 1.21.7 + postcss: 8.5.9 - postcss-loader@6.2.1(postcss@8.5.3)(webpack@5.101.3): + postcss-loader@6.2.1(postcss@8.5.9)(webpack@5.106.1): dependencies: cosmiconfig: 7.1.0 klona: 2.0.6 - postcss: 8.5.3 - semver: 7.7.1 - webpack: 5.101.3 + postcss: 8.5.9 + semver: 7.7.4 + webpack: 5.106.1(webpack-cli@6.0.1) - postcss-logical@5.0.4(postcss@8.5.3): + postcss-logical@5.0.4(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 - postcss-media-minmax@5.0.0(postcss@8.5.3): + postcss-media-minmax@5.0.0(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 - postcss-merge-longhand@5.1.7(postcss@8.5.3): + postcss-merge-longhand@5.1.7(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - stylehacks: 5.1.1(postcss@8.5.3) + stylehacks: 5.1.1(postcss@8.5.9) - postcss-merge-rules@5.1.4(postcss@8.5.3): + postcss-merge-rules@5.1.4(postcss@8.5.9): dependencies: - browserslist: 4.24.4 + browserslist: 4.28.2 caniuse-api: 3.0.0 - cssnano-utils: 3.1.0(postcss@8.5.3) - postcss: 8.5.3 + cssnano-utils: 3.1.0(postcss@8.5.9) + postcss: 8.5.9 postcss-selector-parser: 6.1.2 - postcss-minify-font-values@5.1.0(postcss@8.5.3): + postcss-minify-font-values@5.1.0(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-minify-gradients@5.1.1(postcss@8.5.3): + postcss-minify-gradients@5.1.1(postcss@8.5.9): dependencies: colord: 2.9.3 - cssnano-utils: 3.1.0(postcss@8.5.3) - postcss: 8.5.3 + cssnano-utils: 3.1.0(postcss@8.5.9) + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-minify-params@5.1.4(postcss@8.5.3): + postcss-minify-params@5.1.4(postcss@8.5.9): dependencies: - browserslist: 4.24.4 - cssnano-utils: 3.1.0(postcss@8.5.3) - postcss: 8.5.3 + browserslist: 4.28.2 + cssnano-utils: 3.1.0(postcss@8.5.9) + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-minify-selectors@5.2.1(postcss@8.5.3): + postcss-minify-selectors@5.2.1(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-selector-parser: 6.1.2 - postcss-modules-extract-imports@3.1.0(postcss@8.5.3): + postcss-modules-extract-imports@3.1.0(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 - postcss-modules-local-by-default@4.2.0(postcss@8.5.3): + postcss-modules-local-by-default@4.2.0(postcss@8.5.9): dependencies: - icss-utils: 5.1.0(postcss@8.5.3) - postcss: 8.5.3 - postcss-selector-parser: 7.1.0 + icss-utils: 5.1.0(postcss@8.5.9) + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 - postcss-modules-scope@3.2.1(postcss@8.5.3): + postcss-modules-scope@3.2.1(postcss@8.5.9): dependencies: - postcss: 8.5.3 - postcss-selector-parser: 7.1.0 + postcss: 8.5.9 + postcss-selector-parser: 7.1.1 - postcss-modules-values@4.0.0(postcss@8.5.3): + postcss-modules-values@4.0.0(postcss@8.5.9): dependencies: - icss-utils: 5.1.0(postcss@8.5.3) - postcss: 8.5.3 + icss-utils: 5.1.0(postcss@8.5.9) + postcss: 8.5.9 - postcss-nested@6.2.0(postcss@8.5.3): + postcss-nested@6.2.0(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-selector-parser: 6.1.2 - postcss-nesting@10.2.0(postcss@8.5.3): + postcss-nesting@10.2.0(postcss@8.5.9): dependencies: '@csstools/selector-specificity': 2.2.0(postcss-selector-parser@6.1.2) - postcss: 8.5.3 + postcss: 8.5.9 postcss-selector-parser: 6.1.2 - postcss-normalize-charset@5.1.0(postcss@8.5.3): + postcss-normalize-charset@5.1.0(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 - postcss-normalize-display-values@5.1.0(postcss@8.5.3): + postcss-normalize-display-values@5.1.0(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-normalize-positions@5.1.1(postcss@8.5.3): + postcss-normalize-positions@5.1.1(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-normalize-repeat-style@5.1.1(postcss@8.5.3): + postcss-normalize-repeat-style@5.1.1(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-normalize-string@5.1.0(postcss@8.5.3): + postcss-normalize-string@5.1.0(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-normalize-timing-functions@5.1.0(postcss@8.5.3): + postcss-normalize-timing-functions@5.1.0(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-normalize-unicode@5.1.1(postcss@8.5.3): + postcss-normalize-unicode@5.1.1(postcss@8.5.9): dependencies: - browserslist: 4.24.4 - postcss: 8.5.3 + browserslist: 4.28.2 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-normalize-url@5.1.0(postcss@8.5.3): + postcss-normalize-url@5.1.0(postcss@8.5.9): dependencies: normalize-url: 6.1.0 - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-normalize-whitespace@5.1.1(postcss@8.5.3): + postcss-normalize-whitespace@5.1.1(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-normalize@10.0.1(browserslist@4.24.4)(postcss@8.5.3): + postcss-normalize@10.0.1(browserslist@4.28.2)(postcss@8.5.9): dependencies: '@csstools/normalize.css': 12.1.1 - browserslist: 4.24.4 - postcss: 8.5.3 - postcss-browser-comments: 4.0.0(browserslist@4.24.4)(postcss@8.5.3) + browserslist: 4.28.2 + postcss: 8.5.9 + postcss-browser-comments: 4.0.0(browserslist@4.28.2)(postcss@8.5.9) sanitize.css: 13.0.0 - postcss-opacity-percentage@1.1.3(postcss@8.5.3): + postcss-opacity-percentage@1.1.3(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 - postcss-ordered-values@5.1.3(postcss@8.5.3): + postcss-ordered-values@5.1.3(postcss@8.5.9): dependencies: - cssnano-utils: 3.1.0(postcss@8.5.3) - postcss: 8.5.3 + cssnano-utils: 3.1.0(postcss@8.5.9) + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-overflow-shorthand@3.0.4(postcss@8.5.3): + postcss-overflow-shorthand@3.0.4(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-page-break@3.0.4(postcss@8.5.3): + postcss-page-break@3.0.4(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 - postcss-place@7.0.5(postcss@8.5.3): + postcss-place@7.0.5(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-preset-env@7.8.3(postcss@8.5.3): - dependencies: - '@csstools/postcss-cascade-layers': 1.1.1(postcss@8.5.3) - '@csstools/postcss-color-function': 1.1.1(postcss@8.5.3) - '@csstools/postcss-font-format-keywords': 1.0.1(postcss@8.5.3) - '@csstools/postcss-hwb-function': 1.0.2(postcss@8.5.3) - '@csstools/postcss-ic-unit': 1.0.1(postcss@8.5.3) - '@csstools/postcss-is-pseudo-class': 2.0.7(postcss@8.5.3) - '@csstools/postcss-nested-calc': 1.0.0(postcss@8.5.3) - '@csstools/postcss-normalize-display-values': 1.0.1(postcss@8.5.3) - '@csstools/postcss-oklab-function': 1.1.1(postcss@8.5.3) - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.3) - '@csstools/postcss-stepped-value-functions': 1.0.1(postcss@8.5.3) - '@csstools/postcss-text-decoration-shorthand': 1.0.0(postcss@8.5.3) - '@csstools/postcss-trigonometric-functions': 1.0.2(postcss@8.5.3) - '@csstools/postcss-unset-value': 1.0.2(postcss@8.5.3) - autoprefixer: 10.4.21(postcss@8.5.3) - browserslist: 4.24.4 - css-blank-pseudo: 3.0.3(postcss@8.5.3) - css-has-pseudo: 3.0.4(postcss@8.5.3) - css-prefers-color-scheme: 6.0.3(postcss@8.5.3) + postcss-preset-env@7.8.3(postcss@8.5.9): + dependencies: + '@csstools/postcss-cascade-layers': 1.1.1(postcss@8.5.9) + '@csstools/postcss-color-function': 1.1.1(postcss@8.5.9) + '@csstools/postcss-font-format-keywords': 1.0.1(postcss@8.5.9) + '@csstools/postcss-hwb-function': 1.0.2(postcss@8.5.9) + '@csstools/postcss-ic-unit': 1.0.1(postcss@8.5.9) + '@csstools/postcss-is-pseudo-class': 2.0.7(postcss@8.5.9) + '@csstools/postcss-nested-calc': 1.0.0(postcss@8.5.9) + '@csstools/postcss-normalize-display-values': 1.0.1(postcss@8.5.9) + '@csstools/postcss-oklab-function': 1.1.1(postcss@8.5.9) + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.9) + '@csstools/postcss-stepped-value-functions': 1.0.1(postcss@8.5.9) + '@csstools/postcss-text-decoration-shorthand': 1.0.0(postcss@8.5.9) + '@csstools/postcss-trigonometric-functions': 1.0.2(postcss@8.5.9) + '@csstools/postcss-unset-value': 1.0.2(postcss@8.5.9) + autoprefixer: 10.4.27(postcss@8.5.9) + browserslist: 4.28.2 + css-blank-pseudo: 3.0.3(postcss@8.5.9) + css-has-pseudo: 3.0.4(postcss@8.5.9) + css-prefers-color-scheme: 6.0.3(postcss@8.5.9) cssdb: 7.11.2 - postcss: 8.5.3 - postcss-attribute-case-insensitive: 5.0.2(postcss@8.5.3) - postcss-clamp: 4.1.0(postcss@8.5.3) - postcss-color-functional-notation: 4.2.4(postcss@8.5.3) - postcss-color-hex-alpha: 8.0.4(postcss@8.5.3) - postcss-color-rebeccapurple: 7.1.1(postcss@8.5.3) - postcss-custom-media: 8.0.2(postcss@8.5.3) - postcss-custom-properties: 12.1.11(postcss@8.5.3) - postcss-custom-selectors: 6.0.3(postcss@8.5.3) - postcss-dir-pseudo-class: 6.0.5(postcss@8.5.3) - postcss-double-position-gradients: 3.1.2(postcss@8.5.3) - postcss-env-function: 4.0.6(postcss@8.5.3) - postcss-focus-visible: 6.0.4(postcss@8.5.3) - postcss-focus-within: 5.0.4(postcss@8.5.3) - postcss-font-variant: 5.0.0(postcss@8.5.3) - postcss-gap-properties: 3.0.5(postcss@8.5.3) - postcss-image-set-function: 4.0.7(postcss@8.5.3) - postcss-initial: 4.0.1(postcss@8.5.3) - postcss-lab-function: 4.2.1(postcss@8.5.3) - postcss-logical: 5.0.4(postcss@8.5.3) - postcss-media-minmax: 5.0.0(postcss@8.5.3) - postcss-nesting: 10.2.0(postcss@8.5.3) - postcss-opacity-percentage: 1.1.3(postcss@8.5.3) - postcss-overflow-shorthand: 3.0.4(postcss@8.5.3) - postcss-page-break: 3.0.4(postcss@8.5.3) - postcss-place: 7.0.5(postcss@8.5.3) - postcss-pseudo-class-any-link: 7.1.6(postcss@8.5.3) - postcss-replace-overflow-wrap: 4.0.0(postcss@8.5.3) - postcss-selector-not: 6.0.1(postcss@8.5.3) + postcss: 8.5.9 + postcss-attribute-case-insensitive: 5.0.2(postcss@8.5.9) + postcss-clamp: 4.1.0(postcss@8.5.9) + postcss-color-functional-notation: 4.2.4(postcss@8.5.9) + postcss-color-hex-alpha: 8.0.4(postcss@8.5.9) + postcss-color-rebeccapurple: 7.1.1(postcss@8.5.9) + postcss-custom-media: 8.0.2(postcss@8.5.9) + postcss-custom-properties: 12.1.11(postcss@8.5.9) + postcss-custom-selectors: 6.0.3(postcss@8.5.9) + postcss-dir-pseudo-class: 6.0.5(postcss@8.5.9) + postcss-double-position-gradients: 3.1.2(postcss@8.5.9) + postcss-env-function: 4.0.6(postcss@8.5.9) + postcss-focus-visible: 6.0.4(postcss@8.5.9) + postcss-focus-within: 5.0.4(postcss@8.5.9) + postcss-font-variant: 5.0.0(postcss@8.5.9) + postcss-gap-properties: 3.0.5(postcss@8.5.9) + postcss-image-set-function: 4.0.7(postcss@8.5.9) + postcss-initial: 4.0.1(postcss@8.5.9) + postcss-lab-function: 4.2.1(postcss@8.5.9) + postcss-logical: 5.0.4(postcss@8.5.9) + postcss-media-minmax: 5.0.0(postcss@8.5.9) + postcss-nesting: 10.2.0(postcss@8.5.9) + postcss-opacity-percentage: 1.1.3(postcss@8.5.9) + postcss-overflow-shorthand: 3.0.4(postcss@8.5.9) + postcss-page-break: 3.0.4(postcss@8.5.9) + postcss-place: 7.0.5(postcss@8.5.9) + postcss-pseudo-class-any-link: 7.1.6(postcss@8.5.9) + postcss-replace-overflow-wrap: 4.0.0(postcss@8.5.9) + postcss-selector-not: 6.0.1(postcss@8.5.9) postcss-value-parser: 4.2.0 - postcss-pseudo-class-any-link@7.1.6(postcss@8.5.3): + postcss-pseudo-class-any-link@7.1.6(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-selector-parser: 6.1.2 - postcss-reduce-initial@5.1.2(postcss@8.5.3): + postcss-reduce-initial@5.1.2(postcss@8.5.9): dependencies: - browserslist: 4.24.4 + browserslist: 4.28.2 caniuse-api: 3.0.0 - postcss: 8.5.3 + postcss: 8.5.9 - postcss-reduce-transforms@5.1.0(postcss@8.5.3): + postcss-reduce-transforms@5.1.0(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - postcss-replace-overflow-wrap@4.0.0(postcss@8.5.3): + postcss-replace-overflow-wrap@4.0.0(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 - postcss-selector-not@6.0.1(postcss@8.5.3): + postcss-selector-not@6.0.1(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-selector-parser: 6.1.2 postcss-selector-parser@6.1.2: @@ -18495,20 +19082,20 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-selector-parser@7.1.0: + postcss-selector-parser@7.1.1: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-svgo@5.1.0(postcss@8.5.3): + postcss-svgo@5.1.0(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-value-parser: 4.2.0 - svgo: 2.8.0 + svgo: 2.8.2 - postcss-unique-selectors@5.1.1(postcss@8.5.3): + postcss-unique-selectors@5.1.1(postcss@8.5.9): dependencies: - postcss: 8.5.3 + postcss: 8.5.9 postcss-selector-parser: 6.1.2 postcss-value-parser@4.2.0: {} @@ -18524,7 +19111,7 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - postcss@8.5.3: + postcss@8.5.9: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 @@ -18534,20 +19121,20 @@ snapshots: prelude-ls@1.2.1: {} - prettier-plugin-organize-imports@3.2.4(prettier@3.5.3)(typescript@5.8.2): + prettier-plugin-organize-imports@3.2.4(prettier@3.8.2)(typescript@5.9.3): dependencies: - prettier: 3.5.3 - typescript: 5.8.2 + prettier: 3.8.2 + typescript: 5.9.3 prettier@2.8.8: {} - prettier@3.5.3: {} + prettier@3.8.2: {} pretty-bytes@5.6.0: {} pretty-error@4.0.0: dependencies: - lodash: 4.17.21 + lodash: 4.18.1 renderkid: 3.0.0 pretty-format@27.5.1: @@ -18589,7 +19176,7 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 - proxy-from-env@1.1.0: {} + proxy-from-env@2.1.0: {} psl@1.15.0: dependencies: @@ -18597,31 +19184,37 @@ snapshots: public-encrypt@4.0.3: dependencies: - bn.js: 4.12.1 + bn.js: 4.12.3 browserify-rsa: 4.1.1 create-hash: 1.2.0 - parse-asn1: 5.1.7 + parse-asn1: 5.1.9 randombytes: 2.1.0 safe-buffer: 5.2.1 - pump@3.0.3: + pump@3.0.4: dependencies: end-of-stream: 1.4.5 once: 1.4.0 punycode@2.3.1: {} + pvtsutils@1.3.6: + dependencies: + tslib: 2.8.1 + + pvutils@1.1.5: {} + q@1.5.1: {} - qs@6.13.0: + qs@6.14.2: dependencies: side-channel: 1.1.0 - qs@6.14.0: + qs@6.15.1: dependencies: side-channel: 1.1.0 - quansync@0.2.10: {} + quansync@0.2.11: {} querystring@0.2.1: {} @@ -18648,40 +19241,40 @@ snapshots: range-parser@1.2.1: {} - raw-body@2.5.2: + raw-body@2.5.3: dependencies: bytes: 3.1.2 - http-errors: 2.0.0 + http-errors: 2.0.1 iconv-lite: 0.4.24 unpipe: 1.0.0 react-app-polyfill@3.0.0: dependencies: - core-js: 3.41.0 + core-js: 3.49.0 object-assign: 4.1.1 promise: 8.3.0 raf: 3.4.1 regenerator-runtime: 0.13.11 whatwg-fetch: 3.6.20 - react-copy-to-clipboard@5.1.0(react@18.3.1): + react-copy-to-clipboard@5.1.1(react@18.3.1): dependencies: copy-to-clipboard: 3.3.3 prop-types: 15.8.1 react: 18.3.1 - react-dev-utils@12.0.1(eslint@8.57.1)(typescript@5.8.2)(webpack@5.101.3): + react-dev-utils@12.0.1(eslint@8.57.1)(typescript@5.9.3)(webpack@5.106.1): dependencies: - '@babel/code-frame': 7.26.2 + '@babel/code-frame': 7.29.0 address: 1.2.2 - browserslist: 4.24.4 + browserslist: 4.28.2 chalk: 4.1.2 cross-spawn: 7.0.6 detect-port-alt: 1.1.6 escape-string-regexp: 4.0.0 filesize: 8.0.7 find-up: 5.0.0 - fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.1)(typescript@5.8.2)(webpack@5.101.3) + fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.1)(typescript@5.9.3)(webpack@5.106.1) global-modules: 2.0.0 globby: 11.1.0 gzip-size: 6.0.0 @@ -18693,12 +19286,12 @@ snapshots: prompts: 2.4.2 react-error-overlay: 6.1.0 recursive-readdir: 2.2.3 - shell-quote: 1.8.2 + shell-quote: 1.8.3 strip-ansi: 6.0.1 text-table: 0.2.0 - webpack: 5.101.3 + webpack: 5.106.1(webpack-cli@6.0.1) optionalDependencies: - typescript: 5.8.2 + typescript: 5.9.3 transitivePeerDependencies: - eslint - supports-color @@ -18722,59 +19315,59 @@ snapshots: react-refresh@0.17.0: {} - react-scripts@5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(@types/babel__core@7.20.5)(bufferutil@4.0.9)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(type-fest@0.21.3)(typescript@5.8.2)(utf-8-validate@5.0.10): + react-scripts@5.0.1(@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0))(@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0))(@types/babel__core@7.20.5)(bufferutil@4.1.0)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3))(type-fest@0.21.3)(typescript@5.9.3): dependencies: - '@babel/core': 7.26.10 - '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(react-refresh@0.11.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.101.3))(webpack@5.101.3) + '@babel/core': 7.29.0 + '@pmmmwh/react-refresh-webpack-plugin': 0.5.17(react-refresh@0.11.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.1.0)(webpack@5.106.1))(webpack@5.106.1) '@svgr/webpack': 5.5.0 - babel-jest: 27.5.1(@babel/core@7.26.10) - babel-loader: 8.4.1(@babel/core@7.26.10)(webpack@5.101.3) - babel-plugin-named-asset-import: 0.3.8(@babel/core@7.26.10) + babel-jest: 27.5.1(@babel/core@7.29.0) + babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@5.106.1) + babel-plugin-named-asset-import: 0.3.8(@babel/core@7.29.0) babel-preset-react-app: 10.1.0 bfj: 7.1.0 - browserslist: 4.24.4 + browserslist: 4.28.2 camelcase: 6.3.0 case-sensitive-paths-webpack-plugin: 2.4.0 - css-loader: 6.11.0(webpack@5.101.3) - css-minimizer-webpack-plugin: 3.4.1(webpack@5.101.3) + css-loader: 6.11.0(webpack@5.106.1) + css-minimizer-webpack-plugin: 3.4.1(webpack@5.106.1) dotenv: 10.0.0 dotenv-expand: 5.1.0 eslint: 8.57.1 - eslint-config-react-app: 7.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.10))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10))(typescript@5.8.2) - eslint-webpack-plugin: 3.2.0(eslint@8.57.1)(webpack@5.101.3) - file-loader: 6.2.0(webpack@5.101.3) + eslint-config-react-app: 7.0.1(@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0))(@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)))(typescript@5.9.3) + eslint-webpack-plugin: 3.2.0(eslint@8.57.1)(webpack@5.106.1) + file-loader: 6.2.0(webpack@5.106.1) fs-extra: 10.1.0 - html-webpack-plugin: 5.6.3(webpack@5.101.3) + html-webpack-plugin: 5.6.6(webpack@5.106.1) identity-obj-proxy: 3.0.0 - jest: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10) + jest: 27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)) jest-resolve: 27.5.1 - jest-watch-typeahead: 1.1.0(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2))(utf-8-validate@5.0.10)) - mini-css-extract-plugin: 2.9.2(webpack@5.101.3) - postcss: 8.5.3 - postcss-flexbugs-fixes: 5.0.2(postcss@8.5.3) - postcss-loader: 6.2.1(postcss@8.5.3)(webpack@5.101.3) - postcss-normalize: 10.0.1(browserslist@4.24.4)(postcss@8.5.3) - postcss-preset-env: 7.8.3(postcss@8.5.3) + jest-watch-typeahead: 1.1.0(jest@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3))) + mini-css-extract-plugin: 2.10.2(webpack@5.106.1) + postcss: 8.5.9 + postcss-flexbugs-fixes: 5.0.2(postcss@8.5.9) + postcss-loader: 6.2.1(postcss@8.5.9)(webpack@5.106.1) + postcss-normalize: 10.0.1(browserslist@4.28.2)(postcss@8.5.9) + postcss-preset-env: 7.8.3(postcss@8.5.9) prompts: 2.4.2 react: 18.3.1 react-app-polyfill: 3.0.0 - react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.8.2)(webpack@5.101.3) + react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.9.3)(webpack@5.106.1) react-refresh: 0.11.0 - resolve: 1.22.10 + resolve: 1.22.11 resolve-url-loader: 4.0.0 - sass-loader: 12.6.0(webpack@5.101.3) - semver: 7.7.1 - source-map-loader: 3.0.2(webpack@5.101.3) - style-loader: 3.3.4(webpack@5.101.3) - tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2)) - terser-webpack-plugin: 5.3.14(webpack@5.101.3) - webpack: 5.101.3 - webpack-dev-server: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.101.3) - webpack-manifest-plugin: 4.1.1(webpack@5.101.3) - workbox-webpack-plugin: 6.6.0(@types/babel__core@7.20.5)(webpack@5.101.3) + sass-loader: 12.6.0(webpack@5.106.1) + semver: 7.7.4 + source-map-loader: 3.0.2(webpack@5.106.1) + style-loader: 3.3.4(webpack@5.106.1) + tailwindcss: 3.4.19 + terser-webpack-plugin: 5.4.0(webpack@5.106.1) + webpack: 5.106.1(webpack-cli@6.0.1) + webpack-dev-server: 4.15.2(bufferutil@4.1.0)(webpack@5.106.1) + webpack-manifest-plugin: 4.1.1(webpack@5.106.1) + workbox-webpack-plugin: 6.6.0(@types/babel__core@7.20.5)(webpack@5.106.1) optionalDependencies: fsevents: 2.3.3 - typescript: 5.8.2 + typescript: 5.9.3 transitivePeerDependencies: - '@babel/plugin-syntax-flow' - '@babel/plugin-transform-react-jsx' @@ -18801,6 +19394,7 @@ snapshots: - sockjs-client - supports-color - ts-node + - tsx - type-fest - uglify-js - utf-8-validate @@ -18808,6 +19402,7 @@ snapshots: - webpack-cli - webpack-hot-middleware - webpack-plugin-serve + - yaml react-spinners@0.14.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: @@ -18849,7 +19444,7 @@ snapshots: read-yaml-file@1.1.0: dependencies: graceful-fs: 4.2.11 - js-yaml: 3.14.1 + js-yaml: 3.14.2 pify: 4.0.1 strip-bom: 3.0.0 @@ -18871,15 +19466,15 @@ snapshots: readdirp@3.6.0: dependencies: - picomatch: 2.3.1 + picomatch: 2.3.2 rechoir@0.8.0: dependencies: - resolve: 1.22.10 + resolve: 1.22.11 recursive-readdir@2.2.3: dependencies: - minimatch: 3.1.2 + minimatch: 3.1.5 redent@3.0.0: dependencies: @@ -18888,18 +19483,24 @@ snapshots: reduce-flatten@2.0.0: {} + refa@0.12.1: + dependencies: + '@eslint-community/regexpp': 4.12.2 + + reflect-metadata@0.2.2: {} + reflect.getprototypeof@1.0.10: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 es-errors: 1.3.0 es-object-atoms: 1.1.1 get-intrinsic: 1.3.0 get-proto: 1.0.1 which-builtin-type: 1.2.1 - regenerate-unicode-properties@10.2.0: + regenerate-unicode-properties@10.2.2: dependencies: regenerate: 1.4.2 @@ -18907,37 +19508,36 @@ snapshots: regenerator-runtime@0.13.11: {} - regenerator-runtime@0.14.1: {} + regex-parser@2.3.1: {} - regenerator-transform@0.15.2: + regexp-ast-analysis@0.7.1: dependencies: - '@babel/runtime': 7.27.0 - - regex-parser@2.3.1: {} + '@eslint-community/regexpp': 4.12.2 + refa: 0.12.1 regexp.prototype.flags@1.5.4: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 es-errors: 1.3.0 get-proto: 1.0.1 gopd: 1.2.0 set-function-name: 2.0.2 - regexpu-core@6.2.0: + regexpu-core@6.4.0: dependencies: regenerate: 1.4.2 - regenerate-unicode-properties: 10.2.0 + regenerate-unicode-properties: 10.2.2 regjsgen: 0.8.0 - regjsparser: 0.12.0 + regjsparser: 0.13.1 unicode-match-property-ecmascript: 2.0.0 - unicode-match-property-value-ecmascript: 2.2.0 + unicode-match-property-value-ecmascript: 2.2.1 regjsgen@0.8.0: {} - regjsparser@0.12.0: + regjsparser@0.13.1: dependencies: - jsesc: 3.0.2 + jsesc: 3.1.0 relateurl@0.2.7: {} @@ -18946,7 +19546,7 @@ snapshots: css-select: 4.3.0 dom-converter: 0.2.0 htmlparser2: 6.1.0 - lodash: 4.17.21 + lodash: 4.18.1 strip-ansi: 6.0.1 require-directory@2.1.1: {} @@ -18982,15 +19582,18 @@ snapshots: resolve.exports@1.1.1: {} - resolve@1.22.10: + resolve@1.22.11: dependencies: is-core-module: 2.16.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - resolve@2.0.0-next.5: + resolve@2.0.0-next.6: dependencies: + es-errors: 1.3.0 is-core-module: 2.16.1 + node-exports-info: 1.6.0 + object-keys: 1.1.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -19013,65 +19616,70 @@ snapshots: rimraf@5.0.10: dependencies: - glob: 10.4.5 + glob: 10.5.0 - ripemd160@2.0.2: + ripemd160@2.0.3: dependencies: - hash-base: 3.0.5 + hash-base: 3.1.2 inherits: 2.0.4 - rollup-plugin-terser@7.0.2(rollup@2.79.2): + rollup-plugin-terser@7.0.2(rollup@2.80.0): dependencies: - '@babel/code-frame': 7.26.2 + '@babel/code-frame': 7.29.0 jest-worker: 26.6.2 - rollup: 2.79.2 + rollup: 2.80.0 serialize-javascript: 4.0.0 - terser: 5.39.0 + terser: 5.46.1 - rollup@2.79.2: + rollup@2.80.0: optionalDependencies: fsevents: 2.3.3 - rollup@4.37.0: + rollup@4.60.1: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.37.0 - '@rollup/rollup-android-arm64': 4.37.0 - '@rollup/rollup-darwin-arm64': 4.37.0 - '@rollup/rollup-darwin-x64': 4.37.0 - '@rollup/rollup-freebsd-arm64': 4.37.0 - '@rollup/rollup-freebsd-x64': 4.37.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.37.0 - '@rollup/rollup-linux-arm-musleabihf': 4.37.0 - '@rollup/rollup-linux-arm64-gnu': 4.37.0 - '@rollup/rollup-linux-arm64-musl': 4.37.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.37.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.37.0 - '@rollup/rollup-linux-riscv64-gnu': 4.37.0 - '@rollup/rollup-linux-riscv64-musl': 4.37.0 - '@rollup/rollup-linux-s390x-gnu': 4.37.0 - '@rollup/rollup-linux-x64-gnu': 4.37.0 - '@rollup/rollup-linux-x64-musl': 4.37.0 - '@rollup/rollup-win32-arm64-msvc': 4.37.0 - '@rollup/rollup-win32-ia32-msvc': 4.37.0 - '@rollup/rollup-win32-x64-msvc': 4.37.0 + '@rollup/rollup-android-arm-eabi': 4.60.1 + '@rollup/rollup-android-arm64': 4.60.1 + '@rollup/rollup-darwin-arm64': 4.60.1 + '@rollup/rollup-darwin-x64': 4.60.1 + '@rollup/rollup-freebsd-arm64': 4.60.1 + '@rollup/rollup-freebsd-x64': 4.60.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.1 + '@rollup/rollup-linux-arm-musleabihf': 4.60.1 + '@rollup/rollup-linux-arm64-gnu': 4.60.1 + '@rollup/rollup-linux-arm64-musl': 4.60.1 + '@rollup/rollup-linux-loong64-gnu': 4.60.1 + '@rollup/rollup-linux-loong64-musl': 4.60.1 + '@rollup/rollup-linux-ppc64-gnu': 4.60.1 + '@rollup/rollup-linux-ppc64-musl': 4.60.1 + '@rollup/rollup-linux-riscv64-gnu': 4.60.1 + '@rollup/rollup-linux-riscv64-musl': 4.60.1 + '@rollup/rollup-linux-s390x-gnu': 4.60.1 + '@rollup/rollup-linux-x64-gnu': 4.60.1 + '@rollup/rollup-linux-x64-musl': 4.60.1 + '@rollup/rollup-openbsd-x64': 4.60.1 + '@rollup/rollup-openharmony-arm64': 4.60.1 + '@rollup/rollup-win32-arm64-msvc': 4.60.1 + '@rollup/rollup-win32-ia32-msvc': 4.60.1 + '@rollup/rollup-win32-x64-gnu': 4.60.1 + '@rollup/rollup-win32-x64-msvc': 4.60.1 fsevents: 2.3.3 - rpc-websockets@9.1.1: + rpc-websockets@9.3.8: dependencies: - '@swc/helpers': 0.5.15 - '@types/uuid': 8.3.4 - '@types/ws': 8.18.0 + '@swc/helpers': 0.5.21 + '@types/uuid': 10.0.0 + '@types/ws': 8.18.1 buffer: 6.0.3 - eventemitter3: 5.0.1 - uuid: 8.3.2 - ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + eventemitter3: 5.0.4 + uuid: 11.1.0 + ws: 8.20.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: - bufferutil: 4.0.9 - utf-8-validate: 5.0.10 + bufferutil: 4.1.0 + utf-8-validate: 6.0.6 - run-applescript@7.0.0: {} + run-applescript@7.1.0: {} run-async@2.4.1: {} @@ -19085,7 +19693,7 @@ snapshots: safe-array-concat@1.1.3: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 get-intrinsic: 1.3.0 has-symbols: 1.1.0 @@ -19110,14 +19718,16 @@ snapshots: sanitize.css@13.0.0: {} - sass-loader@12.6.0(webpack@5.101.3): + sass-loader@12.6.0(webpack@5.106.1): dependencies: klona: 2.0.6 neo-async: 2.6.2 - webpack: 5.101.3 + webpack: 5.106.1(webpack-cli@6.0.1) sax@1.2.4: {} + sax@1.6.0: {} + saxes@5.0.1: dependencies: xmlchars: 2.2.0 @@ -19129,37 +19739,36 @@ snapshots: schema-utils@2.7.0: dependencies: '@types/json-schema': 7.0.15 - ajv: 6.12.6 - ajv-keywords: 3.5.2(ajv@6.12.6) + ajv: 6.14.0 + ajv-keywords: 3.5.2(ajv@6.14.0) schema-utils@2.7.1: dependencies: '@types/json-schema': 7.0.15 - ajv: 6.12.6 - ajv-keywords: 3.5.2(ajv@6.12.6) + ajv: 6.14.0 + ajv-keywords: 3.5.2(ajv@6.14.0) schema-utils@3.3.0: dependencies: '@types/json-schema': 7.0.15 - ajv: 6.12.6 - ajv-keywords: 3.5.2(ajv@6.12.6) - - schema-utils@4.3.0: - dependencies: - '@types/json-schema': 7.0.15 - ajv: 8.17.1 - ajv-formats: 2.1.1(ajv@8.17.1) - ajv-keywords: 5.1.0(ajv@8.17.1) + ajv: 6.14.0 + ajv-keywords: 3.5.2(ajv@6.14.0) - schema-utils@4.3.2: + schema-utils@4.3.3: dependencies: '@types/json-schema': 7.0.15 - ajv: 8.17.1 - ajv-formats: 2.1.1(ajv@8.17.1) - ajv-keywords: 5.1.0(ajv@8.17.1) + ajv: 8.18.0 + ajv-formats: 2.1.1(ajv@8.18.0) + ajv-keywords: 5.1.0(ajv@8.18.0) scrypt-js@3.0.1: {} + scslre@0.3.0: + dependencies: + '@eslint-community/regexpp': 4.12.2 + refa: 0.12.1 + regexp-ast-analysis: 0.7.1 + secp256k1@5.0.1: dependencies: elliptic: 6.6.1 @@ -19170,33 +19779,35 @@ snapshots: selfsigned@2.4.1: dependencies: - '@types/node-forge': 1.3.11 - node-forge: 1.3.1 + '@types/node-forge': 1.3.14 + node-forge: 1.4.0 + + selfsigned@5.5.0: + dependencies: + '@peculiar/x509': 1.14.3 + pkijs: 3.4.0 semver@5.7.2: {} semver@6.3.1: {} - semver@7.7.1: {} - - semver@7.7.2: - optional: true + semver@7.7.4: {} - send@0.19.0: + send@0.19.2: dependencies: debug: 2.6.9 depd: 2.0.0 destroy: 1.2.0 - encodeurl: 1.0.2 + encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 fresh: 0.5.2 - http-errors: 2.0.0 + http-errors: 2.0.1 mime: 1.6.0 ms: 2.1.3 on-finished: 2.4.1 range-parser: 1.2.1 - statuses: 2.0.1 + statuses: 2.0.2 transitivePeerDependencies: - supports-color @@ -19208,24 +19819,24 @@ snapshots: dependencies: randombytes: 2.1.0 - serve-index@1.9.1: + serve-index@1.9.2: dependencies: accepts: 1.3.8 batch: 0.6.1 debug: 2.6.9 escape-html: 1.0.3 - http-errors: 1.6.3 + http-errors: 1.8.1 mime-types: 2.1.35 parseurl: 1.3.3 transitivePeerDependencies: - supports-color - serve-static@1.16.2: + serve-static@1.16.3: dependencies: encodeurl: 2.0.0 escape-html: 1.0.3 parseurl: 1.3.3 - send: 0.19.0 + send: 0.19.2 transitivePeerDependencies: - supports-color @@ -19251,47 +19862,48 @@ snapshots: es-errors: 1.3.0 es-object-atoms: 1.1.1 - setprototypeof@1.1.0: {} - setprototypeof@1.2.0: {} - sha.js@2.4.11: + sha.js@2.4.12: dependencies: inherits: 2.0.4 safe-buffer: 5.2.1 + to-buffer: 1.2.2 shallow-clone@3.0.1: dependencies: kind-of: 6.0.3 - sharp@0.34.3: + sharp@0.34.5: dependencies: - color: 4.2.3 - detect-libc: 2.0.4 - semver: 7.7.2 + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.7.4 optionalDependencies: - '@img/sharp-darwin-arm64': 0.34.3 - '@img/sharp-darwin-x64': 0.34.3 - '@img/sharp-libvips-darwin-arm64': 1.2.0 - '@img/sharp-libvips-darwin-x64': 1.2.0 - '@img/sharp-libvips-linux-arm': 1.2.0 - '@img/sharp-libvips-linux-arm64': 1.2.0 - '@img/sharp-libvips-linux-ppc64': 1.2.0 - '@img/sharp-libvips-linux-s390x': 1.2.0 - '@img/sharp-libvips-linux-x64': 1.2.0 - '@img/sharp-libvips-linuxmusl-arm64': 1.2.0 - '@img/sharp-libvips-linuxmusl-x64': 1.2.0 - '@img/sharp-linux-arm': 0.34.3 - '@img/sharp-linux-arm64': 0.34.3 - '@img/sharp-linux-ppc64': 0.34.3 - '@img/sharp-linux-s390x': 0.34.3 - '@img/sharp-linux-x64': 0.34.3 - '@img/sharp-linuxmusl-arm64': 0.34.3 - '@img/sharp-linuxmusl-x64': 0.34.3 - '@img/sharp-wasm32': 0.34.3 - '@img/sharp-win32-arm64': 0.34.3 - '@img/sharp-win32-ia32': 0.34.3 - '@img/sharp-win32-x64': 0.34.3 + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 optional: true shebang-command@1.2.0: @@ -19306,7 +19918,7 @@ snapshots: shebang-regex@3.0.0: {} - shell-quote@1.8.2: {} + shell-quote@1.8.3: {} shiki@0.14.7: dependencies: @@ -19315,7 +19927,7 @@ snapshots: vscode-oniguruma: 1.7.0 vscode-textmate: 8.0.0 - side-channel-list@1.0.0: + side-channel-list@1.0.1: dependencies: es-errors: 1.3.0 object-inspect: 1.13.4 @@ -19339,7 +19951,7 @@ snapshots: dependencies: es-errors: 1.3.0 object-inspect: 1.13.4 - side-channel-list: 1.0.0 + side-channel-list: 1.0.1 side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 @@ -19349,18 +19961,13 @@ snapshots: signal-exit@4.1.0: {} - simple-swizzle@0.2.2: - dependencies: - is-arrayish: 0.3.2 - optional: true - sisteransi@1.0.5: {} - siwe@3.0.0(ethers@5.8.0): + siwe@3.0.0(ethers@5.8.0(bufferutil@4.1.0)): dependencies: '@spruceid/siwe-parser': 3.0.0 '@stablelib/random': 1.0.2 - ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ethers: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) slash@3.0.0: {} @@ -19376,25 +19983,25 @@ snapshots: sort-package-json@2.15.1: dependencies: - detect-indent: 7.0.1 + detect-indent: 7.0.2 detect-newline: 4.0.1 get-stdin: 9.0.0 git-hooks-list: 3.2.0 is-plain-obj: 4.1.0 - semver: 7.7.1 + semver: 7.7.4 sort-object-keys: 1.1.3 - tinyglobby: 0.2.12 + tinyglobby: 0.2.16 source-list-map@2.0.1: {} source-map-js@1.2.1: {} - source-map-loader@3.0.2(webpack@5.101.3): + source-map-loader@3.0.2(webpack@5.106.1): dependencies: abab: 2.0.6 iconv-lite: 0.6.3 source-map-js: 1.2.1 - webpack: 5.101.3 + webpack: 5.106.1(webpack-cli@6.0.1) source-map-support@0.5.21: dependencies: @@ -19403,7 +20010,7 @@ snapshots: source-map@0.6.1: {} - source-map@0.7.4: {} + source-map@0.7.6: {} source-map@0.8.0-beta.0: dependencies: @@ -19419,20 +20026,20 @@ snapshots: spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.21 + spdx-license-ids: 3.0.23 spdx-exceptions@2.5.0: {} spdx-expression-parse@3.0.1: dependencies: spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.21 + spdx-license-ids: 3.0.23 - spdx-license-ids@3.0.21: {} + spdx-license-ids@3.0.23: {} spdy-transport@3.0.0: dependencies: - debug: 4.4.0 + debug: 4.4.3 detect-node: 2.1.0 hpack.js: 2.1.6 obuf: 1.1.2 @@ -19443,7 +20050,7 @@ snapshots: spdy@4.0.2: dependencies: - debug: 4.4.0 + debug: 4.4.3 handle-thing: 2.0.1 http-deceiver: 1.2.7 select-hose: 2.0.0 @@ -19486,7 +20093,7 @@ snapshots: figures: 3.2.0 find-up: 5.0.0 git-semver-tags: 4.1.1 - semver: 7.7.1 + semver: 7.7.4 stringify-package: 1.0.1 yargs: 16.2.0 @@ -19494,13 +20101,15 @@ snapshots: dependencies: escodegen: 1.14.3 - statuses@1.5.0: {} + static-eval@2.1.1: + dependencies: + escodegen: 2.1.0 - statuses@2.0.1: {} + statuses@1.5.0: {} - std-env@3.8.1: {} + statuses@2.0.2: {} - std-env@3.9.0: {} + std-env@3.10.0: {} stop-iteration-iterator@1.1.0: dependencies: @@ -19512,6 +20121,12 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 + stream-chain@2.2.5: {} + + stream-json@1.9.1: + dependencies: + stream-chain: 2.2.5 + stream-transform@2.1.3: dependencies: mixme: 0.5.10 @@ -19528,7 +20143,7 @@ snapshots: string-length@5.0.1: dependencies: char-regex: 2.0.2 - strip-ansi: 7.1.0 + strip-ansi: 7.2.0 string-natural-compare@3.0.1: {} @@ -19542,20 +20157,20 @@ snapshots: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 - strip-ansi: 7.1.0 + strip-ansi: 7.2.0 string.prototype.includes@2.0.1: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 string.prototype.matchall@4.0.12: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 es-errors: 1.3.0 es-object-atoms: 1.1.1 get-intrinsic: 1.3.0 @@ -19568,36 +20183,36 @@ snapshots: string.prototype.padend@3.1.6: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 es-object-atoms: 1.1.1 string.prototype.repeat@1.0.0: dependencies: define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 string.prototype.trim@1.2.10: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-data-property: 1.1.4 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 es-object-atoms: 1.1.1 has-property-descriptors: 1.0.2 string.prototype.trimend@1.0.9: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 es-object-atoms: 1.1.1 string.prototype.trimstart@1.0.8: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 es-object-atoms: 1.1.1 @@ -19621,9 +20236,9 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.0: + strip-ansi@7.2.0: dependencies: - ansi-regex: 6.1.0 + ansi-regex: 6.2.2 strip-bom@3.0.0: {} @@ -19639,33 +20254,37 @@ snapshots: strip-json-comments@3.1.1: {} + strip-literal@3.1.0: + dependencies: + js-tokens: 9.0.1 + strip-outer@1.0.1: dependencies: escape-string-regexp: 1.0.5 - style-loader@3.3.4(webpack@5.101.3): + style-loader@3.3.4(webpack@5.106.1): dependencies: - webpack: 5.101.3 + webpack: 5.106.1(webpack-cli@6.0.1) styled-jsx@5.1.6(react@18.3.1): dependencies: client-only: 0.0.1 react: 18.3.1 - stylehacks@5.1.1(postcss@8.5.3): + stylehacks@5.1.1(postcss@8.5.9): dependencies: - browserslist: 4.24.4 - postcss: 8.5.3 + browserslist: 4.28.2 + postcss: 8.5.9 postcss-selector-parser: 6.1.2 - sucrase@3.35.0: + sucrase@3.35.1: dependencies: - '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/gen-mapping': 0.3.13 commander: 4.1.1 - glob: 10.4.5 lines-and-columns: 1.2.4 mz: 2.7.0 pirates: 4.0.7 + tinyglobby: 0.2.16 ts-interface-checker: 0.1.13 superstruct@2.0.2: {} @@ -19699,7 +20318,7 @@ snapshots: css-select-base-adapter: 0.1.1 css-tree: 1.0.0-alpha.37 csso: 4.2.0 - js-yaml: 3.14.1 + js-yaml: 3.14.2 mkdirp: 0.5.6 object.values: 1.2.1 sax: 1.2.4 @@ -19707,14 +20326,14 @@ snapshots: unquote: 1.1.1 util.promisify: 1.0.1 - svgo@2.8.0: + svgo@2.8.2: dependencies: - '@trysound/sax': 0.2.0 commander: 7.2.0 css-select: 4.3.0 css-tree: 1.1.3 csso: 4.2.0 picocolors: 1.1.1 + sax: 1.6.0 stable: 0.1.8 symbol-tree@3.2.4: {} @@ -19726,7 +20345,7 @@ snapshots: typical: 5.2.0 wordwrapjs: 4.0.1 - tailwindcss@3.4.17(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2)): + tailwindcss@3.4.19: dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -19742,20 +20361,21 @@ snapshots: normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.1.1 - postcss: 8.5.3 - postcss-import: 15.1.0(postcss@8.5.3) - postcss-js: 4.0.1(postcss@8.5.3) - postcss-load-config: 4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2)) - postcss-nested: 6.2.0(postcss@8.5.3) + postcss: 8.5.9 + postcss-import: 15.1.0(postcss@8.5.9) + postcss-js: 4.1.0(postcss@8.5.9) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.9) + postcss-nested: 6.2.0(postcss@8.5.9) postcss-selector-parser: 6.1.2 - resolve: 1.22.10 - sucrase: 3.35.0 + resolve: 1.22.11 + sucrase: 3.35.1 transitivePeerDependencies: - - ts-node + - tsx + - yaml tapable@1.1.3: {} - tapable@2.2.1: {} + tapable@2.3.2: {} temp-dir@2.0.0: {} @@ -19773,28 +20393,18 @@ snapshots: ansi-escapes: 4.3.2 supports-hyperlinks: 2.3.0 - terser-webpack-plugin@5.3.14(webpack@5.101.3(webpack-cli@6.0.1)): - dependencies: - '@jridgewell/trace-mapping': 0.3.25 - jest-worker: 27.5.1 - schema-utils: 4.3.0 - serialize-javascript: 6.0.2 - terser: 5.39.0 - webpack: 5.101.3(webpack-cli@6.0.1) - - terser-webpack-plugin@5.3.14(webpack@5.101.3): + terser-webpack-plugin@5.4.0(webpack@5.106.1): dependencies: - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 - schema-utils: 4.3.0 - serialize-javascript: 6.0.2 - terser: 5.39.0 - webpack: 5.101.3 + schema-utils: 4.3.3 + terser: 5.46.1 + webpack: 5.106.1(webpack-cli@6.0.1) - terser@5.39.0: + terser@5.46.1: dependencies: - '@jridgewell/source-map': 0.3.6 - acorn: 8.14.1 + '@jridgewell/source-map': 0.3.11 + acorn: 8.16.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -19802,13 +20412,13 @@ snapshots: dependencies: '@istanbuljs/schema': 0.1.3 glob: 7.2.3 - minimatch: 3.1.2 + minimatch: 3.1.5 - test-exclude@7.0.1: + test-exclude@7.0.2: dependencies: '@istanbuljs/schema': 0.1.3 - glob: 10.4.5 - minimatch: 9.0.5 + glob: 10.5.0 + minimatch: 10.2.5 text-encoding-utf-8@1.0.2: {} @@ -19824,7 +20434,7 @@ snapshots: dependencies: any-promise: 1.3.0 - thingies@2.5.0(tslib@2.8.1): + thingies@2.6.0(tslib@2.8.1): dependencies: tslib: 2.8.1 @@ -19847,31 +20457,37 @@ snapshots: tinyexec@0.3.2: {} - tinyglobby@0.2.12: + tinyglobby@0.2.16: dependencies: - fdir: 6.4.3(picomatch@4.0.2) - picomatch: 4.0.2 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 - tinypool@1.0.2: {} + tinypool@1.1.1: {} tinyrainbow@2.0.0: {} - tinyspy@3.0.2: {} + tinyspy@4.0.4: {} tmp-promise@3.0.3: dependencies: - tmp: 0.2.3 + tmp: 0.2.5 optional: true tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 - tmp@0.2.3: + tmp@0.2.5: optional: true tmpl@1.0.5: {} + to-buffer@1.2.2: + dependencies: + isarray: 2.0.5 + safe-buffer: 5.2.1 + typed-array-buffer: 1.0.3 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -19899,7 +20515,7 @@ snapshots: dependencies: punycode: 2.3.1 - tree-dump@1.0.3(tslib@2.8.1): + tree-dump@1.1.0(tslib@2.8.1): dependencies: tslib: 2.8.1 @@ -19915,9 +20531,13 @@ snapshots: dependencies: typescript: 5.2.2 - ts-api-utils@1.4.3(typescript@5.8.2): + ts-api-utils@1.4.3(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + ts-api-utils@2.5.0(typescript@5.9.3): dependencies: - typescript: 5.8.2 + typescript: 5.9.3 ts-command-line-args@2.5.1: dependencies: @@ -19926,35 +20546,35 @@ snapshots: command-line-usage: 6.1.3 string-format: 2.0.0 - ts-essentials@7.0.3(typescript@5.8.2): + ts-essentials@7.0.3(typescript@5.9.3): dependencies: - typescript: 5.8.2 + typescript: 5.9.3 ts-interface-checker@0.1.13: {} - ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.2): + ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 + '@tsconfig/node10': 1.0.12 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 '@types/node': 24.3.0 - acorn: 8.14.1 - acorn-walk: 8.3.4 + acorn: 8.16.0 + acorn-walk: 8.3.5 arg: 4.1.3 create-require: 1.1.1 - diff: 4.0.2 + diff: 4.0.4 make-error: 1.3.6 - typescript: 5.8.2 + typescript: 5.9.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - ts-unused-exports@10.1.0(typescript@5.8.2): + ts-unused-exports@10.1.0(typescript@5.9.3): dependencies: chalk: 4.1.2 tsconfig-paths: 3.15.0 - typescript: 5.8.2 + typescript: 5.9.3 tsconfig-paths@3.15.0: dependencies: @@ -19967,10 +20587,14 @@ snapshots: tslib@2.8.1: {} - tsutils@3.21.0(typescript@5.8.2): + tsutils@3.21.0(typescript@5.9.3): + dependencies: + tslib: 1.14.1 + typescript: 5.9.3 + + tsyringe@4.10.0: dependencies: tslib: 1.14.1 - typescript: 5.8.2 tweetnacl@1.0.3: {} @@ -20001,19 +20625,19 @@ snapshots: media-typer: 0.3.0 mime-types: 2.1.35 - typechain@8.3.2(typescript@5.8.2): + typechain@8.3.2(typescript@5.9.3): dependencies: '@types/prettier': 2.7.3 - debug: 4.4.0 + debug: 4.4.3 fs-extra: 7.0.1 glob: 7.1.7 js-sha3: 0.8.0 - lodash: 4.17.21 + lodash: 4.18.1 mkdirp: 1.0.4 prettier: 2.8.8 ts-command-line-args: 2.5.1 - ts-essentials: 7.0.3(typescript@5.8.2) - typescript: 5.8.2 + ts-essentials: 7.0.3(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -20025,7 +20649,7 @@ snapshots: typed-array-byte-length@1.0.3: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 for-each: 0.3.5 gopd: 1.2.0 has-proto: 1.2.0 @@ -20034,7 +20658,7 @@ snapshots: typed-array-byte-offset@1.0.4: dependencies: available-typed-arrays: 1.0.7 - call-bind: 1.0.8 + call-bind: 1.0.9 for-each: 0.3.5 gopd: 1.2.0 has-proto: 1.2.0 @@ -20043,7 +20667,7 @@ snapshots: typed-array-length@1.0.7: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 for-each: 0.3.5 gopd: 1.2.0 is-typed-array: 1.1.15 @@ -20056,31 +20680,31 @@ snapshots: typedarray@0.0.6: {} - typedoc-plugin-coverage@2.2.0(typedoc@0.25.13(typescript@5.8.2)): + typedoc-plugin-coverage@2.2.0(typedoc@0.25.13(typescript@5.9.3)): dependencies: - typedoc: 0.25.13(typescript@5.8.2) + typedoc: 0.25.13(typescript@5.9.3) - typedoc-plugin-missing-exports@2.3.0(typedoc@0.25.13(typescript@5.8.2)): + typedoc-plugin-missing-exports@2.3.0(typedoc@0.25.13(typescript@5.9.3)): dependencies: - typedoc: 0.25.13(typescript@5.8.2) + typedoc: 0.25.13(typescript@5.9.3) - typedoc-plugin-zod@1.4.0(typedoc@0.25.13(typescript@5.8.2)): + typedoc-plugin-zod@1.4.3(typedoc@0.25.13(typescript@5.9.3)): dependencies: - typedoc: 0.25.13(typescript@5.8.2) + typedoc: 0.25.13(typescript@5.9.3) - typedoc@0.25.13(typescript@5.8.2): + typedoc@0.25.13(typescript@5.9.3): dependencies: lunr: 2.3.9 marked: 4.3.0 - minimatch: 9.0.5 + minimatch: 9.0.9 shiki: 0.14.7 - typescript: 5.8.2 + typescript: 5.9.3 typescript@4.9.5: {} typescript@5.2.2: {} - typescript@5.8.2: {} + typescript@5.9.3: {} typical@4.0.0: {} @@ -20096,7 +20720,7 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 - underscore@1.12.1: {} + underscore@1.13.6: {} undici-types@7.10.0: {} @@ -20105,11 +20729,11 @@ snapshots: unicode-match-property-ecmascript@2.0.0: dependencies: unicode-canonical-property-names-ecmascript: 2.0.1 - unicode-property-aliases-ecmascript: 2.1.0 + unicode-property-aliases-ecmascript: 2.2.0 - unicode-match-property-value-ecmascript@2.2.0: {} + unicode-match-property-value-ecmascript@2.2.1: {} - unicode-property-aliases-ecmascript@2.1.0: {} + unicode-property-aliases-ecmascript@2.2.0: {} unique-string@2.0.0: dependencies: @@ -20125,29 +20749,35 @@ snapshots: unquote@1.1.1: {} - unrs-resolver@1.3.2: + unrs-resolver@1.11.1: + dependencies: + napi-postinstall: 0.3.4 optionalDependencies: - '@unrs/resolver-binding-darwin-arm64': 1.3.2 - '@unrs/resolver-binding-darwin-x64': 1.3.2 - '@unrs/resolver-binding-freebsd-x64': 1.3.2 - '@unrs/resolver-binding-linux-arm-gnueabihf': 1.3.2 - '@unrs/resolver-binding-linux-arm-musleabihf': 1.3.2 - '@unrs/resolver-binding-linux-arm64-gnu': 1.3.2 - '@unrs/resolver-binding-linux-arm64-musl': 1.3.2 - '@unrs/resolver-binding-linux-ppc64-gnu': 1.3.2 - '@unrs/resolver-binding-linux-s390x-gnu': 1.3.2 - '@unrs/resolver-binding-linux-x64-gnu': 1.3.2 - '@unrs/resolver-binding-linux-x64-musl': 1.3.2 - '@unrs/resolver-binding-wasm32-wasi': 1.3.2 - '@unrs/resolver-binding-win32-arm64-msvc': 1.3.2 - '@unrs/resolver-binding-win32-ia32-msvc': 1.3.2 - '@unrs/resolver-binding-win32-x64-msvc': 1.3.2 + '@unrs/resolver-binding-android-arm-eabi': 1.11.1 + '@unrs/resolver-binding-android-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-x64': 1.11.1 + '@unrs/resolver-binding-freebsd-x64': 1.11.1 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 + '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-musl': 1.11.1 + '@unrs/resolver-binding-wasm32-wasi': 1.11.1 + '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 + '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 + '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 upath@1.2.0: {} - update-browserslist-db@1.1.3(browserslist@4.24.4): + update-browserslist-db@1.2.3(browserslist@4.28.2): dependencies: - browserslist: 4.24.4 + browserslist: 4.28.2 escalade: 3.2.0 picocolors: 1.1.1 @@ -20160,7 +20790,7 @@ snapshots: querystringify: 2.2.0 requires-port: 1.0.0 - utf-8-validate@5.0.10: + utf-8-validate@6.0.6: dependencies: node-gyp-build: 4.8.4 optional: true @@ -20170,14 +20800,16 @@ snapshots: util.promisify@1.0.1: dependencies: define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 has-symbols: 1.1.0 - object.getownpropertydescriptors: 2.1.8 + object.getownpropertydescriptors: 2.1.9 utila@0.4.0: {} utils-merge@1.0.1: {} + uuid@11.1.0: {} + uuid@8.3.2: {} v8-compile-cache-lib@3.0.1: {} @@ -20186,7 +20818,7 @@ snapshots: dependencies: '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 1.9.0 - source-map: 0.7.4 + source-map: 0.7.6 validate-npm-package-license@3.0.4: dependencies: @@ -20195,13 +20827,13 @@ snapshots: vary@1.1.2: {} - vite-node@3.0.9(@types/node@24.3.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0): + vite-node@3.2.4(@types/node@24.3.0)(jiti@2.6.1)(terser@5.46.1): dependencies: cac: 6.7.14 - debug: 4.4.0 - es-module-lexer: 1.6.0 + debug: 4.4.3 + es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.2.3(@types/node@24.3.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) + vite: 7.3.2(@types/node@24.3.0)(jiti@2.6.1)(terser@5.46.1) transitivePeerDependencies: - '@types/node' - jiti @@ -20216,43 +20848,48 @@ snapshots: - tsx - yaml - vite@6.2.3(@types/node@24.3.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0): + vite@7.3.2(@types/node@24.3.0)(jiti@2.6.1)(terser@5.46.1): dependencies: - esbuild: 0.25.1 - postcss: 8.5.3 - rollup: 4.37.0 + esbuild: 0.27.7 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + postcss: 8.5.9 + rollup: 4.60.1 + tinyglobby: 0.2.16 optionalDependencies: '@types/node': 24.3.0 fsevents: 2.3.3 - jiti: 2.4.2 - terser: 5.39.0 - yaml: 2.7.0 - - vitest@3.0.9(@types/node@24.3.0)(jiti@2.4.2)(jsdom@16.7.0)(terser@5.39.0)(yaml@2.7.0): - dependencies: - '@vitest/expect': 3.0.9 - '@vitest/mocker': 3.0.9(vite@6.2.3(@types/node@24.3.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0)) - '@vitest/pretty-format': 3.0.9 - '@vitest/runner': 3.0.9 - '@vitest/snapshot': 3.0.9 - '@vitest/spy': 3.0.9 - '@vitest/utils': 3.0.9 - chai: 5.2.0 - debug: 4.4.0 - expect-type: 1.2.0 - magic-string: 0.30.17 + jiti: 2.6.1 + terser: 5.46.1 + + vitest@3.2.4(@types/node@24.3.0)(jiti@2.6.1)(jsdom@16.7.0(bufferutil@4.1.0))(terser@5.46.1): + dependencies: + '@types/chai': 5.2.3 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(vite@7.3.2(@types/node@24.3.0)(jiti@2.6.1)(terser@5.46.1)) + '@vitest/pretty-format': 3.2.4 + '@vitest/runner': 3.2.4 + '@vitest/snapshot': 3.2.4 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.3.3 + debug: 4.4.3 + expect-type: 1.3.0 + magic-string: 0.30.21 pathe: 2.0.3 - std-env: 3.8.1 + picomatch: 4.0.4 + std-env: 3.10.0 tinybench: 2.9.0 tinyexec: 0.3.2 - tinypool: 1.0.2 + tinyglobby: 0.2.16 + tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 6.2.3(@types/node@24.3.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) - vite-node: 3.0.9(@types/node@24.3.0)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0) + vite: 7.3.2(@types/node@24.3.0)(jiti@2.6.1)(terser@5.46.1) + vite-node: 3.2.4(@types/node@24.3.0)(jiti@2.6.1)(terser@5.46.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.3.0 - jsdom: 16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + jsdom: 16.7.0(bufferutil@4.1.0) transitivePeerDependencies: - jiti - less @@ -20287,7 +20924,7 @@ snapshots: dependencies: makeerror: 1.0.12 - watchpack@2.4.2: + watchpack@2.5.1: dependencies: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 @@ -20308,128 +20945,131 @@ snapshots: webidl-conversions@6.1.0: {} - webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3): + webpack-cli@6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1): dependencies: '@discoveryjs/json-ext': 0.6.3 - '@webpack-cli/configtest': 3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3))(webpack@5.101.3(webpack-cli@6.0.1)) - '@webpack-cli/info': 3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3))(webpack@5.101.3(webpack-cli@6.0.1)) - '@webpack-cli/serve': 3.0.1(webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3))(webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3))(webpack@5.101.3(webpack-cli@6.0.1)) + '@webpack-cli/configtest': 3.0.1(webpack-cli@6.0.1)(webpack@5.106.1) + '@webpack-cli/info': 3.0.1(webpack-cli@6.0.1)(webpack@5.106.1) + '@webpack-cli/serve': 3.0.1(webpack-cli@6.0.1)(webpack-dev-server@5.2.3)(webpack@5.106.1) colorette: 2.0.20 commander: 12.1.0 cross-spawn: 7.0.6 - envinfo: 7.14.0 + envinfo: 7.21.0 fastest-levenshtein: 1.0.16 import-local: 3.2.0 interpret: 3.1.1 rechoir: 0.8.0 - webpack: 5.101.3(webpack-cli@6.0.1) + webpack: 5.106.1(webpack-cli@6.0.1) webpack-merge: 6.0.1 optionalDependencies: - webpack-dev-server: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3) + webpack-dev-server: 5.2.3(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack-cli@6.0.1)(webpack@5.106.1) - webpack-dev-middleware@5.3.4(webpack@5.101.3): + webpack-dev-middleware@5.3.4(webpack@5.106.1): dependencies: colorette: 2.0.20 memfs: 3.5.3 mime-types: 2.1.35 range-parser: 1.2.1 - schema-utils: 4.3.0 - webpack: 5.101.3 + schema-utils: 4.3.3 + webpack: 5.106.1(webpack-cli@6.0.1) - webpack-dev-middleware@7.4.2(webpack@5.101.3(webpack-cli@6.0.1)): + webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.106.1): dependencies: colorette: 2.0.20 - memfs: 4.38.2 - mime-types: 2.1.35 + memfs: 4.57.1(tslib@2.8.1) + mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.2.1 - schema-utils: 4.3.0 + schema-utils: 4.3.3 optionalDependencies: - webpack: 5.101.3(webpack-cli@6.0.1) + webpack: 5.106.1(webpack-cli@6.0.1) + transitivePeerDependencies: + - tslib - webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.101.3): + webpack-dev-server@4.15.2(bufferutil@4.1.0)(webpack@5.106.1): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 - '@types/express': 4.17.21 + '@types/express': 4.17.25 '@types/serve-index': 1.9.4 - '@types/serve-static': 1.15.7 + '@types/serve-static': 1.15.10 '@types/sockjs': 0.3.36 - '@types/ws': 8.18.0 + '@types/ws': 8.18.1 ansi-html-community: 0.0.8 bonjour-service: 1.3.0 chokidar: 3.6.0 colorette: 2.0.20 - compression: 1.8.0 + compression: 1.8.1 connect-history-api-fallback: 2.0.0 default-gateway: 6.0.3 - express: 4.21.2 + express: 4.22.1 graceful-fs: 4.2.11 - html-entities: 2.5.3 - http-proxy-middleware: 2.0.7(@types/express@4.17.21) - ipaddr.js: 2.2.0 - launch-editor: 2.10.0 + html-entities: 2.6.0 + http-proxy-middleware: 2.0.9(@types/express@4.17.25) + ipaddr.js: 2.3.0 + launch-editor: 2.13.2 open: 8.4.2 p-retry: 4.6.2 rimraf: 3.0.2 - schema-utils: 4.3.0 + schema-utils: 4.3.3 selfsigned: 2.4.1 - serve-index: 1.9.1 + serve-index: 1.9.2 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 5.3.4(webpack@5.101.3) - ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + webpack-dev-middleware: 5.3.4(webpack@5.106.1) + ws: 8.20.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: - webpack: 5.101.3 + webpack: 5.106.1(webpack-cli@6.0.1) transitivePeerDependencies: - bufferutil - debug - supports-color - utf-8-validate - webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.101.3): + webpack-dev-server@5.2.3(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack-cli@6.0.1)(webpack@5.106.1): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 - '@types/express': 4.17.21 - '@types/express-serve-static-core': 4.19.6 + '@types/express': 4.17.25 + '@types/express-serve-static-core': 4.19.8 '@types/serve-index': 1.9.4 - '@types/serve-static': 1.15.7 + '@types/serve-static': 1.15.10 '@types/sockjs': 0.3.36 - '@types/ws': 8.18.0 + '@types/ws': 8.18.1 ansi-html-community: 0.0.8 bonjour-service: 1.3.0 chokidar: 3.6.0 colorette: 2.0.20 - compression: 1.8.0 + compression: 1.8.1 connect-history-api-fallback: 2.0.0 - express: 4.21.2 + express: 4.22.1 graceful-fs: 4.2.11 - http-proxy-middleware: 2.0.9(@types/express@4.17.21) - ipaddr.js: 2.2.0 - launch-editor: 2.10.0 + http-proxy-middleware: 2.0.9(@types/express@4.17.25) + ipaddr.js: 2.3.0 + launch-editor: 2.13.2 open: 10.2.0 p-retry: 6.2.1 - schema-utils: 4.3.0 - selfsigned: 2.4.1 - serve-index: 1.9.1 + schema-utils: 4.3.3 + selfsigned: 5.5.0 + serve-index: 1.9.2 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.2(webpack@5.101.3(webpack-cli@6.0.1)) - ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.106.1) + ws: 8.20.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: - webpack: 5.101.3(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3) + webpack: 5.106.1(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1) transitivePeerDependencies: - bufferutil - debug - supports-color + - tslib - utf-8-validate - webpack-manifest-plugin@4.1.1(webpack@5.101.3): + webpack-manifest-plugin@4.1.1(webpack@5.106.1): dependencies: - tapable: 2.2.1 - webpack: 5.101.3 + tapable: 2.3.2 + webpack: 5.106.1(webpack-cli@6.0.1) webpack-sources: 2.3.1 webpack-merge@6.0.1: @@ -20448,41 +21088,9 @@ snapshots: source-list-map: 2.0.1 source-map: 0.6.1 - webpack-sources@3.3.3: {} - - webpack@5.101.3: - dependencies: - '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/wasm-edit': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.15.0 - acorn-import-phases: 1.0.4(acorn@8.15.0) - browserslist: 4.24.4 - chrome-trace-event: 1.0.4 - enhanced-resolve: 5.18.1 - es-module-lexer: 1.6.0 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 4.3.2 - tapable: 2.2.1 - terser-webpack-plugin: 5.3.14(webpack@5.101.3) - watchpack: 2.4.2 - webpack-sources: 3.3.3 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js + webpack-sources@3.3.4: {} - webpack@5.101.3(webpack-cli@6.0.1): + webpack@5.106.1(webpack-cli@6.0.1): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -20490,27 +21098,27 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.15.0 - acorn-import-phases: 1.0.4(acorn@8.15.0) - browserslist: 4.24.4 + acorn: 8.16.0 + acorn-import-phases: 1.0.4(acorn@8.16.0) + browserslist: 4.28.2 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.18.1 - es-module-lexer: 1.6.0 + enhanced-resolve: 5.20.1 + es-module-lexer: 2.0.0 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 + loader-runner: 4.3.1 mime-types: 2.1.35 neo-async: 2.6.2 - schema-utils: 4.3.2 - tapable: 2.2.1 - terser-webpack-plugin: 5.3.14(webpack@5.101.3(webpack-cli@6.0.1)) - watchpack: 2.4.2 - webpack-sources: 3.3.3 + schema-utils: 4.3.3 + tapable: 2.3.2 + terser-webpack-plugin: 5.4.0(webpack@5.106.1) + watchpack: 2.5.1 + webpack-sources: 3.3.4 optionalDependencies: - webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.101.3) + webpack-cli: 6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1) transitivePeerDependencies: - '@swc/core' - esbuild @@ -20518,7 +21126,7 @@ snapshots: websocket-driver@0.7.4: dependencies: - http-parser-js: 0.5.9 + http-parser-js: 0.5.10 safe-buffer: 5.2.1 websocket-extensions: 0.1.4 @@ -20551,7 +21159,7 @@ snapshots: whatwg-url@8.7.0: dependencies: - lodash: 4.17.21 + lodash: 4.18.1 tr46: 2.1.0 webidl-conversions: 6.1.0 @@ -20571,13 +21179,13 @@ snapshots: is-async-function: 2.1.1 is-date-object: 1.1.0 is-finalizationregistry: 1.1.1 - is-generator-function: 1.1.0 + is-generator-function: 1.1.2 is-regex: 1.2.1 is-weakref: 1.1.1 isarray: 2.0.5 which-boxed-primitive: 1.1.1 which-collection: 1.0.2 - which-typed-array: 1.1.19 + which-typed-array: 1.1.20 which-collection@1.0.2: dependencies: @@ -20586,10 +21194,10 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.4 - which-typed-array@1.1.19: + which-typed-array@1.1.20: dependencies: available-typed-arrays: 1.0.7 - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 for-each: 0.3.5 get-proto: 1.0.1 @@ -20631,23 +21239,23 @@ snapshots: workbox-build@6.6.0(@types/babel__core@7.20.5): dependencies: - '@apideck/better-ajv-errors': 0.3.6(ajv@8.17.1) - '@babel/core': 7.26.10 - '@babel/preset-env': 7.26.9(@babel/core@7.26.10) - '@babel/runtime': 7.27.0 - '@rollup/plugin-babel': 5.3.1(@babel/core@7.26.10)(@types/babel__core@7.20.5)(rollup@2.79.2) - '@rollup/plugin-node-resolve': 11.2.1(rollup@2.79.2) - '@rollup/plugin-replace': 2.4.2(rollup@2.79.2) + '@apideck/better-ajv-errors': 0.3.7(ajv@8.18.0) + '@babel/core': 7.29.0 + '@babel/preset-env': 7.29.2(@babel/core@7.29.0) + '@babel/runtime': 7.29.2 + '@rollup/plugin-babel': 5.3.1(@babel/core@7.29.0)(@types/babel__core@7.20.5)(rollup@2.80.0) + '@rollup/plugin-node-resolve': 11.2.1(rollup@2.80.0) + '@rollup/plugin-replace': 2.4.2(rollup@2.80.0) '@surma/rollup-plugin-off-main-thread': 2.2.3 - ajv: 8.17.1 + ajv: 8.18.0 common-tags: 1.8.2 fast-json-stable-stringify: 2.1.0 fs-extra: 9.1.0 glob: 7.2.3 - lodash: 4.17.21 + lodash: 4.18.1 pretty-bytes: 5.6.0 - rollup: 2.79.2 - rollup-plugin-terser: 7.0.2(rollup@2.79.2) + rollup: 2.80.0 + rollup-plugin-terser: 7.0.2(rollup@2.80.0) source-map: 0.8.0-beta.0 stringify-object: 3.3.0 strip-comments: 2.0.1 @@ -20728,12 +21336,12 @@ snapshots: workbox-sw@6.6.0: {} - workbox-webpack-plugin@6.6.0(@types/babel__core@7.20.5)(webpack@5.101.3): + workbox-webpack-plugin@6.6.0(@types/babel__core@7.20.5)(webpack@5.106.1): dependencies: fast-json-stable-stringify: 2.1.0 pretty-bytes: 5.6.0 upath: 1.2.0 - webpack: 5.101.3 + webpack: 5.106.1(webpack-cli@6.0.1) webpack-sources: 1.4.3 workbox-build: 6.6.0(@types/babel__core@7.20.5) transitivePeerDependencies: @@ -20759,9 +21367,9 @@ snapshots: wrap-ansi@8.1.0: dependencies: - ansi-styles: 6.2.1 + ansi-styles: 6.2.3 string-width: 5.1.2 - strip-ansi: 7.1.0 + strip-ansi: 7.2.0 wrappy@1.0.2: {} @@ -20772,24 +21380,24 @@ snapshots: signal-exit: 3.0.7 typedarray-to-buffer: 3.1.5 - ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10): + ws@7.5.10(bufferutil@4.1.0)(utf-8-validate@6.0.6): optionalDependencies: - bufferutil: 4.0.9 - utf-8-validate: 5.0.10 + bufferutil: 4.1.0 + utf-8-validate: 6.0.6 - ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): + ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): optionalDependencies: - bufferutil: 4.0.9 - utf-8-validate: 5.0.10 + bufferutil: 4.1.0 + utf-8-validate: 6.0.6 - ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): + ws@8.20.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): optionalDependencies: - bufferutil: 4.0.9 - utf-8-validate: 5.0.10 + bufferutil: 4.1.0 + utf-8-validate: 6.0.6 wsl-utils@0.1.0: dependencies: - is-wsl: 3.1.0 + is-wsl: 3.1.1 xml-name-validator@3.0.0: {} @@ -20803,9 +21411,7 @@ snapshots: yallist@4.0.0: {} - yaml@1.10.2: {} - - yaml@2.7.0: {} + yaml@1.10.3: {} yargs-parser@20.2.9: {} @@ -20825,12 +21431,12 @@ snapshots: yup@0.32.11: dependencies: - '@babel/runtime': 7.27.0 - '@types/lodash': 4.17.16 - lodash: 4.17.21 - lodash-es: 4.17.21 + '@babel/runtime': 7.29.2 + '@types/lodash': 4.17.24 + lodash: 4.18.1 + lodash-es: 4.18.1 nanoclone: 0.2.1 property-expr: 2.0.6 toposort: 2.0.2 - zod@3.24.2: {} + zod@3.25.76: {} From 33ed630c9ad3634f2428911486a92dec1ba9ee3a Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 20 Jun 2025 10:26:28 -0400 Subject: [PATCH 064/303] Use local tarball for nucypher-contracts dependency for now, until we have an actual released package. --- .../nucypher-nucypher-contracts-0.25.0.tgz | Bin 0 -> 636417 bytes packages/shared/package.json | 2 +- pnpm-lock.yaml | 12 ++++++------ 3 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 packages/shared/nucypher-nucypher-contracts-0.25.0.tgz diff --git a/packages/shared/nucypher-nucypher-contracts-0.25.0.tgz b/packages/shared/nucypher-nucypher-contracts-0.25.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..5de0157b78b1ca8ccb701a9675500133aa794717 GIT binary patch literal 636417 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

(S*>;(i6$C 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%0DL)d0(F6h#jnze9HcU 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 |hTf=Me%#B&2-1z#C0I5g$#lzU7ZbAW>u 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 z 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 W0p0_?`o{p@0TIp=Za^zBK>rVXObU(w literal 0 HcmV?d00001 diff --git a/packages/shared/package.json b/packages/shared/package.json index 09d1e5686..56b6dd2c3 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -42,7 +42,7 @@ "dependencies": { "@ethersproject/abi": "^5.8.0", "@ethersproject/providers": "^5.8.0", - "@nucypher/nucypher-contracts": "git+https://github.com/nucypher/nucypher-contracts.git#signing", + "@nucypher/nucypher-contracts": "file:nucypher-nucypher-contracts-0.25.0.tgz", "@nucypher/nucypher-core": "^0.14.5", "axios": "^1.11.0", "deep-equal": "^2.2.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 08bb44467..3facfa5f7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -513,8 +513,8 @@ importers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@nucypher/nucypher-contracts': - specifier: git+https://github.com/nucypher/nucypher-contracts.git#signing - version: https://codeload.github.com/nucypher/nucypher-contracts/tar.gz/7a7bf2207436688d5835d54bdf71f51ce527907f + specifier: file:nucypher-nucypher-contracts-0.25.0.tgz + version: file:packages/shared/nucypher-nucypher-contracts-0.25.0.tgz '@nucypher/nucypher-core': specifier: ^0.14.5 version: 0.14.5 @@ -2707,9 +2707,9 @@ packages: '@nucypher/nucypher-contracts@0.25.0': resolution: {integrity: sha512-4fRPKY6RzkXY1Zv2O0auJZsvP6z7tuj+Fsy83yJvADqFwRuIJfSlwgSgLwISX6q838SRG/Ve2i+sMLZRaVJfYw==} - '@nucypher/nucypher-contracts@https://codeload.github.com/nucypher/nucypher-contracts/tar.gz/7a7bf2207436688d5835d54bdf71f51ce527907f': - resolution: {tarball: https://codeload.github.com/nucypher/nucypher-contracts/tar.gz/7a7bf2207436688d5835d54bdf71f51ce527907f} - version: 0.26.0-alpha.3 + '@nucypher/nucypher-contracts@file:packages/shared/nucypher-nucypher-contracts-0.25.0.tgz': + resolution: {integrity: sha512-bFRzG7Xu/azdpGTHErv+qNZx9Zw9nVrt2uPuFjDMTpnyIq3IYMd9EhJbQVh3lzbabykCJsM+969CgvoSKRI24Q==, tarball: file:packages/shared/nucypher-nucypher-contracts-0.25.0.tgz} + version: 0.25.0 '@nucypher/nucypher-core@0.14.5': resolution: {integrity: sha512-Q3kBuJL0qtTtnxrM5DEQauQUvDlXmwubm9u1h7gbyLhs+aZNC9WDyjEUbE43+uahlHu4k1hKEMxD1gjV165ChA==} @@ -12482,7 +12482,7 @@ snapshots: '@nucypher/nucypher-contracts@0.25.0': {} - '@nucypher/nucypher-contracts@https://codeload.github.com/nucypher/nucypher-contracts/tar.gz/7a7bf2207436688d5835d54bdf71f51ce527907f': {} + '@nucypher/nucypher-contracts@file:packages/shared/nucypher-nucypher-contracts-0.25.0.tgz': {} '@nucypher/nucypher-core@0.14.5': {} From 9d17e76088de3d5e72dd47cb9658d44f3a49adb5 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 23 Jun 2025 11:00:56 +0200 Subject: [PATCH 065/303] =?UTF-8?q?=F0=9F=90=9B=20fix(porter):=20send=20si?= =?UTF-8?q?gning=20request=20data=20in=20body=20instead=20of=20query=20par?= =?UTF-8?q?ams?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - change signUserOp method to use 'data' instead of 'params' for POST request - aligns with other Porter methods that send data in request body - fixes 400 Bad Request error when signing user operations --- packages/shared/src/porter.ts | 4 ++-- packages/taco/src/sign.ts | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index 1a85d2da6..4c372b0b4 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -321,7 +321,7 @@ export class PorterClient { console.log({ options}) - const params: Record = { + const data: Record = { signing_requests: signingRequests, threshold: threshold }; @@ -329,7 +329,7 @@ export class PorterClient { const resp: AxiosResponse = await this.tryAndCall({ url: '/sign', method: 'post', - params, + data, }); const signingResults: { [ursulaAddress: string]: [string, string] } = {}; diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 1789ff977..e32fb7661 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -47,7 +47,10 @@ export async function signUserOp( }; const signingRequests: Record = Object.fromEntries( - signers.map((signer) => [signer.operator, JSON.stringify(signingRequest)]), + signers.map((signer) => [ + signer.operator, + btoa(JSON.stringify(signingRequest)) + ]), ); // Build signing request for the user operation From 4ec70bf8028bc5638d53b0adaf584be4d0b53446 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 23 Jun 2025 15:08:16 +0200 Subject: [PATCH 066/303] =?UTF-8?q?=E2=9C=85=20test:=20update=20signing=20?= =?UTF-8?q?tests=20to=20expect=20base64-encoded=20requests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - update test expectations to match new base64-encoded signing request format - tests now expect btoa(JSON.stringify(...)) instead of JSON.stringify(...) --- packages/taco/test/taco-sign.test.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index 91d18a7a8..20e5eaff8 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -70,20 +70,20 @@ describe('TACo Signing', () => { expect(signUserOpMock).toHaveBeenCalledWith( { - '0x1234': JSON.stringify({ + '0x1234': btoa(JSON.stringify({ userOp, cohortId, chainId, aaVersion, context: undefined - }), - '0xabcd': JSON.stringify({ + })), + '0xabcd': btoa(JSON.stringify({ userOp, cohortId, chainId, aaVersion, context: undefined - }) + })) }, 2, { optimistic: true, returnAggregated: true } @@ -131,20 +131,20 @@ describe('TACo Signing', () => { expect(signUserOpMock).toHaveBeenCalledWith( { - '0x1234': JSON.stringify({ + '0x1234': btoa(JSON.stringify({ userOp, cohortId, chainId, aaVersion, context: undefined - }), - '0xabcd': JSON.stringify({ + })), + '0xabcd': btoa(JSON.stringify({ userOp, cohortId, chainId, aaVersion, context: undefined - }) + })) }, 2, options From 57d6109f70e4e92014a5b81a8455a6c015dbdf97 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 23 Jun 2025 18:24:49 +0200 Subject: [PATCH 067/303] =?UTF-8?q?=F0=9F=94=A7=20refactor:=20match=20Pyth?= =?UTF-8?q?on=20signing=20request=20format?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - change signing request structure to match Python implementation - use snake_case field names (cohort_id, chain_id, signature_type) - serialize userOp as 'data' field instead of direct embedding - update tests to match new request format --- packages/taco/src/sign.ts | 8 +++---- packages/taco/test/taco-sign.test.ts | 32 ++++++++++++++-------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index e32fb7661..2d6e18d3c 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -39,10 +39,10 @@ export async function signUserOp( ); const signingRequest = { - userOp, - cohortId, - chainId, - aaVersion, + data: JSON.stringify(userOp), + cohort_id: cohortId, + chain_id: chainId, + signature_type: aaVersion, context, }; diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index 20e5eaff8..b73014d38 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -71,17 +71,17 @@ describe('TACo Signing', () => { expect(signUserOpMock).toHaveBeenCalledWith( { '0x1234': btoa(JSON.stringify({ - userOp, - cohortId, - chainId, - aaVersion, + data: JSON.stringify(userOp), + cohort_id: cohortId, + chain_id: chainId, + signature_type: aaVersion, context: undefined })), '0xabcd': btoa(JSON.stringify({ - userOp, - cohortId, - chainId, - aaVersion, + data: JSON.stringify(userOp), + cohort_id: cohortId, + chain_id: chainId, + signature_type: aaVersion, context: undefined })) }, @@ -132,17 +132,17 @@ describe('TACo Signing', () => { expect(signUserOpMock).toHaveBeenCalledWith( { '0x1234': btoa(JSON.stringify({ - userOp, - cohortId, - chainId, - aaVersion, + data: JSON.stringify(userOp), + cohort_id: cohortId, + chain_id: chainId, + signature_type: aaVersion, context: undefined })), '0xabcd': btoa(JSON.stringify({ - userOp, - cohortId, - chainId, - aaVersion, + data: JSON.stringify(userOp), + cohort_id: cohortId, + chain_id: chainId, + signature_type: aaVersion, context: undefined })) }, From f746fe7b7b1c23e1f2974d85e2f136249c30627e Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 24 Jun 2025 11:33:42 +0200 Subject: [PATCH 068/303] Fix TACo signing request format for Porter API - Use sorted JSON keys for user operations to match Python implementation - Update signing request structure with proper field names - Add error logging for debugging Porter API responses - Update tests to match new request format --- packages/shared/src/porter.ts | 12 ++++++-- packages/taco/integration-test/sign.test.ts | 32 ++++++++++++++------- packages/taco/src/sign.ts | 10 +++++-- packages/taco/test/taco-sign.test.ts | 32 +++++++++++++-------- 4 files changed, 58 insertions(+), 28 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index 4c372b0b4..947b096e4 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -202,7 +202,15 @@ export class PorterClient { if (resp.status === HttpStatusCode.Ok) { return resp; } - } catch (e) { + } catch (e: any) { + console.error('Porter request failed:', { + url: porterUrl.toString(), + method: config.method, + status: e.response?.status, + statusText: e.response?.statusText, + data: e.response?.data, + requestData: config.data + }); lastError = e; continue; } @@ -314,7 +322,7 @@ export class PorterClient { public async signUserOp( - signingRequests: Record, + signingRequests: Record, threshold: number, options: SigningOptions = { optimistic: true, returnAggregated: true }, ): Promise { diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index 7cf4438f8..43423a969 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -56,17 +56,27 @@ describe.skipIf(!process.env.RUNNING_IN_CI)('Taco Sign Integration Test', () => const porterUris = await getPorterUris(DOMAIN as Domain); // Sign user operation - const signResult = await signUserOp( - provider, - DOMAIN as Domain, - RITUAL_ID, - CHAIN_ID, - userOp, - '0.8.0', - { optimistic: true, returnAggregated: true }, - undefined, - porterUris - ); + try { + const signResult = await signUserOp( + provider, + DOMAIN as Domain, + RITUAL_ID, + CHAIN_ID, + userOp, + '0.8.0', + { optimistic: true, returnAggregated: true }, + undefined, + porterUris + ); + } catch (error: any) { + console.error('Detailed error info:', { + status: error.response?.status, + statusText: error.response?.statusText, + data: error.response?.data, + message: error.message + }); + throw error; + } // Verify sign result expect(signResult).toBeDefined(); diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 2d6e18d3c..32821873a 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -38,12 +38,16 @@ export async function signUserOp( cohortId, ); - const signingRequest = { - data: JSON.stringify(userOp), + // Convert UserOperation to sorted JSON string (matching Python: json.dumps(self.to_dict(), sort_keys=True)) + const userOpString = JSON.stringify(userOp, Object.keys(userOp).sort()); + + const signingRequest: any = { + user_op: userOpString, + aa_version: aaVersion, cohort_id: cohortId, chain_id: chainId, + context: context || {}, signature_type: aaVersion, - context, }; const signingRequests: Record = Object.fromEntries( diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index b73014d38..71451089b 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -68,21 +68,25 @@ describe('TACo Signing', () => { porterUris ); + const expectedUserOpString = JSON.stringify(userOp, Object.keys(userOp).sort()); + expect(signUserOpMock).toHaveBeenCalledWith( { '0x1234': btoa(JSON.stringify({ - data: JSON.stringify(userOp), + user_op: expectedUserOpString, + aa_version: aaVersion, cohort_id: cohortId, chain_id: chainId, - signature_type: aaVersion, - context: undefined + context: {}, + signature_type: aaVersion })), '0xabcd': btoa(JSON.stringify({ - data: JSON.stringify(userOp), + user_op: expectedUserOpString, + aa_version: aaVersion, cohort_id: cohortId, chain_id: chainId, - signature_type: aaVersion, - context: undefined + context: {}, + signature_type: aaVersion })) }, 2, @@ -129,21 +133,25 @@ describe('TACo Signing', () => { porterUris ); + const expectedUserOpString2 = JSON.stringify(userOp, Object.keys(userOp).sort()); + expect(signUserOpMock).toHaveBeenCalledWith( { '0x1234': btoa(JSON.stringify({ - data: JSON.stringify(userOp), + user_op: expectedUserOpString2, + aa_version: aaVersion, cohort_id: cohortId, chain_id: chainId, - signature_type: aaVersion, - context: undefined + context: {}, + signature_type: aaVersion })), '0xabcd': btoa(JSON.stringify({ - data: JSON.stringify(userOp), + user_op: expectedUserOpString2, + aa_version: aaVersion, cohort_id: cohortId, chain_id: chainId, - signature_type: aaVersion, - context: undefined + context: {}, + signature_type: aaVersion })) }, 2, From ecffc29a79b2fe33efa40b10e5cf62d416302186 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 24 Jun 2025 14:32:53 +0200 Subject: [PATCH 069/303] Move UserOperation types and signing utilities to shared package - Add UserOperation type, UserOperationSignatureRequest class, and convertUserOperationToPython utility to shared/src/types.ts - Export new types and classes in shared/src/index.ts - Update taco/src/types.ts to re-export UserOperation from shared package - Eliminates duplication of UserOperation type definitions across packages --- packages/shared/src/index.ts | 1 + packages/shared/src/types.ts | 61 ++++++++++++++++++++++++++++++++++++ packages/taco/src/types.ts | 21 ++----------- 3 files changed, 64 insertions(+), 19 deletions(-) diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 526d9cc5b..7ef65aa23 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -2,6 +2,7 @@ export * from './contracts'; export * from './porter'; export * from './schemas'; export type * from './types'; +export * from './types'; export * from './utils'; export * from './web3'; diff --git a/packages/shared/src/types.ts b/packages/shared/src/types.ts index 02603b3c2..e8b9b9c8a 100644 --- a/packages/shared/src/types.ts +++ b/packages/shared/src/types.ts @@ -1,3 +1,64 @@ export type ChecksumAddress = `0x${string}`; export type HexEncodedBytes = string; export type Base64EncodedBytes = string; + +export type UserOperation = { + sender: string; + nonce: string; + factory: string; + factoryData: string; + callData: string; + callGasLimit: string; + verificationGasLimit: string; + preVerificationGas: string; + maxFeePerGas: string; + maxPriorityFeePerGas: string; + paymaster: string; + paymasterVerificationGasLimit: string; + paymasterPostOpGasLimit: string; + paymasterData: string; + signature: string; +}; + +export class UserOperationSignatureRequest { + constructor( + private userOpString: string, + private aaVersion: string, + private cohortId: number, + private chainId: number, + private context: unknown = {}, + private signatureType: string = "userOp" + ) {} + + toBytes(): Uint8Array { + const data = { + user_op: this.userOpString, + aa_version: this.aaVersion, + cohort_id: this.cohortId, + chain_id: this.chainId, + context: this.context, + signature_type: this.signatureType, + }; + return new TextEncoder().encode(JSON.stringify(data)); + } +} + +export function convertUserOperationToPython(userOp: UserOperation) { + return { + sender: userOp.sender, + nonce: parseInt(userOp.nonce, 16) || 0, + factory: userOp.factory === '0x' ? null : userOp.factory, + factory_data: userOp.factoryData, + call_data: userOp.callData, + call_gas_limit: parseInt(userOp.callGasLimit, 16) || 0, + verification_gas_limit: parseInt(userOp.verificationGasLimit, 16) || 0, + pre_verification_gas: parseInt(userOp.preVerificationGas, 16) || 0, + max_fee_per_gas: parseInt(userOp.maxFeePerGas, 16) || 0, + max_priority_fee_per_gas: parseInt(userOp.maxPriorityFeePerGas, 16) || 0, + paymaster: userOp.paymaster === '0x' ? null : userOp.paymaster, + paymaster_verification_gas_limit: parseInt(userOp.paymasterVerificationGasLimit, 16) || 0, + paymaster_post_op_gas_limit: parseInt(userOp.paymasterPostOpGasLimit, 16) || 0, + paymaster_data: userOp.paymasterData, + signature: userOp.signature, + }; +} diff --git a/packages/taco/src/types.ts b/packages/taco/src/types.ts index 388a3eb1c..8871cc860 100644 --- a/packages/taco/src/types.ts +++ b/packages/taco/src/types.ts @@ -4,22 +4,5 @@ export { Context as CoreContext, } from '@nucypher/nucypher-core'; -// Note: SignResult and SigningOptions are now imported from @nucypher/shared to avoid duplication - -export type UserOperation = { - sender: string; // The Account making the UserOperation - nonce: string; // Anti-replay parameter - factory: string; // Account Factory for new Accounts OR 0x7702 flag for EIP-7702 Accounts, otherwise address(0) - factoryData: string; // data for the Account Factory if factory is provided OR EIP-7702 initialization data, or empty array - callData: string; // The data to pass to the sender during the main execution call - callGasLimit: string; // The amount of gas to allocate the main execution call - verificationGasLimit: string; // The amount of gas to allocate for the verification step - preVerificationGas: string; // Extra gas to pay the bundler - maxFeePerGas: string; // Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) - maxPriorityFeePerGas: string; // Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) - paymaster: string; // Address of paymaster contract, (or empty, if the sender pays for gas by itself) - paymasterVerificationGasLimit: string; // The amount of gas to allocate for the paymaster validation code (only if paymaster exists) - paymasterPostOpGasLimit: string; // The amount of gas to allocate for the paymaster post-operation code (only if paymaster exists) - paymasterData: string; // Data for paymaster (only if paymaster exists) - signature: string; // Data passed into the sender to verify authorization -}; +// Re-export UserOperation from shared package to avoid duplication +export type { UserOperation } from '@nucypher/shared'; From aa12b3d9da597680c11369d39b82ca83f84a510a Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 24 Jun 2025 14:33:09 +0200 Subject: [PATCH 070/303] Implement clean UserOperation signing with shared utilities - Fix Porter client to use POST data instead of query params for /sign endpoint - Fix SigningCoordinator.getThreshold() to use signingCohorts(cohortId).threshold - Update signUserOp() to use shared conversion utilities and proper base64 encoding - Update tests to use shared conversion function and correct signature_type 'userOp' - Remove console.log statements and simplify integration test - All functionality now uses centralized types from shared package --- .../contracts/agents/signingCoordinator.ts | 3 +- .../ethers-typechain/SigningCoordinator.ts | 35 ------------------ .../factories/SigningCoordinator__factory.ts | 19 ---------- packages/shared/src/porter.ts | 23 +++++++----- packages/shared/src/types.ts | 2 +- packages/taco/integration-test/sign.test.ts | 37 +++++++------------ packages/taco/src/sign.ts | 29 ++++++++------- packages/taco/test/taco-sign.test.ts | 16 ++++---- 8 files changed, 54 insertions(+), 110 deletions(-) diff --git a/packages/shared/src/contracts/agents/signingCoordinator.ts b/packages/shared/src/contracts/agents/signingCoordinator.ts index 89ae7dadb..952898cc3 100644 --- a/packages/shared/src/contracts/agents/signingCoordinator.ts +++ b/packages/shared/src/contracts/agents/signingCoordinator.ts @@ -35,7 +35,8 @@ export class SigningCoordinatorAgent { cohortId: number, ): Promise { const coordinator = await this.connectReadOnly(provider, domain); - return await coordinator.getThreshold(cohortId); + const cohort = await coordinator.signingCohorts(cohortId); + return cohort.threshold; } private static async connectReadOnly( diff --git a/packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts b/packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts index 88b784c1f..549518b1d 100644 --- a/packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts +++ b/packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts @@ -57,7 +57,6 @@ export interface SigningCoordinatorInterface extends utils.Interface { 'getCondition(uint32,uint256)': FunctionFragment; 'getRoleAdmin(bytes32)': FunctionFragment; 'getSigner(uint32,address)': FunctionFragment; - 'getThreshold(uint32)': FunctionFragment; 'getSigners(uint32)': FunctionFragment; 'getSigningCohortConditions(uint32,uint256)': FunctionFragment; 'getSigningCohortDataHash(uint32)': FunctionFragment; @@ -105,7 +104,6 @@ export interface SigningCoordinatorInterface extends utils.Interface { | 'getCondition' | 'getRoleAdmin' | 'getSigner' - | 'getThreshold' | 'getSigners' | 'getSigningCohortConditions' | 'getSigningCohortDataHash' @@ -196,10 +194,6 @@ export interface SigningCoordinatorInterface extends utils.Interface { functionFragment: 'getSigner', values: [BigNumberish, string], ): string; - encodeFunctionData( - functionFragment: 'getThreshold', - values: [BigNumberish], - ): string; encodeFunctionData( functionFragment: 'getSigners', values: [BigNumberish], @@ -361,10 +355,6 @@ export interface SigningCoordinatorInterface extends utils.Interface { data: BytesLike, ): Result; decodeFunctionResult(functionFragment: 'getSigner', data: BytesLike): Result; - decodeFunctionResult( - functionFragment: 'getThreshold', - data: BytesLike, - ): Result; decodeFunctionResult(functionFragment: 'getSigners', data: BytesLike): Result; decodeFunctionResult( functionFragment: 'getSigningCohortConditions', @@ -751,11 +741,6 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise<[SigningCoordinator.SigningCohortParticipantStructOutput]>; - getThreshold( - cohortId: BigNumberish, - overrides?: CallOverrides, - ): Promise<[number]>; - getSigners( cohortId: BigNumberish, overrides?: CallOverrides, @@ -960,11 +945,6 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise; - getThreshold( - cohortId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - getSigners( cohortId: BigNumberish, overrides?: CallOverrides, @@ -1165,11 +1145,6 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise; - getThreshold( - cohortId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - getSigners( cohortId: BigNumberish, overrides?: CallOverrides, @@ -1508,11 +1483,6 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise; - getThreshold( - cohortId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - getSigners( cohortId: BigNumberish, overrides?: CallOverrides, @@ -1711,11 +1681,6 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise; - getThreshold( - cohortId: BigNumberish, - overrides?: CallOverrides, - ): Promise; - getSigners( cohortId: BigNumberish, overrides?: CallOverrides, diff --git a/packages/shared/src/contracts/ethers-typechain/factories/SigningCoordinator__factory.ts b/packages/shared/src/contracts/ethers-typechain/factories/SigningCoordinator__factory.ts index f0546ac66..31fb08fbc 100644 --- a/packages/shared/src/contracts/ethers-typechain/factories/SigningCoordinator__factory.ts +++ b/packages/shared/src/contracts/ethers-typechain/factories/SigningCoordinator__factory.ts @@ -656,25 +656,6 @@ const _abi = [ }, ], }, - { - type: 'function', - name: 'getThreshold', - stateMutability: 'view', - inputs: [ - { - name: 'cohortId', - type: 'uint32', - internalType: 'uint32', - }, - ], - outputs: [ - { - name: '', - type: 'uint16', - internalType: 'uint16', - }, - ], - }, { type: 'function', name: 'getSigners', diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index 947b096e4..febb4ab9b 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -202,15 +202,20 @@ export class PorterClient { if (resp.status === HttpStatusCode.Ok) { return resp; } - } catch (e: any) { - console.error('Porter request failed:', { + } catch (e: unknown) { + const errorDetails: Record = { url: porterUrl.toString(), method: config.method, - status: e.response?.status, - statusText: e.response?.statusText, - data: e.response?.data, requestData: config.data - }); + }; + + if (axios.isAxiosError(e)) { + errorDetails.status = e.response?.status; + errorDetails.statusText = e.response?.statusText; + errorDetails.data = e.response?.data; + } + + console.error('Porter request failed:', errorDetails); lastError = e; continue; } @@ -324,11 +329,9 @@ export class PorterClient { public async signUserOp( signingRequests: Record, threshold: number, - options: SigningOptions = { optimistic: true, returnAggregated: true }, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _options: SigningOptions = { optimistic: true, returnAggregated: true }, ): Promise { - - console.log({ options}) - const data: Record = { signing_requests: signingRequests, threshold: threshold diff --git a/packages/shared/src/types.ts b/packages/shared/src/types.ts index e8b9b9c8a..4a97bc881 100644 --- a/packages/shared/src/types.ts +++ b/packages/shared/src/types.ts @@ -27,7 +27,7 @@ export class UserOperationSignatureRequest { private cohortId: number, private chainId: number, private context: unknown = {}, - private signatureType: string = "userOp" + private signatureType: string = "userop" ) {} toBytes(): Uint8Array { diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index 43423a969..9fb9278e6 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -1,10 +1,9 @@ -import { Domain, getPorterUris } from '@nucypher/shared'; +import { Domain, getPorterUris, UserOperation } from '@nucypher/shared'; import { ethers } from 'ethers'; import { beforeAll, describe, expect, test } from 'vitest'; import { initialize } from '../src'; import { signUserOp } from '../src/sign'; -import { UserOperation } from '../src/types'; const RPC_PROVIDER_URL = 'https://ethereum-sepolia-rpc.publicnode.com'; const SIGNER_PRIVATE_KEY = '0x900edb9e8214b2353f82aa195e915128f419a92cfb8bbc0f4784f10ef4112b86'; @@ -56,27 +55,17 @@ describe.skipIf(!process.env.RUNNING_IN_CI)('Taco Sign Integration Test', () => const porterUris = await getPorterUris(DOMAIN as Domain); // Sign user operation - try { - const signResult = await signUserOp( - provider, - DOMAIN as Domain, - RITUAL_ID, - CHAIN_ID, - userOp, - '0.8.0', - { optimistic: true, returnAggregated: true }, - undefined, - porterUris - ); - } catch (error: any) { - console.error('Detailed error info:', { - status: error.response?.status, - statusText: error.response?.statusText, - data: error.response?.data, - message: error.message - }); - throw error; - } + const signResult = await signUserOp( + provider, + DOMAIN as Domain, + RITUAL_ID, + CHAIN_ID, + userOp, + '0.8.0', + { optimistic: true, returnAggregated: true }, + undefined, + porterUris + ); // Verify sign result expect(signResult).toBeDefined(); @@ -84,5 +73,5 @@ describe.skipIf(!process.env.RUNNING_IN_CI)('Taco Sign Integration Test', () => expect(signResult.aggregatedSignature).toBeDefined(); expect(signResult.signingResults).toBeDefined(); expect(Object.keys(signResult.signingResults).length).toBeGreaterThan(0); - }, 15000); + }, 150000); }); \ No newline at end of file diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 32821873a..fa05b04bb 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -1,15 +1,18 @@ import { + convertUserOperationToPython, Domain, getPorterUris, PorterClient, SigningCoordinatorAgent, SigningOptions, SignResult, + toBase64, + UserOperation, + UserOperationSignatureRequest, } from '@nucypher/shared'; import { ethers } from 'ethers'; import { ConditionContext } from './conditions/context'; -import { UserOperation } from './types'; export async function signUserOp( provider: ethers.providers.Provider, @@ -17,7 +20,7 @@ export async function signUserOp( cohortId: number, chainId: number, userOp: UserOperation, - aaVersion: 'mdt' | '0.8.0' | string, + aaVersion: '0.8.0' | string, options: SigningOptions = { optimistic: true, returnAggregated: true }, context?: ConditionContext, porterUris?: string[], @@ -38,22 +41,22 @@ export async function signUserOp( cohortId, ); - // Convert UserOperation to sorted JSON string (matching Python: json.dumps(self.to_dict(), sort_keys=True)) - const userOpString = JSON.stringify(userOp, Object.keys(userOp).sort()); + const pythonUserOp = convertUserOperationToPython(userOp); + const userOpString = JSON.stringify(pythonUserOp, Object.keys(pythonUserOp).sort()); - const signingRequest: any = { - user_op: userOpString, - aa_version: aaVersion, - cohort_id: cohortId, - chain_id: chainId, - context: context || {}, - signature_type: aaVersion, - }; + const signingRequest = new UserOperationSignatureRequest( + userOpString, + aaVersion, + cohortId, + chainId, + context || {}, + "userop" + ); const signingRequests: Record = Object.fromEntries( signers.map((signer) => [ signer.operator, - btoa(JSON.stringify(signingRequest)) + toBase64(signingRequest.toBytes()) ]), ); diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index 71451089b..139323a1f 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -1,4 +1,4 @@ -import { PorterClient, SigningCoordinatorAgent } from '@nucypher/shared'; +import { convertUserOperationToPython, PorterClient, SigningCoordinatorAgent } from '@nucypher/shared'; import { fakePorterUri } from '@nucypher/test-utils'; import { ethers } from 'ethers'; import { beforeEach, describe, expect, it, vi } from 'vitest'; @@ -68,7 +68,8 @@ describe('TACo Signing', () => { porterUris ); - const expectedUserOpString = JSON.stringify(userOp, Object.keys(userOp).sort()); + const pythonUserOp = convertUserOperationToPython(userOp); + const expectedUserOpString = JSON.stringify(pythonUserOp, Object.keys(pythonUserOp).sort()); expect(signUserOpMock).toHaveBeenCalledWith( { @@ -78,7 +79,7 @@ describe('TACo Signing', () => { cohort_id: cohortId, chain_id: chainId, context: {}, - signature_type: aaVersion + signature_type: "userop" })), '0xabcd': btoa(JSON.stringify({ user_op: expectedUserOpString, @@ -86,7 +87,7 @@ describe('TACo Signing', () => { cohort_id: cohortId, chain_id: chainId, context: {}, - signature_type: aaVersion + signature_type: "userop" })) }, 2, @@ -133,7 +134,8 @@ describe('TACo Signing', () => { porterUris ); - const expectedUserOpString2 = JSON.stringify(userOp, Object.keys(userOp).sort()); + const pythonUserOp2 = convertUserOperationToPython(userOp); + const expectedUserOpString2 = JSON.stringify(pythonUserOp2, Object.keys(pythonUserOp2).sort()); expect(signUserOpMock).toHaveBeenCalledWith( { @@ -143,7 +145,7 @@ describe('TACo Signing', () => { cohort_id: cohortId, chain_id: chainId, context: {}, - signature_type: aaVersion + signature_type: "userop" })), '0xabcd': btoa(JSON.stringify({ user_op: expectedUserOpString2, @@ -151,7 +153,7 @@ describe('TACo Signing', () => { cohort_id: cohortId, chain_id: chainId, context: {}, - signature_type: aaVersion + signature_type: "userop" })) }, 2, From e8ed6d38717484fff1aee68fb300f314e35ba677 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 25 Jun 2025 12:55:40 +0200 Subject: [PATCH 071/303] Update TACo signing implementation with improved error handling - Updated SignResponse type to match new API response format with separated signatures and errors - Enhanced PorterClient.sign() with better error handling and response structure validation - Added debug logging to signing integration test - Fixed signer key mapping from operator to provider in signUserOp - Removed debug code for porter ursulas endpoint --- packages/shared/src/porter.ts | 61 ++++++++++++++------- packages/taco/integration-test/sign.test.ts | 1 + packages/taco/src/sign.ts | 4 +- 3 files changed, 46 insertions(+), 20 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index febb4ab9b..0426880ec 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -160,8 +160,10 @@ export type SigningOptions = { type SignResponse = { readonly result: { - readonly digest: HexEncodedBytes; - readonly signing_results: Record; + readonly signing_results: { + readonly signatures: Record; + readonly errors: Record; + }; }; }; @@ -337,28 +339,49 @@ export class PorterClient { threshold: threshold }; - const resp: AxiosResponse = await this.tryAndCall({ - url: '/sign', - method: 'post', - data, - }); + let resp: AxiosResponse; + try { + resp = await this.tryAndCall({ + url: '/sign', + method: 'post', + data, + }); + } catch (error) { + console.error('Error in tryAndCall:', error); + throw error; + } + const signingResults: { [ursulaAddress: string]: [string, string] } = {}; const errors: Record = {}; let messageHash = ''; - for (const [ursulaAddress, [signerAddress, signatureB64]] of Object.entries( - resp.data.result.signing_results - )) { - try { - const decodedData = JSON.parse( - new TextDecoder().decode(fromBase64(signatureB64)) - ); - messageHash = decodedData.message_hash; - signingResults[ursulaAddress] = [signerAddress, decodedData.signature]; - } catch (e: unknown) { - const errorMessage = e instanceof Error ? e.message : 'Unknown error'; - errors[ursulaAddress] = `Failed to decode signature: ${errorMessage}`; + // Check if signing_results exists and has the expected structure + const signingResultsData = resp.data.result.signing_results; + if (!signingResultsData || typeof signingResultsData !== 'object') { + throw new Error(`Invalid signing_results in response: ${JSON.stringify(resp.data.result)}`); + } + + // Copy errors from the response + if (signingResultsData.errors) { + Object.assign(errors, signingResultsData.errors); + } + + // Process signatures + if (signingResultsData.signatures) { + for (const [ursulaAddress, [signerAddress, signatureB64]] of Object.entries( + signingResultsData.signatures + )) { + try { + const decodedData = JSON.parse( + new TextDecoder().decode(fromBase64(signatureB64)) + ); + messageHash = decodedData.message_hash; + signingResults[ursulaAddress] = [signerAddress, decodedData.signature]; + } catch (e: unknown) { + const errorMessage = e instanceof Error ? e.message : 'Unknown error'; + errors[ursulaAddress] = `Failed to decode signature: ${errorMessage}`; + } } } diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index 9fb9278e6..7f928f185 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -66,6 +66,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)('Taco Sign Integration Test', () => undefined, porterUris ); + console.log('Sign result:', signResult); // Verify sign result expect(signResult).toBeDefined(); diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index fa05b04bb..19c8c1a48 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -35,6 +35,8 @@ export async function signUserOp( domain, cohortId, ); + console.log({ signers }); + const threshold = await SigningCoordinatorAgent.getThreshold( provider, domain, @@ -55,7 +57,7 @@ export async function signUserOp( const signingRequests: Record = Object.fromEntries( signers.map((signer) => [ - signer.operator, + signer.provider, toBase64(signingRequest.toBytes()) ]), ); From b7b7a8bd2ba1d0c28f3ade10f879dfbf07b6ae2b Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 25 Jun 2025 14:32:11 +0200 Subject: [PATCH 072/303] =?UTF-8?q?=F0=9F=94=A7=20chore(test):=20update=20?= =?UTF-8?q?integration=20test=20configuration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove private key security risk and use dummy address - Switch to Ethereum Sepolia testnet (chain ID 11155111) - Update RPC provider URL to publicnode.com - Change ritual ID to 1 - Fix test skip condition for CI environment --- packages/taco/integration-test/sign.test.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index 7f928f185..c559a0555 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -6,18 +6,16 @@ import { initialize } from '../src'; import { signUserOp } from '../src/sign'; const RPC_PROVIDER_URL = 'https://ethereum-sepolia-rpc.publicnode.com'; -const SIGNER_PRIVATE_KEY = '0x900edb9e8214b2353f82aa195e915128f419a92cfb8bbc0f4784f10ef4112b86'; +const DUMMY_ADDRESS = '0x742d35Cc6634C0532925a3b8D33C9c0E7b66C8E8'; const DOMAIN = 'lynx'; -const RITUAL_ID = 2; +const RITUAL_ID = 1; const CHAIN_ID = 11155111; describe.skipIf(!process.env.RUNNING_IN_CI)('Taco Sign Integration Test', () => { let provider: ethers.providers.JsonRpcProvider; - let signer: ethers.Wallet; beforeAll(async () => { provider = new ethers.providers.JsonRpcProvider(RPC_PROVIDER_URL); - signer = new ethers.Wallet(SIGNER_PRIVATE_KEY, provider); // Initialize the library await initialize(); @@ -34,7 +32,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)('Taco Sign Integration Test', () => test('should sign a user operation', async () => { // Create a sample user operation with all required fields const userOp: UserOperation = { - sender: signer.address, + sender: DUMMY_ADDRESS, nonce: '0x0', factory: '0x', factoryData: '0x', From f10982f1f5882ef18bc3fc3df5c1dc6c0bb94dc0 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 25 Jun 2025 18:03:21 +0200 Subject: [PATCH 073/303] Fix UserOperation signing request format and type errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix UserOperationSignatureRequest constructor to accept objects instead of strings - Remove double JSON stringification that caused address encoding errors - Update convertUserOperationToPython to handle null/empty values properly - Fix test expectations to match new data format and provider addresses - Resolve AddressEncoder errors by ensuring proper hex address format 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- packages/shared/src/porter.ts | 2 +- packages/shared/src/types.ts | 12 ++++++------ packages/taco/src/sign.ts | 5 ++--- packages/taco/test/taco-sign.test.ts | 18 ++++++++---------- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index 0426880ec..164e7827b 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -338,7 +338,7 @@ export class PorterClient { signing_requests: signingRequests, threshold: threshold }; - + let resp: AxiosResponse; try { resp = await this.tryAndCall({ diff --git a/packages/shared/src/types.ts b/packages/shared/src/types.ts index 4a97bc881..9e256dfb5 100644 --- a/packages/shared/src/types.ts +++ b/packages/shared/src/types.ts @@ -22,7 +22,7 @@ export type UserOperation = { export class UserOperationSignatureRequest { constructor( - private userOpString: string, + private userOp: ReturnType, private aaVersion: string, private cohortId: number, private chainId: number, @@ -32,7 +32,7 @@ export class UserOperationSignatureRequest { toBytes(): Uint8Array { const data = { - user_op: this.userOpString, + user_op: this.userOp, aa_version: this.aaVersion, cohort_id: this.cohortId, chain_id: this.chainId, @@ -48,8 +48,8 @@ export function convertUserOperationToPython(userOp: UserOperation) { sender: userOp.sender, nonce: parseInt(userOp.nonce, 16) || 0, factory: userOp.factory === '0x' ? null : userOp.factory, - factory_data: userOp.factoryData, - call_data: userOp.callData, + factory_data: userOp.factoryData || "0x", + call_data: userOp.callData || "0x", call_gas_limit: parseInt(userOp.callGasLimit, 16) || 0, verification_gas_limit: parseInt(userOp.verificationGasLimit, 16) || 0, pre_verification_gas: parseInt(userOp.preVerificationGas, 16) || 0, @@ -58,7 +58,7 @@ export function convertUserOperationToPython(userOp: UserOperation) { paymaster: userOp.paymaster === '0x' ? null : userOp.paymaster, paymaster_verification_gas_limit: parseInt(userOp.paymasterVerificationGasLimit, 16) || 0, paymaster_post_op_gas_limit: parseInt(userOp.paymasterPostOpGasLimit, 16) || 0, - paymaster_data: userOp.paymasterData, - signature: userOp.signature, + paymaster_data: userOp.paymasterData || "0x", + signature: userOp.signature || "0x", }; } diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 19c8c1a48..7eb708ce6 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -20,7 +20,7 @@ export async function signUserOp( cohortId: number, chainId: number, userOp: UserOperation, - aaVersion: '0.8.0' | string, + aaVersion: 'mdt' | '0.8.0' | string, options: SigningOptions = { optimistic: true, returnAggregated: true }, context?: ConditionContext, porterUris?: string[], @@ -44,10 +44,9 @@ export async function signUserOp( ); const pythonUserOp = convertUserOperationToPython(userOp); - const userOpString = JSON.stringify(pythonUserOp, Object.keys(pythonUserOp).sort()); const signingRequest = new UserOperationSignatureRequest( - userOpString, + pythonUserOp, aaVersion, cohortId, chainId, diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index 139323a1f..c8292cd43 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -69,20 +69,19 @@ describe('TACo Signing', () => { ); const pythonUserOp = convertUserOperationToPython(userOp); - const expectedUserOpString = JSON.stringify(pythonUserOp, Object.keys(pythonUserOp).sort()); expect(signUserOpMock).toHaveBeenCalledWith( { - '0x1234': btoa(JSON.stringify({ - user_op: expectedUserOpString, + '0x5678': btoa(JSON.stringify({ + user_op: pythonUserOp, aa_version: aaVersion, cohort_id: cohortId, chain_id: chainId, context: {}, signature_type: "userop" })), - '0xabcd': btoa(JSON.stringify({ - user_op: expectedUserOpString, + '0xefgh': btoa(JSON.stringify({ + user_op: pythonUserOp, aa_version: aaVersion, cohort_id: cohortId, chain_id: chainId, @@ -135,20 +134,19 @@ describe('TACo Signing', () => { ); const pythonUserOp2 = convertUserOperationToPython(userOp); - const expectedUserOpString2 = JSON.stringify(pythonUserOp2, Object.keys(pythonUserOp2).sort()); expect(signUserOpMock).toHaveBeenCalledWith( { - '0x1234': btoa(JSON.stringify({ - user_op: expectedUserOpString2, + '0x5678': btoa(JSON.stringify({ + user_op: pythonUserOp2, aa_version: aaVersion, cohort_id: cohortId, chain_id: chainId, context: {}, signature_type: "userop" })), - '0xabcd': btoa(JSON.stringify({ - user_op: expectedUserOpString2, + '0xefgh': btoa(JSON.stringify({ + user_op: pythonUserOp2, aa_version: aaVersion, cohort_id: cohortId, chain_id: chainId, From 042fe42c295202642b008da9655c5126fbef1388 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 26 Jun 2025 12:19:26 +0200 Subject: [PATCH 074/303] =?UTF-8?q?=E2=9C=85=20test(taco):=20fix=20UserOpe?= =?UTF-8?q?ration=20signing=20tests=20and=20address=20validation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update test expectations to use JSON.stringify for user_op field serialization - Rename digest field to messageHash in SignResult interface and all related code - Implement strict address validation that fails fast on invalid checksums - Fix Porter test mock response structure to match API format - Update integration test to use properly checksummed addresses Co-Authored-By: Kieran --- packages/shared/src/porter.ts | 4 +- packages/shared/src/types.ts | 24 ++++++++++-- packages/shared/test/porter.test.ts | 41 +++++++++++---------- packages/taco/integration-test/sign.test.ts | 4 +- packages/taco/test/taco-sign.test.ts | 20 +++++----- 5 files changed, 55 insertions(+), 38 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index 164e7827b..fdb57ce6d 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -168,7 +168,7 @@ type SignResponse = { }; export type SignResult = { - digest: string; + messageHash: string; aggregatedSignature: string | undefined; signingResults: { [ursulaAddress: string]: [string, string] }; errors: Record; @@ -391,7 +391,7 @@ export class PorterClient { : undefined; return { - digest: messageHash, + messageHash, aggregatedSignature, signingResults, errors, diff --git a/packages/shared/src/types.ts b/packages/shared/src/types.ts index 9e256dfb5..5917eb5cc 100644 --- a/packages/shared/src/types.ts +++ b/packages/shared/src/types.ts @@ -1,3 +1,5 @@ +import { ethers } from 'ethers'; + export type ChecksumAddress = `0x${string}`; export type HexEncodedBytes = string; export type Base64EncodedBytes = string; @@ -32,7 +34,7 @@ export class UserOperationSignatureRequest { toBytes(): Uint8Array { const data = { - user_op: this.userOp, + user_op: JSON.stringify(this.userOp), aa_version: this.aaVersion, cohort_id: this.cohortId, chain_id: this.chainId, @@ -43,11 +45,25 @@ export class UserOperationSignatureRequest { } } +function normalizeAddress(address: string): string | null { + if (!address || address === '0x') { + return null; + } + + try { + // Use ethers to get the checksummed address - this will throw on invalid addresses + return ethers.utils.getAddress(address); + } catch (error) { + // Re-throw the error to fail fast on invalid addresses + throw new Error(`Invalid address: ${address}. ${error instanceof Error ? error.message : 'Unknown error'}`); + } +} + export function convertUserOperationToPython(userOp: UserOperation) { return { - sender: userOp.sender, + sender: normalizeAddress(userOp.sender), nonce: parseInt(userOp.nonce, 16) || 0, - factory: userOp.factory === '0x' ? null : userOp.factory, + factory: normalizeAddress(userOp.factory), factory_data: userOp.factoryData || "0x", call_data: userOp.callData || "0x", call_gas_limit: parseInt(userOp.callGasLimit, 16) || 0, @@ -55,7 +71,7 @@ export function convertUserOperationToPython(userOp: UserOperation) { pre_verification_gas: parseInt(userOp.preVerificationGas, 16) || 0, max_fee_per_gas: parseInt(userOp.maxFeePerGas, 16) || 0, max_priority_fee_per_gas: parseInt(userOp.maxPriorityFeePerGas, 16) || 0, - paymaster: userOp.paymaster === '0x' ? null : userOp.paymaster, + paymaster: normalizeAddress(userOp.paymaster), paymaster_verification_gas_limit: parseInt(userOp.paymasterVerificationGasLimit, 16) || 0, paymaster_post_op_gas_limit: parseInt(userOp.paymasterPostOpGasLimit, 16) || 0, paymaster_data: userOp.paymasterData || "0x", diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index 672959cfa..fe9493b2d 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -53,29 +53,31 @@ const mockGetUrsulas = (ursulas: Ursula[] = fakeUrsulas()): MockInstance => { const createMockSignResponse = (errorCase?: boolean) => ({ result: { - digest: '0x1234', - signing_results: errorCase ? { - '0x1234': ['0x5678', 'invalid-base64'], - '0xabcd': ['0xefgh', toBase64(new TextEncoder().encode(JSON.stringify({ - message_hash: '0x1234', - signature: '0xijkl' - })))] - } : { - '0x1234': ['0x5678', toBase64(new TextEncoder().encode(JSON.stringify({ - message_hash: '0x1234', - signature: '0x90ab' - })))], - '0xabcd': ['0xefgh', toBase64(new TextEncoder().encode(JSON.stringify({ - message_hash: '0x1234', - signature: '0xijkl' - })))] + signing_results: { + signatures: errorCase ? { + '0x1234': ['0x5678', 'invalid-base64'], + '0xabcd': ['0xefgh', toBase64(new TextEncoder().encode(JSON.stringify({ + message_hash: '0x1234', + signature: '0xijkl' + })))] + } : { + '0x1234': ['0x5678', toBase64(new TextEncoder().encode(JSON.stringify({ + message_hash: '0x1234', + signature: '0x90ab' + })))], + '0xabcd': ['0xefgh', toBase64(new TextEncoder().encode(JSON.stringify({ + message_hash: '0x1234', + signature: '0xijkl' + })))] + } } }, }); const createMockSignImplementation = (endpoint: string) => (success: boolean = true, errorCase?: boolean): MockInstance => { return vi.spyOn(axios, 'request').mockImplementation(async (config) => { - if (config.url === endpoint) { + // Handle sign requests + if (config.url === endpoint && config.baseURL === fakePorterUris[2]) { if (success) { return Promise.resolve({ status: HttpStatusCode.Ok, @@ -84,7 +86,6 @@ const createMockSignImplementation = (endpoint: string) => (success: boolean = t } return Promise.resolve({ status: HttpStatusCode.BadRequest, data: '' }); } - throw new Error('Unexpected endpoint'); }); }; @@ -200,7 +201,7 @@ describe('PorterClient Signing', () => { ); expect(result).toEqual({ - digest: '0x1234', + messageHash: '0x1234', aggregatedSignature: '0x90ab0xijkl', // Combined signatures in sorted order signingResults: { '0x1234': ['0x5678', '0x90ab'], @@ -246,7 +247,7 @@ describe('PorterClient Signing', () => { ); expect(result).toEqual({ - digest: '0x1234', + messageHash: '0x1234', aggregatedSignature: undefined, // No aggregated signature when errors occur signingResults: { '0xabcd': ['0xefgh', '0xijkl'], diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index c559a0555..5ff1b180b 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -6,7 +6,7 @@ import { initialize } from '../src'; import { signUserOp } from '../src/sign'; const RPC_PROVIDER_URL = 'https://ethereum-sepolia-rpc.publicnode.com'; -const DUMMY_ADDRESS = '0x742d35Cc6634C0532925a3b8D33C9c0E7b66C8E8'; +const DUMMY_ADDRESS = '0x742D35Cc6634C0532925A3b8D33c9c0E7B66C8E8'; const DOMAIN = 'lynx'; const RITUAL_ID = 1; const CHAIN_ID = 11155111; @@ -68,7 +68,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)('Taco Sign Integration Test', () => // Verify sign result expect(signResult).toBeDefined(); - expect(signResult.digest).toBeDefined(); + expect(signResult.messageHash).toBeDefined(); expect(signResult.aggregatedSignature).toBeDefined(); expect(signResult.signingResults).toBeDefined(); expect(Object.keys(signResult.signingResults).length).toBeGreaterThan(0); diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index c8292cd43..faf00b5d6 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -23,9 +23,9 @@ describe('TACo Signing', () => { describe('signUserOp', () => { const userOp = { - sender: '0x123', + sender: '0x742D35Cc6634C0532925A3b8D33c9c0E7B66C8E8', nonce: '0x1', - factory: '0x0', + factory: '0x0000000000000000000000000000000000000000', factoryData: '0x', callData: '0xabc', callGasLimit: '0x20000', @@ -33,7 +33,7 @@ describe('TACo Signing', () => { preVerificationGas: '0x1000', maxFeePerGas: '0xabc', maxPriorityFeePerGas: '0x123', - paymaster: '0x0', + paymaster: '0x0000000000000000000000000000000000000000', paymasterVerificationGasLimit: '0x0', paymasterPostOpGasLimit: '0x0', paymasterData: '0x', @@ -47,7 +47,7 @@ describe('TACo Signing', () => { const porterUris = [fakePorterUri]; signUserOpMock.mockResolvedValue({ - digest: '0x1234', + messageHash: '0x1234', aggregatedSignature: '0x90ab0xijkl', signingResults: { '0x1234': ['0x5678', '0x90ab'], @@ -73,7 +73,7 @@ describe('TACo Signing', () => { expect(signUserOpMock).toHaveBeenCalledWith( { '0x5678': btoa(JSON.stringify({ - user_op: pythonUserOp, + user_op: JSON.stringify(pythonUserOp), aa_version: aaVersion, cohort_id: cohortId, chain_id: chainId, @@ -81,7 +81,7 @@ describe('TACo Signing', () => { signature_type: "userop" })), '0xefgh': btoa(JSON.stringify({ - user_op: pythonUserOp, + user_op: JSON.stringify(pythonUserOp), aa_version: aaVersion, cohort_id: cohortId, chain_id: chainId, @@ -94,7 +94,7 @@ describe('TACo Signing', () => { ); expect(result).toEqual({ - digest: '0x1234', + messageHash: '0x1234', aggregatedSignature: '0x90ab0xijkl', signingResults: { '0x1234': ['0x5678', '0x90ab'], @@ -112,7 +112,7 @@ describe('TACo Signing', () => { const options = { optimistic: false, returnAggregated: false }; signUserOpMock.mockResolvedValue({ - digest: '0x1234', + messageHash: '0x1234', aggregatedSignature: '0x90ab0xijkl', signingResults: { '0x1234': ['0x5678', '0x90ab'], @@ -138,7 +138,7 @@ describe('TACo Signing', () => { expect(signUserOpMock).toHaveBeenCalledWith( { '0x5678': btoa(JSON.stringify({ - user_op: pythonUserOp2, + user_op: JSON.stringify(pythonUserOp2), aa_version: aaVersion, cohort_id: cohortId, chain_id: chainId, @@ -146,7 +146,7 @@ describe('TACo Signing', () => { signature_type: "userop" })), '0xefgh': btoa(JSON.stringify({ - user_op: pythonUserOp2, + user_op: JSON.stringify(pythonUserOp2), aa_version: aaVersion, cohort_id: cohortId, chain_id: chainId, From 4fc8f9defb8b4fc51fa1a1d817bec8009a8de026 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 26 Jun 2025 16:36:35 +0200 Subject: [PATCH 075/303] refactor(shared): simplify signing error handling to follow tacoDecrypt pattern - Remove complex try-catch blocks and manual error checking in signUserOp - Use direct destructuring of errors from Porter response - Trust Porter's response structure instead of adding validation overhead - Update tests to match new error handling pattern - Follow same approach as tacoDecrypt for consistent error handling --- packages/shared/src/porter.ts | 59 ++++++++--------------------- packages/shared/test/porter.test.ts | 14 ++++--- 2 files changed, 24 insertions(+), 49 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index fdb57ce6d..f8ff1505c 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -339,54 +339,27 @@ export class PorterClient { threshold: threshold }; - let resp: AxiosResponse; - try { - resp = await this.tryAndCall({ - url: '/sign', - method: 'post', - data, - }); - } catch (error) { - console.error('Error in tryAndCall:', error); - throw error; - } - + const resp: AxiosResponse = await this.tryAndCall({ + url: '/sign', + method: 'post', + data, + }); + const { signatures, errors } = resp.data.result.signing_results; + const signingResults: { [ursulaAddress: string]: [string, string] } = {}; - const errors: Record = {}; let messageHash = ''; - // Check if signing_results exists and has the expected structure - const signingResultsData = resp.data.result.signing_results; - if (!signingResultsData || typeof signingResultsData !== 'object') { - throw new Error(`Invalid signing_results in response: ${JSON.stringify(resp.data.result)}`); - } - - // Copy errors from the response - if (signingResultsData.errors) { - Object.assign(errors, signingResultsData.errors); - } - - // Process signatures - if (signingResultsData.signatures) { - for (const [ursulaAddress, [signerAddress, signatureB64]] of Object.entries( - signingResultsData.signatures - )) { - try { - const decodedData = JSON.parse( - new TextDecoder().decode(fromBase64(signatureB64)) - ); - messageHash = decodedData.message_hash; - signingResults[ursulaAddress] = [signerAddress, decodedData.signature]; - } catch (e: unknown) { - const errorMessage = e instanceof Error ? e.message : 'Unknown error'; - errors[ursulaAddress] = `Failed to decode signature: ${errorMessage}`; - } - } + // Process signatures - decode the JSON payload to extract message hash and signature + for (const [ursulaAddress, [signerAddress, signatureB64]] of Object.entries(signatures || {})) { + const decodedData = JSON.parse( + new TextDecoder().decode(fromBase64(signatureB64)) + ); + messageHash = decodedData.message_hash; + signingResults[ursulaAddress] = [signerAddress, decodedData.signature]; } - // Only return aggregated signature if there are no errors - const aggregatedSignature = Object.keys(errors).length === 0 + const aggregatedSignature = Object.keys(signingResults).length > 0 ? aggregatePorterSignatures(signingResults) : undefined; @@ -394,7 +367,7 @@ export class PorterClient { messageHash, aggregatedSignature, signingResults, - errors, + errors: errors || {}, }; } } \ No newline at end of file diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index fe9493b2d..f57add159 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -55,7 +55,6 @@ const createMockSignResponse = (errorCase?: boolean) => ({ result: { signing_results: { signatures: errorCase ? { - '0x1234': ['0x5678', 'invalid-base64'], '0xabcd': ['0xefgh', toBase64(new TextEncoder().encode(JSON.stringify({ message_hash: '0x1234', signature: '0xijkl' @@ -69,7 +68,10 @@ const createMockSignResponse = (errorCase?: boolean) => ({ message_hash: '0x1234', signature: '0xijkl' })))] - } + }, + errors: errorCase ? { + '0x1234': 'Failed to sign' + } : {} } }, }); @@ -230,8 +232,8 @@ describe('PorterClient Signing', () => { ).rejects.toThrow('Porter returned bad response: 400 - '); }); - it('should handle signature decoding errors in UserOperation signing', async () => { - // Mock a response with invalid base64 signature + it('should handle errors from Porter response in UserOperation signing', async () => { + // Mock a response with errors from Porter mockSignUserOp(true, true); const porterClient = new PorterClient(fakePorterUris[2]); const result = await porterClient.signUserOp( @@ -248,12 +250,12 @@ describe('PorterClient Signing', () => { expect(result).toEqual({ messageHash: '0x1234', - aggregatedSignature: undefined, // No aggregated signature when errors occur + aggregatedSignature: '0xijkl', // Still aggregated from successful signatures signingResults: { '0xabcd': ['0xefgh', '0xijkl'], }, errors: { - '0x1234': 'Failed to decode signature: Invalid character', + '0x1234': 'Failed to sign', }, }); }); From bc1c5aba16bb2971441d153bbaf8b15a81a9ffda Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 27 Jun 2025 11:05:47 +0200 Subject: [PATCH 076/303] Rename Signingcoordinator to signing-coordinator --- packages/shared/src/contracts/agents/index.ts | 2 +- .../agents/{signingCoordinator.ts => signing-coordinator.ts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename packages/shared/src/contracts/agents/{signingCoordinator.ts => signing-coordinator.ts} (100%) diff --git a/packages/shared/src/contracts/agents/index.ts b/packages/shared/src/contracts/agents/index.ts index cb6bbf88d..61a028224 100644 --- a/packages/shared/src/contracts/agents/index.ts +++ b/packages/shared/src/contracts/agents/index.ts @@ -1,4 +1,4 @@ export * from './coordinator'; export * from './global-allow-list'; export * from './subscription-manager'; -export * from './signingCoordinator'; \ No newline at end of file +export * from './signing-coordinator'; \ No newline at end of file diff --git a/packages/shared/src/contracts/agents/signingCoordinator.ts b/packages/shared/src/contracts/agents/signing-coordinator.ts similarity index 100% rename from packages/shared/src/contracts/agents/signingCoordinator.ts rename to packages/shared/src/contracts/agents/signing-coordinator.ts From 506d360f255277db6443f28433a030a79d5b83bf Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 27 Jun 2025 11:39:23 +0200 Subject: [PATCH 077/303] =?UTF-8?q?=E2=9C=A8=20feat(shared):=20add=20getSi?= =?UTF-8?q?gningCohortConditions=20method=20to=20SigningCoordinatorAgent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/contracts/agents/signing-coordinator.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/shared/src/contracts/agents/signing-coordinator.ts b/packages/shared/src/contracts/agents/signing-coordinator.ts index 952898cc3..39d1683f6 100644 --- a/packages/shared/src/contracts/agents/signing-coordinator.ts +++ b/packages/shared/src/contracts/agents/signing-coordinator.ts @@ -39,6 +39,17 @@ export class SigningCoordinatorAgent { return cohort.threshold; } + public static async getSigningCohortConditions( + provider: ethers.providers.Provider, + domain: Domain, + cohortId: number, + chainId: number, + ): Promise { + const coordinator = await this.connectReadOnly(provider, domain); + const cohortCondition = await coordinator.getSigningCohortConditions(cohortId, chainId); + return cohortCondition; + } + private static async connectReadOnly( provider: ethers.providers.Provider, domain: Domain, From 7952557a34b4fd874d7c7b6fe0a62a61b596ffe5 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 27 Jun 2025 11:42:11 +0200 Subject: [PATCH 078/303] =?UTF-8?q?=E2=9C=A8=20feat(taco):=20add=20forSign?= =?UTF-8?q?ingCohort=20method=20to=20ConditionContext?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add async forSigningCohort static method to build context from signing cohort conditions - Fix import ordering and add missing ethers import - Update integration test to use new signing context method with await --- packages/taco/integration-test/sign.test.ts | 6 ++++- .../taco/src/conditions/context/context.ts | 22 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index 5ff1b180b..60dd050db 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -3,6 +3,7 @@ import { ethers } from 'ethers'; import { beforeAll, describe, expect, test } from 'vitest'; import { initialize } from '../src'; +import { context } from '../src/conditions'; import { signUserOp } from '../src/sign'; const RPC_PROVIDER_URL = 'https://ethereum-sepolia-rpc.publicnode.com'; @@ -52,6 +53,9 @@ describe.skipIf(!process.env.RUNNING_IN_CI)('Taco Sign Integration Test', () => // Get porter URIs const porterUris = await getPorterUris(DOMAIN as Domain); + // Get context + const signingContext = await context.ConditionContext.forSigningCohort(provider, DOMAIN as Domain, RITUAL_ID, CHAIN_ID); + // Sign user operation const signResult = await signUserOp( provider, @@ -61,7 +65,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)('Taco Sign Integration Test', () => userOp, '0.8.0', { optimistic: true, returnAggregated: true }, - undefined, + signingContext, porterUris ); console.log('Sign result:', signResult); diff --git a/packages/taco/src/conditions/context/context.ts b/packages/taco/src/conditions/context/context.ts index 26a2046bd..0373785ab 100644 --- a/packages/taco/src/conditions/context/context.ts +++ b/packages/taco/src/conditions/context/context.ts @@ -1,4 +1,5 @@ import { ThresholdMessageKit } from '@nucypher/nucypher-core'; +import { Domain, SigningCoordinatorAgent } from '@nucypher/shared'; import { AuthProvider, AuthSignature, @@ -7,6 +8,7 @@ import { SingleSignOnEIP4361AuthProvider, USER_ADDRESS_PARAM_DEFAULT, } from '@nucypher/taco-auth'; +import { ethers } from 'ethers'; import { CoreConditions, CoreContext } from '../../types'; import { toJSON } from '../../utils'; @@ -263,4 +265,24 @@ export class ConditionContext { ); return new ConditionContext(conditionExpr.condition); } + + public static async forSigningCohort( + provider: ethers.providers.JsonRpcProvider, + domain: Domain, + cohortId: number, + chainId: number, + ): Promise { + // get signing condition from SigningCoordinator contract + const cohortConditionJson = await SigningCoordinatorAgent.getSigningCohortConditions( + provider, + domain, + cohortId, + chainId, + ); + const cohortCondition = new CoreConditions(cohortConditionJson); + const conditionExpr = ConditionExpression.fromCoreConditions( + cohortCondition, + ); + return new ConditionContext(conditionExpr.condition); + } } From 4a7b255c8a947350d9baae4a62edac28402aa581 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 27 Jun 2025 12:25:34 +0200 Subject: [PATCH 079/303] =?UTF-8?q?=E2=9C=85=20test(taco):=20add=20compreh?= =?UTF-8?q?ensive=20tests=20for=20forSigningCohort=20method?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add tests for happy path scenario with valid cohort conditions - Add error handling tests for network failures and invalid responses - Add tests for invalid hex decoding and JSON parsing errors - Add tests for complex compound condition structures - Add tests for invalid condition schema validation - Fix hex decoding in forSigningCohort method to handle contract responses --- .../taco/src/conditions/context/context.ts | 6 +- packages/taco/test/conditions/context.test.ts | 217 ++++++++++++++++++ 2 files changed, 222 insertions(+), 1 deletion(-) diff --git a/packages/taco/src/conditions/context/context.ts b/packages/taco/src/conditions/context/context.ts index 0373785ab..481325252 100644 --- a/packages/taco/src/conditions/context/context.ts +++ b/packages/taco/src/conditions/context/context.ts @@ -273,12 +273,16 @@ export class ConditionContext { chainId: number, ): Promise { // get signing condition from SigningCoordinator contract - const cohortConditionJson = await SigningCoordinatorAgent.getSigningCohortConditions( + const cohortConditionHex = await SigningCoordinatorAgent.getSigningCohortConditions( provider, domain, cohortId, chainId, ); + + // Convert hex string to UTF-8 JSON string + const cohortConditionJson = ethers.utils.toUtf8String(cohortConditionHex); + const cohortCondition = new CoreConditions(cohortConditionJson); const conditionExpr = ConditionExpression.fromCoreConditions( cohortCondition, diff --git a/packages/taco/test/conditions/context.test.ts b/packages/taco/test/conditions/context.test.ts index 887b29536..402c8bb78 100644 --- a/packages/taco/test/conditions/context.test.ts +++ b/packages/taco/test/conditions/context.test.ts @@ -1,4 +1,5 @@ import { initialize } from '@nucypher/nucypher-core'; +import { Domain, SigningCoordinatorAgent } from '@nucypher/shared'; import { AuthProvider, AuthSignature, @@ -1103,3 +1104,219 @@ describe('recognition of context variables in conditions', () => { ); }); }); + +describe('forSigningCohort', () => { + beforeAll(async () => { + await initialize(); + }); + + it('creates ConditionContext from signing cohort conditions', async () => { + const mockProvider = fakeProvider(); + const domain = 'lynx' as Domain; + const cohortId = 1; + const chainId = 11155111; + + // Mock signing cohort conditions JSON + const mockConditionsJson = JSON.stringify({ + version: '1.0.0', + condition: { + conditionType: 'rpc', + chain: chainId, + method: 'eth_getBalance', + parameters: [':userAddress', 'latest'], + returnValueTest: { + comparator: '>', + value: 0 + } + } + }); + + // Convert to hex string as the contract would return + const mockConditionsHex = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(mockConditionsJson)); + + // Mock the SigningCoordinatorAgent method + const getSigningCohortConditionsSpy = vi.spyOn( + SigningCoordinatorAgent, + 'getSigningCohortConditions' + ).mockResolvedValue(mockConditionsHex); + + // Test the forSigningCohort method + const conditionContext = await ConditionContext.forSigningCohort( + mockProvider, + domain, + cohortId, + chainId + ); + + // Verify the method was called with correct parameters + expect(getSigningCohortConditionsSpy).toHaveBeenCalledWith( + mockProvider, + domain, + cohortId, + chainId + ); + + // Verify the context was created correctly + expect(conditionContext).toBeInstanceOf(ConditionContext); + expect(conditionContext.requestedContextParameters).toContain(':userAddress'); + + // Cleanup + getSigningCohortConditionsSpy.mockRestore(); + }); + + it('handles errors when signing cohort conditions fail to load', async () => { + const mockProvider = fakeProvider(); + const domain = 'lynx' as Domain; + const cohortId = 999; + const chainId = 11155111; + + // Mock the SigningCoordinatorAgent method to throw an error + const getSigningCohortConditionsSpy = vi.spyOn( + SigningCoordinatorAgent, + 'getSigningCohortConditions' + ).mockRejectedValue(new Error('Cohort not found')); + + // Test that error is propagated + await expect( + ConditionContext.forSigningCohort(mockProvider, domain, cohortId, chainId) + ).rejects.toThrow('Cohort not found'); + + // Verify the method was called + expect(getSigningCohortConditionsSpy).toHaveBeenCalledWith( + mockProvider, + domain, + cohortId, + chainId + ); + + // Cleanup + getSigningCohortConditionsSpy.mockRestore(); + }); + + it('handles invalid JSON from signing cohort conditions', async () => { + const mockProvider = fakeProvider(); + const domain = 'lynx' as Domain; + const cohortId = 1; + const chainId = 11155111; + + // Mock the SigningCoordinatorAgent method to return invalid hex + const getSigningCohortConditionsSpy = vi.spyOn( + SigningCoordinatorAgent, + 'getSigningCohortConditions' + ).mockResolvedValue('0xinvalidhex'); + + // Test that JSON parse error is handled + await expect( + ConditionContext.forSigningCohort(mockProvider, domain, cohortId, chainId) + ).rejects.toThrow(); + + // Verify the method was called + expect(getSigningCohortConditionsSpy).toHaveBeenCalledWith( + mockProvider, + domain, + cohortId, + chainId + ); + + // Cleanup + getSigningCohortConditionsSpy.mockRestore(); + }); + + + it('handles complex condition structures', async () => { + const mockProvider = fakeProvider(); + const domain = 'lynx' as Domain; + const cohortId = 1; + const chainId = 11155111; + + // Mock compound condition JSON + const mockComplexConditionsJson = JSON.stringify({ + version: '1.0.0', + condition: { + conditionType: 'compound', + operator: 'and', + operands: [ + { + conditionType: 'rpc', + chain: chainId, + method: 'eth_getBalance', + parameters: [':userAddress', 'latest'], + returnValueTest: { + comparator: '>', + value: 0 + } + }, + { + conditionType: 'contract', + contractAddress: '0x1234567890123456789012345678901234567890', + chain: chainId, + standardContractType: 'ERC20', + method: 'balanceOf', + parameters: [':userAddress'], + returnValueTest: { + comparator: '>=', + value: 1000 + } + } + ] + } + }); + + // Convert to hex string as the contract would return + const mockComplexConditionsHex = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(mockComplexConditionsJson)); + + // Mock the SigningCoordinatorAgent method + const getSigningCohortConditionsSpy = vi.spyOn( + SigningCoordinatorAgent, + 'getSigningCohortConditions' + ).mockResolvedValue(mockComplexConditionsHex); + + // Test the forSigningCohort method with complex conditions + const conditionContext = await ConditionContext.forSigningCohort( + mockProvider, + domain, + cohortId, + chainId + ); + + // Verify the context was created correctly + expect(conditionContext).toBeInstanceOf(ConditionContext); + expect(conditionContext.requestedContextParameters).toContain(':userAddress'); + + // Cleanup + getSigningCohortConditionsSpy.mockRestore(); + }); + + it('handles invalid condition schema', async () => { + const mockProvider = fakeProvider(); + const domain = 'lynx' as Domain; + const cohortId = 1; + const chainId = 11155111; + + // Mock invalid condition schema JSON + const mockInvalidConditionsJson = JSON.stringify({ + version: '1.0.0', + condition: { + conditionType: 'invalid_type', + missingRequiredFields: true + } + }); + + // Convert to hex string as the contract would return + const mockInvalidConditionsHex = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(mockInvalidConditionsJson)); + + // Mock the SigningCoordinatorAgent method + const getSigningCohortConditionsSpy = vi.spyOn( + SigningCoordinatorAgent, + 'getSigningCohortConditions' + ).mockResolvedValue(mockInvalidConditionsHex); + + // Test that invalid condition schema throws error + await expect( + ConditionContext.forSigningCohort(mockProvider, domain, cohortId, chainId) + ).rejects.toThrow(); + + // Cleanup + getSigningCohortConditionsSpy.mockRestore(); + }); +}); \ No newline at end of file From 8474516b5807a3364d004a7f3e64564740f14a43 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 1 Jul 2025 11:31:03 +0200 Subject: [PATCH 080/303] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(shared):?= =?UTF-8?q?=20remove=20returnAggregated=20option=20and=20add=20message=20h?= =?UTF-8?q?ash=20validation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove returnAggregated option from SigningOptions type - Remove unused options parameter from signUserOp method - Add validation to ensure all Ursulas return same message hash - Throw error if message hashes don't match across signatures --- packages/shared/src/porter.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index f8ff1505c..504d9876a 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -155,7 +155,6 @@ export type TacoDecryptResult = { // Signing types export type SigningOptions = { optimistic?: boolean; // Whether to return first signatures received or wait for all signatures - returnAggregated?: boolean; // Whether to return the aggregated signature }; type SignResponse = { @@ -331,8 +330,6 @@ export class PorterClient { public async signUserOp( signingRequests: Record, threshold: number, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - _options: SigningOptions = { optimistic: true, returnAggregated: true }, ): Promise { const data: Record = { signing_requests: signingRequests, @@ -355,6 +352,9 @@ export class PorterClient { const decodedData = JSON.parse( new TextDecoder().decode(fromBase64(signatureB64)) ); + if (messageHash && messageHash !== decodedData.message_hash) { + throw new Error('Mismatched message hashes'); + } messageHash = decodedData.message_hash; signingResults[ursulaAddress] = [signerAddress, decodedData.signature]; } From 8af24995d9702a81bfdcc6a1ea4ad60ce36fe350 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 1 Jul 2025 11:31:22 +0200 Subject: [PATCH 081/303] =?UTF-8?q?=E2=9C=85=20test(shared):=20update=20te?= =?UTF-8?q?sts=20for=20signUserOp=20changes=20and=20add=20message=20hash?= =?UTF-8?q?=20validation=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove returnAggregated options from existing tests - Add test case to verify error thrown when message hashes don't match - Update test calls to match new signUserOp signature --- packages/shared/test/porter.test.ts | 53 +++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index f57add159..b3b8c3cdb 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -195,11 +195,7 @@ describe('PorterClient Signing', () => { '0x1234': JSON.stringify(mockPackedUserOp), '0xabcd': JSON.stringify(mockPackedUserOp) }, - 2, - { - optimistic: true, - returnAggregated: true - } + 2 ); expect(result).toEqual({ @@ -241,11 +237,7 @@ describe('PorterClient Signing', () => { '0x1234': JSON.stringify(mockPackedUserOp), '0xabcd': JSON.stringify(mockPackedUserOp) }, - 2, - { - optimistic: true, - returnAggregated: true - } + 2 ); expect(result).toEqual({ @@ -259,5 +251,46 @@ describe('PorterClient Signing', () => { }, }); }); + + it('should throw error when message hashes do not match', async () => { + const createMismatchedResponse = () => ({ + result: { + signing_results: { + signatures: { + '0x1234': ['0x5678', toBase64(new TextEncoder().encode(JSON.stringify({ + message_hash: '0x1234', + signature: '0x90ab' + })))], + '0xabcd': ['0xefgh', toBase64(new TextEncoder().encode(JSON.stringify({ + message_hash: '0xdifferent', // Different message hash + signature: '0xijkl' + })))] + }, + errors: {} + } + }, + }); + + vi.spyOn(axios, 'request').mockImplementation(async (config) => { + if (config.url === '/sign' && config.baseURL === fakePorterUris[2]) { + return Promise.resolve({ + status: HttpStatusCode.Ok, + data: createMismatchedResponse(), + }); + } + }); + + const porterClient = new PorterClient(fakePorterUris[2]); + + await expect( + porterClient.signUserOp( + { + '0x1234': JSON.stringify(mockPackedUserOp), + '0xabcd': JSON.stringify(mockPackedUserOp) + }, + 2 + ) + ).rejects.toThrow('Mismatched message hashes'); + }); }); }); From 4454d829244ad5905bb88f1c4010bf1d2739013c Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 1 Jul 2025 11:31:44 +0200 Subject: [PATCH 082/303] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(taco):=20?= =?UTF-8?q?update=20signUserOp=20function=20to=20match=20new=20shared=20in?= =?UTF-8?q?terface?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove SigningOptions import as no longer needed - Remove options parameter from signUserOp function signature - Update porter.signUserOp call to remove options parameter --- packages/taco/src/sign.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 7eb708ce6..482fcddf4 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -4,7 +4,6 @@ import { getPorterUris, PorterClient, SigningCoordinatorAgent, - SigningOptions, SignResult, toBase64, UserOperation, @@ -21,7 +20,6 @@ export async function signUserOp( chainId: number, userOp: UserOperation, aaVersion: 'mdt' | '0.8.0' | string, - options: SigningOptions = { optimistic: true, returnAggregated: true }, context?: ConditionContext, porterUris?: string[], ): Promise { @@ -62,7 +60,7 @@ export async function signUserOp( ); // Build signing request for the user operation - const result = await porter.signUserOp(signingRequests, threshold, options); + const result = await porter.signUserOp(signingRequests, threshold); return result; } From 2ee841bfe346487c31f23148b81dd3c160fd535b Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 1 Jul 2025 11:32:02 +0200 Subject: [PATCH 083/303] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(taco):=20?= =?UTF-8?q?remove=20unused=20INTERNAL=5FSIGNING=5FCONDITION=20from=20conte?= =?UTF-8?q?xt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove unused INTERNAL_SIGNING_CONDITION constant - Update RESERVED_CONTEXT_PARAMS to only include USER_ADDRESS_PARAM_DEFAULT --- packages/taco/src/conditions/context/context.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/taco/src/conditions/context/context.ts b/packages/taco/src/conditions/context/context.ts index 481325252..7c2264541 100644 --- a/packages/taco/src/conditions/context/context.ts +++ b/packages/taco/src/conditions/context/context.ts @@ -57,9 +57,8 @@ const EXPECTED_AUTH_PROVIDER_TYPES: Record = { ], }; -const INTERNAL_SIGNING_CONDITION = ':signingConditionObject'; -export const RESERVED_CONTEXT_PARAMS = [USER_ADDRESS_PARAM_DEFAULT, INTERNAL_SIGNING_CONDITION]; +export const RESERVED_CONTEXT_PARAMS = [USER_ADDRESS_PARAM_DEFAULT]; export class ConditionContext { public requestedContextParameters: Set; From 99c2453aeb7504655c6589fdd73907bd32760da7 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 1 Jul 2025 11:32:15 +0200 Subject: [PATCH 084/303] =?UTF-8?q?=E2=9C=85=20test(taco):=20update=20sign?= =?UTF-8?q?UserOp=20tests=20for=20new=20function=20signature?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove returnAggregated options from test calls - Update function calls to match new signUserOp signature - Remove unused options variable from test --- packages/taco/test/taco-sign.test.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index faf00b5d6..e631fbe61 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -63,7 +63,6 @@ describe('TACo Signing', () => { chainId, userOp, aaVersion, - { optimistic: true, returnAggregated: true }, undefined, porterUris ); @@ -89,8 +88,7 @@ describe('TACo Signing', () => { signature_type: "userop" })) }, - 2, - { optimistic: true, returnAggregated: true } + 2 ); expect(result).toEqual({ @@ -109,7 +107,6 @@ describe('TACo Signing', () => { const aaVersion = '0.8.0'; const cohortId = 5; const porterUris = [fakePorterUri]; - const options = { optimistic: false, returnAggregated: false }; signUserOpMock.mockResolvedValue({ messageHash: '0x1234', @@ -128,7 +125,6 @@ describe('TACo Signing', () => { chainId, userOp, aaVersion, - options, undefined, porterUris ); @@ -154,8 +150,7 @@ describe('TACo Signing', () => { signature_type: "userop" })) }, - 2, - options + 2 ); }); }); From 3bea4311a1977addaa53d8a78b153aa418d94558 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 1 Jul 2025 11:32:31 +0200 Subject: [PATCH 085/303] =?UTF-8?q?=E2=9C=85=20test(taco):=20update=20inte?= =?UTF-8?q?gration=20test=20for=20new=20signUserOp=20signature?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove returnAggregated option from signUserOp call in integration test --- packages/taco/integration-test/sign.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index 60dd050db..84cb35735 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -64,7 +64,6 @@ describe.skipIf(!process.env.RUNNING_IN_CI)('Taco Sign Integration Test', () => CHAIN_ID, userOp, '0.8.0', - { optimistic: true, returnAggregated: true }, signingContext, porterUris ); From b0e3575efbcc36599a3056003aa4b9f77701cd56 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 1 Jul 2025 11:45:59 +0200 Subject: [PATCH 086/303] =?UTF-8?q?=F0=9F=94=92=20fix(shared):=20only=20ag?= =?UTF-8?q?gregate=20signatures=20when=20threshold=20met?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Change aggregation logic from length > 0 to length >= threshold - Ensures aggregated signature only provided with sufficient signatures --- packages/shared/src/porter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index 504d9876a..60a884e6a 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -359,7 +359,7 @@ export class PorterClient { signingResults[ursulaAddress] = [signerAddress, decodedData.signature]; } - const aggregatedSignature = Object.keys(signingResults).length > 0 + const aggregatedSignature = Object.keys(signingResults).length >= threshold ? aggregatePorterSignatures(signingResults) : undefined; From b19ed2cf37bbe7d0331d83db9965a5b37211c724 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 1 Jul 2025 11:46:35 +0200 Subject: [PATCH 087/303] =?UTF-8?q?=E2=9C=85=20test(shared):=20update=20te?= =?UTF-8?q?sts=20for=20threshold-based=20aggregation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix existing test expectation for insufficient signatures case - Add new test to verify no aggregation when threshold not met - Ensure test coverage for both threshold met and unmet scenarios --- packages/shared/test/porter.test.ts | 46 ++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index b3b8c3cdb..2262a4f22 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -242,7 +242,7 @@ describe('PorterClient Signing', () => { expect(result).toEqual({ messageHash: '0x1234', - aggregatedSignature: '0xijkl', // Still aggregated from successful signatures + aggregatedSignature: undefined, // No aggregation since threshold (2) not met (only 1 signature) signingResults: { '0xabcd': ['0xefgh', '0xijkl'], }, @@ -292,5 +292,49 @@ describe('PorterClient Signing', () => { ) ).rejects.toThrow('Mismatched message hashes'); }); + + it('should not return aggregated signature when threshold not met', async () => { + const createInsufficientResponse = () => ({ + result: { + signing_results: { + signatures: { + '0x1234': ['0x5678', toBase64(new TextEncoder().encode(JSON.stringify({ + message_hash: '0x1234', + signature: '0x90ab' + })))] + // Only 1 signature, but threshold is 2 + }, + errors: {} + } + }, + }); + + vi.spyOn(axios, 'request').mockImplementation(async (config) => { + if (config.url === '/sign' && config.baseURL === fakePorterUris[2]) { + return Promise.resolve({ + status: HttpStatusCode.Ok, + data: createInsufficientResponse(), + }); + } + }); + + const porterClient = new PorterClient(fakePorterUris[2]); + const result = await porterClient.signUserOp( + { + '0x1234': JSON.stringify(mockPackedUserOp), + '0xabcd': JSON.stringify(mockPackedUserOp) + }, + 2 // threshold of 2, but only 1 signature + ); + + expect(result).toEqual({ + messageHash: '0x1234', + aggregatedSignature: undefined, // Should be undefined since threshold not met + signingResults: { + '0x1234': ['0x5678', '0x90ab'], + }, + errors: {}, + }); + }); }); }); From e4b6a3de880e38f3868397677a0b40f4d628115e Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 20 Jun 2025 09:58:45 -0400 Subject: [PATCH 088/303] Initial set up of signing attribute condition. --- packages/taco/src/conditions/base/signing.ts | 22 ++++++++++++++ .../taco/src/conditions/context/context.ts | 6 +++- .../taco/src/conditions/schemas/signing.ts | 30 +++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 packages/taco/src/conditions/base/signing.ts create mode 100644 packages/taco/src/conditions/schemas/signing.ts diff --git a/packages/taco/src/conditions/base/signing.ts b/packages/taco/src/conditions/base/signing.ts new file mode 100644 index 000000000..0d6234d24 --- /dev/null +++ b/packages/taco/src/conditions/base/signing.ts @@ -0,0 +1,22 @@ +import { Condition } from '../condition'; +import { + SigningObjectAttributeConditionProps, + signingObjectAttributeConditionSchema, + SigningObjectAttributeConditionType, +} from '../schemas/signing'; +import { OmitConditionType } from '../shared'; + +export { + SigningObjectAttributeConditionProps, + signingObjectAttributeConditionSchema, + SigningObjectAttributeConditionType, +} from '../schemas/signing'; + +export class SigningObjectAttributeCondition extends Condition { + constructor(value: OmitConditionType) { + super(signingObjectAttributeConditionSchema, { + conditionType: SigningObjectAttributeConditionType, + ...value, + }); + } +} diff --git a/packages/taco/src/conditions/context/context.ts b/packages/taco/src/conditions/context/context.ts index 01c2cdc83..f0a7862cb 100644 --- a/packages/taco/src/conditions/context/context.ts +++ b/packages/taco/src/conditions/context/context.ts @@ -20,6 +20,7 @@ import { CONTEXT_PARAM_REGEXP, USER_ADDRESS_PARAMS, } from '../const'; +import { SIGNING_CONDITION_OBJECT_CONTEXT_VAR } from '../schemas/signing'; export type CustomContextParam = | string @@ -57,7 +58,10 @@ const EXPECTED_AUTH_PROVIDER_TYPES: Record = { ], }; -export const RESERVED_CONTEXT_PARAMS = [USER_ADDRESS_PARAM_DEFAULT]; +export const RESERVED_CONTEXT_PARAMS = [ + USER_ADDRESS_PARAM_DEFAULT, + SIGNING_CONDITION_OBJECT_CONTEXT_VAR, +]; export class ConditionContext { public requestedContextParameters: Set; diff --git a/packages/taco/src/conditions/schemas/signing.ts b/packages/taco/src/conditions/schemas/signing.ts new file mode 100644 index 000000000..2e416f597 --- /dev/null +++ b/packages/taco/src/conditions/schemas/signing.ts @@ -0,0 +1,30 @@ +import { z } from 'zod'; + +import { baseConditionSchema } from './common'; +import { blockchainReturnValueTestSchema } from './return-value-test'; + +export const SigningObjectAttributeConditionType = 'attribute'; + +export const SIGNING_CONDITION_OBJECT_CONTEXT_VAR = ':signingConditionObject'; + +const baseSigningObjectConditionSchema = baseConditionSchema.extend({ + signingObjectContextVar: z + .literal(SIGNING_CONDITION_OBJECT_CONTEXT_VAR) + .default(SIGNING_CONDITION_OBJECT_CONTEXT_VAR) + .describe( + 'The context variable that will be replaced with the signing object at signing', + ), +}); + +export const signingObjectAttributeConditionSchema: z.ZodSchema = + baseSigningObjectConditionSchema.extend({ + conditionType: z + .literal(SigningObjectAttributeConditionType) + .default(SigningObjectAttributeConditionType), + attribute_name: z.string().describe('The name of the attribute to check'), + returnValueTest: blockchainReturnValueTestSchema, + }); + +export type SigningObjectAttributeConditionProps = z.infer< + typeof signingObjectAttributeConditionSchema +>; From 38ffc9aebf7ef2366e57f75bb38b6266ec3514c3 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Mon, 23 Jun 2025 16:11:24 -0400 Subject: [PATCH 089/303] Initial work for SigningObjectAbiAttributeCondition that allows for recursive abi validation. --- packages/taco/src/conditions/base/index.ts | 1 + packages/taco/src/conditions/base/signing.ts | 21 ++++ .../taco/src/conditions/schemas/signing.ts | 104 +++++++++++++++++- 3 files changed, 120 insertions(+), 6 deletions(-) diff --git a/packages/taco/src/conditions/base/index.ts b/packages/taco/src/conditions/base/index.ts index cc6a33328..3a235473d 100644 --- a/packages/taco/src/conditions/base/index.ts +++ b/packages/taco/src/conditions/base/index.ts @@ -7,4 +7,5 @@ export * as jsonApi from './json-api'; export * as jsonRpc from './json-rpc'; export * as jwt from './jwt'; export * as rpc from './rpc'; +export * as signing from './signing'; export * as time from './time'; diff --git a/packages/taco/src/conditions/base/signing.ts b/packages/taco/src/conditions/base/signing.ts index 0d6234d24..11edb066f 100644 --- a/packages/taco/src/conditions/base/signing.ts +++ b/packages/taco/src/conditions/base/signing.ts @@ -1,5 +1,8 @@ import { Condition } from '../condition'; import { + SigningObjectAbiAttributeConditionProps, + signingObjectAbiAttributeConditionSchema, + SigningObjectAbiAttributeConditionType, SigningObjectAttributeConditionProps, signingObjectAttributeConditionSchema, SigningObjectAttributeConditionType, @@ -7,6 +10,13 @@ import { import { OmitConditionType } from '../shared'; export { + AbiCallValidationProps, + abiCallValidationSchema, + AbiParameterValidationProps, + abiParameterValidationSchema, + SigningObjectAbiAttributeConditionProps, + signingObjectAbiAttributeConditionSchema, + SigningObjectAbiAttributeConditionType, SigningObjectAttributeConditionProps, signingObjectAttributeConditionSchema, SigningObjectAttributeConditionType, @@ -20,3 +30,14 @@ export class SigningObjectAttributeCondition extends Condition { }); } } + +export class SigningObjectAbiAttributeCondition extends Condition { + constructor( + value: OmitConditionType, + ) { + super(signingObjectAbiAttributeConditionSchema, { + conditionType: SigningObjectAbiAttributeConditionType, + ...value, + }); + } +} diff --git a/packages/taco/src/conditions/schemas/signing.ts b/packages/taco/src/conditions/schemas/signing.ts index 2e416f597..700177f43 100644 --- a/packages/taco/src/conditions/schemas/signing.ts +++ b/packages/taco/src/conditions/schemas/signing.ts @@ -1,13 +1,12 @@ +import { FunctionFragment } from 'ethers/lib/utils'; import { z } from 'zod'; import { baseConditionSchema } from './common'; import { blockchainReturnValueTestSchema } from './return-value-test'; -export const SigningObjectAttributeConditionType = 'attribute'; - export const SIGNING_CONDITION_OBJECT_CONTEXT_VAR = ':signingConditionObject'; -const baseSigningObjectConditionSchema = baseConditionSchema.extend({ +const signingConditionSchema = baseConditionSchema.extend({ signingObjectContextVar: z .literal(SIGNING_CONDITION_OBJECT_CONTEXT_VAR) .default(SIGNING_CONDITION_OBJECT_CONTEXT_VAR) @@ -16,15 +15,108 @@ const baseSigningObjectConditionSchema = baseConditionSchema.extend({ ), }); +const baseSigningObjectAttributeConditionSchema = signingConditionSchema.extend( + { + attribute_name: z.string().describe('The name of the attribute to check'), + }, +); + +export const SigningObjectAttributeConditionType = 'attribute'; + export const signingObjectAttributeConditionSchema: z.ZodSchema = - baseSigningObjectConditionSchema.extend({ + baseSigningObjectAttributeConditionSchema.extend({ conditionType: z .literal(SigningObjectAttributeConditionType) .default(SigningObjectAttributeConditionType), - attribute_name: z.string().describe('The name of the attribute to check'), - returnValueTest: blockchainReturnValueTestSchema, }); export type SigningObjectAttributeConditionProps = z.infer< typeof signingObjectAttributeConditionSchema >; + +export const abiParameterValidationSchema: z.ZodSchema = z + .object({ + parameterIndex: z + .number() + .int() + .nonnegative() + .describe('index of parameter to check within abi calldata.'), + indexWithinTuple: z + .number() + .int() + .nonnegative() + .optional() + .describe( + 'index of value within tuple value at parameter index to check', + ), + returnValueTest: blockchainReturnValueTestSchema + .optional() + .describe('comparison check for value within calldata'), + nestedAbiValidation: z + .lazy(() => abiCallValidationSchema) + .describe('additional checks for nested abi calldata'), + }) + .refine( + // An XOR check to see if either 'returnValueTest' or 'nestedAbiValidation' is set + (parameterValidation) => + Boolean(parameterValidation.returnValueTest) !== + Boolean(parameterValidation.nestedAbiValidation), + { + message: + "At most one of the fields 'returnValueTest' and 'nestedAbiValidation' must be defined", + path: ['returnValueTest'], + }, + ); + +export type AbiParameterValidationProps = z.infer< + typeof abiParameterValidationSchema +>; + +const isValidFunctionSignature = (signature: string): boolean => { + try { + // TODO: verify this works properly + const fragment = FunctionFragment.from(signature); + return fragment.format() === signature; // ensure the same sighash format was provided + } catch (error) { + return false; + } +}; + +export const abiCallValidationSchema: z.ZodSchema = z + .object({ + allowedAbiCalls: z.record( + z.string(), + z.array(abiParameterValidationSchema), + ), + }) + .refine( + (abiCallValidation) => { + // validate human readable abi signature + const keys = Object.keys(abiCallValidation.allowedAbiCalls); + keys.forEach((abiSignature) => { + if (!isValidFunctionSignature(abiSignature)) { + return false; + } + }); + return true; + }, + { + message: 'Invalid ABI signature provided', + }, + ); + +export type AbiCallValidationProps = z.infer; + +export const SigningObjectAbiAttributeConditionType = 'abi-attribute'; + +export const signingObjectAbiAttributeConditionSchema: z.ZodSchema = + baseSigningObjectAttributeConditionSchema.extend({ + conditionType: z + .literal(SigningObjectAbiAttributeConditionType) + .default(SigningObjectAbiAttributeConditionType), + abiValidation: abiCallValidationSchema, + }); + +export type SigningObjectAbiAttributeConditionProps = z.infer< + typeof signingObjectAbiAttributeConditionSchema +>; From d0423eb2f85a8887cff1f6d211e0ba8162ffac12 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 24 Jun 2025 08:50:05 -0400 Subject: [PATCH 090/303] Code cleanup and initial tests for SigningObjectAttributeCondition. --- packages/taco/src/conditions/base/signing.ts | 1 + .../taco/src/conditions/schemas/signing.ts | 6 +- .../taco/test/conditions/base/signing.test.ts | 119 ++++++++++++++++++ packages/taco/test/test-utils.ts | 15 +++ 4 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 packages/taco/test/conditions/base/signing.test.ts diff --git a/packages/taco/src/conditions/base/signing.ts b/packages/taco/src/conditions/base/signing.ts index 11edb066f..ed4f03a16 100644 --- a/packages/taco/src/conditions/base/signing.ts +++ b/packages/taco/src/conditions/base/signing.ts @@ -14,6 +14,7 @@ export { abiCallValidationSchema, AbiParameterValidationProps, abiParameterValidationSchema, + SIGNING_CONDITION_OBJECT_CONTEXT_VAR, SigningObjectAbiAttributeConditionProps, signingObjectAbiAttributeConditionSchema, SigningObjectAbiAttributeConditionType, diff --git a/packages/taco/src/conditions/schemas/signing.ts b/packages/taco/src/conditions/schemas/signing.ts index 700177f43..540b8aee7 100644 --- a/packages/taco/src/conditions/schemas/signing.ts +++ b/packages/taco/src/conditions/schemas/signing.ts @@ -17,7 +17,10 @@ const signingConditionSchema = baseConditionSchema.extend({ const baseSigningObjectAttributeConditionSchema = signingConditionSchema.extend( { - attribute_name: z.string().describe('The name of the attribute to check'), + attributeName: z + .string() + .min(1) + .describe('The name of the attribute to check'), }, ); @@ -28,6 +31,7 @@ export const signingObjectAttributeConditionSchema: z.ZodSchema = conditionType: z .literal(SigningObjectAttributeConditionType) .default(SigningObjectAttributeConditionType), + returnValueTest: blockchainReturnValueTestSchema, }); export type SigningObjectAttributeConditionProps = z.infer< diff --git a/packages/taco/test/conditions/base/signing.test.ts b/packages/taco/test/conditions/base/signing.test.ts new file mode 100644 index 000000000..09c59447f --- /dev/null +++ b/packages/taco/test/conditions/base/signing.test.ts @@ -0,0 +1,119 @@ +import { describe, expect, it } from 'vitest'; + +import { + SIGNING_CONDITION_OBJECT_CONTEXT_VAR, + SigningObjectAttributeCondition, + signingObjectAttributeConditionSchema, + SigningObjectAttributeConditionType, +} from '../../../src/conditions/base/signing'; +import { testSigningAttributeConditionObj } from '../../test-utils'; + +describe('SigningObjectAttributeCondition', () => { + describe('validation', () => { + it('accepts on a valid schema', () => { + const result = SigningObjectAttributeCondition.validate( + signingObjectAttributeConditionSchema, + testSigningAttributeConditionObj, + ); + + expect(result.error).toBeUndefined(); + expect(result.data).toEqual(testSigningAttributeConditionObj); + }); + + describe('rejects an invalid schema', () => { + it('rejects invalid condition type', () => { + const badSigningAttributeConditionObj = { + ...testSigningAttributeConditionObj, + conditionType: 'myAttribute', + }; + const result = SigningObjectAttributeCondition.validate( + signingObjectAttributeConditionSchema, + badSigningAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + conditionType: { + _errors: ['Invalid literal value, expected "attribute"'], + }, + }); + }); + it('rejects invalid context variable', () => { + const badSigningAttributeConditionObj = { + ...testSigningAttributeConditionObj, + signingObjectContextVar: ':contextVar', + }; + const result = SigningObjectAttributeCondition.validate( + signingObjectAttributeConditionSchema, + badSigningAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + signingObjectContextVar: { + _errors: [ + 'Invalid literal value, expected ":signingConditionObject"', + ], + }, + }); + }); + it('rejects empty attributeName', () => { + const badSigningAttributeConditionObj = { + ...testSigningAttributeConditionObj, + // Intentionally replacing `attributeName` with an invalid value + attributeName: '', + }; + + const result = SigningObjectAttributeCondition.validate( + signingObjectAttributeConditionSchema, + badSigningAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + attributeName: { + _errors: ['String must contain at least 1 character(s)'], + }, + }); + }); + it('rejects invalid attributeName value type', () => { + const badSigningAttributeConditionObj = { + ...testSigningAttributeConditionObj, + // Intentionally replacing `attributeName` with an invalid value + attributeName: 100, + }; + + const result = SigningObjectAttributeCondition.validate( + signingObjectAttributeConditionSchema, + badSigningAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + attributeName: { + _errors: ['Expected string, received number'], + }, + }); + }); + }); + + it('infers condition type from constructor', () => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { conditionType, ...withoutType } = + testSigningAttributeConditionObj; + const condition = new SigningObjectAttributeCondition(withoutType); + expect(condition.value.conditionType).toEqual( + SigningObjectAttributeConditionType, + ); + }); + it('infers context variable from constructor', () => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { conditionType, signingObjectContextVar, ...withoutType } = + testSigningAttributeConditionObj; + const condition = new SigningObjectAttributeCondition(withoutType); + expect(condition.value.signingObjectContextVar).toEqual( + SIGNING_CONDITION_OBJECT_CONTEXT_VAR, + ); + }); + }); +}); diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index d32548b3c..61710432f 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -58,6 +58,10 @@ import { RpcConditionProps, RpcConditionType, } from '../src/conditions/base/rpc'; +import { + SigningObjectAttributeConditionProps, + SigningObjectAttributeConditionType, +} from '../src/conditions/base/signing'; import { TimeConditionMethod, TimeConditionProps, @@ -347,6 +351,17 @@ export const testSequentialConditionObj: SequentialConditionProps = { ], }; +export const testSigningAttributeConditionObj: SigningObjectAttributeConditionProps = + { + conditionType: SigningObjectAttributeConditionType, + signingObjectContextVar: ':signingConditionObject', + attributeName: 'value', + returnValueTest: { + comparator: '>', + value: 100, + }, + }; + export const testFunctionAbi: FunctionAbiProps = { name: 'myFunction', type: 'function', From dd4196b62982cc60c04f99098ac973d01710b269 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 24 Jun 2025 08:50:35 -0400 Subject: [PATCH 091/303] Fix old incorrect rpc test. --- packages/taco/test/conditions/base/rpc.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco/test/conditions/base/rpc.test.ts b/packages/taco/test/conditions/base/rpc.test.ts index e1cb99cb6..be257c73e 100644 --- a/packages/taco/test/conditions/base/rpc.test.ts +++ b/packages/taco/test/conditions/base/rpc.test.ts @@ -42,7 +42,7 @@ describe('validation', () => { it('infers condition type from constructor', () => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { conditionType, ...withoutType } = testRpcConditionObj; - const condition = new RpcCondition(testRpcConditionObj); + const condition = new RpcCondition(withoutType); expect(condition.value.conditionType).toEqual(RpcConditionType); }); From 5ba48e0cfb38c4574db5b4e3228e83b93a07b94e Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 24 Jun 2025 11:55:09 -0400 Subject: [PATCH 092/303] Add functionality and tests for "in","!in" operators. Move operator test from time.test.ts to return-value-test.test.ts. --- .../conditions/schemas/return-value-test.ts | 35 +++++++--- .../taco/test/conditions/base/time.test.ts | 25 ------- .../test/conditions/return-value-test.test.ts | 68 +++++++++++++++++++ 3 files changed, 95 insertions(+), 33 deletions(-) create mode 100644 packages/taco/test/conditions/return-value-test.test.ts diff --git a/packages/taco/src/conditions/schemas/return-value-test.ts b/packages/taco/src/conditions/schemas/return-value-test.ts index 17f168f6c..12470d86f 100644 --- a/packages/taco/src/conditions/schemas/return-value-test.ts +++ b/packages/taco/src/conditions/schemas/return-value-test.ts @@ -7,18 +7,37 @@ import { const returnValueTestBaseSchema = z.object({ index: z.number().int().nonnegative().optional(), - comparator: z.enum(['==', '>', '<', '>=', '<=', '!=']), + // TODO: should we add "!in"? + comparator: z.enum(['==', '>', '<', '>=', '<=', '!=', 'in', '!in']), }); -export const returnValueTestSchema = returnValueTestBaseSchema.extend({ - value: paramOrContextParamSchema, -}); +const requireNonEmptyArrayIfComparatorIsIn = (data: { + comparator: '==' | '>' | '<' | '>=' | '<=' | '!=' | 'in' | '!in'; + value?: unknown; + index?: number | undefined; +}): boolean => { + if (data.comparator === 'in' || data.comparator === '!in') { + return Array.isArray(data.value) && data.value.length > 0; + } + return true; +}; + +const inComparatorErrorConfig = { + message: `"value" must be a non-empty array when comparator is "in"/"!in"`, + path: ['value'], +}; + +export const returnValueTestSchema = returnValueTestBaseSchema + .extend({ + value: paramOrContextParamSchema, + }) + .refine(requireNonEmptyArrayIfComparatorIsIn, inComparatorErrorConfig); -export const blockchainReturnValueTestSchema = returnValueTestBaseSchema.extend( - { +export const blockchainReturnValueTestSchema = returnValueTestBaseSchema + .extend({ value: blockchainParamOrContextParamSchema, - }, -); + }) + .refine(requireNonEmptyArrayIfComparatorIsIn, inComparatorErrorConfig); export type ReturnValueTestProps = z.infer; diff --git a/packages/taco/test/conditions/base/time.test.ts b/packages/taco/test/conditions/base/time.test.ts index 06656301e..ada2c6289 100644 --- a/packages/taco/test/conditions/base/time.test.ts +++ b/packages/taco/test/conditions/base/time.test.ts @@ -30,31 +30,6 @@ describe('validation', () => { expect(result.data).toEqual(conditionObj); }); - it('rejects an invalid schema', () => { - const badObj = { - conditionType: TimeConditionType, - // Intentionally replacing `returnValueTest` with an invalid test - returnValueTest: { - ...returnValueTest, - comparator: 'not-a-comparator', - }, - chain: TEST_CHAIN_ID, - } as unknown as TimeConditionProps; - const result = TimeCondition.validate(timeConditionSchema, badObj); - - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error?.format()).toMatchObject({ - returnValueTest: { - comparator: { - _errors: [ - "Invalid enum value. Expected '==' | '>' | '<' | '>=' | '<=' | '!=', received 'not-a-comparator'", - ], - }, - }, - }); - }); - it('infers condition type from constructor', () => { const condition = new TimeCondition({ returnValueTest, diff --git a/packages/taco/test/conditions/return-value-test.test.ts b/packages/taco/test/conditions/return-value-test.test.ts new file mode 100644 index 000000000..00a251031 --- /dev/null +++ b/packages/taco/test/conditions/return-value-test.test.ts @@ -0,0 +1,68 @@ +import { describe, expect, it } from 'vitest'; + +import { + blockchainReturnValueTestSchema, + returnValueTestSchema, +} from '../../src/conditions/shared'; + +[blockchainReturnValueTestSchema, returnValueTestSchema].forEach((schema) => { + describe('validates schema', () => { + it('throws an error for invalid comparator', async () => { + const result = schema.safeParse({ + comparator: 'not-a-comparator', + value: 0, + }); + expect(result.success).toBe(false); + expect(result.error?.format()).toMatchObject({ + comparator: { + _errors: [ + "Invalid enum value. Expected '==' | '>' | '<' | '>=' | '<=' | '!=' | 'in' | '!in', received 'not-a-comparator'", + ], + }, + }); + }); + it.each([ + ['>', 0], + ['>=', 0], + ['<', 0], + ['<=', 0], + ['==', 0], + ['!=', 0], + ['in', ['value1', 'value2', 'value3']], + ['!in', ['value1', 'value2', 'value3']], + ])('valid comparator value combination', async (testComparator, value) => { + const result = schema.safeParse({ + comparator: testComparator, + value: value, + }); + expect(result.success).toBe(true); + expect(result.error).toBeUndefined(); + }); + it.each([ + ['in', 0], + ['in', 'string'], + ['in', true], + ['in', []], + ['!in', 0], + ['!in', 'string'], + ['!in', true], + ['!in', []], + ])( + 'must be a non-empty array value for "in"/"!in" operators', + async (testComparator, value) => { + const result = schema.safeParse({ + comparator: testComparator, + value: value, + }); + expect(result.success).toBe(false); + expect(result.error!.format()).toMatchObject({ + value: { + _errors: [ + '"value" must be a non-empty array when comparator is "in"/"!in"', + ], + }, + }); + }, + ); + }); +}); From 249244a64e98063dce338a065846e8f9ab9244c2 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 25 Jun 2025 11:12:40 -0400 Subject: [PATCH 093/303] Fix nested abi validation to be optional (either it or return value test should be specified). Improve human abi call signature validation check (wondering if there is a library out there that already does this) - there is one in python. --- .../taco/src/conditions/schemas/signing.ts | 68 +++++++++++++------ 1 file changed, 49 insertions(+), 19 deletions(-) diff --git a/packages/taco/src/conditions/schemas/signing.ts b/packages/taco/src/conditions/schemas/signing.ts index 540b8aee7..93a6f11ad 100644 --- a/packages/taco/src/conditions/schemas/signing.ts +++ b/packages/taco/src/conditions/schemas/signing.ts @@ -1,4 +1,4 @@ -import { FunctionFragment } from 'ethers/lib/utils'; +import { FunctionFragment, ParamType } from 'ethers/lib/utils'; import { z } from 'zod'; import { baseConditionSchema } from './common'; @@ -58,6 +58,7 @@ export const abiParameterValidationSchema: z.ZodSchema = z .describe('comparison check for value within calldata'), nestedAbiValidation: z .lazy(() => abiCallValidationSchema) + .optional() .describe('additional checks for nested abi calldata'), }) .refine( @@ -76,37 +77,66 @@ export type AbiParameterValidationProps = z.infer< typeof abiParameterValidationSchema >; -const isValidFunctionSignature = (signature: string): boolean => { +// TODO: is there something already built out there to validate Solidity types? +const isValidSolidityType = (param: ParamType): boolean => { + // Recursive check for valid Solidity types + if (!param.baseType || !param.baseType.trim()) { + return false; // empty type is not valid + } + + // Check for arrays and tuples + if (param.baseType === 'tuple') { + if (!param.components || param.components.length === 0) { + return false; // arrays and tuples must have components defined + } + return param.components.every(isValidSolidityType); + } else if (param.baseType === 'array') { + if (!param.arrayChildren) { + return false; // arrays must have children defined + } + return isValidSolidityType(param.arrayChildren); + } else { + // YIKES! + const solidityBaseTypePattern = + /^(u?int(8|16|24|32|40|48|56|64|72|80|88|96|104|112|120|128|136|144|152|160|168|176|184|192|200|208|216|224|232|240|248|256)?|bytes([1-9]|[1-2][0-9]|3[0-2])?|string|address|bool)$/; + return solidityBaseTypePattern.test(param.baseType); + } +}; + +// TODO; find a better way to validate the param type - incomplete best effort for now +const isValidHumanAbiCallSignature = (signature: string): boolean => { try { // TODO: verify this works properly const fragment = FunctionFragment.from(signature); - return fragment.format() === signature; // ensure the same sighash format was provided - } catch (error) { + for (const parameter of fragment.inputs) { + if (!isValidSolidityType(parameter)) { + return false; // invalid Solidity type + } + } + + // ensure the same sighash format was provided + return fragment.format() === signature; + } catch { return false; } }; +const humanAbiCallSignatureSchema = z + .string() + .refine(isValidHumanAbiCallSignature, { + message: 'Invalid human readable ABI signature provided', + }) + .describe('A human readable ABI signature, e.g. "transfer(address,uint256)"'); + export const abiCallValidationSchema: z.ZodSchema = z .object({ allowedAbiCalls: z.record( - z.string(), + humanAbiCallSignatureSchema, z.array(abiParameterValidationSchema), ), }) - .refine( - (abiCallValidation) => { - // validate human readable abi signature - const keys = Object.keys(abiCallValidation.allowedAbiCalls); - keys.forEach((abiSignature) => { - if (!isValidFunctionSignature(abiSignature)) { - return false; - } - }); - return true; - }, - { - message: 'Invalid ABI signature provided', - }, + .describe( + 'A map of allowed ABI calls with their respective parameter validations.', ); export type AbiCallValidationProps = z.infer; From 6862338b35020d2caf1cafdf40c8d9fd196d8132 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 25 Jun 2025 11:15:05 -0400 Subject: [PATCH 094/303] Add tests for SigningObjectAbiAttributeCondition including validation of abi call signatures. --- .../taco/test/conditions/base/signing.test.ts | 246 +++++++++++++++++- packages/taco/test/test-utils.ts | 43 +++ 2 files changed, 284 insertions(+), 5 deletions(-) diff --git a/packages/taco/test/conditions/base/signing.test.ts b/packages/taco/test/conditions/base/signing.test.ts index 09c59447f..e4d20736d 100644 --- a/packages/taco/test/conditions/base/signing.test.ts +++ b/packages/taco/test/conditions/base/signing.test.ts @@ -2,11 +2,17 @@ import { describe, expect, it } from 'vitest'; import { SIGNING_CONDITION_OBJECT_CONTEXT_VAR, + SigningObjectAbiAttributeCondition, + signingObjectAbiAttributeConditionSchema, + SigningObjectAbiAttributeConditionType, SigningObjectAttributeCondition, signingObjectAttributeConditionSchema, SigningObjectAttributeConditionType, } from '../../../src/conditions/base/signing'; -import { testSigningAttributeConditionObj } from '../../test-utils'; +import { + testSigningAttributeConditionObj, + testSigningObjectAbiAttributeConditionObj, +} from '../../test-utils'; describe('SigningObjectAttributeCondition', () => { describe('validation', () => { @@ -32,7 +38,7 @@ describe('SigningObjectAttributeCondition', () => { ); expect(result.error).toBeDefined(); expect(result.data).toBeUndefined(); - expect(result.error?.format()).toMatchObject({ + expect(result.error!.format()).toMatchObject({ conditionType: { _errors: ['Invalid literal value, expected "attribute"'], }, @@ -49,7 +55,7 @@ describe('SigningObjectAttributeCondition', () => { ); expect(result.error).toBeDefined(); expect(result.data).toBeUndefined(); - expect(result.error?.format()).toMatchObject({ + expect(result.error!.format()).toMatchObject({ signingObjectContextVar: { _errors: [ 'Invalid literal value, expected ":signingConditionObject"', @@ -70,7 +76,7 @@ describe('SigningObjectAttributeCondition', () => { ); expect(result.error).toBeDefined(); expect(result.data).toBeUndefined(); - expect(result.error?.format()).toMatchObject({ + expect(result.error!.format()).toMatchObject({ attributeName: { _errors: ['String must contain at least 1 character(s)'], }, @@ -89,7 +95,7 @@ describe('SigningObjectAttributeCondition', () => { ); expect(result.error).toBeDefined(); expect(result.data).toBeUndefined(); - expect(result.error?.format()).toMatchObject({ + expect(result.error!.format()).toMatchObject({ attributeName: { _errors: ['Expected string, received number'], }, @@ -117,3 +123,233 @@ describe('SigningObjectAttributeCondition', () => { }); }); }); + +describe('SigningObjectAbiAttributeCondition', () => { + describe('validation', () => { + it('accepts on a valid schema', () => { + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + testSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeUndefined(); + expect(result.data).toEqual(testSigningObjectAbiAttributeConditionObj); + }); + + describe('rejects an invalid schema', () => { + it('rejects invalid condition type', () => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + conditionType: 'myAttribute', + }; + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error!.format()).toMatchObject({ + conditionType: { + _errors: ['Invalid literal value, expected "abi-attribute"'], + }, + }); + }); + it('rejects invalid context variable', () => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + signingObjectContextVar: ':contextVar', + }; + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + signingObjectContextVar: { + _errors: [ + 'Invalid literal value, expected ":signingConditionObject"', + ], + }, + }); + }); + it('rejects empty attributeName', () => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + // Intentionally replacing `attributeName` with an invalid value + attributeName: '', + }; + + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error!.format()).toMatchObject({ + attributeName: { + _errors: ['String must contain at least 1 character(s)'], + }, + }); + }); + it('rejects invalid attributeName value type', () => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + // Intentionally replacing `attributeName` with an invalid value + attributeName: 100, + }; + + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error!.format()).toMatchObject({ + attributeName: { + _errors: ['Expected string, received number'], + }, + }); + }); + it.each([ + 'transfer(address,uint256)', + 'approve(address,uint256)', + 'transferFrom(address,address,uint256)', + 'mint(address,uint256)', + 'burn(uint256)', + 'baseTypes(bool,address,bytes,string)', + 'intTypes(int256,int128,int64,int32,int16,int8)', + 'uintTypes(uint208,uint176,uint128,uint48,uint40,uint24)', + 'bytesTypes(bytes1,bytes32,bytes32,bytes29,bytes7)', + 'otherTypes(uint256,uint128,int32,int8,bytes1,bytes24)', + 'tupleType((string,uint256,address))', + 'arrayType(uint256[],address[])', + 'tupleArrayType((string,int256,address)[])', + 'nestedTupleType(address,(string,uint256,(address,bool)))', + ])('accepts valid abi call signatures', (validAbiCallSignature) => { + const validSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + abiValidation: { + allowedAbiCalls: { + [validAbiCallSignature]: [], + }, + }, + }; + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + validSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeUndefined(); + expect(result.data).toBeDefined(); + }); + it.each([ + 'invalidSignature', + 'mint(address, uint256)', // no spaces + '123start(address,uint256)', // invalid function name + '!start(address,uint256)', // invalid function name + 'bad(!!!, address)', // invalid parameter type + 'transfer(address,uint257)', // invalid parameter type uint257 + 'intType(int23)', // invalid parameter type int23 + 'uintType(uint22)', // invalid parameter type uint22 + 'bytesTypes(bytes0)', // invalid bytes type + 'bytesTypes(bytes33)', // invalid bytes type + 'transfer(address,uint256', // missing closing parenthesis + 'execute(address,uint256,(address,uint256,bytes)', // mismatched paraentheses + 'function transferFrom(address from, address to, uint256 value)', // unsupported signature format + 'function transferFrom(address,address,uint256)', // unsupported signature format + 'event Transfer(address indexed from, address indexed to, address value)', // unsupported event signature + 'transfer(,uint256)', // empty parameter type + 'transfer(address,uint256) extra', // extra text after valid signature + ])('rejects invalid abi call signatures', (invalidAbiCallSignature) => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + abiValidation: { + allowedAbiCalls: { + [invalidAbiCallSignature]: [], + }, + }, + }; + + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error!.format()).toMatchObject({ + abiValidation: { + allowedAbiCalls: { + [invalidAbiCallSignature]: { + _errors: ['Invalid human readable ABI signature provided'], + }, + }, + }, + }); + }); + it('rejects invalid abiCallValidation: both returnValueTest and nestedValidation', () => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + abiValidation: { + allowedAbiCalls: { + 'execute((address,uint256,bytes))': [ + { + parameterIndex: 0, + indexWithinTuple: 0, + returnValueTest: { + comparator: '==', + value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', + }, + nestedAbiValidation: { + allowedAbiCalls: { + 'transfer(address,uint256)': [], + }, + }, + }, + ], + }, + }, + }; + + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error!.format()).toMatchObject({ + abiValidation: { + allowedAbiCalls: { + 'execute((address,uint256,bytes))': { + '0': { + returnValueTest: { + _errors: [ + "At most one of the fields 'returnValueTest' and 'nestedAbiValidation' must be defined", + ], + }, + }, + }, + }, + }, + }); + }); + }); + + it('infers condition type from constructor', () => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { conditionType, ...withoutType } = + testSigningObjectAbiAttributeConditionObj; + const condition = new SigningObjectAbiAttributeCondition(withoutType); + expect(condition.value.conditionType).toEqual( + SigningObjectAbiAttributeConditionType, + ); + }); + it('infers context variable from constructor', () => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { conditionType, signingObjectContextVar, ...withoutType } = + testSigningObjectAbiAttributeConditionObj; + const condition = new SigningObjectAbiAttributeCondition(withoutType); + expect(condition.value.signingObjectContextVar).toEqual( + SIGNING_CONDITION_OBJECT_CONTEXT_VAR, + ); + }); + }); +}); diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 61710432f..7e117620e 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -59,6 +59,9 @@ import { RpcConditionType, } from '../src/conditions/base/rpc'; import { + SIGNING_CONDITION_OBJECT_CONTEXT_VAR, + SigningObjectAbiAttributeConditionProps, + SigningObjectAbiAttributeConditionType, SigningObjectAttributeConditionProps, SigningObjectAttributeConditionType, } from '../src/conditions/base/signing'; @@ -362,6 +365,46 @@ export const testSigningAttributeConditionObj: SigningObjectAttributeConditionPr }, }; +// lots of nested abi calls +export const testSigningObjectAbiAttributeConditionObj: SigningObjectAbiAttributeConditionProps = + { + conditionType: SigningObjectAbiAttributeConditionType, + signingObjectContextVar: SIGNING_CONDITION_OBJECT_CONTEXT_VAR, + attributeName: 'callData', + abiValidation: { + allowedAbiCalls: { + 'execute((address,uint256,bytes))': [ + { + parameterIndex: 0, + indexWithinTuple: 0, + returnValueTest: { + comparator: '==', + value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', + }, + }, + { + parameterIndex: 0, + indexWithinTuple: 2, + nestedAbiValidation: { + allowedAbiCalls: { + 'execute(address,uint256,bytes)': [ + { + parameterIndex: 2, + nestedAbiValidation: { + allowedAbiCalls: { + 'transfer(address,uint256)': [], + }, + }, + }, + ], + }, + }, + }, + ], + }, + }, + }; + export const testFunctionAbi: FunctionAbiProps = { name: 'myFunction', type: 'function', From e26daf34692e3d1245a49bd0df2e31f8f6de14f5 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 25 Jun 2025 16:44:54 -0400 Subject: [PATCH 095/303] Improve validation of abi calls including processing of solidity types, and parameter and tuple indices. Add corresponding tests. --- .../taco/src/conditions/schemas/signing.ts | 116 ++- .../taco/test/conditions/base/signing.test.ts | 691 +++++++++++++----- packages/taco/test/test-utils.ts | 2 +- 3 files changed, 606 insertions(+), 203 deletions(-) diff --git a/packages/taco/src/conditions/schemas/signing.ts b/packages/taco/src/conditions/schemas/signing.ts index 93a6f11ad..67a308ed8 100644 --- a/packages/taco/src/conditions/schemas/signing.ts +++ b/packages/taco/src/conditions/schemas/signing.ts @@ -78,6 +78,33 @@ export type AbiParameterValidationProps = z.infer< >; // TODO: is there something already built out there to validate Solidity types? + +function generateSolidityBaseTypeRegExp(): RegExp { + // Generate a regex pattern for Solidity base types + + // Generate int/uint sizes (8, 16, ..., 256) + const intSizes = Array.from({ length: 32 }, (_, i) => (i + 1) * 8); // [8, 16, ..., 256] + const intSizePattern = intSizes.join('|'); + + // Generate bytes sizes (1, 2, ..., 32) + const bytesSizes = Array.from({ length: 32 }, (_, i) => i + 1); // [1, 2, ..., 32] + const bytesSizePattern = bytesSizes.join('|'); + + // Build the regex string + const baseTypes = [ + `u?int(${intSizePattern})?`, // uint8, uint16, ..., uint256, int8, int16, ..., int256 + `bytes(${bytesSizePattern})?`, // bytes1, bytes2, ..., bytes32 + 'string', + 'address', + 'bool', + ].join('|'); + + return new RegExp(`^(${baseTypes})$`); +} + +// YIKES! +const solidityBaseTypePattern = generateSolidityBaseTypeRegExp(); + const isValidSolidityType = (param: ParamType): boolean => { // Recursive check for valid Solidity types if (!param.baseType || !param.baseType.trim()) { @@ -87,18 +114,15 @@ const isValidSolidityType = (param: ParamType): boolean => { // Check for arrays and tuples if (param.baseType === 'tuple') { if (!param.components || param.components.length === 0) { - return false; // arrays and tuples must have components defined + return false; // tuples must have components defined } return param.components.every(isValidSolidityType); } else if (param.baseType === 'array') { if (!param.arrayChildren) { - return false; // arrays must have children defined + return false; // arrays must have children type defined } return isValidSolidityType(param.arrayChildren); } else { - // YIKES! - const solidityBaseTypePattern = - /^(u?int(8|16|24|32|40|48|56|64|72|80|88|96|104|112|120|128|136|144|152|160|168|176|184|192|200|208|216|224|232|240|248|256)?|bytes([1-9]|[1-2][0-9]|3[0-2])?|string|address|bool)$/; return solidityBaseTypePattern.test(param.baseType); } }; @@ -128,6 +152,73 @@ const humanAbiCallSignatureSchema = z }) .describe('A human readable ABI signature, e.g. "transfer(address,uint256)"'); +/** + * Validates the allowed ABI calls against the provided signature and validations. + * This function is used in the superRefine method of the abiCallValidationSchema. + * + * @param ctx - The Zod refinement context. + * @param signature - The ABI signature to validate against. + * @param validations - The array of validations for the ABI parameters. + */ +function validateAllowedAbiCall( + ctx: z.RefinementCtx, + signature: string, + validations: AbiParameterValidationProps[], +) { + try { + const fragment = FunctionFragment.from(signature); + for (const [index, validation] of validations.entries()) { + if (validation.parameterIndex >= fragment.inputs.length) { + // invalid parameter index + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `Parameter index, "${validation.parameterIndex}", is out of range`, + path: ['allowedAbiCalls', signature, index, 'parameterIndex'], + }); + } + + if (validation.indexWithinTuple !== undefined) { + const paramType = fragment.inputs[validation.parameterIndex]; + if (paramType.baseType !== 'tuple') { + // type at parameter index is not a tuple + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `Type at parameter index, "${validation.parameterIndex}", is not a tuple`, + path: ['allowedAbiCalls', signature, index, 'parameterIndex'], + }); + } else if (validation.indexWithinTuple >= paramType.components.length) { + // invalid index within tuple + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `Index within tuple, "${validation.indexWithinTuple}", is out of range`, + path: ['allowedAbiCalls', signature, index, 'indexWithinTuple'], + }); + } + } + + if (validation.nestedAbiValidation) { + // if there is nested ABI validation, the type must be bytes + let paramType = fragment.inputs[validation.parameterIndex]; + if (validation.indexWithinTuple !== undefined) { + // if there is an index within tuple, get the type of the component at that index + paramType = paramType.components[validation.indexWithinTuple]; + } + + if (paramType.baseType !== 'bytes') { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `Invalid type for nested ABI validation, "${paramType.baseType}"; expected bytes`, + path: ['allowedAbiCalls', signature, index], + }); + } + } + } + } catch { + // even though abi signatures are already validated by nested schema - zod uses “greedy” (continuable) validation so all validations are run + // ignore invalid ABI signature + } +} + export const abiCallValidationSchema: z.ZodSchema = z .object({ allowedAbiCalls: z.record( @@ -135,6 +226,21 @@ export const abiCallValidationSchema: z.ZodSchema = z z.array(abiParameterValidationSchema), ), }) + .refine( + (abiCallValidation) => + Object.keys(abiCallValidation.allowedAbiCalls).length > 0, + { + message: 'At least one allowed ABI call must be defined', + path: ['allowedAbiCalls'], + }, + ) + .superRefine((data, ctx) => { + for (const [signature, validations] of Object.entries( + data.allowedAbiCalls, + )) { + validateAllowedAbiCall(ctx, signature, validations); + } + }) .describe( 'A map of allowed ABI calls with their respective parameter validations.', ); diff --git a/packages/taco/test/conditions/base/signing.test.ts b/packages/taco/test/conditions/base/signing.test.ts index e4d20736d..72febfecf 100644 --- a/packages/taco/test/conditions/base/signing.test.ts +++ b/packages/taco/test/conditions/base/signing.test.ts @@ -125,179 +125,462 @@ describe('SigningObjectAttributeCondition', () => { }); describe('SigningObjectAbiAttributeCondition', () => { - describe('validation', () => { - it('accepts on a valid schema', () => { - const result = SigningObjectAbiAttributeCondition.validate( - signingObjectAbiAttributeConditionSchema, - testSigningObjectAbiAttributeConditionObj, - ); - expect(result.error).toBeUndefined(); - expect(result.data).toEqual(testSigningObjectAbiAttributeConditionObj); + it('accepts on a valid schema', () => { + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + testSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeUndefined(); + expect(result.data).toEqual(testSigningObjectAbiAttributeConditionObj); + }); + + it('rejects invalid condition type', () => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + conditionType: 'myAttribute', + }; + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error!.format()).toMatchObject({ + conditionType: { + _errors: ['Invalid literal value, expected "abi-attribute"'], + }, + }); + }); + it('rejects invalid context variable', () => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + signingObjectContextVar: ':contextVar', + }; + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + signingObjectContextVar: { + _errors: ['Invalid literal value, expected ":signingConditionObject"'], + }, }); + }); + it('rejects empty attributeName', () => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + // Intentionally replacing `attributeName` with an invalid value + attributeName: '', + }; - describe('rejects an invalid schema', () => { - it('rejects invalid condition type', () => { - const badSigningObjectAbiAttributeConditionObj = { - ...testSigningObjectAbiAttributeConditionObj, - conditionType: 'myAttribute', - }; - const result = SigningObjectAbiAttributeCondition.validate( - signingObjectAbiAttributeConditionSchema, - badSigningObjectAbiAttributeConditionObj, - ); - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error!.format()).toMatchObject({ - conditionType: { - _errors: ['Invalid literal value, expected "abi-attribute"'], - }, - }); - }); - it('rejects invalid context variable', () => { - const badSigningObjectAbiAttributeConditionObj = { - ...testSigningObjectAbiAttributeConditionObj, - signingObjectContextVar: ':contextVar', - }; - const result = SigningObjectAbiAttributeCondition.validate( - signingObjectAbiAttributeConditionSchema, - badSigningObjectAbiAttributeConditionObj, - ); - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error?.format()).toMatchObject({ - signingObjectContextVar: { - _errors: [ - 'Invalid literal value, expected ":signingConditionObject"', - ], + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error!.format()).toMatchObject({ + attributeName: { + _errors: ['String must contain at least 1 character(s)'], + }, + }); + }); + it('rejects invalid attributeName value type', () => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + // Intentionally replacing `attributeName` with an invalid value + attributeName: 100, + }; + + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error!.format()).toMatchObject({ + attributeName: { + _errors: ['Expected string, received number'], + }, + }); + }); + it.each([ + 'transfer(address,uint256)', + 'approve(address,uint256)', + 'transferFrom(address,address,uint256)', + 'mint(address,uint256)', + 'burn(uint256)', + 'baseTypes(bool,address,bytes,string)', + 'intTypes(int256,int128,int64,int32,int16,int8)', + 'uintTypes(uint208,uint176,uint128,uint48,uint40,uint24)', + 'bytesTypes(bytes1,bytes32,bytes32,bytes29,bytes7)', + 'otherTypes(uint256,uint128,int32,int8,bytes1,bytes24)', + 'tupleType((string,uint256,address))', + 'arrayType(uint256[],address[],bytes32[],bytes20[2],int24[3],string[4],bool[])', + 'tupleArrayType((string,int256,address)[],(address,uint8,bool)[9])', + 'nestedTupleType(address,(string,uint256,(address,bool)[],(bytes,bool)))', + ])('accepts valid abi call signatures', (validAbiCallSignature) => { + const validSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + abiValidation: { + allowedAbiCalls: { + [validAbiCallSignature]: [], + }, + }, + }; + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + validSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeUndefined(); + expect(result.data).toBeDefined(); + }); + it.each([ + 'invalidSignature', + 'mint(address, uint256)', // no spaces + '123start(address,uint256)', // invalid function name + '!start(address,uint256)', // invalid function name + 'bad(!!!, address)', // invalid parameter type + 'transfer(address,uint257)', // invalid parameter type uint257 + 'intType(int23)', // invalid parameter type int23 + 'uintType(uint22)', // invalid parameter type uint22 + 'bytesTypes(bytes0)', // invalid bytes type + 'bytesTypes(bytes33)', // invalid bytes type + 'transfer(address,uint256', // missing closing parenthesis + 'execute(address,uint256,(address,uint256,bytes)', // mismatched paraentheses + 'function transferFrom(address from, address to, uint256 value)', // unsupported signature format + 'function transferFrom(address,address,uint256)', // unsupported signature format + 'event Transfer(address indexed from, address indexed to, address value)', // unsupported event signature + 'transfer(,uint256)', // empty parameter type + 'transfer(address,uint256) extra', // extra text after valid signature + ])('rejects invalid abi call signatures', (invalidAbiCallSignature) => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + abiValidation: { + allowedAbiCalls: { + [invalidAbiCallSignature]: [], + }, + }, + }; + + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error!.format()).toMatchObject({ + abiValidation: { + allowedAbiCalls: { + [invalidAbiCallSignature]: { + _errors: ['Invalid human readable ABI signature provided'], }, - }); - }); - it('rejects empty attributeName', () => { - const badSigningObjectAbiAttributeConditionObj = { - ...testSigningObjectAbiAttributeConditionObj, - // Intentionally replacing `attributeName` with an invalid value - attributeName: '', - }; + }, + }, + }); + }); + it('rejects invalid abiCallValidation: both returnValueTest and nestedValidation', () => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + abiValidation: { + allowedAbiCalls: { + 'execute((address,uint256,bytes))': [ + { + parameterIndex: 0, + indexWithinTuple: 0, + returnValueTest: { + comparator: '==', + value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', + }, + nestedAbiValidation: { + allowedAbiCalls: { + 'transfer(address,uint256)': [], + }, + }, + }, + ], + }, + }, + }; - const result = SigningObjectAbiAttributeCondition.validate( - signingObjectAbiAttributeConditionSchema, - badSigningObjectAbiAttributeConditionObj, - ); - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error!.format()).toMatchObject({ - attributeName: { - _errors: ['String must contain at least 1 character(s)'], + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error!.format()).toMatchObject({ + abiValidation: { + allowedAbiCalls: { + 'execute((address,uint256,bytes))': { + '0': { + returnValueTest: { + _errors: [ + "At most one of the fields 'returnValueTest' and 'nestedAbiValidation' must be defined", + ], + }, + }, }, - }); - }); - it('rejects invalid attributeName value type', () => { - const badSigningObjectAbiAttributeConditionObj = { - ...testSigningObjectAbiAttributeConditionObj, - // Intentionally replacing `attributeName` with an invalid value - attributeName: 100, - }; + }, + }, + }); + }); + it('rejects invalid parameterIndex in abiCallValidation', () => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + abiValidation: { + allowedAbiCalls: { + 'execute(address,uint256,bytes)': [ + { + parameterIndex: 3, + returnValueTest: { + comparator: '==', + value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', + }, + }, + ], + }, + }, + }; + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error!.format()).toMatchObject({ + abiValidation: { + allowedAbiCalls: { + 'execute(address,uint256,bytes)': { + '0': { + parameterIndex: { + _errors: ['Parameter index, "3", is out of range'], + }, + }, + }, + }, + }, + }); + }); - const result = SigningObjectAbiAttributeCondition.validate( - signingObjectAbiAttributeConditionSchema, - badSigningObjectAbiAttributeConditionObj, - ); - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error!.format()).toMatchObject({ - attributeName: { - _errors: ['Expected string, received number'], + it('rejects invalid tuple type at parameterIndex in abiCallValidation', () => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + abiValidation: { + allowedAbiCalls: { + 'execute(address,uint256,bytes)': [ + { + parameterIndex: 0, + indexWithinTuple: 0, + returnValueTest: { + comparator: '==', + value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', + }, + }, + ], + }, + }, + }; + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error!.format()).toMatchObject({ + abiValidation: { + allowedAbiCalls: { + 'execute(address,uint256,bytes)': { + '0': { + parameterIndex: { + _errors: ['Type at parameter index, "0", is not a tuple'], + }, + }, }, - }); - }); - it.each([ - 'transfer(address,uint256)', - 'approve(address,uint256)', - 'transferFrom(address,address,uint256)', - 'mint(address,uint256)', - 'burn(uint256)', - 'baseTypes(bool,address,bytes,string)', - 'intTypes(int256,int128,int64,int32,int16,int8)', - 'uintTypes(uint208,uint176,uint128,uint48,uint40,uint24)', - 'bytesTypes(bytes1,bytes32,bytes32,bytes29,bytes7)', - 'otherTypes(uint256,uint128,int32,int8,bytes1,bytes24)', - 'tupleType((string,uint256,address))', - 'arrayType(uint256[],address[])', - 'tupleArrayType((string,int256,address)[])', - 'nestedTupleType(address,(string,uint256,(address,bool)))', - ])('accepts valid abi call signatures', (validAbiCallSignature) => { - const validSigningObjectAbiAttributeConditionObj = { - ...testSigningObjectAbiAttributeConditionObj, - abiValidation: { - allowedAbiCalls: { - [validAbiCallSignature]: [], + }, + }, + }); + }); + it('rejects invalid tuple index in abiCallValidation', () => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + abiValidation: { + allowedAbiCalls: { + 'execute((address,uint256,bytes))': [ + { + parameterIndex: 0, + indexWithinTuple: 3, + returnValueTest: { + comparator: '==', + value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', + }, + }, + ], + }, + }, + }; + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error!.format()).toMatchObject({ + abiValidation: { + allowedAbiCalls: { + 'execute((address,uint256,bytes))': { + '0': { + indexWithinTuple: { + _errors: [`Index within tuple, "3", is out of range`], + }, }, }, - }; - const result = SigningObjectAbiAttributeCondition.validate( - signingObjectAbiAttributeConditionSchema, - validSigningObjectAbiAttributeConditionObj, - ); - expect(result.error).toBeUndefined(); - expect(result.data).toBeDefined(); - }); - it.each([ - 'invalidSignature', - 'mint(address, uint256)', // no spaces - '123start(address,uint256)', // invalid function name - '!start(address,uint256)', // invalid function name - 'bad(!!!, address)', // invalid parameter type - 'transfer(address,uint257)', // invalid parameter type uint257 - 'intType(int23)', // invalid parameter type int23 - 'uintType(uint22)', // invalid parameter type uint22 - 'bytesTypes(bytes0)', // invalid bytes type - 'bytesTypes(bytes33)', // invalid bytes type - 'transfer(address,uint256', // missing closing parenthesis - 'execute(address,uint256,(address,uint256,bytes)', // mismatched paraentheses - 'function transferFrom(address from, address to, uint256 value)', // unsupported signature format - 'function transferFrom(address,address,uint256)', // unsupported signature format - 'event Transfer(address indexed from, address indexed to, address value)', // unsupported event signature - 'transfer(,uint256)', // empty parameter type - 'transfer(address,uint256) extra', // extra text after valid signature - ])('rejects invalid abi call signatures', (invalidAbiCallSignature) => { - const badSigningObjectAbiAttributeConditionObj = { - ...testSigningObjectAbiAttributeConditionObj, - abiValidation: { - allowedAbiCalls: { - [invalidAbiCallSignature]: [], + }, + }, + }); + }); + it('rejects invalid nested parameter index in abiCallValidation', () => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + abiValidation: { + allowedAbiCalls: { + 'execute((address,uint256,bytes))': [ + { + parameterIndex: 0, + indexWithinTuple: 2, + nestedAbiValidation: { + allowedAbiCalls: { + 'execute(address,uint256,bytes)': [ + { + parameterIndex: 4, + returnValueTest: { + comparator: '==', + value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', + }, + }, + ], + }, + }, + }, + ], + }, + }, + }; + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error!.format()).toMatchObject({ + abiValidation: { + allowedAbiCalls: { + 'execute((address,uint256,bytes))': { + '0': { + nestedAbiValidation: { + allowedAbiCalls: { + 'execute(address,uint256,bytes)': { + '0': { + parameterIndex: { + _errors: [`Parameter index, "4", is out of range`], + }, + }, + }, + }, + }, }, }, - }; - - const result = SigningObjectAbiAttributeCondition.validate( - signingObjectAbiAttributeConditionSchema, - badSigningObjectAbiAttributeConditionObj, - ); - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error!.format()).toMatchObject({ - abiValidation: { - allowedAbiCalls: { - [invalidAbiCallSignature]: { - _errors: ['Invalid human readable ABI signature provided'], + }, + }, + }); + }); + it('rejects nested abi validation for non-bytes type in abiCallValidation', () => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + abiValidation: { + allowedAbiCalls: { + 'execute((address,uint256,bytes))': [ + { + parameterIndex: 0, + indexWithinTuple: 1, // index of uint256 + nestedAbiValidation: { + allowedAbiCalls: { + 'execute(address,uint256,bytes)': [ + { + parameterIndex: 0, + returnValueTest: { + comparator: '==', + value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', + }, + }, + ], + }, }, }, + ], + }, + }, + }; + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error!.format()).toMatchObject({ + abiValidation: { + allowedAbiCalls: { + 'execute((address,uint256,bytes))': { + '0': { + _errors: [ + `Invalid type for nested ABI validation, "uint256"; expected bytes`, + ], + }, }, - }); - }); - it('rejects invalid abiCallValidation: both returnValueTest and nestedValidation', () => { - const badSigningObjectAbiAttributeConditionObj = { - ...testSigningObjectAbiAttributeConditionObj, - abiValidation: { + }, + }, + }); + }); + + it('infers condition type from constructor', () => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { conditionType, ...withoutType } = + testSigningObjectAbiAttributeConditionObj; + const condition = new SigningObjectAbiAttributeCondition(withoutType); + expect(condition.value.conditionType).toEqual( + SigningObjectAbiAttributeConditionType, + ); + }); + it('infers context variable from constructor', () => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { conditionType, signingObjectContextVar, ...withoutType } = + testSigningObjectAbiAttributeConditionObj; + const condition = new SigningObjectAbiAttributeCondition(withoutType); + expect(condition.value.signingObjectContextVar).toEqual( + SIGNING_CONDITION_OBJECT_CONTEXT_VAR, + ); + }); + it('handles ridiculously complex abi validation', () => { + const executeTupleAbiCallValidation: Record = { + 'execute((address,uint256,bytes))': [ + { + parameterIndex: 0, + indexWithinTuple: 0, + returnValueTest: { + comparator: '==', + value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', + }, + }, + { + parameterIndex: 0, + indexWithinTuple: 2, + nestedAbiValidation: { allowedAbiCalls: { - 'execute((address,uint256,bytes))': [ + 'execute(address,uint256,bytes)': [ { - parameterIndex: 0, - indexWithinTuple: 0, - returnValueTest: { - comparator: '==', - value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', - }, + parameterIndex: 2, nestedAbiValidation: { allowedAbiCalls: { 'transfer(address,uint256)': [], @@ -307,49 +590,63 @@ describe('SigningObjectAbiAttributeCondition', () => { ], }, }, - }; + }, + ], + }; - const result = SigningObjectAbiAttributeCondition.validate( - signingObjectAbiAttributeConditionSchema, - badSigningObjectAbiAttributeConditionObj, - ); - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error!.format()).toMatchObject({ - abiValidation: { - allowedAbiCalls: { - 'execute((address,uint256,bytes))': { - '0': { - returnValueTest: { - _errors: [ - "At most one of the fields 'returnValueTest' and 'nestedAbiValidation' must be defined", - ], - }, + const ridiculousNestingObj = { + conditionType: SigningObjectAbiAttributeConditionType, + signingObjectContextVar: SIGNING_CONDITION_OBJECT_CONTEXT_VAR, + attributeName: 'callData', + abiValidation: { + allowedAbiCalls: { + 'approve(address,uint256)': [], + 'transfer(address,uint256)': [ + { + parameterIndex: 0, + returnValueTest: { + comparator: '==', + value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', + }, + }, + { + parameterIndex: 1, + returnValueTest: { + comparator: '<', + value: BigInt('1000000000'), + }, + }, + ], + 'execute(address,uint256,bytes)': [ + { + parameterIndex: 2, + returnValueTest: { + comparator: '==', + value: 0, + }, + }, + { + parameterIndex: 2, + nestedAbiValidation: { + allowedAbiCalls: { + 'transfer(address,uint256)': [], + 'approve(address,uint256)': [], + ...executeTupleAbiCallValidation, }, }, }, - }, - }); - }); - }); - - it('infers condition type from constructor', () => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { conditionType, ...withoutType } = - testSigningObjectAbiAttributeConditionObj; - const condition = new SigningObjectAbiAttributeCondition(withoutType); - expect(condition.value.conditionType).toEqual( - SigningObjectAbiAttributeConditionType, - ); - }); - it('infers context variable from constructor', () => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { conditionType, signingObjectContextVar, ...withoutType } = - testSigningObjectAbiAttributeConditionObj; - const condition = new SigningObjectAbiAttributeCondition(withoutType); - expect(condition.value.signingObjectContextVar).toEqual( - SIGNING_CONDITION_OBJECT_CONTEXT_VAR, - ); - }); + ], + 'mint(address,uint256)': [], + 'burn(uint256)': [], + ...executeTupleAbiCallValidation, + }, + }, + }; + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + ridiculousNestingObj, + ); + expect(result.error).toBeUndefined(); + expect(result.data).toEqual(ridiculousNestingObj); }); }); diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 7e117620e..27716d1df 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -365,7 +365,7 @@ export const testSigningAttributeConditionObj: SigningObjectAttributeConditionPr }, }; -// lots of nested abi calls +// some nested abi calls export const testSigningObjectAbiAttributeConditionObj: SigningObjectAbiAttributeConditionProps = { conditionType: SigningObjectAbiAttributeConditionType, From fb07524988b06cd981a5e62beee006bfb24bf6aa Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 26 Jun 2025 12:08:31 -0400 Subject: [PATCH 096/303] Remove addressed TODO for !in comparator. --- packages/taco/src/conditions/schemas/return-value-test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/taco/src/conditions/schemas/return-value-test.ts b/packages/taco/src/conditions/schemas/return-value-test.ts index 12470d86f..f978a33e2 100644 --- a/packages/taco/src/conditions/schemas/return-value-test.ts +++ b/packages/taco/src/conditions/schemas/return-value-test.ts @@ -7,7 +7,6 @@ import { const returnValueTestBaseSchema = z.object({ index: z.number().int().nonnegative().optional(), - // TODO: should we add "!in"? comparator: z.enum(['==', '>', '<', '>=', '<=', '!=', 'in', '!in']), }); From eb5a565e11ef4433f7ce95e728051b162a9bf9b1 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 26 Jun 2025 14:24:56 -0400 Subject: [PATCH 097/303] Add SigningObjectAttributeCondition and SigningObjectAbiAttributeCondition objects to anyConditionSchema and to ConditionFactory resolution. --- .../taco/src/conditions/condition-factory.ts | 16 ++++++++++++++++ packages/taco/src/conditions/schemas/utils.ts | 8 +++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/taco/src/conditions/condition-factory.ts b/packages/taco/src/conditions/condition-factory.ts index 190e0a30c..3e2a599ff 100644 --- a/packages/taco/src/conditions/condition-factory.ts +++ b/packages/taco/src/conditions/condition-factory.ts @@ -20,6 +20,14 @@ import { } from './base/json-rpc'; import { JWTCondition, JWTConditionProps, JWTConditionType } from './base/jwt'; import { RpcCondition, RpcConditionProps, RpcConditionType } from './base/rpc'; +import { + SigningObjectAbiAttributeCondition, + SigningObjectAbiAttributeConditionProps, + SigningObjectAbiAttributeConditionType, + SigningObjectAttributeCondition, + SigningObjectAttributeConditionProps, + SigningObjectAttributeConditionType, +} from './base/signing'; import { TimeCondition, TimeConditionProps, @@ -65,6 +73,14 @@ export class ConditionFactory { return new AddressAllowlistCondition( props as AddressAllowlistConditionProps, ); + case SigningObjectAttributeConditionType: + return new SigningObjectAttributeCondition( + props as SigningObjectAttributeConditionProps, + ); + case SigningObjectAbiAttributeConditionType: + return new SigningObjectAbiAttributeCondition( + props as SigningObjectAbiAttributeConditionProps, + ); // Logical Conditions case CompoundConditionType: return new CompoundCondition(props as CompoundConditionProps); diff --git a/packages/taco/src/conditions/schemas/utils.ts b/packages/taco/src/conditions/schemas/utils.ts index 61ecfb610..57e212931 100644 --- a/packages/taco/src/conditions/schemas/utils.ts +++ b/packages/taco/src/conditions/schemas/utils.ts @@ -10,6 +10,10 @@ import { jsonRpcConditionSchema } from './json-rpc'; import { jwtConditionSchema } from './jwt'; import { rpcConditionSchema } from './rpc'; import { sequentialConditionSchema } from './sequential'; +import { + signingObjectAbiAttributeConditionSchema, + signingObjectAttributeConditionSchema, +} from './signing'; import { timeConditionSchema } from './time'; export const anyConditionSchema: z.ZodSchema = z.lazy(() => @@ -18,10 +22,12 @@ export const anyConditionSchema: z.ZodSchema = z.lazy(() => timeConditionSchema, addressAllowlistConditionSchema, contractConditionSchema, - compoundConditionSchema, jsonApiConditionSchema, jsonRpcConditionSchema, jwtConditionSchema, + signingObjectAttributeConditionSchema, + signingObjectAbiAttributeConditionSchema, + compoundConditionSchema, sequentialConditionSchema, ifThenElseConditionSchema, ]), From fec2465f7b52abc8104b52ccca18b0518459bce9 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 26 Jun 2025 14:26:22 -0400 Subject: [PATCH 098/303] Rename test signing object attribute conditiont test object. --- .../taco/test/conditions/base/signing.test.ts | 18 +++++++++--------- packages/taco/test/test-utils.ts | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/taco/test/conditions/base/signing.test.ts b/packages/taco/test/conditions/base/signing.test.ts index 72febfecf..77ab42298 100644 --- a/packages/taco/test/conditions/base/signing.test.ts +++ b/packages/taco/test/conditions/base/signing.test.ts @@ -10,8 +10,8 @@ import { SigningObjectAttributeConditionType, } from '../../../src/conditions/base/signing'; import { - testSigningAttributeConditionObj, testSigningObjectAbiAttributeConditionObj, + testSigningObjectAttributeConditionObj, } from '../../test-utils'; describe('SigningObjectAttributeCondition', () => { @@ -19,17 +19,17 @@ describe('SigningObjectAttributeCondition', () => { it('accepts on a valid schema', () => { const result = SigningObjectAttributeCondition.validate( signingObjectAttributeConditionSchema, - testSigningAttributeConditionObj, + testSigningObjectAttributeConditionObj, ); expect(result.error).toBeUndefined(); - expect(result.data).toEqual(testSigningAttributeConditionObj); + expect(result.data).toEqual(testSigningObjectAttributeConditionObj); }); describe('rejects an invalid schema', () => { it('rejects invalid condition type', () => { const badSigningAttributeConditionObj = { - ...testSigningAttributeConditionObj, + ...testSigningObjectAttributeConditionObj, conditionType: 'myAttribute', }; const result = SigningObjectAttributeCondition.validate( @@ -46,7 +46,7 @@ describe('SigningObjectAttributeCondition', () => { }); it('rejects invalid context variable', () => { const badSigningAttributeConditionObj = { - ...testSigningAttributeConditionObj, + ...testSigningObjectAttributeConditionObj, signingObjectContextVar: ':contextVar', }; const result = SigningObjectAttributeCondition.validate( @@ -65,7 +65,7 @@ describe('SigningObjectAttributeCondition', () => { }); it('rejects empty attributeName', () => { const badSigningAttributeConditionObj = { - ...testSigningAttributeConditionObj, + ...testSigningObjectAttributeConditionObj, // Intentionally replacing `attributeName` with an invalid value attributeName: '', }; @@ -84,7 +84,7 @@ describe('SigningObjectAttributeCondition', () => { }); it('rejects invalid attributeName value type', () => { const badSigningAttributeConditionObj = { - ...testSigningAttributeConditionObj, + ...testSigningObjectAttributeConditionObj, // Intentionally replacing `attributeName` with an invalid value attributeName: 100, }; @@ -106,7 +106,7 @@ describe('SigningObjectAttributeCondition', () => { it('infers condition type from constructor', () => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { conditionType, ...withoutType } = - testSigningAttributeConditionObj; + testSigningObjectAttributeConditionObj; const condition = new SigningObjectAttributeCondition(withoutType); expect(condition.value.conditionType).toEqual( SigningObjectAttributeConditionType, @@ -115,7 +115,7 @@ describe('SigningObjectAttributeCondition', () => { it('infers context variable from constructor', () => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { conditionType, signingObjectContextVar, ...withoutType } = - testSigningAttributeConditionObj; + testSigningObjectAttributeConditionObj; const condition = new SigningObjectAttributeCondition(withoutType); expect(condition.value.signingObjectContextVar).toEqual( SIGNING_CONDITION_OBJECT_CONTEXT_VAR, diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 27716d1df..70a5f2754 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -354,7 +354,7 @@ export const testSequentialConditionObj: SequentialConditionProps = { ], }; -export const testSigningAttributeConditionObj: SigningObjectAttributeConditionProps = +export const testSigningObjectAttributeConditionObj: SigningObjectAttributeConditionProps = { conditionType: SigningObjectAttributeConditionType, signingObjectContextVar: ':signingConditionObject', From ff6fcfcb0ddaad14f43e86631c0fe34ecf6e0ca1 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 26 Jun 2025 14:27:09 -0400 Subject: [PATCH 099/303] Add context tests for determining context variable within signing object conditions. --- packages/taco/test/conditions/context.test.ts | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/packages/taco/test/conditions/context.test.ts b/packages/taco/test/conditions/context.test.ts index e0fb34840..f76307798 100644 --- a/packages/taco/test/conditions/context.test.ts +++ b/packages/taco/test/conditions/context.test.ts @@ -35,6 +35,7 @@ import { import { RESERVED_CONTEXT_PARAMS } from '../../src/conditions/context/context'; import { IfThenElseConditionType } from '../../src/conditions/if-then-else-condition'; import { blockchainParamOrContextParamSchema } from '../../src/conditions/schemas/context'; +import { SIGNING_CONDITION_OBJECT_CONTEXT_VAR } from '../../src/conditions/schemas/signing'; import { SequentialConditionType } from '../../src/conditions/sequential'; import { paramOrContextParamSchema } from '../../src/conditions/shared'; import { fromJSON, toJSON } from '../../src/utils'; @@ -46,6 +47,8 @@ import { testJsonRpcConditionObj, testRpcConditionObj, testRpcReturnValueTest, + testSigningObjectAbiAttributeConditionObj, + testSigningObjectAttributeConditionObj, testTimeConditionObj, UINT256_MAX, } from '../test-utils'; @@ -934,6 +937,14 @@ describe('recognition of context variables in conditions', () => { returnValueTest: rvt, }; + const signingObjectAttributeCondition = { + ...testSigningObjectAttributeConditionObj, + }; + + const signingObjectAbiAttributeCondition = { + ...testSigningObjectAbiAttributeConditionObj, + }; + it('handles context params for rpc condition', () => { const condition = ConditionFactory.conditionFromProps(rpcCondition); const conditionContext = new ConditionContext(condition); @@ -1012,6 +1023,28 @@ describe('recognition of context variables in conditions', () => { ]), ); }); + it('handles context params for signing object attribute condition', () => { + const condition = ConditionFactory.conditionFromProps( + signingObjectAttributeCondition, + ); + const conditionContext = new ConditionContext(condition); + + // Verify all context parameters are detected + expect(conditionContext.requestedContextParameters).toEqual( + new Set([SIGNING_CONDITION_OBJECT_CONTEXT_VAR]), + ); + }); + it('handles context params for signing object abi attribute condition', () => { + const condition = ConditionFactory.conditionFromProps( + signingObjectAbiAttributeCondition, + ); + const conditionContext = new ConditionContext(condition); + + // Verify all context parameters are detected + expect(conditionContext.requestedContextParameters).toEqual( + new Set([SIGNING_CONDITION_OBJECT_CONTEXT_VAR]), + ); + }); it.each([ { conditionType: SequentialConditionType, @@ -1045,6 +1078,14 @@ describe('recognition of context variables in conditions', () => { varName: 'jsonRpcParamsArray', condition: jsonRpcConditionParamsArray, }, + { + varName: 'signingObjectAttribute', + condition: signingObjectAttributeCondition, + }, + { + varName: 'signingObjectAbiAttribute', + condition: signingObjectAbiAttributeCondition, + }, ], }, }, @@ -1100,6 +1141,7 @@ describe('recognition of context variables in conditions', () => { ':queryKey', ':authToken', ':expectedResult', + SIGNING_CONDITION_OBJECT_CONTEXT_VAR, ]), ); }); From ec0809a883fae9fb249585b089e5c5907b511d85 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 1 Jul 2025 11:51:55 +0200 Subject: [PATCH 100/303] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(shared):?= =?UTF-8?q?=20follow=20tacoDecrypt=20pattern=20for=20error=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove throw for mismatched message hashes - Include signature processing errors in result errors instead - Add try-catch for signature decoding failures - Continue processing other signatures when one fails - Let caller decide how to handle errors based on SignResult --- packages/shared/src/porter.ts | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index 60a884e6a..986533815 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -345,18 +345,24 @@ export class PorterClient { const { signatures, errors } = resp.data.result.signing_results; const signingResults: { [ursulaAddress: string]: [string, string] } = {}; + const allErrors: Record = { ...errors }; let messageHash = ''; // Process signatures - decode the JSON payload to extract message hash and signature for (const [ursulaAddress, [signerAddress, signatureB64]] of Object.entries(signatures || {})) { - const decodedData = JSON.parse( - new TextDecoder().decode(fromBase64(signatureB64)) - ); - if (messageHash && messageHash !== decodedData.message_hash) { - throw new Error('Mismatched message hashes'); + try { + const decodedData = JSON.parse( + new TextDecoder().decode(fromBase64(signatureB64)) + ); + if (messageHash && messageHash !== decodedData.message_hash) { + allErrors[ursulaAddress] = 'Mismatched message hash'; + continue; + } + messageHash = decodedData.message_hash; + signingResults[ursulaAddress] = [signerAddress, decodedData.signature]; + } catch (error) { + allErrors[ursulaAddress] = `Failed to decode signature: ${error}`; } - messageHash = decodedData.message_hash; - signingResults[ursulaAddress] = [signerAddress, decodedData.signature]; } const aggregatedSignature = Object.keys(signingResults).length >= threshold @@ -367,7 +373,7 @@ export class PorterClient { messageHash, aggregatedSignature, signingResults, - errors: errors || {}, + errors: allErrors, }; } } \ No newline at end of file From 769290cc173099af485711af81145678022acb41 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 26 Jun 2025 14:30:44 -0400 Subject: [PATCH 101/303] Regenerate condition schema docs. --- .../taco/schema-docs/condition-schemas.md | 67 +++++++++++++++++-- .../schemas/export-for-zod-doc-gen.ts | 1 + .../taco/src/conditions/schemas/signing.ts | 8 +-- 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index 4603e4114..c0bf37680 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -8,10 +8,12 @@ _Union of the following possible types:_ - [TimeCondition](#timecondition) - [AddressAllowlistCondition](#addressallowlistcondition) - [ContractCondition](#contractcondition) -- [CompoundCondition](#compoundcondition) - [JsonApiCondition](#jsonapicondition) - [JsonRpcCondition](#jsonrpccondition) - [JwtCondition](#jwtcondition) +- [SigningObjectAttributeCondition](#signingobjectattributecondition) +- [SigningObjectAbiAttributeCondition](#signingobjectabiattributecondition) +- [CompoundCondition](#compoundcondition) - [SequentialCondition](#sequentialcondition) - [IfThenElseCondition](#ifthenelsecondition) @@ -188,7 +190,7 @@ _Object containing the following properties:_ | Property | Type | | :-------------------- | :-------------------------------------------------------------- | | `index` | `number` (_int, ≥0_) | -| **`comparator`** (\*) | `'==' \| '>' \| '<' \| '>=' \| '<=' \| '!='` | +| **`comparator`** (\*) | `'==' \| '>' \| '<' \| '>=' \| '<=' \| '!=' \| 'in' \| '!in'` | | **`value`** (\*) | [BlockchainParamOrContextParam](#blockchainparamorcontextparam) | _(\*) Required._ @@ -197,11 +199,11 @@ _(\*) Required._ _Object containing the following properties:_ -| Property | Type | -| :-------------------- | :------------------------------------------- | -| `index` | `number` (_int, ≥0_) | -| **`comparator`** (\*) | `'==' \| '>' \| '<' \| '>=' \| '<=' \| '!='` | -| **`value`** (\*) | [ParamOrContextParam](#paramorcontextparam) | +| Property | Type | +| :-------------------- | :------------------------------------------------------------ | +| `index` | `number` (_int, ≥0_) | +| **`comparator`** (\*) | `'==' \| '>' \| '<' \| '>=' \| '<=' \| '!=' \| 'in' \| '!in'` | +| **`value`** (\*) | [ParamOrContextParam](#paramorcontextparam) | _(\*) Required._ @@ -243,6 +245,57 @@ _Object containing the following properties:_ _(\*) Required._ +## AbiCallValidation + +A map of allowed ABI calls with their respective parameter validations. + +_Object containing the following properties:_ + +| Property | Type | +| :------------------------- | :---------------------------------------------------------------------------------------------------------------------------------- | +| **`allowedAbiCalls`** (\*) | _Object with dynamic keys of type_ `string` _and values of type_ _Array of [AbiParameterValidation](#abiparametervalidation) items_ | + +_(\*) Required._ + +## AbiParameterValidation + +_Object containing the following properties:_ + +| Property | Description | Type | +| :------------------------ | :------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **`parameterIndex`** (\*) | Index of parameter to check within abi calldata. | `number` (_int, ≥0_) | +| `indexWithinTuple` | Index of value within tuple value at parameter index to check | `number` (_int, ≥0_) | +| `returnValueTest` | Comparison check for value within calldata | [BlockchainReturnValueTest](#blockchainreturnvaluetest) | +| `nestedAbiValidation` | Additional checks for nested abi calldata | _Object with properties:_

| + +_(\*) Required._ + +## SigningObjectAbiAttributeCondition + +_Object containing the following properties:_ + +| Property | Description | Type | Default | +| :------------------------ | :---------------------------------------------------------------------------- | :-------------------------------------- | :-------------------------- | +| `conditionType` | | `'abi-attribute'` | `'abi-attribute'` | +| `signingObjectContextVar` | The context variable that will be replaced with the signing object at signing | `':signingConditionObject'` | `':signingConditionObject'` | +| **`attributeName`** (\*) | The name of the attribute to check | `string` (_min length: 1_) | | +| **`abiValidation`** (\*) | A map of allowed ABI calls with their respective parameter validations. | [AbiCallValidation](#abicallvalidation) | | + +_(\*) Required._ + +## SigningObjectAttributeCondition + +_Object containing the following properties:_ + +| Property | Description | Type | Default | +| :------------------------- | :---------------------------------------------------------------------------- | :------------------------------------------------------ | :-------------------------- | +| `conditionType` | | `'attribute'` | `'attribute'` | +| `signingObjectContextVar` | The context variable that will be replaced with the signing object at signing | `':signingConditionObject'` | `':signingConditionObject'` | +| **`attributeName`** (\*) | The name of the attribute to check | `string` (_min length: 1_) | | +| **`returnValueTest`** (\*) | | [BlockchainReturnValueTest](#blockchainreturnvaluetest) | | + +_(\*) Required._ + ## TimeCondition _Object containing the following properties:_ diff --git a/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts b/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts index 7fff168cc..453fd8b2c 100755 --- a/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts +++ b/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts @@ -18,6 +18,7 @@ export * from './jwt'; export * from './return-value-test'; export * from './rpc'; export * from './sequential'; +export * from './signing'; export * from './time'; // ts-unused-exports:disable-next-line - this comment line is added to prevent lint from changing or objecting the export order. export * from './address-allowlist'; diff --git a/packages/taco/src/conditions/schemas/signing.ts b/packages/taco/src/conditions/schemas/signing.ts index 67a308ed8..44a312494 100644 --- a/packages/taco/src/conditions/schemas/signing.ts +++ b/packages/taco/src/conditions/schemas/signing.ts @@ -44,22 +44,22 @@ export const abiParameterValidationSchema: z.ZodSchema = z .number() .int() .nonnegative() - .describe('index of parameter to check within abi calldata.'), + .describe('Index of parameter to check within abi calldata.'), indexWithinTuple: z .number() .int() .nonnegative() .optional() .describe( - 'index of value within tuple value at parameter index to check', + 'Index of value within tuple value at parameter index to check', ), returnValueTest: blockchainReturnValueTestSchema .optional() - .describe('comparison check for value within calldata'), + .describe('Comparison check for value within calldata'), nestedAbiValidation: z .lazy(() => abiCallValidationSchema) .optional() - .describe('additional checks for nested abi calldata'), + .describe('Additional checks for nested abi calldata'), }) .refine( // An XOR check to see if either 'returnValueTest' or 'nestedAbiValidation' is set From 262effe64633c74f7ba7dc922368f083f6872ba7 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 1 Jul 2025 11:52:16 +0200 Subject: [PATCH 102/303] =?UTF-8?q?=E2=9C=85=20test(shared):=20update=20te?= =?UTF-8?q?st=20for=20new=20error=20handling=20pattern?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Change mismatched hash test to expect error in result instead of thrown - Verify result contains partial signatures and error details - Test that processing continues with valid signatures despite errors --- packages/shared/test/porter.test.ts | 30 ++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index 2262a4f22..afde4dad8 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -252,7 +252,7 @@ describe('PorterClient Signing', () => { }); }); - it('should throw error when message hashes do not match', async () => { + it('should include error when message hashes do not match', async () => { const createMismatchedResponse = () => ({ result: { signing_results: { @@ -281,16 +281,24 @@ describe('PorterClient Signing', () => { }); const porterClient = new PorterClient(fakePorterUris[2]); - - await expect( - porterClient.signUserOp( - { - '0x1234': JSON.stringify(mockPackedUserOp), - '0xabcd': JSON.stringify(mockPackedUserOp) - }, - 2 - ) - ).rejects.toThrow('Mismatched message hashes'); + const result = await porterClient.signUserOp( + { + '0x1234': JSON.stringify(mockPackedUserOp), + '0xabcd': JSON.stringify(mockPackedUserOp) + }, + 2 + ); + + expect(result).toEqual({ + messageHash: '0x1234', // First valid message hash + aggregatedSignature: undefined, // No aggregation since only 1 valid signature < threshold (2) + signingResults: { + '0x1234': ['0x5678', '0x90ab'], // Only the first valid signature + }, + errors: { + '0xabcd': 'Mismatched message hash', // Error for the mismatched hash + }, + }); }); it('should not return aggregated signature when threshold not met', async () => { From c7a383cc959f6e5d52baf36ff00ba47408ebc697 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 26 Jun 2025 14:54:20 -0400 Subject: [PATCH 103/303] Fix failing test. --- packages/taco/test/conditions/context.test.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/taco/test/conditions/context.test.ts b/packages/taco/test/conditions/context.test.ts index f76307798..bf9015402 100644 --- a/packages/taco/test/conditions/context.test.ts +++ b/packages/taco/test/conditions/context.test.ts @@ -1097,10 +1097,16 @@ describe('recognition of context variables in conditions', () => { operands: [ jsonApiCondition, jsonRpcConditionParamsDict, + signingObjectAbiAttributeCondition, { conditionType: CompoundConditionType, operator: 'and', - operands: [jsonRpcConditionParamsArray, rpcCondition, timeCondition], + operands: [ + jsonRpcConditionParamsArray, + rpcCondition, + timeCondition, + signingObjectAbiAttributeCondition, + ], }, { conditionType: CompoundConditionType, @@ -1121,6 +1127,7 @@ describe('recognition of context variables in conditions', () => { contractCondition, jsonApiCondition, jsonRpcConditionParamsDict, + signingObjectAbiAttributeCondition, ], }, }, From f722cbd3454bf62b513d5f6a330dd640413749be Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 2 Jul 2025 17:25:38 +0200 Subject: [PATCH 104/303] =?UTF-8?q?=E2=9C=A8=20feat(shared):=20add=20optim?= =?UTF-8?q?istic=20signing=20option=20to=20signUserOp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add SigningOptions parameter with optimistic flag - Extract signature decoding logic to eliminate duplication - Optimistic mode: skip hash validation, use all signatures - Non-optimistic mode: validate hashes, only aggregate when threshold+ nodes agree - All signatures included in signingResults regardless of mode - Add comprehensive test coverage for new optimistic signing logic - Update existing test expectations for new signing behavior --- packages/shared/src/porter.ts | 94 +++++++++++++++---- packages/shared/test/porter.test.ts | 135 ++++++++++++++++++++++++++-- 2 files changed, 207 insertions(+), 22 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index 986533815..17ab3effb 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -180,6 +180,35 @@ function aggregatePorterSignatures( return signatures.join(''); } +type DecodedSignature = { + messageHash: string; + signature: string; + signerAddress: string; +}; + +function decodeSignature( + ursulaAddress: string, + signerAddress: string, + signatureB64: string +): { result?: DecodedSignature; error?: string } { + try { + const decodedData = JSON.parse( + new TextDecoder().decode(fromBase64(signatureB64)) + ); + return { + result: { + messageHash: decodedData.message_hash, + signature: decodedData.signature, + signerAddress, + }, + }; + } catch (error) { + return { + error: `Failed to decode signature: ${error}`, + }; + } +} + export class PorterClient { readonly porterUrls: URL[]; @@ -330,6 +359,7 @@ export class PorterClient { public async signUserOp( signingRequests: Record, threshold: number, + options: SigningOptions = {}, ): Promise { const data: Record = { signing_requests: signingRequests, @@ -343,32 +373,64 @@ export class PorterClient { }); const { signatures, errors } = resp.data.result.signing_results; + const allErrors: Record = { ...errors }; + const { optimistic = false } = options; const signingResults: { [ursulaAddress: string]: [string, string] } = {}; - const allErrors: Record = { ...errors }; let messageHash = ''; - - // Process signatures - decode the JSON payload to extract message hash and signature + + // For non-optimistic path + const hashCounts: Map = new Map(); + const hashToSignatures: Map = new Map(); + + // Single pass: decode signatures and populate signingResults for (const [ursulaAddress, [signerAddress, signatureB64]] of Object.entries(signatures || {})) { - try { - const decodedData = JSON.parse( - new TextDecoder().decode(fromBase64(signatureB64)) - ); - if (messageHash && messageHash !== decodedData.message_hash) { - allErrors[ursulaAddress] = 'Mismatched message hash'; - continue; + const decoded = decodeSignature(ursulaAddress, signerAddress, signatureB64); + if (decoded.error) { + allErrors[ursulaAddress] = decoded.error; + continue; + } + + if (!messageHash) { + messageHash = decoded.result!.messageHash; + } + + // Always include all decoded signatures in signingResults + signingResults[ursulaAddress] = [decoded.result!.signerAddress, decoded.result!.signature]; + + if (!optimistic) { + // For non-optimistic: track hashes and group signatures for aggregation + const hash = decoded.result!.messageHash; + hashCounts.set(hash, (hashCounts.get(hash) || 0) + 1); + + if (!hashToSignatures.has(hash)) { + hashToSignatures.set(hash, {}); } - messageHash = decodedData.message_hash; - signingResults[ursulaAddress] = [signerAddress, decodedData.signature]; - } catch (error) { - allErrors[ursulaAddress] = `Failed to decode signature: ${error}`; + hashToSignatures.get(hash)![ursulaAddress] = [decoded.result!.signerAddress, decoded.result!.signature]; } } - const aggregatedSignature = Object.keys(signingResults).length >= threshold - ? aggregatePorterSignatures(signingResults) + // Determine which signatures to aggregate + let signaturesToAggregate: { [ursulaAddress: string]: [string, string] } = {}; + + if (optimistic) { + // Optimistic: aggregate all signatures + signaturesToAggregate = signingResults; + } else { + // Non-optimistic: only aggregate signatures from hash that meets threshold + for (const [hash, count] of hashCounts.entries()) { + if (count >= threshold) { + signaturesToAggregate = hashToSignatures.get(hash)!; + break; + } + } + } + + const aggregatedSignature = Object.keys(signaturesToAggregate).length >= threshold + ? aggregatePorterSignatures(signaturesToAggregate) : undefined; + return { messageHash, aggregatedSignature, diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index afde4dad8..bece59ddd 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -290,14 +290,13 @@ describe('PorterClient Signing', () => { ); expect(result).toEqual({ - messageHash: '0x1234', // First valid message hash - aggregatedSignature: undefined, // No aggregation since only 1 valid signature < threshold (2) + messageHash: '0x1234', // First message hash + aggregatedSignature: undefined, // No aggregation since no hash meets threshold (2) signingResults: { - '0x1234': ['0x5678', '0x90ab'], // Only the first valid signature - }, - errors: { - '0xabcd': 'Mismatched message hash', // Error for the mismatched hash + '0x1234': ['0x5678', '0x90ab'], + '0xabcd': ['0xefgh', '0xijkl'], // All signatures included in signingResults }, + errors: {}, // No errors - mismatched hashes don't generate errors, just prevent aggregation }); }); @@ -344,5 +343,129 @@ describe('PorterClient Signing', () => { errors: {}, }); }); + + it('should successfully sign with optimistic mode', async () => { + mockSignUserOp(true); + const porterClient = new PorterClient(fakePorterUris[2]); + const result = await porterClient.signUserOp( + { + '0x1234': JSON.stringify(mockPackedUserOp), + '0xabcd': JSON.stringify(mockPackedUserOp) + }, + 2, + { optimistic: true } + ); + + expect(result).toEqual({ + messageHash: '0x1234', + aggregatedSignature: '0x90ab0xijkl', // All signatures aggregated in optimistic mode + signingResults: { + '0x1234': ['0x5678', '0x90ab'], + '0xabcd': ['0xefgh', '0xijkl'], + }, + errors: {}, + }); + }); + + it('should handle decode errors in optimistic mode', async () => { + const createOptimisticErrorResponse = () => ({ + result: { + signing_results: { + signatures: { + '0x1234': ['0x5678', toBase64(new TextEncoder().encode(JSON.stringify({ + message_hash: '0x1234', + signature: '0x90ab' + })))], + '0xabcd': ['0xefgh', 'invalid-base64-data!!!'] // Invalid signature data + }, + errors: {} + } + }, + }); + + vi.spyOn(axios, 'request').mockImplementation(async (config) => { + if (config.url === '/sign' && config.baseURL === fakePorterUris[2]) { + return Promise.resolve({ + status: HttpStatusCode.Ok, + data: createOptimisticErrorResponse(), + }); + } + }); + + const porterClient = new PorterClient(fakePorterUris[2]); + const result = await porterClient.signUserOp( + { + '0x1234': JSON.stringify(mockPackedUserOp), + '0xabcd': JSON.stringify(mockPackedUserOp) + }, + 2, + { optimistic: true } + ); + + expect(result).toEqual({ + messageHash: '0x1234', + aggregatedSignature: undefined, // No aggregation since only 1 valid signature < threshold + signingResults: { + '0x1234': ['0x5678', '0x90ab'], // Only valid signature included + }, + errors: { + '0xabcd': expect.stringContaining('Failed to decode signature'), // Decode error + }, + }); + }); + + it('should aggregate only threshold-meeting hash in non-optimistic mode', async () => { + const createMixedHashResponse = () => ({ + result: { + signing_results: { + signatures: { + '0x1234': ['0x5678', toBase64(new TextEncoder().encode(JSON.stringify({ + message_hash: '0xhash1', + signature: '0x90ab' + })))], + '0xabcd': ['0xefgh', toBase64(new TextEncoder().encode(JSON.stringify({ + message_hash: '0xhash1', // Same hash, meets threshold + signature: '0xijkl' + })))], + '0xdef0': ['0xabc1', toBase64(new TextEncoder().encode(JSON.stringify({ + message_hash: '0xhash2', // Different hash, doesn't meet threshold + signature: '0xmnop' + })))] + }, + errors: {} + } + }, + }); + + vi.spyOn(axios, 'request').mockImplementation(async (config) => { + if (config.url === '/sign' && config.baseURL === fakePorterUris[2]) { + return Promise.resolve({ + status: HttpStatusCode.Ok, + data: createMixedHashResponse(), + }); + } + }); + + const porterClient = new PorterClient(fakePorterUris[2]); + const result = await porterClient.signUserOp( + { + '0x1234': JSON.stringify(mockPackedUserOp), + '0xabcd': JSON.stringify(mockPackedUserOp), + '0xdef0': JSON.stringify(mockPackedUserOp) + }, + 2 // threshold of 2 + ); + + expect(result).toEqual({ + messageHash: '0xhash1', // First hash seen + aggregatedSignature: '0x90ab0xijkl', // Only signatures from threshold-meeting hash + signingResults: { + '0x1234': ['0x5678', '0x90ab'], + '0xabcd': ['0xefgh', '0xijkl'], + '0xdef0': ['0xabc1', '0xmnop'], // All signatures included in results + }, + errors: {}, + }); + }); }); }); From 5f8a0bfd05132c3e0329647ea594136b77e767fc Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 26 Jun 2025 15:35:07 -0400 Subject: [PATCH 105/303] Consider the signing object context var to be an automatically injected entry that never needs to be provided by the user/application. It is never included in the list of requested parameters, nor can it be added by the user/application. Ensure that the signing object context variable string itself can't be reused as a custom context variable. --- .../taco/src/conditions/context/context.ts | 15 ++++- packages/taco/test/conditions/context.test.ts | 61 +++++++++++++++---- 2 files changed, 62 insertions(+), 14 deletions(-) diff --git a/packages/taco/src/conditions/context/context.ts b/packages/taco/src/conditions/context/context.ts index f0a7862cb..19b15e2dd 100644 --- a/packages/taco/src/conditions/context/context.ts +++ b/packages/taco/src/conditions/context/context.ts @@ -44,6 +44,8 @@ const ERR_INVALID_AUTH_PROVIDER_TYPE = (param: string, expected: string) => `Invalid AuthProvider type for ${param}; expected ${expected}`; const ERR_AUTH_PROVIDER_NOT_NEEDED_FOR_CONTEXT_PARAM = (param: string) => `AuthProvider not necessary for context parameter: ${param}`; +const ERR_AUTO_INJECTED_CONTEXT_PARAM = (param: string) => + `Context parameter ${param} is automatically injected and cannot be set manually`; type AuthProviderType = | typeof EIP4361AuthProvider @@ -58,10 +60,11 @@ const EXPECTED_AUTH_PROVIDER_TYPES: Record = { ], }; -export const RESERVED_CONTEXT_PARAMS = [ - USER_ADDRESS_PARAM_DEFAULT, +export const AUTOMATICALLY_INJECTED_CONTEXT_PARAMS = [ + // These context parameters are automatically injected on the node side. SIGNING_CONDITION_OBJECT_CONTEXT_VAR, ]; +export const RESERVED_CONTEXT_PARAMS = [USER_ADDRESS_PARAM_DEFAULT]; export class ConditionContext { public requestedContextParameters: Set; @@ -141,6 +144,10 @@ export class ConditionContext { throw new Error(ERR_INVALID_CUSTOM_PARAM(customParam)); } + if (AUTOMATICALLY_INJECTED_CONTEXT_PARAMS.includes(customParam)) { + throw new Error(ERR_AUTO_INJECTED_CONTEXT_PARAM(customParam)); + } + if (RESERVED_CONTEXT_PARAMS.includes(customParam)) { throw new Error(ERR_RESERVED_PARAM(customParam)); } @@ -207,7 +214,9 @@ export class ConditionContext { const properties = Object.keys(condition) as (keyof typeof condition)[]; properties.forEach((prop) => { this.findContextParameter(condition[prop]).forEach((contextVar) => { - requestedParameters.add(contextVar); + if (!AUTOMATICALLY_INJECTED_CONTEXT_PARAMS.includes(contextVar)) { + requestedParameters.add(contextVar); + } }); }); diff --git a/packages/taco/test/conditions/context.test.ts b/packages/taco/test/conditions/context.test.ts index bf9015402..cb04aae4d 100644 --- a/packages/taco/test/conditions/context.test.ts +++ b/packages/taco/test/conditions/context.test.ts @@ -27,6 +27,7 @@ import { ContractConditionType, } from '../../src/conditions/base/contract'; import { RpcCondition } from '../../src/conditions/base/rpc'; +import { SIGNING_CONDITION_OBJECT_CONTEXT_VAR } from '../../src/conditions/base/signing'; import { CompoundConditionType } from '../../src/conditions/compound-condition'; import { ConditionContext, @@ -35,7 +36,6 @@ import { import { RESERVED_CONTEXT_PARAMS } from '../../src/conditions/context/context'; import { IfThenElseConditionType } from '../../src/conditions/if-then-else-condition'; import { blockchainParamOrContextParamSchema } from '../../src/conditions/schemas/context'; -import { SIGNING_CONDITION_OBJECT_CONTEXT_VAR } from '../../src/conditions/schemas/signing'; import { SequentialConditionType } from '../../src/conditions/sequential'; import { paramOrContextParamSchema } from '../../src/conditions/shared'; import { fromJSON, toJSON } from '../../src/utils'; @@ -429,6 +429,47 @@ describe('context', () => { ).toThrow(`Unknown custom context parameter: ${badCustomParamKey}`); }); + describe('signing object context parameter', () => { + it.each([ + testSigningObjectAttributeConditionObj, + testSigningObjectAbiAttributeConditionObj, + ])( + 'rejects on using an auto injected signing object context parameter', + (signingObjectConditionProps) => { + const condition = ConditionFactory.conditionFromProps( + signingObjectConditionProps, + ); + const conditionContext = new ConditionContext(condition); + const badCustomParams: Record = {}; + badCustomParams[SIGNING_CONDITION_OBJECT_CONTEXT_VAR] = + 'this-will-throw'; + expect(() => + conditionContext.addCustomContextParameterValues(badCustomParams), + ).toThrow( + `Context parameter ${SIGNING_CONDITION_OBJECT_CONTEXT_VAR} is automatically injected and cannot be set manually`, + ); + }, + ); + + it.each([ + testSigningObjectAttributeConditionObj, + testSigningObjectAbiAttributeConditionObj, + ])( + 'empty condition context generated since context var will be automatically injected', + async (signingObjectConditionProps) => { + const condition = ConditionFactory.conditionFromProps( + signingObjectConditionProps, + ); + const conditionContext = new ConditionContext(condition); + expect(async () => + conditionContext.toContextParameters(), + ).not.toThrow(); + const asObj = await conditionContext.toContextParameters(); + expect(Object.keys(asObj).length).toBe(0); + }, + ); + }); + describe('custom method parameters', () => { const contractConditionObj: ContractConditionProps = { ...testContractConditionObj, @@ -1028,11 +1069,8 @@ describe('recognition of context variables in conditions', () => { signingObjectAttributeCondition, ); const conditionContext = new ConditionContext(condition); - - // Verify all context parameters are detected - expect(conditionContext.requestedContextParameters).toEqual( - new Set([SIGNING_CONDITION_OBJECT_CONTEXT_VAR]), - ); + // Signing object context var is auto injected so not included in requested context params + expect(conditionContext.requestedContextParameters.size).toBe(0); }); it('handles context params for signing object abi attribute condition', () => { const condition = ConditionFactory.conditionFromProps( @@ -1040,10 +1078,8 @@ describe('recognition of context variables in conditions', () => { ); const conditionContext = new ConditionContext(condition); - // Verify all context parameters are detected - expect(conditionContext.requestedContextParameters).toEqual( - new Set([SIGNING_CONDITION_OBJECT_CONTEXT_VAR]), - ); + // Signing object context var is auto injected so not included in requested context params + expect(conditionContext.requestedContextParameters.size).toBe(0); }); it.each([ { @@ -1148,9 +1184,12 @@ describe('recognition of context variables in conditions', () => { ':queryKey', ':authToken', ':expectedResult', - SIGNING_CONDITION_OBJECT_CONTEXT_VAR, ]), ); + // automatically injected signing object context variable is not included + expect(conditionContext.requestedContextParameters).not.toContain( + SIGNING_CONDITION_OBJECT_CONTEXT_VAR, + ); }); }); From e7fca1f501b8712bfffecb75adaee33ec94221f0 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 2 Jul 2025 13:26:12 -0400 Subject: [PATCH 106/303] Remove unused parameter when decoding a signature. --- packages/shared/src/porter.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index 17ab3effb..d6cfd293a 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -187,7 +187,6 @@ type DecodedSignature = { }; function decodeSignature( - ursulaAddress: string, signerAddress: string, signatureB64: string ): { result?: DecodedSignature; error?: string } { @@ -385,7 +384,7 @@ export class PorterClient { // Single pass: decode signatures and populate signingResults for (const [ursulaAddress, [signerAddress, signatureB64]] of Object.entries(signatures || {})) { - const decoded = decodeSignature(ursulaAddress, signerAddress, signatureB64); + const decoded = decodeSignature(signerAddress, signatureB64); if (decoded.error) { allErrors[ursulaAddress] = decoded.error; continue; From 426c9d13206cda49c6e8baf51c29df0c9245934c Mon Sep 17 00:00:00 2001 From: derekpierre Date: Mon, 30 Jun 2025 08:25:01 -0400 Subject: [PATCH 107/303] Add signing object context variable to list of reserved context params. It is both a reserved context param and an automatically injected param. --- .../taco/src/conditions/context/context.ts | 5 +++- packages/taco/test/conditions/context.test.ts | 23 ++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/packages/taco/src/conditions/context/context.ts b/packages/taco/src/conditions/context/context.ts index 19b15e2dd..3ad2514b2 100644 --- a/packages/taco/src/conditions/context/context.ts +++ b/packages/taco/src/conditions/context/context.ts @@ -64,7 +64,10 @@ export const AUTOMATICALLY_INJECTED_CONTEXT_PARAMS = [ // These context parameters are automatically injected on the node side. SIGNING_CONDITION_OBJECT_CONTEXT_VAR, ]; -export const RESERVED_CONTEXT_PARAMS = [USER_ADDRESS_PARAM_DEFAULT]; +export const RESERVED_CONTEXT_PARAMS = [ + USER_ADDRESS_PARAM_DEFAULT, + SIGNING_CONDITION_OBJECT_CONTEXT_VAR, +]; export class ConditionContext { public requestedContextParameters: Set; diff --git a/packages/taco/test/conditions/context.test.ts b/packages/taco/test/conditions/context.test.ts index cb04aae4d..0e08bf623 100644 --- a/packages/taco/test/conditions/context.test.ts +++ b/packages/taco/test/conditions/context.test.ts @@ -33,7 +33,10 @@ import { ConditionContext, CustomContextParam, } from '../../src/conditions/context'; -import { RESERVED_CONTEXT_PARAMS } from '../../src/conditions/context/context'; +import { + AUTOMATICALLY_INJECTED_CONTEXT_PARAMS, + RESERVED_CONTEXT_PARAMS, +} from '../../src/conditions/context/context'; import { IfThenElseConditionType } from '../../src/conditions/if-then-else-condition'; import { blockchainParamOrContextParamSchema } from '../../src/conditions/schemas/context'; import { SequentialConditionType } from '../../src/conditions/sequential'; @@ -410,11 +413,19 @@ describe('context', () => { RESERVED_CONTEXT_PARAMS.forEach((reservedParam) => { const badCustomParams: Record = {}; badCustomParams[reservedParam] = 'this-will-throw'; - expect(() => - conditionContext.addCustomContextParameterValues(badCustomParams), - ).toThrow( - `Cannot use reserved parameter name ${reservedParam} as custom parameter`, - ); + if (AUTOMATICALLY_INJECTED_CONTEXT_PARAMS.includes(reservedParam)) { + expect(() => + conditionContext.addCustomContextParameterValues(badCustomParams), + ).toThrow( + `Context parameter ${reservedParam} is automatically injected and cannot be set manually`, + ); + } else { + expect(() => + conditionContext.addCustomContextParameterValues(badCustomParams), + ).toThrow( + `Cannot use reserved parameter name ${reservedParam} as custom parameter`, + ); + } }); }); From ee6e637da27664c6e3566ac43ee86165f70fd040 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 2 Jul 2025 13:27:20 -0400 Subject: [PATCH 108/303] Set message hash for non-optimistic case. --- packages/shared/src/porter.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index d6cfd293a..d79c96bcf 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -419,6 +419,7 @@ export class PorterClient { // Non-optimistic: only aggregate signatures from hash that meets threshold for (const [hash, count] of hashCounts.entries()) { if (count >= threshold) { + messageHash = hash; signaturesToAggregate = hashToSignatures.get(hash)!; break; } From 2460e26022f75a6b263b9b232bb50d0ffbd9ba8c Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 2 Jul 2025 09:07:27 -0400 Subject: [PATCH 109/303] Update signing condition type values to include "signing" - matches update made in `nucypher`. --- packages/taco/src/conditions/schemas/signing.ts | 4 ++-- packages/taco/test/conditions/base/signing.test.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/taco/src/conditions/schemas/signing.ts b/packages/taco/src/conditions/schemas/signing.ts index 44a312494..41c233a38 100644 --- a/packages/taco/src/conditions/schemas/signing.ts +++ b/packages/taco/src/conditions/schemas/signing.ts @@ -24,7 +24,7 @@ const baseSigningObjectAttributeConditionSchema = signingConditionSchema.extend( }, ); -export const SigningObjectAttributeConditionType = 'attribute'; +export const SigningObjectAttributeConditionType = 'signing-attribute'; export const signingObjectAttributeConditionSchema: z.ZodSchema = baseSigningObjectAttributeConditionSchema.extend({ @@ -247,7 +247,7 @@ export const abiCallValidationSchema: z.ZodSchema = z export type AbiCallValidationProps = z.infer; -export const SigningObjectAbiAttributeConditionType = 'abi-attribute'; +export const SigningObjectAbiAttributeConditionType = 'signing-abi-attribute'; export const signingObjectAbiAttributeConditionSchema: z.ZodSchema = baseSigningObjectAttributeConditionSchema.extend({ diff --git a/packages/taco/test/conditions/base/signing.test.ts b/packages/taco/test/conditions/base/signing.test.ts index 77ab42298..fa77d282c 100644 --- a/packages/taco/test/conditions/base/signing.test.ts +++ b/packages/taco/test/conditions/base/signing.test.ts @@ -40,7 +40,7 @@ describe('SigningObjectAttributeCondition', () => { expect(result.data).toBeUndefined(); expect(result.error!.format()).toMatchObject({ conditionType: { - _errors: ['Invalid literal value, expected "attribute"'], + _errors: ['Invalid literal value, expected "signing-attribute"'], }, }); }); @@ -147,7 +147,7 @@ describe('SigningObjectAbiAttributeCondition', () => { expect(result.data).toBeUndefined(); expect(result.error!.format()).toMatchObject({ conditionType: { - _errors: ['Invalid literal value, expected "abi-attribute"'], + _errors: ['Invalid literal value, expected "signing-abi-attribute"'], }, }); }); From 850debbd10bd1063a88b6c0eb2c1195218bc7c1c Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 2 Jul 2025 13:38:45 -0400 Subject: [PATCH 110/303] Remove extra returnAggregated value from test. Run pnpm fix. --- packages/shared/src/contracts/agents/index.ts | 2 +- .../contracts/agents/signing-coordinator.ts | 34 ++- packages/shared/src/index.ts | 1 - packages/shared/src/porter.ts | 80 +++--- packages/shared/src/types.ts | 22 +- packages/shared/test/porter.test.ts | 250 ++++++++++++------ packages/taco/integration-test/sign.test.ts | 122 +++++---- .../taco/src/conditions/context/context.ts | 23 +- packages/taco/src/index.ts | 2 +- packages/taco/src/sign.ts | 10 +- packages/taco/test/conditions/context.test.ts | 121 +++++---- packages/taco/test/taco-sign.test.ts | 94 ++++--- 12 files changed, 454 insertions(+), 307 deletions(-) diff --git a/packages/shared/src/contracts/agents/index.ts b/packages/shared/src/contracts/agents/index.ts index 61a028224..2520222a0 100644 --- a/packages/shared/src/contracts/agents/index.ts +++ b/packages/shared/src/contracts/agents/index.ts @@ -1,4 +1,4 @@ export * from './coordinator'; export * from './global-allow-list'; +export * from './signing-coordinator'; export * from './subscription-manager'; -export * from './signing-coordinator'; \ No newline at end of file diff --git a/packages/shared/src/contracts/agents/signing-coordinator.ts b/packages/shared/src/contracts/agents/signing-coordinator.ts index 39d1683f6..95d462f4a 100644 --- a/packages/shared/src/contracts/agents/signing-coordinator.ts +++ b/packages/shared/src/contracts/agents/signing-coordinator.ts @@ -20,13 +20,17 @@ export class SigningCoordinatorAgent { const coordinator = await this.connectReadOnly(provider, domain); const participants = await coordinator.getSigners(cohortId); - return participants.map((participant: SigningCoordinator.SigningCohortParticipantStructOutput) => { - return { - operator: participant.operator, - provider: participant.provider, - signature: participant.signature, - }; - }); + return participants.map( + ( + participant: SigningCoordinator.SigningCohortParticipantStructOutput, + ) => { + return { + operator: participant.operator, + provider: participant.provider, + signature: participant.signature, + }; + }, + ); } public static async getThreshold( @@ -46,7 +50,10 @@ export class SigningCoordinatorAgent { chainId: number, ): Promise { const coordinator = await this.connectReadOnly(provider, domain); - const cohortCondition = await coordinator.getSigningCohortConditions(cohortId, chainId); + const cohortCondition = await coordinator.getSigningCohortConditions( + cohortId, + chainId, + ); return cohortCondition; } @@ -63,7 +70,14 @@ export class SigningCoordinatorAgent { signer?: ethers.Signer, ): Promise { const network = await provider.getNetwork(); - const contractAddress = getContract(domain, network.chainId, 'SigningCoordinator'); - return SigningCoordinator__factory.connect(contractAddress, signer ?? provider); + const contractAddress = getContract( + domain, + network.chainId, + 'SigningCoordinator', + ); + return SigningCoordinator__factory.connect( + contractAddress, + signer ?? provider, + ); } } diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 7ef65aa23..464d3cc14 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -1,7 +1,6 @@ export * from './contracts'; export * from './porter'; export * from './schemas'; -export type * from './types'; export * from './types'; export * from './utils'; export * from './web3'; diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index d79c96bcf..56260dabe 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -154,13 +154,16 @@ export type TacoDecryptResult = { // Signing types export type SigningOptions = { - optimistic?: boolean; // Whether to return first signatures received or wait for all signatures + optimistic?: boolean; // Whether to return first signatures received or wait for all signatures }; type SignResponse = { readonly result: { readonly signing_results: { - readonly signatures: Record; + readonly signatures: Record< + ChecksumAddress, + [ChecksumAddress, Base64EncodedBytes] + >; readonly errors: Record; }; }; @@ -173,10 +176,12 @@ export type SignResult = { errors: Record; }; -function aggregatePorterSignatures( - signaturesWithAddress: { [checksumAddress: string]: [string, string] } -): string { - const signatures = Object.values(signaturesWithAddress).map(([, signature]) => signature); +function aggregatePorterSignatures(signaturesWithAddress: { + [checksumAddress: string]: [string, string]; +}): string { + const signatures = Object.values(signaturesWithAddress).map( + ([, signature]) => signature, + ); return signatures.join(''); } @@ -188,11 +193,11 @@ type DecodedSignature = { function decodeSignature( signerAddress: string, - signatureB64: string + signatureB64: string, ): { result?: DecodedSignature; error?: string } { try { const decodedData = JSON.parse( - new TextDecoder().decode(fromBase64(signatureB64)) + new TextDecoder().decode(fromBase64(signatureB64)), ); return { result: { @@ -235,15 +240,15 @@ export class PorterClient { const errorDetails: Record = { url: porterUrl.toString(), method: config.method, - requestData: config.data + requestData: config.data, }; - + if (axios.isAxiosError(e)) { errorDetails.status = e.response?.status; errorDetails.statusText = e.response?.statusText; errorDetails.data = e.response?.data; } - + console.error('Porter request failed:', errorDetails); lastError = e; continue; @@ -354,7 +359,6 @@ export class PorterClient { return { encryptedResponses, errors }; } - public async signUserOp( signingRequests: Record, threshold: number, @@ -362,9 +366,9 @@ export class PorterClient { ): Promise { const data: Record = { signing_requests: signingRequests, - threshold: threshold + threshold: threshold, }; - + const resp: AxiosResponse = await this.tryAndCall({ url: '/sign', method: 'post', @@ -374,44 +378,56 @@ export class PorterClient { const { signatures, errors } = resp.data.result.signing_results; const allErrors: Record = { ...errors }; const { optimistic = false } = options; - + const signingResults: { [ursulaAddress: string]: [string, string] } = {}; let messageHash = ''; - + // For non-optimistic path const hashCounts: Map = new Map(); - const hashToSignatures: Map = new Map(); - + const hashToSignatures: Map< + string, + { [ursulaAddress: string]: [string, string] } + > = new Map(); + // Single pass: decode signatures and populate signingResults - for (const [ursulaAddress, [signerAddress, signatureB64]] of Object.entries(signatures || {})) { + for (const [ursulaAddress, [signerAddress, signatureB64]] of Object.entries( + signatures || {}, + )) { const decoded = decodeSignature(signerAddress, signatureB64); if (decoded.error) { allErrors[ursulaAddress] = decoded.error; continue; } - + if (!messageHash) { messageHash = decoded.result!.messageHash; } - + // Always include all decoded signatures in signingResults - signingResults[ursulaAddress] = [decoded.result!.signerAddress, decoded.result!.signature]; - + signingResults[ursulaAddress] = [ + decoded.result!.signerAddress, + decoded.result!.signature, + ]; + if (!optimistic) { // For non-optimistic: track hashes and group signatures for aggregation const hash = decoded.result!.messageHash; hashCounts.set(hash, (hashCounts.get(hash) || 0) + 1); - + if (!hashToSignatures.has(hash)) { hashToSignatures.set(hash, {}); } - hashToSignatures.get(hash)![ursulaAddress] = [decoded.result!.signerAddress, decoded.result!.signature]; + hashToSignatures.get(hash)![ursulaAddress] = [ + decoded.result!.signerAddress, + decoded.result!.signature, + ]; } } // Determine which signatures to aggregate - let signaturesToAggregate: { [ursulaAddress: string]: [string, string] } = {}; - + let signaturesToAggregate: { [ursulaAddress: string]: [string, string] } = + {}; + if (optimistic) { // Optimistic: aggregate all signatures signaturesToAggregate = signingResults; @@ -425,11 +441,11 @@ export class PorterClient { } } } - - const aggregatedSignature = Object.keys(signaturesToAggregate).length >= threshold - ? aggregatePorterSignatures(signaturesToAggregate) - : undefined; + const aggregatedSignature = + Object.keys(signaturesToAggregate).length >= threshold + ? aggregatePorterSignatures(signaturesToAggregate) + : undefined; return { messageHash, @@ -438,4 +454,4 @@ export class PorterClient { errors: allErrors, }; } -} \ No newline at end of file +} diff --git a/packages/shared/src/types.ts b/packages/shared/src/types.ts index 5917eb5cc..6f5f7cb64 100644 --- a/packages/shared/src/types.ts +++ b/packages/shared/src/types.ts @@ -29,7 +29,7 @@ export class UserOperationSignatureRequest { private cohortId: number, private chainId: number, private context: unknown = {}, - private signatureType: string = "userop" + private signatureType: string = 'userop', ) {} toBytes(): Uint8Array { @@ -49,13 +49,15 @@ function normalizeAddress(address: string): string | null { if (!address || address === '0x') { return null; } - + try { // Use ethers to get the checksummed address - this will throw on invalid addresses return ethers.utils.getAddress(address); } catch (error) { // Re-throw the error to fail fast on invalid addresses - throw new Error(`Invalid address: ${address}. ${error instanceof Error ? error.message : 'Unknown error'}`); + throw new Error( + `Invalid address: ${address}. ${error instanceof Error ? error.message : 'Unknown error'}`, + ); } } @@ -64,17 +66,19 @@ export function convertUserOperationToPython(userOp: UserOperation) { sender: normalizeAddress(userOp.sender), nonce: parseInt(userOp.nonce, 16) || 0, factory: normalizeAddress(userOp.factory), - factory_data: userOp.factoryData || "0x", - call_data: userOp.callData || "0x", + factory_data: userOp.factoryData || '0x', + call_data: userOp.callData || '0x', call_gas_limit: parseInt(userOp.callGasLimit, 16) || 0, verification_gas_limit: parseInt(userOp.verificationGasLimit, 16) || 0, pre_verification_gas: parseInt(userOp.preVerificationGas, 16) || 0, max_fee_per_gas: parseInt(userOp.maxFeePerGas, 16) || 0, max_priority_fee_per_gas: parseInt(userOp.maxPriorityFeePerGas, 16) || 0, paymaster: normalizeAddress(userOp.paymaster), - paymaster_verification_gas_limit: parseInt(userOp.paymasterVerificationGasLimit, 16) || 0, - paymaster_post_op_gas_limit: parseInt(userOp.paymasterPostOpGasLimit, 16) || 0, - paymaster_data: userOp.paymasterData || "0x", - signature: userOp.signature || "0x", + paymaster_verification_gas_limit: + parseInt(userOp.paymasterVerificationGasLimit, 16) || 0, + paymaster_post_op_gas_limit: + parseInt(userOp.paymasterPostOpGasLimit, 16) || 0, + paymaster_data: userOp.paymasterData || '0x', + signature: userOp.signature || '0x', }; } diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index bece59ddd..35cb3eb32 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -54,42 +54,69 @@ const mockGetUrsulas = (ursulas: Ursula[] = fakeUrsulas()): MockInstance => { const createMockSignResponse = (errorCase?: boolean) => ({ result: { signing_results: { - signatures: errorCase ? { - '0xabcd': ['0xefgh', toBase64(new TextEncoder().encode(JSON.stringify({ - message_hash: '0x1234', - signature: '0xijkl' - })))] - } : { - '0x1234': ['0x5678', toBase64(new TextEncoder().encode(JSON.stringify({ - message_hash: '0x1234', - signature: '0x90ab' - })))], - '0xabcd': ['0xefgh', toBase64(new TextEncoder().encode(JSON.stringify({ - message_hash: '0x1234', - signature: '0xijkl' - })))] - }, - errors: errorCase ? { - '0x1234': 'Failed to sign' - } : {} - } + signatures: errorCase + ? { + '0xabcd': [ + '0xefgh', + toBase64( + new TextEncoder().encode( + JSON.stringify({ + message_hash: '0x1234', + signature: '0xijkl', + }), + ), + ), + ], + } + : { + '0x1234': [ + '0x5678', + toBase64( + new TextEncoder().encode( + JSON.stringify({ + message_hash: '0x1234', + signature: '0x90ab', + }), + ), + ), + ], + '0xabcd': [ + '0xefgh', + toBase64( + new TextEncoder().encode( + JSON.stringify({ + message_hash: '0x1234', + signature: '0xijkl', + }), + ), + ), + ], + }, + errors: errorCase + ? { + '0x1234': 'Failed to sign', + } + : {}, + }, }, }); -const createMockSignImplementation = (endpoint: string) => (success: boolean = true, errorCase?: boolean): MockInstance => { - return vi.spyOn(axios, 'request').mockImplementation(async (config) => { - // Handle sign requests - if (config.url === endpoint && config.baseURL === fakePorterUris[2]) { - if (success) { - return Promise.resolve({ - status: HttpStatusCode.Ok, - data: createMockSignResponse(errorCase), - }); +const createMockSignImplementation = + (endpoint: string) => + (success: boolean = true, errorCase?: boolean): MockInstance => { + return vi.spyOn(axios, 'request').mockImplementation(async (config) => { + // Handle sign requests + if (config.url === endpoint && config.baseURL === fakePorterUris[2]) { + if (success) { + return Promise.resolve({ + status: HttpStatusCode.Ok, + data: createMockSignResponse(errorCase), + }); + } + return Promise.resolve({ status: HttpStatusCode.BadRequest, data: '' }); } - return Promise.resolve({ status: HttpStatusCode.BadRequest, data: '' }); - } - }); -}; + }); + }; const mockSignUserOp = createMockSignImplementation('/sign'); @@ -167,7 +194,6 @@ describe('PorterClient Signing', () => { await initialize(); }); - describe('signUserOp', () => { const mockPackedUserOp = { sender: '0x1234', @@ -193,9 +219,9 @@ describe('PorterClient Signing', () => { const result = await porterClient.signUserOp( { '0x1234': JSON.stringify(mockPackedUserOp), - '0xabcd': JSON.stringify(mockPackedUserOp) + '0xabcd': JSON.stringify(mockPackedUserOp), }, - 2 + 2, ); expect(result).toEqual({ @@ -217,14 +243,13 @@ describe('PorterClient Signing', () => { porterClient.signUserOp( { '0x1234': JSON.stringify(mockPackedUserOp), - '0xabcd': JSON.stringify(mockPackedUserOp) + '0xabcd': JSON.stringify(mockPackedUserOp), }, 2, { optimistic: true, - returnAggregated: true - } - ) + }, + ), ).rejects.toThrow('Porter returned bad response: 400 - '); }); @@ -235,9 +260,9 @@ describe('PorterClient Signing', () => { const result = await porterClient.signUserOp( { '0x1234': JSON.stringify(mockPackedUserOp), - '0xabcd': JSON.stringify(mockPackedUserOp) + '0xabcd': JSON.stringify(mockPackedUserOp), }, - 2 + 2, ); expect(result).toEqual({ @@ -257,17 +282,31 @@ describe('PorterClient Signing', () => { result: { signing_results: { signatures: { - '0x1234': ['0x5678', toBase64(new TextEncoder().encode(JSON.stringify({ - message_hash: '0x1234', - signature: '0x90ab' - })))], - '0xabcd': ['0xefgh', toBase64(new TextEncoder().encode(JSON.stringify({ - message_hash: '0xdifferent', // Different message hash - signature: '0xijkl' - })))] + '0x1234': [ + '0x5678', + toBase64( + new TextEncoder().encode( + JSON.stringify({ + message_hash: '0x1234', + signature: '0x90ab', + }), + ), + ), + ], + '0xabcd': [ + '0xefgh', + toBase64( + new TextEncoder().encode( + JSON.stringify({ + message_hash: '0xdifferent', // Different message hash + signature: '0xijkl', + }), + ), + ), + ], }, - errors: {} - } + errors: {}, + }, }, }); @@ -284,9 +323,9 @@ describe('PorterClient Signing', () => { const result = await porterClient.signUserOp( { '0x1234': JSON.stringify(mockPackedUserOp), - '0xabcd': JSON.stringify(mockPackedUserOp) + '0xabcd': JSON.stringify(mockPackedUserOp), }, - 2 + 2, ); expect(result).toEqual({ @@ -305,14 +344,21 @@ describe('PorterClient Signing', () => { result: { signing_results: { signatures: { - '0x1234': ['0x5678', toBase64(new TextEncoder().encode(JSON.stringify({ - message_hash: '0x1234', - signature: '0x90ab' - })))] + '0x1234': [ + '0x5678', + toBase64( + new TextEncoder().encode( + JSON.stringify({ + message_hash: '0x1234', + signature: '0x90ab', + }), + ), + ), + ], // Only 1 signature, but threshold is 2 }, - errors: {} - } + errors: {}, + }, }, }); @@ -329,9 +375,9 @@ describe('PorterClient Signing', () => { const result = await porterClient.signUserOp( { '0x1234': JSON.stringify(mockPackedUserOp), - '0xabcd': JSON.stringify(mockPackedUserOp) + '0xabcd': JSON.stringify(mockPackedUserOp), }, - 2 // threshold of 2, but only 1 signature + 2, // threshold of 2, but only 1 signature ); expect(result).toEqual({ @@ -350,10 +396,10 @@ describe('PorterClient Signing', () => { const result = await porterClient.signUserOp( { '0x1234': JSON.stringify(mockPackedUserOp), - '0xabcd': JSON.stringify(mockPackedUserOp) + '0xabcd': JSON.stringify(mockPackedUserOp), }, 2, - { optimistic: true } + { optimistic: true }, ); expect(result).toEqual({ @@ -372,14 +418,21 @@ describe('PorterClient Signing', () => { result: { signing_results: { signatures: { - '0x1234': ['0x5678', toBase64(new TextEncoder().encode(JSON.stringify({ - message_hash: '0x1234', - signature: '0x90ab' - })))], - '0xabcd': ['0xefgh', 'invalid-base64-data!!!'] // Invalid signature data + '0x1234': [ + '0x5678', + toBase64( + new TextEncoder().encode( + JSON.stringify({ + message_hash: '0x1234', + signature: '0x90ab', + }), + ), + ), + ], + '0xabcd': ['0xefgh', 'invalid-base64-data!!!'], // Invalid signature data }, - errors: {} - } + errors: {}, + }, }, }); @@ -396,10 +449,10 @@ describe('PorterClient Signing', () => { const result = await porterClient.signUserOp( { '0x1234': JSON.stringify(mockPackedUserOp), - '0xabcd': JSON.stringify(mockPackedUserOp) + '0xabcd': JSON.stringify(mockPackedUserOp), }, 2, - { optimistic: true } + { optimistic: true }, ); expect(result).toEqual({ @@ -419,21 +472,42 @@ describe('PorterClient Signing', () => { result: { signing_results: { signatures: { - '0x1234': ['0x5678', toBase64(new TextEncoder().encode(JSON.stringify({ - message_hash: '0xhash1', - signature: '0x90ab' - })))], - '0xabcd': ['0xefgh', toBase64(new TextEncoder().encode(JSON.stringify({ - message_hash: '0xhash1', // Same hash, meets threshold - signature: '0xijkl' - })))], - '0xdef0': ['0xabc1', toBase64(new TextEncoder().encode(JSON.stringify({ - message_hash: '0xhash2', // Different hash, doesn't meet threshold - signature: '0xmnop' - })))] + '0x1234': [ + '0x5678', + toBase64( + new TextEncoder().encode( + JSON.stringify({ + message_hash: '0xhash1', + signature: '0x90ab', + }), + ), + ), + ], + '0xabcd': [ + '0xefgh', + toBase64( + new TextEncoder().encode( + JSON.stringify({ + message_hash: '0xhash1', // Same hash, meets threshold + signature: '0xijkl', + }), + ), + ), + ], + '0xdef0': [ + '0xabc1', + toBase64( + new TextEncoder().encode( + JSON.stringify({ + message_hash: '0xhash2', // Different hash, doesn't meet threshold + signature: '0xmnop', + }), + ), + ), + ], }, - errors: {} - } + errors: {}, + }, }, }); @@ -451,9 +525,9 @@ describe('PorterClient Signing', () => { { '0x1234': JSON.stringify(mockPackedUserOp), '0xabcd': JSON.stringify(mockPackedUserOp), - '0xdef0': JSON.stringify(mockPackedUserOp) + '0xdef0': JSON.stringify(mockPackedUserOp), }, - 2 // threshold of 2 + 2, // threshold of 2 ); expect(result).toEqual({ diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index 84cb35735..894026572 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -12,68 +12,76 @@ const DOMAIN = 'lynx'; const RITUAL_ID = 1; const CHAIN_ID = 11155111; -describe.skipIf(!process.env.RUNNING_IN_CI)('Taco Sign Integration Test', () => { - let provider: ethers.providers.JsonRpcProvider; +describe.skipIf(!process.env.RUNNING_IN_CI)( + 'Taco Sign Integration Test', + () => { + let provider: ethers.providers.JsonRpcProvider; - beforeAll(async () => { - provider = new ethers.providers.JsonRpcProvider(RPC_PROVIDER_URL); + beforeAll(async () => { + provider = new ethers.providers.JsonRpcProvider(RPC_PROVIDER_URL); - // Initialize the library - await initialize(); + // Initialize the library + await initialize(); - // Verify network connection - const network = await provider.getNetwork(); - if (network.chainId !== CHAIN_ID) { - throw new Error( - `Provider connected to wrong network. Expected ${CHAIN_ID}, got ${network.chainId}`, - ); - } - }); + // Verify network connection + const network = await provider.getNetwork(); + if (network.chainId !== CHAIN_ID) { + throw new Error( + `Provider connected to wrong network. Expected ${CHAIN_ID}, got ${network.chainId}`, + ); + } + }); - test('should sign a user operation', async () => { - // Create a sample user operation with all required fields - const userOp: UserOperation = { - sender: DUMMY_ADDRESS, - nonce: '0x0', - factory: '0x', - factoryData: '0x', - callData: '0x', - callGasLimit: '0x0', - verificationGasLimit: '0x0', - preVerificationGas: '0x0', - maxFeePerGas: '0x0', - maxPriorityFeePerGas: '0x0', - paymaster: '0x', - paymasterVerificationGasLimit: '0x0', - paymasterPostOpGasLimit: '0x0', - paymasterData: '0x', - signature: '0x' - }; + test('should sign a user operation', async () => { + // Create a sample user operation with all required fields + const userOp: UserOperation = { + sender: DUMMY_ADDRESS, + nonce: '0x0', + factory: '0x', + factoryData: '0x', + callData: '0x', + callGasLimit: '0x0', + verificationGasLimit: '0x0', + preVerificationGas: '0x0', + maxFeePerGas: '0x0', + maxPriorityFeePerGas: '0x0', + paymaster: '0x', + paymasterVerificationGasLimit: '0x0', + paymasterPostOpGasLimit: '0x0', + paymasterData: '0x', + signature: '0x', + }; - // Get porter URIs - const porterUris = await getPorterUris(DOMAIN as Domain); + // Get porter URIs + const porterUris = await getPorterUris(DOMAIN as Domain); - // Get context - const signingContext = await context.ConditionContext.forSigningCohort(provider, DOMAIN as Domain, RITUAL_ID, CHAIN_ID); + // Get context + const signingContext = await context.ConditionContext.forSigningCohort( + provider, + DOMAIN as Domain, + RITUAL_ID, + CHAIN_ID, + ); - // Sign user operation - const signResult = await signUserOp( - provider, - DOMAIN as Domain, - RITUAL_ID, - CHAIN_ID, - userOp, - '0.8.0', - signingContext, - porterUris - ); - console.log('Sign result:', signResult); + // Sign user operation + const signResult = await signUserOp( + provider, + DOMAIN as Domain, + RITUAL_ID, + CHAIN_ID, + userOp, + '0.8.0', + signingContext, + porterUris, + ); + console.log('Sign result:', signResult); - // Verify sign result - expect(signResult).toBeDefined(); - expect(signResult.messageHash).toBeDefined(); - expect(signResult.aggregatedSignature).toBeDefined(); - expect(signResult.signingResults).toBeDefined(); - expect(Object.keys(signResult.signingResults).length).toBeGreaterThan(0); - }, 150000); -}); \ No newline at end of file + // Verify sign result + expect(signResult).toBeDefined(); + expect(signResult.messageHash).toBeDefined(); + expect(signResult.aggregatedSignature).toBeDefined(); + expect(signResult.signingResults).toBeDefined(); + expect(Object.keys(signResult.signingResults).length).toBeGreaterThan(0); + }, 150000); + }, +); diff --git a/packages/taco/src/conditions/context/context.ts b/packages/taco/src/conditions/context/context.ts index 7c2264541..01c2cdc83 100644 --- a/packages/taco/src/conditions/context/context.ts +++ b/packages/taco/src/conditions/context/context.ts @@ -57,7 +57,6 @@ const EXPECTED_AUTH_PROVIDER_TYPES: Record = { ], }; - export const RESERVED_CONTEXT_PARAMS = [USER_ADDRESS_PARAM_DEFAULT]; export class ConditionContext { @@ -272,20 +271,20 @@ export class ConditionContext { chainId: number, ): Promise { // get signing condition from SigningCoordinator contract - const cohortConditionHex = await SigningCoordinatorAgent.getSigningCohortConditions( - provider, - domain, - cohortId, - chainId, - ); - + const cohortConditionHex = + await SigningCoordinatorAgent.getSigningCohortConditions( + provider, + domain, + cohortId, + chainId, + ); + // Convert hex string to UTF-8 JSON string const cohortConditionJson = ethers.utils.toUtf8String(cohortConditionHex); - + const cohortCondition = new CoreConditions(cohortConditionJson); - const conditionExpr = ConditionExpression.fromCoreConditions( - cohortCondition, - ); + const conditionExpr = + ConditionExpression.fromCoreConditions(cohortCondition); return new ConditionContext(conditionExpr.condition); } } diff --git a/packages/taco/src/index.ts b/packages/taco/src/index.ts index 6a83abc24..c355f38f7 100644 --- a/packages/taco/src/index.ts +++ b/packages/taco/src/index.ts @@ -11,5 +11,5 @@ export { export * as conditions from './conditions'; -export { decrypt, encrypt, encryptWithPublicKey } from './taco'; export { signUserOp } from './sign'; +export { decrypt, encrypt, encryptWithPublicKey } from './taco'; diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 482fcddf4..a1bfec622 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -34,7 +34,7 @@ export async function signUserOp( cohortId, ); console.log({ signers }); - + const threshold = await SigningCoordinatorAgent.getThreshold( provider, domain, @@ -42,20 +42,20 @@ export async function signUserOp( ); const pythonUserOp = convertUserOperationToPython(userOp); - + const signingRequest = new UserOperationSignatureRequest( pythonUserOp, aaVersion, cohortId, chainId, context || {}, - "userop" + 'userop', ); const signingRequests: Record = Object.fromEntries( signers.map((signer) => [ - signer.provider, - toBase64(signingRequest.toBytes()) + signer.provider, + toBase64(signingRequest.toBytes()), ]), ); diff --git a/packages/taco/test/conditions/context.test.ts b/packages/taco/test/conditions/context.test.ts index 402c8bb78..e0fb34840 100644 --- a/packages/taco/test/conditions/context.test.ts +++ b/packages/taco/test/conditions/context.test.ts @@ -1115,7 +1115,7 @@ describe('forSigningCohort', () => { const domain = 'lynx' as Domain; const cohortId = 1; const chainId = 11155111; - + // Mock signing cohort conditions JSON const mockConditionsJson = JSON.stringify({ version: '1.0.0', @@ -1126,26 +1126,27 @@ describe('forSigningCohort', () => { parameters: [':userAddress', 'latest'], returnValueTest: { comparator: '>', - value: 0 - } - } + value: 0, + }, + }, }); - + // Convert to hex string as the contract would return - const mockConditionsHex = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(mockConditionsJson)); + const mockConditionsHex = ethers.utils.hexlify( + ethers.utils.toUtf8Bytes(mockConditionsJson), + ); // Mock the SigningCoordinatorAgent method - const getSigningCohortConditionsSpy = vi.spyOn( - SigningCoordinatorAgent, - 'getSigningCohortConditions' - ).mockResolvedValue(mockConditionsHex); + const getSigningCohortConditionsSpy = vi + .spyOn(SigningCoordinatorAgent, 'getSigningCohortConditions') + .mockResolvedValue(mockConditionsHex); // Test the forSigningCohort method const conditionContext = await ConditionContext.forSigningCohort( mockProvider, domain, cohortId, - chainId + chainId, ); // Verify the method was called with correct parameters @@ -1153,12 +1154,14 @@ describe('forSigningCohort', () => { mockProvider, domain, cohortId, - chainId + chainId, ); // Verify the context was created correctly expect(conditionContext).toBeInstanceOf(ConditionContext); - expect(conditionContext.requestedContextParameters).toContain(':userAddress'); + expect(conditionContext.requestedContextParameters).toContain( + ':userAddress', + ); // Cleanup getSigningCohortConditionsSpy.mockRestore(); @@ -1171,14 +1174,18 @@ describe('forSigningCohort', () => { const chainId = 11155111; // Mock the SigningCoordinatorAgent method to throw an error - const getSigningCohortConditionsSpy = vi.spyOn( - SigningCoordinatorAgent, - 'getSigningCohortConditions' - ).mockRejectedValue(new Error('Cohort not found')); + const getSigningCohortConditionsSpy = vi + .spyOn(SigningCoordinatorAgent, 'getSigningCohortConditions') + .mockRejectedValue(new Error('Cohort not found')); // Test that error is propagated await expect( - ConditionContext.forSigningCohort(mockProvider, domain, cohortId, chainId) + ConditionContext.forSigningCohort( + mockProvider, + domain, + cohortId, + chainId, + ), ).rejects.toThrow('Cohort not found'); // Verify the method was called @@ -1186,7 +1193,7 @@ describe('forSigningCohort', () => { mockProvider, domain, cohortId, - chainId + chainId, ); // Cleanup @@ -1200,14 +1207,18 @@ describe('forSigningCohort', () => { const chainId = 11155111; // Mock the SigningCoordinatorAgent method to return invalid hex - const getSigningCohortConditionsSpy = vi.spyOn( - SigningCoordinatorAgent, - 'getSigningCohortConditions' - ).mockResolvedValue('0xinvalidhex'); + const getSigningCohortConditionsSpy = vi + .spyOn(SigningCoordinatorAgent, 'getSigningCohortConditions') + .mockResolvedValue('0xinvalidhex'); // Test that JSON parse error is handled await expect( - ConditionContext.forSigningCohort(mockProvider, domain, cohortId, chainId) + ConditionContext.forSigningCohort( + mockProvider, + domain, + cohortId, + chainId, + ), ).rejects.toThrow(); // Verify the method was called @@ -1215,14 +1226,13 @@ describe('forSigningCohort', () => { mockProvider, domain, cohortId, - chainId + chainId, ); // Cleanup getSigningCohortConditionsSpy.mockRestore(); }); - it('handles complex condition structures', async () => { const mockProvider = fakeProvider(); const domain = 'lynx' as Domain; @@ -1243,8 +1253,8 @@ describe('forSigningCohort', () => { parameters: [':userAddress', 'latest'], returnValueTest: { comparator: '>', - value: 0 - } + value: 0, + }, }, { conditionType: 'contract', @@ -1255,33 +1265,36 @@ describe('forSigningCohort', () => { parameters: [':userAddress'], returnValueTest: { comparator: '>=', - value: 1000 - } - } - ] - } + value: 1000, + }, + }, + ], + }, }); - + // Convert to hex string as the contract would return - const mockComplexConditionsHex = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(mockComplexConditionsJson)); + const mockComplexConditionsHex = ethers.utils.hexlify( + ethers.utils.toUtf8Bytes(mockComplexConditionsJson), + ); // Mock the SigningCoordinatorAgent method - const getSigningCohortConditionsSpy = vi.spyOn( - SigningCoordinatorAgent, - 'getSigningCohortConditions' - ).mockResolvedValue(mockComplexConditionsHex); + const getSigningCohortConditionsSpy = vi + .spyOn(SigningCoordinatorAgent, 'getSigningCohortConditions') + .mockResolvedValue(mockComplexConditionsHex); // Test the forSigningCohort method with complex conditions const conditionContext = await ConditionContext.forSigningCohort( mockProvider, domain, cohortId, - chainId + chainId, ); // Verify the context was created correctly expect(conditionContext).toBeInstanceOf(ConditionContext); - expect(conditionContext.requestedContextParameters).toContain(':userAddress'); + expect(conditionContext.requestedContextParameters).toContain( + ':userAddress', + ); // Cleanup getSigningCohortConditionsSpy.mockRestore(); @@ -1298,25 +1311,31 @@ describe('forSigningCohort', () => { version: '1.0.0', condition: { conditionType: 'invalid_type', - missingRequiredFields: true - } + missingRequiredFields: true, + }, }); - + // Convert to hex string as the contract would return - const mockInvalidConditionsHex = ethers.utils.hexlify(ethers.utils.toUtf8Bytes(mockInvalidConditionsJson)); + const mockInvalidConditionsHex = ethers.utils.hexlify( + ethers.utils.toUtf8Bytes(mockInvalidConditionsJson), + ); // Mock the SigningCoordinatorAgent method - const getSigningCohortConditionsSpy = vi.spyOn( - SigningCoordinatorAgent, - 'getSigningCohortConditions' - ).mockResolvedValue(mockInvalidConditionsHex); + const getSigningCohortConditionsSpy = vi + .spyOn(SigningCoordinatorAgent, 'getSigningCohortConditions') + .mockResolvedValue(mockInvalidConditionsHex); // Test that invalid condition schema throws error await expect( - ConditionContext.forSigningCohort(mockProvider, domain, cohortId, chainId) + ConditionContext.forSigningCohort( + mockProvider, + domain, + cohortId, + chainId, + ), ).rejects.toThrow(); // Cleanup getSigningCohortConditionsSpy.mockRestore(); }); -}); \ No newline at end of file +}); diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index e631fbe61..2f019b123 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -1,4 +1,8 @@ -import { convertUserOperationToPython, PorterClient, SigningCoordinatorAgent } from '@nucypher/shared'; +import { + convertUserOperationToPython, + PorterClient, + SigningCoordinatorAgent, +} from '@nucypher/shared'; import { fakePorterUri } from '@nucypher/test-utils'; import { ethers } from 'ethers'; import { beforeEach, describe, expect, it, vi } from 'vitest'; @@ -12,11 +16,13 @@ describe('TACo Signing', () => { beforeEach(() => { signUserOpMock = vi.fn(); mockProvider = {} as ethers.providers.Provider; - - vi.spyOn(PorterClient.prototype, 'signUserOp').mockImplementation(signUserOpMock); + + vi.spyOn(PorterClient.prototype, 'signUserOp').mockImplementation( + signUserOpMock, + ); vi.spyOn(SigningCoordinatorAgent, 'getParticipants').mockResolvedValue([ { operator: '0x1234', provider: '0x5678', signature: '0x90ab' }, - { operator: '0xabcd', provider: '0xefgh', signature: '0xijkl' } + { operator: '0xabcd', provider: '0xefgh', signature: '0xijkl' }, ]); vi.spyOn(SigningCoordinatorAgent, 'getThreshold').mockResolvedValue(2); }); @@ -64,31 +70,35 @@ describe('TACo Signing', () => { userOp, aaVersion, undefined, - porterUris + porterUris, ); const pythonUserOp = convertUserOperationToPython(userOp); expect(signUserOpMock).toHaveBeenCalledWith( { - '0x5678': btoa(JSON.stringify({ - user_op: JSON.stringify(pythonUserOp), - aa_version: aaVersion, - cohort_id: cohortId, - chain_id: chainId, - context: {}, - signature_type: "userop" - })), - '0xefgh': btoa(JSON.stringify({ - user_op: JSON.stringify(pythonUserOp), - aa_version: aaVersion, - cohort_id: cohortId, - chain_id: chainId, - context: {}, - signature_type: "userop" - })) + '0x5678': btoa( + JSON.stringify({ + user_op: JSON.stringify(pythonUserOp), + aa_version: aaVersion, + cohort_id: cohortId, + chain_id: chainId, + context: {}, + signature_type: 'userop', + }), + ), + '0xefgh': btoa( + JSON.stringify({ + user_op: JSON.stringify(pythonUserOp), + aa_version: aaVersion, + cohort_id: cohortId, + chain_id: chainId, + context: {}, + signature_type: 'userop', + }), + ), }, - 2 + 2, ); expect(result).toEqual({ @@ -126,31 +136,35 @@ describe('TACo Signing', () => { userOp, aaVersion, undefined, - porterUris + porterUris, ); const pythonUserOp2 = convertUserOperationToPython(userOp); expect(signUserOpMock).toHaveBeenCalledWith( { - '0x5678': btoa(JSON.stringify({ - user_op: JSON.stringify(pythonUserOp2), - aa_version: aaVersion, - cohort_id: cohortId, - chain_id: chainId, - context: {}, - signature_type: "userop" - })), - '0xefgh': btoa(JSON.stringify({ - user_op: JSON.stringify(pythonUserOp2), - aa_version: aaVersion, - cohort_id: cohortId, - chain_id: chainId, - context: {}, - signature_type: "userop" - })) + '0x5678': btoa( + JSON.stringify({ + user_op: JSON.stringify(pythonUserOp2), + aa_version: aaVersion, + cohort_id: cohortId, + chain_id: chainId, + context: {}, + signature_type: 'userop', + }), + ), + '0xefgh': btoa( + JSON.stringify({ + user_op: JSON.stringify(pythonUserOp2), + aa_version: aaVersion, + cohort_id: cohortId, + chain_id: chainId, + context: {}, + signature_type: 'userop', + }), + ), }, - 2 + 2, ); }); }); From cd9a9e530ef64fdb246471344860ab5f8596bdf8 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 2 Jul 2025 14:12:16 -0400 Subject: [PATCH 111/303] Fix UserOperation struct types to match spec. --- packages/shared/src/types.ts | 34 ++++++++++----------- packages/taco/integration-test/sign.test.ts | 16 +++++----- packages/taco/test/taco-sign.test.ts | 16 +++++----- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/packages/shared/src/types.ts b/packages/shared/src/types.ts index 6f5f7cb64..9148cef91 100644 --- a/packages/shared/src/types.ts +++ b/packages/shared/src/types.ts @@ -6,18 +6,18 @@ export type Base64EncodedBytes = string; export type UserOperation = { sender: string; - nonce: string; + nonce: number; factory: string; factoryData: string; callData: string; - callGasLimit: string; - verificationGasLimit: string; - preVerificationGas: string; - maxFeePerGas: string; - maxPriorityFeePerGas: string; + callGasLimit: number; + verificationGasLimit: number; + preVerificationGas: number; + maxFeePerGas: number; + maxPriorityFeePerGas: number; paymaster: string; - paymasterVerificationGasLimit: string; - paymasterPostOpGasLimit: string; + paymasterVerificationGasLimit: number; + paymasterPostOpGasLimit: number; paymasterData: string; signature: string; }; @@ -64,20 +64,18 @@ function normalizeAddress(address: string): string | null { export function convertUserOperationToPython(userOp: UserOperation) { return { sender: normalizeAddress(userOp.sender), - nonce: parseInt(userOp.nonce, 16) || 0, + nonce: userOp.nonce, factory: normalizeAddress(userOp.factory), factory_data: userOp.factoryData || '0x', call_data: userOp.callData || '0x', - call_gas_limit: parseInt(userOp.callGasLimit, 16) || 0, - verification_gas_limit: parseInt(userOp.verificationGasLimit, 16) || 0, - pre_verification_gas: parseInt(userOp.preVerificationGas, 16) || 0, - max_fee_per_gas: parseInt(userOp.maxFeePerGas, 16) || 0, - max_priority_fee_per_gas: parseInt(userOp.maxPriorityFeePerGas, 16) || 0, + call_gas_limit: userOp.callGasLimit, + verification_gas_limit: userOp.verificationGasLimit, + pre_verification_gas: userOp.preVerificationGas, + max_fee_per_gas: userOp.maxFeePerGas, + max_priority_fee_per_gas: userOp.maxPriorityFeePerGas, paymaster: normalizeAddress(userOp.paymaster), - paymaster_verification_gas_limit: - parseInt(userOp.paymasterVerificationGasLimit, 16) || 0, - paymaster_post_op_gas_limit: - parseInt(userOp.paymasterPostOpGasLimit, 16) || 0, + paymaster_verification_gas_limit: userOp.paymasterVerificationGasLimit, + paymaster_post_op_gas_limit: userOp.paymasterPostOpGasLimit, paymaster_data: userOp.paymasterData || '0x', signature: userOp.signature || '0x', }; diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index 894026572..e09bf57ce 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -36,18 +36,18 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( // Create a sample user operation with all required fields const userOp: UserOperation = { sender: DUMMY_ADDRESS, - nonce: '0x0', + nonce: 0, factory: '0x', factoryData: '0x', callData: '0x', - callGasLimit: '0x0', - verificationGasLimit: '0x0', - preVerificationGas: '0x0', - maxFeePerGas: '0x0', - maxPriorityFeePerGas: '0x0', + callGasLimit: 0, + verificationGasLimit: 0, + preVerificationGas: 0, + maxFeePerGas: 0, + maxPriorityFeePerGas: 0, paymaster: '0x', - paymasterVerificationGasLimit: '0x0', - paymasterPostOpGasLimit: '0x0', + paymasterVerificationGasLimit: 0, + paymasterPostOpGasLimit: 0, paymasterData: '0x', signature: '0x', }; diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index 2f019b123..e109bf6b0 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -30,18 +30,18 @@ describe('TACo Signing', () => { describe('signUserOp', () => { const userOp = { sender: '0x742D35Cc6634C0532925A3b8D33c9c0E7B66C8E8', - nonce: '0x1', + nonce: 1, factory: '0x0000000000000000000000000000000000000000', factoryData: '0x', callData: '0xabc', - callGasLimit: '0x20000', - verificationGasLimit: '0x15000', - preVerificationGas: '0x1000', - maxFeePerGas: '0xabc', - maxPriorityFeePerGas: '0x123', + callGasLimit: 131072, + verificationGasLimit: 86016, + preVerificationGas: 4096, + maxFeePerGas: 2748, + maxPriorityFeePerGas: 291, paymaster: '0x0000000000000000000000000000000000000000', - paymasterVerificationGasLimit: '0x0', - paymasterPostOpGasLimit: '0x0', + paymasterVerificationGasLimit: 0, + paymasterPostOpGasLimit: 0, paymasterData: '0x', signature: '0x', }; From 142cbffa1511cc8bec97a6e0771f4a7ade92ad68 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 4 Jul 2025 08:12:43 -0400 Subject: [PATCH 112/303] Add integration test that validates condition lingo for various condition types. The lingo is validated by calling the /validate_condition_lingo endpoint on one of the lynx nodes. --- .../integration-test/condition-lingo.test.ts | 103 ++++++++++++++++++ packages/taco/package.json | 1 + .../test/conditions/condition-expr.test.ts | 4 +- packages/taco/test/test-utils.ts | 2 +- pnpm-lock.yaml | 3 + 5 files changed, 109 insertions(+), 4 deletions(-) create mode 100644 packages/taco/integration-test/condition-lingo.test.ts diff --git a/packages/taco/integration-test/condition-lingo.test.ts b/packages/taco/integration-test/condition-lingo.test.ts new file mode 100644 index 000000000..d8efd12e0 --- /dev/null +++ b/packages/taco/integration-test/condition-lingo.test.ts @@ -0,0 +1,103 @@ +import axios from 'axios'; +import * as https from 'https'; +import { describe, test } from 'vitest'; +import { CompoundConditionType } from '../src/conditions/compound-condition'; +import { ConditionExpression } from '../src/conditions/condition-expr'; +import { IfThenElseConditionType } from '../src/conditions/if-then-else-condition'; +import { SequentialCondition } from '../src/conditions/sequential'; +import { + testContractConditionObj, + testJsonApiConditionObj, + testJsonRpcConditionObj, + testJWTConditionObj, + testRpcConditionObj, + testSigningObjectAbiAttributeConditionObj, + testSigningObjectAttributeConditionObj, + testTimeConditionObj, +} from '../test/test-utils'; + +const LYNX_NODES = [ + 'https://lynx-1.nucypher.network', + 'https://lynx-2.nucypher.network', + 'https://lynx-3.nucypher.network', +]; + +async function validateConditionExpression( + conditionExpr: ConditionExpression, +): Promise { + const lynxNode = LYNX_NODES[Math.floor(Math.random() * LYNX_NODES.length)]; + const httpsAgent = new https.Agent({ + rejectUnauthorized: false, + }); + + const response = await axios.post( + `${lynxNode}:9151/validate_condition_lingo`, + JSON.stringify(conditionExpr.toJson()), + { + httpsAgent, + headers: { + 'Content-Type': 'application/json', + }, + }, + ); + if (response.status !== 200) { + throw new Error( + `Request failed with status ${response.status}: ${JSON.stringify(response.data)}`, + ); + } + return; +} + +describe.skipIf(!process.env.RUNNING_IN_CI)( + 'TACo Condition Lingos Integration Test', + () => { + test('validate condition lingo with lynx node to confirm consistency', async () => { + const overallCondition = new SequentialCondition({ + conditionVariables: [ + { + varName: 'rpc', + condition: testRpcConditionObj, + }, + { + varName: 'time', + condition: testTimeConditionObj, + }, + { + varName: 'contract', + condition: testContractConditionObj, + }, + { + varName: 'compound', + condition: { + conditionType: CompoundConditionType, + operator: 'or', + operands: [ + testJsonApiConditionObj, + testJsonRpcConditionObj, + testSigningObjectAbiAttributeConditionObj, + testSigningObjectAttributeConditionObj, + ], + }, + }, + { + varName: 'ifThenElse', + condition: { + conditionType: IfThenElseConditionType, + ifCondition: testJWTConditionObj, + thenCondition: { + ...testJsonApiConditionObj, + authorizationToken: ':authToken', + }, + elseCondition: { + ...testJsonRpcConditionObj, + authorizationToken: ':otherAuthToken', + }, + }, + }, + ], + }); + const conditionExpr = new ConditionExpression(overallCondition); + await validateConditionExpression(conditionExpr); + }, 15000); + }, +); diff --git a/packages/taco/package.json b/packages/taco/package.json index 39fcf9f7e..ec9d3e075 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -52,6 +52,7 @@ "devDependencies": { "@nucypher/test-utils": "workspace:*", "@types/semver": "^7.7.0", + "axios": "^1.8.4", "dotenv": "^16.5.0", "glob": "^11.0.1", "modified-zod2md": "0.1.5-modified.4" diff --git a/packages/taco/test/conditions/condition-expr.test.ts b/packages/taco/test/conditions/condition-expr.test.ts index a5a22944e..706879520 100644 --- a/packages/taco/test/conditions/condition-expr.test.ts +++ b/packages/taco/test/conditions/condition-expr.test.ts @@ -414,9 +414,7 @@ describe('condition set', () => { const conditionExprJson = conditionExpr.toJson(); expect(conditionExprJson).toBeDefined(); expect(conditionExprJson).toContain('endpoint'); - expect(conditionExprJson).toContain( - 'https://_this_would_totally_fail.com', - ); + expect(conditionExprJson).toContain('https://api.example.com/data'); expect(conditionExprJson).toContain('parameters'); expect(conditionExprJson).toContain('query'); expect(conditionExprJson).toContain('$.ethereum.usd'); diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 70a5f2754..cac43abf8 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -269,7 +269,7 @@ export const testTimeConditionObj: TimeConditionProps = { export const testJsonApiConditionObj: JsonApiConditionProps = { conditionType: JsonApiConditionType, - endpoint: 'https://_this_would_totally_fail.com', + endpoint: 'https://api.example.com/data', parameters: { ids: 'ethereum', vs_currencies: 'usd', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3facfa5f7..47726b170 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -591,6 +591,9 @@ importers: '@types/semver': specifier: ^7.7.0 version: 7.7.1 + axios: + specifier: ^1.8.4 + version: 1.15.0 dotenv: specifier: ^16.5.0 version: 16.6.1 From b41eeebe07d25d57b0414567357a0226fe1c3b5f Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 4 Jul 2025 08:13:25 -0400 Subject: [PATCH 113/303] Integration test cleanup of test name, and timeout value (for signing it was too long). --- packages/taco/integration-test/encrypt-decrypt.test.ts | 2 +- packages/taco/integration-test/sign.test.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index 7b63626de..24116b2fa 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -29,7 +29,7 @@ const CHAIN_ID = 80002; const CONSUMER_ADDRESS = ethers.utils.computeAddress(CONSUMER_PRIVATE_KEY); describe.skipIf(!process.env.RUNNING_IN_CI)( - 'Taco Encrypt/Decrypt Integration Test', + 'TACo Encrypt/Decrypt Integration Test', () => { let provider: ethers.providers.JsonRpcProvider; let encryptorSigner: ethers.Wallet; diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index e09bf57ce..be70cc2eb 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -13,7 +13,7 @@ const RITUAL_ID = 1; const CHAIN_ID = 11155111; describe.skipIf(!process.env.RUNNING_IN_CI)( - 'Taco Sign Integration Test', + 'TACo Sign Integration Test', () => { let provider: ethers.providers.JsonRpcProvider; @@ -82,6 +82,6 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( expect(signResult.aggregatedSignature).toBeDefined(); expect(signResult.signingResults).toBeDefined(); expect(Object.keys(signResult.signingResults).length).toBeGreaterThan(0); - }, 150000); + }, 15000); }, ); From e1c8fd1bda3b8ea1f7595c517b785c9ece785104 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Mon, 7 Jul 2025 08:31:21 -0400 Subject: [PATCH 114/303] Add comment to clarify running of integration tests. --- packages/taco/integration-test/condition-lingo.test.ts | 1 + packages/taco/integration-test/encrypt-decrypt.test.ts | 1 + packages/taco/integration-test/sign.test.ts | 1 + 3 files changed, 3 insertions(+) diff --git a/packages/taco/integration-test/condition-lingo.test.ts b/packages/taco/integration-test/condition-lingo.test.ts index d8efd12e0..4f2824d52 100644 --- a/packages/taco/integration-test/condition-lingo.test.ts +++ b/packages/taco/integration-test/condition-lingo.test.ts @@ -48,6 +48,7 @@ async function validateConditionExpression( return; } +// skip integration test if RUNNING_IN_CI is not set (it is set in CI environments) describe.skipIf(!process.env.RUNNING_IN_CI)( 'TACo Condition Lingos Integration Test', () => { diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index 24116b2fa..2f1f992b5 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -28,6 +28,7 @@ const CHAIN_ID = 80002; // The wallet address of our consumer const CONSUMER_ADDRESS = ethers.utils.computeAddress(CONSUMER_PRIVATE_KEY); +// skip integration test if RUNNING_IN_CI is not set (it is set in CI environments) describe.skipIf(!process.env.RUNNING_IN_CI)( 'TACo Encrypt/Decrypt Integration Test', () => { diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index be70cc2eb..2ae4877e9 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -12,6 +12,7 @@ const DOMAIN = 'lynx'; const RITUAL_ID = 1; const CHAIN_ID = 11155111; +// skip integration test if RUNNING_IN_CI is not set (it is set in CI environments) describe.skipIf(!process.env.RUNNING_IN_CI)( 'TACo Sign Integration Test', () => { From 149cb3de671564b570a4133b2083059d080f6f22 Mon Sep 17 00:00:00 2001 From: KPrasch Date: Wed, 9 Jul 2025 18:32:06 +0200 Subject: [PATCH 115/303] ECDSA condition implementation --- packages/taco/src/conditions/base/ecdsa.ts | 27 +++++++++++++ packages/taco/src/conditions/base/index.ts | 1 + .../taco/src/conditions/condition-factory.ts | 7 ++++ packages/taco/src/conditions/schemas/ecdsa.ts | 40 +++++++++++++++++++ .../schemas/export-for-zod-doc-gen.ts | 1 + packages/taco/src/conditions/schemas/utils.ts | 2 + 6 files changed, 78 insertions(+) create mode 100644 packages/taco/src/conditions/base/ecdsa.ts create mode 100644 packages/taco/src/conditions/schemas/ecdsa.ts diff --git a/packages/taco/src/conditions/base/ecdsa.ts b/packages/taco/src/conditions/base/ecdsa.ts new file mode 100644 index 000000000..df5453381 --- /dev/null +++ b/packages/taco/src/conditions/base/ecdsa.ts @@ -0,0 +1,27 @@ +import { Condition } from '../condition'; +import { + ECDSAConditionProps, + ecdsaConditionSchema, + ECDSAConditionType, +} from '../schemas/ecdsa'; +import { OmitConditionType } from '../shared'; + +export { + DEFAULT_ECDSA_CURVE, + ECDSACurve, + ECDSA_MESSAGE_PARAM_DEFAULT, + ECDSA_SIGNATURE_PARAM_DEFAULT, + ECDSAConditionProps, + ecdsaConditionSchema, + ECDSAConditionType, + SUPPORTED_ECDSA_CURVES, +} from '../schemas/ecdsa'; + +export class ECDSACondition extends Condition { + constructor(value: OmitConditionType) { + super(ecdsaConditionSchema, { + conditionType: ECDSAConditionType, + ...value, + }); + } +} \ No newline at end of file diff --git a/packages/taco/src/conditions/base/index.ts b/packages/taco/src/conditions/base/index.ts index 3a235473d..37d7be3e7 100644 --- a/packages/taco/src/conditions/base/index.ts +++ b/packages/taco/src/conditions/base/index.ts @@ -3,6 +3,7 @@ export * as addressAllowlist from './address-allowlist'; export * as contract from './contract'; +export * as ecdsa from './ecdsa'; export * as jsonApi from './json-api'; export * as jsonRpc from './json-rpc'; export * as jwt from './jwt'; diff --git a/packages/taco/src/conditions/condition-factory.ts b/packages/taco/src/conditions/condition-factory.ts index 3e2a599ff..9d44e42e4 100644 --- a/packages/taco/src/conditions/condition-factory.ts +++ b/packages/taco/src/conditions/condition-factory.ts @@ -8,6 +8,11 @@ import { ContractConditionProps, ContractConditionType, } from './base/contract'; +import { + ECDSACondition, + ECDSAConditionProps, + ECDSAConditionType, +} from './base/ecdsa'; import { JsonApiCondition, JsonApiConditionProps, @@ -63,6 +68,8 @@ export class ConditionFactory { return new TimeCondition(props as TimeConditionProps); case ContractConditionType: return new ContractCondition(props as ContractConditionProps); + case ECDSAConditionType: + return new ECDSACondition(props as ECDSAConditionProps); case JsonApiConditionType: return new JsonApiCondition(props as JsonApiConditionProps); case JsonRpcConditionType: diff --git a/packages/taco/src/conditions/schemas/ecdsa.ts b/packages/taco/src/conditions/schemas/ecdsa.ts new file mode 100644 index 000000000..a679e4b73 --- /dev/null +++ b/packages/taco/src/conditions/schemas/ecdsa.ts @@ -0,0 +1,40 @@ +import { z } from 'zod'; + +import { baseConditionSchema } from './common'; +import { contextParamSchema } from './context'; + +export const ECDSA_MESSAGE_PARAM_DEFAULT = ':ecdsaMessage'; +export const ECDSA_SIGNATURE_PARAM_DEFAULT = ':ecdsaSignature'; + +export const ECDSAConditionType = 'ecdsa'; + +// Supported ECDSA curves (must match Python backend format) +export const SUPPORTED_ECDSA_CURVES = [ + 'SECP256k1', + 'NIST256p', + 'NIST384p', + 'NIST521p', +] as const; + +export type ECDSACurve = typeof SUPPORTED_ECDSA_CURVES[number]; + +export const DEFAULT_ECDSA_CURVE: ECDSACurve = 'SECP256k1'; + +export const ecdsaConditionSchema = baseConditionSchema.extend({ + conditionType: z.literal(ECDSAConditionType).default(ECDSAConditionType), + message: z.union([ + z.string(), + contextParamSchema, + ]).default(ECDSA_MESSAGE_PARAM_DEFAULT), + signature: z.union([ + z.string().regex(/^[0-9a-fA-F]+$/, 'Signature must be a valid hex string'), + contextParamSchema, + ]).default(ECDSA_SIGNATURE_PARAM_DEFAULT), + verifyingKey: z.union([ + z.string().regex(/^[0-9a-fA-F]+$/, 'Verifying key must be a valid hex string'), + contextParamSchema, + ]), + curve: z.enum(SUPPORTED_ECDSA_CURVES).default(DEFAULT_ECDSA_CURVE), +}); + +export type ECDSAConditionProps = z.infer; \ No newline at end of file diff --git a/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts b/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts index 453fd8b2c..7c95702c2 100755 --- a/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts +++ b/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts @@ -11,6 +11,7 @@ export * from './context'; // ts-unused-exports:disable-next-line - this comment line is added to prevent lint from changing or objecting the export order. export * from './compound'; export * from './contract'; +export * from './ecdsa'; export * from './if-then-else'; export * from './json-api'; export * from './json-rpc'; diff --git a/packages/taco/src/conditions/schemas/utils.ts b/packages/taco/src/conditions/schemas/utils.ts index 57e212931..3425e4df3 100644 --- a/packages/taco/src/conditions/schemas/utils.ts +++ b/packages/taco/src/conditions/schemas/utils.ts @@ -4,6 +4,7 @@ import { compoundConditionSchema } from '../compound-condition'; import { addressAllowlistConditionSchema } from './address-allowlist'; import { contractConditionSchema } from './contract'; +import { ecdsaConditionSchema } from './ecdsa'; import { ifThenElseConditionSchema } from './if-then-else'; import { jsonApiConditionSchema } from './json-api'; import { jsonRpcConditionSchema } from './json-rpc'; @@ -22,6 +23,7 @@ export const anyConditionSchema: z.ZodSchema = z.lazy(() => timeConditionSchema, addressAllowlistConditionSchema, contractConditionSchema, + ecdsaConditionSchema, jsonApiConditionSchema, jsonRpcConditionSchema, jwtConditionSchema, From 4eaca89b65ad2199098c193c12651b0e2a64fa52 Mon Sep 17 00:00:00 2001 From: KPrasch Date: Wed, 9 Jul 2025 18:32:44 +0200 Subject: [PATCH 116/303] ECDSA condition testing --- .../integration-test/encrypt-decrypt.test.ts | 223 ++++++++++++++++++ .../taco/test/conditions/base/ecdsa.test.ts | 148 ++++++++++++ packages/taco/test/conditions/lingo.test.ts | 2 + packages/taco/test/test-utils.ts | 14 ++ 4 files changed, 387 insertions(+) create mode 100644 packages/taco/test/conditions/base/ecdsa.test.ts diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index 2f1f992b5..1310f2397 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -15,6 +15,7 @@ import { } from '../src'; import { CompoundCondition } from '../src/conditions/compound-condition'; import { UINT256_MAX } from '../test/test-utils'; +import { randomBytes, createHash } from 'crypto'; const RPC_PROVIDER_URL = 'https://rpc-amoy.polygon.technology'; const ENCRYPTOR_PRIVATE_KEY = @@ -189,5 +190,227 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( // Verify decryption was successful expect(decryptedMessageString).toEqual(messageString); }, 15000); // 15s timeout + + test('should encrypt and decrypt according to ECDSA signature condition', async () => { + // Create test message + const messageString = 'This message is protected by ECDSA signature verification 🔐'; + const message = toBytes(messageString); + + // Create a test ECDSA keypair for this test + const ecdsaWallet = ethers.Wallet.createRandom(); + const verifyingKey = ecdsaWallet.publicKey.slice(2); // Remove '0x' prefix for uncompressed public key + + // Message that needs to be signed for authorization + const authorizationMessage = 'I authorize access to this encrypted data'; + + // Create the signature that matches Python backend expectations + // Python uses SHA-256 and expects raw signature format + const messageHash = createHash('sha256').update(Buffer.from(authorizationMessage, 'utf8')).digest(); + + // Sign the hash with our private key + const signingKey = new ethers.utils.SigningKey(ecdsaWallet.privateKey); + const signature = signingKey.signDigest(messageHash); + + // Convert signature to hex format expected by Python (r+s format without 0x prefix) + const rHex = signature.r.slice(2).padStart(64, '0'); + const sHex = signature.s.slice(2).padStart(64, '0'); + const signatureHex = rHex + sHex; + + console.log('🔐 ECDSA Test Setup:'); + console.log(` Message: "${authorizationMessage}"`); + console.log(` Message Hash: ${messageHash.toString('hex')}`); + console.log(` Private Key: ${ecdsaWallet.privateKey}`); + console.log(` Public Key: ${verifyingKey}`); + console.log(` Signature R: ${rHex}`); + console.log(` Signature S: ${sHex}`); + console.log(` Full Signature: ${signatureHex}`); + + // Create ECDSA condition that verifies the signature + const ecdsaCondition = new conditions.base.ecdsa.ECDSACondition({ + message: authorizationMessage, + signature: ':ecdsaSignature', + verifyingKey: verifyingKey, + curve: 'SECP256k1', + }); + + // ECDSA condition doesn't require wallet authentication (requiresAuthentication = false) + // but it does have context variables that need to be provided + expect(ecdsaCondition.requiresAuthentication()).toBe(false); + + // Encrypt message with the ECDSA condition + const messageKit = await encrypt( + provider, + DOMAIN, + message, + ecdsaCondition, + RITUAL_ID, + encryptorSigner, + ); + + const encryptedBytes = messageKit.toBytes(); + + // Prepare for decryption + const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); + const conditionContext = + conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); + + // Verify that the context requires the ECDSA signature parameter + expect(conditionContext.requestedContextParameters.has(':ecdsaSignature')).toBe(true); + + // Add the signature to the condition context in the format expected by Python + conditionContext.addCustomContextParameterValues({ + ':ecdsaSignature': signatureHex + }); + + // Decrypt message + const decryptedBytes = await decrypt( + provider, + DOMAIN, + messageKitFromBytes, + conditionContext, + ); + const decryptedMessageString = fromBytes(decryptedBytes); + + // Verify decryption was successful + expect(decryptedMessageString).toEqual(messageString); + + console.log('✅ ECDSA condition test passed!'); + console.log(` Decrypted Message: "${decryptedMessageString}"`); + }, 20000); // 20s timeout + + test('should fail to decrypt with ECDSA condition when signature is invalid', async () => { + // Create test message + const messageString = 'This should fail with wrong signature'; + const message = toBytes(messageString); + + // Create a test ECDSA keypair + const ecdsaWallet = ethers.Wallet.createRandom(); + const verifyingKey = ecdsaWallet.publicKey.slice(2); + + // Message that needs to be signed + const authorizationMessage = 'I authorize access to this encrypted data'; + + // Create ECDSA condition + const ecdsaCondition = new conditions.base.ecdsa.ECDSACondition({ + message: authorizationMessage, + signature: ':ecdsaSignature', + verifyingKey: verifyingKey, + curve: 'SECP256k1', + }); + + // Encrypt message + const messageKit = await encrypt( + provider, + DOMAIN, + message, + ecdsaCondition, + RITUAL_ID, + encryptorSigner, + ); + + const encryptedBytes = messageKit.toBytes(); + + // Prepare for decryption with INVALID signature + const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); + const conditionContext = + conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); + + // Add an INVALID signature (just random hex) + const invalidSignature = '0x' + randomBytes(64).toString('hex'); + conditionContext.addCustomContextParameterValues({ + ':ecdsaSignature': invalidSignature.slice(2) + }); + + // Attempt to decrypt should fail + await expect( + decrypt( + provider, + DOMAIN, + messageKitFromBytes, + conditionContext, + ) + ).rejects.toThrow(); + + console.log('✅ ECDSA invalid signature test passed - decryption properly failed'); + }, 20000); // 20s timeout + + test('should encrypt and decrypt with ECDSA condition using user address context', async () => { + // Create test message + const messageString = 'This message uses both ECDSA and user address authentication 🔐🆔'; + const message = toBytes(messageString); + + // Create a test ECDSA keypair + const ecdsaWallet = ethers.Wallet.createRandom(); + const verifyingKey = ecdsaWallet.publicKey.slice(2); + + // Create ECDSA condition that uses user address as the message + const ecdsaCondition = new conditions.base.ecdsa.ECDSACondition({ + message: USER_ADDRESS_PARAM_DEFAULT, // This makes it require wallet authentication + signature: ':ecdsaSignature', + verifyingKey: verifyingKey, + curve: 'SECP256k1', + }); + + // Now it should require authentication because it uses :userAddress + expect(ecdsaCondition.requiresAuthentication()).toBe(true); + + // Encrypt message + const messageKit = await encrypt( + provider, + DOMAIN, + message, + ecdsaCondition, + RITUAL_ID, + encryptorSigner, + ); + + const encryptedBytes = messageKit.toBytes(); + + // Prepare for decryption + const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); + const conditionContext = + conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); + + // Verify context parameters + expect(conditionContext.requestedContextParameters.has(USER_ADDRESS_PARAM_DEFAULT)).toBe(true); + expect(conditionContext.requestedContextParameters.has(':ecdsaSignature')).toBe(true); + + // Add auth provider for user address + const authProvider = new EIP4361AuthProvider(provider, consumerSigner); + conditionContext.addAuthProvider(USER_ADDRESS_PARAM_DEFAULT, authProvider); + + // Sign the user's address with our test key using correct format + const userAddress = await consumerSigner.getAddress(); + const messageHash = createHash('sha256').update(Buffer.from(userAddress, 'utf8')).digest(); + const signingKey = new ethers.utils.SigningKey(ecdsaWallet.privateKey); + const signature = signingKey.signDigest(messageHash); + + // Convert signature to hex format expected by Python (r+s format without 0x prefix) + const rHex = signature.r.slice(2).padStart(64, '0'); + const sHex = signature.s.slice(2).padStart(64, '0'); + const signatureHex = rHex + sHex; + + // Add the ECDSA signature to context + conditionContext.addCustomContextParameterValues({ + ':ecdsaSignature': signatureHex + }); + + // Decrypt message + const decryptedBytes = await decrypt( + provider, + DOMAIN, + messageKitFromBytes, + conditionContext, + ); + const decryptedMessageString = fromBytes(decryptedBytes); + + // Verify decryption was successful + expect(decryptedMessageString).toEqual(messageString); + + console.log('✅ ECDSA + User Address condition test passed!'); + console.log(` Message: "${messageString}"`); + console.log(` User Address: ${userAddress}`); + console.log(` ECDSA Signature: ${signatureHex.slice(0, 20)}...`); + }, 25000); // 25s timeout }, ); diff --git a/packages/taco/test/conditions/base/ecdsa.test.ts b/packages/taco/test/conditions/base/ecdsa.test.ts new file mode 100644 index 000000000..2fb13611b --- /dev/null +++ b/packages/taco/test/conditions/base/ecdsa.test.ts @@ -0,0 +1,148 @@ +import { describe, expect, it } from 'vitest'; + +import { + ECDSACondition, + ecdsaConditionSchema, + ECDSAConditionType, + SUPPORTED_ECDSA_CURVES, +} from '../../../src/conditions/base/ecdsa'; +import { testECDSAConditionObj } from '../../test-utils'; + +describe('ECDSACondition', () => { + describe('validation', () => { + it('accepts a valid schema', () => { + const result = ECDSACondition.validate( + ecdsaConditionSchema, + testECDSAConditionObj, + ); + + expect(result.error).toBeUndefined(); + expect(result.data).toEqual(testECDSAConditionObj); + }); + + it('rejects invalid message that is not a string or context variable', () => { + const badECDSAObj = { + ...testECDSAConditionObj, + message: 123, + }; + + const result = ECDSACondition.validate(ecdsaConditionSchema, badECDSAObj); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + message: { + _errors: expect.arrayContaining([ + 'Expected string, received number', + ]), + }, + }); + }); + + it('rejects invalid signature that is not a hex string', () => { + const badECDSAObj = { + ...testECDSAConditionObj, + signature: 'not-a-hex-string', + }; + + const result = ECDSACondition.validate(ecdsaConditionSchema, badECDSAObj); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + signature: { + _errors: ['Signature must be a valid hex string'], + }, + }); + }); + + it('rejects invalid verifying key that is not a hex string', () => { + const badECDSAObj = { + ...testECDSAConditionObj, + verifyingKey: 'not-a-hex-string', + }; + + const result = ECDSACondition.validate(ecdsaConditionSchema, badECDSAObj); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + verifyingKey: { + _errors: ['Verifying key must be a valid hex string'], + }, + }); + }); + + it('rejects invalid curve', () => { + const badECDSAObj = { + ...testECDSAConditionObj, + curve: 'invalid-curve', + }; + + const result = ECDSACondition.validate(ecdsaConditionSchema, badECDSAObj); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + curve: { + _errors: expect.arrayContaining([ + expect.stringContaining('Invalid enum value'), + ]), + }, + }); + }); + + it('accepts valid curves', () => { + SUPPORTED_ECDSA_CURVES.forEach((curve) => { + const ecdsaObj = { + ...testECDSAConditionObj, + curve, + }; + + const result = ECDSACondition.validate(ecdsaConditionSchema, ecdsaObj); + + expect(result.error).toBeUndefined(); + expect(result.data).toEqual(ecdsaObj); + }); + }); + + it('accepts context variables for message', () => { + const ecdsaObj = { + ...testECDSAConditionObj, + message: ':customMessage', + }; + + const result = ECDSACondition.validate(ecdsaConditionSchema, ecdsaObj); + + expect(result.error).toBeUndefined(); + expect(result.data).toEqual(ecdsaObj); + }); + + it('accepts context variables for signature', () => { + const ecdsaObj = { + ...testECDSAConditionObj, + signature: ':customSignature', + }; + + const result = ECDSACondition.validate(ecdsaConditionSchema, ecdsaObj); + + expect(result.error).toBeUndefined(); + expect(result.data).toEqual(ecdsaObj); + }); + + it('creates valid condition instance', () => { + const condition = new ECDSACondition({ + message: 'test message', + signature: 'abcdef123456', + verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', + curve: 'secp256k1', + }); + + expect(condition.value.conditionType).toBe(ECDSAConditionType); + expect(condition.value.message).toBe('test message'); + expect(condition.value.signature).toBe('abcdef123456'); + expect(condition.value.verifyingKey).toBe('04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235'); + expect(condition.value.curve).toBe('secp256k1'); + }); + }); +}); \ No newline at end of file diff --git a/packages/taco/test/conditions/lingo.test.ts b/packages/taco/test/conditions/lingo.test.ts index 526e4d258..3878612e1 100644 --- a/packages/taco/test/conditions/lingo.test.ts +++ b/packages/taco/test/conditions/lingo.test.ts @@ -5,6 +5,7 @@ import { ContractCondition } from '../../src/conditions/base/contract'; import { ConditionExpression } from '../../src/conditions/condition-expr'; import { INT256_MIN, + testECDSAConditionObj, testJsonApiConditionObj, testJsonRpcConditionObj, testJWTConditionObj, @@ -89,6 +90,7 @@ describe('check that valid lingo in python is valid in typescript', () => { testJsonApiConditionObj, testJsonRpcConditionObj, testJWTConditionObj, + testECDSAConditionObj, compoundConditionProps, sequentialConditionProps, ifThenElseConditionProps, diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index cac43abf8..d4fe52cf2 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -49,6 +49,12 @@ import { JsonApiConditionProps, JsonApiConditionType, } from '../src/conditions/base/json-api'; +import { + ECDSA_MESSAGE_PARAM_DEFAULT, + ECDSA_SIGNATURE_PARAM_DEFAULT, + ECDSAConditionProps, + ECDSAConditionType, +} from '../src/conditions/base/ecdsa'; import { JWT_PARAM_DEFAULT, JWTConditionProps, @@ -297,6 +303,14 @@ export const testJWTConditionObj: JWTConditionProps = { jwtToken: JWT_PARAM_DEFAULT, }; +export const testECDSAConditionObj: ECDSAConditionProps = { + conditionType: ECDSAConditionType, + message: ECDSA_MESSAGE_PARAM_DEFAULT, + signature: ECDSA_SIGNATURE_PARAM_DEFAULT, + verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', + curve: 'SECP256k1', +}; + export const testRpcConditionObj: RpcConditionProps = { conditionType: RpcConditionType, chain: TEST_CHAIN_ID, From e83a6041461423299e5660f54ef3009ce0a74c52 Mon Sep 17 00:00:00 2001 From: KPrasch Date: Wed, 9 Jul 2025 18:34:20 +0200 Subject: [PATCH 117/303] ECDSA condition example --- packages/taco/examples/ecdsa-condition.ts | 116 ++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 packages/taco/examples/ecdsa-condition.ts diff --git a/packages/taco/examples/ecdsa-condition.ts b/packages/taco/examples/ecdsa-condition.ts new file mode 100644 index 000000000..9e160b3cf --- /dev/null +++ b/packages/taco/examples/ecdsa-condition.ts @@ -0,0 +1,116 @@ +import { ECDSACondition } from '../src/conditions/base/ecdsa'; + +// Example of creating an ECDSA condition +console.log('=== ECDSA Condition Example ==='); + +// Example 1: Basic ECDSA condition with static values +const basicECDSACondition = new ECDSACondition({ + message: 'Hello, world!', + signature: '304402206e41b6b588af8a85c9a9b2e8b4e2b6e1b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9', + verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', + curve: 'SECP256k1', +}); + +console.log('Basic ECDSA Condition:'); +console.log(JSON.stringify(basicECDSACondition.toObj(), null, 2)); + +// Example 2: ECDSA condition with context variables +const dynamicECDSACondition = new ECDSACondition({ + message: ':userMessage', + signature: ':userSignature', + verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', + curve: 'secp256k1', +}); + +console.log('\nDynamic ECDSA Condition (with context variables):'); +console.log(JSON.stringify(dynamicECDSACondition.toObj(), null, 2)); + +// Example 3: ECDSA condition with different curve +const p256ECDSACondition = new ECDSACondition({ + message: 'Authenticated message', + signature: ':ecdsaSignature', + verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', + curve: 'secp256r1', +}); + +console.log('\nECDSA Condition with P-256 curve:'); +console.log(JSON.stringify(p256ECDSACondition.toObj(), null, 2)); + +// Example 4: Using defaults for message and signature +const defaultECDSACondition = new ECDSACondition({ + message: ':ecdsaMessage', // Default context variable + signature: ':ecdsaSignature', // Default context variable + verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', + curve: 'secp256k1', // Default curve +}); + +console.log('\nECDSA Condition with defaults:'); +console.log(JSON.stringify(defaultECDSACondition.toObj(), null, 2)); + +// Example 5: Complex usage with compound condition +import { CompoundCondition } from '../src/conditions/compound-condition'; +import { TimeCondition } from '../src/conditions/base/time'; + +const timeCondition = new TimeCondition({ + returnValueTest: { + comparator: '>=', + value: 1643723400, + }, + chain: 1, + method: 'blocktime', +}); + +const compoundCondition = CompoundCondition.and([ + basicECDSACondition, + timeCondition, +]); + +console.log('\nCompound condition with ECDSA and time conditions:'); +console.log(JSON.stringify(compoundCondition.toObj(), null, 2)); + +// Example 6: Real-world usage scenario +console.log('\n=== Real-world Usage Scenario ==='); + +// This condition checks that: +// 1. The current time is after a specific timestamp +// 2. The user has provided a valid ECDSA signature for a specific message +const authorizationCondition = CompoundCondition.and([ + new TimeCondition({ + returnValueTest: { + comparator: '>=', + value: Math.floor(Date.now() / 1000), // Current timestamp + }, + chain: 1, + method: 'blocktime', + }), + new ECDSACondition({ + message: 'I authorize access to this encrypted data', + signature: ':userSignature', + verifyingKey: ':userPublicKey', + curve: 'secp256k1', + }), +]); + +console.log('Authorization condition:'); +console.log(JSON.stringify(authorizationCondition.toObj(), null, 2)); + +console.log('\n=== Supported Curves ==='); +console.log('The ECDSA condition supports the following curves:'); +console.log('- secp256k1 (Bitcoin, Ethereum)'); +console.log('- secp256r1 (P-256, widely used in TLS)'); +console.log('- secp384r1 (P-384)'); +console.log('- secp521r1 (P-521)'); + +console.log('\n=== Context Variables ==='); +console.log('The following context variables are commonly used:'); +console.log('- :ecdsaMessage (default) - The message that was signed'); +console.log('- :ecdsaSignature (default) - The signature to verify'); +console.log('- :userAddress - The user\'s address (from taco-auth)'); +console.log('- Custom context variables like :userMessage, :userSignature, etc.'); + +console.log('\n=== Usage Notes ==='); +console.log('1. The verifying key must be provided as a hex string'); +console.log('2. The signature must be provided as a hex string'); +console.log('3. The message can be a string or a context variable'); +console.log('4. The curve defaults to secp256k1 if not specified'); +console.log('5. Context variables are resolved at execution time'); \ No newline at end of file From 99fb48261830b0b667b5f76852364e5cab3f5d2b Mon Sep 17 00:00:00 2001 From: KPrasch Date: Fri, 11 Jul 2025 15:01:48 +0200 Subject: [PATCH 118/303] fixes elliptic curve cases and linting errors --- examples/pre/nextjs/next-env.d.ts | 2 +- packages/taco/examples/ecdsa-condition.ts | 8 ++++---- packages/taco/test/conditions/base/ecdsa.test.ts | 4 ++-- packages/taco/test/test-utils.ts | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/pre/nextjs/next-env.d.ts b/examples/pre/nextjs/next-env.d.ts index 40c3d6809..1b3be0840 100644 --- a/examples/pre/nextjs/next-env.d.ts +++ b/examples/pre/nextjs/next-env.d.ts @@ -2,4 +2,4 @@ /// // NOTE: This file should not be edited -// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. +// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/packages/taco/examples/ecdsa-condition.ts b/packages/taco/examples/ecdsa-condition.ts index 9e160b3cf..d5238569e 100644 --- a/packages/taco/examples/ecdsa-condition.ts +++ b/packages/taco/examples/ecdsa-condition.ts @@ -19,7 +19,7 @@ const dynamicECDSACondition = new ECDSACondition({ message: ':userMessage', signature: ':userSignature', verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', - curve: 'secp256k1', + curve: 'SECP256k1', }); console.log('\nDynamic ECDSA Condition (with context variables):'); @@ -30,7 +30,7 @@ const p256ECDSACondition = new ECDSACondition({ message: 'Authenticated message', signature: ':ecdsaSignature', verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', - curve: 'secp256r1', + curve: 'NIST256p', }); console.log('\nECDSA Condition with P-256 curve:'); @@ -41,7 +41,7 @@ const defaultECDSACondition = new ECDSACondition({ message: ':ecdsaMessage', // Default context variable signature: ':ecdsaSignature', // Default context variable verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', - curve: 'secp256k1', // Default curve + curve: 'SECP256k1', // Default curve }); console.log('\nECDSA Condition with defaults:'); @@ -87,7 +87,7 @@ const authorizationCondition = CompoundCondition.and([ message: 'I authorize access to this encrypted data', signature: ':userSignature', verifyingKey: ':userPublicKey', - curve: 'secp256k1', + curve: 'SECP256k1', }), ]); diff --git a/packages/taco/test/conditions/base/ecdsa.test.ts b/packages/taco/test/conditions/base/ecdsa.test.ts index 2fb13611b..96b581ad4 100644 --- a/packages/taco/test/conditions/base/ecdsa.test.ts +++ b/packages/taco/test/conditions/base/ecdsa.test.ts @@ -135,14 +135,14 @@ describe('ECDSACondition', () => { message: 'test message', signature: 'abcdef123456', verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', - curve: 'secp256k1', + curve: 'SECP256k1', }); expect(condition.value.conditionType).toBe(ECDSAConditionType); expect(condition.value.message).toBe('test message'); expect(condition.value.signature).toBe('abcdef123456'); expect(condition.value.verifyingKey).toBe('04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235'); - expect(condition.value.curve).toBe('secp256k1'); + expect(condition.value.curve).toBe('SECP256k1'); }); }); }); \ No newline at end of file diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index d4fe52cf2..84539b772 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -45,16 +45,16 @@ import { ContractConditionType, FunctionAbiProps, } from '../src/conditions/base/contract'; -import { - JsonApiConditionProps, - JsonApiConditionType, -} from '../src/conditions/base/json-api'; import { ECDSA_MESSAGE_PARAM_DEFAULT, ECDSA_SIGNATURE_PARAM_DEFAULT, ECDSAConditionProps, ECDSAConditionType, } from '../src/conditions/base/ecdsa'; +import { + JsonApiConditionProps, + JsonApiConditionType, +} from '../src/conditions/base/json-api'; import { JWT_PARAM_DEFAULT, JWTConditionProps, From 06110a1a19ef907421a1c81e3967245e95c18185 Mon Sep 17 00:00:00 2001 From: KPrasch Date: Fri, 18 Jul 2025 11:31:54 +0200 Subject: [PATCH 119/303] unhardcodes signing keys for ecdsa condition tests --- packages/taco/examples/ecdsa-condition.ts | 46 +++++++++++++++---- .../integration-test/encrypt-decrypt.test.ts | 19 -------- packages/taco/integration-test/sign.test.ts | 1 - 3 files changed, 38 insertions(+), 28 deletions(-) diff --git a/packages/taco/examples/ecdsa-condition.ts b/packages/taco/examples/ecdsa-condition.ts index d5238569e..038ffa9da 100644 --- a/packages/taco/examples/ecdsa-condition.ts +++ b/packages/taco/examples/ecdsa-condition.ts @@ -3,16 +3,18 @@ import { ECDSACondition } from '../src/conditions/base/ecdsa'; // Example of creating an ECDSA condition console.log('=== ECDSA Condition Example ==='); -// Example 1: Basic ECDSA condition with static values -const basicECDSACondition = new ECDSACondition({ - message: 'Hello, world!', - signature: '304402206e41b6b588af8a85c9a9b2e8b4e2b6e1b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9', +// Example 1: Practical ECDSA condition - attestation with hardcoded message, dynamic signature +// This is useful for scenarios where users must sign a specific agreement or attestation +const attestationCondition = new ECDSACondition({ + message: 'I attest that I am authorized to access this data and agree to use it responsibly', + signature: ':userSignature', // User provides signature at runtime verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', curve: 'SECP256k1', }); -console.log('Basic ECDSA Condition:'); -console.log(JSON.stringify(basicECDSACondition.toObj(), null, 2)); +console.log('Practical ECDSA Condition (Attestation):'); +console.log(JSON.stringify(attestationCondition.toObj(), null, 2)); +console.log('Note: User must sign the exact message "I attest..." with their private key to gain access'); // Example 2: ECDSA condition with context variables const dynamicECDSACondition = new ECDSACondition({ @@ -61,7 +63,7 @@ const timeCondition = new TimeCondition({ }); const compoundCondition = CompoundCondition.and([ - basicECDSACondition, + attestationCondition, timeCondition, ]); @@ -113,4 +115,32 @@ console.log('1. The verifying key must be provided as a hex string'); console.log('2. The signature must be provided as a hex string'); console.log('3. The message can be a string or a context variable'); console.log('4. The curve defaults to secp256k1 if not specified'); -console.log('5. Context variables are resolved at execution time'); \ No newline at end of file +console.log('5. Context variables are resolved at execution time'); + +console.log('\n=== Practical Use Cases ==='); +console.log('1. Attestation Pattern (Example 1): Fixed message + dynamic signature'); +console.log(' - User must sign a specific agreement or attestation'); +console.log(' - Verifies user consent to specific terms'); +console.log(' - Common for compliance and legal requirements'); + +console.log('\n2. Dynamic Pattern (Example 2): Context variables for both message and signature'); +console.log(' - Most flexible approach'); +console.log(' - Message and signature provided at decryption time'); +console.log(' - Useful for challenge-response scenarios'); + +console.log('\n3. User Identity Pattern (Example 6): User address as message'); +console.log(' - Proves control of both wallet and ECDSA key'); +console.log(' - Combines wallet authentication with custom key verification'); +console.log(' - Useful for multi-factor authentication'); + +console.log('\n=== Anti-Patterns to Avoid ==='); +console.log('❌ DO NOT hardcode both message AND signature:'); +console.log(' - This makes the condition always pass or always fail'); +console.log(' - No dynamic verification occurs'); +console.log(' - Not useful for access control'); +console.log(' - Example: { message: "fixed", signature: "0x123...", ... }'); + +console.log('\n✅ DO use these patterns instead:'); +console.log(' - Fixed message + dynamic signature (attestations)'); +console.log(' - Dynamic message + dynamic signature (flexible auth)'); +console.log(' - Context variables for runtime resolution'); \ No newline at end of file diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index 1310f2397..d9a2b9a9e 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -216,15 +216,6 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const sHex = signature.s.slice(2).padStart(64, '0'); const signatureHex = rHex + sHex; - console.log('🔐 ECDSA Test Setup:'); - console.log(` Message: "${authorizationMessage}"`); - console.log(` Message Hash: ${messageHash.toString('hex')}`); - console.log(` Private Key: ${ecdsaWallet.privateKey}`); - console.log(` Public Key: ${verifyingKey}`); - console.log(` Signature R: ${rHex}`); - console.log(` Signature S: ${sHex}`); - console.log(` Full Signature: ${signatureHex}`); - // Create ECDSA condition that verifies the signature const ecdsaCondition = new conditions.base.ecdsa.ECDSACondition({ message: authorizationMessage, @@ -273,9 +264,6 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( // Verify decryption was successful expect(decryptedMessageString).toEqual(messageString); - - console.log('✅ ECDSA condition test passed!'); - console.log(` Decrypted Message: "${decryptedMessageString}"`); }, 20000); // 20s timeout test('should fail to decrypt with ECDSA condition when signature is invalid', async () => { @@ -330,8 +318,6 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( conditionContext, ) ).rejects.toThrow(); - - console.log('✅ ECDSA invalid signature test passed - decryption properly failed'); }, 20000); // 20s timeout test('should encrypt and decrypt with ECDSA condition using user address context', async () => { @@ -406,11 +392,6 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( // Verify decryption was successful expect(decryptedMessageString).toEqual(messageString); - - console.log('✅ ECDSA + User Address condition test passed!'); - console.log(` Message: "${messageString}"`); - console.log(` User Address: ${userAddress}`); - console.log(` ECDSA Signature: ${signatureHex.slice(0, 20)}...`); }, 25000); // 25s timeout }, ); diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index 2ae4877e9..953ed94f8 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -75,7 +75,6 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( signingContext, porterUris, ); - console.log('Sign result:', signResult); // Verify sign result expect(signResult).toBeDefined(); From 34658dde1100c53504b31f26cbcd0b9b6f1125d5 Mon Sep 17 00:00:00 2001 From: KPrasch Date: Fri, 18 Jul 2025 15:20:28 +0200 Subject: [PATCH 120/303] respond to RFCs in PR #679 --- packages/taco/examples/ecdsa-condition.ts | 95 ++++--------------- .../integration-test/encrypt-decrypt.test.ts | 82 +++------------- .../taco/src/conditions/schemas/common.ts | 5 + packages/taco/src/conditions/schemas/ecdsa.ts | 37 +++++++- .../taco/test/conditions/base/ecdsa.test.ts | 4 +- 5 files changed, 75 insertions(+), 148 deletions(-) diff --git a/packages/taco/examples/ecdsa-condition.ts b/packages/taco/examples/ecdsa-condition.ts index 038ffa9da..4148fcf60 100644 --- a/packages/taco/examples/ecdsa-condition.ts +++ b/packages/taco/examples/ecdsa-condition.ts @@ -1,10 +1,6 @@ import { ECDSACondition } from '../src/conditions/base/ecdsa'; -// Example of creating an ECDSA condition -console.log('=== ECDSA Condition Example ==='); - // Example 1: Practical ECDSA condition - attestation with hardcoded message, dynamic signature -// This is useful for scenarios where users must sign a specific agreement or attestation const attestationCondition = new ECDSACondition({ message: 'I attest that I am authorized to access this data and agree to use it responsibly', signature: ':userSignature', // User provides signature at runtime @@ -12,10 +8,6 @@ const attestationCondition = new ECDSACondition({ curve: 'SECP256k1', }); -console.log('Practical ECDSA Condition (Attestation):'); -console.log(JSON.stringify(attestationCondition.toObj(), null, 2)); -console.log('Note: User must sign the exact message "I attest..." with their private key to gain access'); - // Example 2: ECDSA condition with context variables const dynamicECDSACondition = new ECDSACondition({ message: ':userMessage', @@ -24,9 +16,6 @@ const dynamicECDSACondition = new ECDSACondition({ curve: 'SECP256k1', }); -console.log('\nDynamic ECDSA Condition (with context variables):'); -console.log(JSON.stringify(dynamicECDSACondition.toObj(), null, 2)); - // Example 3: ECDSA condition with different curve const p256ECDSACondition = new ECDSACondition({ message: 'Authenticated message', @@ -35,9 +24,6 @@ const p256ECDSACondition = new ECDSACondition({ curve: 'NIST256p', }); -console.log('\nECDSA Condition with P-256 curve:'); -console.log(JSON.stringify(p256ECDSACondition.toObj(), null, 2)); - // Example 4: Using defaults for message and signature const defaultECDSACondition = new ECDSACondition({ message: ':ecdsaMessage', // Default context variable @@ -46,9 +32,6 @@ const defaultECDSACondition = new ECDSACondition({ curve: 'SECP256k1', // Default curve }); -console.log('\nECDSA Condition with defaults:'); -console.log(JSON.stringify(defaultECDSACondition.toObj(), null, 2)); - // Example 5: Complex usage with compound condition import { CompoundCondition } from '../src/conditions/compound-condition'; import { TimeCondition } from '../src/conditions/base/time'; @@ -67,15 +50,7 @@ const compoundCondition = CompoundCondition.and([ timeCondition, ]); -console.log('\nCompound condition with ECDSA and time conditions:'); -console.log(JSON.stringify(compoundCondition.toObj(), null, 2)); - // Example 6: Real-world usage scenario -console.log('\n=== Real-world Usage Scenario ==='); - -// This condition checks that: -// 1. The current time is after a specific timestamp -// 2. The user has provided a valid ECDSA signature for a specific message const authorizationCondition = CompoundCondition.and([ new TimeCondition({ returnValueTest: { @@ -93,54 +68,26 @@ const authorizationCondition = CompoundCondition.and([ }), ]); -console.log('Authorization condition:'); -console.log(JSON.stringify(authorizationCondition.toObj(), null, 2)); - -console.log('\n=== Supported Curves ==='); -console.log('The ECDSA condition supports the following curves:'); -console.log('- secp256k1 (Bitcoin, Ethereum)'); -console.log('- secp256r1 (P-256, widely used in TLS)'); -console.log('- secp384r1 (P-384)'); -console.log('- secp521r1 (P-521)'); - -console.log('\n=== Context Variables ==='); -console.log('The following context variables are commonly used:'); -console.log('- :ecdsaMessage (default) - The message that was signed'); -console.log('- :ecdsaSignature (default) - The signature to verify'); -console.log('- :userAddress - The user\'s address (from taco-auth)'); -console.log('- Custom context variables like :userMessage, :userSignature, etc.'); - -console.log('\n=== Usage Notes ==='); -console.log('1. The verifying key must be provided as a hex string'); -console.log('2. The signature must be provided as a hex string'); -console.log('3. The message can be a string or a context variable'); -console.log('4. The curve defaults to secp256k1 if not specified'); -console.log('5. Context variables are resolved at execution time'); - -console.log('\n=== Practical Use Cases ==='); -console.log('1. Attestation Pattern (Example 1): Fixed message + dynamic signature'); -console.log(' - User must sign a specific agreement or attestation'); -console.log(' - Verifies user consent to specific terms'); -console.log(' - Common for compliance and legal requirements'); - -console.log('\n2. Dynamic Pattern (Example 2): Context variables for both message and signature'); -console.log(' - Most flexible approach'); -console.log(' - Message and signature provided at decryption time'); -console.log(' - Useful for challenge-response scenarios'); - -console.log('\n3. User Identity Pattern (Example 6): User address as message'); -console.log(' - Proves control of both wallet and ECDSA key'); -console.log(' - Combines wallet authentication with custom key verification'); -console.log(' - Useful for multi-factor authentication'); +// Example 7: Edwards curve example (Ed25519) +const ed25519Condition = new ECDSACondition({ + message: 'Edwards curve signature verification', + signature: ':ed25519Signature', + verifyingKey: 'a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd', + curve: 'Ed25519', +}); -console.log('\n=== Anti-Patterns to Avoid ==='); -console.log('❌ DO NOT hardcode both message AND signature:'); -console.log(' - This makes the condition always pass or always fail'); -console.log(' - No dynamic verification occurs'); -console.log(' - Not useful for access control'); -console.log(' - Example: { message: "fixed", signature: "0x123...", ... }'); +// Example 8: Brainpool curve example +const brainpoolCondition = new ECDSACondition({ + message: 'Brainpool P-256 verification', + signature: ':brainpoolSignature', + verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', + curve: 'BRAINPOOLP256r1', +}); -console.log('\n✅ DO use these patterns instead:'); -console.log(' - Fixed message + dynamic signature (attestations)'); -console.log(' - Dynamic message + dynamic signature (flexible auth)'); -console.log(' - Context variables for runtime resolution'); \ No newline at end of file +// Example 9: NIST P-384 curve +const p384Condition = new ECDSACondition({ + message: 'High-security P-384 verification', + signature: ':p384Signature', + verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', + curve: 'NIST384p', +}); \ No newline at end of file diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index d9a2b9a9e..177ac98db 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -26,10 +26,8 @@ const DOMAIN = 'lynx'; const RITUAL_ID = 27; const CHAIN_ID = 80002; -// The wallet address of our consumer const CONSUMER_ADDRESS = ethers.utils.computeAddress(CONSUMER_PRIVATE_KEY); -// skip integration test if RUNNING_IN_CI is not set (it is set in CI environments) describe.skipIf(!process.env.RUNNING_IN_CI)( 'TACo Encrypt/Decrypt Integration Test', () => { @@ -42,10 +40,8 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( encryptorSigner = new ethers.Wallet(ENCRYPTOR_PRIVATE_KEY, provider); consumerSigner = new ethers.Wallet(CONSUMER_PRIVATE_KEY, provider); - // Initialize the library await initialize(); - // Verify network connection const network = await provider.getNetwork(); if (network.chainId !== CHAIN_ID) { throw new Error( @@ -55,11 +51,9 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( }); test('should encrypt and decrypt a message with RPC balance condition less than UINT256_MAX', async (value) => { - // Create test message const messageString = 'This is a secret 🤐'; const message = toBytes(messageString); - // Create conditions const hasPositiveBalance = new conditions.base.rpc.RpcCondition({ chain: CHAIN_ID, method: 'eth_getBalance', @@ -77,7 +71,6 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( parameters: [':userAddress', 'latest'], returnValueTest: { comparator: '<', - // max uint256 value: UINT256_MAX, }, }, @@ -88,7 +81,6 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( balanceLessThanMaxUintBigInt, ]); - // Encrypt message const messageKit = await encrypt( provider, DOMAIN, @@ -100,12 +92,10 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const encryptedBytes = messageKit.toBytes(); - // Prepare for decryption const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); const conditionContext = conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); - // Add auth provider for condition if ( conditionContext.requestedContextParameters.has( USER_ADDRESS_PARAM_DEFAULT, @@ -118,7 +108,6 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( ); } - // Decrypt message const decryptedBytes = await decrypt( provider, DOMAIN, @@ -127,31 +116,26 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( ); const decryptedMessageString = fromBytes(decryptedBytes); - // Verify decryption expect(decryptedMessageString).toEqual(messageString); - }, 15000); // 15s timeout + }, 15000); test('should encrypt and decrypt according to wallet allowlist condition', async () => { - // Create test message const messageString = 'This message should only be accessible to allowed wallet addresses'; const message = toBytes(messageString); - // Create wallet allowlist condition with consumer address in the list const addressAllowlistCondition = new conditions.base.addressAllowlist.AddressAllowlistCondition({ userAddress: ':userAddress', addresses: [ CONSUMER_ADDRESS, - '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', // Some other address - '0x0000000000000000000000000000000000000001', // Another address + '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', + '0x0000000000000000000000000000000000000001', ], }); - // Verify that the condition requires authentication expect(addressAllowlistCondition.requiresAuthentication()).toBe(true); - // Encrypt message with the wallet allowlist condition const messageKit = await encrypt( provider, DOMAIN, @@ -163,12 +147,10 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const encryptedBytes = messageKit.toBytes(); - // Prepare for decryption const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); const conditionContext = conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); - // Add auth provider for the consumer wallet const authProvider = new EIP4361AuthProvider(provider, consumerSigner, { domain: 'localhost', uri: 'http://localhost:3000', @@ -178,7 +160,6 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( authProvider, ); - // Decrypt message const decryptedBytes = await decrypt( provider, DOMAIN, @@ -187,36 +168,28 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( ); const decryptedMessageString = fromBytes(decryptedBytes); - // Verify decryption was successful expect(decryptedMessageString).toEqual(messageString); - }, 15000); // 15s timeout + }, 15000); test('should encrypt and decrypt according to ECDSA signature condition', async () => { - // Create test message const messageString = 'This message is protected by ECDSA signature verification 🔐'; const message = toBytes(messageString); - // Create a test ECDSA keypair for this test const ecdsaWallet = ethers.Wallet.createRandom(); - const verifyingKey = ecdsaWallet.publicKey.slice(2); // Remove '0x' prefix for uncompressed public key + const verifyingKey = ecdsaWallet.publicKey.slice(2); // Remove '0x' prefix - // Message that needs to be signed for authorization const authorizationMessage = 'I authorize access to this encrypted data'; - // Create the signature that matches Python backend expectations - // Python uses SHA-256 and expects raw signature format + // Create signature matching Python backend expectations (SHA-256 + raw signature format) const messageHash = createHash('sha256').update(Buffer.from(authorizationMessage, 'utf8')).digest(); - - // Sign the hash with our private key const signingKey = new ethers.utils.SigningKey(ecdsaWallet.privateKey); const signature = signingKey.signDigest(messageHash); - // Convert signature to hex format expected by Python (r+s format without 0x prefix) + // Convert to hex format expected by Python (r+s format without 0x prefix) const rHex = signature.r.slice(2).padStart(64, '0'); const sHex = signature.s.slice(2).padStart(64, '0'); const signatureHex = rHex + sHex; - // Create ECDSA condition that verifies the signature const ecdsaCondition = new conditions.base.ecdsa.ECDSACondition({ message: authorizationMessage, signature: ':ecdsaSignature', @@ -224,11 +197,8 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( curve: 'SECP256k1', }); - // ECDSA condition doesn't require wallet authentication (requiresAuthentication = false) - // but it does have context variables that need to be provided expect(ecdsaCondition.requiresAuthentication()).toBe(false); - // Encrypt message with the ECDSA condition const messageKit = await encrypt( provider, DOMAIN, @@ -240,20 +210,16 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const encryptedBytes = messageKit.toBytes(); - // Prepare for decryption const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); const conditionContext = conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); - // Verify that the context requires the ECDSA signature parameter expect(conditionContext.requestedContextParameters.has(':ecdsaSignature')).toBe(true); - // Add the signature to the condition context in the format expected by Python conditionContext.addCustomContextParameterValues({ ':ecdsaSignature': signatureHex }); - // Decrypt message const decryptedBytes = await decrypt( provider, DOMAIN, @@ -262,23 +228,18 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( ); const decryptedMessageString = fromBytes(decryptedBytes); - // Verify decryption was successful expect(decryptedMessageString).toEqual(messageString); - }, 20000); // 20s timeout + }, 20000); test('should fail to decrypt with ECDSA condition when signature is invalid', async () => { - // Create test message const messageString = 'This should fail with wrong signature'; const message = toBytes(messageString); - // Create a test ECDSA keypair const ecdsaWallet = ethers.Wallet.createRandom(); const verifyingKey = ecdsaWallet.publicKey.slice(2); - // Message that needs to be signed const authorizationMessage = 'I authorize access to this encrypted data'; - // Create ECDSA condition const ecdsaCondition = new conditions.base.ecdsa.ECDSACondition({ message: authorizationMessage, signature: ':ecdsaSignature', @@ -286,7 +247,6 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( curve: 'SECP256k1', }); - // Encrypt message const messageKit = await encrypt( provider, DOMAIN, @@ -298,18 +258,16 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const encryptedBytes = messageKit.toBytes(); - // Prepare for decryption with INVALID signature const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); const conditionContext = conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); - // Add an INVALID signature (just random hex) + // Add invalid signature const invalidSignature = '0x' + randomBytes(64).toString('hex'); conditionContext.addCustomContextParameterValues({ ':ecdsaSignature': invalidSignature.slice(2) }); - // Attempt to decrypt should fail await expect( decrypt( provider, @@ -318,29 +276,25 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( conditionContext, ) ).rejects.toThrow(); - }, 20000); // 20s timeout + }, 20000); test('should encrypt and decrypt with ECDSA condition using user address context', async () => { - // Create test message const messageString = 'This message uses both ECDSA and user address authentication 🔐🆔'; const message = toBytes(messageString); - // Create a test ECDSA keypair const ecdsaWallet = ethers.Wallet.createRandom(); const verifyingKey = ecdsaWallet.publicKey.slice(2); - // Create ECDSA condition that uses user address as the message + // Use user address as the message to require wallet authentication const ecdsaCondition = new conditions.base.ecdsa.ECDSACondition({ - message: USER_ADDRESS_PARAM_DEFAULT, // This makes it require wallet authentication + message: USER_ADDRESS_PARAM_DEFAULT, signature: ':ecdsaSignature', verifyingKey: verifyingKey, curve: 'SECP256k1', }); - // Now it should require authentication because it uses :userAddress expect(ecdsaCondition.requiresAuthentication()).toBe(true); - // Encrypt message const messageKit = await encrypt( provider, DOMAIN, @@ -352,36 +306,31 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const encryptedBytes = messageKit.toBytes(); - // Prepare for decryption const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); const conditionContext = conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); - // Verify context parameters expect(conditionContext.requestedContextParameters.has(USER_ADDRESS_PARAM_DEFAULT)).toBe(true); expect(conditionContext.requestedContextParameters.has(':ecdsaSignature')).toBe(true); - // Add auth provider for user address const authProvider = new EIP4361AuthProvider(provider, consumerSigner); conditionContext.addAuthProvider(USER_ADDRESS_PARAM_DEFAULT, authProvider); - // Sign the user's address with our test key using correct format + // Sign the user's address with test key const userAddress = await consumerSigner.getAddress(); const messageHash = createHash('sha256').update(Buffer.from(userAddress, 'utf8')).digest(); const signingKey = new ethers.utils.SigningKey(ecdsaWallet.privateKey); const signature = signingKey.signDigest(messageHash); - // Convert signature to hex format expected by Python (r+s format without 0x prefix) + // Convert signature to hex format expected by Python (r+s format) const rHex = signature.r.slice(2).padStart(64, '0'); const sHex = signature.s.slice(2).padStart(64, '0'); const signatureHex = rHex + sHex; - // Add the ECDSA signature to context conditionContext.addCustomContextParameterValues({ ':ecdsaSignature': signatureHex }); - // Decrypt message const decryptedBytes = await decrypt( provider, DOMAIN, @@ -390,8 +339,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( ); const decryptedMessageString = fromBytes(decryptedBytes); - // Verify decryption was successful expect(decryptedMessageString).toEqual(messageString); - }, 25000); // 25s timeout + }, 25000); }, ); diff --git a/packages/taco/src/conditions/schemas/common.ts b/packages/taco/src/conditions/schemas/common.ts index b59038878..74c18134b 100644 --- a/packages/taco/src/conditions/schemas/common.ts +++ b/packages/taco/src/conditions/schemas/common.ts @@ -110,3 +110,8 @@ export const httpsURLSchema = z .refine((url) => validateHttpsURL(url), { message: 'Invalid URL', }); + +export const hexStringSchema = z + .string() + .regex(/^[0-9a-fA-F]+$/, 'Invalid hex string') + .describe('A string containing only hexadecimal characters (0-9, a-f, A-F)'); diff --git a/packages/taco/src/conditions/schemas/ecdsa.ts b/packages/taco/src/conditions/schemas/ecdsa.ts index a679e4b73..dbd744d8c 100644 --- a/packages/taco/src/conditions/schemas/ecdsa.ts +++ b/packages/taco/src/conditions/schemas/ecdsa.ts @@ -1,6 +1,6 @@ import { z } from 'zod'; -import { baseConditionSchema } from './common'; +import { baseConditionSchema, hexStringSchema } from './common'; import { contextParamSchema } from './context'; export const ECDSA_MESSAGE_PARAM_DEFAULT = ':ecdsaMessage'; @@ -10,10 +10,37 @@ export const ECDSAConditionType = 'ecdsa'; // Supported ECDSA curves (must match Python backend format) export const SUPPORTED_ECDSA_CURVES = [ - 'SECP256k1', + // NIST curves + 'NIST192p', + 'NIST224p', 'NIST256p', - 'NIST384p', + 'NIST384p', 'NIST521p', + // SECP curves + 'SECP112r1', + 'SECP112r2', + 'SECP128r1', + 'SECP160r1', + 'SECP256k1', + // Brainpool curves (r-variants) + 'BRAINPOOLP160r1', + 'BRAINPOOLP192r1', + 'BRAINPOOLP224r1', + 'BRAINPOOLP256r1', + 'BRAINPOOLP320r1', + 'BRAINPOOLP384r1', + 'BRAINPOOLP512r1', + // Brainpool curves (t-variants) + 'BRAINPOOLP160t1', + 'BRAINPOOLP192t1', + 'BRAINPOOLP224t1', + 'BRAINPOOLP256t1', + 'BRAINPOOLP320t1', + 'BRAINPOOLP384t1', + 'BRAINPOOLP512t1', + // Edwards curves + 'Ed25519', + 'Ed448', ] as const; export type ECDSACurve = typeof SUPPORTED_ECDSA_CURVES[number]; @@ -27,11 +54,11 @@ export const ecdsaConditionSchema = baseConditionSchema.extend({ contextParamSchema, ]).default(ECDSA_MESSAGE_PARAM_DEFAULT), signature: z.union([ - z.string().regex(/^[0-9a-fA-F]+$/, 'Signature must be a valid hex string'), + hexStringSchema, contextParamSchema, ]).default(ECDSA_SIGNATURE_PARAM_DEFAULT), verifyingKey: z.union([ - z.string().regex(/^[0-9a-fA-F]+$/, 'Verifying key must be a valid hex string'), + hexStringSchema, contextParamSchema, ]), curve: z.enum(SUPPORTED_ECDSA_CURVES).default(DEFAULT_ECDSA_CURVE), diff --git a/packages/taco/test/conditions/base/ecdsa.test.ts b/packages/taco/test/conditions/base/ecdsa.test.ts index 96b581ad4..2e68c1ebc 100644 --- a/packages/taco/test/conditions/base/ecdsa.test.ts +++ b/packages/taco/test/conditions/base/ecdsa.test.ts @@ -51,7 +51,7 @@ describe('ECDSACondition', () => { expect(result.data).toBeUndefined(); expect(result.error?.format()).toMatchObject({ signature: { - _errors: ['Signature must be a valid hex string'], + _errors: ['Invalid hex string'], }, }); }); @@ -68,7 +68,7 @@ describe('ECDSACondition', () => { expect(result.data).toBeUndefined(); expect(result.error?.format()).toMatchObject({ verifyingKey: { - _errors: ['Verifying key must be a valid hex string'], + _errors: ['Invalid hex string'], }, }); }); From 2e911610a8594009bcdaac4c281ee708a974ea8d Mon Sep 17 00:00:00 2001 From: KPrasch Date: Fri, 18 Jul 2025 15:34:58 +0200 Subject: [PATCH 121/303] removes support for verifying key as a context variable --- packages/taco/examples/ecdsa-condition.ts | 10 +- .../integration-test/encrypt-decrypt.test.ts | 185 ++---------------- packages/taco/src/conditions/schemas/ecdsa.ts | 4 - .../taco/test/conditions/base/ecdsa.test.ts | 17 -- packages/taco/test/test-utils.ts | 1 - 5 files changed, 16 insertions(+), 201 deletions(-) diff --git a/packages/taco/examples/ecdsa-condition.ts b/packages/taco/examples/ecdsa-condition.ts index 4148fcf60..a6913a48a 100644 --- a/packages/taco/examples/ecdsa-condition.ts +++ b/packages/taco/examples/ecdsa-condition.ts @@ -1,10 +1,9 @@ import { ECDSACondition } from '../src/conditions/base/ecdsa'; -// Example 1: Practical ECDSA condition - attestation with hardcoded message, dynamic signature +// Example 1: ECDSA condition with hardcoded message, dynamic signature const attestationCondition = new ECDSACondition({ message: 'I attest that I am authorized to access this data and agree to use it responsibly', signature: ':userSignature', // User provides signature at runtime - verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', curve: 'SECP256k1', }); @@ -12,7 +11,6 @@ const attestationCondition = new ECDSACondition({ const dynamicECDSACondition = new ECDSACondition({ message: ':userMessage', signature: ':userSignature', - verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', curve: 'SECP256k1', }); @@ -20,7 +18,6 @@ const dynamicECDSACondition = new ECDSACondition({ const p256ECDSACondition = new ECDSACondition({ message: 'Authenticated message', signature: ':ecdsaSignature', - verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', curve: 'NIST256p', }); @@ -28,7 +25,6 @@ const p256ECDSACondition = new ECDSACondition({ const defaultECDSACondition = new ECDSACondition({ message: ':ecdsaMessage', // Default context variable signature: ':ecdsaSignature', // Default context variable - verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', curve: 'SECP256k1', // Default curve }); @@ -63,7 +59,6 @@ const authorizationCondition = CompoundCondition.and([ new ECDSACondition({ message: 'I authorize access to this encrypted data', signature: ':userSignature', - verifyingKey: ':userPublicKey', curve: 'SECP256k1', }), ]); @@ -72,7 +67,6 @@ const authorizationCondition = CompoundCondition.and([ const ed25519Condition = new ECDSACondition({ message: 'Edwards curve signature verification', signature: ':ed25519Signature', - verifyingKey: 'a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd', curve: 'Ed25519', }); @@ -80,7 +74,6 @@ const ed25519Condition = new ECDSACondition({ const brainpoolCondition = new ECDSACondition({ message: 'Brainpool P-256 verification', signature: ':brainpoolSignature', - verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', curve: 'BRAINPOOLP256r1', }); @@ -88,6 +81,5 @@ const brainpoolCondition = new ECDSACondition({ const p384Condition = new ECDSACondition({ message: 'High-security P-384 verification', signature: ':p384Signature', - verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', curve: 'NIST384p', }); \ No newline at end of file diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index 177ac98db..6e55aa5d4 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -171,175 +171,20 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( expect(decryptedMessageString).toEqual(messageString); }, 15000); - test('should encrypt and decrypt according to ECDSA signature condition', async () => { - const messageString = 'This message is protected by ECDSA signature verification 🔐'; - const message = toBytes(messageString); - - const ecdsaWallet = ethers.Wallet.createRandom(); - const verifyingKey = ecdsaWallet.publicKey.slice(2); // Remove '0x' prefix - - const authorizationMessage = 'I authorize access to this encrypted data'; - - // Create signature matching Python backend expectations (SHA-256 + raw signature format) - const messageHash = createHash('sha256').update(Buffer.from(authorizationMessage, 'utf8')).digest(); - const signingKey = new ethers.utils.SigningKey(ecdsaWallet.privateKey); - const signature = signingKey.signDigest(messageHash); - - // Convert to hex format expected by Python (r+s format without 0x prefix) - const rHex = signature.r.slice(2).padStart(64, '0'); - const sHex = signature.s.slice(2).padStart(64, '0'); - const signatureHex = rHex + sHex; - - const ecdsaCondition = new conditions.base.ecdsa.ECDSACondition({ - message: authorizationMessage, - signature: ':ecdsaSignature', - verifyingKey: verifyingKey, - curve: 'SECP256k1', - }); - - expect(ecdsaCondition.requiresAuthentication()).toBe(false); - - const messageKit = await encrypt( - provider, - DOMAIN, - message, - ecdsaCondition, - RITUAL_ID, - encryptorSigner, - ); - - const encryptedBytes = messageKit.toBytes(); - - const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); - const conditionContext = - conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); - - expect(conditionContext.requestedContextParameters.has(':ecdsaSignature')).toBe(true); - - conditionContext.addCustomContextParameterValues({ - ':ecdsaSignature': signatureHex - }); - - const decryptedBytes = await decrypt( - provider, - DOMAIN, - messageKitFromBytes, - conditionContext, - ); - const decryptedMessageString = fromBytes(decryptedBytes); - - expect(decryptedMessageString).toEqual(messageString); - }, 20000); - - test('should fail to decrypt with ECDSA condition when signature is invalid', async () => { - const messageString = 'This should fail with wrong signature'; - const message = toBytes(messageString); - - const ecdsaWallet = ethers.Wallet.createRandom(); - const verifyingKey = ecdsaWallet.publicKey.slice(2); - - const authorizationMessage = 'I authorize access to this encrypted data'; - - const ecdsaCondition = new conditions.base.ecdsa.ECDSACondition({ - message: authorizationMessage, - signature: ':ecdsaSignature', - verifyingKey: verifyingKey, - curve: 'SECP256k1', - }); - - const messageKit = await encrypt( - provider, - DOMAIN, - message, - ecdsaCondition, - RITUAL_ID, - encryptorSigner, - ); - - const encryptedBytes = messageKit.toBytes(); - - const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); - const conditionContext = - conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); - - // Add invalid signature - const invalidSignature = '0x' + randomBytes(64).toString('hex'); - conditionContext.addCustomContextParameterValues({ - ':ecdsaSignature': invalidSignature.slice(2) - }); - - await expect( - decrypt( - provider, - DOMAIN, - messageKitFromBytes, - conditionContext, - ) - ).rejects.toThrow(); - }, 20000); - - test('should encrypt and decrypt with ECDSA condition using user address context', async () => { - const messageString = 'This message uses both ECDSA and user address authentication 🔐🆔'; - const message = toBytes(messageString); - - const ecdsaWallet = ethers.Wallet.createRandom(); - const verifyingKey = ecdsaWallet.publicKey.slice(2); - - // Use user address as the message to require wallet authentication - const ecdsaCondition = new conditions.base.ecdsa.ECDSACondition({ - message: USER_ADDRESS_PARAM_DEFAULT, - signature: ':ecdsaSignature', - verifyingKey: verifyingKey, - curve: 'SECP256k1', - }); - - expect(ecdsaCondition.requiresAuthentication()).toBe(true); - - const messageKit = await encrypt( - provider, - DOMAIN, - message, - ecdsaCondition, - RITUAL_ID, - encryptorSigner, - ); - - const encryptedBytes = messageKit.toBytes(); - - const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); - const conditionContext = - conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); - - expect(conditionContext.requestedContextParameters.has(USER_ADDRESS_PARAM_DEFAULT)).toBe(true); - expect(conditionContext.requestedContextParameters.has(':ecdsaSignature')).toBe(true); - - const authProvider = new EIP4361AuthProvider(provider, consumerSigner); - conditionContext.addAuthProvider(USER_ADDRESS_PARAM_DEFAULT, authProvider); - - // Sign the user's address with test key - const userAddress = await consumerSigner.getAddress(); - const messageHash = createHash('sha256').update(Buffer.from(userAddress, 'utf8')).digest(); - const signingKey = new ethers.utils.SigningKey(ecdsaWallet.privateKey); - const signature = signingKey.signDigest(messageHash); - - // Convert signature to hex format expected by Python (r+s format) - const rHex = signature.r.slice(2).padStart(64, '0'); - const sHex = signature.s.slice(2).padStart(64, '0'); - const signatureHex = rHex + sHex; - - conditionContext.addCustomContextParameterValues({ - ':ecdsaSignature': signatureHex - }); - - const decryptedBytes = await decrypt( - provider, - DOMAIN, - messageKitFromBytes, - conditionContext, - ); - const decryptedMessageString = fromBytes(decryptedBytes); - - expect(decryptedMessageString).toEqual(messageString); - }, 25000); + // ECDSA tests temporarily disabled - verifyingKey is no longer user-configurable + // These tests need to be updated to work with server-side predefined conditions + // that include the verifyingKey to prevent users from creating conditions they can always satisfy + + // test('should encrypt and decrypt according to ECDSA signature condition', async () => { + // // TODO: Update to use predefined ECDSA conditions with server-controlled verifyingKey + // }, 20000); + + // test('should fail to decrypt with ECDSA condition when signature is invalid', async () => { + // // TODO: Update to use predefined ECDSA conditions with server-controlled verifyingKey + // }, 20000); + + // test('should encrypt and decrypt with ECDSA condition using user address context', async () => { + // // TODO: Update to use predefined ECDSA conditions with server-controlled verifyingKey + // }, 25000); }, ); diff --git a/packages/taco/src/conditions/schemas/ecdsa.ts b/packages/taco/src/conditions/schemas/ecdsa.ts index dbd744d8c..ceb3b21bb 100644 --- a/packages/taco/src/conditions/schemas/ecdsa.ts +++ b/packages/taco/src/conditions/schemas/ecdsa.ts @@ -57,10 +57,6 @@ export const ecdsaConditionSchema = baseConditionSchema.extend({ hexStringSchema, contextParamSchema, ]).default(ECDSA_SIGNATURE_PARAM_DEFAULT), - verifyingKey: z.union([ - hexStringSchema, - contextParamSchema, - ]), curve: z.enum(SUPPORTED_ECDSA_CURVES).default(DEFAULT_ECDSA_CURVE), }); diff --git a/packages/taco/test/conditions/base/ecdsa.test.ts b/packages/taco/test/conditions/base/ecdsa.test.ts index 2e68c1ebc..229e51a18 100644 --- a/packages/taco/test/conditions/base/ecdsa.test.ts +++ b/packages/taco/test/conditions/base/ecdsa.test.ts @@ -56,22 +56,7 @@ describe('ECDSACondition', () => { }); }); - it('rejects invalid verifying key that is not a hex string', () => { - const badECDSAObj = { - ...testECDSAConditionObj, - verifyingKey: 'not-a-hex-string', - }; - const result = ECDSACondition.validate(ecdsaConditionSchema, badECDSAObj); - - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error?.format()).toMatchObject({ - verifyingKey: { - _errors: ['Invalid hex string'], - }, - }); - }); it('rejects invalid curve', () => { const badECDSAObj = { @@ -134,14 +119,12 @@ describe('ECDSACondition', () => { const condition = new ECDSACondition({ message: 'test message', signature: 'abcdef123456', - verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', curve: 'SECP256k1', }); expect(condition.value.conditionType).toBe(ECDSAConditionType); expect(condition.value.message).toBe('test message'); expect(condition.value.signature).toBe('abcdef123456'); - expect(condition.value.verifyingKey).toBe('04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235'); expect(condition.value.curve).toBe('SECP256k1'); }); }); diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 84539b772..c312c19a7 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -307,7 +307,6 @@ export const testECDSAConditionObj: ECDSAConditionProps = { conditionType: ECDSAConditionType, message: ECDSA_MESSAGE_PARAM_DEFAULT, signature: ECDSA_SIGNATURE_PARAM_DEFAULT, - verifyingKey: '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', curve: 'SECP256k1', }; From c1c434055e458defb28acacbc3d1a9cb5ae0d4fe Mon Sep 17 00:00:00 2001 From: KPrasch Date: Fri, 18 Jul 2025 15:42:08 +0200 Subject: [PATCH 122/303] refactors ECDSA condition testing to handle pre-defined verifying keys --- .../integration-test/encrypt-decrypt.test.ts | 161 ++++++++++++++++-- packages/taco/test/test-utils.ts | 98 +++++++++++ 2 files changed, 243 insertions(+), 16 deletions(-) diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index 6e55aa5d4..692f20100 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -14,7 +14,11 @@ import { ThresholdMessageKit, } from '../src'; import { CompoundCondition } from '../src/conditions/compound-condition'; -import { UINT256_MAX } from '../test/test-utils'; +import { + UINT256_MAX, + createTestECDSACondition, + createSignatureForPredefinedCondition, +} from '../test/test-utils'; import { randomBytes, createHash } from 'crypto'; const RPC_PROVIDER_URL = 'https://rpc-amoy.polygon.technology'; @@ -171,20 +175,145 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( expect(decryptedMessageString).toEqual(messageString); }, 15000); - // ECDSA tests temporarily disabled - verifyingKey is no longer user-configurable - // These tests need to be updated to work with server-side predefined conditions - // that include the verifyingKey to prevent users from creating conditions they can always satisfy - - // test('should encrypt and decrypt according to ECDSA signature condition', async () => { - // // TODO: Update to use predefined ECDSA conditions with server-controlled verifyingKey - // }, 20000); - - // test('should fail to decrypt with ECDSA condition when signature is invalid', async () => { - // // TODO: Update to use predefined ECDSA conditions with server-controlled verifyingKey - // }, 20000); - - // test('should encrypt and decrypt with ECDSA condition using user address context', async () => { - // // TODO: Update to use predefined ECDSA conditions with server-controlled verifyingKey - // }, 25000); + test('should encrypt and decrypt according to ECDSA signature condition with predefined verifying key', async () => { + const messageString = 'This message is protected by ECDSA signature verification 🔐'; + const message = toBytes(messageString); + + const authorizationMessage = 'I authorize access to this encrypted data'; + + // Create a predefined ECDSA condition (simulates server-side condition creation) + const { condition: ecdsaCondition, privateKey } = createTestECDSACondition(authorizationMessage); + + expect(ecdsaCondition.requiresAuthentication()).toBe(false); + + const messageKit = await encrypt( + provider, + DOMAIN, + message, + ecdsaCondition, + RITUAL_ID, + encryptorSigner, + ); + + const encryptedBytes = messageKit.toBytes(); + + const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); + const conditionContext = + conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); + + expect(conditionContext.requestedContextParameters.has(':ecdsaSignature')).toBe(true); + + // Create signature using the predefined condition's private key + const signatureHex = createSignatureForPredefinedCondition( + { condition: ecdsaCondition.value, verifyingKey: ecdsaCondition.value.verifyingKey, privateKey }, + authorizationMessage + ); + + conditionContext.addCustomContextParameterValues({ + ':ecdsaSignature': signatureHex + }); + + const decryptedBytes = await decrypt( + provider, + DOMAIN, + messageKitFromBytes, + conditionContext, + ); + const decryptedMessageString = fromBytes(decryptedBytes); + + expect(decryptedMessageString).toEqual(messageString); + }, 20000); + + test('should fail to decrypt with ECDSA condition when signature is invalid', async () => { + const messageString = 'This should fail with wrong signature'; + const message = toBytes(messageString); + + const authorizationMessage = 'I authorize access to this encrypted data'; + + // Create a predefined ECDSA condition (simulates server-side condition creation) + const { condition: ecdsaCondition } = createTestECDSACondition(authorizationMessage); + + const messageKit = await encrypt( + provider, + DOMAIN, + message, + ecdsaCondition, + RITUAL_ID, + encryptorSigner, + ); + + const encryptedBytes = messageKit.toBytes(); + + const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); + const conditionContext = + conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); + + // Add invalid signature + const invalidSignature = '0x' + randomBytes(64).toString('hex'); + conditionContext.addCustomContextParameterValues({ + ':ecdsaSignature': invalidSignature.slice(2) + }); + + await expect( + decrypt( + provider, + DOMAIN, + messageKitFromBytes, + conditionContext, + ) + ).rejects.toThrow(); + }, 20000); + + test('should encrypt and decrypt with ECDSA condition using user address context', async () => { + const messageString = 'This message uses both ECDSA and user address authentication 🔐🆔'; + const message = toBytes(messageString); + + // Create a predefined ECDSA condition that uses user address as the message + const { condition: ecdsaCondition, privateKey } = createTestECDSACondition(USER_ADDRESS_PARAM_DEFAULT); + + expect(ecdsaCondition.requiresAuthentication()).toBe(true); + + const messageKit = await encrypt( + provider, + DOMAIN, + message, + ecdsaCondition, + RITUAL_ID, + encryptorSigner, + ); + + const encryptedBytes = messageKit.toBytes(); + + const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); + const conditionContext = + conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); + + expect(conditionContext.requestedContextParameters.has(USER_ADDRESS_PARAM_DEFAULT)).toBe(true); + expect(conditionContext.requestedContextParameters.has(':ecdsaSignature')).toBe(true); + + const authProvider = new EIP4361AuthProvider(provider, consumerSigner); + conditionContext.addAuthProvider(USER_ADDRESS_PARAM_DEFAULT, authProvider); + + // Sign the user's address with the predefined condition's private key + const userAddress = await consumerSigner.getAddress(); + const signatureHex = createSignatureForPredefinedCondition( + { condition: ecdsaCondition.value, verifyingKey: ecdsaCondition.value.verifyingKey, privateKey }, + userAddress + ); + + conditionContext.addCustomContextParameterValues({ + ':ecdsaSignature': signatureHex + }); + + const decryptedBytes = await decrypt( + provider, + DOMAIN, + messageKitFromBytes, + conditionContext, + ); + const decryptedMessageString = fromBytes(decryptedBytes); + + expect(decryptedMessageString).toEqual(messageString); + }, 25000); }, ); diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index c312c19a7..6fcde0970 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -35,6 +35,7 @@ import { } from '@nucypher/test-utils'; import { ethers } from 'ethers'; import { MockInstance, vi } from 'vitest'; +import { createHash } from 'crypto'; import { AddressAllowlistConditionProps, @@ -48,8 +49,10 @@ import { import { ECDSA_MESSAGE_PARAM_DEFAULT, ECDSA_SIGNATURE_PARAM_DEFAULT, + ECDSACondition, ECDSAConditionProps, ECDSAConditionType, + ECDSACurve, } from '../src/conditions/base/ecdsa'; import { JsonApiConditionProps, @@ -96,6 +99,59 @@ import { } from '../src/conditions/shared'; import { DkgClient, DkgRitual } from '../src/dkg'; import { encryptMessage } from '../src/tdec'; +import { z } from 'zod'; +import { Condition } from '../src/conditions/condition'; +import { baseConditionSchema, hexStringSchema } from '../src/conditions/schemas/common'; +import { contextParamSchema } from '../src/conditions/schemas/context'; + +// Test-specific ECDSA condition that includes verifying key for integration testing +// This simulates how predefined ECDSA conditions would work in production +interface TestECDSAConditionProps extends ECDSAConditionProps { + verifyingKey: string; +} + +const testECDSAConditionSchema = baseConditionSchema.extend({ + conditionType: z.literal(ECDSAConditionType).default(ECDSAConditionType), + message: z.union([ + z.string(), + contextParamSchema, + ]).default(ECDSA_MESSAGE_PARAM_DEFAULT), + signature: z.union([ + hexStringSchema, + contextParamSchema, + ]).default(ECDSA_SIGNATURE_PARAM_DEFAULT), + verifyingKey: hexStringSchema, // Test-only: includes verifying key + curve: z.enum(['SECP256k1', 'NIST256p', 'NIST384p', 'NIST521p', 'Ed25519', 'BRAINPOOLP256r1']).default('SECP256k1'), +}); + +export class TestECDSACondition extends Condition { + constructor(value: Omit) { + super(testECDSAConditionSchema, { + conditionType: ECDSAConditionType, + ...value, + }); + } +} + +export function createTestECDSACondition( + message: string, + curve: ECDSACurve = 'SECP256k1' +): { condition: TestECDSACondition; privateKey: string } { + // Simulate server-side key generation for the predefined condition + const testWallet = ethers.Wallet.createRandom(); + + const condition = new TestECDSACondition({ + message: message, + signature: ECDSA_SIGNATURE_PARAM_DEFAULT, + verifyingKey: testWallet.publicKey.slice(2), // Remove '0x' prefix + curve: curve, + }); + + return { + condition, + privateKey: testWallet.privateKey, // For test signature generation + }; +} export const fakeDkgTDecFlowE2E: ( ritualId?: number, @@ -310,6 +366,48 @@ export const testECDSAConditionObj: ECDSAConditionProps = { curve: 'SECP256k1', }; +// Test utility for creating predefined ECDSA conditions (simulates server-side creation) +// In production, these would be created by servers/admins and stored with their verifying keys +export interface PredefinedECDSACondition { + condition: ECDSAConditionProps; + verifyingKey: string; + privateKey: string; // For test signature generation only +} + +export function createPredefinedECDSACondition( + message: string, + curve: ECDSACurve = 'SECP256k1' +): PredefinedECDSACondition { + // Simulate server-side key generation for the predefined condition + const testWallet = ethers.Wallet.createRandom(); + + return { + condition: { + conditionType: ECDSAConditionType, + message: message, + signature: ECDSA_SIGNATURE_PARAM_DEFAULT, + curve: curve, + }, + verifyingKey: testWallet.publicKey.slice(2), // Remove '0x' prefix + privateKey: testWallet.privateKey, // For test purposes only + }; +} + +export function createSignatureForPredefinedCondition( + predefinedCondition: PredefinedECDSACondition, + messageToSign: string +): string { + // Create signature that matches Python backend expectations + const messageHash = createHash('sha256').update(Buffer.from(messageToSign, 'utf8')).digest(); + const signingKey = new ethers.utils.SigningKey(predefinedCondition.privateKey); + const signature = signingKey.signDigest(messageHash); + + // Convert to hex format expected by Python (r+s format without 0x prefix) + const rHex = signature.r.slice(2).padStart(64, '0'); + const sHex = signature.s.slice(2).padStart(64, '0'); + return rHex + sHex; +} + export const testRpcConditionObj: RpcConditionProps = { conditionType: RpcConditionType, chain: TEST_CHAIN_ID, From e1aba882db215d8b68bf6c40fd62b9a7f1919b53 Mon Sep 17 00:00:00 2001 From: KPrasch Date: Tue, 29 Jul 2025 13:41:16 +0200 Subject: [PATCH 123/303] ensures curve is a required param for ecdsa condition api; only permit the usage of :message and :signature context params. --- packages/taco/src/conditions/base/ecdsa.ts | 1 - packages/taco/src/conditions/schemas/ecdsa.ts | 72 +++++++++++++++---- .../taco/test/conditions/base/ecdsa.test.ts | 65 ++++++++++++++++- 3 files changed, 121 insertions(+), 17 deletions(-) diff --git a/packages/taco/src/conditions/base/ecdsa.ts b/packages/taco/src/conditions/base/ecdsa.ts index df5453381..424ba4176 100644 --- a/packages/taco/src/conditions/base/ecdsa.ts +++ b/packages/taco/src/conditions/base/ecdsa.ts @@ -7,7 +7,6 @@ import { import { OmitConditionType } from '../shared'; export { - DEFAULT_ECDSA_CURVE, ECDSACurve, ECDSA_MESSAGE_PARAM_DEFAULT, ECDSA_SIGNATURE_PARAM_DEFAULT, diff --git a/packages/taco/src/conditions/schemas/ecdsa.ts b/packages/taco/src/conditions/schemas/ecdsa.ts index ceb3b21bb..c4dbd10b7 100644 --- a/packages/taco/src/conditions/schemas/ecdsa.ts +++ b/packages/taco/src/conditions/schemas/ecdsa.ts @@ -1,13 +1,65 @@ import { z } from 'zod'; import { baseConditionSchema, hexStringSchema } from './common'; -import { contextParamSchema } from './context'; -export const ECDSA_MESSAGE_PARAM_DEFAULT = ':ecdsaMessage'; -export const ECDSA_SIGNATURE_PARAM_DEFAULT = ':ecdsaSignature'; +export const ECDSA_MESSAGE_PARAM_DEFAULT = ':message'; +export const ECDSA_SIGNATURE_PARAM_DEFAULT = ':signature'; export const ECDSAConditionType = 'ecdsa'; +// Allowed context parameters for ECDSA message field - ONLY :message +const ecdsaMessageContextParamSchema = z.enum([ + ':message', +]).describe('Context parameter for ECDSA message - only :message is allowed'); + +// Allowed context parameters for ECDSA signature field - ONLY :signature +const ecdsaSignatureContextParamSchema = z.enum([ + ':signature', +]).describe('Context parameter for ECDSA signature - only :signature is allowed'); + +// Message field that properly validates context parameters +const ecdsaMessageSchema = z.string().superRefine((val, ctx) => { + if (val.startsWith(':')) { + // It's a context parameter, validate against allowed values + const result = ecdsaMessageContextParamSchema.safeParse(val); + if (!result.success) { + ctx.addIssue({ + code: z.ZodIssueCode.invalid_enum_value, + options: [':message'], + received: val, + message: `Invalid context parameter for message. Only ':message' is allowed.`, + }); + } + } + // Otherwise it's a regular string, which is valid +}); + +// Signature field that properly validates context parameters +const ecdsaSignatureSchema = z.string().superRefine((val, ctx) => { + if (val.startsWith(':')) { + // It's a context parameter, validate against allowed values + const result = ecdsaSignatureContextParamSchema.safeParse(val); + if (!result.success) { + ctx.addIssue({ + code: z.ZodIssueCode.invalid_enum_value, + options: [':signature'], + received: val, + message: `Invalid context parameter for signature. Only ':signature' is allowed.`, + }); + } + } else { + // It's not a context parameter, validate as hex string + const result = hexStringSchema.safeParse(val); + if (!result.success) { + ctx.addIssue({ + code: z.ZodIssueCode.invalid_string, + validation: 'regex', + message: 'Invalid hex string', + }); + } + } +}); + // Supported ECDSA curves (must match Python backend format) export const SUPPORTED_ECDSA_CURVES = [ // NIST curves @@ -45,19 +97,11 @@ export const SUPPORTED_ECDSA_CURVES = [ export type ECDSACurve = typeof SUPPORTED_ECDSA_CURVES[number]; -export const DEFAULT_ECDSA_CURVE: ECDSACurve = 'SECP256k1'; - export const ecdsaConditionSchema = baseConditionSchema.extend({ conditionType: z.literal(ECDSAConditionType).default(ECDSAConditionType), - message: z.union([ - z.string(), - contextParamSchema, - ]).default(ECDSA_MESSAGE_PARAM_DEFAULT), - signature: z.union([ - hexStringSchema, - contextParamSchema, - ]).default(ECDSA_SIGNATURE_PARAM_DEFAULT), - curve: z.enum(SUPPORTED_ECDSA_CURVES).default(DEFAULT_ECDSA_CURVE), + message: ecdsaMessageSchema.default(ECDSA_MESSAGE_PARAM_DEFAULT), + signature: ecdsaSignatureSchema.default(ECDSA_SIGNATURE_PARAM_DEFAULT), + curve: z.enum(SUPPORTED_ECDSA_CURVES), }); export type ECDSAConditionProps = z.infer; \ No newline at end of file diff --git a/packages/taco/test/conditions/base/ecdsa.test.ts b/packages/taco/test/conditions/base/ecdsa.test.ts index 229e51a18..75103c05e 100644 --- a/packages/taco/test/conditions/base/ecdsa.test.ts +++ b/packages/taco/test/conditions/base/ecdsa.test.ts @@ -94,7 +94,7 @@ describe('ECDSACondition', () => { it('accepts context variables for message', () => { const ecdsaObj = { ...testECDSAConditionObj, - message: ':customMessage', + message: ':message', }; const result = ECDSACondition.validate(ecdsaConditionSchema, ecdsaObj); @@ -106,7 +106,7 @@ describe('ECDSACondition', () => { it('accepts context variables for signature', () => { const ecdsaObj = { ...testECDSAConditionObj, - signature: ':customSignature', + signature: ':signature', }; const result = ECDSACondition.validate(ecdsaConditionSchema, ecdsaObj); @@ -115,6 +115,67 @@ describe('ECDSACondition', () => { expect(result.data).toEqual(ecdsaObj); }); + it('rejects arbitrary context variables for message', () => { + const ecdsaObj = { + ...testECDSAConditionObj, + message: ':customMessage', + }; + + const result = ECDSACondition.validate(ecdsaConditionSchema, ecdsaObj); + + expect(result.error).toBeDefined(); + expect(result.error!.issues[0].code).toEqual('invalid_enum_value'); + }); + + it('rejects arbitrary context variables for signature', () => { + const ecdsaObj = { + ...testECDSAConditionObj, + signature: ':customSignature', + }; + + const result = ECDSACondition.validate(ecdsaConditionSchema, ecdsaObj); + + expect(result.error).toBeDefined(); + expect(result.error!.issues[0].code).toEqual('invalid_enum_value'); + }); + + it('rejects the old default context variable :ecdsaMessage', () => { + const ecdsaObj = { + ...testECDSAConditionObj, + message: ':ecdsaMessage', + }; + + const result = ECDSACondition.validate(ecdsaConditionSchema, ecdsaObj); + + expect(result.error).toBeDefined(); + expect(result.error!.issues[0].code).toEqual('invalid_enum_value'); + }); + + it('rejects the old default context variable :ecdsaSignature', () => { + const ecdsaObj = { + ...testECDSAConditionObj, + signature: ':ecdsaSignature', + }; + + const result = ECDSACondition.validate(ecdsaConditionSchema, ecdsaObj); + + expect(result.error).toBeDefined(); + expect(result.error!.issues[0].code).toEqual('invalid_enum_value'); + }); + + it('rejects when curve parameter is missing', () => { + const ecdsaObj = { + ...testECDSAConditionObj, + }; + delete (ecdsaObj as any).curve; // Remove the curve parameter + + const result = ECDSACondition.validate(ecdsaConditionSchema, ecdsaObj); + + expect(result.error).toBeDefined(); + expect(result.error!.issues[0].code).toEqual('invalid_type'); + expect(result.error!.issues[0].path).toEqual(['curve']); + }); + it('creates valid condition instance', () => { const condition = new ECDSACondition({ message: 'test message', From fa9df254ce681e5542b94602980a8bd98bca6c1c Mon Sep 17 00:00:00 2001 From: KPrasch Date: Tue, 29 Jul 2025 13:47:05 +0200 Subject: [PATCH 124/303] appease the linting gods --- packages/shared/src/schemas.ts | 8 +- packages/taco/examples/ecdsa-condition.ts | 11 +-- .../integration-test/encrypt-decrypt.test.ts | 73 ++++++++++++------- packages/taco/src/conditions/base/ecdsa.ts | 4 +- packages/taco/src/conditions/schemas/ecdsa.ts | 18 +++-- .../taco/test/conditions/base/ecdsa.test.ts | 19 ++--- packages/taco/test/test-utils.ts | 60 +++++++++------ 7 files changed, 112 insertions(+), 81 deletions(-) diff --git a/packages/shared/src/schemas.ts b/packages/shared/src/schemas.ts index a2e0dd07c..ea3bfc200 100644 --- a/packages/shared/src/schemas.ts +++ b/packages/shared/src/schemas.ts @@ -23,11 +23,9 @@ export const EthAddressSchema = z .string() .refine(isAddress, { message: 'Invalid Ethereum address' }); -export const EthAddressSchemaStrict = z - .string() - .refine(isAddressStrict, { - message: 'Invalid Ethereum address - it must be valid and checksummed', - }); +export const EthAddressSchemaStrict = z.string().refine(isAddressStrict, { + message: 'Invalid Ethereum address - it must be valid and checksummed', +}); const BLOCK_HASH_REGEXP = new RegExp('^0x[a-fA-F0-9]{64}$'); const BlockNumber = z.number().int().nonnegative(); diff --git a/packages/taco/examples/ecdsa-condition.ts b/packages/taco/examples/ecdsa-condition.ts index a6913a48a..bc414d327 100644 --- a/packages/taco/examples/ecdsa-condition.ts +++ b/packages/taco/examples/ecdsa-condition.ts @@ -2,7 +2,8 @@ import { ECDSACondition } from '../src/conditions/base/ecdsa'; // Example 1: ECDSA condition with hardcoded message, dynamic signature const attestationCondition = new ECDSACondition({ - message: 'I attest that I am authorized to access this data and agree to use it responsibly', + message: + 'I attest that I am authorized to access this data and agree to use it responsibly', signature: ':userSignature', // User provides signature at runtime curve: 'SECP256k1', }); @@ -29,8 +30,8 @@ const defaultECDSACondition = new ECDSACondition({ }); // Example 5: Complex usage with compound condition -import { CompoundCondition } from '../src/conditions/compound-condition'; import { TimeCondition } from '../src/conditions/base/time'; +import { CompoundCondition } from '../src/conditions/compound-condition'; const timeCondition = new TimeCondition({ returnValueTest: { @@ -73,13 +74,13 @@ const ed25519Condition = new ECDSACondition({ // Example 8: Brainpool curve example const brainpoolCondition = new ECDSACondition({ message: 'Brainpool P-256 verification', - signature: ':brainpoolSignature', + signature: ':brainpoolSignature', curve: 'BRAINPOOLP256r1', }); -// Example 9: NIST P-384 curve +// Example 9: NIST P-384 curve const p384Condition = new ECDSACondition({ message: 'High-security P-384 verification', signature: ':p384Signature', curve: 'NIST384p', -}); \ No newline at end of file +}); diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index 692f20100..d8d9ba756 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -5,6 +5,7 @@ import { EIP4361AuthProvider, USER_ADDRESS_PARAM_DEFAULT, } from '@nucypher/taco-auth'; +import { randomBytes } from 'crypto'; import { ethers } from 'ethers'; import { conditions, @@ -14,12 +15,11 @@ import { ThresholdMessageKit, } from '../src'; import { CompoundCondition } from '../src/conditions/compound-condition'; -import { - UINT256_MAX, - createTestECDSACondition, +import { createSignatureForPredefinedCondition, + createTestECDSACondition, + UINT256_MAX, } from '../test/test-utils'; -import { randomBytes, createHash } from 'crypto'; const RPC_PROVIDER_URL = 'https://rpc-amoy.polygon.technology'; const ENCRYPTOR_PRIVATE_KEY = @@ -176,13 +176,15 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( }, 15000); test('should encrypt and decrypt according to ECDSA signature condition with predefined verifying key', async () => { - const messageString = 'This message is protected by ECDSA signature verification 🔐'; + const messageString = + 'This message is protected by ECDSA signature verification 🔐'; const message = toBytes(messageString); const authorizationMessage = 'I authorize access to this encrypted data'; - + // Create a predefined ECDSA condition (simulates server-side condition creation) - const { condition: ecdsaCondition, privateKey } = createTestECDSACondition(authorizationMessage); + const { condition: ecdsaCondition, privateKey } = + createTestECDSACondition(authorizationMessage); expect(ecdsaCondition.requiresAuthentication()).toBe(false); @@ -201,16 +203,22 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const conditionContext = conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); - expect(conditionContext.requestedContextParameters.has(':ecdsaSignature')).toBe(true); + expect( + conditionContext.requestedContextParameters.has(':ecdsaSignature'), + ).toBe(true); // Create signature using the predefined condition's private key const signatureHex = createSignatureForPredefinedCondition( - { condition: ecdsaCondition.value, verifyingKey: ecdsaCondition.value.verifyingKey, privateKey }, - authorizationMessage + { + condition: ecdsaCondition.value, + verifyingKey: ecdsaCondition.value.verifyingKey, + privateKey, + }, + authorizationMessage, ); conditionContext.addCustomContextParameterValues({ - ':ecdsaSignature': signatureHex + ':ecdsaSignature': signatureHex, }); const decryptedBytes = await decrypt( @@ -231,7 +239,8 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const authorizationMessage = 'I authorize access to this encrypted data'; // Create a predefined ECDSA condition (simulates server-side condition creation) - const { condition: ecdsaCondition } = createTestECDSACondition(authorizationMessage); + const { condition: ecdsaCondition } = + createTestECDSACondition(authorizationMessage); const messageKit = await encrypt( provider, @@ -251,25 +260,22 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( // Add invalid signature const invalidSignature = '0x' + randomBytes(64).toString('hex'); conditionContext.addCustomContextParameterValues({ - ':ecdsaSignature': invalidSignature.slice(2) + ':ecdsaSignature': invalidSignature.slice(2), }); await expect( - decrypt( - provider, - DOMAIN, - messageKitFromBytes, - conditionContext, - ) + decrypt(provider, DOMAIN, messageKitFromBytes, conditionContext), ).rejects.toThrow(); }, 20000); test('should encrypt and decrypt with ECDSA condition using user address context', async () => { - const messageString = 'This message uses both ECDSA and user address authentication 🔐🆔'; + const messageString = + 'This message uses both ECDSA and user address authentication 🔐🆔'; const message = toBytes(messageString); // Create a predefined ECDSA condition that uses user address as the message - const { condition: ecdsaCondition, privateKey } = createTestECDSACondition(USER_ADDRESS_PARAM_DEFAULT); + const { condition: ecdsaCondition, privateKey } = + createTestECDSACondition(USER_ADDRESS_PARAM_DEFAULT); expect(ecdsaCondition.requiresAuthentication()).toBe(true); @@ -288,21 +294,34 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const conditionContext = conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); - expect(conditionContext.requestedContextParameters.has(USER_ADDRESS_PARAM_DEFAULT)).toBe(true); - expect(conditionContext.requestedContextParameters.has(':ecdsaSignature')).toBe(true); + expect( + conditionContext.requestedContextParameters.has( + USER_ADDRESS_PARAM_DEFAULT, + ), + ).toBe(true); + expect( + conditionContext.requestedContextParameters.has(':ecdsaSignature'), + ).toBe(true); const authProvider = new EIP4361AuthProvider(provider, consumerSigner); - conditionContext.addAuthProvider(USER_ADDRESS_PARAM_DEFAULT, authProvider); + conditionContext.addAuthProvider( + USER_ADDRESS_PARAM_DEFAULT, + authProvider, + ); // Sign the user's address with the predefined condition's private key const userAddress = await consumerSigner.getAddress(); const signatureHex = createSignatureForPredefinedCondition( - { condition: ecdsaCondition.value, verifyingKey: ecdsaCondition.value.verifyingKey, privateKey }, - userAddress + { + condition: ecdsaCondition.value, + verifyingKey: ecdsaCondition.value.verifyingKey, + privateKey, + }, + userAddress, ); conditionContext.addCustomContextParameterValues({ - ':ecdsaSignature': signatureHex + ':ecdsaSignature': signatureHex, }); const decryptedBytes = await decrypt( diff --git a/packages/taco/src/conditions/base/ecdsa.ts b/packages/taco/src/conditions/base/ecdsa.ts index 424ba4176..731ad6491 100644 --- a/packages/taco/src/conditions/base/ecdsa.ts +++ b/packages/taco/src/conditions/base/ecdsa.ts @@ -7,12 +7,12 @@ import { import { OmitConditionType } from '../shared'; export { - ECDSACurve, ECDSA_MESSAGE_PARAM_DEFAULT, ECDSA_SIGNATURE_PARAM_DEFAULT, ECDSAConditionProps, ecdsaConditionSchema, ECDSAConditionType, + ECDSACurve, SUPPORTED_ECDSA_CURVES, } from '../schemas/ecdsa'; @@ -23,4 +23,4 @@ export class ECDSACondition extends Condition { ...value, }); } -} \ No newline at end of file +} diff --git a/packages/taco/src/conditions/schemas/ecdsa.ts b/packages/taco/src/conditions/schemas/ecdsa.ts index c4dbd10b7..b3591ca67 100644 --- a/packages/taco/src/conditions/schemas/ecdsa.ts +++ b/packages/taco/src/conditions/schemas/ecdsa.ts @@ -8,14 +8,16 @@ export const ECDSA_SIGNATURE_PARAM_DEFAULT = ':signature'; export const ECDSAConditionType = 'ecdsa'; // Allowed context parameters for ECDSA message field - ONLY :message -const ecdsaMessageContextParamSchema = z.enum([ - ':message', -]).describe('Context parameter for ECDSA message - only :message is allowed'); +const ecdsaMessageContextParamSchema = z + .enum([':message']) + .describe('Context parameter for ECDSA message - only :message is allowed'); // Allowed context parameters for ECDSA signature field - ONLY :signature -const ecdsaSignatureContextParamSchema = z.enum([ - ':signature', -]).describe('Context parameter for ECDSA signature - only :signature is allowed'); +const ecdsaSignatureContextParamSchema = z + .enum([':signature']) + .describe( + 'Context parameter for ECDSA signature - only :signature is allowed', + ); // Message field that properly validates context parameters const ecdsaMessageSchema = z.string().superRefine((val, ctx) => { @@ -95,7 +97,7 @@ export const SUPPORTED_ECDSA_CURVES = [ 'Ed448', ] as const; -export type ECDSACurve = typeof SUPPORTED_ECDSA_CURVES[number]; +export type ECDSACurve = (typeof SUPPORTED_ECDSA_CURVES)[number]; export const ecdsaConditionSchema = baseConditionSchema.extend({ conditionType: z.literal(ECDSAConditionType).default(ECDSAConditionType), @@ -104,4 +106,4 @@ export const ecdsaConditionSchema = baseConditionSchema.extend({ curve: z.enum(SUPPORTED_ECDSA_CURVES), }); -export type ECDSAConditionProps = z.infer; \ No newline at end of file +export type ECDSAConditionProps = z.infer; diff --git a/packages/taco/test/conditions/base/ecdsa.test.ts b/packages/taco/test/conditions/base/ecdsa.test.ts index 75103c05e..4daee4918 100644 --- a/packages/taco/test/conditions/base/ecdsa.test.ts +++ b/packages/taco/test/conditions/base/ecdsa.test.ts @@ -32,9 +32,7 @@ describe('ECDSACondition', () => { expect(result.data).toBeUndefined(); expect(result.error?.format()).toMatchObject({ message: { - _errors: expect.arrayContaining([ - 'Expected string, received number', - ]), + _errors: expect.arrayContaining(['Expected string, received number']), }, }); }); @@ -56,8 +54,6 @@ describe('ECDSACondition', () => { }); }); - - it('rejects invalid curve', () => { const badECDSAObj = { ...testECDSAConditionObj, @@ -164,12 +160,13 @@ describe('ECDSACondition', () => { }); it('rejects when curve parameter is missing', () => { - const ecdsaObj = { - ...testECDSAConditionObj, - }; - delete (ecdsaObj as any).curve; // Remove the curve parameter + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { curve: _curve, ...ecdsaObjWithoutCurve } = testECDSAConditionObj; - const result = ECDSACondition.validate(ecdsaConditionSchema, ecdsaObj); + const result = ECDSACondition.validate( + ecdsaConditionSchema, + ecdsaObjWithoutCurve, + ); expect(result.error).toBeDefined(); expect(result.error!.issues[0].code).toEqual('invalid_type'); @@ -189,4 +186,4 @@ describe('ECDSACondition', () => { expect(condition.value.curve).toBe('SECP256k1'); }); }); -}); \ No newline at end of file +}); diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 6fcde0970..ac85231d3 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -3,6 +3,8 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-unused-vars */ +import { createHash } from 'crypto'; + import { AggregatedTranscript, DecryptionShareSimple, @@ -35,7 +37,7 @@ import { } from '@nucypher/test-utils'; import { ethers } from 'ethers'; import { MockInstance, vi } from 'vitest'; -import { createHash } from 'crypto'; +import { z } from 'zod'; import { AddressAllowlistConditionProps, @@ -49,7 +51,6 @@ import { import { ECDSA_MESSAGE_PARAM_DEFAULT, ECDSA_SIGNATURE_PARAM_DEFAULT, - ECDSACondition, ECDSAConditionProps, ECDSAConditionType, ECDSACurve, @@ -83,8 +84,14 @@ import { CompoundConditionProps, CompoundConditionType, } from '../src/conditions/compound-condition'; +import { Condition } from '../src/conditions/condition'; import { ConditionExpression } from '../src/conditions/condition-expr'; import { ERC721Balance } from '../src/conditions/predefined/erc721'; +import { + baseConditionSchema, + hexStringSchema, +} from '../src/conditions/schemas/common'; +import { contextParamSchema } from '../src/conditions/schemas/context'; import { JsonRpcConditionProps, JsonRpcConditionType, @@ -99,10 +106,6 @@ import { } from '../src/conditions/shared'; import { DkgClient, DkgRitual } from '../src/dkg'; import { encryptMessage } from '../src/tdec'; -import { z } from 'zod'; -import { Condition } from '../src/conditions/condition'; -import { baseConditionSchema, hexStringSchema } from '../src/conditions/schemas/common'; -import { contextParamSchema } from '../src/conditions/schemas/context'; // Test-specific ECDSA condition that includes verifying key for integration testing // This simulates how predefined ECDSA conditions would work in production @@ -112,16 +115,23 @@ interface TestECDSAConditionProps extends ECDSAConditionProps { const testECDSAConditionSchema = baseConditionSchema.extend({ conditionType: z.literal(ECDSAConditionType).default(ECDSAConditionType), - message: z.union([ - z.string(), - contextParamSchema, - ]).default(ECDSA_MESSAGE_PARAM_DEFAULT), - signature: z.union([ - hexStringSchema, - contextParamSchema, - ]).default(ECDSA_SIGNATURE_PARAM_DEFAULT), + message: z + .union([z.string(), contextParamSchema]) + .default(ECDSA_MESSAGE_PARAM_DEFAULT), + signature: z + .union([hexStringSchema, contextParamSchema]) + .default(ECDSA_SIGNATURE_PARAM_DEFAULT), verifyingKey: hexStringSchema, // Test-only: includes verifying key - curve: z.enum(['SECP256k1', 'NIST256p', 'NIST384p', 'NIST521p', 'Ed25519', 'BRAINPOOLP256r1']).default('SECP256k1'), + curve: z + .enum([ + 'SECP256k1', + 'NIST256p', + 'NIST384p', + 'NIST521p', + 'Ed25519', + 'BRAINPOOLP256r1', + ]) + .default('SECP256k1'), }); export class TestECDSACondition extends Condition { @@ -135,11 +145,11 @@ export class TestECDSACondition extends Condition { export function createTestECDSACondition( message: string, - curve: ECDSACurve = 'SECP256k1' + curve: ECDSACurve = 'SECP256k1', ): { condition: TestECDSACondition; privateKey: string } { // Simulate server-side key generation for the predefined condition const testWallet = ethers.Wallet.createRandom(); - + const condition = new TestECDSACondition({ message: message, signature: ECDSA_SIGNATURE_PARAM_DEFAULT, @@ -376,11 +386,11 @@ export interface PredefinedECDSACondition { export function createPredefinedECDSACondition( message: string, - curve: ECDSACurve = 'SECP256k1' + curve: ECDSACurve = 'SECP256k1', ): PredefinedECDSACondition { // Simulate server-side key generation for the predefined condition const testWallet = ethers.Wallet.createRandom(); - + return { condition: { conditionType: ECDSAConditionType, @@ -395,13 +405,17 @@ export function createPredefinedECDSACondition( export function createSignatureForPredefinedCondition( predefinedCondition: PredefinedECDSACondition, - messageToSign: string + messageToSign: string, ): string { // Create signature that matches Python backend expectations - const messageHash = createHash('sha256').update(Buffer.from(messageToSign, 'utf8')).digest(); - const signingKey = new ethers.utils.SigningKey(predefinedCondition.privateKey); + const messageHash = createHash('sha256') + .update(Buffer.from(messageToSign, 'utf8')) + .digest(); + const signingKey = new ethers.utils.SigningKey( + predefinedCondition.privateKey, + ); const signature = signingKey.signDigest(messageHash); - + // Convert to hex format expected by Python (r+s format without 0x prefix) const rHex = signature.r.slice(2).padStart(64, '0'); const sHex = signature.s.slice(2).padStart(64, '0'); From 6acdd8132efeb6f10bfd641f1ae37df64e3e9fe2 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Mon, 7 Jul 2025 21:37:57 -0400 Subject: [PATCH 125/303] Simplify Porter functionality to focus only on input/output to/from Porter instance without additional logic for further processing response from Porter. The PorterClient should only focus on what Porter wants and marshalling what Porter returns for the caller to then perform their own processing. --- packages/shared/src/porter.ts | 99 +++++------------------------------ 1 file changed, 13 insertions(+), 86 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index 56260dabe..e658c19a2 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -153,11 +153,7 @@ export type TacoDecryptResult = { }; // Signing types -export type SigningOptions = { - optimistic?: boolean; // Whether to return first signatures received or wait for all signatures -}; - -type SignResponse = { +type TacoSignResponse = { readonly result: { readonly signing_results: { readonly signatures: Record< @@ -169,32 +165,21 @@ type SignResponse = { }; }; -export type SignResult = { - messageHash: string; - aggregatedSignature: string | undefined; - signingResults: { [ursulaAddress: string]: [string, string] }; - errors: Record; -}; - -function aggregatePorterSignatures(signaturesWithAddress: { - [checksumAddress: string]: [string, string]; -}): string { - const signatures = Object.values(signaturesWithAddress).map( - ([, signature]) => signature, - ); - return signatures.join(''); -} - -type DecodedSignature = { +export type TacoSignature = { messageHash: string; signature: string; signerAddress: string; }; +export type TacoSignResult = { + signingResults: { [ursulaAddress: string]: TacoSignature }; + errors: Record; +}; + function decodeSignature( signerAddress: string, signatureB64: string, -): { result?: DecodedSignature; error?: string } { +): { result?: TacoSignature; error?: string } { try { const decodedData = JSON.parse( new TextDecoder().decode(fromBase64(signatureB64)), @@ -362,14 +347,13 @@ export class PorterClient { public async signUserOp( signingRequests: Record, threshold: number, - options: SigningOptions = {}, - ): Promise { + ): Promise { const data: Record = { signing_requests: signingRequests, threshold: threshold, }; - const resp: AxiosResponse = await this.tryAndCall({ + const resp: AxiosResponse = await this.tryAndCall({ url: '/sign', method: 'post', data, @@ -377,79 +361,22 @@ export class PorterClient { const { signatures, errors } = resp.data.result.signing_results; const allErrors: Record = { ...errors }; - const { optimistic = false } = options; - - const signingResults: { [ursulaAddress: string]: [string, string] } = {}; - let messageHash = ''; - - // For non-optimistic path - const hashCounts: Map = new Map(); - const hashToSignatures: Map< - string, - { [ursulaAddress: string]: [string, string] } - > = new Map(); - // Single pass: decode signatures and populate signingResults + const signingResults: { [ursulaAddress: string]: TacoSignature } = {}; for (const [ursulaAddress, [signerAddress, signatureB64]] of Object.entries( signatures || {}, )) { const decoded = decodeSignature(signerAddress, signatureB64); if (decoded.error) { + // issue with decoding signature, add to errors allErrors[ursulaAddress] = decoded.error; continue; } - - if (!messageHash) { - messageHash = decoded.result!.messageHash; - } - // Always include all decoded signatures in signingResults - signingResults[ursulaAddress] = [ - decoded.result!.signerAddress, - decoded.result!.signature, - ]; - - if (!optimistic) { - // For non-optimistic: track hashes and group signatures for aggregation - const hash = decoded.result!.messageHash; - hashCounts.set(hash, (hashCounts.get(hash) || 0) + 1); - - if (!hashToSignatures.has(hash)) { - hashToSignatures.set(hash, {}); - } - hashToSignatures.get(hash)![ursulaAddress] = [ - decoded.result!.signerAddress, - decoded.result!.signature, - ]; - } + signingResults[ursulaAddress] = decoded.result!; } - // Determine which signatures to aggregate - let signaturesToAggregate: { [ursulaAddress: string]: [string, string] } = - {}; - - if (optimistic) { - // Optimistic: aggregate all signatures - signaturesToAggregate = signingResults; - } else { - // Non-optimistic: only aggregate signatures from hash that meets threshold - for (const [hash, count] of hashCounts.entries()) { - if (count >= threshold) { - messageHash = hash; - signaturesToAggregate = hashToSignatures.get(hash)!; - break; - } - } - } - - const aggregatedSignature = - Object.keys(signaturesToAggregate).length >= threshold - ? aggregatePorterSignatures(signaturesToAggregate) - : undefined; - return { - messageHash, - aggregatedSignature, signingResults, errors: allErrors, }; From 86e0c72cd1a38d486bd4d09b5c666a14d9d793dc Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 10 Jul 2025 14:41:45 +0200 Subject: [PATCH 126/303] Add setSigningCohortConditions function - Add setSigningCohortConditions method to SigningCoordinatorAgent - Implement setSigningCohortConditions function in taco/sign.ts - Export the new function from taco package index - Function converts ConditionExpression to JSON and calls contract --- .../contracts/agents/signing-coordinator.ts | 17 ++++++++++++++ packages/taco/src/index.ts | 2 +- packages/taco/src/sign.ts | 23 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/packages/shared/src/contracts/agents/signing-coordinator.ts b/packages/shared/src/contracts/agents/signing-coordinator.ts index 95d462f4a..e4cc059fd 100644 --- a/packages/shared/src/contracts/agents/signing-coordinator.ts +++ b/packages/shared/src/contracts/agents/signing-coordinator.ts @@ -57,6 +57,23 @@ export class SigningCoordinatorAgent { return cohortCondition; } + public static async setSigningCohortConditions( + provider: ethers.providers.Provider, + domain: Domain, + cohortId: number, + chainId: number, + conditions: string, + signer: ethers.Signer, + ): Promise { + const coordinator = await this.connect(provider, domain, signer); + const conditionsHex = ethers.utils.toUtf8Bytes(conditions); + return await coordinator.setSigningCohortConditions( + cohortId, + chainId, + conditionsHex, + ); + } + private static async connectReadOnly( provider: ethers.providers.Provider, domain: Domain, diff --git a/packages/taco/src/index.ts b/packages/taco/src/index.ts index c355f38f7..c03a09061 100644 --- a/packages/taco/src/index.ts +++ b/packages/taco/src/index.ts @@ -11,5 +11,5 @@ export { export * as conditions from './conditions'; -export { signUserOp } from './sign'; +export { signUserOp, setSigningCohortConditions } from './sign'; export { decrypt, encrypt, encryptWithPublicKey } from './taco'; diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index f16605ad0..419fb695a 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -14,6 +14,7 @@ import { } from '@nucypher/shared'; import { ethers } from 'ethers'; +import { ConditionExpression } from './conditions/condition-expr'; import { ConditionContext } from './conditions/context'; const ERR_INSUFFICIENT_SIGNATURES = (errors: unknown) => @@ -173,3 +174,25 @@ export async function signUserOp( signingResults: porterSignResult.signingResults, }; } + +export async function setSigningCohortConditions( + conditions: ConditionExpression, + provider: ethers.providers.JsonRpcProvider, + domain: Domain, + cohortId: number, + chainId: number, + signer: ethers.Signer, +): Promise { + // Convert ConditionContext to CoreConditions JSON + const conditionsJson = conditions.toJson(); + + // Set conditions on the SigningCoordinator contract + return await SigningCoordinatorAgent.setSigningCohortConditions( + provider, + domain, + cohortId, + chainId, + conditionsJson, + signer, + ); +} From e02af58e16bbfdcd452d8995c60c2ccf8fc0ef00 Mon Sep 17 00:00:00 2001 From: KPrasch Date: Tue, 29 Jul 2025 14:06:10 +0200 Subject: [PATCH 127/303] updates additional tests to adhere to the strict ECDSA condition API context params --- packages/taco/examples/ecdsa-condition.ts | 12 +-- .../integration-test/encrypt-decrypt.test.ts | 47 ++++++------ packages/taco/test/test-utils.ts | 75 ++++++++++++++----- 3 files changed, 86 insertions(+), 48 deletions(-) diff --git a/packages/taco/examples/ecdsa-condition.ts b/packages/taco/examples/ecdsa-condition.ts index bc414d327..17d8ae2a7 100644 --- a/packages/taco/examples/ecdsa-condition.ts +++ b/packages/taco/examples/ecdsa-condition.ts @@ -17,16 +17,16 @@ const dynamicECDSACondition = new ECDSACondition({ // Example 3: ECDSA condition with different curve const p256ECDSACondition = new ECDSACondition({ - message: 'Authenticated message', - signature: ':ecdsaSignature', + message: 'hello world', + signature: ':signature', curve: 'NIST256p', }); -// Example 4: Using defaults for message and signature +// This ECDSA condition uses the default context variables const defaultECDSACondition = new ECDSACondition({ - message: ':ecdsaMessage', // Default context variable - signature: ':ecdsaSignature', // Default context variable - curve: 'SECP256k1', // Default curve + message: ':message', // Default context variable + signature: ':signature', // Default context variable + curve: 'SECP256k1', }); // Example 5: Complex usage with compound condition diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index d8d9ba756..23d2922b6 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -204,8 +204,8 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); expect( - conditionContext.requestedContextParameters.has(':ecdsaSignature'), - ).toBe(true); + conditionContext.requestedContextParameters.has(':signature'), + ).toBeTruthy(); // Create signature using the predefined condition's private key const signatureHex = createSignatureForPredefinedCondition( @@ -218,7 +218,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( ); conditionContext.addCustomContextParameterValues({ - ':ecdsaSignature': signatureHex, + ':signature': signatureHex, }); const decryptedBytes = await decrypt( @@ -260,7 +260,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( // Add invalid signature const invalidSignature = '0x' + randomBytes(64).toString('hex'); conditionContext.addCustomContextParameterValues({ - ':ecdsaSignature': invalidSignature.slice(2), + ':signature': invalidSignature.slice(2), }); await expect( @@ -268,16 +268,18 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( ).rejects.toThrow(); }, 20000); - test('should encrypt and decrypt with ECDSA condition using user address context', async () => { + test('should encrypt and decrypt with ECDSA condition using context parameters', async () => { const messageString = - 'This message uses both ECDSA and user address authentication 🔐🆔'; + 'This message uses ECDSA signature verification with context parameters 🔐✍️'; const message = toBytes(messageString); - // Create a predefined ECDSA condition that uses user address as the message + // Create a predefined ECDSA condition that uses :message context parameter const { condition: ecdsaCondition, privateKey } = - createTestECDSACondition(USER_ADDRESS_PARAM_DEFAULT); + createTestECDSACondition(':message'); - expect(ecdsaCondition.requiresAuthentication()).toBe(true); + // ECDSA conditions with :message and :signature don't require auth providers + // like :userAddress does, they just need context parameters to be provided + expect(ecdsaCondition.requiresAuthentication()).toBe(false); const messageKit = await encrypt( provider, @@ -295,33 +297,28 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); expect( - conditionContext.requestedContextParameters.has( - USER_ADDRESS_PARAM_DEFAULT, - ), - ).toBe(true); + conditionContext.requestedContextParameters.has(':message'), + ).toBeTruthy(); expect( - conditionContext.requestedContextParameters.has(':ecdsaSignature'), - ).toBe(true); - - const authProvider = new EIP4361AuthProvider(provider, consumerSigner); - conditionContext.addAuthProvider( - USER_ADDRESS_PARAM_DEFAULT, - authProvider, - ); + conditionContext.requestedContextParameters.has(':signature'), + ).toBeTruthy(); - // Sign the user's address with the predefined condition's private key - const userAddress = await consumerSigner.getAddress(); + // Define the message to be signed (provided via :message context parameter) + const messageToSign = 'User authentication message'; + + // Sign the message with the predefined condition's private key const signatureHex = createSignatureForPredefinedCondition( { condition: ecdsaCondition.value, verifyingKey: ecdsaCondition.value.verifyingKey, privateKey, }, - userAddress, + messageToSign, ); conditionContext.addCustomContextParameterValues({ - ':ecdsaSignature': signatureHex, + ':message': messageToSign, + ':signature': signatureHex, }); const decryptedBytes = await decrypt( diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index ac85231d3..f56782664 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -91,7 +91,6 @@ import { baseConditionSchema, hexStringSchema, } from '../src/conditions/schemas/common'; -import { contextParamSchema } from '../src/conditions/schemas/context'; import { JsonRpcConditionProps, JsonRpcConditionType, @@ -113,25 +112,67 @@ interface TestECDSAConditionProps extends ECDSAConditionProps { verifyingKey: string; } +// Restricted context parameters for test ECDSA conditions (matching production) +const testEcdsaMessageContextParamSchema = z + .enum([':message']) + .describe('Test ECDSA message context parameter - only :message allowed'); + +const testEcdsaSignatureContextParamSchema = z + .enum([':signature']) + .describe('Test ECDSA signature context parameter - only :signature allowed'); + +// Message field with restricted context parameter validation (for tests) +const testEcdsaMessageSchema = z.string().superRefine((val, ctx) => { + if (val.startsWith(':')) { + const result = testEcdsaMessageContextParamSchema.safeParse(val); + if (!result.success) { + ctx.addIssue({ + code: z.ZodIssueCode.invalid_enum_value, + options: [':message'], + received: val, + message: `Invalid context parameter for message. Only ':message' is allowed.`, + }); + } + } +}); + +// Signature field with restricted context parameter validation (for tests) +const testEcdsaSignatureSchema = z.string().superRefine((val, ctx) => { + if (val.startsWith(':')) { + const result = testEcdsaSignatureContextParamSchema.safeParse(val); + if (!result.success) { + ctx.addIssue({ + code: z.ZodIssueCode.invalid_enum_value, + options: [':signature'], + received: val, + message: `Invalid context parameter for signature. Only ':signature' is allowed.`, + }); + } + } else { + const result = hexStringSchema.safeParse(val); + if (!result.success) { + ctx.addIssue({ + code: z.ZodIssueCode.invalid_string, + validation: 'regex', + message: 'Invalid hex string', + }); + } + } +}); + const testECDSAConditionSchema = baseConditionSchema.extend({ conditionType: z.literal(ECDSAConditionType).default(ECDSAConditionType), - message: z - .union([z.string(), contextParamSchema]) - .default(ECDSA_MESSAGE_PARAM_DEFAULT), - signature: z - .union([hexStringSchema, contextParamSchema]) - .default(ECDSA_SIGNATURE_PARAM_DEFAULT), + message: testEcdsaMessageSchema.default(ECDSA_MESSAGE_PARAM_DEFAULT), + signature: testEcdsaSignatureSchema.default(ECDSA_SIGNATURE_PARAM_DEFAULT), verifyingKey: hexStringSchema, // Test-only: includes verifying key - curve: z - .enum([ - 'SECP256k1', - 'NIST256p', - 'NIST384p', - 'NIST521p', - 'Ed25519', - 'BRAINPOOLP256r1', - ]) - .default('SECP256k1'), + curve: z.enum([ + 'SECP256k1', + 'NIST256p', + 'NIST384p', + 'NIST521p', + 'Ed25519', + 'BRAINPOOLP256r1', + ]), // Required, no default for tests }); export class TestECDSACondition extends Condition { From c2cbf82ba19592432674e73b9872cb6e3e884a76 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Mon, 7 Jul 2025 21:45:13 -0400 Subject: [PATCH 128/303] Move processing logic out of Porter and into sign module to simplify PorterClient code. Remove concept of SigningOption since we'll always need to verify matching hashes, threshold of signatures to return anything meaningful from `signUserOp`. Properly aggregate signatures returned by Porter using bytes instead of just hex strings; fixed bug where 0x was repeated within aggregated signature because hex strings were simply appended to each other. Delineate error cases when aggregated signature cannot be produced because of too many errors or too many mismatched hashes based on responses from Porter. If an aggregated signature cannot be produced the function will throw an error. --- packages/taco/src/sign.ts | 100 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 97 insertions(+), 3 deletions(-) diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index a1bfec622..08f902da4 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -1,11 +1,14 @@ import { convertUserOperationToPython, Domain, + fromHexString, getPorterUris, PorterClient, SigningCoordinatorAgent, - SignResult, + TacoSignature, + TacoSignResult, toBase64, + toHexString, UserOperation, UserOperationSignatureRequest, } from '@nucypher/shared'; @@ -13,6 +16,39 @@ import { ethers } from 'ethers'; import { ConditionContext } from './conditions/context'; +const ERR_INSUFFICIENT_SIGNATURES = (errors: unknown) => + `Threshold of signatures not met; TACo signing failed with errors: ${JSON.stringify( + errors, + )}`; +const ERR_MISMATCHED_HASHES = ( + hashToSignatures: Map, +) => + `Threshold of signatures not met; multiple mismatched hashes found: ${JSON.stringify( + Object.fromEntries(hashToSignatures.entries()), + )}`; + +export type SignResult = { + messageHash: string; + aggregatedSignature: string; + signingResults: { [ursulaAddress: string]: TacoSignature }; + errors: Record; +}; + +function aggregateSignatures(signaturesByAddress: { + [checksumAddress: string]: TacoSignature; +}): string { + // Aggregate hex signatures by concatenating them; being carefule to remove the '0x' prefix from each signature except the first one. + const signatures = Object.values(signaturesByAddress).map( + (sig) => sig.signature, + ); + if (signatures.length === 1) { + return signatures[0]; + } + // Concatenate signatures + const allBytes = signatures.flatMap((hex) => Array.from(fromHexString(hex))); + return `0x${toHexString(new Uint8Array(allBytes))}`; +} + export async function signUserOp( provider: ethers.providers.Provider, domain: Domain, @@ -60,7 +96,65 @@ export async function signUserOp( ); // Build signing request for the user operation - const result = await porter.signUserOp(signingRequests, threshold); + const porterSignResult: TacoSignResult = await porter.signUserOp( + signingRequests, + threshold, + ); + + const hashToSignatures: Map< + string, + { [ursulaAddress: string]: TacoSignature } + > = new Map(); + + // Single pass: decode signatures and populate signingResults + for (const [ursulaAddress, signature] of Object.entries( + porterSignResult.signingResults || {}, + )) { + // For non-optimistic: track hashes and group signatures for aggregation + const hash = signature.messageHash; + if (!hashToSignatures.has(hash)) { + hashToSignatures.set(hash, {}); + } + hashToSignatures.get(hash)![ursulaAddress] = signature; + } + + let messageHash = undefined; + let signaturesToAggregate = undefined; + for (const [hash, signatures] of hashToSignatures.entries()) { + if (Object.keys(signatures).length >= threshold) { + signaturesToAggregate = signatures; + messageHash = hash; + break; + } + } + + // Insufficient signatures for a message hash to meet the threshold + if (!messageHash || !signaturesToAggregate) { + // TODO: think more about this logic + if ( + porterSignResult.errors && + Object.keys(porterSignResult.errors).length > signers.length - threshold + ) { + // too many errors to achieve threshold + throw new Error(ERR_INSUFFICIENT_SIGNATURES(porterSignResult.errors)); + } else if (hashToSignatures.size > 1) { + // If we have multiple hashes, it means we have mismatched hashes from different nodes + // we don't really expect this to happen (other than some malicious nodes) + throw new Error(ERR_MISMATCHED_HASHES(hashToSignatures)); + // since there weren't too many errors, the issue is likely hashes + } else { + throw new Error( + ERR_INSUFFICIENT_SIGNATURES(porterSignResult.errors || {}), + ); + } + } + + const aggregatedSignature = aggregateSignatures(signaturesToAggregate); - return result; + return { + messageHash, + aggregatedSignature, + signingResults: porterSignResult.signingResults || {}, + errors: porterSignResult.errors || {}, + }; } From d018cea790baeb878b62fef997094ba29b727089 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 10 Jul 2025 14:42:09 +0200 Subject: [PATCH 129/303] Add comprehensive unit tests for setSigningCohortConditions - Test successful condition setting with simple RPC conditions - Test complex compound conditions (RPC + Contract) - Test error handling from SigningCoordinatorAgent - Use real condition objects instead of mocks for better validation - Verify proper JSON serialization and contract method calls --- packages/taco/test/taco-sign.test.ts | 161 ++++++++++++++++++++++++++- 1 file changed, 160 insertions(+), 1 deletion(-) diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index a2de1f11c..c57cf7995 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -7,7 +7,11 @@ import { fakePorterUri } from '@nucypher/test-utils'; import { ethers } from 'ethers'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { signUserOp } from '../src/sign'; +import { ContractCondition } from '../src/conditions/base/contract'; +import { RpcCondition } from '../src/conditions/base/rpc'; +import { CompoundCondition } from '../src/conditions/compound-condition'; +import { ConditionExpression } from '../src/conditions/condition-expr'; +import { setSigningCohortConditions, signUserOp } from '../src/sign'; describe('TACo Signing', () => { let porterSignUserOpMock: ReturnType; @@ -341,4 +345,159 @@ describe('TACo Signing', () => { }); }); }); + + describe('setSigningCohortConditions', () => { + let mockSigner: ethers.Signer; + let mockProvider: ethers.providers.JsonRpcProvider; + let setSigningCohortConditionsSpy: ReturnType; + + beforeEach(() => { + mockProvider = {} as ethers.providers.JsonRpcProvider; + mockSigner = {} as ethers.Signer; + setSigningCohortConditionsSpy = vi.fn(); + + vi.spyOn(SigningCoordinatorAgent, 'setSigningCohortConditions').mockImplementation( + setSigningCohortConditionsSpy, + ); + }); + + it('should set signing cohort conditions successfully', async () => { + const domain = 'lynx'; + const cohortId = 1; + const chainId = 11155111; + const mockTransaction = { hash: '0x123' } as ethers.ContractTransaction; + + // Create a real ConditionExpression with RPC condition + const rpcCondition = new RpcCondition({ + chain: chainId, + method: 'eth_getBalance', + parameters: [':userAddress', 'latest'], + returnValueTest: { + comparator: '>', + value: BigInt(0), + }, + }); + + const conditionExpression = new ConditionExpression(rpcCondition); + const expectedJson = conditionExpression.toJson(); + + setSigningCohortConditionsSpy.mockResolvedValue(mockTransaction); + + const result = await setSigningCohortConditions( + conditionExpression, + mockProvider, + domain, + cohortId, + chainId, + mockSigner, + ); + + expect(setSigningCohortConditionsSpy).toHaveBeenCalledWith( + mockProvider, + domain, + cohortId, + chainId, + expectedJson, + mockSigner, + ); + expect(result).toBe(mockTransaction); + }); + + it('should handle complex condition expressions', async () => { + const domain = 'lynx'; + const cohortId = 1; + const chainId = 11155111; + const mockTransaction = { hash: '0x456' } as ethers.ContractTransaction; + + // Create a real compound ConditionExpression + const rpcCondition = new RpcCondition({ + chain: chainId, + method: 'eth_getBalance', + parameters: [':userAddress', 'latest'], + returnValueTest: { + comparator: '>', + value: BigInt(0), + }, + }); + + const contractCondition = new ContractCondition({ + contractAddress: '0x1234567890123456789012345678901234567890', + chain: chainId, + standardContractType: 'ERC20', + method: 'balanceOf', + parameters: [':userAddress'], + returnValueTest: { + comparator: '>=', + value: BigInt(1000), + }, + }); + + const compoundCondition = CompoundCondition.and([rpcCondition, contractCondition]); + const conditionExpression = new ConditionExpression(compoundCondition); + const expectedJson = conditionExpression.toJson(); + + setSigningCohortConditionsSpy.mockResolvedValue(mockTransaction); + + const result = await setSigningCohortConditions( + conditionExpression, + mockProvider, + domain, + cohortId, + chainId, + mockSigner, + ); + + expect(setSigningCohortConditionsSpy).toHaveBeenCalledWith( + mockProvider, + domain, + cohortId, + chainId, + expectedJson, + mockSigner, + ); + expect(result).toBe(mockTransaction); + }); + + it('should handle errors from SigningCoordinatorAgent', async () => { + const domain = 'lynx'; + const cohortId = 999; + const chainId = 11155111; + + // Create a real ConditionExpression + const rpcCondition = new RpcCondition({ + chain: chainId, + method: 'eth_getBalance', + parameters: [':userAddress', 'latest'], + returnValueTest: { + comparator: '>', + value: BigInt(0), + }, + }); + + const conditionExpression = new ConditionExpression(rpcCondition); + const expectedJson = conditionExpression.toJson(); + + setSigningCohortConditionsSpy.mockRejectedValue(new Error('Cohort not found')); + + await expect( + setSigningCohortConditions( + conditionExpression, + mockProvider, + domain, + cohortId, + chainId, + mockSigner, + ), + ).rejects.toThrow('Cohort not found'); + + expect(setSigningCohortConditionsSpy).toHaveBeenCalledWith( + mockProvider, + domain, + cohortId, + chainId, + expectedJson, + mockSigner, + ); + }); + }); }); From c6dcced617f6a18fa207297dfaf5ee181905bc20 Mon Sep 17 00:00:00 2001 From: KPrasch Date: Tue, 29 Jul 2025 17:57:33 +0200 Subject: [PATCH 130/303] reintroduces flexibility for ecdsa condition variable names --- packages/taco/examples/ecdsa-condition.ts | 20 +++- .../integration-test/encrypt-decrypt.test.ts | 4 +- packages/taco/src/conditions/schemas/ecdsa.ts | 94 ++----------------- .../taco/test/conditions/base/ecdsa.test.ts | 52 +--------- packages/taco/test/test-utils.ts | 59 ++---------- 5 files changed, 40 insertions(+), 189 deletions(-) diff --git a/packages/taco/examples/ecdsa-condition.ts b/packages/taco/examples/ecdsa-condition.ts index 17d8ae2a7..163acdd31 100644 --- a/packages/taco/examples/ecdsa-condition.ts +++ b/packages/taco/examples/ecdsa-condition.ts @@ -22,13 +22,31 @@ const p256ECDSACondition = new ECDSACondition({ curve: 'NIST256p', }); -// This ECDSA condition uses the default context variables +// This ECDSA condition uses the default context variables (:message and :signature) const defaultECDSACondition = new ECDSACondition({ message: ':message', // Default context variable signature: ':signature', // Default context variable curve: 'SECP256k1', }); +// For compound conditions with multiple ECDSA conditions, use custom context parameters +// to avoid variable name conflicts +const compoundECDSACondition = new CompoundCondition({ + operator: 'and', + operands: [ + new ECDSACondition({ + message: ':message1', // Custom context parameter + signature: ':signature1', // Custom context parameter + curve: 'SECP256k1', + }), + new ECDSACondition({ + message: ':message2', // Different context parameter + signature: ':signature2', // Different context parameter + curve: 'NIST256p', + }), + ], +}); + // Example 5: Complex usage with compound condition import { TimeCondition } from '../src/conditions/base/time'; import { CompoundCondition } from '../src/conditions/compound-condition'; diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index 23d2922b6..6efef6a6e 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -303,9 +303,9 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( conditionContext.requestedContextParameters.has(':signature'), ).toBeTruthy(); - // Define the message to be signed (provided via :message context parameter) + // Define the message to be signed (provided via :message context parameter) const messageToSign = 'User authentication message'; - + // Sign the message with the predefined condition's private key const signatureHex = createSignatureForPredefinedCondition( { diff --git a/packages/taco/src/conditions/schemas/ecdsa.ts b/packages/taco/src/conditions/schemas/ecdsa.ts index b3591ca67..6d26fe001 100644 --- a/packages/taco/src/conditions/schemas/ecdsa.ts +++ b/packages/taco/src/conditions/schemas/ecdsa.ts @@ -1,108 +1,32 @@ import { z } from 'zod'; import { baseConditionSchema, hexStringSchema } from './common'; +import { contextParamSchema } from './context'; export const ECDSA_MESSAGE_PARAM_DEFAULT = ':message'; export const ECDSA_SIGNATURE_PARAM_DEFAULT = ':signature'; export const ECDSAConditionType = 'ecdsa'; -// Allowed context parameters for ECDSA message field - ONLY :message -const ecdsaMessageContextParamSchema = z - .enum([':message']) - .describe('Context parameter for ECDSA message - only :message is allowed'); - -// Allowed context parameters for ECDSA signature field - ONLY :signature -const ecdsaSignatureContextParamSchema = z - .enum([':signature']) - .describe( - 'Context parameter for ECDSA signature - only :signature is allowed', - ); - -// Message field that properly validates context parameters -const ecdsaMessageSchema = z.string().superRefine((val, ctx) => { - if (val.startsWith(':')) { - // It's a context parameter, validate against allowed values - const result = ecdsaMessageContextParamSchema.safeParse(val); - if (!result.success) { - ctx.addIssue({ - code: z.ZodIssueCode.invalid_enum_value, - options: [':message'], - received: val, - message: `Invalid context parameter for message. Only ':message' is allowed.`, - }); - } - } - // Otherwise it's a regular string, which is valid -}); - -// Signature field that properly validates context parameters -const ecdsaSignatureSchema = z.string().superRefine((val, ctx) => { - if (val.startsWith(':')) { - // It's a context parameter, validate against allowed values - const result = ecdsaSignatureContextParamSchema.safeParse(val); - if (!result.success) { - ctx.addIssue({ - code: z.ZodIssueCode.invalid_enum_value, - options: [':signature'], - received: val, - message: `Invalid context parameter for signature. Only ':signature' is allowed.`, - }); - } - } else { - // It's not a context parameter, validate as hex string - const result = hexStringSchema.safeParse(val); - if (!result.success) { - ctx.addIssue({ - code: z.ZodIssueCode.invalid_string, - validation: 'regex', - message: 'Invalid hex string', - }); - } - } -}); - -// Supported ECDSA curves (must match Python backend format) export const SUPPORTED_ECDSA_CURVES = [ - // NIST curves - 'NIST192p', - 'NIST224p', + 'SECP256k1', 'NIST256p', 'NIST384p', 'NIST521p', - // SECP curves - 'SECP112r1', - 'SECP112r2', - 'SECP128r1', - 'SECP160r1', - 'SECP256k1', - // Brainpool curves (r-variants) - 'BRAINPOOLP160r1', - 'BRAINPOOLP192r1', - 'BRAINPOOLP224r1', - 'BRAINPOOLP256r1', - 'BRAINPOOLP320r1', - 'BRAINPOOLP384r1', - 'BRAINPOOLP512r1', - // Brainpool curves (t-variants) - 'BRAINPOOLP160t1', - 'BRAINPOOLP192t1', - 'BRAINPOOLP224t1', - 'BRAINPOOLP256t1', - 'BRAINPOOLP320t1', - 'BRAINPOOLP384t1', - 'BRAINPOOLP512t1', - // Edwards curves 'Ed25519', - 'Ed448', + 'BRAINPOOLP256r1', ] as const; export type ECDSACurve = (typeof SUPPORTED_ECDSA_CURVES)[number]; export const ecdsaConditionSchema = baseConditionSchema.extend({ conditionType: z.literal(ECDSAConditionType).default(ECDSAConditionType), - message: ecdsaMessageSchema.default(ECDSA_MESSAGE_PARAM_DEFAULT), - signature: ecdsaSignatureSchema.default(ECDSA_SIGNATURE_PARAM_DEFAULT), + message: z + .union([z.string(), contextParamSchema]) + .default(ECDSA_MESSAGE_PARAM_DEFAULT), + signature: z + .union([hexStringSchema, contextParamSchema]) + .default(ECDSA_SIGNATURE_PARAM_DEFAULT), curve: z.enum(SUPPORTED_ECDSA_CURVES), }); diff --git a/packages/taco/test/conditions/base/ecdsa.test.ts b/packages/taco/test/conditions/base/ecdsa.test.ts index 4daee4918..eef31dee9 100644 --- a/packages/taco/test/conditions/base/ecdsa.test.ts +++ b/packages/taco/test/conditions/base/ecdsa.test.ts @@ -90,7 +90,7 @@ describe('ECDSACondition', () => { it('accepts context variables for message', () => { const ecdsaObj = { ...testECDSAConditionObj, - message: ':message', + message: ':customMessage', }; const result = ECDSACondition.validate(ecdsaConditionSchema, ecdsaObj); @@ -102,7 +102,7 @@ describe('ECDSACondition', () => { it('accepts context variables for signature', () => { const ecdsaObj = { ...testECDSAConditionObj, - signature: ':signature', + signature: ':customSignature', }; const result = ECDSACondition.validate(ecdsaConditionSchema, ecdsaObj); @@ -111,54 +111,6 @@ describe('ECDSACondition', () => { expect(result.data).toEqual(ecdsaObj); }); - it('rejects arbitrary context variables for message', () => { - const ecdsaObj = { - ...testECDSAConditionObj, - message: ':customMessage', - }; - - const result = ECDSACondition.validate(ecdsaConditionSchema, ecdsaObj); - - expect(result.error).toBeDefined(); - expect(result.error!.issues[0].code).toEqual('invalid_enum_value'); - }); - - it('rejects arbitrary context variables for signature', () => { - const ecdsaObj = { - ...testECDSAConditionObj, - signature: ':customSignature', - }; - - const result = ECDSACondition.validate(ecdsaConditionSchema, ecdsaObj); - - expect(result.error).toBeDefined(); - expect(result.error!.issues[0].code).toEqual('invalid_enum_value'); - }); - - it('rejects the old default context variable :ecdsaMessage', () => { - const ecdsaObj = { - ...testECDSAConditionObj, - message: ':ecdsaMessage', - }; - - const result = ECDSACondition.validate(ecdsaConditionSchema, ecdsaObj); - - expect(result.error).toBeDefined(); - expect(result.error!.issues[0].code).toEqual('invalid_enum_value'); - }); - - it('rejects the old default context variable :ecdsaSignature', () => { - const ecdsaObj = { - ...testECDSAConditionObj, - signature: ':ecdsaSignature', - }; - - const result = ECDSACondition.validate(ecdsaConditionSchema, ecdsaObj); - - expect(result.error).toBeDefined(); - expect(result.error!.issues[0].code).toEqual('invalid_enum_value'); - }); - it('rejects when curve parameter is missing', () => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { curve: _curve, ...ecdsaObjWithoutCurve } = testECDSAConditionObj; diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index f56782664..083962d5b 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -91,6 +91,7 @@ import { baseConditionSchema, hexStringSchema, } from '../src/conditions/schemas/common'; +import { contextParamSchema } from '../src/conditions/schemas/context'; import { JsonRpcConditionProps, JsonRpcConditionType, @@ -112,58 +113,14 @@ interface TestECDSAConditionProps extends ECDSAConditionProps { verifyingKey: string; } -// Restricted context parameters for test ECDSA conditions (matching production) -const testEcdsaMessageContextParamSchema = z - .enum([':message']) - .describe('Test ECDSA message context parameter - only :message allowed'); - -const testEcdsaSignatureContextParamSchema = z - .enum([':signature']) - .describe('Test ECDSA signature context parameter - only :signature allowed'); - -// Message field with restricted context parameter validation (for tests) -const testEcdsaMessageSchema = z.string().superRefine((val, ctx) => { - if (val.startsWith(':')) { - const result = testEcdsaMessageContextParamSchema.safeParse(val); - if (!result.success) { - ctx.addIssue({ - code: z.ZodIssueCode.invalid_enum_value, - options: [':message'], - received: val, - message: `Invalid context parameter for message. Only ':message' is allowed.`, - }); - } - } -}); - -// Signature field with restricted context parameter validation (for tests) -const testEcdsaSignatureSchema = z.string().superRefine((val, ctx) => { - if (val.startsWith(':')) { - const result = testEcdsaSignatureContextParamSchema.safeParse(val); - if (!result.success) { - ctx.addIssue({ - code: z.ZodIssueCode.invalid_enum_value, - options: [':signature'], - received: val, - message: `Invalid context parameter for signature. Only ':signature' is allowed.`, - }); - } - } else { - const result = hexStringSchema.safeParse(val); - if (!result.success) { - ctx.addIssue({ - code: z.ZodIssueCode.invalid_string, - validation: 'regex', - message: 'Invalid hex string', - }); - } - } -}); - const testECDSAConditionSchema = baseConditionSchema.extend({ conditionType: z.literal(ECDSAConditionType).default(ECDSAConditionType), - message: testEcdsaMessageSchema.default(ECDSA_MESSAGE_PARAM_DEFAULT), - signature: testEcdsaSignatureSchema.default(ECDSA_SIGNATURE_PARAM_DEFAULT), + message: z + .union([z.string(), contextParamSchema]) + .default(ECDSA_MESSAGE_PARAM_DEFAULT), + signature: z + .union([hexStringSchema, contextParamSchema]) + .default(ECDSA_SIGNATURE_PARAM_DEFAULT), verifyingKey: hexStringSchema, // Test-only: includes verifying key curve: z.enum([ 'SECP256k1', @@ -172,7 +129,7 @@ const testECDSAConditionSchema = baseConditionSchema.extend({ 'NIST521p', 'Ed25519', 'BRAINPOOLP256r1', - ]), // Required, no default for tests + ]), }); export class TestECDSACondition extends Condition { From 67c6fb62d64a0a0c784f6cf75859d55fb336a5ca Mon Sep 17 00:00:00 2001 From: derekpierre Date: Mon, 7 Jul 2025 21:49:40 -0400 Subject: [PATCH 131/303] Improve signing integration test to ensure that aggregated signature is properly produced based on responses from Porter. --- packages/taco/integration-test/sign.test.ts | 23 +++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index 2ae4877e9..b0589819d 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -1,4 +1,10 @@ -import { Domain, getPorterUris, UserOperation } from '@nucypher/shared'; +import { + Domain, + fromHexString, + getPorterUris, + SigningCoordinatorAgent, + UserOperation, +} from '@nucypher/shared'; import { ethers } from 'ethers'; import { beforeAll, describe, expect, test } from 'vitest'; @@ -9,7 +15,7 @@ import { signUserOp } from '../src/sign'; const RPC_PROVIDER_URL = 'https://ethereum-sepolia-rpc.publicnode.com'; const DUMMY_ADDRESS = '0x742D35Cc6634C0532925A3b8D33c9c0E7B66C8E8'; const DOMAIN = 'lynx'; -const RITUAL_ID = 1; +const COHORT_ID = 1; const CHAIN_ID = 11155111; // skip integration test if RUNNING_IN_CI is not set (it is set in CI environments) @@ -60,7 +66,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const signingContext = await context.ConditionContext.forSigningCohort( provider, DOMAIN as Domain, - RITUAL_ID, + COHORT_ID, CHAIN_ID, ); @@ -68,7 +74,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const signResult = await signUserOp( provider, DOMAIN as Domain, - RITUAL_ID, + COHORT_ID, CHAIN_ID, userOp, '0.8.0', @@ -77,10 +83,19 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( ); console.log('Sign result:', signResult); + const threshold = await SigningCoordinatorAgent.getThreshold( + provider, + DOMAIN as Domain, + COHORT_ID, + ); + // Verify sign result expect(signResult).toBeDefined(); expect(signResult.messageHash).toBeDefined(); expect(signResult.aggregatedSignature).toBeDefined(); + expect(fromHexString(signResult.aggregatedSignature!).length).toEqual( + threshold * 65, // Each signature is 65 bytes (32 bytes r, 32 bytes s, 1 byte v) + ); expect(signResult.signingResults).toBeDefined(); expect(Object.keys(signResult.signingResults).length).toBeGreaterThan(0); }, 15000); From 96c32940688cbfd3375bb7efeaaa8d1978f37aae Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 4 Jul 2025 12:09:07 -0400 Subject: [PATCH 132/303] Add optional authorizationType value for JSON API/RPC conditions to allow for non-Bearer tokens to also be used for requests eg. Basic, X-API-Key. Add tests. --- .../taco/src/conditions/schemas/common.ts | 6 +++ .../taco/src/conditions/schemas/json-api.ts | 41 ++++++++++---- .../taco/src/conditions/schemas/json-rpc.ts | 49 ++++++++++++----- .../test/conditions/base/json-api.test.ts | 53 +++++++++++++++++++ .../test/conditions/base/json-rpc.test.ts | 52 ++++++++++++++++++ 5 files changed, 179 insertions(+), 22 deletions(-) diff --git a/packages/taco/src/conditions/schemas/common.ts b/packages/taco/src/conditions/schemas/common.ts index fc64ae2e7..2f1d24243 100644 --- a/packages/taco/src/conditions/schemas/common.ts +++ b/packages/taco/src/conditions/schemas/common.ts @@ -92,6 +92,12 @@ const validateHttpsURL = (url: string): boolean => { return URL.canParse(url) && url.startsWith('https://'); }; +export const jsonAuthorizationTypeSchema = z.enum([ + 'Bearer', + 'Basic', + 'X-API-Key', +]); + // Use our own URL refinement check due to https://github.com/colinhacks/zod/issues/2236 export const httpsURLSchema = z .string() diff --git a/packages/taco/src/conditions/schemas/json-api.ts b/packages/taco/src/conditions/schemas/json-api.ts index 8fa6e7928..8876facd4 100644 --- a/packages/taco/src/conditions/schemas/json-api.ts +++ b/packages/taco/src/conditions/schemas/json-api.ts @@ -1,18 +1,41 @@ import { z } from 'zod'; -import { baseConditionSchema, httpsURLSchema, jsonPathSchema } from './common'; +import { + baseConditionSchema, + httpsURLSchema, + jsonAuthorizationTypeSchema, + jsonPathSchema, +} from './common'; import { contextParamSchema } from './context'; import { returnValueTestSchema } from './return-value-test'; export const JsonApiConditionType = 'json-api'; -export const jsonApiConditionSchema = baseConditionSchema.extend({ - conditionType: z.literal(JsonApiConditionType).default(JsonApiConditionType), - endpoint: httpsURLSchema, - parameters: z.record(z.string(), z.unknown()).optional(), - query: jsonPathSchema.optional(), - authorizationToken: contextParamSchema.optional(), - returnValueTest: returnValueTestSchema, // Update to allow multiple return values after expanding supported methods -}); +export const jsonApiConditionSchema = baseConditionSchema + .extend({ + conditionType: z + .literal(JsonApiConditionType) + .default(JsonApiConditionType), + endpoint: httpsURLSchema, + parameters: z.record(z.string(), z.unknown()).optional(), + query: jsonPathSchema.optional(), + authorizationToken: contextParamSchema.optional(), + authorizationType: jsonAuthorizationTypeSchema.optional(), + returnValueTest: returnValueTestSchema, // Update to allow multiple return values after expanding supported methods + }) + .refine( + (data) => { + // Ensure that if authorizationType is provided, then authorizationToken is set + if (data.authorizationType && !data.authorizationToken) { + return false; + } + return true; + }, + { + message: + 'authorizationToken must be provided if authorizationType is set', + path: ['authorizationType'], + }, + ); export type JsonApiConditionProps = z.infer; diff --git a/packages/taco/src/conditions/schemas/json-rpc.ts b/packages/taco/src/conditions/schemas/json-rpc.ts index d945f2f5b..bd32820a9 100644 --- a/packages/taco/src/conditions/schemas/json-rpc.ts +++ b/packages/taco/src/conditions/schemas/json-rpc.ts @@ -1,22 +1,45 @@ import { z } from 'zod'; -import { baseConditionSchema, httpsURLSchema, jsonPathSchema } from './common'; +import { + baseConditionSchema, + httpsURLSchema, + jsonAuthorizationTypeSchema, + jsonPathSchema, +} from './common'; import { contextParamSchema } from './context'; import { returnValueTestSchema } from './return-value-test'; export const JsonRpcConditionType = 'json-rpc'; -export const jsonRpcConditionSchema = baseConditionSchema.extend({ - conditionType: z.literal(JsonRpcConditionType).default(JsonRpcConditionType), - endpoint: httpsURLSchema, - method: z.string(), - // list or dictionary - params: z - .union([z.array(z.unknown()), z.record(z.string(), z.unknown())]) - .optional(), - query: jsonPathSchema.optional(), - authorizationToken: contextParamSchema.optional(), - returnValueTest: returnValueTestSchema, -}); +export const jsonRpcConditionSchema = baseConditionSchema + .extend({ + conditionType: z + .literal(JsonRpcConditionType) + .default(JsonRpcConditionType), + endpoint: httpsURLSchema, + method: z.string(), + // list or dictionary + params: z + .union([z.array(z.unknown()), z.record(z.string(), z.unknown())]) + .optional(), + query: jsonPathSchema.optional(), + authorizationToken: contextParamSchema.optional(), + authorizationType: jsonAuthorizationTypeSchema.optional(), + returnValueTest: returnValueTestSchema, + }) + .refine( + (data) => { + // Ensure that if authorizationType is provided, then authorizationToken is set + if (data.authorizationType && !data.authorizationToken) { + return false; + } + return true; + }, + { + message: + 'authorizationToken must be provided if authorizationType is set', + path: ['authorizationType'], + }, + ); export type JsonRpcConditionProps = z.infer; diff --git a/packages/taco/test/conditions/base/json-api.test.ts b/packages/taco/test/conditions/base/json-api.test.ts index a7fc9165b..5ad5d0c05 100644 --- a/packages/taco/test/conditions/base/json-api.test.ts +++ b/packages/taco/test/conditions/base/json-api.test.ts @@ -76,6 +76,59 @@ describe('JsonApiCondition', () => { }); }); + describe('authorizationType', () => { + it.each(['Bearer', 'Basic', 'X-API-Key'])( + 'accepts valid authorization types', + (authType) => { + const result = JsonApiCondition.validate(jsonApiConditionSchema, { + ...testJsonApiConditionObj, + authorizationToken: ':authToken', + authorizationType: authType, + }); + expect(result.error).toBeUndefined(); + expect(result.data).toEqual({ + ...testJsonApiConditionObj, + authorizationToken: ':authToken', + authorizationType: authType, + }); + }, + ); + it('authorizationToken must be set if authorizationType is provided', () => { + const result = JsonApiCondition.validate(jsonApiConditionSchema, { + ...testJsonApiConditionObj, + authorizationType: 'Bearer', + }); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + authorizationType: { + _errors: [ + 'authorizationToken must be provided if authorizationType is set', + ], + }, + }); + }); + it.each(['InvalidType', 'Bearer ', 'Basic123', 'Y-API-Key'])( + 'rejects invalid authorization types', + (authType) => { + const result = JsonApiCondition.validate(jsonApiConditionSchema, { + ...testJsonApiConditionObj, + authorizationToken: ':authToken', + authorizationType: authType, + }); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + authorizationType: { + _errors: [ + `Invalid enum value. Expected 'Bearer' | 'Basic' | 'X-API-Key', received '${authType}'`, + ], + }, + }); + }, + ); + }); + describe('parameters', () => { it('accepts conditions without query path', () => { const { query, ...noQueryObj } = testJsonApiConditionObj; diff --git a/packages/taco/test/conditions/base/json-rpc.test.ts b/packages/taco/test/conditions/base/json-rpc.test.ts index b54244160..7d7facae7 100644 --- a/packages/taco/test/conditions/base/json-rpc.test.ts +++ b/packages/taco/test/conditions/base/json-rpc.test.ts @@ -74,6 +74,58 @@ describe('JsonRpcCondition', () => { }); }); }); + describe('authorizationType', () => { + it.each(['Bearer', 'Basic', 'X-API-Key'])( + 'accepts valid authorization types', + (authType) => { + const result = JsonRpcCondition.validate(jsonRpcConditionSchema, { + ...testJsonRpcConditionObj, + authorizationToken: ':authToken', + authorizationType: authType, + }); + expect(result.error).toBeUndefined(); + expect(result.data).toEqual({ + ...testJsonRpcConditionObj, + authorizationToken: ':authToken', + authorizationType: authType, + }); + }, + ); + it('authorizationToken must be set if authorizationType is provided', () => { + const result = JsonRpcCondition.validate(jsonRpcConditionSchema, { + ...testJsonRpcConditionObj, + authorizationType: 'Basic', + }); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + authorizationType: { + _errors: [ + 'authorizationToken must be provided if authorizationType is set', + ], + }, + }); + }); + it.each(['InvalidType', 'Bearer ', 'Basic123', 'Y-API-Key'])( + 'rejects invalid authorization types', + (authType) => { + const result = JsonRpcCondition.validate(jsonRpcConditionSchema, { + ...testJsonRpcConditionObj, + authorizationToken: ':authToken', + authorizationType: authType, + }); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + authorizationType: { + _errors: [ + `Invalid enum value. Expected 'Bearer' | 'Basic' | 'X-API-Key', received '${authType}'`, + ], + }, + }); + }, + ); + }); describe('properties', () => { it('accepts conditions without query path', () => { From 16a5d11e2fe14247324a4468c1ff73e8d887c86c Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 10 Jul 2025 14:57:01 +0200 Subject: [PATCH 133/303] Add condition serialization round-trip integration test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Test validates condition serialization without blockchain writes - Reads existing conditions from chain and converts to objects - Converts objects back to JSON and verifies byte-perfect match - Ensures read → object → write produces identical data - Gracefully handles missing conditions on test cohorts --- packages/taco/integration-test/sign.test.ts | 76 ++++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index b0589819d..59da4aa5e 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -10,7 +10,9 @@ import { beforeAll, describe, expect, test } from 'vitest'; import { initialize } from '../src'; import { context } from '../src/conditions'; +import { ConditionExpression } from '../src/conditions/condition-expr'; import { signUserOp } from '../src/sign'; +import { CoreConditions } from '../src/types'; const RPC_PROVIDER_URL = 'https://ethereum-sepolia-rpc.publicnode.com'; const DUMMY_ADDRESS = '0x742D35Cc6634C0532925A3b8D33c9c0E7B66C8E8'; @@ -98,6 +100,76 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( ); expect(signResult.signingResults).toBeDefined(); expect(Object.keys(signResult.signingResults).length).toBeGreaterThan(0); - }, 15000); + }, 150000); + + test('should validate condition serialization round-trip with existing cohort conditions', async () => { + // This integration test validates condition serialization/deserialization without writing to blockchain: + // 1. Read existing conditions from a known cohort on the chain + // 2. Convert those bytes to ConditionExpression object + // 3. Convert the object back to bytes (what would be written to chain) + // 4. Verify the bytes match exactly + + // Try to read conditions from the existing ritual/cohort + let retrievedConditionHex: string; + try { + retrievedConditionHex = await SigningCoordinatorAgent.getSigningCohortConditions( + provider, + DOMAIN as Domain, + COHORT_ID, + CHAIN_ID, + ); + } catch (error: unknown) { + const errorMessage = error instanceof Error ? error.message : String(error); + if (errorMessage.includes('cohort does not exist') || + errorMessage.includes('invalid cohort') || + errorMessage.includes('conditions not set')) { + console.log(`Skipping test - no conditions found for cohort ${COHORT_ID}. This test requires an existing cohort with conditions set.`); + return; + } + throw error; + } + + // If the hex is empty or just '0x', skip the test + if (!retrievedConditionHex || retrievedConditionHex === '0x' || retrievedConditionHex.length <= 2) { + console.log(`Skipping test - cohort ${COHORT_ID} has no conditions set.`); + return; + } + + console.log('Retrieved condition hex from chain:', retrievedConditionHex); + + // Convert hex back to JSON string (simulating what the chain stores) + const chainConditionJson = ethers.utils.toUtf8String(retrievedConditionHex); + console.log('Chain condition JSON:', chainConditionJson); + + // Parse the JSON and recreate the ConditionExpression from the chain data + // This simulates reading conditions from chain and converting to our object model + const coreConditions = new CoreConditions(chainConditionJson); + const retrievedConditions = ConditionExpression.fromCoreConditions(coreConditions); + + // Also verify we can create a ConditionContext from it (this validates the data is readable) + const retrievedContext = await context.ConditionContext.forSigningCohort( + provider, + DOMAIN as Domain, + COHORT_ID, + CHAIN_ID, + ); + + // Convert back to JSON (this is what would be written to chain) + const roundTripJson = retrievedConditions.toJson(); + console.log('Round-trip JSON:', roundTripJson); + + // The core verification: ensure serialization round-trip is identical + // This proves that read → object → write produces identical bytes + expect(JSON.parse(roundTripJson)).toEqual(JSON.parse(chainConditionJson)); + + // Additional verification: ensure the objects have expected properties + expect(retrievedConditions.condition).toBeDefined(); + + // Verify that the semantic content is identical (JSON property order may differ) + expect(JSON.parse(roundTripJson)).toEqual(JSON.parse(chainConditionJson)); + + console.log('Condition serialization round-trip validation completed successfully!'); + + }, 60000); // Shorter timeout since no blockchain writes }, -); +); \ No newline at end of file From eb7031f8274cd9824f68609b939bab7c69aa2497 Mon Sep 17 00:00:00 2001 From: KPrasch Date: Tue, 29 Jul 2025 18:25:51 +0200 Subject: [PATCH 134/303] makes verifyingKey part of the production ECDSAConditionProps --- packages/taco/examples/ecdsa-condition.ts | 18 ++++++++ packages/taco/src/conditions/schemas/ecdsa.ts | 1 + .../taco/test/conditions/base/ecdsa.test.ts | 2 + packages/taco/test/test-utils.ts | 41 ++++--------------- 4 files changed, 30 insertions(+), 32 deletions(-) diff --git a/packages/taco/examples/ecdsa-condition.ts b/packages/taco/examples/ecdsa-condition.ts index 163acdd31..05330e1dd 100644 --- a/packages/taco/examples/ecdsa-condition.ts +++ b/packages/taco/examples/ecdsa-condition.ts @@ -1,10 +1,19 @@ import { ECDSACondition } from '../src/conditions/base/ecdsa'; +// Example verifying keys (public keys) - in production these would come from actual key pairs +const EXAMPLE_VERIFYING_KEY_SECP256K1 = + '0437a1c9c0e8ff7a2e0e0a9b5a8c3d5b7e9f1c3e5a7b9d1f3e5c7a9b1d3f5e7c9a1e3f5a7b9c1d3e5f7a9b1c3d5e7f9a1b3c5d7e9f1a3b5c7d9e1f3a5'; +const EXAMPLE_VERIFYING_KEY_NIST256P = + '0423456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; +const EXAMPLE_VERIFYING_KEY_ED25519 = + '0fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba987654321'; + // Example 1: ECDSA condition with hardcoded message, dynamic signature const attestationCondition = new ECDSACondition({ message: 'I attest that I am authorized to access this data and agree to use it responsibly', signature: ':userSignature', // User provides signature at runtime + verifyingKey: EXAMPLE_VERIFYING_KEY_SECP256K1, curve: 'SECP256k1', }); @@ -12,6 +21,7 @@ const attestationCondition = new ECDSACondition({ const dynamicECDSACondition = new ECDSACondition({ message: ':userMessage', signature: ':userSignature', + verifyingKey: EXAMPLE_VERIFYING_KEY_SECP256K1, curve: 'SECP256k1', }); @@ -19,6 +29,7 @@ const dynamicECDSACondition = new ECDSACondition({ const p256ECDSACondition = new ECDSACondition({ message: 'hello world', signature: ':signature', + verifyingKey: EXAMPLE_VERIFYING_KEY_NIST256P, curve: 'NIST256p', }); @@ -26,6 +37,7 @@ const p256ECDSACondition = new ECDSACondition({ const defaultECDSACondition = new ECDSACondition({ message: ':message', // Default context variable signature: ':signature', // Default context variable + verifyingKey: EXAMPLE_VERIFYING_KEY_SECP256K1, curve: 'SECP256k1', }); @@ -37,11 +49,13 @@ const compoundECDSACondition = new CompoundCondition({ new ECDSACondition({ message: ':message1', // Custom context parameter signature: ':signature1', // Custom context parameter + verifyingKey: EXAMPLE_VERIFYING_KEY_SECP256K1, curve: 'SECP256k1', }), new ECDSACondition({ message: ':message2', // Different context parameter signature: ':signature2', // Different context parameter + verifyingKey: EXAMPLE_VERIFYING_KEY_NIST256P, curve: 'NIST256p', }), ], @@ -78,6 +92,7 @@ const authorizationCondition = CompoundCondition.and([ new ECDSACondition({ message: 'I authorize access to this encrypted data', signature: ':userSignature', + verifyingKey: EXAMPLE_VERIFYING_KEY_SECP256K1, curve: 'SECP256k1', }), ]); @@ -86,6 +101,7 @@ const authorizationCondition = CompoundCondition.and([ const ed25519Condition = new ECDSACondition({ message: 'Edwards curve signature verification', signature: ':ed25519Signature', + verifyingKey: EXAMPLE_VERIFYING_KEY_ED25519, curve: 'Ed25519', }); @@ -93,6 +109,7 @@ const ed25519Condition = new ECDSACondition({ const brainpoolCondition = new ECDSACondition({ message: 'Brainpool P-256 verification', signature: ':brainpoolSignature', + verifyingKey: EXAMPLE_VERIFYING_KEY_SECP256K1, curve: 'BRAINPOOLP256r1', }); @@ -100,5 +117,6 @@ const brainpoolCondition = new ECDSACondition({ const p384Condition = new ECDSACondition({ message: 'High-security P-384 verification', signature: ':p384Signature', + verifyingKey: EXAMPLE_VERIFYING_KEY_NIST256P, curve: 'NIST384p', }); diff --git a/packages/taco/src/conditions/schemas/ecdsa.ts b/packages/taco/src/conditions/schemas/ecdsa.ts index 6d26fe001..a7d035864 100644 --- a/packages/taco/src/conditions/schemas/ecdsa.ts +++ b/packages/taco/src/conditions/schemas/ecdsa.ts @@ -27,6 +27,7 @@ export const ecdsaConditionSchema = baseConditionSchema.extend({ signature: z .union([hexStringSchema, contextParamSchema]) .default(ECDSA_SIGNATURE_PARAM_DEFAULT), + verifyingKey: hexStringSchema, curve: z.enum(SUPPORTED_ECDSA_CURVES), }); diff --git a/packages/taco/test/conditions/base/ecdsa.test.ts b/packages/taco/test/conditions/base/ecdsa.test.ts index eef31dee9..ea872a3c4 100644 --- a/packages/taco/test/conditions/base/ecdsa.test.ts +++ b/packages/taco/test/conditions/base/ecdsa.test.ts @@ -129,6 +129,8 @@ describe('ECDSACondition', () => { const condition = new ECDSACondition({ message: 'test message', signature: 'abcdef123456', + verifyingKey: + '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef', curve: 'SECP256k1', }); diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 083962d5b..674ef021f 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -37,7 +37,6 @@ import { } from '@nucypher/test-utils'; import { ethers } from 'ethers'; import { MockInstance, vi } from 'vitest'; -import { z } from 'zod'; import { AddressAllowlistConditionProps, @@ -52,6 +51,7 @@ import { ECDSA_MESSAGE_PARAM_DEFAULT, ECDSA_SIGNATURE_PARAM_DEFAULT, ECDSAConditionProps, + ecdsaConditionSchema, ECDSAConditionType, ECDSACurve, } from '../src/conditions/base/ecdsa'; @@ -87,11 +87,6 @@ import { import { Condition } from '../src/conditions/condition'; import { ConditionExpression } from '../src/conditions/condition-expr'; import { ERC721Balance } from '../src/conditions/predefined/erc721'; -import { - baseConditionSchema, - hexStringSchema, -} from '../src/conditions/schemas/common'; -import { contextParamSchema } from '../src/conditions/schemas/context'; import { JsonRpcConditionProps, JsonRpcConditionType, @@ -107,33 +102,11 @@ import { import { DkgClient, DkgRitual } from '../src/dkg'; import { encryptMessage } from '../src/tdec'; -// Test-specific ECDSA condition that includes verifying key for integration testing -// This simulates how predefined ECDSA conditions would work in production -interface TestECDSAConditionProps extends ECDSAConditionProps { - verifyingKey: string; -} - -const testECDSAConditionSchema = baseConditionSchema.extend({ - conditionType: z.literal(ECDSAConditionType).default(ECDSAConditionType), - message: z - .union([z.string(), contextParamSchema]) - .default(ECDSA_MESSAGE_PARAM_DEFAULT), - signature: z - .union([hexStringSchema, contextParamSchema]) - .default(ECDSA_SIGNATURE_PARAM_DEFAULT), - verifyingKey: hexStringSchema, // Test-only: includes verifying key - curve: z.enum([ - 'SECP256k1', - 'NIST256p', - 'NIST384p', - 'NIST521p', - 'Ed25519', - 'BRAINPOOLP256r1', - ]), -}); +// Test ECDSA condition that uses the main schema (verifyingKey is now included) +const testECDSAConditionSchema = ecdsaConditionSchema; export class TestECDSACondition extends Condition { - constructor(value: Omit) { + constructor(value: Omit) { super(testECDSAConditionSchema, { conditionType: ECDSAConditionType, ...value, @@ -371,6 +344,8 @@ export const testECDSAConditionObj: ECDSAConditionProps = { conditionType: ECDSAConditionType, message: ECDSA_MESSAGE_PARAM_DEFAULT, signature: ECDSA_SIGNATURE_PARAM_DEFAULT, + verifyingKey: + '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef', // Test verifying key curve: 'SECP256k1', }; @@ -388,15 +363,17 @@ export function createPredefinedECDSACondition( ): PredefinedECDSACondition { // Simulate server-side key generation for the predefined condition const testWallet = ethers.Wallet.createRandom(); + const verifyingKey = testWallet.publicKey.slice(2); // Remove '0x' prefix return { condition: { conditionType: ECDSAConditionType, message: message, signature: ECDSA_SIGNATURE_PARAM_DEFAULT, + verifyingKey: verifyingKey, // Include verifyingKey in the condition curve: curve, }, - verifyingKey: testWallet.publicKey.slice(2), // Remove '0x' prefix + verifyingKey: verifyingKey, privateKey: testWallet.privateKey, // For test purposes only }; } From dd1d19fe8401366c73594f3249f0169391a50d73 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Mon, 7 Jul 2025 21:51:14 -0400 Subject: [PATCH 135/303] Update porter and sign module tests to no longer use SigningOptions, and to use proper hex for signatures. Since logic moved from Porter to the sign module, some tests were moved over to the sign test module as well. --- packages/shared/test/porter.test.ts | 118 ++++++---- packages/taco/test/taco-sign.test.ts | 325 ++++++++++++++++++++------- 2 files changed, 321 insertions(+), 122 deletions(-) diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index 35cb3eb32..ccda73b13 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -62,7 +62,7 @@ const createMockSignResponse = (errorCase?: boolean) => ({ new TextEncoder().encode( JSON.stringify({ message_hash: '0x1234', - signature: '0xijkl', + signature: '0xbeef', }), ), ), @@ -75,7 +75,7 @@ const createMockSignResponse = (errorCase?: boolean) => ({ new TextEncoder().encode( JSON.stringify({ message_hash: '0x1234', - signature: '0x90ab', + signature: '0xdead', }), ), ), @@ -86,7 +86,7 @@ const createMockSignResponse = (errorCase?: boolean) => ({ new TextEncoder().encode( JSON.stringify({ message_hash: '0x1234', - signature: '0xijkl', + signature: '0xbeef', }), ), ), @@ -225,11 +225,17 @@ describe('PorterClient Signing', () => { ); expect(result).toEqual({ - messageHash: '0x1234', - aggregatedSignature: '0x90ab0xijkl', // Combined signatures in sorted order signingResults: { - '0x1234': ['0x5678', '0x90ab'], - '0xabcd': ['0xefgh', '0xijkl'], + '0x1234': { + messageHash: '0x1234', + signature: '0xdead', + signerAddress: '0x5678', + }, + '0xabcd': { + messageHash: '0x1234', + signature: '0xbeef', + signerAddress: '0xefgh', + }, }, errors: {}, }); @@ -246,9 +252,6 @@ describe('PorterClient Signing', () => { '0xabcd': JSON.stringify(mockPackedUserOp), }, 2, - { - optimistic: true, - }, ), ).rejects.toThrow('Porter returned bad response: 400 - '); }); @@ -266,10 +269,12 @@ describe('PorterClient Signing', () => { ); expect(result).toEqual({ - messageHash: '0x1234', - aggregatedSignature: undefined, // No aggregation since threshold (2) not met (only 1 signature) signingResults: { - '0xabcd': ['0xefgh', '0xijkl'], + '0xabcd': { + messageHash: '0x1234', + signature: '0xbeef', + signerAddress: '0xefgh', + }, }, errors: { '0x1234': 'Failed to sign', @@ -288,7 +293,7 @@ describe('PorterClient Signing', () => { new TextEncoder().encode( JSON.stringify({ message_hash: '0x1234', - signature: '0x90ab', + signature: '0xdead', }), ), ), @@ -299,7 +304,7 @@ describe('PorterClient Signing', () => { new TextEncoder().encode( JSON.stringify({ message_hash: '0xdifferent', // Different message hash - signature: '0xijkl', + signature: '0xbeef', }), ), ), @@ -329,11 +334,17 @@ describe('PorterClient Signing', () => { ); expect(result).toEqual({ - messageHash: '0x1234', // First message hash - aggregatedSignature: undefined, // No aggregation since no hash meets threshold (2) signingResults: { - '0x1234': ['0x5678', '0x90ab'], - '0xabcd': ['0xefgh', '0xijkl'], // All signatures included in signingResults + '0x1234': { + messageHash: '0x1234', + signature: '0xdead', + signerAddress: '0x5678', + }, + '0xabcd': { + messageHash: '0xdifferent', // Different hash + signature: '0xbeef', + signerAddress: '0xefgh', + }, }, errors: {}, // No errors - mismatched hashes don't generate errors, just prevent aggregation }); @@ -350,7 +361,7 @@ describe('PorterClient Signing', () => { new TextEncoder().encode( JSON.stringify({ message_hash: '0x1234', - signature: '0x90ab', + signature: '0xdead', }), ), ), @@ -381,16 +392,18 @@ describe('PorterClient Signing', () => { ); expect(result).toEqual({ - messageHash: '0x1234', - aggregatedSignature: undefined, // Should be undefined since threshold not met signingResults: { - '0x1234': ['0x5678', '0x90ab'], + '0x1234': { + messageHash: '0x1234', + signature: '0xdead', + signerAddress: '0x5678', + }, }, errors: {}, }); }); - it('should successfully sign with optimistic mode', async () => { + it('should successfully sign', async () => { mockSignUserOp(true); const porterClient = new PorterClient(fakePorterUris[2]); const result = await porterClient.signUserOp( @@ -399,21 +412,26 @@ describe('PorterClient Signing', () => { '0xabcd': JSON.stringify(mockPackedUserOp), }, 2, - { optimistic: true }, ); expect(result).toEqual({ - messageHash: '0x1234', - aggregatedSignature: '0x90ab0xijkl', // All signatures aggregated in optimistic mode signingResults: { - '0x1234': ['0x5678', '0x90ab'], - '0xabcd': ['0xefgh', '0xijkl'], + '0x1234': { + messageHash: '0x1234', + signature: '0xdead', + signerAddress: '0x5678', + }, + '0xabcd': { + messageHash: '0x1234', + signature: '0xbeef', + signerAddress: '0xefgh', + }, }, errors: {}, }); }); - it('should handle decode errors in optimistic mode', async () => { + it('should handle decode errors', async () => { const createOptimisticErrorResponse = () => ({ result: { signing_results: { @@ -424,7 +442,7 @@ describe('PorterClient Signing', () => { new TextEncoder().encode( JSON.stringify({ message_hash: '0x1234', - signature: '0x90ab', + signature: '0xdead', }), ), ), @@ -452,14 +470,15 @@ describe('PorterClient Signing', () => { '0xabcd': JSON.stringify(mockPackedUserOp), }, 2, - { optimistic: true }, ); expect(result).toEqual({ - messageHash: '0x1234', - aggregatedSignature: undefined, // No aggregation since only 1 valid signature < threshold signingResults: { - '0x1234': ['0x5678', '0x90ab'], // Only valid signature included + '0x1234': { + messageHash: '0x1234', + signature: '0xdead', + signerAddress: '0x5678', + }, }, errors: { '0xabcd': expect.stringContaining('Failed to decode signature'), // Decode error @@ -467,7 +486,7 @@ describe('PorterClient Signing', () => { }); }); - it('should aggregate only threshold-meeting hash in non-optimistic mode', async () => { + it('should aggregate only threshold-meeting hash', async () => { const createMixedHashResponse = () => ({ result: { signing_results: { @@ -478,7 +497,7 @@ describe('PorterClient Signing', () => { new TextEncoder().encode( JSON.stringify({ message_hash: '0xhash1', - signature: '0x90ab', + signature: '0xdead', }), ), ), @@ -489,7 +508,7 @@ describe('PorterClient Signing', () => { new TextEncoder().encode( JSON.stringify({ message_hash: '0xhash1', // Same hash, meets threshold - signature: '0xijkl', + signature: '0xbeef', }), ), ), @@ -500,7 +519,7 @@ describe('PorterClient Signing', () => { new TextEncoder().encode( JSON.stringify({ message_hash: '0xhash2', // Different hash, doesn't meet threshold - signature: '0xmnop', + signature: '0xcafe', }), ), ), @@ -531,12 +550,23 @@ describe('PorterClient Signing', () => { ); expect(result).toEqual({ - messageHash: '0xhash1', // First hash seen - aggregatedSignature: '0x90ab0xijkl', // Only signatures from threshold-meeting hash + // different hashes returned separately signingResults: { - '0x1234': ['0x5678', '0x90ab'], - '0xabcd': ['0xefgh', '0xijkl'], - '0xdef0': ['0xabc1', '0xmnop'], // All signatures included in results + '0x1234': { + messageHash: '0xhash1', + signature: '0xdead', + signerAddress: '0x5678', + }, + '0xabcd': { + messageHash: '0xhash1', + signature: '0xbeef', + signerAddress: '0xefgh', + }, + '0xdef0': { + messageHash: '0xhash2', + signature: '0xcafe', + signerAddress: '0xabc1', + }, }, errors: {}, }); diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index e109bf6b0..d34078f20 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -10,19 +10,19 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import { signUserOp } from '../src/sign'; describe('TACo Signing', () => { - let signUserOpMock: ReturnType; + let porterSignUserOpMock: ReturnType; let mockProvider: ethers.providers.Provider; beforeEach(() => { - signUserOpMock = vi.fn(); + porterSignUserOpMock = vi.fn(); mockProvider = {} as ethers.providers.Provider; vi.spyOn(PorterClient.prototype, 'signUserOp').mockImplementation( - signUserOpMock, + porterSignUserOpMock, ); vi.spyOn(SigningCoordinatorAgent, 'getParticipants').mockResolvedValue([ - { operator: '0x1234', provider: '0x5678', signature: '0x90ab' }, - { operator: '0xabcd', provider: '0xefgh', signature: '0xijkl' }, + { operator: '0xsnr1', provider: '0xnode1', signature: '0xdead' }, + { operator: '0xsnr2', provider: '0xnode2', signature: '0xbeef' }, ]); vi.spyOn(SigningCoordinatorAgent, 'getThreshold').mockResolvedValue(2); }); @@ -45,39 +45,114 @@ describe('TACo Signing', () => { paymasterData: '0x', signature: '0x', }; + const chainId = 1; + const cohortId = 5; + const porterUris = [fakePorterUri]; + const aaVersion = '0.8.0'; + const threshold = 2; - it('should sign a user operation with a 0.8.0 account', async () => { - const chainId = 1; - const aaVersion = '0.8.0'; - const cohortId = 5; - const porterUris = [fakePorterUri]; - - signUserOpMock.mockResolvedValue({ - messageHash: '0x1234', - aggregatedSignature: '0x90ab0xijkl', - signingResults: { - '0x1234': ['0x5678', '0x90ab'], - '0xabcd': ['0xefgh', '0xijkl'], - }, - errors: {}, + it.each(['0.8.0', 'mdt'])( + 'should sign a user operation with a valid aa versions', + async (validAAVersion) => { + const signingResults = { + '0xnode1': { + messageHash: '0xhash1', + signature: '0xdead', + signerAddress: '0xsnr1', + }, + '0xnode2': { + messageHash: '0xhash1', + signature: '0xbeef', + signerAddress: '0xsnr2', + }, + }; + const errors = {}; + + porterSignUserOpMock.mockResolvedValue({ + signingResults, + errors, + }); + + const result = await signUserOp( + mockProvider, + 'lynx', + cohortId, + chainId, + userOp, + validAAVersion, + undefined, + porterUris, + ); + + const pythonUserOp = convertUserOperationToPython(userOp); + + expect(porterSignUserOpMock).toHaveBeenCalledWith( + { + '0xnode1': btoa( + JSON.stringify({ + user_op: JSON.stringify(pythonUserOp), + aa_version: validAAVersion, + cohort_id: cohortId, + chain_id: chainId, + context: {}, + signature_type: 'userop', + }), + ), + '0xnode2': btoa( + JSON.stringify({ + user_op: JSON.stringify(pythonUserOp), + aa_version: validAAVersion, + cohort_id: cohortId, + chain_id: chainId, + context: {}, + signature_type: 'userop', + }), + ), + }, + threshold, + ); + + expect(result).toEqual({ + messageHash: '0xhash1', + aggregatedSignature: '0xdeadbeef', + signingResults, + errors, + }); + }, + ); + + it('should handle only errors in Porter response', async () => { + // Mock a response with errors from Porter + const signingResults = {}; + const errors = { + '0xnode1': 'Failed to sign', + '0xnode2': 'Failed to sign', + }; + + porterSignUserOpMock.mockResolvedValue({ + signingResults, + errors, }); - const result = await signUserOp( - mockProvider, - 'lynx', - cohortId, - chainId, - userOp, - aaVersion, - undefined, - porterUris, + await expect( + signUserOp( + mockProvider, + 'lynx', + cohortId, + chainId, + userOp, + aaVersion, + undefined, + porterUris, + ), + ).rejects.toThrow( + `Threshold of signatures not met; TACo signing failed with errors: ${JSON.stringify(errors)}`, ); const pythonUserOp = convertUserOperationToPython(userOp); - - expect(signUserOpMock).toHaveBeenCalledWith( + expect(porterSignUserOpMock).toHaveBeenCalledWith( { - '0x5678': btoa( + '0xnode1': btoa( JSON.stringify({ user_op: JSON.stringify(pythonUserOp), aa_version: aaVersion, @@ -87,7 +162,7 @@ describe('TACo Signing', () => { signature_type: 'userop', }), ), - '0xefgh': btoa( + '0xnode2': btoa( JSON.stringify({ user_op: JSON.stringify(pythonUserOp), aa_version: aaVersion, @@ -98,37 +173,101 @@ describe('TACo Signing', () => { }), ), }, - 2, + threshold, ); + }); + it('should handle insufficient signatures in Porter response', async () => { + const signingResults = { + '0xnode1': { + messageHash: '0xhash1', + signature: '0xdead', + signerAddress: '0xsnr1', + }, + }; + const errors = { + '0xnode2': 'Failed to sign', + }; - expect(result).toEqual({ - messageHash: '0x1234', - aggregatedSignature: '0x90ab0xijkl', - signingResults: { - '0x1234': ['0x5678', '0x90ab'], - '0xabcd': ['0xefgh', '0xijkl'], + porterSignUserOpMock.mockResolvedValue({ + signingResults, + errors, + }); + + await expect( + signUserOp( + mockProvider, + 'lynx', + cohortId, + chainId, + userOp, + aaVersion, + undefined, + porterUris, + ), + ).rejects.toThrow( + `Threshold of signatures not met; TACo signing failed with errors: ${JSON.stringify(errors)}`, + ); + }); + + it('should handle insufficient matched hashes in Porter response', async () => { + const signingResults = { + '0xnode1': { + messageHash: '0xhash1', + signature: '0xdead', + signerAddress: '0xsnr1', }, - errors: {}, + '0xnode2': { + messageHash: '0xhash2', + signature: '0xbeef', + signerAddress: '0xsnr2', + }, + '0xnode3': { + messageHash: '0xhash3', + signature: '0xcafe', + signerAddress: '0xsnr3', + }, + }; + const errors = {}; + + porterSignUserOpMock.mockResolvedValue({ + signingResults, + errors, }); + + await expect( + signUserOp( + mockProvider, + 'lynx', + cohortId, + chainId, + userOp, + aaVersion, + undefined, + porterUris, + ), + ).rejects.toThrowError(/multiple mismatched hashes/); }); - it('should handle custom signing options', async () => { - const chainId = 1; - const aaVersion = '0.8.0'; - const cohortId = 5; - const porterUris = [fakePorterUri]; - - signUserOpMock.mockResolvedValue({ - messageHash: '0x1234', - aggregatedSignature: '0x90ab0xijkl', - signingResults: { - '0x1234': ['0x5678', '0x90ab'], - '0xabcd': ['0xefgh', '0xijkl'], + it('properly handles threshold of 1 signature from Porter', async () => { + vi.spyOn(SigningCoordinatorAgent, 'getThreshold').mockResolvedValue(1); + + const signingResults = { + '0xnode1': { + messageHash: '0xhash1', + signature: '0xdead', + signerAddress: '0xsnr1', }, - errors: {}, + }; + const errors = { + '0xnode2': 'Failed to sign', + }; + + porterSignUserOpMock.mockResolvedValue({ + signingResults, + errors, }); - await signUserOp( + const result = await signUserOp( mockProvider, 'lynx', cohortId, @@ -139,33 +278,63 @@ describe('TACo Signing', () => { porterUris, ); - const pythonUserOp2 = convertUserOperationToPython(userOp); + expect(result).toEqual({ + messageHash: '0xhash1', + aggregatedSignature: '0xdead', + signingResults, + errors, + }); + }); - expect(signUserOpMock).toHaveBeenCalledWith( - { - '0x5678': btoa( - JSON.stringify({ - user_op: JSON.stringify(pythonUserOp2), - aa_version: aaVersion, - cohort_id: cohortId, - chain_id: chainId, - context: {}, - signature_type: 'userop', - }), - ), - '0xefgh': btoa( - JSON.stringify({ - user_op: JSON.stringify(pythonUserOp2), - aa_version: aaVersion, - cohort_id: cohortId, - chain_id: chainId, - context: {}, - signature_type: 'userop', - }), - ), + it('ignore errors/mismatched hashes if threshold of matching hashes and signatures from Porter', async () => { + const signingResults = { + '0xnode1': { + messageHash: '0xhash1', + signature: '0xdead', + signerAddress: '0xsnr1', }, - 2, + '0xnode2': { + messageHash: '0xhash2', + signature: '0xcafe', + signerAddress: '0xsnr2', + }, + '0xnode3': { + messageHash: '0xhash3', + signature: '0xbabe', + signerAddress: '0xsnr3', + }, + '0xnode4': { + messageHash: '0xhash1', + signature: '0xbeef', + signerAddress: '0xsnr4', + }, + }; + const errors = { + '0x7890': 'Failed to sign', + }; + + porterSignUserOpMock.mockResolvedValue({ + signingResults, + errors, + }); + + const result = await signUserOp( + mockProvider, + 'lynx', + cohortId, + chainId, + userOp, + aaVersion, + undefined, + porterUris, ); + + expect(result).toEqual({ + messageHash: '0xhash1', + aggregatedSignature: '0xdeadbeef', + signingResults, + errors, + }); }); }); }); From 73de738a4c38b540a233d0a03c6f1c929c463b99 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 4 Jul 2025 13:03:35 -0400 Subject: [PATCH 136/303] Include authorizationType in various JSON API/RPC conditions in condition lingo test. Re-organize layout of complex condition. --- .../integration-test/condition-lingo.test.ts | 63 ++++++++++++------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/packages/taco/integration-test/condition-lingo.test.ts b/packages/taco/integration-test/condition-lingo.test.ts index 4f2824d52..e8c337fea 100644 --- a/packages/taco/integration-test/condition-lingo.test.ts +++ b/packages/taco/integration-test/condition-lingo.test.ts @@ -53,30 +53,51 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( 'TACo Condition Lingos Integration Test', () => { test('validate condition lingo with lynx node to confirm consistency', async () => { + // Note: there are limits to conditions + // - max 5 operands in a multi-condition (compound, sequential) + // - max 2 nested levels of multi-conditions (compound, sequential, if-then-else) const overallCondition = new SequentialCondition({ conditionVariables: [ { - varName: 'rpc', - condition: testRpcConditionObj, - }, - { - varName: 'time', - condition: testTimeConditionObj, - }, - { - varName: 'contract', - condition: testContractConditionObj, + varName: 'compound-1', + condition: { + conditionType: CompoundConditionType, + operator: 'and', + operands: [ + testRpcConditionObj, + testTimeConditionObj, + testContractConditionObj, + testJsonApiConditionObj, + testJsonRpcConditionObj, + ], + }, }, { - varName: 'compound', + varName: 'compound-2', condition: { conditionType: CompoundConditionType, operator: 'or', operands: [ - testJsonApiConditionObj, - testJsonRpcConditionObj, - testSigningObjectAbiAttributeConditionObj, - testSigningObjectAttributeConditionObj, + { + ...testJsonApiConditionObj, + authorizationToken: ':authToken', + }, + { + ...testJsonApiConditionObj, + authorizationToken: ':authToken', + authorizationType: 'Bearer', + }, + { + ...testJsonApiConditionObj, + authorizationToken: ':authToken', + authorizationType: 'X-API-Key', + }, + { + ...testJsonRpcConditionObj, + authorizationToken: ':otherAuthToken', + authorizationType: 'Basic', + }, + testJWTConditionObj, ], }, }, @@ -84,15 +105,9 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( varName: 'ifThenElse', condition: { conditionType: IfThenElseConditionType, - ifCondition: testJWTConditionObj, - thenCondition: { - ...testJsonApiConditionObj, - authorizationToken: ':authToken', - }, - elseCondition: { - ...testJsonRpcConditionObj, - authorizationToken: ':otherAuthToken', - }, + ifCondition: testSigningObjectAttributeConditionObj, + thenCondition: testSigningObjectAbiAttributeConditionObj, + elseCondition: false, }, }, ], From dd42baa307a332e69c439be3e9927029850be3e1 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 30 Jul 2025 12:23:19 +0200 Subject: [PATCH 137/303] Add .claude/ directory to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 68b9883f8..6e8e08641 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ docs-json .next packages/docs docs +.claude/ From 82c31940749ab0439b1c73027a8ec953475da902 Mon Sep 17 00:00:00 2001 From: KPrasch Date: Tue, 29 Jul 2025 18:45:55 +0200 Subject: [PATCH 138/303] Update packages/taco/integration-test/encrypt-decrypt.test.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- packages/taco/integration-test/encrypt-decrypt.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index 6efef6a6e..bc37acb2f 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -258,9 +258,9 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); // Add invalid signature - const invalidSignature = '0x' + randomBytes(64).toString('hex'); + const invalidSignature = randomBytes(64).toString('hex'); conditionContext.addCustomContextParameterValues({ - ':signature': invalidSignature.slice(2), + ':signature': invalidSignature, }); await expect( From f2c3d7cede9ce3566f83f53e8e2d56cdbaea82e4 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 8 Jul 2025 08:06:57 -0400 Subject: [PATCH 139/303] Improve logic for determining errors vs mismatched hashes. Mismatched hashes is a real edge case, but we handle it nonetheless. --- packages/taco/src/sign.ts | 17 +++++++---------- packages/taco/test/taco-sign.test.ts | 11 +++++++++-- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 08f902da4..423b849ef 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -69,7 +69,6 @@ export async function signUserOp( domain, cohortId, ); - console.log({ signers }); const threshold = await SigningCoordinatorAgent.getThreshold( provider, @@ -130,18 +129,16 @@ export async function signUserOp( // Insufficient signatures for a message hash to meet the threshold if (!messageHash || !signaturesToAggregate) { - // TODO: think more about this logic if ( - porterSignResult.errors && - Object.keys(porterSignResult.errors).length > signers.length - threshold + hashToSignatures.size > 1 && + Object.keys(porterSignResult.errors || {}).length < + signers.length - threshold ) { - // too many errors to achieve threshold - throw new Error(ERR_INSUFFICIENT_SIGNATURES(porterSignResult.errors)); - } else if (hashToSignatures.size > 1) { - // If we have multiple hashes, it means we have mismatched hashes from different nodes - // we don't really expect this to happen (other than some malicious nodes) + // Two things are true: + // 1. we have multiple hashes, which means we have mismatched hashes from different nodes + // we don't really expect this to happen (other than some malicious nodes) + // 2. number of errors still could have allowed for a threshold of signatures throw new Error(ERR_MISMATCHED_HASHES(hashToSignatures)); - // since there weren't too many errors, the issue is likely hashes } else { throw new Error( ERR_INSUFFICIENT_SIGNATURES(porterSignResult.errors || {}), diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index d34078f20..d08d515ec 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -21,8 +21,8 @@ describe('TACo Signing', () => { porterSignUserOpMock, ); vi.spyOn(SigningCoordinatorAgent, 'getParticipants').mockResolvedValue([ - { operator: '0xsnr1', provider: '0xnode1', signature: '0xdead' }, - { operator: '0xsnr2', provider: '0xnode2', signature: '0xbeef' }, + { operator: '0xsnr1', provider: '0xnode1', signature: '0xa' }, + { operator: '0xsnr2', provider: '0xnode2', signature: '0xb' }, ]); vi.spyOn(SigningCoordinatorAgent, 'getThreshold').mockResolvedValue(2); }); @@ -210,6 +210,13 @@ describe('TACo Signing', () => { }); it('should handle insufficient matched hashes in Porter response', async () => { + // set up 3 signers - it matters based on how mismatched hashes are handled + vi.spyOn(SigningCoordinatorAgent, 'getParticipants').mockResolvedValue([ + { operator: '0xsnr1', provider: '0xnode1', signature: '0xa' }, + { operator: '0xsnr2', provider: '0xnode2', signature: '0xb' }, + { operator: '0xsnr3', provider: '0xnode3', signature: '0xc' }, + ]); + const signingResults = { '0xnode1': { messageHash: '0xhash1', From 09581e17bb42b199d112ec380dbfa063efd83086 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 4 Jul 2025 13:12:50 -0400 Subject: [PATCH 140/303] Add description for authorizationType schema and updated generated condition schemas. --- packages/taco/schema-docs/condition-schemas.md | 16 ++++++++++++++-- packages/taco/src/conditions/schemas/common.ts | 8 +++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index c0bf37680..d8c12c73f 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -37,6 +37,16 @@ _(\*) Required._ _String which is a valid URL._ +## JsonAuthorizationType + +The type of authorization to use when making the request. + +_Enum string, one of the following possible values:_ + +- `'Bearer'` +- `'Basic'` +- `'X-API-Key'` + ## JsonPath A string containing either a valid JSON Path Expression, or a Context Parameter. @@ -150,6 +160,7 @@ _Object containing the following properties:_ | `parameters` | _Object with dynamic keys of type_ `string` _and values of type_ `unknown` (_optional & nullable_) | | | `query` | [JsonPath](#jsonpath) | | | `authorizationToken` | [ContextParam](#contextparam) | | +| `authorizationType` | [JsonAuthorizationType](#jsonauthorizationtype) | | | **`returnValueTest`** (\*) | [ReturnValueTest](#returnvaluetest) | | _(\*) Required._ @@ -166,6 +177,7 @@ _Object containing the following properties:_ | `params` | `Array` _or_ _Object with dynamic keys of type_ `string` _and values of type_ `unknown` (_optional & nullable_) | | | `query` | [JsonPath](#jsonpath) | | | `authorizationToken` | [ContextParam](#contextparam) | | +| `authorizationType` | [JsonAuthorizationType](#jsonauthorizationtype) | | | **`returnValueTest`** (\*) | [ReturnValueTest](#returnvaluetest) | | _(\*) Required._ @@ -276,7 +288,7 @@ _Object containing the following properties:_ | Property | Description | Type | Default | | :------------------------ | :---------------------------------------------------------------------------- | :-------------------------------------- | :-------------------------- | -| `conditionType` | | `'abi-attribute'` | `'abi-attribute'` | +| `conditionType` | | `'signing-abi-attribute'` | `'signing-abi-attribute'` | | `signingObjectContextVar` | The context variable that will be replaced with the signing object at signing | `':signingConditionObject'` | `':signingConditionObject'` | | **`attributeName`** (\*) | The name of the attribute to check | `string` (_min length: 1_) | | | **`abiValidation`** (\*) | A map of allowed ABI calls with their respective parameter validations. | [AbiCallValidation](#abicallvalidation) | | @@ -289,7 +301,7 @@ _Object containing the following properties:_ | Property | Description | Type | Default | | :------------------------- | :---------------------------------------------------------------------------- | :------------------------------------------------------ | :-------------------------- | -| `conditionType` | | `'attribute'` | `'attribute'` | +| `conditionType` | | `'signing-attribute'` | `'signing-attribute'` | | `signingObjectContextVar` | The context variable that will be replaced with the signing object at signing | `':signingConditionObject'` | `':signingConditionObject'` | | **`attributeName`** (\*) | The name of the attribute to check | `string` (_min length: 1_) | | | **`returnValueTest`** (\*) | | [BlockchainReturnValueTest](#blockchainreturnvaluetest) | | diff --git a/packages/taco/src/conditions/schemas/common.ts b/packages/taco/src/conditions/schemas/common.ts index 2f1d24243..355047f7c 100644 --- a/packages/taco/src/conditions/schemas/common.ts +++ b/packages/taco/src/conditions/schemas/common.ts @@ -92,11 +92,9 @@ const validateHttpsURL = (url: string): boolean => { return URL.canParse(url) && url.startsWith('https://'); }; -export const jsonAuthorizationTypeSchema = z.enum([ - 'Bearer', - 'Basic', - 'X-API-Key', -]); +export const jsonAuthorizationTypeSchema = z + .enum(['Bearer', 'Basic', 'X-API-Key']) + .describe('The type of authorization to use when making the request.'); // Use our own URL refinement check due to https://github.com/colinhacks/zod/issues/2236 export const httpsURLSchema = z From 158a3e580a9905733224bcb014593a3c24ef0f6e Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 30 Jul 2025 12:24:36 +0200 Subject: [PATCH 141/303] Refactor setSigningCohortConditions parameter order Move provider and domain parameters first for consistency with other agent methods. Change conditions parameter type from ConditionExpression to Condition for improved API ergonomics. --- packages/taco/src/sign.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 419fb695a..1e748df30 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -14,6 +14,7 @@ import { } from '@nucypher/shared'; import { ethers } from 'ethers'; +import { Condition } from './conditions/condition'; import { ConditionExpression } from './conditions/condition-expr'; import { ConditionContext } from './conditions/context'; @@ -176,15 +177,16 @@ export async function signUserOp( } export async function setSigningCohortConditions( - conditions: ConditionExpression, provider: ethers.providers.JsonRpcProvider, domain: Domain, + conditions: Condition, cohortId: number, chainId: number, signer: ethers.Signer, ): Promise { - // Convert ConditionContext to CoreConditions JSON - const conditionsJson = conditions.toJson(); + // Convert Condition to ConditionExpression, then to JSON + const conditionExpression = new ConditionExpression(conditions); + const conditionsJson = conditionExpression.toJson(); // Set conditions on the SigningCoordinator contract return await SigningCoordinatorAgent.setSigningCohortConditions( From c4e9b794208eec434fa147ee61e0a04940eb18d5 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 29 Jul 2025 18:22:10 -0400 Subject: [PATCH 142/303] Remove use of TestECDSACondition in favour of just ECDSACondition. Some cleanup of object types used for ecdsa integration tests. --- .../integration-test/encrypt-decrypt.test.ts | 17 +++++----- packages/taco/test/test-utils.ts | 31 +++++-------------- 2 files changed, 17 insertions(+), 31 deletions(-) diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index bc37acb2f..522869ade 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -14,6 +14,7 @@ import { initialize, ThresholdMessageKit, } from '../src'; +import { ECDSACondition } from '../src/conditions/base/ecdsa'; import { CompoundCondition } from '../src/conditions/compound-condition'; import { createSignatureForPredefinedCondition, @@ -183,9 +184,10 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const authorizationMessage = 'I authorize access to this encrypted data'; // Create a predefined ECDSA condition (simulates server-side condition creation) - const { condition: ecdsaCondition, privateKey } = + const { conditionProps, privateKey } = createTestECDSACondition(authorizationMessage); + const ecdsaCondition = new ECDSACondition(conditionProps); expect(ecdsaCondition.requiresAuthentication()).toBe(false); const messageKit = await encrypt( @@ -210,8 +212,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( // Create signature using the predefined condition's private key const signatureHex = createSignatureForPredefinedCondition( { - condition: ecdsaCondition.value, - verifyingKey: ecdsaCondition.value.verifyingKey, + conditionProps, privateKey, }, authorizationMessage, @@ -239,9 +240,9 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const authorizationMessage = 'I authorize access to this encrypted data'; // Create a predefined ECDSA condition (simulates server-side condition creation) - const { condition: ecdsaCondition } = - createTestECDSACondition(authorizationMessage); + const { conditionProps } = createTestECDSACondition(authorizationMessage); + const ecdsaCondition = new ECDSACondition(conditionProps); const messageKit = await encrypt( provider, DOMAIN, @@ -274,11 +275,12 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const message = toBytes(messageString); // Create a predefined ECDSA condition that uses :message context parameter - const { condition: ecdsaCondition, privateKey } = + const { conditionProps, privateKey } = createTestECDSACondition(':message'); // ECDSA conditions with :message and :signature don't require auth providers // like :userAddress does, they just need context parameters to be provided + const ecdsaCondition = new ECDSACondition(conditionProps); expect(ecdsaCondition.requiresAuthentication()).toBe(false); const messageKit = await encrypt( @@ -309,8 +311,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( // Sign the message with the predefined condition's private key const signatureHex = createSignatureForPredefinedCondition( { - condition: ecdsaCondition.value, - verifyingKey: ecdsaCondition.value.verifyingKey, + conditionProps, privateKey, }, messageToSign, diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 674ef021f..b3e62d3e3 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -51,7 +51,6 @@ import { ECDSA_MESSAGE_PARAM_DEFAULT, ECDSA_SIGNATURE_PARAM_DEFAULT, ECDSAConditionProps, - ecdsaConditionSchema, ECDSAConditionType, ECDSACurve, } from '../src/conditions/base/ecdsa'; @@ -84,7 +83,6 @@ import { CompoundConditionProps, CompoundConditionType, } from '../src/conditions/compound-condition'; -import { Condition } from '../src/conditions/condition'; import { ConditionExpression } from '../src/conditions/condition-expr'; import { ERC721Balance } from '../src/conditions/predefined/erc721'; import { @@ -102,34 +100,23 @@ import { import { DkgClient, DkgRitual } from '../src/dkg'; import { encryptMessage } from '../src/tdec'; -// Test ECDSA condition that uses the main schema (verifyingKey is now included) -const testECDSAConditionSchema = ecdsaConditionSchema; - -export class TestECDSACondition extends Condition { - constructor(value: Omit) { - super(testECDSAConditionSchema, { - conditionType: ECDSAConditionType, - ...value, - }); - } -} - export function createTestECDSACondition( message: string, curve: ECDSACurve = 'SECP256k1', -): { condition: TestECDSACondition; privateKey: string } { +): { conditionProps: ECDSAConditionProps; privateKey: string } { // Simulate server-side key generation for the predefined condition const testWallet = ethers.Wallet.createRandom(); - const condition = new TestECDSACondition({ + const conditionProps: ECDSAConditionProps = { + conditionType: ECDSAConditionType, message: message, signature: ECDSA_SIGNATURE_PARAM_DEFAULT, verifyingKey: testWallet.publicKey.slice(2), // Remove '0x' prefix curve: curve, - }); + }; return { - condition, + conditionProps, privateKey: testWallet.privateKey, // For test signature generation }; } @@ -352,8 +339,7 @@ export const testECDSAConditionObj: ECDSAConditionProps = { // Test utility for creating predefined ECDSA conditions (simulates server-side creation) // In production, these would be created by servers/admins and stored with their verifying keys export interface PredefinedECDSACondition { - condition: ECDSAConditionProps; - verifyingKey: string; + conditionProps: ECDSAConditionProps; privateKey: string; // For test signature generation only } @@ -366,14 +352,13 @@ export function createPredefinedECDSACondition( const verifyingKey = testWallet.publicKey.slice(2); // Remove '0x' prefix return { - condition: { + conditionProps: { conditionType: ECDSAConditionType, message: message, signature: ECDSA_SIGNATURE_PARAM_DEFAULT, - verifyingKey: verifyingKey, // Include verifyingKey in the condition + verifyingKey: verifyingKey, curve: curve, }, - verifyingKey: verifyingKey, privateKey: testWallet.privateKey, // For test purposes only }; } From 71c4ab350c5f3b3efe9f53a885bdd30a89f70c87 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 8 Jul 2025 08:14:21 -0400 Subject: [PATCH 143/303] No need to check whether signingResults or errors are defined or not. Add console error message for mismatched hashes. Code cleanup. --- packages/taco/src/sign.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 423b849ef..72936457c 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -37,7 +37,7 @@ export type SignResult = { function aggregateSignatures(signaturesByAddress: { [checksumAddress: string]: TacoSignature; }): string { - // Aggregate hex signatures by concatenating them; being carefule to remove the '0x' prefix from each signature except the first one. + // Aggregate hex signatures by concatenating them; being careful to remove the '0x' prefix from each signature except the first one. const signatures = Object.values(signaturesByAddress).map( (sig) => sig.signature, ); @@ -107,7 +107,7 @@ export async function signUserOp( // Single pass: decode signatures and populate signingResults for (const [ursulaAddress, signature] of Object.entries( - porterSignResult.signingResults || {}, + porterSignResult.signingResults, )) { // For non-optimistic: track hashes and group signatures for aggregation const hash = signature.messageHash; @@ -131,18 +131,19 @@ export async function signUserOp( if (!messageHash || !signaturesToAggregate) { if ( hashToSignatures.size > 1 && - Object.keys(porterSignResult.errors || {}).length < - signers.length - threshold + Object.keys(porterSignResult.errors).length < signers.length - threshold ) { // Two things are true: // 1. we have multiple hashes, which means we have mismatched hashes from different nodes // we don't really expect this to happen (other than some malicious nodes) // 2. number of errors still could have allowed for a threshold of signatures + console.error( + 'Porter returned mismatched message hashes:', + hashToSignatures, + ); throw new Error(ERR_MISMATCHED_HASHES(hashToSignatures)); } else { - throw new Error( - ERR_INSUFFICIENT_SIGNATURES(porterSignResult.errors || {}), - ); + throw new Error(ERR_INSUFFICIENT_SIGNATURES(porterSignResult.errors)); } } @@ -151,7 +152,7 @@ export async function signUserOp( return { messageHash, aggregatedSignature, - signingResults: porterSignResult.signingResults || {}, - errors: porterSignResult.errors || {}, + signingResults: porterSignResult.signingResults, + errors: porterSignResult.errors, }; } From c6bf160c99887e26f4fb91c5b0d97eeaaf24b904 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 4 Jul 2025 14:05:58 -0400 Subject: [PATCH 144/303] URL(...) is more widely supported than URL.canParse() while providing the same functionality. See MSDN docs. --- packages/taco/src/conditions/schemas/common.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/taco/src/conditions/schemas/common.ts b/packages/taco/src/conditions/schemas/common.ts index 355047f7c..b59038878 100644 --- a/packages/taco/src/conditions/schemas/common.ts +++ b/packages/taco/src/conditions/schemas/common.ts @@ -89,7 +89,14 @@ export const jsonPathSchema = z ); const validateHttpsURL = (url: string): boolean => { - return URL.canParse(url) && url.startsWith('https://'); + try { + const parsedUrl = new URL(url); + // Check if the URL is valid and uses HTTPS + return parsedUrl.protocol === 'https:'; + } catch (e) { + // If URL constructor throws, the URL is invalid + return false; + } }; export const jsonAuthorizationTypeSchema = z From 223086c529609fe0ac54a6f7defacc73de299dc7 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 30 Jul 2025 12:26:00 +0200 Subject: [PATCH 145/303] Update unit tests for new setSigningCohortConditions signature Update test calls to match new parameter order and use Condition objects instead of ConditionExpression. --- packages/taco/test/taco-sign.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index c57cf7995..07e32ab97 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -384,9 +384,9 @@ describe('TACo Signing', () => { setSigningCohortConditionsSpy.mockResolvedValue(mockTransaction); const result = await setSigningCohortConditions( - conditionExpression, mockProvider, domain, + rpcCondition, cohortId, chainId, mockSigner, @@ -439,9 +439,9 @@ describe('TACo Signing', () => { setSigningCohortConditionsSpy.mockResolvedValue(mockTransaction); const result = await setSigningCohortConditions( - conditionExpression, mockProvider, domain, + compoundCondition, cohortId, chainId, mockSigner, @@ -481,9 +481,9 @@ describe('TACo Signing', () => { await expect( setSigningCohortConditions( - conditionExpression, mockProvider, domain, + rpcCondition, cohortId, chainId, mockSigner, From 58806dd41838ce6636646001957a91ed5670db61 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 29 Jul 2025 18:37:57 -0400 Subject: [PATCH 146/303] Add additional refinement on message if provided as 0x-prefixed hex string to ensure that it is indeed valid hex. --- packages/taco/src/conditions/schemas/ecdsa.ts | 35 +++++++++++++------ .../taco/test/conditions/base/ecdsa.test.ts | 32 +++++++++++++++++ 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/packages/taco/src/conditions/schemas/ecdsa.ts b/packages/taco/src/conditions/schemas/ecdsa.ts index a7d035864..a452b1a7f 100644 --- a/packages/taco/src/conditions/schemas/ecdsa.ts +++ b/packages/taco/src/conditions/schemas/ecdsa.ts @@ -19,16 +19,29 @@ export const SUPPORTED_ECDSA_CURVES = [ export type ECDSACurve = (typeof SUPPORTED_ECDSA_CURVES)[number]; -export const ecdsaConditionSchema = baseConditionSchema.extend({ - conditionType: z.literal(ECDSAConditionType).default(ECDSAConditionType), - message: z - .union([z.string(), contextParamSchema]) - .default(ECDSA_MESSAGE_PARAM_DEFAULT), - signature: z - .union([hexStringSchema, contextParamSchema]) - .default(ECDSA_SIGNATURE_PARAM_DEFAULT), - verifyingKey: hexStringSchema, - curve: z.enum(SUPPORTED_ECDSA_CURVES), -}); +export const ecdsaConditionSchema = baseConditionSchema + .extend({ + conditionType: z.literal(ECDSAConditionType).default(ECDSAConditionType), + message: z + .union([z.string(), contextParamSchema]) + .default(ECDSA_MESSAGE_PARAM_DEFAULT), + signature: z + .union([hexStringSchema, contextParamSchema]) + .default(ECDSA_SIGNATURE_PARAM_DEFAULT), + verifyingKey: hexStringSchema, + curve: z.enum(SUPPORTED_ECDSA_CURVES), + }) + .refine( + (data) => { + // ensure that if message starts with 0x that it is valid hex + if (data.message.startsWith('0x')) + return hexStringSchema.safeParse(data.message.slice(2)).success; + return true; + }, + { + message: 'Message must be a valid hex string if it starts with "0x"', + path: ['message'], + }, + ); export type ECDSAConditionProps = z.infer; diff --git a/packages/taco/test/conditions/base/ecdsa.test.ts b/packages/taco/test/conditions/base/ecdsa.test.ts index ea872a3c4..0a27f7942 100644 --- a/packages/taco/test/conditions/base/ecdsa.test.ts +++ b/packages/taco/test/conditions/base/ecdsa.test.ts @@ -37,6 +37,38 @@ describe('ECDSACondition', () => { }); }); + it('rejects 0x-prefixed hex message that is not valid hex', () => { + const badECDSAObj = { + ...testECDSAConditionObj, + message: '0x123g', // Invalid hex + }; + const result = ECDSACondition.validate(ecdsaConditionSchema, badECDSAObj); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + message: { + _errors: [ + 'Message must be a valid hex string if it starts with "0x"', + ], + }, + }); + }); + + it('accepts valid hex message', () => { + const validECDSAObj = { + ...testECDSAConditionObj, + message: '0xabcdef1234567890', + }; + + const result = ECDSACondition.validate( + ecdsaConditionSchema, + validECDSAObj, + ); + + expect(result.error).toBeUndefined(); + expect(result.data).toEqual(validECDSAObj); + }); + it('rejects invalid signature that is not a hex string', () => { const badECDSAObj = { ...testECDSAConditionObj, From b8bf25fc7b6fae0325abbf0d347e16300bfe9120 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 9 Jul 2025 11:04:01 -0400 Subject: [PATCH 147/303] Remove errors from SignResult since if there aren't sufficient signatures, and error is thrown. Aggregated signatures only uses the threshold of signatures provided to it. Add signUserOp method documentation. --- packages/shared/src/schemas.ts | 8 +++---- packages/taco/src/sign.ts | 35 +++++++++++++++++++++------- packages/taco/test/taco-sign.test.ts | 3 --- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/packages/shared/src/schemas.ts b/packages/shared/src/schemas.ts index a2e0dd07c..ea3bfc200 100644 --- a/packages/shared/src/schemas.ts +++ b/packages/shared/src/schemas.ts @@ -23,11 +23,9 @@ export const EthAddressSchema = z .string() .refine(isAddress, { message: 'Invalid Ethereum address' }); -export const EthAddressSchemaStrict = z - .string() - .refine(isAddressStrict, { - message: 'Invalid Ethereum address - it must be valid and checksummed', - }); +export const EthAddressSchemaStrict = z.string().refine(isAddressStrict, { + message: 'Invalid Ethereum address - it must be valid and checksummed', +}); const BLOCK_HASH_REGEXP = new RegExp('^0x[a-fA-F0-9]{64}$'); const BlockNumber = z.number().int().nonnegative(); diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 72936457c..f16605ad0 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -31,16 +31,18 @@ export type SignResult = { messageHash: string; aggregatedSignature: string; signingResults: { [ursulaAddress: string]: TacoSignature }; - errors: Record; }; -function aggregateSignatures(signaturesByAddress: { - [checksumAddress: string]: TacoSignature; -}): string { +function aggregateSignatures( + signaturesByAddress: { + [checksumAddress: string]: TacoSignature; + }, + threshold: number, +): string { // Aggregate hex signatures by concatenating them; being careful to remove the '0x' prefix from each signature except the first one. - const signatures = Object.values(signaturesByAddress).map( - (sig) => sig.signature, - ); + const signatures = Object.values(signaturesByAddress) + .map((sig) => sig.signature) + .slice(0, threshold); if (signatures.length === 1) { return signatures[0]; } @@ -49,6 +51,19 @@ function aggregateSignatures(signaturesByAddress: { return `0x${toHexString(new Uint8Array(allBytes))}`; } +/** + * Signs a UserOperation. + * @param provider - The Ethereum provider to use for signing. + * @param domain - The TACo domain being used. + * @param cohortId - The cohort ID that identifies the signing cohort. + * @param chainId - The chain ID for the signing operation. + * @param userOp - The UserOperation to be signed. + * @param aaVersion - The AA version of the account abstraction to use for signing. + * @param context - Optional condition context for the context variable resolution. + * @param porterUris - Optional URIs for the Porter service. If not provided, will fetch the default URIs from the domain. + * @returns A promise that resolves to a SignResult containing the message hash, aggregated signature, and signing results from the Porter service. + * @throws An error if the signing process fails due to insufficient signatures or mismatched hashes. + */ export async function signUserOp( provider: ethers.providers.Provider, domain: Domain, @@ -147,12 +162,14 @@ export async function signUserOp( } } - const aggregatedSignature = aggregateSignatures(signaturesToAggregate); + const aggregatedSignature = aggregateSignatures( + signaturesToAggregate, + threshold, + ); return { messageHash, aggregatedSignature, signingResults: porterSignResult.signingResults, - errors: porterSignResult.errors, }; } diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index d08d515ec..a2de1f11c 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -116,7 +116,6 @@ describe('TACo Signing', () => { messageHash: '0xhash1', aggregatedSignature: '0xdeadbeef', signingResults, - errors, }); }, ); @@ -289,7 +288,6 @@ describe('TACo Signing', () => { messageHash: '0xhash1', aggregatedSignature: '0xdead', signingResults, - errors, }); }); @@ -340,7 +338,6 @@ describe('TACo Signing', () => { messageHash: '0xhash1', aggregatedSignature: '0xdeadbeef', signingResults, - errors, }); }); }); From 367d743e8e6127204f1ca3faf820991e1001487d Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 30 Jul 2025 12:26:14 +0200 Subject: [PATCH 148/303] Improve integration test reliability and clarity - Remove debug console.log statements - Reduce test timeouts to more reasonable values (15s, 6s) - Simplify condition serialization test logic by removing unnecessary error handling - Add proper assertions for condition validation --- packages/taco/integration-test/sign.test.ts | 54 ++++++--------------- 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index 59da4aa5e..229679a38 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -83,7 +83,6 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( signingContext, porterUris, ); - console.log('Sign result:', signResult); const threshold = await SigningCoordinatorAgent.getThreshold( provider, @@ -100,7 +99,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( ); expect(signResult.signingResults).toBeDefined(); expect(Object.keys(signResult.signingResults).length).toBeGreaterThan(0); - }, 150000); + }, 15000); test('should validate condition serialization round-trip with existing cohort conditions', async () => { // This integration test validates condition serialization/deserialization without writing to blockchain: @@ -109,54 +108,37 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( // 3. Convert the object back to bytes (what would be written to chain) // 4. Verify the bytes match exactly - // Try to read conditions from the existing ritual/cohort - let retrievedConditionHex: string; - try { - retrievedConditionHex = await SigningCoordinatorAgent.getSigningCohortConditions( - provider, - DOMAIN as Domain, - COHORT_ID, - CHAIN_ID, - ); - } catch (error: unknown) { - const errorMessage = error instanceof Error ? error.message : String(error); - if (errorMessage.includes('cohort does not exist') || - errorMessage.includes('invalid cohort') || - errorMessage.includes('conditions not set')) { - console.log(`Skipping test - no conditions found for cohort ${COHORT_ID}. This test requires an existing cohort with conditions set.`); - return; - } - throw error; - } - - // If the hex is empty or just '0x', skip the test - if (!retrievedConditionHex || retrievedConditionHex === '0x' || retrievedConditionHex.length <= 2) { - console.log(`Skipping test - cohort ${COHORT_ID} has no conditions set.`); - return; - } + // Read conditions from the existing ritual/cohort + const retrievedConditionHex = await SigningCoordinatorAgent.getSigningCohortConditions( + provider, + DOMAIN as Domain, + COHORT_ID, + CHAIN_ID, + ); - console.log('Retrieved condition hex from chain:', retrievedConditionHex); + // Verify that conditions are set for this cohort/chain combination + expect(retrievedConditionHex).toBeDefined(); + expect(retrievedConditionHex).not.toBe('0x'); + expect(retrievedConditionHex.length).toBeGreaterThan(2); // Convert hex back to JSON string (simulating what the chain stores) const chainConditionJson = ethers.utils.toUtf8String(retrievedConditionHex); - console.log('Chain condition JSON:', chainConditionJson); // Parse the JSON and recreate the ConditionExpression from the chain data // This simulates reading conditions from chain and converting to our object model const coreConditions = new CoreConditions(chainConditionJson); const retrievedConditions = ConditionExpression.fromCoreConditions(coreConditions); - // Also verify we can create a ConditionContext from it (this validates the data is readable) - const retrievedContext = await context.ConditionContext.forSigningCohort( + // Verify we can create a ConditionContext from it (this validates the data is readable) + await expect(context.ConditionContext.forSigningCohort( provider, DOMAIN as Domain, COHORT_ID, CHAIN_ID, - ); + )).resolves.not.toThrow(); // Convert back to JSON (this is what would be written to chain) const roundTripJson = retrievedConditions.toJson(); - console.log('Round-trip JSON:', roundTripJson); // The core verification: ensure serialization round-trip is identical // This proves that read → object → write produces identical bytes @@ -165,11 +147,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( // Additional verification: ensure the objects have expected properties expect(retrievedConditions.condition).toBeDefined(); - // Verify that the semantic content is identical (JSON property order may differ) - expect(JSON.parse(roundTripJson)).toEqual(JSON.parse(chainConditionJson)); - - console.log('Condition serialization round-trip validation completed successfully!'); - }, 60000); // Shorter timeout since no blockchain writes + }, 6000); // Shorter timeout since no blockchain writes }, ); \ No newline at end of file From c3ca5e2fd024ce30a9873a5ac86b4984607b0fd7 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 29 Jul 2025 18:59:40 -0400 Subject: [PATCH 149/303] Add description for ecdsa condition schema and generate condition-schema docs for the ecdsa condition. --- .../taco/schema-docs/condition-schemas.md | 23 +++++++++++++++++++ packages/taco/src/conditions/schemas/ecdsa.ts | 3 +++ 2 files changed, 26 insertions(+) diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index d8c12c73f..6befb0c06 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -8,6 +8,7 @@ _Union of the following possible types:_ - [TimeCondition](#timecondition) - [AddressAllowlistCondition](#addressallowlistcondition) - [ContractCondition](#contractcondition) +- [EcdsaCondition](#ecdsacondition) - [JsonApiCondition](#jsonapicondition) - [JsonRpcCondition](#jsonrpccondition) - [JwtCondition](#jwtcondition) @@ -33,6 +34,12 @@ _Object containing the following properties:_ _(\*) Required._ +## HexString + +A string containing only hexadecimal characters (0-9, a-f, A-F) + +_String which matches the regular expression `/^[0-9a-fA-F]+$/`._ + ## HttpsURL _String which is a valid URL._ @@ -136,6 +143,22 @@ _Object containing the following properties:_ _(\*) Required._ +## EcdsaCondition + +ECDSA Condition for verifying the authenticity of a message using ECDSA signatures. + +_Object containing the following properties:_ + +| Property | Type | Default | +| :---------------------- | :---------------------------------------------------------------------------------------- | :------------- | +| `conditionType` | `'ecdsa'` | `'ecdsa'` | +| `message` | `string` _or_ [ContextParam](#contextparam) | `':message'` | +| `signature` | [HexString](#hexstring) _or_ [ContextParam](#contextparam) | `':signature'` | +| **`verifyingKey`** (\*) | [HexString](#hexstring) | | +| **`curve`** (\*) | `'SECP256k1' \| 'NIST256p' \| 'NIST384p' \| 'NIST521p' \| 'Ed25519' \| 'BRAINPOOLP256r1'` | | + +_(\*) Required._ + ## IfThenElseCondition _Object containing the following properties:_ diff --git a/packages/taco/src/conditions/schemas/ecdsa.ts b/packages/taco/src/conditions/schemas/ecdsa.ts index a452b1a7f..3b77911bb 100644 --- a/packages/taco/src/conditions/schemas/ecdsa.ts +++ b/packages/taco/src/conditions/schemas/ecdsa.ts @@ -42,6 +42,9 @@ export const ecdsaConditionSchema = baseConditionSchema message: 'Message must be a valid hex string if it starts with "0x"', path: ['message'], }, + ) + .describe( + 'ECDSA Condition for verifying the authenticity of a message using ECDSA signatures.', ); export type ECDSAConditionProps = z.infer; From 3d97ebee188a7ba25dd73813e8a5875ef1a2f716 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 30 Jul 2025 12:53:08 +0200 Subject: [PATCH 150/303] Change SigningCoordinatorAgent conditions parameter to Uint8Array Keep agent interface closer to contract by accepting Uint8Array instead of string. Remove internal UTF-8 conversion to let caller handle the conversion. --- packages/shared/src/contracts/agents/signing-coordinator.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/shared/src/contracts/agents/signing-coordinator.ts b/packages/shared/src/contracts/agents/signing-coordinator.ts index e4cc059fd..251647576 100644 --- a/packages/shared/src/contracts/agents/signing-coordinator.ts +++ b/packages/shared/src/contracts/agents/signing-coordinator.ts @@ -62,15 +62,14 @@ export class SigningCoordinatorAgent { domain: Domain, cohortId: number, chainId: number, - conditions: string, + conditions: Uint8Array, signer: ethers.Signer, ): Promise { const coordinator = await this.connect(provider, domain, signer); - const conditionsHex = ethers.utils.toUtf8Bytes(conditions); return await coordinator.setSigningCohortConditions( cohortId, chainId, - conditionsHex, + conditions, ); } From 9a592e71a63ffcd9afdf99287cb375f491e84c8f Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 30 Jul 2025 09:43:18 -0400 Subject: [PATCH 151/303] Disable no-unused-vars rule for ecdsa example file. --- packages/taco/examples/ecdsa-condition.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/taco/examples/ecdsa-condition.ts b/packages/taco/examples/ecdsa-condition.ts index 05330e1dd..18a81c0dc 100644 --- a/packages/taco/examples/ecdsa-condition.ts +++ b/packages/taco/examples/ecdsa-condition.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ + import { ECDSACondition } from '../src/conditions/base/ecdsa'; // Example verifying keys (public keys) - in production these would come from actual key pairs From ddfd405bf68f706ab3a200bf31501fdef79cb404 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 10 Jul 2025 14:11:08 -0400 Subject: [PATCH 152/303] chore(release): release @nucypher/shared:0.6.0-alpha.0 --- packages/shared/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/package.json b/packages/shared/package.json index 56b6dd2c3..2431c7831 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/shared", - "version": "0.5.0", + "version": "0.6.0-alpha.0", "keywords": [ "pre", "taco", From e177aa0902358942f81df439ef2fa4430867e797 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 30 Jul 2025 13:02:26 +0200 Subject: [PATCH 153/303] Change setSigningCohortConditions to accept Uint8Array parameter Move condition-to-bytes conversion responsibility to caller as suggested by @derekpierre. Update function signature to take Uint8Array directly instead of Condition. Update unit tests to handle conversion from Condition to Uint8Array. Co-authored-by: Derek Pierre --- packages/taco/src/sign.ts | 8 ++------ packages/taco/test/taco-sign.test.ts | 15 +++++++++------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 1e748df30..74b91061e 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -179,22 +179,18 @@ export async function signUserOp( export async function setSigningCohortConditions( provider: ethers.providers.JsonRpcProvider, domain: Domain, - conditions: Condition, + conditions: Uint8Array, cohortId: number, chainId: number, signer: ethers.Signer, ): Promise { - // Convert Condition to ConditionExpression, then to JSON - const conditionExpression = new ConditionExpression(conditions); - const conditionsJson = conditionExpression.toJson(); - // Set conditions on the SigningCoordinator contract return await SigningCoordinatorAgent.setSigningCohortConditions( provider, domain, cohortId, chainId, - conditionsJson, + conditions, signer, ); } diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index 07e32ab97..36a14aadf 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -380,13 +380,14 @@ describe('TACo Signing', () => { const conditionExpression = new ConditionExpression(rpcCondition); const expectedJson = conditionExpression.toJson(); + const expectedBytes = ethers.utils.toUtf8Bytes(expectedJson); setSigningCohortConditionsSpy.mockResolvedValue(mockTransaction); const result = await setSigningCohortConditions( mockProvider, domain, - rpcCondition, + expectedBytes, cohortId, chainId, mockSigner, @@ -397,7 +398,7 @@ describe('TACo Signing', () => { domain, cohortId, chainId, - expectedJson, + expectedBytes, mockSigner, ); expect(result).toBe(mockTransaction); @@ -435,13 +436,14 @@ describe('TACo Signing', () => { const compoundCondition = CompoundCondition.and([rpcCondition, contractCondition]); const conditionExpression = new ConditionExpression(compoundCondition); const expectedJson = conditionExpression.toJson(); + const expectedBytes = ethers.utils.toUtf8Bytes(expectedJson); setSigningCohortConditionsSpy.mockResolvedValue(mockTransaction); const result = await setSigningCohortConditions( mockProvider, domain, - compoundCondition, + expectedBytes, cohortId, chainId, mockSigner, @@ -452,7 +454,7 @@ describe('TACo Signing', () => { domain, cohortId, chainId, - expectedJson, + expectedBytes, mockSigner, ); expect(result).toBe(mockTransaction); @@ -476,6 +478,7 @@ describe('TACo Signing', () => { const conditionExpression = new ConditionExpression(rpcCondition); const expectedJson = conditionExpression.toJson(); + const expectedBytes = ethers.utils.toUtf8Bytes(expectedJson); setSigningCohortConditionsSpy.mockRejectedValue(new Error('Cohort not found')); @@ -483,7 +486,7 @@ describe('TACo Signing', () => { setSigningCohortConditions( mockProvider, domain, - rpcCondition, + expectedBytes, cohortId, chainId, mockSigner, @@ -495,7 +498,7 @@ describe('TACo Signing', () => { domain, cohortId, chainId, - expectedJson, + expectedBytes, mockSigner, ); }); From 722a0f442a9db840fbe7005bd0e0742affbeca55 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 30 Jul 2025 10:17:20 -0400 Subject: [PATCH 154/303] Remove duplicated method for creating test ecdsa condition, and update logic to indicate the specificity of using secp256k1 for the test. --- .../integration-test/encrypt-decrypt.test.ts | 27 +++++------- packages/taco/test/test-utils.ts | 44 +++++-------------- 2 files changed, 24 insertions(+), 47 deletions(-) diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index 522869ade..308ec9201 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -14,11 +14,10 @@ import { initialize, ThresholdMessageKit, } from '../src'; -import { ECDSACondition } from '../src/conditions/base/ecdsa'; import { CompoundCondition } from '../src/conditions/compound-condition'; import { - createSignatureForPredefinedCondition, - createTestECDSACondition, + createSignatureForTestSecp256k1ECDSACondition, + createTestSecp256k1ECDSACondition, UINT256_MAX, } from '../test/test-utils'; @@ -184,10 +183,9 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const authorizationMessage = 'I authorize access to this encrypted data'; // Create a predefined ECDSA condition (simulates server-side condition creation) - const { conditionProps, privateKey } = - createTestECDSACondition(authorizationMessage); + const { condition: ecdsaCondition, privateKey } = + createTestSecp256k1ECDSACondition(authorizationMessage); - const ecdsaCondition = new ECDSACondition(conditionProps); expect(ecdsaCondition.requiresAuthentication()).toBe(false); const messageKit = await encrypt( @@ -210,9 +208,9 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( ).toBeTruthy(); // Create signature using the predefined condition's private key - const signatureHex = createSignatureForPredefinedCondition( + const signatureHex = createSignatureForTestSecp256k1ECDSACondition( { - conditionProps, + condition: ecdsaCondition, privateKey, }, authorizationMessage, @@ -240,9 +238,9 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const authorizationMessage = 'I authorize access to this encrypted data'; // Create a predefined ECDSA condition (simulates server-side condition creation) - const { conditionProps } = createTestECDSACondition(authorizationMessage); + const { condition: ecdsaCondition } = + createTestSecp256k1ECDSACondition(authorizationMessage); - const ecdsaCondition = new ECDSACondition(conditionProps); const messageKit = await encrypt( provider, DOMAIN, @@ -275,12 +273,11 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const message = toBytes(messageString); // Create a predefined ECDSA condition that uses :message context parameter - const { conditionProps, privateKey } = - createTestECDSACondition(':message'); + const { condition: ecdsaCondition, privateKey } = + createTestSecp256k1ECDSACondition(':message'); // ECDSA conditions with :message and :signature don't require auth providers // like :userAddress does, they just need context parameters to be provided - const ecdsaCondition = new ECDSACondition(conditionProps); expect(ecdsaCondition.requiresAuthentication()).toBe(false); const messageKit = await encrypt( @@ -309,9 +306,9 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const messageToSign = 'User authentication message'; // Sign the message with the predefined condition's private key - const signatureHex = createSignatureForPredefinedCondition( + const signatureHex = createSignatureForTestSecp256k1ECDSACondition( { - conditionProps, + condition: ecdsaCondition, privateKey, }, messageToSign, diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index b3e62d3e3..ddc457fa3 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -50,9 +50,9 @@ import { import { ECDSA_MESSAGE_PARAM_DEFAULT, ECDSA_SIGNATURE_PARAM_DEFAULT, + ECDSACondition, ECDSAConditionProps, ECDSAConditionType, - ECDSACurve, } from '../src/conditions/base/ecdsa'; import { JsonApiConditionProps, @@ -100,27 +100,6 @@ import { import { DkgClient, DkgRitual } from '../src/dkg'; import { encryptMessage } from '../src/tdec'; -export function createTestECDSACondition( - message: string, - curve: ECDSACurve = 'SECP256k1', -): { conditionProps: ECDSAConditionProps; privateKey: string } { - // Simulate server-side key generation for the predefined condition - const testWallet = ethers.Wallet.createRandom(); - - const conditionProps: ECDSAConditionProps = { - conditionType: ECDSAConditionType, - message: message, - signature: ECDSA_SIGNATURE_PARAM_DEFAULT, - verifyingKey: testWallet.publicKey.slice(2), // Remove '0x' prefix - curve: curve, - }; - - return { - conditionProps, - privateKey: testWallet.privateKey, // For test signature generation - }; -} - export const fakeDkgTDecFlowE2E: ( ritualId?: number, variant?: FerveoVariant, @@ -338,33 +317,34 @@ export const testECDSAConditionObj: ECDSAConditionProps = { // Test utility for creating predefined ECDSA conditions (simulates server-side creation) // In production, these would be created by servers/admins and stored with their verifying keys -export interface PredefinedECDSACondition { - conditionProps: ECDSAConditionProps; +export interface TestSecp256k1ECDSAConditionInfo { + condition: ECDSACondition; privateKey: string; // For test signature generation only } -export function createPredefinedECDSACondition( +export function createTestSecp256k1ECDSACondition( message: string, - curve: ECDSACurve = 'SECP256k1', -): PredefinedECDSACondition { +): TestSecp256k1ECDSAConditionInfo { + const curve = 'SECP256k1'; + // Simulate server-side key generation for the predefined condition + // ethers.Wallet uses SECP256k1 by default const testWallet = ethers.Wallet.createRandom(); const verifyingKey = testWallet.publicKey.slice(2); // Remove '0x' prefix return { - conditionProps: { - conditionType: ECDSAConditionType, + condition: new ECDSACondition({ message: message, signature: ECDSA_SIGNATURE_PARAM_DEFAULT, verifyingKey: verifyingKey, curve: curve, - }, + }), privateKey: testWallet.privateKey, // For test purposes only }; } -export function createSignatureForPredefinedCondition( - predefinedCondition: PredefinedECDSACondition, +export function createSignatureForTestSecp256k1ECDSACondition( + predefinedCondition: TestSecp256k1ECDSAConditionInfo, messageToSign: string, ): string { // Create signature that matches Python backend expectations From a26f53701dd983cdbdbb51ca563b5418df9b11fe Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 10 Jul 2025 14:12:32 -0400 Subject: [PATCH 155/303] chore(release): release @nucypher/taco-auth:0.4.0-alpha.0 --- packages/taco-auth/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco-auth/package.json b/packages/taco-auth/package.json index 2e68475af..88ab1810b 100644 --- a/packages/taco-auth/package.json +++ b/packages/taco-auth/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco-auth", - "version": "0.3.0", + "version": "0.4.0-alpha.0", "keywords": [ "pre", "threshold", From 5bfb80024de338b40c24f58820b3fe3d3bbb47f2 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 30 Jul 2025 13:13:51 +0200 Subject: [PATCH 156/303] Remove unused imports from sign.ts Remove unused Condition and ConditionExpression imports after API changes. --- packages/taco/src/sign.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 74b91061e..9687b015d 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -14,8 +14,6 @@ import { } from '@nucypher/shared'; import { ethers } from 'ethers'; -import { Condition } from './conditions/condition'; -import { ConditionExpression } from './conditions/condition-expr'; import { ConditionContext } from './conditions/context'; const ERR_INSUFFICIENT_SIGNATURES = (errors: unknown) => From 667231cd8a00220d84e86b90ee32c53530854bd2 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 30 Jul 2025 12:29:39 -0400 Subject: [PATCH 157/303] Add integration test to ensure that SUPPORTED_ECDSA_CURVES in the library are actually supported by the nodes. This test will prove useful in the future to prevent divergence between library and backend. --- .../integration-test/condition-lingo.test.ts | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/packages/taco/integration-test/condition-lingo.test.ts b/packages/taco/integration-test/condition-lingo.test.ts index e8c337fea..3a88e7778 100644 --- a/packages/taco/integration-test/condition-lingo.test.ts +++ b/packages/taco/integration-test/condition-lingo.test.ts @@ -1,9 +1,17 @@ import axios from 'axios'; import * as https from 'https'; import { describe, test } from 'vitest'; -import { CompoundConditionType } from '../src/conditions/compound-condition'; +import { + CompoundCondition, + CompoundConditionType, +} from '../src/conditions/compound-condition'; import { ConditionExpression } from '../src/conditions/condition-expr'; import { IfThenElseConditionType } from '../src/conditions/if-then-else-condition'; +import { + ECDSAConditionProps, + ECDSAConditionType, + SUPPORTED_ECDSA_CURVES, +} from '../src/conditions/schemas/ecdsa'; import { SequentialCondition } from '../src/conditions/sequential'; import { testContractConditionObj, @@ -115,5 +123,44 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const conditionExpr = new ConditionExpression(overallCondition); await validateConditionExpression(conditionExpr); }, 15000); + test('validate ecdsa condition lingo and supported curves consistency', async () => { + // Split SUPPORTED_ECDSA_CURVES into chunks of 5 to respect the operand limit + const preGeneratedVerifyingKeys = { + SECP256k1: + '73149ad37ec1f7cde150064b30e4b0b087ef2f8970c05e53e94f1e87c832d76be0bcc14fdbcf3a6c0118d2288ee85613f31df7faddfa83901f5d45e416d84524', + NIST256p: + 'ef48b327951114d2c54428c5b21a71e01f5cc0660c7087c99df7b1617091425fa660e3ead29e87670ea4074dc8ef5aabb5e433285eeff8c4ff83f6159c11028d', + NIST384p: + '64b65f2e8bfd92d8e14f172100f00e31d467f4f178fcd587e44c07a2482ae3d01ea5a7f67b70e2f77412ecc72954b769b80b0286864c124a3ac769d7705080a66e2b2da408b3d2dac06259118b713000d850898fdcceb5cdb736112c3897a07f', + NIST521p: + '01990fbe474c5c757210d3ad93961bb510b330f37fb8e96b5038616d73ffea0d0bb6956be31859e3bf9c4e1b47e160c8f1493f21f76e7b03cdc9f0df835a33261ac5004e2ad7564ccb95f38f7a81d8b4fecb72816d93ca8e52186fc4209049b46c685ed0d4fe8b34ca6276f0a640184046c751fe131d757b1169a88d4f996c9f6f8274fb', + Ed25519: + 'e6a8ea0dd8b6d7f82ba1b24aeca4ee53f69632ed75480a13e823899a9c3e9554', + BRAINPOOLP256r1: + '975fda96fa12226a378f52a423e2d12d4fed717162ec7e5838169ed57e3357f2410dce2ce1b6bce3bb46ee97d90e542d9895c7d5b0224da05209eaaf0e484acd', + }; + + // Value used for chunkSize is to ensure: + // 1. we don't exceed the max 5 operands in a multi-condition + // 2. we adhere to the fact that "and" compound conditions must have at least 2 operands + // 3. SUPPORTED_ECDSA_CURVES.length is currently 6, so we can split it into chunks of 3 + const chunkSize = 3; + for (let i = 0; i < SUPPORTED_ECDSA_CURVES.length; i += chunkSize) { + const chunk = SUPPORTED_ECDSA_CURVES.slice(i, i + chunkSize); + const operands: ECDSAConditionProps[] = chunk.map((curve) => ({ + conditionType: ECDSAConditionType, + message: ':message', + signature: ':signature', + verifyingKey: preGeneratedVerifyingKeys[curve], + curve, + })); + const overallCondition = new CompoundCondition({ + operator: 'and', + operands, + }); + const conditionExpr = new ConditionExpression(overallCondition); + await validateConditionExpression(conditionExpr); + } + }, 15000); }, ); From b30f65d2719211212267b030a3b539e6b61dc041 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 10 Jul 2025 14:13:57 -0400 Subject: [PATCH 158/303] chore(release): release @nucypher/taco:0.7.0-alpha.0 --- packages/taco/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco/package.json b/packages/taco/package.json index ec9d3e075..3cae96b0b 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco", - "version": "0.6.0", + "version": "0.7.0-alpha.0", "keywords": [ "taco", "threshold", From 8bee7d9eccfccb04e4bc526b730f994b4d324e56 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 30 Jul 2025 16:30:37 +0200 Subject: [PATCH 159/303] Implement correct API design for setSigningCohortConditions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix misunderstanding of @derekpierre's feedback by implementing two-layer design: - Public API: Takes user-friendly Condition parameter (like encrypt()) - Agent layer: Takes Uint8Array for close contract alignment - Internal conversion: Public API handles Condition → ConditionExpression → JSON → Uint8Array This provides optimal developer experience while maintaining efficient internal representation. Co-authored-by: Derek Pierre --- packages/taco/src/sign.ts | 11 +++++++++-- packages/taco/test/taco-sign.test.ts | 6 +++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 9687b015d..b22c03c0b 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -14,6 +14,8 @@ import { } from '@nucypher/shared'; import { ethers } from 'ethers'; +import { Condition } from './conditions/condition'; +import { ConditionExpression } from './conditions/condition-expr'; import { ConditionContext } from './conditions/context'; const ERR_INSUFFICIENT_SIGNATURES = (errors: unknown) => @@ -177,18 +179,23 @@ export async function signUserOp( export async function setSigningCohortConditions( provider: ethers.providers.JsonRpcProvider, domain: Domain, - conditions: Uint8Array, + conditions: Condition, cohortId: number, chainId: number, signer: ethers.Signer, ): Promise { + // Convert Condition to ConditionExpression, then to JSON, then to bytes + const conditionExpression = new ConditionExpression(conditions); + const conditionsJson = conditionExpression.toJson(); + const conditionsBytes = ethers.utils.toUtf8Bytes(conditionsJson); + // Set conditions on the SigningCoordinator contract return await SigningCoordinatorAgent.setSigningCohortConditions( provider, domain, cohortId, chainId, - conditions, + conditionsBytes, signer, ); } diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index 36a14aadf..82fdd7add 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -387,7 +387,7 @@ describe('TACo Signing', () => { const result = await setSigningCohortConditions( mockProvider, domain, - expectedBytes, + rpcCondition, cohortId, chainId, mockSigner, @@ -443,7 +443,7 @@ describe('TACo Signing', () => { const result = await setSigningCohortConditions( mockProvider, domain, - expectedBytes, + compoundCondition, cohortId, chainId, mockSigner, @@ -486,7 +486,7 @@ describe('TACo Signing', () => { setSigningCohortConditions( mockProvider, domain, - expectedBytes, + rpcCondition, cohortId, chainId, mockSigner, From 4a01f74671eb401b2422bf12996500aef54096a8 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 25 Jul 2025 14:28:48 -0400 Subject: [PATCH 160/303] Fix edge case where variable names can be duplicated for nested sequential conditions. We only checked one level for duplicates but not for nested levels - now we check nested levels. --- .../taco/src/conditions/schemas/sequential.ts | 58 ++++++++-- .../taco/test/conditions/sequential.test.ts | 108 ++++++++++++++++-- 2 files changed, 148 insertions(+), 18 deletions(-) diff --git a/packages/taco/src/conditions/schemas/sequential.ts b/packages/taco/src/conditions/schemas/sequential.ts index 60942d047..1d7393d1a 100644 --- a/packages/taco/src/conditions/schemas/sequential.ts +++ b/packages/taco/src/conditions/schemas/sequential.ts @@ -1,10 +1,56 @@ import { z } from 'zod'; +import { ConditionProps } from '../condition'; import { maxNestedDepth } from '../multi-condition'; import { baseConditionSchema, plainStringSchema } from './common'; +import { CompoundConditionType } from './compound'; +import { IfThenElseConditionType } from './if-then-else'; import { anyConditionSchema } from './utils'; +const getAllNestedConditionVariableNames = ( + condition: ConditionProps, +): string[] => { + const conditionVariables: string[] = []; + if (condition.conditionType === SequentialConditionType) { + for (const variable of condition.conditionVariables) { + conditionVariables.push(variable.varName); + conditionVariables.push( + ...getAllNestedConditionVariableNames(variable.condition), + ); + } + } else if (condition.conditionType === IfThenElseConditionType) { + conditionVariables.push( + ...getAllNestedConditionVariableNames(condition.ifCondition), + ); + conditionVariables.push( + ...getAllNestedConditionVariableNames(condition.thenCondition), + ); + if (typeof condition.elseCondition !== 'boolean') { + conditionVariables.push( + ...getAllNestedConditionVariableNames(condition.elseCondition), + ); + } + } else if (condition.conditionType === CompoundConditionType) { + for (const operand of condition.operands) { + conditionVariables.push(...getAllNestedConditionVariableNames(operand)); + } + } + return conditionVariables; +}; + +const noDuplicateVarNames = (condition: ConditionProps): boolean => { + const allVarNames = getAllNestedConditionVariableNames(condition); + const seen = new Set(); + for (const varName of allVarNames) { + if (seen.has(varName)) { + return false; // Duplicate variable name found + } + seen.add(varName); + } + return true; // No duplicates found +}; + export const SequentialConditionType = 'sequential'; export const conditionVariableSchema: z.ZodSchema = z.lazy(() => @@ -30,18 +76,8 @@ export const sequentialConditionSchema: z.ZodSchema = baseConditionSchema }, // Max nested depth of 2 ) .refine( - // check for duplicate var names (condition) => { - const seen = new Set(); - return condition.conditionVariables.every( - (child: ConditionVariableProps) => { - if (seen.has(child.varName)) { - return false; - } - seen.add(child.varName); - return true; - }, - ); + return noDuplicateVarNames(condition); }, { message: 'Duplicate variable names are not allowed', diff --git a/packages/taco/test/conditions/sequential.test.ts b/packages/taco/test/conditions/sequential.test.ts index 0c08b2b95..559f70d4f 100644 --- a/packages/taco/test/conditions/sequential.test.ts +++ b/packages/taco/test/conditions/sequential.test.ts @@ -2,6 +2,7 @@ import { ChainId } from '@nucypher/shared'; import { describe, expect, it } from 'vitest'; import { CompoundConditionType } from '../../src/conditions/compound-condition'; +import { IfThenElseConditionType } from '../../src/conditions/if-then-else-condition'; import { ConditionVariableProps, SequentialCondition, @@ -12,8 +13,8 @@ import { import { testCompoundConditionObj, testContractConditionObj, + testJsonApiConditionObj, testRpcConditionObj, - testSequentialConditionObj, testTimeConditionObj, } from '../test-utils'; @@ -34,9 +35,25 @@ describe('validation', () => { varName: 'compound', condition: testCompoundConditionObj, }; - const sequentialConditionVariable: ConditionVariableProps = { + const nestedSequentialConditionVariable: ConditionVariableProps = { varName: 'nestedSequential', - condition: testSequentialConditionObj, + condition: { + conditionType: SequentialConditionType, + conditionVariables: [ + { + varName: 'nestedRpc', + condition: testRpcConditionObj, + }, + { + varName: 'nestedTime', + condition: testTimeConditionObj, + }, + { + varName: 'nestedContract', + condition: testContractConditionObj, + }, + ], + }, }; it('rejects no varName', () => { @@ -135,7 +152,84 @@ describe('validation', () => { ], }); }); - + it('rejects nested sequential with duplicate varname', () => { + const conditionObj = { + conditionType: SequentialConditionType, + conditionVariables: [ + rpcConditionVariable, + timeConditionVariable, + contractConditionVariable, + { + varName: 'nestedSequential', + condition: { + conditionType: SequentialConditionType, + conditionVariables: [ + contractConditionVariable, + { + varName: 'nestedTime', + condition: testTimeConditionObj, + }, + ], + }, + }, + ], + }; + const result = SequentialCondition.validate( + sequentialConditionSchema, + conditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + conditionVariables: { + _errors: ['Duplicate variable names are not allowed'], + }, + }); + }); + it.each([true, false, testJsonApiConditionObj])( + 'rejects nested sequential with duplicate varname within nested if-then-else', + (variedElseCondition) => { + const conditionObj = { + conditionType: SequentialConditionType, + conditionVariables: [ + { + varName: 'ifThenElse', + condition: { + conditionType: IfThenElseConditionType, + ifCondition: testRpcConditionObj, + thenCondition: testTimeConditionObj, + elseCondition: variedElseCondition, + }, + }, + contractConditionVariable, + { + varName: 'nestedSequential', + condition: { + conditionType: SequentialConditionType, + conditionVariables: [ + contractConditionVariable, + { + varName: 'nestedTime', + condition: testTimeConditionObj, + }, + ], + }, + }, + ], + }; + const result = SequentialCondition.validate( + sequentialConditionSchema, + conditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + conditionVariables: { + _errors: ['Duplicate variable names are not allowed'], + }, + }); + }, + ); it('accepts nested sequential and compound conditions', () => { const conditionObj = { conditionType: SequentialConditionType, @@ -144,7 +238,7 @@ describe('validation', () => { timeConditionVariable, contractConditionVariable, compoundConditionVariable, - sequentialConditionVariable, + nestedSequentialConditionVariable, ], }; const result = SequentialCondition.validate( @@ -159,7 +253,7 @@ describe('validation', () => { timeConditionVariable, contractConditionVariable, compoundConditionVariable, - sequentialConditionVariable, + nestedSequentialConditionVariable, ], }); }); @@ -205,7 +299,7 @@ describe('validation', () => { conditionType: SequentialConditionType, conditionVariables: [ timeConditionVariable, - sequentialConditionVariable, + nestedSequentialConditionVariable, ], }, }, From 7a2373fd2e9d1f37dd56c5250f143d0592dd84e5 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 29 Jul 2025 19:56:06 -0400 Subject: [PATCH 161/303] Improve logic for detecting duplicate condition var names for sequential condition. Co-authored-by: Manuel Montenegro --- packages/taco/src/conditions/schemas/sequential.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/taco/src/conditions/schemas/sequential.ts b/packages/taco/src/conditions/schemas/sequential.ts index 1d7393d1a..1f8998c36 100644 --- a/packages/taco/src/conditions/schemas/sequential.ts +++ b/packages/taco/src/conditions/schemas/sequential.ts @@ -41,14 +41,10 @@ const getAllNestedConditionVariableNames = ( const noDuplicateVarNames = (condition: ConditionProps): boolean => { const allVarNames = getAllNestedConditionVariableNames(condition); - const seen = new Set(); - for (const varName of allVarNames) { - if (seen.has(varName)) { - return false; // Duplicate variable name found - } - seen.add(varName); - } - return true; // No duplicates found + const duplicates = allVarNames.filter( + (item, index) => allVarNames.indexOf(item) !== index, + ); + return duplicates.length === 0; }; export const SequentialConditionType = 'sequential'; From bce20984ed1dd623fbd6c8995e587c170446997e Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 31 Jul 2025 14:27:52 -0400 Subject: [PATCH 162/303] Appease linter. --- packages/taco/integration-test/sign.test.ts | 54 +++++++++++---------- packages/taco/src/index.ts | 2 +- packages/taco/test/taco-sign.test.ts | 30 +++++++----- 3 files changed, 48 insertions(+), 38 deletions(-) diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index 229679a38..8a70e4c2d 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -107,47 +107,51 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( // 2. Convert those bytes to ConditionExpression object // 3. Convert the object back to bytes (what would be written to chain) // 4. Verify the bytes match exactly - + // Read conditions from the existing ritual/cohort - const retrievedConditionHex = await SigningCoordinatorAgent.getSigningCohortConditions( - provider, - DOMAIN as Domain, - COHORT_ID, - CHAIN_ID, - ); - + const retrievedConditionHex = + await SigningCoordinatorAgent.getSigningCohortConditions( + provider, + DOMAIN as Domain, + COHORT_ID, + CHAIN_ID, + ); + // Verify that conditions are set for this cohort/chain combination expect(retrievedConditionHex).toBeDefined(); expect(retrievedConditionHex).not.toBe('0x'); expect(retrievedConditionHex.length).toBeGreaterThan(2); - + // Convert hex back to JSON string (simulating what the chain stores) - const chainConditionJson = ethers.utils.toUtf8String(retrievedConditionHex); - + const chainConditionJson = ethers.utils.toUtf8String( + retrievedConditionHex, + ); + // Parse the JSON and recreate the ConditionExpression from the chain data // This simulates reading conditions from chain and converting to our object model const coreConditions = new CoreConditions(chainConditionJson); - const retrievedConditions = ConditionExpression.fromCoreConditions(coreConditions); - + const retrievedConditions = + ConditionExpression.fromCoreConditions(coreConditions); + // Verify we can create a ConditionContext from it (this validates the data is readable) - await expect(context.ConditionContext.forSigningCohort( - provider, - DOMAIN as Domain, - COHORT_ID, - CHAIN_ID, - )).resolves.not.toThrow(); - + await expect( + context.ConditionContext.forSigningCohort( + provider, + DOMAIN as Domain, + COHORT_ID, + CHAIN_ID, + ), + ).resolves.not.toThrow(); + // Convert back to JSON (this is what would be written to chain) const roundTripJson = retrievedConditions.toJson(); - + // The core verification: ensure serialization round-trip is identical // This proves that read → object → write produces identical bytes expect(JSON.parse(roundTripJson)).toEqual(JSON.parse(chainConditionJson)); - + // Additional verification: ensure the objects have expected properties expect(retrievedConditions.condition).toBeDefined(); - - }, 6000); // Shorter timeout since no blockchain writes }, -); \ No newline at end of file +); diff --git a/packages/taco/src/index.ts b/packages/taco/src/index.ts index c03a09061..b97a54173 100644 --- a/packages/taco/src/index.ts +++ b/packages/taco/src/index.ts @@ -11,5 +11,5 @@ export { export * as conditions from './conditions'; -export { signUserOp, setSigningCohortConditions } from './sign'; +export { setSigningCohortConditions, signUserOp } from './sign'; export { decrypt, encrypt, encryptWithPublicKey } from './taco'; diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index 82fdd7add..824ef1cad 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -355,10 +355,11 @@ describe('TACo Signing', () => { mockProvider = {} as ethers.providers.JsonRpcProvider; mockSigner = {} as ethers.Signer; setSigningCohortConditionsSpy = vi.fn(); - - vi.spyOn(SigningCoordinatorAgent, 'setSigningCohortConditions').mockImplementation( - setSigningCohortConditionsSpy, - ); + + vi.spyOn( + SigningCoordinatorAgent, + 'setSigningCohortConditions', + ).mockImplementation(setSigningCohortConditionsSpy); }); it('should set signing cohort conditions successfully', async () => { @@ -366,7 +367,7 @@ describe('TACo Signing', () => { const cohortId = 1; const chainId = 11155111; const mockTransaction = { hash: '0x123' } as ethers.ContractTransaction; - + // Create a real ConditionExpression with RPC condition const rpcCondition = new RpcCondition({ chain: chainId, @@ -377,7 +378,7 @@ describe('TACo Signing', () => { value: BigInt(0), }, }); - + const conditionExpression = new ConditionExpression(rpcCondition); const expectedJson = conditionExpression.toJson(); const expectedBytes = ethers.utils.toUtf8Bytes(expectedJson); @@ -409,7 +410,7 @@ describe('TACo Signing', () => { const cohortId = 1; const chainId = 11155111; const mockTransaction = { hash: '0x456' } as ethers.ContractTransaction; - + // Create a real compound ConditionExpression const rpcCondition = new RpcCondition({ chain: chainId, @@ -420,7 +421,7 @@ describe('TACo Signing', () => { value: BigInt(0), }, }); - + const contractCondition = new ContractCondition({ contractAddress: '0x1234567890123456789012345678901234567890', chain: chainId, @@ -433,7 +434,10 @@ describe('TACo Signing', () => { }, }); - const compoundCondition = CompoundCondition.and([rpcCondition, contractCondition]); + const compoundCondition = CompoundCondition.and([ + rpcCondition, + contractCondition, + ]); const conditionExpression = new ConditionExpression(compoundCondition); const expectedJson = conditionExpression.toJson(); const expectedBytes = ethers.utils.toUtf8Bytes(expectedJson); @@ -464,7 +468,7 @@ describe('TACo Signing', () => { const domain = 'lynx'; const cohortId = 999; const chainId = 11155111; - + // Create a real ConditionExpression const rpcCondition = new RpcCondition({ chain: chainId, @@ -475,12 +479,14 @@ describe('TACo Signing', () => { value: BigInt(0), }, }); - + const conditionExpression = new ConditionExpression(rpcCondition); const expectedJson = conditionExpression.toJson(); const expectedBytes = ethers.utils.toUtf8Bytes(expectedJson); - setSigningCohortConditionsSpy.mockRejectedValue(new Error('Cohort not found')); + setSigningCohortConditionsSpy.mockRejectedValue( + new Error('Cohort not found'), + ); await expect( setSigningCohortConditions( From 9396b17982868001f03913a3ed6d83f36ce2d121 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 31 Jul 2025 14:31:42 -0400 Subject: [PATCH 163/303] chore(release): release @nucypher/shared:0.6.0-alpha.1 --- packages/shared/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/package.json b/packages/shared/package.json index 2431c7831..e3da97eff 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/shared", - "version": "0.6.0-alpha.0", + "version": "0.6.0-alpha.1", "keywords": [ "pre", "taco", From 63be2828e124efac686288683d85969f636ac588 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 31 Jul 2025 14:34:16 -0400 Subject: [PATCH 164/303] chore(release): release @nucypher/taco-auth:0.4.0-alpha.1 --- packages/taco-auth/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco-auth/package.json b/packages/taco-auth/package.json index 88ab1810b..2801c8e96 100644 --- a/packages/taco-auth/package.json +++ b/packages/taco-auth/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco-auth", - "version": "0.4.0-alpha.0", + "version": "0.4.0-alpha.1", "keywords": [ "pre", "threshold", From d28e00c227b6ef9de2a5b7871f0e124888b5f748 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 31 Jul 2025 14:35:14 -0400 Subject: [PATCH 165/303] chore(release): release @nucypher/taco:0.7.0-alpha.1 --- packages/taco/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco/package.json b/packages/taco/package.json index 3cae96b0b..f6a0b14c8 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco", - "version": "0.7.0-alpha.0", + "version": "0.7.0-alpha.1", "keywords": [ "taco", "threshold", From 29f9c7608c52f5f128217a424670d19570abd110 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 5 Aug 2025 11:30:52 -0400 Subject: [PATCH 166/303] Replace local `nucypher-contracts` dependency with alpha version from npm. --- .../nucypher-nucypher-contracts-0.25.0.tgz | Bin 636417 -> 0 bytes packages/shared/package.json | 2 +- pnpm-lock.yaml | 11 +++++------ 3 files changed, 6 insertions(+), 7 deletions(-) delete mode 100644 packages/shared/nucypher-nucypher-contracts-0.25.0.tgz diff --git a/packages/shared/nucypher-nucypher-contracts-0.25.0.tgz b/packages/shared/nucypher-nucypher-contracts-0.25.0.tgz deleted file mode 100644 index 5de0157b78b1ca8ccb701a9675500133aa794717..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 636417 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

(S*>;(i6$C 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%0DL)d0(F6h#jnze9HcU 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 |hTf=Me%#B&2-1z#C0I5g$#lzU7ZbAW>u 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 z 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 W0p0_?`o{p@0TIp=Za^zBK>rVXObU(w diff --git a/packages/shared/package.json b/packages/shared/package.json index e3da97eff..9f1b68852 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -42,7 +42,7 @@ "dependencies": { "@ethersproject/abi": "^5.8.0", "@ethersproject/providers": "^5.8.0", - "@nucypher/nucypher-contracts": "file:nucypher-nucypher-contracts-0.25.0.tgz", + "@nucypher/nucypher-contracts": "0.26.0-alpha.1", "@nucypher/nucypher-core": "^0.14.5", "axios": "^1.11.0", "deep-equal": "^2.2.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 47726b170..df39bdf9c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -513,8 +513,8 @@ importers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@nucypher/nucypher-contracts': - specifier: file:nucypher-nucypher-contracts-0.25.0.tgz - version: file:packages/shared/nucypher-nucypher-contracts-0.25.0.tgz + specifier: 0.26.0-alpha.1 + version: 0.26.0-alpha.1 '@nucypher/nucypher-core': specifier: ^0.14.5 version: 0.14.5 @@ -2710,9 +2710,8 @@ packages: '@nucypher/nucypher-contracts@0.25.0': resolution: {integrity: sha512-4fRPKY6RzkXY1Zv2O0auJZsvP6z7tuj+Fsy83yJvADqFwRuIJfSlwgSgLwISX6q838SRG/Ve2i+sMLZRaVJfYw==} - '@nucypher/nucypher-contracts@file:packages/shared/nucypher-nucypher-contracts-0.25.0.tgz': - resolution: {integrity: sha512-bFRzG7Xu/azdpGTHErv+qNZx9Zw9nVrt2uPuFjDMTpnyIq3IYMd9EhJbQVh3lzbabykCJsM+969CgvoSKRI24Q==, tarball: file:packages/shared/nucypher-nucypher-contracts-0.25.0.tgz} - version: 0.25.0 + '@nucypher/nucypher-contracts@0.26.0-alpha.1': + resolution: {integrity: sha512-ISS66SyKbDLXFF88Z6k8Tnc/L6Shx6tq22CjPpovbSD2PGS/UzE3uDxvFTKZfgcIJYsi7GV/ho2Brsx4sHYTLg==} '@nucypher/nucypher-core@0.14.5': resolution: {integrity: sha512-Q3kBuJL0qtTtnxrM5DEQauQUvDlXmwubm9u1h7gbyLhs+aZNC9WDyjEUbE43+uahlHu4k1hKEMxD1gjV165ChA==} @@ -12485,7 +12484,7 @@ snapshots: '@nucypher/nucypher-contracts@0.25.0': {} - '@nucypher/nucypher-contracts@file:packages/shared/nucypher-nucypher-contracts-0.25.0.tgz': {} + '@nucypher/nucypher-contracts@0.26.0-alpha.1': {} '@nucypher/nucypher-core@0.14.5': {} From de42a3beb42ae8f12399b687d287de36945fb899 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 6 Aug 2025 13:58:22 +0100 Subject: [PATCH 167/303] =?UTF-8?q?=E2=9C=A8=20feat(taco):=20add=20Context?= =?UTF-8?q?VariableCondition=20with=20flexible=20variable=20matching?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add ContextVariableCondition class supporting various comparison operators - Add context variable schema with validation for context parameters - Integrate ContextVariableCondition into condition factory - Add comprehensive test suite with 194 lines of validation tests - Deprecate AddressAllowlistCondition in favor of more flexible approach - Update test utilities with new condition test objects ContextVariableCondition provides enhanced flexibility for context-based access control with support for ==, >, <, >=, <=, \!=, in, \!in operators. --- .../src/conditions/base/address-allowlist.ts | 4 + .../src/conditions/base/context-variable.ts | 22 ++ packages/taco/src/conditions/base/index.ts | 1 + .../taco/src/conditions/condition-factory.ts | 9 + .../conditions/schemas/address-allowlist.ts | 2 +- .../conditions/schemas/context-variable.ts | 26 +++ .../conditions/base/context-variable.test.ts | 194 ++++++++++++++++++ packages/taco/test/test-utils.ts | 23 ++- 8 files changed, 274 insertions(+), 7 deletions(-) create mode 100644 packages/taco/src/conditions/base/context-variable.ts create mode 100644 packages/taco/src/conditions/schemas/context-variable.ts create mode 100644 packages/taco/test/conditions/base/context-variable.test.ts diff --git a/packages/taco/src/conditions/base/address-allowlist.ts b/packages/taco/src/conditions/base/address-allowlist.ts index cebe2cb6d..67898894e 100644 --- a/packages/taco/src/conditions/base/address-allowlist.ts +++ b/packages/taco/src/conditions/base/address-allowlist.ts @@ -9,6 +9,10 @@ export { AddressAllowlistConditionProps, AddressAllowlistConditionType }; /** * A condition that checks if a wallet address is in a list of allowed addresses. + * + * @deprecated Use ContextVariableCondition instead, which provides more flexible + * context variable matching capabilities and can replicate this functionality + * with contextVariable: ':userAddress' and expectedValues as the addresses array. */ export class AddressAllowlistCondition extends Condition { constructor(value: OmitConditionType) { diff --git a/packages/taco/src/conditions/base/context-variable.ts b/packages/taco/src/conditions/base/context-variable.ts new file mode 100644 index 000000000..b0bf0b331 --- /dev/null +++ b/packages/taco/src/conditions/base/context-variable.ts @@ -0,0 +1,22 @@ +import { Condition } from '../condition'; +import { + ContextVariableConditionProps, + contextVariableConditionSchema, + ContextVariableConditionType, +} from '../schemas/context-variable'; +import { OmitConditionType } from '../shared'; + +export { ContextVariableConditionProps, ContextVariableConditionType }; + +/** + * A condition that checks if a context variable matches one of the expected values. + * Supports case-insensitive comparisons. + */ +export class ContextVariableCondition extends Condition { + constructor(value: OmitConditionType) { + super(contextVariableConditionSchema, { + conditionType: ContextVariableConditionType, + ...value, + }); + } +} \ No newline at end of file diff --git a/packages/taco/src/conditions/base/index.ts b/packages/taco/src/conditions/base/index.ts index 37d7be3e7..79e582140 100644 --- a/packages/taco/src/conditions/base/index.ts +++ b/packages/taco/src/conditions/base/index.ts @@ -10,3 +10,4 @@ export * as jwt from './jwt'; export * as rpc from './rpc'; export * as signing from './signing'; export * as time from './time'; +export * as contextVariable from './context-variable'; diff --git a/packages/taco/src/conditions/condition-factory.ts b/packages/taco/src/conditions/condition-factory.ts index 9d44e42e4..04e3ad86d 100644 --- a/packages/taco/src/conditions/condition-factory.ts +++ b/packages/taco/src/conditions/condition-factory.ts @@ -3,6 +3,11 @@ import { AddressAllowlistConditionProps, AddressAllowlistConditionType, } from './base/address-allowlist'; +import { + ContextVariableCondition, + ContextVariableConditionProps, + ContextVariableConditionType, +} from './base/context-variable'; import { ContractCondition, ContractConditionProps, @@ -88,6 +93,10 @@ export class ConditionFactory { return new SigningObjectAbiAttributeCondition( props as SigningObjectAbiAttributeConditionProps, ); + case ContextVariableConditionType: + return new ContextVariableCondition( + props as ContextVariableConditionProps, + ); // Logical Conditions case CompoundConditionType: return new CompoundCondition(props as CompoundConditionProps); diff --git a/packages/taco/src/conditions/schemas/address-allowlist.ts b/packages/taco/src/conditions/schemas/address-allowlist.ts index d240f3c00..592577ab7 100644 --- a/packages/taco/src/conditions/schemas/address-allowlist.ts +++ b/packages/taco/src/conditions/schemas/address-allowlist.ts @@ -19,7 +19,7 @@ export const addressAllowlistConditionSchema = baseConditionSchema }) .strict() .describe( - 'Address Allowlist Condition for allowing decryption for specific wallet addresses. It is very handy when combined with other conditions.', + 'Address Allowlist Condition for allowing decryption for specific wallet addresses. It is very handy when combined with other conditions. @deprecated Use ContextVariableCondition instead.', ); export type AddressAllowlistConditionProps = z.infer< diff --git a/packages/taco/src/conditions/schemas/context-variable.ts b/packages/taco/src/conditions/schemas/context-variable.ts new file mode 100644 index 000000000..1d541ca15 --- /dev/null +++ b/packages/taco/src/conditions/schemas/context-variable.ts @@ -0,0 +1,26 @@ +import { z } from 'zod'; + +import { baseConditionSchema } from './common'; +import { contextParamSchema } from './context'; +import { returnValueTestSchema } from './return-value-test'; + +export const ContextVariableConditionType = 'variable-match'; + +export const contextVariableConditionSchema = baseConditionSchema + .extend({ + conditionType: z.literal(ContextVariableConditionType), + contextVariable: contextParamSchema.describe( + 'The context variable to check (e.g., ":userAddress", ":customParam")', + ), + returnValueTest: returnValueTestSchema.describe( + 'Test to perform on the context variable value. Supports comparators like ==, >, <, >=, <=, !=, in, !in', + ), + }) + .strict() + .describe( + 'Context Variable Condition for checking if a context variable value passes a specified test. Supports various comparison operators.', + ); + +export type ContextVariableConditionProps = z.infer< + typeof contextVariableConditionSchema +>; \ No newline at end of file diff --git a/packages/taco/test/conditions/base/context-variable.test.ts b/packages/taco/test/conditions/base/context-variable.test.ts new file mode 100644 index 000000000..d81485ad4 --- /dev/null +++ b/packages/taco/test/conditions/base/context-variable.test.ts @@ -0,0 +1,194 @@ +import { describe, expect, it } from 'vitest'; + +import { + ContextVariableCondition, + ContextVariableConditionProps, +} from '../../../src/conditions/base/context-variable'; +import { + contextVariableConditionSchema, + ContextVariableConditionType, +} from '../../../src/conditions/schemas/context-variable'; +import { testContextVariableConditionObj } from '../../test-utils'; + +describe('ContextVariableCondition', () => { + describe('validate', () => { + it('accepts valid condition object', () => { + const result = ContextVariableCondition.validate( + contextVariableConditionSchema, + testContextVariableConditionObj, + ); + + expect(result.error).toBeUndefined(); + expect(result.data).toEqual(testContextVariableConditionObj); + }); + + it('fills in conditionType if missing', () => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { conditionType: _, ...withoutType } = + testContextVariableConditionObj; + const condition = new ContextVariableCondition(withoutType); + + expect(condition.toObj().conditionType).toBe(ContextVariableConditionType); + }); + + it('rejects unknown fields', () => { + const conditionObj = { + ...testContextVariableConditionObj, + unknownField: 'unknown', + } as unknown as ContextVariableConditionProps; + + const result = ContextVariableCondition.validate( + contextVariableConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toMatchObject({ + _errors: ["Unrecognized key(s) in object: 'unknownField'"], + }); + }); + + it('requires contextVariable to be present', () => { + const conditionObj = { + ...testContextVariableConditionObj, + contextVariable: undefined, + } as unknown as ContextVariableConditionProps; + + const result = ContextVariableCondition.validate( + contextVariableConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toHaveProperty('contextVariable'); + }); + + it('requires contextVariable to be a valid context parameter', () => { + const conditionObj = { + ...testContextVariableConditionObj, + contextVariable: 'invalidParam', + } as unknown as ContextVariableConditionProps; + + const result = ContextVariableCondition.validate( + contextVariableConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.message).toContain('Invalid'); + }); + + it('accepts valid context parameters', () => { + const validContextParams = [ + ':userAddress', + ':customParam', + ':myVariable', + ]; + + for (const param of validContextParams) { + const conditionObj = { + ...testContextVariableConditionObj, + contextVariable: param, + }; + + const result = ContextVariableCondition.validate( + contextVariableConditionSchema, + conditionObj, + ); + + expect(result.error).toBeUndefined(); + expect(result.data?.contextVariable).toBe(param); + } + }); + + it('requires returnValueTest to be present', () => { + const conditionObj = { + ...testContextVariableConditionObj, + returnValueTest: undefined, + } as unknown as ContextVariableConditionProps; + + const result = ContextVariableCondition.validate( + contextVariableConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toHaveProperty('returnValueTest'); + }); + }); + + describe('constructor', () => { + it('creates a condition from a valid object', () => { + const condition = new ContextVariableCondition(testContextVariableConditionObj); + expect(condition.toObj()).toEqual(testContextVariableConditionObj); + }); + + it('throws an error for invalid condition', () => { + const invalidCondition = () => { + return new ContextVariableCondition({ + contextVariable: ':userAddress', + returnValueTest: { + comparator: 'in', + value: [], // empty array should fail + }, + }); + }; + + expect(invalidCondition).toThrow(/Invalid condition/); + }); + }); + + describe('requiresAuthentication', () => { + it('returns true when contextVariable references user authentication', () => { + const condition = new ContextVariableCondition({ + contextVariable: ':userAddress', + returnValueTest: { + comparator: 'in', + value: ['0x1234567890123456789012345678901234567890'], + }, + }); + expect(condition.requiresAuthentication()).toBe(true); + }); + + it('returns false when contextVariable does not reference user authentication', () => { + const condition = new ContextVariableCondition({ + contextVariable: ':customParam', + returnValueTest: { + comparator: '==', + value: 'someValue', + }, + }); + expect(condition.requiresAuthentication()).toBe(false); + }); + }); + + describe('equals', () => { + it('returns true for identical conditions', () => { + const condition1 = new ContextVariableCondition( + testContextVariableConditionObj, + ); + const condition2 = new ContextVariableCondition( + testContextVariableConditionObj, + ); + expect(condition1.equals(condition2)).toBe(true); + }); + + it('returns false for different conditions', () => { + const condition1 = new ContextVariableCondition( + testContextVariableConditionObj, + ); + const condition2 = new ContextVariableCondition({ + ...testContextVariableConditionObj, + returnValueTest: { + comparator: '==', + value: 'different-value', + }, + }); + expect(condition1.equals(condition2)).toBe(false); + }); + }); +}); \ No newline at end of file diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index ddc457fa3..d4936e7f0 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -42,6 +42,10 @@ import { AddressAllowlistConditionProps, AddressAllowlistConditionType, } from '../src/conditions/base/address-allowlist'; +import { + ContextVariableConditionProps, + ContextVariableConditionType, +} from '../src/conditions/base/context-variable'; import { ContractConditionProps, ContractConditionType, @@ -370,16 +374,23 @@ export const testRpcConditionObj: RpcConditionProps = { returnValueTest: testRpcReturnValueTest, }; -export const testAddressAllowlistConditionObj: AddressAllowlistConditionProps = - { - conditionType: AddressAllowlistConditionType, - userAddress: ':userAddress', - addresses: [ +export const testAddressAllowlistConditionObj: AddressAllowlistConditionProps = { + conditionType: AddressAllowlistConditionType, + userAddress: ':userAddress', + addresses: [ + '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', + '0x0000000000000000000000000000000000000001', + '0x0000000000000000000000000000000000000002', + ], + returnValueTest: { + comparator: 'in', + value: [ '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', '0x0000000000000000000000000000000000000001', '0x0000000000000000000000000000000000000002', ], - }; + }, +}; export const testContractConditionObj: ContractConditionProps = { conditionType: ContractConditionType, From 09330c3ff1876fbc9f8928cef9878ac81f732029 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 30 Sep 2025 15:59:26 +0100 Subject: [PATCH 168/303] =?UTF-8?q?=E2=9C=A8=20feat(taco):=20add=20JsonCon?= =?UTF-8?q?dition=20schema=20and=20class?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add JsonCondition for direct JSON data evaluation without HTTP requests. Features: - Accepts JSON data as objects, arrays, primitives, or strings - Optional JSONPath query support for value extraction - Context variable resolution in queries and return values - Zod schema validation with jsonConditionSchema This parallels the JsonCondition implementation added to nucypher and provides TypeScript support for the new condition type. --- packages/taco/src/conditions/base/index.ts | 1 + packages/taco/src/conditions/base/json.ts | 22 ++++++++++++++++++++ packages/taco/src/conditions/schemas/json.ts | 15 +++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 packages/taco/src/conditions/base/json.ts create mode 100644 packages/taco/src/conditions/schemas/json.ts diff --git a/packages/taco/src/conditions/base/index.ts b/packages/taco/src/conditions/base/index.ts index 3df5dde24..2e9085294 100644 --- a/packages/taco/src/conditions/base/index.ts +++ b/packages/taco/src/conditions/base/index.ts @@ -4,6 +4,7 @@ export * as contextVariable from './context-variable'; export * as contract from './contract'; export * as ecdsa from './ecdsa'; +export * as json from './json'; export * as jsonApi from './json-api'; export * as jsonRpc from './json-rpc'; export * as jwt from './jwt'; diff --git a/packages/taco/src/conditions/base/json.ts b/packages/taco/src/conditions/base/json.ts new file mode 100644 index 000000000..c22d6fe7c --- /dev/null +++ b/packages/taco/src/conditions/base/json.ts @@ -0,0 +1,22 @@ +import { Condition } from '../condition'; +import { + JsonConditionProps, + jsonConditionSchema, + JsonConditionType, +} from '../schemas/json'; +import { OmitConditionType } from '../shared'; + +export { + JsonConditionProps, + jsonConditionSchema, + JsonConditionType, +} from '../schemas/json'; + +export class JsonCondition extends Condition { + constructor(value: OmitConditionType) { + super(jsonConditionSchema, { + conditionType: JsonConditionType, + ...value, + }); + } +} diff --git a/packages/taco/src/conditions/schemas/json.ts b/packages/taco/src/conditions/schemas/json.ts new file mode 100644 index 000000000..bdb5ea0e0 --- /dev/null +++ b/packages/taco/src/conditions/schemas/json.ts @@ -0,0 +1,15 @@ +import { z } from 'zod'; + +import { baseConditionSchema, jsonPathSchema } from './common'; +import { returnValueTestSchema } from './return-value-test'; + +export const JsonConditionType = 'json'; + +export const jsonConditionSchema = baseConditionSchema.extend({ + conditionType: z.literal(JsonConditionType).default(JsonConditionType), + data: z.any().describe('The JSON data to evaluate. Can be an object, array, primitive value, or JSON string.'), + query: jsonPathSchema.optional().describe('Optional JSONPath query to extract a specific value from the data.'), + returnValueTest: returnValueTestSchema, +}); + +export type JsonConditionProps = z.infer; From 556a09d2716c5b28a63bcb56e65adad15003fcc4 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 6 Aug 2025 14:18:37 +0100 Subject: [PATCH 169/303] =?UTF-8?q?=E2=9C=85=20test(taco):=20fix=20conditi?= =?UTF-8?q?on=20test=20objects=20and=20resolve=20test=20failures?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add missing testContextVariableConditionObj with proper schema structure - Remove invalid returnValueTest from testAddressAllowlistConditionObj --- packages/taco/test/test-utils.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index d4936e7f0..7a8f79bbf 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -374,6 +374,18 @@ export const testRpcConditionObj: RpcConditionProps = { returnValueTest: testRpcReturnValueTest, }; +export const testContextVariableConditionObj: ContextVariableConditionProps = { + conditionType: ContextVariableConditionType, + contextVariable: ':userAddress', + returnValueTest: { + comparator: 'in', + value: [ + '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', + '0x0000000000000000000000000000000000000001', + ], + }, +}; + export const testAddressAllowlistConditionObj: AddressAllowlistConditionProps = { conditionType: AddressAllowlistConditionType, userAddress: ':userAddress', @@ -382,14 +394,6 @@ export const testAddressAllowlistConditionObj: AddressAllowlistConditionProps = '0x0000000000000000000000000000000000000001', '0x0000000000000000000000000000000000000002', ], - returnValueTest: { - comparator: 'in', - value: [ - '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', - '0x0000000000000000000000000000000000000001', - '0x0000000000000000000000000000000000000002', - ], - }, }; export const testContractConditionObj: ContractConditionProps = { From aef66ac338b0e229002e965ad443738391a0aade Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 2 Oct 2025 15:32:44 -0400 Subject: [PATCH 170/303] Initial code for supporting variable operations as part of condition variable (within SequentialCondition) and return value test. --- .../conditions/schemas/return-value-test.ts | 2 + .../taco/src/conditions/schemas/sequential.ts | 2 + .../conditions/schemas/variable-operation.ts | 66 +++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 packages/taco/src/conditions/schemas/variable-operation.ts diff --git a/packages/taco/src/conditions/schemas/return-value-test.ts b/packages/taco/src/conditions/schemas/return-value-test.ts index 7a220db57..1465a369f 100644 --- a/packages/taco/src/conditions/schemas/return-value-test.ts +++ b/packages/taco/src/conditions/schemas/return-value-test.ts @@ -4,10 +4,12 @@ import { blockchainParamOrContextParamSchema, paramOrContextParamSchema, } from './context'; +import { variableOperationSchema } from './variable-operation'; const returnValueTestBaseSchema = z.object({ index: z.number().int().nonnegative().optional(), comparator: z.enum(['==', '>', '<', '>=', '<=', '!=', 'in', '!in']), + operations: z.array(variableOperationSchema).min(1).optional(), }); const requireNonEmptyArrayIfComparatorIsIn = (data: { diff --git a/packages/taco/src/conditions/schemas/sequential.ts b/packages/taco/src/conditions/schemas/sequential.ts index 1f8998c36..db4899a92 100644 --- a/packages/taco/src/conditions/schemas/sequential.ts +++ b/packages/taco/src/conditions/schemas/sequential.ts @@ -7,6 +7,7 @@ import { baseConditionSchema, plainStringSchema } from './common'; import { CompoundConditionType } from './compound'; import { IfThenElseConditionType } from './if-then-else'; import { anyConditionSchema } from './utils'; +import { variableOperationSchema } from './variable-operation'; const getAllNestedConditionVariableNames = ( condition: ConditionProps, @@ -53,6 +54,7 @@ export const conditionVariableSchema: z.ZodSchema = z.lazy(() => z.object({ varName: plainStringSchema, condition: anyConditionSchema, + operations: z.array(variableOperationSchema).min(1).optional(), }), ); export type ConditionVariableProps = z.infer; diff --git a/packages/taco/src/conditions/schemas/variable-operation.ts b/packages/taco/src/conditions/schemas/variable-operation.ts new file mode 100644 index 000000000..6828b34af --- /dev/null +++ b/packages/taco/src/conditions/schemas/variable-operation.ts @@ -0,0 +1,66 @@ +import { z } from 'zod'; + +import { paramOrContextParamSchema } from './context'; + +const OPERATOR_FUNCTIONS = [ + '+=', + '-=', + '*=', + '/=', + '%=', + '^=', + 'index', + 'round', + // operations that don't require 2nd value, keep parameter for simplistic execution consistency + 'abs', + 'avg', + 'ceil', + 'ethToWei', + 'floor', + 'len', + 'max', + 'min', + 'sum', + 'weiToEth', + // casting + 'bool', + 'float', + 'int', + 'str', +] as const; + +const OPERATORS_NOT_REQUIRING_VALUES = [ + 'abs', + 'avg', + 'ceil', + 'ethToWei', + 'floor', + 'len', + 'max', + 'min', + 'sum', + 'weiToEth', + // casting + 'bool', + 'float', + 'int', + 'str', +]; + +export const variableOperationSchema = z + .object({ + operation: z.enum(OPERATOR_FUNCTIONS), + value: paramOrContextParamSchema.optional(), + }) + .refine( + (data) => { + if (OPERATORS_NOT_REQUIRING_VALUES.includes(data.operation)) { + return data.value === undefined; + } + return data.value !== undefined; + }, + { + message: 'Invalid value defined for operation', + path: ['value'], + }, + ); From cb1c0d064b91edbeedc0c05d6d15b7087c3312d6 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 30 Sep 2025 15:59:34 +0100 Subject: [PATCH 171/303] =?UTF-8?q?=E2=9C=A8=20feat(taco):=20register=20Js?= =?UTF-8?q?onCondition=20in=20condition=20factory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add JsonCondition to ConditionFactory.conditionFromProps() to enable condition creation from serialized JSON condition objects. This completes the integration of JsonCondition into the taco-web condition system. --- packages/taco/src/conditions/condition-factory.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/taco/src/conditions/condition-factory.ts b/packages/taco/src/conditions/condition-factory.ts index ad7a000b7..8c302821b 100644 --- a/packages/taco/src/conditions/condition-factory.ts +++ b/packages/taco/src/conditions/condition-factory.ts @@ -13,6 +13,11 @@ import { ECDSAConditionProps, ECDSAConditionType, } from './base/ecdsa'; +import { + JsonCondition, + JsonConditionProps, + JsonConditionType, +} from './base/json'; import { JsonApiCondition, JsonApiConditionProps, @@ -70,6 +75,8 @@ export class ConditionFactory { return new ContractCondition(props as ContractConditionProps); case ECDSAConditionType: return new ECDSACondition(props as ECDSAConditionProps); + case JsonConditionType: + return new JsonCondition(props as JsonConditionProps); case JsonApiConditionType: return new JsonApiCondition(props as JsonApiConditionProps); case JsonRpcConditionType: From 554f397b1827a1a67dd72c12169cf212ae3471b4 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 7 Aug 2025 11:00:00 +0100 Subject: [PATCH 172/303] =?UTF-8?q?=F0=9F=97=91=EF=B8=8F=20remove(taco):?= =?UTF-8?q?=20delete=20deprecated=20AddressAllowlistCondition=20entirely?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Delete AddressAllowlistCondition class, schema, and test files - Remove from condition factory, exports, and schema utilities - Remove AddressAllowlistCondition examples and integration tests - Clean up test utilities removing deprecated objects --- packages/taco/examples/conditions.ts | 22 -- .../integration-test/encrypt-decrypt.test.ts | 51 ----- .../src/conditions/base/address-allowlist.ts | 24 --- packages/taco/src/conditions/base/index.ts | 1 - .../taco/src/conditions/condition-factory.ts | 9 - .../conditions/schemas/address-allowlist.ts | 27 --- .../schemas/export-for-zod-doc-gen.ts | 3 +- packages/taco/src/conditions/schemas/utils.ts | 4 +- .../conditions/base/address-allowlist.test.ts | 193 ------------------ packages/taco/test/test-utils.ts | 13 -- 10 files changed, 3 insertions(+), 344 deletions(-) delete mode 100644 packages/taco/src/conditions/base/address-allowlist.ts delete mode 100644 packages/taco/src/conditions/schemas/address-allowlist.ts delete mode 100644 packages/taco/test/conditions/base/address-allowlist.test.ts diff --git a/packages/taco/examples/conditions.ts b/packages/taco/examples/conditions.ts index f1ed65f53..efb2bb4b8 100644 --- a/packages/taco/examples/conditions.ts +++ b/packages/taco/examples/conditions.ts @@ -125,25 +125,3 @@ console.assert( 'ContractCondition requires a signer', ); -// Address Allowlist Condition Example -const addressAllowlistCondition = - new conditions.base.addressAllowlist.AddressAllowlistCondition({ - userAddress: ':userAddress', - addresses: [ - '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', - '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', - '0x0000000000000000000000000000000000000001', - ], - }); - -console.assert( - addressAllowlistCondition.requiresAuthentication(), - 'AddressAllowlistCondition requires authentication', -); - -// You can check if an address is allowed with the condition's toObj method -const addressToCheck = '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77'; -const addresses = addressAllowlistCondition.toObj().addresses; -// This would be checked by taco nodes after validating the wallet signature provided by encryptor (the value of the variable `addressToCheck`). -const isAllowed = addresses.includes(addressToCheck); -console.assert(isAllowed, 'Address should be allowed but it is not.'); diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index 308ec9201..2c2b52e19 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -123,57 +123,6 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( expect(decryptedMessageString).toEqual(messageString); }, 15000); - test('should encrypt and decrypt according to wallet allowlist condition', async () => { - const messageString = - 'This message should only be accessible to allowed wallet addresses'; - const message = toBytes(messageString); - - const addressAllowlistCondition = - new conditions.base.addressAllowlist.AddressAllowlistCondition({ - userAddress: ':userAddress', - addresses: [ - CONSUMER_ADDRESS, - '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', - '0x0000000000000000000000000000000000000001', - ], - }); - - expect(addressAllowlistCondition.requiresAuthentication()).toBe(true); - - const messageKit = await encrypt( - provider, - DOMAIN, - message, - addressAllowlistCondition, - RITUAL_ID, - encryptorSigner, - ); - - const encryptedBytes = messageKit.toBytes(); - - const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); - const conditionContext = - conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); - - const authProvider = new EIP4361AuthProvider(provider, consumerSigner, { - domain: 'localhost', - uri: 'http://localhost:3000', - }); - conditionContext.addAuthProvider( - USER_ADDRESS_PARAM_DEFAULT, - authProvider, - ); - - const decryptedBytes = await decrypt( - provider, - DOMAIN, - messageKitFromBytes, - conditionContext, - ); - const decryptedMessageString = fromBytes(decryptedBytes); - - expect(decryptedMessageString).toEqual(messageString); - }, 15000); test('should encrypt and decrypt according to ECDSA signature condition with predefined verifying key', async () => { const messageString = diff --git a/packages/taco/src/conditions/base/address-allowlist.ts b/packages/taco/src/conditions/base/address-allowlist.ts deleted file mode 100644 index 67898894e..000000000 --- a/packages/taco/src/conditions/base/address-allowlist.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Condition } from '../condition'; -import { - AddressAllowlistConditionProps, - addressAllowlistConditionSchema, - AddressAllowlistConditionType, -} from '../schemas/address-allowlist'; -import { OmitConditionType } from '../shared'; -export { AddressAllowlistConditionProps, AddressAllowlistConditionType }; - -/** - * A condition that checks if a wallet address is in a list of allowed addresses. - * - * @deprecated Use ContextVariableCondition instead, which provides more flexible - * context variable matching capabilities and can replicate this functionality - * with contextVariable: ':userAddress' and expectedValues as the addresses array. - */ -export class AddressAllowlistCondition extends Condition { - constructor(value: OmitConditionType) { - super(addressAllowlistConditionSchema, { - conditionType: AddressAllowlistConditionType, - ...value, - }); - } -} diff --git a/packages/taco/src/conditions/base/index.ts b/packages/taco/src/conditions/base/index.ts index 79e582140..31fd4ef2a 100644 --- a/packages/taco/src/conditions/base/index.ts +++ b/packages/taco/src/conditions/base/index.ts @@ -1,7 +1,6 @@ // Exporting classes here instead of their respective schema files to // avoid circular dependency on Condition class. -export * as addressAllowlist from './address-allowlist'; export * as contract from './contract'; export * as ecdsa from './ecdsa'; export * as jsonApi from './json-api'; diff --git a/packages/taco/src/conditions/condition-factory.ts b/packages/taco/src/conditions/condition-factory.ts index 04e3ad86d..ad7a000b7 100644 --- a/packages/taco/src/conditions/condition-factory.ts +++ b/packages/taco/src/conditions/condition-factory.ts @@ -1,8 +1,3 @@ -import { - AddressAllowlistCondition, - AddressAllowlistConditionProps, - AddressAllowlistConditionType, -} from './base/address-allowlist'; import { ContextVariableCondition, ContextVariableConditionProps, @@ -81,10 +76,6 @@ export class ConditionFactory { return new JsonRpcCondition(props as JsonRpcConditionProps); case JWTConditionType: return new JWTCondition(props as JWTConditionProps); - case AddressAllowlistConditionType: - return new AddressAllowlistCondition( - props as AddressAllowlistConditionProps, - ); case SigningObjectAttributeConditionType: return new SigningObjectAttributeCondition( props as SigningObjectAttributeConditionProps, diff --git a/packages/taco/src/conditions/schemas/address-allowlist.ts b/packages/taco/src/conditions/schemas/address-allowlist.ts deleted file mode 100644 index 592577ab7..000000000 --- a/packages/taco/src/conditions/schemas/address-allowlist.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { EthAddressSchemaStrict } from '@nucypher/shared'; -import { z } from 'zod'; - -import { baseConditionSchema, UserAddressSchema } from './common'; - -export const AddressAllowlistConditionType = 'address-allowlist'; - -export const addressAllowlistConditionSchema = baseConditionSchema - .extend({ - conditionType: z.literal(AddressAllowlistConditionType), - userAddress: UserAddressSchema, - addresses: z - .array(EthAddressSchemaStrict) - .min(1, 'At least one address must be provided') - .max(25, 'A maximum of 25 addresses is allowed') - .describe( - 'List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form.', - ), - }) - .strict() - .describe( - 'Address Allowlist Condition for allowing decryption for specific wallet addresses. It is very handy when combined with other conditions. @deprecated Use ContextVariableCondition instead.', - ); - -export type AddressAllowlistConditionProps = z.infer< - typeof addressAllowlistConditionSchema ->; diff --git a/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts b/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts index 7c95702c2..73821b5b7 100755 --- a/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts +++ b/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts @@ -21,5 +21,4 @@ export * from './rpc'; export * from './sequential'; export * from './signing'; export * from './time'; -// ts-unused-exports:disable-next-line - this comment line is added to prevent lint from changing or objecting the export order. -export * from './address-allowlist'; +export * from './context-variable'; diff --git a/packages/taco/src/conditions/schemas/utils.ts b/packages/taco/src/conditions/schemas/utils.ts index 3425e4df3..dc72a3374 100644 --- a/packages/taco/src/conditions/schemas/utils.ts +++ b/packages/taco/src/conditions/schemas/utils.ts @@ -2,7 +2,7 @@ import { z } from 'zod'; import { compoundConditionSchema } from '../compound-condition'; -import { addressAllowlistConditionSchema } from './address-allowlist'; +import { contextVariableConditionSchema } from './context-variable'; import { contractConditionSchema } from './contract'; import { ecdsaConditionSchema } from './ecdsa'; import { ifThenElseConditionSchema } from './if-then-else'; @@ -21,7 +21,7 @@ export const anyConditionSchema: z.ZodSchema = z.lazy(() => z.union([ rpcConditionSchema, timeConditionSchema, - addressAllowlistConditionSchema, + contextVariableConditionSchema, contractConditionSchema, ecdsaConditionSchema, jsonApiConditionSchema, diff --git a/packages/taco/test/conditions/base/address-allowlist.test.ts b/packages/taco/test/conditions/base/address-allowlist.test.ts deleted file mode 100644 index 102f1d19a..000000000 --- a/packages/taco/test/conditions/base/address-allowlist.test.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { describe, expect, it } from 'vitest'; - -import { - AddressAllowlistCondition, - AddressAllowlistConditionProps, -} from '../../../src/conditions/base/address-allowlist'; -import { - addressAllowlistConditionSchema, - AddressAllowlistConditionType, -} from '../../../src/conditions/schemas/address-allowlist'; -import { testAddressAllowlistConditionObj } from '../../test-utils'; - -describe('AddressAllowlistCondition', () => { - describe('validate', () => { - it('accepts valid condition object', () => { - const result = AddressAllowlistCondition.validate( - addressAllowlistConditionSchema, - testAddressAllowlistConditionObj, - ); - - expect(result.error).toBeUndefined(); - expect(result.data).toEqual(testAddressAllowlistConditionObj); - }); - - it('fills in conditionType if missing', () => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { conditionType: _, ...withoutType } = - testAddressAllowlistConditionObj; - const condition = new AddressAllowlistCondition(withoutType); - - expect(condition.toObj().conditionType).toBe( - AddressAllowlistConditionType, - ); - }); - - it('rejects unknown fields', () => { - const conditionObj = { - ...testAddressAllowlistConditionObj, - unknownField: 'unknown', - } as unknown as AddressAllowlistConditionProps; - - const result = AddressAllowlistCondition.validate( - addressAllowlistConditionSchema, - conditionObj, - ); - - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - // The error format for unknown fields is just a top-level _errors array - expect(result.error?.format()).toMatchObject({ - _errors: ["Unrecognized key(s) in object: 'unknownField'"], - }); - }); - - it('requires addresses to be present', () => { - const conditionObj = { - ...testAddressAllowlistConditionObj, - addresses: undefined, - } as unknown as AddressAllowlistConditionProps; - - const result = AddressAllowlistCondition.validate( - addressAllowlistConditionSchema, - conditionObj, - ); - - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error?.format()).toHaveProperty('addresses'); - }); - - it('requires addresses to be an array', () => { - const conditionObj = { - ...testAddressAllowlistConditionObj, - addresses: 'not-an-array', - } as unknown as AddressAllowlistConditionProps; - - const result = AddressAllowlistCondition.validate( - addressAllowlistConditionSchema, - conditionObj, - ); - - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error?.message).toContain('Expected array'); - }); - - it('requires at least one address', () => { - const conditionObj = { - ...testAddressAllowlistConditionObj, - addresses: [], - } as unknown as AddressAllowlistConditionProps; - - const result = AddressAllowlistCondition.validate( - addressAllowlistConditionSchema, - conditionObj, - ); - - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error?.message).toContain( - 'At least one address must be provided', - ); - }); - - it('enforces a maximum of 25 addresses', () => { - // Create an array of 26 valid Ethereum addresses - const tooManyAddresses = Array(26) - .fill(0) - .map((_, i) => `0x${(i + 10).toString().padStart(40, '0')}`); - - const conditionObj = { - ...testAddressAllowlistConditionObj, - addresses: tooManyAddresses, - } as unknown as AddressAllowlistConditionProps; - - const result = AddressAllowlistCondition.validate( - addressAllowlistConditionSchema, - conditionObj, - ); - - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error?.message).toContain( - 'A maximum of 25 addresses is allowed', - ); - }); - - it('requires addresses to be valid Ethereum addresses', () => { - const conditionObj = { - ...testAddressAllowlistConditionObj, - addresses: ['not-an-eth-address'], - } as unknown as AddressAllowlistConditionProps; - - const result = AddressAllowlistCondition.validate( - addressAllowlistConditionSchema, - conditionObj, - ); - - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error?.message).toContain('Invalid Ethereum address'); - }); - - it('requires addresses to be checksummed', () => { - const conditionObj = { - ...testAddressAllowlistConditionObj, - // Lowercase version of a valid address - addresses: ['0x1e988ba4692e52bc50b375bcc8585b95c48aad77'], - } as unknown as AddressAllowlistConditionProps; - - const result = AddressAllowlistCondition.validate( - addressAllowlistConditionSchema, - conditionObj, - ); - - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error?.message).toContain( - 'Invalid Ethereum address - it must be valid and checksummed', - ); - }); - }); - - describe('constructor', () => { - it('creates a condition from a valid object', () => { - const condition = new AddressAllowlistCondition( - testAddressAllowlistConditionObj, - ); - expect(condition.toObj()).toEqual(testAddressAllowlistConditionObj); - }); - - it('throws an error for invalid condition', () => { - const invalidCondition = () => { - return new AddressAllowlistCondition({ - userAddress: ':userAddress', - addresses: [], - }); - }; - - // The error is wrapped in a general Error with message containing the Zod validation error - expect(invalidCondition).toThrow(/Invalid condition/); - }); - }); - - describe('requiresAuthentication', () => { - it('returns true', () => { - const condition = new AddressAllowlistCondition( - testAddressAllowlistConditionObj, - ); - expect(condition.requiresAuthentication()).toBe(true); - }); - }); -}); diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 7a8f79bbf..f8a3f569d 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -38,10 +38,6 @@ import { import { ethers } from 'ethers'; import { MockInstance, vi } from 'vitest'; -import { - AddressAllowlistConditionProps, - AddressAllowlistConditionType, -} from '../src/conditions/base/address-allowlist'; import { ContextVariableConditionProps, ContextVariableConditionType, @@ -386,15 +382,6 @@ export const testContextVariableConditionObj: ContextVariableConditionProps = { }, }; -export const testAddressAllowlistConditionObj: AddressAllowlistConditionProps = { - conditionType: AddressAllowlistConditionType, - userAddress: ':userAddress', - addresses: [ - '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', - '0x0000000000000000000000000000000000000001', - '0x0000000000000000000000000000000000000002', - ], -}; export const testContractConditionObj: ContractConditionProps = { conditionType: ContractConditionType, From 77798212ce91833744bfb3c315e11375ffac2fa1 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 2 Oct 2025 16:58:23 -0400 Subject: [PATCH 173/303] Initial tests for variable operation and its usage in return value test and condition variable (sequential condition). --- .../conditions/schemas/variable-operation.ts | 33 +++++-- .../test/conditions/return-value-test.test.ts | 50 ++++++++++ .../taco/test/conditions/sequential.test.ts | 99 +++++++++++++++++++ .../conditions/variable-operation.test.ts | 53 ++++++++++ 4 files changed, 228 insertions(+), 7 deletions(-) create mode 100644 packages/taco/test/conditions/variable-operation.test.ts diff --git a/packages/taco/src/conditions/schemas/variable-operation.ts b/packages/taco/src/conditions/schemas/variable-operation.ts index 6828b34af..86f4a0789 100644 --- a/packages/taco/src/conditions/schemas/variable-operation.ts +++ b/packages/taco/src/conditions/schemas/variable-operation.ts @@ -2,7 +2,7 @@ import { z } from 'zod'; import { paramOrContextParamSchema } from './context'; -const OPERATOR_FUNCTIONS = [ +export const OPERATOR_FUNCTIONS = [ '+=', '-=', '*=', @@ -29,7 +29,7 @@ const OPERATOR_FUNCTIONS = [ 'str', ] as const; -const OPERATORS_NOT_REQUIRING_VALUES = [ +export const OPERATORS_NOT_REQUIRING_VALUES = [ 'abs', 'avg', 'ceil', @@ -54,13 +54,32 @@ export const variableOperationSchema = z }) .refine( (data) => { - if (OPERATORS_NOT_REQUIRING_VALUES.includes(data.operation)) { - return data.value === undefined; + if ( + OPERATORS_NOT_REQUIRING_VALUES.includes(data.operation) && + data.value !== undefined + ) { + return false; } - return data.value !== undefined; + return true; }, { - message: 'Invalid value defined for operation', + message: 'Value not allowed for this operation', path: ['value'], }, - ); + ) + .refine( + (data) => { + if ( + !OPERATORS_NOT_REQUIRING_VALUES.includes(data.operation) && + data.value === undefined + ) { + return false; + } + return true; + }, + { + message: 'Value must be defined for operation', + path: ['value'], + }, + ) + .describe('An operation that can be performed on an obtained variable.'); diff --git a/packages/taco/test/conditions/return-value-test.test.ts b/packages/taco/test/conditions/return-value-test.test.ts index 00a251031..978d54626 100644 --- a/packages/taco/test/conditions/return-value-test.test.ts +++ b/packages/taco/test/conditions/return-value-test.test.ts @@ -1,5 +1,9 @@ import { describe, expect, it } from 'vitest'; +import { + OPERATOR_FUNCTIONS, + OPERATORS_NOT_REQUIRING_VALUES, +} from '../../src/conditions/schemas/variable-operation'; import { blockchainReturnValueTestSchema, returnValueTestSchema, @@ -64,5 +68,51 @@ import { }); }, ); + it.each(OPERATOR_FUNCTIONS)('allows valid operations', (operation) => { + const result = schema.safeParse({ + comparator: '==', + value: 10, + operations: [ + { + operation: operation, + value: OPERATORS_NOT_REQUIRING_VALUES.includes(operation) + ? undefined + : 5, + }, + ], + }); + expect(result.success).toBe(true); + expect(result.error).toBeUndefined(); + }); + it('requires at least one operation if defined', () => { + const result = schema.safeParse({ + comparator: '==', + value: 10, + operations: [], + }); + expect(result.success).toBe(false); + expect(result.error).toBeDefined(); + expect(result.error!.format()).toMatchObject({ + operations: { + _errors: ['Array must contain at least 1 element(s)'], + }, + }); + }); + it('allows multiple valid operations', () => { + const result = schema.safeParse({ + comparator: '==', + value: 10, + operations: [ + { operation: 'index', value: 1 }, + { operation: '+=', value: 5 }, + { operation: '*=', value: 2.5 }, + { operation: '-=', value: 5.5 }, + { operation: 'abs' }, + { operation: '^=', value: BigInt('1000000000000000') }, + ], + }); + expect(result.success).toBe(true); + expect(result.error).toBeUndefined(); + }); }); }); diff --git a/packages/taco/test/conditions/sequential.test.ts b/packages/taco/test/conditions/sequential.test.ts index 559f70d4f..2acda7858 100644 --- a/packages/taco/test/conditions/sequential.test.ts +++ b/packages/taco/test/conditions/sequential.test.ts @@ -3,6 +3,10 @@ import { describe, expect, it } from 'vitest'; import { CompoundConditionType } from '../../src/conditions/compound-condition'; import { IfThenElseConditionType } from '../../src/conditions/if-then-else-condition'; +import { + OPERATOR_FUNCTIONS, + OPERATORS_NOT_REQUIRING_VALUES, +} from '../../src/conditions/schemas/variable-operation'; import { ConditionVariableProps, SequentialCondition, @@ -387,4 +391,99 @@ describe('validation', () => { }); expect(condition.value.conditionType).toEqual(SequentialConditionType); }); + it.each(OPERATOR_FUNCTIONS)('allows valid operations', (operation) => { + const conditionObj = { + conditionType: SequentialConditionType, + conditionVariables: [ + { + varName: 'var1', + condition: testRpcConditionObj, + operations: [ + { + operation: operation, + value: OPERATORS_NOT_REQUIRING_VALUES.includes(operation) + ? undefined + : 5, + }, + ], + }, + rpcConditionVariable, + timeConditionVariable, + contractConditionVariable, + ], + }; + const result = SequentialCondition.validate( + sequentialConditionSchema, + conditionObj, + ); + expect(result.error).toBeUndefined(); + expect(result.data).toEqual(conditionObj); + }); + it('requires at least one operation if defined', () => { + const conditionObj = { + conditionType: SequentialConditionType, + conditionVariables: [ + { + varName: 'var1', + condition: testRpcConditionObj, + operations: [], + }, + contractConditionVariable, + ], + }; + const result = SequentialCondition.validate( + sequentialConditionSchema, + conditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.error?.format()).toMatchObject({ + conditionVariables: { + '0': { + operations: { + _errors: ['Array must contain at least 1 element(s)'], + }, + }, + }, + }); + expect(result.data).toBeUndefined(); + }); + it('allows multiple operations', () => { + const conditionObj = { + conditionType: SequentialConditionType, + conditionVariables: [ + { + varName: 'var1', + condition: testRpcConditionObj, + operations: [ + { operation: 'index', value: 1 }, + { operation: '+=', value: 5 }, + { operation: '*=', value: 2.5 }, + { operation: '-=', value: 5.5 }, + { operation: 'abs' }, + { operation: '^=', value: BigInt('1000000000000000') }, + ], + }, + { + varName: 'var2', + condition: testTimeConditionObj, + operations: [ + { operation: 'ceil' }, + { operation: '/=', value: 2.5 }, + { operation: 'floor' }, + { operation: 'ethToWei' }, + { operation: 'weiToEth' }, + { operation: 'int' }, + { operation: 'float' }, + ], + }, + contractConditionVariable, + ], + }; + const result = SequentialCondition.validate( + sequentialConditionSchema, + conditionObj, + ); + expect(result.error).toBeUndefined(); + expect(result.data).toEqual(conditionObj); + }); }); diff --git a/packages/taco/test/conditions/variable-operation.test.ts b/packages/taco/test/conditions/variable-operation.test.ts new file mode 100644 index 000000000..d68402a13 --- /dev/null +++ b/packages/taco/test/conditions/variable-operation.test.ts @@ -0,0 +1,53 @@ +import { describe, expect, it } from 'vitest'; + +import { + OPERATOR_FUNCTIONS, + OPERATORS_NOT_REQUIRING_VALUES, + variableOperationSchema, +} from '../../src/conditions/schemas/variable-operation'; + +describe('validates schema', () => { + it.each(OPERATOR_FUNCTIONS)('allows valid operation', (operation) => { + const result = variableOperationSchema.safeParse({ + operation: operation, + value: OPERATORS_NOT_REQUIRING_VALUES.includes(operation) ? undefined : 5, + }); + expect(result.success).toBe(true); + expect(result.error).toBeUndefined(); + }); + it.each(OPERATORS_NOT_REQUIRING_VALUES)( + 'disallows operations when value is missing for operation that requires a value', + (operation) => { + const result = variableOperationSchema.safeParse({ + operation: operation, + value: 5, // value should be omitted for these operations + }); + expect(result.success).toBe(false); + expect(result.error!.format()).toMatchObject({ + value: { + _errors: ['Value not allowed for this operation'], + }, + }); + }, + ); + + it.each( + OPERATOR_FUNCTIONS.filter( + (op) => !OPERATORS_NOT_REQUIRING_VALUES.includes(op), + ), + )( + 'disallows operations when value is not provided for operation that requires a value', + (operation) => { + const result = variableOperationSchema.safeParse({ + operation: operation, + // value is missing for these operations + }); + expect(result.success).toBe(false); + expect(result.error!.format()).toMatchObject({ + value: { + _errors: ['Value must be defined for operation'], + }, + }); + }, + ); +}); From e9a92c7f2f88435b8097a7af58c8d21784e0d6d7 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 30 Sep 2025 15:59:42 +0100 Subject: [PATCH 174/303] =?UTF-8?q?=E2=9C=85=20test(taco):=20add=20tests?= =?UTF-8?q?=20for=20JsonCondition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add comprehensive test coverage for JsonCondition: Unit tests (15 tests): - Schema validation for various data types (object, array, primitives) - JSONPath query validation (valid and invalid paths) - Context variable support - Error handling for invalid condition types Integration test: - Backend compatibility validation via Lynx nodes Includes testJsonConditionObj in test-utils for reusability. --- .../integration-test/condition-lingo.test.ts | 10 ++ .../taco/test/conditions/base/json.test.ts | 104 ++++++++++++++++++ packages/taco/test/test-utils.ts | 14 +++ 3 files changed, 128 insertions(+) create mode 100644 packages/taco/test/conditions/base/json.test.ts diff --git a/packages/taco/integration-test/condition-lingo.test.ts b/packages/taco/integration-test/condition-lingo.test.ts index 8ac5c68a2..6aaf790c0 100644 --- a/packages/taco/integration-test/condition-lingo.test.ts +++ b/packages/taco/integration-test/condition-lingo.test.ts @@ -18,6 +18,7 @@ import { testContextVariableConditionObj, testContractConditionObj, testJsonApiConditionObj, + testJsonConditionObj, testJsonRpcConditionObj, testJWTConditionObj, testRpcConditionObj, @@ -173,5 +174,14 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const conditionExpr = new ConditionExpression(contextVariableCondition); await validateConditionExpression(conditionExpr); }, 15000); + + test.skip('validate json condition structure', async () => { + // TODO: Enable once JsonCondition is deployed to Lynx nodes + const jsonCondition = new conditions.base.json.JsonCondition( + testJsonConditionObj, + ); + const conditionExpr = new ConditionExpression(jsonCondition); + await validateConditionExpression(conditionExpr); + }, 15000); }, ); diff --git a/packages/taco/test/conditions/base/json.test.ts b/packages/taco/test/conditions/base/json.test.ts new file mode 100644 index 000000000..cbc41a7dc --- /dev/null +++ b/packages/taco/test/conditions/base/json.test.ts @@ -0,0 +1,104 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { describe, expect, it } from 'vitest'; + +import { + JsonCondition, + JsonConditionProps, + jsonConditionSchema, + JsonConditionType, +} from '../../../src/conditions/base/json'; + +describe('JsonCondition', () => { + describe('validation', () => { + it.each([ + [ + 'object', + { store: { book: [{ price: 10.5 }] } }, + '$.store.book[0].price', + 10.5, + ], + ['array', [1, 2, 3, 4, 5], '$[2]', 3], + ['number', 42, undefined, 42], + ['string', 'hello world', undefined, 'hello world'], + ['boolean', true, undefined, true], + ])('accepts valid schema with %s data', (_, data, query, expectedValue) => { + const testJsonConditionObj: JsonConditionProps = { + conditionType: JsonConditionType, + data, + query, + returnValueTest: { + comparator: '==', + value: expectedValue, + }, + }; + + const result = JsonCondition.validate( + jsonConditionSchema, + testJsonConditionObj, + ); + + expect(result.error).toBeUndefined(); + expect(result.data).toEqual(testJsonConditionObj); + }); + + describe('query validation', () => { + it.each([ + '$.store.book[0].price', + '$[2]', + '$.prices.usd', + '$.store.book[*].price', + '$..price', + ])('accepts valid JSONPath query: %s', (query) => { + const result = JsonCondition.validate(jsonConditionSchema, { + conditionType: JsonConditionType, + data: { test: 'data' }, + query, + returnValueTest: { comparator: '==', value: 0 }, + }); + + expect(result.error).toBeUndefined(); + }); + + it.each(['not-a-jsonpath', '$..[', 'random string'])( + 'rejects invalid JSONPath query: %s', + (query) => { + const result = JsonCondition.validate(jsonConditionSchema, { + conditionType: JsonConditionType, + data: { test: 'data' }, + query, + returnValueTest: { comparator: '==', value: 0 }, + }); + + expect(result.error).toBeDefined(); + const errorMessages = result.error?.errors.map((err) => err.message); + expect( + errorMessages?.includes('Invalid JSONPath expression'), + ).toBeTruthy(); + }, + ); + }); + + describe('context variables', () => { + it('allows context variables in query and return value test', () => { + const result = JsonCondition.validate(jsonConditionSchema, { + conditionType: JsonConditionType, + data: { prices: { usd: 100 } }, + query: '$.prices.:currency', + returnValueTest: { comparator: '==', value: ':expectedValue' }, + }); + + expect(result.error).toBeUndefined(); + }); + }); + + it('rejects invalid condition type', () => { + const result = JsonCondition.validate(jsonConditionSchema, { + conditionType: 'invalid-type', + data: { test: 'data' }, + returnValueTest: { comparator: '==', value: 0 }, + } as unknown as JsonConditionProps); + + expect(result.error).toBeDefined(); + }); + }); +}); diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 51ee3717a..78a4c8791 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -54,6 +54,10 @@ import { ECDSAConditionProps, ECDSAConditionType, } from '../src/conditions/base/ecdsa'; +import { + JsonConditionProps, + JsonConditionType, +} from '../src/conditions/base/json'; import { JsonApiConditionProps, JsonApiConditionType, @@ -276,6 +280,16 @@ export const testTimeConditionObj: TimeConditionProps = { chain: TEST_CHAIN_ID, }; +export const testJsonConditionObj: JsonConditionProps = { + conditionType: JsonConditionType, + data: { store: { book: [{ price: 10.5 }] } }, + query: '$.store.book[0].price', + returnValueTest: { + comparator: '==', + value: 10.5, + }, +}; + export const testJsonApiConditionObj: JsonApiConditionProps = { conditionType: JsonApiConditionType, endpoint: 'https://api.example.com/data', From efe25d86933ccd1c16b4e1853d7e639a3fc6393f Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 7 Aug 2025 11:00:28 +0100 Subject: [PATCH 175/303] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(taco):=20?= =?UTF-8?q?refine=20ContextVariableCondition=20implementation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Change condition type from 'variable-match' to 'context-variable' - Update schema descriptions and add ReturnValueTest description - Enhance tests with it.each() parameterized structure - Add integration test validation and update documentation --- .../integration-test/condition-lingo.test.ts | 6 +++ .../taco/schema-docs/condition-schemas.md | 18 +++++---- .../src/conditions/base/context-variable.ts | 4 +- .../conditions/schemas/context-variable.ts | 8 ++-- .../conditions/schemas/return-value-test.ts | 5 ++- .../conditions/base/context-variable.test.ts | 38 +++++++++---------- 6 files changed, 42 insertions(+), 37 deletions(-) diff --git a/packages/taco/integration-test/condition-lingo.test.ts b/packages/taco/integration-test/condition-lingo.test.ts index 3a88e7778..2624f49cb 100644 --- a/packages/taco/integration-test/condition-lingo.test.ts +++ b/packages/taco/integration-test/condition-lingo.test.ts @@ -15,6 +15,7 @@ import { import { SequentialCondition } from '../src/conditions/sequential'; import { testContractConditionObj, + testContextVariableConditionObj, testJsonApiConditionObj, testJsonRpcConditionObj, testJWTConditionObj, @@ -162,5 +163,10 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( await validateConditionExpression(conditionExpr); } }, 15000); + + test('validate context variable condition structure', async () => { + const conditionExpr = new ConditionExpression(testContextVariableConditionObj); + await validateConditionExpression(conditionExpr); + }, 15000); }, ); diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index 6befb0c06..3afe22a91 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -6,7 +6,7 @@ _Union of the following possible types:_ - [RpcCondition](#rpccondition) - [TimeCondition](#timecondition) -- [AddressAllowlistCondition](#addressallowlistcondition) +- [ContextVariableCondition](#contextvariablecondition) - [ContractCondition](#contractcondition) - [EcdsaCondition](#ecdsacondition) - [JsonApiCondition](#jsonapicondition) @@ -232,6 +232,8 @@ _(\*) Required._ ## ReturnValueTest +Test to perform on a value. Supports comparison operators like ==, >, <, >=, <=, !=, in, !in + _Object containing the following properties:_ | Property | Type | @@ -344,17 +346,17 @@ _Object containing the following properties:_ _(\*) Required._ -## AddressAllowlistCondition +## ContextVariableCondition -Address Allowlist Condition for allowing decryption for specific wallet addresses. It is very handy when combined with other conditions. +Context Variable Condition for performing comparison operations on context variable values. Supports various comparison operators. _Object containing the following properties:_ -| Property | Description | Type | -| :----------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------- | -| **`conditionType`** (\*) | | `'address-allowlist'` | -| **`userAddress`** (\*) | This is a context variable that will be replaced at decryption time. It represents the Ethereum address of the requester attempting decryption. | [UserAddress](#useraddress) | -| **`addresses`** (\*) | List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form. | `Array` (_min: 1, max: 25_) | +| Property | Description | Type | +| :------------------------- | :------------------------------------------------------------------------------------------- | :------------------------------------------------ | +| **`conditionType`** (\*) | | `'context-variable'` | +| **`contextVariable`** (\*) | The context variable to check (e.g., ":userAddress", ":customParam") | `string` (_regex: `/^:[a-zA-Z_][a-zA-Z0-9_]*$/`_) | +| **`returnValueTest`** (\*) | Test to perform on a value. Supports comparison operators like ==, >, <, >=, <=, !=, in, !in | [ReturnValueTest](#returnvaluetest) | _(\*) Required._ diff --git a/packages/taco/src/conditions/base/context-variable.ts b/packages/taco/src/conditions/base/context-variable.ts index b0bf0b331..d774a3860 100644 --- a/packages/taco/src/conditions/base/context-variable.ts +++ b/packages/taco/src/conditions/base/context-variable.ts @@ -9,8 +9,8 @@ import { OmitConditionType } from '../shared'; export { ContextVariableConditionProps, ContextVariableConditionType }; /** - * A condition that checks if a context variable matches one of the expected values. - * Supports case-insensitive comparisons. + * A condition that performs comparison operations on context variable values. + * Supports various comparison operators like ==, >, <, >=, <=, !=, in, !in. */ export class ContextVariableCondition extends Condition { constructor(value: OmitConditionType) { diff --git a/packages/taco/src/conditions/schemas/context-variable.ts b/packages/taco/src/conditions/schemas/context-variable.ts index 1d541ca15..bb8fa19fc 100644 --- a/packages/taco/src/conditions/schemas/context-variable.ts +++ b/packages/taco/src/conditions/schemas/context-variable.ts @@ -4,7 +4,7 @@ import { baseConditionSchema } from './common'; import { contextParamSchema } from './context'; import { returnValueTestSchema } from './return-value-test'; -export const ContextVariableConditionType = 'variable-match'; +export const ContextVariableConditionType = 'context-variable'; export const contextVariableConditionSchema = baseConditionSchema .extend({ @@ -12,13 +12,11 @@ export const contextVariableConditionSchema = baseConditionSchema contextVariable: contextParamSchema.describe( 'The context variable to check (e.g., ":userAddress", ":customParam")', ), - returnValueTest: returnValueTestSchema.describe( - 'Test to perform on the context variable value. Supports comparators like ==, >, <, >=, <=, !=, in, !in', - ), + returnValueTest: returnValueTestSchema, }) .strict() .describe( - 'Context Variable Condition for checking if a context variable value passes a specified test. Supports various comparison operators.', + 'Context Variable Condition for performing comparison operations on context variable values. Supports various comparison operators.', ); export type ContextVariableConditionProps = z.infer< diff --git a/packages/taco/src/conditions/schemas/return-value-test.ts b/packages/taco/src/conditions/schemas/return-value-test.ts index f978a33e2..7a220db57 100644 --- a/packages/taco/src/conditions/schemas/return-value-test.ts +++ b/packages/taco/src/conditions/schemas/return-value-test.ts @@ -30,7 +30,10 @@ export const returnValueTestSchema = returnValueTestBaseSchema .extend({ value: paramOrContextParamSchema, }) - .refine(requireNonEmptyArrayIfComparatorIsIn, inComparatorErrorConfig); + .refine(requireNonEmptyArrayIfComparatorIsIn, inComparatorErrorConfig) + .describe( + 'Test to perform on a value. Supports comparison operators like ==, >, <, >=, <=, !=, in, !in', + ); export const blockchainReturnValueTestSchema = returnValueTestBaseSchema .extend({ diff --git a/packages/taco/test/conditions/base/context-variable.test.ts b/packages/taco/test/conditions/base/context-variable.test.ts index d81485ad4..877e550bc 100644 --- a/packages/taco/test/conditions/base/context-variable.test.ts +++ b/packages/taco/test/conditions/base/context-variable.test.ts @@ -81,27 +81,23 @@ describe('ContextVariableCondition', () => { expect(result.error?.message).toContain('Invalid'); }); - it('accepts valid context parameters', () => { - const validContextParams = [ - ':userAddress', - ':customParam', - ':myVariable', - ]; - - for (const param of validContextParams) { - const conditionObj = { - ...testContextVariableConditionObj, - contextVariable: param, - }; - - const result = ContextVariableCondition.validate( - contextVariableConditionSchema, - conditionObj, - ); - - expect(result.error).toBeUndefined(); - expect(result.data?.contextVariable).toBe(param); - } + it.each([ + ':userAddress', + ':customParam', + ':myVariable' + ])('accepts valid context parameters: %s', (param) => { + const conditionObj = { + ...testContextVariableConditionObj, + contextVariable: param, + }; + + const result = ContextVariableCondition.validate( + contextVariableConditionSchema, + conditionObj, + ); + + expect(result.error).toBeUndefined(); + expect(result.data?.contextVariable).toBe(param); }); it('requires returnValueTest to be present', () => { From 09d4933b756262d6dbd3d010adb850f1e07dfe49 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 2 Oct 2025 21:32:55 -0400 Subject: [PATCH 176/303] Add integration test for variable operation usage; lingo and encrypt/decrypt test. --- .../integration-test/condition-lingo.test.ts | 41 ++++++++++++++++++- .../integration-test/encrypt-decrypt.test.ts | 18 ++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/packages/taco/integration-test/condition-lingo.test.ts b/packages/taco/integration-test/condition-lingo.test.ts index 18796e6f2..b993794a7 100644 --- a/packages/taco/integration-test/condition-lingo.test.ts +++ b/packages/taco/integration-test/condition-lingo.test.ts @@ -125,7 +125,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( }); const conditionExpr = new ConditionExpression(overallCondition); await validateConditionExpression(conditionExpr); - }, 15000); + }, 20000); test('validate ecdsa condition lingo and supported curves consistency', async () => { // Split SUPPORTED_ECDSA_CURVES into chunks of 5 to respect the operand limit const preGeneratedVerifyingKeys = { @@ -182,5 +182,44 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const conditionExpr = new ConditionExpression(jsonCondition); await validateConditionExpression(conditionExpr); }, 15000); + + test('validate conditions with operations', async () => { + const sequentialCondition = new SequentialCondition({ + conditionVariables: [ + { + varName: 'rpcValue', + condition: testRpcConditionObj, + operations: [ + { operation: 'abs' }, + { operation: '^=', value: BigInt('1000000000000000') }, + ], + }, + { + // add some operations + varName: 'timeValue', + condition: { + ...testTimeConditionObj, + returnValueTest: { + comparator: '>', + value: 100, + operations: [ + { operation: 'abs' }, + { operation: 'index', value: 0 }, + { operation: '+=', value: 5 }, + { operation: '*=', value: ':multiplier' }, // context variable + ], + }, + }, + }, + { + varName: 'contractValue', + condition: testContractConditionObj, + operations: [{ operation: '-=', value: 5.5 }], + }, + ], + }); + const conditionExpr = new ConditionExpression(sequentialCondition); + await validateConditionExpression(conditionExpr); + }, 15000); }, ); diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index 79ef78475..0cbd94168 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -69,6 +69,23 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( }, }); + const forcedZeroBalanceDueToOperations = + new conditions.base.rpc.RpcCondition({ + chain: CHAIN_ID, + method: 'eth_getBalance', + parameters: [':userAddress', 'latest'], + returnValueTest: { + comparator: '==', + value: 0, + operations: [ + { operation: '*=', value: 0 }, + // no-op additional operations + { operation: 'abs' }, + { operation: 'int' }, + ], + }, + }); + const balanceLessThanMaxUintBigInt = new conditions.base.rpc.RpcCondition( { chain: CHAIN_ID, @@ -84,6 +101,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const compoundCondition = CompoundCondition.and([ hasPositiveBalance, balanceLessThanMaxUintBigInt, + forcedZeroBalanceDueToOperations, ]); const messageKit = await encrypt( From 6613604c7554128c808085e3a224d78c11dafce5 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 2 Oct 2025 11:35:11 +0100 Subject: [PATCH 177/303] =?UTF-8?q?=E2=9C=85=20test(taco):=20improve=20Jso?= =?UTF-8?q?nCondition=20test=20coverage=20per=20code=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove unused first parameter in parameterized test cases - Add test for JSON-looking strings to verify they remain as strings - Improve test description formatting to show actual data values Addresses code review feedback from @cygnusv --- .../taco/test/conditions/base/json.test.ts | 39 +++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/packages/taco/test/conditions/base/json.test.ts b/packages/taco/test/conditions/base/json.test.ts index cbc41a7dc..801664d0c 100644 --- a/packages/taco/test/conditions/base/json.test.ts +++ b/packages/taco/test/conditions/base/json.test.ts @@ -11,17 +11,12 @@ import { describe('JsonCondition', () => { describe('validation', () => { it.each([ - [ - 'object', - { store: { book: [{ price: 10.5 }] } }, - '$.store.book[0].price', - 10.5, - ], - ['array', [1, 2, 3, 4, 5], '$[2]', 3], - ['number', 42, undefined, 42], - ['string', 'hello world', undefined, 'hello world'], - ['boolean', true, undefined, true], - ])('accepts valid schema with %s data', (_, data, query, expectedValue) => { + [{ store: { book: [{ price: 10.5 }] } }, '$.store.book[0].price', 10.5], + [[1, 2, 3, 4, 5], '$[2]', 3], + [42, undefined, 42], + ['hello world', undefined, 'hello world'], + [true, undefined, true], + ])('accepts valid schema with data: %j', (data, query, expectedValue) => { const testJsonConditionObj: JsonConditionProps = { conditionType: JsonConditionType, data, @@ -41,6 +36,28 @@ describe('JsonCondition', () => { expect(result.data).toEqual(testJsonConditionObj); }); + it('accepts JSON-looking string as string data (not parsed as JSON)', () => { + const jsonString = '{ "store": { "book": [{ "price": 10.5 }] } }'; + const testJsonConditionObj: JsonConditionProps = { + conditionType: JsonConditionType, + data: jsonString, + returnValueTest: { + comparator: '==', + value: jsonString, + }, + }; + + const result = JsonCondition.validate( + jsonConditionSchema, + testJsonConditionObj, + ); + + expect(result.error).toBeUndefined(); + expect(result.data).toEqual(testJsonConditionObj); + // Verify it's still a string, not parsed + expect(typeof result.data?.data).toBe('string'); + }); + describe('query validation', () => { it.each([ '$.store.book[0].price', From 48be9554e9231a1f206086c1f1bd49dd8b52ffb3 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 7 Aug 2025 11:06:33 +0100 Subject: [PATCH 178/303] =?UTF-8?q?=F0=9F=90=9B=20fix(taco):=20fix=20conte?= =?UTF-8?q?xt=20variable=20condition=20integration=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Import conditions module to access ContextVariableCondition class - Create condition instance properly before passing to ConditionExpression - Resolves 'toObj is not a function' error in integration test --- packages/taco/integration-test/condition-lingo.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/taco/integration-test/condition-lingo.test.ts b/packages/taco/integration-test/condition-lingo.test.ts index 2624f49cb..56cf6ac6d 100644 --- a/packages/taco/integration-test/condition-lingo.test.ts +++ b/packages/taco/integration-test/condition-lingo.test.ts @@ -1,6 +1,7 @@ import axios from 'axios'; import * as https from 'https'; import { describe, test } from 'vitest'; +import { conditions } from '../src'; import { CompoundCondition, CompoundConditionType, @@ -165,7 +166,8 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( }, 15000); test('validate context variable condition structure', async () => { - const conditionExpr = new ConditionExpression(testContextVariableConditionObj); + const contextVariableCondition = new conditions.base.contextVariable.ContextVariableCondition(testContextVariableConditionObj); + const conditionExpr = new ConditionExpression(contextVariableCondition); await validateConditionExpression(conditionExpr); }, 15000); }, From 9bbce968663cffbb32d171a5f0463f5235431fa1 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 3 Oct 2025 08:33:41 -0400 Subject: [PATCH 179/303] Add usage of variable operations in ReturnValueTest and ConditionVariable to schema-docs via script. --- .../taco/schema-docs/condition-schemas.md | 44 +++++++++++++------ .../schemas/export-for-zod-doc-gen.ts | 1 + .../conditions/schemas/return-value-test.ts | 8 +++- .../taco/src/conditions/schemas/sequential.ts | 21 ++++++--- .../conditions/schemas/variable-operation.ts | 2 +- 5 files changed, 55 insertions(+), 21 deletions(-) diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index dc32bdfdd..749f639c0 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -249,11 +249,12 @@ _(\*) Required._ _Object containing the following properties:_ -| Property | Type | -| :-------------------- | :-------------------------------------------------------------- | -| `index` | `number` (_int, ≥0_) | -| **`comparator`** (\*) | `'==' \| '>' \| '<' \| '>=' \| '<=' \| '!=' \| 'in' \| '!in'` | -| **`value`** (\*) | [BlockchainParamOrContextParam](#blockchainparamorcontextparam) | +| Property | Description | Type | +| :-------------------- | :---------------------------------------------------------------------- | :----------------------------------------------------------------- | +| `index` | | `number` (_int, ≥0_) | +| **`comparator`** (\*) | | `'==' \| '>' \| '<' \| '>=' \| '<=' \| '!=' \| 'in' \| '!in'` | +| `operations` | Optional operations to perform on the obtained result before comparison | _Array of at least 1 [VariableOperation](#variableoperation) item_ | +| **`value`** (\*) | | [BlockchainParamOrContextParam](#blockchainparamorcontextparam) | _(\*) Required._ @@ -263,11 +264,12 @@ Test to perform on a value. Supports comparison operators like ==, >, <, >=, <=, _Object containing the following properties:_ -| Property | Type | -| :-------------------- | :------------------------------------------------------------ | -| `index` | `number` (_int, ≥0_) | -| **`comparator`** (\*) | `'==' \| '>' \| '<' \| '>=' \| '<=' \| '!=' \| 'in' \| '!in'` | -| **`value`** (\*) | [ParamOrContextParam](#paramorcontextparam) | +| Property | Description | Type | +| :-------------------- | :---------------------------------------------------------------------- | :----------------------------------------------------------------- | +| `index` | | `number` (_int, ≥0_) | +| **`comparator`** (\*) | | `'==' \| '>' \| '<' \| '>=' \| '<=' \| '!=' \| 'in' \| '!in'` | +| `operations` | Optional operations to perform on the obtained result before comparison | _Array of at least 1 [VariableOperation](#variableoperation) item_ | +| **`value`** (\*) | | [ParamOrContextParam](#paramorcontextparam) | _(\*) Required._ @@ -291,10 +293,11 @@ _(\*) Required._ _Object containing the following properties:_ -| Property | Type | -| :------------------- | :---------------------------- | -| **`varName`** (\*) | [PlainString](#plainstring) | -| **`condition`** (\*) | [AnyCondition](#anycondition) | +| Property | Description | Type | +| :------------------- | :-------------------------------------------------------------------------------- | :----------------------------------------------------------------- | +| **`varName`** (\*) | Any string that is not a Context Parameter i.e. does not start with `:`. | [PlainString](#plainstring) | +| **`condition`** (\*) | | [AnyCondition](#anycondition) | +| `operations` | Optional operations to perform on the obtained condition result before storing it | _Array of at least 1 [VariableOperation](#variableoperation) item_ | _(\*) Required._ @@ -360,6 +363,19 @@ _Object containing the following properties:_ _(\*) Required._ +## VariableOperation + +An operation that can be performed on an obtained result. + +_Object containing the following properties:_ + +| Property | Type | +| :------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **`operation`** (\*) | `'+=' \| '-=' \| '*=' \| '/=' \| '%=' \| '^=' \| 'index' \| 'round' \| 'abs' \| 'avg' \| 'ceil' \| 'ethToWei' \| 'floor' \| 'len' \| 'max' \| 'min' \| 'sum' \| 'weiToEth' \| 'bool' \| 'float' \| ...` | +| `value` | [ParamOrContextParam](#paramorcontextparam) | + +_(\*) Required._ + ## TimeCondition _Object containing the following properties:_ diff --git a/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts b/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts index 83fd2b6d5..2a061a74a 100755 --- a/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts +++ b/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts @@ -23,3 +23,4 @@ export * from './rpc'; export * from './sequential'; export * from './signing'; export * from './time'; +export * from './variable-operation'; diff --git a/packages/taco/src/conditions/schemas/return-value-test.ts b/packages/taco/src/conditions/schemas/return-value-test.ts index 1465a369f..ac511b3e9 100644 --- a/packages/taco/src/conditions/schemas/return-value-test.ts +++ b/packages/taco/src/conditions/schemas/return-value-test.ts @@ -9,7 +9,13 @@ import { variableOperationSchema } from './variable-operation'; const returnValueTestBaseSchema = z.object({ index: z.number().int().nonnegative().optional(), comparator: z.enum(['==', '>', '<', '>=', '<=', '!=', 'in', '!in']), - operations: z.array(variableOperationSchema).min(1).optional(), + operations: z + .array(variableOperationSchema) + .min(1) + .optional() + .describe( + 'Optional operations to perform on the obtained result before comparison', + ), }); const requireNonEmptyArrayIfComparatorIsIn = (data: { diff --git a/packages/taco/src/conditions/schemas/sequential.ts b/packages/taco/src/conditions/schemas/sequential.ts index db4899a92..438448f1a 100644 --- a/packages/taco/src/conditions/schemas/sequential.ts +++ b/packages/taco/src/conditions/schemas/sequential.ts @@ -51,12 +51,23 @@ const noDuplicateVarNames = (condition: ConditionProps): boolean => { export const SequentialConditionType = 'sequential'; export const conditionVariableSchema: z.ZodSchema = z.lazy(() => - z.object({ - varName: plainStringSchema, - condition: anyConditionSchema, - operations: z.array(variableOperationSchema).min(1).optional(), - }), + z + .object({ + varName: plainStringSchema, + condition: anyConditionSchema, + operations: z + .array(variableOperationSchema) + .min(1) + .optional() + .describe( + 'Optional operations to perform on the obtained condition result before storing it', + ), + }) + .describe( + 'Executes a condition and stores the result as a variable within a sequential condition.', + ), ); + export type ConditionVariableProps = z.infer; export const sequentialConditionSchema: z.ZodSchema = baseConditionSchema diff --git a/packages/taco/src/conditions/schemas/variable-operation.ts b/packages/taco/src/conditions/schemas/variable-operation.ts index 86f4a0789..67e5c48eb 100644 --- a/packages/taco/src/conditions/schemas/variable-operation.ts +++ b/packages/taco/src/conditions/schemas/variable-operation.ts @@ -82,4 +82,4 @@ export const variableOperationSchema = z path: ['value'], }, ) - .describe('An operation that can be performed on an obtained variable.'); + .describe('An operation that can be performed on an obtained result.'); From 02d6ad6a1d6c5f47e9e18a3d711fcfc3bd54e6eb Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 2 Oct 2025 13:51:26 +0100 Subject: [PATCH 180/303] =?UTF-8?q?=E2=9C=85=20test(taco):=20unskip=20Json?= =?UTF-8?q?Condition=20integration=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taco/integration-test/condition-lingo.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/taco/integration-test/condition-lingo.test.ts b/packages/taco/integration-test/condition-lingo.test.ts index 6aaf790c0..18796e6f2 100644 --- a/packages/taco/integration-test/condition-lingo.test.ts +++ b/packages/taco/integration-test/condition-lingo.test.ts @@ -175,8 +175,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( await validateConditionExpression(conditionExpr); }, 15000); - test.skip('validate json condition structure', async () => { - // TODO: Enable once JsonCondition is deployed to Lynx nodes + test('validate json condition structure', async () => { const jsonCondition = new conditions.base.json.JsonCondition( testJsonConditionObj, ); From 8b1d3bbadc938a92d8f0fe69ab327bfcac4af24d Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 7 Aug 2025 13:32:21 +0100 Subject: [PATCH 181/303] =?UTF-8?q?=F0=9F=92=84=20style(taco):=20format=20?= =?UTF-8?q?ContextVariableCondition=20code=20and=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Apply consistent formatting to context variable files - Fix trailing whitespace and missing newlines - Organize imports in proper order - Improve test formatting and structure --- packages/taco/examples/conditions.ts | 1 - .../integration-test/condition-lingo.test.ts | 9 ++-- .../integration-test/encrypt-decrypt.test.ts | 1 - .../src/conditions/base/context-variable.ts | 2 +- packages/taco/src/conditions/base/index.ts | 2 +- .../conditions/schemas/context-variable.ts | 2 +- .../schemas/export-for-zod-doc-gen.ts | 2 +- .../conditions/base/context-variable.test.ts | 41 ++++++++++--------- packages/taco/test/test-utils.ts | 1 - 9 files changed, 32 insertions(+), 29 deletions(-) diff --git a/packages/taco/examples/conditions.ts b/packages/taco/examples/conditions.ts index efb2bb4b8..19ed8890d 100644 --- a/packages/taco/examples/conditions.ts +++ b/packages/taco/examples/conditions.ts @@ -124,4 +124,3 @@ console.assert( myContractCallCondition.requiresAuthentication(), 'ContractCondition requires a signer', ); - diff --git a/packages/taco/integration-test/condition-lingo.test.ts b/packages/taco/integration-test/condition-lingo.test.ts index 56cf6ac6d..8ac5c68a2 100644 --- a/packages/taco/integration-test/condition-lingo.test.ts +++ b/packages/taco/integration-test/condition-lingo.test.ts @@ -15,8 +15,8 @@ import { } from '../src/conditions/schemas/ecdsa'; import { SequentialCondition } from '../src/conditions/sequential'; import { - testContractConditionObj, testContextVariableConditionObj, + testContractConditionObj, testJsonApiConditionObj, testJsonRpcConditionObj, testJWTConditionObj, @@ -164,9 +164,12 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( await validateConditionExpression(conditionExpr); } }, 15000); - + test('validate context variable condition structure', async () => { - const contextVariableCondition = new conditions.base.contextVariable.ContextVariableCondition(testContextVariableConditionObj); + const contextVariableCondition = + new conditions.base.contextVariable.ContextVariableCondition( + testContextVariableConditionObj, + ); const conditionExpr = new ConditionExpression(contextVariableCondition); await validateConditionExpression(conditionExpr); }, 15000); diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index 2c2b52e19..3b3eaf9eb 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -123,7 +123,6 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( expect(decryptedMessageString).toEqual(messageString); }, 15000); - test('should encrypt and decrypt according to ECDSA signature condition with predefined verifying key', async () => { const messageString = 'This message is protected by ECDSA signature verification 🔐'; diff --git a/packages/taco/src/conditions/base/context-variable.ts b/packages/taco/src/conditions/base/context-variable.ts index d774a3860..35602f39f 100644 --- a/packages/taco/src/conditions/base/context-variable.ts +++ b/packages/taco/src/conditions/base/context-variable.ts @@ -19,4 +19,4 @@ export class ContextVariableCondition extends Condition { ...value, }); } -} \ No newline at end of file +} diff --git a/packages/taco/src/conditions/base/index.ts b/packages/taco/src/conditions/base/index.ts index 31fd4ef2a..3df5dde24 100644 --- a/packages/taco/src/conditions/base/index.ts +++ b/packages/taco/src/conditions/base/index.ts @@ -1,6 +1,7 @@ // Exporting classes here instead of their respective schema files to // avoid circular dependency on Condition class. +export * as contextVariable from './context-variable'; export * as contract from './contract'; export * as ecdsa from './ecdsa'; export * as jsonApi from './json-api'; @@ -9,4 +10,3 @@ export * as jwt from './jwt'; export * as rpc from './rpc'; export * as signing from './signing'; export * as time from './time'; -export * as contextVariable from './context-variable'; diff --git a/packages/taco/src/conditions/schemas/context-variable.ts b/packages/taco/src/conditions/schemas/context-variable.ts index bb8fa19fc..63a2a0b76 100644 --- a/packages/taco/src/conditions/schemas/context-variable.ts +++ b/packages/taco/src/conditions/schemas/context-variable.ts @@ -21,4 +21,4 @@ export const contextVariableConditionSchema = baseConditionSchema export type ContextVariableConditionProps = z.infer< typeof contextVariableConditionSchema ->; \ No newline at end of file +>; diff --git a/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts b/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts index 73821b5b7..caeae2812 100755 --- a/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts +++ b/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts @@ -10,6 +10,7 @@ export * from './common'; export * from './context'; // ts-unused-exports:disable-next-line - this comment line is added to prevent lint from changing or objecting the export order. export * from './compound'; +export * from './context-variable'; export * from './contract'; export * from './ecdsa'; export * from './if-then-else'; @@ -21,4 +22,3 @@ export * from './rpc'; export * from './sequential'; export * from './signing'; export * from './time'; -export * from './context-variable'; diff --git a/packages/taco/test/conditions/base/context-variable.test.ts b/packages/taco/test/conditions/base/context-variable.test.ts index 877e550bc..72a73f013 100644 --- a/packages/taco/test/conditions/base/context-variable.test.ts +++ b/packages/taco/test/conditions/base/context-variable.test.ts @@ -28,7 +28,9 @@ describe('ContextVariableCondition', () => { testContextVariableConditionObj; const condition = new ContextVariableCondition(withoutType); - expect(condition.toObj().conditionType).toBe(ContextVariableConditionType); + expect(condition.toObj().conditionType).toBe( + ContextVariableConditionType, + ); }); it('rejects unknown fields', () => { @@ -81,24 +83,23 @@ describe('ContextVariableCondition', () => { expect(result.error?.message).toContain('Invalid'); }); - it.each([ - ':userAddress', - ':customParam', - ':myVariable' - ])('accepts valid context parameters: %s', (param) => { - const conditionObj = { - ...testContextVariableConditionObj, - contextVariable: param, - }; + it.each([':userAddress', ':customParam', ':myVariable'])( + 'accepts valid context parameters: %s', + (param) => { + const conditionObj = { + ...testContextVariableConditionObj, + contextVariable: param, + }; - const result = ContextVariableCondition.validate( - contextVariableConditionSchema, - conditionObj, - ); + const result = ContextVariableCondition.validate( + contextVariableConditionSchema, + conditionObj, + ); - expect(result.error).toBeUndefined(); - expect(result.data?.contextVariable).toBe(param); - }); + expect(result.error).toBeUndefined(); + expect(result.data?.contextVariable).toBe(param); + }, + ); it('requires returnValueTest to be present', () => { const conditionObj = { @@ -119,7 +120,9 @@ describe('ContextVariableCondition', () => { describe('constructor', () => { it('creates a condition from a valid object', () => { - const condition = new ContextVariableCondition(testContextVariableConditionObj); + const condition = new ContextVariableCondition( + testContextVariableConditionObj, + ); expect(condition.toObj()).toEqual(testContextVariableConditionObj); }); @@ -187,4 +190,4 @@ describe('ContextVariableCondition', () => { expect(condition1.equals(condition2)).toBe(false); }); }); -}); \ No newline at end of file +}); diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index f8a3f569d..51ee3717a 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -382,7 +382,6 @@ export const testContextVariableConditionObj: ContextVariableConditionProps = { }, }; - export const testContractConditionObj: ContractConditionProps = { conditionType: ContractConditionType, contractAddress: '0x0000000000000000000000000000000000000000', From 60c263b957035640e937aa83bfb970622800485d Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 5 Aug 2025 11:36:20 -0400 Subject: [PATCH 182/303] chore(release): release @nucypher/shared:0.6.0-alpha.2 --- packages/shared/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/package.json b/packages/shared/package.json index 9f1b68852..05c4b3041 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/shared", - "version": "0.6.0-alpha.1", + "version": "0.6.0-alpha.2", "keywords": [ "pre", "taco", From ead90cbabf1090c7ca296142ddba6020e4f582be Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 3 Oct 2025 12:18:53 -0400 Subject: [PATCH 183/303] Add restriction on maximum number of operations that can be performed on a variable/result. Update tests and schema docs accordingly. --- .../taco/schema-docs/condition-schemas.md | 60 ++++++++++--------- .../conditions/schemas/return-value-test.ts | 12 ++-- .../taco/src/conditions/schemas/sequential.ts | 12 ++-- .../conditions/schemas/variable-operation.ts | 9 +++ .../test/conditions/return-value-test.test.ts | 24 +++++++- .../taco/test/conditions/sequential.test.ts | 42 +++++++++++-- 6 files changed, 111 insertions(+), 48 deletions(-) diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index 749f639c0..2d0167bb6 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -249,12 +249,12 @@ _(\*) Required._ _Object containing the following properties:_ -| Property | Description | Type | -| :-------------------- | :---------------------------------------------------------------------- | :----------------------------------------------------------------- | -| `index` | | `number` (_int, ≥0_) | -| **`comparator`** (\*) | | `'==' \| '>' \| '<' \| '>=' \| '<=' \| '!=' \| 'in' \| '!in'` | -| `operations` | Optional operations to perform on the obtained result before comparison | _Array of at least 1 [VariableOperation](#variableoperation) item_ | -| **`value`** (\*) | | [BlockchainParamOrContextParam](#blockchainparamorcontextparam) | +| Property | Description | Type | +| :-------------------- | :---------------------------------------------------------------------- | :---------------------------------------------------------------------------------- | +| `index` | | `number` (_int, ≥0_) | +| **`comparator`** (\*) | | `'==' \| '>' \| '<' \| '>=' \| '<=' \| '!=' \| 'in' \| '!in'` | +| `operations` | Optional operations to perform on the obtained result before comparison | _Array of at least 1 and at most 5 [VariableOperation](#variableoperation) items_ | +| **`value`** (\*) | | [BlockchainParamOrContextParam](#blockchainparamorcontextparam) | _(\*) Required._ @@ -264,12 +264,12 @@ Test to perform on a value. Supports comparison operators like ==, >, <, >=, <=, _Object containing the following properties:_ -| Property | Description | Type | -| :-------------------- | :---------------------------------------------------------------------- | :----------------------------------------------------------------- | -| `index` | | `number` (_int, ≥0_) | -| **`comparator`** (\*) | | `'==' \| '>' \| '<' \| '>=' \| '<=' \| '!=' \| 'in' \| '!in'` | -| `operations` | Optional operations to perform on the obtained result before comparison | _Array of at least 1 [VariableOperation](#variableoperation) item_ | -| **`value`** (\*) | | [ParamOrContextParam](#paramorcontextparam) | +| Property | Description | Type | +| :-------------------- | :---------------------------------------------------------------------- | :---------------------------------------------------------------------------------- | +| `index` | | `number` (_int, ≥0_) | +| **`comparator`** (\*) | | `'==' \| '>' \| '<' \| '>=' \| '<=' \| '!=' \| 'in' \| '!in'` | +| `operations` | Optional operations to perform on the obtained result before comparison | _Array of at least 1 and at most 5 [VariableOperation](#variableoperation) items_ | +| **`value`** (\*) | | [ParamOrContextParam](#paramorcontextparam) | _(\*) Required._ @@ -293,11 +293,11 @@ _(\*) Required._ _Object containing the following properties:_ -| Property | Description | Type | -| :------------------- | :-------------------------------------------------------------------------------- | :----------------------------------------------------------------- | -| **`varName`** (\*) | Any string that is not a Context Parameter i.e. does not start with `:`. | [PlainString](#plainstring) | -| **`condition`** (\*) | | [AnyCondition](#anycondition) | -| `operations` | Optional operations to perform on the obtained condition result before storing it | _Array of at least 1 [VariableOperation](#variableoperation) item_ | +| Property | Description | Type | +| :------------------- | :-------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------- | +| **`varName`** (\*) | Any string that is not a Context Parameter i.e. does not start with `:`. | [PlainString](#plainstring) | +| **`condition`** (\*) | | [AnyCondition](#anycondition) | +| `operations` | Optional operations to perform on the obtained condition result before storing it | _Array of at least 1 and at most 5 [VariableOperation](#variableoperation) items_ | _(\*) Required._ @@ -363,6 +363,19 @@ _Object containing the following properties:_ _(\*) Required._ +## TimeCondition + +_Object containing the following properties:_ + +| Property | Type | Default | +| :------------------------- | :------------------------------------------------------ | :------------ | +| `conditionType` | `'time'` | `'time'` | +| **`chain`** (\*) | `number` (_int, ≥0_) | | +| `method` | `'blocktime'` | `'blocktime'` | +| **`returnValueTest`** (\*) | [BlockchainReturnValueTest](#blockchainreturnvaluetest) | | + +_(\*) Required._ + ## VariableOperation An operation that can be performed on an obtained result. @@ -376,18 +389,11 @@ _Object containing the following properties:_ _(\*) Required._ -## TimeCondition +## VariableOperationsArray -_Object containing the following properties:_ +Optional operations to perform on the obtained result -| Property | Type | Default | -| :------------------------- | :------------------------------------------------------ | :------------ | -| `conditionType` | `'time'` | `'time'` | -| **`chain`** (\*) | `number` (_int, ≥0_) | | -| `method` | `'blocktime'` | `'blocktime'` | -| **`returnValueTest`** (\*) | [BlockchainReturnValueTest](#blockchainreturnvaluetest) | | - -_(\*) Required._ +_Array of at least 1 and at most 5 [VariableOperation](#variableoperation) items._ (_optional_) ## More resources diff --git a/packages/taco/src/conditions/schemas/return-value-test.ts b/packages/taco/src/conditions/schemas/return-value-test.ts index ac511b3e9..72e190219 100644 --- a/packages/taco/src/conditions/schemas/return-value-test.ts +++ b/packages/taco/src/conditions/schemas/return-value-test.ts @@ -4,18 +4,14 @@ import { blockchainParamOrContextParamSchema, paramOrContextParamSchema, } from './context'; -import { variableOperationSchema } from './variable-operation'; +import { variableOperationsArraySchema } from './variable-operation'; const returnValueTestBaseSchema = z.object({ index: z.number().int().nonnegative().optional(), comparator: z.enum(['==', '>', '<', '>=', '<=', '!=', 'in', '!in']), - operations: z - .array(variableOperationSchema) - .min(1) - .optional() - .describe( - 'Optional operations to perform on the obtained result before comparison', - ), + operations: variableOperationsArraySchema.describe( + 'Optional operations to perform on the obtained result before comparison', + ), }); const requireNonEmptyArrayIfComparatorIsIn = (data: { diff --git a/packages/taco/src/conditions/schemas/sequential.ts b/packages/taco/src/conditions/schemas/sequential.ts index 438448f1a..3bf54e13c 100644 --- a/packages/taco/src/conditions/schemas/sequential.ts +++ b/packages/taco/src/conditions/schemas/sequential.ts @@ -7,7 +7,7 @@ import { baseConditionSchema, plainStringSchema } from './common'; import { CompoundConditionType } from './compound'; import { IfThenElseConditionType } from './if-then-else'; import { anyConditionSchema } from './utils'; -import { variableOperationSchema } from './variable-operation'; +import { variableOperationsArraySchema } from './variable-operation'; const getAllNestedConditionVariableNames = ( condition: ConditionProps, @@ -55,13 +55,9 @@ export const conditionVariableSchema: z.ZodSchema = z.lazy(() => .object({ varName: plainStringSchema, condition: anyConditionSchema, - operations: z - .array(variableOperationSchema) - .min(1) - .optional() - .describe( - 'Optional operations to perform on the obtained condition result before storing it', - ), + operations: variableOperationsArraySchema.describe( + 'Optional operations to perform on the obtained condition result before storing it', + ), }) .describe( 'Executes a condition and stores the result as a variable within a sequential condition.', diff --git a/packages/taco/src/conditions/schemas/variable-operation.ts b/packages/taco/src/conditions/schemas/variable-operation.ts index 67e5c48eb..e3bfbe57a 100644 --- a/packages/taco/src/conditions/schemas/variable-operation.ts +++ b/packages/taco/src/conditions/schemas/variable-operation.ts @@ -83,3 +83,12 @@ export const variableOperationSchema = z }, ) .describe('An operation that can be performed on an obtained result.'); + +export const MAX_VARIABLE_OPERATIONS = 5; + +export const variableOperationsArraySchema = z + .array(variableOperationSchema) + .min(1) + .max(MAX_VARIABLE_OPERATIONS) + .optional() + .describe('Optional operations to perform on the obtained result'); diff --git a/packages/taco/test/conditions/return-value-test.test.ts b/packages/taco/test/conditions/return-value-test.test.ts index 978d54626..fd9c76cae 100644 --- a/packages/taco/test/conditions/return-value-test.test.ts +++ b/packages/taco/test/conditions/return-value-test.test.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from 'vitest'; import { + MAX_VARIABLE_OPERATIONS, OPERATOR_FUNCTIONS, OPERATORS_NOT_REQUIRING_VALUES, } from '../../src/conditions/schemas/variable-operation'; @@ -98,6 +99,28 @@ import { }, }); }); + it(`allows at most ${MAX_VARIABLE_OPERATIONS} operations`, () => { + const result = schema.safeParse({ + comparator: '==', + value: 10, + operations: Array.from( + { length: MAX_VARIABLE_OPERATIONS + 1 }, + (_, i) => ({ + operation: '+=', + value: i + 1, + }), + ), + }); + expect(result.success).toBe(false); + expect(result.error).toBeDefined(); + expect(result.error!.format()).toMatchObject({ + operations: { + _errors: [ + `Array must contain at most ${MAX_VARIABLE_OPERATIONS} element(s)`, + ], + }, + }); + }); it('allows multiple valid operations', () => { const result = schema.safeParse({ comparator: '==', @@ -106,7 +129,6 @@ import { { operation: 'index', value: 1 }, { operation: '+=', value: 5 }, { operation: '*=', value: 2.5 }, - { operation: '-=', value: 5.5 }, { operation: 'abs' }, { operation: '^=', value: BigInt('1000000000000000') }, ], diff --git a/packages/taco/test/conditions/sequential.test.ts b/packages/taco/test/conditions/sequential.test.ts index 2acda7858..c88a6524c 100644 --- a/packages/taco/test/conditions/sequential.test.ts +++ b/packages/taco/test/conditions/sequential.test.ts @@ -4,6 +4,7 @@ import { describe, expect, it } from 'vitest'; import { CompoundConditionType } from '../../src/conditions/compound-condition'; import { IfThenElseConditionType } from '../../src/conditions/if-then-else-condition'; import { + MAX_VARIABLE_OPERATIONS, OPERATOR_FUNCTIONS, OPERATORS_NOT_REQUIRING_VALUES, } from '../../src/conditions/schemas/variable-operation'; @@ -447,6 +448,42 @@ describe('validation', () => { }); expect(result.data).toBeUndefined(); }); + it(`allows at most ${MAX_VARIABLE_OPERATIONS} operations`, () => { + const conditionObj = { + conditionType: SequentialConditionType, + conditionVariables: [ + { + varName: 'var1', + condition: testRpcConditionObj, + operations: Array.from( + { length: MAX_VARIABLE_OPERATIONS + 1 }, + (_, i) => ({ + operation: '*=', + value: i + 1, + }), + ), + }, + contractConditionVariable, + ], + }; + const result = SequentialCondition.validate( + sequentialConditionSchema, + conditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.error?.format()).toMatchObject({ + conditionVariables: { + '0': { + operations: { + _errors: [ + `Array must contain at most ${MAX_VARIABLE_OPERATIONS} element(s)`, + ], + }, + }, + }, + }); + expect(result.data).toBeUndefined(); + }); it('allows multiple operations', () => { const conditionObj = { conditionType: SequentialConditionType, @@ -456,10 +493,9 @@ describe('validation', () => { condition: testRpcConditionObj, operations: [ { operation: 'index', value: 1 }, - { operation: '+=', value: 5 }, { operation: '*=', value: 2.5 }, { operation: '-=', value: 5.5 }, - { operation: 'abs' }, + { operation: 'int' }, { operation: '^=', value: BigInt('1000000000000000') }, ], }, @@ -472,8 +508,6 @@ describe('validation', () => { { operation: 'floor' }, { operation: 'ethToWei' }, { operation: 'weiToEth' }, - { operation: 'int' }, - { operation: 'float' }, ], }, contractConditionVariable, From 017c17e87b37860580aa35d81477e415b78a226a Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 2 Oct 2025 17:33:07 +0100 Subject: [PATCH 184/303] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(taco):=20?= =?UTF-8?q?require=20JsonCondition=20data=20to=20be=20context=20variable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The data field must now be a context variable that resolves to JSON at decryption time, matching the updated nucypher implementation. - Update jsonConditionSchema to use contextParamSchema for data field - Update all tests to use context variable format (:jsonData) - Add test to verify non-context variable data is rejected - Update test-utils testJsonConditionObj --- packages/taco/src/conditions/schemas/json.ts | 11 ++++- .../taco/test/conditions/base/json.test.ts | 49 +++++++++++-------- packages/taco/test/test-utils.ts | 2 +- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/packages/taco/src/conditions/schemas/json.ts b/packages/taco/src/conditions/schemas/json.ts index bdb5ea0e0..86aa2b625 100644 --- a/packages/taco/src/conditions/schemas/json.ts +++ b/packages/taco/src/conditions/schemas/json.ts @@ -1,14 +1,21 @@ import { z } from 'zod'; import { baseConditionSchema, jsonPathSchema } from './common'; +import { contextParamSchema } from './context'; import { returnValueTestSchema } from './return-value-test'; export const JsonConditionType = 'json'; export const jsonConditionSchema = baseConditionSchema.extend({ conditionType: z.literal(JsonConditionType).default(JsonConditionType), - data: z.any().describe('The JSON data to evaluate. Can be an object, array, primitive value, or JSON string.'), - query: jsonPathSchema.optional().describe('Optional JSONPath query to extract a specific value from the data.'), + data: contextParamSchema.describe( + 'Context variable that resolves to JSON data at decryption time.', + ), + query: jsonPathSchema + .optional() + .describe( + 'Optional JSONPath query to extract a specific value from the data.', + ), returnValueTest: returnValueTestSchema, }); diff --git a/packages/taco/test/conditions/base/json.test.ts b/packages/taco/test/conditions/base/json.test.ts index 801664d0c..5bfe631a8 100644 --- a/packages/taco/test/conditions/base/json.test.ts +++ b/packages/taco/test/conditions/base/json.test.ts @@ -10,20 +10,14 @@ import { describe('JsonCondition', () => { describe('validation', () => { - it.each([ - [{ store: { book: [{ price: 10.5 }] } }, '$.store.book[0].price', 10.5], - [[1, 2, 3, 4, 5], '$[2]', 3], - [42, undefined, 42], - ['hello world', undefined, 'hello world'], - [true, undefined, true], - ])('accepts valid schema with data: %j', (data, query, expectedValue) => { + it('accepts valid schema with context variable data', () => { const testJsonConditionObj: JsonConditionProps = { conditionType: JsonConditionType, - data, - query, + data: ':jsonData', + query: '$.store.book[0].price', returnValueTest: { comparator: '==', - value: expectedValue, + value: 10.5, }, }; @@ -36,14 +30,13 @@ describe('JsonCondition', () => { expect(result.data).toEqual(testJsonConditionObj); }); - it('accepts JSON-looking string as string data (not parsed as JSON)', () => { - const jsonString = '{ "store": { "book": [{ "price": 10.5 }] } }'; + it('accepts valid schema without query', () => { const testJsonConditionObj: JsonConditionProps = { conditionType: JsonConditionType, - data: jsonString, + data: ':jsonData', returnValueTest: { comparator: '==', - value: jsonString, + value: 42, }, }; @@ -54,8 +47,24 @@ describe('JsonCondition', () => { expect(result.error).toBeUndefined(); expect(result.data).toEqual(testJsonConditionObj); - // Verify it's still a string, not parsed - expect(typeof result.data?.data).toBe('string'); + }); + + it('rejects non-context variable data', () => { + const testJsonConditionObj = { + conditionType: JsonConditionType, + data: { store: { book: [{ price: 10.5 }] } }, + returnValueTest: { + comparator: '==', + value: 10.5, + }, + }; + + const result = JsonCondition.validate( + jsonConditionSchema, + testJsonConditionObj as unknown as JsonConditionProps, + ); + + expect(result.error).toBeDefined(); }); describe('query validation', () => { @@ -68,7 +77,7 @@ describe('JsonCondition', () => { ])('accepts valid JSONPath query: %s', (query) => { const result = JsonCondition.validate(jsonConditionSchema, { conditionType: JsonConditionType, - data: { test: 'data' }, + data: ':jsonData', query, returnValueTest: { comparator: '==', value: 0 }, }); @@ -81,7 +90,7 @@ describe('JsonCondition', () => { (query) => { const result = JsonCondition.validate(jsonConditionSchema, { conditionType: JsonConditionType, - data: { test: 'data' }, + data: ':jsonData', query, returnValueTest: { comparator: '==', value: 0 }, }); @@ -96,10 +105,10 @@ describe('JsonCondition', () => { }); describe('context variables', () => { - it('allows context variables in query and return value test', () => { + it('allows context variables in data, query and return value test', () => { const result = JsonCondition.validate(jsonConditionSchema, { conditionType: JsonConditionType, - data: { prices: { usd: 100 } }, + data: ':priceData', query: '$.prices.:currency', returnValueTest: { comparator: '==', value: ':expectedValue' }, }); diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 78a4c8791..a6dfb8f7f 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -282,7 +282,7 @@ export const testTimeConditionObj: TimeConditionProps = { export const testJsonConditionObj: JsonConditionProps = { conditionType: JsonConditionType, - data: { store: { book: [{ price: 10.5 }] } }, + data: ':jsonData', query: '$.store.book[0].price', returnValueTest: { comparator: '==', From 99c364de47501ff6727d733b386a93b9beee9efb Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 7 Aug 2025 14:34:57 +0200 Subject: [PATCH 185/303] minor rewording improvements Co-authored-by: Derek Pierre --- .../taco/schema-docs/condition-schemas.md | 28 +++++++++---------- .../src/conditions/base/context-variable.ts | 1 - .../conditions/schemas/context-variable.ts | 2 +- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index 3afe22a91..515df3fb4 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -100,6 +100,20 @@ _Object containing the following properties:_ _(\*) Required._ +## ContextVariableCondition + +Context Variable Condition for performing comparison operations on context variable values. + +_Object containing the following properties:_ + +| Property | Description | Type | +| :------------------------- | :------------------------------------------------------------------------------------------- | :------------------------------------------------ | +| **`conditionType`** (\*) | | `'context-variable'` | +| **`contextVariable`** (\*) | The context variable to check (e.g., ":userAddress", ":customParam") | `string` (_regex: `/^:[a-zA-Z_][a-zA-Z0-9_]*$/`_) | +| **`returnValueTest`** (\*) | Test to perform on a value. Supports comparison operators like ==, >, <, >=, <=, !=, in, !in | [ReturnValueTest](#returnvaluetest) | + +_(\*) Required._ + ## ContractCondition _Object containing the following properties:_ @@ -346,20 +360,6 @@ _Object containing the following properties:_ _(\*) Required._ -## ContextVariableCondition - -Context Variable Condition for performing comparison operations on context variable values. Supports various comparison operators. - -_Object containing the following properties:_ - -| Property | Description | Type | -| :------------------------- | :------------------------------------------------------------------------------------------- | :------------------------------------------------ | -| **`conditionType`** (\*) | | `'context-variable'` | -| **`contextVariable`** (\*) | The context variable to check (e.g., ":userAddress", ":customParam") | `string` (_regex: `/^:[a-zA-Z_][a-zA-Z0-9_]*$/`_) | -| **`returnValueTest`** (\*) | Test to perform on a value. Supports comparison operators like ==, >, <, >=, <=, !=, in, !in | [ReturnValueTest](#returnvaluetest) | - -_(\*) Required._ - ## More resources For more information, please refer to the TACo documentation: diff --git a/packages/taco/src/conditions/base/context-variable.ts b/packages/taco/src/conditions/base/context-variable.ts index 35602f39f..7a52d5290 100644 --- a/packages/taco/src/conditions/base/context-variable.ts +++ b/packages/taco/src/conditions/base/context-variable.ts @@ -10,7 +10,6 @@ export { ContextVariableConditionProps, ContextVariableConditionType }; /** * A condition that performs comparison operations on context variable values. - * Supports various comparison operators like ==, >, <, >=, <=, !=, in, !in. */ export class ContextVariableCondition extends Condition { constructor(value: OmitConditionType) { diff --git a/packages/taco/src/conditions/schemas/context-variable.ts b/packages/taco/src/conditions/schemas/context-variable.ts index 63a2a0b76..ad50eea7e 100644 --- a/packages/taco/src/conditions/schemas/context-variable.ts +++ b/packages/taco/src/conditions/schemas/context-variable.ts @@ -16,7 +16,7 @@ export const contextVariableConditionSchema = baseConditionSchema }) .strict() .describe( - 'Context Variable Condition for performing comparison operations on context variable values. Supports various comparison operators.', + 'Context Variable Condition for performing comparison operations on context variable values.', ); export type ContextVariableConditionProps = z.infer< From 6e208b4f8281a017c4d6f0775b2cf7987b2a0fde Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 5 Aug 2025 11:37:15 -0400 Subject: [PATCH 186/303] chore(release): release @nucypher/taco-auth:0.4.0-alpha.2 --- packages/taco-auth/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco-auth/package.json b/packages/taco-auth/package.json index 2801c8e96..95f4caabb 100644 --- a/packages/taco-auth/package.json +++ b/packages/taco-auth/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco-auth", - "version": "0.4.0-alpha.1", + "version": "0.4.0-alpha.2", "keywords": [ "pre", "threshold", From 889512e75532454829490f34aaf4eb871cdab709 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 3 Oct 2025 12:28:24 -0400 Subject: [PATCH 187/303] Rename constant for better clarity. --- .../taco/src/conditions/schemas/variable-operation.ts | 6 +++--- .../taco/test/conditions/return-value-test.test.ts | 6 ++---- packages/taco/test/conditions/sequential.test.ts | 4 ++-- .../taco/test/conditions/variable-operation.test.ts | 10 ++++------ 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/packages/taco/src/conditions/schemas/variable-operation.ts b/packages/taco/src/conditions/schemas/variable-operation.ts index e3bfbe57a..0314bc1b9 100644 --- a/packages/taco/src/conditions/schemas/variable-operation.ts +++ b/packages/taco/src/conditions/schemas/variable-operation.ts @@ -29,7 +29,7 @@ export const OPERATOR_FUNCTIONS = [ 'str', ] as const; -export const OPERATORS_NOT_REQUIRING_VALUES = [ +export const UNARY_OPERATOR_FUNCTIONS = [ 'abs', 'avg', 'ceil', @@ -55,7 +55,7 @@ export const variableOperationSchema = z .refine( (data) => { if ( - OPERATORS_NOT_REQUIRING_VALUES.includes(data.operation) && + UNARY_OPERATOR_FUNCTIONS.includes(data.operation) && data.value !== undefined ) { return false; @@ -70,7 +70,7 @@ export const variableOperationSchema = z .refine( (data) => { if ( - !OPERATORS_NOT_REQUIRING_VALUES.includes(data.operation) && + !UNARY_OPERATOR_FUNCTIONS.includes(data.operation) && data.value === undefined ) { return false; diff --git a/packages/taco/test/conditions/return-value-test.test.ts b/packages/taco/test/conditions/return-value-test.test.ts index fd9c76cae..5a9643ca0 100644 --- a/packages/taco/test/conditions/return-value-test.test.ts +++ b/packages/taco/test/conditions/return-value-test.test.ts @@ -3,7 +3,7 @@ import { describe, expect, it } from 'vitest'; import { MAX_VARIABLE_OPERATIONS, OPERATOR_FUNCTIONS, - OPERATORS_NOT_REQUIRING_VALUES, + UNARY_OPERATOR_FUNCTIONS, } from '../../src/conditions/schemas/variable-operation'; import { blockchainReturnValueTestSchema, @@ -76,9 +76,7 @@ import { operations: [ { operation: operation, - value: OPERATORS_NOT_REQUIRING_VALUES.includes(operation) - ? undefined - : 5, + value: UNARY_OPERATOR_FUNCTIONS.includes(operation) ? undefined : 5, }, ], }); diff --git a/packages/taco/test/conditions/sequential.test.ts b/packages/taco/test/conditions/sequential.test.ts index c88a6524c..f3dc4927c 100644 --- a/packages/taco/test/conditions/sequential.test.ts +++ b/packages/taco/test/conditions/sequential.test.ts @@ -6,7 +6,7 @@ import { IfThenElseConditionType } from '../../src/conditions/if-then-else-condi import { MAX_VARIABLE_OPERATIONS, OPERATOR_FUNCTIONS, - OPERATORS_NOT_REQUIRING_VALUES, + UNARY_OPERATOR_FUNCTIONS, } from '../../src/conditions/schemas/variable-operation'; import { ConditionVariableProps, @@ -402,7 +402,7 @@ describe('validation', () => { operations: [ { operation: operation, - value: OPERATORS_NOT_REQUIRING_VALUES.includes(operation) + value: UNARY_OPERATOR_FUNCTIONS.includes(operation) ? undefined : 5, }, diff --git a/packages/taco/test/conditions/variable-operation.test.ts b/packages/taco/test/conditions/variable-operation.test.ts index d68402a13..b2ecc578e 100644 --- a/packages/taco/test/conditions/variable-operation.test.ts +++ b/packages/taco/test/conditions/variable-operation.test.ts @@ -2,7 +2,7 @@ import { describe, expect, it } from 'vitest'; import { OPERATOR_FUNCTIONS, - OPERATORS_NOT_REQUIRING_VALUES, + UNARY_OPERATOR_FUNCTIONS, variableOperationSchema, } from '../../src/conditions/schemas/variable-operation'; @@ -10,12 +10,12 @@ describe('validates schema', () => { it.each(OPERATOR_FUNCTIONS)('allows valid operation', (operation) => { const result = variableOperationSchema.safeParse({ operation: operation, - value: OPERATORS_NOT_REQUIRING_VALUES.includes(operation) ? undefined : 5, + value: UNARY_OPERATOR_FUNCTIONS.includes(operation) ? undefined : 5, }); expect(result.success).toBe(true); expect(result.error).toBeUndefined(); }); - it.each(OPERATORS_NOT_REQUIRING_VALUES)( + it.each(UNARY_OPERATOR_FUNCTIONS)( 'disallows operations when value is missing for operation that requires a value', (operation) => { const result = variableOperationSchema.safeParse({ @@ -32,9 +32,7 @@ describe('validates schema', () => { ); it.each( - OPERATOR_FUNCTIONS.filter( - (op) => !OPERATORS_NOT_REQUIRING_VALUES.includes(op), - ), + OPERATOR_FUNCTIONS.filter((op) => !UNARY_OPERATOR_FUNCTIONS.includes(op)), )( 'disallows operations when value is not provided for operation that requires a value', (operation) => { From 1b45bb449b3e3795b16da6363b75c9136362c789 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 2 Oct 2025 17:37:48 +0100 Subject: [PATCH 188/303] =?UTF-8?q?=E2=9C=85=20test(taco):=20add=20JsonCon?= =?UTF-8?q?dition=20encrypt/decrypt=20integration=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add tests that verify JsonCondition works end-to-end with context variable resolution during encryption and decryption: - Test successful decrypt when JSON data matches condition - Test failed decrypt when JSON data doesn't match condition --- .../integration-test/encrypt-decrypt.test.ts | 140 +++++++++++++++--- 1 file changed, 120 insertions(+), 20 deletions(-) diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index 7a561b292..79ef78475 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -285,16 +285,17 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const message = toBytes(messageString); // Create a context variable condition that checks if userAddress is in allowlist - const contextVariableCondition = new conditions.base.contextVariable.ContextVariableCondition({ - ...testContextVariableConditionObj, - returnValueTest: { - comparator: 'in', - value: [ - CONSUMER_ADDRESS.toLowerCase(), - '0x0000000000000000000000000000000000000001', - ], - }, - }); + const contextVariableCondition = + new conditions.base.contextVariable.ContextVariableCondition({ + ...testContextVariableConditionObj, + returnValueTest: { + comparator: 'in', + value: [ + CONSUMER_ADDRESS.toLowerCase(), + '0x0000000000000000000000000000000000000001', + ], + }, + }); expect(contextVariableCondition.requiresAuthentication()).toBe(true); @@ -342,16 +343,17 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const message = toBytes(messageString); // Create a context variable condition with specific allowed addresses - const restrictedContextVariableCondition = new conditions.base.contextVariable.ContextVariableCondition({ - ...testContextVariableConditionObj, - returnValueTest: { - comparator: 'in', - value: [ - '0x0000000000000000000000000000000000000001', // Not our consumer address - '0x0000000000000000000000000000000000000002', - ], - }, - }); + const restrictedContextVariableCondition = + new conditions.base.contextVariable.ContextVariableCondition({ + ...testContextVariableConditionObj, + returnValueTest: { + comparator: 'in', + value: [ + '0x0000000000000000000000000000000000000001', // Not our consumer address + '0x0000000000000000000000000000000000000002', + ], + }, + }); const messageKit = await encrypt( provider, @@ -379,5 +381,103 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( decrypt(provider, DOMAIN, messageKitFromBytes, conditionContext), ).rejects.toThrow(); }, 20000); + + test('should encrypt and decrypt with JsonCondition using context variable', async () => { + const messageString = 'This message is protected by JsonCondition 🔐'; + const message = toBytes(messageString); + + // JSON data that will be provided at decryption time + const jsonData = { + store: { + book: [ + { price: 10.5, category: 'fiction' }, + { price: 8.99, category: 'non-fiction' }, + ], + }, + }; + + // Create JsonCondition that checks price of first book + const jsonCondition = new conditions.base.json.JsonCondition({ + conditionType: 'json', + data: ':jsonData', + query: '$.store.book[0].price', + returnValueTest: { + comparator: '==', + value: 10.5, + }, + }); + + const messageKit = await encrypt( + provider, + DOMAIN, + message, + jsonCondition, + RITUAL_ID, + encryptorSigner, + ); + + const encryptedBytes = messageKit.toBytes(); + const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); + const conditionContext = + conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); + + expect( + conditionContext.requestedContextParameters.has(':jsonData'), + ).toBeTruthy(); + + // Provide the JSON data as a custom context parameter + conditionContext.addCustomContextParameterValues({ + ':jsonData': jsonData, + }); + + const decryptedBytes = await decrypt( + provider, + DOMAIN, + messageKitFromBytes, + conditionContext, + ); + const decryptedMessageString = fromBytes(decryptedBytes); + + expect(decryptedMessageString).toEqual(messageString); + }, 20000); + + test('should fail to decrypt with JsonCondition when JSON data does not match', async () => { + const messageString = 'This should fail with wrong JSON data'; + const message = toBytes(messageString); + + // Create JsonCondition expecting specific price + const jsonCondition = new conditions.base.json.JsonCondition({ + conditionType: 'json', + data: ':productData', + query: '$.price', + returnValueTest: { + comparator: '>', + value: 100, + }, + }); + + const messageKit = await encrypt( + provider, + DOMAIN, + message, + jsonCondition, + RITUAL_ID, + encryptorSigner, + ); + + const encryptedBytes = messageKit.toBytes(); + const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); + const conditionContext = + conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); + + // Provide JSON data that doesn't meet the condition (price <= 100) + conditionContext.addCustomContextParameterValues({ + ':productData': { price: 50 }, + }); + + await expect( + decrypt(provider, DOMAIN, messageKitFromBytes, conditionContext), + ).rejects.toThrow(); + }, 20000); }, ); From d5fe55a7f93a679d26f08432fad1cce8710906c2 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 8 Aug 2025 14:15:09 +0100 Subject: [PATCH 189/303] =?UTF-8?q?=E2=9C=85=20test(taco):=20add=20Context?= =?UTF-8?q?VariableCondition=20encrypt/decrypt=20integration=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add comprehensive integration tests for ContextVariableCondition in encrypt/decrypt workflows: - Test successful encrypt/decrypt with valid userAddress in allowlist - Test failure case when userAddress is not in allowlist - Verify proper authentication flow with EIP4361AuthProvider - Ensure context parameter validation works correctly Tests validate end-to-end functionality of context variable conditions in real TACo encrypt/decrypt operations. --- .../integration-test/encrypt-decrypt.test.ts | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index 3b3eaf9eb..7a561b292 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -18,6 +18,7 @@ import { CompoundCondition } from '../src/conditions/compound-condition'; import { createSignatureForTestSecp256k1ECDSACondition, createTestSecp256k1ECDSACondition, + testContextVariableConditionObj, UINT256_MAX, } from '../test/test-utils'; @@ -277,5 +278,106 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( expect(decryptedMessageString).toEqual(messageString); }, 25000); + + test('should encrypt and decrypt with ContextVariableCondition', async () => { + const messageString = + 'This message is protected by context variable condition 🔐'; + const message = toBytes(messageString); + + // Create a context variable condition that checks if userAddress is in allowlist + const contextVariableCondition = new conditions.base.contextVariable.ContextVariableCondition({ + ...testContextVariableConditionObj, + returnValueTest: { + comparator: 'in', + value: [ + CONSUMER_ADDRESS.toLowerCase(), + '0x0000000000000000000000000000000000000001', + ], + }, + }); + + expect(contextVariableCondition.requiresAuthentication()).toBe(true); + + const messageKit = await encrypt( + provider, + DOMAIN, + message, + contextVariableCondition, + RITUAL_ID, + encryptorSigner, + ); + + const encryptedBytes = messageKit.toBytes(); + + const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); + const conditionContext = + conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); + + expect( + conditionContext.requestedContextParameters.has( + USER_ADDRESS_PARAM_DEFAULT, + ), + ).toBeTruthy(); + + // Add auth provider for userAddress context parameter + const authProvider = new EIP4361AuthProvider(provider, consumerSigner); + conditionContext.addAuthProvider( + USER_ADDRESS_PARAM_DEFAULT, + authProvider, + ); + + const decryptedBytes = await decrypt( + provider, + DOMAIN, + messageKitFromBytes, + conditionContext, + ); + const decryptedMessageString = fromBytes(decryptedBytes); + + expect(decryptedMessageString).toEqual(messageString); + }, 20000); + + test('should fail to decrypt with ContextVariableCondition when userAddress is not in allowlist', async () => { + const messageString = 'This should fail with wrong address'; + const message = toBytes(messageString); + + // Create a context variable condition with specific allowed addresses + const restrictedContextVariableCondition = new conditions.base.contextVariable.ContextVariableCondition({ + ...testContextVariableConditionObj, + returnValueTest: { + comparator: 'in', + value: [ + '0x0000000000000000000000000000000000000001', // Not our consumer address + '0x0000000000000000000000000000000000000002', + ], + }, + }); + + const messageKit = await encrypt( + provider, + DOMAIN, + message, + restrictedContextVariableCondition, + RITUAL_ID, + encryptorSigner, + ); + + const encryptedBytes = messageKit.toBytes(); + + const messageKitFromBytes = ThresholdMessageKit.fromBytes(encryptedBytes); + const conditionContext = + conditions.context.ConditionContext.fromMessageKit(messageKitFromBytes); + + // Add auth provider for userAddress context parameter (but with wrong address) + const authProvider = new EIP4361AuthProvider(provider, consumerSigner); + conditionContext.addAuthProvider( + USER_ADDRESS_PARAM_DEFAULT, + authProvider, + ); + + await expect( + decrypt(provider, DOMAIN, messageKitFromBytes, conditionContext), + ).rejects.toThrow(); + }, 20000); }, ); From 804c9c2aaa298ee352504f3dd4c75e1f88b7fb0b Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 5 Aug 2025 11:38:17 -0400 Subject: [PATCH 190/303] chore(release): release @nucypher/taco:0.7.0-alpha.2 --- packages/taco/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco/package.json b/packages/taco/package.json index f6a0b14c8..32222200f 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco", - "version": "0.7.0-alpha.1", + "version": "0.7.0-alpha.2", "keywords": [ "taco", "threshold", From 43b7eb2a1da54667e52ebd2c6e9ee5589a848c6d Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 27 Oct 2025 10:29:08 +0000 Subject: [PATCH 191/303] chore(release): release @nucypher/shared:0.6.0-alpha.3 --- packages/shared/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/package.json b/packages/shared/package.json index 05c4b3041..b1b2e4379 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/shared", - "version": "0.6.0-alpha.2", + "version": "0.6.0-alpha.3", "keywords": [ "pre", "taco", From 429a607987f3bcb26125e61ab7be9be663cec985 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Sun, 12 Oct 2025 11:51:10 -0400 Subject: [PATCH 192/303] Remove the use of ^= (pow) operation since it is no longer allowed due to possible expensive nature of operation and possible ddos vector. --- packages/taco/integration-test/condition-lingo.test.ts | 2 +- packages/taco/src/conditions/schemas/variable-operation.ts | 1 - packages/taco/test/conditions/return-value-test.test.ts | 2 +- packages/taco/test/conditions/sequential.test.ts | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/taco/integration-test/condition-lingo.test.ts b/packages/taco/integration-test/condition-lingo.test.ts index b993794a7..cbf705951 100644 --- a/packages/taco/integration-test/condition-lingo.test.ts +++ b/packages/taco/integration-test/condition-lingo.test.ts @@ -191,7 +191,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( condition: testRpcConditionObj, operations: [ { operation: 'abs' }, - { operation: '^=', value: BigInt('1000000000000000') }, + { operation: '+=', value: BigInt('1000000000000000') }, ], }, { diff --git a/packages/taco/src/conditions/schemas/variable-operation.ts b/packages/taco/src/conditions/schemas/variable-operation.ts index 0314bc1b9..520a5c34e 100644 --- a/packages/taco/src/conditions/schemas/variable-operation.ts +++ b/packages/taco/src/conditions/schemas/variable-operation.ts @@ -8,7 +8,6 @@ export const OPERATOR_FUNCTIONS = [ '*=', '/=', '%=', - '^=', 'index', 'round', // operations that don't require 2nd value, keep parameter for simplistic execution consistency diff --git a/packages/taco/test/conditions/return-value-test.test.ts b/packages/taco/test/conditions/return-value-test.test.ts index 5a9643ca0..b08f10bf7 100644 --- a/packages/taco/test/conditions/return-value-test.test.ts +++ b/packages/taco/test/conditions/return-value-test.test.ts @@ -128,7 +128,7 @@ import { { operation: '+=', value: 5 }, { operation: '*=', value: 2.5 }, { operation: 'abs' }, - { operation: '^=', value: BigInt('1000000000000000') }, + { operation: '+=', value: BigInt('1000000000000000') }, ], }); expect(result.success).toBe(true); diff --git a/packages/taco/test/conditions/sequential.test.ts b/packages/taco/test/conditions/sequential.test.ts index f3dc4927c..8336a3b2d 100644 --- a/packages/taco/test/conditions/sequential.test.ts +++ b/packages/taco/test/conditions/sequential.test.ts @@ -496,7 +496,7 @@ describe('validation', () => { { operation: '*=', value: 2.5 }, { operation: '-=', value: 5.5 }, { operation: 'int' }, - { operation: '^=', value: BigInt('1000000000000000') }, + { operation: '+=', value: BigInt('1000000000000000') }, ], }, { From eb0141366357d6094ec74e942bcf65506ec489f5 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 3 Oct 2025 12:52:05 +0100 Subject: [PATCH 193/303] =?UTF-8?q?=F0=9F=93=9D=20docs(taco):=20add=20Json?= =?UTF-8?q?Condition=20to=20schema=20documentation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Export jsonConditionSchema in zod-doc-gen and regenerate condition schemas markdown to include JsonCondition documentation. --- packages/taco/schema-docs/condition-schemas.md | 13 +++++++++++++ .../conditions/schemas/export-for-zod-doc-gen.ts | 1 + 2 files changed, 14 insertions(+) diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index 515df3fb4..dc32bdfdd 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -186,6 +186,19 @@ _Object containing the following properties:_ _(\*) Required._ +## JsonCondition + +_Object containing the following properties:_ + +| Property | Description | Type | Default | +| :------------------------- | :------------------------------------------------------------------------------------------- | :------------------------------------------------ | :------- | +| `conditionType` | | `'json'` | `'json'` | +| **`data`** (\*) | Context variable that resolves to JSON data at decryption time. | `string` (_regex: `/^:[a-zA-Z_][a-zA-Z0-9_]*$/`_) | | +| `query` | Optional JSONPath query to extract a specific value from the data. | [JsonPath](#jsonpath) | | +| **`returnValueTest`** (\*) | Test to perform on a value. Supports comparison operators like ==, >, <, >=, <=, !=, in, !in | [ReturnValueTest](#returnvaluetest) | | + +_(\*) Required._ + ## JsonApiCondition _Object containing the following properties:_ diff --git a/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts b/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts index caeae2812..83fd2b6d5 100755 --- a/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts +++ b/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts @@ -14,6 +14,7 @@ export * from './context-variable'; export * from './contract'; export * from './ecdsa'; export * from './if-then-else'; +export * from './json'; export * from './json-api'; export * from './json-rpc'; export * from './jwt'; From f69c1a96ce3f197f5b995f36e4afd5354a913c53 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 27 Oct 2025 10:29:37 +0000 Subject: [PATCH 194/303] chore(release): release @nucypher/taco-auth:0.4.0-alpha.3 --- packages/taco-auth/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco-auth/package.json b/packages/taco-auth/package.json index 95f4caabb..aadcd3df4 100644 --- a/packages/taco-auth/package.json +++ b/packages/taco-auth/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco-auth", - "version": "0.4.0-alpha.2", + "version": "0.4.0-alpha.3", "keywords": [ "pre", "threshold", From fb228eb83084384c30f1fea5b8f6cf5aae6b8e2e Mon Sep 17 00:00:00 2001 From: derekpierre Date: Mon, 13 Oct 2025 09:00:35 -0400 Subject: [PATCH 195/303] Rerun schema generation script now that the ^= (pow) operator has been removed. --- packages/taco/schema-docs/condition-schemas.md | 8 ++++---- .../taco/src/conditions/schemas/variable-operation.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index 2d0167bb6..b4bbc3430 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -382,10 +382,10 @@ An operation that can be performed on an obtained result. _Object containing the following properties:_ -| Property | Type | -| :------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| **`operation`** (\*) | `'+=' \| '-=' \| '*=' \| '/=' \| '%=' \| '^=' \| 'index' \| 'round' \| 'abs' \| 'avg' \| 'ceil' \| 'ethToWei' \| 'floor' \| 'len' \| 'max' \| 'min' \| 'sum' \| 'weiToEth' \| 'bool' \| 'float' \| ...` | -| `value` | [ParamOrContextParam](#paramorcontextparam) | +| Property | Type | +| :------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **`operation`** (\*) | `'+=' \| '-=' \| '*=' \| '/=' \| '%=' \| 'index' \| 'round' \| 'abs' \| 'avg' \| 'ceil' \| 'ethToWei' \| 'floor' \| 'len' \| 'max' \| 'min' \| 'sum' \| 'weiToEth' \| 'bool' \| 'float' \| 'int' \| ...` | +| `value` | [ParamOrContextParam](#paramorcontextparam) | _(\*) Required._ diff --git a/packages/taco/src/conditions/schemas/variable-operation.ts b/packages/taco/src/conditions/schemas/variable-operation.ts index 520a5c34e..822c89fde 100644 --- a/packages/taco/src/conditions/schemas/variable-operation.ts +++ b/packages/taco/src/conditions/schemas/variable-operation.ts @@ -10,7 +10,7 @@ export const OPERATOR_FUNCTIONS = [ '%=', 'index', 'round', - // operations that don't require 2nd value, keep parameter for simplistic execution consistency + // operations that don't require 2nd value 'abs', 'avg', 'ceil', From 7133b2bb3a2473873fd58fe83da459b7dc6f7b83 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 27 Oct 2025 10:30:33 +0000 Subject: [PATCH 196/303] chore(release): release @nucypher/taco:0.7.0-alpha.3 --- packages/taco/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco/package.json b/packages/taco/package.json index 32222200f..16cce0b65 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco", - "version": "0.7.0-alpha.2", + "version": "0.7.0-alpha.3", "keywords": [ "taco", "threshold", From 2327bda7d73128d1fc7e76bfb35f6809c43390e3 Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Fri, 19 Sep 2025 15:33:50 +0200 Subject: [PATCH 197/303] feat: add AddressAllowlistCondition for wallet-based access control --- packages/taco/examples/conditions.ts | 26 +++ .../integration-test/encrypt-decrypt.test.ts | 44 ++-- .../taco/schema-docs/condition-schemas.md | 15 ++ .../taco/src/conditions/condition-factory.ts | 9 + packages/taco/src/conditions/condition.ts | 2 +- .../predefined/address-allowlist.ts | 49 +++++ .../taco/src/conditions/predefined/index.ts | 1 + .../conditions/schemas/address-allowlist.ts | 27 +++ .../schemas/export-for-zod-doc-gen.ts | 2 + packages/taco/src/conditions/schemas/utils.ts | 2 + .../predefined/address-allowlist.test.ts | 202 ++++++++++++++++++ packages/taco/test/test-utils.ts | 15 ++ pnpm-lock.yaml | 7 - pnpm-workspace.yaml | 2 + 14 files changed, 371 insertions(+), 32 deletions(-) create mode 100644 packages/taco/src/conditions/predefined/address-allowlist.ts create mode 100644 packages/taco/src/conditions/schemas/address-allowlist.ts create mode 100644 packages/taco/test/conditions/predefined/address-allowlist.test.ts diff --git a/packages/taco/examples/conditions.ts b/packages/taco/examples/conditions.ts index 19ed8890d..1a976518f 100644 --- a/packages/taco/examples/conditions.ts +++ b/packages/taco/examples/conditions.ts @@ -124,3 +124,29 @@ console.assert( myContractCallCondition.requiresAuthentication(), 'ContractCondition requires a signer', ); + +// Address Allowlist Condition Example +const addressAllowlistCondition = + new conditions.predefined.addressAllowlist.AddressAllowlistCondition({ + userAddress: ':userAddress', + addresses: [ + '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', + '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', + '0x0000000000000000000000000000000000000001', + ], + }); + +console.assert( + addressAllowlistCondition.requiresAuthentication(), + 'AddressAllowlistCondition requires authentication', +); + +// You can check if an address is allowed with the condition's toObj method +const addressToCheck = '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77'; +const addresses = addressAllowlistCondition.toObj().addresses; +// This would be checked by taco nodes after validating the wallet signature provided by encryptor (the value of the variable `addressToCheck`). +const isAllowed = addresses.includes(addressToCheck); +console.assert( + isAllowed, + 'Address should be in the addresses list but it is not.', +); diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index 0cbd94168..bf169593e 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -18,7 +18,6 @@ import { CompoundCondition } from '../src/conditions/compound-condition'; import { createSignatureForTestSecp256k1ECDSACondition, createTestSecp256k1ECDSACondition, - testContextVariableConditionObj, UINT256_MAX, } from '../test/test-utils'; @@ -303,25 +302,24 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const message = toBytes(messageString); // Create a context variable condition that checks if userAddress is in allowlist - const contextVariableCondition = - new conditions.base.contextVariable.ContextVariableCondition({ - ...testContextVariableConditionObj, - returnValueTest: { - comparator: 'in', - value: [ - CONSUMER_ADDRESS.toLowerCase(), - '0x0000000000000000000000000000000000000001', - ], - }, + + const addressAllowlistCondition = + new conditions.predefined.addressAllowlist.AddressAllowlistCondition({ + userAddress: USER_ADDRESS_PARAM_DEFAULT, + addresses: [ + CONSUMER_ADDRESS, + '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', // Some other address + '0x0000000000000000000000000000000000000001', // Another address + ], }); - expect(contextVariableCondition.requiresAuthentication()).toBe(true); + expect(addressAllowlistCondition.requiresAuthentication()).toBe(true); const messageKit = await encrypt( provider, DOMAIN, message, - contextVariableCondition, + addressAllowlistCondition, RITUAL_ID, encryptorSigner, ); @@ -361,23 +359,21 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const message = toBytes(messageString); // Create a context variable condition with specific allowed addresses - const restrictedContextVariableCondition = - new conditions.base.contextVariable.ContextVariableCondition({ - ...testContextVariableConditionObj, - returnValueTest: { - comparator: 'in', - value: [ - '0x0000000000000000000000000000000000000001', // Not our consumer address - '0x0000000000000000000000000000000000000002', - ], - }, + const restrictedAllowlistCondition = + new conditions.predefined.addressAllowlist.AddressAllowlistCondition({ + userAddress: USER_ADDRESS_PARAM_DEFAULT, + addresses: [ + // consumer address is not in the list + '0x0000000000000000000000000000000000000001', + '0x0000000000000000000000000000000000000002', + ], }); const messageKit = await encrypt( provider, DOMAIN, message, - restrictedContextVariableCondition, + restrictedAllowlistCondition, RITUAL_ID, encryptorSigner, ); diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index b4bbc3430..fb4ecff54 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -6,6 +6,7 @@ _Union of the following possible types:_ - [RpcCondition](#rpccondition) - [TimeCondition](#timecondition) +- [AddressAllowlistCondition](#addressallowlistcondition) - [ContextVariableCondition](#contextvariablecondition) - [ContractCondition](#contractcondition) - [EcdsaCondition](#ecdsacondition) @@ -395,6 +396,20 @@ Optional operations to perform on the obtained result _Array of at least 1 and at most 5 [VariableOperation](#variableoperation) items._ (_optional_) +## AddressAllowlistCondition + +Address Allowlist Condition for allowing decryption for specific wallet addresses. It is very handy when combined with other conditions. + +_Object containing the following properties:_ + +| Property | Description | Type | +| :----------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------- | +| **`conditionType`** (\*) | | `'address-allowlist'` | +| **`userAddress`** (\*) | This is a context variable that will be replaced at decryption time. It represents the Ethereum address of the requester attempting decryption. | [UserAddress](#useraddress) | +| **`addresses`** (\*) | List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form. | `Array` (_min: 1, max: 25_) | + +_(\*) Required._ + ## More resources For more information, please refer to the TACo documentation: diff --git a/packages/taco/src/conditions/condition-factory.ts b/packages/taco/src/conditions/condition-factory.ts index 8c302821b..fcccca0de 100644 --- a/packages/taco/src/conditions/condition-factory.ts +++ b/packages/taco/src/conditions/condition-factory.ts @@ -54,6 +54,11 @@ import { IfThenElseConditionProps, IfThenElseConditionType, } from './if-then-else-condition'; +import { + AddressAllowlistCondition, + AddressAllowlistConditionProps, + AddressAllowlistConditionType, +} from './predefined/address-allowlist'; import { SequentialCondition, SequentialConditionProps, @@ -71,6 +76,10 @@ export class ConditionFactory { return new RpcCondition(props as RpcConditionProps); case TimeConditionType: return new TimeCondition(props as TimeConditionProps); + case AddressAllowlistConditionType: + return new AddressAllowlistCondition( + props as AddressAllowlistConditionProps, + ); case ContractConditionType: return new ContractCondition(props as ContractConditionProps); case ECDSAConditionType: diff --git a/packages/taco/src/conditions/condition.ts b/packages/taco/src/conditions/condition.ts index 1db41e3b6..487e74665 100644 --- a/packages/taco/src/conditions/condition.ts +++ b/packages/taco/src/conditions/condition.ts @@ -10,7 +10,7 @@ export { baseConditionSchema } from './schemas/common'; type ConditionSchema = z.ZodSchema; export type ConditionProps = z.infer; -const ERR_INVALID_CONDITION = (error: z.ZodError) => +export const ERR_INVALID_CONDITION = (error: z.ZodError) => `Invalid condition: ${JSON.stringify(error.issues)}`; export class Condition { diff --git a/packages/taco/src/conditions/predefined/address-allowlist.ts b/packages/taco/src/conditions/predefined/address-allowlist.ts new file mode 100644 index 000000000..d2ba6363e --- /dev/null +++ b/packages/taco/src/conditions/predefined/address-allowlist.ts @@ -0,0 +1,49 @@ +import { + ContextVariableCondition, + ContextVariableConditionProps, + ContextVariableConditionType, +} from '../base/context-variable'; +import { Condition, ERR_INVALID_CONDITION } from '../condition'; +import { + AddressAllowlistConditionProps, + addressAllowlistConditionSchema, + AddressAllowlistConditionType, +} from '../schemas/address-allowlist'; +import { OmitConditionType } from '../shared'; + +export { + AddressAllowlistConditionProps, + AddressAllowlistConditionType, +} from '../schemas/address-allowlist'; + +/** + * A predefined condition that checks if a user's address is in an allowlist. + * This condition uses a ContextVariableCondition internally to check if the + * specified context variable (e.g., ':userAddress') is in the provided list + * of allowed addresses. + */ +export class AddressAllowlistCondition extends ContextVariableCondition { + constructor(value: OmitConditionType) { + const { data, error } = Condition.validate( + addressAllowlistConditionSchema, + { + conditionType: AddressAllowlistConditionType, + ...value, + }, + ); + if (error) { + throw new Error(ERR_INVALID_CONDITION(error)); + } + + const contextVariableCondition: ContextVariableConditionProps = { + conditionType: ContextVariableConditionType, + contextVariable: data.userAddress, + returnValueTest: { + comparator: 'in', + value: data.addresses, + }, + }; + + super(contextVariableCondition); + } +} diff --git a/packages/taco/src/conditions/predefined/index.ts b/packages/taco/src/conditions/predefined/index.ts index 7d29ceb02..cf099e6a2 100644 --- a/packages/taco/src/conditions/predefined/index.ts +++ b/packages/taco/src/conditions/predefined/index.ts @@ -1,2 +1,3 @@ +export * as addressAllowlist from './address-allowlist'; export * as erc20 from './erc20'; export * as erc721 from './erc721'; diff --git a/packages/taco/src/conditions/schemas/address-allowlist.ts b/packages/taco/src/conditions/schemas/address-allowlist.ts new file mode 100644 index 000000000..d240f3c00 --- /dev/null +++ b/packages/taco/src/conditions/schemas/address-allowlist.ts @@ -0,0 +1,27 @@ +import { EthAddressSchemaStrict } from '@nucypher/shared'; +import { z } from 'zod'; + +import { baseConditionSchema, UserAddressSchema } from './common'; + +export const AddressAllowlistConditionType = 'address-allowlist'; + +export const addressAllowlistConditionSchema = baseConditionSchema + .extend({ + conditionType: z.literal(AddressAllowlistConditionType), + userAddress: UserAddressSchema, + addresses: z + .array(EthAddressSchemaStrict) + .min(1, 'At least one address must be provided') + .max(25, 'A maximum of 25 addresses is allowed') + .describe( + 'List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form.', + ), + }) + .strict() + .describe( + 'Address Allowlist Condition for allowing decryption for specific wallet addresses. It is very handy when combined with other conditions.', + ); + +export type AddressAllowlistConditionProps = z.infer< + typeof addressAllowlistConditionSchema +>; diff --git a/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts b/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts index 2a061a74a..b350502cc 100755 --- a/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts +++ b/packages/taco/src/conditions/schemas/export-for-zod-doc-gen.ts @@ -24,3 +24,5 @@ export * from './sequential'; export * from './signing'; export * from './time'; export * from './variable-operation'; +// ts-unused-exports:disable-next-line - this comment line is added to prevent lint from changing or objecting the export order. +export * from './address-allowlist'; diff --git a/packages/taco/src/conditions/schemas/utils.ts b/packages/taco/src/conditions/schemas/utils.ts index dc72a3374..06374b0ad 100644 --- a/packages/taco/src/conditions/schemas/utils.ts +++ b/packages/taco/src/conditions/schemas/utils.ts @@ -2,6 +2,7 @@ import { z } from 'zod'; import { compoundConditionSchema } from '../compound-condition'; +import { addressAllowlistConditionSchema } from './address-allowlist'; import { contextVariableConditionSchema } from './context-variable'; import { contractConditionSchema } from './contract'; import { ecdsaConditionSchema } from './ecdsa'; @@ -21,6 +22,7 @@ export const anyConditionSchema: z.ZodSchema = z.lazy(() => z.union([ rpcConditionSchema, timeConditionSchema, + addressAllowlistConditionSchema, contextVariableConditionSchema, contractConditionSchema, ecdsaConditionSchema, diff --git a/packages/taco/test/conditions/predefined/address-allowlist.test.ts b/packages/taco/test/conditions/predefined/address-allowlist.test.ts new file mode 100644 index 000000000..0f669cee6 --- /dev/null +++ b/packages/taco/test/conditions/predefined/address-allowlist.test.ts @@ -0,0 +1,202 @@ +import { describe, expect, it } from 'vitest'; + +import { ContextVariableConditionType } from '../../../src/conditions/base/context-variable'; +import { + AddressAllowlistCondition, + AddressAllowlistConditionProps, +} from '../../../src/conditions/predefined/address-allowlist'; +import { addressAllowlistConditionSchema } from '../../../src/conditions/schemas/address-allowlist'; +import { testAddressAllowlistConditionObj } from '../../test-utils'; + +describe('AddressAllowlistCondition', () => { + describe('validate', () => { + it('accepts valid condition object', () => { + const result = AddressAllowlistCondition.validate( + addressAllowlistConditionSchema, + testAddressAllowlistConditionObj, + ); + + expect(result.error).toBeUndefined(); + expect(result.data).toEqual(testAddressAllowlistConditionObj); + }); + + it('fills in conditionType if missing', () => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { conditionType: _, ...withoutType } = + testAddressAllowlistConditionObj; + const condition = new AddressAllowlistCondition(withoutType); + + expect(condition.toObj().conditionType).toBe( + ContextVariableConditionType, + ); + }); + + it('rejects unknown fields', () => { + const conditionObj = { + ...testAddressAllowlistConditionObj, + unknownField: 'unknown', + } as unknown as AddressAllowlistConditionProps; + + const result = AddressAllowlistCondition.validate( + addressAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + // The error format for unknown fields is just a top-level _errors array + expect(result.error?.format()).toMatchObject({ + _errors: ["Unrecognized key(s) in object: 'unknownField'"], + }); + }); + + it('requires addresses to be present', () => { + const conditionObj = { + ...testAddressAllowlistConditionObj, + addresses: undefined, + } as unknown as AddressAllowlistConditionProps; + + const result = AddressAllowlistCondition.validate( + addressAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.format()).toHaveProperty('addresses'); + }); + + it('requires addresses to be an array', () => { + const conditionObj = { + ...testAddressAllowlistConditionObj, + addresses: 'not-an-array', + } as unknown as AddressAllowlistConditionProps; + + const result = AddressAllowlistCondition.validate( + addressAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.message).toContain('Expected array'); + }); + + it('requires at least one address', () => { + const conditionObj = { + ...testAddressAllowlistConditionObj, + addresses: [], + } as unknown as AddressAllowlistConditionProps; + + const result = AddressAllowlistCondition.validate( + addressAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.message).toContain( + 'At least one address must be provided', + ); + }); + + it('enforces a maximum of 25 addresses', () => { + // Create an array of 26 valid Ethereum addresses + const tooManyAddresses = Array(26) + .fill(0) + .map((_, i) => `0x${(i + 10).toString().padStart(40, '0')}`); + + const conditionObj = { + ...testAddressAllowlistConditionObj, + addresses: tooManyAddresses, + } as unknown as AddressAllowlistConditionProps; + + const result = AddressAllowlistCondition.validate( + addressAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.message).toContain( + 'A maximum of 25 addresses is allowed', + ); + }); + + it('requires addresses to be valid Ethereum addresses', () => { + const conditionObj = { + ...testAddressAllowlistConditionObj, + addresses: ['not-an-eth-address'], + } as unknown as AddressAllowlistConditionProps; + + const result = AddressAllowlistCondition.validate( + addressAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.message).toContain('Invalid Ethereum address'); + }); + + it('requires addresses to be checksummed', () => { + const conditionObj = { + ...testAddressAllowlistConditionObj, + // Lowercase version of a valid address + addresses: ['0x1e988ba4692e52bc50b375bcc8585b95c48aad77'], + } as unknown as AddressAllowlistConditionProps; + + const result = AddressAllowlistCondition.validate( + addressAllowlistConditionSchema, + conditionObj, + ); + + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error?.message).toContain( + 'Invalid Ethereum address - it must be valid and checksummed', + ); + }); + }); + + describe('constructor', () => { + it('creates a condition from a valid object', () => { + const condition = new AddressAllowlistCondition( + testAddressAllowlistConditionObj, + ); + expect(condition.toObj()).toEqual({ + conditionType: 'context-variable', + contextVariable: ':userAddress', + returnValueTest: { + comparator: 'in', + value: [ + '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', + '0x0000000000000000000000000000000000000001', + '0x0000000000000000000000000000000000000002', + ], + }, + }); + }); + + it('throws an error for invalid condition', () => { + const invalidCondition = () => { + return new AddressAllowlistCondition({ + userAddress: ':userAddress', + addresses: [], + }); + }; + + // The error is wrapped in a general Error with message containing the Zod validation error + expect(invalidCondition).toThrow(/Invalid condition/); + }); + }); + + describe('requiresAuthentication', () => { + it('returns true', () => { + const condition = new AddressAllowlistCondition( + testAddressAllowlistConditionObj, + ); + expect(condition.requiresAuthentication()).toBe(true); + }); + }); +}); diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index a6dfb8f7f..6d61f3646 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -88,6 +88,10 @@ import { CompoundConditionType, } from '../src/conditions/compound-condition'; import { ConditionExpression } from '../src/conditions/condition-expr'; +import { + AddressAllowlistConditionProps, + AddressAllowlistConditionType, +} from '../src/conditions/predefined/address-allowlist'; import { ERC721Balance } from '../src/conditions/predefined/erc721'; import { JsonRpcConditionProps, @@ -280,6 +284,17 @@ export const testTimeConditionObj: TimeConditionProps = { chain: TEST_CHAIN_ID, }; +export const testAddressAllowlistConditionObj: AddressAllowlistConditionProps = + { + conditionType: AddressAllowlistConditionType, + userAddress: ':userAddress', + addresses: [ + '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', + '0x0000000000000000000000000000000000000001', + '0x0000000000000000000000000000000000000002', + ], + }; + export const testJsonConditionObj: JsonConditionProps = { conditionType: JsonConditionType, data: ':jsonData', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index df39bdf9c..04107bb9f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -559,8 +559,6 @@ importers: specifier: ^8.3.2 version: 8.3.2(typescript@5.9.3) - packages/shared/dist/es: {} - packages/taco: dependencies: '@astronautlabs/jsonpath': @@ -623,10 +621,6 @@ importers: specifier: workspace:* version: link:../test-utils - packages/taco-auth/dist/es: {} - - packages/taco/dist/es: {} - packages/test-utils: dependencies: '@nucypher/nucypher-core': @@ -8247,7 +8241,6 @@ packages: engines: {node: '>=0.6.0', teleport: '>=0.2.0'} deprecated: |- You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other. - (For a CapTP with native promises, see @endo/eventual-send and @endo/captp) qs@6.14.2: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 58ec23e7a..3f746d1c1 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -3,4 +3,6 @@ packages: - 'demos/**/*' - 'examples/**/*' - 'packages/**/*' + - '!packages/*/dist/**' + - '!packages/*/node_modules/**' - 'scripts/**/*' From c00b8e65f2cbb32fb1f8d1e7f866cb3332ca20fd Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Thu, 2 Oct 2025 18:23:00 +0200 Subject: [PATCH 198/303] chore: update address allowlist condition example and docs --- packages/taco/examples/conditions.ts | 2 +- packages/taco/schema-docs/condition-schemas.md | 2 +- packages/taco/src/conditions/schemas/address-allowlist.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/taco/examples/conditions.ts b/packages/taco/examples/conditions.ts index 1a976518f..1eeb5e1ad 100644 --- a/packages/taco/examples/conditions.ts +++ b/packages/taco/examples/conditions.ts @@ -143,7 +143,7 @@ console.assert( // You can check if an address is allowed with the condition's toObj method const addressToCheck = '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77'; -const addresses = addressAllowlistCondition.toObj().addresses; +const addresses = addressAllowlistCondition.toObj().returnValueTest.value; // This would be checked by taco nodes after validating the wallet signature provided by encryptor (the value of the variable `addressToCheck`). const isAllowed = addresses.includes(addressToCheck); console.assert( diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index fb4ecff54..abc283493 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -398,7 +398,7 @@ _Array of at least 1 and at most 5 [VariableOperation](#variableoperation) ite ## AddressAllowlistCondition -Address Allowlist Condition for allowing decryption for specific wallet addresses. It is very handy when combined with other conditions. +Address Allowlist Condition for allowing decryption for specific wallet addresses. _Object containing the following properties:_ diff --git a/packages/taco/src/conditions/schemas/address-allowlist.ts b/packages/taco/src/conditions/schemas/address-allowlist.ts index d240f3c00..04045ea30 100644 --- a/packages/taco/src/conditions/schemas/address-allowlist.ts +++ b/packages/taco/src/conditions/schemas/address-allowlist.ts @@ -19,7 +19,7 @@ export const addressAllowlistConditionSchema = baseConditionSchema }) .strict() .describe( - 'Address Allowlist Condition for allowing decryption for specific wallet addresses. It is very handy when combined with other conditions.', + 'Address Allowlist Condition for allowing decryption for specific wallet addresses.', ); export type AddressAllowlistConditionProps = z.infer< From 641ef9aec0b8bdd19cbc756b1f6d78e8ec7bbd38 Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Wed, 22 Oct 2025 19:40:57 +0200 Subject: [PATCH 199/303] refactor: simplify AddressAllowlistCondition to accept array input and auto-transform to ContextVariableCondition --- packages/taco/examples/conditions.ts | 13 ++--- .../integration-test/encrypt-decrypt.test.ts | 26 ++++----- .../taco/schema-docs/condition-schemas.md | 13 +---- .../taco/src/conditions/condition-factory.ts | 9 --- .../predefined/address-allowlist.ts | 35 +++++------ .../conditions/schemas/address-allowlist.ts | 23 ++------ packages/taco/src/conditions/schemas/utils.ts | 2 - .../predefined/address-allowlist.test.ts | 58 +++++++------------ packages/taco/test/test-utils.ts | 19 ++---- 9 files changed, 64 insertions(+), 134 deletions(-) diff --git a/packages/taco/examples/conditions.ts b/packages/taco/examples/conditions.ts index 1eeb5e1ad..a69c6cc00 100644 --- a/packages/taco/examples/conditions.ts +++ b/packages/taco/examples/conditions.ts @@ -127,14 +127,11 @@ console.assert( // Address Allowlist Condition Example const addressAllowlistCondition = - new conditions.predefined.addressAllowlist.AddressAllowlistCondition({ - userAddress: ':userAddress', - addresses: [ - '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', - '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', - '0x0000000000000000000000000000000000000001', - ], - }); + new conditions.predefined.addressAllowlist.AddressAllowlistCondition([ + '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', + '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', + '0x0000000000000000000000000000000000000001', + ]); console.assert( addressAllowlistCondition.requiresAuthentication(), diff --git a/packages/taco/integration-test/encrypt-decrypt.test.ts b/packages/taco/integration-test/encrypt-decrypt.test.ts index bf169593e..f1676dc20 100644 --- a/packages/taco/integration-test/encrypt-decrypt.test.ts +++ b/packages/taco/integration-test/encrypt-decrypt.test.ts @@ -304,14 +304,11 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( // Create a context variable condition that checks if userAddress is in allowlist const addressAllowlistCondition = - new conditions.predefined.addressAllowlist.AddressAllowlistCondition({ - userAddress: USER_ADDRESS_PARAM_DEFAULT, - addresses: [ - CONSUMER_ADDRESS, - '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', // Some other address - '0x0000000000000000000000000000000000000001', // Another address - ], - }); + new conditions.predefined.addressAllowlist.AddressAllowlistCondition([ + CONSUMER_ADDRESS, + '0x742d35Cc6634C0532925a3b844Bc454e4438f44e', // Some other address + '0x0000000000000000000000000000000000000001', // Another address + ]); expect(addressAllowlistCondition.requiresAuthentication()).toBe(true); @@ -360,14 +357,11 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( // Create a context variable condition with specific allowed addresses const restrictedAllowlistCondition = - new conditions.predefined.addressAllowlist.AddressAllowlistCondition({ - userAddress: USER_ADDRESS_PARAM_DEFAULT, - addresses: [ - // consumer address is not in the list - '0x0000000000000000000000000000000000000001', - '0x0000000000000000000000000000000000000002', - ], - }); + new conditions.predefined.addressAllowlist.AddressAllowlistCondition([ + // consumer address is not in the list + '0x0000000000000000000000000000000000000001', + '0x0000000000000000000000000000000000000002', + ]); const messageKit = await encrypt( provider, diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index abc283493..0cc23c753 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -6,7 +6,6 @@ _Union of the following possible types:_ - [RpcCondition](#rpccondition) - [TimeCondition](#timecondition) -- [AddressAllowlistCondition](#addressallowlistcondition) - [ContextVariableCondition](#contextvariablecondition) - [ContractCondition](#contractcondition) - [EcdsaCondition](#ecdsacondition) @@ -398,17 +397,9 @@ _Array of at least 1 and at most 5 [VariableOperation](#variableoperation) ite ## AddressAllowlistCondition -Address Allowlist Condition for allowing decryption for specific wallet addresses. +List of allowed wallet addresses. Addresses should be provided in checksummed form. -_Object containing the following properties:_ - -| Property | Description | Type | -| :----------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------- | -| **`conditionType`** (\*) | | `'address-allowlist'` | -| **`userAddress`** (\*) | This is a context variable that will be replaced at decryption time. It represents the Ethereum address of the requester attempting decryption. | [UserAddress](#useraddress) | -| **`addresses`** (\*) | List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form. | `Array` (_min: 1, max: 25_) | - -_(\*) Required._ +_Array of at least 1 and at most 25 `string` items._ ## More resources diff --git a/packages/taco/src/conditions/condition-factory.ts b/packages/taco/src/conditions/condition-factory.ts index fcccca0de..8c302821b 100644 --- a/packages/taco/src/conditions/condition-factory.ts +++ b/packages/taco/src/conditions/condition-factory.ts @@ -54,11 +54,6 @@ import { IfThenElseConditionProps, IfThenElseConditionType, } from './if-then-else-condition'; -import { - AddressAllowlistCondition, - AddressAllowlistConditionProps, - AddressAllowlistConditionType, -} from './predefined/address-allowlist'; import { SequentialCondition, SequentialConditionProps, @@ -76,10 +71,6 @@ export class ConditionFactory { return new RpcCondition(props as RpcConditionProps); case TimeConditionType: return new TimeCondition(props as TimeConditionProps); - case AddressAllowlistConditionType: - return new AddressAllowlistCondition( - props as AddressAllowlistConditionProps, - ); case ContractConditionType: return new ContractCondition(props as ContractConditionProps); case ECDSAConditionType: diff --git a/packages/taco/src/conditions/predefined/address-allowlist.ts b/packages/taco/src/conditions/predefined/address-allowlist.ts index d2ba6363e..d596090ca 100644 --- a/packages/taco/src/conditions/predefined/address-allowlist.ts +++ b/packages/taco/src/conditions/predefined/address-allowlist.ts @@ -1,49 +1,42 @@ +import { USER_ADDRESS_PARAM_DEFAULT } from '@nucypher/taco-auth'; + import { ContextVariableCondition, ContextVariableConditionProps, ContextVariableConditionType, } from '../base/context-variable'; -import { Condition, ERR_INVALID_CONDITION } from '../condition'; +import { ERR_INVALID_CONDITION } from '../condition'; import { AddressAllowlistConditionProps, addressAllowlistConditionSchema, - AddressAllowlistConditionType, } from '../schemas/address-allowlist'; -import { OmitConditionType } from '../shared'; -export { - AddressAllowlistConditionProps, - AddressAllowlistConditionType, -} from '../schemas/address-allowlist'; +export { AddressAllowlistConditionProps } from '../schemas/address-allowlist'; /** - * A predefined condition that checks if a user's address is in an allowlist. - * This condition uses a ContextVariableCondition internally to check if the - * specified context variable (e.g., ':userAddress') is in the provided list - * of allowed addresses. + * A Client-side condition that checks if a user's address is in an allowlist and transforms the object into `ContextVariableCondition`. + * The nodes process this as a standard context variable that checks if the user's address is in the allowlist. + * @remark This condition doesn’t have a unique type of its own; it is simply a wrapper for creating a `ContextVariableCondition`. */ export class AddressAllowlistCondition extends ContextVariableCondition { - constructor(value: OmitConditionType) { - const { data, error } = Condition.validate( + constructor(value: AddressAllowlistConditionProps) { + const { data, error } = AddressAllowlistCondition.validate( addressAllowlistConditionSchema, - { - conditionType: AddressAllowlistConditionType, - ...value, - }, + value, ); if (error) { throw new Error(ERR_INVALID_CONDITION(error)); } - const contextVariableCondition: ContextVariableConditionProps = { + const contextVariableConditionProps: ContextVariableConditionProps = { conditionType: ContextVariableConditionType, - contextVariable: data.userAddress, + contextVariable: USER_ADDRESS_PARAM_DEFAULT, returnValueTest: { comparator: 'in', - value: data.addresses, + value: data, }, }; - super(contextVariableCondition); + super(contextVariableConditionProps); } } diff --git a/packages/taco/src/conditions/schemas/address-allowlist.ts b/packages/taco/src/conditions/schemas/address-allowlist.ts index 04045ea30..074515978 100644 --- a/packages/taco/src/conditions/schemas/address-allowlist.ts +++ b/packages/taco/src/conditions/schemas/address-allowlist.ts @@ -1,25 +1,12 @@ import { EthAddressSchemaStrict } from '@nucypher/shared'; import { z } from 'zod'; -import { baseConditionSchema, UserAddressSchema } from './common'; - -export const AddressAllowlistConditionType = 'address-allowlist'; - -export const addressAllowlistConditionSchema = baseConditionSchema - .extend({ - conditionType: z.literal(AddressAllowlistConditionType), - userAddress: UserAddressSchema, - addresses: z - .array(EthAddressSchemaStrict) - .min(1, 'At least one address must be provided') - .max(25, 'A maximum of 25 addresses is allowed') - .describe( - 'List of wallet addresses allowed to decrypt. Addresses should be provided in checksummed form.', - ), - }) - .strict() +export const addressAllowlistConditionSchema = z + .array(EthAddressSchemaStrict) + .min(1, 'At least one address must be provided') + .max(25, 'A maximum of 25 addresses is allowed') .describe( - 'Address Allowlist Condition for allowing decryption for specific wallet addresses.', + 'List of allowed wallet addresses. Addresses should be provided in checksummed form.', ); export type AddressAllowlistConditionProps = z.infer< diff --git a/packages/taco/src/conditions/schemas/utils.ts b/packages/taco/src/conditions/schemas/utils.ts index 06374b0ad..dc72a3374 100644 --- a/packages/taco/src/conditions/schemas/utils.ts +++ b/packages/taco/src/conditions/schemas/utils.ts @@ -2,7 +2,6 @@ import { z } from 'zod'; import { compoundConditionSchema } from '../compound-condition'; -import { addressAllowlistConditionSchema } from './address-allowlist'; import { contextVariableConditionSchema } from './context-variable'; import { contractConditionSchema } from './contract'; import { ecdsaConditionSchema } from './ecdsa'; @@ -22,7 +21,6 @@ export const anyConditionSchema: z.ZodSchema = z.lazy(() => z.union([ rpcConditionSchema, timeConditionSchema, - addressAllowlistConditionSchema, contextVariableConditionSchema, contractConditionSchema, ecdsaConditionSchema, diff --git a/packages/taco/test/conditions/predefined/address-allowlist.test.ts b/packages/taco/test/conditions/predefined/address-allowlist.test.ts index 0f669cee6..0bfb7b341 100644 --- a/packages/taco/test/conditions/predefined/address-allowlist.test.ts +++ b/packages/taco/test/conditions/predefined/address-allowlist.test.ts @@ -20,11 +20,10 @@ describe('AddressAllowlistCondition', () => { expect(result.data).toEqual(testAddressAllowlistConditionObj); }); - it('fills in conditionType if missing', () => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { conditionType: _, ...withoutType } = - testAddressAllowlistConditionObj; - const condition = new AddressAllowlistCondition(withoutType); + it('transforms to ContextVariableCondition with correct conditionType', () => { + const condition = new AddressAllowlistCondition( + testAddressAllowlistConditionObj, + ); expect(condition.toObj().conditionType).toBe( ContextVariableConditionType, @@ -46,15 +45,13 @@ describe('AddressAllowlistCondition', () => { expect(result.data).toBeUndefined(); // The error format for unknown fields is just a top-level _errors array expect(result.error?.format()).toMatchObject({ - _errors: ["Unrecognized key(s) in object: 'unknownField'"], + _errors: ['Expected array, received object'], }); }); it('requires addresses to be present', () => { - const conditionObj = { - ...testAddressAllowlistConditionObj, - addresses: undefined, - } as unknown as AddressAllowlistConditionProps; + const conditionObj = + undefined as unknown as AddressAllowlistConditionProps; const result = AddressAllowlistCondition.validate( addressAllowlistConditionSchema, @@ -63,14 +60,14 @@ describe('AddressAllowlistCondition', () => { expect(result.error).toBeDefined(); expect(result.data).toBeUndefined(); - expect(result.error?.format()).toHaveProperty('addresses'); + expect(result.error?.format()).toMatchObject({ + _errors: ['Required'], + }); }); it('requires addresses to be an array', () => { - const conditionObj = { - ...testAddressAllowlistConditionObj, - addresses: 'not-an-array', - } as unknown as AddressAllowlistConditionProps; + const conditionObj = + 'not-an-array' as unknown as AddressAllowlistConditionProps; const result = AddressAllowlistCondition.validate( addressAllowlistConditionSchema, @@ -83,10 +80,7 @@ describe('AddressAllowlistCondition', () => { }); it('requires at least one address', () => { - const conditionObj = { - ...testAddressAllowlistConditionObj, - addresses: [], - } as unknown as AddressAllowlistConditionProps; + const conditionObj = [] as unknown as AddressAllowlistConditionProps; const result = AddressAllowlistCondition.validate( addressAllowlistConditionSchema, @@ -106,10 +100,8 @@ describe('AddressAllowlistCondition', () => { .fill(0) .map((_, i) => `0x${(i + 10).toString().padStart(40, '0')}`); - const conditionObj = { - ...testAddressAllowlistConditionObj, - addresses: tooManyAddresses, - } as unknown as AddressAllowlistConditionProps; + const conditionObj = + tooManyAddresses as unknown as AddressAllowlistConditionProps; const result = AddressAllowlistCondition.validate( addressAllowlistConditionSchema, @@ -124,10 +116,9 @@ describe('AddressAllowlistCondition', () => { }); it('requires addresses to be valid Ethereum addresses', () => { - const conditionObj = { - ...testAddressAllowlistConditionObj, - addresses: ['not-an-eth-address'], - } as unknown as AddressAllowlistConditionProps; + const conditionObj = [ + 'not-an-eth-address', + ] as unknown as AddressAllowlistConditionProps; const result = AddressAllowlistCondition.validate( addressAllowlistConditionSchema, @@ -140,11 +131,9 @@ describe('AddressAllowlistCondition', () => { }); it('requires addresses to be checksummed', () => { - const conditionObj = { - ...testAddressAllowlistConditionObj, - // Lowercase version of a valid address - addresses: ['0x1e988ba4692e52bc50b375bcc8585b95c48aad77'], - } as unknown as AddressAllowlistConditionProps; + const conditionObj = [ + '0x1e988ba4692e52bc50b375bcc8585b95c48aad77', + ] as unknown as AddressAllowlistConditionProps; const result = AddressAllowlistCondition.validate( addressAllowlistConditionSchema, @@ -180,10 +169,7 @@ describe('AddressAllowlistCondition', () => { it('throws an error for invalid condition', () => { const invalidCondition = () => { - return new AddressAllowlistCondition({ - userAddress: ':userAddress', - addresses: [], - }); + return new AddressAllowlistCondition([]); }; // The error is wrapped in a general Error with message containing the Zod validation error diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 6d61f3646..9b2212f3b 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -88,10 +88,7 @@ import { CompoundConditionType, } from '../src/conditions/compound-condition'; import { ConditionExpression } from '../src/conditions/condition-expr'; -import { - AddressAllowlistConditionProps, - AddressAllowlistConditionType, -} from '../src/conditions/predefined/address-allowlist'; +import { AddressAllowlistConditionProps } from '../src/conditions/predefined/address-allowlist'; import { ERC721Balance } from '../src/conditions/predefined/erc721'; import { JsonRpcConditionProps, @@ -285,15 +282,11 @@ export const testTimeConditionObj: TimeConditionProps = { }; export const testAddressAllowlistConditionObj: AddressAllowlistConditionProps = - { - conditionType: AddressAllowlistConditionType, - userAddress: ':userAddress', - addresses: [ - '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', - '0x0000000000000000000000000000000000000001', - '0x0000000000000000000000000000000000000002', - ], - }; + [ + '0x1e988ba4692e52Bc50b375bcC8585b95c48AaD77', + '0x0000000000000000000000000000000000000001', + '0x0000000000000000000000000000000000000002', + ]; export const testJsonConditionObj: JsonConditionProps = { conditionType: JsonConditionType, From eba5832b389bc39a7cc833d50b97525a2c1ba4a7 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 22 Oct 2025 18:44:43 -0400 Subject: [PATCH 200/303] Modify `nucypher-core` dependency to use local dependency so that the latest changes from `nucypher-core` can be used. --- package.json | 4 ++-- packages/shared/package.json | 2 +- packages/taco/package.json | 2 +- pnpm-lock.yaml | 32 ++++++++++++++------------------ 4 files changed, 18 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index e5c742053..e6a583769 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ }, "dependencies": { "@changesets/cli": "^2.28.1", - "@nucypher/nucypher-core": "^0.14.5", + "@nucypher/nucypher-core": "link:../nucypher-core/nucypher-core-wasm-bundler", "ethers": "^5.8.0" }, "devDependencies": { @@ -65,7 +65,7 @@ ] }, "overrides": { - "@nucypher/nucypher-core": "^0.14.5", + "@nucypher/nucypher-core": "link:../nucypher-core/nucypher-core-wasm-bundler", "glob-parent@<5.1.2": ">=5.1.2", "node-forge@<1.0.0": ">=1.0.0", "node-forge@<1.3.0": ">=1.3.0", diff --git a/packages/shared/package.json b/packages/shared/package.json index b1b2e4379..9839c6575 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -43,7 +43,7 @@ "@ethersproject/abi": "^5.8.0", "@ethersproject/providers": "^5.8.0", "@nucypher/nucypher-contracts": "0.26.0-alpha.1", - "@nucypher/nucypher-core": "^0.14.5", + "@nucypher/nucypher-core": "link:../../../nucypher-core/nucypher-core-wasm-bundler", "axios": "^1.11.0", "deep-equal": "^2.2.3", "ethers": "^5.8.0", diff --git a/packages/taco/package.json b/packages/taco/package.json index 16cce0b65..f916773c2 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -42,7 +42,7 @@ }, "dependencies": { "@astronautlabs/jsonpath": "^1.1.2", - "@nucypher/nucypher-core": "^0.14.5", + "@nucypher/nucypher-core": "link:../../../nucypher-core/nucypher-core-wasm-bundler", "@nucypher/shared": "workspace:*", "@nucypher/taco-auth": "workspace:*", "ethers": "^5.8.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 04107bb9f..d4493e84a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,7 @@ settings: excludeLinksFromLockfile: false overrides: - '@nucypher/nucypher-core': ^0.14.5 + '@nucypher/nucypher-core': link:../nucypher-core/nucypher-core-wasm-bundler glob-parent@<5.1.2: '>=5.1.2' node-forge@<1.0.0: '>=1.0.0' node-forge@<1.3.0: '>=1.3.0' @@ -19,8 +19,8 @@ importers: specifier: ^2.28.1 version: 2.30.0(@types/node@24.3.0) '@nucypher/nucypher-core': - specifier: ^0.14.5 - version: 0.14.5 + specifier: link:../nucypher-core/nucypher-core-wasm-bundler + version: link:../nucypher-core/nucypher-core-wasm-bundler ethers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -491,8 +491,8 @@ importers: packages/pre: dependencies: '@nucypher/nucypher-core': - specifier: ^0.14.5 - version: 0.14.5 + specifier: link:../../../nucypher-core/nucypher-core-wasm-bundler + version: link:../../../nucypher-core/nucypher-core-wasm-bundler '@nucypher/shared': specifier: workspace:* version: link:../shared @@ -516,8 +516,8 @@ importers: specifier: 0.26.0-alpha.1 version: 0.26.0-alpha.1 '@nucypher/nucypher-core': - specifier: ^0.14.5 - version: 0.14.5 + specifier: link:../../../nucypher-core/nucypher-core-wasm-bundler + version: link:../../../nucypher-core/nucypher-core-wasm-bundler axios: specifier: ^1.11.0 version: 1.15.0 @@ -565,8 +565,8 @@ importers: specifier: ^1.1.2 version: 1.1.2 '@nucypher/nucypher-core': - specifier: ^0.14.5 - version: 0.14.5 + specifier: link:../../../nucypher-core/nucypher-core-wasm-bundler + version: link:../../../nucypher-core/nucypher-core-wasm-bundler '@nucypher/shared': specifier: workspace:* version: link:../shared @@ -624,8 +624,8 @@ importers: packages/test-utils: dependencies: '@nucypher/nucypher-core': - specifier: ^0.14.5 - version: 0.14.5 + specifier: link:../../../nucypher-core/nucypher-core-wasm-bundler + version: link:../../../nucypher-core/nucypher-core-wasm-bundler '@nucypher/shared': specifier: workspace:* version: link:../shared @@ -2707,9 +2707,6 @@ packages: '@nucypher/nucypher-contracts@0.26.0-alpha.1': resolution: {integrity: sha512-ISS66SyKbDLXFF88Z6k8Tnc/L6Shx6tq22CjPpovbSD2PGS/UzE3uDxvFTKZfgcIJYsi7GV/ho2Brsx4sHYTLg==} - '@nucypher/nucypher-core@0.14.5': - resolution: {integrity: sha512-Q3kBuJL0qtTtnxrM5DEQauQUvDlXmwubm9u1h7gbyLhs+aZNC9WDyjEUbE43+uahlHu4k1hKEMxD1gjV165ChA==} - '@nucypher/shared@0.5.0': resolution: {integrity: sha512-Y+0oEgVtoud4BP/pvj2elPm5igrQ8AAUwYYmUiLpXNqQMRF4zFnYaGbl+xhKk45CYG8S9cDKJEN8nopzVADTNw==} engines: {node: '>=18', pnpm: '>=8.0.0'} @@ -8241,6 +8238,7 @@ packages: engines: {node: '>=0.6.0', teleport: '>=0.2.0'} deprecated: |- You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other. + (For a CapTP with native promises, see @endo/eventual-send and @endo/captp) qs@6.14.2: @@ -12479,14 +12477,12 @@ snapshots: '@nucypher/nucypher-contracts@0.26.0-alpha.1': {} - '@nucypher/nucypher-core@0.14.5': {} - '@nucypher/shared@0.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: '@ethersproject/abi': 5.8.0 '@ethersproject/providers': 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@nucypher/nucypher-contracts': 0.25.0 - '@nucypher/nucypher-core': 0.14.5 + '@nucypher/nucypher-core': link:../nucypher-core/nucypher-core-wasm-bundler axios: 1.15.0 deep-equal: 2.2.3 ethers: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -12512,7 +12508,7 @@ snapshots: '@nucypher/taco@0.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: '@astronautlabs/jsonpath': 1.1.2 - '@nucypher/nucypher-core': 0.14.5 + '@nucypher/nucypher-core': link:../nucypher-core/nucypher-core-wasm-bundler '@nucypher/shared': 0.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@nucypher/taco-auth': 0.3.0(bufferutil@4.1.0)(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(utf-8-validate@6.0.6) ethers: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) From 7260f87aa904894366fef607e6cd62b8a87dd518 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 23 Oct 2025 16:14:04 -0400 Subject: [PATCH 201/303] Update Porter module to use `nucypher-core` signature request and response objects. --- packages/shared/src/porter.ts | 79 ++++----- packages/shared/test/porter.test.ts | 266 ++++++++++++---------------- 2 files changed, 148 insertions(+), 197 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index e658c19a2..796829d34 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -4,7 +4,9 @@ import { EncryptedThresholdDecryptionResponse, PublicKey, RetrievalKit, + SignatureResponse, TreasureMap, + UserOperationSignatureRequest, } from '@nucypher/nucypher-core'; import axios, { AxiosRequestConfig, @@ -148,11 +150,20 @@ type PostTacoDecryptResponse = { }; export type TacoDecryptResult = { - encryptedResponses: Record; - errors: Record; + encryptedResponses: Record< + ChecksumAddress, + EncryptedThresholdDecryptionResponse + >; + errors: Record; }; // Signing types + +type PostTacoSignRequest = { + readonly signing_requests: Record; + readonly threshold: number; +}; + type TacoSignResponse = { readonly result: { readonly signing_results: { @@ -172,32 +183,10 @@ export type TacoSignature = { }; export type TacoSignResult = { - signingResults: { [ursulaAddress: string]: TacoSignature }; - errors: Record; + signingResults: Record; + errors: Record; }; -function decodeSignature( - signerAddress: string, - signatureB64: string, -): { result?: TacoSignature; error?: string } { - try { - const decodedData = JSON.parse( - new TextDecoder().decode(fromBase64(signatureB64)), - ); - return { - result: { - messageHash: decodedData.message_hash, - signature: decodedData.signature, - signerAddress, - }, - }; - } catch (error) { - return { - error: `Failed to decode signature: ${error}`, - }; - } -} - export class PorterClient { readonly porterUrls: URL[]; @@ -345,11 +334,16 @@ export class PorterClient { } public async signUserOp( - signingRequests: Record, + signingRequests: Record, threshold: number, ): Promise { - const data: Record = { - signing_requests: signingRequests, + const data: PostTacoSignRequest = { + signing_requests: Object.fromEntries( + Object.entries(signingRequests).map(([ursula, signingRequest]) => [ + ursula, + toBase64(signingRequest.toBytes()), + ]), + ), threshold: threshold, }; @@ -358,27 +352,26 @@ export class PorterClient { method: 'post', data, }); - const { signatures, errors } = resp.data.result.signing_results; - const allErrors: Record = { ...errors }; const signingResults: { [ursulaAddress: string]: TacoSignature } = {}; - for (const [ursulaAddress, [signerAddress, signatureB64]] of Object.entries( - signatures || {}, - )) { - const decoded = decodeSignature(signerAddress, signatureB64); - if (decoded.error) { - // issue with decoding signature, add to errors - allErrors[ursulaAddress] = decoded.error; - continue; - } - // Always include all decoded signatures in signingResults - signingResults[ursulaAddress] = decoded.result!; + for (const [ + ursulaAddress, + [signerAddress, signatureResponseBase64], + ] of Object.entries(signatures || {})) { + const signatureResponse = SignatureResponse.fromBytes( + fromBase64(signatureResponseBase64), + ); + signingResults[ursulaAddress] = { + messageHash: `0x${toHexString(signatureResponse.hash)}`, + signature: `0x${toHexString(signatureResponse.signature)}`, + signerAddress, + }; } return { signingResults, - errors: allErrors, + errors, }; } } diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index ccda73b13..6fa6d7b4f 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -2,6 +2,12 @@ import { fakeUrsulas } from '@nucypher/test-utils'; import axios, { HttpStatusCode } from 'axios'; import { beforeAll, describe, expect, it, MockInstance, vi } from 'vitest'; +import { + SignatureResponse, + UserOperation, + UserOperationSignatureRequest, +} from '@nucypher/nucypher-core'; + import { domains, getPorterUris, @@ -13,6 +19,7 @@ import { toHexString, Ursula, } from '../src'; +import { fromHexString } from '../src/utils'; const fakePorterUris = [ 'https://_this_should_crash.com/', @@ -57,14 +64,13 @@ const createMockSignResponse = (errorCase?: boolean) => ({ signatures: errorCase ? { '0xabcd': [ - '0xefgh', + '0xefff', toBase64( - new TextEncoder().encode( - JSON.stringify({ - message_hash: '0x1234', - signature: '0xbeef', - }), - ), + new SignatureResponse( + fromHexString('0x1234'), + fromHexString('0xbeef'), + 0, + ).toBytes(), ), ], } @@ -72,23 +78,21 @@ const createMockSignResponse = (errorCase?: boolean) => ({ '0x1234': [ '0x5678', toBase64( - new TextEncoder().encode( - JSON.stringify({ - message_hash: '0x1234', - signature: '0xdead', - }), - ), + new SignatureResponse( + fromHexString('0x1234'), + fromHexString('0xdead'), + 0, + ).toBytes(), ), ], '0xabcd': [ - '0xefgh', + '0xefff', toBase64( - new TextEncoder().encode( - JSON.stringify({ - message_hash: '0x1234', - signature: '0xbeef', - }), - ), + new SignatureResponse( + fromHexString('0x1234'), + fromHexString('0xbeef'), + 0, + ).toBytes(), ), ], }, @@ -195,31 +199,34 @@ describe('PorterClient Signing', () => { }); describe('signUserOp', () => { - const mockPackedUserOp = { - sender: '0x1234', - nonce: '0x1', - factory: '0x0', - factoryData: '0x', - callData: '0xabc', - callGasLimit: '0x20000', - verificationGasLimit: '0x15000', - preVerificationGas: '0x1000', - maxFeePerGas: '0xabc', - maxPriorityFeePerGas: '0x123', - paymaster: '0x0', - paymasterVerificationGasLimit: '0x0', - paymasterPostOpGasLimit: '0x0', - paymasterData: '0x', - signature: '0x', - }; + // since this uses wasm it must be called after initialize (beforeAll()) so we use a factory function + const createUserSignatureRequest = () => + new UserOperationSignatureRequest( + new UserOperation( + '0x000000000000000000000000000000000000000a', + BigInt(0), // nonce + fromHexString('0xabc'), // callData + BigInt(0), // callGasLimit + BigInt(0), // verificationGasLimit + BigInt(0), // preVerificationGasLimit + BigInt(0), // maxFeePerGas + BigInt(0), // maxPriorityFeePerGas + ), + 1, // cohort ID + BigInt(1), // chain ID + '0.8.0', + null, + ); it('should successfully sign a UserOperation', async () => { + const userOpSignatureRequest = createUserSignatureRequest(); + mockSignUserOp(true); const porterClient = new PorterClient(fakePorterUris[2]); const result = await porterClient.signUserOp( { - '0x1234': JSON.stringify(mockPackedUserOp), - '0xabcd': JSON.stringify(mockPackedUserOp), + '0x1234': userOpSignatureRequest, + '0xabcd': userOpSignatureRequest, }, 2, ); @@ -234,7 +241,7 @@ describe('PorterClient Signing', () => { '0xabcd': { messageHash: '0x1234', signature: '0xbeef', - signerAddress: '0xefgh', + signerAddress: '0xefff', }, }, errors: {}, @@ -242,14 +249,16 @@ describe('PorterClient Signing', () => { }); it('should handle UserOperation signing failures', async () => { + const userOpSignatureRequest = createUserSignatureRequest(); + mockSignUserOp(false); const porterClient = new PorterClient(fakePorterUris[2]); await expect( porterClient.signUserOp( { - '0x1234': JSON.stringify(mockPackedUserOp), - '0xabcd': JSON.stringify(mockPackedUserOp), + '0x1234': userOpSignatureRequest, + '0xabcd': userOpSignatureRequest, }, 2, ), @@ -257,13 +266,15 @@ describe('PorterClient Signing', () => { }); it('should handle errors from Porter response in UserOperation signing', async () => { + const userOpSignatureRequest = createUserSignatureRequest(); + // Mock a response with errors from Porter mockSignUserOp(true, true); const porterClient = new PorterClient(fakePorterUris[2]); const result = await porterClient.signUserOp( { - '0x1234': JSON.stringify(mockPackedUserOp), - '0xabcd': JSON.stringify(mockPackedUserOp), + '0x1234': userOpSignatureRequest, + '0xabcd': userOpSignatureRequest, }, 2, ); @@ -273,7 +284,7 @@ describe('PorterClient Signing', () => { '0xabcd': { messageHash: '0x1234', signature: '0xbeef', - signerAddress: '0xefgh', + signerAddress: '0xefff', }, }, errors: { @@ -283,6 +294,8 @@ describe('PorterClient Signing', () => { }); it('should include error when message hashes do not match', async () => { + const userOpSignatureRequest = createUserSignatureRequest(); + const createMismatchedResponse = () => ({ result: { signing_results: { @@ -290,23 +303,21 @@ describe('PorterClient Signing', () => { '0x1234': [ '0x5678', toBase64( - new TextEncoder().encode( - JSON.stringify({ - message_hash: '0x1234', - signature: '0xdead', - }), - ), + new SignatureResponse( + fromHexString('0x1234'), + fromHexString('0xdead'), + 0, + ).toBytes(), ), ], '0xabcd': [ - '0xefgh', + '0xefff', toBase64( - new TextEncoder().encode( - JSON.stringify({ - message_hash: '0xdifferent', // Different message hash - signature: '0xbeef', - }), - ), + new SignatureResponse( + fromHexString('0xdddd'), // Different message hash + fromHexString('0xbeef'), + 0, + ).toBytes(), ), ], }, @@ -327,8 +338,8 @@ describe('PorterClient Signing', () => { const porterClient = new PorterClient(fakePorterUris[2]); const result = await porterClient.signUserOp( { - '0x1234': JSON.stringify(mockPackedUserOp), - '0xabcd': JSON.stringify(mockPackedUserOp), + '0x1234': userOpSignatureRequest, + '0xabcd': userOpSignatureRequest, }, 2, ); @@ -341,9 +352,9 @@ describe('PorterClient Signing', () => { signerAddress: '0x5678', }, '0xabcd': { - messageHash: '0xdifferent', // Different hash + messageHash: '0xdddd', // Different hash signature: '0xbeef', - signerAddress: '0xefgh', + signerAddress: '0xefff', }, }, errors: {}, // No errors - mismatched hashes don't generate errors, just prevent aggregation @@ -351,6 +362,8 @@ describe('PorterClient Signing', () => { }); it('should not return aggregated signature when threshold not met', async () => { + const userOpSignatureRequest = createUserSignatureRequest(); + const createInsufficientResponse = () => ({ result: { signing_results: { @@ -358,12 +371,11 @@ describe('PorterClient Signing', () => { '0x1234': [ '0x5678', toBase64( - new TextEncoder().encode( - JSON.stringify({ - message_hash: '0x1234', - signature: '0xdead', - }), - ), + new SignatureResponse( + fromHexString('0x1234'), + fromHexString('0xdead'), + 0, + ).toBytes(), ), ], // Only 1 signature, but threshold is 2 @@ -385,8 +397,8 @@ describe('PorterClient Signing', () => { const porterClient = new PorterClient(fakePorterUris[2]); const result = await porterClient.signUserOp( { - '0x1234': JSON.stringify(mockPackedUserOp), - '0xabcd': JSON.stringify(mockPackedUserOp), + '0x1234': userOpSignatureRequest, + '0xabcd': userOpSignatureRequest, }, 2, // threshold of 2, but only 1 signature ); @@ -404,12 +416,14 @@ describe('PorterClient Signing', () => { }); it('should successfully sign', async () => { + const userOpSignatureRequest = createUserSignatureRequest(); + mockSignUserOp(true); const porterClient = new PorterClient(fakePorterUris[2]); const result = await porterClient.signUserOp( { - '0x1234': JSON.stringify(mockPackedUserOp), - '0xabcd': JSON.stringify(mockPackedUserOp), + '0x1234': userOpSignatureRequest, + '0xabcd': userOpSignatureRequest, }, 2, ); @@ -424,69 +438,16 @@ describe('PorterClient Signing', () => { '0xabcd': { messageHash: '0x1234', signature: '0xbeef', - signerAddress: '0xefgh', + signerAddress: '0xefff', }, }, errors: {}, }); }); - it('should handle decode errors', async () => { - const createOptimisticErrorResponse = () => ({ - result: { - signing_results: { - signatures: { - '0x1234': [ - '0x5678', - toBase64( - new TextEncoder().encode( - JSON.stringify({ - message_hash: '0x1234', - signature: '0xdead', - }), - ), - ), - ], - '0xabcd': ['0xefgh', 'invalid-base64-data!!!'], // Invalid signature data - }, - errors: {}, - }, - }, - }); - - vi.spyOn(axios, 'request').mockImplementation(async (config) => { - if (config.url === '/sign' && config.baseURL === fakePorterUris[2]) { - return Promise.resolve({ - status: HttpStatusCode.Ok, - data: createOptimisticErrorResponse(), - }); - } - }); - - const porterClient = new PorterClient(fakePorterUris[2]); - const result = await porterClient.signUserOp( - { - '0x1234': JSON.stringify(mockPackedUserOp), - '0xabcd': JSON.stringify(mockPackedUserOp), - }, - 2, - ); - - expect(result).toEqual({ - signingResults: { - '0x1234': { - messageHash: '0x1234', - signature: '0xdead', - signerAddress: '0x5678', - }, - }, - errors: { - '0xabcd': expect.stringContaining('Failed to decode signature'), // Decode error - }, - }); - }); - it('should aggregate only threshold-meeting hash', async () => { + const userOpSignatureRequest = createUserSignatureRequest(); + const createMixedHashResponse = () => ({ result: { signing_results: { @@ -494,34 +455,31 @@ describe('PorterClient Signing', () => { '0x1234': [ '0x5678', toBase64( - new TextEncoder().encode( - JSON.stringify({ - message_hash: '0xhash1', - signature: '0xdead', - }), - ), + new SignatureResponse( + fromHexString('0x0001'), + fromHexString('0xdead'), + 0, + ).toBytes(), ), ], '0xabcd': [ - '0xefgh', + '0xefff', toBase64( - new TextEncoder().encode( - JSON.stringify({ - message_hash: '0xhash1', // Same hash, meets threshold - signature: '0xbeef', - }), - ), + new SignatureResponse( + fromHexString('0x0001'), // Same hash, meets threshold + fromHexString('0xbeef'), + 0, + ).toBytes(), ), ], '0xdef0': [ '0xabc1', toBase64( - new TextEncoder().encode( - JSON.stringify({ - message_hash: '0xhash2', // Different hash, doesn't meet threshold - signature: '0xcafe', - }), - ), + new SignatureResponse( + fromHexString('0x0002'), // Different hash, doesn't meet threshold + fromHexString('0xcafe'), + 0, + ).toBytes(), ), ], }, @@ -542,9 +500,9 @@ describe('PorterClient Signing', () => { const porterClient = new PorterClient(fakePorterUris[2]); const result = await porterClient.signUserOp( { - '0x1234': JSON.stringify(mockPackedUserOp), - '0xabcd': JSON.stringify(mockPackedUserOp), - '0xdef0': JSON.stringify(mockPackedUserOp), + '0x1234': userOpSignatureRequest, + '0xabcd': userOpSignatureRequest, + '0xdef0': userOpSignatureRequest, }, 2, // threshold of 2 ); @@ -553,17 +511,17 @@ describe('PorterClient Signing', () => { // different hashes returned separately signingResults: { '0x1234': { - messageHash: '0xhash1', + messageHash: '0x0001', signature: '0xdead', signerAddress: '0x5678', }, '0xabcd': { - messageHash: '0xhash1', + messageHash: '0x0001', signature: '0xbeef', - signerAddress: '0xefgh', + signerAddress: '0xefff', }, '0xdef0': { - messageHash: '0xhash2', + messageHash: '0x0002', signature: '0xcafe', signerAddress: '0xabc1', }, From 5c68c88a57f700227e31d4543fcdad1539374ebb Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 23 Oct 2025 16:16:54 -0400 Subject: [PATCH 202/303] Update tests to accommodate changes to `nucypher-core` objects from 0.15.0 release. --- packages/taco/test/taco.test.ts | 2 +- packages/taco/test/test-utils.ts | 7 ++++--- packages/test-utils/src/utils.ts | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/taco/test/taco.test.ts b/packages/taco/test/taco.test.ts index e035f211f..23ce52803 100644 --- a/packages/taco/test/taco.test.ts +++ b/packages/taco/test/taco.test.ts @@ -63,7 +63,7 @@ describe('taco', () => { const { decryptionShares } = fakeTDecFlow({ ...mockedDkg, message: toBytes(message), - dkgPublicKey: mockedDkg.dkg.publicKey(), + dkgPublicKey: mockedDkg.serverAggregate.publicKey, thresholdMessageKit: messageKit, }); const { participantSecrets, participants } = await mockDkgParticipants( diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 9b2212f3b..68f5f968d 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -134,7 +134,7 @@ export const fakeDkgTDecFlowE2E: ( threshold = 4, ) => { const ritual = fakeDkgFlow(variant, ritualId, sharesNum, threshold); - const dkgPublicKey = ritual.dkg.publicKey(); + const dkgPublicKey = ritual.serverAggregate.publicKey; const provider = fakeProvider(); const thresholdMessageKit = await encryptMessage( message, @@ -160,7 +160,7 @@ export const fakeDkgTDecFlowE2E: ( export const fakeCoordinatorRitual = async (): Promise => { const ritual = await fakeDkgTDecFlowE2E(); - const dkgPkBytes = ritual.dkg.publicKey().toBytes(); + const dkgPkBytes = ritual.serverAggregate.publicKey.toBytes(); return { initiator: ritual.validators[0].address.toString(), dkgSize: ritual.sharesNum, @@ -221,10 +221,11 @@ export const fakeDkgRitual = (ritual: { dkg: Dkg; sharesNum: number; threshold: number; + serverAggregate: AggregatedTranscript; }) => { return new DkgRitual( fakeRitualId, - ritual.dkg.publicKey(), + ritual.serverAggregate.publicKey, ritual.sharesNum, ritual.threshold, DkgRitualState.ACTIVE, diff --git a/packages/test-utils/src/utils.ts b/packages/test-utils/src/utils.ts index dc328f23c..77395dd87 100644 --- a/packages/test-utils/src/utils.ts +++ b/packages/test-utils/src/utils.ts @@ -239,7 +239,7 @@ export const fakeDkgFlow = ( for (let i = 0; i < sharesNum; i++) { const keypair = Keypair.random(); validatorKeypairs.push(keypair); - const validator = new Validator(genEthAddr(i), keypair.publicKey); + const validator = new Validator(genEthAddr(i), keypair.publicKey, i); validators.push(validator); } From f4c9e0877783c533a92bb767c62781446b058f8c Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 23 Oct 2025 16:21:23 -0400 Subject: [PATCH 203/303] Define `UserOperationToSign` as a common type that any library can use to specify their corresponding UserOperation. Convert `UserOperationToSign` to `nucypher-core`:UserOperation when crafting signature request. Use latest types from Porter for sending signature requests and processing signature response. Add/update tests. --- packages/shared/src/types.ts | 142 ++++++------ packages/taco/integration-test/sign.test.ts | 4 +- packages/taco/src/sign.ts | 34 ++- packages/taco/src/types.ts | 4 +- packages/taco/test/taco-sign.test.ts | 242 +++++++++++++++----- 5 files changed, 276 insertions(+), 150 deletions(-) diff --git a/packages/shared/src/types.ts b/packages/shared/src/types.ts index 9148cef91..23ad354fb 100644 --- a/packages/shared/src/types.ts +++ b/packages/shared/src/types.ts @@ -1,82 +1,90 @@ -import { ethers } from 'ethers'; +import { UserOperation } from '@nucypher/nucypher-core'; + +import { fromHexString } from './utils'; export type ChecksumAddress = `0x${string}`; export type HexEncodedBytes = string; export type Base64EncodedBytes = string; -export type UserOperation = { - sender: string; - nonce: number; - factory: string; - factoryData: string; - callData: string; - callGasLimit: number; - verificationGasLimit: number; - preVerificationGas: number; - maxFeePerGas: number; - maxPriorityFeePerGas: number; - paymaster: string; - paymasterVerificationGasLimit: number; - paymasterPostOpGasLimit: number; - paymasterData: string; - signature: string; +export type UserOperationToSign = { + sender: `0x${string}`; + nonce: bigint | number; + callData: `0x${string}` | Uint8Array; + callGasLimit: bigint | number; + verificationGasLimit: bigint | number; + preVerificationGas: bigint | number; + maxFeePerGas: bigint | number; + maxPriorityFeePerGas: bigint | number; + // optional fields + factory?: `0x${string}` | undefined; + factoryData?: `0x${string}` | Uint8Array | undefined; + paymaster?: `0x${string}` | undefined; + paymasterVerificationGasLimit?: bigint | number | undefined; + paymasterPostOpGasLimit?: bigint | number | undefined; + paymasterData?: `0x${string}` | Uint8Array | undefined; + signature?: `0x${string}` | Uint8Array | undefined; }; -export class UserOperationSignatureRequest { - constructor( - private userOp: ReturnType, - private aaVersion: string, - private cohortId: number, - private chainId: number, - private context: unknown = {}, - private signatureType: string = 'userop', - ) {} +export function toCoreUserOperation( + userOperation: UserOperationToSign, +): UserOperation { + const userOp = new UserOperation( + userOperation.sender, + typeof userOperation.nonce === 'bigint' + ? userOperation.nonce + : BigInt(userOperation.nonce), + userOperation.callData instanceof Uint8Array + ? userOperation.callData + : fromHexString(userOperation.callData), + typeof userOperation.callGasLimit === 'bigint' + ? userOperation.callGasLimit + : BigInt(userOperation.callGasLimit), + typeof userOperation.verificationGasLimit === 'bigint' + ? userOperation.verificationGasLimit + : BigInt(userOperation.verificationGasLimit), + typeof userOperation.preVerificationGas === 'bigint' + ? userOperation.preVerificationGas + : BigInt(userOperation.preVerificationGas || 0), + typeof userOperation.maxFeePerGas === 'bigint' + ? userOperation.maxFeePerGas + : BigInt(userOperation.maxFeePerGas), + typeof userOperation.maxPriorityFeePerGas === 'bigint' + ? userOperation.maxPriorityFeePerGas + : BigInt(userOperation.maxPriorityFeePerGas), + ); - toBytes(): Uint8Array { - const data = { - user_op: JSON.stringify(this.userOp), - aa_version: this.aaVersion, - cohort_id: this.cohortId, - chain_id: this.chainId, - context: this.context, - signature_type: this.signatureType, - }; - return new TextEncoder().encode(JSON.stringify(data)); - } -} + // optional factory data + if (userOperation.factory) { + const factory_data = + userOperation.factoryData instanceof Uint8Array + ? userOperation.factoryData + : fromHexString(userOperation.factoryData || '0x'); -function normalizeAddress(address: string): string | null { - if (!address || address === '0x') { - return null; + userOp.setFactoryData(userOperation.factory, factory_data); } - try { - // Use ethers to get the checksummed address - this will throw on invalid addresses - return ethers.utils.getAddress(address); - } catch (error) { - // Re-throw the error to fail fast on invalid addresses - throw new Error( - `Invalid address: ${address}. ${error instanceof Error ? error.message : 'Unknown error'}`, + // optional paymaster data + if (userOperation.paymaster) { + const paymaster_data = + userOperation.paymasterData instanceof Uint8Array + ? userOperation.paymasterData + : fromHexString(userOperation.paymasterData || '0x'); + const paymaster_verification_gas_limit = + typeof userOperation.paymasterVerificationGasLimit === 'bigint' + ? userOperation.paymasterVerificationGasLimit + : BigInt(userOperation.paymasterVerificationGasLimit || 0); + const paymaster_post_op_gas_limit = + typeof userOperation.paymasterPostOpGasLimit === 'bigint' + ? userOperation.paymasterPostOpGasLimit + : BigInt(userOperation.paymasterPostOpGasLimit || 0); + + userOp.setPaymasterData( + userOperation.paymaster, + paymaster_verification_gas_limit, + paymaster_post_op_gas_limit, + paymaster_data, ); } -} -export function convertUserOperationToPython(userOp: UserOperation) { - return { - sender: normalizeAddress(userOp.sender), - nonce: userOp.nonce, - factory: normalizeAddress(userOp.factory), - factory_data: userOp.factoryData || '0x', - call_data: userOp.callData || '0x', - call_gas_limit: userOp.callGasLimit, - verification_gas_limit: userOp.verificationGasLimit, - pre_verification_gas: userOp.preVerificationGas, - max_fee_per_gas: userOp.maxFeePerGas, - max_priority_fee_per_gas: userOp.maxPriorityFeePerGas, - paymaster: normalizeAddress(userOp.paymaster), - paymaster_verification_gas_limit: userOp.paymasterVerificationGasLimit, - paymaster_post_op_gas_limit: userOp.paymasterPostOpGasLimit, - paymaster_data: userOp.paymasterData || '0x', - signature: userOp.signature || '0x', - }; + return userOp; } diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index 8a70e4c2d..9f65c92e2 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -3,7 +3,7 @@ import { fromHexString, getPorterUris, SigningCoordinatorAgent, - UserOperation, + UserOperationToSign, } from '@nucypher/shared'; import { ethers } from 'ethers'; import { beforeAll, describe, expect, test } from 'vitest'; @@ -43,7 +43,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( test('should sign a user operation', async () => { // Create a sample user operation with all required fields - const userOp: UserOperation = { + const userOp: UserOperationToSign = { sender: DUMMY_ADDRESS, nonce: 0, factory: '0x', diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index b22c03c0b..7df6bd2cb 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -1,5 +1,5 @@ +import { UserOperationSignatureRequest } from '@nucypher/nucypher-core'; import { - convertUserOperationToPython, Domain, fromHexString, getPorterUris, @@ -7,10 +7,9 @@ import { SigningCoordinatorAgent, TacoSignature, TacoSignResult, - toBase64, + toCoreUserOperation, toHexString, - UserOperation, - UserOperationSignatureRequest, + UserOperationToSign, } from '@nucypher/shared'; import { ethers } from 'ethers'; @@ -71,7 +70,7 @@ export async function signUserOp( domain: Domain, cohortId: number, chainId: number, - userOp: UserOperation, + userOp: UserOperationToSign, aaVersion: 'mdt' | '0.8.0' | string, context?: ConditionContext, porterUris?: string[], @@ -93,23 +92,20 @@ export async function signUserOp( cohortId, ); - const pythonUserOp = convertUserOperationToPython(userOp); - + const coreContext = context ? await context.toCoreContext() : null; + const coreUserOp = toCoreUserOperation(userOp); const signingRequest = new UserOperationSignatureRequest( - pythonUserOp, - aaVersion, + coreUserOp, cohortId, - chainId, - context || {}, - 'userop', + BigInt(chainId), + aaVersion, + coreContext, ); - const signingRequests: Record = Object.fromEntries( - signers.map((signer) => [ - signer.provider, - toBase64(signingRequest.toBytes()), - ]), - ); + const signingRequests: Record = + Object.fromEntries( + signers.map((signer) => [signer.provider, signingRequest]), + ); // Build signing request for the user operation const porterSignResult: TacoSignResult = await porter.signUserOp( @@ -119,7 +115,7 @@ export async function signUserOp( const hashToSignatures: Map< string, - { [ursulaAddress: string]: TacoSignature } + Record > = new Map(); // Single pass: decode signatures and populate signingResults diff --git a/packages/taco/src/types.ts b/packages/taco/src/types.ts index 8871cc860..d41b148c2 100644 --- a/packages/taco/src/types.ts +++ b/packages/taco/src/types.ts @@ -4,5 +4,5 @@ export { Context as CoreContext, } from '@nucypher/nucypher-core'; -// Re-export UserOperation from shared package to avoid duplication -export type { UserOperation } from '@nucypher/shared'; +// Re-export UserOperationToSign from shared package to avoid duplication +export { UserOperationToSign } from '@nucypher/shared'; diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index 824ef1cad..aa481fc13 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -1,11 +1,18 @@ import { - convertUserOperationToPython, + UserOperation, + UserOperationSignatureRequest, +} from '@nucypher/nucypher-core'; +import { + fromHexString, + initialize, PorterClient, SigningCoordinatorAgent, + toCoreUserOperation, + UserOperationToSign, } from '@nucypher/shared'; import { fakePorterUri } from '@nucypher/test-utils'; import { ethers } from 'ethers'; -import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'; import { ContractCondition } from '../src/conditions/base/contract'; import { RpcCondition } from '../src/conditions/base/rpc'; @@ -13,10 +20,70 @@ import { CompoundCondition } from '../src/conditions/compound-condition'; import { ConditionExpression } from '../src/conditions/condition-expr'; import { setSigningCohortConditions, signUserOp } from '../src/sign'; +function getNumberValue(value: bigint | number): bigint { + return typeof value === 'bigint' ? value : BigInt(value); +} + +function checkUserOpEquality(op1: UserOperationToSign, op2: UserOperation) { + expect(op1.sender).toEqual(op2.sender); + + expect(getNumberValue(op1.nonce)).toEqual(getNumberValue(op2.nonce)); + + const callData = + op1.callData instanceof Uint8Array + ? op1.callData + : fromHexString(op1.callData); + expect(callData).toEqual(callData); + + expect(getNumberValue(op1.callGasLimit)).toEqual(op2.callGasLimit); + expect(getNumberValue(op1.verificationGasLimit)).toEqual( + op2.verificationGasLimit, + ); + expect(getNumberValue(op1.preVerificationGas)).toEqual( + op2.preVerificationGas, + ); + expect(getNumberValue(op1.maxFeePerGas)).toEqual(op2.maxFeePerGas); + expect(getNumberValue(op1.maxPriorityFeePerGas)).toEqual( + op2.maxPriorityFeePerGas, + ); + + if (op1.factory === undefined) { + expect(op2.factory).toBeUndefined(); + } else { + expect(op1.factory).toEqual(op2.factory); + const factoryData = + op1.factoryData instanceof Uint8Array + ? op1.factoryData + : fromHexString(op1.factoryData || '0x'); + expect(factoryData).toEqual(op2.factoryData); + } + + if (op1.paymaster === undefined) { + expect(op2.paymaster).toBeUndefined(); + } else { + expect(op1.paymaster).toEqual(op2.paymaster); + expect( + getNumberValue(op1.paymasterVerificationGasLimit || BigInt(0)), + ).toEqual(op2.paymasterVerificationGasLimit); + expect(getNumberValue(op1.paymasterPostOpGasLimit || BigInt(0))).toEqual( + op2.paymasterPostOpGasLimit, + ); + const paymasterData = + op1.paymasterData instanceof Uint8Array + ? op1.paymasterData + : fromHexString(op1.paymasterData || '0x'); + expect(paymasterData).toEqual(op2.paymasterData); + } +} + describe('TACo Signing', () => { let porterSignUserOpMock: ReturnType; let mockProvider: ethers.providers.Provider; + beforeAll(async () => { + await initialize(); + }); + beforeEach(() => { porterSignUserOpMock = vi.fn(); mockProvider = {} as ethers.providers.Provider; @@ -31,23 +98,94 @@ describe('TACo Signing', () => { vi.spyOn(SigningCoordinatorAgent, 'getThreshold').mockResolvedValue(2); }); + describe('toCoreUserOperation', () => { + const userOpToSign: UserOperationToSign = { + sender: '0x742D35Cc6634C0532925A3b8D33c9c0E7B66C8E8', + nonce: BigInt(1), + callData: fromHexString('0xabc'), + callGasLimit: BigInt(131072), + verificationGasLimit: BigInt(86016), + preVerificationGas: BigInt(4096), + maxFeePerGas: BigInt(2748), + maxPriorityFeePerGas: BigInt(291), + }; + + it('should convert base fields', () => { + const coreUserOp = toCoreUserOperation(userOpToSign); + checkUserOpEquality(userOpToSign, coreUserOp); + }); + it('should convert factory optional fields', () => { + const updatedUserOp: UserOperationToSign = { + ...userOpToSign, + factory: '0x000000000000000000000000000000000000000A', + factoryData: fromHexString('0xdef'), + }; + const coreUserOp = toCoreUserOperation(updatedUserOp); + checkUserOpEquality(updatedUserOp, coreUserOp); + }); + it('should convert factory data to default when not specified but factory is', () => { + const updatedUserOp: UserOperationToSign = { + ...userOpToSign, + factory: '0x000000000000000000000000000000000000000A', + }; + const coreUserOp = toCoreUserOperation(updatedUserOp); + checkUserOpEquality(updatedUserOp, coreUserOp); + }); + it('should convert paymaster optional fields', () => { + const updatedUserOp: UserOperationToSign = { + ...userOpToSign, + paymaster: '0x000000000000000000000000000000000000000C', + paymasterVerificationGasLimit: BigInt(50000), + paymasterPostOpGasLimit: BigInt(30000), + paymasterData: fromHexString('0xdef'), + }; + const coreUserOp = toCoreUserOperation(updatedUserOp); + checkUserOpEquality(updatedUserOp, coreUserOp); + }); + it('should convert paymaster optional fields to defaults when not specified but paymaster is', () => { + const updatedUserOp: UserOperationToSign = { + ...userOpToSign, + paymaster: '0x000000000000000000000000000000000000000C', + }; + const coreUserOp = toCoreUserOperation(updatedUserOp); + checkUserOpEquality(updatedUserOp, coreUserOp); + }); + it('should handle alternative types: number and byte fields', () => { + const updatedUserOp: UserOperationToSign = { + ...userOpToSign, + // number instead of bigint + nonce: 1, + callData: '0xabc', // hex instead of byte array + callGasLimit: 131072, + verificationGasLimit: 86016, + preVerificationGas: 4096, + maxFeePerGas: 2748, + maxPriorityFeePerGas: 291, + // include optional fields + factory: '0x000000000000000000000000000000000000000A', + factoryData: '0xabc', // hex instead of byte array + + paymaster: '0x000000000000000000000000000000000000000C', + // number instead of big int + paymasterVerificationGasLimit: 50000, + paymasterPostOpGasLimit: 30000, + paymasterData: '0xdef', // hex instead of byte array + }; + const coreUserOp = toCoreUserOperation(updatedUserOp); + checkUserOpEquality(updatedUserOp, coreUserOp); + }); + }); + describe('signUserOp', () => { - const userOp = { + const userOp: UserOperationToSign = { sender: '0x742D35Cc6634C0532925A3b8D33c9c0E7B66C8E8', - nonce: 1, - factory: '0x0000000000000000000000000000000000000000', - factoryData: '0x', - callData: '0xabc', - callGasLimit: 131072, - verificationGasLimit: 86016, - preVerificationGas: 4096, - maxFeePerGas: 2748, - maxPriorityFeePerGas: 291, - paymaster: '0x0000000000000000000000000000000000000000', - paymasterVerificationGasLimit: 0, - paymasterPostOpGasLimit: 0, - paymasterData: '0x', - signature: '0x', + nonce: BigInt(1), + callData: fromHexString('0xabc'), + callGasLimit: BigInt(131072), + verificationGasLimit: BigInt(86016), + preVerificationGas: BigInt(4096), + maxFeePerGas: BigInt(2748), + maxPriorityFeePerGas: BigInt(291), }; const chainId = 1; const cohortId = 5; @@ -88,34 +226,26 @@ describe('TACo Signing', () => { porterUris, ); - const pythonUserOp = convertUserOperationToPython(userOp); - expect(porterSignUserOpMock).toHaveBeenCalledWith( { - '0xnode1': btoa( - JSON.stringify({ - user_op: JSON.stringify(pythonUserOp), - aa_version: validAAVersion, - cohort_id: cohortId, - chain_id: chainId, - context: {}, - signature_type: 'userop', - }), - ), - '0xnode2': btoa( - JSON.stringify({ - user_op: JSON.stringify(pythonUserOp), - aa_version: validAAVersion, - cohort_id: cohortId, - chain_id: chainId, - context: {}, - signature_type: 'userop', - }), - ), + '0xnode1': expect.any(UserOperationSignatureRequest), + '0xnode2': expect.any(UserOperationSignatureRequest), }, threshold, ); + const call = porterSignUserOpMock.mock.calls.at(-1)!; + const [op] = call; + + const requests = [op['0xnode1'], op['0xnode2']]; + requests.forEach((element) => { + checkUserOpEquality(userOp, element.userOp); + expect(element.aaVersion).toEqual(validAAVersion); + expect(element.cohortId).toEqual(cohortId); + expect(element.chainId).toEqual(BigInt(chainId)); + expect(element.context).toBeUndefined(); + }); + expect(result).toEqual({ messageHash: '0xhash1', aggregatedSignature: '0xdeadbeef', @@ -152,32 +282,24 @@ describe('TACo Signing', () => { `Threshold of signatures not met; TACo signing failed with errors: ${JSON.stringify(errors)}`, ); - const pythonUserOp = convertUserOperationToPython(userOp); expect(porterSignUserOpMock).toHaveBeenCalledWith( { - '0xnode1': btoa( - JSON.stringify({ - user_op: JSON.stringify(pythonUserOp), - aa_version: aaVersion, - cohort_id: cohortId, - chain_id: chainId, - context: {}, - signature_type: 'userop', - }), - ), - '0xnode2': btoa( - JSON.stringify({ - user_op: JSON.stringify(pythonUserOp), - aa_version: aaVersion, - cohort_id: cohortId, - chain_id: chainId, - context: {}, - signature_type: 'userop', - }), - ), + '0xnode1': expect.any(UserOperationSignatureRequest), + '0xnode2': expect.any(UserOperationSignatureRequest), }, threshold, ); + const call = porterSignUserOpMock.mock.calls.at(-1)!; + const [op] = call; + + const requests = [op['0xnode1'], op['0xnode2']]; + requests.forEach((element) => { + checkUserOpEquality(userOp, element.userOp); + expect(element.aaVersion).toEqual(aaVersion); + expect(element.cohortId).toEqual(cohortId); + expect(element.chainId).toEqual(BigInt(chainId)); + expect(element.context).toBeUndefined(); + }); }); it('should handle insufficient signatures in Porter response', async () => { const signingResults = { From 3ea1fd04d37af486a630e8f189a5370e44002255 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 24 Oct 2025 20:06:03 -0400 Subject: [PATCH 204/303] Use latest update for `SignatureResponse` from `nucypher-core` which now includes signer address. Modify Porter response to handle SignatureResponse and not a tuple of signer address and SignatureResponse. Update tests. --- packages/shared/src/porter.ts | 14 +-- packages/shared/test/porter.test.ts | 136 +++++++++++++--------------- 2 files changed, 67 insertions(+), 83 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index 796829d34..1e466c6cf 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -167,10 +167,7 @@ type PostTacoSignRequest = { type TacoSignResponse = { readonly result: { readonly signing_results: { - readonly signatures: Record< - ChecksumAddress, - [ChecksumAddress, Base64EncodedBytes] - >; + readonly signatures: Record; readonly errors: Record; }; }; @@ -355,17 +352,16 @@ export class PorterClient { const { signatures, errors } = resp.data.result.signing_results; const signingResults: { [ursulaAddress: string]: TacoSignature } = {}; - for (const [ - ursulaAddress, - [signerAddress, signatureResponseBase64], - ] of Object.entries(signatures || {})) { + for (const [ursulaAddress, signatureResponseBase64] of Object.entries( + signatures || {}, + )) { const signatureResponse = SignatureResponse.fromBytes( fromBase64(signatureResponseBase64), ); signingResults[ursulaAddress] = { messageHash: `0x${toHexString(signatureResponse.hash)}`, signature: `0x${toHexString(signatureResponse.signature)}`, - signerAddress, + signerAddress: signatureResponse.signer, }; } diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index 6fa6d7b4f..b34c3e238 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -64,9 +64,9 @@ const createMockSignResponse = (errorCase?: boolean) => ({ signatures: errorCase ? { '0xabcd': [ - '0xefff', toBase64( new SignatureResponse( + '0x0000000000000000000000000000000000000001', fromHexString('0x1234'), fromHexString('0xbeef'), 0, @@ -76,9 +76,9 @@ const createMockSignResponse = (errorCase?: boolean) => ({ } : { '0x1234': [ - '0x5678', toBase64( new SignatureResponse( + '0x0000000000000000000000000000000000000002', fromHexString('0x1234'), fromHexString('0xdead'), 0, @@ -86,9 +86,9 @@ const createMockSignResponse = (errorCase?: boolean) => ({ ), ], '0xabcd': [ - '0xefff', toBase64( new SignatureResponse( + '0x0000000000000000000000000000000000000001', fromHexString('0x1234'), fromHexString('0xbeef'), 0, @@ -236,12 +236,12 @@ describe('PorterClient Signing', () => { '0x1234': { messageHash: '0x1234', signature: '0xdead', - signerAddress: '0x5678', + signerAddress: '0x0000000000000000000000000000000000000002', }, '0xabcd': { messageHash: '0x1234', signature: '0xbeef', - signerAddress: '0xefff', + signerAddress: '0x0000000000000000000000000000000000000001', }, }, errors: {}, @@ -284,7 +284,7 @@ describe('PorterClient Signing', () => { '0xabcd': { messageHash: '0x1234', signature: '0xbeef', - signerAddress: '0xefff', + signerAddress: '0x0000000000000000000000000000000000000001', }, }, errors: { @@ -300,26 +300,22 @@ describe('PorterClient Signing', () => { result: { signing_results: { signatures: { - '0x1234': [ - '0x5678', - toBase64( - new SignatureResponse( - fromHexString('0x1234'), - fromHexString('0xdead'), - 0, - ).toBytes(), - ), - ], - '0xabcd': [ - '0xefff', - toBase64( - new SignatureResponse( - fromHexString('0xdddd'), // Different message hash - fromHexString('0xbeef'), - 0, - ).toBytes(), - ), - ], + '0x1234': toBase64( + new SignatureResponse( + '0x0000000000000000000000000000000000000002', + fromHexString('0x1234'), + fromHexString('0xdead'), + 0, + ).toBytes(), + ), + '0xabcd': toBase64( + new SignatureResponse( + '0x0000000000000000000000000000000000000001', + fromHexString('0xdddd'), // Different message hash + fromHexString('0xbeef'), + 0, + ).toBytes(), + ), }, errors: {}, }, @@ -349,12 +345,12 @@ describe('PorterClient Signing', () => { '0x1234': { messageHash: '0x1234', signature: '0xdead', - signerAddress: '0x5678', + signerAddress: '0x0000000000000000000000000000000000000002', }, '0xabcd': { messageHash: '0xdddd', // Different hash signature: '0xbeef', - signerAddress: '0xefff', + signerAddress: '0x0000000000000000000000000000000000000001', }, }, errors: {}, // No errors - mismatched hashes don't generate errors, just prevent aggregation @@ -368,16 +364,14 @@ describe('PorterClient Signing', () => { result: { signing_results: { signatures: { - '0x1234': [ - '0x5678', - toBase64( - new SignatureResponse( - fromHexString('0x1234'), - fromHexString('0xdead'), - 0, - ).toBytes(), - ), - ], + '0x1234': toBase64( + new SignatureResponse( + '0x0000000000000000000000000000000000000002', + fromHexString('0x1234'), + fromHexString('0xdead'), + 0, + ).toBytes(), + ), // Only 1 signature, but threshold is 2 }, errors: {}, @@ -408,7 +402,7 @@ describe('PorterClient Signing', () => { '0x1234': { messageHash: '0x1234', signature: '0xdead', - signerAddress: '0x5678', + signerAddress: '0x0000000000000000000000000000000000000002', }, }, errors: {}, @@ -433,12 +427,12 @@ describe('PorterClient Signing', () => { '0x1234': { messageHash: '0x1234', signature: '0xdead', - signerAddress: '0x5678', + signerAddress: '0x0000000000000000000000000000000000000002', }, '0xabcd': { messageHash: '0x1234', signature: '0xbeef', - signerAddress: '0xefff', + signerAddress: '0x0000000000000000000000000000000000000001', }, }, errors: {}, @@ -452,36 +446,30 @@ describe('PorterClient Signing', () => { result: { signing_results: { signatures: { - '0x1234': [ - '0x5678', - toBase64( - new SignatureResponse( - fromHexString('0x0001'), - fromHexString('0xdead'), - 0, - ).toBytes(), - ), - ], - '0xabcd': [ - '0xefff', - toBase64( - new SignatureResponse( - fromHexString('0x0001'), // Same hash, meets threshold - fromHexString('0xbeef'), - 0, - ).toBytes(), - ), - ], - '0xdef0': [ - '0xabc1', - toBase64( - new SignatureResponse( - fromHexString('0x0002'), // Different hash, doesn't meet threshold - fromHexString('0xcafe'), - 0, - ).toBytes(), - ), - ], + '0x1234': toBase64( + new SignatureResponse( + '0x0000000000000000000000000000000000000002', + fromHexString('0x0001'), + fromHexString('0xdead'), + 0, + ).toBytes(), + ), + '0xabcd': toBase64( + new SignatureResponse( + '0x0000000000000000000000000000000000000001', + fromHexString('0x0001'), // Same hash, meets threshold + fromHexString('0xbeef'), + 0, + ).toBytes(), + ), + '0xdef0': toBase64( + new SignatureResponse( + '0x0000000000000000000000000000000000000003', + fromHexString('0x0002'), // Different hash, doesn't meet threshold + fromHexString('0xcafe'), + 0, + ).toBytes(), + ), }, errors: {}, }, @@ -513,17 +501,17 @@ describe('PorterClient Signing', () => { '0x1234': { messageHash: '0x0001', signature: '0xdead', - signerAddress: '0x5678', + signerAddress: '0x0000000000000000000000000000000000000002', }, '0xabcd': { messageHash: '0x0001', signature: '0xbeef', - signerAddress: '0xefff', + signerAddress: '0x0000000000000000000000000000000000000001', }, '0xdef0': { messageHash: '0x0002', signature: '0xcafe', - signerAddress: '0xabc1', + signerAddress: '0x0000000000000000000000000000000000000003', }, }, errors: {}, From 27fe23bcaf2ee6b757f1039c4d4fe9af855a06db Mon Sep 17 00:00:00 2001 From: derekpierre Date: Mon, 27 Oct 2025 10:46:12 -0400 Subject: [PATCH 205/303] Add conversion of PackedUserOperationToSign -> PackedUserOperation (core object). Add type guard for PackedUserOperationToSign. Add helper methods for converting number values to bigint, and data values to Uint8Array. --- packages/shared/src/types.ts | 99 ++++++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 39 deletions(-) diff --git a/packages/shared/src/types.ts b/packages/shared/src/types.ts index 23ad354fb..2f4a2c301 100644 --- a/packages/shared/src/types.ts +++ b/packages/shared/src/types.ts @@ -1,4 +1,4 @@ -import { UserOperation } from '@nucypher/nucypher-core'; +import { PackedUserOperation, UserOperation } from '@nucypher/nucypher-core'; import { fromHexString } from './utils'; @@ -25,59 +25,57 @@ export type UserOperationToSign = { signature?: `0x${string}` | Uint8Array | undefined; }; +export type PackedUserOperationToSign = { + sender: `0x${string}`; + nonce: bigint | number; + initCode: `0x${string}` | Uint8Array; + callData: `0x${string}` | Uint8Array; + accountGasLimit: `0x${string}` | Uint8Array; + preVerificationGas: bigint | number; + gasFees: `0x${string}` | Uint8Array; + paymasterAndData: `0x${string}` | Uint8Array; +}; + +function getBigIntValue(value: bigint | number): bigint { + return typeof value === 'bigint' ? value : BigInt(value); +} + +function getUint8ArrayValue(value: `0x${string}` | Uint8Array): Uint8Array { + return value instanceof Uint8Array ? value : fromHexString(value); +} + export function toCoreUserOperation( userOperation: UserOperationToSign, ): UserOperation { const userOp = new UserOperation( userOperation.sender, - typeof userOperation.nonce === 'bigint' - ? userOperation.nonce - : BigInt(userOperation.nonce), - userOperation.callData instanceof Uint8Array - ? userOperation.callData - : fromHexString(userOperation.callData), - typeof userOperation.callGasLimit === 'bigint' - ? userOperation.callGasLimit - : BigInt(userOperation.callGasLimit), - typeof userOperation.verificationGasLimit === 'bigint' - ? userOperation.verificationGasLimit - : BigInt(userOperation.verificationGasLimit), - typeof userOperation.preVerificationGas === 'bigint' - ? userOperation.preVerificationGas - : BigInt(userOperation.preVerificationGas || 0), - typeof userOperation.maxFeePerGas === 'bigint' - ? userOperation.maxFeePerGas - : BigInt(userOperation.maxFeePerGas), - typeof userOperation.maxPriorityFeePerGas === 'bigint' - ? userOperation.maxPriorityFeePerGas - : BigInt(userOperation.maxPriorityFeePerGas), + getBigIntValue(userOperation.nonce), + getUint8ArrayValue(userOperation.callData), + getBigIntValue(userOperation.callGasLimit), + getBigIntValue(userOperation.verificationGasLimit), + getBigIntValue(userOperation.preVerificationGas), + getBigIntValue(userOperation.maxFeePerGas), + getBigIntValue(userOperation.maxPriorityFeePerGas), ); // optional factory data if (userOperation.factory) { - const factory_data = - userOperation.factoryData instanceof Uint8Array - ? userOperation.factoryData - : fromHexString(userOperation.factoryData || '0x'); + const factory_data = getUint8ArrayValue(userOperation.factoryData || '0x'); userOp.setFactoryData(userOperation.factory, factory_data); } // optional paymaster data if (userOperation.paymaster) { - const paymaster_data = - userOperation.paymasterData instanceof Uint8Array - ? userOperation.paymasterData - : fromHexString(userOperation.paymasterData || '0x'); - const paymaster_verification_gas_limit = - typeof userOperation.paymasterVerificationGasLimit === 'bigint' - ? userOperation.paymasterVerificationGasLimit - : BigInt(userOperation.paymasterVerificationGasLimit || 0); - const paymaster_post_op_gas_limit = - typeof userOperation.paymasterPostOpGasLimit === 'bigint' - ? userOperation.paymasterPostOpGasLimit - : BigInt(userOperation.paymasterPostOpGasLimit || 0); - + const paymaster_verification_gas_limit = getBigIntValue( + userOperation.paymasterVerificationGasLimit || 0, + ); + const paymaster_post_op_gas_limit = getBigIntValue( + userOperation.paymasterPostOpGasLimit || 0, + ); + const paymaster_data = getUint8ArrayValue( + userOperation.paymasterData || '0x', + ); userOp.setPaymasterData( userOperation.paymaster, paymaster_verification_gas_limit, @@ -88,3 +86,26 @@ export function toCoreUserOperation( return userOp; } + +export function toCorePackedUserOperation( + packedUserOperation: PackedUserOperationToSign, +): PackedUserOperation { + const packedUserOp = new PackedUserOperation( + packedUserOperation.sender, + getBigIntValue(packedUserOperation.nonce), + getUint8ArrayValue(packedUserOperation.initCode), + getUint8ArrayValue(packedUserOperation.callData), + getUint8ArrayValue(packedUserOperation.accountGasLimit), + getBigIntValue(packedUserOperation.preVerificationGas), + getUint8ArrayValue(packedUserOperation.gasFees), + getUint8ArrayValue(packedUserOperation.paymasterAndData), + ); + + return packedUserOp; +} + +export function isPackedUserOperation( + op: UserOperationToSign | PackedUserOperationToSign, +): op is PackedUserOperationToSign { + return 'initCode' in op && 'gasFees' in op; +} From 1a26942f88f2473cdcd5f8a5c545e40e16de041f Mon Sep 17 00:00:00 2001 From: derekpierre Date: Mon, 27 Oct 2025 10:49:48 -0400 Subject: [PATCH 206/303] Add support allowing both UserOperations and PackedUserOperations to be signed. --- .../contracts/agents/signing-coordinator.ts | 2 +- packages/shared/src/porter.ts | 8 +- packages/taco/src/sign.ts | 74 +++++++++++++++---- 3 files changed, 68 insertions(+), 16 deletions(-) diff --git a/packages/shared/src/contracts/agents/signing-coordinator.ts b/packages/shared/src/contracts/agents/signing-coordinator.ts index 251647576..c2fe8b507 100644 --- a/packages/shared/src/contracts/agents/signing-coordinator.ts +++ b/packages/shared/src/contracts/agents/signing-coordinator.ts @@ -5,7 +5,7 @@ import { Domain } from '../../porter'; import { SigningCoordinator__factory } from '../ethers-typechain'; import { SigningCoordinator } from '../ethers-typechain/SigningCoordinator'; -type SignerInfo = { +export type SignerInfo = { operator: string; provider: string; signature: string; diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index 1e466c6cf..c79479db7 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -2,6 +2,7 @@ import { CapsuleFrag, EncryptedThresholdDecryptionRequest, EncryptedThresholdDecryptionResponse, + PackedUserOperationSignatureRequest, PublicKey, RetrievalKit, SignatureResponse, @@ -331,7 +332,10 @@ export class PorterClient { } public async signUserOp( - signingRequests: Record, + signingRequests: Record< + string, + UserOperationSignatureRequest | PackedUserOperationSignatureRequest + >, threshold: number, ): Promise { const data: PostTacoSignRequest = { @@ -356,7 +360,7 @@ export class PorterClient { signatures || {}, )) { const signatureResponse = SignatureResponse.fromBytes( - fromBase64(signatureResponseBase64), + fromBase64(signatureResponseBase64 as string), ); signingResults[ursulaAddress] = { messageHash: `0x${toHexString(signatureResponse.hash)}`, diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 7df6bd2cb..e60fd94e0 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -1,12 +1,19 @@ -import { UserOperationSignatureRequest } from '@nucypher/nucypher-core'; +import { + PackedUserOperationSignatureRequest, + UserOperationSignatureRequest, +} from '@nucypher/nucypher-core'; import { Domain, fromHexString, getPorterUris, + isPackedUserOperation, + PackedUserOperationToSign, PorterClient, + SignerInfo, SigningCoordinatorAgent, TacoSignature, TacoSignResult, + toCorePackedUserOperation, toCoreUserOperation, toHexString, UserOperationToSign, @@ -52,6 +59,53 @@ function aggregateSignatures( return `0x${toHexString(new Uint8Array(allBytes))}`; } +async function makeSigningRequests( + signers: SignerInfo[], + cohortId: number, + chainId: number, + userOp: UserOperationToSign | PackedUserOperationToSign, + aaVersion: string, + context?: ConditionContext, +): Promise< + Record< + string, + PackedUserOperationSignatureRequest | UserOperationSignatureRequest + > +> { + const coreContext = context ? await context.toCoreContext() : null; + + let signingRequest: + | PackedUserOperationSignatureRequest + | UserOperationSignatureRequest; + if (isPackedUserOperation(userOp)) { + const corePackedUserOp = toCorePackedUserOperation(userOp); + signingRequest = new PackedUserOperationSignatureRequest( + corePackedUserOp, + cohortId, + BigInt(chainId), + aaVersion, + coreContext, + ); + } else { + const coreUserOp = toCoreUserOperation(userOp); + signingRequest = new UserOperationSignatureRequest( + coreUserOp, + cohortId, + BigInt(chainId), + aaVersion, + coreContext, + ); + } + + const signingRequests: Record< + string, + PackedUserOperationSignatureRequest | UserOperationSignatureRequest + > = Object.fromEntries( + signers.map((signer) => [signer.provider, signingRequest]), + ); + return signingRequests; +} + /** * Signs a UserOperation. * @param provider - The Ethereum provider to use for signing. @@ -70,7 +124,7 @@ export async function signUserOp( domain: Domain, cohortId: number, chainId: number, - userOp: UserOperationToSign, + userOp: UserOperationToSign | PackedUserOperationToSign, aaVersion: 'mdt' | '0.8.0' | string, context?: ConditionContext, porterUris?: string[], @@ -92,21 +146,15 @@ export async function signUserOp( cohortId, ); - const coreContext = context ? await context.toCoreContext() : null; - const coreUserOp = toCoreUserOperation(userOp); - const signingRequest = new UserOperationSignatureRequest( - coreUserOp, + const signingRequests = await makeSigningRequests( + signers, cohortId, - BigInt(chainId), + chainId, + userOp, aaVersion, - coreContext, + context, ); - const signingRequests: Record = - Object.fromEntries( - signers.map((signer) => [signer.provider, signingRequest]), - ); - // Build signing request for the user operation const porterSignResult: TacoSignResult = await porter.signUserOp( signingRequests, From 3c7660b7d419e9ed1b98d3f7e3f68157228e0c27 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Mon, 27 Oct 2025 14:47:03 -0400 Subject: [PATCH 207/303] Add tests for signing of packed user operation objects. --- packages/shared/test/porter.test.ts | 60 +++++++++-- packages/taco/test/taco-sign.test.ts | 144 ++++++++++++++++++++++++--- 2 files changed, 182 insertions(+), 22 deletions(-) diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index b34c3e238..c6d84178e 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -3,6 +3,8 @@ import axios, { HttpStatusCode } from 'axios'; import { beforeAll, describe, expect, it, MockInstance, vi } from 'vitest'; import { + PackedUserOperation, + PackedUserOperationSignatureRequest, SignatureResponse, UserOperation, UserOperationSignatureRequest, @@ -204,13 +206,13 @@ describe('PorterClient Signing', () => { new UserOperationSignatureRequest( new UserOperation( '0x000000000000000000000000000000000000000a', - BigInt(0), // nonce + BigInt(123), // nonce fromHexString('0xabc'), // callData - BigInt(0), // callGasLimit - BigInt(0), // verificationGasLimit - BigInt(0), // preVerificationGasLimit - BigInt(0), // maxFeePerGas - BigInt(0), // maxPriorityFeePerGas + BigInt(456), // callGasLimit + BigInt(789), // verificationGasLimit + BigInt(101112), // preVerificationGasLimit + BigInt(131415), // maxFeePerGas + BigInt(161718), // maxPriorityFeePerGas ), 1, // cohort ID BigInt(1), // chain ID @@ -248,6 +250,52 @@ describe('PorterClient Signing', () => { }); }); + it('should successfully sign a PackedUserOperation', async () => { + const packedUserOperationSignatureRequest = + new PackedUserOperationSignatureRequest( + new PackedUserOperation( + '0x000000000000000000000000000000000000000a', + BigInt(123), // nonce + fromHexString('0xabc'), // initCode + fromHexString('0xdef'), // callData + fromHexString('0x01020304'), // accountGasLimit + BigInt(101112), // preVerificationGas + fromHexString('0x05060708'), // gasFees + fromHexString('0x090a0b0c'), // paymasterAndData + ), + 1, // cohort ID + BigInt(1), // chain ID + 'mdt', + null, + ); + + mockSignUserOp(true); + const porterClient = new PorterClient(fakePorterUris[2]); + const result = await porterClient.signUserOp( + { + '0x1234': packedUserOperationSignatureRequest, + '0xabcd': packedUserOperationSignatureRequest, + }, + 2, + ); + + expect(result).toEqual({ + signingResults: { + '0x1234': { + messageHash: '0x1234', + signature: '0xdead', + signerAddress: '0x0000000000000000000000000000000000000002', + }, + '0xabcd': { + messageHash: '0x1234', + signature: '0xbeef', + signerAddress: '0x0000000000000000000000000000000000000001', + }, + }, + errors: {}, + }); + }); + it('should handle UserOperation signing failures', async () => { const userOpSignatureRequest = createUserSignatureRequest(); diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index aa481fc13..93bf040fa 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -1,12 +1,17 @@ import { + PackedUserOperation, + PackedUserOperationSignatureRequest, UserOperation, UserOperationSignatureRequest, } from '@nucypher/nucypher-core'; import { fromHexString, initialize, + isPackedUserOperation, + PackedUserOperationToSign, PorterClient, SigningCoordinatorAgent, + toCorePackedUserOperation, toCoreUserOperation, UserOperationToSign, } from '@nucypher/shared'; @@ -24,10 +29,52 @@ function getNumberValue(value: bigint | number): bigint { return typeof value === 'bigint' ? value : BigInt(value); } +function checkPackedUserOpEquality( + op1: PackedUserOperationToSign, + op2: PackedUserOperation, +) { + expect(op1.sender).toEqual(op2.sender); + expect(getNumberValue(op1.nonce)).toEqual(op2.nonce); + + const initCode = + op1.initCode instanceof Uint8Array + ? op1.initCode + : fromHexString(op1.initCode); + expect(initCode).toEqual(op2.initCode); + + const callData = + op1.callData instanceof Uint8Array + ? op1.callData + : fromHexString(op1.callData); + expect(callData).toEqual(op2.callData); + + const accountGasLimit = + op1.accountGasLimit instanceof Uint8Array + ? op1.accountGasLimit + : fromHexString(op1.accountGasLimit); + expect(accountGasLimit).toEqual(op2.accountGasLimits); + + expect(getNumberValue(op1.preVerificationGas)).toEqual( + op2.preVerificationGas, + ); + + const gasFees = + op1.gasFees instanceof Uint8Array + ? op1.gasFees + : fromHexString(op1.gasFees); + expect(gasFees).toEqual(op2.gasFees); + + const paymasterAndData = + op1.paymasterAndData instanceof Uint8Array + ? op1.paymasterAndData + : fromHexString(op1.paymasterAndData); + expect(paymasterAndData).toEqual(op2.paymasterAndData); +} + function checkUserOpEquality(op1: UserOperationToSign, op2: UserOperation) { expect(op1.sender).toEqual(op2.sender); - expect(getNumberValue(op1.nonce)).toEqual(getNumberValue(op2.nonce)); + expect(getNumberValue(op1.nonce)).toEqual(op2.nonce); const callData = op1.callData instanceof Uint8Array @@ -153,9 +200,9 @@ describe('TACo Signing', () => { it('should handle alternative types: number and byte fields', () => { const updatedUserOp: UserOperationToSign = { ...userOpToSign, - // number instead of bigint + // number instead of bigint, hex instead of byte array nonce: 1, - callData: '0xabc', // hex instead of byte array + callData: '0xabc', callGasLimit: 131072, verificationGasLimit: 86016, preVerificationGas: 4096, @@ -163,18 +210,50 @@ describe('TACo Signing', () => { maxPriorityFeePerGas: 291, // include optional fields factory: '0x000000000000000000000000000000000000000A', - factoryData: '0xabc', // hex instead of byte array + factoryData: '0xabc', paymaster: '0x000000000000000000000000000000000000000C', // number instead of big int paymasterVerificationGasLimit: 50000, paymasterPostOpGasLimit: 30000, - paymasterData: '0xdef', // hex instead of byte array + paymasterData: '0xdef', }; const coreUserOp = toCoreUserOperation(updatedUserOp); checkUserOpEquality(updatedUserOp, coreUserOp); }); }); + describe('toCorePackedUserOperation', () => { + const packedUserOpToSign: PackedUserOperationToSign = { + sender: '0x742D35Cc6634C0532925A3b8D33c9c0E7B66C8E8', + nonce: BigInt(123), + initCode: fromHexString('0xabc'), + callData: fromHexString('0xdef'), + accountGasLimit: fromHexString('0x01020304'), + preVerificationGas: BigInt(101112), + gasFees: fromHexString('0x05060708'), + paymasterAndData: fromHexString('0x090a0b0c'), + }; + + it('should convert base fields', () => { + const corePackedUserOp = toCorePackedUserOperation(packedUserOpToSign); + checkPackedUserOpEquality(packedUserOpToSign, corePackedUserOp); + }); + it('should handle alternative types: number and byte fields', () => { + const updatedPackedUserOp: PackedUserOperationToSign = { + // number instead of bigint, hex instead of byte array + ...packedUserOpToSign, + nonce: 1, + initCode: '0xabc', + callData: '0xdef', + accountGasLimit: '0x01020304', + preVerificationGas: 4096, + gasFees: '0x05060708', + paymasterAndData: '0x090a0b0c', + }; + const corePackedUserOp = toCorePackedUserOperation(updatedPackedUserOp); + checkPackedUserOpEquality(updatedPackedUserOp, corePackedUserOp); + }); + }); describe('signUserOp', () => { const userOp: UserOperationToSign = { @@ -187,15 +266,34 @@ describe('TACo Signing', () => { maxFeePerGas: BigInt(2748), maxPriorityFeePerGas: BigInt(291), }; + const packedUserOp: PackedUserOperationToSign = { + sender: '0x742D35Cc6634C0532925A3b8D33c9c0E7B66C8E8', + nonce: BigInt(1), + initCode: fromHexString('0xabc'), + callData: fromHexString('0xdef'), + accountGasLimit: fromHexString('0x01020304'), + preVerificationGas: BigInt(101112), + gasFees: fromHexString('0x05060708'), + paymasterAndData: fromHexString('0x090a0b0c'), + }; + const chainId = 1; const cohortId = 5; const porterUris = [fakePorterUri]; const aaVersion = '0.8.0'; const threshold = 2; - it.each(['0.8.0', 'mdt'])( - 'should sign a user operation with a valid aa versions', - async (validAAVersion) => { + it.each([ + ['0.8.0', userOp], + ['0.8.0', packedUserOp], + ['mdt', userOp], + ['mdt', packedUserOp], + ])( + 'should sign user operation and packed user operations for valid aa versions', + async ( + validAAVersion: string, + userOp: UserOperationToSign | PackedUserOperationToSign, + ) => { const signingResults = { '0xnode1': { messageHash: '0xhash1', @@ -226,20 +324,34 @@ describe('TACo Signing', () => { porterUris, ); - expect(porterSignUserOpMock).toHaveBeenCalledWith( - { - '0xnode1': expect.any(UserOperationSignatureRequest), - '0xnode2': expect.any(UserOperationSignatureRequest), - }, - threshold, - ); + if (isPackedUserOperation(userOp)) { + expect(porterSignUserOpMock).toHaveBeenCalledWith( + { + '0xnode1': expect.any(PackedUserOperationSignatureRequest), + '0xnode2': expect.any(PackedUserOperationSignatureRequest), + }, + threshold, + ); + } else { + expect(porterSignUserOpMock).toHaveBeenCalledWith( + { + '0xnode1': expect.any(UserOperationSignatureRequest), + '0xnode2': expect.any(UserOperationSignatureRequest), + }, + threshold, + ); + } const call = porterSignUserOpMock.mock.calls.at(-1)!; const [op] = call; const requests = [op['0xnode1'], op['0xnode2']]; requests.forEach((element) => { - checkUserOpEquality(userOp, element.userOp); + if (isPackedUserOperation(userOp)) { + checkPackedUserOpEquality(userOp, element.packedUserOp); + } else { + checkUserOpEquality(userOp, element.userOp); + } expect(element.aaVersion).toEqual(validAAVersion); expect(element.cohortId).toEqual(cohortId); expect(element.chainId).toEqual(BigInt(chainId)); From d985c131b9c25cf99f6dfd175f89212366e4e4a1 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 29 Oct 2025 20:55:17 -0400 Subject: [PATCH 208/303] Properly convert optional fields for UserOperation. --- packages/shared/src/types.ts | 32 ++++++++------ packages/taco/test/taco-sign.test.ts | 63 +++++++++++++++++++++++----- 2 files changed, 71 insertions(+), 24 deletions(-) diff --git a/packages/shared/src/types.ts b/packages/shared/src/types.ts index 2f4a2c301..8d4b96cdb 100644 --- a/packages/shared/src/types.ts +++ b/packages/shared/src/types.ts @@ -60,27 +60,33 @@ export function toCoreUserOperation( // optional factory data if (userOperation.factory) { - const factory_data = getUint8ArrayValue(userOperation.factoryData || '0x'); + let factory_data = undefined; + if (userOperation.factoryData) { + factory_data = getUint8ArrayValue(userOperation.factoryData); + } userOp.setFactoryData(userOperation.factory, factory_data); } // optional paymaster data if (userOperation.paymaster) { - const paymaster_verification_gas_limit = getBigIntValue( - userOperation.paymasterVerificationGasLimit || 0, - ); - const paymaster_post_op_gas_limit = getBigIntValue( - userOperation.paymasterPostOpGasLimit || 0, - ); - const paymaster_data = getUint8ArrayValue( - userOperation.paymasterData || '0x', - ); + if (!userOperation.paymasterVerificationGasLimit) { + throw new Error( + 'paymasterVerificationGasLimit is required when paymaster is set', + ); + } else if (!userOperation.paymasterPostOpGasLimit) { + throw new Error( + 'paymasterPostOpGasLimit is required when paymaster is set', + ); + } + userOp.setPaymasterData( userOperation.paymaster, - paymaster_verification_gas_limit, - paymaster_post_op_gas_limit, - paymaster_data, + getBigIntValue(userOperation.paymasterVerificationGasLimit), + getBigIntValue(userOperation.paymasterPostOpGasLimit), + userOperation.paymasterData + ? getUint8ArrayValue(userOperation.paymasterData) + : undefined, ); } diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index 93bf040fa..a3552fa06 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -80,7 +80,7 @@ function checkUserOpEquality(op1: UserOperationToSign, op2: UserOperation) { op1.callData instanceof Uint8Array ? op1.callData : fromHexString(op1.callData); - expect(callData).toEqual(callData); + expect(callData).toEqual(op2.callData); expect(getNumberValue(op1.callGasLimit)).toEqual(op2.callGasLimit); expect(getNumberValue(op1.verificationGasLimit)).toEqual( @@ -98,10 +98,15 @@ function checkUserOpEquality(op1: UserOperationToSign, op2: UserOperation) { expect(op2.factory).toBeUndefined(); } else { expect(op1.factory).toEqual(op2.factory); + } + + if (op1.factoryData === undefined) { + expect(op2.factoryData).toBeUndefined(); + } else { const factoryData = op1.factoryData instanceof Uint8Array ? op1.factoryData - : fromHexString(op1.factoryData || '0x'); + : fromHexString(op1.factoryData); expect(factoryData).toEqual(op2.factoryData); } @@ -109,16 +114,31 @@ function checkUserOpEquality(op1: UserOperationToSign, op2: UserOperation) { expect(op2.paymaster).toBeUndefined(); } else { expect(op1.paymaster).toEqual(op2.paymaster); - expect( - getNumberValue(op1.paymasterVerificationGasLimit || BigInt(0)), - ).toEqual(op2.paymasterVerificationGasLimit); - expect(getNumberValue(op1.paymasterPostOpGasLimit || BigInt(0))).toEqual( + } + + if (op1.paymasterVerificationGasLimit === undefined) { + expect(op2.paymasterVerificationGasLimit).toBeUndefined(); + } else { + expect(getNumberValue(op1.paymasterVerificationGasLimit)).toEqual( + op2.paymasterVerificationGasLimit, + ); + } + + if (op1.paymasterPostOpGasLimit === undefined) { + expect(op2.paymasterPostOpGasLimit).toBeUndefined(); + } else { + expect(getNumberValue(op1.paymasterPostOpGasLimit)).toEqual( op2.paymasterPostOpGasLimit, ); + } + + if (op1.paymasterData === undefined) { + expect(op2.paymasterData).toBeUndefined(); + } else { const paymasterData = op1.paymasterData instanceof Uint8Array ? op1.paymasterData - : fromHexString(op1.paymasterData || '0x'); + : fromHexString(op1.paymasterData); expect(paymasterData).toEqual(op2.paymasterData); } } @@ -161,7 +181,7 @@ describe('TACo Signing', () => { const coreUserOp = toCoreUserOperation(userOpToSign); checkUserOpEquality(userOpToSign, coreUserOp); }); - it('should convert factory optional fields', () => { + it('should allow factory optional fields', () => { const updatedUserOp: UserOperationToSign = { ...userOpToSign, factory: '0x000000000000000000000000000000000000000A', @@ -170,7 +190,7 @@ describe('TACo Signing', () => { const coreUserOp = toCoreUserOperation(updatedUserOp); checkUserOpEquality(updatedUserOp, coreUserOp); }); - it('should convert factory data to default when not specified but factory is', () => { + it('should allow factory and no factory data', () => { const updatedUserOp: UserOperationToSign = { ...userOpToSign, factory: '0x000000000000000000000000000000000000000A', @@ -178,7 +198,7 @@ describe('TACo Signing', () => { const coreUserOp = toCoreUserOperation(updatedUserOp); checkUserOpEquality(updatedUserOp, coreUserOp); }); - it('should convert paymaster optional fields', () => { + it('should allow paymaster optional fields with paymasterData', () => { const updatedUserOp: UserOperationToSign = { ...userOpToSign, paymaster: '0x000000000000000000000000000000000000000C', @@ -189,14 +209,35 @@ describe('TACo Signing', () => { const coreUserOp = toCoreUserOperation(updatedUserOp); checkUserOpEquality(updatedUserOp, coreUserOp); }); - it('should convert paymaster optional fields to defaults when not specified but paymaster is', () => { + it('should allow paymaster optional fields with no paymasterData', () => { const updatedUserOp: UserOperationToSign = { ...userOpToSign, paymaster: '0x000000000000000000000000000000000000000C', + paymasterVerificationGasLimit: BigInt(50000), + paymasterPostOpGasLimit: BigInt(30000), }; const coreUserOp = toCoreUserOperation(updatedUserOp); checkUserOpEquality(updatedUserOp, coreUserOp); }); + it('should raise when paymaster specified but other required fields are not present', () => { + let updatedUserOp: UserOperationToSign = { + ...userOpToSign, + paymaster: '0x000000000000000000000000000000000000000C', + // missing required paymasterVerificationGasLimit and paymasterPostOpGasLimit + }; + expect(() => toCoreUserOperation(updatedUserOp)).toThrow( + 'paymasterVerificationGasLimit is required when paymaster is set', + ); + + updatedUserOp = { + ...updatedUserOp, + paymasterVerificationGasLimit: BigInt(50000), + // missing required paymasterPostOpGasLimit + }; + expect(() => toCoreUserOperation(updatedUserOp)).toThrow( + 'paymasterPostOpGasLimit is required when paymaster is set', + ); + }); it('should handle alternative types: number and byte fields', () => { const updatedUserOp: UserOperationToSign = { ...userOpToSign, From e2b5f96ed43649fd94dd4939208c43c6a5f2c7c5 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 29 Oct 2025 20:55:51 -0400 Subject: [PATCH 209/303] Code cleanup. --- packages/shared/src/porter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index c79479db7..c3b782f39 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -345,7 +345,7 @@ export class PorterClient { toBase64(signingRequest.toBytes()), ]), ), - threshold: threshold, + threshold, }; const resp: AxiosResponse = await this.tryAndCall({ From f42b217635f335c00521bf2ee5b32ff9e211d31a Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 30 Oct 2025 08:48:55 -0400 Subject: [PATCH 210/303] Use experimental nucypher-core 0.15.1-dev.1 package. --- package.json | 4 ++-- packages/pre/package.json | 2 +- packages/shared/package.json | 4 ++-- packages/taco/package.json | 2 +- packages/test-utils/package.json | 2 +- pnpm-lock.yaml | 33 ++++++++++++++++++-------------- 6 files changed, 26 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index e6a583769..a246a2bf5 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ }, "dependencies": { "@changesets/cli": "^2.28.1", - "@nucypher/nucypher-core": "link:../nucypher-core/nucypher-core-wasm-bundler", + "@nucypher/nucypher-core": "^0.15.1-dev.1", "ethers": "^5.8.0" }, "devDependencies": { @@ -65,7 +65,7 @@ ] }, "overrides": { - "@nucypher/nucypher-core": "link:../nucypher-core/nucypher-core-wasm-bundler", + "@nucypher/nucypher-core": "^0.15.1-dev.1", "glob-parent@<5.1.2": ">=5.1.2", "node-forge@<1.0.0": ">=1.0.0", "node-forge@<1.3.0": ">=1.3.0", diff --git a/packages/pre/package.json b/packages/pre/package.json index 6aa3ccf7f..71437f31e 100644 --- a/packages/pre/package.json +++ b/packages/pre/package.json @@ -38,7 +38,7 @@ "typedoc": "typedoc" }, "dependencies": { - "@nucypher/nucypher-core": "^0.14.5", + "@nucypher/nucypher-core": "^0.15.1-dev.1", "@nucypher/shared": "workspace:*", "ethers": "^5.8.0" }, diff --git a/packages/shared/package.json b/packages/shared/package.json index 9839c6575..bf115eb89 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -43,8 +43,8 @@ "@ethersproject/abi": "^5.8.0", "@ethersproject/providers": "^5.8.0", "@nucypher/nucypher-contracts": "0.26.0-alpha.1", - "@nucypher/nucypher-core": "link:../../../nucypher-core/nucypher-core-wasm-bundler", - "axios": "^1.11.0", + "@nucypher/nucypher-core": "^0.15.1-dev.1", + "axios": "^1.8.4", "deep-equal": "^2.2.3", "ethers": "^5.8.0", "qs": "^6.14.0", diff --git a/packages/taco/package.json b/packages/taco/package.json index f916773c2..5045921b2 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -42,7 +42,7 @@ }, "dependencies": { "@astronautlabs/jsonpath": "^1.1.2", - "@nucypher/nucypher-core": "link:../../../nucypher-core/nucypher-core-wasm-bundler", + "@nucypher/nucypher-core": "^0.15.1-dev.1", "@nucypher/shared": "workspace:*", "@nucypher/taco-auth": "workspace:*", "ethers": "^5.8.0", diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 1295e2594..5264c3dfa 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -29,7 +29,7 @@ "lint:fix": "pnpm lint --fix" }, "dependencies": { - "@nucypher/nucypher-core": "^0.14.5", + "@nucypher/nucypher-core": "^0.15.1-dev.1", "@nucypher/shared": "workspace:*", "@nucypher/taco-auth": "workspace:*", "axios": "^1.11.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d4493e84a..869016a1a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,7 @@ settings: excludeLinksFromLockfile: false overrides: - '@nucypher/nucypher-core': link:../nucypher-core/nucypher-core-wasm-bundler + '@nucypher/nucypher-core': ^0.15.1-dev.1 glob-parent@<5.1.2: '>=5.1.2' node-forge@<1.0.0: '>=1.0.0' node-forge@<1.3.0: '>=1.3.0' @@ -19,8 +19,8 @@ importers: specifier: ^2.28.1 version: 2.30.0(@types/node@24.3.0) '@nucypher/nucypher-core': - specifier: link:../nucypher-core/nucypher-core-wasm-bundler - version: link:../nucypher-core/nucypher-core-wasm-bundler + specifier: ^0.15.1-dev.1 + version: 0.15.1-dev.3 ethers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -491,8 +491,8 @@ importers: packages/pre: dependencies: '@nucypher/nucypher-core': - specifier: link:../../../nucypher-core/nucypher-core-wasm-bundler - version: link:../../../nucypher-core/nucypher-core-wasm-bundler + specifier: ^0.15.1-dev.1 + version: 0.15.1-dev.3 '@nucypher/shared': specifier: workspace:* version: link:../shared @@ -516,10 +516,10 @@ importers: specifier: 0.26.0-alpha.1 version: 0.26.0-alpha.1 '@nucypher/nucypher-core': - specifier: link:../../../nucypher-core/nucypher-core-wasm-bundler - version: link:../../../nucypher-core/nucypher-core-wasm-bundler + specifier: ^0.15.1-dev.1 + version: 0.15.1-dev.3 axios: - specifier: ^1.11.0 + specifier: ^1.8.4 version: 1.15.0 deep-equal: specifier: ^2.2.3 @@ -565,8 +565,8 @@ importers: specifier: ^1.1.2 version: 1.1.2 '@nucypher/nucypher-core': - specifier: link:../../../nucypher-core/nucypher-core-wasm-bundler - version: link:../../../nucypher-core/nucypher-core-wasm-bundler + specifier: ^0.15.1-dev.1 + version: 0.15.1-dev.3 '@nucypher/shared': specifier: workspace:* version: link:../shared @@ -624,8 +624,8 @@ importers: packages/test-utils: dependencies: '@nucypher/nucypher-core': - specifier: link:../../../nucypher-core/nucypher-core-wasm-bundler - version: link:../../../nucypher-core/nucypher-core-wasm-bundler + specifier: ^0.15.1-dev.1 + version: 0.15.1-dev.3 '@nucypher/shared': specifier: workspace:* version: link:../shared @@ -2707,6 +2707,9 @@ packages: '@nucypher/nucypher-contracts@0.26.0-alpha.1': resolution: {integrity: sha512-ISS66SyKbDLXFF88Z6k8Tnc/L6Shx6tq22CjPpovbSD2PGS/UzE3uDxvFTKZfgcIJYsi7GV/ho2Brsx4sHYTLg==} + '@nucypher/nucypher-core@0.15.1-dev.3': + resolution: {integrity: sha512-0MJ8XvH2X5OyEx+f2i9A2iA+KosHzxZbOt8V3Ye6ZDlMC5N4aeDOEJ02ftwnc0C0NO0CPqTuLlYGbrreW57K+w==} + '@nucypher/shared@0.5.0': resolution: {integrity: sha512-Y+0oEgVtoud4BP/pvj2elPm5igrQ8AAUwYYmUiLpXNqQMRF4zFnYaGbl+xhKk45CYG8S9cDKJEN8nopzVADTNw==} engines: {node: '>=18', pnpm: '>=8.0.0'} @@ -12477,12 +12480,14 @@ snapshots: '@nucypher/nucypher-contracts@0.26.0-alpha.1': {} + '@nucypher/nucypher-core@0.15.1-dev.3': {} + '@nucypher/shared@0.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: '@ethersproject/abi': 5.8.0 '@ethersproject/providers': 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@nucypher/nucypher-contracts': 0.25.0 - '@nucypher/nucypher-core': link:../nucypher-core/nucypher-core-wasm-bundler + '@nucypher/nucypher-core': 0.15.1-dev.3 axios: 1.15.0 deep-equal: 2.2.3 ethers: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -12508,7 +12513,7 @@ snapshots: '@nucypher/taco@0.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: '@astronautlabs/jsonpath': 1.1.2 - '@nucypher/nucypher-core': link:../nucypher-core/nucypher-core-wasm-bundler + '@nucypher/nucypher-core': 0.15.1-dev.3 '@nucypher/shared': 0.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@nucypher/taco-auth': 0.3.0(bufferutil@4.1.0)(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(utf-8-validate@6.0.6) ethers: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) From e7d10f0cb4e3a5e44448a7a5ecb1642e01ec2c30 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 4 Nov 2025 11:37:10 -0500 Subject: [PATCH 211/303] Don't set optional fields for UserOperation integration test. --- packages/taco/integration-test/sign.test.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/taco/integration-test/sign.test.ts b/packages/taco/integration-test/sign.test.ts index 9f65c92e2..9ce8dc548 100644 --- a/packages/taco/integration-test/sign.test.ts +++ b/packages/taco/integration-test/sign.test.ts @@ -46,18 +46,12 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const userOp: UserOperationToSign = { sender: DUMMY_ADDRESS, nonce: 0, - factory: '0x', - factoryData: '0x', callData: '0x', callGasLimit: 0, verificationGasLimit: 0, preVerificationGas: 0, maxFeePerGas: 0, maxPriorityFeePerGas: 0, - paymaster: '0x', - paymasterVerificationGasLimit: 0, - paymasterPostOpGasLimit: 0, - paymasterData: '0x', signature: '0x', }; From 735043a215cd22ab06087eb16e204cfba34c1a20 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 4 Nov 2025 11:47:31 -0500 Subject: [PATCH 212/303] Install latest local `nucypher-core` dependency that includes encrypted signing request/response code. --- package.json | 4 ++-- packages/pre/package.json | 2 +- packages/shared/package.json | 2 +- packages/taco/package.json | 2 +- packages/test-utils/package.json | 2 +- pnpm-lock.yaml | 31 +++++++++++++------------------ 6 files changed, 19 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index a246a2bf5..e6a583769 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ }, "dependencies": { "@changesets/cli": "^2.28.1", - "@nucypher/nucypher-core": "^0.15.1-dev.1", + "@nucypher/nucypher-core": "link:../nucypher-core/nucypher-core-wasm-bundler", "ethers": "^5.8.0" }, "devDependencies": { @@ -65,7 +65,7 @@ ] }, "overrides": { - "@nucypher/nucypher-core": "^0.15.1-dev.1", + "@nucypher/nucypher-core": "link:../nucypher-core/nucypher-core-wasm-bundler", "glob-parent@<5.1.2": ">=5.1.2", "node-forge@<1.0.0": ">=1.0.0", "node-forge@<1.3.0": ">=1.3.0", diff --git a/packages/pre/package.json b/packages/pre/package.json index 71437f31e..9adc2b69b 100644 --- a/packages/pre/package.json +++ b/packages/pre/package.json @@ -38,7 +38,7 @@ "typedoc": "typedoc" }, "dependencies": { - "@nucypher/nucypher-core": "^0.15.1-dev.1", + "@nucypher/nucypher-core": "link:../../../nucypher-core/nucypher-core-wasm-bundler", "@nucypher/shared": "workspace:*", "ethers": "^5.8.0" }, diff --git a/packages/shared/package.json b/packages/shared/package.json index bf115eb89..d1cdea3fe 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -43,7 +43,7 @@ "@ethersproject/abi": "^5.8.0", "@ethersproject/providers": "^5.8.0", "@nucypher/nucypher-contracts": "0.26.0-alpha.1", - "@nucypher/nucypher-core": "^0.15.1-dev.1", + "@nucypher/nucypher-core": "link:../../../nucypher-core/nucypher-core-wasm-bundler", "axios": "^1.8.4", "deep-equal": "^2.2.3", "ethers": "^5.8.0", diff --git a/packages/taco/package.json b/packages/taco/package.json index 5045921b2..f916773c2 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -42,7 +42,7 @@ }, "dependencies": { "@astronautlabs/jsonpath": "^1.1.2", - "@nucypher/nucypher-core": "^0.15.1-dev.1", + "@nucypher/nucypher-core": "link:../../../nucypher-core/nucypher-core-wasm-bundler", "@nucypher/shared": "workspace:*", "@nucypher/taco-auth": "workspace:*", "ethers": "^5.8.0", diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 5264c3dfa..9fa84db27 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -29,7 +29,7 @@ "lint:fix": "pnpm lint --fix" }, "dependencies": { - "@nucypher/nucypher-core": "^0.15.1-dev.1", + "@nucypher/nucypher-core": "link:../../../nucypher-core/nucypher-core-wasm-bundler", "@nucypher/shared": "workspace:*", "@nucypher/taco-auth": "workspace:*", "axios": "^1.11.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 869016a1a..d7ef49cc9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,7 @@ settings: excludeLinksFromLockfile: false overrides: - '@nucypher/nucypher-core': ^0.15.1-dev.1 + '@nucypher/nucypher-core': link:../nucypher-core/nucypher-core-wasm-bundler glob-parent@<5.1.2: '>=5.1.2' node-forge@<1.0.0: '>=1.0.0' node-forge@<1.3.0: '>=1.3.0' @@ -19,8 +19,8 @@ importers: specifier: ^2.28.1 version: 2.30.0(@types/node@24.3.0) '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.1 - version: 0.15.1-dev.3 + specifier: link:../nucypher-core/nucypher-core-wasm-bundler + version: link:../nucypher-core/nucypher-core-wasm-bundler ethers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -491,8 +491,8 @@ importers: packages/pre: dependencies: '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.1 - version: 0.15.1-dev.3 + specifier: link:../../../nucypher-core/nucypher-core-wasm-bundler + version: link:../../../nucypher-core/nucypher-core-wasm-bundler '@nucypher/shared': specifier: workspace:* version: link:../shared @@ -516,8 +516,8 @@ importers: specifier: 0.26.0-alpha.1 version: 0.26.0-alpha.1 '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.1 - version: 0.15.1-dev.3 + specifier: link:../../../nucypher-core/nucypher-core-wasm-bundler + version: link:../../../nucypher-core/nucypher-core-wasm-bundler axios: specifier: ^1.8.4 version: 1.15.0 @@ -565,8 +565,8 @@ importers: specifier: ^1.1.2 version: 1.1.2 '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.1 - version: 0.15.1-dev.3 + specifier: link:../../../nucypher-core/nucypher-core-wasm-bundler + version: link:../../../nucypher-core/nucypher-core-wasm-bundler '@nucypher/shared': specifier: workspace:* version: link:../shared @@ -624,8 +624,8 @@ importers: packages/test-utils: dependencies: '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.1 - version: 0.15.1-dev.3 + specifier: link:../../../nucypher-core/nucypher-core-wasm-bundler + version: link:../../../nucypher-core/nucypher-core-wasm-bundler '@nucypher/shared': specifier: workspace:* version: link:../shared @@ -2707,9 +2707,6 @@ packages: '@nucypher/nucypher-contracts@0.26.0-alpha.1': resolution: {integrity: sha512-ISS66SyKbDLXFF88Z6k8Tnc/L6Shx6tq22CjPpovbSD2PGS/UzE3uDxvFTKZfgcIJYsi7GV/ho2Brsx4sHYTLg==} - '@nucypher/nucypher-core@0.15.1-dev.3': - resolution: {integrity: sha512-0MJ8XvH2X5OyEx+f2i9A2iA+KosHzxZbOt8V3Ye6ZDlMC5N4aeDOEJ02ftwnc0C0NO0CPqTuLlYGbrreW57K+w==} - '@nucypher/shared@0.5.0': resolution: {integrity: sha512-Y+0oEgVtoud4BP/pvj2elPm5igrQ8AAUwYYmUiLpXNqQMRF4zFnYaGbl+xhKk45CYG8S9cDKJEN8nopzVADTNw==} engines: {node: '>=18', pnpm: '>=8.0.0'} @@ -12480,14 +12477,12 @@ snapshots: '@nucypher/nucypher-contracts@0.26.0-alpha.1': {} - '@nucypher/nucypher-core@0.15.1-dev.3': {} - '@nucypher/shared@0.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: '@ethersproject/abi': 5.8.0 '@ethersproject/providers': 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@nucypher/nucypher-contracts': 0.25.0 - '@nucypher/nucypher-core': 0.15.1-dev.3 + '@nucypher/nucypher-core': link:../nucypher-core/nucypher-core-wasm-bundler axios: 1.15.0 deep-equal: 2.2.3 ethers: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -12513,7 +12508,7 @@ snapshots: '@nucypher/taco@0.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: '@astronautlabs/jsonpath': 1.1.2 - '@nucypher/nucypher-core': 0.15.1-dev.3 + '@nucypher/nucypher-core': link:../nucypher-core/nucypher-core-wasm-bundler '@nucypher/shared': 0.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@nucypher/taco-auth': 0.3.0(bufferutil@4.1.0)(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(utf-8-validate@6.0.6) ethers: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) From d146b657e14bda072dfdb1364227fc96fe5155b0 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 7 Nov 2025 15:02:11 -0500 Subject: [PATCH 213/303] Add capabilities for creating/handling encrypted requests/responses for signing to facilitate end-to-end encrypted communication between requester and nodes. Update to use updated Porter inputs and outputs. --- .../contracts/agents/signing-coordinator.ts | 10 +- packages/shared/src/porter.ts | 67 +++--- packages/taco/src/sign.ts | 197 ++++++++++++------ 3 files changed, 173 insertions(+), 101 deletions(-) diff --git a/packages/shared/src/contracts/agents/signing-coordinator.ts b/packages/shared/src/contracts/agents/signing-coordinator.ts index c2fe8b507..4bf439e1c 100644 --- a/packages/shared/src/contracts/agents/signing-coordinator.ts +++ b/packages/shared/src/contracts/agents/signing-coordinator.ts @@ -1,4 +1,5 @@ import { getContract } from '@nucypher/nucypher-contracts'; +import { SessionStaticKey, SessionStaticSecret } from '@nucypher/nucypher-core'; import { ethers } from 'ethers'; import { Domain } from '../../porter'; @@ -6,9 +7,9 @@ import { SigningCoordinator__factory } from '../ethers-typechain'; import { SigningCoordinator } from '../ethers-typechain/SigningCoordinator'; export type SignerInfo = { - operator: string; provider: string; - signature: string; + signerAddress: string; + signingRequestStaticKey: SessionStaticKey; }; export class SigningCoordinatorAgent { @@ -25,9 +26,10 @@ export class SigningCoordinatorAgent { participant: SigningCoordinator.SigningCohortParticipantStructOutput, ) => { return { - operator: participant.operator, provider: participant.provider, - signature: participant.signature, + signerAddress: participant.operator, + // TODO fix once available via nucypher-contract dependency + signingRequestStaticKey: SessionStaticSecret.random().publicKey(), }; }, ); diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index c3b782f39..f460c7dba 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -2,12 +2,11 @@ import { CapsuleFrag, EncryptedThresholdDecryptionRequest, EncryptedThresholdDecryptionResponse, - PackedUserOperationSignatureRequest, + EncryptedThresholdSignatureRequest, + EncryptedThresholdSignatureResponse, PublicKey, RetrievalKit, - SignatureResponse, TreasureMap, - UserOperationSignatureRequest, } from '@nucypher/nucypher-core'; import axios, { AxiosRequestConfig, @@ -161,14 +160,20 @@ export type TacoDecryptResult = { // Signing types type PostTacoSignRequest = { - readonly signing_requests: Record; + readonly encrypted_signing_requests: Record< + ChecksumAddress, + Base64EncodedBytes + >; readonly threshold: number; }; type TacoSignResponse = { readonly result: { readonly signing_results: { - readonly signatures: Record; + readonly encrypted_signature_responses: Record< + ChecksumAddress, + Base64EncodedBytes + >; readonly errors: Record; }; }; @@ -181,7 +186,10 @@ export type TacoSignature = { }; export type TacoSignResult = { - signingResults: Record; + encryptedResponses: Record< + ChecksumAddress, + EncryptedThresholdSignatureResponse + >; errors: Record; }; @@ -332,18 +340,20 @@ export class PorterClient { } public async signUserOp( - signingRequests: Record< + encryptedSigningRequests: Record< string, - UserOperationSignatureRequest | PackedUserOperationSignatureRequest + EncryptedThresholdSignatureRequest >, threshold: number, ): Promise { const data: PostTacoSignRequest = { - signing_requests: Object.fromEntries( - Object.entries(signingRequests).map(([ursula, signingRequest]) => [ - ursula, - toBase64(signingRequest.toBytes()), - ]), + encrypted_signing_requests: Object.fromEntries( + Object.entries(encryptedSigningRequests).map( + ([ursula, encryptedSigningRequest]) => [ + ursula, + toBase64(encryptedSigningRequest.toBytes()), + ], + ), ), threshold, }; @@ -353,25 +363,22 @@ export class PorterClient { method: 'post', data, }); - const { signatures, errors } = resp.data.result.signing_results; - - const signingResults: { [ursulaAddress: string]: TacoSignature } = {}; - for (const [ursulaAddress, signatureResponseBase64] of Object.entries( - signatures || {}, + const { encrypted_signature_responses, errors } = + resp.data.result.signing_results; + + const encryptedResponses: { + [ursulaAddress: string]: EncryptedThresholdSignatureResponse; + } = {}; + for (const [ursulaAddress, encryptedResponseBase64] of Object.entries( + encrypted_signature_responses || {}, )) { - const signatureResponse = SignatureResponse.fromBytes( - fromBase64(signatureResponseBase64 as string), - ); - signingResults[ursulaAddress] = { - messageHash: `0x${toHexString(signatureResponse.hash)}`, - signature: `0x${toHexString(signatureResponse.signature)}`, - signerAddress: signatureResponse.signer, - }; + const encryptedSignatureResponse = + EncryptedThresholdSignatureResponse.fromBytes( + fromBase64(encryptedResponseBase64), + ); + encryptedResponses[ursulaAddress] = encryptedSignatureResponse; } - return { - signingResults, - errors, - }; + return { encryptedResponses, errors }; } } diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index e60fd94e0..9a1f1fde8 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -1,5 +1,10 @@ import { + EncryptedThresholdSignatureRequest, + EncryptedThresholdSignatureResponse, PackedUserOperationSignatureRequest, + SessionSharedSecret, + SessionStaticSecret, + SignatureResponse, UserOperationSignatureRequest, } from '@nucypher/nucypher-core'; import { @@ -12,7 +17,6 @@ import { SignerInfo, SigningCoordinatorAgent, TacoSignature, - TacoSignResult, toCorePackedUserOperation, toCoreUserOperation, toHexString, @@ -60,19 +64,19 @@ function aggregateSignatures( } async function makeSigningRequests( - signers: SignerInfo[], cohortId: number, chainId: number, + signers: Array, userOp: UserOperationToSign | PackedUserOperationToSign, aaVersion: string, - context?: ConditionContext, -): Promise< - Record< - string, - PackedUserOperationSignatureRequest | UserOperationSignatureRequest - > -> { - const coreContext = context ? await context.toCoreContext() : null; + conditionContext?: ConditionContext, +): Promise<{ + sharedSecrets: Record; + encryptedRequests: Record; +}> { + const coreContext = conditionContext + ? await conditionContext.toCoreContext() + : null; let signingRequest: | PackedUserOperationSignatureRequest @@ -97,13 +101,29 @@ async function makeSigningRequests( ); } - const signingRequests: Record< - string, - PackedUserOperationSignatureRequest | UserOperationSignatureRequest - > = Object.fromEntries( - signers.map((signer) => [signer.provider, signingRequest]), + const ephemeralSessionKey = SessionStaticSecret.random(); + + const sharedSecrets: Record = Object.fromEntries( + signers.map(({ provider, signingRequestStaticKey }) => { + const sharedSecret = ephemeralSessionKey.deriveSharedSecret( + signingRequestStaticKey, + ); + return [provider, sharedSecret]; + }), ); - return signingRequests; + + const encryptedRequests: Record = + Object.fromEntries( + Object.entries(sharedSecrets).map(([provider, sessionSharedSecret]) => { + const encryptedRequest = signingRequest.encrypt( + sessionSharedSecret, + ephemeralSessionKey.publicKey(), + ); + return [provider, encryptedRequest]; + }), + ); + + return { sharedSecrets, encryptedRequests }; } /** @@ -146,67 +166,30 @@ export async function signUserOp( cohortId, ); - const signingRequests = await makeSigningRequests( - signers, + const { sharedSecrets, encryptedRequests } = await makeSigningRequests( cohortId, chainId, + signers, userOp, aaVersion, context, ); // Build signing request for the user operation - const porterSignResult: TacoSignResult = await porter.signUserOp( - signingRequests, + const { encryptedResponses, errors } = await porter.signUserOp( + encryptedRequests, threshold, ); - - const hashToSignatures: Map< - string, - Record - > = new Map(); - - // Single pass: decode signatures and populate signingResults - for (const [ursulaAddress, signature] of Object.entries( - porterSignResult.signingResults, - )) { - // For non-optimistic: track hashes and group signatures for aggregation - const hash = signature.messageHash; - if (!hashToSignatures.has(hash)) { - hashToSignatures.set(hash, {}); - } - hashToSignatures.get(hash)![ursulaAddress] = signature; + if (Object.keys(encryptedResponses).length < threshold) { + // not enough signatures returned + throw new Error(ERR_INSUFFICIENT_SIGNATURES(errors)); } - let messageHash = undefined; - let signaturesToAggregate = undefined; - for (const [hash, signatures] of hashToSignatures.entries()) { - if (Object.keys(signatures).length >= threshold) { - signaturesToAggregate = signatures; - messageHash = hash; - break; - } - } - - // Insufficient signatures for a message hash to meet the threshold - if (!messageHash || !signaturesToAggregate) { - if ( - hashToSignatures.size > 1 && - Object.keys(porterSignResult.errors).length < signers.length - threshold - ) { - // Two things are true: - // 1. we have multiple hashes, which means we have mismatched hashes from different nodes - // we don't really expect this to happen (other than some malicious nodes) - // 2. number of errors still could have allowed for a threshold of signatures - console.error( - 'Porter returned mismatched message hashes:', - hashToSignatures, - ); - throw new Error(ERR_MISMATCHED_HASHES(hashToSignatures)); - } else { - throw new Error(ERR_INSUFFICIENT_SIGNATURES(porterSignResult.errors)); - } - } + const signaturesToAggregate = collectSignatures( + encryptedResponses, + sharedSecrets, + threshold, + ); const aggregatedSignature = aggregateSignatures( signaturesToAggregate, @@ -214,9 +197,9 @@ export async function signUserOp( ); return { - messageHash, + messageHash: Object.values(signaturesToAggregate)[0].messageHash, aggregatedSignature, - signingResults: porterSignResult.signingResults, + signingResults: signaturesToAggregate, }; } @@ -243,3 +226,83 @@ export async function setSigningCohortConditions( signer, ); } + +function decryptSignatureResponses( + encryptedResponses: Record, + sharedSecrets: Record, +): Record { + const decryptedResponses: Record = + Object.fromEntries( + Object.entries(encryptedResponses).map( + ([ursulaAddress, encryptedResponse]) => [ + ursulaAddress, + encryptedResponse.decrypt(sharedSecrets[ursulaAddress]), + ], + ), + ); + + const tacoSignatures: Record = Object.fromEntries( + Object.entries(decryptedResponses).map( + ([ursulaAddress, signatureResponse]) => [ + ursulaAddress, + { + messageHash: `0x${toHexString(signatureResponse.hash)}`, + signature: `0x${toHexString(signatureResponse.signature)}`, + signerAddress: signatureResponse.signer, + }, + ], + ), + ); + + return tacoSignatures; +} + +function collectSignatures( + encryptedResponses: Record, + sharedSecrets: Record, + threshold: number, +): Record { + const decryptedSignatures = decryptSignatureResponses( + encryptedResponses, + sharedSecrets, + ); + + const hashToSignatures: Map< + string, + Record + > = new Map(); + + // Single pass: decode signatures and populate signingResults + for (const [ursulaAddress, signature] of Object.entries( + decryptedSignatures, + )) { + // For non-optimistic: track hashes and group signatures for aggregation + const hash = signature.messageHash; + if (!hashToSignatures.has(hash)) { + hashToSignatures.set(hash, {}); + } + hashToSignatures.get(hash)![ursulaAddress] = signature; + } + + // Find a hash that meets the threshold + let signaturesToAggregate = undefined; + for (const signatures of hashToSignatures.values()) { + if (Object.keys(signatures).length >= threshold) { + signaturesToAggregate = signatures; + break; + } + } + + // Insufficient signatures for a message hash to meet the threshold + if (!signaturesToAggregate) { + //we have multiple hashes, which means we have mismatched hashes from different nodes + // we don't really expect this to happen (other than some malicious nodes) + console.error( + 'Porter returned mismatched message hashes:', + hashToSignatures, + ); + throw new Error(ERR_MISMATCHED_HASHES(hashToSignatures)); + } + + return signaturesToAggregate; +} From 79d824464072f7cf12ccb9ed00acd828475ba191 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 7 Nov 2025 15:04:06 -0500 Subject: [PATCH 214/303] Add tests for encrypted signing requests/responses. --- packages/shared/test/porter.test.ts | 464 +++++++++------------------ packages/taco/test/taco-sign.test.ts | 356 +++++++++++++------- 2 files changed, 393 insertions(+), 427 deletions(-) diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index c6d84178e..ae057ba54 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -5,6 +5,7 @@ import { beforeAll, describe, expect, it, MockInstance, vi } from 'vitest'; import { PackedUserOperation, PackedUserOperationSignatureRequest, + SessionStaticSecret, SignatureResponse, UserOperation, UserOperationSignatureRequest, @@ -60,52 +61,77 @@ const mockGetUrsulas = (ursulas: Ursula[] = fakeUrsulas()): MockInstance => { }); }; -const createMockSignResponse = (errorCase?: boolean) => ({ - result: { - signing_results: { - signatures: errorCase - ? { - '0xabcd': [ - toBase64( - new SignatureResponse( - '0x0000000000000000000000000000000000000001', - fromHexString('0x1234'), - fromHexString('0xbeef'), - 0, - ).toBytes(), - ), - ], - } - : { - '0x1234': [ - toBase64( - new SignatureResponse( - '0x0000000000000000000000000000000000000002', - fromHexString('0x1234'), - fromHexString('0xdead'), - 0, - ).toBytes(), - ), - ], - '0xabcd': [ - toBase64( - new SignatureResponse( - '0x0000000000000000000000000000000000000001', - fromHexString('0x1234'), - fromHexString('0xbeef'), - 0, - ).toBytes(), - ), - ], - }, - errors: errorCase - ? { - '0x1234': 'Failed to sign', - } - : {}, +const createMockSignResponse = (errorCase?: boolean) => { + // mimic requester public key obtained from original encrypted request + const requesterPk = SessionStaticSecret.random().publicKey(); + + const response = { + result: { + signing_results: { + encrypted_signature_responses: errorCase + ? { + '0xabcd': [ + toBase64( + new SignatureResponse( + '0x0000000000000000000000000000000000000001', + fromHexString('0x1234'), + fromHexString('0xbeef'), + 0, + ) + .encrypt( + SessionStaticSecret.random().deriveSharedSecret( + requesterPk, + ), + ) + .toBytes(), + ), + ], + } + : { + '0x1234': [ + toBase64( + new SignatureResponse( + '0x0000000000000000000000000000000000000002', + fromHexString('0x1234'), + fromHexString('0xdead'), + 0, + ) + .encrypt( + SessionStaticSecret.random().deriveSharedSecret( + requesterPk, + ), + ) + .toBytes(), + ), + ], + '0xabcd': [ + toBase64( + new SignatureResponse( + '0x0000000000000000000000000000000000000001', + fromHexString('0x1234'), + fromHexString('0xbeef'), + 0, + ) + .encrypt( + SessionStaticSecret.random().deriveSharedSecret( + requesterPk, + ), + ) + .toBytes(), + ), + ], + }, + errors: errorCase + ? { + '0x1234': 'Failed to sign', + } + : {}, + }, }, - }, -}); + }; + + return response; +}; const createMockSignImplementation = (endpoint: string) => @@ -202,7 +228,15 @@ describe('PorterClient Signing', () => { describe('signUserOp', () => { // since this uses wasm it must be called after initialize (beforeAll()) so we use a factory function - const createUserSignatureRequest = () => + let requesterSk: SessionStaticSecret; + let requesterPk: any; + + beforeAll(async () => { + requesterSk = SessionStaticSecret.random(); + requesterPk = requesterSk.publicKey(); + }); + + const createUserOpSignatureRequest = () => new UserOperationSignatureRequest( new UserOperation( '0x000000000000000000000000000000000000000a', @@ -221,33 +255,30 @@ describe('PorterClient Signing', () => { ); it('should successfully sign a UserOperation', async () => { - const userOpSignatureRequest = createUserSignatureRequest(); + const userOpSignatureRequest = createUserOpSignatureRequest(); mockSignUserOp(true); const porterClient = new PorterClient(fakePorterUris[2]); const result = await porterClient.signUserOp( { - '0x1234': userOpSignatureRequest, - '0xabcd': userOpSignatureRequest, + '0x1234': userOpSignatureRequest.encrypt( + requesterSk.deriveSharedSecret( + SessionStaticSecret.random().publicKey(), + ), + requesterPk, + ), + '0xabcd': userOpSignatureRequest.encrypt( + requesterSk.deriveSharedSecret( + SessionStaticSecret.random().publicKey(), + ), + requesterPk, + ), }, 2, ); - expect(result).toEqual({ - signingResults: { - '0x1234': { - messageHash: '0x1234', - signature: '0xdead', - signerAddress: '0x0000000000000000000000000000000000000002', - }, - '0xabcd': { - messageHash: '0x1234', - signature: '0xbeef', - signerAddress: '0x0000000000000000000000000000000000000001', - }, - }, - errors: {}, - }); + expect(Object.keys(result.errors).length).toBe(0); + expect(Object.keys(result.encryptedResponses).length).toBe(2); }); it('should successfully sign a PackedUserOperation', async () => { @@ -273,31 +304,28 @@ describe('PorterClient Signing', () => { const porterClient = new PorterClient(fakePorterUris[2]); const result = await porterClient.signUserOp( { - '0x1234': packedUserOperationSignatureRequest, - '0xabcd': packedUserOperationSignatureRequest, + '0x1234': packedUserOperationSignatureRequest.encrypt( + requesterSk.deriveSharedSecret( + SessionStaticSecret.random().publicKey(), + ), + requesterPk, + ), + '0xabcd': packedUserOperationSignatureRequest.encrypt( + requesterSk.deriveSharedSecret( + SessionStaticSecret.random().publicKey(), + ), + requesterPk, + ), }, 2, ); - expect(result).toEqual({ - signingResults: { - '0x1234': { - messageHash: '0x1234', - signature: '0xdead', - signerAddress: '0x0000000000000000000000000000000000000002', - }, - '0xabcd': { - messageHash: '0x1234', - signature: '0xbeef', - signerAddress: '0x0000000000000000000000000000000000000001', - }, - }, - errors: {}, - }); + expect(Object.keys(result.errors).length).toBe(0); + expect(Object.keys(result.encryptedResponses).length).toBe(2); }); it('should handle UserOperation signing failures', async () => { - const userOpSignatureRequest = createUserSignatureRequest(); + const userOpSignatureRequest = createUserOpSignatureRequest(); mockSignUserOp(false); const porterClient = new PorterClient(fakePorterUris[2]); @@ -305,8 +333,18 @@ describe('PorterClient Signing', () => { await expect( porterClient.signUserOp( { - '0x1234': userOpSignatureRequest, - '0xabcd': userOpSignatureRequest, + '0x1234': userOpSignatureRequest.encrypt( + requesterSk.deriveSharedSecret( + SessionStaticSecret.random().publicKey(), + ), + requesterPk, + ), + '0xabcd': userOpSignatureRequest.encrypt( + requesterSk.deriveSharedSecret( + SessionStaticSecret.random().publicKey(), + ), + requesterPk, + ), }, 2, ), @@ -314,256 +352,60 @@ describe('PorterClient Signing', () => { }); it('should handle errors from Porter response in UserOperation signing', async () => { - const userOpSignatureRequest = createUserSignatureRequest(); + const userOpSignatureRequest = createUserOpSignatureRequest(); // Mock a response with errors from Porter mockSignUserOp(true, true); const porterClient = new PorterClient(fakePorterUris[2]); const result = await porterClient.signUserOp( { - '0x1234': userOpSignatureRequest, - '0xabcd': userOpSignatureRequest, - }, - 2, - ); - - expect(result).toEqual({ - signingResults: { - '0xabcd': { - messageHash: '0x1234', - signature: '0xbeef', - signerAddress: '0x0000000000000000000000000000000000000001', - }, - }, - errors: { - '0x1234': 'Failed to sign', - }, - }); - }); - - it('should include error when message hashes do not match', async () => { - const userOpSignatureRequest = createUserSignatureRequest(); - - const createMismatchedResponse = () => ({ - result: { - signing_results: { - signatures: { - '0x1234': toBase64( - new SignatureResponse( - '0x0000000000000000000000000000000000000002', - fromHexString('0x1234'), - fromHexString('0xdead'), - 0, - ).toBytes(), - ), - '0xabcd': toBase64( - new SignatureResponse( - '0x0000000000000000000000000000000000000001', - fromHexString('0xdddd'), // Different message hash - fromHexString('0xbeef'), - 0, - ).toBytes(), - ), - }, - errors: {}, - }, - }, - }); - - vi.spyOn(axios, 'request').mockImplementation(async (config) => { - if (config.url === '/sign' && config.baseURL === fakePorterUris[2]) { - return Promise.resolve({ - status: HttpStatusCode.Ok, - data: createMismatchedResponse(), - }); - } - }); - - const porterClient = new PorterClient(fakePorterUris[2]); - const result = await porterClient.signUserOp( - { - '0x1234': userOpSignatureRequest, - '0xabcd': userOpSignatureRequest, + '0x1234': userOpSignatureRequest.encrypt( + requesterSk.deriveSharedSecret( + SessionStaticSecret.random().publicKey(), + ), + requesterPk, + ), + '0xabcd': userOpSignatureRequest.encrypt( + requesterSk.deriveSharedSecret( + SessionStaticSecret.random().publicKey(), + ), + requesterPk, + ), }, 2, ); - expect(result).toEqual({ - signingResults: { - '0x1234': { - messageHash: '0x1234', - signature: '0xdead', - signerAddress: '0x0000000000000000000000000000000000000002', - }, - '0xabcd': { - messageHash: '0xdddd', // Different hash - signature: '0xbeef', - signerAddress: '0x0000000000000000000000000000000000000001', - }, - }, - errors: {}, // No errors - mismatched hashes don't generate errors, just prevent aggregation - }); - }); - - it('should not return aggregated signature when threshold not met', async () => { - const userOpSignatureRequest = createUserSignatureRequest(); - - const createInsufficientResponse = () => ({ - result: { - signing_results: { - signatures: { - '0x1234': toBase64( - new SignatureResponse( - '0x0000000000000000000000000000000000000002', - fromHexString('0x1234'), - fromHexString('0xdead'), - 0, - ).toBytes(), - ), - // Only 1 signature, but threshold is 2 - }, - errors: {}, - }, - }, - }); - - vi.spyOn(axios, 'request').mockImplementation(async (config) => { - if (config.url === '/sign' && config.baseURL === fakePorterUris[2]) { - return Promise.resolve({ - status: HttpStatusCode.Ok, - data: createInsufficientResponse(), - }); - } - }); - - const porterClient = new PorterClient(fakePorterUris[2]); - const result = await porterClient.signUserOp( - { - '0x1234': userOpSignatureRequest, - '0xabcd': userOpSignatureRequest, - }, - 2, // threshold of 2, but only 1 signature - ); - - expect(result).toEqual({ - signingResults: { - '0x1234': { - messageHash: '0x1234', - signature: '0xdead', - signerAddress: '0x0000000000000000000000000000000000000002', - }, - }, - errors: {}, + expect(Object.keys(result.encryptedResponses).length).toBe(1); + expect(result.errors).toEqual({ + '0x1234': 'Failed to sign', }); }); it('should successfully sign', async () => { - const userOpSignatureRequest = createUserSignatureRequest(); + const userOpSignatureRequest = createUserOpSignatureRequest(); mockSignUserOp(true); const porterClient = new PorterClient(fakePorterUris[2]); const result = await porterClient.signUserOp( { - '0x1234': userOpSignatureRequest, - '0xabcd': userOpSignatureRequest, + '0x1234': userOpSignatureRequest.encrypt( + requesterSk.deriveSharedSecret( + SessionStaticSecret.random().publicKey(), + ), + requesterPk, + ), + '0xabcd': userOpSignatureRequest.encrypt( + requesterSk.deriveSharedSecret( + SessionStaticSecret.random().publicKey(), + ), + requesterPk, + ), }, 2, ); - expect(result).toEqual({ - signingResults: { - '0x1234': { - messageHash: '0x1234', - signature: '0xdead', - signerAddress: '0x0000000000000000000000000000000000000002', - }, - '0xabcd': { - messageHash: '0x1234', - signature: '0xbeef', - signerAddress: '0x0000000000000000000000000000000000000001', - }, - }, - errors: {}, - }); - }); - - it('should aggregate only threshold-meeting hash', async () => { - const userOpSignatureRequest = createUserSignatureRequest(); - - const createMixedHashResponse = () => ({ - result: { - signing_results: { - signatures: { - '0x1234': toBase64( - new SignatureResponse( - '0x0000000000000000000000000000000000000002', - fromHexString('0x0001'), - fromHexString('0xdead'), - 0, - ).toBytes(), - ), - '0xabcd': toBase64( - new SignatureResponse( - '0x0000000000000000000000000000000000000001', - fromHexString('0x0001'), // Same hash, meets threshold - fromHexString('0xbeef'), - 0, - ).toBytes(), - ), - '0xdef0': toBase64( - new SignatureResponse( - '0x0000000000000000000000000000000000000003', - fromHexString('0x0002'), // Different hash, doesn't meet threshold - fromHexString('0xcafe'), - 0, - ).toBytes(), - ), - }, - errors: {}, - }, - }, - }); - - vi.spyOn(axios, 'request').mockImplementation(async (config) => { - if (config.url === '/sign' && config.baseURL === fakePorterUris[2]) { - return Promise.resolve({ - status: HttpStatusCode.Ok, - data: createMixedHashResponse(), - }); - } - }); - - const porterClient = new PorterClient(fakePorterUris[2]); - const result = await porterClient.signUserOp( - { - '0x1234': userOpSignatureRequest, - '0xabcd': userOpSignatureRequest, - '0xdef0': userOpSignatureRequest, - }, - 2, // threshold of 2 - ); - - expect(result).toEqual({ - // different hashes returned separately - signingResults: { - '0x1234': { - messageHash: '0x0001', - signature: '0xdead', - signerAddress: '0x0000000000000000000000000000000000000002', - }, - '0xabcd': { - messageHash: '0x0001', - signature: '0xbeef', - signerAddress: '0x0000000000000000000000000000000000000001', - }, - '0xdef0': { - messageHash: '0x0002', - signature: '0xcafe', - signerAddress: '0x0000000000000000000000000000000000000003', - }, - }, - errors: {}, - }); + expect(Object.keys(result.errors).length).toBe(0); + expect(Object.keys(result.encryptedResponses).length).toBe(2); }); }); }); diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index a3552fa06..d8d7322c6 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -1,8 +1,10 @@ import { + EncryptedThresholdSignatureRequest, PackedUserOperation, - PackedUserOperationSignatureRequest, + SessionStaticKey, + SessionStaticSecret, + SignatureResponse, UserOperation, - UserOperationSignatureRequest, } from '@nucypher/nucypher-core'; import { fromHexString, @@ -10,6 +12,7 @@ import { isPackedUserOperation, PackedUserOperationToSign, PorterClient, + SignerInfo, SigningCoordinatorAgent, toCorePackedUserOperation, toCoreUserOperation, @@ -25,6 +28,8 @@ import { CompoundCondition } from '../src/conditions/compound-condition'; import { ConditionExpression } from '../src/conditions/condition-expr'; import { setSigningCohortConditions, signUserOp } from '../src/sign'; +import { mockMakeSessionKey } from './test-utils'; + function getNumberValue(value: bigint | number): bigint { return typeof value === 'bigint' ? value : BigInt(value); } @@ -151,6 +156,10 @@ describe('TACo Signing', () => { await initialize(); }); + let signersInfo: Record; + let requesterSk: SessionStaticSecret; + let signerStaticKeys: Record; + beforeEach(() => { porterSignUserOpMock = vi.fn(); mockProvider = {} as ethers.providers.Provider; @@ -158,10 +167,30 @@ describe('TACo Signing', () => { vi.spyOn(PorterClient.prototype, 'signUserOp').mockImplementation( porterSignUserOpMock, ); - vi.spyOn(SigningCoordinatorAgent, 'getParticipants').mockResolvedValue([ - { operator: '0xsnr1', provider: '0xnode1', signature: '0xa' }, - { operator: '0xsnr2', provider: '0xnode2', signature: '0xb' }, - ]); + signerStaticKeys = { + '0xnode1': SessionStaticSecret.random().publicKey(), + '0xnode2': SessionStaticSecret.random().publicKey(), + }; + + requesterSk = SessionStaticSecret.random(); + mockMakeSessionKey(requesterSk); + + signersInfo = { + '0xnode1': { + signerAddress: '0x0000000000000000000000000000000000000001', + provider: '0xnode1', + signingRequestStaticKey: signerStaticKeys['0xnode1'], + }, + '0xnode2': { + signerAddress: '0x0000000000000000000000000000000000000002', + provider: '0xnode2', + signingRequestStaticKey: signerStaticKeys['0xnode2'], + }, + }; + + vi.spyOn(SigningCoordinatorAgent, 'getParticipants').mockResolvedValue( + Object.values(signersInfo), + ); vi.spyOn(SigningCoordinatorAgent, 'getThreshold').mockResolvedValue(2); }); @@ -335,22 +364,32 @@ describe('TACo Signing', () => { validAAVersion: string, userOp: UserOperationToSign | PackedUserOperationToSign, ) => { - const signingResults = { - '0xnode1': { - messageHash: '0xhash1', - signature: '0xdead', - signerAddress: '0xsnr1', - }, - '0xnode2': { - messageHash: '0xhash1', - signature: '0xbeef', - signerAddress: '0xsnr2', - }, + const encryptedResponses = { + '0xnode1': new SignatureResponse( + signersInfo['0xnode1'].signerAddress, + fromHexString('0xa1'), + fromHexString('0xdead'), + 0, + ).encrypt( + requesterSk.deriveSharedSecret( + signersInfo['0xnode1'].signingRequestStaticKey, + ), + ), + '0xnode2': new SignatureResponse( + signersInfo['0xnode2'].signerAddress, + fromHexString('0xa1'), + fromHexString('0xbeef'), + 0, + ).encrypt( + requesterSk.deriveSharedSecret( + signersInfo['0xnode2'].signingRequestStaticKey, + ), + ), }; const errors = {}; porterSignUserOpMock.mockResolvedValue({ - signingResults, + encryptedResponses, errors, }); @@ -365,58 +404,66 @@ describe('TACo Signing', () => { porterUris, ); - if (isPackedUserOperation(userOp)) { - expect(porterSignUserOpMock).toHaveBeenCalledWith( - { - '0xnode1': expect.any(PackedUserOperationSignatureRequest), - '0xnode2': expect.any(PackedUserOperationSignatureRequest), - }, - threshold, - ); - } else { - expect(porterSignUserOpMock).toHaveBeenCalledWith( - { - '0xnode1': expect.any(UserOperationSignatureRequest), - '0xnode2': expect.any(UserOperationSignatureRequest), - }, - threshold, - ); - } + expect(porterSignUserOpMock).toHaveBeenCalledWith( + { + '0xnode1': expect.any(EncryptedThresholdSignatureRequest), + '0xnode2': expect.any(EncryptedThresholdSignatureRequest), + }, + threshold, + ); const call = porterSignUserOpMock.mock.calls.at(-1)!; const [op] = call; - const requests = [op['0xnode1'], op['0xnode2']]; - requests.forEach((element) => { + const nodes = ['0xnode1', '0xnode2']; + nodes.forEach((node) => { + const element = op[node]; + const decryptedRequest = element.decrypt( + requesterSk.deriveSharedSecret( + signersInfo[node].signingRequestStaticKey, + ), + ); + if (isPackedUserOperation(userOp)) { - checkPackedUserOpEquality(userOp, element.packedUserOp); + checkPackedUserOpEquality(userOp, decryptedRequest.packedUserOp); } else { - checkUserOpEquality(userOp, element.userOp); + checkUserOpEquality(userOp, decryptedRequest.userOp); } - expect(element.aaVersion).toEqual(validAAVersion); - expect(element.cohortId).toEqual(cohortId); - expect(element.chainId).toEqual(BigInt(chainId)); - expect(element.context).toBeUndefined(); + expect(decryptedRequest.aaVersion).toEqual(validAAVersion); + expect(decryptedRequest.cohortId).toEqual(cohortId); + expect(decryptedRequest.chainId).toEqual(BigInt(chainId)); + expect(decryptedRequest.context).toBeUndefined(); }); expect(result).toEqual({ - messageHash: '0xhash1', + messageHash: '0xa1', aggregatedSignature: '0xdeadbeef', - signingResults, + signingResults: { + '0xnode1': { + messageHash: '0xa1', + signature: '0xdead', + signerAddress: signersInfo['0xnode1'].signerAddress, + }, + '0xnode2': { + messageHash: '0xa1', + signature: '0xbeef', + signerAddress: signersInfo['0xnode2'].signerAddress, + }, + }, }); }, ); it('should handle only errors in Porter response', async () => { // Mock a response with errors from Porter - const signingResults = {}; + const encryptedResponses = {}; const errors = { '0xnode1': 'Failed to sign', '0xnode2': 'Failed to sign', }; porterSignUserOpMock.mockResolvedValue({ - signingResults, + encryptedResponses, errors, }); @@ -437,37 +484,49 @@ describe('TACo Signing', () => { expect(porterSignUserOpMock).toHaveBeenCalledWith( { - '0xnode1': expect.any(UserOperationSignatureRequest), - '0xnode2': expect.any(UserOperationSignatureRequest), + '0xnode1': expect.any(EncryptedThresholdSignatureRequest), + '0xnode2': expect.any(EncryptedThresholdSignatureRequest), }, threshold, ); const call = porterSignUserOpMock.mock.calls.at(-1)!; const [op] = call; - const requests = [op['0xnode1'], op['0xnode2']]; - requests.forEach((element) => { - checkUserOpEquality(userOp, element.userOp); - expect(element.aaVersion).toEqual(aaVersion); - expect(element.cohortId).toEqual(cohortId); - expect(element.chainId).toEqual(BigInt(chainId)); - expect(element.context).toBeUndefined(); + const nodes = ['0xnode1', '0xnode2']; + nodes.forEach((node) => { + const element = op[node]; + const decryptedRequest = element.decrypt( + requesterSk.deriveSharedSecret( + signersInfo[node].signingRequestStaticKey, + ), + ); + checkUserOpEquality(userOp, decryptedRequest.userOp); + expect(decryptedRequest.aaVersion).toEqual(aaVersion); + expect(decryptedRequest.cohortId).toEqual(cohortId); + expect(decryptedRequest.chainId).toEqual(BigInt(chainId)); + expect(decryptedRequest.context).toBeUndefined(); }); }); it('should handle insufficient signatures in Porter response', async () => { - const signingResults = { - '0xnode1': { - messageHash: '0xhash1', - signature: '0xdead', - signerAddress: '0xsnr1', - }, + const encryptedResponses = { + '0xnode1': new SignatureResponse( + signersInfo['0xnode1'].signerAddress, + fromHexString('0xa1'), + fromHexString('0xdead'), + 0, + ).encrypt( + requesterSk.deriveSharedSecret( + signersInfo['0xnode1'].signingRequestStaticKey, + ), + ), }; + const errors = { '0xnode2': 'Failed to sign', }; porterSignUserOpMock.mockResolvedValue({ - signingResults, + encryptedResponses, errors, }); @@ -488,34 +547,49 @@ describe('TACo Signing', () => { }); it('should handle insufficient matched hashes in Porter response', async () => { - // set up 3 signers - it matters based on how mismatched hashes are handled + // use 3 signers - it matters based on how mismatched hashes are handled + const node3SecretKey = SessionStaticSecret.random(); vi.spyOn(SigningCoordinatorAgent, 'getParticipants').mockResolvedValue([ - { operator: '0xsnr1', provider: '0xnode1', signature: '0xa' }, - { operator: '0xsnr2', provider: '0xnode2', signature: '0xb' }, - { operator: '0xsnr3', provider: '0xnode3', signature: '0xc' }, + ...Object.values(signersInfo), + { + signerAddress: '0x0000000000000000000000000000000000000003', + provider: '0xnode3', + signingRequestStaticKey: node3SecretKey.publicKey(), + }, ]); - const signingResults = { - '0xnode1': { - messageHash: '0xhash1', - signature: '0xdead', - signerAddress: '0xsnr1', - }, - '0xnode2': { - messageHash: '0xhash2', - signature: '0xbeef', - signerAddress: '0xsnr2', - }, - '0xnode3': { - messageHash: '0xhash3', - signature: '0xcafe', - signerAddress: '0xsnr3', - }, + const encryptedResponses = { + '0xnode1': new SignatureResponse( + signersInfo['0xnode1'].signerAddress, + fromHexString('0xa1'), + fromHexString('0xdead'), + 0, + ).encrypt( + requesterSk.deriveSharedSecret( + signersInfo['0xnode1'].signingRequestStaticKey, + ), + ), + '0xnode2': new SignatureResponse( + signersInfo['0xnode2'].signerAddress, + fromHexString('0xa2'), + fromHexString('0xbeef'), + 0, + ).encrypt( + requesterSk.deriveSharedSecret( + signersInfo['0xnode2'].signingRequestStaticKey, + ), + ), + '0xnode3': new SignatureResponse( + '0x0000000000000000000000000000000000000003', + fromHexString('0xa3'), + fromHexString('0xcafe'), + 0, + ).encrypt(requesterSk.deriveSharedSecret(node3SecretKey.publicKey())), }; const errors = {}; porterSignUserOpMock.mockResolvedValue({ - signingResults, + encryptedResponses, errors, }); @@ -536,19 +610,24 @@ describe('TACo Signing', () => { it('properly handles threshold of 1 signature from Porter', async () => { vi.spyOn(SigningCoordinatorAgent, 'getThreshold').mockResolvedValue(1); - const signingResults = { - '0xnode1': { - messageHash: '0xhash1', - signature: '0xdead', - signerAddress: '0xsnr1', - }, + const encryptedResponses = { + '0xnode1': new SignatureResponse( + signersInfo['0xnode1'].signerAddress, + fromHexString('0xa1'), + fromHexString('0xdead'), + 0, + ).encrypt( + requesterSk.deriveSharedSecret( + signersInfo['0xnode1'].signingRequestStaticKey, + ), + ), }; const errors = { '0xnode2': 'Failed to sign', }; porterSignUserOpMock.mockResolvedValue({ - signingResults, + encryptedResponses, errors, }); @@ -564,41 +643,75 @@ describe('TACo Signing', () => { ); expect(result).toEqual({ - messageHash: '0xhash1', + messageHash: '0xa1', aggregatedSignature: '0xdead', - signingResults, + signingResults: { + '0xnode1': { + messageHash: '0xa1', + signature: '0xdead', + signerAddress: signersInfo['0xnode1'].signerAddress, + }, + }, }); }); it('ignore errors/mismatched hashes if threshold of matching hashes and signatures from Porter', async () => { - const signingResults = { - '0xnode1': { - messageHash: '0xhash1', - signature: '0xdead', - signerAddress: '0xsnr1', - }, - '0xnode2': { - messageHash: '0xhash2', - signature: '0xcafe', - signerAddress: '0xsnr2', - }, - '0xnode3': { - messageHash: '0xhash3', - signature: '0xbabe', - signerAddress: '0xsnr3', + const node3SecretKey = SessionStaticSecret.random(); + const node4SecretKey = SessionStaticSecret.random(); + vi.spyOn(SigningCoordinatorAgent, 'getParticipants').mockResolvedValue([ + ...Object.values(signersInfo), + { + signerAddress: '0x0000000000000000000000000000000000000003', + provider: '0xnode3', + signingRequestStaticKey: node3SecretKey.publicKey(), }, - '0xnode4': { - messageHash: '0xhash1', - signature: '0xbeef', - signerAddress: '0xsnr4', + { + signerAddress: '0x000000000000000000000000000000000000004', + provider: '0xnode4', + signingRequestStaticKey: node4SecretKey.publicKey(), }, + ]); + + const encryptedResponses = { + '0xnode1': new SignatureResponse( + signersInfo['0xnode1'].signerAddress, + fromHexString('0xa1'), // matching hash + fromHexString('0xdead'), + 0, + ).encrypt( + requesterSk.deriveSharedSecret( + signersInfo['0xnode1'].signingRequestStaticKey, + ), + ), + '0xnode2': new SignatureResponse( + signersInfo['0xnode2'].signerAddress, + fromHexString('0xa2'), + fromHexString('0xbeef'), + 0, + ).encrypt( + requesterSk.deriveSharedSecret( + signersInfo['0xnode2'].signingRequestStaticKey, + ), + ), + '0xnode3': new SignatureResponse( + '0x0000000000000000000000000000000000000003', + fromHexString('0xa3'), + fromHexString('0xcafe'), + 0, + ).encrypt(requesterSk.deriveSharedSecret(node3SecretKey.publicKey())), + '0xnode4': new SignatureResponse( + '0x0000000000000000000000000000000000000004', + fromHexString('0xa1'), // matching hash + fromHexString('0xcafe'), + 0, + ).encrypt(requesterSk.deriveSharedSecret(node4SecretKey.publicKey())), }; const errors = { '0x7890': 'Failed to sign', }; porterSignUserOpMock.mockResolvedValue({ - signingResults, + encryptedResponses, errors, }); @@ -614,9 +727,20 @@ describe('TACo Signing', () => { ); expect(result).toEqual({ - messageHash: '0xhash1', - aggregatedSignature: '0xdeadbeef', - signingResults, + messageHash: '0xa1', + aggregatedSignature: '0xdeadcafe', // from node1 and node4 + signingResults: { + '0xnode1': { + messageHash: '0xa1', + signature: '0xdead', + signerAddress: signersInfo['0xnode1'].signerAddress, + }, + '0xnode4': { + messageHash: '0xa1', + signature: '0xcafe', + signerAddress: '0x0000000000000000000000000000000000000004', + }, + }, }); }); }); From ec2ae322a4fae933a1a0a4265c556832bd53d3cb Mon Sep 17 00:00:00 2001 From: derekpierre Date: Sun, 9 Nov 2025 20:53:33 -0500 Subject: [PATCH 215/303] Update `nucypher-core` dependency to point to experimental version. --- package.json | 4 ++-- packages/pre/package.json | 2 +- packages/shared/package.json | 2 +- packages/taco/package.json | 2 +- packages/test-utils/package.json | 2 +- pnpm-lock.yaml | 31 ++++++++++++++++++------------- 6 files changed, 24 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index e6a583769..cbdddf377 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ }, "dependencies": { "@changesets/cli": "^2.28.1", - "@nucypher/nucypher-core": "link:../nucypher-core/nucypher-core-wasm-bundler", + "@nucypher/nucypher-core": "^0.15.1-dev.2", "ethers": "^5.8.0" }, "devDependencies": { @@ -65,7 +65,7 @@ ] }, "overrides": { - "@nucypher/nucypher-core": "link:../nucypher-core/nucypher-core-wasm-bundler", + "@nucypher/nucypher-core": "^0.15.1-dev.2", "glob-parent@<5.1.2": ">=5.1.2", "node-forge@<1.0.0": ">=1.0.0", "node-forge@<1.3.0": ">=1.3.0", diff --git a/packages/pre/package.json b/packages/pre/package.json index 9adc2b69b..59e2fb337 100644 --- a/packages/pre/package.json +++ b/packages/pre/package.json @@ -38,7 +38,7 @@ "typedoc": "typedoc" }, "dependencies": { - "@nucypher/nucypher-core": "link:../../../nucypher-core/nucypher-core-wasm-bundler", + "@nucypher/nucypher-core": "^0.15.1-dev.2", "@nucypher/shared": "workspace:*", "ethers": "^5.8.0" }, diff --git a/packages/shared/package.json b/packages/shared/package.json index d1cdea3fe..0469d4fb5 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -43,7 +43,7 @@ "@ethersproject/abi": "^5.8.0", "@ethersproject/providers": "^5.8.0", "@nucypher/nucypher-contracts": "0.26.0-alpha.1", - "@nucypher/nucypher-core": "link:../../../nucypher-core/nucypher-core-wasm-bundler", + "@nucypher/nucypher-core": "^0.15.1-dev.2", "axios": "^1.8.4", "deep-equal": "^2.2.3", "ethers": "^5.8.0", diff --git a/packages/taco/package.json b/packages/taco/package.json index f916773c2..8211466ff 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -42,7 +42,7 @@ }, "dependencies": { "@astronautlabs/jsonpath": "^1.1.2", - "@nucypher/nucypher-core": "link:../../../nucypher-core/nucypher-core-wasm-bundler", + "@nucypher/nucypher-core": "^0.15.1-dev.2", "@nucypher/shared": "workspace:*", "@nucypher/taco-auth": "workspace:*", "ethers": "^5.8.0", diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 9fa84db27..39df81e44 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -29,7 +29,7 @@ "lint:fix": "pnpm lint --fix" }, "dependencies": { - "@nucypher/nucypher-core": "link:../../../nucypher-core/nucypher-core-wasm-bundler", + "@nucypher/nucypher-core": "^0.15.1-dev.2", "@nucypher/shared": "workspace:*", "@nucypher/taco-auth": "workspace:*", "axios": "^1.11.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d7ef49cc9..dcd3840e5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,7 @@ settings: excludeLinksFromLockfile: false overrides: - '@nucypher/nucypher-core': link:../nucypher-core/nucypher-core-wasm-bundler + '@nucypher/nucypher-core': ^0.15.1-dev.2 glob-parent@<5.1.2: '>=5.1.2' node-forge@<1.0.0: '>=1.0.0' node-forge@<1.3.0: '>=1.3.0' @@ -19,8 +19,8 @@ importers: specifier: ^2.28.1 version: 2.30.0(@types/node@24.3.0) '@nucypher/nucypher-core': - specifier: link:../nucypher-core/nucypher-core-wasm-bundler - version: link:../nucypher-core/nucypher-core-wasm-bundler + specifier: ^0.15.1-dev.2 + version: 0.15.1-dev.3 ethers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -491,8 +491,8 @@ importers: packages/pre: dependencies: '@nucypher/nucypher-core': - specifier: link:../../../nucypher-core/nucypher-core-wasm-bundler - version: link:../../../nucypher-core/nucypher-core-wasm-bundler + specifier: ^0.15.1-dev.2 + version: 0.15.1-dev.3 '@nucypher/shared': specifier: workspace:* version: link:../shared @@ -516,8 +516,8 @@ importers: specifier: 0.26.0-alpha.1 version: 0.26.0-alpha.1 '@nucypher/nucypher-core': - specifier: link:../../../nucypher-core/nucypher-core-wasm-bundler - version: link:../../../nucypher-core/nucypher-core-wasm-bundler + specifier: ^0.15.1-dev.2 + version: 0.15.1-dev.3 axios: specifier: ^1.8.4 version: 1.15.0 @@ -565,8 +565,8 @@ importers: specifier: ^1.1.2 version: 1.1.2 '@nucypher/nucypher-core': - specifier: link:../../../nucypher-core/nucypher-core-wasm-bundler - version: link:../../../nucypher-core/nucypher-core-wasm-bundler + specifier: ^0.15.1-dev.2 + version: 0.15.1-dev.3 '@nucypher/shared': specifier: workspace:* version: link:../shared @@ -624,8 +624,8 @@ importers: packages/test-utils: dependencies: '@nucypher/nucypher-core': - specifier: link:../../../nucypher-core/nucypher-core-wasm-bundler - version: link:../../../nucypher-core/nucypher-core-wasm-bundler + specifier: ^0.15.1-dev.2 + version: 0.15.1-dev.3 '@nucypher/shared': specifier: workspace:* version: link:../shared @@ -2707,6 +2707,9 @@ packages: '@nucypher/nucypher-contracts@0.26.0-alpha.1': resolution: {integrity: sha512-ISS66SyKbDLXFF88Z6k8Tnc/L6Shx6tq22CjPpovbSD2PGS/UzE3uDxvFTKZfgcIJYsi7GV/ho2Brsx4sHYTLg==} + '@nucypher/nucypher-core@0.15.1-dev.3': + resolution: {integrity: sha512-0MJ8XvH2X5OyEx+f2i9A2iA+KosHzxZbOt8V3Ye6ZDlMC5N4aeDOEJ02ftwnc0C0NO0CPqTuLlYGbrreW57K+w==} + '@nucypher/shared@0.5.0': resolution: {integrity: sha512-Y+0oEgVtoud4BP/pvj2elPm5igrQ8AAUwYYmUiLpXNqQMRF4zFnYaGbl+xhKk45CYG8S9cDKJEN8nopzVADTNw==} engines: {node: '>=18', pnpm: '>=8.0.0'} @@ -12477,12 +12480,14 @@ snapshots: '@nucypher/nucypher-contracts@0.26.0-alpha.1': {} + '@nucypher/nucypher-core@0.15.1-dev.3': {} + '@nucypher/shared@0.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: '@ethersproject/abi': 5.8.0 '@ethersproject/providers': 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@nucypher/nucypher-contracts': 0.25.0 - '@nucypher/nucypher-core': link:../nucypher-core/nucypher-core-wasm-bundler + '@nucypher/nucypher-core': 0.15.1-dev.3 axios: 1.15.0 deep-equal: 2.2.3 ethers: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -12508,7 +12513,7 @@ snapshots: '@nucypher/taco@0.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: '@astronautlabs/jsonpath': 1.1.2 - '@nucypher/nucypher-core': link:../nucypher-core/nucypher-core-wasm-bundler + '@nucypher/nucypher-core': 0.15.1-dev.3 '@nucypher/shared': 0.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@nucypher/taco-auth': 0.3.0(bufferutil@4.1.0)(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(utf-8-validate@6.0.6) ethers: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) From a5cb76515e1732033006a63c5905008b1b8249ca Mon Sep 17 00:00:00 2001 From: derekpierre Date: Sun, 9 Nov 2025 21:13:43 -0500 Subject: [PATCH 216/303] Update nucypher-contracts dependency to latest development version. Run typechain build of contracts Update CoordinatorAgent to not use isEncryptionAuthorized since no longer available in Coordinator contract Update SigningCoordinatorAgent to properly set signingRequestStaticKey from contract. --- packages/shared/package.json | 2 +- .../src/contracts/agents/coordinator.ts | 20 +- .../contracts/agents/signing-coordinator.ts | 9 +- .../contracts/ethers-typechain/Coordinator.ts | 782 +++++++++++++----- .../ethers-typechain/SigningCoordinator.ts | 179 ++-- .../factories/Coordinator__factory.ts | 508 +++++++++--- .../factories/SigningCoordinator__factory.ts | 92 ++- packages/taco/test/test-utils.ts | 10 - pnpm-lock.yaml | 10 +- 9 files changed, 1156 insertions(+), 456 deletions(-) diff --git a/packages/shared/package.json b/packages/shared/package.json index 0469d4fb5..3c1930138 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -42,7 +42,7 @@ "dependencies": { "@ethersproject/abi": "^5.8.0", "@ethersproject/providers": "^5.8.0", - "@nucypher/nucypher-contracts": "0.26.0-alpha.1", + "@nucypher/nucypher-contracts": "^0.26.0-alpha.2", "@nucypher/nucypher-core": "^0.15.1-dev.2", "axios": "^1.8.4", "deep-equal": "^2.2.3", diff --git a/packages/shared/src/contracts/agents/coordinator.ts b/packages/shared/src/contracts/agents/coordinator.ts index ab50500c3..a570cb76c 100644 --- a/packages/shared/src/contracts/agents/coordinator.ts +++ b/packages/shared/src/contracts/agents/coordinator.ts @@ -1,9 +1,5 @@ import { getContract } from '@nucypher/nucypher-contracts'; -import { - DkgPublicKey, - SessionStaticKey, - ThresholdMessageKit, -} from '@nucypher/nucypher-core'; +import { DkgPublicKey, SessionStaticKey } from '@nucypher/nucypher-core'; import { BigNumberish, ethers } from 'ethers'; import { Domain } from '../../porter'; @@ -140,20 +136,6 @@ export class DkgCoordinatorAgent { return await coordinator.getRitualIdFromPublicKey(pointStruct); } - public static async isEncryptionAuthorized( - provider: ethers.providers.Provider, - domain: Domain, - ritualId: number, - thresholdMessageKit: ThresholdMessageKit, - ): Promise { - const coordinator = await this.connectReadOnly(provider, domain); - return await coordinator.isEncryptionAuthorized( - ritualId, - thresholdMessageKit.acp.authorization, - thresholdMessageKit.ciphertextHeader.toBytes(), - ); - } - private static async connectReadOnly( provider: ethers.providers.Provider, domain: Domain, diff --git a/packages/shared/src/contracts/agents/signing-coordinator.ts b/packages/shared/src/contracts/agents/signing-coordinator.ts index 4bf439e1c..22c974305 100644 --- a/packages/shared/src/contracts/agents/signing-coordinator.ts +++ b/packages/shared/src/contracts/agents/signing-coordinator.ts @@ -1,8 +1,9 @@ import { getContract } from '@nucypher/nucypher-contracts'; -import { SessionStaticKey, SessionStaticSecret } from '@nucypher/nucypher-core'; +import { SessionStaticKey } from '@nucypher/nucypher-core'; import { ethers } from 'ethers'; import { Domain } from '../../porter'; +import { fromHexString } from '../../utils'; import { SigningCoordinator__factory } from '../ethers-typechain'; import { SigningCoordinator } from '../ethers-typechain/SigningCoordinator'; @@ -27,9 +28,11 @@ export class SigningCoordinatorAgent { ) => { return { provider: participant.provider, - signerAddress: participant.operator, + signerAddress: participant.signerAddress, // TODO fix once available via nucypher-contract dependency - signingRequestStaticKey: SessionStaticSecret.random().publicKey(), + signingRequestStaticKey: SessionStaticKey.fromBytes( + fromHexString(participant.signingRequestStaticKey), + ), }; }, ); diff --git a/packages/shared/src/contracts/ethers-typechain/Coordinator.ts b/packages/shared/src/contracts/ethers-typechain/Coordinator.ts index 21619add1..c327751e1 100644 --- a/packages/shared/src/contracts/ethers-typechain/Coordinator.ts +++ b/packages/shared/src/contracts/ethers-typechain/Coordinator.ts @@ -67,23 +67,31 @@ export interface CoordinatorInterface extends utils.Interface { functions: { 'DEFAULT_ADMIN_ROLE()': FunctionFragment; 'FEE_MODEL_MANAGER_ROLE()': FunctionFragment; + 'HANDOVER_SUPERVISOR_ROLE()': FunctionFragment; 'TREASURY_ROLE()': FunctionFragment; 'acceptDefaultAdminTransfer()': FunctionFragment; 'application()': FunctionFragment; 'approveFeeModel(address)': FunctionFragment; 'beginDefaultAdminTransfer(address)': FunctionFragment; + 'blindedSharePosition(uint256,uint16)': FunctionFragment; 'cancelDefaultAdminTransfer()': FunctionFragment; + 'cancelHandover(uint32,address)': FunctionFragment; 'changeDefaultAdminDelay(uint48)': FunctionFragment; 'cohortFingerprint(address[])': FunctionFragment; 'defaultAdmin()': FunctionFragment; 'defaultAdminDelay()': FunctionFragment; 'defaultAdminDelayIncreaseWait()': FunctionFragment; + 'dkgTimeout()': FunctionFragment; + 'dkgTimeoutStub()': FunctionFragment; 'expectedTranscriptSize(uint16,uint16)': FunctionFragment; 'extendRitual(uint32,uint32)': FunctionFragment; 'feeModelsRegistry(address)': FunctionFragment; + 'finalizeHandover(uint32,address)': FunctionFragment; 'getAccessController(uint32)': FunctionFragment; 'getAuthority(uint32)': FunctionFragment; 'getFeeModel(uint32)': FunctionFragment; + 'getHandoverKey(uint32,address)': FunctionFragment; + 'getHandoverState(uint32,address)': FunctionFragment; 'getInitiator(uint32)': FunctionFragment; 'getParticipant(uint32,address,bool)': FunctionFragment; 'getParticipantFromProvider(uint32,address)': FunctionFragment; @@ -98,11 +106,12 @@ export interface CoordinatorInterface extends utils.Interface { 'getThresholdForRitualSize(uint16)': FunctionFragment; 'getTimestamps(uint32)': FunctionFragment; 'grantRole(bytes32,address)': FunctionFragment; + 'handoverRequest(uint32,address,address)': FunctionFragment; + 'handoverTimeout()': FunctionFragment; + 'handovers(bytes32)': FunctionFragment; 'hasRole(bytes32,address)': FunctionFragment; - 'initialize(uint32,uint16,address)': FunctionFragment; - 'initializeNumberOfRituals()': FunctionFragment; + 'initialize(uint16,address)': FunctionFragment; 'initiateRitual(address,address[],address,uint32,address)': FunctionFragment; - 'isEncryptionAuthorized(uint32,bytes,bytes)': FunctionFragment; 'isParticipant(uint32,address)': FunctionFragment; 'isProviderKeySet(address)': FunctionFragment; 'isProviderPublicKeySet(address)': FunctionFragment; @@ -113,9 +122,9 @@ export interface CoordinatorInterface extends utils.Interface { 'pendingDefaultAdmin()': FunctionFragment; 'pendingDefaultAdminDelay()': FunctionFragment; 'postAggregation(uint32,bytes,(bytes32,bytes16),bytes)': FunctionFragment; - 'postTranscript(uint32,bytes)': FunctionFragment; + 'postBlindedShare(uint32,bytes)': FunctionFragment; + 'postHandoverTranscript(uint32,address,bytes,bytes)': FunctionFragment; 'publishTranscript(uint32,bytes)': FunctionFragment; - 'reinitializeDefaultAdmin(address)': FunctionFragment; 'renounceRole(bytes32,address)': FunctionFragment; 'revokeRole(bytes32,address)': FunctionFragment; 'rituals(uint256)': FunctionFragment; @@ -123,34 +132,40 @@ export interface CoordinatorInterface extends utils.Interface { 'setMaxDkgSize(uint16)': FunctionFragment; 'setProviderPublicKey((bytes32,bytes32,bytes32))': FunctionFragment; 'setReimbursementPool(address)': FunctionFragment; - 'setTimeout(uint32)': FunctionFragment; 'supportsInterface(bytes4)': FunctionFragment; 'timeout()': FunctionFragment; 'transferRitualAuthority(uint32,address)': FunctionFragment; - 'withdrawAllTokens(address)': FunctionFragment; }; getFunction( nameOrSignatureOrTopic: | 'DEFAULT_ADMIN_ROLE' | 'FEE_MODEL_MANAGER_ROLE' + | 'HANDOVER_SUPERVISOR_ROLE' | 'TREASURY_ROLE' | 'acceptDefaultAdminTransfer' | 'application' | 'approveFeeModel' | 'beginDefaultAdminTransfer' + | 'blindedSharePosition' | 'cancelDefaultAdminTransfer' + | 'cancelHandover' | 'changeDefaultAdminDelay' | 'cohortFingerprint' | 'defaultAdmin' | 'defaultAdminDelay' | 'defaultAdminDelayIncreaseWait' + | 'dkgTimeout' + | 'dkgTimeoutStub' | 'expectedTranscriptSize' | 'extendRitual' | 'feeModelsRegistry' + | 'finalizeHandover' | 'getAccessController' | 'getAuthority' | 'getFeeModel' + | 'getHandoverKey' + | 'getHandoverState' | 'getInitiator' | 'getParticipant' | 'getParticipantFromProvider' @@ -165,11 +180,12 @@ export interface CoordinatorInterface extends utils.Interface { | 'getThresholdForRitualSize' | 'getTimestamps' | 'grantRole' + | 'handoverRequest' + | 'handoverTimeout' + | 'handovers' | 'hasRole' | 'initialize' - | 'initializeNumberOfRituals' | 'initiateRitual' - | 'isEncryptionAuthorized' | 'isParticipant' | 'isProviderKeySet' | 'isProviderPublicKeySet' @@ -180,9 +196,9 @@ export interface CoordinatorInterface extends utils.Interface { | 'pendingDefaultAdmin' | 'pendingDefaultAdminDelay' | 'postAggregation' - | 'postTranscript' + | 'postBlindedShare' + | 'postHandoverTranscript' | 'publishTranscript' - | 'reinitializeDefaultAdmin' | 'renounceRole' | 'revokeRole' | 'rituals' @@ -190,11 +206,9 @@ export interface CoordinatorInterface extends utils.Interface { | 'setMaxDkgSize' | 'setProviderPublicKey' | 'setReimbursementPool' - | 'setTimeout' | 'supportsInterface' | 'timeout' - | 'transferRitualAuthority' - | 'withdrawAllTokens', + | 'transferRitualAuthority', ): FunctionFragment; encodeFunctionData( @@ -205,6 +219,10 @@ export interface CoordinatorInterface extends utils.Interface { functionFragment: 'FEE_MODEL_MANAGER_ROLE', values?: undefined, ): string; + encodeFunctionData( + functionFragment: 'HANDOVER_SUPERVISOR_ROLE', + values?: undefined, + ): string; encodeFunctionData( functionFragment: 'TREASURY_ROLE', values?: undefined, @@ -225,10 +243,18 @@ export interface CoordinatorInterface extends utils.Interface { functionFragment: 'beginDefaultAdminTransfer', values: [string], ): string; + encodeFunctionData( + functionFragment: 'blindedSharePosition', + values: [BigNumberish, BigNumberish], + ): string; encodeFunctionData( functionFragment: 'cancelDefaultAdminTransfer', values?: undefined, ): string; + encodeFunctionData( + functionFragment: 'cancelHandover', + values: [BigNumberish, string], + ): string; encodeFunctionData( functionFragment: 'changeDefaultAdminDelay', values: [BigNumberish], @@ -249,6 +275,14 @@ export interface CoordinatorInterface extends utils.Interface { functionFragment: 'defaultAdminDelayIncreaseWait', values?: undefined, ): string; + encodeFunctionData( + functionFragment: 'dkgTimeout', + values?: undefined, + ): string; + encodeFunctionData( + functionFragment: 'dkgTimeoutStub', + values?: undefined, + ): string; encodeFunctionData( functionFragment: 'expectedTranscriptSize', values: [BigNumberish, BigNumberish], @@ -261,6 +295,10 @@ export interface CoordinatorInterface extends utils.Interface { functionFragment: 'feeModelsRegistry', values: [string], ): string; + encodeFunctionData( + functionFragment: 'finalizeHandover', + values: [BigNumberish, string], + ): string; encodeFunctionData( functionFragment: 'getAccessController', values: [BigNumberish], @@ -273,6 +311,14 @@ export interface CoordinatorInterface extends utils.Interface { functionFragment: 'getFeeModel', values: [BigNumberish], ): string; + encodeFunctionData( + functionFragment: 'getHandoverKey', + values: [BigNumberish, string], + ): string; + encodeFunctionData( + functionFragment: 'getHandoverState', + values: [BigNumberish, string], + ): string; encodeFunctionData( functionFragment: 'getInitiator', values: [BigNumberish], @@ -329,26 +375,30 @@ export interface CoordinatorInterface extends utils.Interface { functionFragment: 'grantRole', values: [BytesLike, string], ): string; + encodeFunctionData( + functionFragment: 'handoverRequest', + values: [BigNumberish, string, string], + ): string; + encodeFunctionData( + functionFragment: 'handoverTimeout', + values?: undefined, + ): string; + encodeFunctionData( + functionFragment: 'handovers', + values: [BytesLike], + ): string; encodeFunctionData( functionFragment: 'hasRole', values: [BytesLike, string], ): string; encodeFunctionData( functionFragment: 'initialize', - values: [BigNumberish, BigNumberish, string], - ): string; - encodeFunctionData( - functionFragment: 'initializeNumberOfRituals', - values?: undefined, + values: [BigNumberish, string], ): string; encodeFunctionData( functionFragment: 'initiateRitual', values: [string, string[], string, BigNumberish, string], ): string; - encodeFunctionData( - functionFragment: 'isEncryptionAuthorized', - values: [BigNumberish, BytesLike, BytesLike], - ): string; encodeFunctionData( functionFragment: 'isParticipant', values: [BigNumberish, string], @@ -387,16 +437,16 @@ export interface CoordinatorInterface extends utils.Interface { values: [BigNumberish, BytesLike, BLS12381.G1PointStruct, BytesLike], ): string; encodeFunctionData( - functionFragment: 'postTranscript', + functionFragment: 'postBlindedShare', values: [BigNumberish, BytesLike], ): string; encodeFunctionData( - functionFragment: 'publishTranscript', - values: [BigNumberish, BytesLike], + functionFragment: 'postHandoverTranscript', + values: [BigNumberish, string, BytesLike, BytesLike], ): string; encodeFunctionData( - functionFragment: 'reinitializeDefaultAdmin', - values: [string], + functionFragment: 'publishTranscript', + values: [BigNumberish, BytesLike], ): string; encodeFunctionData( functionFragment: 'renounceRole', @@ -426,10 +476,6 @@ export interface CoordinatorInterface extends utils.Interface { functionFragment: 'setReimbursementPool', values: [string], ): string; - encodeFunctionData( - functionFragment: 'setTimeout', - values: [BigNumberish], - ): string; encodeFunctionData( functionFragment: 'supportsInterface', values: [BytesLike], @@ -439,10 +485,6 @@ export interface CoordinatorInterface extends utils.Interface { functionFragment: 'transferRitualAuthority', values: [BigNumberish, string], ): string; - encodeFunctionData( - functionFragment: 'withdrawAllTokens', - values: [string], - ): string; decodeFunctionResult( functionFragment: 'DEFAULT_ADMIN_ROLE', @@ -452,6 +494,10 @@ export interface CoordinatorInterface extends utils.Interface { functionFragment: 'FEE_MODEL_MANAGER_ROLE', data: BytesLike, ): Result; + decodeFunctionResult( + functionFragment: 'HANDOVER_SUPERVISOR_ROLE', + data: BytesLike, + ): Result; decodeFunctionResult( functionFragment: 'TREASURY_ROLE', data: BytesLike, @@ -472,10 +518,18 @@ export interface CoordinatorInterface extends utils.Interface { functionFragment: 'beginDefaultAdminTransfer', data: BytesLike, ): Result; + decodeFunctionResult( + functionFragment: 'blindedSharePosition', + data: BytesLike, + ): Result; decodeFunctionResult( functionFragment: 'cancelDefaultAdminTransfer', data: BytesLike, ): Result; + decodeFunctionResult( + functionFragment: 'cancelHandover', + data: BytesLike, + ): Result; decodeFunctionResult( functionFragment: 'changeDefaultAdminDelay', data: BytesLike, @@ -496,6 +550,11 @@ export interface CoordinatorInterface extends utils.Interface { functionFragment: 'defaultAdminDelayIncreaseWait', data: BytesLike, ): Result; + decodeFunctionResult(functionFragment: 'dkgTimeout', data: BytesLike): Result; + decodeFunctionResult( + functionFragment: 'dkgTimeoutStub', + data: BytesLike, + ): Result; decodeFunctionResult( functionFragment: 'expectedTranscriptSize', data: BytesLike, @@ -508,6 +567,10 @@ export interface CoordinatorInterface extends utils.Interface { functionFragment: 'feeModelsRegistry', data: BytesLike, ): Result; + decodeFunctionResult( + functionFragment: 'finalizeHandover', + data: BytesLike, + ): Result; decodeFunctionResult( functionFragment: 'getAccessController', data: BytesLike, @@ -520,6 +583,14 @@ export interface CoordinatorInterface extends utils.Interface { functionFragment: 'getFeeModel', data: BytesLike, ): Result; + decodeFunctionResult( + functionFragment: 'getHandoverKey', + data: BytesLike, + ): Result; + decodeFunctionResult( + functionFragment: 'getHandoverState', + data: BytesLike, + ): Result; decodeFunctionResult( functionFragment: 'getInitiator', data: BytesLike, @@ -573,18 +644,19 @@ export interface CoordinatorInterface extends utils.Interface { data: BytesLike, ): Result; decodeFunctionResult(functionFragment: 'grantRole', data: BytesLike): Result; - decodeFunctionResult(functionFragment: 'hasRole', data: BytesLike): Result; - decodeFunctionResult(functionFragment: 'initialize', data: BytesLike): Result; decodeFunctionResult( - functionFragment: 'initializeNumberOfRituals', + functionFragment: 'handoverRequest', data: BytesLike, ): Result; decodeFunctionResult( - functionFragment: 'initiateRitual', + functionFragment: 'handoverTimeout', data: BytesLike, ): Result; + decodeFunctionResult(functionFragment: 'handovers', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'hasRole', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'initialize', data: BytesLike): Result; decodeFunctionResult( - functionFragment: 'isEncryptionAuthorized', + functionFragment: 'initiateRitual', data: BytesLike, ): Result; decodeFunctionResult( @@ -622,15 +694,15 @@ export interface CoordinatorInterface extends utils.Interface { data: BytesLike, ): Result; decodeFunctionResult( - functionFragment: 'postTranscript', + functionFragment: 'postBlindedShare', data: BytesLike, ): Result; decodeFunctionResult( - functionFragment: 'publishTranscript', + functionFragment: 'postHandoverTranscript', data: BytesLike, ): Result; decodeFunctionResult( - functionFragment: 'reinitializeDefaultAdmin', + functionFragment: 'publishTranscript', data: BytesLike, ): Result; decodeFunctionResult( @@ -655,7 +727,6 @@ export interface CoordinatorInterface extends utils.Interface { functionFragment: 'setReimbursementPool', data: BytesLike, ): Result; - decodeFunctionResult(functionFragment: 'setTimeout', data: BytesLike): Result; decodeFunctionResult( functionFragment: 'supportsInterface', data: BytesLike, @@ -665,19 +736,20 @@ export interface CoordinatorInterface extends utils.Interface { functionFragment: 'transferRitualAuthority', data: BytesLike, ): Result; - decodeFunctionResult( - functionFragment: 'withdrawAllTokens', - data: BytesLike, - ): Result; events: { 'AggregationPosted(uint32,address,bytes32)': EventFragment; + 'BlindedSharePosted(uint32,address)': EventFragment; 'DefaultAdminDelayChangeCanceled()': EventFragment; 'DefaultAdminDelayChangeScheduled(uint48,uint48)': EventFragment; 'DefaultAdminTransferCanceled()': EventFragment; 'DefaultAdminTransferScheduled(address,uint48)': EventFragment; 'EndRitual(uint32,bool)': EventFragment; 'FeeModelApproved(address)': EventFragment; + 'HandoverCanceled(uint32,address,address)': EventFragment; + 'HandoverFinalized(uint32,address,address)': EventFragment; + 'HandoverRequest(uint32,address,address)': EventFragment; + 'HandoverTranscriptPosted(uint32,address,address)': EventFragment; 'Initialized(uint64)': EventFragment; 'MaxDkgSizeChanged(uint16,uint16)': EventFragment; 'ParticipantPublicKeySet(uint32,address,(bytes32,bytes32,bytes32))': EventFragment; @@ -689,11 +761,11 @@ export interface CoordinatorInterface extends utils.Interface { 'RoleRevoked(bytes32,address,address)': EventFragment; 'StartAggregationRound(uint32)': EventFragment; 'StartRitual(uint32,address,address[])': EventFragment; - 'TimeoutChanged(uint32,uint32)': EventFragment; 'TranscriptPosted(uint32,address,bytes32)': EventFragment; }; getEvent(nameOrSignatureOrTopic: 'AggregationPosted'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'BlindedSharePosted'): EventFragment; getEvent( nameOrSignatureOrTopic: 'DefaultAdminDelayChangeCanceled', ): EventFragment; @@ -708,6 +780,10 @@ export interface CoordinatorInterface extends utils.Interface { ): EventFragment; getEvent(nameOrSignatureOrTopic: 'EndRitual'): EventFragment; getEvent(nameOrSignatureOrTopic: 'FeeModelApproved'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'HandoverCanceled'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'HandoverFinalized'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'HandoverRequest'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'HandoverTranscriptPosted'): EventFragment; getEvent(nameOrSignatureOrTopic: 'Initialized'): EventFragment; getEvent(nameOrSignatureOrTopic: 'MaxDkgSizeChanged'): EventFragment; getEvent(nameOrSignatureOrTopic: 'ParticipantPublicKeySet'): EventFragment; @@ -719,7 +795,6 @@ export interface CoordinatorInterface extends utils.Interface { getEvent(nameOrSignatureOrTopic: 'RoleRevoked'): EventFragment; getEvent(nameOrSignatureOrTopic: 'StartAggregationRound'): EventFragment; getEvent(nameOrSignatureOrTopic: 'StartRitual'): EventFragment; - getEvent(nameOrSignatureOrTopic: 'TimeoutChanged'): EventFragment; getEvent(nameOrSignatureOrTopic: 'TranscriptPosted'): EventFragment; } @@ -736,6 +811,18 @@ export type AggregationPostedEvent = TypedEvent< export type AggregationPostedEventFilter = TypedEventFilter; +export interface BlindedSharePostedEventObject { + ritualId: number; + departingParticipant: string; +} +export type BlindedSharePostedEvent = TypedEvent< + [number, string], + BlindedSharePostedEventObject +>; + +export type BlindedSharePostedEventFilter = + TypedEventFilter; + export interface DefaultAdminDelayChangeCanceledEventObject {} export type DefaultAdminDelayChangeCanceledEvent = TypedEvent< [], @@ -800,6 +887,57 @@ export type FeeModelApprovedEvent = TypedEvent< export type FeeModelApprovedEventFilter = TypedEventFilter; +export interface HandoverCanceledEventObject { + ritualId: number; + departingParticipant: string; + incomingParticipant: string; +} +export type HandoverCanceledEvent = TypedEvent< + [number, string, string], + HandoverCanceledEventObject +>; + +export type HandoverCanceledEventFilter = + TypedEventFilter; + +export interface HandoverFinalizedEventObject { + ritualId: number; + departingParticipant: string; + incomingParticipant: string; +} +export type HandoverFinalizedEvent = TypedEvent< + [number, string, string], + HandoverFinalizedEventObject +>; + +export type HandoverFinalizedEventFilter = + TypedEventFilter; + +export interface HandoverRequestEventObject { + ritualId: number; + departingParticipant: string; + incomingParticipant: string; +} +export type HandoverRequestEvent = TypedEvent< + [number, string, string], + HandoverRequestEventObject +>; + +export type HandoverRequestEventFilter = TypedEventFilter; + +export interface HandoverTranscriptPostedEventObject { + ritualId: number; + departingParticipant: string; + incomingParticipant: string; +} +export type HandoverTranscriptPostedEvent = TypedEvent< + [number, string, string], + HandoverTranscriptPostedEventObject +>; + +export type HandoverTranscriptPostedEventFilter = + TypedEventFilter; + export interface InitializedEventObject { version: BigNumber; } @@ -927,17 +1065,6 @@ export type StartRitualEvent = TypedEvent< export type StartRitualEventFilter = TypedEventFilter; -export interface TimeoutChangedEventObject { - oldTimeout: number; - newTimeout: number; -} -export type TimeoutChangedEvent = TypedEvent< - [number, number], - TimeoutChangedEventObject ->; - -export type TimeoutChangedEventFilter = TypedEventFilter; - export interface TranscriptPostedEventObject { ritualId: number; node: string; @@ -982,6 +1109,8 @@ export interface Coordinator extends BaseContract { FEE_MODEL_MANAGER_ROLE(overrides?: CallOverrides): Promise<[string]>; + HANDOVER_SUPERVISOR_ROLE(overrides?: CallOverrides): Promise<[string]>; + TREASURY_ROLE(overrides?: CallOverrides): Promise<[string]>; acceptDefaultAdminTransfer( @@ -1000,10 +1129,22 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; + blindedSharePosition( + index: BigNumberish, + threshold: BigNumberish, + overrides?: CallOverrides, + ): Promise<[BigNumber]>; + cancelDefaultAdminTransfer( overrides?: Overrides & { from?: string }, ): Promise; + cancelHandover( + ritualId: BigNumberish, + departingParticipant: string, + overrides?: Overrides & { from?: string }, + ): Promise; + changeDefaultAdminDelay( newDelay: BigNumberish, overrides?: Overrides & { from?: string }, @@ -1020,6 +1161,10 @@ export interface Coordinator extends BaseContract { defaultAdminDelayIncreaseWait(overrides?: CallOverrides): Promise<[number]>; + dkgTimeout(overrides?: CallOverrides): Promise<[number]>; + + dkgTimeoutStub(overrides?: CallOverrides): Promise<[number]>; + expectedTranscriptSize( dkgSize: BigNumberish, threshold: BigNumberish, @@ -1037,6 +1182,12 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise<[boolean]>; + finalizeHandover( + ritualId: BigNumberish, + departingParticipant: string, + overrides?: Overrides & { from?: string }, + ): Promise; + getAccessController( ritualId: BigNumberish, overrides?: CallOverrides, @@ -1052,6 +1203,18 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise<[string]>; + getHandoverKey( + ritualId: BigNumberish, + departingProvider: string, + overrides?: CallOverrides, + ): Promise<[string]>; + + getHandoverState( + ritualId: BigNumberish, + departingParticipant: string, + overrides?: CallOverrides, + ): Promise<[number]>; + getInitiator( ritualId: BigNumberish, overrides?: CallOverrides, @@ -1129,6 +1292,28 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; + handoverRequest( + ritualId: BigNumberish, + departingParticipant: string, + incomingParticipant: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + handoverTimeout(overrides?: CallOverrides): Promise<[number]>; + + handovers( + handoverKey: BytesLike, + overrides?: CallOverrides, + ): Promise< + [number, string, string, string, string] & { + requestTimestamp: number; + incomingProvider: string; + transcript: string; + decryptionRequestStaticKey: string; + blindedShare: string; + } + >; + hasRole( role: BytesLike, account: string, @@ -1136,16 +1321,11 @@ export interface Coordinator extends BaseContract { ): Promise<[boolean]>; initialize( - _timeout: BigNumberish, _maxDkgSize: BigNumberish, _admin: string, overrides?: Overrides & { from?: string }, ): Promise; - initializeNumberOfRituals( - overrides?: Overrides & { from?: string }, - ): Promise; - initiateRitual( feeModel: string, providers: string[], @@ -1155,13 +1335,6 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - isEncryptionAuthorized( - arg0: BigNumberish, - arg1: BytesLike, - arg2: BytesLike, - overrides?: CallOverrides, - ): Promise<[boolean]>; - isParticipant( ritualId: BigNumberish, provider: string, @@ -1205,20 +1378,23 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - postTranscript( - arg0: BigNumberish, - arg1: BytesLike, + postBlindedShare( + ritualId: BigNumberish, + blindedShare: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; - publishTranscript( + postHandoverTranscript( ritualId: BigNumberish, + departingParticipant: string, transcript: BytesLike, + decryptionRequestStaticKey: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; - reinitializeDefaultAdmin( - newDefaultAdmin: string, + publishTranscript( + ritualId: BigNumberish, + transcript: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; @@ -1235,7 +1411,7 @@ export interface Coordinator extends BaseContract { ): Promise; rituals( - ritualId: BigNumberish, + index: BigNumberish, overrides?: CallOverrides, ): Promise< [ @@ -1288,11 +1464,6 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - setTimeout( - newTimeout: BigNumberish, - overrides?: Overrides & { from?: string }, - ): Promise; - supportsInterface( interfaceId: BytesLike, overrides?: CallOverrides, @@ -1305,17 +1476,14 @@ export interface Coordinator extends BaseContract { newAuthority: string, overrides?: Overrides & { from?: string }, ): Promise; - - withdrawAllTokens( - token: string, - overrides?: Overrides & { from?: string }, - ): Promise; }; DEFAULT_ADMIN_ROLE(overrides?: CallOverrides): Promise; FEE_MODEL_MANAGER_ROLE(overrides?: CallOverrides): Promise; + HANDOVER_SUPERVISOR_ROLE(overrides?: CallOverrides): Promise; + TREASURY_ROLE(overrides?: CallOverrides): Promise; acceptDefaultAdminTransfer( @@ -1334,10 +1502,22 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; + blindedSharePosition( + index: BigNumberish, + threshold: BigNumberish, + overrides?: CallOverrides, + ): Promise; + cancelDefaultAdminTransfer( overrides?: Overrides & { from?: string }, ): Promise; + cancelHandover( + ritualId: BigNumberish, + departingParticipant: string, + overrides?: Overrides & { from?: string }, + ): Promise; + changeDefaultAdminDelay( newDelay: BigNumberish, overrides?: Overrides & { from?: string }, @@ -1354,6 +1534,10 @@ export interface Coordinator extends BaseContract { defaultAdminDelayIncreaseWait(overrides?: CallOverrides): Promise; + dkgTimeout(overrides?: CallOverrides): Promise; + + dkgTimeoutStub(overrides?: CallOverrides): Promise; + expectedTranscriptSize( dkgSize: BigNumberish, threshold: BigNumberish, @@ -1368,6 +1552,12 @@ export interface Coordinator extends BaseContract { feeModelsRegistry(arg0: string, overrides?: CallOverrides): Promise; + finalizeHandover( + ritualId: BigNumberish, + departingParticipant: string, + overrides?: Overrides & { from?: string }, + ): Promise; + getAccessController( ritualId: BigNumberish, overrides?: CallOverrides, @@ -1383,6 +1573,18 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + getHandoverKey( + ritualId: BigNumberish, + departingProvider: string, + overrides?: CallOverrides, + ): Promise; + + getHandoverState( + ritualId: BigNumberish, + departingParticipant: string, + overrides?: CallOverrides, + ): Promise; + getInitiator( ritualId: BigNumberish, overrides?: CallOverrides, @@ -1460,6 +1662,28 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; + handoverRequest( + ritualId: BigNumberish, + departingParticipant: string, + incomingParticipant: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + handoverTimeout(overrides?: CallOverrides): Promise; + + handovers( + handoverKey: BytesLike, + overrides?: CallOverrides, + ): Promise< + [number, string, string, string, string] & { + requestTimestamp: number; + incomingProvider: string; + transcript: string; + decryptionRequestStaticKey: string; + blindedShare: string; + } + >; + hasRole( role: BytesLike, account: string, @@ -1467,16 +1691,11 @@ export interface Coordinator extends BaseContract { ): Promise; initialize( - _timeout: BigNumberish, _maxDkgSize: BigNumberish, _admin: string, overrides?: Overrides & { from?: string }, ): Promise; - initializeNumberOfRituals( - overrides?: Overrides & { from?: string }, - ): Promise; - initiateRitual( feeModel: string, providers: string[], @@ -1486,13 +1705,6 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - isEncryptionAuthorized( - arg0: BigNumberish, - arg1: BytesLike, - arg2: BytesLike, - overrides?: CallOverrides, - ): Promise; - isParticipant( ritualId: BigNumberish, provider: string, @@ -1536,20 +1748,23 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - postTranscript( - arg0: BigNumberish, - arg1: BytesLike, + postBlindedShare( + ritualId: BigNumberish, + blindedShare: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; - publishTranscript( + postHandoverTranscript( ritualId: BigNumberish, + departingParticipant: string, transcript: BytesLike, + decryptionRequestStaticKey: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; - reinitializeDefaultAdmin( - newDefaultAdmin: string, + publishTranscript( + ritualId: BigNumberish, + transcript: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; @@ -1566,7 +1781,7 @@ export interface Coordinator extends BaseContract { ): Promise; rituals( - ritualId: BigNumberish, + index: BigNumberish, overrides?: CallOverrides, ): Promise< [ @@ -1619,11 +1834,6 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - setTimeout( - newTimeout: BigNumberish, - overrides?: Overrides & { from?: string }, - ): Promise; - supportsInterface( interfaceId: BytesLike, overrides?: CallOverrides, @@ -1637,16 +1847,13 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - withdrawAllTokens( - token: string, - overrides?: Overrides & { from?: string }, - ): Promise; - callStatic: { DEFAULT_ADMIN_ROLE(overrides?: CallOverrides): Promise; FEE_MODEL_MANAGER_ROLE(overrides?: CallOverrides): Promise; + HANDOVER_SUPERVISOR_ROLE(overrides?: CallOverrides): Promise; + TREASURY_ROLE(overrides?: CallOverrides): Promise; acceptDefaultAdminTransfer(overrides?: CallOverrides): Promise; @@ -1660,8 +1867,20 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + blindedSharePosition( + index: BigNumberish, + threshold: BigNumberish, + overrides?: CallOverrides, + ): Promise; + cancelDefaultAdminTransfer(overrides?: CallOverrides): Promise; + cancelHandover( + ritualId: BigNumberish, + departingParticipant: string, + overrides?: CallOverrides, + ): Promise; + changeDefaultAdminDelay( newDelay: BigNumberish, overrides?: CallOverrides, @@ -1678,6 +1897,10 @@ export interface Coordinator extends BaseContract { defaultAdminDelayIncreaseWait(overrides?: CallOverrides): Promise; + dkgTimeout(overrides?: CallOverrides): Promise; + + dkgTimeoutStub(overrides?: CallOverrides): Promise; + expectedTranscriptSize( dkgSize: BigNumberish, threshold: BigNumberish, @@ -1695,6 +1918,12 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + finalizeHandover( + ritualId: BigNumberish, + departingParticipant: string, + overrides?: CallOverrides, + ): Promise; + getAccessController( ritualId: BigNumberish, overrides?: CallOverrides, @@ -1710,6 +1939,18 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + getHandoverKey( + ritualId: BigNumberish, + departingProvider: string, + overrides?: CallOverrides, + ): Promise; + + getHandoverState( + ritualId: BigNumberish, + departingParticipant: string, + overrides?: CallOverrides, + ): Promise; + getInitiator( ritualId: BigNumberish, overrides?: CallOverrides, @@ -1787,6 +2028,28 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + handoverRequest( + ritualId: BigNumberish, + departingParticipant: string, + incomingParticipant: string, + overrides?: CallOverrides, + ): Promise; + + handoverTimeout(overrides?: CallOverrides): Promise; + + handovers( + handoverKey: BytesLike, + overrides?: CallOverrides, + ): Promise< + [number, string, string, string, string] & { + requestTimestamp: number; + incomingProvider: string; + transcript: string; + decryptionRequestStaticKey: string; + blindedShare: string; + } + >; + hasRole( role: BytesLike, account: string, @@ -1794,14 +2057,11 @@ export interface Coordinator extends BaseContract { ): Promise; initialize( - _timeout: BigNumberish, _maxDkgSize: BigNumberish, _admin: string, overrides?: CallOverrides, ): Promise; - initializeNumberOfRituals(overrides?: CallOverrides): Promise; - initiateRitual( feeModel: string, providers: string[], @@ -1811,13 +2071,6 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; - isEncryptionAuthorized( - arg0: BigNumberish, - arg1: BytesLike, - arg2: BytesLike, - overrides?: CallOverrides, - ): Promise; - isParticipant( ritualId: BigNumberish, provider: string, @@ -1861,20 +2114,23 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; - postTranscript( - arg0: BigNumberish, - arg1: BytesLike, + postBlindedShare( + ritualId: BigNumberish, + blindedShare: BytesLike, overrides?: CallOverrides, ): Promise; - publishTranscript( + postHandoverTranscript( ritualId: BigNumberish, + departingParticipant: string, transcript: BytesLike, + decryptionRequestStaticKey: BytesLike, overrides?: CallOverrides, ): Promise; - reinitializeDefaultAdmin( - newDefaultAdmin: string, + publishTranscript( + ritualId: BigNumberish, + transcript: BytesLike, overrides?: CallOverrides, ): Promise; @@ -1891,7 +2147,7 @@ export interface Coordinator extends BaseContract { ): Promise; rituals( - ritualId: BigNumberish, + index: BigNumberish, overrides?: CallOverrides, ): Promise< [ @@ -1942,11 +2198,6 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; - setTimeout( - newTimeout: BigNumberish, - overrides?: CallOverrides, - ): Promise; - supportsInterface( interfaceId: BytesLike, overrides?: CallOverrides, @@ -1959,8 +2210,6 @@ export interface Coordinator extends BaseContract { newAuthority: string, overrides?: CallOverrides, ): Promise; - - withdrawAllTokens(token: string, overrides?: CallOverrides): Promise; }; filters: { @@ -1975,6 +2224,15 @@ export interface Coordinator extends BaseContract { aggregatedTranscriptDigest?: null, ): AggregationPostedEventFilter; + 'BlindedSharePosted(uint32,address)'( + ritualId?: BigNumberish | null, + departingParticipant?: string | null, + ): BlindedSharePostedEventFilter; + BlindedSharePosted( + ritualId?: BigNumberish | null, + departingParticipant?: string | null, + ): BlindedSharePostedEventFilter; + 'DefaultAdminDelayChangeCanceled()'(): DefaultAdminDelayChangeCanceledEventFilter; DefaultAdminDelayChangeCanceled(): DefaultAdminDelayChangeCanceledEventFilter; @@ -2011,6 +2269,50 @@ export interface Coordinator extends BaseContract { 'FeeModelApproved(address)'(feeModel?: null): FeeModelApprovedEventFilter; FeeModelApproved(feeModel?: null): FeeModelApprovedEventFilter; + 'HandoverCanceled(uint32,address,address)'( + ritualId?: BigNumberish | null, + departingParticipant?: string | null, + incomingParticipant?: string | null, + ): HandoverCanceledEventFilter; + HandoverCanceled( + ritualId?: BigNumberish | null, + departingParticipant?: string | null, + incomingParticipant?: string | null, + ): HandoverCanceledEventFilter; + + 'HandoverFinalized(uint32,address,address)'( + ritualId?: BigNumberish | null, + departingParticipant?: string | null, + incomingParticipant?: string | null, + ): HandoverFinalizedEventFilter; + HandoverFinalized( + ritualId?: BigNumberish | null, + departingParticipant?: string | null, + incomingParticipant?: string | null, + ): HandoverFinalizedEventFilter; + + 'HandoverRequest(uint32,address,address)'( + ritualId?: BigNumberish | null, + departingParticipant?: string | null, + incomingParticipant?: string | null, + ): HandoverRequestEventFilter; + HandoverRequest( + ritualId?: BigNumberish | null, + departingParticipant?: string | null, + incomingParticipant?: string | null, + ): HandoverRequestEventFilter; + + 'HandoverTranscriptPosted(uint32,address,address)'( + ritualId?: BigNumberish | null, + departingParticipant?: string | null, + incomingParticipant?: string | null, + ): HandoverTranscriptPostedEventFilter; + HandoverTranscriptPosted( + ritualId?: BigNumberish | null, + departingParticipant?: string | null, + incomingParticipant?: string | null, + ): HandoverTranscriptPostedEventFilter; + 'Initialized(uint64)'(version?: null): InitializedEventFilter; Initialized(version?: null): InitializedEventFilter; @@ -2110,15 +2412,6 @@ export interface Coordinator extends BaseContract { participants?: null, ): StartRitualEventFilter; - 'TimeoutChanged(uint32,uint32)'( - oldTimeout?: null, - newTimeout?: null, - ): TimeoutChangedEventFilter; - TimeoutChanged( - oldTimeout?: null, - newTimeout?: null, - ): TimeoutChangedEventFilter; - 'TranscriptPosted(uint32,address,bytes32)'( ritualId?: BigNumberish | null, node?: string | null, @@ -2136,6 +2429,8 @@ export interface Coordinator extends BaseContract { FEE_MODEL_MANAGER_ROLE(overrides?: CallOverrides): Promise; + HANDOVER_SUPERVISOR_ROLE(overrides?: CallOverrides): Promise; + TREASURY_ROLE(overrides?: CallOverrides): Promise; acceptDefaultAdminTransfer( @@ -2154,10 +2449,22 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; + blindedSharePosition( + index: BigNumberish, + threshold: BigNumberish, + overrides?: CallOverrides, + ): Promise; + cancelDefaultAdminTransfer( overrides?: Overrides & { from?: string }, ): Promise; + cancelHandover( + ritualId: BigNumberish, + departingParticipant: string, + overrides?: Overrides & { from?: string }, + ): Promise; + changeDefaultAdminDelay( newDelay: BigNumberish, overrides?: Overrides & { from?: string }, @@ -2176,6 +2483,10 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + dkgTimeout(overrides?: CallOverrides): Promise; + + dkgTimeoutStub(overrides?: CallOverrides): Promise; + expectedTranscriptSize( dkgSize: BigNumberish, threshold: BigNumberish, @@ -2193,6 +2504,12 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + finalizeHandover( + ritualId: BigNumberish, + departingParticipant: string, + overrides?: Overrides & { from?: string }, + ): Promise; + getAccessController( ritualId: BigNumberish, overrides?: CallOverrides, @@ -2208,6 +2525,18 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + getHandoverKey( + ritualId: BigNumberish, + departingProvider: string, + overrides?: CallOverrides, + ): Promise; + + getHandoverState( + ritualId: BigNumberish, + departingParticipant: string, + overrides?: CallOverrides, + ): Promise; + getInitiator( ritualId: BigNumberish, overrides?: CallOverrides, @@ -2286,6 +2615,20 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; + handoverRequest( + ritualId: BigNumberish, + departingParticipant: string, + incomingParticipant: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + handoverTimeout(overrides?: CallOverrides): Promise; + + handovers( + handoverKey: BytesLike, + overrides?: CallOverrides, + ): Promise; + hasRole( role: BytesLike, account: string, @@ -2293,16 +2636,11 @@ export interface Coordinator extends BaseContract { ): Promise; initialize( - _timeout: BigNumberish, _maxDkgSize: BigNumberish, _admin: string, overrides?: Overrides & { from?: string }, ): Promise; - initializeNumberOfRituals( - overrides?: Overrides & { from?: string }, - ): Promise; - initiateRitual( feeModel: string, providers: string[], @@ -2312,13 +2650,6 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - isEncryptionAuthorized( - arg0: BigNumberish, - arg1: BytesLike, - arg2: BytesLike, - overrides?: CallOverrides, - ): Promise; - isParticipant( ritualId: BigNumberish, provider: string, @@ -2358,20 +2689,23 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - postTranscript( - arg0: BigNumberish, - arg1: BytesLike, + postBlindedShare( + ritualId: BigNumberish, + blindedShare: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; - publishTranscript( + postHandoverTranscript( ritualId: BigNumberish, + departingParticipant: string, transcript: BytesLike, + decryptionRequestStaticKey: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; - reinitializeDefaultAdmin( - newDefaultAdmin: string, + publishTranscript( + ritualId: BigNumberish, + transcript: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; @@ -2387,10 +2721,7 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - rituals( - ritualId: BigNumberish, - overrides?: CallOverrides, - ): Promise; + rituals(index: BigNumberish, overrides?: CallOverrides): Promise; rollbackDefaultAdminDelay( overrides?: Overrides & { from?: string }, @@ -2411,11 +2742,6 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - setTimeout( - newTimeout: BigNumberish, - overrides?: Overrides & { from?: string }, - ): Promise; - supportsInterface( interfaceId: BytesLike, overrides?: CallOverrides, @@ -2428,11 +2754,6 @@ export interface Coordinator extends BaseContract { newAuthority: string, overrides?: Overrides & { from?: string }, ): Promise; - - withdrawAllTokens( - token: string, - overrides?: Overrides & { from?: string }, - ): Promise; }; populateTransaction: { @@ -2444,6 +2765,10 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + HANDOVER_SUPERVISOR_ROLE( + overrides?: CallOverrides, + ): Promise; + TREASURY_ROLE(overrides?: CallOverrides): Promise; acceptDefaultAdminTransfer( @@ -2462,10 +2787,22 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; + blindedSharePosition( + index: BigNumberish, + threshold: BigNumberish, + overrides?: CallOverrides, + ): Promise; + cancelDefaultAdminTransfer( overrides?: Overrides & { from?: string }, ): Promise; + cancelHandover( + ritualId: BigNumberish, + departingParticipant: string, + overrides?: Overrides & { from?: string }, + ): Promise; + changeDefaultAdminDelay( newDelay: BigNumberish, overrides?: Overrides & { from?: string }, @@ -2484,6 +2821,10 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + dkgTimeout(overrides?: CallOverrides): Promise; + + dkgTimeoutStub(overrides?: CallOverrides): Promise; + expectedTranscriptSize( dkgSize: BigNumberish, threshold: BigNumberish, @@ -2501,6 +2842,12 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + finalizeHandover( + ritualId: BigNumberish, + departingParticipant: string, + overrides?: Overrides & { from?: string }, + ): Promise; + getAccessController( ritualId: BigNumberish, overrides?: CallOverrides, @@ -2516,6 +2863,18 @@ export interface Coordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + getHandoverKey( + ritualId: BigNumberish, + departingProvider: string, + overrides?: CallOverrides, + ): Promise; + + getHandoverState( + ritualId: BigNumberish, + departingParticipant: string, + overrides?: CallOverrides, + ): Promise; + getInitiator( ritualId: BigNumberish, overrides?: CallOverrides, @@ -2594,6 +2953,20 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; + handoverRequest( + ritualId: BigNumberish, + departingParticipant: string, + incomingParticipant: string, + overrides?: Overrides & { from?: string }, + ): Promise; + + handoverTimeout(overrides?: CallOverrides): Promise; + + handovers( + handoverKey: BytesLike, + overrides?: CallOverrides, + ): Promise; + hasRole( role: BytesLike, account: string, @@ -2601,16 +2974,11 @@ export interface Coordinator extends BaseContract { ): Promise; initialize( - _timeout: BigNumberish, _maxDkgSize: BigNumberish, _admin: string, overrides?: Overrides & { from?: string }, ): Promise; - initializeNumberOfRituals( - overrides?: Overrides & { from?: string }, - ): Promise; - initiateRitual( feeModel: string, providers: string[], @@ -2620,13 +2988,6 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - isEncryptionAuthorized( - arg0: BigNumberish, - arg1: BytesLike, - arg2: BytesLike, - overrides?: CallOverrides, - ): Promise; - isParticipant( ritualId: BigNumberish, provider: string, @@ -2670,20 +3031,23 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - postTranscript( - arg0: BigNumberish, - arg1: BytesLike, + postBlindedShare( + ritualId: BigNumberish, + blindedShare: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; - publishTranscript( + postHandoverTranscript( ritualId: BigNumberish, + departingParticipant: string, transcript: BytesLike, + decryptionRequestStaticKey: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; - reinitializeDefaultAdmin( - newDefaultAdmin: string, + publishTranscript( + ritualId: BigNumberish, + transcript: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; @@ -2700,7 +3064,7 @@ export interface Coordinator extends BaseContract { ): Promise; rituals( - ritualId: BigNumberish, + index: BigNumberish, overrides?: CallOverrides, ): Promise; @@ -2723,11 +3087,6 @@ export interface Coordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - setTimeout( - newTimeout: BigNumberish, - overrides?: Overrides & { from?: string }, - ): Promise; - supportsInterface( interfaceId: BytesLike, overrides?: CallOverrides, @@ -2740,10 +3099,5 @@ export interface Coordinator extends BaseContract { newAuthority: string, overrides?: Overrides & { from?: string }, ): Promise; - - withdrawAllTokens( - token: string, - overrides?: Overrides & { from?: string }, - ): Promise; }; } diff --git a/packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts b/packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts index 549518b1d..72bfa1963 100644 --- a/packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts +++ b/packages/shared/src/contracts/ethers-typechain/SigningCoordinator.ts @@ -29,21 +29,29 @@ import type { export declare namespace SigningCoordinator { export type SigningCohortParticipantStruct = { provider: string; - operator: string; - signature: BytesLike; + signerAddress: string; + signingRequestStaticKey: BytesLike; + gap: BigNumberish[]; }; export type SigningCohortParticipantStructOutput = [ string, string, string, - ] & { provider: string; operator: string; signature: string }; + BigNumber[], + ] & { + provider: string; + signerAddress: string; + signingRequestStaticKey: string; + gap: BigNumber[]; + }; } export interface SigningCoordinatorInterface extends utils.Interface { functions: { 'DEFAULT_ADMIN_ROLE()': FunctionFragment; 'INITIATOR_ROLE()': FunctionFragment; + 'SIGNING_REQUEST_KEY_LENGTH()': FunctionFragment; 'acceptDefaultAdminTransfer()': FunctionFragment; 'application()': FunctionFragment; 'beginDefaultAdminTransfer(address)': FunctionFragment; @@ -53,15 +61,16 @@ export interface SigningCoordinatorInterface extends utils.Interface { 'defaultAdminDelay()': FunctionFragment; 'defaultAdminDelayIncreaseWait()': FunctionFragment; 'deployAdditionalChainForSigningMultisig(uint256,uint32)': FunctionFragment; + 'extendSigningCohortDuration(uint32,uint32)': FunctionFragment; 'getChains(uint32)': FunctionFragment; - 'getCondition(uint32,uint256)': FunctionFragment; 'getRoleAdmin(bytes32)': FunctionFragment; 'getSigner(uint32,address)': FunctionFragment; 'getSigners(uint32)': FunctionFragment; 'getSigningCohortConditions(uint32,uint256)': FunctionFragment; - 'getSigningCohortDataHash(uint32)': FunctionFragment; + 'getSigningCohortDataHash(uint32,address)': FunctionFragment; 'getSigningCohortState(uint32)': FunctionFragment; 'getSigningCoordinatorChild(uint256)': FunctionFragment; + 'getThreshold(uint32)': FunctionFragment; 'grantRole(bytes32,address)': FunctionFragment; 'hasRole(bytes32,address)': FunctionFragment; 'initialize(uint32,uint16,address,address)': FunctionFragment; @@ -73,7 +82,7 @@ export interface SigningCoordinatorInterface extends utils.Interface { 'owner()': FunctionFragment; 'pendingDefaultAdmin()': FunctionFragment; 'pendingDefaultAdminDelay()': FunctionFragment; - 'postSigningCohortSignature(uint32,bytes)': FunctionFragment; + 'postSigningCohortData(uint32,bytes,bytes)': FunctionFragment; 'renounceRole(bytes32,address)': FunctionFragment; 'revokeRole(bytes32,address)': FunctionFragment; 'rollbackDefaultAdminDelay()': FunctionFragment; @@ -91,6 +100,7 @@ export interface SigningCoordinatorInterface extends utils.Interface { nameOrSignatureOrTopic: | 'DEFAULT_ADMIN_ROLE' | 'INITIATOR_ROLE' + | 'SIGNING_REQUEST_KEY_LENGTH' | 'acceptDefaultAdminTransfer' | 'application' | 'beginDefaultAdminTransfer' @@ -100,8 +110,8 @@ export interface SigningCoordinatorInterface extends utils.Interface { | 'defaultAdminDelay' | 'defaultAdminDelayIncreaseWait' | 'deployAdditionalChainForSigningMultisig' + | 'extendSigningCohortDuration' | 'getChains' - | 'getCondition' | 'getRoleAdmin' | 'getSigner' | 'getSigners' @@ -109,6 +119,7 @@ export interface SigningCoordinatorInterface extends utils.Interface { | 'getSigningCohortDataHash' | 'getSigningCohortState' | 'getSigningCoordinatorChild' + | 'getThreshold' | 'grantRole' | 'hasRole' | 'initialize' @@ -120,7 +131,7 @@ export interface SigningCoordinatorInterface extends utils.Interface { | 'owner' | 'pendingDefaultAdmin' | 'pendingDefaultAdminDelay' - | 'postSigningCohortSignature' + | 'postSigningCohortData' | 'renounceRole' | 'revokeRole' | 'rollbackDefaultAdminDelay' @@ -142,6 +153,10 @@ export interface SigningCoordinatorInterface extends utils.Interface { functionFragment: 'INITIATOR_ROLE', values?: undefined, ): string; + encodeFunctionData( + functionFragment: 'SIGNING_REQUEST_KEY_LENGTH', + values?: undefined, + ): string; encodeFunctionData( functionFragment: 'acceptDefaultAdminTransfer', values?: undefined, @@ -179,12 +194,12 @@ export interface SigningCoordinatorInterface extends utils.Interface { values: [BigNumberish, BigNumberish], ): string; encodeFunctionData( - functionFragment: 'getChains', - values: [BigNumberish], + functionFragment: 'extendSigningCohortDuration', + values: [BigNumberish, BigNumberish], ): string; encodeFunctionData( - functionFragment: 'getCondition', - values: [BigNumberish, BigNumberish], + functionFragment: 'getChains', + values: [BigNumberish], ): string; encodeFunctionData( functionFragment: 'getRoleAdmin', @@ -204,7 +219,7 @@ export interface SigningCoordinatorInterface extends utils.Interface { ): string; encodeFunctionData( functionFragment: 'getSigningCohortDataHash', - values: [BigNumberish], + values: [BigNumberish, string], ): string; encodeFunctionData( functionFragment: 'getSigningCohortState', @@ -214,6 +229,10 @@ export interface SigningCoordinatorInterface extends utils.Interface { functionFragment: 'getSigningCoordinatorChild', values: [BigNumberish], ): string; + encodeFunctionData( + functionFragment: 'getThreshold', + values: [BigNumberish], + ): string; encodeFunctionData( functionFragment: 'grantRole', values: [BytesLike, string], @@ -256,8 +275,8 @@ export interface SigningCoordinatorInterface extends utils.Interface { values?: undefined, ): string; encodeFunctionData( - functionFragment: 'postSigningCohortSignature', - values: [BigNumberish, BytesLike], + functionFragment: 'postSigningCohortData', + values: [BigNumberish, BytesLike, BytesLike], ): string; encodeFunctionData( functionFragment: 'renounceRole', @@ -309,6 +328,10 @@ export interface SigningCoordinatorInterface extends utils.Interface { functionFragment: 'INITIATOR_ROLE', data: BytesLike, ): Result; + decodeFunctionResult( + functionFragment: 'SIGNING_REQUEST_KEY_LENGTH', + data: BytesLike, + ): Result; decodeFunctionResult( functionFragment: 'acceptDefaultAdminTransfer', data: BytesLike, @@ -345,11 +368,11 @@ export interface SigningCoordinatorInterface extends utils.Interface { functionFragment: 'deployAdditionalChainForSigningMultisig', data: BytesLike, ): Result; - decodeFunctionResult(functionFragment: 'getChains', data: BytesLike): Result; decodeFunctionResult( - functionFragment: 'getCondition', + functionFragment: 'extendSigningCohortDuration', data: BytesLike, ): Result; + decodeFunctionResult(functionFragment: 'getChains', data: BytesLike): Result; decodeFunctionResult( functionFragment: 'getRoleAdmin', data: BytesLike, @@ -372,6 +395,10 @@ export interface SigningCoordinatorInterface extends utils.Interface { functionFragment: 'getSigningCoordinatorChild', data: BytesLike, ): Result; + decodeFunctionResult( + functionFragment: 'getThreshold', + data: BytesLike, + ): Result; decodeFunctionResult(functionFragment: 'grantRole', data: BytesLike): Result; decodeFunctionResult(functionFragment: 'hasRole', data: BytesLike): Result; decodeFunctionResult(functionFragment: 'initialize', data: BytesLike): Result; @@ -402,7 +429,7 @@ export interface SigningCoordinatorInterface extends utils.Interface { data: BytesLike, ): Result; decodeFunctionResult( - functionFragment: 'postSigningCohortSignature', + functionFragment: 'postSigningCohortData', data: BytesLike, ): Result; decodeFunctionResult( @@ -455,7 +482,7 @@ export interface SigningCoordinatorInterface extends utils.Interface { 'RoleRevoked(bytes32,address,address)': EventFragment; 'SigningCohortConditionsSet(uint32,uint256,bytes)': EventFragment; 'SigningCohortDeployed(uint32,uint256)': EventFragment; - 'SigningCohortSignaturePosted(uint32,address,bytes)': EventFragment; + 'SigningCohortSignaturePosted(uint32,address,address,bytes)': EventFragment; 'TimeoutChanged(uint32,uint32)': EventFragment; }; @@ -638,10 +665,11 @@ export type SigningCohortDeployedEventFilter = export interface SigningCohortSignaturePostedEventObject { cohortId: number; provider: string; + signer: string; signature: string; } export type SigningCohortSignaturePostedEvent = TypedEvent< - [number, string, string], + [number, string, string, string], SigningCohortSignaturePostedEventObject >; @@ -690,6 +718,8 @@ export interface SigningCoordinator extends BaseContract { INITIATOR_ROLE(overrides?: CallOverrides): Promise<[string]>; + SIGNING_REQUEST_KEY_LENGTH(overrides?: CallOverrides): Promise<[BigNumber]>; + acceptDefaultAdminTransfer( overrides?: Overrides & { from?: string }, ): Promise; @@ -722,16 +752,16 @@ export interface SigningCoordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - getChains( + extendSigningCohortDuration( cohortId: BigNumberish, - overrides?: CallOverrides, - ): Promise<[BigNumber[]]>; + additionalDuration: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; - getCondition( + getChains( cohortId: BigNumberish, - chainId: BigNumberish, overrides?: CallOverrides, - ): Promise<[string]>; + ): Promise<[BigNumber[]]>; getRoleAdmin(role: BytesLike, overrides?: CallOverrides): Promise<[string]>; @@ -754,6 +784,7 @@ export interface SigningCoordinator extends BaseContract { getSigningCohortDataHash( cohortId: BigNumberish, + operator: string, overrides?: CallOverrides, ): Promise<[string]>; @@ -767,6 +798,11 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise<[string]>; + getThreshold( + cohortId: BigNumberish, + overrides?: CallOverrides, + ): Promise<[number]>; + grantRole( role: BytesLike, account: string, @@ -821,9 +857,10 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise<[number, number] & { newDelay: number; schedule: number }>; - postSigningCohortSignature( + postSigningCohortData( cohortId: BigNumberish, signature: BytesLike, + signingRequestStaticKey: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; @@ -894,6 +931,8 @@ export interface SigningCoordinator extends BaseContract { INITIATOR_ROLE(overrides?: CallOverrides): Promise; + SIGNING_REQUEST_KEY_LENGTH(overrides?: CallOverrides): Promise; + acceptDefaultAdminTransfer( overrides?: Overrides & { from?: string }, ): Promise; @@ -926,16 +965,16 @@ export interface SigningCoordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - getChains( + extendSigningCohortDuration( cohortId: BigNumberish, - overrides?: CallOverrides, - ): Promise; + additionalDuration: BigNumberish, + overrides?: Overrides & { from?: string }, + ): Promise; - getCondition( + getChains( cohortId: BigNumberish, - chainId: BigNumberish, overrides?: CallOverrides, - ): Promise; + ): Promise; getRoleAdmin(role: BytesLike, overrides?: CallOverrides): Promise; @@ -958,6 +997,7 @@ export interface SigningCoordinator extends BaseContract { getSigningCohortDataHash( cohortId: BigNumberish, + operator: string, overrides?: CallOverrides, ): Promise; @@ -971,6 +1011,11 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + getThreshold( + cohortId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + grantRole( role: BytesLike, account: string, @@ -1025,9 +1070,10 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise<[number, number] & { newDelay: number; schedule: number }>; - postSigningCohortSignature( + postSigningCohortData( cohortId: BigNumberish, signature: BytesLike, + signingRequestStaticKey: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; @@ -1098,6 +1144,8 @@ export interface SigningCoordinator extends BaseContract { INITIATOR_ROLE(overrides?: CallOverrides): Promise; + SIGNING_REQUEST_KEY_LENGTH(overrides?: CallOverrides): Promise; + acceptDefaultAdminTransfer(overrides?: CallOverrides): Promise; application(overrides?: CallOverrides): Promise; @@ -1126,16 +1174,16 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise; - getChains( + extendSigningCohortDuration( cohortId: BigNumberish, + additionalDuration: BigNumberish, overrides?: CallOverrides, - ): Promise; + ): Promise; - getCondition( + getChains( cohortId: BigNumberish, - chainId: BigNumberish, overrides?: CallOverrides, - ): Promise; + ): Promise; getRoleAdmin(role: BytesLike, overrides?: CallOverrides): Promise; @@ -1158,6 +1206,7 @@ export interface SigningCoordinator extends BaseContract { getSigningCohortDataHash( cohortId: BigNumberish, + operator: string, overrides?: CallOverrides, ): Promise; @@ -1171,6 +1220,11 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + getThreshold( + cohortId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + grantRole( role: BytesLike, account: string, @@ -1225,9 +1279,10 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise<[number, number] & { newDelay: number; schedule: number }>; - postSigningCohortSignature( + postSigningCohortData( cohortId: BigNumberish, signature: BytesLike, + signingRequestStaticKey: BytesLike, overrides?: CallOverrides, ): Promise; @@ -1401,14 +1456,16 @@ export interface SigningCoordinator extends BaseContract { chainId?: null, ): SigningCohortDeployedEventFilter; - 'SigningCohortSignaturePosted(uint32,address,bytes)'( + 'SigningCohortSignaturePosted(uint32,address,address,bytes)'( cohortId?: BigNumberish | null, provider?: string | null, + signer?: string | null, signature?: null, ): SigningCohortSignaturePostedEventFilter; SigningCohortSignaturePosted( cohortId?: BigNumberish | null, provider?: string | null, + signer?: string | null, signature?: null, ): SigningCohortSignaturePostedEventFilter; @@ -1427,6 +1484,8 @@ export interface SigningCoordinator extends BaseContract { INITIATOR_ROLE(overrides?: CallOverrides): Promise; + SIGNING_REQUEST_KEY_LENGTH(overrides?: CallOverrides): Promise; + acceptDefaultAdminTransfer( overrides?: Overrides & { from?: string }, ): Promise; @@ -1461,14 +1520,14 @@ export interface SigningCoordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - getChains( + extendSigningCohortDuration( cohortId: BigNumberish, - overrides?: CallOverrides, + additionalDuration: BigNumberish, + overrides?: Overrides & { from?: string }, ): Promise; - getCondition( + getChains( cohortId: BigNumberish, - chainId: BigNumberish, overrides?: CallOverrides, ): Promise; @@ -1496,6 +1555,7 @@ export interface SigningCoordinator extends BaseContract { getSigningCohortDataHash( cohortId: BigNumberish, + operator: string, overrides?: CallOverrides, ): Promise; @@ -1509,6 +1569,11 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + getThreshold( + cohortId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + grantRole( role: BytesLike, account: string, @@ -1559,9 +1624,10 @@ export interface SigningCoordinator extends BaseContract { pendingDefaultAdminDelay(overrides?: CallOverrides): Promise; - postSigningCohortSignature( + postSigningCohortData( cohortId: BigNumberish, signature: BytesLike, + signingRequestStaticKey: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; @@ -1625,6 +1691,10 @@ export interface SigningCoordinator extends BaseContract { INITIATOR_ROLE(overrides?: CallOverrides): Promise; + SIGNING_REQUEST_KEY_LENGTH( + overrides?: CallOverrides, + ): Promise; + acceptDefaultAdminTransfer( overrides?: Overrides & { from?: string }, ): Promise; @@ -1659,14 +1729,14 @@ export interface SigningCoordinator extends BaseContract { overrides?: Overrides & { from?: string }, ): Promise; - getChains( + extendSigningCohortDuration( cohortId: BigNumberish, - overrides?: CallOverrides, + additionalDuration: BigNumberish, + overrides?: Overrides & { from?: string }, ): Promise; - getCondition( + getChains( cohortId: BigNumberish, - chainId: BigNumberish, overrides?: CallOverrides, ): Promise; @@ -1694,6 +1764,7 @@ export interface SigningCoordinator extends BaseContract { getSigningCohortDataHash( cohortId: BigNumberish, + operator: string, overrides?: CallOverrides, ): Promise; @@ -1707,6 +1778,11 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise; + getThreshold( + cohortId: BigNumberish, + overrides?: CallOverrides, + ): Promise; + grantRole( role: BytesLike, account: string, @@ -1763,9 +1839,10 @@ export interface SigningCoordinator extends BaseContract { overrides?: CallOverrides, ): Promise; - postSigningCohortSignature( + postSigningCohortData( cohortId: BigNumberish, signature: BytesLike, + signingRequestStaticKey: BytesLike, overrides?: Overrides & { from?: string }, ): Promise; diff --git a/packages/shared/src/contracts/ethers-typechain/factories/Coordinator__factory.ts b/packages/shared/src/contracts/ethers-typechain/factories/Coordinator__factory.ts index e3800e887..ae8e72d4c 100644 --- a/packages/shared/src/contracts/ethers-typechain/factories/Coordinator__factory.ts +++ b/packages/shared/src/contracts/ethers-typechain/factories/Coordinator__factory.ts @@ -16,6 +16,16 @@ const _abi = [ type: 'address', internalType: 'contract ITACoChildApplication', }, + { + name: '_dkgTimeout', + type: 'uint32', + internalType: 'uint32', + }, + { + name: '_handoverTimeout', + type: 'uint32', + internalType: 'uint32', + }, ], }, { @@ -66,33 +76,6 @@ const _abi = [ }, ], }, - { - type: 'error', - name: 'AddressEmptyCode', - inputs: [ - { - name: 'target', - type: 'address', - internalType: 'address', - }, - ], - }, - { - type: 'error', - name: 'AddressInsufficientBalance', - inputs: [ - { - name: 'account', - type: 'address', - internalType: 'address', - }, - ], - }, - { - type: 'error', - name: 'FailedInnerCall', - inputs: [], - }, { type: 'error', name: 'InvalidInitialization', @@ -119,17 +102,6 @@ const _abi = [ }, ], }, - { - type: 'error', - name: 'SafeERC20FailedOperation', - inputs: [ - { - name: 'token', - type: 'address', - internalType: 'address', - }, - ], - }, { type: 'event', name: 'AggregationPosted', @@ -155,6 +127,25 @@ const _abi = [ ], anonymous: false, }, + { + type: 'event', + name: 'BlindedSharePosted', + inputs: [ + { + name: 'ritualId', + type: 'uint32', + internalType: 'uint32', + indexed: true, + }, + { + name: 'departingParticipant', + type: 'address', + internalType: 'address', + indexed: true, + }, + ], + anonymous: false, + }, { type: 'event', name: 'DefaultAdminDelayChangeCanceled', @@ -237,6 +228,106 @@ const _abi = [ ], anonymous: false, }, + { + type: 'event', + name: 'HandoverCanceled', + inputs: [ + { + name: 'ritualId', + type: 'uint32', + internalType: 'uint32', + indexed: true, + }, + { + name: 'departingParticipant', + type: 'address', + internalType: 'address', + indexed: true, + }, + { + name: 'incomingParticipant', + type: 'address', + internalType: 'address', + indexed: true, + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'HandoverFinalized', + inputs: [ + { + name: 'ritualId', + type: 'uint32', + internalType: 'uint32', + indexed: true, + }, + { + name: 'departingParticipant', + type: 'address', + internalType: 'address', + indexed: true, + }, + { + name: 'incomingParticipant', + type: 'address', + internalType: 'address', + indexed: true, + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'HandoverRequest', + inputs: [ + { + name: 'ritualId', + type: 'uint32', + internalType: 'uint32', + indexed: true, + }, + { + name: 'departingParticipant', + type: 'address', + internalType: 'address', + indexed: true, + }, + { + name: 'incomingParticipant', + type: 'address', + internalType: 'address', + indexed: true, + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'HandoverTranscriptPosted', + inputs: [ + { + name: 'ritualId', + type: 'uint32', + internalType: 'uint32', + indexed: true, + }, + { + name: 'departingParticipant', + type: 'address', + internalType: 'address', + indexed: true, + }, + { + name: 'incomingParticipant', + type: 'address', + internalType: 'address', + indexed: true, + }, + ], + anonymous: false, + }, { type: 'event', name: 'Initialized', @@ -481,25 +572,6 @@ const _abi = [ ], anonymous: false, }, - { - type: 'event', - name: 'TimeoutChanged', - inputs: [ - { - name: 'oldTimeout', - type: 'uint32', - internalType: 'uint32', - indexed: false, - }, - { - name: 'newTimeout', - type: 'uint32', - internalType: 'uint32', - indexed: false, - }, - ], - anonymous: false, - }, { type: 'event', name: 'TranscriptPosted', @@ -551,6 +623,19 @@ const _abi = [ }, ], }, + { + type: 'function', + name: 'HANDOVER_SUPERVISOR_ROLE', + stateMutability: 'view', + inputs: [], + outputs: [ + { + name: '', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + }, { type: 'function', name: 'TREASURY_ROLE', @@ -610,6 +695,30 @@ const _abi = [ ], outputs: [], }, + { + type: 'function', + name: 'blindedSharePosition', + stateMutability: 'pure', + inputs: [ + { + name: 'index', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'threshold', + type: 'uint16', + internalType: 'uint16', + }, + ], + outputs: [ + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, { type: 'function', name: 'cancelDefaultAdminTransfer', @@ -617,6 +726,24 @@ const _abi = [ inputs: [], outputs: [], }, + { + type: 'function', + name: 'cancelHandover', + stateMutability: 'nonpayable', + inputs: [ + { + name: 'ritualId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'departingParticipant', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + }, { type: 'function', name: 'changeDefaultAdminDelay', @@ -688,6 +815,32 @@ const _abi = [ }, ], }, + { + type: 'function', + name: 'dkgTimeout', + stateMutability: 'view', + inputs: [], + outputs: [ + { + name: '', + type: 'uint32', + internalType: 'uint32', + }, + ], + }, + { + type: 'function', + name: 'dkgTimeoutStub', + stateMutability: 'view', + inputs: [], + outputs: [ + { + name: '', + type: 'uint32', + internalType: 'uint32', + }, + ], + }, { type: 'function', name: 'expectedTranscriptSize', @@ -749,6 +902,24 @@ const _abi = [ }, ], }, + { + type: 'function', + name: 'finalizeHandover', + stateMutability: 'nonpayable', + inputs: [ + { + name: 'ritualId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'departingParticipant', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + }, { type: 'function', name: 'getAccessController', @@ -806,6 +977,54 @@ const _abi = [ }, ], }, + { + type: 'function', + name: 'getHandoverKey', + stateMutability: 'view', + inputs: [ + { + name: 'ritualId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'departingProvider', + type: 'address', + internalType: 'address', + }, + ], + outputs: [ + { + name: '', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + }, + { + type: 'function', + name: 'getHandoverState', + stateMutability: 'view', + inputs: [ + { + name: 'ritualId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'departingParticipant', + type: 'address', + internalType: 'address', + }, + ], + outputs: [ + { + name: '', + type: 'uint8', + internalType: 'enum Coordinator.HandoverState', + }, + ], + }, { type: 'function', name: 'getInitiator', @@ -1240,6 +1459,81 @@ const _abi = [ ], outputs: [], }, + { + type: 'function', + name: 'handoverRequest', + stateMutability: 'nonpayable', + inputs: [ + { + name: 'ritualId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'departingParticipant', + type: 'address', + internalType: 'address', + }, + { + name: 'incomingParticipant', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + }, + { + type: 'function', + name: 'handoverTimeout', + stateMutability: 'view', + inputs: [], + outputs: [ + { + name: '', + type: 'uint32', + internalType: 'uint32', + }, + ], + }, + { + type: 'function', + name: 'handovers', + stateMutability: 'view', + inputs: [ + { + name: 'handoverKey', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + outputs: [ + { + name: 'requestTimestamp', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'incomingProvider', + type: 'address', + internalType: 'address', + }, + { + name: 'transcript', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'decryptionRequestStaticKey', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'blindedShare', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, { type: 'function', name: 'hasRole', @@ -1269,11 +1563,6 @@ const _abi = [ name: 'initialize', stateMutability: 'nonpayable', inputs: [ - { - name: '_timeout', - type: 'uint32', - internalType: 'uint32', - }, { name: '_maxDkgSize', type: 'uint16', @@ -1287,13 +1576,6 @@ const _abi = [ ], outputs: [], }, - { - type: 'function', - name: 'initializeNumberOfRituals', - stateMutability: 'nonpayable', - inputs: [], - outputs: [], - }, { type: 'function', name: 'initiateRitual', @@ -1333,35 +1615,6 @@ const _abi = [ }, ], }, - { - type: 'function', - name: 'isEncryptionAuthorized', - stateMutability: 'view', - inputs: [ - { - name: '', - type: 'uint32', - internalType: 'uint32', - }, - { - name: '', - type: 'bytes', - internalType: 'bytes', - }, - { - name: '', - type: 'bytes', - internalType: 'bytes', - }, - ], - outputs: [ - { - name: '', - type: 'bool', - internalType: 'bool', - }, - ], - }, { type: 'function', name: 'isParticipant', @@ -1560,16 +1813,16 @@ const _abi = [ }, { type: 'function', - name: 'postTranscript', + name: 'postBlindedShare', stateMutability: 'nonpayable', inputs: [ { - name: '', + name: 'ritualId', type: 'uint32', internalType: 'uint32', }, { - name: '', + name: 'blindedShare', type: 'bytes', internalType: 'bytes', }, @@ -1578,7 +1831,7 @@ const _abi = [ }, { type: 'function', - name: 'publishTranscript', + name: 'postHandoverTranscript', stateMutability: 'nonpayable', inputs: [ { @@ -1586,23 +1839,38 @@ const _abi = [ type: 'uint32', internalType: 'uint32', }, + { + name: 'departingParticipant', + type: 'address', + internalType: 'address', + }, { name: 'transcript', type: 'bytes', internalType: 'bytes', }, + { + name: 'decryptionRequestStaticKey', + type: 'bytes', + internalType: 'bytes', + }, ], outputs: [], }, { type: 'function', - name: 'reinitializeDefaultAdmin', + name: 'publishTranscript', stateMutability: 'nonpayable', inputs: [ { - name: 'newDefaultAdmin', - type: 'address', - internalType: 'address', + name: 'ritualId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'transcript', + type: 'bytes', + internalType: 'bytes', }, ], outputs: [], @@ -1649,7 +1917,7 @@ const _abi = [ stateMutability: 'view', inputs: [ { - name: 'ritualId', + name: 'index', type: 'uint256', internalType: 'uint256', }, @@ -1797,19 +2065,6 @@ const _abi = [ ], outputs: [], }, - { - type: 'function', - name: 'setTimeout', - stateMutability: 'nonpayable', - inputs: [ - { - name: 'newTimeout', - type: 'uint32', - internalType: 'uint32', - }, - ], - outputs: [], - }, { type: 'function', name: 'supportsInterface', @@ -1860,19 +2115,6 @@ const _abi = [ ], outputs: [], }, - { - type: 'function', - name: 'withdrawAllTokens', - stateMutability: 'nonpayable', - inputs: [ - { - name: 'token', - type: 'address', - internalType: 'contract IERC20', - }, - ], - outputs: [], - }, ] as const; export class Coordinator__factory { diff --git a/packages/shared/src/contracts/ethers-typechain/factories/SigningCoordinator__factory.ts b/packages/shared/src/contracts/ethers-typechain/factories/SigningCoordinator__factory.ts index 31fb08fbc..1ec9d4dd5 100644 --- a/packages/shared/src/contracts/ethers-typechain/factories/SigningCoordinator__factory.ts +++ b/packages/shared/src/contracts/ethers-typechain/factories/SigningCoordinator__factory.ts @@ -389,6 +389,12 @@ const _abi = [ internalType: 'address', indexed: true, }, + { + name: 'signer', + type: 'address', + internalType: 'address', + indexed: true, + }, { name: 'signature', type: 'bytes', @@ -443,6 +449,19 @@ const _abi = [ }, ], }, + { + type: 'function', + name: 'SIGNING_REQUEST_KEY_LENGTH', + stateMutability: 'view', + inputs: [], + outputs: [ + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, { type: 'function', name: 'acceptDefaultAdminTransfer', @@ -555,26 +574,25 @@ const _abi = [ }, { type: 'function', - name: 'getChains', - stateMutability: 'view', + name: 'extendSigningCohortDuration', + stateMutability: 'nonpayable', inputs: [ { name: 'cohortId', type: 'uint32', internalType: 'uint32', }, - ], - outputs: [ { - name: '', - type: 'uint256[]', - internalType: 'uint256[]', + name: 'additionalDuration', + type: 'uint32', + internalType: 'uint32', }, ], + outputs: [], }, { type: 'function', - name: 'getCondition', + name: 'getChains', stateMutability: 'view', inputs: [ { @@ -582,17 +600,12 @@ const _abi = [ type: 'uint32', internalType: 'uint32', }, - { - name: 'chainId', - type: 'uint256', - internalType: 'uint256', - }, ], outputs: [ { name: '', - type: 'bytes', - internalType: 'bytes', + type: 'uint256[]', + internalType: 'uint256[]', }, ], }, @@ -642,15 +655,20 @@ const _abi = [ internalType: 'address', }, { - name: 'operator', + name: 'signerAddress', type: 'address', internalType: 'address', }, { - name: 'signature', + name: 'signingRequestStaticKey', type: 'bytes', internalType: 'bytes', }, + { + name: 'gap', + type: 'uint256[20]', + internalType: 'uint256[20]', + }, ], internalType: 'struct SigningCoordinator.SigningCohortParticipant', }, @@ -678,15 +696,20 @@ const _abi = [ internalType: 'address', }, { - name: 'operator', + name: 'signerAddress', type: 'address', internalType: 'address', }, { - name: 'signature', + name: 'signingRequestStaticKey', type: 'bytes', internalType: 'bytes', }, + { + name: 'gap', + type: 'uint256[20]', + internalType: 'uint256[20]', + }, ], internalType: 'struct SigningCoordinator.SigningCohortParticipant[]', }, @@ -726,6 +749,11 @@ const _abi = [ type: 'uint32', internalType: 'uint32', }, + { + name: 'operator', + type: 'address', + internalType: 'address', + }, ], outputs: [ { @@ -773,6 +801,25 @@ const _abi = [ }, ], }, + { + type: 'function', + name: 'getThreshold', + stateMutability: 'view', + inputs: [ + { + name: 'cohortId', + type: 'uint32', + internalType: 'uint32', + }, + ], + outputs: [ + { + name: '', + type: 'uint16', + internalType: 'uint16', + }, + ], + }, { type: 'function', name: 'grantRole', @@ -1002,7 +1049,7 @@ const _abi = [ }, { type: 'function', - name: 'postSigningCohortSignature', + name: 'postSigningCohortData', stateMutability: 'nonpayable', inputs: [ { @@ -1015,6 +1062,11 @@ const _abi = [ type: 'bytes', internalType: 'bytes', }, + { + name: 'signingRequestStaticKey', + type: 'bytes', + internalType: 'bytes', + }, ], outputs: [], }, diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 68f5f968d..37ee90430 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -244,16 +244,6 @@ export const mockGetActiveRitual = (dkgRitual: DkgRitual): MockInstance => { }); }; -export const mockIsEncryptionAuthorized = ( - isAuthorized = true, -): MockInstance => { - return vi - .spyOn(DkgCoordinatorAgent, 'isEncryptionAuthorized') - .mockImplementation(async () => { - return Promise.resolve(isAuthorized); - }); -}; - export const mockMakeSessionKey = (secret: SessionStaticSecret) => { return vi .spyOn(SessionStaticSecret, 'random') diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dcd3840e5..7ce93f6de 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -513,8 +513,8 @@ importers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@nucypher/nucypher-contracts': - specifier: 0.26.0-alpha.1 - version: 0.26.0-alpha.1 + specifier: ^0.26.0-alpha.2 + version: 0.26.0-alpha.2 '@nucypher/nucypher-core': specifier: ^0.15.1-dev.2 version: 0.15.1-dev.3 @@ -2704,8 +2704,8 @@ packages: '@nucypher/nucypher-contracts@0.25.0': resolution: {integrity: sha512-4fRPKY6RzkXY1Zv2O0auJZsvP6z7tuj+Fsy83yJvADqFwRuIJfSlwgSgLwISX6q838SRG/Ve2i+sMLZRaVJfYw==} - '@nucypher/nucypher-contracts@0.26.0-alpha.1': - resolution: {integrity: sha512-ISS66SyKbDLXFF88Z6k8Tnc/L6Shx6tq22CjPpovbSD2PGS/UzE3uDxvFTKZfgcIJYsi7GV/ho2Brsx4sHYTLg==} + '@nucypher/nucypher-contracts@0.26.0-alpha.2': + resolution: {integrity: sha512-Vo5AeJ+7iqj1PNpIKfgajkVK7BGNETre8fxDtKyYSaW+9SNXh5ext7eacdvDRdQg/EDmhk0IItch1wXVyVydtQ==} '@nucypher/nucypher-core@0.15.1-dev.3': resolution: {integrity: sha512-0MJ8XvH2X5OyEx+f2i9A2iA+KosHzxZbOt8V3Ye6ZDlMC5N4aeDOEJ02ftwnc0C0NO0CPqTuLlYGbrreW57K+w==} @@ -12478,7 +12478,7 @@ snapshots: '@nucypher/nucypher-contracts@0.25.0': {} - '@nucypher/nucypher-contracts@0.26.0-alpha.1': {} + '@nucypher/nucypher-contracts@0.26.0-alpha.2': {} '@nucypher/nucypher-core@0.15.1-dev.3': {} From b38a66a579ec73f6169e855559e283839ee6156b Mon Sep 17 00:00:00 2001 From: derekpierre Date: Mon, 10 Nov 2025 05:55:56 -0500 Subject: [PATCH 217/303] chore(release): release @nucypher/shared:0.6.0-alpha.4 --- packages/shared/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/package.json b/packages/shared/package.json index 3c1930138..3b875bc99 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/shared", - "version": "0.6.0-alpha.3", + "version": "0.6.0-alpha.4", "keywords": [ "pre", "taco", From 0bdeb87c932be06db79c569a16ed41ba71d53eb8 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 19 Nov 2025 19:47:46 -0500 Subject: [PATCH 218/303] Properly sort signatures based on signer addresses when aggregating signatures returned from nodes. --- packages/taco/src/sign.ts | 35 ++++++++++++++++++---------- packages/taco/test/taco-sign.test.ts | 17 +++++++------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index ef2df329b..9942776ca 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -51,20 +51,31 @@ export type SignResult = { }; function aggregateSignatures( - signaturesByAddress: { - [checksumAddress: string]: TacoSignature; - }, + signatures: TacoSignature[], threshold: number, ): string { - // Aggregate hex signatures by concatenating them; being careful to remove the '0x' prefix from each signature except the first one. - const signatures = Object.values(signaturesByAddress) - .map((sig) => sig.signature) - .slice(0, threshold); - if (signatures.length === 1) { - return signatures[0]; + // Aggregate hex signatures by concatenating them; being careful to sort + // and remove the '0x' prefix from each signature except the first one. + + // sort by signer address + const sortedSignatures = signatures + .slice() + .sort((a, b) =>{ + const addrA = BigInt(a.signerAddress); + const addrB = BigInt(b.signerAddress); + return addrA < addrB ? -1 : addrA > addrB ? 1 : 0; + }) + .map((sig) => sig.signature); + + const thresholdSignatures = sortedSignatures.slice(0, threshold); + if (thresholdSignatures.length === 1) { + return thresholdSignatures[0]; } + // Concatenate signatures - const allBytes = signatures.flatMap((hex) => Array.from(fromHexString(hex))); + const allBytes = thresholdSignatures.flatMap((sig) => + Array.from(fromHexString(sig)), + ); return `0x${toHexString(new Uint8Array(allBytes))}`; } @@ -197,7 +208,7 @@ export async function signUserOp( ); const aggregatedSignature = aggregateSignatures( - signaturesToAggregate, + Object.values(signaturesToAggregate), threshold, ); @@ -300,7 +311,7 @@ function collectSignatures( // Insufficient signatures for a message hash to meet the threshold if (!signaturesToAggregate) { - //we have multiple hashes, which means we have mismatched hashes from different nodes + // we have multiple hashes, which means we have mismatched hashes from different nodes // we don't really expect this to happen (other than some malicious nodes) console.error( 'Porter returned mismatched message hashes:', diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index ed73e3c03..360cdb768 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -357,24 +357,25 @@ describe('TACo Signing', () => { userOp: UserOperationToSign | PackedUserOperationToSign, ) => { const encryptedResponses = { - '0xnode1': new SignatureResponse( - signersInfo['0xnode1'].signerAddress, + // return out of order to ensure sorting works correctly + '0xnode2': new SignatureResponse( + signersInfo['0xnode2'].signerAddress, fromHexString('0xa1'), - fromHexString('0xdead'), + fromHexString('0xbeef'), 0, ).encrypt( requesterSk.deriveSharedSecret( - signersInfo['0xnode1'].signingRequestStaticKey, + signersInfo['0xnode2'].signingRequestStaticKey, ), ), - '0xnode2': new SignatureResponse( - signersInfo['0xnode2'].signerAddress, + '0xnode1': new SignatureResponse( + signersInfo['0xnode1'].signerAddress, fromHexString('0xa1'), - fromHexString('0xbeef'), + fromHexString('0xdead'), 0, ).encrypt( requesterSk.deriveSharedSecret( - signersInfo['0xnode2'].signingRequestStaticKey, + signersInfo['0xnode1'].signingRequestStaticKey, ), ), }; From 1be73cdc2b380145c063bdfb372bfd6ab0062031 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Mon, 10 Nov 2025 05:57:21 -0500 Subject: [PATCH 219/303] chore(release): release @nucypher/taco-auth:0.4.0-alpha.4 --- packages/taco-auth/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco-auth/package.json b/packages/taco-auth/package.json index aadcd3df4..6f073ae0a 100644 --- a/packages/taco-auth/package.json +++ b/packages/taco-auth/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco-auth", - "version": "0.4.0-alpha.3", + "version": "0.4.0-alpha.4", "keywords": [ "pre", "threshold", From 682253c17044d6738f9ceda4d685927bcb6a0280 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 19 Nov 2025 19:49:32 -0500 Subject: [PATCH 220/303] Use `accountGasLimits` and not `accountGasLimit` as property on PackedUserOperationToSign. --- packages/shared/src/types.ts | 4 ++-- packages/shared/test/porter.test.ts | 2 +- packages/taco/test/taco-sign.test.ts | 16 ++++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/shared/src/types.ts b/packages/shared/src/types.ts index 8d4b96cdb..c0fd94aec 100644 --- a/packages/shared/src/types.ts +++ b/packages/shared/src/types.ts @@ -30,7 +30,7 @@ export type PackedUserOperationToSign = { nonce: bigint | number; initCode: `0x${string}` | Uint8Array; callData: `0x${string}` | Uint8Array; - accountGasLimit: `0x${string}` | Uint8Array; + accountGasLimits: `0x${string}` | Uint8Array; preVerificationGas: bigint | number; gasFees: `0x${string}` | Uint8Array; paymasterAndData: `0x${string}` | Uint8Array; @@ -101,7 +101,7 @@ export function toCorePackedUserOperation( getBigIntValue(packedUserOperation.nonce), getUint8ArrayValue(packedUserOperation.initCode), getUint8ArrayValue(packedUserOperation.callData), - getUint8ArrayValue(packedUserOperation.accountGasLimit), + getUint8ArrayValue(packedUserOperation.accountGasLimits), getBigIntValue(packedUserOperation.preVerificationGas), getUint8ArrayValue(packedUserOperation.gasFees), getUint8ArrayValue(packedUserOperation.paymasterAndData), diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index ae057ba54..046894664 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -289,7 +289,7 @@ describe('PorterClient Signing', () => { BigInt(123), // nonce fromHexString('0xabc'), // initCode fromHexString('0xdef'), // callData - fromHexString('0x01020304'), // accountGasLimit + fromHexString('0x01020304'), // accountGasLimits BigInt(101112), // preVerificationGas fromHexString('0x05060708'), // gasFees fromHexString('0x090a0b0c'), // paymasterAndData diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index 360cdb768..fcce85295 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -53,11 +53,11 @@ function checkPackedUserOpEquality( : fromHexString(op1.callData); expect(callData).toEqual(op2.callData); - const accountGasLimit = - op1.accountGasLimit instanceof Uint8Array - ? op1.accountGasLimit - : fromHexString(op1.accountGasLimit); - expect(accountGasLimit).toEqual(op2.accountGasLimits); + const accountGasLimits = + op1.accountGasLimits instanceof Uint8Array + ? op1.accountGasLimits + : fromHexString(op1.accountGasLimits); + expect(accountGasLimits).toEqual(op2.accountGasLimits); expect(toBigInt(op1.preVerificationGas)).toEqual(op2.preVerificationGas); @@ -290,7 +290,7 @@ describe('TACo Signing', () => { nonce: BigInt(123), initCode: fromHexString('0xabc'), callData: fromHexString('0xdef'), - accountGasLimit: fromHexString('0x01020304'), + accountGasLimits: fromHexString('0x01020304'), preVerificationGas: BigInt(101112), gasFees: fromHexString('0x05060708'), paymasterAndData: fromHexString('0x090a0b0c'), @@ -307,7 +307,7 @@ describe('TACo Signing', () => { nonce: 1, initCode: '0xabc', callData: '0xdef', - accountGasLimit: '0x01020304', + accountGasLimits: '0x01020304', preVerificationGas: 4096, gasFees: '0x05060708', paymasterAndData: '0x090a0b0c', @@ -333,7 +333,7 @@ describe('TACo Signing', () => { nonce: BigInt(1), initCode: fromHexString('0xabc'), callData: fromHexString('0xdef'), - accountGasLimit: fromHexString('0x01020304'), + accountGasLimits: fromHexString('0x01020304'), preVerificationGas: BigInt(101112), gasFees: fromHexString('0x05060708'), paymasterAndData: fromHexString('0x090a0b0c'), From 686fdaf5aca3b04f2782be62da1797616fd74d6c Mon Sep 17 00:00:00 2001 From: derekpierre Date: Mon, 10 Nov 2025 05:58:37 -0500 Subject: [PATCH 221/303] chore(release): release @nucypher/taco:0.7.0-alpha.4 --- packages/taco/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco/package.json b/packages/taco/package.json index 8211466ff..b90f88388 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco", - "version": "0.7.0-alpha.3", + "version": "0.7.0-alpha.4", "keywords": [ "taco", "threshold", From 05767e30c6c0bc5e6a99c8bf8bd22b94a885dbef Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 19 Nov 2025 19:51:00 -0500 Subject: [PATCH 222/303] Allow optional signature property on PackedUserOperationToSign. --- packages/shared/src/types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/shared/src/types.ts b/packages/shared/src/types.ts index c0fd94aec..8d5ea9f0c 100644 --- a/packages/shared/src/types.ts +++ b/packages/shared/src/types.ts @@ -34,6 +34,7 @@ export type PackedUserOperationToSign = { preVerificationGas: bigint | number; gasFees: `0x${string}` | Uint8Array; paymasterAndData: `0x${string}` | Uint8Array; + signature?: `0x${string}` | Uint8Array | undefined; }; function getBigIntValue(value: bigint | number): bigint { From 40b85c5f5c78fdd8384846e08b9a0cad89b44955 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 11 Nov 2025 08:54:54 -0500 Subject: [PATCH 223/303] Make test function name clearer. Co-authored-by: Manuel Montenegro --- packages/taco/test/taco-sign.test.ts | 30 ++++++++++------------------ 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index d8d7322c6..ed73e3c03 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -30,7 +30,7 @@ import { setSigningCohortConditions, signUserOp } from '../src/sign'; import { mockMakeSessionKey } from './test-utils'; -function getNumberValue(value: bigint | number): bigint { +function toBigInt(value: bigint | number): bigint { return typeof value === 'bigint' ? value : BigInt(value); } @@ -39,7 +39,7 @@ function checkPackedUserOpEquality( op2: PackedUserOperation, ) { expect(op1.sender).toEqual(op2.sender); - expect(getNumberValue(op1.nonce)).toEqual(op2.nonce); + expect(toBigInt(op1.nonce)).toEqual(op2.nonce); const initCode = op1.initCode instanceof Uint8Array @@ -59,9 +59,7 @@ function checkPackedUserOpEquality( : fromHexString(op1.accountGasLimit); expect(accountGasLimit).toEqual(op2.accountGasLimits); - expect(getNumberValue(op1.preVerificationGas)).toEqual( - op2.preVerificationGas, - ); + expect(toBigInt(op1.preVerificationGas)).toEqual(op2.preVerificationGas); const gasFees = op1.gasFees instanceof Uint8Array @@ -79,7 +77,7 @@ function checkPackedUserOpEquality( function checkUserOpEquality(op1: UserOperationToSign, op2: UserOperation) { expect(op1.sender).toEqual(op2.sender); - expect(getNumberValue(op1.nonce)).toEqual(op2.nonce); + expect(toBigInt(op1.nonce)).toEqual(op2.nonce); const callData = op1.callData instanceof Uint8Array @@ -87,17 +85,11 @@ function checkUserOpEquality(op1: UserOperationToSign, op2: UserOperation) { : fromHexString(op1.callData); expect(callData).toEqual(op2.callData); - expect(getNumberValue(op1.callGasLimit)).toEqual(op2.callGasLimit); - expect(getNumberValue(op1.verificationGasLimit)).toEqual( - op2.verificationGasLimit, - ); - expect(getNumberValue(op1.preVerificationGas)).toEqual( - op2.preVerificationGas, - ); - expect(getNumberValue(op1.maxFeePerGas)).toEqual(op2.maxFeePerGas); - expect(getNumberValue(op1.maxPriorityFeePerGas)).toEqual( - op2.maxPriorityFeePerGas, - ); + expect(toBigInt(op1.callGasLimit)).toEqual(op2.callGasLimit); + expect(toBigInt(op1.verificationGasLimit)).toEqual(op2.verificationGasLimit); + expect(toBigInt(op1.preVerificationGas)).toEqual(op2.preVerificationGas); + expect(toBigInt(op1.maxFeePerGas)).toEqual(op2.maxFeePerGas); + expect(toBigInt(op1.maxPriorityFeePerGas)).toEqual(op2.maxPriorityFeePerGas); if (op1.factory === undefined) { expect(op2.factory).toBeUndefined(); @@ -124,7 +116,7 @@ function checkUserOpEquality(op1: UserOperationToSign, op2: UserOperation) { if (op1.paymasterVerificationGasLimit === undefined) { expect(op2.paymasterVerificationGasLimit).toBeUndefined(); } else { - expect(getNumberValue(op1.paymasterVerificationGasLimit)).toEqual( + expect(toBigInt(op1.paymasterVerificationGasLimit)).toEqual( op2.paymasterVerificationGasLimit, ); } @@ -132,7 +124,7 @@ function checkUserOpEquality(op1: UserOperationToSign, op2: UserOperation) { if (op1.paymasterPostOpGasLimit === undefined) { expect(op2.paymasterPostOpGasLimit).toBeUndefined(); } else { - expect(getNumberValue(op1.paymasterPostOpGasLimit)).toEqual( + expect(toBigInt(op1.paymasterPostOpGasLimit)).toEqual( op2.paymasterPostOpGasLimit, ); } From 57b0cb29da02f120edf6595fd14d434d908669ef Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 19 Nov 2025 19:51:18 -0500 Subject: [PATCH 224/303] Expose `PackedUserOperationToSign` and `UserOperationToSign` from within `nucypher/taco` package. --- packages/taco/src/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/taco/src/index.ts b/packages/taco/src/index.ts index 34e6bdf0f..866ce1c24 100644 --- a/packages/taco/src/index.ts +++ b/packages/taco/src/index.ts @@ -1,6 +1,8 @@ export { DkgPublicKey, ThresholdMessageKit } from '@nucypher/nucypher-core'; export { Domain, + PackedUserOperationToSign, + UserOperationToSign, domains, fromBytes, getPorterUris, From f9fcb286f4aee45132a728f6606f4b4f7169205b Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 11 Nov 2025 09:23:14 -0500 Subject: [PATCH 225/303] Remove lingering TODO that was already addressed. --- packages/shared/src/contracts/agents/signing-coordinator.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/shared/src/contracts/agents/signing-coordinator.ts b/packages/shared/src/contracts/agents/signing-coordinator.ts index 22c974305..354874ddf 100644 --- a/packages/shared/src/contracts/agents/signing-coordinator.ts +++ b/packages/shared/src/contracts/agents/signing-coordinator.ts @@ -29,7 +29,6 @@ export class SigningCoordinatorAgent { return { provider: participant.provider, signerAddress: participant.signerAddress, - // TODO fix once available via nucypher-contract dependency signingRequestStaticKey: SessionStaticKey.fromBytes( fromHexString(participant.signingRequestStaticKey), ), From faef12b4e813ed06a2a2e5498fe2f74cc0500d73 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 20 Nov 2025 10:59:14 -0500 Subject: [PATCH 226/303] Fix sorting of signatures when aggregating signatures. --- packages/taco/src/sign.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 9942776ca..31b5c62bf 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -58,13 +58,12 @@ function aggregateSignatures( // and remove the '0x' prefix from each signature except the first one. // sort by signer address - const sortedSignatures = signatures - .slice() - .sort((a, b) =>{ - const addrA = BigInt(a.signerAddress); - const addrB = BigInt(b.signerAddress); - return addrA < addrB ? -1 : addrA > addrB ? 1 : 0; - }) + const sortedSignatures = [...signatures] + .sort((a, b) => + a.signerAddress + .toLowerCase() + .localeCompare(b.signerAddress.toLowerCase()), + ) .map((sig) => sig.signature); const thresholdSignatures = sortedSignatures.slice(0, threshold); From 261f77d5a6a9379099ce6aea945dfab91967fe00 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 11 Nov 2025 09:33:48 -0500 Subject: [PATCH 227/303] Move TacoSignature out of Porter and into sign.ts since Porter no longer handles unencrypted responses. Export relevant types from sign module. --- packages/shared/src/porter.ts | 6 ------ packages/taco/src/index.ts | 7 ++++++- packages/taco/src/sign.ts | 7 ++++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/shared/src/porter.ts b/packages/shared/src/porter.ts index f460c7dba..a71239bc8 100644 --- a/packages/shared/src/porter.ts +++ b/packages/shared/src/porter.ts @@ -179,12 +179,6 @@ type TacoSignResponse = { }; }; -export type TacoSignature = { - messageHash: string; - signature: string; - signerAddress: string; -}; - export type TacoSignResult = { encryptedResponses: Record< ChecksumAddress, diff --git a/packages/taco/src/index.ts b/packages/taco/src/index.ts index b97a54173..34e6bdf0f 100644 --- a/packages/taco/src/index.ts +++ b/packages/taco/src/index.ts @@ -11,5 +11,10 @@ export { export * as conditions from './conditions'; -export { setSigningCohortConditions, signUserOp } from './sign'; +export { + SignResult, + TacoSignature, + setSigningCohortConditions, + signUserOp, +} from './sign'; export { decrypt, encrypt, encryptWithPublicKey } from './taco'; diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 9a1f1fde8..ef2df329b 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -16,7 +16,6 @@ import { PorterClient, SignerInfo, SigningCoordinatorAgent, - TacoSignature, toCorePackedUserOperation, toCoreUserOperation, toHexString, @@ -39,6 +38,12 @@ const ERR_MISMATCHED_HASHES = ( Object.fromEntries(hashToSignatures.entries()), )}`; +export type TacoSignature = { + messageHash: string; + signature: string; + signerAddress: string; +}; + export type SignResult = { messageHash: string; aggregatedSignature: string; From aaea7644ba1c50efbcf5880966859abf0e1a7216 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 13 Nov 2025 15:44:44 -0500 Subject: [PATCH 228/303] Update `nucypher-core` depdendency to 0.15.1-dev.3 for latest changes regarding nonce value being provided as uint256 string. --- package.json | 4 ++-- packages/pre/package.json | 2 +- packages/shared/package.json | 2 +- packages/taco/package.json | 2 +- packages/test-utils/package.json | 2 +- pnpm-lock.yaml | 12 ++++++------ 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index cbdddf377..9ef80ef5e 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ }, "dependencies": { "@changesets/cli": "^2.28.1", - "@nucypher/nucypher-core": "^0.15.1-dev.2", + "@nucypher/nucypher-core": "^0.15.1-dev.3", "ethers": "^5.8.0" }, "devDependencies": { @@ -65,7 +65,7 @@ ] }, "overrides": { - "@nucypher/nucypher-core": "^0.15.1-dev.2", + "@nucypher/nucypher-core": "^0.15.1-dev.3", "glob-parent@<5.1.2": ">=5.1.2", "node-forge@<1.0.0": ">=1.0.0", "node-forge@<1.3.0": ">=1.3.0", diff --git a/packages/pre/package.json b/packages/pre/package.json index 59e2fb337..0bbd16163 100644 --- a/packages/pre/package.json +++ b/packages/pre/package.json @@ -38,7 +38,7 @@ "typedoc": "typedoc" }, "dependencies": { - "@nucypher/nucypher-core": "^0.15.1-dev.2", + "@nucypher/nucypher-core": "^0.15.1-dev.3", "@nucypher/shared": "workspace:*", "ethers": "^5.8.0" }, diff --git a/packages/shared/package.json b/packages/shared/package.json index 3b875bc99..d43c4865b 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -43,7 +43,7 @@ "@ethersproject/abi": "^5.8.0", "@ethersproject/providers": "^5.8.0", "@nucypher/nucypher-contracts": "^0.26.0-alpha.2", - "@nucypher/nucypher-core": "^0.15.1-dev.2", + "@nucypher/nucypher-core": "^0.15.1-dev.3", "axios": "^1.8.4", "deep-equal": "^2.2.3", "ethers": "^5.8.0", diff --git a/packages/taco/package.json b/packages/taco/package.json index b90f88388..986f27d1f 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -42,7 +42,7 @@ }, "dependencies": { "@astronautlabs/jsonpath": "^1.1.2", - "@nucypher/nucypher-core": "^0.15.1-dev.2", + "@nucypher/nucypher-core": "^0.15.1-dev.3", "@nucypher/shared": "workspace:*", "@nucypher/taco-auth": "workspace:*", "ethers": "^5.8.0", diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 39df81e44..77cb5d995 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -29,7 +29,7 @@ "lint:fix": "pnpm lint --fix" }, "dependencies": { - "@nucypher/nucypher-core": "^0.15.1-dev.2", + "@nucypher/nucypher-core": "^0.15.1-dev.3", "@nucypher/shared": "workspace:*", "@nucypher/taco-auth": "workspace:*", "axios": "^1.11.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7ce93f6de..87ddf9990 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,7 @@ settings: excludeLinksFromLockfile: false overrides: - '@nucypher/nucypher-core': ^0.15.1-dev.2 + '@nucypher/nucypher-core': ^0.15.1-dev.3 glob-parent@<5.1.2: '>=5.1.2' node-forge@<1.0.0: '>=1.0.0' node-forge@<1.3.0: '>=1.3.0' @@ -19,7 +19,7 @@ importers: specifier: ^2.28.1 version: 2.30.0(@types/node@24.3.0) '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.2 + specifier: ^0.15.1-dev.3 version: 0.15.1-dev.3 ethers: specifier: ^5.8.0 @@ -491,7 +491,7 @@ importers: packages/pre: dependencies: '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.2 + specifier: ^0.15.1-dev.3 version: 0.15.1-dev.3 '@nucypher/shared': specifier: workspace:* @@ -516,7 +516,7 @@ importers: specifier: ^0.26.0-alpha.2 version: 0.26.0-alpha.2 '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.2 + specifier: ^0.15.1-dev.3 version: 0.15.1-dev.3 axios: specifier: ^1.8.4 @@ -565,7 +565,7 @@ importers: specifier: ^1.1.2 version: 1.1.2 '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.2 + specifier: ^0.15.1-dev.3 version: 0.15.1-dev.3 '@nucypher/shared': specifier: workspace:* @@ -624,7 +624,7 @@ importers: packages/test-utils: dependencies: '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.2 + specifier: ^0.15.1-dev.3 version: 0.15.1-dev.3 '@nucypher/shared': specifier: workspace:* From a45d05db0f43454a1ca447178eb616d5914cba62 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 31 Oct 2025 16:55:33 +0000 Subject: [PATCH 229/303] feat(conditions): add JSON, hex, and keccak operators Implement new variable operations to match nucypher/nucypher#3664: - JSON conversion: fromJson, toJson - Hex conversion: fromHex, toHex - Hashing: keccak All operators are unary (don't require a value parameter). Maintains consistency between nucypher and taco-web codebases. --- .../conditions/schemas/variable-operation.ts | 16 ++++ .../conditions/variable-operation.test.ts | 92 +++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/packages/taco/src/conditions/schemas/variable-operation.ts b/packages/taco/src/conditions/schemas/variable-operation.ts index 822c89fde..2df358640 100644 --- a/packages/taco/src/conditions/schemas/variable-operation.ts +++ b/packages/taco/src/conditions/schemas/variable-operation.ts @@ -26,6 +26,14 @@ export const OPERATOR_FUNCTIONS = [ 'float', 'int', 'str', + // JSON conversion + 'fromJson', + 'toJson', + // hex conversion + 'fromHex', + 'toHex', + // hashing + 'keccak', ] as const; export const UNARY_OPERATOR_FUNCTIONS = [ @@ -44,6 +52,14 @@ export const UNARY_OPERATOR_FUNCTIONS = [ 'float', 'int', 'str', + // JSON conversion + 'fromJson', + 'toJson', + // hex conversion + 'fromHex', + 'toHex', + // hashing + 'keccak', ]; export const variableOperationSchema = z diff --git a/packages/taco/test/conditions/variable-operation.test.ts b/packages/taco/test/conditions/variable-operation.test.ts index b2ecc578e..558c66a7e 100644 --- a/packages/taco/test/conditions/variable-operation.test.ts +++ b/packages/taco/test/conditions/variable-operation.test.ts @@ -49,3 +49,95 @@ describe('validates schema', () => { }, ); }); + +describe('new operators', () => { + describe('JSON conversion', () => { + it('toJson converts object to JSON string', () => { + const result = variableOperationSchema.safeParse({ + operation: 'toJson', + }); + expect(result.success).toBe(true); + }); + + it('toJson converts array to JSON string', () => { + const result = variableOperationSchema.safeParse({ + operation: 'toJson', + }); + expect(result.success).toBe(true); + }); + + it('fromJson parses JSON string to object', () => { + const result = variableOperationSchema.safeParse({ + operation: 'fromJson', + }); + expect(result.success).toBe(true); + }); + + it('fromJson parses JSON string to array', () => { + const result = variableOperationSchema.safeParse({ + operation: 'fromJson', + }); + expect(result.success).toBe(true); + }); + }); + + describe('hex conversion', () => { + it('toHex converts bytes to hex string', () => { + const result = variableOperationSchema.safeParse({ + operation: 'toHex', + }); + expect(result.success).toBe(true); + }); + + it('toHex converts string to hex', () => { + const result = variableOperationSchema.safeParse({ + operation: 'toHex', + }); + expect(result.success).toBe(true); + }); + + it('toHex converts integers to hex', () => { + const result = variableOperationSchema.safeParse({ + operation: 'toHex', + }); + expect(result.success).toBe(true); + }); + + it('fromHex converts hex string to bytes', () => { + const result = variableOperationSchema.safeParse({ + operation: 'fromHex', + }); + expect(result.success).toBe(true); + }); + }); + + describe('keccak hashing', () => { + it('keccak hashes strings', () => { + const result = variableOperationSchema.safeParse({ + operation: 'keccak', + }); + expect(result.success).toBe(true); + }); + + it('keccak hashes empty string', () => { + const result = variableOperationSchema.safeParse({ + operation: 'keccak', + }); + expect(result.success).toBe(true); + }); + + it('keccak hashes integers', () => { + const result = variableOperationSchema.safeParse({ + operation: 'keccak', + }); + expect(result.success).toBe(true); + }); + + it('keccak hashes bytes', () => { + const result = variableOperationSchema.safeParse({ + operation: 'keccak', + }); + expect(result.success).toBe(true); + }); + }); +}); From 1c710b83ed049212dd39ae61c211370180fbcb97 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 20 Nov 2025 11:30:25 -0500 Subject: [PATCH 230/303] chore(release): release @nucypher/shared:0.6.0-alpha.5 --- packages/shared/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/package.json b/packages/shared/package.json index d43c4865b..36d1b2b05 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/shared", - "version": "0.6.0-alpha.4", + "version": "0.6.0-alpha.5", "keywords": [ "pre", "taco", From c70e830b6dcc4ad4357347cff4e830899712029f Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 5 Nov 2025 09:23:34 +0000 Subject: [PATCH 231/303] test(conditions): improve test coverage for new operators Remove duplicate unit tests already covered by parametrized tests. Add integration test validating JSON, hex, and keccak operations. --- .../integration-test/condition-lingo.test.ts | 48 ++++++++++ .../conditions/variable-operation.test.ts | 92 ------------------- 2 files changed, 48 insertions(+), 92 deletions(-) diff --git a/packages/taco/integration-test/condition-lingo.test.ts b/packages/taco/integration-test/condition-lingo.test.ts index cbf705951..814e6b49b 100644 --- a/packages/taco/integration-test/condition-lingo.test.ts +++ b/packages/taco/integration-test/condition-lingo.test.ts @@ -221,5 +221,53 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( const conditionExpr = new ConditionExpression(sequentialCondition); await validateConditionExpression(conditionExpr); }, 15000); + + test('validate conditions with JSON, hex, and keccak operations', async () => { + const sequentialCondition = new SequentialCondition({ + conditionVariables: [ + { + varName: 'jsonValue', + condition: { + ...testJsonApiConditionObj, + returnValueTest: { + comparator: '==', + value: + '0x7b226b6579223a2276616c7565222c226e756d626572223a3432ffffffffffffff', + operations: [{ operation: 'toJson' }, { operation: 'toHex' }], + }, + }, + }, + { + varName: 'hexValue', + condition: { + ...testRpcConditionObj, + returnValueTest: { + comparator: '==', + value: 'test string', + operations: [{ operation: 'toHex' }, { operation: 'fromHex' }], + }, + }, + }, + { + varName: 'keccakValue', + condition: { + ...testTimeConditionObj, + returnValueTest: { + comparator: '==', + value: + '0x9c22ff5f21f0b81b113e633f7db6da94fededef11b2119b40888b89664fb9a3cb658', + operations: [ + { operation: 'str' }, + { operation: 'keccak' }, + { operation: 'toHex' }, + ], + }, + }, + }, + ], + }); + const conditionExpr = new ConditionExpression(sequentialCondition); + await validateConditionExpression(conditionExpr); + }, 15000); }, ); diff --git a/packages/taco/test/conditions/variable-operation.test.ts b/packages/taco/test/conditions/variable-operation.test.ts index 558c66a7e..b2ecc578e 100644 --- a/packages/taco/test/conditions/variable-operation.test.ts +++ b/packages/taco/test/conditions/variable-operation.test.ts @@ -49,95 +49,3 @@ describe('validates schema', () => { }, ); }); - -describe('new operators', () => { - describe('JSON conversion', () => { - it('toJson converts object to JSON string', () => { - const result = variableOperationSchema.safeParse({ - operation: 'toJson', - }); - expect(result.success).toBe(true); - }); - - it('toJson converts array to JSON string', () => { - const result = variableOperationSchema.safeParse({ - operation: 'toJson', - }); - expect(result.success).toBe(true); - }); - - it('fromJson parses JSON string to object', () => { - const result = variableOperationSchema.safeParse({ - operation: 'fromJson', - }); - expect(result.success).toBe(true); - }); - - it('fromJson parses JSON string to array', () => { - const result = variableOperationSchema.safeParse({ - operation: 'fromJson', - }); - expect(result.success).toBe(true); - }); - }); - - describe('hex conversion', () => { - it('toHex converts bytes to hex string', () => { - const result = variableOperationSchema.safeParse({ - operation: 'toHex', - }); - expect(result.success).toBe(true); - }); - - it('toHex converts string to hex', () => { - const result = variableOperationSchema.safeParse({ - operation: 'toHex', - }); - expect(result.success).toBe(true); - }); - - it('toHex converts integers to hex', () => { - const result = variableOperationSchema.safeParse({ - operation: 'toHex', - }); - expect(result.success).toBe(true); - }); - - it('fromHex converts hex string to bytes', () => { - const result = variableOperationSchema.safeParse({ - operation: 'fromHex', - }); - expect(result.success).toBe(true); - }); - }); - - describe('keccak hashing', () => { - it('keccak hashes strings', () => { - const result = variableOperationSchema.safeParse({ - operation: 'keccak', - }); - expect(result.success).toBe(true); - }); - - it('keccak hashes empty string', () => { - const result = variableOperationSchema.safeParse({ - operation: 'keccak', - }); - expect(result.success).toBe(true); - }); - - it('keccak hashes integers', () => { - const result = variableOperationSchema.safeParse({ - operation: 'keccak', - }); - expect(result.success).toBe(true); - }); - - it('keccak hashes bytes', () => { - const result = variableOperationSchema.safeParse({ - operation: 'keccak', - }); - expect(result.success).toBe(true); - }); - }); -}); From 12bb90ade56fdf9313041787cee2fae73725fc38 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 20 Nov 2025 11:32:16 -0500 Subject: [PATCH 232/303] chore(release): release @nucypher/taco-auth:0.4.0-alpha.5 --- packages/taco-auth/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco-auth/package.json b/packages/taco-auth/package.json index 6f073ae0a..a1aa56aa3 100644 --- a/packages/taco-auth/package.json +++ b/packages/taco-auth/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco-auth", - "version": "0.4.0-alpha.4", + "version": "0.4.0-alpha.5", "keywords": [ "pre", "threshold", From bbc10583b341b656311b6dc47d86d9acfec428b4 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 13 Nov 2025 15:45:43 -0500 Subject: [PATCH 233/303] Update call to (Packed)UserOperation class in `nucypher-core` to provide nonce as a string. Update tests to account for nonce being returned as a string. --- packages/shared/src/types.ts | 8 +++-- packages/shared/test/porter.test.ts | 44 ++++++++++++++-------------- packages/taco/test/taco-sign.test.ts | 5 ++-- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/packages/shared/src/types.ts b/packages/shared/src/types.ts index 8d5ea9f0c..25eef5be0 100644 --- a/packages/shared/src/types.ts +++ b/packages/shared/src/types.ts @@ -41,6 +41,10 @@ function getBigIntValue(value: bigint | number): bigint { return typeof value === 'bigint' ? value : BigInt(value); } +function getUint256String(value: bigint | number): string { + return getBigIntValue(value).toString(); +} + function getUint8ArrayValue(value: `0x${string}` | Uint8Array): Uint8Array { return value instanceof Uint8Array ? value : fromHexString(value); } @@ -50,7 +54,7 @@ export function toCoreUserOperation( ): UserOperation { const userOp = new UserOperation( userOperation.sender, - getBigIntValue(userOperation.nonce), + getUint256String(userOperation.nonce), // nonce as string to support big numbers getUint8ArrayValue(userOperation.callData), getBigIntValue(userOperation.callGasLimit), getBigIntValue(userOperation.verificationGasLimit), @@ -99,7 +103,7 @@ export function toCorePackedUserOperation( ): PackedUserOperation { const packedUserOp = new PackedUserOperation( packedUserOperation.sender, - getBigIntValue(packedUserOperation.nonce), + getUint256String(packedUserOperation.nonce), // nonce as string to support big numbers getUint8ArrayValue(packedUserOperation.initCode), getUint8ArrayValue(packedUserOperation.callData), getUint8ArrayValue(packedUserOperation.accountGasLimits), diff --git a/packages/shared/test/porter.test.ts b/packages/shared/test/porter.test.ts index 046894664..2e43b906b 100644 --- a/packages/shared/test/porter.test.ts +++ b/packages/shared/test/porter.test.ts @@ -3,11 +3,9 @@ import axios, { HttpStatusCode } from 'axios'; import { beforeAll, describe, expect, it, MockInstance, vi } from 'vitest'; import { - PackedUserOperation, PackedUserOperationSignatureRequest, SessionStaticSecret, SignatureResponse, - UserOperation, UserOperationSignatureRequest, } from '@nucypher/nucypher-core'; @@ -19,6 +17,8 @@ import { initialize, PorterClient, toBase64, + toCorePackedUserOperation, + toCoreUserOperation, toHexString, Ursula, } from '../src'; @@ -238,16 +238,16 @@ describe('PorterClient Signing', () => { const createUserOpSignatureRequest = () => new UserOperationSignatureRequest( - new UserOperation( - '0x000000000000000000000000000000000000000a', - BigInt(123), // nonce - fromHexString('0xabc'), // callData - BigInt(456), // callGasLimit - BigInt(789), // verificationGasLimit - BigInt(101112), // preVerificationGasLimit - BigInt(131415), // maxFeePerGas - BigInt(161718), // maxPriorityFeePerGas - ), + toCoreUserOperation({ + sender: '0x000000000000000000000000000000000000000a', + nonce: BigInt(123), + callData: fromHexString('0xabc'), + callGasLimit: BigInt(456), + verificationGasLimit: BigInt(789), + preVerificationGas: BigInt(101112), + maxFeePerGas: BigInt(131415), + maxPriorityFeePerGas: BigInt(161718), + }), 1, // cohort ID BigInt(1), // chain ID '0.8.0', @@ -284,16 +284,16 @@ describe('PorterClient Signing', () => { it('should successfully sign a PackedUserOperation', async () => { const packedUserOperationSignatureRequest = new PackedUserOperationSignatureRequest( - new PackedUserOperation( - '0x000000000000000000000000000000000000000a', - BigInt(123), // nonce - fromHexString('0xabc'), // initCode - fromHexString('0xdef'), // callData - fromHexString('0x01020304'), // accountGasLimits - BigInt(101112), // preVerificationGas - fromHexString('0x05060708'), // gasFees - fromHexString('0x090a0b0c'), // paymasterAndData - ), + toCorePackedUserOperation({ + sender: '0x000000000000000000000000000000000000000a', + nonce: BigInt(123), + initCode: fromHexString('0xabc'), + callData: fromHexString('0xdef'), + accountGasLimits: fromHexString('0x01020304'), + preVerificationGas: BigInt(101112), + gasFees: fromHexString('0x05060708'), + paymasterAndData: fromHexString('0x090a0b0c'), + }), 1, // cohort ID BigInt(1), // chain ID 'mdt', diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index fcce85295..c9a10cf98 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -39,7 +39,8 @@ function checkPackedUserOpEquality( op2: PackedUserOperation, ) { expect(op1.sender).toEqual(op2.sender); - expect(toBigInt(op1.nonce)).toEqual(op2.nonce); + + expect(toBigInt(op1.nonce).toString()).toEqual(`${op2.nonce}`); // nonce as string internally to support big numbers const initCode = op1.initCode instanceof Uint8Array @@ -77,7 +78,7 @@ function checkPackedUserOpEquality( function checkUserOpEquality(op1: UserOperationToSign, op2: UserOperation) { expect(op1.sender).toEqual(op2.sender); - expect(toBigInt(op1.nonce)).toEqual(op2.nonce); + expect(toBigInt(op1.nonce).toString()).toEqual(`${op2.nonce}`); // nonce as string internally to support big numbers const callData = op1.callData instanceof Uint8Array From db2736be26dbeda9be5c4c2cd7413479ace66f08 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 26 Nov 2025 09:56:48 -0500 Subject: [PATCH 234/303] Fix invalid string used in condition lingo. --- packages/taco/integration-test/condition-lingo.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco/integration-test/condition-lingo.test.ts b/packages/taco/integration-test/condition-lingo.test.ts index 814e6b49b..f6a5351c2 100644 --- a/packages/taco/integration-test/condition-lingo.test.ts +++ b/packages/taco/integration-test/condition-lingo.test.ts @@ -243,7 +243,7 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( ...testRpcConditionObj, returnValueTest: { comparator: '==', - value: 'test string', + value: '"test string"', operations: [{ operation: 'toHex' }, { operation: 'fromHex' }], }, }, From de6784d495e47d9f81bc5f5ff3add77d1cc43f81 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 20 Nov 2025 11:33:44 -0500 Subject: [PATCH 235/303] chore(release): release @nucypher/taco:0.7.0-alpha.5 --- packages/taco/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco/package.json b/packages/taco/package.json index 986f27d1f..e7a3653fe 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco", - "version": "0.7.0-alpha.4", + "version": "0.7.0-alpha.5", "keywords": [ "taco", "threshold", From 163b13b0a8ac9d4c449bf9fb240319ff16c004e4 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 5 Jan 2026 16:48:58 +0000 Subject: [PATCH 236/303] =?UTF-8?q?=F0=9F=90=9B=20fix(taco):=20add=20jsonC?= =?UTF-8?q?onditionSchema=20to=20anyConditionSchema?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The json condition type was missing from the anyConditionSchema union, causing validation failures when json conditions were used inside compound or sequential conditions. --- packages/taco/src/conditions/schemas/utils.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/taco/src/conditions/schemas/utils.ts b/packages/taco/src/conditions/schemas/utils.ts index dc72a3374..b58c472cb 100644 --- a/packages/taco/src/conditions/schemas/utils.ts +++ b/packages/taco/src/conditions/schemas/utils.ts @@ -6,6 +6,7 @@ import { contextVariableConditionSchema } from './context-variable'; import { contractConditionSchema } from './contract'; import { ecdsaConditionSchema } from './ecdsa'; import { ifThenElseConditionSchema } from './if-then-else'; +import { jsonConditionSchema } from './json'; import { jsonApiConditionSchema } from './json-api'; import { jsonRpcConditionSchema } from './json-rpc'; import { jwtConditionSchema } from './jwt'; @@ -24,6 +25,7 @@ export const anyConditionSchema: z.ZodSchema = z.lazy(() => contextVariableConditionSchema, contractConditionSchema, ecdsaConditionSchema, + jsonConditionSchema, jsonApiConditionSchema, jsonRpcConditionSchema, jwtConditionSchema, From c2a93d6f86f211b229d60101b7db679f575f01bf Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 26 Nov 2025 09:57:23 -0500 Subject: [PATCH 237/303] Add `fromJson` operation for test completeness. --- packages/taco/integration-test/condition-lingo.test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/taco/integration-test/condition-lingo.test.ts b/packages/taco/integration-test/condition-lingo.test.ts index f6a5351c2..ffb4adead 100644 --- a/packages/taco/integration-test/condition-lingo.test.ts +++ b/packages/taco/integration-test/condition-lingo.test.ts @@ -233,7 +233,11 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( comparator: '==', value: '0x7b226b6579223a2276616c7565222c226e756d626572223a3432ffffffffffffff', - operations: [{ operation: 'toJson' }, { operation: 'toHex' }], + operations: [ + { operation: 'fromJson' }, + { operation: 'toJson' }, + { operation: 'toHex' }, + ], }, }, }, From 4dcc394cee52bcea59f6bfe9c78c0744f6df7f28 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 5 Jan 2026 16:49:03 +0000 Subject: [PATCH 238/303] =?UTF-8?q?=E2=9C=85=20test(taco):=20add=20anyCond?= =?UTF-8?q?itionSchema=20completeness=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a regression test that validates all 14 condition types can be used inside compound conditions. This prevents future omissions from anyConditionSchema by failing fast with a descriptive error message. Also adds testIfThenElseConditionObj to test-utils for completeness. --- .../conditions/any-condition-schema.test.ts | 80 +++++++++++++++++++ packages/taco/test/test-utils.ts | 11 +++ 2 files changed, 91 insertions(+) create mode 100644 packages/taco/test/conditions/any-condition-schema.test.ts diff --git a/packages/taco/test/conditions/any-condition-schema.test.ts b/packages/taco/test/conditions/any-condition-schema.test.ts new file mode 100644 index 000000000..4ee4f8106 --- /dev/null +++ b/packages/taco/test/conditions/any-condition-schema.test.ts @@ -0,0 +1,80 @@ +import { describe, expect, it } from 'vitest'; + +import { + CompoundCondition, + compoundConditionSchema, + CompoundConditionType, +} from '../../src/conditions/compound-condition'; +import { + testCompoundConditionObj, + testContextVariableConditionObj, + testContractConditionObj, + testECDSAConditionObj, + testIfThenElseConditionObj, + testJsonApiConditionObj, + testJsonConditionObj, + testJsonRpcConditionObj, + testJWTConditionObj, + testRpcConditionObj, + testSequentialConditionObj, + testSigningObjectAbiAttributeConditionObj, + testSigningObjectAttributeConditionObj, + testTimeConditionObj, +} from '../test-utils'; + +/** + * This test ensures that all condition types are included in anyConditionSchema. + * If a new condition type is added but not included in anyConditionSchema, + * it will fail validation when used inside compound/sequential conditions. + * + * When adding a new condition type: + * 1. Add a test object in test-utils.ts + * 2. Add it to the test cases below + * 3. Ensure it's imported and added to anyConditionSchema in schemas/utils.ts + */ +describe('anyConditionSchema completeness', () => { + const allConditionTestObjects = [ + { name: 'rpc', obj: testRpcConditionObj }, + { name: 'time', obj: testTimeConditionObj }, + { name: 'contract', obj: testContractConditionObj }, + { name: 'contextVariable', obj: testContextVariableConditionObj }, + { name: 'json', obj: testJsonConditionObj }, + { name: 'jsonApi', obj: testJsonApiConditionObj }, + { name: 'jsonRpc', obj: testJsonRpcConditionObj }, + { name: 'jwt', obj: testJWTConditionObj }, + { name: 'ecdsa', obj: testECDSAConditionObj }, + { + name: 'signingObjectAttribute', + obj: testSigningObjectAttributeConditionObj, + }, + { + name: 'signingObjectAbiAttribute', + obj: testSigningObjectAbiAttributeConditionObj, + }, + { name: 'compound', obj: testCompoundConditionObj }, + { name: 'sequential', obj: testSequentialConditionObj }, + { name: 'ifThenElse', obj: testIfThenElseConditionObj }, + ]; + + it.each(allConditionTestObjects)( + 'validates $name condition inside compound condition', + ({ name, obj }) => { + const compoundWithCondition = { + conditionType: CompoundConditionType, + operator: 'not', + operands: [obj], + }; + + const result = CompoundCondition.validate( + compoundConditionSchema, + compoundWithCondition, + ); + + expect( + result.error, + `${name} condition should be valid inside compound condition. ` + + `If this fails, ensure ${name}ConditionSchema is added to anyConditionSchema in schemas/utils.ts`, + ).toBeUndefined(); + }, + ); +}); diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 37ee90430..88adb2654 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -88,6 +88,10 @@ import { CompoundConditionType, } from '../src/conditions/compound-condition'; import { ConditionExpression } from '../src/conditions/condition-expr'; +import { + IfThenElseConditionProps, + IfThenElseConditionType, +} from '../src/conditions/if-then-else-condition'; import { AddressAllowlistConditionProps } from '../src/conditions/predefined/address-allowlist'; import { ERC721Balance } from '../src/conditions/predefined/erc721'; import { @@ -433,6 +437,13 @@ export const testSequentialConditionObj: SequentialConditionProps = { ], }; +export const testIfThenElseConditionObj: IfThenElseConditionProps = { + conditionType: IfThenElseConditionType, + ifCondition: testRpcConditionObj, + thenCondition: testTimeConditionObj, + elseCondition: testContractConditionObj, +}; + export const testSigningObjectAttributeConditionObj: SigningObjectAttributeConditionProps = { conditionType: SigningObjectAttributeConditionType, From e3864e3732faec159dd8e1b7e57d134169c8432c Mon Sep 17 00:00:00 2001 From: derekpierre Date: Mon, 5 Jan 2026 12:23:28 -0500 Subject: [PATCH 239/303] Add getSigningCoordinatorChild to SigningCoordinatorAgent. --- .../shared/src/contracts/agents/signing-coordinator.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/shared/src/contracts/agents/signing-coordinator.ts b/packages/shared/src/contracts/agents/signing-coordinator.ts index 354874ddf..46a40f991 100644 --- a/packages/shared/src/contracts/agents/signing-coordinator.ts +++ b/packages/shared/src/contracts/agents/signing-coordinator.ts @@ -77,6 +77,15 @@ export class SigningCoordinatorAgent { ); } + public static async getSigningCoordinatorChild( + provider: ethers.providers.Provider, + domain: Domain, + chainId: number, + ): Promise { + const coordinator = await this.connectReadOnly(provider, domain); + return await coordinator.getSigningCoordinatorChild(chainId); + } + private static async connectReadOnly( provider: ethers.providers.Provider, domain: Domain, From 78a60b5ce6da87e3d90c440409d0651dc82a7274 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 5 Jan 2026 20:49:18 +0000 Subject: [PATCH 240/303] fix(taco): exclude sequential varName references from required context params findContextParameters() was incorrectly treating internal sequential condition varName references (like :amountValue) as external context parameters that must be provided by the caller. Now when a sequential condition defines varName: 'amountValue' and later references ':amountValue' in a returnValueTest, it's correctly recognized as an internally-scoped variable rather than an external context parameter. Changes: - Export getAllNestedConditionVariableNames from sequential.ts - Modify findContextParameters() to collect and exclude internal varNames - Add tests for sequential condition varName scoping --- .../taco/src/conditions/context/context.ts | 12 +- .../taco/src/conditions/schemas/sequential.ts | 2 +- packages/taco/test/conditions/context.test.ts | 221 ++++++++++++++++++ 3 files changed, 233 insertions(+), 2 deletions(-) diff --git a/packages/taco/src/conditions/context/context.ts b/packages/taco/src/conditions/context/context.ts index 3ad2514b2..318d9d43c 100644 --- a/packages/taco/src/conditions/context/context.ts +++ b/packages/taco/src/conditions/context/context.ts @@ -20,6 +20,7 @@ import { CONTEXT_PARAM_REGEXP, USER_ADDRESS_PARAMS, } from '../const'; +import { getAllNestedConditionVariableNames } from '../schemas/sequential'; import { SIGNING_CONDITION_OBJECT_CONTEXT_VAR } from '../schemas/signing'; export type CustomContextParam = @@ -210,6 +211,12 @@ export class ConditionContext { } private static findContextParameters(condition: ConditionProps) { + // Collect internally-defined variable names from sequential conditions + // These are scoped within the condition and should not be required as external context + const internalVarNames = new Set( + getAllNestedConditionVariableNames(condition).map((name) => `:${name}`), + ); + // find all the context variables we need const requestedParameters = new Set(); @@ -217,7 +224,10 @@ export class ConditionContext { const properties = Object.keys(condition) as (keyof typeof condition)[]; properties.forEach((prop) => { this.findContextParameter(condition[prop]).forEach((contextVar) => { - if (!AUTOMATICALLY_INJECTED_CONTEXT_PARAMS.includes(contextVar)) { + if ( + !AUTOMATICALLY_INJECTED_CONTEXT_PARAMS.includes(contextVar) && + !internalVarNames.has(contextVar) + ) { requestedParameters.add(contextVar); } }); diff --git a/packages/taco/src/conditions/schemas/sequential.ts b/packages/taco/src/conditions/schemas/sequential.ts index 3bf54e13c..43cc66237 100644 --- a/packages/taco/src/conditions/schemas/sequential.ts +++ b/packages/taco/src/conditions/schemas/sequential.ts @@ -9,7 +9,7 @@ import { IfThenElseConditionType } from './if-then-else'; import { anyConditionSchema } from './utils'; import { variableOperationsArraySchema } from './variable-operation'; -const getAllNestedConditionVariableNames = ( +export const getAllNestedConditionVariableNames = ( condition: ConditionProps, ): string[] => { const conditionVariables: string[] = []; diff --git a/packages/taco/test/conditions/context.test.ts b/packages/taco/test/conditions/context.test.ts index 0e08bf623..76e7f8015 100644 --- a/packages/taco/test/conditions/context.test.ts +++ b/packages/taco/test/conditions/context.test.ts @@ -1438,3 +1438,224 @@ describe('forSigningCohort', () => { getSigningCohortConditionsSpy.mockRestore(); }); }); + +describe('sequential condition varName scoping', () => { + it('excludes internal varName references from required context parameters', () => { + // This sequential condition defines varNames 'rpcValue' and 'timeValue' + // and references ':rpcValue' in a subsequent returnValueTest + // The ':rpcValue' should NOT be treated as an external context parameter + const sequentialCondition = { + conditionType: SequentialConditionType, + conditionVariables: [ + { + varName: 'rpcValue', + condition: testRpcConditionObj, + }, + { + varName: 'timeValue', + condition: { + ...testTimeConditionObj, + returnValueTest: { + comparator: '>', + value: ':rpcValue', // References internal varName + }, + }, + }, + ], + }; + + const condition = ConditionFactory.conditionFromProps(sequentialCondition); + const conditionContext = new ConditionContext(condition); + + // :rpcValue should NOT be in requestedContextParameters since it's internally defined + expect(conditionContext.requestedContextParameters).not.toContain( + ':rpcValue', + ); + expect(conditionContext.requestedContextParameters).not.toContain( + ':timeValue', + ); + }); + + it('correctly identifies external context params while excluding internal varNames', () => { + // This sequential condition has both: + // - Internal varNames: 'rpcValue', 'contractValue' + // - External context params: ':externalMultiplier', ':externalThreshold' + const sequentialCondition = { + conditionType: SequentialConditionType, + conditionVariables: [ + { + varName: 'rpcValue', + condition: testRpcConditionObj, + }, + { + varName: 'contractValue', + condition: { + ...testContractConditionObj, + returnValueTest: { + comparator: '>', + value: ':rpcValue', // Internal reference + }, + }, + }, + { + varName: 'finalValue', + condition: { + ...testTimeConditionObj, + returnValueTest: { + comparator: '>=', + value: ':externalThreshold', // External context param + operations: [ + { operation: '*=', value: ':externalMultiplier' }, // External context param + ], + }, + }, + }, + ], + }; + + const condition = ConditionFactory.conditionFromProps(sequentialCondition); + const conditionContext = new ConditionContext(condition); + + // Internal varNames should NOT be in requestedContextParameters + expect(conditionContext.requestedContextParameters).not.toContain( + ':rpcValue', + ); + expect(conditionContext.requestedContextParameters).not.toContain( + ':contractValue', + ); + expect(conditionContext.requestedContextParameters).not.toContain( + ':finalValue', + ); + + // External context params SHOULD be in requestedContextParameters + expect(conditionContext.requestedContextParameters).toContain( + ':externalThreshold', + ); + expect(conditionContext.requestedContextParameters).toContain( + ':externalMultiplier', + ); + }); + + it('handles nested sequential conditions with varName scoping', () => { + // Nested sequential conditions should have their varNames properly scoped + const nestedSequentialCondition = { + conditionType: SequentialConditionType, + conditionVariables: [ + { + varName: 'outerRpc', + condition: testRpcConditionObj, + }, + { + varName: 'nestedSequential', + condition: { + conditionType: SequentialConditionType, + conditionVariables: [ + { + varName: 'innerRpc', + condition: testRpcConditionObj, + }, + { + varName: 'innerTime', + condition: { + ...testTimeConditionObj, + returnValueTest: { + comparator: '>', + value: ':innerRpc', // References inner varName + }, + }, + }, + ], + }, + }, + { + varName: 'outerFinal', + condition: { + ...testTimeConditionObj, + returnValueTest: { + comparator: '>=', + value: ':outerRpc', // References outer varName + }, + }, + }, + ], + }; + + const condition = ConditionFactory.conditionFromProps( + nestedSequentialCondition, + ); + const conditionContext = new ConditionContext(condition); + + // All internal varNames (outer and inner) should NOT be in requestedContextParameters + expect(conditionContext.requestedContextParameters).not.toContain( + ':outerRpc', + ); + expect(conditionContext.requestedContextParameters).not.toContain( + ':nestedSequential', + ); + expect(conditionContext.requestedContextParameters).not.toContain( + ':innerRpc', + ); + expect(conditionContext.requestedContextParameters).not.toContain( + ':innerTime', + ); + expect(conditionContext.requestedContextParameters).not.toContain( + ':outerFinal', + ); + + // Should have no external context parameters in this case + expect(conditionContext.requestedContextParameters.size).toBe(0); + }); + + it('handles compound conditions containing sequential conditions with varName scoping', () => { + const compoundWithSequential = { + conditionType: CompoundConditionType, + operator: 'or', + operands: [ + { + conditionType: SequentialConditionType, + conditionVariables: [ + { + varName: 'seqVar1', + condition: testRpcConditionObj, + }, + { + varName: 'seqVar2', + condition: { + ...testTimeConditionObj, + returnValueTest: { + comparator: '>', + value: ':seqVar1', // Internal reference + }, + }, + }, + ], + }, + { + ...testContractConditionObj, + returnValueTest: { + comparator: '>=', + value: ':externalParam', // External context param + }, + }, + ], + }; + + const condition = ConditionFactory.conditionFromProps( + compoundWithSequential, + ); + const conditionContext = new ConditionContext(condition); + + // Internal varNames should NOT be in requestedContextParameters + expect(conditionContext.requestedContextParameters).not.toContain( + ':seqVar1', + ); + expect(conditionContext.requestedContextParameters).not.toContain( + ':seqVar2', + ); + + // External context param SHOULD be in requestedContextParameters + expect(conditionContext.requestedContextParameters).toContain( + ':externalParam', + ); + }); +}); From 242e1cc85c75f9c21100dbe1b627a2c138990ba0 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 5 Jan 2026 17:04:16 +0000 Subject: [PATCH 241/303] =?UTF-8?q?=F0=9F=93=9D=20docs(taco):=20regenerate?= =?UTF-8?q?=20condition=20schema=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds JsonCondition to the anyConditionSchema documentation. --- packages/taco/schema-docs/condition-schemas.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index 0cc23c753..8a0b3611e 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -9,6 +9,7 @@ _Union of the following possible types:_ - [ContextVariableCondition](#contextvariablecondition) - [ContractCondition](#contractcondition) - [EcdsaCondition](#ecdsacondition) +- [JsonCondition](#jsoncondition) - [JsonApiCondition](#jsonapicondition) - [JsonRpcCondition](#jsonrpccondition) - [JwtCondition](#jwtcondition) From 5b008b582055d5a9efeff17cc0a889bc75cbb0a7 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 6 Jan 2026 15:43:58 -0500 Subject: [PATCH 242/303] Ensure that SequentCondition condition variables are accounted for properly when finding outstanding context parameters for the user to provide, since condition variable values don't need to be provided by the user but are referenced as context parameters. --- .../taco/src/conditions/context/context.ts | 46 ++++++++++--- packages/taco/test/conditions/context.test.ts | 68 +++++++++++++++++++ 2 files changed, 106 insertions(+), 8 deletions(-) diff --git a/packages/taco/src/conditions/context/context.ts b/packages/taco/src/conditions/context/context.ts index 318d9d43c..d6eca58fa 100644 --- a/packages/taco/src/conditions/context/context.ts +++ b/packages/taco/src/conditions/context/context.ts @@ -22,6 +22,10 @@ import { } from '../const'; import { getAllNestedConditionVariableNames } from '../schemas/sequential'; import { SIGNING_CONDITION_OBJECT_CONTEXT_VAR } from '../schemas/signing'; +import { + SequentialConditionProps, + SequentialConditionType, +} from '../sequential'; export type CustomContextParam = | string @@ -199,10 +203,28 @@ export class ConditionContext { }); } else if (typeof value === 'object') { // dictionary (Record - complex object eg. Condition, ConditionVariable, ReturnValueTest etc.) + + // Collect internally-defined variable names from sequential conditions + // These are scoped within the condition and should not be required as external context + const internalContextVariablesFromConditionVariables = new Set(); + if ( + 'conditionType' in value && + value.conditionType === SequentialConditionType + ) { + getAllNestedConditionVariableNames( + value as SequentialConditionProps, + ).forEach((varName) => { + internalContextVariablesFromConditionVariables.add(`:${varName}`); + }); + } + + // iterate through all entries for (const [, entry] of Object.entries(value)) { const contextVarsForValue = this.findContextParameter(entry); contextVarsForValue.forEach((contextVar) => { - includedContextVars.add(contextVar); + if (!internalContextVariablesFromConditionVariables.has(contextVar)) { + includedContextVars.add(contextVar); + } }); } } @@ -211,22 +233,30 @@ export class ConditionContext { } private static findContextParameters(condition: ConditionProps) { - // Collect internally-defined variable names from sequential conditions - // These are scoped within the condition and should not be required as external context - const internalVarNames = new Set( - getAllNestedConditionVariableNames(condition).map((name) => `:${name}`), - ); - // find all the context variables we need const requestedParameters = new Set(); + // Collect internally-defined variable names from sequential conditions + // These are scoped within the condition and should not be required as external context + const internalContextVariablesFromConditionVariables = new Set(); + if ( + 'conditionType' in condition && + condition.conditionType === SequentialConditionType + ) { + getAllNestedConditionVariableNames( + condition as SequentialConditionProps, + ).forEach((varName) => { + internalContextVariablesFromConditionVariables.add(`:${varName}`); + }); + } + // iterate through all properties in ConditionProps const properties = Object.keys(condition) as (keyof typeof condition)[]; properties.forEach((prop) => { this.findContextParameter(condition[prop]).forEach((contextVar) => { if ( !AUTOMATICALLY_INJECTED_CONTEXT_PARAMS.includes(contextVar) && - !internalVarNames.has(contextVar) + !internalContextVariablesFromConditionVariables.has(contextVar) ) { requestedParameters.add(contextVar); } diff --git a/packages/taco/test/conditions/context.test.ts b/packages/taco/test/conditions/context.test.ts index 76e7f8015..6f4f91152 100644 --- a/packages/taco/test/conditions/context.test.ts +++ b/packages/taco/test/conditions/context.test.ts @@ -1658,4 +1658,72 @@ describe('sequential condition varName scoping', () => { ':externalParam', ); }); + it('handles external context variable within sequential', () => { + const compoundWithSequential = { + conditionType: CompoundConditionType, + operator: 'or', + operands: [ + { + conditionType: SequentialConditionType, + conditionVariables: [ + { + varName: 'seqVar1', + condition: testRpcConditionObj, + }, + { + varName: 'seqVar2', + condition: { + ...testTimeConditionObj, + returnValueTest: { + comparator: '>', + value: ':externalContextVar1', // External context param + }, + }, + }, + { + varName: 'seqVar3', + condition: { + ...testContractConditionObj, + returnValueTest: { + comparator: '<=', + value: ':seqVar1', // Internal reference + }, + }, + }, + ], + }, + { + ...testContractConditionObj, + returnValueTest: { + comparator: '>=', + value: ':externalContextVar2', // External context param + }, + }, + ], + }; + + const condition = ConditionFactory.conditionFromProps( + compoundWithSequential, + ); + const conditionContext = new ConditionContext(condition); + + // Internal varNames should NOT be in requestedContextParameters + expect(conditionContext.requestedContextParameters).not.toContain( + ':seqVar1', + ); + expect(conditionContext.requestedContextParameters).not.toContain( + ':seqVar2', + ); + expect(conditionContext.requestedContextParameters).not.toContain( + ':seqVar3', + ); + + // External context param SHOULD be in requestedContextParameters + expect(conditionContext.requestedContextParameters).toContain( + ':externalContextVar1', + ); + expect(conditionContext.requestedContextParameters).toContain( + ':externalContextVar2', + ); + }); }); From 32f3673d407c28901947b3950d64cf29cf8820ab Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 13 Jan 2026 15:16:03 +0000 Subject: [PATCH 243/303] feat(taco): increase max nested depth from 2 to 4 for multi-condition types Increase the maximum nesting depth allowed for compound, if-then-else, and sequential conditions from 2 to 4 levels. This provides more flexibility for complex condition hierarchies. Update all related tests to validate against the new depth limit. --- .../taco/src/conditions/schemas/compound.ts | 6 +- .../src/conditions/schemas/if-then-else.ts | 18 ++--- .../taco/src/conditions/schemas/sequential.ts | 6 +- .../conditions/compound-condition.test.ts | 42 ++++++++++-- .../conditions/if-then-else-condition.test.ts | 52 +++++++++++--- .../taco/test/conditions/sequential.test.ts | 67 +++++++++++++++++-- 6 files changed, 156 insertions(+), 35 deletions(-) diff --git a/packages/taco/src/conditions/schemas/compound.ts b/packages/taco/src/conditions/schemas/compound.ts index df8dd40ce..1a390c72a 100644 --- a/packages/taco/src/conditions/schemas/compound.ts +++ b/packages/taco/src/conditions/schemas/compound.ts @@ -37,11 +37,11 @@ export const compoundConditionSchema: z.ZodSchema = z.lazy(() => }), ) .refine( - (condition) => maxNestedDepth(2)(condition), + (condition) => maxNestedDepth(4)(condition), { - message: 'Exceeded max nested depth of 2 for multi-condition type', + message: 'Exceeded max nested depth of 4 for multi-condition type', path: ['operands'], - }, // Max nested depth of 2 + }, // Max nested depth of 4 ), ); diff --git a/packages/taco/src/conditions/schemas/if-then-else.ts b/packages/taco/src/conditions/schemas/if-then-else.ts index dc90ee992..725196629 100644 --- a/packages/taco/src/conditions/schemas/if-then-else.ts +++ b/packages/taco/src/conditions/schemas/if-then-else.ts @@ -19,32 +19,32 @@ export const ifThenElseConditionSchema: z.ZodSchema = z.lazy(() => }) .refine( // already at 2nd level since checking member condition - (condition) => maxNestedDepth(2)(condition.ifCondition, 2), + (condition) => maxNestedDepth(4)(condition.ifCondition, 2), { - message: 'Exceeded max nested depth of 2 for multi-condition type', + message: 'Exceeded max nested depth of 4 for multi-condition type', path: ['ifCondition'], - }, // Max nested depth of 2 + }, // Max nested depth of 4 ) .refine( // already at 2nd level since checking member condition - (condition) => maxNestedDepth(2)(condition.thenCondition, 2), + (condition) => maxNestedDepth(4)(condition.thenCondition, 2), { - message: 'Exceeded max nested depth of 2 for multi-condition type', + message: 'Exceeded max nested depth of 4 for multi-condition type', path: ['thenCondition'], - }, // Max nested depth of 2 + }, // Max nested depth of 4 ) .refine( (condition) => { if (typeof condition.elseCondition !== 'boolean') { // already at 2nd level since checking member condition - return maxNestedDepth(2)(condition.elseCondition, 2); + return maxNestedDepth(4)(condition.elseCondition, 2); } return true; }, { - message: 'Exceeded max nested depth of 2 for multi-condition type', + message: 'Exceeded max nested depth of 4 for multi-condition type', path: ['elseCondition'], - }, // Max nested depth of 2 + }, // Max nested depth of 4 ), ); diff --git a/packages/taco/src/conditions/schemas/sequential.ts b/packages/taco/src/conditions/schemas/sequential.ts index ed6b1f9d6..e7cfd5a2e 100644 --- a/packages/taco/src/conditions/schemas/sequential.ts +++ b/packages/taco/src/conditions/schemas/sequential.ts @@ -74,11 +74,11 @@ export const sequentialConditionSchema: z.ZodSchema = baseConditionSchema conditionVariables: z.array(conditionVariableSchema).min(2).max(10), }) .refine( - (condition) => maxNestedDepth(2)(condition), + (condition) => maxNestedDepth(4)(condition), { - message: 'Exceeded max nested depth of 2 for multi-condition type', + message: 'Exceeded max nested depth of 4 for multi-condition type', path: ['conditionVariables'], - }, // Max nested depth of 2 + }, // Max nested depth of 4 ) .refine( (condition) => { diff --git a/packages/taco/test/conditions/compound-condition.test.ts b/packages/taco/test/conditions/compound-condition.test.ts index aae719596..3d0e214cf 100644 --- a/packages/taco/test/conditions/compound-condition.test.ts +++ b/packages/taco/test/conditions/compound-condition.test.ts @@ -204,11 +204,11 @@ describe('validation', () => { }); it('limits max depth of nested compound condition', () => { + // Create 5 levels of nesting to exceed max depth of 4 const result = CompoundCondition.validate(compoundConditionSchema, { operator: 'or', operands: [ testRpcConditionObj, - testContractConditionObj, { conditionType: CompoundConditionType, operator: 'and', @@ -217,7 +217,21 @@ describe('validation', () => { { conditionType: CompoundConditionType, operator: 'or', - operands: [testTimeConditionObj, testRpcConditionObj], + operands: [ + testRpcConditionObj, + { + conditionType: CompoundConditionType, + operator: 'and', + operands: [ + testTimeConditionObj, + { + conditionType: CompoundConditionType, + operator: 'or', + operands: [testTimeConditionObj, testRpcConditionObj], + }, + ], + }, + ], }, ], }, @@ -227,20 +241,34 @@ describe('validation', () => { expect(result.data).toBeUndefined(); expect(result.error?.format()).toMatchObject({ operands: { - _errors: [`Exceeded max nested depth of 2 for multi-condition type`], + _errors: [`Exceeded max nested depth of 4 for multi-condition type`], }, }); }); it('limits max depth of nested sequential condition', () => { + // Create 5 levels of nesting to exceed max depth of 4 const result = CompoundCondition.validate(compoundConditionSchema, { operator: 'or', operands: [ testRpcConditionObj, - testContractConditionObj, { conditionType: CompoundConditionType, - operator: 'not', - operands: [testSequentialConditionObj], + operator: 'and', + operands: [ + testTimeConditionObj, + { + conditionType: CompoundConditionType, + operator: 'or', + operands: [ + testRpcConditionObj, + { + conditionType: CompoundConditionType, + operator: 'not', + operands: [testSequentialConditionObj], + }, + ], + }, + ], }, ], }); @@ -248,7 +276,7 @@ describe('validation', () => { expect(result.data).toBeUndefined(); expect(result.error?.format()).toMatchObject({ operands: { - _errors: ['Exceeded max nested depth of 2 for multi-condition type'], + _errors: ['Exceeded max nested depth of 4 for multi-condition type'], }, }); }); diff --git a/packages/taco/test/conditions/if-then-else-condition.test.ts b/packages/taco/test/conditions/if-then-else-condition.test.ts index 50897ec9f..c2bc5c5e3 100644 --- a/packages/taco/test/conditions/if-then-else-condition.test.ts +++ b/packages/taco/test/conditions/if-then-else-condition.test.ts @@ -115,11 +115,23 @@ describe('validation', () => { ); it('limits max depth of nested if condition', () => { + // Need 5 levels of nesting to exceed max depth of 4 + // ifThenElse(1) -> ifThenElse(2) -> ifThenElse(3) -> ifThenElse(4) -> compound(5) const result = IfThenElseCondition.validate(ifThenElseConditionSchema, { ifCondition: { conditionType: IfThenElseConditionType, - ifCondition: testRpcConditionObj, - thenCondition: testCompoundConditionObj, + ifCondition: { + conditionType: IfThenElseConditionType, + ifCondition: { + conditionType: IfThenElseConditionType, + ifCondition: testRpcConditionObj, + thenCondition: testCompoundConditionObj, + elseCondition: testTimeConditionObj, + }, + thenCondition: testTimeConditionObj, + elseCondition: true, + }, + thenCondition: testTimeConditionObj, elseCondition: testTimeConditionObj, }, thenCondition: testRpcConditionObj, @@ -129,18 +141,30 @@ describe('validation', () => { expect(result.data).toBeUndefined(); expect(result.error?.format()).toMatchObject({ ifCondition: { - _errors: [`Exceeded max nested depth of 2 for multi-condition type`], + _errors: [`Exceeded max nested depth of 4 for multi-condition type`], }, }); }); it('limits max depth of nested then condition', () => { + // Need 5 levels of nesting to exceed max depth of 4 + // ifThenElse(1) -> ifThenElse(2) -> ifThenElse(3) -> ifThenElse(4) -> compound(5) const result = IfThenElseCondition.validate(ifThenElseConditionSchema, { ifCondition: testRpcConditionObj, thenCondition: { conditionType: IfThenElseConditionType, ifCondition: testRpcConditionObj, - thenCondition: testCompoundConditionObj, + thenCondition: { + conditionType: IfThenElseConditionType, + ifCondition: testRpcConditionObj, + thenCondition: { + conditionType: IfThenElseConditionType, + ifCondition: testRpcConditionObj, + thenCondition: testCompoundConditionObj, + elseCondition: true, + }, + elseCondition: true, + }, elseCondition: true, }, elseCondition: testTimeConditionObj, @@ -149,27 +173,39 @@ describe('validation', () => { expect(result.data).toBeUndefined(); expect(result.error?.format()).toMatchObject({ thenCondition: { - _errors: [`Exceeded max nested depth of 2 for multi-condition type`], + _errors: [`Exceeded max nested depth of 4 for multi-condition type`], }, }); }); it('limits max depth of nested else condition', () => { + // Need 5 levels of nesting to exceed max depth of 4 + // ifThenElse(1) -> ifThenElse(2) -> ifThenElse(3) -> ifThenElse(4) -> sequential(5) const result = IfThenElseCondition.validate(ifThenElseConditionSchema, { ifCondition: testRpcConditionObj, thenCondition: testTimeConditionObj, elseCondition: { conditionType: IfThenElseConditionType, ifCondition: testRpcConditionObj, - thenCondition: testSequentialConditionObj, - elseCondition: testTimeConditionObj, + thenCondition: testTimeConditionObj, + elseCondition: { + conditionType: IfThenElseConditionType, + ifCondition: testRpcConditionObj, + thenCondition: testTimeConditionObj, + elseCondition: { + conditionType: IfThenElseConditionType, + ifCondition: testRpcConditionObj, + thenCondition: testSequentialConditionObj, + elseCondition: testTimeConditionObj, + }, + }, }, }); expect(result.error).toBeDefined(); expect(result.data).toBeUndefined(); expect(result.error?.format()).toMatchObject({ elseCondition: { - _errors: [`Exceeded max nested depth of 2 for multi-condition type`], + _errors: [`Exceeded max nested depth of 4 for multi-condition type`], }, }); }); diff --git a/packages/taco/test/conditions/sequential.test.ts b/packages/taco/test/conditions/sequential.test.ts index 602b90e1a..39fde6835 100644 --- a/packages/taco/test/conditions/sequential.test.ts +++ b/packages/taco/test/conditions/sequential.test.ts @@ -264,6 +264,8 @@ describe('validation', () => { }); it('limits max depth of nested compound condition', () => { + // Need 5 levels of nesting to exceed max depth of 4 + // sequential(1) -> compound(2) -> compound(3) -> compound(4) -> compound(5) const result = SequentialCondition.validate(sequentialConditionSchema, { conditionVariables: [ rpcConditionVariable, @@ -277,7 +279,21 @@ describe('validation', () => { { conditionType: CompoundConditionType, operator: 'and', - operands: [testTimeConditionObj, testRpcConditionObj], + operands: [ + { + conditionType: CompoundConditionType, + operator: 'or', + operands: [ + { + conditionType: CompoundConditionType, + operator: 'not', + operands: [testTimeConditionObj], + }, + testRpcConditionObj, + ], + }, + testTimeConditionObj, + ], }, ], }, @@ -288,23 +304,64 @@ describe('validation', () => { expect(result.data).toBeUndefined(); expect(result.error?.format()).toMatchObject({ conditionVariables: { - _errors: [`Exceeded max nested depth of 2 for multi-condition type`], + _errors: [`Exceeded max nested depth of 4 for multi-condition type`], }, }); }); it('limits max depth of nested sequential condition', () => { + // Need 5 levels of nesting to exceed max depth of 4 + // sequential(1) -> sequential(2) -> sequential(3) -> sequential(4) -> sequential(5) const result = SequentialCondition.validate(sequentialConditionSchema, { conditionVariables: [ rpcConditionVariable, contractConditionVariable, { - varName: 'sequentialNested', + varName: 'level2', condition: { conditionType: SequentialConditionType, conditionVariables: [ timeConditionVariable, - nestedSequentialConditionVariable, + { + varName: 'level3', + condition: { + conditionType: SequentialConditionType, + conditionVariables: [ + { + varName: 'level4a', + condition: testRpcConditionObj, + }, + { + varName: 'level4', + condition: { + conditionType: SequentialConditionType, + conditionVariables: [ + { + varName: 'level5a', + condition: testTimeConditionObj, + }, + { + varName: 'level5', + condition: { + conditionType: SequentialConditionType, + conditionVariables: [ + { + varName: 'level6a', + condition: testTimeConditionObj, + }, + { + varName: 'level6b', + condition: testContractConditionObj, + }, + ], + }, + }, + ], + }, + }, + ], + }, + }, ], }, }, @@ -314,7 +371,7 @@ describe('validation', () => { expect(result.data).toBeUndefined(); expect(result.error?.format()).toMatchObject({ conditionVariables: { - _errors: ['Exceeded max nested depth of 2 for multi-condition type'], + _errors: ['Exceeded max nested depth of 4 for multi-condition type'], }, }); }); From 8486f4e190a4e41a7a394b60e9b18c68f159874d Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 6 Jan 2026 15:51:36 -0500 Subject: [PATCH 244/303] Add additional assertions for context variable tests to be extra thorough. --- packages/taco/test/conditions/context.test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/taco/test/conditions/context.test.ts b/packages/taco/test/conditions/context.test.ts index 6f4f91152..41156eb27 100644 --- a/packages/taco/test/conditions/context.test.ts +++ b/packages/taco/test/conditions/context.test.ts @@ -1468,6 +1468,7 @@ describe('sequential condition varName scoping', () => { const conditionContext = new ConditionContext(condition); // :rpcValue should NOT be in requestedContextParameters since it's internally defined + expect(conditionContext.requestedContextParameters.size).toBe(0); expect(conditionContext.requestedContextParameters).not.toContain( ':rpcValue', ); @@ -1528,6 +1529,7 @@ describe('sequential condition varName scoping', () => { ); // External context params SHOULD be in requestedContextParameters + expect(conditionContext.requestedContextParameters.size).toBe(2); expect(conditionContext.requestedContextParameters).toContain( ':externalThreshold', ); @@ -1654,6 +1656,7 @@ describe('sequential condition varName scoping', () => { ); // External context param SHOULD be in requestedContextParameters + expect(conditionContext.requestedContextParameters.size).toBe(1); expect(conditionContext.requestedContextParameters).toContain( ':externalParam', ); @@ -1719,6 +1722,7 @@ describe('sequential condition varName scoping', () => { ); // External context param SHOULD be in requestedContextParameters + expect(conditionContext.requestedContextParameters.size).toBe(2); expect(conditionContext.requestedContextParameters).toContain( ':externalContextVar1', ); From cb4122164e5b073c9521a02ea5b7df3d6b098730 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 5 Jan 2026 19:59:34 +0000 Subject: [PATCH 245/303] chore(release): release @nucypher/shared:0.6.0-alpha.6 --- packages/shared/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/package.json b/packages/shared/package.json index 36d1b2b05..dd9b4e233 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/shared", - "version": "0.6.0-alpha.5", + "version": "0.6.0-alpha.6", "keywords": [ "pre", "taco", From 59786b2d688886ded8436a27cdd4f1acf3d38f2a Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 13 Jan 2026 15:16:27 +0000 Subject: [PATCH 246/303] feat(taco): add exponent operator and increase max sequential conditions to 20 - Add **= (exponent) operator to variable operations for power calculations - Increase max sequential condition variables from 10 to 20 - Add tests for exponent operator with numeric and context parameter values --- .../taco/src/conditions/schemas/sequential.ts | 2 +- .../conditions/schemas/variable-operation.ts | 1 + .../taco/test/conditions/sequential.test.ts | 4 +- .../conditions/variable-operation.test.ts | 38 +++++++++++++++++++ 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/packages/taco/src/conditions/schemas/sequential.ts b/packages/taco/src/conditions/schemas/sequential.ts index e7cfd5a2e..b9c1f932c 100644 --- a/packages/taco/src/conditions/schemas/sequential.ts +++ b/packages/taco/src/conditions/schemas/sequential.ts @@ -71,7 +71,7 @@ export const sequentialConditionSchema: z.ZodSchema = baseConditionSchema conditionType: z .literal(SequentialConditionType) .default(SequentialConditionType), - conditionVariables: z.array(conditionVariableSchema).min(2).max(10), + conditionVariables: z.array(conditionVariableSchema).min(2).max(20), }) .refine( (condition) => maxNestedDepth(4)(condition), diff --git a/packages/taco/src/conditions/schemas/variable-operation.ts b/packages/taco/src/conditions/schemas/variable-operation.ts index 2df358640..092e8aec9 100644 --- a/packages/taco/src/conditions/schemas/variable-operation.ts +++ b/packages/taco/src/conditions/schemas/variable-operation.ts @@ -8,6 +8,7 @@ export const OPERATOR_FUNCTIONS = [ '*=', '/=', '%=', + '**=', 'index', 'round', // operations that don't require 2nd value diff --git a/packages/taco/test/conditions/sequential.test.ts b/packages/taco/test/conditions/sequential.test.ts index 39fde6835..a0ff0f60d 100644 --- a/packages/taco/test/conditions/sequential.test.ts +++ b/packages/taco/test/conditions/sequential.test.ts @@ -112,7 +112,7 @@ describe('validation', () => { }); it('rejects > max number of condition variables', () => { - const tooManyConditionVariables = new Array(11); + const tooManyConditionVariables = new Array(21); for (let i = 0; i < tooManyConditionVariables.length; i++) { tooManyConditionVariables[i] = { varName: `var${i}`, @@ -127,7 +127,7 @@ describe('validation', () => { expect(result.data).toBeUndefined(); expect(result.error?.format()).toMatchObject({ conditionVariables: { - _errors: ['Array must contain at most 10 element(s)'], + _errors: ['Array must contain at most 20 element(s)'], }, }); }); diff --git a/packages/taco/test/conditions/variable-operation.test.ts b/packages/taco/test/conditions/variable-operation.test.ts index b2ecc578e..84358da29 100644 --- a/packages/taco/test/conditions/variable-operation.test.ts +++ b/packages/taco/test/conditions/variable-operation.test.ts @@ -49,3 +49,41 @@ describe('validates schema', () => { }, ); }); + +describe('exponent operator', () => { + it('validates **= operator with numeric value', () => { + const result = variableOperationSchema.safeParse({ + operation: '**=', + value: 18, + }); + expect(result.success).toBe(true); + expect(result.data).toEqual({ + operation: '**=', + value: 18, + }); + }); + + it('validates **= operator with context parameter', () => { + const result = variableOperationSchema.safeParse({ + operation: '**=', + value: ':tokenDecimals', + }); + expect(result.success).toBe(true); + expect(result.data).toEqual({ + operation: '**=', + value: ':tokenDecimals', + }); + }); + + it('rejects **= operator without value', () => { + const result = variableOperationSchema.safeParse({ + operation: '**=', + }); + expect(result.success).toBe(false); + expect(result.error!.format()).toMatchObject({ + value: { + _errors: ['Value must be defined for operation'], + }, + }); + }); +}); From f32a525466b1ccdf6e0049ed1e4f004be97a7e91 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 7 Jan 2026 08:23:04 -0500 Subject: [PATCH 247/303] Don't do depth-first search for all condition variable names; instead go level-by-level so that condition variables are appropriately scoped when looking for context variables that need to be provided by the user. --- .../taco/src/conditions/context/context.ts | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/packages/taco/src/conditions/context/context.ts b/packages/taco/src/conditions/context/context.ts index d6eca58fa..d9c14540e 100644 --- a/packages/taco/src/conditions/context/context.ts +++ b/packages/taco/src/conditions/context/context.ts @@ -20,7 +20,7 @@ import { CONTEXT_PARAM_REGEXP, USER_ADDRESS_PARAMS, } from '../const'; -import { getAllNestedConditionVariableNames } from '../schemas/sequential'; +import { ConditionVariableProps } from '../schemas/sequential'; import { SIGNING_CONDITION_OBJECT_CONTEXT_VAR } from '../schemas/signing'; import { SequentialConditionProps, @@ -211,11 +211,13 @@ export class ConditionContext { 'conditionType' in value && value.conditionType === SequentialConditionType ) { - getAllNestedConditionVariableNames( - value as SequentialConditionProps, - ).forEach((varName) => { - internalContextVariablesFromConditionVariables.add(`:${varName}`); - }); + (value as SequentialConditionProps).conditionVariables.forEach( + (variable: ConditionVariableProps) => { + internalContextVariablesFromConditionVariables.add( + `:${variable.varName}`, + ); + }, + ); } // iterate through all entries @@ -243,11 +245,13 @@ export class ConditionContext { 'conditionType' in condition && condition.conditionType === SequentialConditionType ) { - getAllNestedConditionVariableNames( - condition as SequentialConditionProps, - ).forEach((varName) => { - internalContextVariablesFromConditionVariables.add(`:${varName}`); - }); + (condition as SequentialConditionProps).conditionVariables.forEach( + (variable: ConditionVariableProps) => { + internalContextVariablesFromConditionVariables.add( + `:${variable.varName}`, + ); + }, + ); } // iterate through all properties in ConditionProps From ae85e8d999f0e8140db6ee5ac04104037b009092 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 5 Jan 2026 19:59:41 +0000 Subject: [PATCH 248/303] chore(release): release @nucypher/taco-auth:0.4.0-alpha.6 --- packages/taco-auth/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco-auth/package.json b/packages/taco-auth/package.json index a1aa56aa3..3bae78e34 100644 --- a/packages/taco-auth/package.json +++ b/packages/taco-auth/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco-auth", - "version": "0.4.0-alpha.5", + "version": "0.4.0-alpha.6", "keywords": [ "pre", "threshold", From 2ec28005349f2f75c127e2e3d1b45907b5de30fa Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 14 Jan 2026 16:16:31 +0000 Subject: [PATCH 249/303] feat(taco): replace **= operator with pow using array syntax - Change operator from '**=' to 'pow' in OPERATOR_FUNCTIONS - Update pow operator to accept [base, exponent] array format - Update tests to reflect new pow operator syntax with array values - Aligns with nucypher backend API changes This change maintains backward compatibility by design - the operator name and signature change together, requiring explicit migration. --- .../conditions/schemas/variable-operation.ts | 2 +- .../conditions/variable-operation.test.ts | 26 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/taco/src/conditions/schemas/variable-operation.ts b/packages/taco/src/conditions/schemas/variable-operation.ts index 092e8aec9..dace4e7a0 100644 --- a/packages/taco/src/conditions/schemas/variable-operation.ts +++ b/packages/taco/src/conditions/schemas/variable-operation.ts @@ -8,7 +8,7 @@ export const OPERATOR_FUNCTIONS = [ '*=', '/=', '%=', - '**=', + 'pow', 'index', 'round', // operations that don't require 2nd value diff --git a/packages/taco/test/conditions/variable-operation.test.ts b/packages/taco/test/conditions/variable-operation.test.ts index 84358da29..f68b5c8ec 100644 --- a/packages/taco/test/conditions/variable-operation.test.ts +++ b/packages/taco/test/conditions/variable-operation.test.ts @@ -50,34 +50,34 @@ describe('validates schema', () => { ); }); -describe('exponent operator', () => { - it('validates **= operator with numeric value', () => { +describe('pow operator', () => { + it('validates pow operator with array value', () => { const result = variableOperationSchema.safeParse({ - operation: '**=', - value: 18, + operation: 'pow', + value: [10, 18], }); expect(result.success).toBe(true); expect(result.data).toEqual({ - operation: '**=', - value: 18, + operation: 'pow', + value: [10, 18], }); }); - it('validates **= operator with context parameter', () => { + it('validates pow operator with context parameter in array', () => { const result = variableOperationSchema.safeParse({ - operation: '**=', - value: ':tokenDecimals', + operation: 'pow', + value: [10, ':tokenDecimals'], }); expect(result.success).toBe(true); expect(result.data).toEqual({ - operation: '**=', - value: ':tokenDecimals', + operation: 'pow', + value: [10, ':tokenDecimals'], }); }); - it('rejects **= operator without value', () => { + it('rejects pow operator without value', () => { const result = variableOperationSchema.safeParse({ - operation: '**=', + operation: 'pow', }); expect(result.success).toBe(false); expect(result.error!.format()).toMatchObject({ From d45f936415d87fb1d9cf009e5b80f100d4c7172b Mon Sep 17 00:00:00 2001 From: derekpierre Date: Wed, 7 Jan 2026 08:26:14 -0500 Subject: [PATCH 250/303] Update max number of conditions for sequential condition to 10 which was already done in `nucypher` via PR 3662. Update test. --- packages/taco/src/conditions/schemas/sequential.ts | 2 +- packages/taco/test/conditions/sequential.test.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/taco/src/conditions/schemas/sequential.ts b/packages/taco/src/conditions/schemas/sequential.ts index 43cc66237..ed6b1f9d6 100644 --- a/packages/taco/src/conditions/schemas/sequential.ts +++ b/packages/taco/src/conditions/schemas/sequential.ts @@ -71,7 +71,7 @@ export const sequentialConditionSchema: z.ZodSchema = baseConditionSchema conditionType: z .literal(SequentialConditionType) .default(SequentialConditionType), - conditionVariables: z.array(conditionVariableSchema).min(2).max(5), + conditionVariables: z.array(conditionVariableSchema).min(2).max(10), }) .refine( (condition) => maxNestedDepth(2)(condition), diff --git a/packages/taco/test/conditions/sequential.test.ts b/packages/taco/test/conditions/sequential.test.ts index 8336a3b2d..602b90e1a 100644 --- a/packages/taco/test/conditions/sequential.test.ts +++ b/packages/taco/test/conditions/sequential.test.ts @@ -112,7 +112,7 @@ describe('validation', () => { }); it('rejects > max number of condition variables', () => { - const tooManyConditionVariables = new Array(6); + const tooManyConditionVariables = new Array(11); for (let i = 0; i < tooManyConditionVariables.length; i++) { tooManyConditionVariables[i] = { varName: `var${i}`, @@ -127,7 +127,7 @@ describe('validation', () => { expect(result.data).toBeUndefined(); expect(result.error?.format()).toMatchObject({ conditionVariables: { - _errors: ['Array must contain at most 5 element(s)'], + _errors: ['Array must contain at most 10 element(s)'], }, }); }); From a60aa04c6503dfd8c94872078388b5d0afafa8a3 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 5 Jan 2026 19:59:45 +0000 Subject: [PATCH 251/303] chore(release): release @nucypher/taco:0.7.0-alpha.6 --- packages/taco/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco/package.json b/packages/taco/package.json index e7a3653fe..4c93460dc 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco", - "version": "0.7.0-alpha.5", + "version": "0.7.0-alpha.6", "keywords": [ "taco", "threshold", From 6fdeaf08c00059e4a327efd34819ec5f836ceec8 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 15 Jan 2026 15:22:52 +0000 Subject: [PATCH 252/303] feat(taco): rename pow operator to *pow= for multiply-then-power semantics - Rename operator from 'pow' to '*pow=' in OPERATOR_FUNCTIONS - Update test suite to use '*pow=' operator name - Operator now computes: initial_value * (base ** exponent) - Aligns with nucypher backend API for token decimal conversions --- .../conditions/schemas/variable-operation.ts | 2 +- .../test/conditions/variable-operation.test.ts | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/taco/src/conditions/schemas/variable-operation.ts b/packages/taco/src/conditions/schemas/variable-operation.ts index dace4e7a0..c702fd150 100644 --- a/packages/taco/src/conditions/schemas/variable-operation.ts +++ b/packages/taco/src/conditions/schemas/variable-operation.ts @@ -8,7 +8,7 @@ export const OPERATOR_FUNCTIONS = [ '*=', '/=', '%=', - 'pow', + '*pow=', 'index', 'round', // operations that don't require 2nd value diff --git a/packages/taco/test/conditions/variable-operation.test.ts b/packages/taco/test/conditions/variable-operation.test.ts index f68b5c8ec..6ef36b06f 100644 --- a/packages/taco/test/conditions/variable-operation.test.ts +++ b/packages/taco/test/conditions/variable-operation.test.ts @@ -50,34 +50,34 @@ describe('validates schema', () => { ); }); -describe('pow operator', () => { - it('validates pow operator with array value', () => { +describe('*pow= operator', () => { + it('validates *pow= operator with array value', () => { const result = variableOperationSchema.safeParse({ - operation: 'pow', + operation: '*pow=', value: [10, 18], }); expect(result.success).toBe(true); expect(result.data).toEqual({ - operation: 'pow', + operation: '*pow=', value: [10, 18], }); }); - it('validates pow operator with context parameter in array', () => { + it('validates *pow= operator with context parameter in array', () => { const result = variableOperationSchema.safeParse({ - operation: 'pow', + operation: '*pow=', value: [10, ':tokenDecimals'], }); expect(result.success).toBe(true); expect(result.data).toEqual({ - operation: 'pow', + operation: '*pow=', value: [10, ':tokenDecimals'], }); }); - it('rejects pow operator without value', () => { + it('rejects *pow= operator without value', () => { const result = variableOperationSchema.safeParse({ - operation: 'pow', + operation: '*pow=', }); expect(result.success).toBe(false); expect(result.error!.format()).toMatchObject({ From e6531794053c61c8c1e1af28da6c9ce66b1ce130 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 19 Jan 2026 11:22:03 +0000 Subject: [PATCH 253/303] refactor(taco): replace *pow= with toTokenBaseUnits operator Replace the generic *pow= operator with a specialized toTokenBaseUnits operator that takes decimals as a single value instead of [base, exponent] array. This aligns with the nucypher backend change that returns int instead of float to avoid precision loss for high-precision token decimal conversions. --- .../conditions/schemas/variable-operation.ts | 2 +- .../conditions/variable-operation.test.ts | 26 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/taco/src/conditions/schemas/variable-operation.ts b/packages/taco/src/conditions/schemas/variable-operation.ts index c702fd150..722a8eac3 100644 --- a/packages/taco/src/conditions/schemas/variable-operation.ts +++ b/packages/taco/src/conditions/schemas/variable-operation.ts @@ -8,7 +8,7 @@ export const OPERATOR_FUNCTIONS = [ '*=', '/=', '%=', - '*pow=', + 'toTokenBaseUnits', 'index', 'round', // operations that don't require 2nd value diff --git a/packages/taco/test/conditions/variable-operation.test.ts b/packages/taco/test/conditions/variable-operation.test.ts index 6ef36b06f..3dd38a070 100644 --- a/packages/taco/test/conditions/variable-operation.test.ts +++ b/packages/taco/test/conditions/variable-operation.test.ts @@ -50,34 +50,34 @@ describe('validates schema', () => { ); }); -describe('*pow= operator', () => { - it('validates *pow= operator with array value', () => { +describe('toTokenBaseUnits operator', () => { + it('validates toTokenBaseUnits operator with decimals value', () => { const result = variableOperationSchema.safeParse({ - operation: '*pow=', - value: [10, 18], + operation: 'toTokenBaseUnits', + value: 18, }); expect(result.success).toBe(true); expect(result.data).toEqual({ - operation: '*pow=', - value: [10, 18], + operation: 'toTokenBaseUnits', + value: 18, }); }); - it('validates *pow= operator with context parameter in array', () => { + it('validates toTokenBaseUnits operator with context parameter', () => { const result = variableOperationSchema.safeParse({ - operation: '*pow=', - value: [10, ':tokenDecimals'], + operation: 'toTokenBaseUnits', + value: ':tokenDecimals', }); expect(result.success).toBe(true); expect(result.data).toEqual({ - operation: '*pow=', - value: [10, ':tokenDecimals'], + operation: 'toTokenBaseUnits', + value: ':tokenDecimals', }); }); - it('rejects *pow= operator without value', () => { + it('rejects toTokenBaseUnits operator without value', () => { const result = variableOperationSchema.safeParse({ - operation: '*pow=', + operation: 'toTokenBaseUnits', }); expect(result.success).toBe(false); expect(result.error!.format()).toMatchObject({ From 7fefe61d6bc424907c79d6ca7ba003d6ae3b1e36 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 7 Jan 2026 15:03:59 +0000 Subject: [PATCH 254/303] chore(release): release @nucypher/shared:0.6.0-alpha.8 --- packages/shared/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/package.json b/packages/shared/package.json index dd9b4e233..0900fdb3a 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/shared", - "version": "0.6.0-alpha.6", + "version": "0.6.0-alpha.8", "keywords": [ "pre", "taco", From b51e5e2d7dca26b825da9d76bd765a1cda6c231e Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 19 Jan 2026 16:26:46 +0000 Subject: [PATCH 255/303] test(taco): update integration test comments for new condition limits Update comments to reflect current limits: - max 5 operands in compound condition - max 20 condition variables in sequential condition - max 4 nested levels (previously 2) Also increase ECDSA test chunkSize from 3 to 5. --- .../taco/integration-test/condition-lingo.test.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/taco/integration-test/condition-lingo.test.ts b/packages/taco/integration-test/condition-lingo.test.ts index ffb4adead..165c36f75 100644 --- a/packages/taco/integration-test/condition-lingo.test.ts +++ b/packages/taco/integration-test/condition-lingo.test.ts @@ -65,8 +65,9 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( () => { test('validate condition lingo with lynx node to confirm consistency', async () => { // Note: there are limits to conditions - // - max 5 operands in a multi-condition (compound, sequential) - // - max 2 nested levels of multi-conditions (compound, sequential, if-then-else) + // - max 5 operands in a compound condition + // - max 20 condition variables in a sequential condition + // - max 4 nested levels of multi-conditions (compound, sequential, if-then-else) const overallCondition = new SequentialCondition({ conditionVariables: [ { @@ -143,11 +144,9 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( '975fda96fa12226a378f52a423e2d12d4fed717162ec7e5838169ed57e3357f2410dce2ce1b6bce3bb46ee97d90e542d9895c7d5b0224da05209eaaf0e484acd', }; - // Value used for chunkSize is to ensure: - // 1. we don't exceed the max 5 operands in a multi-condition - // 2. we adhere to the fact that "and" compound conditions must have at least 2 operands - // 3. SUPPORTED_ECDSA_CURVES.length is currently 6, so we can split it into chunks of 3 - const chunkSize = 3; + // chunkSize ensures we don't exceed max 5 operands in a compound condition + // and that "and" compound conditions have at least 2 operands + const chunkSize = 5; for (let i = 0; i < SUPPORTED_ECDSA_CURVES.length; i += chunkSize) { const chunk = SUPPORTED_ECDSA_CURVES.slice(i, i + chunkSize); const operands: ECDSAConditionProps[] = chunk.map((curve) => ({ From e6c06488bd48569de2b256dc362d430ffe46f0f0 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 7 Jan 2026 15:04:05 +0000 Subject: [PATCH 256/303] chore(release): release @nucypher/taco-auth:0.4.0-alpha.8 --- packages/taco-auth/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco-auth/package.json b/packages/taco-auth/package.json index 3bae78e34..8c93e9759 100644 --- a/packages/taco-auth/package.json +++ b/packages/taco-auth/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco-auth", - "version": "0.4.0-alpha.6", + "version": "0.4.0-alpha.8", "keywords": [ "pre", "threshold", From 664713ac7cbe3d8b7622df5c91c664a5266d2a81 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Mon, 19 Jan 2026 16:26:49 +0000 Subject: [PATCH 257/303] docs(taco): regenerate condition schema docs Updates reflect toTokenBaseUnits operator and increased sequential condition limit from 5 to 20. --- .../integration-test/condition-lingo.test.ts | 8 +++++--- packages/taco/schema-docs/condition-schemas.md | 16 ++++++++-------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/taco/integration-test/condition-lingo.test.ts b/packages/taco/integration-test/condition-lingo.test.ts index 165c36f75..ee06c6be3 100644 --- a/packages/taco/integration-test/condition-lingo.test.ts +++ b/packages/taco/integration-test/condition-lingo.test.ts @@ -144,9 +144,11 @@ describe.skipIf(!process.env.RUNNING_IN_CI)( '975fda96fa12226a378f52a423e2d12d4fed717162ec7e5838169ed57e3357f2410dce2ce1b6bce3bb46ee97d90e542d9895c7d5b0224da05209eaaf0e484acd', }; - // chunkSize ensures we don't exceed max 5 operands in a compound condition - // and that "and" compound conditions have at least 2 operands - const chunkSize = 5; + // Value used for chunkSize is to ensure: + // 1. we don't exceed the max 5 operands in a compound condition + // 2. we adhere to the fact that "and" compound conditions must have at least 2 operands + // 3. SUPPORTED_ECDSA_CURVES.length is currently 6, so we can split it into chunks of 3 + const chunkSize = 3; for (let i = 0; i < SUPPORTED_ECDSA_CURVES.length; i += chunkSize) { const chunk = SUPPORTED_ECDSA_CURVES.slice(i, i + chunkSize); const operands: ECDSAConditionProps[] = chunk.map((curve) => ({ diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index 8a0b3611e..61510b805 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -306,10 +306,10 @@ _(\*) Required._ _Object containing the following properties:_ -| Property | Type | Default | -| :---------------------------- | :---------------------------------------------------------------------------------- | :------------- | -| `conditionType` | `'sequential'` | `'sequential'` | -| **`conditionVariables`** (\*) | _Array of at least 2 and at most 5 [ConditionVariable](#conditionvariable) items_ | | +| Property | Type | Default | +| :---------------------------- | :----------------------------------------------------------------------------------- | :------------- | +| `conditionType` | `'sequential'` | `'sequential'` | +| **`conditionVariables`** (\*) | _Array of at least 2 and at most 20 [ConditionVariable](#conditionvariable) items_ | | _(\*) Required._ @@ -383,10 +383,10 @@ An operation that can be performed on an obtained result. _Object containing the following properties:_ -| Property | Type | -| :------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **`operation`** (\*) | `'+=' \| '-=' \| '*=' \| '/=' \| '%=' \| 'index' \| 'round' \| 'abs' \| 'avg' \| 'ceil' \| 'ethToWei' \| 'floor' \| 'len' \| 'max' \| 'min' \| 'sum' \| 'weiToEth' \| 'bool' \| 'float' \| 'int' \| ...` | -| `value` | [ParamOrContextParam](#paramorcontextparam) | +| Property | Type | +| :------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **`operation`** (\*) | `'+=' \| '-=' \| '*=' \| '/=' \| '%=' \| 'toTokenBaseUnits' \| 'index' \| 'round' \| 'abs' \| 'avg' \| 'ceil' \| 'ethToWei' \| 'floor' \| 'len' \| 'max' \| 'min' \| 'sum' \| 'weiToEth' \| 'bool' \| 'float' \| ...` | +| `value` | [ParamOrContextParam](#paramorcontextparam) | _(\*) Required._ From 90bc8b21031284a56c8002b806c61542490a2dd6 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 7 Jan 2026 15:04:09 +0000 Subject: [PATCH 258/303] chore(release): release @nucypher/taco:0.7.0-alpha.8 --- packages/taco/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco/package.json b/packages/taco/package.json index 4c93460dc..5ec8dbc1a 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco", - "version": "0.7.0-alpha.6", + "version": "0.7.0-alpha.8", "keywords": [ "taco", "threshold", From 495f1d1bfa010d88de42518b9ba010913a29260e Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 28 Jan 2026 10:34:11 +0000 Subject: [PATCH 259/303] chore(shared): update @nucypher/nucypher-contracts to 0.26.0-alpha.3 --- packages/shared/package.json | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/shared/package.json b/packages/shared/package.json index 0900fdb3a..1cbb78d2b 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -42,7 +42,7 @@ "dependencies": { "@ethersproject/abi": "^5.8.0", "@ethersproject/providers": "^5.8.0", - "@nucypher/nucypher-contracts": "^0.26.0-alpha.2", + "@nucypher/nucypher-contracts": "^0.26.0-alpha.3", "@nucypher/nucypher-core": "^0.15.1-dev.3", "axios": "^1.8.4", "deep-equal": "^2.2.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 87ddf9990..cc9bcfd09 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -513,8 +513,8 @@ importers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@nucypher/nucypher-contracts': - specifier: ^0.26.0-alpha.2 - version: 0.26.0-alpha.2 + specifier: ^0.26.0-alpha.3 + version: 0.26.0-alpha.3 '@nucypher/nucypher-core': specifier: ^0.15.1-dev.3 version: 0.15.1-dev.3 @@ -2704,8 +2704,8 @@ packages: '@nucypher/nucypher-contracts@0.25.0': resolution: {integrity: sha512-4fRPKY6RzkXY1Zv2O0auJZsvP6z7tuj+Fsy83yJvADqFwRuIJfSlwgSgLwISX6q838SRG/Ve2i+sMLZRaVJfYw==} - '@nucypher/nucypher-contracts@0.26.0-alpha.2': - resolution: {integrity: sha512-Vo5AeJ+7iqj1PNpIKfgajkVK7BGNETre8fxDtKyYSaW+9SNXh5ext7eacdvDRdQg/EDmhk0IItch1wXVyVydtQ==} + '@nucypher/nucypher-contracts@0.26.0-alpha.3': + resolution: {integrity: sha512-BQSDTl+E77JHS0ck79vyGQTPjTFZieWaKY1nSAghQGTS3drOU21loqe9v6221zlycU6T1cZ4c3ffGXW3qc37ng==} '@nucypher/nucypher-core@0.15.1-dev.3': resolution: {integrity: sha512-0MJ8XvH2X5OyEx+f2i9A2iA+KosHzxZbOt8V3Ye6ZDlMC5N4aeDOEJ02ftwnc0C0NO0CPqTuLlYGbrreW57K+w==} @@ -12478,7 +12478,7 @@ snapshots: '@nucypher/nucypher-contracts@0.25.0': {} - '@nucypher/nucypher-contracts@0.26.0-alpha.2': {} + '@nucypher/nucypher-contracts@0.26.0-alpha.3': {} '@nucypher/nucypher-core@0.15.1-dev.3': {} From 437cd86adcaca3c2f09fa14bf1e33303230ee4c7 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 5 Feb 2026 16:08:39 +0000 Subject: [PATCH 260/303] feat(taco): Add create2 operation for local address computation Add a new create2 operation to the variable operation system that computes Ethereum CREATE2 addresses locally, eliminating RPC calls to factory contracts for counterfactual address resolution. The operation takes an object value with deployerAddress and bytecodeHash fields, both supporting context variable resolution. This enables full Account Abstraction address derivation pipelines. Implements taco-web equivalent of nucypher/nucypher#3703. --- .../taco/src/conditions/schemas/context.ts | 11 ++ .../conditions/schemas/variable-operation.ts | 17 ++- .../test/conditions/return-value-test.test.ts | 4 +- .../taco/test/conditions/sequential.test.ts | 7 +- .../conditions/variable-operation.test.ts | 102 +++++++++++++++++- packages/taco/test/test-utils.ts | 19 ++++ 6 files changed, 151 insertions(+), 9 deletions(-) diff --git a/packages/taco/src/conditions/schemas/context.ts b/packages/taco/src/conditions/schemas/context.ts index d4925e8bb..13f1a6382 100644 --- a/packages/taco/src/conditions/schemas/context.ts +++ b/packages/taco/src/conditions/schemas/context.ts @@ -25,6 +25,16 @@ const paramSchema = z.union([ z.bigint(), ]); +// Schema for CREATE2 operation value - supports both literal addresses/hashes and context parameters +export const create2ValueSchema = z + .object({ + deployerAddress: z.union([plainStringSchema, contextParamSchema]), + bytecodeHash: z.union([plainStringSchema, contextParamSchema]), + }) + .describe( + 'Value for create2 operation containing deployerAddress and bytecodeHash for computing CREATE2 addresses locally.', + ); + const blockchainParamSchema = z .union([ plainStringSchema, @@ -40,6 +50,7 @@ export const paramOrContextParamSchema: z.ZodSchema = z.union([ paramSchema, contextParamSchema, z.lazy(() => z.array(paramOrContextParamSchema)), + create2ValueSchema, ]); export const blockchainParamOrContextParamSchema: z.ZodSchema = z.union([ diff --git a/packages/taco/src/conditions/schemas/variable-operation.ts b/packages/taco/src/conditions/schemas/variable-operation.ts index 722a8eac3..61ee59f35 100644 --- a/packages/taco/src/conditions/schemas/variable-operation.ts +++ b/packages/taco/src/conditions/schemas/variable-operation.ts @@ -1,6 +1,6 @@ import { z } from 'zod'; -import { paramOrContextParamSchema } from './context'; +import { create2ValueSchema, paramOrContextParamSchema } from './context'; export const OPERATOR_FUNCTIONS = [ '+=', @@ -35,6 +35,8 @@ export const OPERATOR_FUNCTIONS = [ 'toHex', // hashing 'keccak', + // address computation + 'create2', ] as const; export const UNARY_OPERATOR_FUNCTIONS = [ @@ -98,6 +100,19 @@ export const variableOperationSchema = z path: ['value'], }, ) + .refine( + (data) => { + if (data.operation === 'create2') { + return create2ValueSchema.safeParse(data.value).success; + } + return true; + }, + { + message: + 'create2 operation requires an object with deployerAddress and bytecodeHash', + path: ['value'], + }, + ) .describe('An operation that can be performed on an obtained result.'); export const MAX_VARIABLE_OPERATIONS = 5; diff --git a/packages/taco/test/conditions/return-value-test.test.ts b/packages/taco/test/conditions/return-value-test.test.ts index b08f10bf7..b0fd39942 100644 --- a/packages/taco/test/conditions/return-value-test.test.ts +++ b/packages/taco/test/conditions/return-value-test.test.ts @@ -3,12 +3,12 @@ import { describe, expect, it } from 'vitest'; import { MAX_VARIABLE_OPERATIONS, OPERATOR_FUNCTIONS, - UNARY_OPERATOR_FUNCTIONS, } from '../../src/conditions/schemas/variable-operation'; import { blockchainReturnValueTestSchema, returnValueTestSchema, } from '../../src/conditions/shared'; +import { getTestValueForOperation } from '../test-utils'; [blockchainReturnValueTestSchema, returnValueTestSchema].forEach((schema) => { describe('validates schema', () => { @@ -76,7 +76,7 @@ import { operations: [ { operation: operation, - value: UNARY_OPERATOR_FUNCTIONS.includes(operation) ? undefined : 5, + value: getTestValueForOperation(operation), }, ], }); diff --git a/packages/taco/test/conditions/sequential.test.ts b/packages/taco/test/conditions/sequential.test.ts index a0ff0f60d..fe3f75601 100644 --- a/packages/taco/test/conditions/sequential.test.ts +++ b/packages/taco/test/conditions/sequential.test.ts @@ -6,7 +6,6 @@ import { IfThenElseConditionType } from '../../src/conditions/if-then-else-condi import { MAX_VARIABLE_OPERATIONS, OPERATOR_FUNCTIONS, - UNARY_OPERATOR_FUNCTIONS, } from '../../src/conditions/schemas/variable-operation'; import { ConditionVariableProps, @@ -16,6 +15,7 @@ import { SequentialConditionType, } from '../../src/conditions/sequential'; import { + getTestValueForOperation, testCompoundConditionObj, testContractConditionObj, testJsonApiConditionObj, @@ -449,6 +449,7 @@ describe('validation', () => { }); expect(condition.value.conditionType).toEqual(SequentialConditionType); }); + it.each(OPERATOR_FUNCTIONS)('allows valid operations', (operation) => { const conditionObj = { conditionType: SequentialConditionType, @@ -459,9 +460,7 @@ describe('validation', () => { operations: [ { operation: operation, - value: UNARY_OPERATOR_FUNCTIONS.includes(operation) - ? undefined - : 5, + value: getTestValueForOperation(operation), }, ], }, diff --git a/packages/taco/test/conditions/variable-operation.test.ts b/packages/taco/test/conditions/variable-operation.test.ts index 3dd38a070..9c209459c 100644 --- a/packages/taco/test/conditions/variable-operation.test.ts +++ b/packages/taco/test/conditions/variable-operation.test.ts @@ -5,12 +5,16 @@ import { UNARY_OPERATOR_FUNCTIONS, variableOperationSchema, } from '../../src/conditions/schemas/variable-operation'; +import { getTestValueForOperation } from '../test-utils'; + +// Operations that require a specific value type (not a simple primitive) +const OBJECT_VALUE_OPERATIONS = ['create2']; describe('validates schema', () => { it.each(OPERATOR_FUNCTIONS)('allows valid operation', (operation) => { const result = variableOperationSchema.safeParse({ operation: operation, - value: UNARY_OPERATOR_FUNCTIONS.includes(operation) ? undefined : 5, + value: getTestValueForOperation(operation), }); expect(result.success).toBe(true); expect(result.error).toBeUndefined(); @@ -32,7 +36,11 @@ describe('validates schema', () => { ); it.each( - OPERATOR_FUNCTIONS.filter((op) => !UNARY_OPERATOR_FUNCTIONS.includes(op)), + OPERATOR_FUNCTIONS.filter( + (op) => + !UNARY_OPERATOR_FUNCTIONS.includes(op) && + !OBJECT_VALUE_OPERATIONS.includes(op), + ), )( 'disallows operations when value is not provided for operation that requires a value', (operation) => { @@ -87,3 +95,93 @@ describe('toTokenBaseUnits operator', () => { }); }); }); + +describe('create2 operator', () => { + it('validates create2 operator with deployerAddress and bytecodeHash', () => { + const result = variableOperationSchema.safeParse({ + operation: 'create2', + value: { + deployerAddress: '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f', + bytecodeHash: + '0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f', + }, + }); + expect(result.success).toBe(true); + expect(result.data).toEqual({ + operation: 'create2', + value: { + deployerAddress: '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f', + bytecodeHash: + '0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f', + }, + }); + }); + + it('validates create2 operator with context parameters', () => { + const result = variableOperationSchema.safeParse({ + operation: 'create2', + value: { + deployerAddress: ':factoryAddress', + bytecodeHash: ':initCodeHash', + }, + }); + expect(result.success).toBe(true); + expect(result.data).toEqual({ + operation: 'create2', + value: { + deployerAddress: ':factoryAddress', + bytecodeHash: ':initCodeHash', + }, + }); + }); + + it('validates create2 operator with mixed literal and context parameter', () => { + const result = variableOperationSchema.safeParse({ + operation: 'create2', + value: { + deployerAddress: '0x69Aa2f9fe1572F1B640E1bbc512f5c3a734fc77c', + bytecodeHash: ':initCodeHash', + }, + }); + expect(result.success).toBe(true); + }); + + it('rejects create2 operator without value', () => { + const result = variableOperationSchema.safeParse({ + operation: 'create2', + }); + expect(result.success).toBe(false); + // Multiple validation errors occur: missing value + invalid create2 value structure + const errors = result.error!.format().value?._errors ?? []; + expect(errors.length).toBeGreaterThan(0); + }); + + it('rejects create2 operator with missing deployerAddress', () => { + const result = variableOperationSchema.safeParse({ + operation: 'create2', + value: { + bytecodeHash: + '0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f', + }, + }); + expect(result.success).toBe(false); + }); + + it('rejects create2 operator with missing bytecodeHash', () => { + const result = variableOperationSchema.safeParse({ + operation: 'create2', + value: { + deployerAddress: '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f', + }, + }); + expect(result.success).toBe(false); + }); + + it('rejects create2 operator with primitive value', () => { + const result = variableOperationSchema.safeParse({ + operation: 'create2', + value: 5, + }); + expect(result.success).toBe(false); + }); +}); diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 88adb2654..009e2b290 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -98,6 +98,7 @@ import { JsonRpcConditionProps, JsonRpcConditionType, } from '../src/conditions/schemas/json-rpc'; +import { UNARY_OPERATOR_FUNCTIONS } from '../src/conditions/schemas/variable-operation'; import { SequentialConditionProps, SequentialConditionType, @@ -109,6 +110,24 @@ import { import { DkgClient, DkgRitual } from '../src/dkg'; import { encryptMessage } from '../src/tdec'; +/** + * Returns a valid test value for the given operation type. + * Used in parameterized tests that iterate over OPERATOR_FUNCTIONS. + */ +export const getTestValueForOperation = (operation: string) => { + if (UNARY_OPERATOR_FUNCTIONS.includes(operation)) { + return undefined; + } + if (operation === 'create2') { + return { + deployerAddress: '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f', + bytecodeHash: + '0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f', + }; + } + return 5; +}; + export const fakeDkgTDecFlowE2E: ( ritualId?: number, variant?: FerveoVariant, From 4487d9f3be2786546400a23c8cc829ce0d8afdfe Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 6 Feb 2026 15:08:25 +0000 Subject: [PATCH 261/303] refactor(taco): Scope create2 schema to variable-operation module Move create2ValueSchema from context.ts to variable-operation.ts and remove it from the paramOrContextParamSchema union. This prevents non-create2 operations from accepting create2-shaped values. Also tighten validation: deployerAddress and bytecodeHash now require 0x-prefixed hex strings instead of any plain string. --- .../taco/src/conditions/schemas/context.ts | 11 ------- .../conditions/schemas/variable-operation.ts | 32 +++++++++++++++++-- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/packages/taco/src/conditions/schemas/context.ts b/packages/taco/src/conditions/schemas/context.ts index 13f1a6382..d4925e8bb 100644 --- a/packages/taco/src/conditions/schemas/context.ts +++ b/packages/taco/src/conditions/schemas/context.ts @@ -25,16 +25,6 @@ const paramSchema = z.union([ z.bigint(), ]); -// Schema for CREATE2 operation value - supports both literal addresses/hashes and context parameters -export const create2ValueSchema = z - .object({ - deployerAddress: z.union([plainStringSchema, contextParamSchema]), - bytecodeHash: z.union([plainStringSchema, contextParamSchema]), - }) - .describe( - 'Value for create2 operation containing deployerAddress and bytecodeHash for computing CREATE2 addresses locally.', - ); - const blockchainParamSchema = z .union([ plainStringSchema, @@ -50,7 +40,6 @@ export const paramOrContextParamSchema: z.ZodSchema = z.union([ paramSchema, contextParamSchema, z.lazy(() => z.array(paramOrContextParamSchema)), - create2ValueSchema, ]); export const blockchainParamOrContextParamSchema: z.ZodSchema = z.union([ diff --git a/packages/taco/src/conditions/schemas/variable-operation.ts b/packages/taco/src/conditions/schemas/variable-operation.ts index 61ee59f35..4ef1689c8 100644 --- a/packages/taco/src/conditions/schemas/variable-operation.ts +++ b/packages/taco/src/conditions/schemas/variable-operation.ts @@ -1,6 +1,19 @@ import { z } from 'zod'; -import { create2ValueSchema, paramOrContextParamSchema } from './context'; +import { contextParamSchema, paramOrContextParamSchema } from './context'; + +const hexPrefixedStringSchema = z + .string() + .regex(/^0x[0-9a-fA-F]+$/, 'Must be a 0x-prefixed hex string'); + +const create2ValueSchema = z + .object({ + deployerAddress: z.union([hexPrefixedStringSchema, contextParamSchema]), + bytecodeHash: z.union([hexPrefixedStringSchema, contextParamSchema]), + }) + .describe( + 'Value for create2 operation containing deployerAddress and bytecodeHash for computing CREATE2 addresses locally.', + ); export const OPERATOR_FUNCTIONS = [ '+=', @@ -68,7 +81,7 @@ export const UNARY_OPERATOR_FUNCTIONS = [ export const variableOperationSchema = z .object({ operation: z.enum(OPERATOR_FUNCTIONS), - value: paramOrContextParamSchema.optional(), + value: z.union([paramOrContextParamSchema, create2ValueSchema]).optional(), }) .refine( (data) => { @@ -113,6 +126,21 @@ export const variableOperationSchema = z path: ['value'], }, ) + .refine( + (data) => { + if ( + data.operation !== 'create2' && + create2ValueSchema.safeParse(data.value).success + ) { + return false; + } + return true; + }, + { + message: 'create2-shaped values are only valid for the create2 operation', + path: ['value'], + }, + ) .describe('An operation that can be performed on an obtained result.'); export const MAX_VARIABLE_OPERATIONS = 5; From 47db5360f464866855ee05d64d74fc2d803b253e Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 10 Feb 2026 14:56:05 +0000 Subject: [PATCH 262/303] test(taco): Include create2 in missing-value parametrized test Remove OBJECT_VALUE_OPERATIONS exclusion list so create2 is covered by the regression backstop test for operations requiring a value. Use toContain assertion since create2 produces multiple errors. --- .../test/conditions/variable-operation.test.ts | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/packages/taco/test/conditions/variable-operation.test.ts b/packages/taco/test/conditions/variable-operation.test.ts index 9c209459c..670b1a832 100644 --- a/packages/taco/test/conditions/variable-operation.test.ts +++ b/packages/taco/test/conditions/variable-operation.test.ts @@ -7,9 +7,6 @@ import { } from '../../src/conditions/schemas/variable-operation'; import { getTestValueForOperation } from '../test-utils'; -// Operations that require a specific value type (not a simple primitive) -const OBJECT_VALUE_OPERATIONS = ['create2']; - describe('validates schema', () => { it.each(OPERATOR_FUNCTIONS)('allows valid operation', (operation) => { const result = variableOperationSchema.safeParse({ @@ -36,11 +33,7 @@ describe('validates schema', () => { ); it.each( - OPERATOR_FUNCTIONS.filter( - (op) => - !UNARY_OPERATOR_FUNCTIONS.includes(op) && - !OBJECT_VALUE_OPERATIONS.includes(op), - ), + OPERATOR_FUNCTIONS.filter((op) => !UNARY_OPERATOR_FUNCTIONS.includes(op)), )( 'disallows operations when value is not provided for operation that requires a value', (operation) => { @@ -49,11 +42,9 @@ describe('validates schema', () => { // value is missing for these operations }); expect(result.success).toBe(false); - expect(result.error!.format()).toMatchObject({ - value: { - _errors: ['Value must be defined for operation'], - }, - }); + expect(result.error!.format().value?._errors).toContain( + 'Value must be defined for operation', + ); }, ); }); From 5f8da3234935b7b77e9130a43aa9b8f1f43aa275 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 10 Feb 2026 15:01:39 +0000 Subject: [PATCH 263/303] docs(taco): Regenerate schema docs for create2 changes --- packages/taco/schema-docs/condition-schemas.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index 61510b805..1f36881f5 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -383,10 +383,10 @@ An operation that can be performed on an obtained result. _Object containing the following properties:_ -| Property | Type | -| :------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **`operation`** (\*) | `'+=' \| '-=' \| '*=' \| '/=' \| '%=' \| 'toTokenBaseUnits' \| 'index' \| 'round' \| 'abs' \| 'avg' \| 'ceil' \| 'ethToWei' \| 'floor' \| 'len' \| 'max' \| 'min' \| 'sum' \| 'weiToEth' \| 'bool' \| 'float' \| ...` | -| `value` | [ParamOrContextParam](#paramorcontextparam) | +| Property | Type | +| :------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **`operation`** (\*) | `'+=' \| '-=' \| '*=' \| '/=' \| '%=' \| 'toTokenBaseUnits' \| 'index' \| 'round' \| 'abs' \| 'avg' \| 'ceil' \| 'ethToWei' \| 'floor' \| 'len' \| 'max' \| 'min' \| 'sum' \| 'weiToEth' \| 'bool' \| 'float' \| ...` | +| `value` | [ParamOrContextParam](#paramorcontextparam) _or_ _Object with properties:_

Description: Value for create2 operation containing deployerAddress and bytecodeHash for computing CREATE2 addresses locally.

| _(\*) Required._ From f7b8640d1360a26efda22070fb638e7214cd1e6c Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 10 Feb 2026 12:00:34 -0500 Subject: [PATCH 264/303] Separation of responsibilities between common variable operations schema and the create2 operation schema. Revert change to test since no longer needed. --- .../conditions/schemas/variable-operation.ts | 71 +++++++++---------- .../conditions/variable-operation.test.ts | 8 ++- 2 files changed, 39 insertions(+), 40 deletions(-) diff --git a/packages/taco/src/conditions/schemas/variable-operation.ts b/packages/taco/src/conditions/schemas/variable-operation.ts index 4ef1689c8..41c6a1689 100644 --- a/packages/taco/src/conditions/schemas/variable-operation.ts +++ b/packages/taco/src/conditions/schemas/variable-operation.ts @@ -7,10 +7,17 @@ const hexPrefixedStringSchema = z .regex(/^0x[0-9a-fA-F]+$/, 'Must be a 0x-prefixed hex string'); const create2ValueSchema = z - .object({ - deployerAddress: z.union([hexPrefixedStringSchema, contextParamSchema]), - bytecodeHash: z.union([hexPrefixedStringSchema, contextParamSchema]), - }) + .object( + { + deployerAddress: z.union([hexPrefixedStringSchema, contextParamSchema]), + bytecodeHash: z.union([hexPrefixedStringSchema, contextParamSchema]), + }, + { + required_error: 'Value must be defined for operation', + invalid_type_error: + 'create2 operation requires an object with deployerAddress and bytecodeHash', + }, + ) .describe( 'Value for create2 operation containing deployerAddress and bytecodeHash for computing CREATE2 addresses locally.', ); @@ -78,10 +85,20 @@ export const UNARY_OPERATOR_FUNCTIONS = [ 'keccak', ]; -export const variableOperationSchema = z - .object({ - operation: z.enum(OPERATOR_FUNCTIONS), - value: z.union([paramOrContextParamSchema, create2ValueSchema]).optional(), +const baseVariableOperationSchema = z.object({ + operation: z.enum(OPERATOR_FUNCTIONS), + value: z.any().optional(), +}); + +const commonVariableOperationSchema = baseVariableOperationSchema + .extend({ + operation: z.enum( + OPERATOR_FUNCTIONS.filter((op) => op !== 'create2') as [ + string, + ...string[], + ], + ), + value: paramOrContextParamSchema.optional(), }) .refine( (data) => { @@ -112,35 +129,15 @@ export const variableOperationSchema = z message: 'Value must be defined for operation', path: ['value'], }, - ) - .refine( - (data) => { - if (data.operation === 'create2') { - return create2ValueSchema.safeParse(data.value).success; - } - return true; - }, - { - message: - 'create2 operation requires an object with deployerAddress and bytecodeHash', - path: ['value'], - }, - ) - .refine( - (data) => { - if ( - data.operation !== 'create2' && - create2ValueSchema.safeParse(data.value).success - ) { - return false; - } - return true; - }, - { - message: 'create2-shaped values are only valid for the create2 operation', - path: ['value'], - }, - ) + ); + +const create2VariableOperationSchema = baseVariableOperationSchema.extend({ + operation: z.literal('create2'), + value: create2ValueSchema, +}); + +export const variableOperationSchema = z + .union([commonVariableOperationSchema, create2VariableOperationSchema]) .describe('An operation that can be performed on an obtained result.'); export const MAX_VARIABLE_OPERATIONS = 5; diff --git a/packages/taco/test/conditions/variable-operation.test.ts b/packages/taco/test/conditions/variable-operation.test.ts index 670b1a832..ce95c224f 100644 --- a/packages/taco/test/conditions/variable-operation.test.ts +++ b/packages/taco/test/conditions/variable-operation.test.ts @@ -42,9 +42,11 @@ describe('validates schema', () => { // value is missing for these operations }); expect(result.success).toBe(false); - expect(result.error!.format().value?._errors).toContain( - 'Value must be defined for operation', - ); + expect(result.error!.format()).toMatchObject({ + value: { + _errors: ['Value must be defined for operation'], + }, + }); }, ); }); From 0c1fca966ca9a3a55e55f5fefb5718e8404144bf Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 11 Feb 2026 10:36:22 +0000 Subject: [PATCH 265/303] docs(taco): Regenerate schema docs for union approach --- packages/taco/schema-docs/condition-schemas.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index 1f36881f5..7e471b3a0 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -381,14 +381,10 @@ _(\*) Required._ An operation that can be performed on an obtained result. -_Object containing the following properties:_ - -| Property | Type | -| :------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **`operation`** (\*) | `'+=' \| '-=' \| '*=' \| '/=' \| '%=' \| 'toTokenBaseUnits' \| 'index' \| 'round' \| 'abs' \| 'avg' \| 'ceil' \| 'ethToWei' \| 'floor' \| 'len' \| 'max' \| 'min' \| 'sum' \| 'weiToEth' \| 'bool' \| 'float' \| ...` | -| `value` | [ParamOrContextParam](#paramorcontextparam) _or_ _Object with properties:_
  • `deployerAddress`: `string` (_regex: `/^0x[0-9a-fA-F]+$/`_) _or_ [ContextParam](#contextparam)
  • `bytecodeHash`: `string` (_regex: `/^0x[0-9a-fA-F]+$/`_) _or_ [ContextParam](#contextparam)
Description: Value for create2 operation containing deployerAddress and bytecodeHash for computing CREATE2 addresses locally.

| +_Union of the following possible types:_ -_(\*) Required._ +- _Object with properties:_
  • `operation`: `'+=' | '-=' | '*=' | '/=' | '%=' | 'toTokenBaseUnits' | 'index' | 'round' | 'abs' | 'avg' | 'ceil' | 'ethToWei' | 'floor' | 'len' | 'max' | 'min' | 'sum' | 'weiToEth' | 'bool' | 'float' | ...`
  • `value`: [ParamOrContextParam](#paramorcontextparam)
+- _Object with properties:_
  • `operation`: `'create2'`
  • `value`: _Object with properties:_
    • `deployerAddress`: `string` (_regex: `/^0x[0-9a-fA-F]+$/`_) _or_ [ContextParam](#contextparam)
    • `bytecodeHash`: `string` (_regex: `/^0x[0-9a-fA-F]+$/`_) _or_ [ContextParam](#contextparam)
    - Value for create2 operation containing deployerAddress and bytecodeHash for computing CREATE2 addresses locally.
## VariableOperationsArray From bedf800090eb235a7b9e006d09f0a3da5186044a Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 28 Jan 2026 10:36:20 +0000 Subject: [PATCH 266/303] chore(release): release @nucypher/shared:0.6.0-alpha.10 --- packages/shared/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/package.json b/packages/shared/package.json index 1cbb78d2b..28c73a0c7 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/shared", - "version": "0.6.0-alpha.8", + "version": "0.6.0-alpha.10", "keywords": [ "pre", "taco", From dd026f61c42878982ba5478fc2649db79a99ac06 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 11 Feb 2026 10:36:26 +0000 Subject: [PATCH 267/303] test(taco): Verify non-create2 ops reject create2 values Add parametrized test ensuring all non-unary, non-create2 operations reject create2-shaped object values. --- .../conditions/variable-operation.test.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packages/taco/test/conditions/variable-operation.test.ts b/packages/taco/test/conditions/variable-operation.test.ts index ce95c224f..706f7ff3f 100644 --- a/packages/taco/test/conditions/variable-operation.test.ts +++ b/packages/taco/test/conditions/variable-operation.test.ts @@ -177,4 +177,23 @@ describe('create2 operator', () => { }); expect(result.success).toBe(false); }); + + it.each( + OPERATOR_FUNCTIONS.filter( + (op) => !UNARY_OPERATOR_FUNCTIONS.includes(op) && op !== 'create2', + ), + )( + 'rejects create2-shaped value for non-create2 operation %s', + (operation) => { + const result = variableOperationSchema.safeParse({ + operation, + value: { + deployerAddress: '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f', + bytecodeHash: + '0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f', + }, + }); + expect(result.success).toBe(false); + }, + ); }); From e0ae27189ece162621e752bc0575d9353de8a0f2 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 28 Jan 2026 10:36:29 +0000 Subject: [PATCH 268/303] chore(release): release @nucypher/taco-auth:0.4.0-alpha.10 --- packages/taco-auth/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco-auth/package.json b/packages/taco-auth/package.json index 8c93e9759..482bf3bbc 100644 --- a/packages/taco-auth/package.json +++ b/packages/taco-auth/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco-auth", - "version": "0.4.0-alpha.8", + "version": "0.4.0-alpha.10", "keywords": [ "pre", "threshold", From ea827398b24ac68c29ac69b285fcce5b997948a6 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 12 Feb 2026 08:53:17 +0000 Subject: [PATCH 269/303] feat(shared): Add in-memory cache to SigningCoordinatorAgent Caches getParticipants and getThreshold results with a 10-second TTL to avoid redundant contract reads during short time windows. Cache is keyed by domain and cohortId, with a public clearCache() method for manual invalidation. via [HAPI](https://hapi.run) Co-Authored-By: HAPI --- .../contracts/agents/signing-coordinator.ts | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/packages/shared/src/contracts/agents/signing-coordinator.ts b/packages/shared/src/contracts/agents/signing-coordinator.ts index 46a40f991..5d64cec1f 100644 --- a/packages/shared/src/contracts/agents/signing-coordinator.ts +++ b/packages/shared/src/contracts/agents/signing-coordinator.ts @@ -14,15 +14,39 @@ export type SignerInfo = { }; export class SigningCoordinatorAgent { + private static readonly CACHE_TTL_MS = 10_000; + private static cache = new Map(); + + private static getCached(key: string): T | undefined { + const entry = this.cache.get(key); + if (entry && Date.now() < entry.expiry) { + return entry.data as T; + } + this.cache.delete(key); + return undefined; + } + + private static setCache(key: string, data: unknown): void { + this.cache.set(key, { data, expiry: Date.now() + this.CACHE_TTL_MS }); + } + + public static clearCache(): void { + this.cache.clear(); + } + public static async getParticipants( provider: ethers.providers.Provider, domain: Domain, cohortId: number, ): Promise { + const cacheKey = `participants:${domain}:${cohortId}`; + const cached = this.getCached(cacheKey); + if (cached !== undefined) return cached; + const coordinator = await this.connectReadOnly(provider, domain); const participants = await coordinator.getSigners(cohortId); - return participants.map( + const result = participants.map( ( participant: SigningCoordinator.SigningCohortParticipantStructOutput, ) => { @@ -35,6 +59,9 @@ export class SigningCoordinatorAgent { }; }, ); + + this.setCache(cacheKey, result); + return result; } public static async getThreshold( @@ -42,9 +69,16 @@ export class SigningCoordinatorAgent { domain: Domain, cohortId: number, ): Promise { + const cacheKey = `threshold:${domain}:${cohortId}`; + const cached = this.getCached(cacheKey); + if (cached !== undefined) return cached; + const coordinator = await this.connectReadOnly(provider, domain); const cohort = await coordinator.signingCohorts(cohortId); - return cohort.threshold; + const result = cohort.threshold; + + this.setCache(cacheKey, result); + return result; } public static async getSigningCohortConditions( From ba60cf872246f8bc3beb173947489588e31d9951 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 28 Jan 2026 10:36:39 +0000 Subject: [PATCH 270/303] chore(release): release @nucypher/taco:0.7.0-alpha.10 --- packages/taco/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco/package.json b/packages/taco/package.json index 5ec8dbc1a..605c55518 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco", - "version": "0.7.0-alpha.8", + "version": "0.7.0-alpha.10", "keywords": [ "taco", "threshold", From 71e6fd9854b5f758be34af32d95170b4e0e1c4db Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 12 Feb 2026 08:53:24 +0000 Subject: [PATCH 271/303] test(shared): Add tests for SigningCoordinatorAgent cache Covers cache hits, TTL expiry, per-domain and per-cohortId isolation, and manual cache clearing. via [HAPI](https://hapi.run) Co-Authored-By: HAPI --- .../test/signing-coordinator-cache.test.ts | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 packages/shared/test/signing-coordinator-cache.test.ts diff --git a/packages/shared/test/signing-coordinator-cache.test.ts b/packages/shared/test/signing-coordinator-cache.test.ts new file mode 100644 index 000000000..30030f184 --- /dev/null +++ b/packages/shared/test/signing-coordinator-cache.test.ts @@ -0,0 +1,130 @@ +import { SessionStaticSecret } from '@nucypher/nucypher-core'; +import { initialize } from '@nucypher/shared'; +import { + afterEach, + beforeAll, + beforeEach, + describe, + expect, + it, + vi, +} from 'vitest'; + +import { SigningCoordinatorAgent } from '../src/contracts/agents/signing-coordinator'; + +// We need to mock the private connectReadOnly method's dependencies +// Mock getContract from nucypher-contracts and the factory +vi.mock('@nucypher/nucypher-contracts', () => ({ + getContract: vi.fn().mockReturnValue('0xMockContractAddress'), +})); + +vi.mock('../src/contracts/ethers-typechain', () => ({ + SigningCoordinator__factory: { + connect: vi.fn(), + }, +})); + +import { SigningCoordinator__factory } from '../src/contracts/ethers-typechain'; + +describe('SigningCoordinatorAgent cache', () => { + const mockProvider = { + getNetwork: vi.fn(), + } as any; + + const domain = 'lynx' as const; + const cohortId = 5; + + let mockContract: any; + + beforeAll(async () => { + await initialize(); + }); + + beforeEach(() => { + vi.useFakeTimers(); + + mockProvider.getNetwork.mockResolvedValue({ chainId: 11155111 }); + + const signerKey = SessionStaticSecret.random(); + mockContract = { + getSigners: vi.fn().mockResolvedValue([ + { + provider: '0xnode1', + signerAddress: '0x0000000000000000000000000000000000000001', + signingRequestStaticKey: `0x${Buffer.from(signerKey.publicKey().toBytes()).toString('hex')}`, + }, + ]), + signingCohorts: vi.fn().mockResolvedValue({ threshold: 2 }), + }; + + vi.mocked(SigningCoordinator__factory.connect).mockReturnValue( + mockContract as any, + ); + + // Clear cache between tests + SigningCoordinatorAgent.clearCache(); + }); + + afterEach(() => { + vi.useRealTimers(); + vi.restoreAllMocks(); + }); + + it('caches getParticipants for same domain and cohortId', async () => { + await SigningCoordinatorAgent.getParticipants( + mockProvider, + domain, + cohortId, + ); + await SigningCoordinatorAgent.getParticipants( + mockProvider, + domain, + cohortId, + ); + + expect(mockContract.getSigners).toHaveBeenCalledTimes(1); + }); + + it('caches getThreshold for same domain and cohortId', async () => { + await SigningCoordinatorAgent.getThreshold(mockProvider, domain, cohortId); + await SigningCoordinatorAgent.getThreshold(mockProvider, domain, cohortId); + + expect(mockContract.signingCohorts).toHaveBeenCalledTimes(1); + }); + + it('expires cache after 10 seconds', async () => { + await SigningCoordinatorAgent.getThreshold(mockProvider, domain, cohortId); + + vi.advanceTimersByTime(10_001); + + await SigningCoordinatorAgent.getThreshold(mockProvider, domain, cohortId); + + expect(mockContract.signingCohorts).toHaveBeenCalledTimes(2); + }); + + it('does not share cache across different cohortIds', async () => { + await SigningCoordinatorAgent.getThreshold(mockProvider, domain, 1); + await SigningCoordinatorAgent.getThreshold(mockProvider, domain, 2); + + expect(mockContract.signingCohorts).toHaveBeenCalledTimes(2); + }); + + it('does not share cache across different domains', async () => { + await SigningCoordinatorAgent.getThreshold(mockProvider, 'lynx', cohortId); + await SigningCoordinatorAgent.getThreshold( + mockProvider, + 'mainnet', + cohortId, + ); + + expect(mockContract.signingCohorts).toHaveBeenCalledTimes(2); + }); + + it('clearCache forces fresh fetch', async () => { + await SigningCoordinatorAgent.getThreshold(mockProvider, domain, cohortId); + SigningCoordinatorAgent.clearCache(); + await SigningCoordinatorAgent.getThreshold(mockProvider, domain, cohortId); + + expect(mockContract.signingCohorts).toHaveBeenCalledTimes(2); + }); +}); From a5f3253d3aaf8f9d2762eaad198ef0121a30b613 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 13 Feb 2026 09:12:11 +0000 Subject: [PATCH 272/303] chore(release): release @nucypher/shared:0.6.0-alpha.11 via [HAPI](https://hapi.run) Co-Authored-By: HAPI --- packages/shared/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/package.json b/packages/shared/package.json index 28c73a0c7..edca190e1 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/shared", - "version": "0.6.0-alpha.10", + "version": "0.6.0-alpha.11", "keywords": [ "pre", "taco", From 5a35bb20e8cd460fc9e62284b9fac571243713d6 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 14 Jan 2026 15:03:21 +0000 Subject: [PATCH 273/303] feat(taco): add indexWithinArray support to ABI parameter validation Add indexWithinArray field to abiParameterValidationSchema to enable validation of specific elements within array parameters. This allows more granular validation of ABI calldata when dealing with: - Arrays of primitive types (address[], uint256[], etc.) - Arrays of tuples ((address,uint256,bytes)[]) - Arrays of bytes with nested ABI validation The validation logic ensures: - indexWithinArray can only be used with array types - Combined indexWithinArray and indexWithinTuple properly navigate into array elements before checking tuple structure - Nested ABI validation correctly handles arrays of bytes --- .../taco/src/conditions/schemas/signing.ts | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/packages/taco/src/conditions/schemas/signing.ts b/packages/taco/src/conditions/schemas/signing.ts index 41c233a38..d202d936c 100644 --- a/packages/taco/src/conditions/schemas/signing.ts +++ b/packages/taco/src/conditions/schemas/signing.ts @@ -45,6 +45,12 @@ export const abiParameterValidationSchema: z.ZodSchema = z .int() .nonnegative() .describe('Index of parameter to check within abi calldata.'), + indexWithinArray: z + .number() + .int() + .nonnegative() + .optional() + .describe('Index within array at parameter index to check'), indexWithinTuple: z .number() .int() @@ -177,8 +183,31 @@ function validateAllowedAbiCall( }); } - if (validation.indexWithinTuple !== undefined) { + // Validate indexWithinArray if present + if (validation.indexWithinArray !== undefined) { const paramType = fragment.inputs[validation.parameterIndex]; + if (paramType.baseType !== 'array') { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `Type at parameter index, "${validation.parameterIndex}", is not an array. indexWithinArray can only be used with array types.`, + path: ['allowedAbiCalls', signature, index, 'parameterIndex'], + }); + } + // Note: Cannot validate array index bounds at schema validation time + } + + // Validate indexWithinTuple if present + if (validation.indexWithinTuple !== undefined) { + let paramType = fragment.inputs[validation.parameterIndex]; + + // If indexWithinArray is present, get the array element type + if ( + validation.indexWithinArray !== undefined && + paramType.baseType === 'array' + ) { + paramType = paramType.arrayChildren; + } + if (paramType.baseType !== 'tuple') { // type at parameter index is not a tuple ctx.addIssue({ @@ -199,6 +228,16 @@ function validateAllowedAbiCall( if (validation.nestedAbiValidation) { // if there is nested ABI validation, the type must be bytes let paramType = fragment.inputs[validation.parameterIndex]; + + // Handle array indexing + if ( + validation.indexWithinArray !== undefined && + paramType.baseType === 'array' + ) { + paramType = paramType.arrayChildren; + } + + // Handle tuple indexing if (validation.indexWithinTuple !== undefined) { // if there is an index within tuple, get the type of the component at that index paramType = paramType.components[validation.indexWithinTuple]; From 95285c56ad1dd1b0bc3bcab12e05d898ffa899c8 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 12 Feb 2026 10:33:32 +0000 Subject: [PATCH 274/303] refactor(shared): Extract TtlCache to utility module Move cache logic from SigningCoordinatorAgent into a reusable TtlCache class. Bump TTL from 10s to 60s per review feedback. via [HAPI](https://hapi.run) Co-Authored-By: HAPI --- packages/shared/src/cache.ts | 25 +++++++++++++++++++ .../contracts/agents/signing-coordinator.ts | 25 +++++-------------- .../test/signing-coordinator-cache.test.ts | 4 +-- 3 files changed, 33 insertions(+), 21 deletions(-) create mode 100644 packages/shared/src/cache.ts diff --git a/packages/shared/src/cache.ts b/packages/shared/src/cache.ts new file mode 100644 index 000000000..1cd62d853 --- /dev/null +++ b/packages/shared/src/cache.ts @@ -0,0 +1,25 @@ +export class TtlCache { + private readonly ttlMs: number; + private readonly store = new Map(); + + constructor(ttlMs: number) { + this.ttlMs = ttlMs; + } + + get(key: string): T | undefined { + const entry = this.store.get(key); + if (entry && Date.now() < entry.expiry) { + return entry.data as T; + } + this.store.delete(key); + return undefined; + } + + set(key: string, data: unknown): void { + this.store.set(key, { data, expiry: Date.now() + this.ttlMs }); + } + + clear(): void { + this.store.clear(); + } +} diff --git a/packages/shared/src/contracts/agents/signing-coordinator.ts b/packages/shared/src/contracts/agents/signing-coordinator.ts index 5d64cec1f..4839ddbe2 100644 --- a/packages/shared/src/contracts/agents/signing-coordinator.ts +++ b/packages/shared/src/contracts/agents/signing-coordinator.ts @@ -2,6 +2,7 @@ import { getContract } from '@nucypher/nucypher-contracts'; import { SessionStaticKey } from '@nucypher/nucypher-core'; import { ethers } from 'ethers'; +import { TtlCache } from '../../cache'; import { Domain } from '../../porter'; import { fromHexString } from '../../utils'; import { SigningCoordinator__factory } from '../ethers-typechain'; @@ -14,21 +15,7 @@ export type SignerInfo = { }; export class SigningCoordinatorAgent { - private static readonly CACHE_TTL_MS = 10_000; - private static cache = new Map(); - - private static getCached(key: string): T | undefined { - const entry = this.cache.get(key); - if (entry && Date.now() < entry.expiry) { - return entry.data as T; - } - this.cache.delete(key); - return undefined; - } - - private static setCache(key: string, data: unknown): void { - this.cache.set(key, { data, expiry: Date.now() + this.CACHE_TTL_MS }); - } + private static cache = new TtlCache(60_000); public static clearCache(): void { this.cache.clear(); @@ -40,7 +27,7 @@ export class SigningCoordinatorAgent { cohortId: number, ): Promise { const cacheKey = `participants:${domain}:${cohortId}`; - const cached = this.getCached(cacheKey); + const cached = this.cache.get(cacheKey); if (cached !== undefined) return cached; const coordinator = await this.connectReadOnly(provider, domain); @@ -60,7 +47,7 @@ export class SigningCoordinatorAgent { }, ); - this.setCache(cacheKey, result); + this.cache.set(cacheKey, result); return result; } @@ -70,14 +57,14 @@ export class SigningCoordinatorAgent { cohortId: number, ): Promise { const cacheKey = `threshold:${domain}:${cohortId}`; - const cached = this.getCached(cacheKey); + const cached = this.cache.get(cacheKey); if (cached !== undefined) return cached; const coordinator = await this.connectReadOnly(provider, domain); const cohort = await coordinator.signingCohorts(cohortId); const result = cohort.threshold; - this.setCache(cacheKey, result); + this.cache.set(cacheKey, result); return result; } diff --git a/packages/shared/test/signing-coordinator-cache.test.ts b/packages/shared/test/signing-coordinator-cache.test.ts index 30030f184..dcce7b5a8 100644 --- a/packages/shared/test/signing-coordinator-cache.test.ts +++ b/packages/shared/test/signing-coordinator-cache.test.ts @@ -92,10 +92,10 @@ describe('SigningCoordinatorAgent cache', () => { expect(mockContract.signingCohorts).toHaveBeenCalledTimes(1); }); - it('expires cache after 10 seconds', async () => { + it('expires cache after 60 seconds', async () => { await SigningCoordinatorAgent.getThreshold(mockProvider, domain, cohortId); - vi.advanceTimersByTime(10_001); + vi.advanceTimersByTime(60_001); await SigningCoordinatorAgent.getThreshold(mockProvider, domain, cohortId); From db2a0e64afc1fe178cf5eed1d0f48b1b00a959ff Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 12 Nov 2025 14:02:12 +0000 Subject: [PATCH 275/303] feat(conditions): add :nullAddress as automatically injected context variable This context variable is automatically injected on the node side and resolves to the Ethereum null address (0x0000000000000000000000000000000000000000). - Add :nullAddress to AUTOMATICALLY_INJECTED_CONTEXT_PARAMS - Add :nullAddress to RESERVED_CONTEXT_PARAMS to prevent manual setting - Existing tests already handle automatically injected parameters Related to nucypher/nucypher#3668 --- packages/taco/src/conditions/context/context.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/taco/src/conditions/context/context.ts b/packages/taco/src/conditions/context/context.ts index 3ad2514b2..7ee5947ca 100644 --- a/packages/taco/src/conditions/context/context.ts +++ b/packages/taco/src/conditions/context/context.ts @@ -63,10 +63,12 @@ const EXPECTED_AUTH_PROVIDER_TYPES: Record = { export const AUTOMATICALLY_INJECTED_CONTEXT_PARAMS = [ // These context parameters are automatically injected on the node side. SIGNING_CONDITION_OBJECT_CONTEXT_VAR, + ':nullAddress', ]; export const RESERVED_CONTEXT_PARAMS = [ USER_ADDRESS_PARAM_DEFAULT, SIGNING_CONDITION_OBJECT_CONTEXT_VAR, + ':nullAddress', ]; export class ConditionContext { From 992afee207e8991f560842fe07410feefc17aec2 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 13 Feb 2026 09:14:44 +0000 Subject: [PATCH 276/303] chore(release): release @nucypher/taco-auth:0.4.0-alpha.11 via [HAPI](https://hapi.run) Co-Authored-By: HAPI --- packages/taco-auth/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco-auth/package.json b/packages/taco-auth/package.json index 482bf3bbc..823a1c65c 100644 --- a/packages/taco-auth/package.json +++ b/packages/taco-auth/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco-auth", - "version": "0.4.0-alpha.10", + "version": "0.4.0-alpha.11", "keywords": [ "pre", "threshold", From 2e33825dfe822b345d215511b08200df35017f88 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 14 Jan 2026 15:03:28 +0000 Subject: [PATCH 277/303] test(taco): add tests for indexWithinArray ABI validation Add comprehensive test coverage for indexWithinArray feature: - Valid indexWithinArray with array parameters - Rejection of indexWithinArray for non-array types - Combined indexWithinArray and indexWithinTuple for arrays of tuples - Rejection of indexWithinTuple for arrays of non-tuples - Nested ABI validation with indexWithinArray for bytes arrays - Rejection of nested ABI validation for arrays of non-bytes All tests verify both success and failure cases with appropriate error messages. --- .../taco/test/conditions/base/signing.test.ts | 201 ++++++++++++++++++ 1 file changed, 201 insertions(+) diff --git a/packages/taco/test/conditions/base/signing.test.ts b/packages/taco/test/conditions/base/signing.test.ts index fa77d282c..cfd1a34b2 100644 --- a/packages/taco/test/conditions/base/signing.test.ts +++ b/packages/taco/test/conditions/base/signing.test.ts @@ -365,6 +365,207 @@ describe('SigningObjectAbiAttributeCondition', () => { }); }); + it('accepts valid indexWithinArray in abiCallValidation', () => { + const validSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + abiValidation: { + allowedAbiCalls: { + 'batchTransfer(address[],uint256[])': [ + { + parameterIndex: 0, + indexWithinArray: 0, + returnValueTest: { + comparator: '==', + value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', + }, + }, + ], + }, + }, + }; + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + validSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeUndefined(); + expect(result.data).toBeDefined(); + }); + + it('rejects indexWithinArray for non-array type in abiCallValidation', () => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + abiValidation: { + allowedAbiCalls: { + 'execute(address,uint256,bytes)': [ + { + parameterIndex: 0, + indexWithinArray: 0, + returnValueTest: { + comparator: '==', + value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', + }, + }, + ], + }, + }, + }; + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error!.format()).toMatchObject({ + abiValidation: { + allowedAbiCalls: { + 'execute(address,uint256,bytes)': { + '0': { + parameterIndex: { + _errors: [ + 'Type at parameter index, "0", is not an array. indexWithinArray can only be used with array types.', + ], + }, + }, + }, + }, + }, + }); + }); + + it('accepts indexWithinArray and indexWithinTuple for array of tuples', () => { + const validSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + abiValidation: { + allowedAbiCalls: { + 'executeBatch((address,uint256,bytes)[])': [ + { + parameterIndex: 0, + indexWithinArray: 0, + indexWithinTuple: 0, + returnValueTest: { + comparator: '==', + value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', + }, + }, + ], + }, + }, + }; + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + validSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeUndefined(); + expect(result.data).toBeDefined(); + }); + + it('rejects indexWithinTuple for array of non-tuples', () => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + abiValidation: { + allowedAbiCalls: { + 'batchTransfer(address[],uint256[])': [ + { + parameterIndex: 0, + indexWithinArray: 0, + indexWithinTuple: 0, + returnValueTest: { + comparator: '==', + value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', + }, + }, + ], + }, + }, + }; + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error!.format()).toMatchObject({ + abiValidation: { + allowedAbiCalls: { + 'batchTransfer(address[],uint256[])': { + '0': { + parameterIndex: { + _errors: ['Type at parameter index, "0", is not a tuple'], + }, + }, + }, + }, + }, + }); + }); + + it('accepts nested ABI validation with indexWithinArray', () => { + const validSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + abiValidation: { + allowedAbiCalls: { + 'executeBatch(bytes[])': [ + { + parameterIndex: 0, + indexWithinArray: 0, + nestedAbiValidation: { + allowedAbiCalls: { + 'transfer(address,uint256)': [], + }, + }, + }, + ], + }, + }, + }; + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + validSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeUndefined(); + expect(result.data).toBeDefined(); + }); + + it('rejects nested ABI validation for array of non-bytes', () => { + const badSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + abiValidation: { + allowedAbiCalls: { + 'batchTransfer(address[],uint256[])': [ + { + parameterIndex: 0, + indexWithinArray: 0, + nestedAbiValidation: { + allowedAbiCalls: { + 'transfer(address,uint256)': [], + }, + }, + }, + ], + }, + }, + }; + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + badSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeDefined(); + expect(result.data).toBeUndefined(); + expect(result.error!.format()).toMatchObject({ + abiValidation: { + allowedAbiCalls: { + 'batchTransfer(address[],uint256[])': { + '0': { + _errors: [ + 'Invalid type for nested ABI validation, "address"; expected bytes', + ], + }, + }, + }, + }, + }); + }); + it('rejects invalid tuple type at parameterIndex in abiCallValidation', () => { const badSigningObjectAbiAttributeConditionObj = { ...testSigningObjectAbiAttributeConditionObj, From a5427f99610fb5fa48ebdd054513f9d390439f4f Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 13 Feb 2026 12:26:37 +0000 Subject: [PATCH 278/303] refactor(shared): Use helper method for cache key construction Reorder cache keys from field:domain:cohortId to domain:cohortId:field (broader to specific) and extract a cacheKey() helper to keep key structure consistent, per review feedback. --- .../contracts/agents/signing-coordinator.ts | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/shared/src/contracts/agents/signing-coordinator.ts b/packages/shared/src/contracts/agents/signing-coordinator.ts index 4839ddbe2..0e5a9c6bb 100644 --- a/packages/shared/src/contracts/agents/signing-coordinator.ts +++ b/packages/shared/src/contracts/agents/signing-coordinator.ts @@ -17,6 +17,14 @@ export type SignerInfo = { export class SigningCoordinatorAgent { private static cache = new TtlCache(60_000); + private static cacheKey( + domain: Domain, + cohortId: number, + field: string, + ): string { + return `${domain}:${cohortId}:${field}`; + } + public static clearCache(): void { this.cache.clear(); } @@ -26,8 +34,8 @@ export class SigningCoordinatorAgent { domain: Domain, cohortId: number, ): Promise { - const cacheKey = `participants:${domain}:${cohortId}`; - const cached = this.cache.get(cacheKey); + const key = this.cacheKey(domain, cohortId, 'participants'); + const cached = this.cache.get(key); if (cached !== undefined) return cached; const coordinator = await this.connectReadOnly(provider, domain); @@ -47,7 +55,7 @@ export class SigningCoordinatorAgent { }, ); - this.cache.set(cacheKey, result); + this.cache.set(key, result); return result; } @@ -56,15 +64,15 @@ export class SigningCoordinatorAgent { domain: Domain, cohortId: number, ): Promise { - const cacheKey = `threshold:${domain}:${cohortId}`; - const cached = this.cache.get(cacheKey); + const key = this.cacheKey(domain, cohortId, 'threshold'); + const cached = this.cache.get(key); if (cached !== undefined) return cached; const coordinator = await this.connectReadOnly(provider, domain); const cohort = await coordinator.signingCohorts(cohortId); const result = cohort.threshold; - this.cache.set(cacheKey, result); + this.cache.set(key, result); return result; } From 2f77175f49338fd929cc98655cf5e0770113e1e5 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 20 Feb 2026 16:51:29 +0000 Subject: [PATCH 279/303] refactor(conditions): Extract nullAddress string literal into constant Replace ':nullAddress' string literals with NULL_ADDRESS_CONTEXT_VAR constant defined in conditions/const.ts, used in both AUTOMATICALLY_INJECTED_CONTEXT_PARAMS and RESERVED_CONTEXT_PARAMS. --- packages/taco/src/conditions/const.ts | 2 ++ packages/taco/src/conditions/context/context.ts | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/taco/src/conditions/const.ts b/packages/taco/src/conditions/const.ts index 39d053240..bbe28ecf5 100644 --- a/packages/taco/src/conditions/const.ts +++ b/packages/taco/src/conditions/const.ts @@ -12,6 +12,8 @@ export const CONTEXT_PARAM_FULL_MATCH_REGEXP = new RegExp( export const CONTEXT_PARAM_PREFIX = ':'; +export const NULL_ADDRESS_CONTEXT_VAR = ':nullAddress'; + export const USER_ADDRESS_PARAMS = [ // Ordering matters, this should always be last USER_ADDRESS_PARAM_DEFAULT, diff --git a/packages/taco/src/conditions/context/context.ts b/packages/taco/src/conditions/context/context.ts index 7ee5947ca..b0523519c 100644 --- a/packages/taco/src/conditions/context/context.ts +++ b/packages/taco/src/conditions/context/context.ts @@ -18,6 +18,7 @@ import { CONTEXT_PARAM_FULL_MATCH_REGEXP, CONTEXT_PARAM_PREFIX, CONTEXT_PARAM_REGEXP, + NULL_ADDRESS_CONTEXT_VAR, USER_ADDRESS_PARAMS, } from '../const'; import { SIGNING_CONDITION_OBJECT_CONTEXT_VAR } from '../schemas/signing'; @@ -63,12 +64,12 @@ const EXPECTED_AUTH_PROVIDER_TYPES: Record = { export const AUTOMATICALLY_INJECTED_CONTEXT_PARAMS = [ // These context parameters are automatically injected on the node side. SIGNING_CONDITION_OBJECT_CONTEXT_VAR, - ':nullAddress', + NULL_ADDRESS_CONTEXT_VAR, ]; export const RESERVED_CONTEXT_PARAMS = [ USER_ADDRESS_PARAM_DEFAULT, SIGNING_CONDITION_OBJECT_CONTEXT_VAR, - ':nullAddress', + NULL_ADDRESS_CONTEXT_VAR, ]; export class ConditionContext { From 67f1d15a92751884605f623eb20e6ddee7cc3509 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Fri, 13 Feb 2026 09:14:48 +0000 Subject: [PATCH 280/303] chore(release): release @nucypher/taco:0.7.0-alpha.11 via [HAPI](https://hapi.run) Co-Authored-By: HAPI --- packages/taco/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco/package.json b/packages/taco/package.json index 605c55518..0167c3709 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco", - "version": "0.7.0-alpha.10", + "version": "0.7.0-alpha.11", "keywords": [ "taco", "threshold", From fb18b36bc8bc3098fbed4b2d853fcbb064708dfb Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 29 Jan 2026 14:09:15 +0000 Subject: [PATCH 281/303] feat(signing): Replace index fields with unified subIndices Replace separate indexWithinArray and indexWithinTuple fields with a single subIndices array that handles arbitrary nesting of arrays and tuples. This resolves the ambiguity of operation ordering when both array and tuple indexing are needed. The subIndices approach interprets each index based on the current ABI type at that position: - Arrays (type[]) consume an index and access that element - Tuples ((a,b,c)) consume an index and access that field - Supports any depth of nesting This aligns with the corresponding nucypher/nucypher PR #3685 changes. --- .../taco/schema-docs/condition-schemas.md | 12 +- .../taco/src/conditions/schemas/signing.ts | 145 +++++++++--------- .../taco/test/conditions/base/signing.test.ts | 125 +++++++-------- packages/taco/test/test-utils.ts | 4 +- 4 files changed, 141 insertions(+), 145 deletions(-) diff --git a/packages/taco/schema-docs/condition-schemas.md b/packages/taco/schema-docs/condition-schemas.md index 61510b805..f665893a8 100644 --- a/packages/taco/schema-docs/condition-schemas.md +++ b/packages/taco/schema-docs/condition-schemas.md @@ -329,12 +329,12 @@ _(\*) Required._ _Object containing the following properties:_ -| Property | Description | Type | -| :------------------------ | :------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| **`parameterIndex`** (\*) | Index of parameter to check within abi calldata. | `number` (_int, ≥0_) | -| `indexWithinTuple` | Index of value within tuple value at parameter index to check | `number` (_int, ≥0_) | -| `returnValueTest` | Comparison check for value within calldata | [BlockchainReturnValueTest](#blockchainreturnvaluetest) | -| `nestedAbiValidation` | Additional checks for nested abi calldata | _Object with properties:_
  • `allowedAbiCalls`: _Object with dynamic keys of type_ `string` _and values of type_ _Array of [AbiParameterValidation](#abiparametervalidation) items_
| +| Property | Description | Type | +| :------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **`parameterIndex`** (\*) | Index of parameter to check within abi calldata. | `number` (_int, ≥0_) | +| `subIndices` | Sequential indices for navigating nested structures (arrays and tuples). The ABI type determines interpretation at each step: array types access elements, tuple types access fields by index. | _Array of `number` (_int, ≥0_) items_ | +| `returnValueTest` | Comparison check for value within calldata | [BlockchainReturnValueTest](#blockchainreturnvaluetest) | +| `nestedAbiValidation` | Additional checks for nested abi calldata | _Object with properties:_
  • `allowedAbiCalls`: _Object with dynamic keys of type_ `string` _and values of type_ _Array of [AbiParameterValidation](#abiparametervalidation) items_
| _(\*) Required._ diff --git a/packages/taco/src/conditions/schemas/signing.ts b/packages/taco/src/conditions/schemas/signing.ts index d202d936c..d70a37a32 100644 --- a/packages/taco/src/conditions/schemas/signing.ts +++ b/packages/taco/src/conditions/schemas/signing.ts @@ -45,19 +45,13 @@ export const abiParameterValidationSchema: z.ZodSchema = z .int() .nonnegative() .describe('Index of parameter to check within abi calldata.'), - indexWithinArray: z - .number() - .int() - .nonnegative() - .optional() - .describe('Index within array at parameter index to check'), - indexWithinTuple: z - .number() - .int() - .nonnegative() + subIndices: z + .array(z.number().int().nonnegative()) .optional() .describe( - 'Index of value within tuple value at parameter index to check', + 'Sequential indices for navigating nested structures (arrays and tuples). ' + + 'The ABI type determines interpretation at each step: array types consume an index ' + + 'and access that element, tuple types consume an index and access that field.', ), returnValueTest: blockchainReturnValueTestSchema .optional() @@ -158,6 +152,57 @@ const humanAbiCallSignatureSchema = z }) .describe('A human readable ABI signature, e.g. "transfer(address,uint256)"'); +/** + * Resolves the final ParamType after applying subIndices navigation. + * Returns the resolved type or null if navigation fails (with errors added to ctx). + * + * @param ctx - The Zod refinement context. + * @param paramType - The starting ParamType to navigate from. + * @param subIndices - The array of indices to navigate through. + * @param signature - The ABI signature (for error messages). + * @param validationIndex - The index of the validation (for error paths). + * @returns The resolved ParamType or null if validation failed. + */ +function resolveTypeWithSubIndices( + ctx: z.RefinementCtx, + paramType: ParamType, + subIndices: number[], + signature: string, + validationIndex: number, +): ParamType | null { + let currentType = paramType; + + for (let i = 0; i < subIndices.length; i++) { + const idx = subIndices[i]; + + if (currentType.baseType === 'array') { + // Array type - navigate to element type (cannot validate bounds at schema time) + currentType = currentType.arrayChildren; + } else if (currentType.baseType === 'tuple') { + // Tuple type - navigate to component at index + if (idx >= currentType.components.length) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `Index ${idx} at subIndices position ${i} is out of range for tuple with ${currentType.components.length} fields`, + path: ['allowedAbiCalls', signature, validationIndex, 'subIndices'], + }); + return null; + } + currentType = currentType.components[idx]; + } else { + // Not an indexable type + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `Cannot apply index at subIndices position ${i}: type "${currentType.baseType}" is not indexable (not an array or tuple)`, + path: ['allowedAbiCalls', signature, validationIndex, 'subIndices'], + }); + return null; + } + } + + return currentType; +} + /** * Validates the allowed ABI calls against the provided signature and validations. * This function is used in the superRefine method of the abiCallValidationSchema. @@ -181,79 +226,39 @@ function validateAllowedAbiCall( message: `Parameter index, "${validation.parameterIndex}", is out of range`, path: ['allowedAbiCalls', signature, index, 'parameterIndex'], }); + continue; } - // Validate indexWithinArray if present - if (validation.indexWithinArray !== undefined) { - const paramType = fragment.inputs[validation.parameterIndex]; - if (paramType.baseType !== 'array') { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: `Type at parameter index, "${validation.parameterIndex}", is not an array. indexWithinArray can only be used with array types.`, - path: ['allowedAbiCalls', signature, index, 'parameterIndex'], - }); - } - // Note: Cannot validate array index bounds at schema validation time - } - - // Validate indexWithinTuple if present - if (validation.indexWithinTuple !== undefined) { - let paramType = fragment.inputs[validation.parameterIndex]; - - // If indexWithinArray is present, get the array element type - if ( - validation.indexWithinArray !== undefined && - paramType.baseType === 'array' - ) { - paramType = paramType.arrayChildren; - } - - if (paramType.baseType !== 'tuple') { - // type at parameter index is not a tuple - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: `Type at parameter index, "${validation.parameterIndex}", is not a tuple`, - path: ['allowedAbiCalls', signature, index, 'parameterIndex'], - }); - } else if (validation.indexWithinTuple >= paramType.components.length) { - // invalid index within tuple - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: `Index within tuple, "${validation.indexWithinTuple}", is out of range`, - path: ['allowedAbiCalls', signature, index, 'indexWithinTuple'], - }); + let finalType = fragment.inputs[validation.parameterIndex]; + + // Validate and resolve subIndices if present + if (validation.subIndices && validation.subIndices.length > 0) { + const resolvedType = resolveTypeWithSubIndices( + ctx, + finalType, + validation.subIndices, + signature, + index, + ); + if (resolvedType === null) { + continue; // Validation failed, errors already added } + finalType = resolvedType; } if (validation.nestedAbiValidation) { - // if there is nested ABI validation, the type must be bytes - let paramType = fragment.inputs[validation.parameterIndex]; - - // Handle array indexing - if ( - validation.indexWithinArray !== undefined && - paramType.baseType === 'array' - ) { - paramType = paramType.arrayChildren; - } - - // Handle tuple indexing - if (validation.indexWithinTuple !== undefined) { - // if there is an index within tuple, get the type of the component at that index - paramType = paramType.components[validation.indexWithinTuple]; - } - - if (paramType.baseType !== 'bytes') { + // if there is nested ABI validation, the final type must be bytes + if (finalType.baseType !== 'bytes') { ctx.addIssue({ code: z.ZodIssueCode.custom, - message: `Invalid type for nested ABI validation, "${paramType.baseType}"; expected bytes`, + message: `Invalid type for nested ABI validation, "${finalType.baseType}"; expected bytes`, path: ['allowedAbiCalls', signature, index], }); } } } } catch { - // even though abi signatures are already validated by nested schema - zod uses “greedy” (continuable) validation so all validations are run + // even though abi signatures are already validated by nested schema - zod uses "greedy" (continuable) validation so all validations are run // ignore invalid ABI signature } } diff --git a/packages/taco/test/conditions/base/signing.test.ts b/packages/taco/test/conditions/base/signing.test.ts index cfd1a34b2..8d07e12ea 100644 --- a/packages/taco/test/conditions/base/signing.test.ts +++ b/packages/taco/test/conditions/base/signing.test.ts @@ -289,7 +289,7 @@ describe('SigningObjectAbiAttributeCondition', () => { 'execute((address,uint256,bytes))': [ { parameterIndex: 0, - indexWithinTuple: 0, + subIndices: [0], returnValueTest: { comparator: '==', value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', @@ -365,7 +365,7 @@ describe('SigningObjectAbiAttributeCondition', () => { }); }); - it('accepts valid indexWithinArray in abiCallValidation', () => { + it('accepts valid subIndices for array type in abiCallValidation', () => { const validSigningObjectAbiAttributeConditionObj = { ...testSigningObjectAbiAttributeConditionObj, abiValidation: { @@ -373,7 +373,7 @@ describe('SigningObjectAbiAttributeCondition', () => { 'batchTransfer(address[],uint256[])': [ { parameterIndex: 0, - indexWithinArray: 0, + subIndices: [0], returnValueTest: { comparator: '==', value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', @@ -391,7 +391,7 @@ describe('SigningObjectAbiAttributeCondition', () => { expect(result.data).toBeDefined(); }); - it('rejects indexWithinArray for non-array type in abiCallValidation', () => { + it('rejects subIndices for non-indexable type in abiCallValidation', () => { const badSigningObjectAbiAttributeConditionObj = { ...testSigningObjectAbiAttributeConditionObj, abiValidation: { @@ -399,7 +399,7 @@ describe('SigningObjectAbiAttributeCondition', () => { 'execute(address,uint256,bytes)': [ { parameterIndex: 0, - indexWithinArray: 0, + subIndices: [0], returnValueTest: { comparator: '==', value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', @@ -420,9 +420,9 @@ describe('SigningObjectAbiAttributeCondition', () => { allowedAbiCalls: { 'execute(address,uint256,bytes)': { '0': { - parameterIndex: { + subIndices: { _errors: [ - 'Type at parameter index, "0", is not an array. indexWithinArray can only be used with array types.', + 'Cannot apply index at subIndices position 0: type "address" is not indexable (not an array or tuple)', ], }, }, @@ -432,7 +432,7 @@ describe('SigningObjectAbiAttributeCondition', () => { }); }); - it('accepts indexWithinArray and indexWithinTuple for array of tuples', () => { + it('accepts subIndices for array of tuples', () => { const validSigningObjectAbiAttributeConditionObj = { ...testSigningObjectAbiAttributeConditionObj, abiValidation: { @@ -440,8 +440,7 @@ describe('SigningObjectAbiAttributeCondition', () => { 'executeBatch((address,uint256,bytes)[])': [ { parameterIndex: 0, - indexWithinArray: 0, - indexWithinTuple: 0, + subIndices: [0, 0], // array[0] -> tuple[0] returnValueTest: { comparator: '==', value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', @@ -459,16 +458,41 @@ describe('SigningObjectAbiAttributeCondition', () => { expect(result.data).toBeDefined(); }); - it('rejects indexWithinTuple for array of non-tuples', () => { + it('accepts subIndices for tuple of arrays', () => { + const validSigningObjectAbiAttributeConditionObj = { + ...testSigningObjectAbiAttributeConditionObj, + abiValidation: { + allowedAbiCalls: { + 'multiTransfer((address[],uint256[],bytes))': [ + { + parameterIndex: 0, + subIndices: [0, 0], // tuple[0] -> array[0] + returnValueTest: { + comparator: '==', + value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', + }, + }, + ], + }, + }, + }; + const result = SigningObjectAbiAttributeCondition.validate( + signingObjectAbiAttributeConditionSchema, + validSigningObjectAbiAttributeConditionObj, + ); + expect(result.error).toBeUndefined(); + expect(result.data).toBeDefined(); + }); + + it('rejects subIndices with out of range tuple index', () => { const badSigningObjectAbiAttributeConditionObj = { ...testSigningObjectAbiAttributeConditionObj, abiValidation: { allowedAbiCalls: { - 'batchTransfer(address[],uint256[])': [ + 'execute((address,uint256,bytes))': [ { parameterIndex: 0, - indexWithinArray: 0, - indexWithinTuple: 0, + subIndices: [5], // tuple only has 3 fields returnValueTest: { comparator: '==', value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', @@ -487,10 +511,12 @@ describe('SigningObjectAbiAttributeCondition', () => { expect(result.error!.format()).toMatchObject({ abiValidation: { allowedAbiCalls: { - 'batchTransfer(address[],uint256[])': { + 'execute((address,uint256,bytes))': { '0': { - parameterIndex: { - _errors: ['Type at parameter index, "0", is not a tuple'], + subIndices: { + _errors: [ + 'Index 5 at subIndices position 0 is out of range for tuple with 3 fields', + ], }, }, }, @@ -499,7 +525,7 @@ describe('SigningObjectAbiAttributeCondition', () => { }); }); - it('accepts nested ABI validation with indexWithinArray', () => { + it('accepts nested ABI validation with subIndices', () => { const validSigningObjectAbiAttributeConditionObj = { ...testSigningObjectAbiAttributeConditionObj, abiValidation: { @@ -507,7 +533,7 @@ describe('SigningObjectAbiAttributeCondition', () => { 'executeBatch(bytes[])': [ { parameterIndex: 0, - indexWithinArray: 0, + subIndices: [0], nestedAbiValidation: { allowedAbiCalls: { 'transfer(address,uint256)': [], @@ -526,7 +552,7 @@ describe('SigningObjectAbiAttributeCondition', () => { expect(result.data).toBeDefined(); }); - it('rejects nested ABI validation for array of non-bytes', () => { + it('rejects nested ABI validation when subIndices resolves to non-bytes', () => { const badSigningObjectAbiAttributeConditionObj = { ...testSigningObjectAbiAttributeConditionObj, abiValidation: { @@ -534,7 +560,7 @@ describe('SigningObjectAbiAttributeCondition', () => { 'batchTransfer(address[],uint256[])': [ { parameterIndex: 0, - indexWithinArray: 0, + subIndices: [0], nestedAbiValidation: { allowedAbiCalls: { 'transfer(address,uint256)': [], @@ -566,7 +592,7 @@ describe('SigningObjectAbiAttributeCondition', () => { }); }); - it('rejects invalid tuple type at parameterIndex in abiCallValidation', () => { + it('rejects subIndices on non-tuple type at parameterIndex', () => { const badSigningObjectAbiAttributeConditionObj = { ...testSigningObjectAbiAttributeConditionObj, abiValidation: { @@ -574,7 +600,7 @@ describe('SigningObjectAbiAttributeCondition', () => { 'execute(address,uint256,bytes)': [ { parameterIndex: 0, - indexWithinTuple: 0, + subIndices: [0], returnValueTest: { comparator: '==', value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', @@ -595,46 +621,10 @@ describe('SigningObjectAbiAttributeCondition', () => { allowedAbiCalls: { 'execute(address,uint256,bytes)': { '0': { - parameterIndex: { - _errors: ['Type at parameter index, "0", is not a tuple'], - }, - }, - }, - }, - }, - }); - }); - it('rejects invalid tuple index in abiCallValidation', () => { - const badSigningObjectAbiAttributeConditionObj = { - ...testSigningObjectAbiAttributeConditionObj, - abiValidation: { - allowedAbiCalls: { - 'execute((address,uint256,bytes))': [ - { - parameterIndex: 0, - indexWithinTuple: 3, - returnValueTest: { - comparator: '==', - value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', - }, - }, - ], - }, - }, - }; - const result = SigningObjectAbiAttributeCondition.validate( - signingObjectAbiAttributeConditionSchema, - badSigningObjectAbiAttributeConditionObj, - ); - expect(result.error).toBeDefined(); - expect(result.data).toBeUndefined(); - expect(result.error!.format()).toMatchObject({ - abiValidation: { - allowedAbiCalls: { - 'execute((address,uint256,bytes))': { - '0': { - indexWithinTuple: { - _errors: [`Index within tuple, "3", is out of range`], + subIndices: { + _errors: [ + 'Cannot apply index at subIndices position 0: type "address" is not indexable (not an array or tuple)', + ], }, }, }, @@ -642,6 +632,7 @@ describe('SigningObjectAbiAttributeCondition', () => { }, }); }); + it('rejects invalid nested parameter index in abiCallValidation', () => { const badSigningObjectAbiAttributeConditionObj = { ...testSigningObjectAbiAttributeConditionObj, @@ -650,7 +641,7 @@ describe('SigningObjectAbiAttributeCondition', () => { 'execute((address,uint256,bytes))': [ { parameterIndex: 0, - indexWithinTuple: 2, + subIndices: [2], nestedAbiValidation: { allowedAbiCalls: { 'execute(address,uint256,bytes)': [ @@ -705,7 +696,7 @@ describe('SigningObjectAbiAttributeCondition', () => { 'execute((address,uint256,bytes))': [ { parameterIndex: 0, - indexWithinTuple: 1, // index of uint256 + subIndices: [1], // index of uint256 nestedAbiValidation: { allowedAbiCalls: { 'execute(address,uint256,bytes)': [ @@ -768,7 +759,7 @@ describe('SigningObjectAbiAttributeCondition', () => { 'execute((address,uint256,bytes))': [ { parameterIndex: 0, - indexWithinTuple: 0, + subIndices: [0], returnValueTest: { comparator: '==', value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', @@ -776,7 +767,7 @@ describe('SigningObjectAbiAttributeCondition', () => { }, { parameterIndex: 0, - indexWithinTuple: 2, + subIndices: [2], nestedAbiValidation: { allowedAbiCalls: { 'execute(address,uint256,bytes)': [ diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 88adb2654..031d6bb3a 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -466,7 +466,7 @@ export const testSigningObjectAbiAttributeConditionObj: SigningObjectAbiAttribut 'execute((address,uint256,bytes))': [ { parameterIndex: 0, - indexWithinTuple: 0, + subIndices: [0], returnValueTest: { comparator: '==', value: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', @@ -474,7 +474,7 @@ export const testSigningObjectAbiAttributeConditionObj: SigningObjectAbiAttribut }, { parameterIndex: 0, - indexWithinTuple: 2, + subIndices: [2], nestedAbiValidation: { allowedAbiCalls: { 'execute(address,uint256,bytes)': [ From 4d7ca12b0af72c8608f5738dd30f94a3139780cc Mon Sep 17 00:00:00 2001 From: James Campbell Date: Wed, 25 Feb 2026 14:01:59 +0000 Subject: [PATCH 282/303] refactor(shared): Use toHexString utility for hex conversion in test Replace Buffer.from(...).toString('hex') with the existing toHexString utility from @nucypher/shared for consistency with the rest of the codebase. --- packages/shared/test/signing-coordinator-cache.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/shared/test/signing-coordinator-cache.test.ts b/packages/shared/test/signing-coordinator-cache.test.ts index dcce7b5a8..ed2a266fa 100644 --- a/packages/shared/test/signing-coordinator-cache.test.ts +++ b/packages/shared/test/signing-coordinator-cache.test.ts @@ -11,6 +11,7 @@ import { } from 'vitest'; import { SigningCoordinatorAgent } from '../src/contracts/agents/signing-coordinator'; +import { toHexString } from '../src/utils'; // We need to mock the private connectReadOnly method's dependencies // Mock getContract from nucypher-contracts and the factory @@ -51,7 +52,7 @@ describe('SigningCoordinatorAgent cache', () => { { provider: '0xnode1', signerAddress: '0x0000000000000000000000000000000000000001', - signingRequestStaticKey: `0x${Buffer.from(signerKey.publicKey().toBytes()).toString('hex')}`, + signingRequestStaticKey: `0x${toHexString(signerKey.publicKey().toBytes())}`, }, ]), signingCohorts: vi.fn().mockResolvedValue({ threshold: 2 }), From 08458c18406adac7c4ca4d9bff55cc5960178f8f Mon Sep 17 00:00:00 2001 From: James Campbell Date: Tue, 3 Mar 2026 11:04:37 +0000 Subject: [PATCH 283/303] refactor(taco): Use undefined instead of null in resolveTypeWithSubIndices Idiomatic TypeScript prefers undefined over null for absent values. Addresses PR review feedback. --- packages/taco/src/conditions/schemas/signing.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/taco/src/conditions/schemas/signing.ts b/packages/taco/src/conditions/schemas/signing.ts index d70a37a32..09e6f5da6 100644 --- a/packages/taco/src/conditions/schemas/signing.ts +++ b/packages/taco/src/conditions/schemas/signing.ts @@ -154,14 +154,14 @@ const humanAbiCallSignatureSchema = z /** * Resolves the final ParamType after applying subIndices navigation. - * Returns the resolved type or null if navigation fails (with errors added to ctx). + * Returns the resolved type or undefined if navigation fails (with errors added to ctx). * * @param ctx - The Zod refinement context. * @param paramType - The starting ParamType to navigate from. * @param subIndices - The array of indices to navigate through. * @param signature - The ABI signature (for error messages). * @param validationIndex - The index of the validation (for error paths). - * @returns The resolved ParamType or null if validation failed. + * @returns The resolved ParamType or undefined if validation failed. */ function resolveTypeWithSubIndices( ctx: z.RefinementCtx, @@ -169,7 +169,7 @@ function resolveTypeWithSubIndices( subIndices: number[], signature: string, validationIndex: number, -): ParamType | null { +): ParamType | undefined { let currentType = paramType; for (let i = 0; i < subIndices.length; i++) { @@ -186,7 +186,7 @@ function resolveTypeWithSubIndices( message: `Index ${idx} at subIndices position ${i} is out of range for tuple with ${currentType.components.length} fields`, path: ['allowedAbiCalls', signature, validationIndex, 'subIndices'], }); - return null; + return undefined; } currentType = currentType.components[idx]; } else { @@ -196,7 +196,7 @@ function resolveTypeWithSubIndices( message: `Cannot apply index at subIndices position ${i}: type "${currentType.baseType}" is not indexable (not an array or tuple)`, path: ['allowedAbiCalls', signature, validationIndex, 'subIndices'], }); - return null; + return undefined; } } @@ -240,7 +240,7 @@ function validateAllowedAbiCall( signature, index, ); - if (resolvedType === null) { + if (resolvedType === undefined) { continue; // Validation failed, errors already added } finalType = resolvedType; From 4d05456df61a11499d2e3e44a76293a234d8d158 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 5 Mar 2026 13:21:29 +0000 Subject: [PATCH 284/303] chore(release): release @nucypher/shared:0.6.0-alpha.12 --- packages/shared/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/package.json b/packages/shared/package.json index edca190e1..6322499c6 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/shared", - "version": "0.6.0-alpha.11", + "version": "0.6.0-alpha.12", "keywords": [ "pre", "taco", From 33b40eaf414209fb6486dc1b6225d1fbc4b990c9 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 5 Mar 2026 13:21:41 +0000 Subject: [PATCH 285/303] chore(release): release @nucypher/taco-auth:0.4.0-alpha.12 --- packages/taco-auth/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco-auth/package.json b/packages/taco-auth/package.json index 823a1c65c..0ab7beda5 100644 --- a/packages/taco-auth/package.json +++ b/packages/taco-auth/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco-auth", - "version": "0.4.0-alpha.11", + "version": "0.4.0-alpha.12", "keywords": [ "pre", "threshold", From a6efe669833a86c75b988c44fe140d6d8c219684 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 5 Mar 2026 13:22:09 +0000 Subject: [PATCH 286/303] chore(release): release @nucypher/taco:0.7.0-alpha.12 --- packages/taco/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taco/package.json b/packages/taco/package.json index 0167c3709..449d3f85c 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -1,6 +1,6 @@ { "name": "@nucypher/taco", - "version": "0.7.0-alpha.11", + "version": "0.7.0-alpha.12", "keywords": [ "taco", "threshold", From 87a01e2b54b4995259933d53e3e4b489aeed8286 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 10 Apr 2026 13:51:29 -0400 Subject: [PATCH 287/303] Update .nvmrc to update developer version since 18 is end-of-life. --- .nvmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.nvmrc b/.nvmrc index 3c032078a..2bd5a0a98 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -18 +22 From 5980aa422636bd87fd3e6bb74bc4869883ed43ff Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 10 Apr 2026 13:52:11 -0400 Subject: [PATCH 288/303] Update CI jobs to use newer node versions. Don't include node v25 which has a change where node's built-in localStorage can interfere with the browser-like one. --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7c24f96b3..971c863fa 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,7 +9,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - node: ['18.x', '20.x', '22.x'] + node: ['22.x', '24.x'] os: [ubuntu-latest] steps: - uses: actions/checkout@v5 From 7eaa8f34bdab3c7b58a83fefcb8ecb1c2252b0ae Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 10 Apr 2026 14:04:56 -0400 Subject: [PATCH 289/303] Fix es lint error, "at()" was introduced in ES2022. --- packages/taco/test/taco-sign.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index c9a10cf98..7de3f3d0d 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -406,7 +406,7 @@ describe('TACo Signing', () => { threshold, ); - const call = porterSignUserOpMock.mock.calls.at(-1)!; + const call = porterSignUserOpMock.mock.calls[porterSignUserOpMock.mock.calls.length - 1]!; const [op] = call; const nodes = ['0xnode1', '0xnode2']; @@ -483,7 +483,7 @@ describe('TACo Signing', () => { }, threshold, ); - const call = porterSignUserOpMock.mock.calls.at(-1)!; + const call = porterSignUserOpMock.mock.calls[porterSignUserOpMock.mock.calls.length - 1]!; const [op] = call; const nodes = ['0xnode1', '0xnode2']; From cb6e621d564c93bed883bbfaf2e61d1d17dc51c9 Mon Sep 17 00:00:00 2001 From: James Campbell Date: Thu, 9 Apr 2026 16:57:25 +0100 Subject: [PATCH 290/303] feat(taco): Generate JSON Schema alongside markdown schema docs The existing schema-docs-generation script produces a human-readable markdown reference for condition schemas. This adds a sibling output that emits a standard JSON Schema document for the full ConditionExpression envelope ({version, condition}). Editors that understand $schema (VS Code, JetBrains, Cursor) and LLMs both consume this format directly, giving inline validation, autocomplete, and structured output for any conditions.json file without depending on @nucypher/taco at runtime. The lazy union root (anyConditionSchema) is wrapped in the ConditionExpression shape so the schema validates the same shape that ConditionExpression.fromObj parses. BigInt bounds (uint256 ranges) are stripped during serialization because standard JSON Schema requires numeric bounds; the integer type constraint still applies. The markdown output also picks up an unrelated description-text refresh from regenerating against the current schemas. --- packages/taco/package.json | 3 +- .../taco/schema-docs/condition-schema.json | 1087 +++ .../taco/scripts/schema-docs-generation.ts | 67 +- pnpm-lock.yaml | 7621 ++++++++--------- 4 files changed, 4788 insertions(+), 3990 deletions(-) create mode 100644 packages/taco/schema-docs/condition-schema.json diff --git a/packages/taco/package.json b/packages/taco/package.json index 449d3f85c..b0b34ba9e 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -55,7 +55,8 @@ "axios": "^1.8.4", "dotenv": "^16.5.0", "glob": "^11.0.1", - "modified-zod2md": "0.1.5-modified.4" + "modified-zod2md": "0.1.5-modified.4", + "zod-to-json-schema": "^3.24.5" }, "engines": { "node": ">=18", diff --git a/packages/taco/schema-docs/condition-schema.json b/packages/taco/schema-docs/condition-schema.json new file mode 100644 index 000000000..c4699b63d --- /dev/null +++ b/packages/taco/schema-docs/condition-schema.json @@ -0,0 +1,1087 @@ +{ + "$ref": "#/definitions/ConditionExpression", + "definitions": { + "ConditionExpression": { + "type": "object", + "properties": { + "version": { + "type": "string", + "const": "1.0.0" + }, + "condition": { + "anyOf": [ + { + "type": "object", + "properties": { + "conditionType": { + "type": "string", + "const": "rpc", + "default": "rpc" + }, + "chain": { + "type": "integer", + "minimum": 0 + }, + "method": { + "type": "string", + "enum": [ + "eth_getBalance" + ], + "description": "Only 'eth_getBalance' method is supported" + }, + "parameters": { + "anyOf": [ + { + "type": "array", + "minItems": 2, + "maxItems": 2, + "items": [ + { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "const": ":userAddress", + "description": "This is a context variable that will be replaced at decryption time. It represents the Ethereum address of the requester attempting decryption." + }, + { + "type": "string", + "pattern": "^:[a-zA-Z_][a-zA-Z0-9_]*$", + "description": "A Context Parameter i.e. a placeholder used within conditions and specified at the encryption time, whose value is provided at decryption time." + } + ] + }, + { + "anyOf": [ + { + "anyOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string", + "pattern": "^0x[a-fA-F0-9]{64}$" + }, + { + "type": "string", + "enum": [ + "earliest", + "finalized", + "safe", + "latest", + "pending" + ] + } + ] + }, + { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/parameters/anyOf/0/items/0/anyOf/2" + } + ], + "description": "A block identifier or a context variable that will be replaced with a block identifier at execution time." + } + ], + "description": "Spec requires 2 parameters - an address and a block identifier" + }, + { + "type": "array", + "minItems": 1, + "maxItems": 1, + "items": [ + { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/parameters/anyOf/0/items/0" + } + ], + "description": "Block identifier, which defaults to 'latest' if not specified" + } + ] + }, + "returnValueTest": { + "type": "object", + "properties": { + "index": { + "type": "integer", + "minimum": 0 + }, + "comparator": { + "type": "string", + "enum": [ + "==", + ">", + "<", + ">=", + "<=", + "!=", + "in", + "!in" + ] + }, + "operations": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "object", + "properties": { + "operation": { + "type": "string", + "enum": [ + "+=", + "-=", + "*=", + "/=", + "%=", + "toTokenBaseUnits", + "index", + "round", + "abs", + "avg", + "ceil", + "ethToWei", + "floor", + "len", + "max", + "min", + "sum", + "weiToEth", + "bool", + "float", + "int", + "str", + "fromJson", + "toJson", + "fromHex", + "toHex", + "keccak" + ] + }, + "value": { + "anyOf": [ + { + "anyOf": [ + { + "type": "string", + "description": "Any string that is not a Context Parameter i.e. does not start with `:`." + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "integer", + "format": "int64" + } + ] + }, + { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/parameters/anyOf/0/items/0/anyOf/2" + }, + { + "type": "array", + "items": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/returnValueTest/properties/operations/items/anyOf/0/properties/value" + } + } + ] + } + }, + "required": [ + "operation" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "operation": { + "type": "string", + "const": "create2" + }, + "value": { + "type": "object", + "properties": { + "deployerAddress": { + "anyOf": [ + { + "type": "string", + "pattern": "^0x[0-9a-fA-F]+$" + }, + { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/parameters/anyOf/0/items/0/anyOf/2" + } + ] + }, + "bytecodeHash": { + "anyOf": [ + { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/returnValueTest/properties/operations/items/anyOf/1/properties/value/properties/deployerAddress/anyOf/0" + }, + { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/parameters/anyOf/0/items/0/anyOf/2" + } + ] + } + }, + "required": [ + "deployerAddress", + "bytecodeHash" + ], + "additionalProperties": false, + "description": "Value for create2 operation containing deployerAddress and bytecodeHash for computing CREATE2 addresses locally." + } + }, + "required": [ + "operation", + "value" + ], + "additionalProperties": false + } + ], + "description": "An operation that can be performed on an obtained result." + }, + "minItems": 1, + "maxItems": 5, + "description": "Optional operations to perform on the obtained result before comparison" + }, + "value": { + "anyOf": [ + { + "anyOf": [ + { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/returnValueTest/properties/operations/items/anyOf/0/properties/value/anyOf/0/anyOf/0" + }, + { + "type": "boolean" + }, + { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + { + "type": "integer", + "format": "int64" + } + ], + "description": "Blockchain-compatible parameter values for blockchain RPC API calls and Smart Contracts functions; numbers must be in safe range and bigints must be in the range [-2^255, 2^256-1])." + }, + { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/parameters/anyOf/0/items/0/anyOf/2" + }, + { + "type": "array", + "items": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/returnValueTest/properties/value" + } + } + ] + } + }, + "required": [ + "comparator", + "value" + ], + "additionalProperties": false + } + }, + "required": [ + "chain", + "method", + "parameters", + "returnValueTest" + ], + "additionalProperties": false, + "description": "RPC Condition for calling [Ethereum JSON RPC APIs](https://ethereum.github.io/execution-apis/api-documentation/)" + }, + { + "type": "object", + "properties": { + "conditionType": { + "type": "string", + "const": "time", + "default": "time" + }, + "chain": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/chain" + }, + "method": { + "type": "string", + "const": "blocktime", + "default": "blocktime" + }, + "returnValueTest": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/returnValueTest" + } + }, + "required": [ + "chain", + "returnValueTest" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "conditionType": { + "type": "string", + "const": "context-variable" + }, + "contextVariable": { + "type": "string", + "pattern": "^:[a-zA-Z_][a-zA-Z0-9_]*$", + "description": "The context variable to check (e.g., \":userAddress\", \":customParam\")" + }, + "returnValueTest": { + "type": "object", + "properties": { + "index": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/returnValueTest/properties/index" + }, + "comparator": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/returnValueTest/properties/comparator" + }, + "operations": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/returnValueTest/properties/operations" + }, + "value": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/returnValueTest/properties/operations/items/anyOf/0/properties/value" + } + }, + "required": [ + "comparator", + "value" + ], + "additionalProperties": false, + "description": "Test to perform on a value. Supports comparison operators like ==, >, <, >=, <=, !=, in, !in" + } + }, + "required": [ + "conditionType", + "contextVariable", + "returnValueTest" + ], + "additionalProperties": false, + "description": "Context Variable Condition for performing comparison operations on context variable values." + }, + { + "type": "object", + "properties": { + "conditionType": { + "type": "string", + "const": "contract", + "default": "contract" + }, + "chain": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/chain" + }, + "method": { + "type": "string" + }, + "parameters": { + "type": "array", + "items": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/returnValueTest/properties/value" + } + }, + "returnValueTest": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/returnValueTest" + }, + "contractAddress": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/parameters/anyOf/0/items/0/anyOf/0" + }, + "standardContractType": { + "type": "string", + "enum": [ + "ERC20", + "ERC721" + ] + }, + "functionAbi": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string", + "const": "function" + }, + "inputs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "bool", + "string", + "address", + "address payable", + "bytes1", + "bytes2", + "bytes3", + "bytes4", + "bytes5", + "bytes6", + "bytes7", + "bytes8", + "bytes9", + "bytes10", + "bytes11", + "bytes12", + "bytes13", + "bytes14", + "bytes15", + "bytes16", + "bytes17", + "bytes18", + "bytes19", + "bytes20", + "bytes21", + "bytes22", + "bytes23", + "bytes24", + "bytes25", + "bytes26", + "bytes27", + "bytes28", + "bytes29", + "bytes30", + "bytes31", + "bytes32", + "bytes", + "uint8", + "uint16", + "uint24", + "uint32", + "uint40", + "uint48", + "uint56", + "uint64", + "uint72", + "uint80", + "uint88", + "uint96", + "uint104", + "uint112", + "uint120", + "uint128", + "uint136", + "uint144", + "uint152", + "uint160", + "uint168", + "uint176", + "uint184", + "uint192", + "uint200", + "uint208", + "uint216", + "uint224", + "uint232", + "uint240", + "uint248", + "uint256", + "int8", + "int16", + "int24", + "int32", + "int40", + "int48", + "int56", + "int64", + "int72", + "int80", + "int88", + "int96", + "int104", + "int112", + "int120", + "int128", + "int136", + "int144", + "int152", + "int160", + "int168", + "int176", + "int184", + "int192", + "int200", + "int208", + "int216", + "int224", + "int232", + "int240", + "int248", + "int256" + ] + }, + "internalType": { + "type": "string", + "enum": [ + "bool", + "string", + "address", + "address payable", + "bytes1", + "bytes2", + "bytes3", + "bytes4", + "bytes5", + "bytes6", + "bytes7", + "bytes8", + "bytes9", + "bytes10", + "bytes11", + "bytes12", + "bytes13", + "bytes14", + "bytes15", + "bytes16", + "bytes17", + "bytes18", + "bytes19", + "bytes20", + "bytes21", + "bytes22", + "bytes23", + "bytes24", + "bytes25", + "bytes26", + "bytes27", + "bytes28", + "bytes29", + "bytes30", + "bytes31", + "bytes32", + "bytes", + "uint8", + "uint16", + "uint24", + "uint32", + "uint40", + "uint48", + "uint56", + "uint64", + "uint72", + "uint80", + "uint88", + "uint96", + "uint104", + "uint112", + "uint120", + "uint128", + "uint136", + "uint144", + "uint152", + "uint160", + "uint168", + "uint176", + "uint184", + "uint192", + "uint200", + "uint208", + "uint216", + "uint224", + "uint232", + "uint240", + "uint248", + "uint256", + "int8", + "int16", + "int24", + "int32", + "int40", + "int48", + "int56", + "int64", + "int72", + "int80", + "int88", + "int96", + "int104", + "int112", + "int120", + "int128", + "int136", + "int144", + "int152", + "int160", + "int168", + "int176", + "int184", + "int192", + "int200", + "int208", + "int216", + "int224", + "int232", + "int240", + "int248", + "int256" + ] + } + }, + "required": [ + "name", + "type", + "internalType" + ], + "additionalProperties": false + }, + "minItems": 0 + }, + "outputs": { + "type": "array", + "items": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/3/properties/functionAbi/properties/inputs/items" + }, + "minItems": 1 + }, + "stateMutability": { + "type": "string", + "enum": [ + "view", + "pure" + ] + } + }, + "required": [ + "name", + "type", + "inputs", + "outputs", + "stateMutability" + ], + "additionalProperties": false + } + }, + "required": [ + "chain", + "method", + "parameters", + "returnValueTest", + "contractAddress" + ], + "additionalProperties": false, + "description": "RPC Condition for calling [Ethereum JSON RPC APIs](https://ethereum.github.io/execution-apis/api-documentation/)" + }, + { + "type": "object", + "properties": { + "conditionType": { + "type": "string", + "const": "ecdsa", + "default": "ecdsa" + }, + "message": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/parameters/anyOf/0/items/0/anyOf/2" + } + ], + "default": ":message" + }, + "signature": { + "anyOf": [ + { + "type": "string", + "pattern": "^[0-9a-fA-F]+$", + "description": "A string containing only hexadecimal characters (0-9, a-f, A-F)" + }, + { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/parameters/anyOf/0/items/0/anyOf/2" + } + ], + "default": ":signature" + }, + "verifyingKey": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/4/properties/signature/anyOf/0" + }, + "curve": { + "type": "string", + "enum": [ + "SECP256k1", + "NIST256p", + "NIST384p", + "NIST521p", + "Ed25519", + "BRAINPOOLP256r1" + ] + } + }, + "required": [ + "verifyingKey", + "curve" + ], + "additionalProperties": false, + "description": "ECDSA Condition for verifying the authenticity of a message using ECDSA signatures." + }, + { + "type": "object", + "properties": { + "conditionType": { + "type": "string", + "const": "json", + "default": "json" + }, + "data": { + "type": "string", + "pattern": "^:[a-zA-Z_][a-zA-Z0-9_]*$", + "description": "Context variable that resolves to JSON data at decryption time." + }, + "query": { + "type": "string", + "description": "Optional JSONPath query to extract a specific value from the data." + }, + "returnValueTest": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/2/properties/returnValueTest" + } + }, + "required": [ + "data", + "returnValueTest" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "conditionType": { + "type": "string", + "const": "json-api", + "default": "json-api" + }, + "endpoint": { + "type": "string", + "format": "uri" + }, + "parameters": { + "type": "object", + "additionalProperties": {} + }, + "query": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/5/properties/query", + "description": "A string containing either a valid JSON Path Expression, or a Context Parameter." + }, + "authorizationToken": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/parameters/anyOf/0/items/0/anyOf/2", + "description": "A Context Parameter i.e. a placeholder used within conditions and specified at the encryption time, whose value is provided at decryption time." + }, + "authorizationType": { + "type": "string", + "enum": [ + "Bearer", + "Basic", + "X-API-Key" + ], + "description": "The type of authorization to use when making the request." + }, + "returnValueTest": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/2/properties/returnValueTest" + } + }, + "required": [ + "endpoint", + "returnValueTest" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "conditionType": { + "type": "string", + "const": "json-rpc", + "default": "json-rpc" + }, + "endpoint": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/6/properties/endpoint" + }, + "method": { + "type": "string" + }, + "params": { + "anyOf": [ + { + "type": "array", + "items": {} + }, + { + "type": "object", + "additionalProperties": {} + } + ] + }, + "query": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/5/properties/query", + "description": "A string containing either a valid JSON Path Expression, or a Context Parameter." + }, + "authorizationToken": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/parameters/anyOf/0/items/0/anyOf/2", + "description": "A Context Parameter i.e. a placeholder used within conditions and specified at the encryption time, whose value is provided at decryption time." + }, + "authorizationType": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/6/properties/authorizationType", + "description": "The type of authorization to use when making the request." + }, + "returnValueTest": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/2/properties/returnValueTest" + } + }, + "required": [ + "endpoint", + "method", + "returnValueTest" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "conditionType": { + "type": "string", + "const": "jwt", + "default": "jwt" + }, + "publicKey": { + "type": "string" + }, + "expectedIssuer": { + "type": "string" + }, + "jwtToken": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/parameters/anyOf/0/items/0/anyOf/2", + "default": ":jwtToken", + "description": "A Context Parameter i.e. a placeholder used within conditions and specified at the encryption time, whose value is provided at decryption time." + } + }, + "required": [ + "publicKey" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "conditionType": { + "type": "string", + "const": "signing-attribute", + "default": "signing-attribute" + }, + "signingObjectContextVar": { + "type": "string", + "const": ":signingConditionObject", + "default": ":signingConditionObject", + "description": "The context variable that will be replaced with the signing object at signing" + }, + "attributeName": { + "type": "string", + "minLength": 1, + "description": "The name of the attribute to check" + }, + "returnValueTest": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/returnValueTest" + } + }, + "required": [ + "attributeName", + "returnValueTest" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "conditionType": { + "type": "string", + "const": "signing-abi-attribute", + "default": "signing-abi-attribute" + }, + "signingObjectContextVar": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/9/properties/signingObjectContextVar" + }, + "attributeName": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/9/properties/attributeName" + }, + "abiValidation": { + "type": "object", + "properties": { + "allowedAbiCalls": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "object", + "properties": { + "parameterIndex": { + "type": "integer", + "minimum": 0, + "description": "Index of parameter to check within abi calldata." + }, + "subIndices": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0 + }, + "description": "Sequential indices for navigating nested structures (arrays and tuples). The ABI type determines interpretation at each step: array types consume an index and access that element, tuple types consume an index and access that field." + }, + "returnValueTest": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/returnValueTest", + "description": "Comparison check for value within calldata" + }, + "nestedAbiValidation": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/10/properties/abiValidation", + "description": "Additional checks for nested abi calldata" + } + }, + "required": [ + "parameterIndex" + ], + "additionalProperties": false + } + } + } + }, + "required": [ + "allowedAbiCalls" + ], + "additionalProperties": false, + "description": "A map of allowed ABI calls with their respective parameter validations." + } + }, + "required": [ + "attributeName", + "abiValidation" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "conditionType": { + "type": "string", + "const": "compound", + "default": "compound" + }, + "operator": { + "type": "string", + "enum": [ + "and", + "or", + "not" + ] + }, + "operands": { + "type": "array", + "items": { + "$ref": "#/definitions/ConditionExpression/properties/condition" + }, + "minItems": 1, + "maxItems": 5 + } + }, + "required": [ + "operator", + "operands" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "conditionType": { + "type": "string", + "const": "sequential", + "default": "sequential" + }, + "conditionVariables": { + "type": "array", + "items": { + "type": "object", + "properties": { + "varName": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/returnValueTest/properties/operations/items/anyOf/0/properties/value/anyOf/0/anyOf/0" + }, + "condition": { + "$ref": "#/definitions/ConditionExpression/properties/condition" + }, + "operations": { + "$ref": "#/definitions/ConditionExpression/properties/condition/anyOf/0/properties/returnValueTest/properties/operations", + "description": "Optional operations to perform on the obtained condition result before storing it" + } + }, + "required": [ + "varName", + "condition" + ], + "additionalProperties": false, + "description": "Executes a condition and stores the result as a variable within a sequential condition." + }, + "minItems": 2, + "maxItems": 20 + } + }, + "required": [ + "conditionVariables" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "conditionType": { + "type": "string", + "const": "if-then-else", + "default": "if-then-else" + }, + "ifCondition": { + "$ref": "#/definitions/ConditionExpression/properties/condition" + }, + "thenCondition": { + "$ref": "#/definitions/ConditionExpression/properties/condition" + }, + "elseCondition": { + "anyOf": [ + { + "$ref": "#/definitions/ConditionExpression/properties/condition" + }, + { + "type": "boolean" + } + ] + } + }, + "required": [ + "ifCondition", + "thenCondition", + "elseCondition" + ], + "additionalProperties": false + } + ] + } + }, + "required": [ + "version", + "condition" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} diff --git a/packages/taco/scripts/schema-docs-generation.ts b/packages/taco/scripts/schema-docs-generation.ts index 55d45aa69..0a4f485e2 100644 --- a/packages/taco/scripts/schema-docs-generation.ts +++ b/packages/taco/scripts/schema-docs-generation.ts @@ -13,6 +13,10 @@ import { mkdir, writeFile } from 'fs/promises'; import { glob } from 'glob'; import * as path from 'path'; +import { z } from 'zod'; +import { zodToJsonSchema } from 'zod-to-json-schema'; + +import { anyConditionSchema } from '../src/conditions/schemas/utils'; // Because of an issue with the bundleRequire that is used within zod2md, the importModules function has been modified to work and the files that calls it needed to be copied. @@ -80,6 +84,7 @@ const schemaSource = './src/conditions/schemas/export-for-zod-doc-gen.ts'; const schemaOutputDirectory = './schema-docs/'; // The directory where Markdown will be saved const schemaOutputFile = 'condition-schemas.md'; // File name where the Markdown will be saved +const jsonSchemaOutputFile = 'condition-schema.json'; // JSON Schema for editor / LLM consumption const appendedText = ` ## More resources @@ -118,4 +123,64 @@ async function generateMdFiles() { ); } -generateMdFiles(); +// Generates a standard JSON Schema document describing the full +// ConditionExpression envelope ({version, condition}). Editors that +// understand $schema (VS Code, JetBrains, etc.) and LLMs both consume +// this format directly, giving inline validation and structured output +// without depending on @nucypher/taco at runtime. +async function generateJsonSchema() { + try { + const conditionExpressionSchema = z.object({ + version: z.literal('1.0.0'), + condition: anyConditionSchema, + }); + + const jsonSchema = zodToJsonSchema(conditionExpressionSchema, { + name: 'ConditionExpression', + $refStrategy: 'root', + }); + + await mkdir(schemaOutputDirectory, { recursive: true }); + // BigInt bounds (e.g. uint256 ranges) are not representable in + // standard JSON Schema, which requires numeric bounds. Walk the + // tree and drop any minimum/maximum whose value is a BigInt — the + // type constraint (`integer`) still applies. + const stripBigIntBounds = (node: unknown): void => { + if (Array.isArray(node)) { + node.forEach(stripBigIntBounds); + return; + } + if (node && typeof node === 'object') { + const obj = node as Record; + for (const key of ['minimum', 'maximum']) { + if (typeof obj[key] === 'bigint') { + delete obj[key]; + } + } + for (const v of Object.values(obj)) { + stripBigIntBounds(v); + } + } + }; + stripBigIntBounds(jsonSchema); + + await writeFile( + schemaOutputDirectory + jsonSchemaOutputFile, + JSON.stringify(jsonSchema, null, 2) + '\n', + ); + + console.info( + 'Condition JSON Schema generated successfully at:', + schemaOutputDirectory + jsonSchemaOutputFile, + ); + } catch (error) { + console.error('Failed to generate JSON Schema:', error); + } +} + +async function main() { + await generateMdFiles(); + await generateJsonSchema(); +} + +main(); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cc9bcfd09..54a258136 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,13 +17,13 @@ importers: dependencies: '@changesets/cli': specifier: ^2.28.1 - version: 2.30.0(@types/node@24.3.0) + version: 2.29.5 '@nucypher/nucypher-core': specifier: ^0.15.1-dev.3 version: 0.15.1-dev.3 ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) devDependencies: '@skypack/package-check': specifier: ^0.2.2 @@ -33,31 +33,31 @@ importers: version: 24.3.0 '@typescript-eslint/eslint-plugin': specifier: ^6.21.0 - version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^6.21.0 - version: 6.21.0(eslint@8.57.1)(typescript@5.9.3) + version: 6.21.0(eslint@8.57.1)(typescript@5.8.3) '@vitest/coverage-v8': specifier: ^3.2.4 - version: 3.2.4(vitest@3.2.4(@types/node@24.3.0)(jiti@2.6.1)(jsdom@16.7.0(bufferutil@4.1.0))(terser@5.46.1)) + version: 3.2.4(vitest@3.0.9(@types/node@24.3.0)(jiti@2.4.2)(jsdom@16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(terser@5.43.1)(yaml@2.8.0)) bundlemon: specifier: ^3.1.0 - version: 3.1.0(typescript@5.9.3) + version: 3.1.0(typescript@5.8.3) eslint: specifier: ^8.57.1 version: 8.57.1 eslint-config-prettier: specifier: ^9.1.0 - version: 9.1.2(eslint@8.57.1) + version: 9.1.0(eslint@8.57.1) eslint-config-typestrict: specifier: ^1.0.5 - version: 1.0.5(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3))(eslint-plugin-sonarjs@4.0.2(eslint@8.57.1)) + version: 1.0.5(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3))(eslint-plugin-sonarjs@3.0.3(eslint@8.57.1)) eslint-plugin-eslint-comments: specifier: ^3.2.0 version: 3.2.0(eslint@8.57.1) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) + version: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1) eslint-plugin-no-only-tests: specifier: ^3.3.0 version: 3.3.0 @@ -66,7 +66,7 @@ importers: version: 10.0.0(eslint@8.57.1) eslint-plugin-unused-imports: specifier: ^4.1.4 - version: 4.4.1(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) + version: 4.1.4(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1) gh-pages: specifier: ^6.3.0 version: 6.3.0 @@ -75,67 +75,67 @@ importers: version: 4.1.5 prettier: specifier: ^3.5.3 - version: 3.8.2 + version: 3.6.1 prettier-plugin-organize-imports: specifier: ^3.2.4 - version: 3.2.4(prettier@3.8.2)(typescript@5.9.3) + version: 3.2.4(prettier@3.6.1)(typescript@5.8.3) sort-package-json: specifier: ^2.15.1 version: 2.15.1 ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@24.3.0)(typescript@5.9.3) + version: 10.9.2(@types/node@24.3.0)(typescript@5.8.3) ts-unused-exports: specifier: ^10.1.0 - version: 10.1.0(typescript@5.9.3) + version: 10.1.0(typescript@5.8.3) typedoc: specifier: ^0.25.13 - version: 0.25.13(typescript@5.9.3) + version: 0.25.13(typescript@5.8.3) typedoc-plugin-coverage: specifier: ^2.2.0 - version: 2.2.0(typedoc@0.25.13(typescript@5.9.3)) + version: 2.2.0(typedoc@0.25.13(typescript@5.8.3)) typedoc-plugin-missing-exports: specifier: ^2.3.0 - version: 2.3.0(typedoc@0.25.13(typescript@5.9.3)) + version: 2.3.0(typedoc@0.25.13(typescript@5.8.3)) typedoc-plugin-zod: specifier: ^1.4.0 - version: 1.4.3(typedoc@0.25.13(typescript@5.9.3)) + version: 1.4.2(typedoc@0.25.13(typescript@5.8.3)) typescript: specifier: ^5.8.2 - version: 5.9.3 + version: 5.8.3 vitest: specifier: ^3.0.9 - version: 3.2.4(@types/node@24.3.0)(jiti@2.6.1)(jsdom@16.7.0(bufferutil@4.1.0))(terser@5.46.1) + version: 3.0.9(@types/node@24.3.0)(jiti@2.4.2)(jsdom@16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(terser@5.43.1)(yaml@2.8.0) demos/taco-demo: dependencies: '@irys/sdk': specifier: ^0.1.24 - version: 0.1.24(@types/node@24.3.0)(arweave@1.15.7)(bufferutil@4.1.0)(got@11.8.6)(typescript@4.9.5)(utf-8-validate@6.0.6) + version: 0.1.24(arweave@1.15.7)(bufferutil@4.0.9)(got@11.8.6)(typescript@4.9.5)(utf-8-validate@5.0.10) '@nucypher/taco': specifier: ^0.6.0 - version: 0.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 0.6.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@nucypher/taco-auth': specifier: ^0.3.0 - version: 0.3.0(bufferutil@4.1.0)(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(utf-8-validate@6.0.6) + version: 0.3.0(bufferutil@4.0.9)(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@usedapp/core': specifier: ^1.2.16 - version: 1.2.16(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(node-fetch@2.7.0)(react@18.3.1) + version: 1.2.16(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(node-fetch@2.7.0)(react@18.3.1) buffer: specifier: ^6.0.3 version: 6.0.3 ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) file-loader: specifier: ^6.2.0 - version: 6.2.0(webpack@5.106.1) + version: 6.2.0(webpack@5.99.9) react: specifier: ^18.3.1 version: 18.3.1 react-copy-to-clipboard: specifier: ^5.1.0 - version: 5.1.1(react@18.3.1) + version: 5.1.0(react@18.3.1) react-dom: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) @@ -145,28 +145,28 @@ importers: devDependencies: '@pmmmwh/react-refresh-webpack-plugin': specifier: ^0.6.0 - version: 0.6.2(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.3)(webpack@5.106.1) + version: 0.6.1(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.2)(webpack@5.99.9) '@types/react': specifier: ^18.3.20 - version: 18.3.28 + version: 18.3.23 '@types/react-copy-to-clipboard': specifier: ^5.0.7 version: 5.0.7 '@types/react-dom': specifier: ^18.3.5 - version: 18.3.7(@types/react@18.3.28) + version: 18.3.7(@types/react@18.3.23) copy-webpack-plugin: specifier: ^13.0.0 - version: 13.0.1(webpack@5.106.1) + version: 13.0.0(webpack@5.99.9) crypto-browserify: specifier: ^3.12.1 version: 3.12.1 esbuild-loader: specifier: ^2.21.0 - version: 2.21.0(webpack@5.106.1) + version: 2.21.0(webpack@5.99.9) html-webpack-plugin: specifier: ^5.6.3 - version: 5.6.6(webpack@5.106.1) + version: 5.6.3(webpack@5.99.9) process: specifier: ^0.11.10 version: 0.11.10 @@ -187,40 +187,40 @@ importers: version: 1.1.2 webpack: specifier: ^5.99.9 - version: 5.106.1(webpack-cli@6.0.1) + version: 5.99.9(webpack-cli@6.0.1) webpack-cli: specifier: ^6.0.1 - version: 6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1) + version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) webpack-dev-server: specifier: ^5.2.2 - version: 5.2.3(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack-cli@6.0.1)(webpack@5.106.1) + version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) demos/taco-nft-demo: dependencies: '@nucypher/taco': specifier: ^0.6.0 - version: 0.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 0.6.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@nucypher/taco-auth': specifier: ^0.3.0 - version: 0.3.0(bufferutil@4.1.0)(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(utf-8-validate@6.0.6) + version: 0.3.0(bufferutil@4.0.9)(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@usedapp/core': specifier: ^1.2.16 - version: 1.2.16(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(node-fetch@2.7.0)(react@18.3.1) + version: 1.2.16(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(node-fetch@2.7.0)(react@18.3.1) buffer: specifier: ^6.0.3 version: 6.0.3 ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) file-loader: specifier: ^6.2.0 - version: 6.2.0(webpack@5.106.1) + version: 6.2.0(webpack@5.99.9) react: specifier: ^18.3.1 version: 18.3.1 react-copy-to-clipboard: specifier: ^5.1.0 - version: 5.1.1(react@18.3.1) + version: 5.1.0(react@18.3.1) react-dom: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) @@ -230,25 +230,25 @@ importers: devDependencies: '@pmmmwh/react-refresh-webpack-plugin': specifier: ^0.6.0 - version: 0.6.2(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.3)(webpack@5.106.1) + version: 0.6.1(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.2)(webpack@5.99.9) '@types/react': specifier: ^18.3.20 - version: 18.3.28 + version: 18.3.23 '@types/react-copy-to-clipboard': specifier: ^5.0.7 version: 5.0.7 '@types/react-dom': specifier: ^18.3.5 - version: 18.3.7(@types/react@18.3.28) + version: 18.3.7(@types/react@18.3.23) copy-webpack-plugin: specifier: ^13.0.0 - version: 13.0.1(webpack@5.106.1) + version: 13.0.0(webpack@5.99.9) esbuild-loader: specifier: ^2.21.0 - version: 2.21.0(webpack@5.106.1) + version: 2.21.0(webpack@5.99.9) html-webpack-plugin: specifier: ^5.6.3 - version: 5.6.6(webpack@5.106.1) + version: 5.6.3(webpack@5.99.9) react-refresh: specifier: ^0.17.0 version: 0.17.0 @@ -263,13 +263,13 @@ importers: version: 4.9.5 webpack: specifier: ^5.99.9 - version: 5.106.1(webpack-cli@6.0.1) + version: 5.99.9(webpack-cli@6.0.1) webpack-cli: specifier: ^6.0.1 - version: 6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1) + version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) webpack-dev-server: specifier: ^5.2.2 - version: 5.2.3(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack-cli@6.0.1)(webpack@5.106.1) + version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) examples/pre/nextjs: dependencies: @@ -290,10 +290,10 @@ importers: version: 8.57.0 eslint-config-next: specifier: 14.0.4 - version: 14.0.4(eslint@8.57.0)(typescript@5.9.3) + version: 14.0.4(eslint@8.57.0)(typescript@5.8.3) ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) next: specifier: 15.3.4 version: 15.3.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -311,10 +311,10 @@ importers: version: link:../../../packages/pre dotenv: specifier: ^16.4.7 - version: 16.6.1 + version: 16.5.0 ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) examples/pre/react: dependencies: @@ -323,7 +323,7 @@ importers: version: link:../../../packages/pre ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) react: specifier: ^18.3.1 version: 18.3.1 @@ -336,13 +336,13 @@ importers: version: 24.3.0 '@types/react': specifier: ^18.3.20 - version: 18.3.28 + version: 18.3.23 '@types/react-dom': specifier: ^18.3.5 - version: 18.3.7(@types/react@18.3.28) + version: 18.3.7(@types/react@18.3.23) react-scripts: specifier: ^5.0.1 - version: 5.0.1(@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0))(@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0))(@types/babel__core@7.20.5)(bufferutil@4.1.0)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3))(type-fest@0.21.3)(typescript@5.9.3) + version: 5.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.27.4))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.27.4))(@types/babel__core@7.20.5)(bufferutil@4.0.9)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(type-fest@0.21.3)(typescript@5.8.3)(utf-8-validate@5.0.10) examples/pre/webpack-5: dependencies: @@ -352,22 +352,22 @@ importers: devDependencies: copy-webpack-plugin: specifier: ^13.0.0 - version: 13.0.1(webpack@5.106.1) + version: 13.0.0(webpack@5.99.9) esbuild-loader: specifier: ^2.21.0 - version: 2.21.0(webpack@5.106.1) + version: 2.21.0(webpack@5.99.9) ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) webpack: specifier: ^5.99.9 - version: 5.106.1(webpack-cli@6.0.1) + version: 5.99.9(webpack-cli@6.0.1) webpack-cli: specifier: ^6.0.1 - version: 6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1) + version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) webpack-dev-server: specifier: ^5.2.2 - version: 5.2.3(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack-cli@6.0.1)(webpack@5.106.1) + version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) examples/taco/nextjs: dependencies: @@ -397,7 +397,7 @@ importers: version: 14.0.4(eslint@8.57.0)(typescript@5.2.2) ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) next: specifier: 15.3.4 version: 15.3.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -421,10 +421,10 @@ importers: version: link:../../../packages/taco-auth dotenv: specifier: ^16.5.0 - version: 16.6.1 + version: 16.5.0 ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) examples/taco/react: dependencies: @@ -439,7 +439,7 @@ importers: version: link:../../../packages/taco-auth ethers: specifier: ^5.7.2 - version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) react: specifier: ^18.3.1 version: 18.3.1 @@ -452,13 +452,13 @@ importers: version: 24.3.0 '@types/react': specifier: ^18.3.20 - version: 18.3.28 + version: 18.3.23 '@types/react-dom': specifier: ^18.3.5 - version: 18.3.7(@types/react@18.3.28) + version: 18.3.7(@types/react@18.3.23) react-scripts: specifier: ^5.0.1 - version: 5.0.1(@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0))(@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0))(@types/babel__core@7.20.5)(bufferutil@4.1.0)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3))(type-fest@0.21.3)(typescript@5.9.3) + version: 5.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.27.4))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.27.4))(@types/babel__core@7.20.5)(bufferutil@4.0.9)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(type-fest@0.21.3)(typescript@5.8.3)(utf-8-validate@5.0.10) examples/taco/webpack-5: dependencies: @@ -470,23 +470,23 @@ importers: version: link:../../../packages/taco-auth ethers: specifier: ^5.7.2 - version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) devDependencies: copy-webpack-plugin: specifier: ^13.0.0 - version: 13.0.1(webpack@5.106.1) + version: 13.0.0(webpack@5.99.9) esbuild-loader: specifier: ^2.21.0 - version: 2.21.0(webpack@5.106.1) + version: 2.21.0(webpack@5.99.9) webpack: specifier: ^5.99.9 - version: 5.106.1(webpack-cli@6.0.1) + version: 5.99.9(webpack-cli@6.0.1) webpack-cli: specifier: ^6.0.1 - version: 6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1) + version: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) webpack-dev-server: specifier: ^5.2.2 - version: 5.2.3(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack-cli@6.0.1)(webpack@5.106.1) + version: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) packages/pre: dependencies: @@ -498,7 +498,7 @@ importers: version: link:../shared ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) devDependencies: '@nucypher/test-utils': specifier: workspace:* @@ -511,7 +511,7 @@ importers: version: 5.8.0 '@ethersproject/providers': specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@nucypher/nucypher-contracts': specifier: ^0.26.0-alpha.3 version: 0.26.0-alpha.3 @@ -520,44 +520,44 @@ importers: version: 0.15.1-dev.3 axios: specifier: ^1.8.4 - version: 1.15.0 + version: 1.10.0 deep-equal: specifier: ^2.2.3 version: 2.2.3 ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) qs: specifier: ^6.14.0 - version: 6.15.1 + version: 6.14.0 zod: specifier: ^3.24.2 - version: 3.25.76 + version: 3.25.67 devDependencies: '@nucypher/test-utils': specifier: workspace:* version: link:../test-utils '@typechain/ethers-v5': specifier: ^11.1.2 - version: 11.1.2(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(typechain@8.3.2(typescript@5.9.3))(typescript@5.9.3) + version: 11.1.2(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.8.3))(typescript@5.8.3) '@types/deep-equal': specifier: ^1.0.4 version: 1.0.4 '@types/qs': specifier: ^6.9.18 - version: 6.15.0 + version: 6.14.0 '@types/tmp': specifier: ^0.2.6 version: 0.2.6 cz-conventional-changelog: specifier: ^3.3.0 - version: 3.3.0(@types/node@24.3.0)(typescript@5.9.3) + version: 3.3.0(@types/node@24.3.0)(typescript@5.8.3) standard-version: specifier: ^9.5.0 version: 9.5.0 typechain: specifier: ^8.3.2 - version: 8.3.2(typescript@5.9.3) + version: 8.3.2(typescript@5.8.3) packages/taco: dependencies: @@ -575,32 +575,35 @@ importers: version: link:../taco-auth ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) semver: specifier: ^7.7.1 - version: 7.7.4 + version: 7.7.2 zod: specifier: ^3.24.2 - version: 3.25.76 + version: 3.25.67 devDependencies: '@nucypher/test-utils': specifier: workspace:* version: link:../test-utils '@types/semver': specifier: ^7.7.0 - version: 7.7.1 + version: 7.7.0 axios: specifier: ^1.8.4 - version: 1.15.0 + version: 1.10.0 dotenv: specifier: ^16.5.0 - version: 16.6.1 + version: 16.5.0 glob: specifier: ^11.0.1 - version: 11.1.0 + version: 11.0.3 modified-zod2md: specifier: 0.1.5-modified.4 - version: 0.1.5-modified.4(zod@3.25.76) + version: 0.1.5-modified.4(zod@3.25.67) + zod-to-json-schema: + specifier: ^3.24.5 + version: 3.25.2(zod@3.25.67) packages/taco-auth: dependencies: @@ -612,10 +615,10 @@ importers: version: link:../shared siwe: specifier: ^3.0.0 - version: 3.0.0(ethers@5.8.0(bufferutil@4.1.0)) + version: 3.0.0(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) zod: specifier: ^3.24.2 - version: 3.25.76 + version: 3.25.67 devDependencies: '@nucypher/test-utils': specifier: workspace:* @@ -637,10 +640,10 @@ importers: version: 1.15.0 ethers: specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) vitest: specifier: ^3.0.9 - version: 3.2.4(@types/node@24.3.0)(jiti@2.6.1)(jsdom@16.7.0(bufferutil@4.1.0))(terser@5.46.1) + version: 3.2.4(@types/node@24.3.0)(jiti@2.4.2)(jsdom@16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(terser@5.43.1)(yaml@2.8.0) packages: @@ -652,26 +655,25 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@apideck/better-ajv-errors@0.3.7': - resolution: {integrity: sha512-TajUJwGWbDwkCx/CZi7tRE8PVB7simCvKJfHUsSdvps+aTM/PDPP4gkLmKnc+x3CE//y9i/nj74GqdL/hwk7Iw==} + '@apideck/better-ajv-errors@0.3.6': + resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==} engines: {node: '>=10'} peerDependencies: ajv: '>=8' - '@aptos-labs/aptos-cli@1.1.1': - resolution: {integrity: sha512-sB7CokCM6s76SLJmccysbnFR+MDik6udKfj2+9ZsmTLV0/t73veIeCDKbvWJmbW267ibx4HiGbPI7L+1+yjEbQ==} + '@aptos-labs/aptos-cli@1.0.2': + resolution: {integrity: sha512-PYPsd0Kk3ynkxNfe3S4fanI3DiUICCoh4ibQderbvjPFL5A0oK6F4lPEO2t0MDsQySTk2t4vh99Xjy6Bd9y+aQ==} hasBin: true '@aptos-labs/aptos-client@1.2.0': resolution: {integrity: sha512-pBlIAT/W+Qa0TOr/318U8r0Gxw/jfyRLcvDGMEXgcVrPqO9Qhwsmozw6LPPIZ963FB7smwIaMeexWFDs3zijcg==} engines: {node: '>=15.10.0'} - deprecated: This version is deprecated. Please upgrade to version 2.1.0 or later. peerDependencies: axios: ^1.8.4 got: ^11.8.6 - '@aptos-labs/aptos-dynamic-transaction-composer@0.1.6': - resolution: {integrity: sha512-reIq7g/J02nRT6XILCX51zA9n7n0lwxZQB56fVaE2D3WB5Lt6qgw71ITlt2mvng/x/r8gY7bYyyUhKAx4hMuBw==} + '@aptos-labs/aptos-dynamic-transaction-composer@0.1.3': + resolution: {integrity: sha512-bJl+Zq5QbhpcPIJakAkl9tnT3T02mxCYhZThQDhUmjsOZ5wMRlKJ0P7aaq1dmlybSHkVj7vRgOy2t86/NDKKng==} '@aptos-labs/script-composer-pack@0.0.9': resolution: {integrity: sha512-Y3kA1rgF65HETgoTn2omDymsgO+fnZouPLrKJZ9sbxTGdOekIIHtGee3A2gk84eCqa02ZKBumZmP+IDCXRtU/g==} @@ -679,73 +681,68 @@ packages: '@aptos-labs/ts-sdk@1.39.0': resolution: {integrity: sha512-VFEWZsqb8Mto8XbLK8lDRdUvyHjp+geiwFxRzRcQK6HftMGB4bYuEsOI2Vy6u/TqkUft8DvmpV5yX027R5/SMQ==} engines: {node: '>=20.0.0'} - deprecated: This version is deprecated, please upgrade to 5.2.1, or the latest version '@astronautlabs/jsonpath@1.1.2': resolution: {integrity: sha512-FqL/muoreH7iltYC1EB5Tvox5E8NSOOPGkgns4G+qxRKl6k5dxEVljUjB5NcKESzkqwnUqWjSZkL61XGYOuV+A==} - '@babel/code-frame@7.29.0': - resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.29.0': - resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + '@babel/compat-data@7.27.5': + resolution: {integrity: sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==} engines: {node: '>=6.9.0'} - '@babel/core@7.29.0': - resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + '@babel/core@7.27.4': + resolution: {integrity: sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==} engines: {node: '>=6.9.0'} - '@babel/eslint-parser@7.28.6': - resolution: {integrity: sha512-QGmsKi2PBO/MHSQk+AAgA9R6OHQr+VqnniFE0eMWZcVcfBZoA2dKn2hUsl3Csg/Plt9opRUWdY7//VXsrIlEiA==} + '@babel/eslint-parser@7.27.5': + resolution: {integrity: sha512-HLkYQfRICudzcOtjGwkPvGc5nF1b4ljLZh1IRDj50lRZ718NAKVgQpIAUX8bfg6u/yuSKY3L7E0YzIV+OxrB8Q==} engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} peerDependencies: '@babel/core': ^7.11.0 eslint: ^7.5.0 || ^8.0.0 || ^9.0.0 - '@babel/generator@7.29.1': - resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + '@babel/generator@7.27.5': + resolution: {integrity: sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==} engines: {node: '>=6.9.0'} '@babel/helper-annotate-as-pure@7.27.3': resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.28.6': - resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} engines: {node: '>=6.9.0'} - '@babel/helper-create-class-features-plugin@7.28.6': - resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==} + '@babel/helper-create-class-features-plugin@7.27.1': + resolution: {integrity: sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-create-regexp-features-plugin@7.28.5': - resolution: {integrity: sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==} + '@babel/helper-create-regexp-features-plugin@7.27.1': + resolution: {integrity: sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-define-polyfill-provider@0.6.8': - resolution: {integrity: sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==} + '@babel/helper-define-polyfill-provider@0.6.4': + resolution: {integrity: sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - '@babel/helper-globals@7.28.0': - resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-member-expression-to-functions@7.28.5': - resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + '@babel/helper-member-expression-to-functions@7.27.1': + resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.28.6': - resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.28.6': - resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + '@babel/helper-module-transforms@7.27.3': + resolution: {integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -754,8 +751,8 @@ packages: resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.28.6': - resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} engines: {node: '>=6.9.0'} '@babel/helper-remap-async-to-generator@7.27.1': @@ -764,8 +761,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-replace-supers@7.28.6': - resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} + '@babel/helper-replace-supers@7.27.1': + resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -778,29 +775,29 @@ packages: resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.28.5': - resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} engines: {node: '>=6.9.0'} '@babel/helper-validator-option@7.27.1': resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helper-wrap-function@7.28.6': - resolution: {integrity: sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==} + '@babel/helper-wrap-function@7.27.1': + resolution: {integrity: sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.29.2': - resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + '@babel/helpers@7.27.6': + resolution: {integrity: sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==} engines: {node: '>=6.9.0'} - '@babel/parser@7.29.2': - resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + '@babel/parser@7.27.5': + resolution: {integrity: sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5': - resolution: {integrity: sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==} + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1': + resolution: {integrity: sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -823,8 +820,8 @@ packages: peerDependencies: '@babel/core': ^7.13.0 - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6': - resolution: {integrity: sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==} + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.27.1': + resolution: {integrity: sha512-6BpaYGDavZqkI6yT+KSPdpZFfpnd68UKXbcjI9pJ13pvHhPrCKWOOLp+ysvMeA+DxnhuPpgIaRpxRxo5A9t5jw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -836,8 +833,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-proposal-decorators@7.29.0': - resolution: {integrity: sha512-CVBVv3VY/XRMxRYq5dwr2DS7/MvqPm23cOCjbwNnVrfOqcWlnefua1uUs0sjdKOGjvPUG633o07uWzJq4oI6dA==} + '@babel/plugin-proposal-decorators@7.27.1': + resolution: {integrity: sha512-DTxe4LBPrtFdsWzgpmbBKevg3e9PBy+dXRt19kSbucbZvL2uqtdqwwpluL1jfxYE0wIDTFp1nTy/q6gNLsxXrg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -904,26 +901,26 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-decorators@7.28.6': - resolution: {integrity: sha512-71EYI0ONURHJBL4rSFXnITXqXrrY8q4P0q006DPfN+Rk+ASM+++IBXem/ruokgBZR8YNEWZ8R6B+rCb8VcUTqA==} + '@babel/plugin-syntax-decorators@7.27.1': + resolution: {integrity: sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-flow@7.28.6': - resolution: {integrity: sha512-D+OrJumc9McXNEBI/JmFnc/0uCM2/Y3PEBG3gfV3QIYkKv5pvnpzFrl1kYCrcHJP8nOeFB/SHi1IHz29pNGuew==} + '@babel/plugin-syntax-flow@7.27.1': + resolution: {integrity: sha512-p9OkPbZ5G7UT1MofwYFigGebnrzGJacoBSQM0/6bi/PUMVE+qlWDD/OalvQKbwgQzU6dl0xAv6r4X7Jme0RYxA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-assertions@7.28.6': - resolution: {integrity: sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==} + '@babel/plugin-syntax-import-assertions@7.27.1': + resolution: {integrity: sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-attributes@7.28.6': - resolution: {integrity: sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==} + '@babel/plugin-syntax-import-attributes@7.27.1': + resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -938,8 +935,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-jsx@7.28.6': - resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -986,8 +983,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-typescript@7.28.6': - resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} + '@babel/plugin-syntax-typescript@7.27.1': + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1004,14 +1001,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-generator-functions@7.29.0': - resolution: {integrity: sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==} + '@babel/plugin-transform-async-generator-functions@7.27.1': + resolution: {integrity: sha512-eST9RrwlpaoJBDHShc+DS2SG4ATTi2MYNb4OxYkf3n+7eb49LWpnS+HSpVfW4x927qQwgk8A2hGNVaajAEw0EA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-to-generator@7.28.6': - resolution: {integrity: sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==} + '@babel/plugin-transform-async-to-generator@7.27.1': + resolution: {integrity: sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1022,44 +1019,44 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoping@7.28.6': - resolution: {integrity: sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==} + '@babel/plugin-transform-block-scoping@7.27.5': + resolution: {integrity: sha512-JF6uE2s67f0y2RZcm2kpAUEbD50vH62TyWVebxwHAlbSdM49VqPz8t4a1uIjp4NIOIZ4xzLfjY5emt/RCyC7TQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-properties@7.28.6': - resolution: {integrity: sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==} + '@babel/plugin-transform-class-properties@7.27.1': + resolution: {integrity: sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-static-block@7.28.6': - resolution: {integrity: sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==} + '@babel/plugin-transform-class-static-block@7.27.1': + resolution: {integrity: sha512-s734HmYU78MVzZ++joYM+NkJusItbdRcbm+AGRgJCt3iA+yux0QpD9cBVdz3tKyrjVYWRl7j0mHSmv4lhV0aoA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 - '@babel/plugin-transform-classes@7.28.6': - resolution: {integrity: sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==} + '@babel/plugin-transform-classes@7.27.1': + resolution: {integrity: sha512-7iLhfFAubmpeJe/Wo2TVuDrykh/zlWXLzPNdL0Jqn/Xu8R3QQ8h9ff8FQoISZOsw74/HFqFI7NX63HN7QFIHKA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-computed-properties@7.28.6': - resolution: {integrity: sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==} + '@babel/plugin-transform-computed-properties@7.27.1': + resolution: {integrity: sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-destructuring@7.28.5': - resolution: {integrity: sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==} + '@babel/plugin-transform-destructuring@7.27.3': + resolution: {integrity: sha512-s4Jrok82JpiaIprtY2nHsYmrThKvvwgHwjgd7UMiYhZaN0asdXNLr0y+NjTfkA7SyQE5i2Fb7eawUOZmLvyqOA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-dotall-regex@7.28.6': - resolution: {integrity: sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==} + '@babel/plugin-transform-dotall-regex@7.27.1': + resolution: {integrity: sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1070,8 +1067,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0': - resolution: {integrity: sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==} + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1': + resolution: {integrity: sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1082,14 +1079,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-explicit-resource-management@7.28.6': - resolution: {integrity: sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-exponentiation-operator@7.28.6': - resolution: {integrity: sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==} + '@babel/plugin-transform-exponentiation-operator@7.27.1': + resolution: {integrity: sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1118,8 +1109,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-json-strings@7.28.6': - resolution: {integrity: sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==} + '@babel/plugin-transform-json-strings@7.27.1': + resolution: {integrity: sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1130,8 +1121,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-logical-assignment-operators@7.28.6': - resolution: {integrity: sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==} + '@babel/plugin-transform-logical-assignment-operators@7.27.1': + resolution: {integrity: sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1148,14 +1139,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-commonjs@7.28.6': - resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} + '@babel/plugin-transform-modules-commonjs@7.27.1': + resolution: {integrity: sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-systemjs@7.29.0': - resolution: {integrity: sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==} + '@babel/plugin-transform-modules-systemjs@7.27.1': + resolution: {integrity: sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1166,8 +1157,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-named-capturing-groups-regex@7.29.0': - resolution: {integrity: sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==} + '@babel/plugin-transform-named-capturing-groups-regex@7.27.1': + resolution: {integrity: sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1178,20 +1169,20 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-nullish-coalescing-operator@7.28.6': - resolution: {integrity: sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==} + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1': + resolution: {integrity: sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-numeric-separator@7.28.6': - resolution: {integrity: sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==} + '@babel/plugin-transform-numeric-separator@7.27.1': + resolution: {integrity: sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-rest-spread@7.28.6': - resolution: {integrity: sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==} + '@babel/plugin-transform-object-rest-spread@7.27.3': + resolution: {integrity: sha512-7ZZtznF9g4l2JCImCo5LNKFHB5eXnN39lLtLY5Tg+VkR0jwOt7TBciMckuiQIOIW7L5tkQOCh3bVGYeXgMx52Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1202,32 +1193,32 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-catch-binding@7.28.6': - resolution: {integrity: sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==} + '@babel/plugin-transform-optional-catch-binding@7.27.1': + resolution: {integrity: sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-chaining@7.28.6': - resolution: {integrity: sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==} + '@babel/plugin-transform-optional-chaining@7.27.1': + resolution: {integrity: sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-parameters@7.27.7': - resolution: {integrity: sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==} + '@babel/plugin-transform-parameters@7.27.1': + resolution: {integrity: sha512-018KRk76HWKeZ5l4oTj2zPpSh+NbGdt0st5S6x0pga6HgrjBOJb24mMDHorFopOOd6YHkLgOZ+zaCjZGPO4aKg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-methods@7.28.6': - resolution: {integrity: sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==} + '@babel/plugin-transform-private-methods@7.27.1': + resolution: {integrity: sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-property-in-object@7.28.6': - resolution: {integrity: sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==} + '@babel/plugin-transform-private-property-in-object@7.27.1': + resolution: {integrity: sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1244,8 +1235,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-display-name@7.28.0': - resolution: {integrity: sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==} + '@babel/plugin-transform-react-display-name@7.27.1': + resolution: {integrity: sha512-p9+Vl3yuHPmkirRrg021XiP+EETmPMQTLr6Ayjj85RLNEbb3Eya/4VI0vAdzQG9SEAl2Lnt7fy5lZyMzjYoZQQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1256,8 +1247,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx@7.28.6': - resolution: {integrity: sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==} + '@babel/plugin-transform-react-jsx@7.27.1': + resolution: {integrity: sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1268,14 +1259,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regenerator@7.29.0': - resolution: {integrity: sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==} + '@babel/plugin-transform-regenerator@7.27.5': + resolution: {integrity: sha512-uhB8yHerfe3MWnuLAhEbeQ4afVoqv8BQsPqrTv7e/jZ9y00kJL6l9a/f4OWaKxotmjzewfEyXE1vgDJenkQ2/Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regexp-modifiers@7.28.6': - resolution: {integrity: sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==} + '@babel/plugin-transform-regexp-modifiers@7.27.1': + resolution: {integrity: sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1286,8 +1277,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-runtime@7.29.0': - resolution: {integrity: sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==} + '@babel/plugin-transform-runtime@7.27.4': + resolution: {integrity: sha512-D68nR5zxU64EUzV8i7T3R5XP0Xhrou/amNnddsRQssx6GrTLdZl1rLxyjtVZBd+v/NVX4AbTPOB5aU8thAZV1A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1298,8 +1289,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-spread@7.28.6': - resolution: {integrity: sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==} + '@babel/plugin-transform-spread@7.27.1': + resolution: {integrity: sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1322,8 +1313,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.28.6': - resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} + '@babel/plugin-transform-typescript@7.27.1': + resolution: {integrity: sha512-Q5sT5+O4QUebHdbwKedFBEwRLb02zJ7r4A5Gg2hUoLuU3FjdMcyqcywqUrLCaDsFCxzokf7u9kuy7qz51YUuAg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1334,8 +1325,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-property-regex@7.28.6': - resolution: {integrity: sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==} + '@babel/plugin-transform-unicode-property-regex@7.27.1': + resolution: {integrity: sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1346,14 +1337,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-sets-regex@7.28.6': - resolution: {integrity: sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==} + '@babel/plugin-transform-unicode-sets-regex@7.27.1': + resolution: {integrity: sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/preset-env@7.29.2': - resolution: {integrity: sha512-DYD23veRYGvBFhcTY1iUvJnDNpuqNd/BzBwCvzOTKUnJjKg5kpUBh3/u9585Agdkgj+QuygG7jLfOPWMa2KVNw==} + '@babel/preset-env@7.27.2': + resolution: {integrity: sha512-Ma4zSuYSlGNRlCLO+EAzLnCmJK2vdstgv+n7aUP+/IKZrOfWHOJVdSJtuub8RzHTj3ahD37k5OKJWvzf16TQyQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1363,32 +1354,32 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 - '@babel/preset-react@7.28.5': - resolution: {integrity: sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==} + '@babel/preset-react@7.27.1': + resolution: {integrity: sha512-oJHWh2gLhU9dW9HHr42q0cI0/iHHXTLGe39qvpAZZzagHy0MzYLCnCVV0symeRvzmjHyVU7mw2K06E6u/JwbhA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/preset-typescript@7.28.5': - resolution: {integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==} + '@babel/preset-typescript@7.27.1': + resolution: {integrity: sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.29.2': - resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + '@babel/runtime@7.27.6': + resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} engines: {node: '>=6.9.0'} - '@babel/template@7.28.6': - resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.29.0': - resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + '@babel/traverse@7.27.4': + resolution: {integrity: sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==} engines: {node: '>=6.9.0'} - '@babel/types@7.29.0': - resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + '@babel/types@7.27.6': + resolution: {integrity: sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@0.2.3': @@ -1398,8 +1389,8 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@changesets/apply-release-plan@7.1.0': - resolution: {integrity: sha512-yq8ML3YS7koKQ/9bk1PqO0HMzApIFNwjlwCnwFEXMzNe8NpzeeYYKCmnhWJGkN8g7E51MnWaSbqRcTcdIxUgnQ==} + '@changesets/apply-release-plan@7.0.12': + resolution: {integrity: sha512-EaET7As5CeuhTzvXTQCRZeBUcisoYPDDcXvgTE/2jmmypKp0RC7LxKj/yzqeh/1qFTZI7oDGFcL1PHRuQuketQ==} '@changesets/assemble-release-plan@6.0.9': resolution: {integrity: sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==} @@ -1407,12 +1398,12 @@ packages: '@changesets/changelog-git@0.2.1': resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} - '@changesets/cli@2.30.0': - resolution: {integrity: sha512-5D3Nk2JPqMI1wK25pEymeWRSlSMdo5QOGlyfrKg0AOufrUcjEE3RQgaCpHoBiM31CSNrtSgdJ0U6zL1rLDDfBA==} + '@changesets/cli@2.29.5': + resolution: {integrity: sha512-0j0cPq3fgxt2dPdFsg4XvO+6L66RC0pZybT9F4dG5TBrLA3jA/1pNkdTXH9IBBVHkgsKrNKenI3n1mPyPlIydg==} hasBin: true - '@changesets/config@3.1.3': - resolution: {integrity: sha512-vnXjcey8YgBn2L1OPWd3ORs0bGC4LoYcK/ubpgvzNVr53JXV5GiTVj7fWdMRsoKUH7hhhMAQnsJUqLr21EncNw==} + '@changesets/config@3.1.1': + resolution: {integrity: sha512-bd+3Ap2TKXxljCggI0mKPfzCQKeV/TU4yO2h2C6vAihIo8tzseAn2e7klSuiyYYXvgu53zMN1OeYMIQkaQoWnA==} '@changesets/errors@0.2.0': resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} @@ -1420,8 +1411,8 @@ packages: '@changesets/get-dependents-graph@2.1.3': resolution: {integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==} - '@changesets/get-release-plan@4.0.15': - resolution: {integrity: sha512-Q04ZaRPuEVZtA+auOYgFaVQQSA98dXiVe/yFaZfY7hoSmQICHGvP0TF4u3EDNHWmmCS4ekA/XSpKlSM2PyTS2g==} + '@changesets/get-release-plan@4.0.13': + resolution: {integrity: sha512-DWG1pus72FcNeXkM12tx+xtExyH/c9I1z+2aXlObH3i9YA7+WZEVaiHzHl03thpvAgWTRaH64MpfHxozfF7Dvg==} '@changesets/get-version-range-type@0.4.0': resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} @@ -1432,14 +1423,14 @@ packages: '@changesets/logger@0.1.1': resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} - '@changesets/parse@0.4.3': - resolution: {integrity: sha512-ZDmNc53+dXdWEv7fqIUSgRQOLYoUom5Z40gmLgmATmYR9NbL6FJJHwakcCpzaeCy+1D0m0n7mT4jj2B/MQPl7A==} + '@changesets/parse@0.4.1': + resolution: {integrity: sha512-iwksMs5Bf/wUItfcg+OXrEpravm5rEd9Bf4oyIPL4kVTmJQ7PNDSd6MDYkpSJR1pn7tz/k8Zf2DhTCqX08Ou+Q==} '@changesets/pre@2.0.2': resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} - '@changesets/read@0.6.7': - resolution: {integrity: sha512-D1G4AUYGrBEk8vj8MGwf75k9GpN6XL3wg8i42P2jZZwFLXnlr2Pn7r9yuQNbaMCarP7ZQWNJbV6XLeysAIMhTA==} + '@changesets/read@0.6.5': + resolution: {integrity: sha512-UPzNGhsSjHD3Veb0xO/MwvasGe8eMyNrR/sT9gR8Q3DhOQZirgKhhXv/8hVsI0QpPjR004Z9iFxoJU6in3uGMg==} '@changesets/should-skip-package@0.1.2': resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} @@ -1458,24 +1449,24 @@ packages: peerDependencies: commander: ~12.1.0 - '@commitlint/config-validator@20.5.0': - resolution: {integrity: sha512-T/Uh6iJUzyx7j35GmHWdIiGRQB+ouZDk0pwAaYq4SXgB54KZhFdJ0vYmxiW6AMYICTIWuyMxDBl1jK74oFp/Gw==} + '@commitlint/config-validator@19.8.1': + resolution: {integrity: sha512-0jvJ4u+eqGPBIzzSdqKNX1rvdbSU1lPNYlfQQRIFnBgLy26BtC0cFnr7c/AyuzExMxWsMOte6MkTi9I3SQ3iGQ==} engines: {node: '>=v18'} - '@commitlint/execute-rule@20.0.0': - resolution: {integrity: sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==} + '@commitlint/execute-rule@19.8.1': + resolution: {integrity: sha512-YfJyIqIKWI64Mgvn/sE7FXvVMQER/Cd+s3hZke6cI1xgNT/f6ZAz5heND0QtffH+KbcqAwXDEE1/5niYayYaQA==} engines: {node: '>=v18'} - '@commitlint/load@20.5.0': - resolution: {integrity: sha512-sLhhYTL/KxeOTZjjabKDhwidGZan84XKK1+XFkwDYL/4883kIajcz/dZFAhBJmZPtL8+nBx6bnkzA95YxPeDPw==} + '@commitlint/load@19.8.1': + resolution: {integrity: sha512-9V99EKG3u7z+FEoe4ikgq7YGRCSukAcvmKQuTtUyiYPnOd9a2/H9Ak1J9nJA1HChRQp9OA/sIKPugGS+FK/k1A==} engines: {node: '>=v18'} - '@commitlint/resolve-extends@20.5.0': - resolution: {integrity: sha512-3SHPWUW2v0tyspCTcfSsYml0gses92l6TlogwzvM2cbxDgmhSRc+fldDjvGkCXJrjSM87BBaWYTPWwwyASZRrg==} + '@commitlint/resolve-extends@19.8.1': + resolution: {integrity: sha512-GM0mAhFk49I+T/5UCYns5ayGStkTt4XFFrjjf0L4S26xoMTSkdCf9ZRO8en1kuopC4isDFuEm7ZOm/WRVeElVg==} engines: {node: '>=v18'} - '@commitlint/types@20.5.0': - resolution: {integrity: sha512-ZJoS8oSq2CAZEpc/YI9SulLrdiIyXeHb/OGqGrkUP6Q7YV+0ouNAa7GjqRdXeQPncHQIDz/jbCTlHScvYvO/gA==} + '@commitlint/types@19.8.1': + resolution: {integrity: sha512-/yCrWGCoA1SVKOks25EGadP9Pnj0oAIHGpl2wH2M2Y46dPM2ueb8wyCVOD7O3WCTkaJ0IkKvzhl1JY7+uCT2Dw==} engines: {node: '>=v18'} '@cspotcode/source-map-support@0.8.1': @@ -1579,14 +1570,17 @@ packages: resolution: {integrity: sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==} engines: {node: '>=14.17.0'} - '@emnapi/core@1.9.2': - resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} + '@emnapi/core@1.4.3': + resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==} - '@emnapi/runtime@1.9.2': - resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==} + '@emnapi/runtime@1.4.3': + resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} - '@emnapi/wasi-threads@1.2.1': - resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + '@emnapi/runtime@1.4.5': + resolution: {integrity: sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==} + + '@emnapi/wasi-threads@1.0.2': + resolution: {integrity: sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==} '@esbuild/aix-ppc64@0.19.12': resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} @@ -1594,8 +1588,8 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.27.7': - resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} + '@esbuild/aix-ppc64@0.25.5': + resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] @@ -1612,8 +1606,8 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.27.7': - resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} + '@esbuild/android-arm64@0.25.5': + resolution: {integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==} engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -1630,8 +1624,8 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.27.7': - resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} + '@esbuild/android-arm@0.25.5': + resolution: {integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==} engines: {node: '>=18'} cpu: [arm] os: [android] @@ -1648,8 +1642,8 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.27.7': - resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} + '@esbuild/android-x64@0.25.5': + resolution: {integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==} engines: {node: '>=18'} cpu: [x64] os: [android] @@ -1666,8 +1660,8 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.27.7': - resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} + '@esbuild/darwin-arm64@0.25.5': + resolution: {integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] @@ -1684,8 +1678,8 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.27.7': - resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} + '@esbuild/darwin-x64@0.25.5': + resolution: {integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] @@ -1702,8 +1696,8 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.27.7': - resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} + '@esbuild/freebsd-arm64@0.25.5': + resolution: {integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] @@ -1720,8 +1714,8 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.27.7': - resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} + '@esbuild/freebsd-x64@0.25.5': + resolution: {integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] @@ -1738,8 +1732,8 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.27.7': - resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} + '@esbuild/linux-arm64@0.25.5': + resolution: {integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==} engines: {node: '>=18'} cpu: [arm64] os: [linux] @@ -1756,8 +1750,8 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.27.7': - resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} + '@esbuild/linux-arm@0.25.5': + resolution: {integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==} engines: {node: '>=18'} cpu: [arm] os: [linux] @@ -1774,8 +1768,8 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.27.7': - resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} + '@esbuild/linux-ia32@0.25.5': + resolution: {integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==} engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -1792,8 +1786,8 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.27.7': - resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} + '@esbuild/linux-loong64@0.25.5': + resolution: {integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] @@ -1810,8 +1804,8 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.27.7': - resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} + '@esbuild/linux-mips64el@0.25.5': + resolution: {integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] @@ -1828,8 +1822,8 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.27.7': - resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} + '@esbuild/linux-ppc64@0.25.5': + resolution: {integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] @@ -1846,8 +1840,8 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.27.7': - resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} + '@esbuild/linux-riscv64@0.25.5': + resolution: {integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] @@ -1864,8 +1858,8 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.27.7': - resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} + '@esbuild/linux-s390x@0.25.5': + resolution: {integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==} engines: {node: '>=18'} cpu: [s390x] os: [linux] @@ -1882,14 +1876,14 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.27.7': - resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} + '@esbuild/linux-x64@0.25.5': + resolution: {integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.27.7': - resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} + '@esbuild/netbsd-arm64@0.25.5': + resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] @@ -1906,14 +1900,14 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.27.7': - resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} + '@esbuild/netbsd-x64@0.25.5': + resolution: {integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.27.7': - resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} + '@esbuild/openbsd-arm64@0.25.5': + resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] @@ -1930,18 +1924,12 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.27.7': - resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} + '@esbuild/openbsd-x64@0.25.5': + resolution: {integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.27.7': - resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - '@esbuild/sunos-x64@0.16.17': resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==} engines: {node: '>=12'} @@ -1954,8 +1942,8 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.27.7': - resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} + '@esbuild/sunos-x64@0.25.5': + resolution: {integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] @@ -1972,8 +1960,8 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.27.7': - resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} + '@esbuild/win32-arm64@0.25.5': + resolution: {integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==} engines: {node: '>=18'} cpu: [arm64] os: [win32] @@ -1990,8 +1978,8 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.27.7': - resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} + '@esbuild/win32-ia32@0.25.5': + resolution: {integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==} engines: {node: '>=18'} cpu: [ia32] os: [win32] @@ -2008,20 +1996,20 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.27.7': - resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} + '@esbuild/win32-x64@0.25.5': + resolution: {integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.9.1': - resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + '@eslint-community/eslint-utils@4.7.0': + resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.12.2': - resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} '@eslint/eslintrc@2.1.4': @@ -2148,168 +2136,142 @@ packages: resolution: {integrity: sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==} engines: {node: '>=6.9.0'} - '@img/colour@1.1.0': - resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} - engines: {node: '>=18'} - - '@img/sharp-darwin-arm64@0.34.5': - resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + '@img/sharp-darwin-arm64@0.34.3': + resolution: {integrity: sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [darwin] - '@img/sharp-darwin-x64@0.34.5': - resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + '@img/sharp-darwin-x64@0.34.3': + resolution: {integrity: sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.2.4': - resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + '@img/sharp-libvips-darwin-arm64@1.2.0': + resolution: {integrity: sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ==} cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.2.4': - resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + '@img/sharp-libvips-darwin-x64@1.2.0': + resolution: {integrity: sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg==} cpu: [x64] os: [darwin] - '@img/sharp-libvips-linux-arm64@1.2.4': - resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + '@img/sharp-libvips-linux-arm64@1.2.0': + resolution: {integrity: sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA==} cpu: [arm64] os: [linux] libc: [glibc] - '@img/sharp-libvips-linux-arm@1.2.4': - resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + '@img/sharp-libvips-linux-arm@1.2.0': + resolution: {integrity: sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw==} cpu: [arm] os: [linux] libc: [glibc] - '@img/sharp-libvips-linux-ppc64@1.2.4': - resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + '@img/sharp-libvips-linux-ppc64@1.2.0': + resolution: {integrity: sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ==} cpu: [ppc64] os: [linux] libc: [glibc] - '@img/sharp-libvips-linux-riscv64@1.2.4': - resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@img/sharp-libvips-linux-s390x@1.2.4': - resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + '@img/sharp-libvips-linux-s390x@1.2.0': + resolution: {integrity: sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw==} cpu: [s390x] os: [linux] libc: [glibc] - '@img/sharp-libvips-linux-x64@1.2.4': - resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + '@img/sharp-libvips-linux-x64@1.2.0': + resolution: {integrity: sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg==} cpu: [x64] os: [linux] libc: [glibc] - '@img/sharp-libvips-linuxmusl-arm64@1.2.4': - resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + '@img/sharp-libvips-linuxmusl-arm64@1.2.0': + resolution: {integrity: sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q==} cpu: [arm64] os: [linux] libc: [musl] - '@img/sharp-libvips-linuxmusl-x64@1.2.4': - resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + '@img/sharp-libvips-linuxmusl-x64@1.2.0': + resolution: {integrity: sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q==} cpu: [x64] os: [linux] libc: [musl] - '@img/sharp-linux-arm64@0.34.5': - resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + '@img/sharp-linux-arm64@0.34.3': + resolution: {integrity: sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] libc: [glibc] - '@img/sharp-linux-arm@0.34.5': - resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + '@img/sharp-linux-arm@0.34.3': + resolution: {integrity: sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] libc: [glibc] - '@img/sharp-linux-ppc64@0.34.5': - resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + '@img/sharp-linux-ppc64@0.34.3': + resolution: {integrity: sha512-GLtbLQMCNC5nxuImPR2+RgrviwKwVql28FWZIW1zWruy6zLgA5/x2ZXk3mxj58X/tszVF69KK0Is83V8YgWhLA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@img/sharp-linux-riscv64@0.34.5': - resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@img/sharp-linux-s390x@0.34.5': - resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + '@img/sharp-linux-s390x@0.34.3': + resolution: {integrity: sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] libc: [glibc] - '@img/sharp-linux-x64@0.34.5': - resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + '@img/sharp-linux-x64@0.34.3': + resolution: {integrity: sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] libc: [glibc] - '@img/sharp-linuxmusl-arm64@0.34.5': - resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + '@img/sharp-linuxmusl-arm64@0.34.3': + resolution: {integrity: sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] libc: [musl] - '@img/sharp-linuxmusl-x64@0.34.5': - resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + '@img/sharp-linuxmusl-x64@0.34.3': + resolution: {integrity: sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] libc: [musl] - '@img/sharp-wasm32@0.34.5': - resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + '@img/sharp-wasm32@0.34.3': + resolution: {integrity: sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [wasm32] - '@img/sharp-win32-arm64@0.34.5': - resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + '@img/sharp-win32-arm64@0.34.3': + resolution: {integrity: sha512-MjnHPnbqMXNC2UgeLJtX4XqoVHHlZNd+nPt1kRPmj63wURegwBhZlApELdtxM2OIZDRv/DFtLcNhVbd1z8GYXQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [win32] - '@img/sharp-win32-ia32@0.34.5': - resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + '@img/sharp-win32-ia32@0.34.3': + resolution: {integrity: sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ia32] os: [win32] - '@img/sharp-win32-x64@0.34.5': - resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + '@img/sharp-win32-x64@0.34.3': + resolution: {integrity: sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [win32] - '@inquirer/external-editor@1.0.3': - resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@irys/arweave@0.0.2': resolution: {integrity: sha512-ddE5h4qXbl0xfGlxrtBIwzflaxZUDlDs43TuT0u1OMfyobHul4AA1VEX72Rpzw2bOh4vzoytSqA1jCM7x9YtHg==} @@ -2323,14 +2285,18 @@ packages: deprecated: 'Arweave support is deprecated - We recommend migrating to the Irys datachain: https://migrate-to.irys.xyz/' hasBin: true + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} - '@isaacs/cliui@9.0.0': - resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==} - engines: {node: '>=18'} - '@istanbuljs/load-nyc-config@1.1.0': resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} engines: {node: '>=8'} @@ -2409,24 +2375,26 @@ packages: resolution: {integrity: sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/source-map@0.3.11': - resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.6': + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} @@ -2437,116 +2405,14 @@ packages: peerDependencies: tslib: '2' - '@jsonjoy.com/base64@17.67.0': - resolution: {integrity: sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==} - engines: {node: '>=10.0'} - peerDependencies: - tslib: '2' - - '@jsonjoy.com/buffers@1.2.1': - resolution: {integrity: sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==} - engines: {node: '>=10.0'} - peerDependencies: - tslib: '2' - - '@jsonjoy.com/buffers@17.67.0': - resolution: {integrity: sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==} - engines: {node: '>=10.0'} - peerDependencies: - tslib: '2' - - '@jsonjoy.com/codegen@1.0.0': - resolution: {integrity: sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==} - engines: {node: '>=10.0'} - peerDependencies: - tslib: '2' - - '@jsonjoy.com/codegen@17.67.0': - resolution: {integrity: sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==} - engines: {node: '>=10.0'} - peerDependencies: - tslib: '2' - - '@jsonjoy.com/fs-core@4.57.1': - resolution: {integrity: sha512-YrEi/ZPmgc+GfdO0esBF04qv8boK9Dg9WpRQw/+vM8Qt3nnVIJWIa8HwZ/LXVZ0DB11XUROM8El/7yYTJX+WtA==} - engines: {node: '>=10.0'} - peerDependencies: - tslib: '2' - - '@jsonjoy.com/fs-fsa@4.57.1': - resolution: {integrity: sha512-ooEPvSW/HQDivPDPZMibHGKZf/QS4WRir1czGZmXmp3MsQqLECZEpN0JobrD8iV9BzsuwdIv+PxtWX9WpPLsIA==} - engines: {node: '>=10.0'} - peerDependencies: - tslib: '2' - - '@jsonjoy.com/fs-node-builtins@4.57.1': - resolution: {integrity: sha512-XHkFKQ5GSH3uxm8c3ZYXVrexGdscpWKIcMWKFQpMpMJc8gA3AwOMBJXJlgpdJqmrhPyQXxaY9nbkNeYpacC0Og==} - engines: {node: '>=10.0'} - peerDependencies: - tslib: '2' - - '@jsonjoy.com/fs-node-to-fsa@4.57.1': - resolution: {integrity: sha512-pqGHyWWzNck4jRfaGV39hkqpY5QjRUQ/nRbNT7FYbBa0xf4bDG+TE1Gt2KWZrSkrkZZDE3qZUjYMbjwSliX6pg==} - engines: {node: '>=10.0'} - peerDependencies: - tslib: '2' - - '@jsonjoy.com/fs-node-utils@4.57.1': - resolution: {integrity: sha512-vp+7ZzIB8v43G+GLXTS4oDUSQmhAsRz532QmmWBbdYA20s465JvwhkSFvX9cVTqRRAQg+vZ7zWDaIEh0lFe2gw==} - engines: {node: '>=10.0'} - peerDependencies: - tslib: '2' - - '@jsonjoy.com/fs-node@4.57.1': - resolution: {integrity: sha512-3YaKhP8gXEKN+2O49GLNfNb5l2gbnCFHyAaybbA2JkkbQP3dpdef7WcUaHAulg/c5Dg4VncHsA3NWAUSZMR5KQ==} - engines: {node: '>=10.0'} - peerDependencies: - tslib: '2' - - '@jsonjoy.com/fs-print@4.57.1': - resolution: {integrity: sha512-Ynct7ZJmfk6qoXDOKfpovNA36ITUx8rChLmRQtW08J73VOiuNsU8PB6d/Xs7fxJC2ohWR3a5AqyjmLojfrw5yw==} - engines: {node: '>=10.0'} - peerDependencies: - tslib: '2' - - '@jsonjoy.com/fs-snapshot@4.57.1': - resolution: {integrity: sha512-/oG8xBNFMbDXTq9J7vepSA1kerS5vpgd3p5QZSPd+nX59uwodGJftI51gDYyHRpP57P3WCQf7LHtBYPqwUg2Bg==} - engines: {node: '>=10.0'} - peerDependencies: - tslib: '2' - - '@jsonjoy.com/json-pack@1.21.0': - resolution: {integrity: sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==} - engines: {node: '>=10.0'} - peerDependencies: - tslib: '2' - - '@jsonjoy.com/json-pack@17.67.0': - resolution: {integrity: sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==} - engines: {node: '>=10.0'} - peerDependencies: - tslib: '2' - - '@jsonjoy.com/json-pointer@1.0.2': - resolution: {integrity: sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==} - engines: {node: '>=10.0'} - peerDependencies: - tslib: '2' - - '@jsonjoy.com/json-pointer@17.67.0': - resolution: {integrity: sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==} - engines: {node: '>=10.0'} - peerDependencies: - tslib: '2' - - '@jsonjoy.com/util@1.9.0': - resolution: {integrity: sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==} + '@jsonjoy.com/json-pack@1.4.0': + resolution: {integrity: sha512-Akn8XZqN3xO9YGcgvIiTauBBXTP92QSvw6EcGha+p5nm7brhbwvev5gw4fi+ouLGrBpfPpb72+S5pxl4mkMIGQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/util@17.67.0': - resolution: {integrity: sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==} + '@jsonjoy.com/util@1.8.0': + resolution: {integrity: sha512-HeR0JQNEdBozt+FrfyM5T0X3R+fIN0D+BRDkxPP5o41fTWzHfeZEqtK16aTW8haU+h+SG7XYq9PP5kobvOmkSA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -2564,8 +2430,8 @@ packages: resolution: {integrity: sha512-sFpN+TX13E9fdBDh9lvQeZdJn4qYoRb/6QF2oZZK/Pn559IhCFacPMU1rMuqyXoFQF3JSJfii2l98B87QDPeCQ==} engines: {node: '>=14.0.0'} - '@napi-rs/wasm-runtime@0.2.12': - resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + '@napi-rs/wasm-runtime@0.2.11': + resolution: {integrity: sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==} '@near-js/crypto@0.0.3': resolution: {integrity: sha512-3WC2A1a1cH8Cqrx+0iDjp1ASEEhxN/KHEMENYb0KZH6Hp5bXIY7Akt4quC7JlgJS5ESvEiLa40tS5h0zAhBWGw==} @@ -2670,17 +2536,13 @@ packages: '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} - '@noble/curves@1.9.7': - resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} + '@noble/curves@1.9.2': + resolution: {integrity: sha512-HxngEd2XUcg9xi20JkwlLCtYwfoFw4JGkuZpT+WlsPD4gB/cxkvTD8fSsoAnphGZhFdZYKeQIPCuFlWPm1uE0g==} engines: {node: ^14.21.3 || >=16} '@noble/ed25519@1.7.5': resolution: {integrity: sha512-xuS0nwRMQBvSxDa7UxMb61xTiH3MxTgUfhyPUALVIe0FlOAz4sjELwyDRyUvqeEYfRSG9qNjFIycqLZppg4RSA==} - '@noble/hashes@1.4.0': - resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} - engines: {node: '>= 16'} - '@noble/hashes@1.8.0': resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} engines: {node: ^14.21.3 || >=16} @@ -2722,40 +2584,6 @@ packages: resolution: {integrity: sha512-LehkMgoM7VDgqg3kqvMX8PFOiVgyFMVAqsbdbcffj31z2tf7C0q8RBinj61YDaLotx++py6us6M+T2cJAywnaA==} engines: {node: '>=18', pnpm: '>=8.0.0'} - '@peculiar/asn1-cms@2.6.1': - resolution: {integrity: sha512-vdG4fBF6Lkirkcl53q6eOdn3XYKt+kJTG59edgRZORlg/3atWWEReRCx5rYE1ZzTTX6vLK5zDMjHh7vbrcXGtw==} - - '@peculiar/asn1-csr@2.6.1': - resolution: {integrity: sha512-WRWnKfIocHyzFYQTka8O/tXCiBquAPSrRjXbOkHbO4qdmS6loffCEGs+rby6WxxGdJCuunnhS2duHURhjyio6w==} - - '@peculiar/asn1-ecc@2.6.1': - resolution: {integrity: sha512-+Vqw8WFxrtDIN5ehUdvlN2m73exS2JVG0UAyfVB31gIfor3zWEAQPD+K9ydCxaj3MLen9k0JhKpu9LqviuCE1g==} - - '@peculiar/asn1-pfx@2.6.1': - resolution: {integrity: sha512-nB5jVQy3MAAWvq0KY0R2JUZG8bO/bTLpnwyOzXyEh/e54ynGTatAR+csOnXkkVD9AFZ2uL8Z7EV918+qB1qDvw==} - - '@peculiar/asn1-pkcs8@2.6.1': - resolution: {integrity: sha512-JB5iQ9Izn5yGMw3ZG4Nw3Xn/hb/G38GYF3lf7WmJb8JZUydhVGEjK/ZlFSWhnlB7K/4oqEs8HnfFIKklhR58Tw==} - - '@peculiar/asn1-pkcs9@2.6.1': - resolution: {integrity: sha512-5EV8nZoMSxeWmcxWmmcolg22ojZRgJg+Y9MX2fnE2bGRo5KQLqV5IL9kdSQDZxlHz95tHvIq9F//bvL1OeNILw==} - - '@peculiar/asn1-rsa@2.6.1': - resolution: {integrity: sha512-1nVMEh46SElUt5CB3RUTV4EG/z7iYc7EoaDY5ECwganibQPkZ/Y2eMsTKB/LeyrUJ+W/tKoD9WUqIy8vB+CEdA==} - - '@peculiar/asn1-schema@2.6.0': - resolution: {integrity: sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==} - - '@peculiar/asn1-x509-attr@2.6.1': - resolution: {integrity: sha512-tlW6cxoHwgcQghnJwv3YS+9OO1737zgPogZ+CgWRUK4roEwIPzRH4JEiG770xe5HX2ATfCpmX60gurfWIF9dcQ==} - - '@peculiar/asn1-x509@2.6.1': - resolution: {integrity: sha512-O9jT5F1A2+t3r7C4VT7LYGXqkGLK7Kj1xFpz7U0isPrubwU5PbDoyYtx6MiGst29yq7pXN5vZbQFKRCP+lLZlA==} - - '@peculiar/x509@1.14.3': - resolution: {integrity: sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==} - engines: {node: '>=20.0.0'} - '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -2786,14 +2614,14 @@ packages: webpack-plugin-serve: optional: true - '@pmmmwh/react-refresh-webpack-plugin@0.6.2': - resolution: {integrity: sha512-IhIAD5n4XvGHuL9nAgWfsBR0TdxtjrUWETYKCBHxauYXEv+b+ctEbs9neEgPC7Ecgzv4bpZTBwesAoGDeFymzA==} + '@pmmmwh/react-refresh-webpack-plugin@0.6.1': + resolution: {integrity: sha512-95DXXJxNkpYu+sqmpDp7vbw9JCyiNpHuCsvuMuOgVFrKQlwEIn9Y1+NNIQJq+zFL+eWyxw6htthB5CtdwJupNA==} engines: {node: '>=18.12'} peerDependencies: '@types/webpack': 5.x react-refresh: '>=0.10.0 <1.0.0' sockjs-client: ^1.4.0 - type-fest: '>=0.17.0 <6.0.0' + type-fest: '>=0.17.0 <5.0.0' webpack: ^5.0.0 webpack-dev-server: ^4.8.0 || 5.x webpack-hot-middleware: 2.x @@ -2846,149 +2674,122 @@ packages: peerDependencies: rollup: ^1.20.0||^2.0.0 - '@rollup/rollup-android-arm-eabi@4.60.1': - resolution: {integrity: sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==} + '@rollup/rollup-android-arm-eabi@4.44.1': + resolution: {integrity: sha512-JAcBr1+fgqx20m7Fwe1DxPUl/hPkee6jA6Pl7n1v2EFiktAHenTaXl5aIFjUIEsfn9w3HE4gK1lEgNGMzBDs1w==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.60.1': - resolution: {integrity: sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==} + '@rollup/rollup-android-arm64@4.44.1': + resolution: {integrity: sha512-RurZetXqTu4p+G0ChbnkwBuAtwAbIwJkycw1n6GvlGlBuS4u5qlr5opix8cBAYFJgaY05TWtM+LaoFggUmbZEQ==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.60.1': - resolution: {integrity: sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==} + '@rollup/rollup-darwin-arm64@4.44.1': + resolution: {integrity: sha512-fM/xPesi7g2M7chk37LOnmnSTHLG/v2ggWqKj3CCA1rMA4mm5KVBT1fNoswbo1JhPuNNZrVwpTvlCVggv8A2zg==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.60.1': - resolution: {integrity: sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==} + '@rollup/rollup-darwin-x64@4.44.1': + resolution: {integrity: sha512-gDnWk57urJrkrHQ2WVx9TSVTH7lSlU7E3AFqiko+bgjlh78aJ88/3nycMax52VIVjIm3ObXnDL2H00e/xzoipw==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.60.1': - resolution: {integrity: sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==} + '@rollup/rollup-freebsd-arm64@4.44.1': + resolution: {integrity: sha512-wnFQmJ/zPThM5zEGcnDcCJeYJgtSLjh1d//WuHzhf6zT3Md1BvvhJnWoy+HECKu2bMxaIcfWiu3bJgx6z4g2XA==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.60.1': - resolution: {integrity: sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==} + '@rollup/rollup-freebsd-x64@4.44.1': + resolution: {integrity: sha512-uBmIxoJ4493YATvU2c0upGz87f99e3wop7TJgOA/bXMFd2SvKCI7xkxY/5k50bv7J6dw1SXT4MQBQSLn8Bb/Uw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.60.1': - resolution: {integrity: sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==} + '@rollup/rollup-linux-arm-gnueabihf@4.44.1': + resolution: {integrity: sha512-n0edDmSHlXFhrlmTK7XBuwKlG5MbS7yleS1cQ9nn4kIeW+dJH+ExqNgQ0RrFRew8Y+0V/x6C5IjsHrJmiHtkxQ==} cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.60.1': - resolution: {integrity: sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==} + '@rollup/rollup-linux-arm-musleabihf@4.44.1': + resolution: {integrity: sha512-8WVUPy3FtAsKSpyk21kV52HCxB+me6YkbkFHATzC2Yd3yuqHwy2lbFL4alJOLXKljoRw08Zk8/xEj89cLQ/4Nw==} cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.60.1': - resolution: {integrity: sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==} + '@rollup/rollup-linux-arm64-gnu@4.44.1': + resolution: {integrity: sha512-yuktAOaeOgorWDeFJggjuCkMGeITfqvPgkIXhDqsfKX8J3jGyxdDZgBV/2kj/2DyPaLiX6bPdjJDTu9RB8lUPQ==} cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.60.1': - resolution: {integrity: sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==} + '@rollup/rollup-linux-arm64-musl@4.44.1': + resolution: {integrity: sha512-W+GBM4ifET1Plw8pdVaecwUgxmiH23CfAUj32u8knq0JPFyK4weRy6H7ooxYFD19YxBulL0Ktsflg5XS7+7u9g==} cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.60.1': - resolution: {integrity: sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==} + '@rollup/rollup-linux-loongarch64-gnu@4.44.1': + resolution: {integrity: sha512-1zqnUEMWp9WrGVuVak6jWTl4fEtrVKfZY7CvcBmUUpxAJ7WcSowPSAWIKa/0o5mBL/Ij50SIf9tuirGx63Ovew==} cpu: [loong64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.60.1': - resolution: {integrity: sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==} - cpu: [loong64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-ppc64-gnu@4.60.1': - resolution: {integrity: sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==} + '@rollup/rollup-linux-powerpc64le-gnu@4.44.1': + resolution: {integrity: sha512-Rl3JKaRu0LHIx7ExBAAnf0JcOQetQffaw34T8vLlg9b1IhzcBgaIdnvEbbsZq9uZp3uAH+JkHd20Nwn0h9zPjA==} cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.60.1': - resolution: {integrity: sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==} - cpu: [ppc64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-riscv64-gnu@4.60.1': - resolution: {integrity: sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==} + '@rollup/rollup-linux-riscv64-gnu@4.44.1': + resolution: {integrity: sha512-j5akelU3snyL6K3N/iX7otLBIl347fGwmd95U5gS/7z6T4ftK288jKq3A5lcFKcx7wwzb5rgNvAg3ZbV4BqUSw==} cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.60.1': - resolution: {integrity: sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==} + '@rollup/rollup-linux-riscv64-musl@4.44.1': + resolution: {integrity: sha512-ppn5llVGgrZw7yxbIm8TTvtj1EoPgYUAbfw0uDjIOzzoqlZlZrLJ/KuiE7uf5EpTpCTrNt1EdtzF0naMm0wGYg==} cpu: [riscv64] os: [linux] libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.60.1': - resolution: {integrity: sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==} + '@rollup/rollup-linux-s390x-gnu@4.44.1': + resolution: {integrity: sha512-Hu6hEdix0oxtUma99jSP7xbvjkUM/ycke/AQQ4EC5g7jNRLLIwjcNwaUy95ZKBJJwg1ZowsclNnjYqzN4zwkAw==} cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.60.1': - resolution: {integrity: sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==} + '@rollup/rollup-linux-x64-gnu@4.44.1': + resolution: {integrity: sha512-EtnsrmZGomz9WxK1bR5079zee3+7a+AdFlghyd6VbAjgRJDbTANJ9dcPIPAi76uG05micpEL+gPGmAKYTschQw==} cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.60.1': - resolution: {integrity: sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==} + '@rollup/rollup-linux-x64-musl@4.44.1': + resolution: {integrity: sha512-iAS4p+J1az6Usn0f8xhgL4PaU878KEtutP4hqw52I4IO6AGoyOkHCxcc4bqufv1tQLdDWFx8lR9YlwxKuv3/3g==} cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openbsd-x64@4.60.1': - resolution: {integrity: sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==} - cpu: [x64] - os: [openbsd] - - '@rollup/rollup-openharmony-arm64@4.60.1': - resolution: {integrity: sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==} - cpu: [arm64] - os: [openharmony] - - '@rollup/rollup-win32-arm64-msvc@4.60.1': - resolution: {integrity: sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==} + '@rollup/rollup-win32-arm64-msvc@4.44.1': + resolution: {integrity: sha512-NtSJVKcXwcqozOl+FwI41OH3OApDyLk3kqTJgx8+gp6On9ZEt5mYhIsKNPGuaZr3p9T6NWPKGU/03Vw4CNU9qg==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.60.1': - resolution: {integrity: sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==} + '@rollup/rollup-win32-ia32-msvc@4.44.1': + resolution: {integrity: sha512-JYA3qvCOLXSsnTR3oiyGws1Dm0YTuxAAeaYGVlGpUsHqloPcFjPg+X0Fj2qODGLNwQOAcCiQmHub/V007kiH5A==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.60.1': - resolution: {integrity: sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.60.1': - resolution: {integrity: sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==} + '@rollup/rollup-win32-x64-msvc@4.44.1': + resolution: {integrity: sha512-J8o22LuF0kTe7m+8PvW9wk3/bRq5+mRo5Dqo6+vXb7otCm3TPhYOJqOaQtGU9YMWQSL3krMnoOxMr0+9E6F3Ug==} cpu: [x64] os: [win32] '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - '@rushstack/eslint-patch@1.16.1': - resolution: {integrity: sha512-TvZbIpeKqGQQ7X0zSCvPH9riMSFQFSggnfBjFZ1mEoILW+UuXCKwOoPcgjMwiUtRqFZ8jWhPJc4um14vC6I4ag==} + '@rushstack/eslint-patch@1.11.0': + resolution: {integrity: sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==} '@scure/base@1.2.6': resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} @@ -2999,10 +2800,6 @@ packages: '@scure/bip39@1.6.0': resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} - '@simple-libs/stream-utils@1.2.0': - resolution: {integrity: sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==} - engines: {node: '>=18'} - '@sinclair/typebox@0.24.51': resolution: {integrity: sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==} @@ -3024,27 +2821,27 @@ packages: resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} engines: {node: '>=5.10'} - '@solana/codecs-core@2.3.0': - resolution: {integrity: sha512-oG+VZzN6YhBHIoSKgS5ESM9VIGzhWjEHEGNPSibiDTxFhsFWxNaz8LbMDPjBUE69r9wmdGLkrQ+wVPbnJcZPvw==} + '@solana/codecs-core@2.1.1': + resolution: {integrity: sha512-iPQW3UZ2Vi7QFBo2r9tw0NubtH8EdrhhmZulx6lC8V5a+qjaxovtM/q/UW2BTNpqqHLfO0tIcLyBLrNH4HTWPg==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' - '@solana/codecs-numbers@2.3.0': - resolution: {integrity: sha512-jFvvwKJKffvG7Iz9dmN51OGB7JBcy2CJ6Xf3NqD/VP90xak66m/Lg48T01u5IQ/hc15mChVHiBm+HHuOFDUrQg==} + '@solana/codecs-numbers@2.1.1': + resolution: {integrity: sha512-m20IUPJhPUmPkHSlZ2iMAjJ7PaYUvlMtFhCQYzm9BEBSI6OCvXTG3GAPpAnSGRBfg5y+QNqqmKn4QHU3B6zzCQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' - '@solana/errors@2.3.0': - resolution: {integrity: sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==} + '@solana/errors@2.1.1': + resolution: {integrity: sha512-sj6DaWNbSJFvLzT8UZoabMefQUfSW/8tXK7NTiagsDmh+Q87eyQDDC9L3z+mNmx9b6dEf6z660MOIplDD2nfEw==} engines: {node: '>=20.18.0'} hasBin: true peerDependencies: typescript: '>=5.3.3' - '@solana/web3.js@1.98.4': - resolution: {integrity: sha512-vv9lfnvjUsRiq//+j5pBdXig0IQdtzA0BRZ3bXEP4KaIyF1CcaydWqgyzQgfZMNIsWNWmG+AUHwPy4AHOD6gpw==} + '@solana/web3.js@1.98.2': + resolution: {integrity: sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A==} '@spruceid/siwe-parser@3.0.0': resolution: {integrity: sha512-Y92k63ilw/8jH9Ry4G2e7lQd0jZAvb0d/Q7ssSD0D9mp/Zt2aCXIc3g0ny9yhplpAx1QXHsMz/JJptHK/zDGdw==} @@ -3061,8 +2858,8 @@ packages: '@stablelib/wipe@1.0.1': resolution: {integrity: sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==} - '@supercharge/promise-pool@3.3.0': - resolution: {integrity: sha512-qGzCltMN05ohRRQAXB8TPWt+0Coz9Va266gr9nYN1qc/f/EIaup3VRg7b59mtRaeKTRcxreF20l/udCM/gOqNg==} + '@supercharge/promise-pool@3.2.0': + resolution: {integrity: sha512-pj0cAALblTZBPtMltWOlZTQSLT07jIaFNeM8TWoJD1cQMgDB9mcMlVMoetiB35OzNJpqQ2b+QEtwiR9f20mADg==} engines: {node: '>=8'} '@surma/rollup-plugin-off-main-thread@2.2.3': @@ -3130,8 +2927,8 @@ packages: '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} - '@swc/helpers@0.5.21': - resolution: {integrity: sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==} + '@swc/helpers@0.5.17': + resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} '@szmarczak/http-timer@4.0.6': resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} @@ -3141,8 +2938,12 @@ packages: resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} engines: {node: '>= 6'} - '@tsconfig/node10@1.0.12': - resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==} + '@trysound/sax@0.2.0': + resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} + engines: {node: '>=10.13.0'} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} '@tsconfig/node12@1.0.11': resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} @@ -3153,8 +2954,8 @@ packages: '@tsconfig/node16@1.0.4': resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - '@tybys/wasm-util@0.10.1': - resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@tybys/wasm-util@0.9.0': + resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} '@typechain/ethers-v5@11.1.2': resolution: {integrity: sha512-ID6pqWkao54EuUQa0P5RgjvfA3MYqxUQKpbGKERbsjBW5Ra7EIXvbMlPp2pcP5IAdUkyMCFYsP2SN5q7mPdLDQ==} @@ -3174,8 +2975,8 @@ packages: '@types/babel__template@7.4.4': resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - '@types/babel__traverse@7.28.0': - resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + '@types/babel__traverse@7.20.7': + resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} '@types/body-parser@1.19.6': resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} @@ -3186,8 +2987,8 @@ packages: '@types/cacheable-request@6.0.3': resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} - '@types/chai@5.2.3': - resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + '@types/chai@5.2.2': + resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} '@types/connect-history-api-fallback@1.5.4': resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==} @@ -3195,6 +2996,9 @@ packages: '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + '@types/conventional-commits-parser@5.0.1': + resolution: {integrity: sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==} + '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} @@ -3216,11 +3020,14 @@ packages: '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - '@types/express-serve-static-core@4.19.8': - resolution: {integrity: sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==} + '@types/express-serve-static-core@4.19.6': + resolution: {integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==} + + '@types/express-serve-static-core@5.0.6': + resolution: {integrity: sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==} - '@types/express@4.17.25': - resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} + '@types/express@4.17.23': + resolution: {integrity: sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==} '@types/graceful-fs@4.1.9': resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} @@ -3228,14 +3035,14 @@ packages: '@types/html-minifier-terser@6.1.0': resolution: {integrity: sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==} - '@types/http-cache-semantics@4.2.0': - resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} + '@types/http-cache-semantics@4.0.4': + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} '@types/http-errors@2.0.5': resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} - '@types/http-proxy@1.17.17': - resolution: {integrity: sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==} + '@types/http-proxy@1.17.16': + resolution: {integrity: sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==} '@types/istanbul-lib-coverage@2.0.6': resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} @@ -3255,8 +3062,8 @@ packages: '@types/keyv@3.1.4': resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} - '@types/lodash@4.17.24': - resolution: {integrity: sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==} + '@types/lodash@4.17.19': + resolution: {integrity: sha512-NYqRyg/hIQrYPT9lbOeYc3kIRabJDn/k4qQHIXUpx88CBDww2fD15Sg5kbXlW86zm2XEW4g0QxkTI3/Kfkc7xQ==} '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} @@ -3264,8 +3071,8 @@ packages: '@types/minimist@1.2.5': resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} - '@types/node-forge@1.3.14': - resolution: {integrity: sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==} + '@types/node-forge@1.3.11': + resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} '@types/node@11.11.6': resolution: {integrity: sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==} @@ -3291,8 +3098,8 @@ packages: '@types/q@1.5.8': resolution: {integrity: sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==} - '@types/qs@6.15.0': - resolution: {integrity: sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==} + '@types/qs@6.14.0': + resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} @@ -3308,8 +3115,8 @@ packages: peerDependencies: '@types/react': ^18.0.0 - '@types/react@18.3.28': - resolution: {integrity: sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==} + '@types/react@18.3.23': + resolution: {integrity: sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==} '@types/react@18.3.5': resolution: {integrity: sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA==} @@ -3326,20 +3133,17 @@ packages: '@types/retry@0.12.2': resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} - '@types/semver@7.7.1': - resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} + '@types/semver@7.7.0': + resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==} - '@types/send@0.17.6': - resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==} - - '@types/send@1.2.1': - resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} + '@types/send@0.17.5': + resolution: {integrity: sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==} '@types/serve-index@1.9.4': resolution: {integrity: sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==} - '@types/serve-static@1.15.10': - resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} + '@types/serve-static@1.15.8': + resolution: {integrity: sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==} '@types/sockjs@0.3.36': resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==} @@ -3353,8 +3157,8 @@ packages: '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} - '@types/uuid@10.0.0': - resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} + '@types/uuid@8.3.4': + resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==} '@types/ws@7.4.7': resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} @@ -3365,11 +3169,11 @@ packages: '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - '@types/yargs@16.0.11': - resolution: {integrity: sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==} + '@types/yargs@16.0.9': + resolution: {integrity: sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==} - '@types/yargs@17.0.35': - resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} + '@types/yargs@17.0.33': + resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} '@typescript-eslint/eslint-plugin@5.62.0': resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==} @@ -3496,110 +3300,110 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - '@uniswap/token-lists@1.0.0-beta.35': - resolution: {integrity: sha512-v43brw8Fx+D904fOCXL5kTU75cIPH40U/WTKB96K1gxOibk2jVsxW3AULBE5Buj5dJpeVwj/l6TNgB6QPw7lJg==} + '@uniswap/token-lists@1.0.0-beta.34': + resolution: {integrity: sha512-Hc3TfrFaupg0M84e/Zv7BoF+fmMWDV15mZ5s8ZQt2qZxUcNw2GQW+L6L/2k74who31G+p1m3GRYbJpAo7d1pqA==} engines: {node: '>=10'} - '@unrs/resolver-binding-android-arm-eabi@1.11.1': - resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} + '@unrs/resolver-binding-android-arm-eabi@1.9.2': + resolution: {integrity: sha512-tS+lqTU3N0kkthU+rYp0spAYq15DU8ld9kXkaKg9sbQqJNF+WPMuNHZQGCgdxrUOEO0j22RKMwRVhF1HTl+X8A==} cpu: [arm] os: [android] - '@unrs/resolver-binding-android-arm64@1.11.1': - resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} + '@unrs/resolver-binding-android-arm64@1.9.2': + resolution: {integrity: sha512-MffGiZULa/KmkNjHeuuflLVqfhqLv1vZLm8lWIyeADvlElJ/GLSOkoUX+5jf4/EGtfwrNFcEaB8BRas03KT0/Q==} cpu: [arm64] os: [android] - '@unrs/resolver-binding-darwin-arm64@1.11.1': - resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} + '@unrs/resolver-binding-darwin-arm64@1.9.2': + resolution: {integrity: sha512-dzJYK5rohS1sYl1DHdJ3mwfwClJj5BClQnQSyAgEfggbUwA9RlROQSSbKBLqrGfsiC/VyrDPtbO8hh56fnkbsQ==} cpu: [arm64] os: [darwin] - '@unrs/resolver-binding-darwin-x64@1.11.1': - resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} + '@unrs/resolver-binding-darwin-x64@1.9.2': + resolution: {integrity: sha512-gaIMWK+CWtXcg9gUyznkdV54LzQ90S3X3dn8zlh+QR5Xy7Y+Efqw4Rs4im61K1juy4YNb67vmJsCDAGOnIeffQ==} cpu: [x64] os: [darwin] - '@unrs/resolver-binding-freebsd-x64@1.11.1': - resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} + '@unrs/resolver-binding-freebsd-x64@1.9.2': + resolution: {integrity: sha512-S7QpkMbVoVJb0xwHFwujnwCAEDe/596xqY603rpi/ioTn9VDgBHnCCxh+UFrr5yxuMH+dliHfjwCZJXOPJGPnw==} cpu: [x64] os: [freebsd] - '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': - resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} + '@unrs/resolver-binding-linux-arm-gnueabihf@1.9.2': + resolution: {integrity: sha512-+XPUMCuCCI80I46nCDFbGum0ZODP5NWGiwS3Pj8fOgsG5/ctz+/zzuBlq/WmGa+EjWZdue6CF0aWWNv84sE1uw==} cpu: [arm] os: [linux] - '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': - resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} + '@unrs/resolver-binding-linux-arm-musleabihf@1.9.2': + resolution: {integrity: sha512-sqvUyAd1JUpwbz33Ce2tuTLJKM+ucSsYpPGl2vuFwZnEIg0CmdxiZ01MHQ3j6ExuRqEDUCy8yvkDKvjYFPb8Zg==} cpu: [arm] os: [linux] - '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': - resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} + '@unrs/resolver-binding-linux-arm64-gnu@1.9.2': + resolution: {integrity: sha512-UYA0MA8ajkEDCFRQdng/FVx3F6szBvk3EPnkTTQuuO9lV1kPGuTB+V9TmbDxy5ikaEgyWKxa4CI3ySjklZ9lFA==} cpu: [arm64] os: [linux] libc: [glibc] - '@unrs/resolver-binding-linux-arm64-musl@1.11.1': - resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} + '@unrs/resolver-binding-linux-arm64-musl@1.9.2': + resolution: {integrity: sha512-P/CO3ODU9YJIHFqAkHbquKtFst0COxdphc8TKGL5yCX75GOiVpGqd1d15ahpqu8xXVsqP4MGFP2C3LRZnnL5MA==} cpu: [arm64] os: [linux] libc: [musl] - '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': - resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} + '@unrs/resolver-binding-linux-ppc64-gnu@1.9.2': + resolution: {integrity: sha512-uKStFlOELBxBum2s1hODPtgJhY4NxYJE9pAeyBgNEzHgTqTiVBPjfTlPFJkfxyTjQEuxZbbJlJnMCrRgD7ubzw==} cpu: [ppc64] os: [linux] libc: [glibc] - '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': - resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} + '@unrs/resolver-binding-linux-riscv64-gnu@1.9.2': + resolution: {integrity: sha512-LkbNnZlhINfY9gK30AHs26IIVEZ9PEl9qOScYdmY2o81imJYI4IMnJiW0vJVtXaDHvBvxeAgEy5CflwJFIl3tQ==} cpu: [riscv64] os: [linux] libc: [glibc] - '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': - resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} + '@unrs/resolver-binding-linux-riscv64-musl@1.9.2': + resolution: {integrity: sha512-vI+e6FzLyZHSLFNomPi+nT+qUWN4YSj8pFtQZSFTtmgFoxqB6NyjxSjAxEC1m93qn6hUXhIsh8WMp+fGgxCoRg==} cpu: [riscv64] os: [linux] libc: [musl] - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': - resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} + '@unrs/resolver-binding-linux-s390x-gnu@1.9.2': + resolution: {integrity: sha512-sSO4AlAYhSM2RAzBsRpahcJB1msc6uYLAtP6pesPbZtptF8OU/CbCPhSRW6cnYOGuVmEmWVW5xVboAqCnWTeHQ==} cpu: [s390x] os: [linux] libc: [glibc] - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': - resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} + '@unrs/resolver-binding-linux-x64-gnu@1.9.2': + resolution: {integrity: sha512-jkSkwch0uPFva20Mdu8orbQjv2A3G88NExTN2oPTI1AJ+7mZfYW3cDCTyoH6OnctBKbBVeJCEqh0U02lTkqD5w==} cpu: [x64] os: [linux] libc: [glibc] - '@unrs/resolver-binding-linux-x64-musl@1.11.1': - resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} + '@unrs/resolver-binding-linux-x64-musl@1.9.2': + resolution: {integrity: sha512-Uk64NoiTpQbkpl+bXsbeyOPRpUoMdcUqa+hDC1KhMW7aN1lfW8PBlBH4mJ3n3Y47dYE8qi0XTxy1mBACruYBaw==} cpu: [x64] os: [linux] libc: [musl] - '@unrs/resolver-binding-wasm32-wasi@1.11.1': - resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} + '@unrs/resolver-binding-wasm32-wasi@1.9.2': + resolution: {integrity: sha512-EpBGwkcjDicjR/ybC0g8wO5adPNdVuMrNalVgYcWi+gYtC1XYNuxe3rufcO7dA76OHGeVabcO6cSkPJKVcbCXQ==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': - resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} + '@unrs/resolver-binding-win32-arm64-msvc@1.9.2': + resolution: {integrity: sha512-EdFbGn7o1SxGmN6aZw9wAkehZJetFPao0VGZ9OMBwKx6TkvDuj6cNeLimF/Psi6ts9lMOe+Dt6z19fZQ9Ye2fw==} cpu: [arm64] os: [win32] - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': - resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} + '@unrs/resolver-binding-win32-ia32-msvc@1.9.2': + resolution: {integrity: sha512-JY9hi1p7AG+5c/dMU8o2kWemM8I6VZxfGwn1GCtf3c5i+IKcMo2NQ8OjZ4Z3/itvY/Si3K10jOBQn7qsD/whUA==} cpu: [ia32] os: [win32] - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': - resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} + '@unrs/resolver-binding-win32-x64-msvc@1.9.2': + resolution: {integrity: sha512-ryoo+EB19lMxAd80ln9BVf8pdOAxLb97amrQ3SFN9OCRn/5M5wvwDgAe4i8ZjhpbiHoDeP8yavcTEnpKBo7lZg==} cpu: [x64] os: [win32] @@ -3619,9 +3423,23 @@ packages: '@vitest/browser': optional: true + '@vitest/expect@3.0.9': + resolution: {integrity: sha512-5eCqRItYgIML7NNVgJj6TVCmdzE7ZVgJhruW0ziSQV4V7PvLkDL1bBkBdcTs/VuIz0IxPb5da1IDSqc1TR9eig==} + '@vitest/expect@3.2.4': resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + '@vitest/mocker@3.0.9': + resolution: {integrity: sha512-ryERPIBOnvevAkTq+L1lD+DTFBRcjueL9lOUfXsLfwP92h4e+Heb+PjiqS3/OURWPtywfafK0kj++yDFjWUmrA==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + '@vitest/mocker@3.2.4': resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} peerDependencies: @@ -3633,18 +3451,33 @@ packages: vite: optional: true + '@vitest/pretty-format@3.0.9': + resolution: {integrity: sha512-OW9F8t2J3AwFEwENg3yMyKWweF7oRJlMyHOMIhO5F3n0+cgQAJZBjNgrF8dLwFTEXl5jUqBLXd9QyyKv8zEcmA==} + '@vitest/pretty-format@3.2.4': resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + '@vitest/runner@3.0.9': + resolution: {integrity: sha512-NX9oUXgF9HPfJSwl8tUZCMP1oGx2+Sf+ru6d05QjzQz4OwWg0psEzwY6VexP2tTHWdOkhKHUIZH+fS6nA7jfOw==} + '@vitest/runner@3.2.4': resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} + '@vitest/snapshot@3.0.9': + resolution: {integrity: sha512-AiLUiuZ0FuA+/8i19mTYd+re5jqjEc2jZbgJ2up0VY0Ddyyxg/uUtBDpIFAy4uzKaQxOW8gMgBdAJJ2ydhu39A==} + '@vitest/snapshot@3.2.4': resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} + '@vitest/spy@3.0.9': + resolution: {integrity: sha512-/CcK2UDl0aQ2wtkp3YVWldrpLRNCfVcIOFGlVGKO4R5eajsH393Z1yiXLVQ7vWsj26JOEjeZI0x5sm5P4OGUNQ==} + '@vitest/spy@3.2.4': resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + '@vitest/utils@3.0.9': + resolution: {integrity: sha512-ilHM5fHhZ89MCp5aAaM9uhfl1c2JdxVxl3McqsdVyVNN6JffnEen8UMCdRTzOhGXNQGo5GNL9QugHrz727Wnng==} + '@vitest/utils@3.2.4': resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} @@ -3739,12 +3572,6 @@ packages: acorn-globals@6.0.0: resolution: {integrity: sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==} - acorn-import-phases@1.0.4: - resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} - engines: {node: '>=10.13.0'} - peerDependencies: - acorn: ^8.14.0 - acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -3754,8 +3581,8 @@ packages: resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} engines: {node: '>=0.4.0'} - acorn-walk@8.3.5: - resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} engines: {node: '>=0.4.0'} acorn@7.4.1: @@ -3763,8 +3590,8 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - acorn@8.16.0: - resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} engines: {node: '>=0.4.0'} hasBin: true @@ -3808,11 +3635,11 @@ packages: peerDependencies: ajv: ^8.8.2 - ajv@6.14.0: - resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - ajv@8.18.0: - resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} algo-msgpack-with-bigint@2.1.1: resolution: {integrity: sha512-F1tGh056XczEaEAqu7s+hlZUDWwOBT70Eq0lfMpBP2YguSQVyxRbprLq5rELXKQOyOaixTWYhMeMQMzP0U5FoQ==} @@ -3822,8 +3649,8 @@ packages: resolution: {integrity: sha512-9moZxdqeJ6GdE4N6fA/GlUP4LrbLZMYcYkt141J4Ss68OfEgH9qW0wBuZ3ZOKEx/xjc5bg7mLP2Gjg7nwrkmww==} engines: {node: '>=14.0.0'} - anser@2.3.5: - resolution: {integrity: sha512-vcZjxvvVoxTeR5XBNJB38oTu/7eDCZlwdz32N1eNgpyPF7j/Z7Idf+CUwQOkKKpJ7RJyjxgLHCM7vdIK0iCNMQ==} + anser@2.3.2: + resolution: {integrity: sha512-PMqBCBvrOVDRqLGooQb+z+t1Q0PiPyurUQeZRR5uHBOVZcW8B04KMmnT12USnhpNX2wCPagWzLVppQMUG3u0Dw==} ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} @@ -3847,8 +3674,8 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.2.2: - resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} engines: {node: '>=12'} ansi-sequence-parser@1.1.3: @@ -3866,8 +3693,8 @@ packages: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} - ansi-styles@6.2.3: - resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} any-promise@1.3.0: @@ -3978,10 +3805,6 @@ packages: asn1.js@5.4.1: resolution: {integrity: sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==} - asn1js@3.0.7: - resolution: {integrity: sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ==} - engines: {node: '>=12.0.0'} - assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -3989,8 +3812,8 @@ packages: ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} - ast-v8-to-istanbul@0.3.12: - resolution: {integrity: sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g==} + ast-v8-to-istanbul@0.3.3: + resolution: {integrity: sha512-MuXMrSLVVoA6sYN/6Hke18vMzrT4TZNbZIj/hvh0fnYFpO+/kFXcLIaiPwXXWaQUPg4yJD8fj+lfJ7/1EBconw==} async-function@1.0.0: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} @@ -4009,8 +3832,8 @@ packages: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} - autoprefixer@10.4.27: - resolution: {integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==} + autoprefixer@10.4.21: + resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: @@ -4020,8 +3843,8 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axe-core@4.11.2: - resolution: {integrity: sha512-byD6KPdvo72y/wj2T/4zGEvvlis+PsZsn/yPS3pEO+sFpcrqRpX/TJCxvVaEsNeMrfQbCr7w163YqoD9IYwHXw==} + axe-core@4.10.3: + resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} engines: {node: '>=4'} axios-retry@4.5.0: @@ -4029,6 +3852,9 @@ packages: peerDependencies: axios: 0.x || 1.x + axios@1.10.0: + resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} + axios@1.15.0: resolution: {integrity: sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==} @@ -4066,33 +3892,28 @@ packages: peerDependencies: '@babel/core': ^7.1.0 - babel-plugin-polyfill-corejs2@0.4.17: - resolution: {integrity: sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - - babel-plugin-polyfill-corejs3@0.13.0: - resolution: {integrity: sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==} + babel-plugin-polyfill-corejs2@0.4.13: + resolution: {integrity: sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-corejs3@0.14.2: - resolution: {integrity: sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==} + babel-plugin-polyfill-corejs3@0.11.1: + resolution: {integrity: sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-regenerator@0.6.8: - resolution: {integrity: sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==} + babel-plugin-polyfill-regenerator@0.6.4: + resolution: {integrity: sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 babel-plugin-transform-react-remove-prop-types@0.4.24: resolution: {integrity: sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==} - babel-preset-current-node-syntax@1.2.0: - resolution: {integrity: sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==} + babel-preset-current-node-syntax@1.1.0: + resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} peerDependencies: - '@babel/core': ^7.0.0 || ^8.0.0-0 + '@babel/core': ^7.0.0 babel-preset-jest@27.5.1: resolution: {integrity: sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==} @@ -4106,10 +3927,6 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - balanced-match@4.0.4: - resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} - engines: {node: 18 || 20 || >=22} - base-x@3.0.11: resolution: {integrity: sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==} @@ -4123,11 +3940,6 @@ packages: resolution: {integrity: sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==} engines: {node: '>=6.0.0'} - baseline-browser-mapping@2.10.17: - resolution: {integrity: sha512-HdrkN8eVG2CXxeifv/VdJ4A4RSra1DTW8dc/hdxzhGHN8QePs6gKaWM9pHPcpCoxYZJuOZ8drHmbdpLHjCYjLA==} - engines: {node: '>=6.0.0'} - hasBin: true - batch@0.6.1: resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} @@ -4145,8 +3957,8 @@ packages: big.js@5.2.2: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} - bignumber.js@9.3.1: - resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + bignumber.js@9.3.0: + resolution: {integrity: sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA==} binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} @@ -4164,17 +3976,17 @@ packages: bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} - bn.js@4.12.3: - resolution: {integrity: sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==} + bn.js@4.12.2: + resolution: {integrity: sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==} bn.js@5.2.1: resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} - bn.js@5.2.3: - resolution: {integrity: sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==} + bn.js@5.2.2: + resolution: {integrity: sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==} - body-parser@1.20.4: - resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} + body-parser@1.20.3: + resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} bonjour-service@1.3.0: @@ -4183,22 +3995,14 @@ packages: boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - boolbase@2.0.0: - resolution: {integrity: sha512-DkVaaQHymRhpYEYo9x1oo7Q7B0Y6KJUsjm3c9eTyFDby4MHLBTwZ6ZDWBel5zrYxj1WsZgC5oLpiz+93MluXeA==} - engines: {node: '>=20.19.0'} - borsh@0.7.0: resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} - brace-expansion@1.1.13: - resolution: {integrity: sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==} - - brace-expansion@2.0.3: - resolution: {integrity: sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==} + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - brace-expansion@5.0.5: - resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} - engines: {node: 18 || 20 || >=22} + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} @@ -4227,12 +4031,12 @@ packages: resolution: {integrity: sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==} engines: {node: '>= 0.10'} - browserify-sign@4.2.5: - resolution: {integrity: sha512-C2AUdAJg6rlM2W5QMp2Q4KGQMVBwR1lIimTsUnutJ8bMpW5B52pGpR2gEnNBNwijumDo5FojQ0L9JrXA8m4YEw==} - engines: {node: '>= 0.10'} + browserify-sign@4.2.3: + resolution: {integrity: sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==} + engines: {node: '>= 0.12'} - browserslist@4.28.2: - resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + browserslist@4.25.1: + resolution: {integrity: sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -4257,8 +4061,8 @@ packages: buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - bufferutil@4.1.0: - resolution: {integrity: sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw==} + bufferutil@4.0.9: + resolution: {integrity: sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==} engines: {node: '>=6.14.2'} builtin-modules@3.3.0: @@ -4292,10 +4096,6 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} - bytestreamjs@2.0.1: - resolution: {integrity: sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==} - engines: {node: '>=6.0.0'} - cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -4316,8 +4116,8 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} - call-bind@1.0.9: - resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} engines: {node: '>= 0.4'} call-bound@1.0.4: @@ -4350,16 +4150,16 @@ packages: caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - caniuse-lite@1.0.30001787: - resolution: {integrity: sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg==} + caniuse-lite@1.0.30001726: + resolution: {integrity: sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==} case-sensitive-paths-webpack-plugin@2.4.0: resolution: {integrity: sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==} engines: {node: '>=4'} - chai@5.3.3: - resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} - engines: {node: '>=18'} + chai@5.2.0: + resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} + engines: {node: '>=12'} chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} @@ -4369,8 +4169,8 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - chalk@5.6.2: - resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + chalk@5.4.1: + resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} char-regex@1.0.2: @@ -4384,11 +4184,8 @@ packages: chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - chardet@2.1.1: - resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} - - check-error@2.1.3: - resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} check-types@11.2.3: @@ -4406,8 +4203,8 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - cipher-base@1.0.7: - resolution: {integrity: sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==} + cipher-base@1.0.6: + resolution: {integrity: sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==} engines: {node: '>= 0.10'} cjs-module-lexer@1.4.3: @@ -4454,8 +4251,8 @@ packages: resolution: {integrity: sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==} engines: {node: '>= 4.0'} - collect-v8-coverage@1.0.3: - resolution: {integrity: sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==} + collect-v8-coverage@1.0.2: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -4470,6 +4267,13 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + colord@2.9.3: resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} @@ -4500,10 +4304,6 @@ packages: resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} engines: {node: '>=18'} - commander@14.0.3: - resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} - engines: {node: '>=20'} - commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -4538,8 +4338,8 @@ packages: resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} engines: {node: '>= 0.6'} - compression@1.8.1: - resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==} + compression@1.8.0: + resolution: {integrity: sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==} engines: {node: '>= 0.8.0'} concat-map@0.0.1: @@ -4632,11 +4432,6 @@ packages: engines: {node: '>=10'} hasBin: true - conventional-commits-parser@6.4.0: - resolution: {integrity: sha512-tvRg7FIBNlyPzjdG8wWRlPHQJJHI7DylhtRGeU9Lq+JuoPh5BKpPRX83ZdLrvXuOSu5Eo/e7SzOQhU4Hd2Miuw==} - engines: {node: '>=18'} - hasBin: true - conventional-recommended-bump@6.1.0: resolution: {integrity: sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==} engines: {node: '>=10'} @@ -4648,36 +4443,36 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - cookie-signature@1.0.7: - resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} + cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - cookie@0.7.2: - resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + cookie@0.7.1: + resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} engines: {node: '>= 0.6'} copy-to-clipboard@3.3.3: resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} - copy-webpack-plugin@13.0.1: - resolution: {integrity: sha512-J+YV3WfhY6W/Xf9h+J1znYuqTye2xkBUIGyTPWuBAT27qajBa5mR4f8WBmfDY3YjRftT2kqZZiLi1qf0H+UOFw==} + copy-webpack-plugin@13.0.0: + resolution: {integrity: sha512-FgR/h5a6hzJqATDGd9YG41SeDViH+0bkHn6WNXCi5zKAZkeESeSxLySSsFLHqLEVCh0E+rITmCf0dusXWYukeQ==} engines: {node: '>= 18.12.0'} peerDependencies: webpack: ^5.1.0 - core-js-compat@3.49.0: - resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} + core-js-compat@3.43.0: + resolution: {integrity: sha512-2GML2ZsCc5LR7hZYz4AXmjQw8zuy2T//2QntwdnpuYI7jteT6GVYJL7F6C2C57R7gSYrcqVW3lAALefdbhBLDA==} - core-js-pure@3.49.0: - resolution: {integrity: sha512-XM4RFka59xATyJv/cS3O3Kml72hQXUeGRuuTmMYFxwzc9/7C8OYTaIR/Ji+Yt8DXzsFLNhat15cE/JP15HrCgw==} + core-js-pure@3.43.0: + resolution: {integrity: sha512-i/AgxU2+A+BbJdMxh3v7/vxi2SbFqxiFmg6VsDwYB4jkucrd1BZNA9a9gphC0fYMG5IBSgQcbQnk865VCLe7xA==} - core-js@3.49.0: - resolution: {integrity: sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==} + core-js@3.43.0: + resolution: {integrity: sha512-N6wEbTTZSYOY2rYAn85CuvWWkCK6QweMn7/4Nr3w+gDBeBhk/x4EJeY6FPo4QzDoJZxVTv8U7CMvgWk6pOHHqA==} core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - cosmiconfig-typescript-loader@6.3.0: - resolution: {integrity: sha512-Akr82WH1Wfqatyiqpj8HDkO2o2KmJRu1FhKfSNJP3K4IdXwHfEyL7MOb62i1AGQVLtIQM+iCE9CGOtrfhR+mmA==} + cosmiconfig-typescript-loader@6.1.0: + resolution: {integrity: sha512-tJ1w35ZRUiM5FeTzT7DtYWAFFv37ZLqSRkGi2oeCK1gPhvaWjkAtfXvLmvE1pRfxxp9aQo6ba/Pvg1dKj05D4g==} engines: {node: '>=v18'} peerDependencies: '@types/node': '*' @@ -4701,8 +4496,8 @@ packages: typescript: optional: true - cosmiconfig@9.0.1: - resolution: {integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==} + cosmiconfig@9.0.0: + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} engines: {node: '>=14'} peerDependencies: typescript: '>=4.9.5' @@ -4713,6 +4508,9 @@ packages: create-ecdh@4.0.4: resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} + create-hash@1.1.3: + resolution: {integrity: sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA==} + create-hash@1.2.0: resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} @@ -4820,8 +4618,8 @@ packages: resolution: {integrity: sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==} engines: {node: '>= 6'} - css-what@6.2.2: - resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} engines: {node: '>= 6'} cssdb@7.11.2: @@ -4864,8 +4662,8 @@ packages: resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} engines: {node: '>=8'} - csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} csv-generate@3.4.3: resolution: {integrity: sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==} @@ -4926,8 +4724,8 @@ packages: supports-color: optional: true - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -4943,8 +4741,8 @@ packages: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} - decimal.js@10.6.0: - resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + decimal.js@10.5.0: + resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==} decompress-response@6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} @@ -4972,12 +4770,12 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} - default-browser-id@5.0.1: - resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} + default-browser-id@5.0.0: + resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} engines: {node: '>=18'} - default-browser@5.5.0: - resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} + default-browser@5.2.1: + resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} engines: {node: '>=18'} default-gateway@6.0.3: @@ -5038,12 +4836,12 @@ packages: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} - detect-indent@7.0.2: - resolution: {integrity: sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==} + detect-indent@7.0.1: + resolution: {integrity: sha512-Mc7QhQ8s+cLrnUfU/Ji94vG/r8M26m8f++vyres4ZoojaRDpZ1eSIh/EpzLNwlWuvzSZ3UbDFspjFvTDXe6e/g==} engines: {node: '>=12.20'} - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + detect-libc@2.0.4: + resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} engines: {node: '>=8'} detect-newline@3.1.0: @@ -5069,8 +4867,8 @@ packages: resolution: {integrity: sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} - diff@4.0.4: - resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==} + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} diffie-hellman@5.0.3: @@ -5139,8 +4937,8 @@ packages: resolution: {integrity: sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==} engines: {node: '>=10'} - dotenv@16.6.1: - resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + dotenv@16.5.0: + resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} engines: {node: '>=12'} dotgitignore@2.1.0: @@ -5168,8 +4966,8 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electron-to-chromium@1.5.334: - resolution: {integrity: sha512-mgjZAz7Jyx1SRCwEpy9wefDS7GvNPazLthHg8eQMJ76wBdGQQDW33TCrUTvQ4wzpmOrv2zrFoD3oNufMdyMpog==} + electron-to-chromium@1.5.176: + resolution: {integrity: sha512-2nDK9orkm7M9ZZkjO3PjbEd3VUulQLyg5T9O3enJdFvUg46Hzd4DUvTvAuEgbdHYXyFsiG4A5sO9IzToMH1cDg==} elliptic@6.6.1: resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} @@ -5195,6 +4993,10 @@ packages: resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} engines: {node: '>= 4'} + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + encodeurl@2.0.0: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} @@ -5202,8 +5004,8 @@ packages: end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - enhanced-resolve@5.20.1: - resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} + enhanced-resolve@5.18.2: + resolution: {integrity: sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==} engines: {node: '>=10.13.0'} enquirer@2.4.1: @@ -5217,19 +5019,19 @@ packages: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} - envinfo@7.21.0: - resolution: {integrity: sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==} + envinfo@7.14.0: + resolution: {integrity: sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==} engines: {node: '>=4'} hasBin: true - error-ex@1.3.4: - resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} error-stack-parser@2.1.4: resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} - es-abstract@1.24.2: - resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==} + es-abstract@1.24.0: + resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} engines: {node: '>= 0.4'} es-array-method-boxes-properly@1.0.0: @@ -5246,16 +5048,13 @@ packages: es-get-iterator@1.1.3: resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} - es-iterator-helpers@1.3.2: - resolution: {integrity: sha512-HVLACW1TppGYjJ8H6/jqH/pqOtKRw6wMlrB23xfExmFWxFquAIWCmwoLsOyN96K4a5KbmOf5At9ZUO3GZbetAw==} + es-iterator-helpers@1.2.1: + resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} engines: {node: '>= 0.4'} es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - es-module-lexer@2.0.0: - resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} - es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} @@ -5293,8 +5092,8 @@ packages: engines: {node: '>=12'} hasBin: true - esbuild@0.27.7: - resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} + esbuild@0.25.5: + resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==} engines: {node: '>=18'} hasBin: true @@ -5336,8 +5135,8 @@ packages: typescript: optional: true - eslint-config-prettier@9.1.2: - resolution: {integrity: sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==} + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} hasBin: true peerDependencies: eslint: '>=7.0.0' @@ -5358,8 +5157,8 @@ packages: '@typescript-eslint/eslint-plugin': ^5 eslint-plugin-sonarjs: '*' - eslint-import-resolver-node@0.3.10: - resolution: {integrity: sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==} + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} eslint-import-resolver-typescript@3.10.1: resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==} @@ -5465,10 +5264,10 @@ packages: peerDependencies: eslint: '>=5.0.0' - eslint-plugin-sonarjs@4.0.2: - resolution: {integrity: sha512-BTcT1zr1iTbmJtVlcesISwnXzh+9uhf9LEOr+RRNf4kR8xA0HQTPft4oiyOCzCOGKkpSJxjR8ZYF6H7VPyplyw==} + eslint-plugin-sonarjs@3.0.3: + resolution: {integrity: sha512-/UrTz8wyTW0MQVJKUF70vSjsMMf54+0cKHWAuYObuE82vNM8zrscm0wvZprolHNN0PIdnvVQ9Dm6MQkIzOKu4A==} peerDependencies: - eslint: ^8.0.0 || ^9.0.0 || ^10.0.0 + eslint: ^8.0.0 || ^9.0.0 eslint-plugin-testing-library@5.11.1: resolution: {integrity: sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw==} @@ -5476,11 +5275,11 @@ packages: peerDependencies: eslint: ^7.5.0 || ^8.0.0 - eslint-plugin-unused-imports@4.4.1: - resolution: {integrity: sha512-oZGYUz1X3sRMGUB+0cZyK2VcvRX5lm/vB56PgNNcU+7ficUCKm66oZWKUubXWnOuPjQ8PvmXtCViXBMONPe7tQ==} + eslint-plugin-unused-imports@4.1.4: + resolution: {integrity: sha512-YptD6IzQjDardkl0POxnnRBhU1OEePMV0nd6siHaRBbd+lyh6NAhFEobiznKU7kTsSsDeSD62Pe7kAM1b7dAZQ==} peerDependencies: '@typescript-eslint/eslint-plugin': ^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0 - eslint: ^10.0.0 || ^9.0.0 || ^8.0.0 + eslint: ^9.0.0 || ^8.0.0 peerDependenciesMeta: '@typescript-eslint/eslint-plugin': optional: true @@ -5524,8 +5323,8 @@ packages: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - esprima@1.2.5: - resolution: {integrity: sha512-S9VbPDU0adFErpDai3qDkjq8+G05ONtKzcyNrPKg/ZKa+tf879nX2KexNU95b31UoTJjRLInNBHHHjFPoCd7lQ==} + esprima@1.2.2: + resolution: {integrity: sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==} engines: {node: '>=0.4.0'} hasBin: true @@ -5534,8 +5333,8 @@ packages: engines: {node: '>=4'} hasBin: true - esquery@1.7.0: - resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} esrecurse@4.3.0: @@ -5570,8 +5369,8 @@ packages: eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} - eventemitter3@5.0.4: - resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} @@ -5592,19 +5391,19 @@ packages: resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==} engines: {node: '>=0.10.0'} - expect-type@1.3.0: - resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + expect-type@1.2.1: + resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} engines: {node: '>=12.0.0'} expect@27.5.1: resolution: {integrity: sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} - exponential-backoff@3.1.3: - resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} + exponential-backoff@3.1.2: + resolution: {integrity: sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==} - express@4.22.1: - resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==} + express@4.21.2: + resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} engines: {node: '>= 0.10.0'} extendable-error@0.1.7: @@ -5634,15 +5433,15 @@ packages: fast-stable-stringify@1.0.0: resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} - fast-uri@3.1.0: - resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + fast-uri@3.0.6: + resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} fastest-levenshtein@1.0.16: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} engines: {node: '>= 4.9.1'} - fastq@1.20.1: - resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} faye-websocket@0.11.4: resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} @@ -5651,9 +5450,8 @@ packages: fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} + fdir@6.4.6: + resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -5683,8 +5481,8 @@ packages: peerDependencies: webpack: ^4.0.0 || ^5.0.0 - filelist@1.0.6: - resolution: {integrity: sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==} + filelist@1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} filename-reserved-regex@2.0.0: resolution: {integrity: sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==} @@ -5702,8 +5500,8 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - finalhandler@1.3.2: - resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} + finalhandler@1.3.1: + resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} engines: {node: '>= 0.8'} find-cache-dir@3.3.2: @@ -5748,11 +5546,20 @@ packages: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true - flatted@3.4.2: - resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true - follow-redirects@1.15.11: - resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -5782,8 +5589,12 @@ packages: vue-template-compiler: optional: true - form-data@3.0.4: - resolution: {integrity: sha512-f0cRzm6dkyVYV3nPoooP8XlccPQukegwhAnpoLcXy+X+A8KfpGOoXwDr9FLZd3wzgLaBGQBE3lY93Zm/i1JvIQ==} + form-data@3.0.3: + resolution: {integrity: sha512-q5YBMeWy6E2Un0nMGWMgI65MAKtaylxfNJGJxpGh45YDciZB4epbWpaAfImil6CPAPTYB4sh0URQNDRIZG5F2w==} + engines: {node: '>= 6'} + + form-data@4.0.3: + resolution: {integrity: sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==} engines: {node: '>= 6'} form-data@4.0.5: @@ -5794,8 +5605,8 @@ packages: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} - fraction.js@5.3.4: - resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} @@ -5805,8 +5616,8 @@ packages: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} - fs-extra@11.3.4: - resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==} + fs-extra@11.3.0: + resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==} engines: {node: '>=14.14'} fs-extra@7.0.1: @@ -5821,8 +5632,8 @@ packages: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} - fs-monkey@1.1.0: - resolution: {integrity: sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw==} + fs-monkey@1.0.6: + resolution: {integrity: sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==} fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -5845,10 +5656,6 @@ packages: functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - generator-function@2.0.1: - resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} - engines: {node: '>= 0.4'} - gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -5893,8 +5700,8 @@ packages: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} - get-tsconfig@4.13.7: - resolution: {integrity: sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==} + get-tsconfig@4.10.1: + resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} gh-pages@6.3.0: resolution: {integrity: sha512-Ot5lU6jK0Eb+sszG8pciXdjMXdBJ5wODvgjR+imihTqsUWF2K6dJ9HST55lgqcs8wWcw6o6wAsUzfcYRhJPXbA==} @@ -5907,7 +5714,6 @@ packages: git-raw-commits@2.0.11: resolution: {integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==} engines: {node: '>=10'} - deprecated: This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead. hasBin: true git-remote-origin-url@2.0.0: @@ -5917,7 +5723,6 @@ packages: git-semver-tags@4.1.1: resolution: {integrity: sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==} engines: {node: '>=10'} - deprecated: This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead. hasBin: true gitconfiglocal@1.0.0: @@ -5931,33 +5736,25 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob-to-regex.js@1.2.0: - resolution: {integrity: sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==} - engines: {node: '>=10.0'} - peerDependencies: - tslib: '2' - glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - glob@10.5.0: - resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true - glob@11.1.0: - resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==} + glob@11.0.3: + resolution: {integrity: sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==} engines: {node: 20 || >=22} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true glob@7.1.7: resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + deprecated: Glob versions prior to v9 are no longer supported glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + deprecated: Glob versions prior to v9 are no longer supported global-directory@4.0.1: resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} @@ -5979,14 +5776,14 @@ packages: resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} engines: {node: '>=6'} + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + globals@13.24.0: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} - globals@17.4.0: - resolution: {integrity: sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==} - engines: {node: '>=18'} - globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} @@ -6016,8 +5813,8 @@ packages: handle-thing@2.0.1: resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} - handlebars@4.7.9: - resolution: {integrity: sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==} + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} engines: {node: '>=0.4.7'} hasBin: true @@ -6055,14 +5852,13 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} + hash-base@2.0.2: + resolution: {integrity: sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw==} + hash-base@3.0.5: resolution: {integrity: sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==} engines: {node: '>= 0.10'} - hash-base@3.1.2: - resolution: {integrity: sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==} - engines: {node: '>= 0.8'} - hash.js@1.1.7: resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} @@ -6113,8 +5909,8 @@ packages: engines: {node: '>=12'} hasBin: true - html-webpack-plugin@5.6.6: - resolution: {integrity: sha512-bLjW01UTrvoWTJQL5LsMRo1SypHW80FTm12OJRSnr3v6YHNhfe+1r0MYUZJMACxnCHURVnBWRwAsWs2yPU9Ezw==} + html-webpack-plugin@5.6.3: + resolution: {integrity: sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg==} engines: {node: '>=10.13.0'} peerDependencies: '@rspack/core': 0.x || 1.x @@ -6134,12 +5930,16 @@ packages: http-deceiver@1.2.7: resolution: {integrity: sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==} + http-errors@1.6.3: + resolution: {integrity: sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==} + engines: {node: '>= 0.6'} + http-errors@1.8.1: resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==} engines: {node: '>= 0.6'} - http-errors@2.0.1: - resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} http-parser-js@0.5.10: @@ -6170,8 +5970,8 @@ packages: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} - human-id@4.1.3: - resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} + human-id@4.1.1: + resolution: {integrity: sha512-3gKm/gCSUipeLsRYZbbdA1BD83lBoWUkZ7G9VFrhWPAU76KwYo5KR8V28bpoPm/ygy0x5/GCbpRQdY7VLYCoIg==} hasBin: true human-signals@2.1.0: @@ -6193,10 +5993,6 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} - iconv-lite@0.7.2: - resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} - engines: {node: '>=0.10.0'} - icss-utils@5.1.0: resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} engines: {node: ^10 || ^12 || >= 14} @@ -6229,8 +6025,8 @@ packages: engines: {node: '>=8'} hasBin: true - import-meta-resolve@4.2.0: - resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + import-meta-resolve@4.1.0: + resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} @@ -6244,6 +6040,9 @@ packages: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + inherits@2.0.3: + resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -6258,8 +6057,8 @@ packages: resolution: {integrity: sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==} engines: {node: '>=12.0.0'} - inquirer@8.2.7: - resolution: {integrity: sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==} + inquirer@8.2.6: + resolution: {integrity: sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==} engines: {node: '>=12.0.0'} internal-slot@1.1.0: @@ -6274,8 +6073,8 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} - ipaddr.js@2.3.0: - resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} + ipaddr.js@2.2.0: + resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==} engines: {node: '>= 10'} is-arguments@1.2.0: @@ -6289,6 +6088,9 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + is-async-function@2.1.1: resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} engines: {node: '>= 0.4'} @@ -6350,8 +6152,8 @@ packages: resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} engines: {node: '>=6'} - is-generator-function@1.1.2: - resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} + is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} engines: {node: '>= 0.4'} is-glob@4.0.3: @@ -6378,8 +6180,8 @@ packages: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} - is-network-error@1.3.1: - resolution: {integrity: sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==} + is-network-error@1.1.0: + resolution: {integrity: sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==} engines: {node: '>=16'} is-number-object@1.1.1: @@ -6502,8 +6304,8 @@ packages: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} - is-wsl@3.1.1: - resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} engines: {node: '>=16'} isarray@1.0.0: @@ -6544,8 +6346,8 @@ packages: resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} engines: {node: '>=10'} - istanbul-reports@3.2.0: - resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} engines: {node: '>=8'} iterator.prototype@1.1.5: @@ -6555,17 +6357,17 @@ packages: jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - jackspeak@4.2.3: - resolution: {integrity: sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==} + jackspeak@4.1.1: + resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} engines: {node: 20 || >=22} - jake@10.9.4: - resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} + jake@10.9.2: + resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} engines: {node: '>=10'} hasBin: true - jayson@4.3.0: - resolution: {integrity: sha512-AauzHcUcqs8OBnCHOkJY280VaTiCm57AbuO7lqzcw7JapGj50BisE3xhksye4zlTSR1+1tAz67wLTl8tEH1obQ==} + jayson@4.2.0: + resolution: {integrity: sha512-VfJ9t1YLwacIubLhONk0KFeosUBwstRWQ0IRT1KDjEjnVnSOVHC3uwugyV7L0c7R9lpVyrUGT2XWiBA1UTtpyg==} engines: {node: '>=8'} hasBin: true @@ -6741,16 +6543,16 @@ packages: resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true - jiti@2.6.1: - resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + jiti@2.4.2: + resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} hasBin: true joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} - js-base64@3.7.8: - resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==} + js-base64@3.7.7: + resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} js-sha256@0.9.0: resolution: {integrity: sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==} @@ -6761,21 +6563,18 @@ packages: js-sha512@0.8.0: resolution: {integrity: sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==} - js-tokens@10.0.0: - resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} - js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} js-tokens@9.0.1: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} - js-yaml@3.14.2: - resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true - js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true jsdom@16.7.0: @@ -6787,6 +6586,11 @@ packages: canvas: optional: true + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -6810,6 +6614,9 @@ packages: json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -6831,24 +6638,20 @@ packages: jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - jsonfile@6.2.0: - resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} jsonparse@1.3.1: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} engines: {'0': node >= 0.2.0} - jsonpath@1.3.0: - resolution: {integrity: sha512-0kjkYHJBkAy50Z5QzArZ7udmvxrJzkpKYW27fiF//BrMY7TQibYLl+FYIXN2BiYmwMIVzSfD8aDRj6IzgBX2/w==} + jsonpath@1.1.1: + resolution: {integrity: sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==} jsonpointer@5.0.1: resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} engines: {node: '>=0.10.0'} - jsx-ast-utils-x@0.1.0: - resolution: {integrity: sha512-eQQBjBnsVtGacsG9uJNB8qOr3yA8rga4wAaGG1qRcBzSIvfhERLrWxMAM1hp5fcS6Abo8M4+bUBTekYR0qTPQw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - jsx-ast-utils@3.3.5: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} @@ -6887,8 +6690,8 @@ packages: resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} engines: {node: '>=0.10'} - launch-editor@2.13.2: - resolution: {integrity: sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==} + launch-editor@2.10.0: + resolution: {integrity: sha512-D7dBRJo/qcGX9xlvt/6wUYzQxjh5G1RvZPgPv8vi4KRU99DVQL/oW7tnVOCCTm2HGeo3C5HvGE5Yrh6UBoZ0vA==} leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} @@ -6921,8 +6724,8 @@ packages: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - loader-runner@4.3.1: - resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} + loader-runner@4.3.0: + resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} engines: {node: '>=6.11.5'} loader-utils@2.0.4: @@ -6949,8 +6752,8 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} - lodash-es@4.18.1: - resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} @@ -6965,6 +6768,9 @@ packages: lodash.ismatch@4.4.0: resolution: {integrity: sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==} + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + lodash.map@4.6.0: resolution: {integrity: sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==} @@ -6992,9 +6798,6 @@ packages: lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - lodash@4.18.1: - resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} - log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} @@ -7007,8 +6810,8 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true - loupe@3.2.1: - resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + loupe@3.1.4: + resolution: {integrity: sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==} lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} @@ -7020,8 +6823,8 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.3.3: - resolution: {integrity: sha512-JvNw9Y81y33E+BEYPr0U7omo+U9AySnsMsEiXgwT6yqd31VQWTLNQqmT4ou5eqPFUrTfIDFta2wKhB1hyohtAQ==} + lru-cache@11.1.0: + resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -7037,8 +6840,8 @@ packages: magic-string@0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} magicast@0.3.5: resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} @@ -7091,19 +6894,14 @@ packages: resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==} engines: {node: '>= 4.0.0'} - memfs@4.57.1: - resolution: {integrity: sha512-WvzrWPwMQT+PtbX2Et64R4qXKK0fj/8pO85MrUCzymX3twwCiJCdvntW3HdhG1teLJcHDDLIKx5+c3HckWYZtQ==} - peerDependencies: - tslib: '2' + memfs@4.24.0: + resolution: {integrity: sha512-PiyWpigBOgdsdvnn4U3PlQytj46ZEw/dMVmcqXuX1KUHoYzaGTL25E9rfK+c26mPAh9RmBdXldoxbQkYbH20Uw==} + engines: {node: '>= 4.0.0'} memorystream@0.3.1: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} - meow@13.2.0: - resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} - engines: {node: '>=18'} - meow@8.1.2: resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==} engines: {node: '>=10'} @@ -7145,10 +6943,6 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} - mime-types@3.0.2: - resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} - engines: {node: '>=18'} - mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} @@ -7170,8 +6964,8 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - mini-css-extract-plugin@2.10.2: - resolution: {integrity: sha512-AOSS0IdEB95ayVkxn5oGzNQwqAi2J0Jb/kKm43t7H73s8+f5873g0yuj0PNvK4dO75mu5DHg4nlgp4k6Kga8eg==} + mini-css-extract-plugin@2.9.2: + resolution: {integrity: sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==} engines: {node: '>= 12.13.0'} peerDependencies: webpack: ^5.0.0 @@ -7182,23 +6976,23 @@ packages: minimalistic-crypto-utils@1.0.1: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} - minimatch@10.2.5: - resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} - engines: {node: 18 || 20 || >=22} + minimatch@10.0.3: + resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} + engines: {node: 20 || >=22} - minimatch@3.1.5: - resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - minimatch@5.1.9: - resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} minimatch@9.0.3: resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} engines: {node: '>=16 || 14 >=14.17'} - minimatch@9.0.9: - resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} minimist-options@4.1.0: @@ -7211,8 +7005,8 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@7.1.3: - resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} mixme@0.5.10: @@ -7278,8 +7072,8 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - napi-postinstall@0.3.4: - resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} + napi-postinstall@0.2.4: + resolution: {integrity: sha512-ZEzHJwBhZ8qQSbknHqYcdtQVr8zUgGyM/q6h6qAyhtyVMNrSgDhrC4disf03dYW0e+czXyLnZINnCTEkWy0eJg==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} hasBin: true @@ -7309,7 +7103,6 @@ packages: next@15.3.4: resolution: {integrity: sha512-mHKd50C+mCjam/gcnwqL1T1vPx/XQNFlXqFIVdgQdVAFY9iIQtY0IfaVflEYzKiqjeA7B0cYYMaCrmAYFjs4rA==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} - deprecated: This version has a security vulnerability. Please upgrade to a patched version. See https://nextjs.org/blog/CVE-2025-66478 for more details. hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 @@ -7340,10 +7133,6 @@ packages: node-addon-api@5.1.0: resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} - node-exports-info@1.6.0: - resolution: {integrity: sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==} - engines: {node: '>= 0.4'} - node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -7353,8 +7142,8 @@ packages: encoding: optional: true - node-forge@1.4.0: - resolution: {integrity: sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==} + node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} node-gyp-build@4.8.4: @@ -7364,8 +7153,8 @@ packages: node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - node-releases@2.0.37: - resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==} + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -7378,6 +7167,10 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + normalize-url@6.1.0: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} engines: {node: '>=10'} @@ -7394,12 +7187,8 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - nth-check@3.0.1: - resolution: {integrity: sha512-GX0gsdbGVCgnRgbeGaubfjpBXyYRWOOCVeYh08bSQvDZqxz5ndXs1OTfAt/h36G1xvI94YIspsI0sVFqAV9+RQ==} - engines: {node: '>=20.19.0'} - - nwsapi@2.2.23: - resolution: {integrity: sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==} + nwsapi@2.2.20: + resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==} object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} @@ -7433,9 +7222,9 @@ packages: resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} engines: {node: '>= 0.4'} - object.getownpropertydescriptors@2.1.9: - resolution: {integrity: sha512-mt8YM6XwsTTovI+kdZdHSxoyF2DI59up034orlC9NfweclcWOt7CVascNNLp6U+bjFVCVCIh9PwS76tDM/rH8g==} - engines: {node: '>= 0.4'} + object.getownpropertydescriptors@2.1.8: + resolution: {integrity: sha512-qkHIGe4q0lSYMv0XI4SsBTJz3WaURhLvd0lKSgtVuOsJ2krg4SgMw3PIRQFMp07yi++UR3se2mkcLqsBNpBb/A==} + engines: {node: '>= 0.8'} object.groupby@1.0.3: resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} @@ -7452,8 +7241,8 @@ packages: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} - on-headers@1.1.0: - resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==} + on-headers@1.0.2: + resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} engines: {node: '>= 0.8'} once@1.4.0: @@ -7563,8 +7352,8 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} - parse-asn1@5.1.9: - resolution: {integrity: sha512-fIYNuZ/HastSb80baGOuPRo1O9cf4baWw5WsAp7dBuUzeTD/BoaG8sVTdlPFksBE2lF21dN+A1AnrpIjSWqHHg==} + parse-asn1@5.1.7: + resolution: {integrity: sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==} engines: {node: '>= 0.10'} parse-json@4.0.0: @@ -7616,12 +7405,12 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} - path-scurry@2.0.2: - resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} - engines: {node: 18 || 20 || >=22} + path-scurry@2.0.0: + resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} + engines: {node: 20 || >=22} - path-to-regexp@0.1.13: - resolution: {integrity: sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==} + path-to-regexp@0.1.12: + resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} path-to-regexp@2.4.0: resolution: {integrity: sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==} @@ -7641,9 +7430,9 @@ packages: resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} engines: {node: '>= 14.16'} - pbkdf2@3.1.5: - resolution: {integrity: sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==} - engines: {node: '>= 0.10'} + pbkdf2@3.1.3: + resolution: {integrity: sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA==} + engines: {node: '>=0.12'} performance-now@2.1.0: resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} @@ -7654,12 +7443,12 @@ packages: picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - picomatch@2.3.2: - resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - picomatch@4.0.4: - resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} pidtree@0.3.1: @@ -7691,10 +7480,6 @@ packages: resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==} engines: {node: '>=8'} - pkijs@3.4.0: - resolution: {integrity: sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw==} - engines: {node: '>=16.0.0'} - poseidon-lite@0.2.1: resolution: {integrity: sha512-xIr+G6HeYfOhCuswdqcFpSX47SPhm0EpisWJ6h7fHlWwaVIvH3dLnejpatrtw6Xc6HaLrpq05y7VRfvDmDGIog==} @@ -7861,8 +7646,8 @@ packages: peerDependencies: postcss: ^8.0.0 - postcss-js@4.1.0: - resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} + postcss-js@4.0.1: + resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: postcss: ^8.4.21 @@ -7873,22 +7658,16 @@ packages: peerDependencies: postcss: ^8.2 - postcss-load-config@6.0.1: - resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} - engines: {node: '>= 18'} + postcss-load-config@4.0.2: + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} + engines: {node: '>= 14'} peerDependencies: - jiti: '>=1.21.0' postcss: '>=8.0.9' - tsx: ^4.8.1 - yaml: ^2.4.2 + ts-node: '>=9.0.0' peerDependenciesMeta: - jiti: - optional: true postcss: optional: true - tsx: - optional: true - yaml: + ts-node: optional: true postcss-loader@6.2.1: @@ -8111,8 +7890,8 @@ packages: resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} engines: {node: '>=4'} - postcss-selector-parser@7.1.1: - resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} + postcss-selector-parser@7.1.0: + resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} engines: {node: '>=4'} postcss-svgo@5.1.0: @@ -8138,8 +7917,8 @@ packages: resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} - postcss@8.5.9: - resolution: {integrity: sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==} + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.1.2: @@ -8168,8 +7947,8 @@ packages: engines: {node: '>=10.13.0'} hasBin: true - prettier@3.8.2: - resolution: {integrity: sha512-8c3mgTe0ASwWAJK+78dpviD+A8EqhndQPUBpNUIPt6+xWlIigCwfN01lWr9MAede4uqXGTEKeQWTvzb3vjia0Q==} + prettier@3.6.1: + resolution: {integrity: sha512-5xGWRa90Sp2+x1dQtNpIpeOQpTDBs9cZDmA/qs2vDNN2i18PdapqY7CmBeyLlMuGqXJRIOPaCaVZTLNQRWUH/A==} engines: {node: '>=14'} hasBin: true @@ -8212,6 +7991,9 @@ packages: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + proxy-from-env@2.1.0: resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} engines: {node: '>=10'} @@ -8222,20 +8004,13 @@ packages: public-encrypt@4.0.3: resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} - pump@3.0.4: - resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + pump@3.0.3: + resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - pvtsutils@1.3.6: - resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} - - pvutils@1.1.5: - resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} - engines: {node: '>=16.0.0'} - q@1.5.1: resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==} engines: {node: '>=0.6.0', teleport: '>=0.2.0'} @@ -8244,16 +8019,16 @@ packages: (For a CapTP with native promises, see @endo/eventual-send and @endo/captp) - qs@6.14.2: - resolution: {integrity: sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==} + qs@6.13.0: + resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} engines: {node: '>=0.6'} - qs@6.15.1: - resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} + qs@6.14.0: + resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} engines: {node: '>=0.6'} - quansync@0.2.11: - resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + quansync@0.2.10: + resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==} querystring@0.2.1: resolution: {integrity: sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==} @@ -8287,18 +8062,18 @@ packages: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} - raw-body@2.5.3: - resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} + raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} react-app-polyfill@3.0.0: resolution: {integrity: sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==} engines: {node: '>=14'} - react-copy-to-clipboard@5.1.1: - resolution: {integrity: sha512-s+HrzLyJBxrpGTYXF15dTgMjAJpEPZT/Yp6NytAtZMRngejxt6Pt5WrfFxLAcsqUDU6sY1Jz6tyHwIicE1U2Xg==} + react-copy-to-clipboard@5.1.0: + resolution: {integrity: sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A==} peerDependencies: - react: '>=15.3.0' + react: ^15.3.0 || 16 || 17 || 18 react-dev-utils@12.0.1: resolution: {integrity: sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==} @@ -8411,15 +8186,12 @@ packages: resolution: {integrity: sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - reflect-metadata@0.2.2: - resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} - reflect.getprototypeof@1.0.10: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} - regenerate-unicode-properties@10.2.2: - resolution: {integrity: sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==} + regenerate-unicode-properties@10.2.0: + resolution: {integrity: sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==} engines: {node: '>=4'} regenerate@1.4.2: @@ -8439,15 +8211,15 @@ packages: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} - regexpu-core@6.4.0: - resolution: {integrity: sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==} + regexpu-core@6.2.0: + resolution: {integrity: sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==} engines: {node: '>=4'} regjsgen@0.8.0: resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} - regjsparser@0.13.1: - resolution: {integrity: sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==} + regjsparser@0.12.0: + resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==} hasBin: true relateurl@0.2.7: @@ -8506,14 +8278,13 @@ packages: resolution: {integrity: sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==} engines: {node: '>=10'} - resolve@1.22.11: - resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} engines: {node: '>= 0.4'} hasBin: true - resolve@2.0.0-next.6: - resolution: {integrity: sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==} - engines: {node: '>= 0.4'} + resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} hasBin: true responselike@2.0.1: @@ -8540,9 +8311,11 @@ packages: resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} hasBin: true - ripemd160@2.0.3: - resolution: {integrity: sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==} - engines: {node: '>= 0.8'} + ripemd160@2.0.1: + resolution: {integrity: sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w==} + + ripemd160@2.0.2: + resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} rollup-plugin-terser@7.0.2: resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} @@ -8550,21 +8323,21 @@ packages: peerDependencies: rollup: ^2.0.0 - rollup@2.80.0: - resolution: {integrity: sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ==} + rollup@2.79.2: + resolution: {integrity: sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==} engines: {node: '>=10.0.0'} hasBin: true - rollup@4.60.1: - resolution: {integrity: sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==} + rollup@4.44.1: + resolution: {integrity: sha512-x8H8aPvD+xbl0Do8oez5f5o8eMS3trfCghc4HhLAnCkj7Vl0d1JWGs0UF/D886zLW2rOj2QymV/JcSSsw+XDNg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - rpc-websockets@9.3.8: - resolution: {integrity: sha512-7r+fm4tSJmLf9GvZfL1DJ1SJwpagpp6AazqM0FUaeV7CA+7+NYINSk1syWa4tU/6OF2CyBicLtzENGmXRJH6wQ==} + rpc-websockets@9.1.1: + resolution: {integrity: sha512-1IXGM/TfPT6nfYMIXkJdzn+L4JEsmb0FL1O2OBjaH03V3yuUDdKFulGLMFG6ErV+8pZ5HVC0limve01RyO+saA==} - run-applescript@7.1.0: - resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + run-applescript@7.0.0: + resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} engines: {node: '>=18'} run-async@2.4.1: @@ -8623,10 +8396,6 @@ packages: sax@1.2.4: resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} - sax@1.6.0: - resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} - engines: {node: '>=11.0.0'} - saxes@5.0.1: resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==} engines: {node: '>=10'} @@ -8646,8 +8415,8 @@ packages: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} engines: {node: '>= 10.13.0'} - schema-utils@4.3.3: - resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} + schema-utils@4.3.2: + resolution: {integrity: sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==} engines: {node: '>= 10.13.0'} scrypt-js@3.0.1: @@ -8668,10 +8437,6 @@ packages: resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} engines: {node: '>=10'} - selfsigned@5.5.0: - resolution: {integrity: sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==} - engines: {node: '>=18'} - semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -8680,13 +8445,13 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.7.4: - resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} engines: {node: '>=10'} hasBin: true - send@0.19.2: - resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} + send@0.19.0: + resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} engines: {node: '>= 0.8.0'} serialize-javascript@4.0.0: @@ -8695,12 +8460,12 @@ packages: serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - serve-index@1.9.2: - resolution: {integrity: sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ==} + serve-index@1.9.1: + resolution: {integrity: sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==} engines: {node: '>= 0.8.0'} - serve-static@1.16.3: - resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} + serve-static@1.16.2: + resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} engines: {node: '>= 0.8.0'} set-function-length@1.2.2: @@ -8715,20 +8480,22 @@ packages: resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} engines: {node: '>= 0.4'} + setprototypeof@1.1.0: + resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} + setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - sha.js@2.4.12: - resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} - engines: {node: '>= 0.10'} + sha.js@2.4.11: + resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} hasBin: true shallow-clone@3.0.1: resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} engines: {node: '>=8'} - sharp@0.34.5: - resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + sharp@0.34.3: + resolution: {integrity: sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} shebang-command@1.2.0: @@ -8754,8 +8521,8 @@ packages: shiki@0.14.7: resolution: {integrity: sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==} - side-channel-list@1.0.1: - resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} side-channel-map@1.0.1: @@ -8780,6 +8547,9 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -8826,9 +8596,9 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - source-map@0.7.6: - resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} - engines: {node: '>= 12'} + source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} source-map@0.8.0-beta.0: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} @@ -8851,8 +8621,8 @@ packages: spdx-expression-parse@3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - spdx-license-ids@3.0.23: - resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} + spdx-license-ids@3.0.21: + resolution: {integrity: sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==} spdy-transport@3.0.0: resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} @@ -8895,19 +8665,16 @@ packages: static-eval@2.0.2: resolution: {integrity: sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==} - static-eval@2.1.1: - resolution: {integrity: sha512-MgWpQ/ZjGieSVB3eOJVs4OA2LT/q1vx98KPCTTQPzq/aLr0YUXTsgryTXr4SLfR0ZfUUCiedM9n/ABeDIyy4mA==} - statuses@1.5.0: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} - statuses@2.0.2: - resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} - std-env@3.10.0: - resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + std-env@3.9.0: + resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} @@ -8996,8 +8763,8 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.2.0: - resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} engines: {node: '>=12'} strip-bom@3.0.0: @@ -9024,8 +8791,8 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strip-literal@3.1.0: - resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} + strip-literal@3.0.0: + resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} strip-outer@1.0.1: resolution: {integrity: sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==} @@ -9056,8 +8823,8 @@ packages: peerDependencies: postcss: ^8.2.15 - sucrase@3.35.1: - resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} engines: {node: '>=16 || 14 >=14.17'} hasBin: true @@ -9094,8 +8861,8 @@ packages: deprecated: This SVGO version is no longer supported. Upgrade to v2.x.x. hasBin: true - svgo@2.8.2: - resolution: {integrity: sha512-TyzE4NVGLUFy+H/Uy4N6c3G0HEeprsVfge6Lmq+0FdQQ/zqoVYB62IsBZORsiL+o96s6ff/V6/3UQo/C0cgCAA==} + svgo@2.8.0: + resolution: {integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==} engines: {node: '>=10.13.0'} hasBin: true @@ -9106,8 +8873,8 @@ packages: resolution: {integrity: sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==} engines: {node: '>=8.0.0'} - tailwindcss@3.4.19: - resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==} + tailwindcss@3.4.17: + resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} engines: {node: '>=14.0.0'} hasBin: true @@ -9115,8 +8882,8 @@ packages: resolution: {integrity: sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==} engines: {node: '>=6'} - tapable@2.3.2: - resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==} + tapable@2.2.2: + resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} engines: {node: '>=6'} temp-dir@2.0.0: @@ -9135,8 +8902,8 @@ packages: resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} engines: {node: '>=8'} - terser-webpack-plugin@5.4.0: - resolution: {integrity: sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==} + terser-webpack-plugin@5.3.14: + resolution: {integrity: sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' @@ -9151,8 +8918,8 @@ packages: uglify-js: optional: true - terser@5.46.1: - resolution: {integrity: sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==} + terser@5.43.1: + resolution: {integrity: sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==} engines: {node: '>=10'} hasBin: true @@ -9160,8 +8927,8 @@ packages: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} - test-exclude@7.0.2: - resolution: {integrity: sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw==} + test-exclude@7.0.1: + resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} engines: {node: '>=18'} text-encoding-utf-8@1.0.2: @@ -9181,8 +8948,8 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - thingies@2.6.0: - resolution: {integrity: sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==} + thingies@1.21.0: + resolution: {integrity: sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==} engines: {node: '>=10.18'} peerDependencies: tslib: ^2 @@ -9208,8 +8975,8 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - tinyglobby@0.2.16: - resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} + tinyglobby@0.2.14: + resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} engines: {node: '>=12.0.0'} tinypool@1.1.1: @@ -9220,8 +8987,12 @@ packages: resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} engines: {node: '>=14.0.0'} - tinyspy@4.0.4: - resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + + tinyspy@4.0.3: + resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==} engines: {node: '>=14.0.0'} tmp-promise@3.0.3: @@ -9231,15 +9002,15 @@ packages: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} - tmp@0.2.5: - resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} + tmp@0.2.3: + resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} engines: {node: '>=14.14'} tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} - to-buffer@1.2.2: - resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} + to-buffer@1.2.1: + resolution: {integrity: sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==} engines: {node: '>= 0.4'} to-regex-range@5.0.1: @@ -9270,8 +9041,8 @@ packages: resolution: {integrity: sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==} engines: {node: '>=8'} - tree-dump@1.1.0: - resolution: {integrity: sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==} + tree-dump@1.0.3: + resolution: {integrity: sha512-il+Cv80yVHFBwokQSfd4bldvr1Md951DpgAGfmhydt04L+YzHgubm2tQ7zueWDcGENKHq0ZvGFR/hjvNXilHEg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -9293,12 +9064,6 @@ packages: peerDependencies: typescript: '>=4.2.0' - ts-api-utils@2.5.0: - resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} - engines: {node: '>=18.12'} - peerDependencies: - typescript: '>=4.8.4' - ts-command-line-args@2.5.1: resolution: {integrity: sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==} hasBin: true @@ -9346,10 +9111,6 @@ packages: peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - tsyringe@4.10.0: - resolution: {integrity: sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==} - engines: {node: '>= 6.0.0'} - tweetnacl@1.0.3: resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} @@ -9432,8 +9193,8 @@ packages: peerDependencies: typedoc: 0.24.x || 0.25.x - typedoc-plugin-zod@1.4.3: - resolution: {integrity: sha512-j3kb4dGGK5OegtiIOH4F4etYdqq2lh+sTx6sABTmptPJJm8qx9XHyNlzfLYqW86ZVfL0hFR3+B/Ij9YXQw9TsA==} + typedoc-plugin-zod@1.4.2: + resolution: {integrity: sha512-DERrqbKyW1DAWgs+L3sgCTxrVJQuHg4whj0FZcXWIVdwtoYYSnxK2XSS9gepBwyRwlojjVux1ZjSPwDsWz9ulg==} peerDependencies: typedoc: 0.23.x || 0.24.x || 0.25.x || 0.26.x || 0.27.x || 0.28.x @@ -9454,8 +9215,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + typescript@5.8.3: + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} engines: {node: '>=14.17'} hasBin: true @@ -9476,8 +9237,8 @@ packages: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} - underscore@1.13.6: - resolution: {integrity: sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==} + underscore@1.12.1: + resolution: {integrity: sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==} undici-types@7.10.0: resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} @@ -9490,12 +9251,12 @@ packages: resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} engines: {node: '>=4'} - unicode-match-property-value-ecmascript@2.2.1: - resolution: {integrity: sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==} + unicode-match-property-value-ecmascript@2.2.0: + resolution: {integrity: sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==} engines: {node: '>=4'} - unicode-property-aliases-ecmascript@2.2.0: - resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==} + unicode-property-aliases-ecmascript@2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} engines: {node: '>=4'} unique-string@2.0.0: @@ -9521,15 +9282,15 @@ packages: unquote@1.1.1: resolution: {integrity: sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==} - unrs-resolver@1.11.1: - resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + unrs-resolver@1.9.2: + resolution: {integrity: sha512-VUyWiTNQD7itdiMuJy+EuLEErLj3uwX/EpHQF8EOf33Dq3Ju6VW1GXm+swk6+1h7a49uv9fKZ+dft9jU7esdLA==} upath@1.2.0: resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} engines: {node: '>=4'} - update-browserslist-db@1.2.3: - resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + update-browserslist-db@1.1.3: + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -9540,8 +9301,8 @@ packages: url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} - utf-8-validate@6.0.6: - resolution: {integrity: sha512-q3l3P9UtEEiAHcsgsqTgf9PPjctrDWoIXW3NpOHFdRDbLvu4DLIcxHangJ4RLrWkBcKjmcs/6NkerI8T/rE4LA==} + utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} engines: {node: '>=6.14.2'} util-deprecate@1.0.2: @@ -9557,10 +9318,6 @@ packages: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} - uuid@11.1.0: - resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} - hasBin: true - uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true @@ -9579,13 +9336,58 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + vite-node@3.0.9: + resolution: {integrity: sha512-w3Gdx7jDcuT9cNn9jExXgOyKmf5UOTb6WMHz8LGAm54eS1Elf5OuBhCxl6zJxGhEeIkgsE1WbHuoL0mj/UXqXg==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + vite-node@3.2.4: resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true - vite@7.3.2: - resolution: {integrity: sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==} + vite@6.3.5: + resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vite@7.0.0: + resolution: {integrity: sha512-ixXJB1YRgDIw2OszKQS9WxGHKwLdCsbQNkpJN171udl6szi/rIySHL6/Os3s2+oE4P/FLD4dxg4mD7Wust+u5g==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -9624,6 +9426,34 @@ packages: yaml: optional: true + vitest@3.0.9: + resolution: {integrity: sha512-BbcFDqNyBlfSpATmTtXOAOj71RNKDDvjBM/uPfnxxVGrG+FSH2RQIwgeEngTaTkuU/h0ScFvf+tRcKfYXzBybQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/debug': ^4.1.12 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@vitest/browser': 3.0.9 + '@vitest/ui': 3.0.9 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/debug': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + vitest@3.2.4: resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -9675,8 +9505,8 @@ packages: walker@1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} - watchpack@2.5.1: - resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} + watchpack@2.4.4: + resolution: {integrity: sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==} engines: {node: '>=10.13.0'} wbuf@1.7.3: @@ -9719,8 +9549,8 @@ packages: peerDependencies: webpack: ^4.0.0 || ^5.0.0 - webpack-dev-middleware@7.4.5: - resolution: {integrity: sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA==} + webpack-dev-middleware@7.4.2: + resolution: {integrity: sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==} engines: {node: '>= 18.12.0'} peerDependencies: webpack: ^5.0.0 @@ -9741,8 +9571,8 @@ packages: webpack-cli: optional: true - webpack-dev-server@5.2.3: - resolution: {integrity: sha512-9Gyu2F7+bg4Vv+pjbovuYDhHX+mqdqITykfzdM9UyKqKHlsE5aAjRhR+oOEfXW5vBeu8tarzlJFIZva4ZjAdrQ==} + webpack-dev-server@5.2.2: + resolution: {integrity: sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==} engines: {node: '>= 18.12.0'} hasBin: true peerDependencies: @@ -9771,12 +9601,12 @@ packages: resolution: {integrity: sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==} engines: {node: '>=10.13.0'} - webpack-sources@3.3.4: - resolution: {integrity: sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==} + webpack-sources@3.3.3: + resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==} engines: {node: '>=10.13.0'} - webpack@5.106.1: - resolution: {integrity: sha512-EW8af29ak8Oaf4T8k8YsajjrDBDYgnKZ5er6ljWFJsXABfTNowQfvHLftwcepVgdz+IoLSdEAbBiM9DFXoll9w==} + webpack@5.99.9: + resolution: {integrity: sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -9795,7 +9625,6 @@ packages: whatwg-encoding@1.0.5: resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==} - deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation whatwg-fetch@3.6.20: resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==} @@ -9828,8 +9657,8 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} - which-typed-array@1.1.20: - resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} + which-typed-array@1.1.19: + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} engines: {node: '>= 0.4'} which@1.3.1: @@ -9959,8 +9788,8 @@ packages: utf-8-validate: optional: true - ws@8.20.0: - resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} + ws@8.18.2: + resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -9995,10 +9824,15 @@ packages: yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - yaml@1.10.3: - resolution: {integrity: sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==} + yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} + yaml@2.8.0: + resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==} + engines: {node: '>= 14.6'} + hasBin: true + yargs-parser@20.2.9: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'} @@ -10019,8 +9853,13 @@ packages: resolution: {integrity: sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==} engines: {node: '>=10'} - zod@3.25.76: - resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod-to-json-schema@3.25.2: + resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} + peerDependencies: + zod: ^3.25.28 || ^4 + + zod@3.25.67: + resolution: {integrity: sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==} snapshots: @@ -10028,42 +9867,43 @@ snapshots: '@ampproject/remapping@2.3.0': dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 - '@apideck/better-ajv-errors@0.3.7(ajv@8.18.0)': + '@apideck/better-ajv-errors@0.3.6(ajv@8.17.1)': dependencies: - ajv: 8.18.0 + ajv: 8.17.1 + json-schema: 0.4.0 jsonpointer: 5.0.1 leven: 3.1.0 - '@aptos-labs/aptos-cli@1.1.1': + '@aptos-labs/aptos-cli@1.0.2': dependencies: commander: 12.1.0 - '@aptos-labs/aptos-client@1.2.0(axios@1.15.0)(got@11.8.6)': + '@aptos-labs/aptos-client@1.2.0(axios@1.10.0)(got@11.8.6)': dependencies: - axios: 1.15.0 + axios: 1.10.0 got: 11.8.6 - '@aptos-labs/aptos-dynamic-transaction-composer@0.1.6': {} + '@aptos-labs/aptos-dynamic-transaction-composer@0.1.3': {} '@aptos-labs/script-composer-pack@0.0.9': dependencies: - '@aptos-labs/aptos-dynamic-transaction-composer': 0.1.6 + '@aptos-labs/aptos-dynamic-transaction-composer': 0.1.3 - '@aptos-labs/ts-sdk@1.39.0(axios@1.15.0)(got@11.8.6)': + '@aptos-labs/ts-sdk@1.39.0(axios@1.10.0)(got@11.8.6)': dependencies: - '@aptos-labs/aptos-cli': 1.1.1 - '@aptos-labs/aptos-client': 1.2.0(axios@1.15.0)(got@11.8.6) + '@aptos-labs/aptos-cli': 1.0.2 + '@aptos-labs/aptos-client': 1.2.0(axios@1.10.0)(got@11.8.6) '@aptos-labs/script-composer-pack': 0.0.9 - '@noble/curves': 1.9.7 + '@noble/curves': 1.9.2 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - eventemitter3: 5.0.4 - form-data: 4.0.5 - js-base64: 3.7.8 + eventemitter3: 5.0.1 + form-data: 4.0.3 + js-base64: 3.7.7 jwt-decode: 4.0.0 poseidon-lite: 0.2.1 transitivePeerDependencies: @@ -10074,907 +9914,890 @@ snapshots: dependencies: static-eval: 2.0.2 - '@babel/code-frame@7.29.0': + '@babel/code-frame@7.27.1': dependencies: - '@babel/helper-validator-identifier': 7.28.5 + '@babel/helper-validator-identifier': 7.27.1 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.29.0': {} + '@babel/compat-data@7.27.5': {} - '@babel/core@7.29.0': + '@babel/core@7.27.4': dependencies: - '@babel/code-frame': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helpers': 7.29.2 - '@babel/parser': 7.29.2 - '@babel/template': 7.28.6 - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 - '@jridgewell/remapping': 2.3.5 + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.27.4) + '@babel/helpers': 7.27.6 + '@babel/parser': 7.27.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.27.4 + '@babel/types': 7.27.6 convert-source-map: 2.0.0 - debug: 4.4.3 + debug: 4.4.1 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/eslint-parser@7.28.6(@babel/core@7.29.0)(eslint@8.57.1)': + '@babel/eslint-parser@7.27.5(@babel/core@7.27.4)(eslint@8.57.1)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.27.4 '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 eslint: 8.57.1 eslint-visitor-keys: 2.1.0 semver: 6.3.1 - '@babel/generator@7.29.1': + '@babel/generator@7.27.5': dependencies: - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 + '@babel/parser': 7.27.5 + '@babel/types': 7.27.6 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.1.0 '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/types': 7.29.0 + '@babel/types': 7.27.6 - '@babel/helper-compilation-targets@7.28.6': + '@babel/helper-compilation-targets@7.27.2': dependencies: - '@babel/compat-data': 7.29.0 + '@babel/compat-data': 7.27.5 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.28.2 + browserslist: 4.25.1 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)': + '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.27.4 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-member-expression-to-functions': 7.27.1 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.4) '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.27.4 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.29.0)': + '@babel/helper-create-regexp-features-plugin@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.27.4 '@babel/helper-annotate-as-pure': 7.27.3 - regexpu-core: 6.4.0 + regexpu-core: 6.2.0 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.8(@babel/core@7.29.0)': + '@babel/helper-define-polyfill-provider@0.6.4(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - debug: 4.4.3 + '@babel/core': 7.27.4 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + debug: 4.4.1 lodash.debounce: 4.0.8 - resolve: 1.22.11 + resolve: 1.22.10 transitivePeerDependencies: - supports-color - '@babel/helper-globals@7.28.0': {} - - '@babel/helper-member-expression-to-functions@7.28.5': + '@babel/helper-member-expression-to-functions@7.27.1': dependencies: - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 + '@babel/traverse': 7.27.4 + '@babel/types': 7.27.6 transitivePeerDependencies: - supports-color - '@babel/helper-module-imports@7.28.6': + '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 + '@babel/traverse': 7.27.4 + '@babel/types': 7.27.6 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + '@babel/helper-module-transforms@7.27.3(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-imports': 7.28.6 - '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.29.0 + '@babel/core': 7.27.4 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.27.4 transitivePeerDependencies: - supports-color '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.29.0 + '@babel/types': 7.27.6 - '@babel/helper-plugin-utils@7.28.6': {} + '@babel/helper-plugin-utils@7.27.1': {} - '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.29.0)': + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.27.4 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-wrap-function': 7.28.6 - '@babel/traverse': 7.29.0 + '@babel/helper-wrap-function': 7.27.1 + '@babel/traverse': 7.27.4 transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': + '@babel/helper-replace-supers@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/core': 7.27.4 + '@babel/helper-member-expression-to-functions': 7.27.1 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.27.4 transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 + '@babel/traverse': 7.27.4 + '@babel/types': 7.27.6 transitivePeerDependencies: - supports-color '@babel/helper-string-parser@7.27.1': {} - '@babel/helper-validator-identifier@7.28.5': {} + '@babel/helper-validator-identifier@7.27.1': {} '@babel/helper-validator-option@7.27.1': {} - '@babel/helper-wrap-function@7.28.6': + '@babel/helper-wrap-function@7.27.1': dependencies: - '@babel/template': 7.28.6 - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 + '@babel/template': 7.27.2 + '@babel/traverse': 7.27.4 + '@babel/types': 7.27.6 transitivePeerDependencies: - supports-color - '@babel/helpers@7.29.2': + '@babel/helpers@7.27.6': dependencies: - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 + '@babel/template': 7.27.2 + '@babel/types': 7.27.6 - '@babel/parser@7.29.2': + '@babel/parser@7.27.5': dependencies: - '@babel/types': 7.29.0 + '@babel/types': 7.27.6 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.29.0)': + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.29.0 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.27.4 transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.27.4) transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.29.0 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.27.4 transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.29.0)': + '@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-decorators@7.29.0(@babel/core@7.29.0)': + '@babel/plugin-proposal-decorators@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-decorators': 7.28.6(@babel/core@7.29.0) + '@babel/core': 7.27.4 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-decorators': 7.27.1(@babel/core@7.27.4) transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.29.0)': + '@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.29.0) + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.27.4) - '@babel/plugin-proposal-numeric-separator@7.18.6(@babel/core@7.29.0)': + '@babel/plugin-proposal-numeric-separator@7.18.6(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.29.0) + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.27.4) - '@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.29.0)': + '@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.27.4) transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.29.0)': + '@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0)': + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.27.4 - '@babel/plugin-proposal-private-property-in-object@7.21.11(@babel/core@7.29.0)': + '@babel/plugin-proposal-private-property-in-object@7.21.11(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.27.4 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.29.0) + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.27.4) transitivePeerDependencies: - supports-color - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.29.0)': + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.29.0)': + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.29.0)': + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.29.0)': + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-decorators@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-syntax-decorators@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-syntax-flow@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-assertions@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.29.0)': + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.29.0)': + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.29.0)': + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.29.0)': + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.29.0)': + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.29.0)': + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.29.0)': + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.29.0)': + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.29.0)': + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.29.0)': + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.29.0)': + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-async-generator-functions@7.29.0(@babel/core@7.29.0)': + '@babel/plugin-transform-async-generator-functions@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) - '@babel/traverse': 7.29.0 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.27.4) + '@babel/traverse': 7.27.4 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-imports': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) + '@babel/core': 7.27.4 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.27.4) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-block-scoping@7.27.5(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-static-block@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-class-static-block@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-classes@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-classes@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.27.4 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-globals': 7.28.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) - '@babel/traverse': 7.29.0 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.4) + '@babel/traverse': 7.27.4 + globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/template': 7.28.6 - - '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.29.0)': + '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/template': 7.27.2 - '@babel/plugin-transform-dotall-regex@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-destructuring@7.27.3(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-explicit-resource-management@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-exponentiation-operator@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-exponentiation-operator@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-flow-strip-types@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-flow-strip-types@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-flow': 7.28.6(@babel/core@7.29.0) + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-flow': 7.27.1(@babel/core@7.27.4) - '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.29.0 + '@babel/core': 7.27.4 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.27.4 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-json-strings@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-literals@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-logical-assignment-operators@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-logical-assignment-operators@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-systemjs@7.29.0(@babel/core@7.29.0)': + '@babel/plugin-transform-modules-systemjs@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.29.0 + '@babel/core': 7.27.4 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.27.4 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': + '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-object-rest-spread@7.27.3(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color + '@babel/core': 7.27.4 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-destructuring': 7.27.3(@babel/core@7.27.4) + '@babel/plugin-transform-parameters': 7.27.1(@babel/core@7.27.4) - '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.4) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-optional-chaining@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.29.0)': + '@babel/plugin-transform-parameters@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.27.4 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.29.0)': + '@babel/plugin-transform-react-display-name@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/core': 7.27.4 + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.27.4) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.27.4 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-module-imports': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) - '@babel/types': 7.29.0 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.4) + '@babel/types': 7.27.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.27.4 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-regenerator@7.29.0(@babel/core@7.29.0)': + '@babel/plugin-transform-regenerator@7.27.5(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-regexp-modifiers@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-runtime@7.29.0(@babel/core@7.29.0)': + '@babel/plugin-transform-runtime@7.27.4(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-imports': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.0) - babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.29.0) - babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.0) + '@babel/core': 7.27.4 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + babel-plugin-polyfill-corejs2: 0.4.13(@babel/core@7.27.4) + babel-plugin-polyfill-corejs3: 0.11.1(@babel/core@7.27.4) + babel-plugin-polyfill-regenerator: 0.6.4(@babel/core@7.27.4) semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-spread@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-spread@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-typescript@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.27.4 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.4) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-property-regex@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-unicode-property-regex@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-sets-regex@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.27.4) + '@babel/helper-plugin-utils': 7.27.1 - '@babel/preset-env@7.29.2(@babel/core@7.29.0)': + '@babel/preset-env@7.27.2(@babel/core@7.27.4)': dependencies: - '@babel/compat-data': 7.29.0 - '@babel/core': 7.29.0 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/compat-data': 7.27.5 + '@babel/core': 7.27.4 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.29.0) - '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0) - '@babel/plugin-syntax-import-assertions': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.29.0) - '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-async-generator-functions': 7.29.0(@babel/core@7.29.0) - '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-computed-properties': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) - '@babel/plugin-transform-dotall-regex': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) - '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-explicit-resource-management': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-exponentiation-operator': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-json-strings': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-logical-assignment-operators': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-modules-systemjs': 7.29.0(@babel/core@7.29.0) - '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) - '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-object-rest-spread': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-optional-catch-binding': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) - '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-regenerator': 7.29.0(@babel/core@7.29.0) - '@babel/plugin-transform-regexp-modifiers': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-unicode-property-regex': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-unicode-sets-regex': 7.28.6(@babel/core@7.29.0) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.0) - babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.0) - babel-plugin-polyfill-corejs3: 0.14.2(@babel/core@7.29.0) - babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.0) - core-js-compat: 3.49.0 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.27.4) + '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.27.4) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-async-generator-functions': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-block-scoping': 7.27.5(@babel/core@7.27.4) + '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-class-static-block': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-classes': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-destructuring': 7.27.3(@babel/core@7.27.4) + '@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-exponentiation-operator': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-logical-assignment-operators': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-modules-systemjs': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-object-rest-spread': 7.27.3(@babel/core@7.27.4) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-parameters': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-regenerator': 7.27.5(@babel/core@7.27.4) + '@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.27.4) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.27.4) + babel-plugin-polyfill-corejs2: 0.4.13(@babel/core@7.27.4) + babel-plugin-polyfill-corejs3: 0.11.1(@babel/core@7.27.4) + babel-plugin-polyfill-regenerator: 0.6.4(@babel/core@7.27.4) + core-js-compat: 3.43.0 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.0)': + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/types': 7.29.0 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/types': 7.27.6 esutils: 2.0.3 - '@babel/preset-react@7.28.5(@babel/core@7.29.0)': + '@babel/preset-react@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.29.0) - '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-display-name': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.27.4) transitivePeerDependencies: - supports-color - '@babel/preset-typescript@7.28.5(@babel/core@7.29.0)': + '@babel/preset-typescript@7.27.1(@babel/core@7.27.4)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-typescript': 7.27.1(@babel/core@7.27.4) transitivePeerDependencies: - supports-color - '@babel/runtime@7.29.2': {} + '@babel/runtime@7.27.6': {} - '@babel/template@7.28.6': + '@babel/template@7.27.2': dependencies: - '@babel/code-frame': 7.29.0 - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.27.5 + '@babel/types': 7.27.6 - '@babel/traverse@7.29.0': + '@babel/traverse@7.27.4': dependencies: - '@babel/code-frame': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.29.2 - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 - debug: 4.4.3 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.5 + '@babel/parser': 7.27.5 + '@babel/template': 7.27.2 + '@babel/types': 7.27.6 + debug: 4.4.1 + globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.29.0': + '@babel/types@7.27.6': dependencies: '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 + '@babel/helper-validator-identifier': 7.27.1 '@bcoe/v8-coverage@0.2.3': {} '@bcoe/v8-coverage@1.0.2': {} - '@changesets/apply-release-plan@7.1.0': + '@changesets/apply-release-plan@7.0.12': dependencies: - '@changesets/config': 3.1.3 + '@changesets/config': 3.1.1 '@changesets/get-version-range-type': 0.4.0 '@changesets/git': 3.0.4 '@changesets/should-skip-package': 0.1.2 @@ -10986,7 +10809,7 @@ snapshots: outdent: 0.5.0 prettier: 2.8.8 resolve-from: 5.0.0 - semver: 7.7.4 + semver: 7.7.2 '@changesets/assemble-release-plan@6.0.9': dependencies: @@ -10995,49 +10818,48 @@ snapshots: '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 - semver: 7.7.4 + semver: 7.7.2 '@changesets/changelog-git@0.2.1': dependencies: '@changesets/types': 6.1.0 - '@changesets/cli@2.30.0(@types/node@24.3.0)': + '@changesets/cli@2.29.5': dependencies: - '@changesets/apply-release-plan': 7.1.0 + '@changesets/apply-release-plan': 7.0.12 '@changesets/assemble-release-plan': 6.0.9 '@changesets/changelog-git': 0.2.1 - '@changesets/config': 3.1.3 + '@changesets/config': 3.1.1 '@changesets/errors': 0.2.0 '@changesets/get-dependents-graph': 2.1.3 - '@changesets/get-release-plan': 4.0.15 + '@changesets/get-release-plan': 4.0.13 '@changesets/git': 3.0.4 '@changesets/logger': 0.1.1 '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.7 + '@changesets/read': 0.6.5 '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@changesets/write': 0.4.0 - '@inquirer/external-editor': 1.0.3(@types/node@24.3.0) '@manypkg/get-packages': 1.1.3 ansi-colors: 4.1.3 + ci-info: 3.9.0 enquirer: 2.4.1 + external-editor: 3.1.0 fs-extra: 7.0.1 mri: 1.2.0 + p-limit: 2.3.0 package-manager-detector: 0.2.11 picocolors: 1.1.1 resolve-from: 5.0.0 - semver: 7.7.4 + semver: 7.7.2 spawndamnit: 3.0.1 term-size: 2.2.1 - transitivePeerDependencies: - - '@types/node' - '@changesets/config@3.1.3': + '@changesets/config@3.1.1': dependencies: '@changesets/errors': 0.2.0 '@changesets/get-dependents-graph': 2.1.3 '@changesets/logger': 0.1.1 - '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 @@ -11052,14 +10874,14 @@ snapshots: '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 picocolors: 1.1.1 - semver: 7.7.4 + semver: 7.7.2 - '@changesets/get-release-plan@4.0.15': + '@changesets/get-release-plan@4.0.13': dependencies: '@changesets/assemble-release-plan': 6.0.9 - '@changesets/config': 3.1.3 + '@changesets/config': 3.1.1 '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.7 + '@changesets/read': 0.6.5 '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 @@ -11077,10 +10899,10 @@ snapshots: dependencies: picocolors: 1.1.1 - '@changesets/parse@0.4.3': + '@changesets/parse@0.4.1': dependencies: '@changesets/types': 6.1.0 - js-yaml: 4.1.1 + js-yaml: 3.14.1 '@changesets/pre@2.0.2': dependencies: @@ -11089,11 +10911,11 @@ snapshots: '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 - '@changesets/read@0.6.7': + '@changesets/read@0.6.5': dependencies: '@changesets/git': 3.0.4 '@changesets/logger': 0.1.1 - '@changesets/parse': 0.4.3 + '@changesets/parse': 0.4.1 '@changesets/types': 6.1.0 fs-extra: 7.0.1 p-filter: 2.1.0 @@ -11112,52 +10934,53 @@ snapshots: dependencies: '@changesets/types': 6.1.0 fs-extra: 7.0.1 - human-id: 4.1.3 + human-id: 4.1.1 prettier: 2.8.8 '@commander-js/extra-typings@12.1.0(commander@12.1.0)': dependencies: commander: 12.1.0 - '@commitlint/config-validator@20.5.0': + '@commitlint/config-validator@19.8.1': dependencies: - '@commitlint/types': 20.5.0 - ajv: 8.18.0 + '@commitlint/types': 19.8.1 + ajv: 8.17.1 optional: true - '@commitlint/execute-rule@20.0.0': + '@commitlint/execute-rule@19.8.1': optional: true - '@commitlint/load@20.5.0(@types/node@24.3.0)(typescript@5.9.3)': + '@commitlint/load@19.8.1(@types/node@24.3.0)(typescript@5.8.3)': dependencies: - '@commitlint/config-validator': 20.5.0 - '@commitlint/execute-rule': 20.0.0 - '@commitlint/resolve-extends': 20.5.0 - '@commitlint/types': 20.5.0 - cosmiconfig: 9.0.1(typescript@5.9.3) - cosmiconfig-typescript-loader: 6.3.0(@types/node@24.3.0)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3) - is-plain-obj: 4.1.0 - lodash.mergewith: 4.6.2 - picocolors: 1.1.1 + '@commitlint/config-validator': 19.8.1 + '@commitlint/execute-rule': 19.8.1 + '@commitlint/resolve-extends': 19.8.1 + '@commitlint/types': 19.8.1 + chalk: 5.4.1 + cosmiconfig: 9.0.0(typescript@5.8.3) + cosmiconfig-typescript-loader: 6.1.0(@types/node@24.3.0)(cosmiconfig@9.0.0(typescript@5.8.3))(typescript@5.8.3) + lodash.isplainobject: 4.0.6 + lodash.merge: 4.6.2 + lodash.uniq: 4.5.0 transitivePeerDependencies: - '@types/node' - typescript optional: true - '@commitlint/resolve-extends@20.5.0': + '@commitlint/resolve-extends@19.8.1': dependencies: - '@commitlint/config-validator': 20.5.0 - '@commitlint/types': 20.5.0 + '@commitlint/config-validator': 19.8.1 + '@commitlint/types': 19.8.1 global-directory: 4.0.1 - import-meta-resolve: 4.2.0 + import-meta-resolve: 4.1.0 lodash.mergewith: 4.6.2 resolve-from: 5.0.0 optional: true - '@commitlint/types@20.5.0': + '@commitlint/types@19.8.1': dependencies: - conventional-commits-parser: 6.4.0 - picocolors: 1.1.1 + '@types/conventional-commits-parser': 5.0.1 + chalk: 5.4.1 optional: true '@cspotcode/source-map-support@0.8.1': @@ -11166,79 +10989,79 @@ snapshots: '@csstools/normalize.css@12.1.1': {} - '@csstools/postcss-cascade-layers@1.1.1(postcss@8.5.9)': + '@csstools/postcss-cascade-layers@1.1.1(postcss@8.5.6)': dependencies: '@csstools/selector-specificity': 2.2.0(postcss-selector-parser@6.1.2) - postcss: 8.5.9 + postcss: 8.5.6 postcss-selector-parser: 6.1.2 - '@csstools/postcss-color-function@1.1.1(postcss@8.5.9)': + '@csstools/postcss-color-function@1.1.1(postcss@8.5.6)': dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.9) - postcss: 8.5.9 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.6) + postcss: 8.5.6 postcss-value-parser: 4.2.0 - '@csstools/postcss-font-format-keywords@1.0.1(postcss@8.5.9)': + '@csstools/postcss-font-format-keywords@1.0.1(postcss@8.5.6)': dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - '@csstools/postcss-hwb-function@1.0.2(postcss@8.5.9)': + '@csstools/postcss-hwb-function@1.0.2(postcss@8.5.6)': dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - '@csstools/postcss-ic-unit@1.0.1(postcss@8.5.9)': + '@csstools/postcss-ic-unit@1.0.1(postcss@8.5.6)': dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.9) - postcss: 8.5.9 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.6) + postcss: 8.5.6 postcss-value-parser: 4.2.0 - '@csstools/postcss-is-pseudo-class@2.0.7(postcss@8.5.9)': + '@csstools/postcss-is-pseudo-class@2.0.7(postcss@8.5.6)': dependencies: '@csstools/selector-specificity': 2.2.0(postcss-selector-parser@6.1.2) - postcss: 8.5.9 + postcss: 8.5.6 postcss-selector-parser: 6.1.2 - '@csstools/postcss-nested-calc@1.0.0(postcss@8.5.9)': + '@csstools/postcss-nested-calc@1.0.0(postcss@8.5.6)': dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - '@csstools/postcss-normalize-display-values@1.0.1(postcss@8.5.9)': + '@csstools/postcss-normalize-display-values@1.0.1(postcss@8.5.6)': dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - '@csstools/postcss-oklab-function@1.1.1(postcss@8.5.9)': + '@csstools/postcss-oklab-function@1.1.1(postcss@8.5.6)': dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.9) - postcss: 8.5.9 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.6) + postcss: 8.5.6 postcss-value-parser: 4.2.0 - '@csstools/postcss-progressive-custom-properties@1.3.0(postcss@8.5.9)': + '@csstools/postcss-progressive-custom-properties@1.3.0(postcss@8.5.6)': dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - '@csstools/postcss-stepped-value-functions@1.0.1(postcss@8.5.9)': + '@csstools/postcss-stepped-value-functions@1.0.1(postcss@8.5.6)': dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - '@csstools/postcss-text-decoration-shorthand@1.0.0(postcss@8.5.9)': + '@csstools/postcss-text-decoration-shorthand@1.0.0(postcss@8.5.6)': dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - '@csstools/postcss-trigonometric-functions@1.0.2(postcss@8.5.9)': + '@csstools/postcss-trigonometric-functions@1.0.2(postcss@8.5.6)': dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - '@csstools/postcss-unset-value@1.0.2(postcss@8.5.9)': + '@csstools/postcss-unset-value@1.0.2(postcss@8.5.6)': dependencies: - postcss: 8.5.9 + postcss: 8.5.6 '@csstools/selector-specificity@2.2.0(postcss-selector-parser@6.1.2)': dependencies: @@ -11246,18 +11069,23 @@ snapshots: '@discoveryjs/json-ext@0.6.3': {} - '@emnapi/core@1.9.2': + '@emnapi/core@1.4.3': dependencies: - '@emnapi/wasi-threads': 1.2.1 + '@emnapi/wasi-threads': 1.0.2 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.9.2': + '@emnapi/runtime@1.4.3': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.2.1': + '@emnapi/runtime@1.4.5': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.0.2': dependencies: tslib: 2.8.1 optional: true @@ -11265,7 +11093,7 @@ snapshots: '@esbuild/aix-ppc64@0.19.12': optional: true - '@esbuild/aix-ppc64@0.27.7': + '@esbuild/aix-ppc64@0.25.5': optional: true '@esbuild/android-arm64@0.16.17': @@ -11274,7 +11102,7 @@ snapshots: '@esbuild/android-arm64@0.19.12': optional: true - '@esbuild/android-arm64@0.27.7': + '@esbuild/android-arm64@0.25.5': optional: true '@esbuild/android-arm@0.16.17': @@ -11283,7 +11111,7 @@ snapshots: '@esbuild/android-arm@0.19.12': optional: true - '@esbuild/android-arm@0.27.7': + '@esbuild/android-arm@0.25.5': optional: true '@esbuild/android-x64@0.16.17': @@ -11292,7 +11120,7 @@ snapshots: '@esbuild/android-x64@0.19.12': optional: true - '@esbuild/android-x64@0.27.7': + '@esbuild/android-x64@0.25.5': optional: true '@esbuild/darwin-arm64@0.16.17': @@ -11301,7 +11129,7 @@ snapshots: '@esbuild/darwin-arm64@0.19.12': optional: true - '@esbuild/darwin-arm64@0.27.7': + '@esbuild/darwin-arm64@0.25.5': optional: true '@esbuild/darwin-x64@0.16.17': @@ -11310,7 +11138,7 @@ snapshots: '@esbuild/darwin-x64@0.19.12': optional: true - '@esbuild/darwin-x64@0.27.7': + '@esbuild/darwin-x64@0.25.5': optional: true '@esbuild/freebsd-arm64@0.16.17': @@ -11319,7 +11147,7 @@ snapshots: '@esbuild/freebsd-arm64@0.19.12': optional: true - '@esbuild/freebsd-arm64@0.27.7': + '@esbuild/freebsd-arm64@0.25.5': optional: true '@esbuild/freebsd-x64@0.16.17': @@ -11328,7 +11156,7 @@ snapshots: '@esbuild/freebsd-x64@0.19.12': optional: true - '@esbuild/freebsd-x64@0.27.7': + '@esbuild/freebsd-x64@0.25.5': optional: true '@esbuild/linux-arm64@0.16.17': @@ -11337,7 +11165,7 @@ snapshots: '@esbuild/linux-arm64@0.19.12': optional: true - '@esbuild/linux-arm64@0.27.7': + '@esbuild/linux-arm64@0.25.5': optional: true '@esbuild/linux-arm@0.16.17': @@ -11346,7 +11174,7 @@ snapshots: '@esbuild/linux-arm@0.19.12': optional: true - '@esbuild/linux-arm@0.27.7': + '@esbuild/linux-arm@0.25.5': optional: true '@esbuild/linux-ia32@0.16.17': @@ -11355,7 +11183,7 @@ snapshots: '@esbuild/linux-ia32@0.19.12': optional: true - '@esbuild/linux-ia32@0.27.7': + '@esbuild/linux-ia32@0.25.5': optional: true '@esbuild/linux-loong64@0.16.17': @@ -11364,7 +11192,7 @@ snapshots: '@esbuild/linux-loong64@0.19.12': optional: true - '@esbuild/linux-loong64@0.27.7': + '@esbuild/linux-loong64@0.25.5': optional: true '@esbuild/linux-mips64el@0.16.17': @@ -11373,7 +11201,7 @@ snapshots: '@esbuild/linux-mips64el@0.19.12': optional: true - '@esbuild/linux-mips64el@0.27.7': + '@esbuild/linux-mips64el@0.25.5': optional: true '@esbuild/linux-ppc64@0.16.17': @@ -11382,7 +11210,7 @@ snapshots: '@esbuild/linux-ppc64@0.19.12': optional: true - '@esbuild/linux-ppc64@0.27.7': + '@esbuild/linux-ppc64@0.25.5': optional: true '@esbuild/linux-riscv64@0.16.17': @@ -11391,7 +11219,7 @@ snapshots: '@esbuild/linux-riscv64@0.19.12': optional: true - '@esbuild/linux-riscv64@0.27.7': + '@esbuild/linux-riscv64@0.25.5': optional: true '@esbuild/linux-s390x@0.16.17': @@ -11400,7 +11228,7 @@ snapshots: '@esbuild/linux-s390x@0.19.12': optional: true - '@esbuild/linux-s390x@0.27.7': + '@esbuild/linux-s390x@0.25.5': optional: true '@esbuild/linux-x64@0.16.17': @@ -11409,10 +11237,10 @@ snapshots: '@esbuild/linux-x64@0.19.12': optional: true - '@esbuild/linux-x64@0.27.7': + '@esbuild/linux-x64@0.25.5': optional: true - '@esbuild/netbsd-arm64@0.27.7': + '@esbuild/netbsd-arm64@0.25.5': optional: true '@esbuild/netbsd-x64@0.16.17': @@ -11421,10 +11249,10 @@ snapshots: '@esbuild/netbsd-x64@0.19.12': optional: true - '@esbuild/netbsd-x64@0.27.7': + '@esbuild/netbsd-x64@0.25.5': optional: true - '@esbuild/openbsd-arm64@0.27.7': + '@esbuild/openbsd-arm64@0.25.5': optional: true '@esbuild/openbsd-x64@0.16.17': @@ -11433,10 +11261,7 @@ snapshots: '@esbuild/openbsd-x64@0.19.12': optional: true - '@esbuild/openbsd-x64@0.27.7': - optional: true - - '@esbuild/openharmony-arm64@0.27.7': + '@esbuild/openbsd-x64@0.25.5': optional: true '@esbuild/sunos-x64@0.16.17': @@ -11445,7 +11270,7 @@ snapshots: '@esbuild/sunos-x64@0.19.12': optional: true - '@esbuild/sunos-x64@0.27.7': + '@esbuild/sunos-x64@0.25.5': optional: true '@esbuild/win32-arm64@0.16.17': @@ -11454,7 +11279,7 @@ snapshots: '@esbuild/win32-arm64@0.19.12': optional: true - '@esbuild/win32-arm64@0.27.7': + '@esbuild/win32-arm64@0.25.5': optional: true '@esbuild/win32-ia32@0.16.17': @@ -11463,7 +11288,7 @@ snapshots: '@esbuild/win32-ia32@0.19.12': optional: true - '@esbuild/win32-ia32@0.27.7': + '@esbuild/win32-ia32@0.25.5': optional: true '@esbuild/win32-x64@0.16.17': @@ -11472,31 +11297,31 @@ snapshots: '@esbuild/win32-x64@0.19.12': optional: true - '@esbuild/win32-x64@0.27.7': + '@esbuild/win32-x64@0.25.5': optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@8.57.0)': + '@eslint-community/eslint-utils@4.7.0(eslint@8.57.0)': dependencies: eslint: 8.57.0 eslint-visitor-keys: 3.4.3 - '@eslint-community/eslint-utils@4.9.1(eslint@8.57.1)': + '@eslint-community/eslint-utils@4.7.0(eslint@8.57.1)': dependencies: eslint: 8.57.1 eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.12.2': {} + '@eslint-community/regexpp@4.12.1': {} '@eslint/eslintrc@2.1.4': dependencies: - ajv: 6.14.0 - debug: 4.4.3 + ajv: 6.12.6 + debug: 4.4.1 espree: 9.6.1 globals: 13.24.0 ignore: 5.3.2 import-fresh: 3.3.1 - js-yaml: 4.1.1 - minimatch: 3.1.5 + js-yaml: 4.1.0 + minimatch: 3.1.2 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color @@ -11556,7 +11381,7 @@ snapshots: dependencies: '@ethersproject/bytes': 5.8.0 '@ethersproject/logger': 5.8.0 - bn.js: 5.2.3 + bn.js: 5.2.2 '@ethersproject/bytes@5.8.0': dependencies: @@ -11642,7 +11467,7 @@ snapshots: dependencies: '@ethersproject/logger': 5.8.0 - '@ethersproject/providers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + '@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@ethersproject/abstract-provider': 5.8.0 '@ethersproject/abstract-signer': 5.8.0 @@ -11663,7 +11488,7 @@ snapshots: '@ethersproject/transactions': 5.8.0 '@ethersproject/web': 5.8.0 bech32: 1.1.4 - ws: 8.18.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -11689,7 +11514,7 @@ snapshots: '@ethersproject/bytes': 5.8.0 '@ethersproject/logger': 5.8.0 '@ethersproject/properties': 5.8.0 - bn.js: 5.2.3 + bn.js: 5.2.2 elliptic: 6.6.1 hash.js: 1.1.7 @@ -11763,16 +11588,16 @@ snapshots: '@humanwhocodes/config-array@0.11.14': dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.4.3 - minimatch: 3.1.5 + debug: 4.4.1 + minimatch: 3.1.2 transitivePeerDependencies: - supports-color '@humanwhocodes/config-array@0.13.0': dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.4.3 - minimatch: 3.1.5 + debug: 4.4.1 + minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -11782,117 +11607,99 @@ snapshots: '@hutson/parse-repository-url@3.0.2': {} - '@img/colour@1.1.0': - optional: true - - '@img/sharp-darwin-arm64@0.34.5': + '@img/sharp-darwin-arm64@0.34.3': optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-arm64': 1.2.0 optional: true - '@img/sharp-darwin-x64@0.34.5': + '@img/sharp-darwin-x64@0.34.3': optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.2.4 - optional: true - - '@img/sharp-libvips-darwin-arm64@1.2.4': + '@img/sharp-libvips-darwin-x64': 1.2.0 optional: true - '@img/sharp-libvips-darwin-x64@1.2.4': + '@img/sharp-libvips-darwin-arm64@1.2.0': optional: true - '@img/sharp-libvips-linux-arm64@1.2.4': + '@img/sharp-libvips-darwin-x64@1.2.0': optional: true - '@img/sharp-libvips-linux-arm@1.2.4': + '@img/sharp-libvips-linux-arm64@1.2.0': optional: true - '@img/sharp-libvips-linux-ppc64@1.2.4': + '@img/sharp-libvips-linux-arm@1.2.0': optional: true - '@img/sharp-libvips-linux-riscv64@1.2.4': + '@img/sharp-libvips-linux-ppc64@1.2.0': optional: true - '@img/sharp-libvips-linux-s390x@1.2.4': + '@img/sharp-libvips-linux-s390x@1.2.0': optional: true - '@img/sharp-libvips-linux-x64@1.2.4': + '@img/sharp-libvips-linux-x64@1.2.0': optional: true - '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + '@img/sharp-libvips-linuxmusl-arm64@1.2.0': optional: true - '@img/sharp-libvips-linuxmusl-x64@1.2.4': + '@img/sharp-libvips-linuxmusl-x64@1.2.0': optional: true - '@img/sharp-linux-arm64@0.34.5': + '@img/sharp-linux-arm64@0.34.3': optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.0 optional: true - '@img/sharp-linux-arm@0.34.5': + '@img/sharp-linux-arm@0.34.3': optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.0 optional: true - '@img/sharp-linux-ppc64@0.34.5': + '@img/sharp-linux-ppc64@0.34.3': optionalDependencies: - '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.0 optional: true - '@img/sharp-linux-riscv64@0.34.5': + '@img/sharp-linux-s390x@0.34.3': optionalDependencies: - '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.0 optional: true - '@img/sharp-linux-s390x@0.34.5': + '@img/sharp-linux-x64@0.34.3': optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.0 optional: true - '@img/sharp-linux-x64@0.34.5': + '@img/sharp-linuxmusl-arm64@0.34.3': optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.0 optional: true - '@img/sharp-linuxmusl-arm64@0.34.5': + '@img/sharp-linuxmusl-x64@0.34.3': optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.0 optional: true - '@img/sharp-linuxmusl-x64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.2.4 - optional: true - - '@img/sharp-wasm32@0.34.5': + '@img/sharp-wasm32@0.34.3': dependencies: - '@emnapi/runtime': 1.9.2 + '@emnapi/runtime': 1.4.5 optional: true - '@img/sharp-win32-arm64@0.34.5': + '@img/sharp-win32-arm64@0.34.3': optional: true - '@img/sharp-win32-ia32@0.34.5': + '@img/sharp-win32-ia32@0.34.3': optional: true - '@img/sharp-win32-x64@0.34.5': + '@img/sharp-win32-x64@0.34.3': optional: true - '@inquirer/external-editor@1.0.3(@types/node@24.3.0)': - dependencies: - chardet: 2.1.1 - iconv-lite: 0.7.2 - optionalDependencies: - '@types/node': 24.3.0 - '@irys/arweave@0.0.2': dependencies: asn1.js: 5.4.1 async-retry: 1.3.3 axios: 1.15.0 base64-js: 1.5.1 - bignumber.js: 9.3.1 + bignumber.js: 9.3.0 transitivePeerDependencies: - debug @@ -11903,36 +11710,35 @@ snapshots: transitivePeerDependencies: - debug - '@irys/sdk@0.1.24(@types/node@24.3.0)(arweave@1.15.7)(bufferutil@4.1.0)(got@11.8.6)(typescript@4.9.5)(utf-8-validate@6.0.6)': + '@irys/sdk@0.1.24(arweave@1.15.7)(bufferutil@4.0.9)(got@11.8.6)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: - '@aptos-labs/ts-sdk': 1.39.0(axios@1.15.0)(got@11.8.6) + '@aptos-labs/ts-sdk': 1.39.0(axios@1.10.0)(got@11.8.6) '@ethersproject/bignumber': 5.8.0 '@ethersproject/contracts': 5.8.0 - '@ethersproject/providers': 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@ethersproject/providers': 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@ethersproject/wallet': 5.8.0 '@irys/query': 0.0.8 '@near-js/crypto': 0.0.3 '@near-js/keystores-browser': 0.0.3 '@near-js/providers': 0.0.4 '@near-js/transactions': 0.1.1 - '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@4.9.5)(utf-8-validate@6.0.6) - '@supercharge/promise-pool': 3.3.0 + '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@supercharge/promise-pool': 3.2.0 algosdk: 1.24.1 - arbundles: 0.10.1(arweave@1.15.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6) + arbundles: 0.10.1(arweave@1.15.7)(bufferutil@4.0.9)(utf-8-validate@5.0.10) async-retry: 1.3.3 - axios: 1.15.0 + axios: 1.10.0 base64url: 3.0.1 - bignumber.js: 9.3.1 + bignumber.js: 9.3.0 bs58: 5.0.0 commander: 8.3.0 csv: 5.5.3 - inquirer: 8.2.7(@types/node@24.3.0) + inquirer: 8.2.6 js-sha256: 0.9.0 mime-types: 2.1.35 near-seed-phrase: 0.2.1 tslib: 2.8.1 transitivePeerDependencies: - - '@types/node' - arweave - bufferutil - debug @@ -11941,23 +11747,27 @@ snapshots: - typescript - utf-8-validate + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 string-width-cjs: string-width@4.2.3 - strip-ansi: 7.2.0 + strip-ansi: 7.1.0 strip-ansi-cjs: strip-ansi@6.0.1 wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 - '@isaacs/cliui@9.0.0': {} - '@istanbuljs/load-nyc-config@1.1.0': dependencies: camelcase: 5.3.1 find-up: 4.1.0 get-package-type: 0.1.0 - js-yaml: 3.14.2 + js-yaml: 3.14.1 resolve-from: 5.0.0 '@istanbuljs/schema@0.1.3': {} @@ -11980,7 +11790,7 @@ snapshots: jest-util: 28.1.3 slash: 3.0.0 - '@jest/core@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3))': + '@jest/core@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(utf-8-validate@5.0.10)': dependencies: '@jest/console': 27.5.1 '@jest/reporters': 27.5.1 @@ -11994,13 +11804,13 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 27.5.1 - jest-config: 27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)) + jest-config: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(utf-8-validate@5.0.10) jest-haste-map: 27.5.1 jest-message-util: 27.5.1 jest-regex-util: 27.5.1 jest-resolve: 27.5.1 jest-resolve-dependencies: 27.5.1 - jest-runner: 27.5.1(bufferutil@4.1.0) + jest-runner: 27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) jest-runtime: 27.5.1 jest-snapshot: 27.5.1 jest-util: 27.5.1 @@ -12048,7 +11858,7 @@ snapshots: '@jest/types': 27.5.1 '@types/node': 24.3.0 chalk: 4.1.2 - collect-v8-coverage: 1.0.3 + collect-v8-coverage: 1.0.2 exit: 0.1.2 glob: 7.2.3 graceful-fs: 4.2.11 @@ -12056,7 +11866,7 @@ snapshots: istanbul-lib-instrument: 5.2.1 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.2.0 + istanbul-reports: 3.1.7 jest-haste-map: 27.5.1 jest-resolve: 27.5.1 jest-util: 27.5.1 @@ -12084,14 +11894,14 @@ snapshots: '@jest/console': 27.5.1 '@jest/types': 27.5.1 '@types/istanbul-lib-coverage': 2.0.6 - collect-v8-coverage: 1.0.3 + collect-v8-coverage: 1.0.2 '@jest/test-result@28.1.3': dependencies: '@jest/console': 28.1.3 '@jest/types': 28.1.3 '@types/istanbul-lib-coverage': 2.0.6 - collect-v8-coverage: 1.0.3 + collect-v8-coverage: 1.0.2 '@jest/test-sequencer@27.5.1': dependencies: @@ -12104,7 +11914,7 @@ snapshots: '@jest/transform@27.5.1': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.27.4 '@jest/types': 27.5.1 babel-plugin-istanbul: 6.1.1 chalk: 4.1.2 @@ -12127,7 +11937,7 @@ snapshots: '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 '@types/node': 24.3.0 - '@types/yargs': 16.0.11 + '@types/yargs': 16.0.9 chalk: 4.1.2 '@jest/types@28.1.3': @@ -12136,177 +11946,64 @@ snapshots: '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 '@types/node': 24.3.0 - '@types/yargs': 17.0.35 + '@types/yargs': 17.0.33 chalk: 4.1.2 - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/remapping@2.3.5': + '@jridgewell/gen-mapping@0.3.8': dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/source-map@0.3.11': + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/source-map@0.3.6': dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 - '@jridgewell/sourcemap-codec@1.5.5': {} + '@jridgewell/sourcemap-codec@1.5.0': {} - '@jridgewell/trace-mapping@0.3.31': + '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/trace-mapping@0.3.9': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/sourcemap-codec': 1.5.0 '@jsonjoy.com/base64@1.1.2(tslib@2.8.1)': dependencies: tslib: 2.8.1 - '@jsonjoy.com/base64@17.67.0(tslib@2.8.1)': - dependencies: - tslib: 2.8.1 - - '@jsonjoy.com/buffers@1.2.1(tslib@2.8.1)': - dependencies: - tslib: 2.8.1 - - '@jsonjoy.com/buffers@17.67.0(tslib@2.8.1)': - dependencies: - tslib: 2.8.1 - - '@jsonjoy.com/codegen@1.0.0(tslib@2.8.1)': - dependencies: - tslib: 2.8.1 - - '@jsonjoy.com/codegen@17.67.0(tslib@2.8.1)': - dependencies: - tslib: 2.8.1 - - '@jsonjoy.com/fs-core@4.57.1(tslib@2.8.1)': - dependencies: - '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) - thingies: 2.6.0(tslib@2.8.1) - tslib: 2.8.1 - - '@jsonjoy.com/fs-fsa@4.57.1(tslib@2.8.1)': - dependencies: - '@jsonjoy.com/fs-core': 4.57.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) - thingies: 2.6.0(tslib@2.8.1) - tslib: 2.8.1 - - '@jsonjoy.com/fs-node-builtins@4.57.1(tslib@2.8.1)': - dependencies: - tslib: 2.8.1 - - '@jsonjoy.com/fs-node-to-fsa@4.57.1(tslib@2.8.1)': - dependencies: - '@jsonjoy.com/fs-fsa': 4.57.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) - tslib: 2.8.1 - - '@jsonjoy.com/fs-node-utils@4.57.1(tslib@2.8.1)': - dependencies: - '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) - tslib: 2.8.1 - - '@jsonjoy.com/fs-node@4.57.1(tslib@2.8.1)': - dependencies: - '@jsonjoy.com/fs-core': 4.57.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.57.1(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.57.1(tslib@2.8.1) - glob-to-regex.js: 1.2.0(tslib@2.8.1) - thingies: 2.6.0(tslib@2.8.1) - tslib: 2.8.1 - - '@jsonjoy.com/fs-print@4.57.1(tslib@2.8.1)': - dependencies: - '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) - tree-dump: 1.1.0(tslib@2.8.1) - tslib: 2.8.1 - - '@jsonjoy.com/fs-snapshot@4.57.1(tslib@2.8.1)': - dependencies: - '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) - '@jsonjoy.com/json-pack': 17.67.0(tslib@2.8.1) - '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) - tslib: 2.8.1 - - '@jsonjoy.com/json-pack@1.21.0(tslib@2.8.1)': + '@jsonjoy.com/json-pack@1.4.0(tslib@2.8.1)': dependencies: '@jsonjoy.com/base64': 1.1.2(tslib@2.8.1) - '@jsonjoy.com/buffers': 1.2.1(tslib@2.8.1) - '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) - '@jsonjoy.com/json-pointer': 1.0.2(tslib@2.8.1) - '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) - hyperdyperid: 1.2.0 - thingies: 2.6.0(tslib@2.8.1) - tree-dump: 1.1.0(tslib@2.8.1) - tslib: 2.8.1 - - '@jsonjoy.com/json-pack@17.67.0(tslib@2.8.1)': - dependencies: - '@jsonjoy.com/base64': 17.67.0(tslib@2.8.1) - '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) - '@jsonjoy.com/codegen': 17.67.0(tslib@2.8.1) - '@jsonjoy.com/json-pointer': 17.67.0(tslib@2.8.1) - '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.8.0(tslib@2.8.1) hyperdyperid: 1.2.0 - thingies: 2.6.0(tslib@2.8.1) - tree-dump: 1.1.0(tslib@2.8.1) - tslib: 2.8.1 - - '@jsonjoy.com/json-pointer@1.0.2(tslib@2.8.1)': - dependencies: - '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) - '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + thingies: 1.21.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/json-pointer@17.67.0(tslib@2.8.1)': + '@jsonjoy.com/util@1.8.0(tslib@2.8.1)': dependencies: - '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) - tslib: 2.8.1 - - '@jsonjoy.com/util@1.9.0(tslib@2.8.1)': - dependencies: - '@jsonjoy.com/buffers': 1.2.1(tslib@2.8.1) - '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) - tslib: 2.8.1 - - '@jsonjoy.com/util@17.67.0(tslib@2.8.1)': - dependencies: - '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) - '@jsonjoy.com/codegen': 17.67.0(tslib@2.8.1) tslib: 2.8.1 '@leichtgewicht/ip-codec@2.0.5': {} '@manypkg/find-root@1.1.0': dependencies: - '@babel/runtime': 7.29.2 + '@babel/runtime': 7.27.6 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 '@manypkg/get-packages@1.1.3': dependencies: - '@babel/runtime': 7.29.2 + '@babel/runtime': 7.27.6 '@changesets/types': 4.1.0 '@manypkg/find-root': 1.1.0 fs-extra: 8.1.0 @@ -12315,11 +12012,11 @@ snapshots: '@metamask/detect-provider@2.0.0': {} - '@napi-rs/wasm-runtime@0.2.12': + '@napi-rs/wasm-runtime@0.2.11': dependencies: - '@emnapi/core': 1.9.2 - '@emnapi/runtime': 1.9.2 - '@tybys/wasm-util': 0.10.1 + '@emnapi/core': 1.4.3 + '@emnapi/runtime': 1.4.3 + '@tybys/wasm-util': 0.9.0 optional: true '@near-js/crypto@0.0.3': @@ -12452,14 +12149,12 @@ snapshots: dependencies: eslint-scope: 5.1.1 - '@noble/curves@1.9.7': + '@noble/curves@1.9.2': dependencies: '@noble/hashes': 1.8.0 '@noble/ed25519@1.7.5': {} - '@noble/hashes@1.4.0': {} - '@noble/hashes@1.8.0': {} '@nodelib/fs.scandir@2.1.5': @@ -12472,7 +12167,7 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.20.1 + fastq: 1.19.1 '@nolyfill/is-core-module@1.0.39': {} @@ -12482,169 +12177,79 @@ snapshots: '@nucypher/nucypher-core@0.15.1-dev.3': {} - '@nucypher/shared@0.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + '@nucypher/shared@0.5.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@ethersproject/abi': 5.8.0 - '@ethersproject/providers': 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@ethersproject/providers': 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@nucypher/nucypher-contracts': 0.25.0 '@nucypher/nucypher-core': 0.15.1-dev.3 axios: 1.15.0 deep-equal: 2.2.3 - ethers: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) - qs: 6.15.1 - zod: 3.25.76 + ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + qs: 6.14.0 + zod: 3.25.67 transitivePeerDependencies: - bufferutil - debug - utf-8-validate - '@nucypher/taco-auth@0.3.0(bufferutil@4.1.0)(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(utf-8-validate@6.0.6)': + '@nucypher/taco-auth@0.3.0(bufferutil@4.0.9)(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: '@ethersproject/abstract-signer': 5.8.0 - '@nucypher/shared': 0.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) - siwe: 3.0.0(ethers@5.8.0(bufferutil@4.1.0)) - zod: 3.25.76 + '@nucypher/shared': 0.5.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + siwe: 3.0.0(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + zod: 3.25.67 transitivePeerDependencies: - bufferutil - debug - ethers - utf-8-validate - '@nucypher/taco@0.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + '@nucypher/taco@0.6.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@astronautlabs/jsonpath': 1.1.2 '@nucypher/nucypher-core': 0.15.1-dev.3 - '@nucypher/shared': 0.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) - '@nucypher/taco-auth': 0.3.0(bufferutil@4.1.0)(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(utf-8-validate@6.0.6) - ethers: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) - semver: 7.7.4 - zod: 3.25.76 + '@nucypher/shared': 0.5.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@nucypher/taco-auth': 0.3.0(bufferutil@4.0.9)(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + semver: 7.7.2 + zod: 3.25.67 transitivePeerDependencies: - bufferutil - debug - utf-8-validate - '@peculiar/asn1-cms@2.6.1': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.1 - '@peculiar/asn1-x509-attr': 2.6.1 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-csr@2.6.1': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.1 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-ecc@2.6.1': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.1 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-pfx@2.6.1': - dependencies: - '@peculiar/asn1-cms': 2.6.1 - '@peculiar/asn1-pkcs8': 2.6.1 - '@peculiar/asn1-rsa': 2.6.1 - '@peculiar/asn1-schema': 2.6.0 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-pkcs8@2.6.1': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.1 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-pkcs9@2.6.1': - dependencies: - '@peculiar/asn1-cms': 2.6.1 - '@peculiar/asn1-pfx': 2.6.1 - '@peculiar/asn1-pkcs8': 2.6.1 - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.1 - '@peculiar/asn1-x509-attr': 2.6.1 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-rsa@2.6.1': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.1 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-schema@2.6.0': - dependencies: - asn1js: 3.0.7 - pvtsutils: 1.3.6 - tslib: 2.8.1 - - '@peculiar/asn1-x509-attr@2.6.1': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.1 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-x509@2.6.1': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - asn1js: 3.0.7 - pvtsutils: 1.3.6 - tslib: 2.8.1 - - '@peculiar/x509@1.14.3': - dependencies: - '@peculiar/asn1-cms': 2.6.1 - '@peculiar/asn1-csr': 2.6.1 - '@peculiar/asn1-ecc': 2.6.1 - '@peculiar/asn1-pkcs9': 2.6.1 - '@peculiar/asn1-rsa': 2.6.1 - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.1 - pvtsutils: 1.3.6 - reflect-metadata: 0.2.2 - tslib: 2.8.1 - tsyringe: 4.10.0 - '@pkgjs/parseargs@0.11.0': optional: true - '@pmmmwh/react-refresh-webpack-plugin@0.5.17(react-refresh@0.11.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.1.0)(webpack@5.106.1))(webpack@5.106.1)': + '@pmmmwh/react-refresh-webpack-plugin@0.5.17(react-refresh@0.11.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.99.9))(webpack@5.99.9)': dependencies: ansi-html: 0.0.9 - core-js-pure: 3.49.0 + core-js-pure: 3.43.0 error-stack-parser: 2.1.4 html-entities: 2.6.0 loader-utils: 2.0.4 react-refresh: 0.11.0 - schema-utils: 4.3.3 - source-map: 0.7.6 - webpack: 5.106.1(webpack-cli@6.0.1) + schema-utils: 4.3.2 + source-map: 0.7.4 + webpack: 5.99.9(webpack-cli@6.0.1) optionalDependencies: type-fest: 0.21.3 - webpack-dev-server: 4.15.2(bufferutil@4.1.0)(webpack@5.106.1) + webpack-dev-server: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.99.9) - '@pmmmwh/react-refresh-webpack-plugin@0.6.2(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.3)(webpack@5.106.1)': + '@pmmmwh/react-refresh-webpack-plugin@0.6.1(react-refresh@0.17.0)(type-fest@0.21.3)(webpack-dev-server@5.2.2)(webpack@5.99.9)': dependencies: - anser: 2.3.5 - core-js-pure: 3.49.0 + anser: 2.3.2 + core-js-pure: 3.43.0 error-stack-parser: 2.1.4 html-entities: 2.6.0 react-refresh: 0.17.0 - schema-utils: 4.3.3 - source-map: 0.7.6 - webpack: 5.106.1(webpack-cli@6.0.1) + schema-utils: 4.3.2 + source-map: 0.7.4 + webpack: 5.99.9(webpack-cli@6.0.1) optionalDependencies: type-fest: 0.21.3 - webpack-dev-server: 5.2.3(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack-cli@6.0.1)(webpack@5.106.1) + webpack-dev-server: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) '@randlabs/communication-bridge@1.0.1': optional: true @@ -12654,124 +12259,109 @@ snapshots: '@randlabs/communication-bridge': 1.0.1 optional: true - '@rollup/plugin-babel@5.3.1(@babel/core@7.29.0)(@types/babel__core@7.20.5)(rollup@2.80.0)': + '@rollup/plugin-babel@5.3.1(@babel/core@7.27.4)(@types/babel__core@7.20.5)(rollup@2.79.2)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-imports': 7.28.6 - '@rollup/pluginutils': 3.1.0(rollup@2.80.0) - rollup: 2.80.0 + '@babel/core': 7.27.4 + '@babel/helper-module-imports': 7.27.1 + '@rollup/pluginutils': 3.1.0(rollup@2.79.2) + rollup: 2.79.2 optionalDependencies: '@types/babel__core': 7.20.5 transitivePeerDependencies: - supports-color - '@rollup/plugin-node-resolve@11.2.1(rollup@2.80.0)': + '@rollup/plugin-node-resolve@11.2.1(rollup@2.79.2)': dependencies: - '@rollup/pluginutils': 3.1.0(rollup@2.80.0) + '@rollup/pluginutils': 3.1.0(rollup@2.79.2) '@types/resolve': 1.17.1 builtin-modules: 3.3.0 deepmerge: 4.3.1 is-module: 1.0.0 - resolve: 1.22.11 - rollup: 2.80.0 - - '@rollup/plugin-replace@2.4.2(rollup@2.80.0)': - dependencies: - '@rollup/pluginutils': 3.1.0(rollup@2.80.0) - magic-string: 0.25.9 - rollup: 2.80.0 - - '@rollup/pluginutils@3.1.0(rollup@2.80.0)': - dependencies: - '@types/estree': 0.0.39 - estree-walker: 1.0.1 - picomatch: 2.3.2 - rollup: 2.80.0 + resolve: 1.22.10 + rollup: 2.79.2 - '@rollup/rollup-android-arm-eabi@4.60.1': - optional: true - - '@rollup/rollup-android-arm64@4.60.1': - optional: true - - '@rollup/rollup-darwin-arm64@4.60.1': - optional: true - - '@rollup/rollup-darwin-x64@4.60.1': - optional: true + '@rollup/plugin-replace@2.4.2(rollup@2.79.2)': + dependencies: + '@rollup/pluginutils': 3.1.0(rollup@2.79.2) + magic-string: 0.25.9 + rollup: 2.79.2 - '@rollup/rollup-freebsd-arm64@4.60.1': - optional: true + '@rollup/pluginutils@3.1.0(rollup@2.79.2)': + dependencies: + '@types/estree': 0.0.39 + estree-walker: 1.0.1 + picomatch: 2.3.1 + rollup: 2.79.2 - '@rollup/rollup-freebsd-x64@4.60.1': + '@rollup/rollup-android-arm-eabi@4.44.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.60.1': + '@rollup/rollup-android-arm64@4.44.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.60.1': + '@rollup/rollup-darwin-arm64@4.44.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.60.1': + '@rollup/rollup-darwin-x64@4.44.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.60.1': + '@rollup/rollup-freebsd-arm64@4.44.1': optional: true - '@rollup/rollup-linux-loong64-gnu@4.60.1': + '@rollup/rollup-freebsd-x64@4.44.1': optional: true - '@rollup/rollup-linux-loong64-musl@4.60.1': + '@rollup/rollup-linux-arm-gnueabihf@4.44.1': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.60.1': + '@rollup/rollup-linux-arm-musleabihf@4.44.1': optional: true - '@rollup/rollup-linux-ppc64-musl@4.60.1': + '@rollup/rollup-linux-arm64-gnu@4.44.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.60.1': + '@rollup/rollup-linux-arm64-musl@4.44.1': optional: true - '@rollup/rollup-linux-riscv64-musl@4.60.1': + '@rollup/rollup-linux-loongarch64-gnu@4.44.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.60.1': + '@rollup/rollup-linux-powerpc64le-gnu@4.44.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.60.1': + '@rollup/rollup-linux-riscv64-gnu@4.44.1': optional: true - '@rollup/rollup-linux-x64-musl@4.60.1': + '@rollup/rollup-linux-riscv64-musl@4.44.1': optional: true - '@rollup/rollup-openbsd-x64@4.60.1': + '@rollup/rollup-linux-s390x-gnu@4.44.1': optional: true - '@rollup/rollup-openharmony-arm64@4.60.1': + '@rollup/rollup-linux-x64-gnu@4.44.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.60.1': + '@rollup/rollup-linux-x64-musl@4.44.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.60.1': + '@rollup/rollup-win32-arm64-msvc@4.44.1': optional: true - '@rollup/rollup-win32-x64-gnu@4.60.1': + '@rollup/rollup-win32-ia32-msvc@4.44.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.60.1': + '@rollup/rollup-win32-x64-msvc@4.44.1': optional: true '@rtsao/scc@1.1.0': {} - '@rushstack/eslint-patch@1.16.1': {} + '@rushstack/eslint-patch@1.11.0': {} '@scure/base@1.2.6': {} '@scure/bip32@1.7.0': dependencies: - '@noble/curves': 1.9.7 + '@noble/curves': 1.9.2 '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 @@ -12780,9 +12370,6 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 - '@simple-libs/stream-utils@1.2.0': - optional: true - '@sinclair/typebox@0.24.51': {} '@sindresorhus/is@4.6.0': {} @@ -12804,39 +12391,39 @@ snapshots: dependencies: buffer: 6.0.3 - '@solana/codecs-core@2.3.0(typescript@4.9.5)': + '@solana/codecs-core@2.1.1(typescript@4.9.5)': dependencies: - '@solana/errors': 2.3.0(typescript@4.9.5) + '@solana/errors': 2.1.1(typescript@4.9.5) typescript: 4.9.5 - '@solana/codecs-numbers@2.3.0(typescript@4.9.5)': + '@solana/codecs-numbers@2.1.1(typescript@4.9.5)': dependencies: - '@solana/codecs-core': 2.3.0(typescript@4.9.5) - '@solana/errors': 2.3.0(typescript@4.9.5) + '@solana/codecs-core': 2.1.1(typescript@4.9.5) + '@solana/errors': 2.1.1(typescript@4.9.5) typescript: 4.9.5 - '@solana/errors@2.3.0(typescript@4.9.5)': + '@solana/errors@2.1.1(typescript@4.9.5)': dependencies: - chalk: 5.6.2 - commander: 14.0.3 + chalk: 5.4.1 + commander: 13.1.0 typescript: 4.9.5 - '@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@4.9.5)(utf-8-validate@6.0.6)': + '@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.29.2 - '@noble/curves': 1.9.7 + '@babel/runtime': 7.27.6 + '@noble/curves': 1.9.2 '@noble/hashes': 1.8.0 '@solana/buffer-layout': 4.0.1 - '@solana/codecs-numbers': 2.3.0(typescript@4.9.5) + '@solana/codecs-numbers': 2.1.1(typescript@4.9.5) agentkeepalive: 4.6.0 - bn.js: 5.2.3 + bn.js: 5.2.2 borsh: 0.7.0 bs58: 4.0.1 buffer: 6.0.3 fast-stable-stringify: 1.0.0 - jayson: 4.3.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + jayson: 4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) node-fetch: 2.7.0 - rpc-websockets: 9.3.8 + rpc-websockets: 9.1.1 superstruct: 2.0.2 transitivePeerDependencies: - bufferutil @@ -12862,7 +12449,7 @@ snapshots: '@stablelib/wipe@1.0.1': {} - '@supercharge/promise-pool@3.3.0': {} + '@supercharge/promise-pool@3.2.0': {} '@surma/rollup-plugin-off-main-thread@2.2.3': dependencies: @@ -12908,11 +12495,11 @@ snapshots: '@svgr/hast-util-to-babel-ast@5.5.0': dependencies: - '@babel/types': 7.29.0 + '@babel/types': 7.27.6 '@svgr/plugin-jsx@5.5.0': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.27.4 '@svgr/babel-preset': 5.5.0 '@svgr/hast-util-to-babel-ast': 5.5.0 svg-parser: 2.0.4 @@ -12927,10 +12514,10 @@ snapshots: '@svgr/webpack@5.5.0': dependencies: - '@babel/core': 7.29.0 - '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.29.0) - '@babel/preset-env': 7.29.2(@babel/core@7.29.0) - '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@babel/core': 7.27.4 + '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.27.4) + '@babel/preset-env': 7.27.2(@babel/core@7.27.4) + '@babel/preset-react': 7.27.1(@babel/core@7.27.4) '@svgr/core': 5.5.0 '@svgr/plugin-jsx': 5.5.0 '@svgr/plugin-svgo': 5.5.0 @@ -12944,7 +12531,7 @@ snapshots: dependencies: tslib: 2.8.1 - '@swc/helpers@0.5.21': + '@swc/helpers@0.5.17': dependencies: tslib: 2.8.1 @@ -12954,7 +12541,9 @@ snapshots: '@tootallnate/once@1.1.2': {} - '@tsconfig/node10@1.0.12': {} + '@trysound/sax@0.2.0': {} + + '@tsconfig/node10@1.0.11': {} '@tsconfig/node12@1.0.11': {} @@ -12962,41 +12551,41 @@ snapshots: '@tsconfig/node16@1.0.4': {} - '@tybys/wasm-util@0.10.1': + '@tybys/wasm-util@0.9.0': dependencies: tslib: 2.8.1 optional: true - '@typechain/ethers-v5@11.1.2(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(typechain@8.3.2(typescript@5.9.3))(typescript@5.9.3)': + '@typechain/ethers-v5@11.1.2(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.8.3))(typescript@5.8.3)': dependencies: '@ethersproject/abi': 5.8.0 - '@ethersproject/providers': 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) - ethers: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) - lodash: 4.18.1 - ts-essentials: 7.0.3(typescript@5.9.3) - typechain: 8.3.2(typescript@5.9.3) - typescript: 5.9.3 + '@ethersproject/providers': 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + lodash: 4.17.21 + ts-essentials: 7.0.3(typescript@5.8.3) + typechain: 8.3.2(typescript@5.8.3) + typescript: 5.8.3 '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 + '@babel/parser': 7.27.5 + '@babel/types': 7.27.6 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.28.0 + '@types/babel__traverse': 7.20.7 '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.29.0 + '@babel/types': 7.27.6 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 + '@babel/parser': 7.27.5 + '@babel/types': 7.27.6 - '@types/babel__traverse@7.28.0': + '@types/babel__traverse@7.20.7': dependencies: - '@babel/types': 7.29.0 + '@babel/types': 7.27.6 '@types/body-parser@1.19.6': dependencies: @@ -13009,25 +12598,29 @@ snapshots: '@types/cacheable-request@6.0.3': dependencies: - '@types/http-cache-semantics': 4.2.0 + '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 '@types/node': 24.3.0 '@types/responselike': 1.0.3 - '@types/chai@5.2.3': + '@types/chai@5.2.2': dependencies: '@types/deep-eql': 4.0.2 - assertion-error: 2.0.1 '@types/connect-history-api-fallback@1.5.4': dependencies: - '@types/express-serve-static-core': 4.19.8 + '@types/express-serve-static-core': 5.0.6 '@types/node': 24.3.0 '@types/connect@3.4.38': dependencies: '@types/node': 24.3.0 + '@types/conventional-commits-parser@5.0.1': + dependencies: + '@types/node': 24.3.0 + optional: true + '@types/deep-eql@4.0.2': {} '@types/deep-equal@1.0.4': {} @@ -13051,19 +12644,26 @@ snapshots: '@types/estree@1.0.8': {} - '@types/express-serve-static-core@4.19.8': + '@types/express-serve-static-core@4.19.6': dependencies: '@types/node': 24.3.0 - '@types/qs': 6.15.0 + '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 - '@types/send': 1.2.1 + '@types/send': 0.17.5 - '@types/express@4.17.25': + '@types/express-serve-static-core@5.0.6': + dependencies: + '@types/node': 24.3.0 + '@types/qs': 6.14.0 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.5 + + '@types/express@4.17.23': dependencies: '@types/body-parser': 1.19.6 - '@types/express-serve-static-core': 4.19.8 - '@types/qs': 6.15.0 - '@types/serve-static': 1.15.10 + '@types/express-serve-static-core': 4.19.6 + '@types/qs': 6.14.0 + '@types/serve-static': 1.15.8 '@types/graceful-fs@4.1.9': dependencies: @@ -13071,11 +12671,11 @@ snapshots: '@types/html-minifier-terser@6.1.0': {} - '@types/http-cache-semantics@4.2.0': {} + '@types/http-cache-semantics@4.0.4': {} '@types/http-errors@2.0.5': {} - '@types/http-proxy@1.17.17': + '@types/http-proxy@1.17.16': dependencies: '@types/node': 24.3.0 @@ -13097,13 +12697,13 @@ snapshots: dependencies: '@types/node': 24.3.0 - '@types/lodash@4.17.24': {} + '@types/lodash@4.17.19': {} '@types/mime@1.3.5': {} '@types/minimist@1.2.5': {} - '@types/node-forge@1.3.14': + '@types/node-forge@1.3.11': dependencies: '@types/node': 24.3.0 @@ -13125,31 +12725,31 @@ snapshots: '@types/q@1.5.8': {} - '@types/qs@6.15.0': {} + '@types/qs@6.14.0': {} '@types/range-parser@1.2.7': {} '@types/react-copy-to-clipboard@5.0.7': dependencies: - '@types/react': 18.3.28 + '@types/react': 18.3.23 '@types/react-dom@18.3.0': dependencies: - '@types/react': 18.3.28 + '@types/react': 18.3.23 - '@types/react-dom@18.3.7(@types/react@18.3.28)': + '@types/react-dom@18.3.7(@types/react@18.3.23)': dependencies: - '@types/react': 18.3.28 + '@types/react': 18.3.23 - '@types/react@18.3.28': + '@types/react@18.3.23': dependencies: '@types/prop-types': 15.7.15 - csstype: 3.2.3 + csstype: 3.1.3 '@types/react@18.3.5': dependencies: '@types/prop-types': 15.7.15 - csstype: 3.2.3 + csstype: 3.1.3 '@types/resolve@1.17.1': dependencies: @@ -13163,26 +12763,22 @@ snapshots: '@types/retry@0.12.2': {} - '@types/semver@7.7.1': {} + '@types/semver@7.7.0': {} - '@types/send@0.17.6': + '@types/send@0.17.5': dependencies: '@types/mime': 1.3.5 '@types/node': 24.3.0 - '@types/send@1.2.1': - dependencies: - '@types/node': 24.3.0 - '@types/serve-index@1.9.4': dependencies: - '@types/express': 4.17.25 + '@types/express': 4.17.23 - '@types/serve-static@1.15.10': + '@types/serve-static@1.15.8': dependencies: '@types/http-errors': 2.0.5 '@types/node': 24.3.0 - '@types/send': 0.17.6 + '@types/send': 0.17.5 '@types/sockjs@0.3.36': dependencies: @@ -13194,7 +12790,7 @@ snapshots: '@types/trusted-types@2.0.7': {} - '@types/uuid@10.0.0': {} + '@types/uuid@8.3.4': {} '@types/ws@7.4.7': dependencies: @@ -13206,70 +12802,70 @@ snapshots: '@types/yargs-parser@21.0.3': {} - '@types/yargs@16.0.11': + '@types/yargs@16.0.9': dependencies: '@types/yargs-parser': 21.0.3 - '@types/yargs@17.0.35': + '@types/yargs@17.0.33': dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3)': dependencies: - '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.9.3) + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.8.3) '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.9.3) - debug: 4.4.3 + '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.8.3) + debug: 4.4.1 eslint: 8.57.1 graphemer: 1.4.0 ignore: 5.3.2 natural-compare-lite: 1.4.0 - semver: 7.7.4 - tsutils: 3.21.0(typescript@5.9.3) + semver: 7.7.2 + tsutils: 3.21.0(typescript@5.8.3) optionalDependencies: - typescript: 5.9.3 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3)': dependencies: - '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.3) + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.8.3) '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.8.3) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.3 + debug: 4.4.1 eslint: 8.57.1 graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - semver: 7.7.4 - ts-api-utils: 1.4.3(typescript@5.9.3) + semver: 7.7.2 + ts-api-utils: 1.4.3(typescript@5.8.3) optionalDependencies: - typescript: 5.9.3 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/experimental-utils@5.62.0(eslint@8.57.1)(typescript@5.9.3)': + '@typescript-eslint/experimental-utils@5.62.0(eslint@8.57.1)(typescript@5.8.3)': dependencies: - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.8.3) eslint: 8.57.1 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3)': + '@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.3)': dependencies: '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.9.3) - debug: 4.4.3 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.8.3) + debug: 4.4.1 eslint: 8.57.1 optionalDependencies: - typescript: 5.9.3 + typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -13279,36 +12875,36 @@ snapshots: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.2.2) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.3 + debug: 4.4.1 eslint: 8.57.0 optionalDependencies: typescript: 5.2.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.9.3)': + '@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.8.3)': dependencies: '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.8.3) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.3 + debug: 4.4.1 eslint: 8.57.0 optionalDependencies: - typescript: 5.9.3 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3)': + '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3)': dependencies: '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.8.3) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.3 + debug: 4.4.1 eslint: 8.57.1 optionalDependencies: - typescript: 5.9.3 + typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -13322,27 +12918,27 @@ snapshots: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 - '@typescript-eslint/type-utils@5.62.0(eslint@8.57.1)(typescript@5.9.3)': + '@typescript-eslint/type-utils@5.62.0(eslint@8.57.1)(typescript@5.8.3)': dependencies: - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.9.3) - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.9.3) - debug: 4.4.3 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.8.3) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.8.3) + debug: 4.4.1 eslint: 8.57.1 - tsutils: 3.21.0(typescript@5.9.3) + tsutils: 3.21.0(typescript@5.8.3) optionalDependencies: - typescript: 5.9.3 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@6.21.0(eslint@8.57.1)(typescript@5.9.3)': + '@typescript-eslint/type-utils@6.21.0(eslint@8.57.1)(typescript@5.8.3)': dependencies: - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.9.3) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.9.3) - debug: 4.4.3 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.8.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.8.3) + debug: 4.4.1 eslint: 8.57.1 - ts-api-utils: 1.4.3(typescript@5.9.3) + ts-api-utils: 1.4.3(typescript@5.8.3) optionalDependencies: - typescript: 5.9.3 + typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -13350,17 +12946,17 @@ snapshots: '@typescript-eslint/types@6.21.0': {} - '@typescript-eslint/typescript-estree@5.62.0(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@5.62.0(typescript@5.8.3)': dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.4.3 + debug: 4.4.1 globby: 11.1.0 is-glob: 4.0.3 - semver: 7.7.4 - tsutils: 3.21.0(typescript@5.9.3) + semver: 7.7.2 + tsutils: 3.21.0(typescript@5.8.3) optionalDependencies: - typescript: 5.9.3 + typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -13368,57 +12964,57 @@ snapshots: dependencies: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.3 + debug: 4.4.1 globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 - semver: 7.7.4 + semver: 7.7.2 ts-api-utils: 1.4.3(typescript@5.2.2) optionalDependencies: typescript: 5.2.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@6.21.0(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@6.21.0(typescript@5.8.3)': dependencies: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.3 + debug: 4.4.1 globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 - semver: 7.7.4 - ts-api-utils: 1.4.3(typescript@5.9.3) + semver: 7.7.2 + ts-api-utils: 1.4.3(typescript@5.8.3) optionalDependencies: - typescript: 5.9.3 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@5.9.3)': + '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) + '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1) '@types/json-schema': 7.0.15 - '@types/semver': 7.7.1 + '@types/semver': 7.7.0 '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.8.3) eslint: 8.57.1 eslint-scope: 5.1.1 - semver: 7.7.4 + semver: 7.7.2 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/utils@6.21.0(eslint@8.57.1)(typescript@5.9.3)': + '@typescript-eslint/utils@6.21.0(eslint@8.57.1)(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) + '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1) '@types/json-schema': 7.0.15 - '@types/semver': 7.7.1 + '@types/semver': 7.7.0 '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.8.3) eslint: 8.57.1 - semver: 7.7.4 + semver: 7.7.2 transitivePeerDependencies: - supports-color - typescript @@ -13435,72 +13031,72 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@uniswap/token-lists@1.0.0-beta.35': {} + '@uniswap/token-lists@1.0.0-beta.34': {} - '@unrs/resolver-binding-android-arm-eabi@1.11.1': + '@unrs/resolver-binding-android-arm-eabi@1.9.2': optional: true - '@unrs/resolver-binding-android-arm64@1.11.1': + '@unrs/resolver-binding-android-arm64@1.9.2': optional: true - '@unrs/resolver-binding-darwin-arm64@1.11.1': + '@unrs/resolver-binding-darwin-arm64@1.9.2': optional: true - '@unrs/resolver-binding-darwin-x64@1.11.1': + '@unrs/resolver-binding-darwin-x64@1.9.2': optional: true - '@unrs/resolver-binding-freebsd-x64@1.11.1': + '@unrs/resolver-binding-freebsd-x64@1.9.2': optional: true - '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + '@unrs/resolver-binding-linux-arm-gnueabihf@1.9.2': optional: true - '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + '@unrs/resolver-binding-linux-arm-musleabihf@1.9.2': optional: true - '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + '@unrs/resolver-binding-linux-arm64-gnu@1.9.2': optional: true - '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + '@unrs/resolver-binding-linux-arm64-musl@1.9.2': optional: true - '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + '@unrs/resolver-binding-linux-ppc64-gnu@1.9.2': optional: true - '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + '@unrs/resolver-binding-linux-riscv64-gnu@1.9.2': optional: true - '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + '@unrs/resolver-binding-linux-riscv64-musl@1.9.2': optional: true - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + '@unrs/resolver-binding-linux-s390x-gnu@1.9.2': optional: true - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + '@unrs/resolver-binding-linux-x64-gnu@1.9.2': optional: true - '@unrs/resolver-binding-linux-x64-musl@1.11.1': + '@unrs/resolver-binding-linux-x64-musl@1.9.2': optional: true - '@unrs/resolver-binding-wasm32-wasi@1.11.1': + '@unrs/resolver-binding-wasm32-wasi@1.9.2': dependencies: - '@napi-rs/wasm-runtime': 0.2.12 + '@napi-rs/wasm-runtime': 0.2.11 optional: true - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + '@unrs/resolver-binding-win32-arm64-msvc@1.9.2': optional: true - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + '@unrs/resolver-binding-win32-ia32-msvc@1.9.2': optional: true - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + '@unrs/resolver-binding-win32-x64-msvc@1.9.2': optional: true - '@usedapp/core@1.2.16(ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(node-fetch@2.7.0)(react@18.3.1)': + '@usedapp/core@1.2.16(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(node-fetch@2.7.0)(react@18.3.1)': dependencies: '@metamask/detect-provider': 2.0.0 - '@uniswap/token-lists': 1.0.0-beta.35 - ethers: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@uniswap/token-lists': 1.0.0-beta.34 + ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) fetch-mock: 9.11.0(node-fetch@2.7.0) lodash.merge: 4.6.2 lodash.pickby: 4.6.0 @@ -13510,65 +13106,105 @@ snapshots: - node-fetch - supports-color - '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/node@24.3.0)(jiti@2.6.1)(jsdom@16.7.0(bufferutil@4.1.0))(terser@5.46.1))': + '@vitest/coverage-v8@3.2.4(vitest@3.0.9(@types/node@24.3.0)(jiti@2.4.2)(jsdom@16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(terser@5.43.1)(yaml@2.8.0))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 - ast-v8-to-istanbul: 0.3.12 - debug: 4.4.3 + ast-v8-to-istanbul: 0.3.3 + debug: 4.4.1 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 - istanbul-reports: 3.2.0 - magic-string: 0.30.21 + istanbul-reports: 3.1.7 + magic-string: 0.30.17 magicast: 0.3.5 - std-env: 3.10.0 - test-exclude: 7.0.2 + std-env: 3.9.0 + test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/node@24.3.0)(jiti@2.6.1)(jsdom@16.7.0(bufferutil@4.1.0))(terser@5.46.1) + vitest: 3.0.9(@types/node@24.3.0)(jiti@2.4.2)(jsdom@16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(terser@5.43.1)(yaml@2.8.0) transitivePeerDependencies: - supports-color + '@vitest/expect@3.0.9': + dependencies: + '@vitest/spy': 3.0.9 + '@vitest/utils': 3.0.9 + chai: 5.2.0 + tinyrainbow: 2.0.0 + '@vitest/expect@3.2.4': dependencies: - '@types/chai': 5.2.3 + '@types/chai': 5.2.2 '@vitest/spy': 3.2.4 '@vitest/utils': 3.2.4 - chai: 5.3.3 + chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@7.3.2(@types/node@24.3.0)(jiti@2.6.1)(terser@5.46.1))': + '@vitest/mocker@3.0.9(vite@6.3.5(@types/node@24.3.0)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0))': + dependencies: + '@vitest/spy': 3.0.9 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + vite: 6.3.5(@types/node@24.3.0)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) + + '@vitest/mocker@3.2.4(vite@7.0.0(@types/node@24.3.0)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 - magic-string: 0.30.21 + magic-string: 0.30.17 optionalDependencies: - vite: 7.3.2(@types/node@24.3.0)(jiti@2.6.1)(terser@5.46.1) + vite: 7.0.0(@types/node@24.3.0)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) + + '@vitest/pretty-format@3.0.9': + dependencies: + tinyrainbow: 2.0.0 '@vitest/pretty-format@3.2.4': dependencies: tinyrainbow: 2.0.0 + '@vitest/runner@3.0.9': + dependencies: + '@vitest/utils': 3.0.9 + pathe: 2.0.3 + '@vitest/runner@3.2.4': dependencies: '@vitest/utils': 3.2.4 pathe: 2.0.3 - strip-literal: 3.1.0 + strip-literal: 3.0.0 + + '@vitest/snapshot@3.0.9': + dependencies: + '@vitest/pretty-format': 3.0.9 + magic-string: 0.30.17 + pathe: 2.0.3 '@vitest/snapshot@3.2.4': dependencies: '@vitest/pretty-format': 3.2.4 - magic-string: 0.30.21 + magic-string: 0.30.17 pathe: 2.0.3 + '@vitest/spy@3.0.9': + dependencies: + tinyspy: 3.0.2 + '@vitest/spy@3.2.4': dependencies: - tinyspy: 4.0.4 + tinyspy: 4.0.3 + + '@vitest/utils@3.0.9': + dependencies: + '@vitest/pretty-format': 3.0.9 + loupe: 3.1.4 + tinyrainbow: 2.0.0 '@vitest/utils@3.2.4': dependencies: '@vitest/pretty-format': 3.2.4 - loupe: 3.2.1 + loupe: 3.1.4 tinyrainbow: 2.0.0 '@webassemblyjs/ast@1.14.1': @@ -13647,22 +13283,22 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@xtuc/long': 4.2.2 - '@webpack-cli/configtest@3.0.1(webpack-cli@6.0.1)(webpack@5.106.1)': + '@webpack-cli/configtest@3.0.1(webpack-cli@6.0.1)(webpack@5.99.9)': dependencies: - webpack: 5.106.1(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1) + webpack: 5.99.9(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) - '@webpack-cli/info@3.0.1(webpack-cli@6.0.1)(webpack@5.106.1)': + '@webpack-cli/info@3.0.1(webpack-cli@6.0.1)(webpack@5.99.9)': dependencies: - webpack: 5.106.1(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1) + webpack: 5.99.9(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) - '@webpack-cli/serve@3.0.1(webpack-cli@6.0.1)(webpack-dev-server@5.2.3)(webpack@5.106.1)': + '@webpack-cli/serve@3.0.1(webpack-cli@6.0.1)(webpack-dev-server@5.2.2)(webpack@5.99.9)': dependencies: - webpack: 5.106.1(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1) + webpack: 5.99.9(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) optionalDependencies: - webpack-dev-server: 5.2.3(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack-cli@6.0.1)(webpack@5.106.1) + webpack-dev-server: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) '@xtuc/ieee754@1.2.0': {} @@ -13685,23 +13321,19 @@ snapshots: acorn: 7.4.1 acorn-walk: 7.2.0 - acorn-import-phases@1.0.4(acorn@8.16.0): + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: - acorn: 8.16.0 - - acorn-jsx@5.3.2(acorn@8.16.0): - dependencies: - acorn: 8.16.0 + acorn: 8.15.0 acorn-walk@7.2.0: {} - acorn-walk@8.3.5: + acorn-walk@8.3.4: dependencies: - acorn: 8.16.0 + acorn: 8.15.0 acorn@7.4.1: {} - acorn@8.16.0: {} + acorn@8.15.0: {} add-stream@1.0.0: {} @@ -13716,7 +13348,7 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.4.3 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -13724,30 +13356,30 @@ snapshots: dependencies: humanize-ms: 1.2.1 - ajv-formats@2.1.1(ajv@8.18.0): + ajv-formats@2.1.1(ajv@8.17.1): optionalDependencies: - ajv: 8.18.0 + ajv: 8.17.1 - ajv-keywords@3.5.2(ajv@6.14.0): + ajv-keywords@3.5.2(ajv@6.12.6): dependencies: - ajv: 6.14.0 + ajv: 6.12.6 - ajv-keywords@5.1.0(ajv@8.18.0): + ajv-keywords@5.1.0(ajv@8.17.1): dependencies: - ajv: 8.18.0 + ajv: 8.17.1 fast-deep-equal: 3.1.3 - ajv@6.14.0: + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 fast-json-stable-stringify: 2.1.0 json-schema-traverse: 0.4.1 uri-js: 4.4.1 - ajv@8.18.0: + ajv@8.17.1: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.0 + fast-uri: 3.0.6 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 @@ -13768,7 +13400,7 @@ snapshots: transitivePeerDependencies: - encoding - anser@2.3.5: {} + anser@2.3.2: {} ansi-colors@4.1.3: {} @@ -13782,7 +13414,7 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.2.2: {} + ansi-regex@6.1.0: {} ansi-sequence-parser@1.1.3: {} @@ -13796,22 +13428,22 @@ snapshots: ansi-styles@5.2.0: {} - ansi-styles@6.2.3: {} + ansi-styles@6.2.1: {} any-promise@1.3.0: {} anymatch@3.1.3: dependencies: normalize-path: 3.0.0 - picomatch: 2.3.2 + picomatch: 2.3.1 apg-js@4.4.0: {} - arbundles@0.10.1(arweave@1.15.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6): + arbundles@0.10.1(arweave@1.15.7)(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@ethersproject/bytes': 5.8.0 '@ethersproject/hash': 5.8.0 - '@ethersproject/providers': 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@ethersproject/providers': 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@ethersproject/signing-key': 5.8.0 '@ethersproject/transactions': 5.8.0 '@ethersproject/wallet': 5.8.0 @@ -13866,10 +13498,10 @@ snapshots: array-includes@3.1.9: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.24.2 + es-abstract: 1.24.0 es-object-atoms: 1.1.1 get-intrinsic: 1.3.0 is-string: 1.1.1 @@ -13879,43 +13511,43 @@ snapshots: array.prototype.findlast@1.2.5: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.24.2 + es-abstract: 1.24.0 es-errors: 1.3.0 es-object-atoms: 1.1.1 es-shim-unscopables: 1.1.0 array.prototype.findlastindex@1.2.6: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.24.2 + es-abstract: 1.24.0 es-errors: 1.3.0 es-object-atoms: 1.1.1 es-shim-unscopables: 1.1.0 array.prototype.flat@1.3.3: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.24.2 + es-abstract: 1.24.0 es-shim-unscopables: 1.1.0 array.prototype.flatmap@1.3.3: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.24.2 + es-abstract: 1.24.0 es-shim-unscopables: 1.1.0 array.prototype.reduce@1.0.8: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.24.2 + es-abstract: 1.24.0 es-array-method-boxes-properly: 1.0.0 es-errors: 1.3.0 es-object-atoms: 1.1.1 @@ -13923,18 +13555,18 @@ snapshots: array.prototype.tosorted@1.1.4: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.24.2 + es-abstract: 1.24.0 es-errors: 1.3.0 es-shim-unscopables: 1.1.0 arraybuffer.prototype.slice@1.0.4: dependencies: array-buffer-byte-length: 1.0.2 - call-bind: 1.0.9 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.24.2 + es-abstract: 1.24.0 es-errors: 1.3.0 get-intrinsic: 1.3.0 is-array-buffer: 3.0.5 @@ -13944,7 +13576,7 @@ snapshots: arweave-stream-tx@1.2.2(arweave@1.15.7): dependencies: arweave: 1.15.7 - exponential-backoff: 3.1.3 + exponential-backoff: 3.1.2 optional: true arweave@1.15.7: @@ -13952,39 +13584,33 @@ snapshots: arconnect: 0.4.2 asn1.js: 5.4.1 base64-js: 1.5.1 - bignumber.js: 9.3.1 + bignumber.js: 9.3.0 optional: true asap@2.0.6: {} asn1.js@4.10.1: dependencies: - bn.js: 4.12.3 + bn.js: 4.12.2 inherits: 2.0.4 minimalistic-assert: 1.0.1 asn1.js@5.4.1: dependencies: - bn.js: 4.12.3 + bn.js: 4.12.2 inherits: 2.0.4 minimalistic-assert: 1.0.1 safer-buffer: 2.1.2 - asn1js@3.0.7: - dependencies: - pvtsutils: 1.3.6 - pvutils: 1.1.5 - tslib: 2.8.1 - assertion-error@2.0.1: {} ast-types-flow@0.0.8: {} - ast-v8-to-istanbul@0.3.12: + ast-v8-to-istanbul@0.3.3: dependencies: - '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/trace-mapping': 0.3.25 estree-walker: 3.0.3 - js-tokens: 10.0.0 + js-tokens: 9.0.1 async-function@1.0.0: {} @@ -13998,29 +13624,38 @@ snapshots: at-least-node@1.0.0: {} - autoprefixer@10.4.27(postcss@8.5.9): + autoprefixer@10.4.21(postcss@8.5.6): dependencies: - browserslist: 4.28.2 - caniuse-lite: 1.0.30001787 - fraction.js: 5.3.4 + browserslist: 4.25.1 + caniuse-lite: 1.0.30001726 + fraction.js: 4.3.7 + normalize-range: 0.1.2 picocolors: 1.1.1 - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.1.0 - axe-core@4.11.2: {} + axe-core@4.10.3: {} axios-retry@4.5.0(axios@1.15.0): dependencies: axios: 1.15.0 is-retry-allowed: 2.2.0 + axios@1.10.0: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.3 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + axios@1.15.0: dependencies: - follow-redirects: 1.15.11 + follow-redirects: 1.16.0 form-data: 4.0.5 proxy-from-env: 2.1.0 transitivePeerDependencies: @@ -14028,32 +13663,32 @@ snapshots: axobject-query@4.1.0: {} - babel-jest@27.5.1(@babel/core@7.29.0): + babel-jest@27.5.1(@babel/core@7.27.4): dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.27.4 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 '@types/babel__core': 7.20.5 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 27.5.1(@babel/core@7.29.0) + babel-preset-jest: 27.5.1(@babel/core@7.27.4) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 transitivePeerDependencies: - supports-color - babel-loader@8.4.1(@babel/core@7.29.0)(webpack@5.106.1): + babel-loader@8.4.1(@babel/core@7.27.4)(webpack@5.99.9): dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.27.4 find-cache-dir: 3.3.2 loader-utils: 2.0.4 make-dir: 3.1.0 schema-utils: 2.7.1 - webpack: 5.106.1(webpack-cli@6.0.1) + webpack: 5.99.9(webpack-cli@6.0.1) babel-plugin-istanbul@6.1.1: dependencies: - '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-plugin-utils': 7.27.1 '@istanbuljs/load-nyc-config': 1.1.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-instrument: 5.2.1 @@ -14063,97 +13698,89 @@ snapshots: babel-plugin-jest-hoist@27.5.1: dependencies: - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 + '@babel/template': 7.27.2 + '@babel/types': 7.27.6 '@types/babel__core': 7.20.5 - '@types/babel__traverse': 7.28.0 + '@types/babel__traverse': 7.20.7 babel-plugin-macros@3.1.0: dependencies: - '@babel/runtime': 7.29.2 + '@babel/runtime': 7.27.6 cosmiconfig: 7.1.0 - resolve: 1.22.11 + resolve: 1.22.10 - babel-plugin-named-asset-import@0.3.8(@babel/core@7.29.0): + babel-plugin-named-asset-import@0.3.8(@babel/core@7.27.4): dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.27.4 - babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.0): + babel-plugin-polyfill-corejs2@0.4.13(@babel/core@7.27.4): dependencies: - '@babel/compat-data': 7.29.0 - '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + '@babel/compat-data': 7.27.5 + '@babel/core': 7.27.4 + '@babel/helper-define-polyfill-provider': 0.6.4(@babel/core@7.27.4) semver: 6.3.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.29.0): - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) - core-js-compat: 3.49.0 - transitivePeerDependencies: - - supports-color - - babel-plugin-polyfill-corejs3@0.14.2(@babel/core@7.29.0): + babel-plugin-polyfill-corejs3@0.11.1(@babel/core@7.27.4): dependencies: - '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) - core-js-compat: 3.49.0 + '@babel/core': 7.27.4 + '@babel/helper-define-polyfill-provider': 0.6.4(@babel/core@7.27.4) + core-js-compat: 3.43.0 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.8(@babel/core@7.29.0): + babel-plugin-polyfill-regenerator@0.6.4(@babel/core@7.27.4): dependencies: - '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + '@babel/core': 7.27.4 + '@babel/helper-define-polyfill-provider': 0.6.4(@babel/core@7.27.4) transitivePeerDependencies: - supports-color babel-plugin-transform-react-remove-prop-types@0.4.24: {} - babel-preset-current-node-syntax@1.2.0(@babel/core@7.29.0): - dependencies: - '@babel/core': 7.29.0 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.29.0) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.29.0) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.29.0) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.29.0) - '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.29.0) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.29.0) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.29.0) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.29.0) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.29.0) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.29.0) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.29.0) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.29.0) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.29.0) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.29.0) - - babel-preset-jest@27.5.1(@babel/core@7.29.0): - dependencies: - '@babel/core': 7.29.0 + babel-preset-current-node-syntax@1.1.0(@babel/core@7.27.4): + dependencies: + '@babel/core': 7.27.4 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.27.4) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.27.4) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.27.4) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.27.4) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.27.4) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.27.4) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.27.4) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.27.4) + + babel-preset-jest@27.5.1(@babel/core@7.27.4): + dependencies: + '@babel/core': 7.27.4 babel-plugin-jest-hoist: 27.5.1 - babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.4) babel-preset-react-app@10.1.0: dependencies: - '@babel/core': 7.29.0 - '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.29.0) - '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.0) - '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.29.0) - '@babel/plugin-proposal-numeric-separator': 7.18.6(@babel/core@7.29.0) - '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.29.0) - '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.29.0) - '@babel/plugin-proposal-private-property-in-object': 7.21.11(@babel/core@7.29.0) - '@babel/plugin-transform-flow-strip-types': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.29.0) - '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) - '@babel/preset-env': 7.29.2(@babel/core@7.29.0) - '@babel/preset-react': 7.28.5(@babel/core@7.29.0) - '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) - '@babel/runtime': 7.29.2 + '@babel/core': 7.27.4 + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.27.4) + '@babel/plugin-proposal-decorators': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.27.4) + '@babel/plugin-proposal-numeric-separator': 7.18.6(@babel/core@7.27.4) + '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.27.4) + '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.27.4) + '@babel/plugin-proposal-private-property-in-object': 7.21.11(@babel/core@7.27.4) + '@babel/plugin-transform-flow-strip-types': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-react-display-name': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-runtime': 7.27.4(@babel/core@7.27.4) + '@babel/preset-env': 7.27.2(@babel/core@7.27.4) + '@babel/preset-react': 7.27.1(@babel/core@7.27.4) + '@babel/preset-typescript': 7.27.1(@babel/core@7.27.4) + '@babel/runtime': 7.27.6 babel-plugin-macros: 3.1.0 babel-plugin-transform-react-remove-prop-types: 0.4.24 transitivePeerDependencies: @@ -14161,8 +13788,6 @@ snapshots: balanced-match@1.0.2: {} - balanced-match@4.0.4: {} - base-x@3.0.11: dependencies: safe-buffer: 5.2.1 @@ -14173,8 +13798,6 @@ snapshots: base64url@3.0.1: {} - baseline-browser-mapping@2.10.17: {} - batch@0.6.1: {} bech32@1.1.4: {} @@ -14188,25 +13811,25 @@ snapshots: bluebird: 3.7.2 check-types: 11.2.3 hoopy: 0.1.4 - jsonpath: 1.3.0 + jsonpath: 1.1.1 tryer: 1.0.1 big.js@5.2.2: {} - bignumber.js@9.3.1: {} + bignumber.js@9.3.0: {} binary-extensions@2.3.0: {} bip39-light@1.0.7: dependencies: create-hash: 1.2.0 - pbkdf2: 3.1.5 + pbkdf2: 3.1.3 bip39@3.0.2: dependencies: '@types/node': 11.11.6 create-hash: 1.2.0 - pbkdf2: 3.1.5 + pbkdf2: 3.1.3 randombytes: 2.1.0 bl@4.1.0: @@ -14217,24 +13840,24 @@ snapshots: bluebird@3.7.2: {} - bn.js@4.12.3: {} + bn.js@4.12.2: {} bn.js@5.2.1: {} - bn.js@5.2.3: {} + bn.js@5.2.2: {} - body-parser@1.20.4: + body-parser@1.20.3: dependencies: bytes: 3.1.2 content-type: 1.0.5 debug: 2.6.9 depd: 2.0.0 destroy: 1.2.0 - http-errors: 2.0.1 + http-errors: 2.0.0 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.14.2 - raw-body: 2.5.3 + qs: 6.13.0 + raw-body: 2.5.2 type-is: 1.6.18 unpipe: 1.0.0 transitivePeerDependencies: @@ -14247,27 +13870,21 @@ snapshots: boolbase@1.0.0: {} - boolbase@2.0.0: {} - borsh@0.7.0: dependencies: bn.js: 5.2.1 bs58: 4.0.1 text-encoding-utf-8: 1.0.2 - brace-expansion@1.1.13: + brace-expansion@1.1.12: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.0.3: + brace-expansion@2.0.2: dependencies: balanced-match: 1.0.2 - brace-expansion@5.0.5: - dependencies: - balanced-match: 4.0.4 - braces@3.0.3: dependencies: fill-range: 7.1.1 @@ -14283,7 +13900,7 @@ snapshots: browserify-aes@1.2.0: dependencies: buffer-xor: 1.0.3 - cipher-base: 1.0.7 + cipher-base: 1.0.6 create-hash: 1.2.0 evp_bytestokey: 1.0.3 inherits: 2.0.4 @@ -14297,36 +13914,36 @@ snapshots: browserify-des@1.0.2: dependencies: - cipher-base: 1.0.7 + cipher-base: 1.0.6 des.js: 1.1.0 inherits: 2.0.4 safe-buffer: 5.2.1 browserify-rsa@4.1.1: dependencies: - bn.js: 5.2.3 + bn.js: 5.2.2 randombytes: 2.1.0 safe-buffer: 5.2.1 - browserify-sign@4.2.5: + browserify-sign@4.2.3: dependencies: - bn.js: 5.2.3 + bn.js: 5.2.2 browserify-rsa: 4.1.1 create-hash: 1.2.0 create-hmac: 1.1.7 elliptic: 6.6.1 + hash-base: 3.0.5 inherits: 2.0.4 - parse-asn1: 5.1.9 + parse-asn1: 5.1.7 readable-stream: 2.3.8 safe-buffer: 5.2.1 - browserslist@4.28.2: + browserslist@4.25.1: dependencies: - baseline-browser-mapping: 2.10.17 - caniuse-lite: 1.0.30001787 - electron-to-chromium: 1.5.334 - node-releases: 2.0.37 - update-browserslist-db: 1.2.3(browserslist@4.28.2) + caniuse-lite: 1.0.30001726 + electron-to-chromium: 1.5.176 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.25.1) bs58@4.0.1: dependencies: @@ -14354,7 +13971,7 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 - bufferutil@4.1.0: + bufferutil@4.0.9: dependencies: node-gyp-build: 4.8.4 optional: true @@ -14363,7 +13980,7 @@ snapshots: bundle-name@4.1.0: dependencies: - run-applescript: 7.1.0 + run-applescript: 7.0.0 bundle-require@4.2.1(esbuild@0.19.12): dependencies: @@ -14374,7 +13991,7 @@ snapshots: dependencies: bytes: 3.1.2 - bundlemon@3.1.0(typescript@5.9.3): + bundlemon@3.1.0(typescript@5.8.3): dependencies: axios: 1.15.0 axios-retry: 4.5.0(axios@1.15.0) @@ -14383,7 +14000,7 @@ snapshots: bytes: 3.1.2 chalk: 4.1.2 commander: 11.1.0 - cosmiconfig: 8.3.6(typescript@5.9.3) + cosmiconfig: 8.3.6(typescript@5.8.3) gzip-size: 6.0.0 micromatch: 4.0.8 yup: 0.32.11 @@ -14397,8 +14014,6 @@ snapshots: bytes@3.1.2: {} - bytestreamjs@2.0.1: {} - cac@6.7.14: {} cacheable-lookup@5.0.4: {} @@ -14420,7 +14035,7 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 - call-bind@1.0.9: + call-bind@1.0.8: dependencies: call-bind-apply-helpers: 1.0.2 es-define-property: 1.0.1 @@ -14453,21 +14068,21 @@ snapshots: caniuse-api@3.0.0: dependencies: - browserslist: 4.28.2 - caniuse-lite: 1.0.30001787 + browserslist: 4.25.1 + caniuse-lite: 1.0.30001726 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 - caniuse-lite@1.0.30001787: {} + caniuse-lite@1.0.30001726: {} case-sensitive-paths-webpack-plugin@2.4.0: {} - chai@5.3.3: + chai@5.2.0: dependencies: assertion-error: 2.0.1 - check-error: 2.1.3 + check-error: 2.1.1 deep-eql: 5.0.2 - loupe: 3.2.1 + loupe: 3.1.4 pathval: 2.0.1 chalk@2.4.2: @@ -14481,7 +14096,7 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 - chalk@5.6.2: {} + chalk@5.4.1: {} char-regex@1.0.2: {} @@ -14489,9 +14104,7 @@ snapshots: chardet@0.7.0: {} - chardet@2.1.1: {} - - check-error@2.1.3: {} + check-error@2.1.1: {} check-types@11.2.3: {} @@ -14511,11 +14124,10 @@ snapshots: ci-info@3.9.0: {} - cipher-base@1.0.7: + cipher-base@1.0.6: dependencies: inherits: 2.0.4 safe-buffer: 5.2.1 - to-buffer: 1.2.2 cjs-module-lexer@1.4.3: {} @@ -14559,7 +14171,7 @@ snapshots: chalk: 2.4.2 q: 1.5.1 - collect-v8-coverage@1.0.3: {} + collect-v8-coverage@1.0.2: {} color-convert@1.9.3: dependencies: @@ -14573,6 +14185,18 @@ snapshots: color-name@1.1.4: {} + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + optional: true + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + optional: true + colord@2.9.3: {} colorette@2.0.20: {} @@ -14601,8 +14225,6 @@ snapshots: commander@13.1.0: {} - commander@14.0.3: {} - commander@2.20.3: {} commander@4.1.1: {} @@ -14611,10 +14233,10 @@ snapshots: commander@8.3.0: {} - commitizen@4.3.1(@types/node@24.3.0)(typescript@5.9.3): + commitizen@4.3.1(@types/node@24.3.0)(typescript@5.8.3): dependencies: cachedir: 2.3.0 - cz-conventional-changelog: 3.3.0(@types/node@24.3.0)(typescript@5.9.3) + cz-conventional-changelog: 3.3.0(@types/node@24.3.0)(typescript@5.8.3) dedent: 0.7.0 detect-indent: 6.1.0 find-node-modules: 2.1.3 @@ -14644,13 +14266,13 @@ snapshots: dependencies: mime-db: 1.54.0 - compression@1.8.1: + compression@1.8.0: dependencies: bytes: 3.1.2 compressible: 2.0.18 debug: 2.6.9 negotiator: 0.6.4 - on-headers: 1.1.0 + on-headers: 1.0.2 safe-buffer: 5.2.1 vary: 1.1.2 transitivePeerDependencies: @@ -14693,7 +14315,7 @@ snapshots: conventional-changelog-conventionalcommits@4.6.3: dependencies: compare-func: 2.0.0 - lodash: 4.18.1 + lodash: 4.17.21 q: 1.5.1 conventional-changelog-core@4.2.4: @@ -14706,7 +14328,7 @@ snapshots: git-raw-commits: 2.0.11 git-remote-origin-url: 2.0.0 git-semver-tags: 4.1.1 - lodash: 4.18.1 + lodash: 4.17.21 normalize-package-data: 3.0.3 q: 1.5.1 read-pkg: 3.0.0 @@ -14740,9 +14362,9 @@ snapshots: dependencies: conventional-commits-filter: 2.0.7 dateformat: 3.0.3 - handlebars: 4.7.9 + handlebars: 4.7.8 json-stringify-safe: 5.0.1 - lodash: 4.18.1 + lodash: 4.17.21 meow: 8.1.2 semver: 6.3.1 split: 1.0.1 @@ -14773,17 +14395,11 @@ snapshots: dependencies: JSONStream: 1.3.5 is-text-path: 1.0.1 - lodash: 4.18.1 + lodash: 4.17.21 meow: 8.1.2 split2: 3.2.2 through2: 4.0.2 - conventional-commits-parser@6.4.0: - dependencies: - '@simple-libs/stream-utils': 1.2.0 - meow: 13.2.0 - optional: true - conventional-recommended-bump@6.1.0: dependencies: concat-stream: 2.0.0 @@ -14799,39 +14415,39 @@ snapshots: convert-source-map@2.0.0: {} - cookie-signature@1.0.7: {} + cookie-signature@1.0.6: {} - cookie@0.7.2: {} + cookie@0.7.1: {} copy-to-clipboard@3.3.3: dependencies: toggle-selection: 1.0.6 - copy-webpack-plugin@13.0.1(webpack@5.106.1): + copy-webpack-plugin@13.0.0(webpack@5.99.9): dependencies: glob-parent: 6.0.2 normalize-path: 3.0.0 - schema-utils: 4.3.3 + schema-utils: 4.3.2 serialize-javascript: 6.0.2 - tinyglobby: 0.2.16 - webpack: 5.106.1(webpack-cli@6.0.1) + tinyglobby: 0.2.14 + webpack: 5.99.9(webpack-cli@6.0.1) - core-js-compat@3.49.0: + core-js-compat@3.43.0: dependencies: - browserslist: 4.28.2 + browserslist: 4.25.1 - core-js-pure@3.49.0: {} + core-js-pure@3.43.0: {} - core-js@3.49.0: {} + core-js@3.43.0: {} core-util-is@1.0.3: {} - cosmiconfig-typescript-loader@6.3.0(@types/node@24.3.0)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3): + cosmiconfig-typescript-loader@6.1.0(@types/node@24.3.0)(cosmiconfig@9.0.0(typescript@5.8.3))(typescript@5.8.3): dependencies: '@types/node': 24.3.0 - cosmiconfig: 9.0.1(typescript@5.9.3) - jiti: 2.6.1 - typescript: 5.9.3 + cosmiconfig: 9.0.0(typescript@5.8.3) + jiti: 2.4.2 + typescript: 5.8.3 optional: true cosmiconfig@6.0.0: @@ -14840,7 +14456,7 @@ snapshots: import-fresh: 3.3.1 parse-json: 5.2.0 path-type: 4.0.0 - yaml: 1.10.3 + yaml: 1.10.2 cosmiconfig@7.1.0: dependencies: @@ -14848,48 +14464,55 @@ snapshots: import-fresh: 3.3.1 parse-json: 5.2.0 path-type: 4.0.0 - yaml: 1.10.3 + yaml: 1.10.2 - cosmiconfig@8.3.6(typescript@5.9.3): + cosmiconfig@8.3.6(typescript@5.8.3): dependencies: import-fresh: 3.3.1 - js-yaml: 4.1.1 + js-yaml: 4.1.0 parse-json: 5.2.0 path-type: 4.0.0 optionalDependencies: - typescript: 5.9.3 + typescript: 5.8.3 - cosmiconfig@9.0.1(typescript@5.9.3): + cosmiconfig@9.0.0(typescript@5.8.3): dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 - js-yaml: 4.1.1 + js-yaml: 4.1.0 parse-json: 5.2.0 optionalDependencies: - typescript: 5.9.3 + typescript: 5.8.3 optional: true create-ecdh@4.0.4: dependencies: - bn.js: 4.12.3 + bn.js: 4.12.2 elliptic: 6.6.1 + create-hash@1.1.3: + dependencies: + cipher-base: 1.0.6 + inherits: 2.0.4 + ripemd160: 2.0.1 + sha.js: 2.4.11 + create-hash@1.2.0: dependencies: - cipher-base: 1.0.7 + cipher-base: 1.0.6 inherits: 2.0.4 md5.js: 1.3.5 - ripemd160: 2.0.3 - sha.js: 2.4.12 + ripemd160: 2.0.2 + sha.js: 2.4.11 create-hmac@1.1.7: dependencies: - cipher-base: 1.0.7 + cipher-base: 1.0.6 create-hash: 1.2.0 inherits: 2.0.4 - ripemd160: 2.0.3 + ripemd160: 2.0.2 safe-buffer: 5.2.1 - sha.js: 2.4.12 + sha.js: 2.4.11 create-require@1.1.1: {} @@ -14916,60 +14539,60 @@ snapshots: crypto-browserify@3.12.1: dependencies: browserify-cipher: 1.0.1 - browserify-sign: 4.2.5 + browserify-sign: 4.2.3 create-ecdh: 4.0.4 create-hash: 1.2.0 create-hmac: 1.1.7 diffie-hellman: 5.0.3 hash-base: 3.0.5 inherits: 2.0.4 - pbkdf2: 3.1.5 + pbkdf2: 3.1.3 public-encrypt: 4.0.3 randombytes: 2.1.0 randomfill: 1.0.4 crypto-random-string@2.0.0: {} - css-blank-pseudo@3.0.3(postcss@8.5.9): + css-blank-pseudo@3.0.3(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-selector-parser: 6.1.2 - css-declaration-sorter@6.4.1(postcss@8.5.9): + css-declaration-sorter@6.4.1(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 - css-has-pseudo@3.0.4(postcss@8.5.9): + css-has-pseudo@3.0.4(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-selector-parser: 6.1.2 - css-loader@6.11.0(webpack@5.106.1): + css-loader@6.11.0(webpack@5.99.9): dependencies: - icss-utils: 5.1.0(postcss@8.5.9) - postcss: 8.5.9 - postcss-modules-extract-imports: 3.1.0(postcss@8.5.9) - postcss-modules-local-by-default: 4.2.0(postcss@8.5.9) - postcss-modules-scope: 3.2.1(postcss@8.5.9) - postcss-modules-values: 4.0.0(postcss@8.5.9) + icss-utils: 5.1.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.6) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.6) + postcss-modules-scope: 3.2.1(postcss@8.5.6) + postcss-modules-values: 4.0.0(postcss@8.5.6) postcss-value-parser: 4.2.0 - semver: 7.7.4 + semver: 7.7.2 optionalDependencies: - webpack: 5.106.1(webpack-cli@6.0.1) + webpack: 5.99.9(webpack-cli@6.0.1) - css-minimizer-webpack-plugin@3.4.1(webpack@5.106.1): + css-minimizer-webpack-plugin@3.4.1(webpack@5.99.9): dependencies: - cssnano: 5.1.15(postcss@8.5.9) + cssnano: 5.1.15(postcss@8.5.6) jest-worker: 27.5.1 - postcss: 8.5.9 - schema-utils: 4.3.3 + postcss: 8.5.6 + schema-utils: 4.3.2 serialize-javascript: 6.0.2 source-map: 0.6.1 - webpack: 5.106.1(webpack-cli@6.0.1) + webpack: 5.99.9(webpack-cli@6.0.1) - css-prefers-color-scheme@6.0.3(postcss@8.5.9): + css-prefers-color-scheme@6.0.3(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 css-select-base-adapter@0.1.1: {} @@ -14978,12 +14601,12 @@ snapshots: boolbase: 1.0.0 css-what: 3.4.2 domutils: 1.7.0 - nth-check: 3.0.1 + nth-check: 2.1.1 css-select@4.3.0: dependencies: boolbase: 1.0.0 - css-what: 6.2.2 + css-what: 6.1.0 domhandler: 4.3.1 domutils: 2.8.0 nth-check: 2.1.1 @@ -15000,55 +14623,55 @@ snapshots: css-what@3.4.2: {} - css-what@6.2.2: {} + css-what@6.1.0: {} cssdb@7.11.2: {} cssesc@3.0.0: {} - cssnano-preset-default@5.2.14(postcss@8.5.9): - dependencies: - css-declaration-sorter: 6.4.1(postcss@8.5.9) - cssnano-utils: 3.1.0(postcss@8.5.9) - postcss: 8.5.9 - postcss-calc: 8.2.4(postcss@8.5.9) - postcss-colormin: 5.3.1(postcss@8.5.9) - postcss-convert-values: 5.1.3(postcss@8.5.9) - postcss-discard-comments: 5.1.2(postcss@8.5.9) - postcss-discard-duplicates: 5.1.0(postcss@8.5.9) - postcss-discard-empty: 5.1.1(postcss@8.5.9) - postcss-discard-overridden: 5.1.0(postcss@8.5.9) - postcss-merge-longhand: 5.1.7(postcss@8.5.9) - postcss-merge-rules: 5.1.4(postcss@8.5.9) - postcss-minify-font-values: 5.1.0(postcss@8.5.9) - postcss-minify-gradients: 5.1.1(postcss@8.5.9) - postcss-minify-params: 5.1.4(postcss@8.5.9) - postcss-minify-selectors: 5.2.1(postcss@8.5.9) - postcss-normalize-charset: 5.1.0(postcss@8.5.9) - postcss-normalize-display-values: 5.1.0(postcss@8.5.9) - postcss-normalize-positions: 5.1.1(postcss@8.5.9) - postcss-normalize-repeat-style: 5.1.1(postcss@8.5.9) - postcss-normalize-string: 5.1.0(postcss@8.5.9) - postcss-normalize-timing-functions: 5.1.0(postcss@8.5.9) - postcss-normalize-unicode: 5.1.1(postcss@8.5.9) - postcss-normalize-url: 5.1.0(postcss@8.5.9) - postcss-normalize-whitespace: 5.1.1(postcss@8.5.9) - postcss-ordered-values: 5.1.3(postcss@8.5.9) - postcss-reduce-initial: 5.1.2(postcss@8.5.9) - postcss-reduce-transforms: 5.1.0(postcss@8.5.9) - postcss-svgo: 5.1.0(postcss@8.5.9) - postcss-unique-selectors: 5.1.1(postcss@8.5.9) - - cssnano-utils@3.1.0(postcss@8.5.9): - dependencies: - postcss: 8.5.9 - - cssnano@5.1.15(postcss@8.5.9): - dependencies: - cssnano-preset-default: 5.2.14(postcss@8.5.9) + cssnano-preset-default@5.2.14(postcss@8.5.6): + dependencies: + css-declaration-sorter: 6.4.1(postcss@8.5.6) + cssnano-utils: 3.1.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-calc: 8.2.4(postcss@8.5.6) + postcss-colormin: 5.3.1(postcss@8.5.6) + postcss-convert-values: 5.1.3(postcss@8.5.6) + postcss-discard-comments: 5.1.2(postcss@8.5.6) + postcss-discard-duplicates: 5.1.0(postcss@8.5.6) + postcss-discard-empty: 5.1.1(postcss@8.5.6) + postcss-discard-overridden: 5.1.0(postcss@8.5.6) + postcss-merge-longhand: 5.1.7(postcss@8.5.6) + postcss-merge-rules: 5.1.4(postcss@8.5.6) + postcss-minify-font-values: 5.1.0(postcss@8.5.6) + postcss-minify-gradients: 5.1.1(postcss@8.5.6) + postcss-minify-params: 5.1.4(postcss@8.5.6) + postcss-minify-selectors: 5.2.1(postcss@8.5.6) + postcss-normalize-charset: 5.1.0(postcss@8.5.6) + postcss-normalize-display-values: 5.1.0(postcss@8.5.6) + postcss-normalize-positions: 5.1.1(postcss@8.5.6) + postcss-normalize-repeat-style: 5.1.1(postcss@8.5.6) + postcss-normalize-string: 5.1.0(postcss@8.5.6) + postcss-normalize-timing-functions: 5.1.0(postcss@8.5.6) + postcss-normalize-unicode: 5.1.1(postcss@8.5.6) + postcss-normalize-url: 5.1.0(postcss@8.5.6) + postcss-normalize-whitespace: 5.1.1(postcss@8.5.6) + postcss-ordered-values: 5.1.3(postcss@8.5.6) + postcss-reduce-initial: 5.1.2(postcss@8.5.6) + postcss-reduce-transforms: 5.1.0(postcss@8.5.6) + postcss-svgo: 5.1.0(postcss@8.5.6) + postcss-unique-selectors: 5.1.1(postcss@8.5.6) + + cssnano-utils@3.1.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + cssnano@5.1.15(postcss@8.5.6): + dependencies: + cssnano-preset-default: 5.2.14(postcss@8.5.6) lilconfig: 2.1.0 - postcss: 8.5.9 - yaml: 1.10.3 + postcss: 8.5.6 + yaml: 1.10.2 csso@4.2.0: dependencies: @@ -15062,7 +14685,7 @@ snapshots: dependencies: cssom: 0.3.8 - csstype@3.2.3: {} + csstype@3.1.3: {} csv-generate@3.4.3: {} @@ -15077,16 +14700,16 @@ snapshots: csv-stringify: 5.6.5 stream-transform: 2.1.3 - cz-conventional-changelog@3.3.0(@types/node@24.3.0)(typescript@5.9.3): + cz-conventional-changelog@3.3.0(@types/node@24.3.0)(typescript@5.8.3): dependencies: chalk: 2.4.2 - commitizen: 4.3.1(@types/node@24.3.0)(typescript@5.9.3) + commitizen: 4.3.1(@types/node@24.3.0)(typescript@5.8.3) conventional-commit-types: 3.0.0 lodash.map: 4.6.0 longest: 2.0.1 word-wrap: 1.2.5 optionalDependencies: - '@commitlint/load': 20.5.0(@types/node@24.3.0)(typescript@5.9.3) + '@commitlint/load': 19.8.1(@types/node@24.3.0)(typescript@5.8.3) transitivePeerDependencies: - '@types/node' - typescript @@ -15129,7 +14752,7 @@ snapshots: dependencies: ms: 2.1.3 - debug@4.4.3: + debug@4.4.1: dependencies: ms: 2.1.3 @@ -15140,7 +14763,7 @@ snapshots: decamelize@1.2.0: {} - decimal.js@10.6.0: {} + decimal.js@10.5.0: {} decompress-response@6.0.0: dependencies: @@ -15153,7 +14776,7 @@ snapshots: deep-equal@2.2.3: dependencies: array-buffer-byte-length: 1.0.2 - call-bind: 1.0.9 + call-bind: 1.0.8 es-get-iterator: 1.1.3 get-intrinsic: 1.3.0 is-arguments: 1.2.0 @@ -15169,7 +14792,7 @@ snapshots: side-channel: 1.1.0 which-boxed-primitive: 1.1.1 which-collection: 1.0.2 - which-typed-array: 1.1.20 + which-typed-array: 1.1.19 deep-extend@0.6.0: {} @@ -15177,12 +14800,12 @@ snapshots: deepmerge@4.3.1: {} - default-browser-id@5.0.1: {} + default-browser-id@5.0.0: {} - default-browser@5.5.0: + default-browser@5.2.1: dependencies: bundle-name: 4.1.0 - default-browser-id: 5.0.1 + default-browser-id: 5.0.0 default-gateway@6.0.3: dependencies: @@ -15229,9 +14852,9 @@ snapshots: detect-indent@6.1.0: {} - detect-indent@7.0.2: {} + detect-indent@7.0.1: {} - detect-libc@2.1.2: + detect-libc@2.0.4: optional: true detect-newline@3.1.0: {} @@ -15251,11 +14874,11 @@ snapshots: diff-sequences@27.5.1: {} - diff@4.0.4: {} + diff@4.0.2: {} diffie-hellman@5.0.3: dependencies: - bn.js: 4.12.3 + bn.js: 4.12.2 miller-rabin: 4.0.1 randombytes: 2.1.0 @@ -15328,12 +14951,12 @@ snapshots: dotenv@10.0.0: {} - dotenv@16.6.1: {} + dotenv@16.5.0: {} dotgitignore@2.1.0: dependencies: find-up: 3.0.0 - minimatch: 3.1.5 + minimatch: 3.1.2 dunder-proto@1.0.1: dependencies: @@ -15351,13 +14974,13 @@ snapshots: ejs@3.1.10: dependencies: - jake: 10.9.4 + jake: 10.9.2 - electron-to-chromium@1.5.334: {} + electron-to-chromium@1.5.176: {} elliptic@6.6.1: dependencies: - bn.js: 4.12.3 + bn.js: 4.12.2 brorand: 1.1.0 hash.js: 1.1.7 hmac-drbg: 1.0.1 @@ -15377,16 +15000,18 @@ snapshots: emojis-list@3.0.0: {} + encodeurl@1.0.2: {} + encodeurl@2.0.0: {} end-of-stream@1.4.5: dependencies: once: 1.4.0 - enhanced-resolve@5.20.1: + enhanced-resolve@5.18.2: dependencies: graceful-fs: 4.2.11 - tapable: 2.3.2 + tapable: 2.2.2 enquirer@2.4.1: dependencies: @@ -15398,9 +15023,9 @@ snapshots: env-paths@2.2.1: optional: true - envinfo@7.21.0: {} + envinfo@7.14.0: {} - error-ex@1.3.4: + error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 @@ -15408,12 +15033,12 @@ snapshots: dependencies: stackframe: 1.3.4 - es-abstract@1.24.2: + es-abstract@1.24.0: dependencies: array-buffer-byte-length: 1.0.2 arraybuffer.prototype.slice: 1.0.4 available-typed-arrays: 1.0.7 - call-bind: 1.0.9 + call-bind: 1.0.8 call-bound: 1.0.4 data-view-buffer: 1.0.2 data-view-byte-length: 1.0.2 @@ -15463,7 +15088,7 @@ snapshots: typed-array-byte-offset: 1.0.4 typed-array-length: 1.0.7 unbox-primitive: 1.1.0 - which-typed-array: 1.1.20 + which-typed-array: 1.1.19 es-array-method-boxes-properly@1.0.0: {} @@ -15473,7 +15098,7 @@ snapshots: es-get-iterator@1.1.3: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 get-intrinsic: 1.3.0 has-symbols: 1.1.0 is-arguments: 1.2.0 @@ -15483,12 +15108,12 @@ snapshots: isarray: 2.0.5 stop-iteration-iterator: 1.1.0 - es-iterator-helpers@1.3.2: + es-iterator-helpers@1.2.1: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.24.2 + es-abstract: 1.24.0 es-errors: 1.3.0 es-set-tostringtag: 2.1.0 function-bind: 1.1.2 @@ -15500,12 +15125,10 @@ snapshots: has-symbols: 1.1.0 internal-slot: 1.1.0 iterator.prototype: 1.1.5 - math-intrinsics: 1.1.0 + safe-array-concat: 1.1.3 es-module-lexer@1.7.0: {} - es-module-lexer@2.0.0: {} - es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 @@ -15533,14 +15156,14 @@ snapshots: dependencies: es6-promise: 4.2.8 - esbuild-loader@2.21.0(webpack@5.106.1): + esbuild-loader@2.21.0(webpack@5.99.9): dependencies: esbuild: 0.16.17 joycon: 3.1.1 json5: 2.2.3 loader-utils: 2.0.4 - tapable: 2.3.2 - webpack: 5.106.1(webpack-cli@6.0.1) + tapable: 2.2.2 + webpack: 5.99.9(webpack-cli@6.0.1) webpack-sources: 1.4.3 esbuild@0.16.17: @@ -15594,34 +15217,33 @@ snapshots: '@esbuild/win32-ia32': 0.19.12 '@esbuild/win32-x64': 0.19.12 - esbuild@0.27.7: + esbuild@0.25.5: optionalDependencies: - '@esbuild/aix-ppc64': 0.27.7 - '@esbuild/android-arm': 0.27.7 - '@esbuild/android-arm64': 0.27.7 - '@esbuild/android-x64': 0.27.7 - '@esbuild/darwin-arm64': 0.27.7 - '@esbuild/darwin-x64': 0.27.7 - '@esbuild/freebsd-arm64': 0.27.7 - '@esbuild/freebsd-x64': 0.27.7 - '@esbuild/linux-arm': 0.27.7 - '@esbuild/linux-arm64': 0.27.7 - '@esbuild/linux-ia32': 0.27.7 - '@esbuild/linux-loong64': 0.27.7 - '@esbuild/linux-mips64el': 0.27.7 - '@esbuild/linux-ppc64': 0.27.7 - '@esbuild/linux-riscv64': 0.27.7 - '@esbuild/linux-s390x': 0.27.7 - '@esbuild/linux-x64': 0.27.7 - '@esbuild/netbsd-arm64': 0.27.7 - '@esbuild/netbsd-x64': 0.27.7 - '@esbuild/openbsd-arm64': 0.27.7 - '@esbuild/openbsd-x64': 0.27.7 - '@esbuild/openharmony-arm64': 0.27.7 - '@esbuild/sunos-x64': 0.27.7 - '@esbuild/win32-arm64': 0.27.7 - '@esbuild/win32-ia32': 0.27.7 - '@esbuild/win32-x64': 0.27.7 + '@esbuild/aix-ppc64': 0.25.5 + '@esbuild/android-arm': 0.25.5 + '@esbuild/android-arm64': 0.25.5 + '@esbuild/android-x64': 0.25.5 + '@esbuild/darwin-arm64': 0.25.5 + '@esbuild/darwin-x64': 0.25.5 + '@esbuild/freebsd-arm64': 0.25.5 + '@esbuild/freebsd-x64': 0.25.5 + '@esbuild/linux-arm': 0.25.5 + '@esbuild/linux-arm64': 0.25.5 + '@esbuild/linux-ia32': 0.25.5 + '@esbuild/linux-loong64': 0.25.5 + '@esbuild/linux-mips64el': 0.25.5 + '@esbuild/linux-ppc64': 0.25.5 + '@esbuild/linux-riscv64': 0.25.5 + '@esbuild/linux-s390x': 0.25.5 + '@esbuild/linux-x64': 0.25.5 + '@esbuild/netbsd-arm64': 0.25.5 + '@esbuild/netbsd-x64': 0.25.5 + '@esbuild/openbsd-arm64': 0.25.5 + '@esbuild/openbsd-x64': 0.25.5 + '@esbuild/sunos-x64': 0.25.5 + '@esbuild/win32-arm64': 0.25.5 + '@esbuild/win32-ia32': 0.25.5 + '@esbuild/win32-x64': 0.25.5 escalade@3.2.0: {} @@ -15653,12 +15275,12 @@ snapshots: eslint-config-next@14.0.4(eslint@8.57.0)(typescript@5.2.2): dependencies: '@next/eslint-plugin-next': 14.0.4 - '@rushstack/eslint-patch': 1.16.1 + '@rushstack/eslint-patch': 1.11.0 '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.2.2) eslint: 8.57.0 - eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.0) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.0) eslint-plugin-react: 7.37.5(eslint@8.57.0) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.0) @@ -15669,48 +15291,48 @@ snapshots: - eslint-plugin-import-x - supports-color - eslint-config-next@14.0.4(eslint@8.57.0)(typescript@5.9.3): + eslint-config-next@14.0.4(eslint@8.57.0)(typescript@5.8.3): dependencies: '@next/eslint-plugin-next': 14.0.4 - '@rushstack/eslint-patch': 1.16.1 - '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.9.3) + '@rushstack/eslint-patch': 1.11.0 + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.8.3) eslint: 8.57.0 - eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.0) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.0) eslint-plugin-react: 7.37.5(eslint@8.57.0) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.0) optionalDependencies: - typescript: 5.9.3 + typescript: 5.8.3 transitivePeerDependencies: - eslint-import-resolver-webpack - eslint-plugin-import-x - supports-color - eslint-config-prettier@9.1.2(eslint@8.57.1): + eslint-config-prettier@9.1.0(eslint@8.57.1): dependencies: eslint: 8.57.1 - eslint-config-react-app@7.0.1(@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0))(@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)))(typescript@5.9.3): + eslint-config-react-app@7.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.27.4))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.27.4))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(utf-8-validate@5.0.10))(typescript@5.8.3): dependencies: - '@babel/core': 7.29.0 - '@babel/eslint-parser': 7.28.6(@babel/core@7.29.0)(eslint@8.57.1) - '@rushstack/eslint-patch': 1.16.1 - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.9.3) + '@babel/core': 7.27.4 + '@babel/eslint-parser': 7.27.5(@babel/core@7.27.4)(eslint@8.57.1) + '@rushstack/eslint-patch': 1.11.0 + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.8.3) babel-preset-react-app: 10.1.0 confusing-browser-globals: 1.0.11 eslint: 8.57.1 - eslint-plugin-flowtype: 8.0.3(@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0))(@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0))(eslint@8.57.1) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) - eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)))(typescript@5.9.3) + eslint-plugin-flowtype: 8.0.3(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.27.4))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.27.4))(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1) + eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(utf-8-validate@5.0.10))(typescript@5.8.3) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) eslint-plugin-react: 7.37.5(eslint@8.57.1) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) - eslint-plugin-testing-library: 5.11.1(eslint@8.57.1)(typescript@5.9.3) + eslint-plugin-testing-library: 5.11.1(eslint@8.57.1)(typescript@5.8.3) optionalDependencies: - typescript: 5.9.3 + typescript: 5.8.3 transitivePeerDependencies: - '@babel/plugin-syntax-flow' - '@babel/plugin-transform-react-jsx' @@ -15719,62 +15341,62 @@ snapshots: - jest - supports-color - eslint-config-typestrict@1.0.5(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3))(eslint-plugin-sonarjs@4.0.2(eslint@8.57.1)): + eslint-config-typestrict@1.0.5(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3))(eslint-plugin-sonarjs@3.0.3(eslint@8.57.1)): dependencies: - '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) - eslint-plugin-sonarjs: 4.0.2(eslint@8.57.1) + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3) + eslint-plugin-sonarjs: 3.0.3(eslint@8.57.1) - eslint-import-resolver-node@0.3.10: + eslint-import-resolver-node@0.3.9: dependencies: debug: 3.2.7 is-core-module: 2.16.1 - resolve: 2.0.0-next.6 + resolve: 1.22.10 transitivePeerDependencies: - supports-color eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.0): dependencies: '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.3 + debug: 4.4.1 eslint: 8.57.0 - get-tsconfig: 4.13.7 + get-tsconfig: 4.10.1 is-bun-module: 2.0.0 stable-hash: 0.0.5 - tinyglobby: 0.2.16 - unrs-resolver: 1.11.1 + tinyglobby: 0.2.14 + unrs-resolver: 1.9.2 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint@8.57.1): + eslint-module-utils@2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.8.3) eslint: 8.57.1 - eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0): + eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.8.3) eslint: 8.57.0 - eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.0) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint@8.57.1): + eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.8.3) eslint: 8.57.1 - eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color @@ -15784,15 +15406,15 @@ snapshots: eslint: 8.57.1 ignore: 5.3.2 - eslint-plugin-flowtype@8.0.3(@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0))(@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0))(eslint@8.57.1): + eslint-plugin-flowtype@8.0.3(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.27.4))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.27.4))(eslint@8.57.1): dependencies: - '@babel/plugin-syntax-flow': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-flow': 7.27.1(@babel/core@7.27.4) + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.27.4) eslint: 8.57.1 - lodash: 4.18.1 + lodash: 4.17.21 string-natural-compare: 3.0.1 - eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -15802,12 +15424,12 @@ snapshots: debug: 3.2.7 doctrine: 2.1.0 eslint: 8.57.1 - eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint@8.57.1) + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 - minimatch: 3.1.5 + minimatch: 3.1.2 object.fromentries: 2.0.8 object.groupby: 1.0.3 object.values: 1.2.1 @@ -15815,13 +15437,13 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.8.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -15831,12 +15453,12 @@ snapshots: debug: 3.2.7 doctrine: 2.1.0 eslint: 8.57.0 - eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0) + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 - minimatch: 3.1.5 + minimatch: 3.1.2 object.fromentries: 2.0.8 object.groupby: 1.0.3 object.values: 1.2.1 @@ -15844,13 +15466,13 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.8.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -15860,12 +15482,12 @@ snapshots: debug: 3.2.7 doctrine: 2.1.0 eslint: 8.57.1 - eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint@8.57.1) + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 - minimatch: 3.1.5 + minimatch: 3.1.2 object.fromentries: 2.0.8 object.groupby: 1.0.3 object.values: 1.2.1 @@ -15873,19 +15495,19 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.8.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)))(typescript@5.9.3): + eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(utf-8-validate@5.0.10))(typescript@5.8.3): dependencies: - '@typescript-eslint/experimental-utils': 5.62.0(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/experimental-utils': 5.62.0(eslint@8.57.1)(typescript@5.8.3) eslint: 8.57.1 optionalDependencies: - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) - jest: 27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)) + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3) + jest: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(utf-8-validate@5.0.10) transitivePeerDependencies: - supports-color - typescript @@ -15896,7 +15518,7 @@ snapshots: array-includes: 3.1.9 array.prototype.flatmap: 1.3.3 ast-types-flow: 0.0.8 - axe-core: 4.11.2 + axe-core: 4.10.3 axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 @@ -15904,7 +15526,7 @@ snapshots: hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 - minimatch: 3.1.5 + minimatch: 3.1.2 object.fromentries: 2.0.8 safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 @@ -15915,7 +15537,7 @@ snapshots: array-includes: 3.1.9 array.prototype.flatmap: 1.3.3 ast-types-flow: 0.0.8 - axe-core: 4.11.2 + axe-core: 4.10.3 axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 @@ -15923,7 +15545,7 @@ snapshots: hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 - minimatch: 3.1.5 + minimatch: 3.1.2 object.fromentries: 2.0.8 safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 @@ -15945,17 +15567,17 @@ snapshots: array.prototype.flatmap: 1.3.3 array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 - es-iterator-helpers: 1.3.2 + es-iterator-helpers: 1.2.1 eslint: 8.57.0 estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 - minimatch: 3.1.5 + minimatch: 3.1.2 object.entries: 1.1.9 object.fromentries: 2.0.8 object.values: 1.2.1 prop-types: 15.8.1 - resolve: 2.0.0-next.6 + resolve: 2.0.0-next.5 semver: 6.3.1 string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 @@ -15967,17 +15589,17 @@ snapshots: array.prototype.flatmap: 1.3.3 array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 - es-iterator-helpers: 1.3.2 + es-iterator-helpers: 1.2.1 eslint: 8.57.1 estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 - minimatch: 3.1.5 + minimatch: 3.1.2 object.entries: 1.1.9 object.fromentries: 2.0.8 object.values: 1.2.1 prop-types: 15.8.1 - resolve: 2.0.0-next.6 + resolve: 2.0.0-next.5 semver: 6.3.1 string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 @@ -15986,35 +15608,32 @@ snapshots: dependencies: eslint: 8.57.1 - eslint-plugin-sonarjs@4.0.2(eslint@8.57.1): + eslint-plugin-sonarjs@3.0.3(eslint@8.57.1): dependencies: - '@eslint-community/regexpp': 4.12.2 + '@eslint-community/regexpp': 4.12.1 builtin-modules: 3.3.0 bytes: 3.1.2 eslint: 8.57.1 functional-red-black-tree: 1.0.1 - globals: 17.4.0 - jsx-ast-utils-x: 0.1.0 - lodash.merge: 4.6.2 - minimatch: 10.2.5 + jsx-ast-utils: 3.3.5 + minimatch: 9.0.5 scslre: 0.3.0 - semver: 7.7.4 - ts-api-utils: 2.5.0(typescript@5.9.3) - typescript: 5.9.3 + semver: 7.7.2 + typescript: 5.8.3 - eslint-plugin-testing-library@5.11.1(eslint@8.57.1)(typescript@5.9.3): + eslint-plugin-testing-library@5.11.1(eslint@8.57.1)(typescript@5.8.3): dependencies: - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.8.3) eslint: 8.57.1 transitivePeerDependencies: - supports-color - typescript - eslint-plugin-unused-imports@4.4.1(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1): + eslint-plugin-unused-imports@4.1.4(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1): dependencies: eslint: 8.57.1 optionalDependencies: - '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3) eslint-scope@5.1.1: dependencies: @@ -16030,36 +15649,36 @@ snapshots: eslint-visitor-keys@3.4.3: {} - eslint-webpack-plugin@3.2.0(eslint@8.57.1)(webpack@5.106.1): + eslint-webpack-plugin@3.2.0(eslint@8.57.1)(webpack@5.99.9): dependencies: '@types/eslint': 8.56.12 eslint: 8.57.1 jest-worker: 28.1.3 micromatch: 4.0.8 normalize-path: 3.0.0 - schema-utils: 4.3.3 - webpack: 5.106.1(webpack-cli@6.0.1) + schema-utils: 4.3.2 + webpack: 5.99.9(webpack-cli@6.0.1) eslint@8.57.0: dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.0) - '@eslint-community/regexpp': 4.12.2 + '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.0) + '@eslint-community/regexpp': 4.12.1 '@eslint/eslintrc': 2.1.4 '@eslint/js': 8.57.0 '@humanwhocodes/config-array': 0.11.14 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 '@ungap/structured-clone': 1.3.0 - ajv: 6.14.0 + ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.3 + debug: 4.4.1 doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 - esquery: 1.7.0 + esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 6.0.1 @@ -16071,11 +15690,11 @@ snapshots: imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 - js-yaml: 4.1.1 + js-yaml: 4.1.0 json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 lodash.merge: 4.6.2 - minimatch: 3.1.5 + minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.4 strip-ansi: 6.0.1 @@ -16085,24 +15704,24 @@ snapshots: eslint@8.57.1: dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) - '@eslint-community/regexpp': 4.12.2 + '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1) + '@eslint-community/regexpp': 4.12.1 '@eslint/eslintrc': 2.1.4 '@eslint/js': 8.57.1 '@humanwhocodes/config-array': 0.13.0 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 '@ungap/structured-clone': 1.3.0 - ajv: 6.14.0 + ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.3 + debug: 4.4.1 doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 - esquery: 1.7.0 + esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 6.0.1 @@ -16114,11 +15733,11 @@ snapshots: imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 - js-yaml: 4.1.1 + js-yaml: 4.1.0 json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 lodash.merge: 4.6.2 - minimatch: 3.1.5 + minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.4 strip-ansi: 6.0.1 @@ -16128,15 +15747,15 @@ snapshots: espree@9.6.1: dependencies: - acorn: 8.16.0 - acorn-jsx: 5.3.2(acorn@8.16.0) + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) eslint-visitor-keys: 3.4.3 - esprima@1.2.5: {} + esprima@1.2.2: {} esprima@4.0.1: {} - esquery@1.7.0: + esquery@1.6.0: dependencies: estraverse: 5.3.0 @@ -16158,7 +15777,7 @@ snapshots: etag@1.8.1: {} - ethers@5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@ethersproject/abi': 5.8.0 '@ethersproject/abstract-provider': 5.8.0 @@ -16178,7 +15797,7 @@ snapshots: '@ethersproject/networks': 5.8.0 '@ethersproject/pbkdf2': 5.8.0 '@ethersproject/properties': 5.8.0 - '@ethersproject/providers': 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@ethersproject/providers': 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@ethersproject/random': 5.8.0 '@ethersproject/rlp': 5.8.0 '@ethersproject/sha2': 5.8.0 @@ -16196,7 +15815,7 @@ snapshots: eventemitter3@4.0.7: {} - eventemitter3@5.0.4: {} + eventemitter3@5.0.1: {} events@3.3.0: {} @@ -16223,7 +15842,7 @@ snapshots: dependencies: homedir-polyfill: 1.0.3 - expect-type@1.3.0: {} + expect-type@1.2.1: {} expect@27.5.1: dependencies: @@ -16232,39 +15851,39 @@ snapshots: jest-matcher-utils: 27.5.1 jest-message-util: 27.5.1 - exponential-backoff@3.1.3: + exponential-backoff@3.1.2: optional: true - express@4.22.1: + express@4.21.2: dependencies: accepts: 1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.4 + body-parser: 1.20.3 content-disposition: 0.5.4 content-type: 1.0.5 - cookie: 0.7.2 - cookie-signature: 1.0.7 + cookie: 0.7.1 + cookie-signature: 1.0.6 debug: 2.6.9 depd: 2.0.0 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 1.3.2 + finalhandler: 1.3.1 fresh: 0.5.2 - http-errors: 2.0.1 + http-errors: 2.0.0 merge-descriptors: 1.0.3 methods: 1.1.2 on-finished: 2.4.1 parseurl: 1.3.3 - path-to-regexp: 0.1.13 + path-to-regexp: 0.1.12 proxy-addr: 2.0.7 - qs: 6.14.2 + qs: 6.13.0 range-parser: 1.2.1 safe-buffer: 5.2.1 - send: 0.19.2 - serve-static: 1.16.3 + send: 0.19.0 + serve-static: 1.16.2 setprototypeof: 1.2.0 - statuses: 2.0.2 + statuses: 2.0.1 type-is: 1.6.18 utils-merge: 1.0.1 vary: 1.1.2 @@ -16297,11 +15916,11 @@ snapshots: fast-stable-stringify@1.0.0: {} - fast-uri@3.1.0: {} + fast-uri@3.0.6: {} fastest-levenshtein@1.0.16: {} - fastq@1.20.1: + fastq@1.19.1: dependencies: reusify: 1.1.0 @@ -16313,16 +15932,16 @@ snapshots: dependencies: bser: 2.1.1 - fdir@6.5.0(picomatch@4.0.4): + fdir@6.4.6(picomatch@4.0.2): optionalDependencies: - picomatch: 4.0.4 + picomatch: 4.0.2 fetch-mock@9.11.0(node-fetch@2.7.0): dependencies: - '@babel/core': 7.29.0 - '@babel/runtime': 7.29.2 - core-js: 3.49.0 - debug: 4.4.3 + '@babel/core': 7.27.4 + '@babel/runtime': 7.27.6 + core-js: 3.43.0 + debug: 4.4.1 glob-to-regexp: 0.4.1 is-subset: 0.1.1 lodash.isequal: 4.5.0 @@ -16342,15 +15961,15 @@ snapshots: dependencies: flat-cache: 3.2.0 - file-loader@6.2.0(webpack@5.106.1): + file-loader@6.2.0(webpack@5.99.9): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.106.1(webpack-cli@6.0.1) + webpack: 5.99.9(webpack-cli@6.0.1) - filelist@1.0.6: + filelist@1.0.4: dependencies: - minimatch: 5.1.9 + minimatch: 5.1.6 filename-reserved-regex@2.0.0: {} @@ -16366,14 +15985,14 @@ snapshots: dependencies: to-regex-range: 5.0.1 - finalhandler@1.3.2: + finalhandler@1.3.1: dependencies: debug: 2.6.9 encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 parseurl: 1.3.3 - statuses: 2.0.2 + statuses: 2.0.1 unpipe: 1.0.0 transitivePeerDependencies: - supports-color @@ -16422,15 +16041,17 @@ snapshots: flat-cache@3.2.0: dependencies: - flatted: 3.4.2 + flatted: 3.3.3 keyv: 4.5.4 rimraf: 3.0.2 flat@5.0.2: {} - flatted@3.4.2: {} + flatted@3.3.3: {} + + follow-redirects@1.15.9: {} - follow-redirects@1.15.11: {} + follow-redirects@1.16.0: {} for-each@0.3.5: dependencies: @@ -16441,9 +16062,9 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.1)(typescript@5.9.3)(webpack@5.106.1): + fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.1)(typescript@5.8.3)(webpack@5.99.9): dependencies: - '@babel/code-frame': 7.29.0 + '@babel/code-frame': 7.27.1 '@types/json-schema': 7.0.15 chalk: 4.1.2 chokidar: 3.6.0 @@ -16452,16 +16073,23 @@ snapshots: fs-extra: 9.1.0 glob: 7.2.3 memfs: 3.5.3 - minimatch: 3.1.5 + minimatch: 3.1.2 schema-utils: 2.7.0 - semver: 7.7.4 + semver: 7.7.2 tapable: 1.1.3 - typescript: 5.9.3 - webpack: 5.106.1(webpack-cli@6.0.1) + typescript: 5.8.3 + webpack: 5.99.9(webpack-cli@6.0.1) optionalDependencies: eslint: 8.57.1 - form-data@3.0.4: + form-data@3.0.3: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + mime-types: 2.1.35 + + form-data@4.0.3: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 @@ -16479,20 +16107,20 @@ snapshots: forwarded@0.2.0: {} - fraction.js@5.3.4: {} + fraction.js@4.3.7: {} fresh@0.5.2: {} fs-extra@10.1.0: dependencies: graceful-fs: 4.2.11 - jsonfile: 6.2.0 + jsonfile: 6.1.0 universalify: 2.0.1 - fs-extra@11.3.4: + fs-extra@11.3.0: dependencies: graceful-fs: 4.2.11 - jsonfile: 6.2.0 + jsonfile: 6.1.0 universalify: 2.0.1 fs-extra@7.0.1: @@ -16511,10 +16139,10 @@ snapshots: dependencies: at-least-node: 1.0.0 graceful-fs: 4.2.11 - jsonfile: 6.2.0 + jsonfile: 6.1.0 universalify: 2.0.1 - fs-monkey@1.1.0: {} + fs-monkey@1.0.6: {} fs.realpath@1.0.0: {} @@ -16525,7 +16153,7 @@ snapshots: function.prototype.name@1.1.8: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 call-bound: 1.0.4 define-properties: 1.2.1 functions-have-names: 1.2.3 @@ -16536,8 +16164,6 @@ snapshots: functions-have-names@1.2.3: {} - generator-function@2.0.1: {} - gensync@1.0.0-beta.2: {} get-caller-file@2.0.5: {} @@ -16575,7 +16201,7 @@ snapshots: get-stream@5.2.0: dependencies: - pump: 3.0.4 + pump: 3.0.3 get-stream@6.0.1: {} @@ -16585,7 +16211,7 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 - get-tsconfig@4.13.7: + get-tsconfig@4.10.1: dependencies: resolve-pkg-maps: 1.0.0 @@ -16596,7 +16222,7 @@ snapshots: email-addresses: 5.0.0 filenamify: 4.3.0 find-cache-dir: 3.3.2 - fs-extra: 11.3.4 + fs-extra: 11.3.0 globby: 11.1.0 git-hooks-list@3.2.0: {} @@ -16604,7 +16230,7 @@ snapshots: git-raw-commits@2.0.11: dependencies: dargs: 7.0.0 - lodash: 4.18.1 + lodash: 4.17.21 meow: 8.1.2 split2: 3.2.2 through2: 4.0.2 @@ -16631,36 +16257,32 @@ snapshots: dependencies: is-glob: 4.0.3 - glob-to-regex.js@1.2.0(tslib@2.8.1): - dependencies: - tslib: 2.8.1 - glob-to-regexp@0.4.1: {} - glob@10.5.0: + glob@10.4.5: dependencies: foreground-child: 3.3.1 jackspeak: 3.4.3 - minimatch: 9.0.9 - minipass: 7.1.3 + minimatch: 9.0.5 + minipass: 7.1.2 package-json-from-dist: 1.0.1 path-scurry: 1.11.1 - glob@11.1.0: + glob@11.0.3: dependencies: foreground-child: 3.3.1 - jackspeak: 4.2.3 - minimatch: 10.2.5 - minipass: 7.1.3 + jackspeak: 4.1.1 + minimatch: 10.0.3 + minipass: 7.1.2 package-json-from-dist: 1.0.1 - path-scurry: 2.0.2 + path-scurry: 2.0.0 glob@7.1.7: dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.1.5 + minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 @@ -16669,7 +16291,7 @@ snapshots: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.1.5 + minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 @@ -16702,12 +16324,12 @@ snapshots: kind-of: 6.0.3 which: 1.3.1 + globals@11.12.0: {} + globals@13.24.0: dependencies: type-fest: 0.20.2 - globals@17.4.0: {} - globalthis@1.0.4: dependencies: define-properties: 1.2.1 @@ -16748,7 +16370,7 @@ snapshots: handle-thing@2.0.1: {} - handlebars@4.7.9: + handlebars@4.7.8: dependencies: minimist: 1.2.8 neo-async: 2.6.2 @@ -16781,17 +16403,14 @@ snapshots: dependencies: has-symbols: 1.1.0 - hash-base@3.0.5: + hash-base@2.0.2: dependencies: inherits: 2.0.4 - safe-buffer: 5.2.1 - hash-base@3.1.2: + hash-base@3.0.5: dependencies: inherits: 2.0.4 - readable-stream: 2.3.8 safe-buffer: 5.2.1 - to-buffer: 1.2.2 hash.js@1.1.7: dependencies: @@ -16847,17 +16466,17 @@ snapshots: he: 1.2.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.46.1 + terser: 5.43.1 - html-webpack-plugin@5.6.6(webpack@5.106.1): + html-webpack-plugin@5.6.3(webpack@5.99.9): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 - lodash: 4.18.1 + lodash: 4.17.21 pretty-error: 4.0.0 - tapable: 2.3.2 + tapable: 2.2.2 optionalDependencies: - webpack: 5.106.1(webpack-cli@6.0.1) + webpack: 5.99.9(webpack-cli@6.0.1) htmlparser2@6.1.0: dependencies: @@ -16870,6 +16489,13 @@ snapshots: http-deceiver@1.2.7: {} + http-errors@1.6.3: + dependencies: + depd: 1.1.2 + inherits: 2.0.3 + setprototypeof: 1.1.0 + statuses: 1.5.0 + http-errors@1.8.1: dependencies: depd: 1.1.2 @@ -16878,12 +16504,12 @@ snapshots: statuses: 1.5.0 toidentifier: 1.0.1 - http-errors@2.0.1: + http-errors@2.0.0: dependencies: depd: 2.0.0 inherits: 2.0.4 setprototypeof: 1.2.0 - statuses: 2.0.2 + statuses: 2.0.1 toidentifier: 1.0.1 http-parser-js@0.5.10: {} @@ -16892,26 +16518,26 @@ snapshots: dependencies: '@tootallnate/once': 1.1.2 agent-base: 6.0.2 - debug: 4.4.3 + debug: 4.4.1 transitivePeerDependencies: - supports-color - http-proxy-middleware@2.0.9(@types/express@4.17.25): + http-proxy-middleware@2.0.9(@types/express@4.17.23): dependencies: - '@types/http-proxy': 1.17.17 + '@types/http-proxy': 1.17.16 http-proxy: 1.18.1 is-glob: 4.0.3 is-plain-obj: 3.0.0 micromatch: 4.0.8 optionalDependencies: - '@types/express': 4.17.25 + '@types/express': 4.17.23 transitivePeerDependencies: - debug http-proxy@1.18.1: dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.11 + follow-redirects: 1.15.9 requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -16924,11 +16550,11 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.4.3 + debug: 4.4.1 transitivePeerDependencies: - supports-color - human-id@4.1.3: {} + human-id@4.1.1: {} human-signals@2.1.0: {} @@ -16946,13 +16572,9 @@ snapshots: dependencies: safer-buffer: 2.1.2 - iconv-lite@0.7.2: + icss-utils@5.1.0(postcss@8.5.6): dependencies: - safer-buffer: 2.1.2 - - icss-utils@5.1.0(postcss@8.5.9): - dependencies: - postcss: 8.5.9 + postcss: 8.5.6 idb@7.1.1: {} @@ -16976,7 +16598,7 @@ snapshots: pkg-dir: 4.2.0 resolve-cwd: 3.0.0 - import-meta-resolve@4.2.0: + import-meta-resolve@4.1.0: optional: true imurmurhash@0.1.4: {} @@ -16988,6 +16610,8 @@ snapshots: once: 1.4.0 wrappy: 1.0.2 + inherits@2.0.3: {} + inherits@2.0.4: {} ini@1.3.8: {} @@ -17013,15 +16637,15 @@ snapshots: through: 2.3.8 wrap-ansi: 7.0.0 - inquirer@8.2.7(@types/node@24.3.0): + inquirer@8.2.6: dependencies: - '@inquirer/external-editor': 1.0.3(@types/node@24.3.0) ansi-escapes: 4.3.2 chalk: 4.1.2 cli-cursor: 3.1.0 cli-width: 3.0.0 + external-editor: 3.1.0 figures: 3.2.0 - lodash: 4.18.1 + lodash: 4.17.21 mute-stream: 0.0.8 ora: 5.4.1 run-async: 2.4.1 @@ -17030,8 +16654,6 @@ snapshots: strip-ansi: 6.0.1 through: 2.3.8 wrap-ansi: 6.2.0 - transitivePeerDependencies: - - '@types/node' internal-slot@1.1.0: dependencies: @@ -17043,7 +16665,7 @@ snapshots: ipaddr.js@1.9.1: {} - ipaddr.js@2.3.0: {} + ipaddr.js@2.2.0: {} is-arguments@1.2.0: dependencies: @@ -17052,12 +16674,15 @@ snapshots: is-array-buffer@3.0.5: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 call-bound: 1.0.4 get-intrinsic: 1.3.0 is-arrayish@0.2.1: {} + is-arrayish@0.3.2: + optional: true + is-async-function@2.1.1: dependencies: async-function: 1.0.0 @@ -17081,7 +16706,7 @@ snapshots: is-bun-module@2.0.0: dependencies: - semver: 7.7.4 + semver: 7.7.2 is-callable@1.2.7: {} @@ -17114,10 +16739,9 @@ snapshots: is-generator-fn@2.1.0: {} - is-generator-function@1.1.2: + is-generator-function@1.1.0: dependencies: call-bound: 1.0.4 - generator-function: 2.0.1 get-proto: 1.0.1 has-tostringtag: 1.0.2 safe-regex-test: 1.1.0 @@ -17138,7 +16762,7 @@ snapshots: is-negative-zero@2.0.3: {} - is-network-error@1.3.1: {} + is-network-error@1.1.0: {} is-number-object@1.1.1: dependencies: @@ -17209,7 +16833,7 @@ snapshots: is-typed-array@1.1.15: dependencies: - which-typed-array: 1.1.20 + which-typed-array: 1.1.19 is-typedarray@1.0.0: {} @@ -17234,7 +16858,7 @@ snapshots: dependencies: is-docker: 2.2.1 - is-wsl@3.1.1: + is-wsl@3.1.0: dependencies: is-inside-container: 1.0.0 @@ -17246,16 +16870,16 @@ snapshots: isobject@3.0.1: {} - isomorphic-ws@4.0.1(ws@7.5.10(bufferutil@4.1.0)(utf-8-validate@6.0.6)): + isomorphic-ws@4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)): dependencies: - ws: 7.5.10(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) istanbul-lib-coverage@3.2.2: {} istanbul-lib-instrument@5.2.1: dependencies: - '@babel/core': 7.29.0 - '@babel/parser': 7.29.2 + '@babel/core': 7.27.4 + '@babel/parser': 7.27.5 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -17270,7 +16894,7 @@ snapshots: istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.4.3 + debug: 4.4.1 istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -17278,13 +16902,13 @@ snapshots: istanbul-lib-source-maps@5.0.6: dependencies: - '@jridgewell/trace-mapping': 0.3.31 - debug: 4.4.3 + '@jridgewell/trace-mapping': 0.3.25 + debug: 4.4.1 istanbul-lib-coverage: 3.2.2 transitivePeerDependencies: - supports-color - istanbul-reports@3.2.0: + istanbul-reports@3.1.7: dependencies: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 @@ -17304,17 +16928,18 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 - jackspeak@4.2.3: + jackspeak@4.1.1: dependencies: - '@isaacs/cliui': 9.0.0 + '@isaacs/cliui': 8.0.2 - jake@10.9.4: + jake@10.9.2: dependencies: async: 3.2.6 - filelist: 1.0.6 - picocolors: 1.1.1 + chalk: 4.1.2 + filelist: 1.0.4 + minimatch: 3.1.2 - jayson@4.3.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + jayson@4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@types/connect': 3.4.38 '@types/node': 12.20.55 @@ -17323,11 +16948,11 @@ snapshots: delay: 5.0.0 es6-promisify: 5.0.0 eyes: 0.1.8 - isomorphic-ws: 4.0.1(ws@7.5.10(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + isomorphic-ws: 4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) json-stringify-safe: 5.0.1 stream-json: 1.9.1 uuid: 8.3.2 - ws: 7.5.10(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -17362,16 +16987,16 @@ snapshots: transitivePeerDependencies: - supports-color - jest-cli@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)): + jest-cli@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(utf-8-validate@5.0.10): dependencies: - '@jest/core': 27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)) + '@jest/core': 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(utf-8-validate@5.0.10) '@jest/test-result': 27.5.1 '@jest/types': 27.5.1 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 import-local: 3.2.0 - jest-config: 27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)) + jest-config: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(utf-8-validate@5.0.10) jest-util: 27.5.1 jest-validate: 27.5.1 prompts: 2.4.2 @@ -17383,25 +17008,25 @@ snapshots: - ts-node - utf-8-validate - jest-config@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)): + jest-config@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(utf-8-validate@5.0.10): dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.27.4 '@jest/test-sequencer': 27.5.1 '@jest/types': 27.5.1 - babel-jest: 27.5.1(@babel/core@7.29.0) + babel-jest: 27.5.1(@babel/core@7.27.4) chalk: 4.1.2 ci-info: 3.9.0 deepmerge: 4.3.1 glob: 7.2.3 graceful-fs: 4.2.11 jest-circus: 27.5.1 - jest-environment-jsdom: 27.5.1(bufferutil@4.1.0) + jest-environment-jsdom: 27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) jest-environment-node: 27.5.1 jest-get-type: 27.5.1 jest-jasmine2: 27.5.1 jest-regex-util: 27.5.1 jest-resolve: 27.5.1 - jest-runner: 27.5.1(bufferutil@4.1.0) + jest-runner: 27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) jest-util: 27.5.1 jest-validate: 27.5.1 micromatch: 4.0.8 @@ -17410,7 +17035,7 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - ts-node: 10.9.2(@types/node@24.3.0)(typescript@5.9.3) + ts-node: 10.9.2(@types/node@24.3.0)(typescript@5.8.3) transitivePeerDependencies: - bufferutil - canvas @@ -17436,7 +17061,7 @@ snapshots: jest-util: 27.5.1 pretty-format: 27.5.1 - jest-environment-jsdom@27.5.1(bufferutil@4.1.0): + jest-environment-jsdom@27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@jest/environment': 27.5.1 '@jest/fake-timers': 27.5.1 @@ -17444,7 +17069,7 @@ snapshots: '@types/node': 24.3.0 jest-mock: 27.5.1 jest-util: 27.5.1 - jsdom: 16.7.0(bufferutil@4.1.0) + jsdom: 16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - canvas @@ -17515,7 +17140,7 @@ snapshots: jest-message-util@27.5.1: dependencies: - '@babel/code-frame': 7.29.0 + '@babel/code-frame': 7.27.1 '@jest/types': 27.5.1 '@types/stack-utils': 2.0.3 chalk: 4.1.2 @@ -17527,7 +17152,7 @@ snapshots: jest-message-util@28.1.3: dependencies: - '@babel/code-frame': 7.29.0 + '@babel/code-frame': 7.27.1 '@jest/types': 28.1.3 '@types/stack-utils': 2.0.3 chalk: 4.1.2 @@ -17567,11 +17192,11 @@ snapshots: jest-pnp-resolver: 1.2.3(jest-resolve@27.5.1) jest-util: 27.5.1 jest-validate: 27.5.1 - resolve: 1.22.11 + resolve: 1.22.10 resolve.exports: 1.1.1 slash: 3.0.0 - jest-runner@27.5.1(bufferutil@4.1.0): + jest-runner@27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@jest/console': 27.5.1 '@jest/environment': 27.5.1 @@ -17583,7 +17208,7 @@ snapshots: emittery: 0.8.1 graceful-fs: 4.2.11 jest-docblock: 27.5.1 - jest-environment-jsdom: 27.5.1(bufferutil@4.1.0) + jest-environment-jsdom: 27.5.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) jest-environment-node: 27.5.1 jest-haste-map: 27.5.1 jest-leak-detector: 27.5.1 @@ -17611,7 +17236,7 @@ snapshots: '@jest/types': 27.5.1 chalk: 4.1.2 cjs-module-lexer: 1.4.3 - collect-v8-coverage: 1.0.3 + collect-v8-coverage: 1.0.2 execa: 5.1.1 glob: 7.2.3 graceful-fs: 4.2.11 @@ -17634,16 +17259,16 @@ snapshots: jest-snapshot@27.5.1: dependencies: - '@babel/core': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 + '@babel/core': 7.27.4 + '@babel/generator': 7.27.5 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.4) + '@babel/traverse': 7.27.4 + '@babel/types': 7.27.6 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 - '@types/babel__traverse': 7.28.0 + '@types/babel__traverse': 7.20.7 '@types/prettier': 2.7.3 - babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.4) chalk: 4.1.2 expect: 27.5.1 graceful-fs: 4.2.11 @@ -17655,7 +17280,7 @@ snapshots: jest-util: 27.5.1 natural-compare: 1.4.0 pretty-format: 27.5.1 - semver: 7.7.4 + semver: 7.7.2 transitivePeerDependencies: - supports-color @@ -17666,7 +17291,7 @@ snapshots: chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 - picomatch: 2.3.2 + picomatch: 2.3.1 jest-util@28.1.3: dependencies: @@ -17675,7 +17300,7 @@ snapshots: chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 - picomatch: 2.3.2 + picomatch: 2.3.1 jest-validate@27.5.1: dependencies: @@ -17686,16 +17311,16 @@ snapshots: leven: 3.1.0 pretty-format: 27.5.1 - jest-watch-typeahead@1.1.0(jest@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3))): + jest-watch-typeahead@1.1.0(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(utf-8-validate@5.0.10)): dependencies: ansi-escapes: 4.3.2 chalk: 4.1.2 - jest: 27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)) + jest: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(utf-8-validate@5.0.10) jest-regex-util: 28.0.2 jest-watcher: 28.1.3 slash: 4.0.0 string-length: 5.0.1 - strip-ansi: 7.2.0 + strip-ansi: 7.1.0 jest-watcher@27.5.1: dependencies: @@ -17736,11 +17361,11 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jest@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)): + jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(utf-8-validate@5.0.10): dependencies: - '@jest/core': 27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)) + '@jest/core': 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(utf-8-validate@5.0.10) import-local: 3.2.0 - jest-cli: 27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)) + jest-cli: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - canvas @@ -17750,12 +17375,12 @@ snapshots: jiti@1.21.7: {} - jiti@2.6.1: + jiti@2.4.2: optional: true joycon@3.1.1: {} - js-base64@3.7.8: {} + js-base64@3.7.7: {} js-sha256@0.9.0: {} @@ -17763,38 +17388,36 @@ snapshots: js-sha512@0.8.0: {} - js-tokens@10.0.0: {} - js-tokens@4.0.0: {} js-tokens@9.0.1: {} - js-yaml@3.14.2: + js-yaml@3.14.1: dependencies: argparse: 1.0.10 esprima: 4.0.1 - js-yaml@4.1.1: + js-yaml@4.1.0: dependencies: argparse: 2.0.1 - jsdom@16.7.0(bufferutil@4.1.0): + jsdom@16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: abab: 2.0.6 - acorn: 8.16.0 + acorn: 8.15.0 acorn-globals: 6.0.0 cssom: 0.4.4 cssstyle: 2.3.0 data-urls: 2.0.0 - decimal.js: 10.6.0 + decimal.js: 10.5.0 domexception: 2.0.1 escodegen: 2.1.0 - form-data: 3.0.4 + form-data: 3.0.3 html-encoding-sniffer: 2.0.1 http-proxy-agent: 4.0.1 https-proxy-agent: 5.0.1 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.23 + nwsapi: 2.2.20 parse5: 6.0.1 saxes: 5.0.1 symbol-tree: 3.2.4 @@ -17805,18 +17428,20 @@ snapshots: whatwg-encoding: 1.0.5 whatwg-mimetype: 2.3.0 whatwg-url: 8.7.0 - ws: 7.5.10(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) xml-name-validator: 3.0.0 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate + jsesc@3.0.2: {} + jsesc@3.1.0: {} json-bigint@1.0.0: dependencies: - bignumber.js: 9.3.1 + bignumber.js: 9.3.0 json-buffer@3.0.1: {} @@ -17828,6 +17453,8 @@ snapshots: json-schema-traverse@1.0.0: {} + json-schema@0.4.0: {} + json-stable-stringify-without-jsonify@1.0.1: {} json-stringify-safe@5.0.1: {} @@ -17844,7 +17471,7 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 - jsonfile@6.2.0: + jsonfile@6.1.0: dependencies: universalify: 2.0.1 optionalDependencies: @@ -17852,16 +17479,14 @@ snapshots: jsonparse@1.3.1: {} - jsonpath@1.3.0: + jsonpath@1.1.1: dependencies: - esprima: 1.2.5 - static-eval: 2.1.1 - underscore: 1.13.6 + esprima: 1.2.2 + static-eval: 2.0.2 + underscore: 1.12.1 jsonpointer@5.0.1: {} - jsx-ast-utils-x@0.1.0: {} - jsx-ast-utils@3.3.5: dependencies: array-includes: 3.1.9 @@ -17895,7 +17520,7 @@ snapshots: dependencies: language-subtag-registry: 0.3.23 - launch-editor@2.13.2: + launch-editor@2.10.0: dependencies: picocolors: 1.1.1 shell-quote: 1.8.3 @@ -17927,7 +17552,7 @@ snapshots: load-tsconfig@0.2.5: {} - loader-runner@4.3.1: {} + loader-runner@4.3.0: {} loader-utils@2.0.4: dependencies: @@ -17955,7 +17580,7 @@ snapshots: dependencies: p-locate: 5.0.0 - lodash-es@4.18.1: {} + lodash-es@4.17.21: {} lodash.camelcase@4.3.0: {} @@ -17965,6 +17590,9 @@ snapshots: lodash.ismatch@4.4.0: {} + lodash.isplainobject@4.0.6: + optional: true + lodash.map@4.6.0: {} lodash.memoize@4.1.2: {} @@ -17984,8 +17612,6 @@ snapshots: lodash@4.17.21: {} - lodash@4.18.1: {} - log-symbols@4.1.0: dependencies: chalk: 4.1.2 @@ -17997,7 +17623,7 @@ snapshots: dependencies: js-tokens: 4.0.0 - loupe@3.2.1: {} + loupe@3.1.4: {} lower-case@2.0.2: dependencies: @@ -18007,7 +17633,7 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.3.3: {} + lru-cache@11.1.0: {} lru-cache@5.1.1: dependencies: @@ -18023,14 +17649,14 @@ snapshots: dependencies: sourcemap-codec: 1.4.8 - magic-string@0.30.21: + magic-string@0.30.17: dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/sourcemap-codec': 1.5.0 magicast@0.3.5: dependencies: - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 + '@babel/parser': 7.27.5 + '@babel/types': 7.27.6 source-map-js: 1.2.1 make-dir@3.1.0: @@ -18039,7 +17665,7 @@ snapshots: make-dir@4.0.0: dependencies: - semver: 7.7.4 + semver: 7.7.2 make-error@1.3.6: {} @@ -18069,30 +17695,17 @@ snapshots: memfs@3.5.3: dependencies: - fs-monkey: 1.1.0 - - memfs@4.57.1(tslib@2.8.1): - dependencies: - '@jsonjoy.com/fs-core': 4.57.1(tslib@2.8.1) - '@jsonjoy.com/fs-fsa': 4.57.1(tslib@2.8.1) - '@jsonjoy.com/fs-node': 4.57.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-to-fsa': 4.57.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.57.1(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.57.1(tslib@2.8.1) - '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) - '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) - glob-to-regex.js: 1.2.0(tslib@2.8.1) - thingies: 2.6.0(tslib@2.8.1) - tree-dump: 1.1.0(tslib@2.8.1) + fs-monkey: 1.0.6 + + memfs@4.24.0: + dependencies: + '@jsonjoy.com/json-pack': 1.4.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.8.0(tslib@2.8.1) + tree-dump: 1.0.3(tslib@2.8.1) tslib: 2.8.1 memorystream@0.3.1: {} - meow@13.2.0: - optional: true - meow@8.1.2: dependencies: '@types/minimist': 1.2.5 @@ -18120,11 +17733,11 @@ snapshots: micromatch@4.0.8: dependencies: braces: 3.0.3 - picomatch: 2.3.2 + picomatch: 2.3.1 miller-rabin@4.0.1: dependencies: - bn.js: 4.12.3 + bn.js: 4.12.2 brorand: 1.1.0 mime-db@1.52.0: {} @@ -18135,10 +17748,6 @@ snapshots: dependencies: mime-db: 1.52.0 - mime-types@3.0.2: - dependencies: - mime-db: 1.54.0 - mime@1.6.0: {} mimic-fn@2.1.0: {} @@ -18149,35 +17758,35 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.10.2(webpack@5.106.1): + mini-css-extract-plugin@2.9.2(webpack@5.99.9): dependencies: - schema-utils: 4.3.3 - tapable: 2.3.2 - webpack: 5.106.1(webpack-cli@6.0.1) + schema-utils: 4.3.2 + tapable: 2.2.2 + webpack: 5.99.9(webpack-cli@6.0.1) minimalistic-assert@1.0.1: {} minimalistic-crypto-utils@1.0.1: {} - minimatch@10.2.5: + minimatch@10.0.3: dependencies: - brace-expansion: 5.0.5 + '@isaacs/brace-expansion': 5.0.0 - minimatch@3.1.5: + minimatch@3.1.2: dependencies: - brace-expansion: 1.1.13 + brace-expansion: 1.1.12 - minimatch@5.1.9: + minimatch@5.1.6: dependencies: - brace-expansion: 2.0.3 + brace-expansion: 2.0.2 minimatch@9.0.3: dependencies: - brace-expansion: 2.0.3 + brace-expansion: 2.0.2 - minimatch@9.0.9: + minimatch@9.0.5: dependencies: - brace-expansion: 2.0.3 + brace-expansion: 2.0.2 minimist-options@4.1.0: dependencies: @@ -18189,7 +17798,7 @@ snapshots: minimist@1.2.8: {} - minipass@7.1.3: {} + minipass@7.1.2: {} mixme@0.5.10: {} @@ -18199,14 +17808,14 @@ snapshots: mkdirp@1.0.4: {} - modified-zod2md@0.1.5-modified.4(zod@3.25.76): + modified-zod2md@0.1.5-modified.4(zod@3.25.67): dependencies: '@commander-js/extra-typings': 12.1.0(commander@12.1.0) bundle-require: 4.2.1(esbuild@0.19.12) commander: 12.1.0 esbuild: 0.19.12 modified-zod2md: 'link:' - zod: 3.25.76 + zod: 3.25.67 modify-values@1.0.1: {} @@ -18243,7 +17852,7 @@ snapshots: nanoid@3.3.4: {} - napi-postinstall@0.3.4: {} + napi-postinstall@0.2.4: {} natural-compare-lite@1.4.0: {} @@ -18274,7 +17883,7 @@ snapshots: '@swc/counter': 0.1.3 '@swc/helpers': 0.5.15 busboy: 1.6.0 - caniuse-lite: 1.0.30001787 + caniuse-lite: 1.0.30001726 postcss: 8.4.31 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -18288,7 +17897,7 @@ snapshots: '@next/swc-linux-x64-musl': 15.3.4 '@next/swc-win32-arm64-msvc': 15.3.4 '@next/swc-win32-x64-msvc': 15.3.4 - sharp: 0.34.5 + sharp: 0.34.3 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -18304,29 +17913,22 @@ snapshots: node-addon-api@5.1.0: {} - node-exports-info@1.6.0: - dependencies: - array.prototype.flatmap: 1.3.3 - es-errors: 1.3.0 - object.entries: 1.1.9 - semver: 6.3.1 - node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 - node-forge@1.4.0: {} + node-forge@1.3.1: {} node-gyp-build@4.8.4: {} node-int64@0.4.0: {} - node-releases@2.0.37: {} + node-releases@2.0.19: {} normalize-package-data@2.5.0: dependencies: hosted-git-info: 2.8.9 - resolve: 1.22.11 + resolve: 1.22.10 semver: 5.7.2 validate-npm-package-license: 3.0.4 @@ -18334,11 +17936,13 @@ snapshots: dependencies: hosted-git-info: 4.1.0 is-core-module: 2.16.1 - semver: 7.7.4 + semver: 7.7.2 validate-npm-package-license: 3.0.4 normalize-path@3.0.0: {} + normalize-range@0.1.2: {} + normalize-url@6.1.0: {} npm-run-all@4.1.5: @@ -18347,7 +17951,7 @@ snapshots: chalk: 2.4.2 cross-spawn: 6.0.6 memorystream: 0.3.1 - minimatch: 3.1.5 + minimatch: 3.1.2 pidtree: 0.3.1 read-pkg: 3.0.0 shell-quote: 1.8.3 @@ -18361,11 +17965,7 @@ snapshots: dependencies: boolbase: 1.0.0 - nth-check@3.0.1: - dependencies: - boolbase: 2.0.0 - - nwsapi@2.2.23: {} + nwsapi@2.2.20: {} object-assign@4.1.1: {} @@ -18375,14 +17975,14 @@ snapshots: object-is@1.1.6: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 define-properties: 1.2.1 object-keys@1.1.1: {} object.assign@4.1.7: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 call-bound: 1.0.4 define-properties: 1.2.1 es-object-atoms: 1.1.1 @@ -18391,37 +17991,37 @@ snapshots: object.entries@1.1.9: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 call-bound: 1.0.4 define-properties: 1.2.1 es-object-atoms: 1.1.1 object.fromentries@2.0.8: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.24.2 + es-abstract: 1.24.0 es-object-atoms: 1.1.1 - object.getownpropertydescriptors@2.1.9: + object.getownpropertydescriptors@2.1.8: dependencies: array.prototype.reduce: 1.0.8 - call-bind: 1.0.9 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.24.2 + es-abstract: 1.24.0 es-object-atoms: 1.1.1 gopd: 1.2.0 safe-array-concat: 1.1.3 object.groupby@1.0.3: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.24.2 + es-abstract: 1.24.0 object.values@1.2.1: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 call-bound: 1.0.4 define-properties: 1.2.1 es-object-atoms: 1.1.1 @@ -18432,7 +18032,7 @@ snapshots: dependencies: ee-first: 1.1.1 - on-headers@1.1.0: {} + on-headers@1.0.2: {} once@1.4.0: dependencies: @@ -18444,7 +18044,7 @@ snapshots: open@10.2.0: dependencies: - default-browser: 5.5.0 + default-browser: 5.2.1 define-lazy-prop: 3.0.0 is-inside-container: 1.0.0 wsl-utils: 0.1.0 @@ -18539,7 +18139,7 @@ snapshots: p-retry@6.2.1: dependencies: '@types/retry': 0.12.2 - is-network-error: 1.3.1 + is-network-error: 1.1.0 retry: 0.13.1 p-try@1.0.0: {} @@ -18550,7 +18150,7 @@ snapshots: package-manager-detector@0.2.11: dependencies: - quansync: 0.2.11 + quansync: 0.2.10 param-case@3.0.4: dependencies: @@ -18561,23 +18161,24 @@ snapshots: dependencies: callsites: 3.1.0 - parse-asn1@5.1.9: + parse-asn1@5.1.7: dependencies: asn1.js: 4.10.1 browserify-aes: 1.2.0 evp_bytestokey: 1.0.3 - pbkdf2: 3.1.5 + hash-base: 3.0.5 + pbkdf2: 3.1.3 safe-buffer: 5.2.1 parse-json@4.0.0: dependencies: - error-ex: 1.3.4 + error-ex: 1.3.2 json-parse-better-errors: 1.0.2 parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.29.0 - error-ex: 1.3.4 + '@babel/code-frame': 7.27.1 + error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -18607,14 +18208,14 @@ snapshots: path-scurry@1.11.1: dependencies: lru-cache: 10.4.3 - minipass: 7.1.3 + minipass: 7.1.2 - path-scurry@2.0.2: + path-scurry@2.0.0: dependencies: - lru-cache: 11.3.3 - minipass: 7.1.3 + lru-cache: 11.1.0 + minipass: 7.1.2 - path-to-regexp@0.1.13: {} + path-to-regexp@0.1.12: {} path-to-regexp@2.4.0: {} @@ -18628,14 +18229,14 @@ snapshots: pathval@2.0.1: {} - pbkdf2@3.1.5: + pbkdf2@3.1.3: dependencies: - create-hash: 1.2.0 + create-hash: 1.1.3 create-hmac: 1.1.7 - ripemd160: 2.0.3 + ripemd160: 2.0.1 safe-buffer: 5.2.1 - sha.js: 2.4.12 - to-buffer: 1.2.2 + sha.js: 2.4.11 + to-buffer: 1.2.1 performance-now@2.1.0: {} @@ -18643,9 +18244,9 @@ snapshots: picocolors@1.1.1: {} - picomatch@2.3.2: {} + picomatch@2.3.1: {} - picomatch@4.0.4: {} + picomatch@4.0.2: {} pidtree@0.3.1: {} @@ -18665,412 +18266,404 @@ snapshots: dependencies: find-up: 3.0.0 - pkijs@3.4.0: - dependencies: - '@noble/hashes': 1.4.0 - asn1js: 3.0.7 - bytestreamjs: 2.0.1 - pvtsutils: 1.3.6 - pvutils: 1.1.5 - tslib: 2.8.1 - poseidon-lite@0.2.1: {} possible-typed-array-names@1.1.0: {} - postcss-attribute-case-insensitive@5.0.2(postcss@8.5.9): + postcss-attribute-case-insensitive@5.0.2(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-selector-parser: 6.1.2 - postcss-browser-comments@4.0.0(browserslist@4.28.2)(postcss@8.5.9): + postcss-browser-comments@4.0.0(browserslist@4.25.1)(postcss@8.5.6): dependencies: - browserslist: 4.28.2 - postcss: 8.5.9 + browserslist: 4.25.1 + postcss: 8.5.6 - postcss-calc@8.2.4(postcss@8.5.9): + postcss-calc@8.2.4(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-selector-parser: 6.1.2 postcss-value-parser: 4.2.0 - postcss-clamp@4.1.0(postcss@8.5.9): + postcss-clamp@4.1.0(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-color-functional-notation@4.2.4(postcss@8.5.9): + postcss-color-functional-notation@4.2.4(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-color-hex-alpha@8.0.4(postcss@8.5.9): + postcss-color-hex-alpha@8.0.4(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-color-rebeccapurple@7.1.1(postcss@8.5.9): + postcss-color-rebeccapurple@7.1.1(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-colormin@5.3.1(postcss@8.5.9): + postcss-colormin@5.3.1(postcss@8.5.6): dependencies: - browserslist: 4.28.2 + browserslist: 4.25.1 caniuse-api: 3.0.0 colord: 2.9.3 - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-convert-values@5.1.3(postcss@8.5.9): + postcss-convert-values@5.1.3(postcss@8.5.6): dependencies: - browserslist: 4.28.2 - postcss: 8.5.9 + browserslist: 4.25.1 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-custom-media@8.0.2(postcss@8.5.9): + postcss-custom-media@8.0.2(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-custom-properties@12.1.11(postcss@8.5.9): + postcss-custom-properties@12.1.11(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-custom-selectors@6.0.3(postcss@8.5.9): + postcss-custom-selectors@6.0.3(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-selector-parser: 6.1.2 - postcss-dir-pseudo-class@6.0.5(postcss@8.5.9): + postcss-dir-pseudo-class@6.0.5(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-selector-parser: 6.1.2 - postcss-discard-comments@5.1.2(postcss@8.5.9): + postcss-discard-comments@5.1.2(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 - postcss-discard-duplicates@5.1.0(postcss@8.5.9): + postcss-discard-duplicates@5.1.0(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 - postcss-discard-empty@5.1.1(postcss@8.5.9): + postcss-discard-empty@5.1.1(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 - postcss-discard-overridden@5.1.0(postcss@8.5.9): + postcss-discard-overridden@5.1.0(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 - postcss-double-position-gradients@3.1.2(postcss@8.5.9): + postcss-double-position-gradients@3.1.2(postcss@8.5.6): dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.9) - postcss: 8.5.9 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.6) + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-env-function@4.0.6(postcss@8.5.9): + postcss-env-function@4.0.6(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-flexbugs-fixes@5.0.2(postcss@8.5.9): + postcss-flexbugs-fixes@5.0.2(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 - postcss-focus-visible@6.0.4(postcss@8.5.9): + postcss-focus-visible@6.0.4(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-selector-parser: 6.1.2 - postcss-focus-within@5.0.4(postcss@8.5.9): + postcss-focus-within@5.0.4(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-selector-parser: 6.1.2 - postcss-font-variant@5.0.0(postcss@8.5.9): + postcss-font-variant@5.0.0(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 - postcss-gap-properties@3.0.5(postcss@8.5.9): + postcss-gap-properties@3.0.5(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 - postcss-image-set-function@4.0.7(postcss@8.5.9): + postcss-image-set-function@4.0.7(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-import@15.1.0(postcss@8.5.9): + postcss-import@15.1.0(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 read-cache: 1.0.0 - resolve: 1.22.11 + resolve: 1.22.10 - postcss-initial@4.0.1(postcss@8.5.9): + postcss-initial@4.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 - postcss-js@4.1.0(postcss@8.5.9): + postcss-js@4.0.1(postcss@8.5.6): dependencies: camelcase-css: 2.0.1 - postcss: 8.5.9 + postcss: 8.5.6 - postcss-lab-function@4.2.1(postcss@8.5.9): + postcss-lab-function@4.2.1(postcss@8.5.6): dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.9) - postcss: 8.5.9 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.6) + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.9): + postcss-load-config@4.0.2(postcss@8.5.6)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3)): dependencies: lilconfig: 3.1.3 + yaml: 2.8.0 optionalDependencies: - jiti: 1.21.7 - postcss: 8.5.9 + postcss: 8.5.6 + ts-node: 10.9.2(@types/node@24.3.0)(typescript@5.8.3) - postcss-loader@6.2.1(postcss@8.5.9)(webpack@5.106.1): + postcss-loader@6.2.1(postcss@8.5.6)(webpack@5.99.9): dependencies: cosmiconfig: 7.1.0 klona: 2.0.6 - postcss: 8.5.9 - semver: 7.7.4 - webpack: 5.106.1(webpack-cli@6.0.1) + postcss: 8.5.6 + semver: 7.7.2 + webpack: 5.99.9(webpack-cli@6.0.1) - postcss-logical@5.0.4(postcss@8.5.9): + postcss-logical@5.0.4(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 - postcss-media-minmax@5.0.0(postcss@8.5.9): + postcss-media-minmax@5.0.0(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 - postcss-merge-longhand@5.1.7(postcss@8.5.9): + postcss-merge-longhand@5.1.7(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - stylehacks: 5.1.1(postcss@8.5.9) + stylehacks: 5.1.1(postcss@8.5.6) - postcss-merge-rules@5.1.4(postcss@8.5.9): + postcss-merge-rules@5.1.4(postcss@8.5.6): dependencies: - browserslist: 4.28.2 + browserslist: 4.25.1 caniuse-api: 3.0.0 - cssnano-utils: 3.1.0(postcss@8.5.9) - postcss: 8.5.9 + cssnano-utils: 3.1.0(postcss@8.5.6) + postcss: 8.5.6 postcss-selector-parser: 6.1.2 - postcss-minify-font-values@5.1.0(postcss@8.5.9): + postcss-minify-font-values@5.1.0(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-minify-gradients@5.1.1(postcss@8.5.9): + postcss-minify-gradients@5.1.1(postcss@8.5.6): dependencies: colord: 2.9.3 - cssnano-utils: 3.1.0(postcss@8.5.9) - postcss: 8.5.9 + cssnano-utils: 3.1.0(postcss@8.5.6) + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-minify-params@5.1.4(postcss@8.5.9): + postcss-minify-params@5.1.4(postcss@8.5.6): dependencies: - browserslist: 4.28.2 - cssnano-utils: 3.1.0(postcss@8.5.9) - postcss: 8.5.9 + browserslist: 4.25.1 + cssnano-utils: 3.1.0(postcss@8.5.6) + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-minify-selectors@5.2.1(postcss@8.5.9): + postcss-minify-selectors@5.2.1(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-selector-parser: 6.1.2 - postcss-modules-extract-imports@3.1.0(postcss@8.5.9): + postcss-modules-extract-imports@3.1.0(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 - postcss-modules-local-by-default@4.2.0(postcss@8.5.9): + postcss-modules-local-by-default@4.2.0(postcss@8.5.6): dependencies: - icss-utils: 5.1.0(postcss@8.5.9) - postcss: 8.5.9 - postcss-selector-parser: 7.1.1 + icss-utils: 5.1.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 postcss-value-parser: 4.2.0 - postcss-modules-scope@3.2.1(postcss@8.5.9): + postcss-modules-scope@3.2.1(postcss@8.5.6): dependencies: - postcss: 8.5.9 - postcss-selector-parser: 7.1.1 + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 - postcss-modules-values@4.0.0(postcss@8.5.9): + postcss-modules-values@4.0.0(postcss@8.5.6): dependencies: - icss-utils: 5.1.0(postcss@8.5.9) - postcss: 8.5.9 + icss-utils: 5.1.0(postcss@8.5.6) + postcss: 8.5.6 - postcss-nested@6.2.0(postcss@8.5.9): + postcss-nested@6.2.0(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-selector-parser: 6.1.2 - postcss-nesting@10.2.0(postcss@8.5.9): + postcss-nesting@10.2.0(postcss@8.5.6): dependencies: '@csstools/selector-specificity': 2.2.0(postcss-selector-parser@6.1.2) - postcss: 8.5.9 + postcss: 8.5.6 postcss-selector-parser: 6.1.2 - postcss-normalize-charset@5.1.0(postcss@8.5.9): + postcss-normalize-charset@5.1.0(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 - postcss-normalize-display-values@5.1.0(postcss@8.5.9): + postcss-normalize-display-values@5.1.0(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-positions@5.1.1(postcss@8.5.9): + postcss-normalize-positions@5.1.1(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-repeat-style@5.1.1(postcss@8.5.9): + postcss-normalize-repeat-style@5.1.1(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-string@5.1.0(postcss@8.5.9): + postcss-normalize-string@5.1.0(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-timing-functions@5.1.0(postcss@8.5.9): + postcss-normalize-timing-functions@5.1.0(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-unicode@5.1.1(postcss@8.5.9): + postcss-normalize-unicode@5.1.1(postcss@8.5.6): dependencies: - browserslist: 4.28.2 - postcss: 8.5.9 + browserslist: 4.25.1 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-url@5.1.0(postcss@8.5.9): + postcss-normalize-url@5.1.0(postcss@8.5.6): dependencies: normalize-url: 6.1.0 - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-whitespace@5.1.1(postcss@8.5.9): + postcss-normalize-whitespace@5.1.1(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize@10.0.1(browserslist@4.28.2)(postcss@8.5.9): + postcss-normalize@10.0.1(browserslist@4.25.1)(postcss@8.5.6): dependencies: '@csstools/normalize.css': 12.1.1 - browserslist: 4.28.2 - postcss: 8.5.9 - postcss-browser-comments: 4.0.0(browserslist@4.28.2)(postcss@8.5.9) + browserslist: 4.25.1 + postcss: 8.5.6 + postcss-browser-comments: 4.0.0(browserslist@4.25.1)(postcss@8.5.6) sanitize.css: 13.0.0 - postcss-opacity-percentage@1.1.3(postcss@8.5.9): + postcss-opacity-percentage@1.1.3(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 - postcss-ordered-values@5.1.3(postcss@8.5.9): + postcss-ordered-values@5.1.3(postcss@8.5.6): dependencies: - cssnano-utils: 3.1.0(postcss@8.5.9) - postcss: 8.5.9 + cssnano-utils: 3.1.0(postcss@8.5.6) + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-overflow-shorthand@3.0.4(postcss@8.5.9): + postcss-overflow-shorthand@3.0.4(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-page-break@3.0.4(postcss@8.5.9): + postcss-page-break@3.0.4(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 - postcss-place@7.0.5(postcss@8.5.9): + postcss-place@7.0.5(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-preset-env@7.8.3(postcss@8.5.9): - dependencies: - '@csstools/postcss-cascade-layers': 1.1.1(postcss@8.5.9) - '@csstools/postcss-color-function': 1.1.1(postcss@8.5.9) - '@csstools/postcss-font-format-keywords': 1.0.1(postcss@8.5.9) - '@csstools/postcss-hwb-function': 1.0.2(postcss@8.5.9) - '@csstools/postcss-ic-unit': 1.0.1(postcss@8.5.9) - '@csstools/postcss-is-pseudo-class': 2.0.7(postcss@8.5.9) - '@csstools/postcss-nested-calc': 1.0.0(postcss@8.5.9) - '@csstools/postcss-normalize-display-values': 1.0.1(postcss@8.5.9) - '@csstools/postcss-oklab-function': 1.1.1(postcss@8.5.9) - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.9) - '@csstools/postcss-stepped-value-functions': 1.0.1(postcss@8.5.9) - '@csstools/postcss-text-decoration-shorthand': 1.0.0(postcss@8.5.9) - '@csstools/postcss-trigonometric-functions': 1.0.2(postcss@8.5.9) - '@csstools/postcss-unset-value': 1.0.2(postcss@8.5.9) - autoprefixer: 10.4.27(postcss@8.5.9) - browserslist: 4.28.2 - css-blank-pseudo: 3.0.3(postcss@8.5.9) - css-has-pseudo: 3.0.4(postcss@8.5.9) - css-prefers-color-scheme: 6.0.3(postcss@8.5.9) + postcss-preset-env@7.8.3(postcss@8.5.6): + dependencies: + '@csstools/postcss-cascade-layers': 1.1.1(postcss@8.5.6) + '@csstools/postcss-color-function': 1.1.1(postcss@8.5.6) + '@csstools/postcss-font-format-keywords': 1.0.1(postcss@8.5.6) + '@csstools/postcss-hwb-function': 1.0.2(postcss@8.5.6) + '@csstools/postcss-ic-unit': 1.0.1(postcss@8.5.6) + '@csstools/postcss-is-pseudo-class': 2.0.7(postcss@8.5.6) + '@csstools/postcss-nested-calc': 1.0.0(postcss@8.5.6) + '@csstools/postcss-normalize-display-values': 1.0.1(postcss@8.5.6) + '@csstools/postcss-oklab-function': 1.1.1(postcss@8.5.6) + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.6) + '@csstools/postcss-stepped-value-functions': 1.0.1(postcss@8.5.6) + '@csstools/postcss-text-decoration-shorthand': 1.0.0(postcss@8.5.6) + '@csstools/postcss-trigonometric-functions': 1.0.2(postcss@8.5.6) + '@csstools/postcss-unset-value': 1.0.2(postcss@8.5.6) + autoprefixer: 10.4.21(postcss@8.5.6) + browserslist: 4.25.1 + css-blank-pseudo: 3.0.3(postcss@8.5.6) + css-has-pseudo: 3.0.4(postcss@8.5.6) + css-prefers-color-scheme: 6.0.3(postcss@8.5.6) cssdb: 7.11.2 - postcss: 8.5.9 - postcss-attribute-case-insensitive: 5.0.2(postcss@8.5.9) - postcss-clamp: 4.1.0(postcss@8.5.9) - postcss-color-functional-notation: 4.2.4(postcss@8.5.9) - postcss-color-hex-alpha: 8.0.4(postcss@8.5.9) - postcss-color-rebeccapurple: 7.1.1(postcss@8.5.9) - postcss-custom-media: 8.0.2(postcss@8.5.9) - postcss-custom-properties: 12.1.11(postcss@8.5.9) - postcss-custom-selectors: 6.0.3(postcss@8.5.9) - postcss-dir-pseudo-class: 6.0.5(postcss@8.5.9) - postcss-double-position-gradients: 3.1.2(postcss@8.5.9) - postcss-env-function: 4.0.6(postcss@8.5.9) - postcss-focus-visible: 6.0.4(postcss@8.5.9) - postcss-focus-within: 5.0.4(postcss@8.5.9) - postcss-font-variant: 5.0.0(postcss@8.5.9) - postcss-gap-properties: 3.0.5(postcss@8.5.9) - postcss-image-set-function: 4.0.7(postcss@8.5.9) - postcss-initial: 4.0.1(postcss@8.5.9) - postcss-lab-function: 4.2.1(postcss@8.5.9) - postcss-logical: 5.0.4(postcss@8.5.9) - postcss-media-minmax: 5.0.0(postcss@8.5.9) - postcss-nesting: 10.2.0(postcss@8.5.9) - postcss-opacity-percentage: 1.1.3(postcss@8.5.9) - postcss-overflow-shorthand: 3.0.4(postcss@8.5.9) - postcss-page-break: 3.0.4(postcss@8.5.9) - postcss-place: 7.0.5(postcss@8.5.9) - postcss-pseudo-class-any-link: 7.1.6(postcss@8.5.9) - postcss-replace-overflow-wrap: 4.0.0(postcss@8.5.9) - postcss-selector-not: 6.0.1(postcss@8.5.9) + postcss: 8.5.6 + postcss-attribute-case-insensitive: 5.0.2(postcss@8.5.6) + postcss-clamp: 4.1.0(postcss@8.5.6) + postcss-color-functional-notation: 4.2.4(postcss@8.5.6) + postcss-color-hex-alpha: 8.0.4(postcss@8.5.6) + postcss-color-rebeccapurple: 7.1.1(postcss@8.5.6) + postcss-custom-media: 8.0.2(postcss@8.5.6) + postcss-custom-properties: 12.1.11(postcss@8.5.6) + postcss-custom-selectors: 6.0.3(postcss@8.5.6) + postcss-dir-pseudo-class: 6.0.5(postcss@8.5.6) + postcss-double-position-gradients: 3.1.2(postcss@8.5.6) + postcss-env-function: 4.0.6(postcss@8.5.6) + postcss-focus-visible: 6.0.4(postcss@8.5.6) + postcss-focus-within: 5.0.4(postcss@8.5.6) + postcss-font-variant: 5.0.0(postcss@8.5.6) + postcss-gap-properties: 3.0.5(postcss@8.5.6) + postcss-image-set-function: 4.0.7(postcss@8.5.6) + postcss-initial: 4.0.1(postcss@8.5.6) + postcss-lab-function: 4.2.1(postcss@8.5.6) + postcss-logical: 5.0.4(postcss@8.5.6) + postcss-media-minmax: 5.0.0(postcss@8.5.6) + postcss-nesting: 10.2.0(postcss@8.5.6) + postcss-opacity-percentage: 1.1.3(postcss@8.5.6) + postcss-overflow-shorthand: 3.0.4(postcss@8.5.6) + postcss-page-break: 3.0.4(postcss@8.5.6) + postcss-place: 7.0.5(postcss@8.5.6) + postcss-pseudo-class-any-link: 7.1.6(postcss@8.5.6) + postcss-replace-overflow-wrap: 4.0.0(postcss@8.5.6) + postcss-selector-not: 6.0.1(postcss@8.5.6) postcss-value-parser: 4.2.0 - postcss-pseudo-class-any-link@7.1.6(postcss@8.5.9): + postcss-pseudo-class-any-link@7.1.6(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-selector-parser: 6.1.2 - postcss-reduce-initial@5.1.2(postcss@8.5.9): + postcss-reduce-initial@5.1.2(postcss@8.5.6): dependencies: - browserslist: 4.28.2 + browserslist: 4.25.1 caniuse-api: 3.0.0 - postcss: 8.5.9 + postcss: 8.5.6 - postcss-reduce-transforms@5.1.0(postcss@8.5.9): + postcss-reduce-transforms@5.1.0(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-replace-overflow-wrap@4.0.0(postcss@8.5.9): + postcss-replace-overflow-wrap@4.0.0(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 - postcss-selector-not@6.0.1(postcss@8.5.9): + postcss-selector-not@6.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-selector-parser: 6.1.2 postcss-selector-parser@6.1.2: @@ -19078,20 +18671,20 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-selector-parser@7.1.1: + postcss-selector-parser@7.1.0: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-svgo@5.1.0(postcss@8.5.9): + postcss-svgo@5.1.0(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - svgo: 2.8.2 + svgo: 2.8.0 - postcss-unique-selectors@5.1.1(postcss@8.5.9): + postcss-unique-selectors@5.1.1(postcss@8.5.6): dependencies: - postcss: 8.5.9 + postcss: 8.5.6 postcss-selector-parser: 6.1.2 postcss-value-parser@4.2.0: {} @@ -19107,7 +18700,7 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - postcss@8.5.9: + postcss@8.5.6: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 @@ -19117,20 +18710,20 @@ snapshots: prelude-ls@1.2.1: {} - prettier-plugin-organize-imports@3.2.4(prettier@3.8.2)(typescript@5.9.3): + prettier-plugin-organize-imports@3.2.4(prettier@3.6.1)(typescript@5.8.3): dependencies: - prettier: 3.8.2 - typescript: 5.9.3 + prettier: 3.6.1 + typescript: 5.8.3 prettier@2.8.8: {} - prettier@3.8.2: {} + prettier@3.6.1: {} pretty-bytes@5.6.0: {} pretty-error@4.0.0: dependencies: - lodash: 4.18.1 + lodash: 4.17.21 renderkid: 3.0.0 pretty-format@27.5.1: @@ -19172,6 +18765,8 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 + proxy-from-env@1.1.0: {} + proxy-from-env@2.1.0: {} psl@1.15.0: @@ -19180,37 +18775,31 @@ snapshots: public-encrypt@4.0.3: dependencies: - bn.js: 4.12.3 + bn.js: 4.12.2 browserify-rsa: 4.1.1 create-hash: 1.2.0 - parse-asn1: 5.1.9 + parse-asn1: 5.1.7 randombytes: 2.1.0 safe-buffer: 5.2.1 - pump@3.0.4: + pump@3.0.3: dependencies: end-of-stream: 1.4.5 once: 1.4.0 punycode@2.3.1: {} - pvtsutils@1.3.6: - dependencies: - tslib: 2.8.1 - - pvutils@1.1.5: {} - q@1.5.1: {} - qs@6.14.2: + qs@6.13.0: dependencies: side-channel: 1.1.0 - qs@6.15.1: + qs@6.14.0: dependencies: side-channel: 1.1.0 - quansync@0.2.11: {} + quansync@0.2.10: {} querystring@0.2.1: {} @@ -19237,40 +18826,40 @@ snapshots: range-parser@1.2.1: {} - raw-body@2.5.3: + raw-body@2.5.2: dependencies: bytes: 3.1.2 - http-errors: 2.0.1 + http-errors: 2.0.0 iconv-lite: 0.4.24 unpipe: 1.0.0 react-app-polyfill@3.0.0: dependencies: - core-js: 3.49.0 + core-js: 3.43.0 object-assign: 4.1.1 promise: 8.3.0 raf: 3.4.1 regenerator-runtime: 0.13.11 whatwg-fetch: 3.6.20 - react-copy-to-clipboard@5.1.1(react@18.3.1): + react-copy-to-clipboard@5.1.0(react@18.3.1): dependencies: copy-to-clipboard: 3.3.3 prop-types: 15.8.1 react: 18.3.1 - react-dev-utils@12.0.1(eslint@8.57.1)(typescript@5.9.3)(webpack@5.106.1): + react-dev-utils@12.0.1(eslint@8.57.1)(typescript@5.8.3)(webpack@5.99.9): dependencies: - '@babel/code-frame': 7.29.0 + '@babel/code-frame': 7.27.1 address: 1.2.2 - browserslist: 4.28.2 + browserslist: 4.25.1 chalk: 4.1.2 cross-spawn: 7.0.6 detect-port-alt: 1.1.6 escape-string-regexp: 4.0.0 filesize: 8.0.7 find-up: 5.0.0 - fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.1)(typescript@5.9.3)(webpack@5.106.1) + fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.1)(typescript@5.8.3)(webpack@5.99.9) global-modules: 2.0.0 globby: 11.1.0 gzip-size: 6.0.0 @@ -19285,9 +18874,9 @@ snapshots: shell-quote: 1.8.3 strip-ansi: 6.0.1 text-table: 0.2.0 - webpack: 5.106.1(webpack-cli@6.0.1) + webpack: 5.99.9(webpack-cli@6.0.1) optionalDependencies: - typescript: 5.9.3 + typescript: 5.8.3 transitivePeerDependencies: - eslint - supports-color @@ -19311,59 +18900,59 @@ snapshots: react-refresh@0.17.0: {} - react-scripts@5.0.1(@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0))(@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0))(@types/babel__core@7.20.5)(bufferutil@4.1.0)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3))(type-fest@0.21.3)(typescript@5.9.3): + react-scripts@5.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.27.4))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.27.4))(@types/babel__core@7.20.5)(bufferutil@4.0.9)(eslint@8.57.1)(react@18.3.1)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(type-fest@0.21.3)(typescript@5.8.3)(utf-8-validate@5.0.10): dependencies: - '@babel/core': 7.29.0 - '@pmmmwh/react-refresh-webpack-plugin': 0.5.17(react-refresh@0.11.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.1.0)(webpack@5.106.1))(webpack@5.106.1) + '@babel/core': 7.27.4 + '@pmmmwh/react-refresh-webpack-plugin': 0.5.17(react-refresh@0.11.0)(type-fest@0.21.3)(webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.99.9))(webpack@5.99.9) '@svgr/webpack': 5.5.0 - babel-jest: 27.5.1(@babel/core@7.29.0) - babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@5.106.1) - babel-plugin-named-asset-import: 0.3.8(@babel/core@7.29.0) + babel-jest: 27.5.1(@babel/core@7.27.4) + babel-loader: 8.4.1(@babel/core@7.27.4)(webpack@5.99.9) + babel-plugin-named-asset-import: 0.3.8(@babel/core@7.27.4) babel-preset-react-app: 10.1.0 bfj: 7.1.0 - browserslist: 4.28.2 + browserslist: 4.25.1 camelcase: 6.3.0 case-sensitive-paths-webpack-plugin: 2.4.0 - css-loader: 6.11.0(webpack@5.106.1) - css-minimizer-webpack-plugin: 3.4.1(webpack@5.106.1) + css-loader: 6.11.0(webpack@5.99.9) + css-minimizer-webpack-plugin: 3.4.1(webpack@5.99.9) dotenv: 10.0.0 dotenv-expand: 5.1.0 eslint: 8.57.1 - eslint-config-react-app: 7.0.1(@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0))(@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)))(typescript@5.9.3) - eslint-webpack-plugin: 3.2.0(eslint@8.57.1)(webpack@5.106.1) - file-loader: 6.2.0(webpack@5.106.1) + eslint-config-react-app: 7.0.1(@babel/plugin-syntax-flow@7.27.1(@babel/core@7.27.4))(@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.27.4))(eslint@8.57.1)(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(utf-8-validate@5.0.10))(typescript@5.8.3) + eslint-webpack-plugin: 3.2.0(eslint@8.57.1)(webpack@5.99.9) + file-loader: 6.2.0(webpack@5.99.9) fs-extra: 10.1.0 - html-webpack-plugin: 5.6.6(webpack@5.106.1) + html-webpack-plugin: 5.6.3(webpack@5.99.9) identity-obj-proxy: 3.0.0 - jest: 27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3)) + jest: 27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(utf-8-validate@5.0.10) jest-resolve: 27.5.1 - jest-watch-typeahead: 1.1.0(jest@27.5.1(bufferutil@4.1.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3))) - mini-css-extract-plugin: 2.10.2(webpack@5.106.1) - postcss: 8.5.9 - postcss-flexbugs-fixes: 5.0.2(postcss@8.5.9) - postcss-loader: 6.2.1(postcss@8.5.9)(webpack@5.106.1) - postcss-normalize: 10.0.1(browserslist@4.28.2)(postcss@8.5.9) - postcss-preset-env: 7.8.3(postcss@8.5.9) + jest-watch-typeahead: 1.1.0(jest@27.5.1(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3))(utf-8-validate@5.0.10)) + mini-css-extract-plugin: 2.9.2(webpack@5.99.9) + postcss: 8.5.6 + postcss-flexbugs-fixes: 5.0.2(postcss@8.5.6) + postcss-loader: 6.2.1(postcss@8.5.6)(webpack@5.99.9) + postcss-normalize: 10.0.1(browserslist@4.25.1)(postcss@8.5.6) + postcss-preset-env: 7.8.3(postcss@8.5.6) prompts: 2.4.2 react: 18.3.1 react-app-polyfill: 3.0.0 - react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.9.3)(webpack@5.106.1) + react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@5.8.3)(webpack@5.99.9) react-refresh: 0.11.0 - resolve: 1.22.11 + resolve: 1.22.10 resolve-url-loader: 4.0.0 - sass-loader: 12.6.0(webpack@5.106.1) - semver: 7.7.4 - source-map-loader: 3.0.2(webpack@5.106.1) - style-loader: 3.3.4(webpack@5.106.1) - tailwindcss: 3.4.19 - terser-webpack-plugin: 5.4.0(webpack@5.106.1) - webpack: 5.106.1(webpack-cli@6.0.1) - webpack-dev-server: 4.15.2(bufferutil@4.1.0)(webpack@5.106.1) - webpack-manifest-plugin: 4.1.1(webpack@5.106.1) - workbox-webpack-plugin: 6.6.0(@types/babel__core@7.20.5)(webpack@5.106.1) + sass-loader: 12.6.0(webpack@5.99.9) + semver: 7.7.2 + source-map-loader: 3.0.2(webpack@5.99.9) + style-loader: 3.3.4(webpack@5.99.9) + tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3)) + terser-webpack-plugin: 5.3.14(webpack@5.99.9) + webpack: 5.99.9(webpack-cli@6.0.1) + webpack-dev-server: 4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.99.9) + webpack-manifest-plugin: 4.1.1(webpack@5.99.9) + workbox-webpack-plugin: 6.6.0(@types/babel__core@7.20.5)(webpack@5.99.9) optionalDependencies: fsevents: 2.3.3 - typescript: 5.9.3 + typescript: 5.8.3 transitivePeerDependencies: - '@babel/plugin-syntax-flow' - '@babel/plugin-transform-react-jsx' @@ -19390,7 +18979,6 @@ snapshots: - sockjs-client - supports-color - ts-node - - tsx - type-fest - uglify-js - utf-8-validate @@ -19398,7 +18986,6 @@ snapshots: - webpack-cli - webpack-hot-middleware - webpack-plugin-serve - - yaml react-spinners@0.14.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: @@ -19440,7 +19027,7 @@ snapshots: read-yaml-file@1.1.0: dependencies: graceful-fs: 4.2.11 - js-yaml: 3.14.2 + js-yaml: 3.14.1 pify: 4.0.1 strip-bom: 3.0.0 @@ -19462,15 +19049,15 @@ snapshots: readdirp@3.6.0: dependencies: - picomatch: 2.3.2 + picomatch: 2.3.1 rechoir@0.8.0: dependencies: - resolve: 1.22.11 + resolve: 1.22.10 recursive-readdir@2.2.3: dependencies: - minimatch: 3.1.5 + minimatch: 3.1.2 redent@3.0.0: dependencies: @@ -19481,22 +19068,20 @@ snapshots: refa@0.12.1: dependencies: - '@eslint-community/regexpp': 4.12.2 - - reflect-metadata@0.2.2: {} + '@eslint-community/regexpp': 4.12.1 reflect.getprototypeof@1.0.10: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.24.2 + es-abstract: 1.24.0 es-errors: 1.3.0 es-object-atoms: 1.1.1 get-intrinsic: 1.3.0 get-proto: 1.0.1 which-builtin-type: 1.2.1 - regenerate-unicode-properties@10.2.2: + regenerate-unicode-properties@10.2.0: dependencies: regenerate: 1.4.2 @@ -19508,32 +19093,32 @@ snapshots: regexp-ast-analysis@0.7.1: dependencies: - '@eslint-community/regexpp': 4.12.2 + '@eslint-community/regexpp': 4.12.1 refa: 0.12.1 regexp.prototype.flags@1.5.4: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 define-properties: 1.2.1 es-errors: 1.3.0 get-proto: 1.0.1 gopd: 1.2.0 set-function-name: 2.0.2 - regexpu-core@6.4.0: + regexpu-core@6.2.0: dependencies: regenerate: 1.4.2 - regenerate-unicode-properties: 10.2.2 + regenerate-unicode-properties: 10.2.0 regjsgen: 0.8.0 - regjsparser: 0.13.1 + regjsparser: 0.12.0 unicode-match-property-ecmascript: 2.0.0 - unicode-match-property-value-ecmascript: 2.2.1 + unicode-match-property-value-ecmascript: 2.2.0 regjsgen@0.8.0: {} - regjsparser@0.13.1: + regjsparser@0.12.0: dependencies: - jsesc: 3.1.0 + jsesc: 3.0.2 relateurl@0.2.7: {} @@ -19542,7 +19127,7 @@ snapshots: css-select: 4.3.0 dom-converter: 0.2.0 htmlparser2: 6.1.0 - lodash: 4.18.1 + lodash: 4.17.21 strip-ansi: 6.0.1 require-directory@2.1.1: {} @@ -19578,18 +19163,15 @@ snapshots: resolve.exports@1.1.1: {} - resolve@1.22.11: + resolve@1.22.10: dependencies: is-core-module: 2.16.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - resolve@2.0.0-next.6: + resolve@2.0.0-next.5: dependencies: - es-errors: 1.3.0 is-core-module: 2.16.1 - node-exports-info: 1.6.0 - object-keys: 1.1.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -19612,70 +19194,70 @@ snapshots: rimraf@5.0.10: dependencies: - glob: 10.5.0 + glob: 10.4.5 - ripemd160@2.0.3: + ripemd160@2.0.1: dependencies: - hash-base: 3.1.2 + hash-base: 2.0.2 + inherits: 2.0.4 + + ripemd160@2.0.2: + dependencies: + hash-base: 3.0.5 inherits: 2.0.4 - rollup-plugin-terser@7.0.2(rollup@2.80.0): + rollup-plugin-terser@7.0.2(rollup@2.79.2): dependencies: - '@babel/code-frame': 7.29.0 + '@babel/code-frame': 7.27.1 jest-worker: 26.6.2 - rollup: 2.80.0 + rollup: 2.79.2 serialize-javascript: 4.0.0 - terser: 5.46.1 + terser: 5.43.1 - rollup@2.80.0: + rollup@2.79.2: optionalDependencies: fsevents: 2.3.3 - rollup@4.60.1: + rollup@4.44.1: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.60.1 - '@rollup/rollup-android-arm64': 4.60.1 - '@rollup/rollup-darwin-arm64': 4.60.1 - '@rollup/rollup-darwin-x64': 4.60.1 - '@rollup/rollup-freebsd-arm64': 4.60.1 - '@rollup/rollup-freebsd-x64': 4.60.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.60.1 - '@rollup/rollup-linux-arm-musleabihf': 4.60.1 - '@rollup/rollup-linux-arm64-gnu': 4.60.1 - '@rollup/rollup-linux-arm64-musl': 4.60.1 - '@rollup/rollup-linux-loong64-gnu': 4.60.1 - '@rollup/rollup-linux-loong64-musl': 4.60.1 - '@rollup/rollup-linux-ppc64-gnu': 4.60.1 - '@rollup/rollup-linux-ppc64-musl': 4.60.1 - '@rollup/rollup-linux-riscv64-gnu': 4.60.1 - '@rollup/rollup-linux-riscv64-musl': 4.60.1 - '@rollup/rollup-linux-s390x-gnu': 4.60.1 - '@rollup/rollup-linux-x64-gnu': 4.60.1 - '@rollup/rollup-linux-x64-musl': 4.60.1 - '@rollup/rollup-openbsd-x64': 4.60.1 - '@rollup/rollup-openharmony-arm64': 4.60.1 - '@rollup/rollup-win32-arm64-msvc': 4.60.1 - '@rollup/rollup-win32-ia32-msvc': 4.60.1 - '@rollup/rollup-win32-x64-gnu': 4.60.1 - '@rollup/rollup-win32-x64-msvc': 4.60.1 + '@rollup/rollup-android-arm-eabi': 4.44.1 + '@rollup/rollup-android-arm64': 4.44.1 + '@rollup/rollup-darwin-arm64': 4.44.1 + '@rollup/rollup-darwin-x64': 4.44.1 + '@rollup/rollup-freebsd-arm64': 4.44.1 + '@rollup/rollup-freebsd-x64': 4.44.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.44.1 + '@rollup/rollup-linux-arm-musleabihf': 4.44.1 + '@rollup/rollup-linux-arm64-gnu': 4.44.1 + '@rollup/rollup-linux-arm64-musl': 4.44.1 + '@rollup/rollup-linux-loongarch64-gnu': 4.44.1 + '@rollup/rollup-linux-powerpc64le-gnu': 4.44.1 + '@rollup/rollup-linux-riscv64-gnu': 4.44.1 + '@rollup/rollup-linux-riscv64-musl': 4.44.1 + '@rollup/rollup-linux-s390x-gnu': 4.44.1 + '@rollup/rollup-linux-x64-gnu': 4.44.1 + '@rollup/rollup-linux-x64-musl': 4.44.1 + '@rollup/rollup-win32-arm64-msvc': 4.44.1 + '@rollup/rollup-win32-ia32-msvc': 4.44.1 + '@rollup/rollup-win32-x64-msvc': 4.44.1 fsevents: 2.3.3 - rpc-websockets@9.3.8: + rpc-websockets@9.1.1: dependencies: - '@swc/helpers': 0.5.21 - '@types/uuid': 10.0.0 + '@swc/helpers': 0.5.17 + '@types/uuid': 8.3.4 '@types/ws': 8.18.1 buffer: 6.0.3 - eventemitter3: 5.0.4 - uuid: 11.1.0 - ws: 8.20.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + eventemitter3: 5.0.1 + uuid: 8.3.2 + ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - bufferutil: 4.1.0 - utf-8-validate: 6.0.6 + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 - run-applescript@7.1.0: {} + run-applescript@7.0.0: {} run-async@2.4.1: {} @@ -19689,7 +19271,7 @@ snapshots: safe-array-concat@1.1.3: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 call-bound: 1.0.4 get-intrinsic: 1.3.0 has-symbols: 1.1.0 @@ -19714,16 +19296,14 @@ snapshots: sanitize.css@13.0.0: {} - sass-loader@12.6.0(webpack@5.106.1): + sass-loader@12.6.0(webpack@5.99.9): dependencies: klona: 2.0.6 neo-async: 2.6.2 - webpack: 5.106.1(webpack-cli@6.0.1) + webpack: 5.99.9(webpack-cli@6.0.1) sax@1.2.4: {} - sax@1.6.0: {} - saxes@5.0.1: dependencies: xmlchars: 2.2.0 @@ -19735,33 +19315,33 @@ snapshots: schema-utils@2.7.0: dependencies: '@types/json-schema': 7.0.15 - ajv: 6.14.0 - ajv-keywords: 3.5.2(ajv@6.14.0) + ajv: 6.12.6 + ajv-keywords: 3.5.2(ajv@6.12.6) schema-utils@2.7.1: dependencies: '@types/json-schema': 7.0.15 - ajv: 6.14.0 - ajv-keywords: 3.5.2(ajv@6.14.0) + ajv: 6.12.6 + ajv-keywords: 3.5.2(ajv@6.12.6) schema-utils@3.3.0: dependencies: '@types/json-schema': 7.0.15 - ajv: 6.14.0 - ajv-keywords: 3.5.2(ajv@6.14.0) + ajv: 6.12.6 + ajv-keywords: 3.5.2(ajv@6.12.6) - schema-utils@4.3.3: + schema-utils@4.3.2: dependencies: '@types/json-schema': 7.0.15 - ajv: 8.18.0 - ajv-formats: 2.1.1(ajv@8.18.0) - ajv-keywords: 5.1.0(ajv@8.18.0) + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) scrypt-js@3.0.1: {} scslre@0.3.0: dependencies: - '@eslint-community/regexpp': 4.12.2 + '@eslint-community/regexpp': 4.12.1 refa: 0.12.1 regexp-ast-analysis: 0.7.1 @@ -19775,35 +19355,30 @@ snapshots: selfsigned@2.4.1: dependencies: - '@types/node-forge': 1.3.14 - node-forge: 1.4.0 - - selfsigned@5.5.0: - dependencies: - '@peculiar/x509': 1.14.3 - pkijs: 3.4.0 + '@types/node-forge': 1.3.11 + node-forge: 1.3.1 semver@5.7.2: {} semver@6.3.1: {} - semver@7.7.4: {} + semver@7.7.2: {} - send@0.19.2: + send@0.19.0: dependencies: debug: 2.6.9 depd: 2.0.0 destroy: 1.2.0 - encodeurl: 2.0.0 + encodeurl: 1.0.2 escape-html: 1.0.3 etag: 1.8.1 fresh: 0.5.2 - http-errors: 2.0.1 + http-errors: 2.0.0 mime: 1.6.0 ms: 2.1.3 on-finished: 2.4.1 range-parser: 1.2.1 - statuses: 2.0.2 + statuses: 2.0.1 transitivePeerDependencies: - supports-color @@ -19815,24 +19390,24 @@ snapshots: dependencies: randombytes: 2.1.0 - serve-index@1.9.2: + serve-index@1.9.1: dependencies: accepts: 1.3.8 batch: 0.6.1 debug: 2.6.9 escape-html: 1.0.3 - http-errors: 1.8.1 + http-errors: 1.6.3 mime-types: 2.1.35 parseurl: 1.3.3 transitivePeerDependencies: - supports-color - serve-static@1.16.3: + serve-static@1.16.2: dependencies: encodeurl: 2.0.0 escape-html: 1.0.3 parseurl: 1.3.3 - send: 0.19.2 + send: 0.19.0 transitivePeerDependencies: - supports-color @@ -19858,48 +19433,47 @@ snapshots: es-errors: 1.3.0 es-object-atoms: 1.1.1 + setprototypeof@1.1.0: {} + setprototypeof@1.2.0: {} - sha.js@2.4.12: + sha.js@2.4.11: dependencies: inherits: 2.0.4 safe-buffer: 5.2.1 - to-buffer: 1.2.2 shallow-clone@3.0.1: dependencies: kind-of: 6.0.3 - sharp@0.34.5: + sharp@0.34.3: dependencies: - '@img/colour': 1.1.0 - detect-libc: 2.1.2 - semver: 7.7.4 + color: 4.2.3 + detect-libc: 2.0.4 + semver: 7.7.2 optionalDependencies: - '@img/sharp-darwin-arm64': 0.34.5 - '@img/sharp-darwin-x64': 0.34.5 - '@img/sharp-libvips-darwin-arm64': 1.2.4 - '@img/sharp-libvips-darwin-x64': 1.2.4 - '@img/sharp-libvips-linux-arm': 1.2.4 - '@img/sharp-libvips-linux-arm64': 1.2.4 - '@img/sharp-libvips-linux-ppc64': 1.2.4 - '@img/sharp-libvips-linux-riscv64': 1.2.4 - '@img/sharp-libvips-linux-s390x': 1.2.4 - '@img/sharp-libvips-linux-x64': 1.2.4 - '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 - '@img/sharp-libvips-linuxmusl-x64': 1.2.4 - '@img/sharp-linux-arm': 0.34.5 - '@img/sharp-linux-arm64': 0.34.5 - '@img/sharp-linux-ppc64': 0.34.5 - '@img/sharp-linux-riscv64': 0.34.5 - '@img/sharp-linux-s390x': 0.34.5 - '@img/sharp-linux-x64': 0.34.5 - '@img/sharp-linuxmusl-arm64': 0.34.5 - '@img/sharp-linuxmusl-x64': 0.34.5 - '@img/sharp-wasm32': 0.34.5 - '@img/sharp-win32-arm64': 0.34.5 - '@img/sharp-win32-ia32': 0.34.5 - '@img/sharp-win32-x64': 0.34.5 + '@img/sharp-darwin-arm64': 0.34.3 + '@img/sharp-darwin-x64': 0.34.3 + '@img/sharp-libvips-darwin-arm64': 1.2.0 + '@img/sharp-libvips-darwin-x64': 1.2.0 + '@img/sharp-libvips-linux-arm': 1.2.0 + '@img/sharp-libvips-linux-arm64': 1.2.0 + '@img/sharp-libvips-linux-ppc64': 1.2.0 + '@img/sharp-libvips-linux-s390x': 1.2.0 + '@img/sharp-libvips-linux-x64': 1.2.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.0 + '@img/sharp-libvips-linuxmusl-x64': 1.2.0 + '@img/sharp-linux-arm': 0.34.3 + '@img/sharp-linux-arm64': 0.34.3 + '@img/sharp-linux-ppc64': 0.34.3 + '@img/sharp-linux-s390x': 0.34.3 + '@img/sharp-linux-x64': 0.34.3 + '@img/sharp-linuxmusl-arm64': 0.34.3 + '@img/sharp-linuxmusl-x64': 0.34.3 + '@img/sharp-wasm32': 0.34.3 + '@img/sharp-win32-arm64': 0.34.3 + '@img/sharp-win32-ia32': 0.34.3 + '@img/sharp-win32-x64': 0.34.3 optional: true shebang-command@1.2.0: @@ -19923,7 +19497,7 @@ snapshots: vscode-oniguruma: 1.7.0 vscode-textmate: 8.0.0 - side-channel-list@1.0.1: + side-channel-list@1.0.0: dependencies: es-errors: 1.3.0 object-inspect: 1.13.4 @@ -19947,7 +19521,7 @@ snapshots: dependencies: es-errors: 1.3.0 object-inspect: 1.13.4 - side-channel-list: 1.0.1 + side-channel-list: 1.0.0 side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 @@ -19957,13 +19531,18 @@ snapshots: signal-exit@4.1.0: {} + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + optional: true + sisteransi@1.0.5: {} - siwe@3.0.0(ethers@5.8.0(bufferutil@4.1.0)): + siwe@3.0.0(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)): dependencies: '@spruceid/siwe-parser': 3.0.0 '@stablelib/random': 1.0.2 - ethers: 5.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) slash@3.0.0: {} @@ -19979,25 +19558,25 @@ snapshots: sort-package-json@2.15.1: dependencies: - detect-indent: 7.0.2 + detect-indent: 7.0.1 detect-newline: 4.0.1 get-stdin: 9.0.0 git-hooks-list: 3.2.0 is-plain-obj: 4.1.0 - semver: 7.7.4 + semver: 7.7.2 sort-object-keys: 1.1.3 - tinyglobby: 0.2.16 + tinyglobby: 0.2.14 source-list-map@2.0.1: {} source-map-js@1.2.1: {} - source-map-loader@3.0.2(webpack@5.106.1): + source-map-loader@3.0.2(webpack@5.99.9): dependencies: abab: 2.0.6 iconv-lite: 0.6.3 source-map-js: 1.2.1 - webpack: 5.106.1(webpack-cli@6.0.1) + webpack: 5.99.9(webpack-cli@6.0.1) source-map-support@0.5.21: dependencies: @@ -20006,7 +19585,7 @@ snapshots: source-map@0.6.1: {} - source-map@0.7.6: {} + source-map@0.7.4: {} source-map@0.8.0-beta.0: dependencies: @@ -20022,20 +19601,20 @@ snapshots: spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.23 + spdx-license-ids: 3.0.21 spdx-exceptions@2.5.0: {} spdx-expression-parse@3.0.1: dependencies: spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.23 + spdx-license-ids: 3.0.21 - spdx-license-ids@3.0.23: {} + spdx-license-ids@3.0.21: {} spdy-transport@3.0.0: dependencies: - debug: 4.4.3 + debug: 4.4.1 detect-node: 2.1.0 hpack.js: 2.1.6 obuf: 1.1.2 @@ -20046,7 +19625,7 @@ snapshots: spdy@4.0.2: dependencies: - debug: 4.4.3 + debug: 4.4.1 handle-thing: 2.0.1 http-deceiver: 1.2.7 select-hose: 2.0.0 @@ -20089,7 +19668,7 @@ snapshots: figures: 3.2.0 find-up: 5.0.0 git-semver-tags: 4.1.1 - semver: 7.7.4 + semver: 7.7.2 stringify-package: 1.0.1 yargs: 16.2.0 @@ -20097,15 +19676,11 @@ snapshots: dependencies: escodegen: 1.14.3 - static-eval@2.1.1: - dependencies: - escodegen: 2.1.0 - statuses@1.5.0: {} - statuses@2.0.2: {} + statuses@2.0.1: {} - std-env@3.10.0: {} + std-env@3.9.0: {} stop-iteration-iterator@1.1.0: dependencies: @@ -20139,7 +19714,7 @@ snapshots: string-length@5.0.1: dependencies: char-regex: 2.0.2 - strip-ansi: 7.2.0 + strip-ansi: 7.1.0 string-natural-compare@3.0.1: {} @@ -20153,20 +19728,20 @@ snapshots: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 - strip-ansi: 7.2.0 + strip-ansi: 7.1.0 string.prototype.includes@2.0.1: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.24.2 + es-abstract: 1.24.0 string.prototype.matchall@4.0.12: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.24.2 + es-abstract: 1.24.0 es-errors: 1.3.0 es-object-atoms: 1.1.1 get-intrinsic: 1.3.0 @@ -20179,36 +19754,36 @@ snapshots: string.prototype.padend@3.1.6: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.24.2 + es-abstract: 1.24.0 es-object-atoms: 1.1.1 string.prototype.repeat@1.0.0: dependencies: define-properties: 1.2.1 - es-abstract: 1.24.2 + es-abstract: 1.24.0 string.prototype.trim@1.2.10: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 call-bound: 1.0.4 define-data-property: 1.1.4 define-properties: 1.2.1 - es-abstract: 1.24.2 + es-abstract: 1.24.0 es-object-atoms: 1.1.1 has-property-descriptors: 1.0.2 string.prototype.trimend@1.0.9: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 call-bound: 1.0.4 define-properties: 1.2.1 es-object-atoms: 1.1.1 string.prototype.trimstart@1.0.8: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 define-properties: 1.2.1 es-object-atoms: 1.1.1 @@ -20232,9 +19807,9 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.2.0: + strip-ansi@7.1.0: dependencies: - ansi-regex: 6.2.2 + ansi-regex: 6.1.0 strip-bom@3.0.0: {} @@ -20250,7 +19825,7 @@ snapshots: strip-json-comments@3.1.1: {} - strip-literal@3.1.0: + strip-literal@3.0.0: dependencies: js-tokens: 9.0.1 @@ -20258,29 +19833,29 @@ snapshots: dependencies: escape-string-regexp: 1.0.5 - style-loader@3.3.4(webpack@5.106.1): + style-loader@3.3.4(webpack@5.99.9): dependencies: - webpack: 5.106.1(webpack-cli@6.0.1) + webpack: 5.99.9(webpack-cli@6.0.1) styled-jsx@5.1.6(react@18.3.1): dependencies: client-only: 0.0.1 react: 18.3.1 - stylehacks@5.1.1(postcss@8.5.9): + stylehacks@5.1.1(postcss@8.5.6): dependencies: - browserslist: 4.28.2 - postcss: 8.5.9 + browserslist: 4.25.1 + postcss: 8.5.6 postcss-selector-parser: 6.1.2 - sucrase@3.35.1: + sucrase@3.35.0: dependencies: - '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/gen-mapping': 0.3.8 commander: 4.1.1 + glob: 10.4.5 lines-and-columns: 1.2.4 mz: 2.7.0 pirates: 4.0.7 - tinyglobby: 0.2.16 ts-interface-checker: 0.1.13 superstruct@2.0.2: {} @@ -20314,7 +19889,7 @@ snapshots: css-select-base-adapter: 0.1.1 css-tree: 1.0.0-alpha.37 csso: 4.2.0 - js-yaml: 3.14.2 + js-yaml: 3.14.1 mkdirp: 0.5.6 object.values: 1.2.1 sax: 1.2.4 @@ -20322,14 +19897,14 @@ snapshots: unquote: 1.1.1 util.promisify: 1.0.1 - svgo@2.8.2: + svgo@2.8.0: dependencies: + '@trysound/sax': 0.2.0 commander: 7.2.0 css-select: 4.3.0 css-tree: 1.1.3 csso: 4.2.0 picocolors: 1.1.1 - sax: 1.6.0 stable: 0.1.8 symbol-tree@3.2.4: {} @@ -20341,7 +19916,7 @@ snapshots: typical: 5.2.0 wordwrapjs: 4.0.1 - tailwindcss@3.4.19: + tailwindcss@3.4.17(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -20357,21 +19932,20 @@ snapshots: normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.1.1 - postcss: 8.5.9 - postcss-import: 15.1.0(postcss@8.5.9) - postcss-js: 4.1.0(postcss@8.5.9) - postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.9) - postcss-nested: 6.2.0(postcss@8.5.9) + postcss: 8.5.6 + postcss-import: 15.1.0(postcss@8.5.6) + postcss-js: 4.0.1(postcss@8.5.6) + postcss-load-config: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3)) + postcss-nested: 6.2.0(postcss@8.5.6) postcss-selector-parser: 6.1.2 - resolve: 1.22.11 - sucrase: 3.35.1 + resolve: 1.22.10 + sucrase: 3.35.0 transitivePeerDependencies: - - tsx - - yaml + - ts-node tapable@1.1.3: {} - tapable@2.3.2: {} + tapable@2.2.2: {} temp-dir@2.0.0: {} @@ -20389,18 +19963,19 @@ snapshots: ansi-escapes: 4.3.2 supports-hyperlinks: 2.3.0 - terser-webpack-plugin@5.4.0(webpack@5.106.1): + terser-webpack-plugin@5.3.14(webpack@5.99.9): dependencies: - '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 - schema-utils: 4.3.3 - terser: 5.46.1 - webpack: 5.106.1(webpack-cli@6.0.1) + schema-utils: 4.3.2 + serialize-javascript: 6.0.2 + terser: 5.43.1 + webpack: 5.99.9(webpack-cli@6.0.1) - terser@5.46.1: + terser@5.43.1: dependencies: - '@jridgewell/source-map': 0.3.11 - acorn: 8.16.0 + '@jridgewell/source-map': 0.3.6 + acorn: 8.15.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -20408,13 +19983,13 @@ snapshots: dependencies: '@istanbuljs/schema': 0.1.3 glob: 7.2.3 - minimatch: 3.1.5 + minimatch: 3.1.2 - test-exclude@7.0.2: + test-exclude@7.0.1: dependencies: '@istanbuljs/schema': 0.1.3 - glob: 10.5.0 - minimatch: 10.2.5 + glob: 10.4.5 + minimatch: 9.0.5 text-encoding-utf-8@1.0.2: {} @@ -20430,7 +20005,7 @@ snapshots: dependencies: any-promise: 1.3.0 - thingies@2.6.0(tslib@2.8.1): + thingies@1.21.0(tslib@2.8.1): dependencies: tslib: 2.8.1 @@ -20453,32 +20028,34 @@ snapshots: tinyexec@0.3.2: {} - tinyglobby@0.2.16: + tinyglobby@0.2.14: dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 + fdir: 6.4.6(picomatch@4.0.2) + picomatch: 4.0.2 tinypool@1.1.1: {} tinyrainbow@2.0.0: {} - tinyspy@4.0.4: {} + tinyspy@3.0.2: {} + + tinyspy@4.0.3: {} tmp-promise@3.0.3: dependencies: - tmp: 0.2.5 + tmp: 0.2.3 optional: true tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 - tmp@0.2.5: + tmp@0.2.3: optional: true tmpl@1.0.5: {} - to-buffer@1.2.2: + to-buffer@1.2.1: dependencies: isarray: 2.0.5 safe-buffer: 5.2.1 @@ -20511,7 +20088,7 @@ snapshots: dependencies: punycode: 2.3.1 - tree-dump@1.1.0(tslib@2.8.1): + tree-dump@1.0.3(tslib@2.8.1): dependencies: tslib: 2.8.1 @@ -20527,13 +20104,9 @@ snapshots: dependencies: typescript: 5.2.2 - ts-api-utils@1.4.3(typescript@5.9.3): - dependencies: - typescript: 5.9.3 - - ts-api-utils@2.5.0(typescript@5.9.3): + ts-api-utils@1.4.3(typescript@5.8.3): dependencies: - typescript: 5.9.3 + typescript: 5.8.3 ts-command-line-args@2.5.1: dependencies: @@ -20542,35 +20115,35 @@ snapshots: command-line-usage: 6.1.3 string-format: 2.0.0 - ts-essentials@7.0.3(typescript@5.9.3): + ts-essentials@7.0.3(typescript@5.8.3): dependencies: - typescript: 5.9.3 + typescript: 5.8.3 ts-interface-checker@0.1.13: {} - ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.3): + ts-node@10.9.2(@types/node@24.3.0)(typescript@5.8.3): dependencies: '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.12 + '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 '@types/node': 24.3.0 - acorn: 8.16.0 - acorn-walk: 8.3.5 + acorn: 8.15.0 + acorn-walk: 8.3.4 arg: 4.1.3 create-require: 1.1.1 - diff: 4.0.4 + diff: 4.0.2 make-error: 1.3.6 - typescript: 5.9.3 + typescript: 5.8.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - ts-unused-exports@10.1.0(typescript@5.9.3): + ts-unused-exports@10.1.0(typescript@5.8.3): dependencies: chalk: 4.1.2 tsconfig-paths: 3.15.0 - typescript: 5.9.3 + typescript: 5.8.3 tsconfig-paths@3.15.0: dependencies: @@ -20583,14 +20156,10 @@ snapshots: tslib@2.8.1: {} - tsutils@3.21.0(typescript@5.9.3): - dependencies: - tslib: 1.14.1 - typescript: 5.9.3 - - tsyringe@4.10.0: + tsutils@3.21.0(typescript@5.8.3): dependencies: tslib: 1.14.1 + typescript: 5.8.3 tweetnacl@1.0.3: {} @@ -20621,19 +20190,19 @@ snapshots: media-typer: 0.3.0 mime-types: 2.1.35 - typechain@8.3.2(typescript@5.9.3): + typechain@8.3.2(typescript@5.8.3): dependencies: '@types/prettier': 2.7.3 - debug: 4.4.3 + debug: 4.4.1 fs-extra: 7.0.1 glob: 7.1.7 js-sha3: 0.8.0 - lodash: 4.18.1 + lodash: 4.17.21 mkdirp: 1.0.4 prettier: 2.8.8 ts-command-line-args: 2.5.1 - ts-essentials: 7.0.3(typescript@5.9.3) - typescript: 5.9.3 + ts-essentials: 7.0.3(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -20645,7 +20214,7 @@ snapshots: typed-array-byte-length@1.0.3: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 for-each: 0.3.5 gopd: 1.2.0 has-proto: 1.2.0 @@ -20654,7 +20223,7 @@ snapshots: typed-array-byte-offset@1.0.4: dependencies: available-typed-arrays: 1.0.7 - call-bind: 1.0.9 + call-bind: 1.0.8 for-each: 0.3.5 gopd: 1.2.0 has-proto: 1.2.0 @@ -20663,7 +20232,7 @@ snapshots: typed-array-length@1.0.7: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 for-each: 0.3.5 gopd: 1.2.0 is-typed-array: 1.1.15 @@ -20676,31 +20245,31 @@ snapshots: typedarray@0.0.6: {} - typedoc-plugin-coverage@2.2.0(typedoc@0.25.13(typescript@5.9.3)): + typedoc-plugin-coverage@2.2.0(typedoc@0.25.13(typescript@5.8.3)): dependencies: - typedoc: 0.25.13(typescript@5.9.3) + typedoc: 0.25.13(typescript@5.8.3) - typedoc-plugin-missing-exports@2.3.0(typedoc@0.25.13(typescript@5.9.3)): + typedoc-plugin-missing-exports@2.3.0(typedoc@0.25.13(typescript@5.8.3)): dependencies: - typedoc: 0.25.13(typescript@5.9.3) + typedoc: 0.25.13(typescript@5.8.3) - typedoc-plugin-zod@1.4.3(typedoc@0.25.13(typescript@5.9.3)): + typedoc-plugin-zod@1.4.2(typedoc@0.25.13(typescript@5.8.3)): dependencies: - typedoc: 0.25.13(typescript@5.9.3) + typedoc: 0.25.13(typescript@5.8.3) - typedoc@0.25.13(typescript@5.9.3): + typedoc@0.25.13(typescript@5.8.3): dependencies: lunr: 2.3.9 marked: 4.3.0 - minimatch: 9.0.9 + minimatch: 9.0.5 shiki: 0.14.7 - typescript: 5.9.3 + typescript: 5.8.3 typescript@4.9.5: {} typescript@5.2.2: {} - typescript@5.9.3: {} + typescript@5.8.3: {} typical@4.0.0: {} @@ -20716,7 +20285,7 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 - underscore@1.13.6: {} + underscore@1.12.1: {} undici-types@7.10.0: {} @@ -20725,11 +20294,11 @@ snapshots: unicode-match-property-ecmascript@2.0.0: dependencies: unicode-canonical-property-names-ecmascript: 2.0.1 - unicode-property-aliases-ecmascript: 2.2.0 + unicode-property-aliases-ecmascript: 2.1.0 - unicode-match-property-value-ecmascript@2.2.1: {} + unicode-match-property-value-ecmascript@2.2.0: {} - unicode-property-aliases-ecmascript@2.2.0: {} + unicode-property-aliases-ecmascript@2.1.0: {} unique-string@2.0.0: dependencies: @@ -20745,35 +20314,35 @@ snapshots: unquote@1.1.1: {} - unrs-resolver@1.11.1: + unrs-resolver@1.9.2: dependencies: - napi-postinstall: 0.3.4 + napi-postinstall: 0.2.4 optionalDependencies: - '@unrs/resolver-binding-android-arm-eabi': 1.11.1 - '@unrs/resolver-binding-android-arm64': 1.11.1 - '@unrs/resolver-binding-darwin-arm64': 1.11.1 - '@unrs/resolver-binding-darwin-x64': 1.11.1 - '@unrs/resolver-binding-freebsd-x64': 1.11.1 - '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 - '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 - '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 - '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 - '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 - '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-x64-musl': 1.11.1 - '@unrs/resolver-binding-wasm32-wasi': 1.11.1 - '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 - '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 - '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 + '@unrs/resolver-binding-android-arm-eabi': 1.9.2 + '@unrs/resolver-binding-android-arm64': 1.9.2 + '@unrs/resolver-binding-darwin-arm64': 1.9.2 + '@unrs/resolver-binding-darwin-x64': 1.9.2 + '@unrs/resolver-binding-freebsd-x64': 1.9.2 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.9.2 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.9.2 + '@unrs/resolver-binding-linux-arm64-gnu': 1.9.2 + '@unrs/resolver-binding-linux-arm64-musl': 1.9.2 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.9.2 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.9.2 + '@unrs/resolver-binding-linux-riscv64-musl': 1.9.2 + '@unrs/resolver-binding-linux-s390x-gnu': 1.9.2 + '@unrs/resolver-binding-linux-x64-gnu': 1.9.2 + '@unrs/resolver-binding-linux-x64-musl': 1.9.2 + '@unrs/resolver-binding-wasm32-wasi': 1.9.2 + '@unrs/resolver-binding-win32-arm64-msvc': 1.9.2 + '@unrs/resolver-binding-win32-ia32-msvc': 1.9.2 + '@unrs/resolver-binding-win32-x64-msvc': 1.9.2 upath@1.2.0: {} - update-browserslist-db@1.2.3(browserslist@4.28.2): + update-browserslist-db@1.1.3(browserslist@4.25.1): dependencies: - browserslist: 4.28.2 + browserslist: 4.25.1 escalade: 3.2.0 picocolors: 1.1.1 @@ -20786,7 +20355,7 @@ snapshots: querystringify: 2.2.0 requires-port: 1.0.0 - utf-8-validate@6.0.6: + utf-8-validate@5.0.10: dependencies: node-gyp-build: 4.8.4 optional: true @@ -20796,16 +20365,14 @@ snapshots: util.promisify@1.0.1: dependencies: define-properties: 1.2.1 - es-abstract: 1.24.2 + es-abstract: 1.24.0 has-symbols: 1.1.0 - object.getownpropertydescriptors: 2.1.9 + object.getownpropertydescriptors: 2.1.8 utila@0.4.0: {} utils-merge@1.0.1: {} - uuid@11.1.0: {} - uuid@8.3.2: {} v8-compile-cache-lib@3.0.1: {} @@ -20814,7 +20381,7 @@ snapshots: dependencies: '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 1.9.0 - source-map: 0.7.6 + source-map: 0.7.4 validate-npm-package-license@3.0.4: dependencies: @@ -20823,13 +20390,34 @@ snapshots: vary@1.1.2: {} - vite-node@3.2.4(@types/node@24.3.0)(jiti@2.6.1)(terser@5.46.1): + vite-node@3.0.9(@types/node@24.3.0)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0): + dependencies: + cac: 6.7.14 + debug: 4.4.1 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 6.3.5(@types/node@24.3.0)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + vite-node@3.2.4(@types/node@24.3.0)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0): dependencies: cac: 6.7.14 - debug: 4.4.3 + debug: 4.4.1 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.3.2(@types/node@24.3.0)(jiti@2.6.1)(terser@5.46.1) + vite: 7.0.0(@types/node@24.3.0)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) transitivePeerDependencies: - '@types/node' - jiti @@ -20844,48 +20432,103 @@ snapshots: - tsx - yaml - vite@7.3.2(@types/node@24.3.0)(jiti@2.6.1)(terser@5.46.1): + vite@6.3.5(@types/node@24.3.0)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0): dependencies: - esbuild: 0.27.7 - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 - postcss: 8.5.9 - rollup: 4.60.1 - tinyglobby: 0.2.16 + esbuild: 0.25.5 + fdir: 6.4.6(picomatch@4.0.2) + picomatch: 4.0.2 + postcss: 8.5.6 + rollup: 4.44.1 + tinyglobby: 0.2.14 + optionalDependencies: + '@types/node': 24.3.0 + fsevents: 2.3.3 + jiti: 2.4.2 + terser: 5.43.1 + yaml: 2.8.0 + + vite@7.0.0(@types/node@24.3.0)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0): + dependencies: + esbuild: 0.25.5 + fdir: 6.4.6(picomatch@4.0.2) + picomatch: 4.0.2 + postcss: 8.5.6 + rollup: 4.44.1 + tinyglobby: 0.2.14 optionalDependencies: '@types/node': 24.3.0 fsevents: 2.3.3 - jiti: 2.6.1 - terser: 5.46.1 + jiti: 2.4.2 + terser: 5.43.1 + yaml: 2.8.0 + + vitest@3.0.9(@types/node@24.3.0)(jiti@2.4.2)(jsdom@16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(terser@5.43.1)(yaml@2.8.0): + dependencies: + '@vitest/expect': 3.0.9 + '@vitest/mocker': 3.0.9(vite@6.3.5(@types/node@24.3.0)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0)) + '@vitest/pretty-format': 3.2.4 + '@vitest/runner': 3.0.9 + '@vitest/snapshot': 3.0.9 + '@vitest/spy': 3.0.9 + '@vitest/utils': 3.0.9 + chai: 5.2.0 + debug: 4.4.1 + expect-type: 1.2.1 + magic-string: 0.30.17 + pathe: 2.0.3 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.1.1 + tinyrainbow: 2.0.0 + vite: 6.3.5(@types/node@24.3.0)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) + vite-node: 3.0.9(@types/node@24.3.0)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 24.3.0 + jsdom: 16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml - vitest@3.2.4(@types/node@24.3.0)(jiti@2.6.1)(jsdom@16.7.0(bufferutil@4.1.0))(terser@5.46.1): + vitest@3.2.4(@types/node@24.3.0)(jiti@2.4.2)(jsdom@16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(terser@5.43.1)(yaml@2.8.0): dependencies: - '@types/chai': 5.2.3 + '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.3.2(@types/node@24.3.0)(jiti@2.6.1)(terser@5.46.1)) + '@vitest/mocker': 3.2.4(vite@7.0.0(@types/node@24.3.0)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 '@vitest/spy': 3.2.4 '@vitest/utils': 3.2.4 - chai: 5.3.3 - debug: 4.4.3 - expect-type: 1.3.0 - magic-string: 0.30.21 + chai: 5.2.0 + debug: 4.4.1 + expect-type: 1.2.1 + magic-string: 0.30.17 pathe: 2.0.3 - picomatch: 4.0.4 - std-env: 3.10.0 + picomatch: 4.0.2 + std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 - tinyglobby: 0.2.16 + tinyglobby: 0.2.14 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.3.2(@types/node@24.3.0)(jiti@2.6.1)(terser@5.46.1) - vite-node: 3.2.4(@types/node@24.3.0)(jiti@2.6.1)(terser@5.46.1) + vite: 7.0.0(@types/node@24.3.0)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) + vite-node: 3.2.4(@types/node@24.3.0)(jiti@2.4.2)(terser@5.43.1)(yaml@2.8.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.3.0 - jsdom: 16.7.0(bufferutil@4.1.0) + jsdom: 16.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - jiti - less @@ -20920,7 +20563,7 @@ snapshots: dependencies: makeerror: 1.0.12 - watchpack@2.5.1: + watchpack@2.4.4: dependencies: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 @@ -20941,131 +20584,128 @@ snapshots: webidl-conversions@6.1.0: {} - webpack-cli@6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1): + webpack-cli@6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9): dependencies: '@discoveryjs/json-ext': 0.6.3 - '@webpack-cli/configtest': 3.0.1(webpack-cli@6.0.1)(webpack@5.106.1) - '@webpack-cli/info': 3.0.1(webpack-cli@6.0.1)(webpack@5.106.1) - '@webpack-cli/serve': 3.0.1(webpack-cli@6.0.1)(webpack-dev-server@5.2.3)(webpack@5.106.1) + '@webpack-cli/configtest': 3.0.1(webpack-cli@6.0.1)(webpack@5.99.9) + '@webpack-cli/info': 3.0.1(webpack-cli@6.0.1)(webpack@5.99.9) + '@webpack-cli/serve': 3.0.1(webpack-cli@6.0.1)(webpack-dev-server@5.2.2)(webpack@5.99.9) colorette: 2.0.20 commander: 12.1.0 cross-spawn: 7.0.6 - envinfo: 7.21.0 + envinfo: 7.14.0 fastest-levenshtein: 1.0.16 import-local: 3.2.0 interpret: 3.1.1 rechoir: 0.8.0 - webpack: 5.106.1(webpack-cli@6.0.1) + webpack: 5.99.9(webpack-cli@6.0.1) webpack-merge: 6.0.1 optionalDependencies: - webpack-dev-server: 5.2.3(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack-cli@6.0.1)(webpack@5.106.1) + webpack-dev-server: 5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9) - webpack-dev-middleware@5.3.4(webpack@5.106.1): + webpack-dev-middleware@5.3.4(webpack@5.99.9): dependencies: colorette: 2.0.20 memfs: 3.5.3 mime-types: 2.1.35 range-parser: 1.2.1 - schema-utils: 4.3.3 - webpack: 5.106.1(webpack-cli@6.0.1) + schema-utils: 4.3.2 + webpack: 5.99.9(webpack-cli@6.0.1) - webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.106.1): + webpack-dev-middleware@7.4.2(webpack@5.99.9): dependencies: colorette: 2.0.20 - memfs: 4.57.1(tslib@2.8.1) - mime-types: 3.0.2 + memfs: 4.24.0 + mime-types: 2.1.35 on-finished: 2.4.1 range-parser: 1.2.1 - schema-utils: 4.3.3 + schema-utils: 4.3.2 optionalDependencies: - webpack: 5.106.1(webpack-cli@6.0.1) - transitivePeerDependencies: - - tslib + webpack: 5.99.9(webpack-cli@6.0.1) - webpack-dev-server@4.15.2(bufferutil@4.1.0)(webpack@5.106.1): + webpack-dev-server@4.15.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack@5.99.9): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 - '@types/express': 4.17.25 + '@types/express': 4.17.23 '@types/serve-index': 1.9.4 - '@types/serve-static': 1.15.10 + '@types/serve-static': 1.15.8 '@types/sockjs': 0.3.36 '@types/ws': 8.18.1 ansi-html-community: 0.0.8 bonjour-service: 1.3.0 chokidar: 3.6.0 colorette: 2.0.20 - compression: 1.8.1 + compression: 1.8.0 connect-history-api-fallback: 2.0.0 default-gateway: 6.0.3 - express: 4.22.1 + express: 4.21.2 graceful-fs: 4.2.11 html-entities: 2.6.0 - http-proxy-middleware: 2.0.9(@types/express@4.17.25) - ipaddr.js: 2.3.0 - launch-editor: 2.13.2 + http-proxy-middleware: 2.0.9(@types/express@4.17.23) + ipaddr.js: 2.2.0 + launch-editor: 2.10.0 open: 8.4.2 p-retry: 4.6.2 rimraf: 3.0.2 - schema-utils: 4.3.3 + schema-utils: 4.3.2 selfsigned: 2.4.1 - serve-index: 1.9.2 + serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 5.3.4(webpack@5.106.1) - ws: 8.20.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + webpack-dev-middleware: 5.3.4(webpack@5.99.9) + ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - webpack: 5.106.1(webpack-cli@6.0.1) + webpack: 5.99.9(webpack-cli@6.0.1) transitivePeerDependencies: - bufferutil - debug - supports-color - utf-8-validate - webpack-dev-server@5.2.3(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack-cli@6.0.1)(webpack@5.106.1): + webpack-dev-server@5.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)(webpack-cli@6.0.1)(webpack@5.99.9): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 - '@types/express': 4.17.25 - '@types/express-serve-static-core': 4.19.8 + '@types/express': 4.17.23 + '@types/express-serve-static-core': 4.19.6 '@types/serve-index': 1.9.4 - '@types/serve-static': 1.15.10 + '@types/serve-static': 1.15.8 '@types/sockjs': 0.3.36 '@types/ws': 8.18.1 ansi-html-community: 0.0.8 bonjour-service: 1.3.0 chokidar: 3.6.0 colorette: 2.0.20 - compression: 1.8.1 + compression: 1.8.0 connect-history-api-fallback: 2.0.0 - express: 4.22.1 + express: 4.21.2 graceful-fs: 4.2.11 - http-proxy-middleware: 2.0.9(@types/express@4.17.25) - ipaddr.js: 2.3.0 - launch-editor: 2.13.2 + http-proxy-middleware: 2.0.9(@types/express@4.17.23) + ipaddr.js: 2.2.0 + launch-editor: 2.10.0 open: 10.2.0 p-retry: 6.2.1 - schema-utils: 4.3.3 - selfsigned: 5.5.0 - serve-index: 1.9.2 + schema-utils: 4.3.2 + selfsigned: 2.4.1 + serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.106.1) - ws: 8.20.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + webpack-dev-middleware: 7.4.2(webpack@5.99.9) + ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - webpack: 5.106.1(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1) + webpack: 5.99.9(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) transitivePeerDependencies: - bufferutil - debug - supports-color - - tslib - utf-8-validate - webpack-manifest-plugin@4.1.1(webpack@5.106.1): + webpack-manifest-plugin@4.1.1(webpack@5.99.9): dependencies: - tapable: 2.3.2 - webpack: 5.106.1(webpack-cli@6.0.1) + tapable: 2.2.2 + webpack: 5.99.9(webpack-cli@6.0.1) webpack-sources: 2.3.1 webpack-merge@6.0.1: @@ -21084,9 +20724,9 @@ snapshots: source-list-map: 2.0.1 source-map: 0.6.1 - webpack-sources@3.3.4: {} + webpack-sources@3.3.3: {} - webpack@5.106.1(webpack-cli@6.0.1): + webpack@5.99.9(webpack-cli@6.0.1): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -21094,27 +20734,26 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.16.0 - acorn-import-phases: 1.0.4(acorn@8.16.0) - browserslist: 4.28.2 + acorn: 8.15.0 + browserslist: 4.25.1 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.20.1 - es-module-lexer: 2.0.0 + enhanced-resolve: 5.18.2 + es-module-lexer: 1.7.0 eslint-scope: 5.1.1 events: 3.3.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 + loader-runner: 4.3.0 mime-types: 2.1.35 neo-async: 2.6.2 - schema-utils: 4.3.3 - tapable: 2.3.2 - terser-webpack-plugin: 5.4.0(webpack@5.106.1) - watchpack: 2.5.1 - webpack-sources: 3.3.4 + schema-utils: 4.3.2 + tapable: 2.2.2 + terser-webpack-plugin: 5.3.14(webpack@5.99.9) + watchpack: 2.4.4 + webpack-sources: 3.3.3 optionalDependencies: - webpack-cli: 6.0.1(webpack-dev-server@5.2.3)(webpack@5.106.1) + webpack-cli: 6.0.1(webpack-dev-server@5.2.2)(webpack@5.99.9) transitivePeerDependencies: - '@swc/core' - esbuild @@ -21155,7 +20794,7 @@ snapshots: whatwg-url@8.7.0: dependencies: - lodash: 4.18.1 + lodash: 4.17.21 tr46: 2.1.0 webidl-conversions: 6.1.0 @@ -21175,13 +20814,13 @@ snapshots: is-async-function: 2.1.1 is-date-object: 1.1.0 is-finalizationregistry: 1.1.1 - is-generator-function: 1.1.2 + is-generator-function: 1.1.0 is-regex: 1.2.1 is-weakref: 1.1.1 isarray: 2.0.5 which-boxed-primitive: 1.1.1 which-collection: 1.0.2 - which-typed-array: 1.1.20 + which-typed-array: 1.1.19 which-collection@1.0.2: dependencies: @@ -21190,10 +20829,10 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.4 - which-typed-array@1.1.20: + which-typed-array@1.1.19: dependencies: available-typed-arrays: 1.0.7 - call-bind: 1.0.9 + call-bind: 1.0.8 call-bound: 1.0.4 for-each: 0.3.5 get-proto: 1.0.1 @@ -21235,23 +20874,23 @@ snapshots: workbox-build@6.6.0(@types/babel__core@7.20.5): dependencies: - '@apideck/better-ajv-errors': 0.3.7(ajv@8.18.0) - '@babel/core': 7.29.0 - '@babel/preset-env': 7.29.2(@babel/core@7.29.0) - '@babel/runtime': 7.29.2 - '@rollup/plugin-babel': 5.3.1(@babel/core@7.29.0)(@types/babel__core@7.20.5)(rollup@2.80.0) - '@rollup/plugin-node-resolve': 11.2.1(rollup@2.80.0) - '@rollup/plugin-replace': 2.4.2(rollup@2.80.0) + '@apideck/better-ajv-errors': 0.3.6(ajv@8.17.1) + '@babel/core': 7.27.4 + '@babel/preset-env': 7.27.2(@babel/core@7.27.4) + '@babel/runtime': 7.27.6 + '@rollup/plugin-babel': 5.3.1(@babel/core@7.27.4)(@types/babel__core@7.20.5)(rollup@2.79.2) + '@rollup/plugin-node-resolve': 11.2.1(rollup@2.79.2) + '@rollup/plugin-replace': 2.4.2(rollup@2.79.2) '@surma/rollup-plugin-off-main-thread': 2.2.3 - ajv: 8.18.0 + ajv: 8.17.1 common-tags: 1.8.2 fast-json-stable-stringify: 2.1.0 fs-extra: 9.1.0 glob: 7.2.3 - lodash: 4.18.1 + lodash: 4.17.21 pretty-bytes: 5.6.0 - rollup: 2.80.0 - rollup-plugin-terser: 7.0.2(rollup@2.80.0) + rollup: 2.79.2 + rollup-plugin-terser: 7.0.2(rollup@2.79.2) source-map: 0.8.0-beta.0 stringify-object: 3.3.0 strip-comments: 2.0.1 @@ -21332,12 +20971,12 @@ snapshots: workbox-sw@6.6.0: {} - workbox-webpack-plugin@6.6.0(@types/babel__core@7.20.5)(webpack@5.106.1): + workbox-webpack-plugin@6.6.0(@types/babel__core@7.20.5)(webpack@5.99.9): dependencies: fast-json-stable-stringify: 2.1.0 pretty-bytes: 5.6.0 upath: 1.2.0 - webpack: 5.106.1(webpack-cli@6.0.1) + webpack: 5.99.9(webpack-cli@6.0.1) webpack-sources: 1.4.3 workbox-build: 6.6.0(@types/babel__core@7.20.5) transitivePeerDependencies: @@ -21363,9 +21002,9 @@ snapshots: wrap-ansi@8.1.0: dependencies: - ansi-styles: 6.2.3 + ansi-styles: 6.2.1 string-width: 5.1.2 - strip-ansi: 7.2.0 + strip-ansi: 7.1.0 wrappy@1.0.2: {} @@ -21376,24 +21015,24 @@ snapshots: signal-exit: 3.0.7 typedarray-to-buffer: 3.1.5 - ws@7.5.10(bufferutil@4.1.0)(utf-8-validate@6.0.6): + ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10): optionalDependencies: - bufferutil: 4.1.0 - utf-8-validate: 6.0.6 + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 - ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): optionalDependencies: - bufferutil: 4.1.0 - utf-8-validate: 6.0.6 + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 - ws@8.20.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10): optionalDependencies: - bufferutil: 4.1.0 - utf-8-validate: 6.0.6 + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 wsl-utils@0.1.0: dependencies: - is-wsl: 3.1.1 + is-wsl: 3.1.0 xml-name-validator@3.0.0: {} @@ -21407,7 +21046,9 @@ snapshots: yallist@4.0.0: {} - yaml@1.10.3: {} + yaml@1.10.2: {} + + yaml@2.8.0: {} yargs-parser@20.2.9: {} @@ -21427,12 +21068,16 @@ snapshots: yup@0.32.11: dependencies: - '@babel/runtime': 7.29.2 - '@types/lodash': 4.17.24 - lodash: 4.18.1 - lodash-es: 4.18.1 + '@babel/runtime': 7.27.6 + '@types/lodash': 4.17.19 + lodash: 4.17.21 + lodash-es: 4.17.21 nanoclone: 0.2.1 property-expr: 2.0.6 toposort: 2.0.2 - zod@3.25.76: {} + zod-to-json-schema@3.25.2(zod@3.25.67): + dependencies: + zod: 3.25.67 + + zod@3.25.67: {} From 960a542230bf011a69afff46b3a9489ce3882931 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 21 Apr 2026 09:44:43 -0400 Subject: [PATCH 291/303] Bump next from 15.3.4 to 15.5.14. --- examples/pre/nextjs/next-env.d.ts | 1 + examples/pre/nextjs/package.json | 2 +- examples/taco/nextjs/next-env.d.ts | 1 + examples/taco/nextjs/package.json | 2 +- pnpm-lock.yaml | 119 +++++++++++------------------ 5 files changed, 49 insertions(+), 76 deletions(-) diff --git a/examples/pre/nextjs/next-env.d.ts b/examples/pre/nextjs/next-env.d.ts index 1b3be0840..830fb594c 100644 --- a/examples/pre/nextjs/next-env.d.ts +++ b/examples/pre/nextjs/next-env.d.ts @@ -1,5 +1,6 @@ /// /// +/// // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/examples/pre/nextjs/package.json b/examples/pre/nextjs/package.json index d9a266493..937cdbd13 100644 --- a/examples/pre/nextjs/package.json +++ b/examples/pre/nextjs/package.json @@ -17,7 +17,7 @@ "eslint": "8.57.0", "eslint-config-next": "14.0.4", "ethers": "^5.8.0", - "next": "15.3.4", + "next": "15.5.14", "react": "18.3.1", "react-dom": "18.3.1" } diff --git a/examples/taco/nextjs/next-env.d.ts b/examples/taco/nextjs/next-env.d.ts index 1b3be0840..830fb594c 100644 --- a/examples/taco/nextjs/next-env.d.ts +++ b/examples/taco/nextjs/next-env.d.ts @@ -1,5 +1,6 @@ /// /// +/// // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/examples/taco/nextjs/package.json b/examples/taco/nextjs/package.json index 98718953b..660cc475e 100644 --- a/examples/taco/nextjs/package.json +++ b/examples/taco/nextjs/package.json @@ -20,7 +20,7 @@ "eslint": "8.57.0", "eslint-config-next": "14.0.4", "ethers": "^5.8.0", - "next": "15.3.4", + "next": "15.5.14", "react": "18.3.1", "react-dom": "18.3.1", "typescript": "5.2.2" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 54a258136..6b87841de 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -295,8 +295,8 @@ importers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) next: - specifier: 15.3.4 - version: 15.3.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 15.5.14 + version: 15.5.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: 18.3.1 version: 18.3.1 @@ -399,8 +399,8 @@ importers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) next: - specifier: 15.3.4 - version: 15.3.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 15.5.14 + version: 15.5.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: 18.3.1 version: 18.3.1 @@ -1573,9 +1573,6 @@ packages: '@emnapi/core@1.4.3': resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==} - '@emnapi/runtime@1.4.3': - resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} - '@emnapi/runtime@1.4.5': resolution: {integrity: sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==} @@ -2475,60 +2472,60 @@ packages: '@near-js/utils@0.0.4': resolution: {integrity: sha512-mPUEPJbTCMicGitjEGvQqOe8AS7O4KkRCxqd0xuE/X6gXF1jz1pYMZn4lNUeUz2C84YnVSGLAM0o9zcN6Y4hiA==} - '@next/env@15.3.4': - resolution: {integrity: sha512-ZkdYzBseS6UjYzz6ylVKPOK+//zLWvD6Ta+vpoye8cW11AjiQjGYVibF0xuvT4L0iJfAPfZLFidaEzAOywyOAQ==} + '@next/env@15.5.14': + resolution: {integrity: sha512-aXeirLYuASxEgi4X4WhfXsShCFxWDfNn/8ZeC5YXAS2BB4A8FJi1kwwGL6nvMVboE7fZCzmJPNdMvVHc8JpaiA==} '@next/eslint-plugin-next@14.0.4': resolution: {integrity: sha512-U3qMNHmEZoVmHA0j/57nRfi3AscXNvkOnxDmle/69Jz/G0o/gWjXTDdlgILZdrxQ0Lw/jv2mPW8PGy0EGIHXhQ==} - '@next/swc-darwin-arm64@15.3.4': - resolution: {integrity: sha512-z0qIYTONmPRbwHWvpyrFXJd5F9YWLCsw3Sjrzj2ZvMYy9NPQMPZ1NjOJh4ojr4oQzcGYwgJKfidzehaNa1BpEg==} + '@next/swc-darwin-arm64@15.5.14': + resolution: {integrity: sha512-Y9K6SPzobnZvrRDPO2s0grgzC+Egf0CqfbdvYmQVaztV890zicw8Z8+4Vqw8oPck8r1TjUHxVh8299Cg4TrxXg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@15.3.4': - resolution: {integrity: sha512-Z0FYJM8lritw5Wq+vpHYuCIzIlEMjewG2aRkc3Hi2rcbULknYL/xqfpBL23jQnCSrDUGAo/AEv0Z+s2bff9Zkw==} + '@next/swc-darwin-x64@15.5.14': + resolution: {integrity: sha512-aNnkSMjSFRTOmkd7qoNI2/rETQm/vKD6c/Ac9BZGa9CtoOzy3c2njgz7LvebQJ8iPxdeTuGnAjagyis8a9ifBw==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@15.3.4': - resolution: {integrity: sha512-l8ZQOCCg7adwmsnFm8m5q9eIPAHdaB2F3cxhufYtVo84pymwKuWfpYTKcUiFcutJdp9xGHC+F1Uq3xnFU1B/7g==} + '@next/swc-linux-arm64-gnu@15.5.14': + resolution: {integrity: sha512-tjlpia+yStPRS//6sdmlVwuO1Rioern4u2onafa5n+h2hCS9MAvMXqpVbSrjgiEOoCs0nJy7oPOmWgtRRNSM5Q==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] libc: [glibc] - '@next/swc-linux-arm64-musl@15.3.4': - resolution: {integrity: sha512-wFyZ7X470YJQtpKot4xCY3gpdn8lE9nTlldG07/kJYexCUpX1piX+MBfZdvulo+t1yADFVEuzFfVHfklfEx8kw==} + '@next/swc-linux-arm64-musl@15.5.14': + resolution: {integrity: sha512-8B8cngBaLadl5lbDRdxGCP1Lef8ipD6KlxS3v0ElDAGil6lafrAM3B258p1KJOglInCVFUjk751IXMr2ixeQOQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] libc: [musl] - '@next/swc-linux-x64-gnu@15.3.4': - resolution: {integrity: sha512-gEbH9rv9o7I12qPyvZNVTyP/PWKqOp8clvnoYZQiX800KkqsaJZuOXkWgMa7ANCCh/oEN2ZQheh3yH8/kWPSEg==} + '@next/swc-linux-x64-gnu@15.5.14': + resolution: {integrity: sha512-bAS6tIAg8u4Gn3Nz7fCPpSoKAexEt2d5vn1mzokcqdqyov6ZJ6gu6GdF9l8ORFrBuRHgv3go/RfzYz5BkZ6YSQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] libc: [glibc] - '@next/swc-linux-x64-musl@15.3.4': - resolution: {integrity: sha512-Cf8sr0ufuC/nu/yQ76AnarbSAXcwG/wj+1xFPNbyNo8ltA6kw5d5YqO8kQuwVIxk13SBdtgXrNyom3ZosHAy4A==} + '@next/swc-linux-x64-musl@15.5.14': + resolution: {integrity: sha512-mMxv/FcrT7Gfaq4tsR22l17oKWXZmH/lVqcvjX0kfp5I0lKodHYLICKPoX1KRnnE+ci6oIUdriUhuA3rBCDiSw==} engines: {node: '>= 10'} cpu: [x64] os: [linux] libc: [musl] - '@next/swc-win32-arm64-msvc@15.3.4': - resolution: {integrity: sha512-ay5+qADDN3rwRbRpEhTOreOn1OyJIXS60tg9WMYTWCy3fB6rGoyjLVxc4dR9PYjEdR2iDYsaF5h03NA+XuYPQQ==} + '@next/swc-win32-arm64-msvc@15.5.14': + resolution: {integrity: sha512-OTmiBlYThppnvnsqx0rBqjDRemlmIeZ8/o4zI7veaXoeO1PVHoyj2lfTfXTiiGjCyRDhA10y4h6ZvZvBiynr2g==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-x64-msvc@15.3.4': - resolution: {integrity: sha512-4kDt31Bc9DGyYs41FTL1/kNpDeHyha2TC0j5sRRoKCyrhNcfZ/nRQkAUlF27mETwm8QyHqIjHJitfcza2Iykfg==} + '@next/swc-win32-x64-msvc@15.5.14': + resolution: {integrity: sha512-+W7eFf3RS7m4G6tppVTOSyP9Y6FsJXfOuKzav1qKniiFm3KFByQfPEcouHdjlZmysl4zJGuGLQ/M9XyVeyeNEg==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -2921,9 +2918,6 @@ packages: resolution: {integrity: sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==} engines: {node: '>=10'} - '@swc/counter@0.1.3': - resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} @@ -4088,10 +4082,6 @@ packages: engines: {node: '>=18'} hasBin: true - busboy@1.6.0: - resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} - engines: {node: '>=10.16.0'} - bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} @@ -7100,13 +7090,13 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - next@15.3.4: - resolution: {integrity: sha512-mHKd50C+mCjam/gcnwqL1T1vPx/XQNFlXqFIVdgQdVAFY9iIQtY0IfaVflEYzKiqjeA7B0cYYMaCrmAYFjs4rA==} + next@15.5.14: + resolution: {integrity: sha512-M6S+4JyRjmKic2Ssm7jHUPkE6YUJ6lv4507jprsSZLulubz0ihO2E+S4zmQK3JZ2ov81JrugukKU4Tz0ivgqqQ==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 - '@playwright/test': ^1.41.2 + '@playwright/test': ^1.51.1 babel-plugin-react-compiler: '*' react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 @@ -8692,10 +8682,6 @@ packages: stream-transform@2.1.3: resolution: {integrity: sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==} - streamsearch@1.1.0: - resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} - engines: {node: '>=10.0.0'} - string-format@2.0.0: resolution: {integrity: sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==} @@ -11075,11 +11061,6 @@ snapshots: tslib: 2.8.1 optional: true - '@emnapi/runtime@1.4.3': - dependencies: - tslib: 2.8.1 - optional: true - '@emnapi/runtime@1.4.5': dependencies: tslib: 2.8.1 @@ -12015,7 +11996,7 @@ snapshots: '@napi-rs/wasm-runtime@0.2.11': dependencies: '@emnapi/core': 1.4.3 - '@emnapi/runtime': 1.4.3 + '@emnapi/runtime': 1.4.5 '@tybys/wasm-util': 0.9.0 optional: true @@ -12115,34 +12096,34 @@ snapshots: depd: 2.0.0 mustache: 4.2.0 - '@next/env@15.3.4': {} + '@next/env@15.5.14': {} '@next/eslint-plugin-next@14.0.4': dependencies: glob: 7.1.7 - '@next/swc-darwin-arm64@15.3.4': + '@next/swc-darwin-arm64@15.5.14': optional: true - '@next/swc-darwin-x64@15.3.4': + '@next/swc-darwin-x64@15.5.14': optional: true - '@next/swc-linux-arm64-gnu@15.3.4': + '@next/swc-linux-arm64-gnu@15.5.14': optional: true - '@next/swc-linux-arm64-musl@15.3.4': + '@next/swc-linux-arm64-musl@15.5.14': optional: true - '@next/swc-linux-x64-gnu@15.3.4': + '@next/swc-linux-x64-gnu@15.5.14': optional: true - '@next/swc-linux-x64-musl@15.3.4': + '@next/swc-linux-x64-musl@15.5.14': optional: true - '@next/swc-win32-arm64-msvc@15.3.4': + '@next/swc-win32-arm64-msvc@15.5.14': optional: true - '@next/swc-win32-x64-msvc@15.3.4': + '@next/swc-win32-x64-msvc@15.5.14': optional: true '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': @@ -12525,8 +12506,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@swc/counter@0.1.3': {} - '@swc/helpers@0.5.15': dependencies: tslib: 2.8.1 @@ -14008,10 +13987,6 @@ snapshots: - debug - typescript - busboy@1.6.0: - dependencies: - streamsearch: 1.1.0 - bytes@3.1.2: {} cac@6.7.14: {} @@ -17877,26 +17852,24 @@ snapshots: neo-async@2.6.2: {} - next@15.3.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next@15.5.14(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@next/env': 15.3.4 - '@swc/counter': 0.1.3 + '@next/env': 15.5.14 '@swc/helpers': 0.5.15 - busboy: 1.6.0 caniuse-lite: 1.0.30001726 postcss: 8.4.31 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) styled-jsx: 5.1.6(react@18.3.1) optionalDependencies: - '@next/swc-darwin-arm64': 15.3.4 - '@next/swc-darwin-x64': 15.3.4 - '@next/swc-linux-arm64-gnu': 15.3.4 - '@next/swc-linux-arm64-musl': 15.3.4 - '@next/swc-linux-x64-gnu': 15.3.4 - '@next/swc-linux-x64-musl': 15.3.4 - '@next/swc-win32-arm64-msvc': 15.3.4 - '@next/swc-win32-x64-msvc': 15.3.4 + '@next/swc-darwin-arm64': 15.5.14 + '@next/swc-darwin-x64': 15.5.14 + '@next/swc-linux-arm64-gnu': 15.5.14 + '@next/swc-linux-arm64-musl': 15.5.14 + '@next/swc-linux-x64-gnu': 15.5.14 + '@next/swc-linux-x64-musl': 15.5.14 + '@next/swc-win32-arm64-msvc': 15.5.14 + '@next/swc-win32-x64-msvc': 15.5.14 sharp: 0.34.3 transitivePeerDependencies: - '@babel/core' @@ -19702,8 +19675,6 @@ snapshots: dependencies: mixme: 0.5.10 - streamsearch@1.1.0: {} - string-format@2.0.0: {} string-length@4.0.2: From f982815fa3c83bd500ab145bbac91690ecf745e9 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 21 Apr 2026 09:47:38 -0400 Subject: [PATCH 292/303] Bump qs from 6.14.0 to 6.14.2. --- packages/shared/package.json | 2 +- pnpm-lock.yaml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/shared/package.json b/packages/shared/package.json index 6322499c6..88187fcba 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -47,7 +47,7 @@ "axios": "^1.8.4", "deep-equal": "^2.2.3", "ethers": "^5.8.0", - "qs": "^6.14.0", + "qs": "^6.14.2", "zod": "^3.24.2" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6b87841de..94826c8e9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -528,8 +528,8 @@ importers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) qs: - specifier: ^6.14.0 - version: 6.14.0 + specifier: ^6.14.2 + version: 6.15.1 zod: specifier: ^3.24.2 version: 3.25.67 @@ -8013,8 +8013,8 @@ packages: resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} engines: {node: '>=0.6'} - qs@6.14.0: - resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + qs@6.15.1: + resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} engines: {node: '>=0.6'} quansync@0.2.10: @@ -12167,7 +12167,7 @@ snapshots: axios: 1.15.0 deep-equal: 2.2.3 ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - qs: 6.14.0 + qs: 6.15.1 zod: 3.25.67 transitivePeerDependencies: - bufferutil @@ -18768,7 +18768,7 @@ snapshots: dependencies: side-channel: 1.1.0 - qs@6.14.0: + qs@6.15.1: dependencies: side-channel: 1.1.0 From 7a2c321bbb88c1365c7912507e4a59cd3134b6bf Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 21 Apr 2026 09:49:53 -0400 Subject: [PATCH 293/303] Bump axios to 1.13.5. --- packages/shared/package.json | 2 +- packages/test-utils/package.json | 2 +- pnpm-lock.yaml | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/shared/package.json b/packages/shared/package.json index 88187fcba..08aae5684 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -44,7 +44,7 @@ "@ethersproject/providers": "^5.8.0", "@nucypher/nucypher-contracts": "^0.26.0-alpha.3", "@nucypher/nucypher-core": "^0.15.1-dev.3", - "axios": "^1.8.4", + "axios": "^1.13.5", "deep-equal": "^2.2.3", "ethers": "^5.8.0", "qs": "^6.14.2", diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 77cb5d995..3fe7874e6 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -32,7 +32,7 @@ "@nucypher/nucypher-core": "^0.15.1-dev.3", "@nucypher/shared": "workspace:*", "@nucypher/taco-auth": "workspace:*", - "axios": "^1.11.0", + "axios": "^1.13.5", "ethers": "^5.8.0", "vitest": "^3.0.9" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 94826c8e9..44ec4510a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -519,8 +519,8 @@ importers: specifier: ^0.15.1-dev.3 version: 0.15.1-dev.3 axios: - specifier: ^1.8.4 - version: 1.10.0 + specifier: ^1.13.5 + version: 1.15.0 deep-equal: specifier: ^2.2.3 version: 2.2.3 @@ -636,7 +636,7 @@ importers: specifier: workspace:* version: link:../taco-auth axios: - specifier: ^1.11.0 + specifier: ^1.13.5 version: 1.15.0 ethers: specifier: ^5.8.0 @@ -16512,7 +16512,7 @@ snapshots: http-proxy@1.18.1: dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.9 + follow-redirects: 1.16.0 requires-port: 1.0.0 transitivePeerDependencies: - debug From 423c976bfae334f20670797c7b1a9315f59838c0 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 21 Apr 2026 10:16:30 -0400 Subject: [PATCH 294/303] Bump glob to 11.1.0. --- packages/taco/package.json | 2 +- pnpm-lock.yaml | 55 +++++++++++++++++++------------------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/packages/taco/package.json b/packages/taco/package.json index b0b34ba9e..d8f270169 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -54,7 +54,7 @@ "@types/semver": "^7.7.0", "axios": "^1.8.4", "dotenv": "^16.5.0", - "glob": "^11.0.1", + "glob": "^11.1.0", "modified-zod2md": "0.1.5-modified.4", "zod-to-json-schema": "^3.24.5" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 44ec4510a..a126b9c34 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -596,8 +596,8 @@ importers: specifier: ^16.5.0 version: 16.5.0 glob: - specifier: ^11.0.1 - version: 11.0.3 + specifier: ^11.1.0 + version: 11.1.0 modified-zod2md: specifier: 0.1.5-modified.4 version: 0.1.5-modified.4(zod@3.25.67) @@ -2282,14 +2282,6 @@ packages: deprecated: 'Arweave support is deprecated - We recommend migrating to the Irys datachain: https://migrate-to.irys.xyz/' hasBin: true - '@isaacs/balanced-match@4.0.1': - resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} - engines: {node: 20 || >=22} - - '@isaacs/brace-expansion@5.0.0': - resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} - engines: {node: 20 || >=22} - '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -3921,6 +3913,10 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + base-x@3.0.11: resolution: {integrity: sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==} @@ -3998,6 +3994,10 @@ packages: brace-expansion@2.0.2: resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + brace-expansion@5.0.5: + resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} + engines: {node: 18 || 20 || >=22} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} @@ -5733,18 +5733,19 @@ packages: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true - glob@11.0.3: - resolution: {integrity: sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==} + glob@11.1.0: + resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==} engines: {node: 20 || >=22} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true glob@7.1.7: resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me global-directory@4.0.1: resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} @@ -6966,9 +6967,9 @@ packages: minimalistic-crypto-utils@1.0.1: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} - minimatch@10.0.3: - resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} - engines: {node: 20 || >=22} + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -11728,12 +11729,6 @@ snapshots: - typescript - utf-8-validate - '@isaacs/balanced-match@4.0.1': {} - - '@isaacs/brace-expansion@5.0.0': - dependencies: - '@isaacs/balanced-match': 4.0.1 - '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -13767,6 +13762,8 @@ snapshots: balanced-match@1.0.2: {} + balanced-match@4.0.4: {} + base-x@3.0.11: dependencies: safe-buffer: 5.2.1 @@ -13864,6 +13861,10 @@ snapshots: dependencies: balanced-match: 1.0.2 + brace-expansion@5.0.5: + dependencies: + balanced-match: 4.0.4 + braces@3.0.3: dependencies: fill-range: 7.1.1 @@ -16243,11 +16244,11 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 - glob@11.0.3: + glob@11.1.0: dependencies: foreground-child: 3.3.1 jackspeak: 4.1.1 - minimatch: 10.0.3 + minimatch: 10.2.5 minipass: 7.1.2 package-json-from-dist: 1.0.1 path-scurry: 2.0.0 @@ -17743,9 +17744,9 @@ snapshots: minimalistic-crypto-utils@1.0.1: {} - minimatch@10.0.3: + minimatch@10.2.5: dependencies: - '@isaacs/brace-expansion': 5.0.0 + brace-expansion: 5.0.5 minimatch@3.1.2: dependencies: From e455cbace2a9bff0d4e71d5430154bf1e9b0d154 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 21 Apr 2026 10:30:52 -0400 Subject: [PATCH 295/303] Bunp actions/setup-node from 4 to 6. --- .github/workflows/lynx.yml | 2 +- .github/workflows/main.yml | 2 +- .github/workflows/mainnet.yml | 2 +- .github/workflows/npm.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/tapir.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/lynx.yml b/.github/workflows/lynx.yml index 0dda49320..3170b2249 100644 --- a/.github/workflows/lynx.yml +++ b/.github/workflows/lynx.yml @@ -31,7 +31,7 @@ jobs: with: version: 9 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v6 with: node-version: ${{ matrix.node }} cache: 'pnpm' diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 971c863fa..aa112a255 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,7 +17,7 @@ jobs: - uses: pnpm/action-setup@v4 with: version: 9 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v6 with: node-version: ${{ matrix.node }} cache: 'pnpm' diff --git a/.github/workflows/mainnet.yml b/.github/workflows/mainnet.yml index d6c5ec860..913e8cb4a 100644 --- a/.github/workflows/mainnet.yml +++ b/.github/workflows/mainnet.yml @@ -29,7 +29,7 @@ jobs: with: version: 9 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v6 with: node-version: ${{ matrix.node }} cache: 'pnpm' diff --git a/.github/workflows/npm.yml b/.github/workflows/npm.yml index 6a5df4521..93152ecb2 100644 --- a/.github/workflows/npm.yml +++ b/.github/workflows/npm.yml @@ -17,7 +17,7 @@ jobs: - uses: pnpm/action-setup@v4 with: version: 9 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v6 with: node-version: ${{ matrix.node }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1ec57b994..8626a5009 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: - uses: pnpm/action-setup@v4 with: version: 9 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v6 with: node-version: ${{ matrix.node }} cache: 'pnpm' diff --git a/.github/workflows/tapir.yml b/.github/workflows/tapir.yml index 66523f192..e894ddafe 100644 --- a/.github/workflows/tapir.yml +++ b/.github/workflows/tapir.yml @@ -33,7 +33,7 @@ jobs: with: version: 9 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v6 with: node-version: ${{ matrix.node }} cache: 'pnpm' From c3f02a16374e51b8835afb4d8456340c02bf01d3 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 21 Apr 2026 10:37:21 -0400 Subject: [PATCH 296/303] Bump actions/checkout from 5 to 6. --- .github/workflows/lynx.yml | 2 +- .github/workflows/main.yml | 2 +- .github/workflows/mainnet.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/tapir.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/lynx.yml b/.github/workflows/lynx.yml index 3170b2249..c3e2a1164 100644 --- a/.github/workflows/lynx.yml +++ b/.github/workflows/lynx.yml @@ -25,7 +25,7 @@ jobs: os: [ubuntu-latest] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: pnpm/action-setup@v4 with: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index aa112a255..2cf7a06f8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,7 +12,7 @@ jobs: node: ['22.x', '24.x'] os: [ubuntu-latest] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: pnpm/action-setup@v4 with: diff --git a/.github/workflows/mainnet.yml b/.github/workflows/mainnet.yml index 913e8cb4a..e3b174d21 100644 --- a/.github/workflows/mainnet.yml +++ b/.github/workflows/mainnet.yml @@ -23,7 +23,7 @@ jobs: os: [ubuntu-latest] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: pnpm/action-setup@v4 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8626a5009..0b1d39df3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,7 @@ jobs: name: Publish NPM package using changesets runs-on: 'ubuntu-latest' steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: pnpm/action-setup@v4 with: version: 9 diff --git a/.github/workflows/tapir.yml b/.github/workflows/tapir.yml index e894ddafe..c0ac2096f 100644 --- a/.github/workflows/tapir.yml +++ b/.github/workflows/tapir.yml @@ -27,7 +27,7 @@ jobs: os: [ubuntu-latest] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: pnpm/action-setup@v4 with: From ba281a36d20b4e1756ea13d0dcd35a15e1148575 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 21 Apr 2026 10:43:29 -0400 Subject: [PATCH 297/303] Bump typedoc plugins: zod plugin to 1.4.2 and coverage plugin to 3.4.1. --- package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 9ef80ef5e..77500c7f8 100644 --- a/package.json +++ b/package.json @@ -51,9 +51,9 @@ "ts-node": "^10.9.2", "ts-unused-exports": "^10.1.0", "typedoc": "^0.25.13", - "typedoc-plugin-coverage": "^2.2.0", + "typedoc-plugin-coverage": "^3.4.1", "typedoc-plugin-missing-exports": "^2.3.0", - "typedoc-plugin-zod": "^1.4.0", + "typedoc-plugin-zod": "^1.4.2", "typescript": "^5.8.2", "vitest": "^3.0.9" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a126b9c34..0637d8396 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -92,13 +92,13 @@ importers: specifier: ^0.25.13 version: 0.25.13(typescript@5.8.3) typedoc-plugin-coverage: - specifier: ^2.2.0 - version: 2.2.0(typedoc@0.25.13(typescript@5.8.3)) + specifier: ^3.4.1 + version: 3.4.1(typedoc@0.25.13(typescript@5.8.3)) typedoc-plugin-missing-exports: specifier: ^2.3.0 version: 2.3.0(typedoc@0.25.13(typescript@5.8.3)) typedoc-plugin-zod: - specifier: ^1.4.0 + specifier: ^1.4.2 version: 1.4.2(typedoc@0.25.13(typescript@5.8.3)) typescript: specifier: ^5.8.2 @@ -9169,11 +9169,11 @@ packages: typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - typedoc-plugin-coverage@2.2.0: - resolution: {integrity: sha512-/hq9nwSNBz2p7+VYfljT/zFSmaxN8tlfcIp6CCAaQN6VIxXCciYFIqR+pcckRhjmfHIeSJ5uy2OpCt5F683npA==} - engines: {node: '>= 16'} + typedoc-plugin-coverage@3.4.1: + resolution: {integrity: sha512-V23DAwinAMpGMGcL1R1s8Snr26hrjfIdwGf+4jR/65ZdmeAN+yRX0onfx5JlembTQhR6AePQ/parfQNS0AZ64A==} + engines: {node: '>= 18'} peerDependencies: - typedoc: ^0.22.12 || 0.23.x || 0.24.x || 0.25.x + typedoc: 0.25.x || 0.26.x || 0.27.x typedoc-plugin-missing-exports@2.3.0: resolution: {integrity: sha512-iI9ITNNLlbsLCBBeYDyu0Qqp3GN/9AGyWNKg8bctRXuZEPT7G1L+0+MNWG9MsHcf/BFmNbXL0nQ8mC/tXRicog==} @@ -20217,7 +20217,7 @@ snapshots: typedarray@0.0.6: {} - typedoc-plugin-coverage@2.2.0(typedoc@0.25.13(typescript@5.8.3)): + typedoc-plugin-coverage@3.4.1(typedoc@0.25.13(typescript@5.8.3)): dependencies: typedoc: 0.25.13(typescript@5.8.3) From 524564fdefd5297f6b0cd55491a02e3d792dafe6 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 16 Apr 2026 11:20:38 -0400 Subject: [PATCH 298/303] Update nucypher-core dependency version in lockfile; this version includes AA v0.7 support. --- package.json | 4 ++-- packages/shared/package.json | 2 +- packages/taco/package.json | 2 +- pnpm-lock.yaml | 32 ++++++++++++++++---------------- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 77500c7f8..5baa672cc 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ }, "dependencies": { "@changesets/cli": "^2.28.1", - "@nucypher/nucypher-core": "^0.15.1-dev.3", + "@nucypher/nucypher-core": "^0.15.1-dev.4", "ethers": "^5.8.0" }, "devDependencies": { @@ -65,7 +65,7 @@ ] }, "overrides": { - "@nucypher/nucypher-core": "^0.15.1-dev.3", + "@nucypher/nucypher-core": "^0.15.1-dev.4", "glob-parent@<5.1.2": ">=5.1.2", "node-forge@<1.0.0": ">=1.0.0", "node-forge@<1.3.0": ">=1.3.0", diff --git a/packages/shared/package.json b/packages/shared/package.json index 08aae5684..a68f57bf1 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -43,7 +43,7 @@ "@ethersproject/abi": "^5.8.0", "@ethersproject/providers": "^5.8.0", "@nucypher/nucypher-contracts": "^0.26.0-alpha.3", - "@nucypher/nucypher-core": "^0.15.1-dev.3", + "@nucypher/nucypher-core": "^0.15.1-dev.4", "axios": "^1.13.5", "deep-equal": "^2.2.3", "ethers": "^5.8.0", diff --git a/packages/taco/package.json b/packages/taco/package.json index d8f270169..fdb49227d 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -42,7 +42,7 @@ }, "dependencies": { "@astronautlabs/jsonpath": "^1.1.2", - "@nucypher/nucypher-core": "^0.15.1-dev.3", + "@nucypher/nucypher-core": "^0.15.1-dev.4", "@nucypher/shared": "workspace:*", "@nucypher/taco-auth": "workspace:*", "ethers": "^5.8.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0637d8396..010aec7ab 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,7 @@ settings: excludeLinksFromLockfile: false overrides: - '@nucypher/nucypher-core': ^0.15.1-dev.3 + '@nucypher/nucypher-core': ^0.15.1-dev.4 glob-parent@<5.1.2: '>=5.1.2' node-forge@<1.0.0: '>=1.0.0' node-forge@<1.3.0: '>=1.3.0' @@ -19,8 +19,8 @@ importers: specifier: ^2.28.1 version: 2.29.5 '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.3 - version: 0.15.1-dev.3 + specifier: ^0.15.1-dev.4 + version: 0.15.1-dev.4 ethers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -491,8 +491,8 @@ importers: packages/pre: dependencies: '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.3 - version: 0.15.1-dev.3 + specifier: ^0.15.1-dev.4 + version: 0.15.1-dev.4 '@nucypher/shared': specifier: workspace:* version: link:../shared @@ -516,8 +516,8 @@ importers: specifier: ^0.26.0-alpha.3 version: 0.26.0-alpha.3 '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.3 - version: 0.15.1-dev.3 + specifier: ^0.15.1-dev.4 + version: 0.15.1-dev.4 axios: specifier: ^1.13.5 version: 1.15.0 @@ -565,8 +565,8 @@ importers: specifier: ^1.1.2 version: 1.1.2 '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.3 - version: 0.15.1-dev.3 + specifier: ^0.15.1-dev.4 + version: 0.15.1-dev.4 '@nucypher/shared': specifier: workspace:* version: link:../shared @@ -627,8 +627,8 @@ importers: packages/test-utils: dependencies: '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.3 - version: 0.15.1-dev.3 + specifier: ^0.15.1-dev.4 + version: 0.15.1-dev.4 '@nucypher/shared': specifier: workspace:* version: link:../shared @@ -2558,8 +2558,8 @@ packages: '@nucypher/nucypher-contracts@0.26.0-alpha.3': resolution: {integrity: sha512-BQSDTl+E77JHS0ck79vyGQTPjTFZieWaKY1nSAghQGTS3drOU21loqe9v6221zlycU6T1cZ4c3ffGXW3qc37ng==} - '@nucypher/nucypher-core@0.15.1-dev.3': - resolution: {integrity: sha512-0MJ8XvH2X5OyEx+f2i9A2iA+KosHzxZbOt8V3Ye6ZDlMC5N4aeDOEJ02ftwnc0C0NO0CPqTuLlYGbrreW57K+w==} + '@nucypher/nucypher-core@0.15.1-dev.4': + resolution: {integrity: sha512-PQvWV7jsa8LSaYaCCIujebVAx897W2t77cfKw5/Gn6hIiFqm6Idw6QZl2SnSND09ZuuPM/eH/s1jJgaFVGUwWQ==} '@nucypher/shared@0.5.0': resolution: {integrity: sha512-Y+0oEgVtoud4BP/pvj2elPm5igrQ8AAUwYYmUiLpXNqQMRF4zFnYaGbl+xhKk45CYG8S9cDKJEN8nopzVADTNw==} @@ -12151,14 +12151,14 @@ snapshots: '@nucypher/nucypher-contracts@0.26.0-alpha.3': {} - '@nucypher/nucypher-core@0.15.1-dev.3': {} + '@nucypher/nucypher-core@0.15.1-dev.4': {} '@nucypher/shared@0.5.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@ethersproject/abi': 5.8.0 '@ethersproject/providers': 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@nucypher/nucypher-contracts': 0.25.0 - '@nucypher/nucypher-core': 0.15.1-dev.3 + '@nucypher/nucypher-core': 0.15.1-dev.4 axios: 1.15.0 deep-equal: 2.2.3 ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -12184,7 +12184,7 @@ snapshots: '@nucypher/taco@0.6.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@astronautlabs/jsonpath': 1.1.2 - '@nucypher/nucypher-core': 0.15.1-dev.3 + '@nucypher/nucypher-core': 0.15.1-dev.4 '@nucypher/shared': 0.5.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@nucypher/taco-auth': 0.3.0(bufferutil@4.0.9)(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) From 9bd2525460be04452d5a66f038daa7f20cd2adb7 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 16 Apr 2026 11:21:30 -0400 Subject: [PATCH 299/303] Allow 0.7.0 to be specified for an AA version; update tests. --- packages/taco/src/sign.ts | 2 +- packages/taco/test/taco-sign.test.ts | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 31b5c62bf..27547cae7 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -160,7 +160,7 @@ export async function signUserOp( cohortId: number, chainId: number, userOp: UserOperationToSign | PackedUserOperationToSign, - aaVersion: 'mdt' | '0.8.0' | string, + aaVersion: 'mdt' | '0.7.0' | '0.8.0' | string, context?: ConditionContext, porterUris?: string[], ): Promise { diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index 7de3f3d0d..356482db9 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -347,6 +347,8 @@ describe('TACo Signing', () => { const threshold = 2; it.each([ + ['0.7.0', userOp], + ['0.7.0', packedUserOp], ['0.8.0', userOp], ['0.8.0', packedUserOp], ['mdt', userOp], @@ -406,7 +408,10 @@ describe('TACo Signing', () => { threshold, ); - const call = porterSignUserOpMock.mock.calls[porterSignUserOpMock.mock.calls.length - 1]!; + const call = + porterSignUserOpMock.mock.calls[ + porterSignUserOpMock.mock.calls.length - 1 + ]!; const [op] = call; const nodes = ['0xnode1', '0xnode2']; @@ -483,7 +488,10 @@ describe('TACo Signing', () => { }, threshold, ); - const call = porterSignUserOpMock.mock.calls[porterSignUserOpMock.mock.calls.length - 1]!; + const call = + porterSignUserOpMock.mock.calls[ + porterSignUserOpMock.mock.calls.length - 1 + ]!; const [op] = call; const nodes = ['0xnode1', '0xnode2']; From 2fa2ef56eff976ebc4de4c20130d3440c97d40af Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 17 Apr 2026 10:09:01 -0400 Subject: [PATCH 300/303] Remove |string to constrain values that can be provided for aaVersion parameter Update test. --- packages/taco/src/sign.ts | 2 +- packages/taco/test/taco-sign.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index 27547cae7..d7425b7e1 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -160,7 +160,7 @@ export async function signUserOp( cohortId: number, chainId: number, userOp: UserOperationToSign | PackedUserOperationToSign, - aaVersion: 'mdt' | '0.7.0' | '0.8.0' | string, + aaVersion: 'mdt' | '0.7.0' | '0.8.0', context?: ConditionContext, porterUris?: string[], ): Promise { diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index 356482db9..cfb5ba16f 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -395,7 +395,7 @@ describe('TACo Signing', () => { cohortId, chainId, userOp, - validAAVersion, + validAAVersion as 'mdt' | '0.7.0' | '0.8.0', undefined, porterUris, ); From a9c2a47a04e41007a50fca850c320e30d86af429 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 21 Apr 2026 08:59:43 -0400 Subject: [PATCH 301/303] Update `nucypher-core` version used in pre and test-utils packages. --- packages/pre/package.json | 2 +- packages/test-utils/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/pre/package.json b/packages/pre/package.json index 0bbd16163..46901b4d4 100644 --- a/packages/pre/package.json +++ b/packages/pre/package.json @@ -38,7 +38,7 @@ "typedoc": "typedoc" }, "dependencies": { - "@nucypher/nucypher-core": "^0.15.1-dev.3", + "@nucypher/nucypher-core": "^0.15.1-dev.4", "@nucypher/shared": "workspace:*", "ethers": "^5.8.0" }, diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 3fe7874e6..2c6b36a9c 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -29,7 +29,7 @@ "lint:fix": "pnpm lint --fix" }, "dependencies": { - "@nucypher/nucypher-core": "^0.15.1-dev.3", + "@nucypher/nucypher-core": "^0.15.1-dev.4", "@nucypher/shared": "workspace:*", "@nucypher/taco-auth": "workspace:*", "axios": "^1.13.5", From da4737f67ea6acdfcc97f06b3bb77ba85841414c Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 21 Apr 2026 09:00:50 -0400 Subject: [PATCH 302/303] Define and export AAVersion type. Update test to use new type. --- packages/taco/src/index.ts | 1 + packages/taco/src/sign.ts | 6 ++++-- packages/taco/test/taco-sign.test.ts | 13 ++++++++----- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/taco/src/index.ts b/packages/taco/src/index.ts index 866ce1c24..a2fe19992 100644 --- a/packages/taco/src/index.ts +++ b/packages/taco/src/index.ts @@ -14,6 +14,7 @@ export { export * as conditions from './conditions'; export { + AAVersion, SignResult, TacoSignature, setSigningCohortConditions, diff --git a/packages/taco/src/sign.ts b/packages/taco/src/sign.ts index d7425b7e1..0f220771a 100644 --- a/packages/taco/src/sign.ts +++ b/packages/taco/src/sign.ts @@ -50,6 +50,8 @@ export type SignResult = { signingResults: { [ursulaAddress: string]: TacoSignature }; }; +export type AAVersion = '0.8.0' | 'mdt' | '0.7.0'; + function aggregateSignatures( signatures: TacoSignature[], threshold: number, @@ -83,7 +85,7 @@ async function makeSigningRequests( chainId: number, signers: Array, userOp: UserOperationToSign | PackedUserOperationToSign, - aaVersion: string, + aaVersion: AAVersion, conditionContext?: ConditionContext, ): Promise<{ sharedSecrets: Record; @@ -160,7 +162,7 @@ export async function signUserOp( cohortId: number, chainId: number, userOp: UserOperationToSign | PackedUserOperationToSign, - aaVersion: 'mdt' | '0.7.0' | '0.8.0', + aaVersion: AAVersion, context?: ConditionContext, porterUris?: string[], ): Promise { diff --git a/packages/taco/test/taco-sign.test.ts b/packages/taco/test/taco-sign.test.ts index cfb5ba16f..0498ea19e 100644 --- a/packages/taco/test/taco-sign.test.ts +++ b/packages/taco/test/taco-sign.test.ts @@ -26,7 +26,7 @@ import { ContractCondition } from '../src/conditions/base/contract'; import { RpcCondition } from '../src/conditions/base/rpc'; import { CompoundCondition } from '../src/conditions/compound-condition'; import { ConditionExpression } from '../src/conditions/condition-expr'; -import { setSigningCohortConditions, signUserOp } from '../src/sign'; +import { AAVersion, setSigningCohortConditions, signUserOp } from '../src/sign'; import { mockMakeSessionKey } from './test-utils'; @@ -346,17 +346,20 @@ describe('TACo Signing', () => { const aaVersion = '0.8.0'; const threshold = 2; - it.each([ + const validAAVersionCases: Array< + [AAVersion, UserOperationToSign | PackedUserOperationToSign] + > = [ ['0.7.0', userOp], ['0.7.0', packedUserOp], ['0.8.0', userOp], ['0.8.0', packedUserOp], ['mdt', userOp], ['mdt', packedUserOp], - ])( + ]; + it.each(validAAVersionCases)( 'should sign user operation and packed user operations for valid aa versions', async ( - validAAVersion: string, + validAAVersion: AAVersion, userOp: UserOperationToSign | PackedUserOperationToSign, ) => { const encryptedResponses = { @@ -395,7 +398,7 @@ describe('TACo Signing', () => { cohortId, chainId, userOp, - validAAVersion as 'mdt' | '0.7.0' | '0.8.0', + validAAVersion, undefined, porterUris, ); From d90e3c6bfdb52a41a75059d41e1e9a74ff618070 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 28 Apr 2026 14:59:15 -0400 Subject: [PATCH 303/303] Update nucypher-core dependency to 0.16.0. --- package.json | 4 ++-- packages/pre/package.json | 2 +- packages/shared/package.json | 2 +- packages/taco/package.json | 2 +- packages/test-utils/package.json | 2 +- pnpm-lock.yaml | 32 ++++++++++++++++---------------- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index 5baa672cc..f5dfb2751 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ }, "dependencies": { "@changesets/cli": "^2.28.1", - "@nucypher/nucypher-core": "^0.15.1-dev.4", + "@nucypher/nucypher-core": "^0.16.0", "ethers": "^5.8.0" }, "devDependencies": { @@ -65,7 +65,7 @@ ] }, "overrides": { - "@nucypher/nucypher-core": "^0.15.1-dev.4", + "@nucypher/nucypher-core": "^0.16.0", "glob-parent@<5.1.2": ">=5.1.2", "node-forge@<1.0.0": ">=1.0.0", "node-forge@<1.3.0": ">=1.3.0", diff --git a/packages/pre/package.json b/packages/pre/package.json index 46901b4d4..e27e3a3f3 100644 --- a/packages/pre/package.json +++ b/packages/pre/package.json @@ -38,7 +38,7 @@ "typedoc": "typedoc" }, "dependencies": { - "@nucypher/nucypher-core": "^0.15.1-dev.4", + "@nucypher/nucypher-core": "^0.16.0", "@nucypher/shared": "workspace:*", "ethers": "^5.8.0" }, diff --git a/packages/shared/package.json b/packages/shared/package.json index a68f57bf1..1159aaa37 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -43,7 +43,7 @@ "@ethersproject/abi": "^5.8.0", "@ethersproject/providers": "^5.8.0", "@nucypher/nucypher-contracts": "^0.26.0-alpha.3", - "@nucypher/nucypher-core": "^0.15.1-dev.4", + "@nucypher/nucypher-core": "^0.16.0", "axios": "^1.13.5", "deep-equal": "^2.2.3", "ethers": "^5.8.0", diff --git a/packages/taco/package.json b/packages/taco/package.json index fdb49227d..f2e4e9fab 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -42,7 +42,7 @@ }, "dependencies": { "@astronautlabs/jsonpath": "^1.1.2", - "@nucypher/nucypher-core": "^0.15.1-dev.4", + "@nucypher/nucypher-core": "^0.16.0", "@nucypher/shared": "workspace:*", "@nucypher/taco-auth": "workspace:*", "ethers": "^5.8.0", diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 2c6b36a9c..d6c7f3ec0 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -29,7 +29,7 @@ "lint:fix": "pnpm lint --fix" }, "dependencies": { - "@nucypher/nucypher-core": "^0.15.1-dev.4", + "@nucypher/nucypher-core": "^0.16.0", "@nucypher/shared": "workspace:*", "@nucypher/taco-auth": "workspace:*", "axios": "^1.13.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 010aec7ab..2f0f5c1a0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,7 @@ settings: excludeLinksFromLockfile: false overrides: - '@nucypher/nucypher-core': ^0.15.1-dev.4 + '@nucypher/nucypher-core': ^0.16.0 glob-parent@<5.1.2: '>=5.1.2' node-forge@<1.0.0: '>=1.0.0' node-forge@<1.3.0: '>=1.3.0' @@ -19,8 +19,8 @@ importers: specifier: ^2.28.1 version: 2.29.5 '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.4 - version: 0.15.1-dev.4 + specifier: ^0.16.0 + version: 0.16.0 ethers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -491,8 +491,8 @@ importers: packages/pre: dependencies: '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.4 - version: 0.15.1-dev.4 + specifier: ^0.16.0 + version: 0.16.0 '@nucypher/shared': specifier: workspace:* version: link:../shared @@ -516,8 +516,8 @@ importers: specifier: ^0.26.0-alpha.3 version: 0.26.0-alpha.3 '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.4 - version: 0.15.1-dev.4 + specifier: ^0.16.0 + version: 0.16.0 axios: specifier: ^1.13.5 version: 1.15.0 @@ -565,8 +565,8 @@ importers: specifier: ^1.1.2 version: 1.1.2 '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.4 - version: 0.15.1-dev.4 + specifier: ^0.16.0 + version: 0.16.0 '@nucypher/shared': specifier: workspace:* version: link:../shared @@ -627,8 +627,8 @@ importers: packages/test-utils: dependencies: '@nucypher/nucypher-core': - specifier: ^0.15.1-dev.4 - version: 0.15.1-dev.4 + specifier: ^0.16.0 + version: 0.16.0 '@nucypher/shared': specifier: workspace:* version: link:../shared @@ -2558,8 +2558,8 @@ packages: '@nucypher/nucypher-contracts@0.26.0-alpha.3': resolution: {integrity: sha512-BQSDTl+E77JHS0ck79vyGQTPjTFZieWaKY1nSAghQGTS3drOU21loqe9v6221zlycU6T1cZ4c3ffGXW3qc37ng==} - '@nucypher/nucypher-core@0.15.1-dev.4': - resolution: {integrity: sha512-PQvWV7jsa8LSaYaCCIujebVAx897W2t77cfKw5/Gn6hIiFqm6Idw6QZl2SnSND09ZuuPM/eH/s1jJgaFVGUwWQ==} + '@nucypher/nucypher-core@0.16.0': + resolution: {integrity: sha512-cvA3G2yvJj0MWSD2fLgY4e8GqNUZLvBwikDOEPVOOVaQYR67OWdDUcSjrlgbGie9R6TPfkw5eyRP1xumPMs28A==} '@nucypher/shared@0.5.0': resolution: {integrity: sha512-Y+0oEgVtoud4BP/pvj2elPm5igrQ8AAUwYYmUiLpXNqQMRF4zFnYaGbl+xhKk45CYG8S9cDKJEN8nopzVADTNw==} @@ -12151,14 +12151,14 @@ snapshots: '@nucypher/nucypher-contracts@0.26.0-alpha.3': {} - '@nucypher/nucypher-core@0.15.1-dev.4': {} + '@nucypher/nucypher-core@0.16.0': {} '@nucypher/shared@0.5.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@ethersproject/abi': 5.8.0 '@ethersproject/providers': 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@nucypher/nucypher-contracts': 0.25.0 - '@nucypher/nucypher-core': 0.15.1-dev.4 + '@nucypher/nucypher-core': 0.16.0 axios: 1.15.0 deep-equal: 2.2.3 ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -12184,7 +12184,7 @@ snapshots: '@nucypher/taco@0.6.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@astronautlabs/jsonpath': 1.1.2 - '@nucypher/nucypher-core': 0.15.1-dev.4 + '@nucypher/nucypher-core': 0.16.0 '@nucypher/shared': 0.5.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@nucypher/taco-auth': 0.3.0(bufferutil@4.0.9)(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)