diff --git a/apps/extension/package.json b/apps/extension/package.json index 4a1bdbe4..cf962bd9 100644 --- a/apps/extension/package.json +++ b/apps/extension/package.json @@ -21,18 +21,18 @@ "@penumbra-labs/registry": "^12.0.0", "@penumbra-zone/bech32m": "10.0.0", "@penumbra-zone/client": "21.0.0", - "@penumbra-zone/crypto-web": "28.0.0", + "@penumbra-zone/crypto-web": "29.0.1", "@penumbra-zone/getters": "20.0.0", "@penumbra-zone/keys": "4.2.1", - "@penumbra-zone/perspective": "36.0.0", + "@penumbra-zone/perspective": "39.0.0", "@penumbra-zone/protobuf": "6.3.0", - "@penumbra-zone/query": "37.0.0", - "@penumbra-zone/services": "41.0.1", - "@penumbra-zone/storage": "36.0.1", + "@penumbra-zone/query": "workspace:*", + "@penumbra-zone/services": "44.0.0", + "@penumbra-zone/storage": "39.0.0", "@penumbra-zone/transport-chrome": "8.0.1", "@penumbra-zone/transport-dom": "7.5.0", - "@penumbra-zone/types": "26.1.0", - "@penumbra-zone/wasm": "32.0.0", + "@penumbra-zone/types": "26.2.1", + "@penumbra-zone/wasm": "33.1.0", "@radix-ui/react-icons": "^1.3.0", "@repo/context": "workspace:*", "@repo/ui": "workspace:*", diff --git a/packages/context/package.json b/packages/context/package.json index 1db7a2fb..45708230 100644 --- a/packages/context/package.json +++ b/packages/context/package.json @@ -19,18 +19,18 @@ "@bufbuild/protobuf": "^1.x", "@penumbra-labs/registry": "^12.0.0", "@penumbra-zone/bech32m": "10.0.0", - "@penumbra-zone/crypto-web": "28.0.0", + "@penumbra-zone/crypto-web": "29.0.1", "@penumbra-zone/getters": "20.0.0", "@penumbra-zone/keys": "4.2.1", - "@penumbra-zone/perspective": "36.0.0", + "@penumbra-zone/perspective": "39.0.0", "@penumbra-zone/protobuf": "6.3.0", - "@penumbra-zone/query": "37.0.0", - "@penumbra-zone/services": "41.0.1", - "@penumbra-zone/storage": "36.0.1", + "@penumbra-zone/query": "workspace:*", + "@penumbra-zone/services": "44.0.0", + "@penumbra-zone/storage": "39.0.0", "@penumbra-zone/transport-chrome": "8.0.1", "@penumbra-zone/transport-dom": "7.5.0", - "@penumbra-zone/types": "26.1.0", - "@penumbra-zone/wasm": "32.0.0", + "@penumbra-zone/types": "26.2.1", + "@penumbra-zone/wasm": "33.1.0", "exponential-backoff": "^3.1.1" } } diff --git a/packages/noble/package.json b/packages/noble/package.json index 3a986fbf..56f81897 100644 --- a/packages/noble/package.json +++ b/packages/noble/package.json @@ -19,6 +19,6 @@ "@cosmjs/stargate": "^0.32.4", "@penumbra-zone/bech32m": "10.0.0", "@penumbra-zone/protobuf": "6.3.0", - "@penumbra-zone/wasm": "32.0.0" + "@penumbra-zone/wasm": "33.1.0" } } diff --git a/packages/query/CHANGELOG.md b/packages/query/CHANGELOG.md new file mode 100644 index 00000000..4689b2f5 --- /dev/null +++ b/packages/query/CHANGELOG.md @@ -0,0 +1,689 @@ +# @penumbra-zone/query + +## 40.0.0 + +### Patch Changes + +- Updated dependencies [838de8a] +- Updated dependencies [ccbe3a5] + - @penumbra-zone/types@26.2.1 + - @penumbra-zone/wasm@33.1.0 + - @penumbra-zone/crypto-web@29.0.1 + +## 39.0.0 + +### Patch Changes + +- Updated dependencies [291bc7d] + - @penumbra-zone/types@26.2.0 + - @penumbra-zone/crypto-web@29.0.0 + - @penumbra-zone/wasm@33.0.0 + +## 38.0.0 + +### Patch Changes + +- Updated dependencies [fa39e46] + - @penumbra-zone/wasm@32.1.0 + +## 37.0.0 + +### Patch Changes + +- Updated dependencies [b5d2922] + - @penumbra-zone/types@26.1.0 + - @penumbra-zone/crypto-web@28.0.0 + - @penumbra-zone/wasm@32.0.0 + +## 36.0.0 + +### Patch Changes + +- Updated dependencies [3269282] + - @penumbra-zone/protobuf@6.3.0 + - @penumbra-zone/bech32m@10.0.0 + - @penumbra-zone/getters@20.0.0 + - @penumbra-zone/types@26.0.0 + - @penumbra-zone/wasm@31.0.0 + - @penumbra-zone/crypto-web@27.0.0 + +## 35.1.0 + +### Minor Changes + +- 8c036f5: batching storage operations with promises + +## 35.0.0 + +### Patch Changes + +- Updated dependencies [48725e3] + - @penumbra-zone/wasm@30.1.0 + +## 34.0.0 + +### Patch Changes + +- 8bf66ea: Remove validator info throttle +- Updated dependencies [e0db143] +- Updated dependencies [e543db4] + - @penumbra-zone/wasm@30.0.0 + - @penumbra-zone/protobuf@6.2.0 + - @penumbra-zone/bech32m@9.0.0 + - @penumbra-zone/getters@19.0.0 + - @penumbra-zone/types@25.0.0 + - @penumbra-zone/crypto-web@26.0.0 + +## 33.0.0 + +### Minor Changes + +- 487e26d: perform idb genesis in the block processor + +### Patch Changes + +- Updated dependencies [735e22b] + - @penumbra-zone/wasm@29.1.0 + +## 32.0.0 + +### Minor Changes + +- b6e32f8: Check for IbcRelays to add to txs + +### Patch Changes + +- Updated dependencies [b6e32f8] +- Updated dependencies [b6e32f8] +- Updated dependencies [b6e32f8] +- Updated dependencies [b6e32f8] + - @penumbra-zone/protobuf@6.1.0 + - @penumbra-zone/bech32m@8.0.0 + - @penumbra-zone/wasm@29.0.0 + - @penumbra-zone/types@24.0.0 + - @penumbra-zone/getters@18.0.0 + - @penumbra-zone/crypto-web@25.0.0 + +## 31.0.1 + +### Patch Changes + +- e343d22: [bug fix] Only process relevant transactions for NFTs +- e343d22: Extract, refactor, and test IdentifyTransactions + +## 31.0.0 + +### Patch Changes + +- Updated dependencies [3a5c074] +- Updated dependencies [3a5c074] +- Updated dependencies [990291f] + - @penumbra-zone/getters@17.0.0 + - @penumbra-zone/wasm@28.0.0 + - @penumbra-zone/types@23.0.0 + - @penumbra-zone/crypto-web@24.0.0 + +## 30.0.0 + +### Major Changes + +- e01d5f8: fresh and existing wallets skip trial decryption + +### Patch Changes + +- Updated dependencies [e01d5f8] + - @penumbra-zone/types@22.0.0 + - @penumbra-zone/wasm@27.0.0 + - @penumbra-zone/crypto-web@23.0.0 + +## 29.0.0 + +### Minor Changes + +- e7d0767: Customize symbol for LP position NFTs + +### Patch Changes + +- Updated dependencies [e7d0767] + - @penumbra-zone/wasm@26.2.0 + +## 28.0.0 + +### Patch Changes + +- Updated dependencies [598d148] + - @penumbra-zone/wasm@26.1.0 + +## 27.0.0 + +### Minor Changes + +- 94d2c8d: special case local genesis sync + +### Patch Changes + +- Updated dependencies [f8730e9] + - @penumbra-zone/getters@16.0.0 + - @penumbra-zone/types@21.0.0 + - @penumbra-zone/crypto-web@22.0.0 + - @penumbra-zone/wasm@26.0.0 + +## 26.0.0 + +### Patch Changes + +- Updated dependencies [49263c6] + - @penumbra-zone/protobuf@6.0.0 + - @penumbra-zone/bech32m@7.0.0 + - @penumbra-zone/getters@15.0.0 + - @penumbra-zone/types@20.0.0 + - @penumbra-zone/wasm@25.0.0 + - @penumbra-zone/crypto-web@21.0.0 + +## 25.0.0 + +### Minor Changes + +- 10ef940: Updating to v0.80.0 bufbuild types + +### Patch Changes + +- Updated dependencies [10ef940] + - @penumbra-zone/protobuf@5.7.0 + - @penumbra-zone/getters@14.0.0 + - @penumbra-zone/types@19.0.0 + - @penumbra-zone/wasm@24.0.0 + - @penumbra-zone/crypto-web@20.0.0 + +## 24.0.0 + +### Minor Changes + +- 807648a: Support viewing fresh state of jailed validators + +### Patch Changes + +- bd43d49: correctly save gas prices from compact block +- Updated dependencies [bd43d49] +- Updated dependencies [bd43d49] +- Updated dependencies [807648a] + - @penumbra-zone/types@18.2.0 + - @penumbra-zone/getters@13.0.1 + - @penumbra-zone/crypto-web@19.0.0 + - @penumbra-zone/wasm@23.0.0 + +## 23.0.0 + +### Patch Changes + +- Updated dependencies [534a6ad] + - @penumbra-zone/wasm@22.1.0 + +## 22.0.0 + +### Patch Changes + +- Updated dependencies [f5bea48] + - @penumbra-zone/types@18.1.0 + - @penumbra-zone/crypto-web@18.0.0 + - @penumbra-zone/wasm@22.0.0 + +## 21.0.0 + +### Patch Changes + +- Updated dependencies [a9ffd2d] +- Updated dependencies + - @penumbra-zone/types@18.0.0 + - @penumbra-zone/protobuf@5.6.0 + - @penumbra-zone/crypto-web@17.0.0 + - @penumbra-zone/wasm@21.0.0 + - @penumbra-zone/getters@13.0.0 + +## 20.0.0 + +### Patch Changes + +- Updated dependencies [318690e] + - @penumbra-zone/wasm@20.2.0 + +## 19.0.0 + +### Patch Changes + +- 3477bef: bugfix: injecting globalThis.**DEV** correctly on prod builds +- Updated dependencies [3477bef] +- Updated dependencies [d6ce325] + - @penumbra-zone/types@17.0.1 + - @penumbra-zone/wasm@20.1.0 + - @penumbra-zone/crypto-web@16.0.1 + +## 18.0.0 + +### Patch Changes + +- Updated dependencies [4e30796] +- Updated dependencies [86c1bbe] + - @penumbra-zone/wasm@20.0.0 + - @penumbra-zone/getters@12.1.0 + - @penumbra-zone/types@17.0.0 + - @penumbra-zone/crypto-web@16.0.0 + +## 17.0.0 + +### Minor Changes + +- 0233722: added proxying timestampByHeight + +### Patch Changes + +- Updated dependencies [0233722] + - @penumbra-zone/types@16.1.0 + - @penumbra-zone/crypto-web@15.0.0 + - @penumbra-zone/wasm@19.0.0 + +## 16.0.0 + +### Patch Changes + +- Updated dependencies [22bf02c] + - @penumbra-zone/protobuf@5.5.0 + - @penumbra-zone/getters@12.0.0 + - @penumbra-zone/wasm@18.0.0 + - @penumbra-zone/types@16.0.0 + - @penumbra-zone/crypto-web@14.0.0 + +## 15.0.2 + +### Patch Changes + +- 3aaead1: Move the "default" option in package.json exports field to the last +- Updated dependencies [3aaead1] + - @penumbra-zone/crypto-web@13.0.1 + - @penumbra-zone/types@15.1.1 + - @penumbra-zone/wasm@17.0.2 + +## 15.0.1 + +### Patch Changes + +- Updated dependencies [1a57749] + - @penumbra-zone/wasm@17.0.1 + +## 15.0.0 + +### Minor Changes + +- 83151cb: Use the generated metadata for delegation tokens + +### Patch Changes + +- Updated dependencies [83151cb] +- Updated dependencies [cbc2419] +- Updated dependencies [877fb1f] +- Updated dependencies [1011b3b] +- Updated dependencies [5641af2] + - @penumbra-zone/wasm@17.0.0 + - @penumbra-zone/types@15.1.0 + - @penumbra-zone/crypto-web@13.0.0 + +## 14.0.0 + +### Minor Changes + +- fa798d9: Bufbuild + registry dep update + +### Patch Changes + +- Updated dependencies [fa798d9] +- Updated dependencies [fa798d9] + - @penumbra-zone/wasm@16.0.0 + - @penumbra-zone/protobuf@5.4.0 + - @penumbra-zone/getters@11.0.0 + - @penumbra-zone/types@15.0.0 + - @penumbra-zone/crypto-web@12.0.0 + +## 13.0.0 + +### Patch Changes + +- Updated dependencies [28a48d7] +- Updated dependencies [28a48d7] + - @penumbra-zone/wasm@15.0.0 + - @penumbra-zone/types@14.0.0 + - @penumbra-zone/crypto-web@11.0.0 + +## 12.0.0 + +### Minor Changes + +- 43ccd96: Modify GasPrices storage to support multi-asset fees + +### Patch Changes + +- Updated dependencies [43ccd96] + - @penumbra-zone/types@13.1.0 + - @penumbra-zone/wasm@14.0.0 + - @penumbra-zone/crypto-web@10.0.0 + +## 11.0.0 + +### Patch Changes + +- 3708e2c: include peer deps as dev deps +- e9e1320: ratelimit validator init, and don't await it. +- Updated dependencies [e9e1320] +- Updated dependencies [3708e2c] +- Updated dependencies [af2d6b6] +- Updated dependencies [2f1c39f] + - @penumbra-zone/protobuf@5.3.1 + - @penumbra-zone/bech32m@6.1.1 + - @penumbra-zone/getters@10.1.0 + - @penumbra-zone/crypto-web@9.0.0 + - @penumbra-zone/types@13.0.0 + - @penumbra-zone/wasm@13.0.0 + +## 10.0.0 + +### Major Changes + +- remove staking token metadata parameter for block processor + +## 9.0.0 + +### Minor Changes + +- Synchronize published @buf deps + +### Patch Changes + +- Updated dependencies + - @penumbra-zone/getters@10.0.0 + - @penumbra-zone/protobuf@5.3.0 + - @penumbra-zone/types@12.0.0 + - @penumbra-zone/wasm@12.0.0 + - @penumbra-zone/crypto-web@8.0.0 + +## 8.0.0 + +### Patch Changes + +- Updated dependencies + - @penumbra-zone/types@11.0.0 + - @penumbra-zone/crypto-web@7.0.0 + - @penumbra-zone/wasm@11.0.0 + +## 7.0.0 + +### Minor Changes + +- 4161587: Update to latest bufbuild deps (v0.77.4) + +### Patch Changes + +- Updated dependencies [4161587] +- Updated dependencies [e207faa] + - @penumbra-zone/protobuf@5.2.0 + - @penumbra-zone/getters@9.0.0 + - @penumbra-zone/types@10.0.0 + - @penumbra-zone/wasm@10.0.0 + - @penumbra-zone/crypto-web@6.0.0 + +## 6.0.0 + +### Minor Changes + +- 9b3f561: properly build esm relative paths + +### Patch Changes + +- Updated dependencies [9b3f561] + - @penumbra-zone/protobuf@5.1.0 + - @penumbra-zone/bech32m@6.1.0 + - @penumbra-zone/getters@8.0.0 + - @penumbra-zone/crypto-web@5.0.0 + - @penumbra-zone/types@9.0.0 + - @penumbra-zone/wasm@9.0.0 + +## 5.0.0 + +### Major Changes + +- f067fab: reconfigure all package builds + +### Patch Changes + +- Updated dependencies [f067fab] + - @penumbra-zone/protobuf@5.0.0 + - @penumbra-zone/bech32m@6.0.0 + - @penumbra-zone/getters@7.0.0 + - @penumbra-zone/crypto-web@4.0.0 + - @penumbra-zone/types@8.0.0 + - @penumbra-zone/wasm@8.0.0 + +## 4.1.1 + +### Patch Changes + +- Updated dependencies [a75256f] +- Updated dependencies [468ecc7] +- Updated dependencies [a75256f] + - @penumbra-zone/bech32m@5.1.0 + - @penumbra-zone/getters@6.2.0 + - @penumbra-zone/protobuf@4.2.0 + - @penumbra-zone/types@7.1.1 + - @penumbra-zone/wasm@7.1.1 + - @penumbra-zone/crypto-web@3.0.11 + +## 4.1.0 + +### Minor Changes + +- ab9d743: decouple service/rpc init + +### Patch Changes + +- 6ee8222: prevent processing the same block twice +- Updated dependencies [ab9d743] +- Updated dependencies [282eabf] +- Updated dependencies [81b9536] +- Updated dependencies [14ba562] +- Updated dependencies [6b06e04] +- Updated dependencies [c8e8d15] + - @penumbra-zone/types@7.1.0 + - @penumbra-zone/protobuf@4.1.0 + - @penumbra-zone/wasm@7.1.0 + - @penumbra-zone/getters@6.1.0 + - @penumbra-zone/crypto-web@3.0.10 + +## 4.0.2 + +### Patch Changes + +- Updated dependencies [8fe4de6] + - @penumbra-zone/protobuf@4.0.0 + - @penumbra-zone/bech32m@5.0.0 + - @penumbra-zone/getters@6.0.0 + - @penumbra-zone/wasm@7.0.0 + - @penumbra-zone/types@7.0.1 + - @penumbra-zone/crypto-web@3.0.9 + +## 4.0.1 + +### Patch Changes + +- Updated dependencies [bb5f621] +- Updated dependencies [8b121ec] + - @penumbra-zone/types@7.0.0 + - @penumbra-zone/protobuf@3.0.0 + - @penumbra-zone/bech32m@4.0.0 + - @penumbra-zone/getters@5.0.0 + - @penumbra-zone/wasm@6.0.0 + - @penumbra-zone/crypto-web@3.0.8 + +## 4.0.0 + +### Major Changes + +- 029eebb: use service definitions from protobuf collection package + +### Minor Changes + +- 3ea1e6c: update buf types dependencies + +### Patch Changes + +- Updated dependencies [120b654] +- Updated dependencies [4f8c150] +- Updated dependencies [029eebb] +- Updated dependencies [029eebb] +- Updated dependencies [e86448e] +- Updated dependencies [3ea1e6c] + - @penumbra-zone/getters@4.1.0 + - @penumbra-zone/protobuf@2.1.0 + - @penumbra-zone/types@6.0.0 + - @penumbra-zone/wasm@5.1.0 + - @penumbra-zone/bech32m@3.2.0 + - @penumbra-zone/crypto-web@3.0.7 + +## 3.2.1 + +### Patch Changes + +- @penumbra-zone/wasm@5.0.1 + +## 3.2.0 + +### Minor Changes + +- e4c9fce: Add features to handle auction withdrawals + +### Patch Changes + +- e35c6f7: Deps bumped to latest +- Updated dependencies [146b48d] +- Updated dependencies [65677c1] +- Updated dependencies [8ccaf30] +- Updated dependencies [8ccaf30] +- Updated dependencies [e35c6f7] +- Updated dependencies [cf63b30] +- Updated dependencies [99feb9d] +- Updated dependencies [e4c9fce] +- Updated dependencies [8ccaf30] + - @penumbra-zone/getters@4.0.0 + - @penumbra-zone/types@5.0.0 + - @penumbra-zone/wasm@5.0.0 + - @penumbra-zone/bech32m@3.1.1 + - @penumbra-zone/crypto-web@3.0.6 + +## 3.1.0 + +### Minor Changes + +- v8.0.0 versioning and manifest + +### Patch Changes + +- Updated dependencies + - @penumbra-zone/bech32m@3.1.0 + - @penumbra-zone/types@4.1.0 + - @penumbra-zone/wasm@4.0.4 + - @penumbra-zone/getters@3.0.2 + - @penumbra-zone/crypto-web@3.0.5 + +## 3.0.2 + +### Patch Changes + +- Updated dependencies [8410d2f] + - @penumbra-zone/bech32m@3.0.1 + - @penumbra-zone/getters@3.0.1 + - @penumbra-zone/types@4.0.1 + - @penumbra-zone/wasm@4.0.3 + - @penumbra-zone/crypto-web@3.0.4 + +## 3.0.1 + +### Patch Changes + +- Updated dependencies [6fb898a] + - @penumbra-zone/types@4.0.0 + - @penumbra-zone/crypto-web@3.0.3 + - @penumbra-zone/wasm@4.0.2 + +## 3.0.0 + +### Major Changes + +- 3148375: remove `/src/` path segment from exports + +### Minor Changes + +- 55f31c9: Save sct positions of swaps + +### Patch Changes + +- Updated dependencies [3148375] +- Updated dependencies [fdd4303] + - @penumbra-zone/constants@4.0.0 + - @penumbra-zone/polyfills@3.0.0 + - @penumbra-zone/getters@3.0.0 + - @penumbra-zone/types@3.0.0 + - @penumbra-zone/bech32m@3.0.0 + - @penumbra-zone/crypto-web@3.0.2 + - @penumbra-zone/wasm@4.0.1 + +## 2.0.3 + +### Patch Changes + +- Updated dependencies [78ab976] +- Updated dependencies [862283c] + - @penumbra-zone/wasm@4.0.0 + - @penumbra-zone/constants@3.0.0 + - @penumbra-zone/getters@2.0.1 + - @penumbra-zone/types@2.0.1 + - @penumbra-zone/crypto-web@3.0.1 + +## 2.0.2 + +### Patch Changes + +- Updated dependencies [b4082b7] + - @penumbra-zone/crypto-web@3.0.0 + +## 2.0.1 + +### Patch Changes + +- Updated dependencies [66c2407] + - @penumbra-zone/wasm@3.0.0 + +## 2.0.0 + +### Major Changes + +- 929d278: barrel imports to facilitate better tree shaking + +### Patch Changes + +- 8933117: Account for changes to core +- Updated dependencies [8933117] +- Updated dependencies [929d278] + - @penumbra-zone/wasm@2.0.0 + - @penumbra-zone/constants@2.0.0 + - @penumbra-zone/getters@2.0.0 + - @penumbra-zone/bech32@2.0.0 + - @penumbra-zone/crypto-web@2.0.0 + - @penumbra-zone/types@2.0.0 + - @penumbra-zone/polyfills@2.0.0 + +## 1.0.2 + +### Patch Changes + +- Updated dependencies + - @penumbra-zone/constants@1.1.0 + - @penumbra-zone/types@1.1.0 + - @penumbra-zone/crypto-web@1.0.1 + - @penumbra-zone/wasm@1.0.2 diff --git a/packages/query/eslint.config.mjs b/packages/query/eslint.config.mjs new file mode 100644 index 00000000..a3150f6a --- /dev/null +++ b/packages/query/eslint.config.mjs @@ -0,0 +1,3 @@ +import eslintConfig from '@penumbra-zone/configs/eslint'; + +export default eslintConfig; diff --git a/packages/query/package.json b/packages/query/package.json new file mode 100644 index 00000000..245e8e58 --- /dev/null +++ b/packages/query/package.json @@ -0,0 +1,45 @@ +{ + "name": "@penumbra-zone/query", + "version": "40.0.0", + "license": "(MIT OR Apache-2.0)", + "type": "module", + "scripts": { + "build": "tsc --build --verbose", + "clean": "rm -rfv dist *.tsbuildinfo package penumbra-zone-*.tgz", + "dev:pack": "tsc-watch --onSuccess \"$npm_execpath pack\"", + "lint": "eslint src", + "lint:fix": "eslint src --fix", + "lint:strict": "tsc --noEmit && eslint src --max-warnings 0", + "test": "vitest run" + }, + "files": [ + "dist", + "!dist/**/*.test.*" + ], + "exports": { + "./*": "./src/*.ts" + }, + "publishConfig": { + "exports": { + "./*": { + "types": "./dist/*.d.ts", + "default": "./dist/*.js" + } + } + }, + "dependencies": { + "@bufbuild/protobuf": "^1.x", + "@connectrpc/connect": "^1.x", + "@connectrpc/connect-web": "^1.x", + "@penumbra-zone/bech32m": "10.0.0", + "@penumbra-zone/crypto-web": "29.0.1", + "@penumbra-zone/getters": "20.0.0", + "@penumbra-zone/protobuf": "6.3.0", + "@penumbra-zone/types": "26.2.1", + "@penumbra-zone/wasm": "33.1.0", + "exponential-backoff": "^3.1.1" + }, + "engine": { + "node": ">=22" + } +} diff --git a/packages/query/src/block-processor.ts b/packages/query/src/block-processor.ts new file mode 100644 index 00000000..34def28c --- /dev/null +++ b/packages/query/src/block-processor.ts @@ -0,0 +1,710 @@ +import { AssetId, Metadata } from '@penumbra-zone/protobuf/penumbra/core/asset/v1/asset_pb'; +import { AuctionId } from '@penumbra-zone/protobuf/penumbra/core/component/auction/v1/auction_pb'; +import { + PositionState, + PositionState_PositionStateEnum, +} from '@penumbra-zone/protobuf/penumbra/core/component/dex/v1/dex_pb'; +import { Nullifier } from '@penumbra-zone/protobuf/penumbra/core/component/sct/v1/sct_pb'; +import { ValidatorInfoResponse } from '@penumbra-zone/protobuf/penumbra/core/component/stake/v1/stake_pb'; +import { Action } from '@penumbra-zone/protobuf/penumbra/core/transaction/v1/transaction_pb'; +import { StateCommitment } from '@penumbra-zone/protobuf/penumbra/crypto/tct/v1/tct_pb'; +import { SpendableNoteRecord, SwapRecord } from '@penumbra-zone/protobuf/penumbra/view/v1/view_pb'; +import { auctionIdFromBech32 } from '@penumbra-zone/bech32m/pauctid'; +import { bech32mIdentityKey } from '@penumbra-zone/bech32m/penumbravalid'; +import { getAssetId } from '@penumbra-zone/getters/metadata'; +import { + getExchangeRateFromValidatorInfoResponse, + getIdentityKeyFromValidatorInfoResponse, +} from '@penumbra-zone/getters/validator-info-response'; +import { toDecimalExchangeRate } from '@penumbra-zone/types/amount'; +import { assetPatterns, PRICE_RELEVANCE_THRESHOLDS } from '@penumbra-zone/types/assets'; +import type { BlockProcessorInterface } from '@penumbra-zone/types/block-processor'; +import { uint8ArrayToHex } from '@penumbra-zone/types/hex'; +import type { IndexedDbInterface } from '@penumbra-zone/types/indexed-db'; +import type { ViewServerInterface } from '@penumbra-zone/types/servers'; +import { ScanBlockResult } from '@penumbra-zone/types/state-commitment-tree'; +import { computePositionId, getLpNftMetadata } from '@penumbra-zone/wasm/dex'; +import { customizeSymbol } from '@penumbra-zone/wasm/metadata'; +import { backOff } from 'exponential-backoff'; +import { updatePricesFromSwaps } from './helpers/price-indexer.js'; +import { processActionDutchAuctionEnd } from './helpers/process-action-dutch-auction-end.js'; +import { processActionDutchAuctionSchedule } from './helpers/process-action-dutch-auction-schedule.js'; +import { processActionDutchAuctionWithdraw } from './helpers/process-action-dutch-auction-withdraw.js'; +import { RootQuerier } from './root-querier.js'; +import { IdentityKey } from '@penumbra-zone/protobuf/penumbra/core/keys/v1/keys_pb'; +import { getDelegationTokenMetadata } from '@penumbra-zone/wasm/stake'; +import { toPlainMessage } from '@bufbuild/protobuf'; +import { getAssetIdFromGasPrices } from '@penumbra-zone/getters/compact-block'; +import { getSpendableNoteRecordCommitment } from '@penumbra-zone/getters/spendable-note-record'; +import { getSwapRecordCommitment } from '@penumbra-zone/getters/swap-record'; +import { CompactBlock } from '@penumbra-zone/protobuf/penumbra/core/component/compact_block/v1/compact_block_pb'; +import { shouldSkipTrialDecrypt } from './helpers/skip-trial-decrypt.js'; +import { identifyTransactions, RelevantTx } from './helpers/identify-txs.js'; + +declare global { + // eslint-disable-next-line no-var -- expected globals + var __DEV__: boolean | undefined; + // eslint-disable-next-line no-var -- expected globals + var __ASSERT_ROOT__: boolean | undefined; +} + +const isSwapRecordWithSwapCommitment = ( + r?: unknown, +): r is Exclude => + r instanceof SwapRecord && r.swapCommitment instanceof StateCommitment; + +const isSpendableNoteRecordWithNoteCommitment = ( + r?: unknown, +): r is Exclude => + r instanceof SpendableNoteRecord && r.noteCommitment instanceof StateCommitment; + +interface QueryClientProps { + querier: RootQuerier; + indexedDb: IndexedDbInterface; + viewServer: ViewServerInterface; + numeraires: AssetId[]; + stakingAssetId: AssetId; + genesisBlock: CompactBlock | undefined; + walletCreationBlockHeight: number | undefined; +} + +interface ProcessBlockParams { + compactBlock: CompactBlock; + latestKnownBlockHeight: bigint; + skipTrialDecrypt?: boolean; +} + +const POSITION_STATES: PositionState[] = [ + new PositionState({ state: PositionState_PositionStateEnum.OPENED }), + new PositionState({ state: PositionState_PositionStateEnum.CLOSED }), + new PositionState({ state: PositionState_PositionStateEnum.WITHDRAWN, sequence: 0n }), +]; + +export class BlockProcessor implements BlockProcessorInterface { + private readonly querier: RootQuerier; + private readonly indexedDb: IndexedDbInterface; + private readonly viewServer: ViewServerInterface; + private readonly abortController: AbortController = new AbortController(); + private numeraires: AssetId[]; + private readonly stakingAssetId: AssetId; + private syncPromise: Promise | undefined; + private readonly genesisBlock: CompactBlock | undefined; + private readonly walletCreationBlockHeight: number | undefined; + + constructor({ + indexedDb, + viewServer, + querier, + numeraires, + stakingAssetId, + genesisBlock, + walletCreationBlockHeight, + }: QueryClientProps) { + this.indexedDb = indexedDb; + this.viewServer = viewServer; + this.querier = querier; + this.numeraires = numeraires; + this.stakingAssetId = stakingAssetId; + this.genesisBlock = genesisBlock; + this.walletCreationBlockHeight = walletCreationBlockHeight; + } + + // If sync() is called multiple times concurrently, they'll all wait for + // the same promise rather than each starting their own sync process. + public sync = (): Promise => + (this.syncPromise ??= backOff(() => this.syncAndStore(), { + delayFirstAttempt: false, + startingDelay: 5_000, // 5 seconds + numOfAttempts: Infinity, + maxDelay: 20_000, // 20 seconds + retry: async (e, attemptNumber) => { + console.error(`Sync failure #${attemptNumber}: `, e); + await this.viewServer.resetTreeToStored(); + return !this.abortController.signal.aborted; + }, + })).finally( + // if the above promise completes, exponential backoff has ended (aborted). + // reset the rejected promise to allow for a new sync to be started. + () => (this.syncPromise = undefined), + ); + + public stop = (r: string) => this.abortController.abort(`Sync stop ${r}`); + + setNumeraires(numeraires: AssetId[]): void { + this.numeraires = numeraires; + } + + /** + * Sync local state to present. This method will + * - identify current synced height (or `-1n` to represent a 'pre-genesis' state) + * - query remote rpc for the chain's latest block height + * - pre-genesis, initialize 0th epoch and validator info + * - pre-genesis, process a local genesis block if provided + * - query remote rpc to begin streaming at the next block + * - iterate + */ + private async syncAndStore() { + const PRE_GENESIS_SYNC_HEIGHT = -1n; + + // start at next block, or genesis if height is undefined + let currentHeight = (await this.indexedDb.getFullSyncHeight()) ?? PRE_GENESIS_SYNC_HEIGHT; + + // this is the first network query of the block processor. use backoff to + // delay until network is available + let latestKnownBlockHeight = await backOff( + async () => { + const latest = await this.querier.tendermint.latestBlockHeight(); + if (!latest) { + throw new Error('Unknown latest block height'); + } + return latest; + }, + { retry: () => true }, + ); + + // handle the special case where no syncing has been done yet, and + // prepares for syncing and checks for a bundled genesis block, + // which can save time by avoiding an initial network request. + if (currentHeight === PRE_GENESIS_SYNC_HEIGHT) { + // create first epoch + await this.indexedDb.addEpoch(0n); + + // initialize validator info at genesis + // TODO: use batch endpoint https://github.com/penumbra-zone/penumbra/issues/4688 + void this.updateValidatorInfos(0n); + + // conditional only runs if there is a bundled genesis block provided for the chain + if (this.genesisBlock?.height === currentHeight + 1n) { + currentHeight = this.genesisBlock.height; + + // Set the trial decryption flag for the genesis compact block + const skipTrialDecrypt = shouldSkipTrialDecrypt( + this.walletCreationBlockHeight, + currentHeight, + ); + + await this.processBlock({ + compactBlock: this.genesisBlock, + latestKnownBlockHeight: latestKnownBlockHeight, + skipTrialDecrypt, + }); + } + } + + // this is an indefinite stream of the (compact) chain from the network + // intended to run continuously + for await (const compactBlock of this.querier.compactBlock.compactBlockRange({ + startHeight: currentHeight + 1n, + keepAlive: true, + abortSignal: this.abortController.signal, + })) { + // confirm block height to prevent corruption of local state + if (compactBlock.height === currentHeight + 1n) { + currentHeight = compactBlock.height; + } else { + throw new Error(`Unexpected block height: ${compactBlock.height} at ${currentHeight}`); + } + + // Set the trial decryption flag for all other compact blocks + const skipTrialDecrypt = shouldSkipTrialDecrypt( + this.walletCreationBlockHeight, + currentHeight, + ); + + await this.processBlock({ + compactBlock: compactBlock, + latestKnownBlockHeight: latestKnownBlockHeight, + skipTrialDecrypt, + }); + + // We only query Tendermint for the latest known block height once, when + // the block processor starts running. Once we're caught up, though, the + // chain will of course continue adding blocks, and we'll keep processing + // them. So, we need to update `latestKnownBlockHeight` once we've passed + // it. + if (compactBlock.height > latestKnownBlockHeight) { + latestKnownBlockHeight = compactBlock.height; + } + } + } + + // logic for processing a compact block + private async processBlock({ + compactBlock, + latestKnownBlockHeight, + skipTrialDecrypt = false, + }: ProcessBlockParams) { + if (compactBlock.appParametersUpdated) { + await this.indexedDb.saveAppParams(await this.querier.app.appParams()); + } + if (compactBlock.fmdParameters) { + await this.indexedDb.saveFmdParams(compactBlock.fmdParameters); + } + if (compactBlock.gasPrices) { + await this.indexedDb.saveGasPrices({ + ...toPlainMessage(compactBlock.gasPrices), + assetId: toPlainMessage(this.stakingAssetId), + }); + } + if (compactBlock.altGasPrices.length) { + for (const altGas of compactBlock.altGasPrices) { + await this.indexedDb.saveGasPrices({ + ...toPlainMessage(altGas), + assetId: getAssetIdFromGasPrices(altGas), + }); + } + } + + // wasm view server scan + // - decrypts new notes + // - decrypts new swaps + // - updates idb with advice + const scannerWantsFlush = await this.viewServer.scanBlock(compactBlock, skipTrialDecrypt); + + // flushing is slow, avoid it until + // - wasm says + // - every 5000th block + // - every block at tip + const flushReasons = { + scannerWantsFlush, + interval: compactBlock.height % 5000n === 0n, + new: compactBlock.height > latestKnownBlockHeight, + }; + + const recordsByCommitment = new Map(); + let flush: ScanBlockResult | undefined; + if (Object.values(flushReasons).some(Boolean)) { + flush = this.viewServer.flushUpdates(); + + // in an atomic query, this + // - saves 'sctUpdates' + // - saves new decrypted notes + // - saves new decrypted swaps + // - updates last block synced + await this.indexedDb.saveScanResult(flush); + + // - detect unknown asset types + // - shielded pool for asset metadata + // - or, generate default fallback metadata + // - update idb + await this.identifyNewAssets(flush.newNotes); + + for (const spendableNoteRecord of flush.newNotes) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion + recordsByCommitment.set(spendableNoteRecord.noteCommitment!, spendableNoteRecord); + } + for (const swapRecord of flush.newSwaps) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TODO: justify non-null assertion + recordsByCommitment.set(swapRecord.swapCommitment!, swapRecord); + } + } + + // nullifiers on this block may match notes or swaps from db + // - update idb, mark as spent/claimed + // - return nullifiers used in this way + const spentNullifiers = await this.resolveNullifiers( + compactBlock.nullifiers, + compactBlock.height, + ); + + // if a new record involves a state commitment, scan all block tx + if (spentNullifiers.size || recordsByCommitment.size) { + // this is a network query + const blockTx = await this.querier.app.txsByHeight(compactBlock.height); + + // Filter down to transactions & note records in block relevant to user + const { relevantTxs, recoveredSourceRecords } = await identifyTransactions( + spentNullifiers, + recordsByCommitment, + blockTx, + addr => this.viewServer.isControlledAddress(addr), + ); + + // this simply stores the new records with 'rehydrated' sources to idb + // TODO: this is the second time we save these records, after "saveScanResult" + await this.saveRecoveredCommitmentSources(recoveredSourceRecords); + + await this.processTransactions(relevantTxs); + + // at this point txinfo can be generated and saved. this will resolve + // pending broadcasts, and populate the transaction list. + // - calls wasm for each relevant tx + // - saves to idb + await this.saveTransactions(compactBlock.height, relevantTxs); + } + + /** + * This... really isn't great. + * + * You can see above that we're already iterating over flush.newNotes. So + * why don't we put this call to + * `this.maybeUpsertAuctionWithNoteCommitment()` inside that earlier `for` + * loop? + * + * The problem is, we need to call `this.processTransactions()` before + * calling `this.maybeUpsertAuctionWithNoteCommitment()`, because + * `this.processTransactions()` is what saves the auction NFT metadata to + * the database. `this.maybeUpsertAuctionWithNoteCommitment()` depends on + * that auction NFT metadata being saved already to be able to detect + * whether a given note is for an auction NFT; only then will it save the + * note's commitment to the `AUCTIONS` table. + * + * "So why not just move `this.processTransactions()` to before the block + * where we handle `flush.newNotes`?" Because `this.processTransactions()` + * should only run after we've handled `flush.newNotes`, since we depend + * on the result of the flush to determine whether there are transactions + * to process in the first place. It's a catch-22. + * + * This isn't a problem in core because core isn't going back and forth + * between Rust and TypeScript like we are. If and when we move the block + * processor into Rust, this issue should be resolved. + */ + for (const spendableNoteRecord of flush?.newNotes ?? []) { + await this.maybeUpsertAuctionWithNoteCommitment(spendableNoteRecord); + } + + // We do not store historical prices, + // so there is no point in saving prices that would already be considered obsolete at the time of saving + const blockInPriceRelevanceThreshold = + compactBlock.height >= latestKnownBlockHeight - BigInt(PRICE_RELEVANCE_THRESHOLDS.default); + + // we can't use third-party price oracles for privacy reasons, + // so we have to get asset prices from swap results during block scans + // and store them locally in indexed-db. + if (blockInPriceRelevanceThreshold && compactBlock.swapOutputs.length) { + await updatePricesFromSwaps( + this.indexedDb, + this.numeraires, + compactBlock.swapOutputs, + compactBlock.height, + ); + } + + // The presence of `epochRoot` indicates that this is the final block of the current epoch. + if (compactBlock.epochRoot) { + await this.handleEpochTransition(compactBlock.height, latestKnownBlockHeight); + } + + if (globalThis.__ASSERT_ROOT__) { + await this.assertRootValid(compactBlock.height); + } + } + + /* + * Compares the locally stored, filtered TCT root with the actual one on chain. They should match. + * This is expensive to do every block, so should only be done in development for debugging purposes. + */ + private async assertRootValid(blockHeight: bigint): Promise { + const remoteRoot = await this.querier.cnidarium.fetchRemoteRoot(blockHeight); + const inMemoryRoot = this.viewServer.getSctRoot(); + + if (remoteRoot.equals(inMemoryRoot)) { + console.debug( + `Block height: ${blockHeight} root matches remote ✅ \n`, + `Hash: ${uint8ArrayToHex(inMemoryRoot.inner)}`, + ); + } else { + console.warn( + `Block height: ${blockHeight} root does not match remote ❌ \n`, + `Local hash: ${uint8ArrayToHex(inMemoryRoot.inner)} \n`, + `Remote hash: ${uint8ArrayToHex(remoteRoot.inner)}`, + ); + } + } + + private async saveRecoveredCommitmentSources(recovered: (SpendableNoteRecord | SwapRecord)[]) { + for (const record of recovered) { + if (isSpendableNoteRecordWithNoteCommitment(record)) { + await this.indexedDb.saveSpendableNote({ + ...toPlainMessage(record), + noteCommitment: toPlainMessage(getSpendableNoteRecordCommitment(record)), + }); + } else if (isSwapRecordWithSwapCommitment(record)) { + await this.indexedDb.saveSwap({ + ...toPlainMessage(record), + swapCommitment: toPlainMessage(getSwapRecordCommitment(record)), + }); + } else { + throw new Error('Unexpected record type'); + } + } + } + + private async identifyNewAssets(notes: SpendableNoteRecord[]) { + const saveOperations = []; + + for (const note of notes) { + const assetId = note.note?.value?.assetId; + if (!assetId) { + continue; + } + + saveOperations.push(this.saveAndReturnMetadata(assetId)); + } + + await Promise.all(saveOperations); + } + + // TODO: refactor. there is definitely a better way to do this. batch + // endpoint issue https://github.com/penumbra-zone/penumbra/issues/4688 + private async saveAndReturnMetadata(assetId: AssetId): Promise { + const metadataAlreadyInDb = await this.indexedDb.getAssetsMetadata(assetId); + if (metadataAlreadyInDb) { + return metadataAlreadyInDb; + } + + const metadataFromNode = await this.querier.shieldedPool.assetMetadataById(assetId); + + // do not save IBC token metadata that are not in the prax registry + const isIbcAsset = metadataFromNode && assetPatterns.ibc.matches(metadataFromNode.display); + + if (metadataFromNode && !isIbcAsset) { + const customized = customizeSymbol(metadataFromNode); + await this.indexedDb.saveAssetsMetadata({ + ...customized, + penumbraAssetId: getAssetId(customized), + }); + return metadataFromNode; + } + + return undefined; + } + + private async saveAndReturnDelegationMetadata( + identityKey: IdentityKey, + ): Promise { + const delegationTokenAssetId = new AssetId({ + altBaseDenom: `udelegation_${bech32mIdentityKey(identityKey)}`, + }); + + const metadataAlreadyInDb = await this.indexedDb.getAssetsMetadata(delegationTokenAssetId); + if (metadataAlreadyInDb) { + return metadataAlreadyInDb; + } + + const generatedMetadata = getDelegationTokenMetadata(identityKey); + + const customized = customizeSymbol(generatedMetadata); + await this.indexedDb.saveAssetsMetadata({ + ...customized, + penumbraAssetId: getAssetId(customized), + }); + return generatedMetadata; + } + + // Nullifier is published in network when a note is spent or swap is claimed. + private async resolveNullifiers(nullifiers: Nullifier[], height: bigint) { + const spentNullifiers = new Set(); + const readOperations = []; + const writeOperations = []; + + for (const nullifier of nullifiers) { + const readPromise = (async () => { + const record = + (await this.indexedDb.getSpendableNoteByNullifier(nullifier)) ?? + (await this.indexedDb.getSwapByNullifier(nullifier)); + return { nullifier, record }; + })(); + + readOperations.push(readPromise); + } + + // Await all reads in parallel + const readResults = await Promise.all(readOperations); + + // Process the read results and queue up write operations + for (const { nullifier, record } of readResults) { + if (!record) { + continue; + } + + spentNullifiers.add(nullifier); + + if (record instanceof SpendableNoteRecord) { + record.heightSpent = height; + const writePromise = this.indexedDb.saveSpendableNote({ + ...toPlainMessage(record), + noteCommitment: toPlainMessage(getSpendableNoteRecordCommitment(record)), + }); + writeOperations.push(writePromise); + } else if (record instanceof SwapRecord) { + record.heightClaimed = height; + const writePromise = this.indexedDb.saveSwap({ + ...toPlainMessage(record), + swapCommitment: toPlainMessage(getSwapRecordCommitment(record)), + }); + writeOperations.push(writePromise); + } + } + + // Await all writes in parallel + await Promise.all(writeOperations); + + return spentNullifiers; + } + + /** + * Identify various pieces of data from the transaction that we need to save, + * such as metadata, liquidity positions, etc. + */ + private async processTransactions(txs: RelevantTx[]) { + for (const { data } of txs) { + for (const { action } of data.body?.actions ?? []) { + await Promise.all([this.identifyAuctionNfts(action), this.identifyLpNftPositions(action)]); + } + } + } + + /** + * during wasm tx info generation later, wasm independently queries idb for + * asset metadata, so we have to pre-populate. Auction NFTs aren't known by + * the chain so aren't populated by identifyNewAssets. + */ + private async identifyAuctionNfts(action: Action['action']) { + if (action.case === 'actionDutchAuctionSchedule' && action.value.description) { + await processActionDutchAuctionSchedule(action.value.description, this.indexedDb); + } else if (action.case === 'actionDutchAuctionEnd' && action.value.auctionId) { + await processActionDutchAuctionEnd(action.value, this.querier.auction, this.indexedDb); + } else if (action.case === 'actionDutchAuctionWithdraw' && action.value.auctionId) { + await processActionDutchAuctionWithdraw( + action.value.auctionId, + action.value.seq, + this.indexedDb, + ); + } + } + + /** + * during wasm tx info generation later, wasm independently queries idb for + * asset metadata, so we have to pre-populate. LpNft position states aren't + * known by the chain so aren't populated by identifyNewAssets + * - detect LpNft position opens + * - generate all possible position state metadata + * - update idb + */ + private async identifyLpNftPositions(action: Action['action']) { + if (action.case === 'positionOpen' && action.value.position) { + for (const state of POSITION_STATES) { + const metadata = getLpNftMetadata(computePositionId(action.value.position), state); + const customized = customizeSymbol(metadata); + await this.indexedDb.saveAssetsMetadata({ + ...customized, + penumbraAssetId: getAssetId(metadata), + }); + } + // to optimize on-chain storage PositionId is not written in the positionOpen action, + // but can be computed via hashing of immutable position fields + await this.indexedDb.addPosition( + computePositionId(action.value.position), + action.value.position, + ); + } + if (action.case === 'positionClose' && action.value.positionId) { + await this.indexedDb.updatePosition( + action.value.positionId, + new PositionState({ state: PositionState_PositionStateEnum.CLOSED }), + ); + } + if (action.case === 'positionWithdraw' && action.value.positionId) { + // Record the LPNFT for the current sequence number. + const positionState = new PositionState({ + state: PositionState_PositionStateEnum.WITHDRAWN, + sequence: action.value.sequence, + }); + const metadata = getLpNftMetadata(action.value.positionId, positionState); + const customized = customizeSymbol(metadata); + await this.indexedDb.saveAssetsMetadata({ + ...customized, + penumbraAssetId: getAssetId(metadata), + }); + + await this.indexedDb.updatePosition(action.value.positionId, positionState); + } + } + + private async maybeUpsertAuctionWithNoteCommitment(spendableNoteRecord: SpendableNoteRecord) { + const assetId = spendableNoteRecord.note?.value?.assetId; + if (!assetId) { + return; + } + + const metadata = await this.indexedDb.getAssetsMetadata(assetId); + const captureGroups = assetPatterns.auctionNft.capture(metadata?.display ?? ''); + if (!captureGroups) { + return; + } + + const auctionId = new AuctionId(auctionIdFromBech32(captureGroups.auctionId)); + + await this.indexedDb.upsertAuction(auctionId, { + noteCommitment: spendableNoteRecord.noteCommitment, + }); + } + + private async saveTransactions(height: bigint, relevantTx: RelevantTx[]) { + for (const { id, data } of relevantTx) { + await this.indexedDb.saveTransaction(id, height, data); + } + } + + private async handleEpochTransition( + endHeightOfPreviousEpoch: bigint, + latestKnownBlockHeight: bigint, + ): Promise { + const nextEpochStartHeight = endHeightOfPreviousEpoch + 1n; + await this.indexedDb.addEpoch(nextEpochStartHeight); + + const { sctParams } = (await this.indexedDb.getAppParams()) ?? {}; + const nextEpochIsLatestKnownEpoch = + sctParams && latestKnownBlockHeight - nextEpochStartHeight < sctParams.epochDuration; + + // If we're doing a full sync from block 0, there could be hundreds or even + // thousands of epoch transitions in the chain already. If we update + // validator infos on every epoch transition, we'd be making tons of + // unnecessary calls to the RPC node for validator infos. Instead, we'll + // only get updated validator infos once we're within the latest known + // epoch. + if (nextEpochIsLatestKnownEpoch) { + void this.updateValidatorInfos(nextEpochStartHeight); + } + } + + private async updateValidatorInfos(nextEpochStartHeight: bigint): Promise { + // It's important to clear the table so any stale (jailed, tombstoned, etc) entries are filtered out. + await this.indexedDb.clearValidatorInfos(); + + for await (const validatorInfoResponse of this.querier.stake.allValidatorInfos()) { + if (!validatorInfoResponse.validatorInfo) { + continue; + } + + await this.indexedDb.upsertValidatorInfo(validatorInfoResponse.validatorInfo); + + await this.updatePriceForValidatorDelegationToken( + validatorInfoResponse, + nextEpochStartHeight, + ); + } + } + + private async updatePriceForValidatorDelegationToken( + validatorInfoResponse: ValidatorInfoResponse, + nextEpochStartHeight: bigint, + ) { + const identityKey = getIdentityKeyFromValidatorInfoResponse(validatorInfoResponse); + + const metadata = await this.saveAndReturnDelegationMetadata(identityKey); + + if (metadata) { + const assetId = getAssetId(metadata); + const exchangeRate = getExchangeRateFromValidatorInfoResponse(validatorInfoResponse); + + await this.indexedDb.updatePrice( + assetId, + this.stakingAssetId, + toDecimalExchangeRate(exchangeRate), + nextEpochStartHeight, + ); + } + } +} diff --git a/packages/query/src/helpers/identify-txs.test.ts b/packages/query/src/helpers/identify-txs.test.ts new file mode 100644 index 00000000..7f93a4f7 --- /dev/null +++ b/packages/query/src/helpers/identify-txs.test.ts @@ -0,0 +1,380 @@ +import { describe, expect, test } from 'vitest'; +import { Nullifier } from '@penumbra-zone/protobuf/penumbra/core/component/sct/v1/sct_pb'; +import { StateCommitment } from '@penumbra-zone/protobuf/penumbra/crypto/tct/v1/tct_pb'; +import { + Action, + Transaction, + TransactionBody, +} from '@penumbra-zone/protobuf/penumbra/core/transaction/v1/transaction_pb'; +import { + BLANK_TX_SOURCE, + getCommitmentsFromActions, + getNullifiersFromActions, + identifyTransactions, +} from './identify-txs.js'; +import { + Output, + OutputBody, + Spend, + SpendBody, +} from '@penumbra-zone/protobuf/penumbra/core/component/shielded_pool/v1/shielded_pool_pb'; +import { + Swap, + SwapBody, + SwapClaim, + SwapClaimBody, +} from '@penumbra-zone/protobuf/penumbra/core/component/dex/v1/dex_pb'; +import { SpendableNoteRecord, SwapRecord } from '@penumbra-zone/protobuf/penumbra/view/v1/view_pb'; +import { Any } from '@bufbuild/protobuf'; +import { + FungibleTokenPacketData, + IbcRelay, +} from '@penumbra-zone/protobuf/penumbra/core/component/ibc/v1/ibc_pb'; +import { addressFromBech32m } from '@penumbra-zone/bech32m/penumbra'; +import { Address } from '@penumbra-zone/protobuf/penumbra/core/keys/v1/keys_pb'; +import { Packet } from '@penumbra-zone/protobuf/ibc/core/channel/v1/channel_pb'; +import { MsgRecvPacket } from '@penumbra-zone/protobuf/ibc/core/channel/v1/tx_pb'; + +describe('getCommitmentsFromActions', () => { + test('returns empty array when tx.body.actions is undefined', () => { + const tx = new Transaction(); + const commitments = getCommitmentsFromActions(tx); + expect(commitments).toEqual([]); + }); + + test('returns noteCommitment from output actions', () => { + const noteCommitment = new StateCommitment({ inner: new Uint8Array([1, 2, 3]) }); + const outputAction = new Action({ + action: { + case: 'output', + value: new Output({ + body: new OutputBody({ + notePayload: { + noteCommitment, + }, + }), + }), + }, + }); + + const tx = new Transaction({ + body: new TransactionBody({ + actions: [outputAction], + }), + }); + + const commitments = getCommitmentsFromActions(tx); + expect(commitments).toEqual([noteCommitment]); + }); + + test('returns commitment from swap actions', () => { + const commitment = new StateCommitment({ inner: new Uint8Array([4, 5, 6]) }); + const swapAction = new Action({ + action: { + case: 'swap', + value: new Swap({ + body: new SwapBody({ + payload: { + commitment, + }, + }), + }), + }, + }); + + const tx = new Transaction({ + body: new TransactionBody({ + actions: [swapAction], + }), + }); + + const commitments = getCommitmentsFromActions(tx); + expect(commitments).toEqual([commitment]); + }); + + test('returns output commitments from swapClaim actions', () => { + const output1Commitment = new StateCommitment({ inner: new Uint8Array([7, 8, 9]) }); + const output2Commitment = new StateCommitment({ inner: new Uint8Array([10, 11, 12]) }); + + const swapClaimAction = new Action({ + action: { + case: 'swapClaim', + value: new SwapClaim({ + body: new SwapClaimBody({ + output1Commitment, + output2Commitment, + }), + }), + }, + }); + + const tx = new Transaction({ + body: new TransactionBody({ + actions: [swapClaimAction], + }), + }); + + const commitments = getCommitmentsFromActions(tx); + expect(commitments).toEqual([output1Commitment, output2Commitment]); + }); + + test('ignores actions without commitments', () => { + const unknownAction = new Action({ + action: { + case: 'validatorDefinition', + value: {}, + }, + }); + + const tx = new Transaction({ + body: new TransactionBody({ + actions: [unknownAction], + }), + }); + + const commitments = getCommitmentsFromActions(tx); + expect(commitments).toEqual([]); + }); +}); + +describe('getNullifiersFromActions', () => { + test('returns empty array when tx.body.actions is undefined', () => { + const tx = new Transaction(); + const nullifiers = getNullifiersFromActions(tx); + expect(nullifiers).toEqual([]); + }); + + test('returns nullifier from spend actions', () => { + const nullifier = new Nullifier({ inner: new Uint8Array([1, 2, 3]) }); + const spendAction = new Action({ + action: { + case: 'spend', + value: new Spend({ + body: new SpendBody({ + nullifier, + }), + }), + }, + }); + + const tx = new Transaction({ + body: new TransactionBody({ + actions: [spendAction], + }), + }); + + const nullifiers = getNullifiersFromActions(tx); + expect(nullifiers).toEqual([nullifier]); + }); + + test('returns nullifier from swapClaim actions', () => { + const nullifier = new Nullifier({ inner: new Uint8Array([4, 5, 6]) }); + const swapClaimAction = new Action({ + action: { + case: 'swapClaim', + value: new SwapClaim({ + body: new SwapClaimBody({ + nullifier, + }), + }), + }, + }); + + const tx = new Transaction({ + body: new TransactionBody({ + actions: [swapClaimAction], + }), + }); + + const nullifiers = getNullifiersFromActions(tx); + expect(nullifiers).toEqual([nullifier]); + }); + + test('ignores actions without nullifiers', () => { + const outputAction = new Action({ + action: { + case: 'output', + value: new Output(), + }, + }); + + const tx = new Transaction({ + body: new TransactionBody({ + actions: [outputAction], + }), + }); + + const nullifiers = getNullifiersFromActions(tx); + expect(nullifiers).toEqual([]); + }); +}); + +describe('identifyTransactions', () => { + test('returns empty arrays when no relevant transactions are found', async () => { + const tx = new Transaction(); + const blockTx = [tx]; + const spentNullifiers = new Set(); + const commitmentRecords = new Map(); + + const result = await identifyTransactions( + spentNullifiers, + commitmentRecords, + blockTx, + () => false, + ); + + expect(result.relevantTxs).toEqual([]); + expect(result.recoveredSourceRecords).toEqual([]); + }); + + test('identifies relevant transactions and recovers sources', async () => { + // Transaction 1: Matching nullifier + const nullifier = new Nullifier({ inner: new Uint8Array([1, 2, 3]) }); + const tx1 = new Transaction({ + body: new TransactionBody({ + actions: [ + new Action({ + action: { + case: 'spend', + value: new Spend({ + body: new SpendBody({ + nullifier, + }), + }), + }, + }), + ], + }), + }); + + // Transaction 2: Matching commitment + const commitment = new StateCommitment({ inner: new Uint8Array([4, 5, 6]) }); + const tx2 = new Transaction({ + body: new TransactionBody({ + actions: [ + new Action({ + action: { + case: 'output', + value: new Output({ + body: new OutputBody({ + notePayload: { + noteCommitment: commitment, + }, + }), + }), + }, + }), + ], + }), + }); + + // Transaction 3: Irrelevant commitment + const tx3 = new Transaction({ + body: new TransactionBody({ + actions: [ + new Action({ + action: { + case: 'output', + value: new Output({ + body: new OutputBody({ + notePayload: { + noteCommitment: new StateCommitment({ inner: new Uint8Array([7, 8, 9]) }), + }, + }), + }), + }, + }), + ], + }), + }); + + // Transaction 4: Irrelevant nullifier + const tx4 = new Transaction({ + body: new TransactionBody({ + actions: [ + new Action({ + action: { + case: 'spend', + value: new Spend({ + body: new SpendBody({ + nullifier: new Nullifier({ inner: new Uint8Array([4, 5, 6]) }), + }), + }), + }, + }), + ], + }), + }); + + const spentNullifiers = new Set([nullifier]); + + const spendableNoteRecord = new SpendableNoteRecord({ + source: BLANK_TX_SOURCE, + }); + + const commitmentRecords = new Map([ + [commitment, spendableNoteRecord], // Expecting match + [new StateCommitment({ inner: new Uint8Array([1, 6, 9]) }), new SpendableNoteRecord()], // not expecting match + ]); + + const spentNullifiersBeforeSize = spentNullifiers.size; + const commitmentRecordsBeforeSize = commitmentRecords.size; + const result = await identifyTransactions( + spentNullifiers, + commitmentRecords, + [ + tx1, // relevant + tx2, // relevant + tx3, // not + tx4, // not + ], + () => false, + ); + + expect(result.relevantTxs.length).toBe(2); + expect(result.recoveredSourceRecords.length).toBe(1); + + // Source was recovered + expect(result.recoveredSourceRecords[0]!.source?.equals(BLANK_TX_SOURCE)).toEqual(false); + + // Expect inputs where not mutated + expect(spentNullifiersBeforeSize).toEqual(spentNullifiers.size); + expect(commitmentRecordsBeforeSize).toEqual(commitmentRecords.size); + }); + + test('identifies ibc relays', async () => { + const knownAddr = + 'penumbra1e8k5cyds484dxvapeamwveh5khqv4jsvyvaf5wwxaaccgfghm229qw03pcar3ryy8smptevstycch0qk3uu0rgkvtjpxy3cu3rjd0agawqtlz6erev28a6sg69u7cxy0t02nd4'; + const unknownAddr = + 'penumbracompat1147mfall0zr6am5r45qkwht7xqqrdsp50czde7empv7yq2nk3z8yyfh9k9520ddgswkmzar22vhz9dwtuem7uxw0qytfpv7lk3q9dp8ccaw2fn5c838rfackazmgf3ahhwqq0da'; + const tx = new Transaction({ + body: { + actions: [createIbcRelay(knownAddr), createIbcRelay(unknownAddr)], + }, + }); + const blockTx = [tx]; + const spentNullifiers = new Set(); + const commitmentRecords = new Map(); + + const result = await identifyTransactions(spentNullifiers, commitmentRecords, blockTx, addr => + addr.equals(new Address(addressFromBech32m(knownAddr))), + ); + + expect(result.relevantTxs.length).toBe(1); + expect(result.relevantTxs[0]?.data.equals(tx)).toBeTruthy(); + expect(result.recoveredSourceRecords.length).toBe(0); + }); +}); + +const createIbcRelay = (receiver: string): Action => { + const tokenPacketData = new FungibleTokenPacketData({ receiver }); + const encoder = new TextEncoder(); + const relevantRelay = Any.pack( + new MsgRecvPacket({ + packet: new Packet({ data: encoder.encode(tokenPacketData.toJsonString()) }), + }), + ); + return new Action({ + action: { case: 'ibcRelayAction', value: new IbcRelay({ rawAction: relevantRelay }) }, + }); +}; diff --git a/packages/query/src/helpers/identify-txs.ts b/packages/query/src/helpers/identify-txs.ts new file mode 100644 index 00000000..f74a9531 --- /dev/null +++ b/packages/query/src/helpers/identify-txs.ts @@ -0,0 +1,187 @@ +import { + CommitmentSource, + Nullifier, +} from '@penumbra-zone/protobuf/penumbra/core/component/sct/v1/sct_pb'; +import { StateCommitment } from '@penumbra-zone/protobuf/penumbra/crypto/tct/v1/tct_pb'; +import { SpendableNoteRecord, SwapRecord } from '@penumbra-zone/protobuf/penumbra/view/v1/view_pb'; +import { Transaction } from '@penumbra-zone/protobuf/penumbra/core/transaction/v1/transaction_pb'; +import { TransactionId } from '@penumbra-zone/protobuf/penumbra/core/txhash/v1/txhash_pb'; +import { sha256Hash } from '@penumbra-zone/crypto-web/sha256'; +import { MsgRecvPacket } from '@penumbra-zone/protobuf/ibc/core/channel/v1/tx_pb'; +import { FungibleTokenPacketData } from '@penumbra-zone/protobuf/penumbra/core/component/ibc/v1/ibc_pb'; +import { ViewServerInterface } from '@penumbra-zone/types/servers'; +import { parseIntoAddr } from '@penumbra-zone/types/address'; + +export const BLANK_TX_SOURCE = new CommitmentSource({ + source: { case: 'transaction', value: { id: new Uint8Array() } }, +}); + +// Identifies if a tx with a relay action of which the receiver is the user +const hasRelevantIbcRelay = ( + tx: Transaction, + isControlledAddr: ViewServerInterface['isControlledAddress'], +) => { + return tx.body?.actions.some(action => { + if (action.action.case !== 'ibcRelayAction') { + return false; + } + + if (!action.action.value.rawAction?.is(MsgRecvPacket.typeName)) { + return false; + } + + const recvPacket = new MsgRecvPacket(); + const success = action.action.value.rawAction.unpackTo(recvPacket); + if (!success) { + throw new Error('Error while trying to unpack Any to MsgRecvPacket'); + } + + if (!recvPacket.packet?.data) { + throw new Error('No FungibleTokenPacketData MsgRecvPacket'); + } + + try { + const dataString = new TextDecoder().decode(recvPacket.packet.data); + const { receiver } = FungibleTokenPacketData.fromJsonString(dataString); + const receivingAddr = parseIntoAddr(receiver); + return isControlledAddr(receivingAddr); + // eslint-disable-next-line @typescript-eslint/no-unused-vars -- TODO: Fix eslint issue + } catch (e) { + return false; + } + }); +}; + +// Used as a type-check helper as .filter(Boolean) still results with undefined as a possible value +const isDefined = (value: T | null | undefined): value is NonNullable => + value !== null && value !== undefined; + +export const getCommitmentsFromActions = (tx: Transaction): StateCommitment[] => { + if (!tx.body?.actions) { + return []; + } + + return tx.body.actions + .flatMap(({ action }) => { + // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- TODO: Fix eslint issue + switch (action.case) { + case 'output': + return action.value.body?.notePayload?.noteCommitment; + case 'swap': + return action.value.body?.payload?.commitment; + case 'swapClaim': + return [action.value.body?.output1Commitment, action.value.body?.output2Commitment]; + default: + return; + } + }) + .filter(isDefined); +}; + +export const getNullifiersFromActions = (tx: Transaction): Nullifier[] => { + if (!tx.body?.actions) { + return []; + } + + return tx.body.actions + .flatMap(({ action }) => { + // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- TODO: Fix eslint issue + switch (action.case) { + case 'spend': + case 'swapClaim': + return action.value.body?.nullifier; + default: + return; + } + }) + .filter(isDefined); +}; + +export interface RelevantTx { + id: TransactionId; + data: Transaction; +} + +type RecoveredSourceRecords = (SpendableNoteRecord | SwapRecord)[]; + +const generateTxId = async (tx: Transaction): Promise => { + return new TransactionId({ inner: await sha256Hash(tx.toBinary()) }); +}; + +const searchRelevant = async ( + tx: Transaction, + spentNullifiers: Set, + commitmentRecords: Map, + isControlledAddr: ViewServerInterface['isControlledAddress'], +): Promise< + { relevantTx: RelevantTx; recoveredSourceRecords: RecoveredSourceRecords } | undefined +> => { + let txId: TransactionId | undefined; // If set, that means this tx is relevant and should be returned to the caller + const recoveredSourceRecords: RecoveredSourceRecords = []; + + const txNullifiers = getNullifiersFromActions(tx); + for (const spentNullifier of spentNullifiers) { + if (txNullifiers.some(txNullifier => spentNullifier.equals(txNullifier))) { + txId ??= await generateTxId(tx); + } + } + + const txCommitments = getCommitmentsFromActions(tx); + for (const [stateCommitment, spendableNoteRecord] of commitmentRecords) { + if (txCommitments.some(txCommitment => stateCommitment.equals(txCommitment))) { + txId ??= await generateTxId(tx); + + // Blank sources can be recovered by associating them with the transaction + if (BLANK_TX_SOURCE.equals(spendableNoteRecord.source)) { + const recovered = spendableNoteRecord.clone(); + recovered.source = new CommitmentSource({ + source: { case: 'transaction', value: { id: txId.inner } }, + }); + recoveredSourceRecords.push(recovered); + } + } + } + + if (hasRelevantIbcRelay(tx, isControlledAddr)) { + txId ??= await generateTxId(tx); + } + + if (txId) { + return { + relevantTx: { id: txId, data: tx }, + recoveredSourceRecords, + }; + } + + return undefined; +}; + +// identify transactions that involve a new record by comparing nullifiers and state commitments +// also returns records with recovered sources +export const identifyTransactions = async ( + spentNullifiers: Set, + commitmentRecords: Map, + blockTx: Transaction[], + isControlledAddr: ViewServerInterface['isControlledAddress'], +): Promise<{ + relevantTxs: RelevantTx[]; + recoveredSourceRecords: RecoveredSourceRecords; +}> => { + const relevantTxs: RelevantTx[] = []; + const recoveredSourceRecords: RecoveredSourceRecords = []; + + const searchPromises = blockTx.map(tx => + searchRelevant(tx, spentNullifiers, commitmentRecords, isControlledAddr), + ); + const results = await Promise.all(searchPromises); + + for (const result of results) { + if (result?.relevantTx) { + relevantTxs.push(result.relevantTx); + } + if (result?.recoveredSourceRecords.length) { + recoveredSourceRecords.push(...result.recoveredSourceRecords); + } + } + return { relevantTxs, recoveredSourceRecords }; +}; diff --git a/packages/query/src/helpers/price-indexer.test.ts b/packages/query/src/helpers/price-indexer.test.ts new file mode 100644 index 00000000..9165e5f3 --- /dev/null +++ b/packages/query/src/helpers/price-indexer.test.ts @@ -0,0 +1,115 @@ +import { deriveAndSavePriceFromBSOD } from './price-indexer.js'; +import { BatchSwapOutputData } from '@penumbra-zone/protobuf/penumbra/core/component/dex/v1/dex_pb'; +import { beforeEach, describe, expect, it, Mock, vi } from 'vitest'; +import { IndexedDbInterface } from '@penumbra-zone/types/indexed-db'; +import { AssetId } from '@penumbra-zone/protobuf/penumbra/core/asset/v1/asset_pb'; +import { base64ToUint8Array } from '@penumbra-zone/types/base64'; + +describe('updatePricesFromSwaps()', () => { + let indexedDbMock: IndexedDbInterface; + const updatePriceMock: Mock = vi.fn(); + const height = 123n; + const numeraireAssetId = new AssetId({ + inner: base64ToUint8Array('reum7wQmk/owgvGMWMZn/6RFPV24zIKq3W6In/WwZgg='), + }); + + beforeEach(() => { + vi.clearAllMocks(); + + indexedDbMock = { + updatePrice: updatePriceMock, + } as unknown as IndexedDbInterface; + }); + + it('should update prices correctly for a swapOutput with NUMERAIRE as swapAsset2', async () => { + const asset1 = new AssetId({ inner: new Uint8Array(12) }); + const swapOutputs: BatchSwapOutputData[] = [ + new BatchSwapOutputData({ + tradingPair: { + asset1: asset1, + asset2: numeraireAssetId, + }, + delta1: { lo: 250n }, + lambda2: { lo: 1200n }, + unfilled1: { lo: 0n }, + }), + ]; + + await deriveAndSavePriceFromBSOD(indexedDbMock, numeraireAssetId, swapOutputs, height); + expect(updatePriceMock).toBeCalledTimes(1); + expect(updatePriceMock).toBeCalledWith(asset1, numeraireAssetId, 4.8, height); + }); + + it('should update prices correctly for a swapOutput with NUMERAIRE as swapAsset1', async () => { + const asset1 = new AssetId({ inner: new Uint8Array(12) }); + const swapOutputs: BatchSwapOutputData[] = [ + new BatchSwapOutputData({ + tradingPair: { + asset1: numeraireAssetId, + asset2: asset1, + }, + delta2: { lo: 40n }, + lambda1: { lo: 12740n }, + unfilled2: { lo: 0n }, + }), + ]; + + await deriveAndSavePriceFromBSOD(indexedDbMock, numeraireAssetId, swapOutputs, height); + expect(updatePriceMock).toBeCalledTimes(1); + expect(updatePriceMock).toBeCalledWith(asset1, numeraireAssetId, 318.5, height); + }); + + it('should not update prices if delta is zero', async () => { + const asset1 = new AssetId({ inner: new Uint8Array(12) }); + const swapOutputs: BatchSwapOutputData[] = [ + new BatchSwapOutputData({ + tradingPair: { + asset1: numeraireAssetId, + asset2: asset1, + }, + delta2: { lo: 0n }, + lambda1: { lo: 12740n }, + unfilled2: { lo: 0n }, + }), + ]; + + await deriveAndSavePriceFromBSOD(indexedDbMock, numeraireAssetId, swapOutputs, height); + expect(updatePriceMock).toBeCalledTimes(0); + }); + + it('should update prices correctly for partially filled', async () => { + const asset1 = new AssetId({ inner: new Uint8Array(12) }); + const swapOutputs: BatchSwapOutputData[] = [ + new BatchSwapOutputData({ + tradingPair: { + asset1: asset1, + asset2: numeraireAssetId, + }, + delta1: { lo: 250n }, + lambda2: { lo: 1200n }, + unfilled1: { lo: 100n }, + }), + ]; + await deriveAndSavePriceFromBSOD(indexedDbMock, numeraireAssetId, swapOutputs, height); + expect(updatePriceMock).toBeCalledTimes(1); + expect(updatePriceMock).toBeCalledWith(asset1, numeraireAssetId, 8, height); + }); + + it('should not update prices if swap is fully unfilled', async () => { + const asset1 = new AssetId({ inner: new Uint8Array(12) }); + const swapOutputs: BatchSwapOutputData[] = [ + new BatchSwapOutputData({ + tradingPair: { + asset1: numeraireAssetId, + asset2: asset1, + }, + delta2: { lo: 100n }, + lambda1: { lo: 12740n }, + unfilled2: { lo: 100n }, + }), + ]; + + await deriveAndSavePriceFromBSOD(indexedDbMock, numeraireAssetId, swapOutputs, height); + expect(updatePriceMock).toBeCalledTimes(0); + }); +}); diff --git a/packages/query/src/helpers/price-indexer.ts b/packages/query/src/helpers/price-indexer.ts new file mode 100644 index 00000000..17782c07 --- /dev/null +++ b/packages/query/src/helpers/price-indexer.ts @@ -0,0 +1,99 @@ +import { BatchSwapOutputData } from '@penumbra-zone/protobuf/penumbra/core/component/dex/v1/dex_pb'; +import { IndexedDbInterface } from '@penumbra-zone/types/indexed-db'; +import { divideAmounts, isZero, subtractAmounts } from '@penumbra-zone/types/amount'; +import { AssetId } from '@penumbra-zone/protobuf/penumbra/core/asset/v1/asset_pb'; +import { Amount } from '@penumbra-zone/protobuf/penumbra/core/num/v1/num_pb'; +import { + getDelta1Amount, + getDelta2Amount, + getLambda1Amount, + getLambda2Amount, + getSwapAsset1, + getSwapAsset2, + getUnfilled1Amount, + getUnfilled2Amount, +} from '@penumbra-zone/getters/batch-swap-output-data'; + +/** + * + * @param delta - total amount of 'pricedAsset' that was input to the batch swap + * @param unfilled - total amount of 'pricedAsset' that was returned unfilled + * @param lambda - total amount of 'numeraire' that was output from the batch swap + * Price formula: + * price = (lambda)/(delta - unfilled) + * The price cannot be calculated if + * - lambda is zero + * - delta is zero + * - (delta - unfilled) is zero + * @return 0 if the price cannot be calculated and some positive number if the price has been calculated. + */ +export const calculatePrice = (delta: Amount, unfilled: Amount, lambda: Amount): number => { + const filledAmount = subtractAmounts(delta, unfilled); + + return isZero(delta) || isZero(lambda) || isZero(filledAmount) + ? 0 + : divideAmounts(lambda, filledAmount).toNumber(); +}; + +export const updatePricesFromSwaps = async ( + indexedDb: IndexedDbInterface, + numeraires: AssetId[], + swapOutputs: BatchSwapOutputData[], + height: bigint, +) => { + for (const numeraireAssetId of numeraires) { + await deriveAndSavePriceFromBSOD(indexedDb, numeraireAssetId, swapOutputs, height); + } +}; + +/** + * Each 'BatchSwapOutputData' (BSOD) can generate up to two prices + * Each BSOD in block has a unique trading pair + * Trading pair has a canonical ordering, there's only one trading pair per pair of assets + * Each BSOD can generate up to two prices + * 1. pricedAsset -> numeraire (selling price) + * 2. numeraire -> pricedAsset (buying price) + * This function processes only (1) price and ignores (2) price + * We can get a BSOD with zero deltas(inputs), and we shouldn't save the price in that case + */ +export const deriveAndSavePriceFromBSOD = async ( + indexedDb: IndexedDbInterface, + numeraireAssetId: AssetId, + swapOutputs: BatchSwapOutputData[], + height: bigint, +) => { + for (const swapOutput of swapOutputs) { + const swapAsset1 = getSwapAsset1(swapOutput); + const swapAsset2 = getSwapAsset2(swapOutput); + + let numerairePerUnit = 0; + let pricedAsset: AssetId | undefined = undefined; + + // case for trading pair + if (swapAsset2.equals(numeraireAssetId)) { + pricedAsset = swapAsset1; + // numerairePerUnit = lambda2/(delta1-unfilled1) + numerairePerUnit = calculatePrice( + getDelta1Amount(swapOutput), + getUnfilled1Amount(swapOutput), + getLambda2Amount(swapOutput), + ); + } + // case for trading pair + else if (swapAsset1.equals(numeraireAssetId)) { + pricedAsset = swapAsset2; + // numerairePerUnit = lambda1/(delta2-unfilled2) + numerairePerUnit = calculatePrice( + getDelta2Amount(swapOutput), + getUnfilled2Amount(swapOutput), + getLambda1Amount(swapOutput), + ); + } + + if (pricedAsset === undefined || numerairePerUnit === 0) { + continue; + } + + await indexedDb.updatePrice(pricedAsset, numeraireAssetId, numerairePerUnit, height); + } +}; diff --git a/packages/query/src/helpers/process-action-dutch-auction-end.test.ts b/packages/query/src/helpers/process-action-dutch-auction-end.test.ts new file mode 100644 index 00000000..6fef7121 --- /dev/null +++ b/packages/query/src/helpers/process-action-dutch-auction-end.test.ts @@ -0,0 +1,117 @@ +import { Mock, beforeEach, describe, expect, it, vi } from 'vitest'; +import { processActionDutchAuctionEnd } from './process-action-dutch-auction-end.js'; +import { AssetId, Metadata, Value } from '@penumbra-zone/protobuf/penumbra/core/asset/v1/asset_pb'; +import { + ActionDutchAuctionEnd, + AuctionId, + DutchAuction, +} from '@penumbra-zone/protobuf/penumbra/core/component/auction/v1/auction_pb'; +import { IndexedDbInterface } from '@penumbra-zone/types/indexed-db'; + +const inner0123 = Uint8Array.from({ length: 32 }, () => Math.floor(Math.random() * 256)); +const inner4567 = Uint8Array.from({ length: 32 }, () => Math.floor(Math.random() * 256)); + +vi.mock('@penumbra-zone/wasm/auction', () => ({ + getAuctionNftMetadata: () => + Metadata.fromJson({ + penumbraAssetId: { inner: 'ARpgNbcWB8SkCuCBjlTsW8eDmEqeJQGWYDhbUk3Q1pc=' }, + display: 'test', + }), +})); + +describe('processActionDutchAuctionEnd()', () => { + let auctionQuerier: { auctionStateById: Mock }; + let indexedDb: { + saveAssetsMetadata: Mock; + upsertAuction: Mock; + addAuctionOutstandingReserves: Mock; + }; + const auctionId = new AuctionId({ inner: inner0123 }); + const action = new ActionDutchAuctionEnd({ auctionId }); + + beforeEach(() => { + auctionQuerier = { + auctionStateById: vi.fn(), + }; + indexedDb = { + saveAssetsMetadata: vi.fn(), + upsertAuction: vi.fn(), + addAuctionOutstandingReserves: vi.fn(), + }; + }); + + it('saves metadata for the ended auction NFT', async () => { + await processActionDutchAuctionEnd( + action, + auctionQuerier, + indexedDb as unknown as IndexedDbInterface, + ); + + expect(indexedDb.saveAssetsMetadata).toHaveBeenCalledWith( + expect.objectContaining({ display: 'test' }), + ); + }); + + it('upserts the auction with the sequence number', async () => { + const inputAssetId = new AssetId({ inner: inner0123 }); + const outputAssetId = new AssetId({ inner: inner4567 }); + + auctionQuerier.auctionStateById.mockResolvedValueOnce( + new DutchAuction({ + state: { + inputReserves: { hi: 0n, lo: 1234n }, + outputReserves: { hi: 0n, lo: 5678n }, + }, + description: { + input: { + amount: { hi: 0n, lo: 6912n }, + assetId: inputAssetId, + }, + outputId: outputAssetId, + }, + }), + ); + + await processActionDutchAuctionEnd( + action, + auctionQuerier, + indexedDb as unknown as IndexedDbInterface, + ); + + expect(indexedDb.upsertAuction).toHaveBeenCalledWith(auctionId, { + seqNum: 1n, + }); + }); + + it('adds the auction reserves', async () => { + const inputAssetId = new AssetId({ inner: inner0123 }); + const outputAssetId = new AssetId({ inner: inner4567 }); + + auctionQuerier.auctionStateById.mockResolvedValueOnce( + new DutchAuction({ + state: { + inputReserves: { hi: 0n, lo: 1234n }, + outputReserves: { hi: 0n, lo: 5678n }, + }, + description: { + input: { + amount: { hi: 0n, lo: 6912n }, + assetId: inputAssetId, + }, + outputId: outputAssetId, + }, + }), + ); + + await processActionDutchAuctionEnd( + action, + auctionQuerier, + indexedDb as unknown as IndexedDbInterface, + ); + + expect(indexedDb.addAuctionOutstandingReserves).toHaveBeenCalledWith(auctionId, { + input: new Value({ amount: { hi: 0n, lo: 1234n }, assetId: inputAssetId }), + output: new Value({ amount: { hi: 0n, lo: 5678n }, assetId: outputAssetId }), + }); + }); +}); diff --git a/packages/query/src/helpers/process-action-dutch-auction-end.ts b/packages/query/src/helpers/process-action-dutch-auction-end.ts new file mode 100644 index 00000000..a0a44e85 --- /dev/null +++ b/packages/query/src/helpers/process-action-dutch-auction-end.ts @@ -0,0 +1,48 @@ +import { Value } from '@penumbra-zone/protobuf/penumbra/core/asset/v1/asset_pb'; +import { + ActionDutchAuctionEnd, + DutchAuction, +} from '@penumbra-zone/protobuf/penumbra/core/component/auction/v1/auction_pb'; +import { getAssetId } from '@penumbra-zone/getters/metadata'; +import { IndexedDbInterface } from '@penumbra-zone/types/indexed-db'; +import { AuctionQuerierInterface } from '@penumbra-zone/types/querier'; +import { getAuctionNftMetadata } from '@penumbra-zone/wasm/auction'; + +const getInputValue = (auction?: DutchAuction) => + new Value({ + amount: auction?.state?.inputReserves, + assetId: auction?.description?.input?.assetId, + }); + +const getOutputValue = (auction?: DutchAuction) => + new Value({ + amount: auction?.state?.outputReserves, + assetId: auction?.description?.outputId, + }); + +export const processActionDutchAuctionEnd = async ( + action: ActionDutchAuctionEnd, + auctionQuerier: AuctionQuerierInterface, + indexedDb: IndexedDbInterface, +) => { + if (!action.auctionId) { + return; + } + + // Always a sequence number of 1 when ending a Dutch auction + const seqNum = 1n; + + const metadata = getAuctionNftMetadata(action.auctionId, seqNum); + const auction = await auctionQuerier.auctionStateById(action.auctionId); + + const outstandingReserves = { + input: getInputValue(auction), + output: getOutputValue(auction), + }; + + await Promise.all([ + indexedDb.saveAssetsMetadata({ ...metadata, penumbraAssetId: getAssetId(metadata) }), + indexedDb.upsertAuction(action.auctionId, { seqNum }), + indexedDb.addAuctionOutstandingReserves(action.auctionId, outstandingReserves), + ]); +}; diff --git a/packages/query/src/helpers/process-action-dutch-auction-schedule.ts b/packages/query/src/helpers/process-action-dutch-auction-schedule.ts new file mode 100644 index 00000000..1e91f48e --- /dev/null +++ b/packages/query/src/helpers/process-action-dutch-auction-schedule.ts @@ -0,0 +1,24 @@ +import { DutchAuctionDescription } from '@penumbra-zone/protobuf/penumbra/core/component/auction/v1/auction_pb'; +import { getAssetId } from '@penumbra-zone/getters/metadata'; +import { IndexedDbInterface } from '@penumbra-zone/types/indexed-db'; +import { getAuctionId, getAuctionNftMetadata } from '@penumbra-zone/wasm/auction'; + +export const processActionDutchAuctionSchedule = async ( + description: DutchAuctionDescription, + indexedDb: IndexedDbInterface, +) => { + const auctionId = getAuctionId(description); + + // Always a sequence number of 0 when starting a Dutch auction + const seqNum = 0n; + + const metadata = getAuctionNftMetadata(auctionId, seqNum); + + await Promise.all([ + indexedDb.saveAssetsMetadata({ ...metadata, penumbraAssetId: getAssetId(metadata) }), + indexedDb.upsertAuction(auctionId, { + auction: description, + seqNum, + }), + ]); +}; diff --git a/packages/query/src/helpers/process-action-dutch-auction-withdraw.ts b/packages/query/src/helpers/process-action-dutch-auction-withdraw.ts new file mode 100644 index 00000000..2c85af1d --- /dev/null +++ b/packages/query/src/helpers/process-action-dutch-auction-withdraw.ts @@ -0,0 +1,20 @@ +import { AuctionId } from '@penumbra-zone/protobuf/penumbra/core/component/auction/v1/auction_pb'; +import { getAssetId } from '@penumbra-zone/getters/metadata'; +import { IndexedDbInterface } from '@penumbra-zone/types/indexed-db'; +import { getAuctionNftMetadata } from '@penumbra-zone/wasm/auction'; + +export const processActionDutchAuctionWithdraw = async ( + auctionId: AuctionId, + seqNum: bigint, + indexedDb: IndexedDbInterface, +) => { + const metadata = getAuctionNftMetadata(auctionId, seqNum); + + await Promise.all([ + indexedDb.saveAssetsMetadata({ ...metadata, penumbraAssetId: getAssetId(metadata) }), + indexedDb.upsertAuction(auctionId, { + seqNum, + }), + indexedDb.deleteAuctionOutstandingReserves(auctionId), + ]); +}; diff --git a/packages/query/src/helpers/skip-trial-decrypt.test.ts b/packages/query/src/helpers/skip-trial-decrypt.test.ts new file mode 100644 index 00000000..d9d7c15f --- /dev/null +++ b/packages/query/src/helpers/skip-trial-decrypt.test.ts @@ -0,0 +1,53 @@ +import { describe, expect, it } from 'vitest'; +import { shouldSkipTrialDecrypt } from './skip-trial-decrypt.js'; + +describe('skipTrialDecrypt()', () => { + it('should not skip trial decryption if walletCreationBlockHeight is undefined', () => { + const currentHeight = 0n; + const walletCreationBlockHeight = undefined; + + const skipTrialDecrypt = shouldSkipTrialDecrypt(walletCreationBlockHeight, currentHeight); + + expect(skipTrialDecrypt).toBe(false); + }); + it('should not skip trial decryption for genesis block when wallet creation block height is zero', () => { + const currentHeight = 0n; + const walletCreationBlockHeight = 0; + + const skipTrialDecrypt = shouldSkipTrialDecrypt(walletCreationBlockHeight, currentHeight); + + expect(skipTrialDecrypt).toBe(false); + }); + it('should skip trial decryption for genesis block when wallet creation block height is not zero', () => { + const currentHeight = 0n; + const walletCreationBlockHeight = 100; + + const skipTrialDecrypt = shouldSkipTrialDecrypt(walletCreationBlockHeight, currentHeight); + + expect(skipTrialDecrypt).toBe(true); + }); + it('should skip trial decryption for other blocks when wallet creation block height is not zero', () => { + const currentHeight = 1n; + const walletCreationBlockHeight = 100; + + const skipTrialDecrypt = shouldSkipTrialDecrypt(walletCreationBlockHeight, currentHeight); + + expect(skipTrialDecrypt).toBe(true); + }); + it('should not skip trial decryption when wallet creation block height equals current height', () => { + const currentHeight = 100n; + const walletCreationBlockHeight = 100; + + const skipTrialDecrypt = shouldSkipTrialDecrypt(walletCreationBlockHeight, currentHeight); + + expect(skipTrialDecrypt).toBe(false); + }); + it('should not skip trial decryption when wallet creation block height is greater than current height', () => { + const currentHeight = 200n; + const walletCreationBlockHeight = 100; + + const skipTrialDecrypt = shouldSkipTrialDecrypt(walletCreationBlockHeight, currentHeight); + + expect(skipTrialDecrypt).toBe(false); + }); +}); diff --git a/packages/query/src/helpers/skip-trial-decrypt.ts b/packages/query/src/helpers/skip-trial-decrypt.ts new file mode 100644 index 00000000..895f3c2b --- /dev/null +++ b/packages/query/src/helpers/skip-trial-decrypt.ts @@ -0,0 +1,11 @@ +// Used to determine whether trial decryption should be skipped for this block +export const shouldSkipTrialDecrypt = ( + creationHeight: number | undefined, + currentHeight: bigint, +) => { + if (creationHeight === undefined || creationHeight === 0) { + return false; + } + + return currentHeight < BigInt(creationHeight); +}; diff --git a/packages/query/src/queriers/app.ts b/packages/query/src/queriers/app.ts new file mode 100644 index 00000000..e5853cc2 --- /dev/null +++ b/packages/query/src/queriers/app.ts @@ -0,0 +1,34 @@ +import { PromiseClient } from '@connectrpc/connect'; +import { createClient } from './utils.js'; +import { AppParameters } from '@penumbra-zone/protobuf/penumbra/core/app/v1/app_pb'; +import { Transaction } from '@penumbra-zone/protobuf/penumbra/core/transaction/v1/transaction_pb'; +import { AppService } from '@penumbra-zone/protobuf'; +import type { AppQuerierInterface } from '@penumbra-zone/types/querier'; + +export class AppQuerier implements AppQuerierInterface { + private readonly client: PromiseClient; + + constructor({ grpcEndpoint }: { grpcEndpoint: string }) { + this.client = createClient(grpcEndpoint, AppService); + } + + async appParams(): Promise { + const { appParameters } = await this.client.appParameters({}); + if (!appParameters) { + throw new Error('no app parameters in response'); + } + return appParameters; + } + + async txsByHeight(blockHeight: bigint): Promise { + const { blockHeight: responseHeight, transactions } = await this.client.transactionsByHeight({ + blockHeight, + }); + if (responseHeight !== blockHeight) { + throw new Error( + `block height mismatch: requested ${blockHeight}, received ${responseHeight}`, + ); + } + return transactions; + } +} diff --git a/packages/query/src/queriers/auction.ts b/packages/query/src/queriers/auction.ts new file mode 100644 index 00000000..3cc4f99d --- /dev/null +++ b/packages/query/src/queriers/auction.ts @@ -0,0 +1,31 @@ +import { AuctionQuerierInterface } from '@penumbra-zone/types/querier'; +import { AuctionService } from '@penumbra-zone/protobuf'; +import { PromiseClient } from '@connectrpc/connect'; +import { createClient } from './utils.js'; +import { + AuctionId, + DutchAuction, +} from '@penumbra-zone/protobuf/penumbra/core/component/auction/v1/auction_pb'; +import { typeUrlMatchesTypeName } from '@penumbra-zone/types/protobuf'; + +export class AuctionQuerier implements AuctionQuerierInterface { + private readonly client: PromiseClient; + + constructor({ grpcEndpoint }: { grpcEndpoint: string }) { + this.client = createClient(grpcEndpoint, AuctionService); + } + + async auctionStateById(id: AuctionId): Promise< + // Add more auction types to this union type as they are created. + DutchAuction | undefined + > { + const result = await this.client.auctionStateById({ id }); + + // As more auction types are created, handle them here. + if (typeUrlMatchesTypeName(result.auction?.typeUrl, DutchAuction.typeName)) { + return DutchAuction.fromBinary(result.auction.value); + } + + return undefined; + } +} diff --git a/packages/query/src/queriers/cnidarium.ts b/packages/query/src/queriers/cnidarium.ts new file mode 100644 index 00000000..3ea7b2ed --- /dev/null +++ b/packages/query/src/queriers/cnidarium.ts @@ -0,0 +1,26 @@ +import { PromiseClient } from '@connectrpc/connect'; +import { createClient } from './utils.js'; +import { CnidariumService } from '@penumbra-zone/protobuf'; +import { KeyValueRequest } from '@penumbra-zone/protobuf/penumbra/cnidarium/v1/cnidarium_pb'; +import { CnidariumQuerierInterface } from '@penumbra-zone/types/querier'; +import { MerkleRoot } from '@penumbra-zone/protobuf/penumbra/crypto/tct/v1/tct_pb'; + +export class CnidariumQuerier implements CnidariumQuerierInterface { + private readonly client: PromiseClient; + + constructor({ grpcEndpoint }: { grpcEndpoint: string }) { + this.client = createClient(grpcEndpoint, CnidariumService); + } + + async fetchRemoteRoot(blockHeight: bigint): Promise { + const keyValueRequest = new KeyValueRequest({ + key: `sct/tree/anchor_by_height/${blockHeight}`, + }); + const keyValue = await this.client.keyValue(keyValueRequest); + if (!keyValue.value) { + throw new Error('no value in KeyValueResponse'); + } + + return MerkleRoot.fromBinary(keyValue.value.value); + } +} diff --git a/packages/query/src/queriers/compact-block.ts b/packages/query/src/queriers/compact-block.ts new file mode 100644 index 00000000..5bb8bf60 --- /dev/null +++ b/packages/query/src/queriers/compact-block.ts @@ -0,0 +1,34 @@ +import { PromiseClient } from '@connectrpc/connect'; +import { + CompactBlock, + CompactBlockRangeRequest, +} from '@penumbra-zone/protobuf/penumbra/core/component/compact_block/v1/compact_block_pb'; +import { CompactBlockService } from '@penumbra-zone/protobuf'; +import { createClient } from './utils.js'; +import type { + CompactBlockQuerierInterface, + CompactBlockRangeParams, +} from '@penumbra-zone/types/querier'; + +export class CompactBlockQuerier implements CompactBlockQuerierInterface { + private readonly client: PromiseClient; + + constructor({ grpcEndpoint }: { grpcEndpoint: string }) { + this.client = createClient(grpcEndpoint, CompactBlockService); + } + + async *compactBlockRange({ + startHeight, + keepAlive, + abortSignal, + }: CompactBlockRangeParams): AsyncIterable { + const req = new CompactBlockRangeRequest({ keepAlive, startHeight }); + const iterable = this.client.compactBlockRange(req, { signal: abortSignal }); + for await (const res of iterable) { + if (!res.compactBlock) { + throw new Error('No block in response'); + } + yield res.compactBlock; + } + } +} diff --git a/packages/query/src/queriers/ibc-client.ts b/packages/query/src/queriers/ibc-client.ts new file mode 100644 index 00000000..a190f58e --- /dev/null +++ b/packages/query/src/queriers/ibc-client.ts @@ -0,0 +1,20 @@ +import { PromiseClient } from '@connectrpc/connect'; +import { createClient } from './utils.js'; +import { IbcClientService } from '@penumbra-zone/protobuf'; +import { + QueryClientStatesRequest, + QueryClientStatesResponse, +} from '@penumbra-zone/protobuf/ibc/core/client/v1/query_pb'; +import type { IbcClientQuerierInterface } from '@penumbra-zone/types/querier'; + +export class IbcClientQuerier implements IbcClientQuerierInterface { + private readonly client: PromiseClient; + + constructor({ grpcEndpoint }: { grpcEndpoint: string }) { + this.client = createClient(grpcEndpoint, IbcClientService); + } + + async ibcClientStates(req: QueryClientStatesRequest): Promise { + return await this.client.clientStates(req); + } +} diff --git a/packages/query/src/queriers/sct.ts b/packages/query/src/queriers/sct.ts new file mode 100644 index 00000000..a38b0829 --- /dev/null +++ b/packages/query/src/queriers/sct.ts @@ -0,0 +1,19 @@ +import { PromiseClient } from '@connectrpc/connect'; +import { createClient } from './utils.js'; +import { SctService } from '@penumbra-zone/protobuf'; +import { SctQuerierInterface } from '@penumbra-zone/types/querier'; +import { + TimestampByHeightRequest, + TimestampByHeightResponse, +} from '@penumbra-zone/protobuf/penumbra/core/component/sct/v1/sct_pb'; + +export class SctQuerier implements SctQuerierInterface { + private readonly client: PromiseClient; + + constructor({ grpcEndpoint }: { grpcEndpoint: string }) { + this.client = createClient(grpcEndpoint, SctService); + } + timestampByHeight(req: TimestampByHeightRequest): Promise { + return this.client.timestampByHeight(req); + } +} diff --git a/packages/query/src/queriers/shielded-pool.ts b/packages/query/src/queriers/shielded-pool.ts new file mode 100644 index 00000000..7ca7d858 --- /dev/null +++ b/packages/query/src/queriers/shielded-pool.ts @@ -0,0 +1,30 @@ +import { PromiseClient } from '@connectrpc/connect'; +import { createClient } from './utils.js'; +import { ShieldedPoolService } from '@penumbra-zone/protobuf'; +import { AssetId, Metadata } from '@penumbra-zone/protobuf/penumbra/core/asset/v1/asset_pb'; +import type { ShieldedPoolQuerierInterface } from '@penumbra-zone/types/querier'; + +declare global { + // eslint-disable-next-line no-var -- expected globals + var __DEV__: boolean | undefined; +} + +export class ShieldedPoolQuerier implements ShieldedPoolQuerierInterface { + private readonly client: PromiseClient; + + constructor({ grpcEndpoint }: { grpcEndpoint: string }) { + this.client = createClient(grpcEndpoint, ShieldedPoolService); + } + + async assetMetadataById(assetId: AssetId): Promise { + try { + const { denomMetadata } = await this.client.assetMetadataById({ assetId }); + return denomMetadata; + } catch (e) { + if (globalThis.__DEV__) { + console.debug(e); + } + return undefined; + } + } +} diff --git a/packages/query/src/queriers/staking.ts b/packages/query/src/queriers/staking.ts new file mode 100644 index 00000000..6bfeb9e4 --- /dev/null +++ b/packages/query/src/queriers/staking.ts @@ -0,0 +1,36 @@ +import { PromiseClient } from '@connectrpc/connect'; +import { createClient } from './utils.js'; +import { StakeService } from '@penumbra-zone/protobuf'; +import { + GetValidatorInfoRequest, + GetValidatorInfoResponse, + ValidatorInfoResponse, + ValidatorPenaltyRequest, + ValidatorPenaltyResponse, +} from '@penumbra-zone/protobuf/penumbra/core/component/stake/v1/stake_pb'; +import { StakeQuerierInterface } from '@penumbra-zone/types/querier'; + +export class StakeQuerier implements StakeQuerierInterface { + private readonly client: PromiseClient; + + constructor({ grpcEndpoint }: { grpcEndpoint: string }) { + this.client = createClient(grpcEndpoint, StakeService); + } + + validatorInfo(req: GetValidatorInfoRequest): Promise { + return this.client.getValidatorInfo(req); + } + + allValidatorInfos(): AsyncIterable { + /** + * Include inactive validators when saving to our local database, since we + * serve the `ValidatorInfo` RPC method from the extension, and may receive + * requests for inactive validators. + */ + return this.client.validatorInfo({ showInactive: true }); + } + + validatorPenalty(req: ValidatorPenaltyRequest): Promise { + return this.client.validatorPenalty(req); + } +} diff --git a/packages/query/src/queriers/tendermint.ts b/packages/query/src/queriers/tendermint.ts new file mode 100644 index 00000000..4d21e768 --- /dev/null +++ b/packages/query/src/queriers/tendermint.ts @@ -0,0 +1,50 @@ +import { PromiseClient } from '@connectrpc/connect'; +import { createClient } from './utils.js'; +import { TendermintProxyService } from '@penumbra-zone/protobuf'; +import { TransactionId } from '@penumbra-zone/protobuf/penumbra/core/txhash/v1/txhash_pb'; +import { Transaction } from '@penumbra-zone/protobuf/penumbra/core/transaction/v1/transaction_pb'; +import type { TendermintQuerierInterface } from '@penumbra-zone/types/querier'; + +declare global { + // eslint-disable-next-line no-var -- expected globals + var __DEV__: boolean | undefined; +} + +export class TendermintQuerier implements TendermintQuerierInterface { + private readonly client: PromiseClient; + + constructor({ grpcEndpoint }: { grpcEndpoint: string }) { + this.client = createClient(grpcEndpoint, TendermintProxyService); + } + + async latestBlockHeight() { + try { + const { syncInfo } = await this.client.getStatus({}); + return syncInfo?.latestBlockHeight; + } catch (e) { + if (globalThis.__DEV__) { + console.debug(e); + } + return undefined; + } + } + + async broadcastTx(tx: Transaction) { + const params = tx.toBinary(); + // Note that "synchronous" here means "wait for the tx to be accepted by + // the fullnode", not "wait for the tx to be included on chain. + const { hash, log, code } = await this.client.broadcastTxSync({ params }); + + if (code !== 0n) { + throw new Error(`Tendermint error ${code.toString()}: ${log}`); + } + + return new TransactionId({ inner: hash }); + } + + async getTransaction(txId: TransactionId): Promise<{ height: bigint; transaction: Transaction }> { + const res = await this.client.getTx({ hash: txId.inner }); + const transaction = Transaction.fromBinary(res.tx); + return { height: res.height, transaction }; + } +} diff --git a/packages/query/src/queriers/utils.ts b/packages/query/src/queriers/utils.ts new file mode 100644 index 00000000..20d4a7ef --- /dev/null +++ b/packages/query/src/queriers/utils.ts @@ -0,0 +1,13 @@ +import { createPromiseClient, PromiseClient } from '@connectrpc/connect'; +import { createGrpcWebTransport } from '@connectrpc/connect-web'; +import { ServiceType } from '@bufbuild/protobuf'; + +export const createClient = ( + grpcEndpoint: string, + serviceType: T, +): PromiseClient => { + const transport = createGrpcWebTransport({ + baseUrl: grpcEndpoint, + }); + return createPromiseClient(serviceType, transport); +}; diff --git a/packages/query/src/root-querier.ts b/packages/query/src/root-querier.ts new file mode 100644 index 00000000..1445ef87 --- /dev/null +++ b/packages/query/src/root-querier.ts @@ -0,0 +1,36 @@ +import { CompactBlockQuerier } from './queriers/compact-block.js'; +import { AppQuerier } from './queriers/app.js'; +import { TendermintQuerier } from './queriers/tendermint.js'; +import { ShieldedPoolQuerier } from './queriers/shielded-pool.js'; +import { IbcClientQuerier } from './queriers/ibc-client.js'; +import { CnidariumQuerier } from './queriers/cnidarium.js'; +import { StakeQuerier } from './queriers/staking.js'; +import type { RootQuerierInterface } from '@penumbra-zone/types/querier'; +import { AuctionQuerier } from './queriers/auction.js'; +import { SctQuerier } from './queriers/sct.js'; + +// Given the amount of query services, this root querier aggregates them all +// to make it easier for consumers +export class RootQuerier implements RootQuerierInterface { + readonly app: AppQuerier; + readonly compactBlock: CompactBlockQuerier; + readonly tendermint: TendermintQuerier; + readonly shieldedPool: ShieldedPoolQuerier; + readonly ibcClient: IbcClientQuerier; + readonly sct: SctQuerier; + readonly stake: StakeQuerier; + readonly cnidarium: CnidariumQuerier; + readonly auction: AuctionQuerier; + + constructor({ grpcEndpoint }: { grpcEndpoint: string }) { + this.app = new AppQuerier({ grpcEndpoint }); + this.compactBlock = new CompactBlockQuerier({ grpcEndpoint }); + this.tendermint = new TendermintQuerier({ grpcEndpoint }); + this.shieldedPool = new ShieldedPoolQuerier({ grpcEndpoint }); + this.ibcClient = new IbcClientQuerier({ grpcEndpoint }); + this.sct = new SctQuerier({ grpcEndpoint }); + this.stake = new StakeQuerier({ grpcEndpoint }); + this.cnidarium = new CnidariumQuerier({ grpcEndpoint }); + this.auction = new AuctionQuerier({ grpcEndpoint }); + } +} diff --git a/packages/query/tsconfig.json b/packages/query/tsconfig.json new file mode 100644 index 00000000..334d91f9 --- /dev/null +++ b/packages/query/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "@repo/tsconfig/base.json", + "include": ["."], + "exclude": ["node_modules"] +} diff --git a/packages/query/vitest.config.ts b/packages/query/vitest.config.ts new file mode 100644 index 00000000..0c2847ad --- /dev/null +++ b/packages/query/vitest.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig(({ mode }) => { + return { + define: { 'globalThis.__DEV__': mode !== 'production' }, + }; +}); diff --git a/packages/ui/package.json b/packages/ui/package.json index 9f2e4c8e..3d8fa325 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -32,10 +32,10 @@ "@penumbra-labs/registry": "^12.0.0", "@penumbra-zone/bech32m": "10.0.0", "@penumbra-zone/getters": "20.0.0", - "@penumbra-zone/perspective": "36.0.0", + "@penumbra-zone/perspective": "39.0.0", "@penumbra-zone/protobuf": "6.3.0", - "@penumbra-zone/types": "26.1.0", - "@penumbra-zone/wasm": "32.0.0", + "@penumbra-zone/types": "26.2.1", + "@penumbra-zone/wasm": "33.1.0", "@radix-ui/react-avatar": "^1.1.0", "@radix-ui/react-checkbox": "^1.1.1", "@radix-ui/react-dialog": "1.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ab5a46e3..625fbfd7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,7 +34,7 @@ importers: version: link:packages/tsconfig '@storybook/react-vite': specifier: 8.2.9 - version: 8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.24.3)(storybook@8.3.4)(typescript@5.5.4)(vite@5.4.10(@types/node@22.5.4)(terser@5.34.1))(webpack-sources@3.2.3) + version: 8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.28.0)(storybook@8.3.4)(typescript@5.5.4)(vite@5.4.11(@types/node@22.5.4)(terser@5.34.1))(webpack-sources@3.2.3) '@turbo/gen': specifier: ^2.1.1 version: 2.1.1(@swc/core@1.7.28)(@types/node@22.5.4)(typescript@5.5.4) @@ -96,8 +96,8 @@ importers: specifier: 21.0.0 version: 21.0.0(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/transport-dom@7.5.0) '@penumbra-zone/crypto-web': - specifier: 28.0.0 - version: 28.0.0(@penumbra-zone/types@26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) + specifier: 29.0.1 + version: 29.0.1(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) '@penumbra-zone/getters': specifier: 20.0.0 version: 20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) @@ -105,20 +105,20 @@ importers: specifier: 4.2.1 version: 4.2.1 '@penumbra-zone/perspective': - specifier: 36.0.0 - version: 36.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/wasm@32.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))) + specifier: 39.0.0 + version: 39.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/wasm@33.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))) '@penumbra-zone/protobuf': specifier: 6.3.0 version: 6.3.0(@bufbuild/protobuf@1.10.0) '@penumbra-zone/query': - specifier: 37.0.0 - version: 37.0.0(htymxraugqbluqqla3g523ff4i) + specifier: workspace:* + version: link:../../packages/query '@penumbra-zone/services': - specifier: 41.0.1 - version: 41.0.1(bea7luxaeaz2agxedzi5yqnhfm) + specifier: 44.0.0 + version: 44.0.0(54wyt4x6rbd5bfc2l4nqok2nh4) '@penumbra-zone/storage': - specifier: 36.0.1 - version: 36.0.1(22nytnrbt7ixf4wow4zyq4xyze) + specifier: 39.0.0 + version: 39.0.0(mazdjjpndxgwbkfdli2rf6n6ne) '@penumbra-zone/transport-chrome': specifier: 8.0.1 version: 8.0.1(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/transport-dom@7.5.0) @@ -126,11 +126,11 @@ importers: specifier: 7.5.0 version: 7.5.0 '@penumbra-zone/types': - specifier: 26.1.0 - version: 26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) + specifier: 26.2.1 + version: 26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) '@penumbra-zone/wasm': - specifier: 32.0.0 - version: 32.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) + specifier: 33.1.0 + version: 33.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) '@radix-ui/react-icons': specifier: ^1.3.0 version: 1.3.0(react@18.3.1) @@ -262,8 +262,8 @@ importers: specifier: 10.0.0 version: 10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) '@penumbra-zone/crypto-web': - specifier: 28.0.0 - version: 28.0.0(@penumbra-zone/types@26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) + specifier: 29.0.1 + version: 29.0.1(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) '@penumbra-zone/getters': specifier: 20.0.0 version: 20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) @@ -271,20 +271,20 @@ importers: specifier: 4.2.1 version: 4.2.1 '@penumbra-zone/perspective': - specifier: 36.0.0 - version: 36.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/wasm@32.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))) + specifier: 39.0.0 + version: 39.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/wasm@33.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))) '@penumbra-zone/protobuf': specifier: 6.3.0 version: 6.3.0(@bufbuild/protobuf@1.10.0) '@penumbra-zone/query': - specifier: 37.0.0 - version: 37.0.0(htymxraugqbluqqla3g523ff4i) + specifier: workspace:* + version: link:../query '@penumbra-zone/services': - specifier: 41.0.1 - version: 41.0.1(bea7luxaeaz2agxedzi5yqnhfm) + specifier: 44.0.0 + version: 44.0.0(54wyt4x6rbd5bfc2l4nqok2nh4) '@penumbra-zone/storage': - specifier: 36.0.1 - version: 36.0.1(22nytnrbt7ixf4wow4zyq4xyze) + specifier: 39.0.0 + version: 39.0.0(mazdjjpndxgwbkfdli2rf6n6ne) '@penumbra-zone/transport-chrome': specifier: 8.0.1 version: 8.0.1(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/transport-dom@7.5.0) @@ -292,11 +292,11 @@ importers: specifier: 7.5.0 version: 7.5.0 '@penumbra-zone/types': - specifier: 26.1.0 - version: 26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) + specifier: 26.2.1 + version: 26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) '@penumbra-zone/wasm': - specifier: 32.0.0 - version: 32.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) + specifier: 33.1.0 + version: 33.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) exponential-backoff: specifier: ^3.1.1 version: 3.1.1 @@ -313,8 +313,41 @@ importers: specifier: 6.3.0 version: 6.3.0(@bufbuild/protobuf@1.10.0) '@penumbra-zone/wasm': - specifier: 32.0.0 - version: 32.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) + specifier: 33.1.0 + version: 33.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) + + packages/query: + dependencies: + '@bufbuild/protobuf': + specifier: ^1.x + version: 1.10.0 + '@connectrpc/connect': + specifier: ^1.x + version: 1.4.0(@bufbuild/protobuf@1.10.0) + '@connectrpc/connect-web': + specifier: ^1.x + version: 1.4.0(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0)) + '@penumbra-zone/bech32m': + specifier: 10.0.0 + version: 10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) + '@penumbra-zone/crypto-web': + specifier: 29.0.1 + version: 29.0.1(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) + '@penumbra-zone/getters': + specifier: 20.0.0 + version: 20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) + '@penumbra-zone/protobuf': + specifier: 6.3.0 + version: 6.3.0(@bufbuild/protobuf@1.10.0) + '@penumbra-zone/types': + specifier: 26.2.1 + version: 26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) + '@penumbra-zone/wasm': + specifier: 33.1.0 + version: 33.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) + exponential-backoff: + specifier: ^3.1.1 + version: 3.1.1 packages/tailwind-config: dependencies: @@ -345,17 +378,17 @@ importers: specifier: 20.0.0 version: 20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) '@penumbra-zone/perspective': - specifier: 36.0.0 - version: 36.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/wasm@32.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))) + specifier: 39.0.0 + version: 39.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/wasm@33.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))) '@penumbra-zone/protobuf': specifier: 6.3.0 version: 6.3.0(@bufbuild/protobuf@1.10.0) '@penumbra-zone/types': - specifier: 26.1.0 - version: 26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) + specifier: 26.2.1 + version: 26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) '@penumbra-zone/wasm': - specifier: 32.0.0 - version: 32.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) + specifier: 33.1.0 + version: 33.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) '@radix-ui/react-avatar': specifier: ^1.1.0 version: 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -482,7 +515,7 @@ importers: version: 8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.2.9(@babel/preset-env@7.25.4(@babel/core@7.25.2)))(typescript@5.6.2) '@storybook/react-vite': specifier: 8.2.9 - version: 8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.24.3)(storybook@8.2.9(@babel/preset-env@7.25.4(@babel/core@7.25.2)))(typescript@5.6.2)(vite@5.4.10(@types/node@22.7.4)(terser@5.34.1))(webpack-sources@3.2.3) + version: 8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.28.0)(storybook@8.2.9(@babel/preset-env@7.25.4(@babel/core@7.25.2)))(typescript@5.6.2)(vite@5.4.11(@types/node@22.7.4)(terser@5.34.1))(webpack-sources@3.2.3) '@testing-library/dom': specifier: ^10.4.0 version: 10.4.0 @@ -1311,6 +1344,9 @@ packages: '@emotion/cache@11.13.1': resolution: {integrity: sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==} + '@emotion/cache@11.13.5': + resolution: {integrity: sha512-Z3xbtJ+UcK76eWkagZ1onvn/wAVb1GOMuR15s30Fm2wrMgC7jzpnO2JZXr4eujTTqoQFUrZIw/rT0c6Zzjca1g==} + '@emotion/hash@0.9.2': resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} @@ -1341,8 +1377,8 @@ packages: '@emotion/serialize@1.3.1': resolution: {integrity: sha512-dEPNKzBPU+vFPGa+z3axPRn8XVDetYORmDC0wAiej+TNcOZE70ZMJa0X7JdeoM6q/nWTMZeLpN/fTnD9o8MQBA==} - '@emotion/serialize@1.3.2': - resolution: {integrity: sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==} + '@emotion/serialize@1.3.3': + resolution: {integrity: sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==} '@emotion/sheet@1.4.0': resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==} @@ -1371,8 +1407,8 @@ packages: '@emotion/utils@1.4.0': resolution: {integrity: sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ==} - '@emotion/utils@1.4.1': - resolution: {integrity: sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA==} + '@emotion/utils@1.4.2': + resolution: {integrity: sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==} '@emotion/weak-memoize@0.4.0': resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} @@ -1671,6 +1707,12 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@eslint-community/eslint-utils@4.4.1': + resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} + 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==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} @@ -1840,8 +1882,8 @@ packages: resolution: {integrity: sha512-3rDakgJZ77+RiQUuSK69t1F0m8BQKA8Vh5DCS5V0DWvNY67zob2JhhQrhCO0AKLGINTRSFd1tBaHcJTkhefoSw==} engines: {node: '>=18'} - '@mui/core-downloads-tracker@6.1.6': - resolution: {integrity: sha512-nz1SlR9TdBYYPz4qKoNasMPRiGb4PaIHFkzLzhju0YVYS5QSuFF2+n7CsiHMIDcHv3piPu/xDWI53ruhOqvZwQ==} + '@mui/core-downloads-tracker@6.1.9': + resolution: {integrity: sha512-TWqj7b1w5cmSz4H/uf+y2AHxAH4ldPR7D2bz0XVyn60GCAo/zRbRPx7cF8gTs/i7CiYeHzV6dtat0VpMwOtolw==} '@mui/material@6.1.1': resolution: {integrity: sha512-b+eULldTqtqTCbN++2BtBWCir/1LwEYw+2mIlOt2GiEUh1EBBw4/wIukGKKNt3xrCZqRA80yLLkV6tF61Lq3cA==} @@ -1863,8 +1905,8 @@ packages: '@types/react': optional: true - '@mui/private-theming@6.1.6': - resolution: {integrity: sha512-ioAiFckaD/fJSnTrUMWgjl9HYBWt7ixCh7zZw7gDZ+Tae7NuprNV6QJK95EidDT7K0GetR2rU3kAeIR61Myttw==} + '@mui/private-theming@6.1.9': + resolution: {integrity: sha512-7aum/O1RquBYhfwL/7egDyl9GqJgPM6hoJDFFBbhF6Sgv9yI9v4w3ArKUkuVvR0CtVj4NXRVMKEioh1bjUzvuA==} engines: {node: '>=14.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -1873,8 +1915,8 @@ packages: '@types/react': optional: true - '@mui/styled-engine@6.1.6': - resolution: {integrity: sha512-I+yS1cSuSvHnZDBO7e7VHxTWpj+R7XlSZvTC4lS/OIbUNJOMMSd3UDP6V2sfwzAdmdDNBi7NGCRv2SZ6O9hGDA==} + '@mui/styled-engine@6.1.9': + resolution: {integrity: sha512-xynSLlJRxHLzSfQaiDjkaTx8LiFb9ByVa7aOdwFnTxGWFMY1F+mkXwAUY4jDDE+MAxkWxlzzQE0wOohnsxhdQg==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.4.1 @@ -1886,8 +1928,8 @@ packages: '@emotion/styled': optional: true - '@mui/system@6.1.6': - resolution: {integrity: sha512-qOf1VUE9wK8syiB0BBCp82oNBAVPYdj4Trh+G1s+L+ImYiKlubWhhqlnvWt3xqMevR+D2h1CXzA1vhX2FvA+VQ==} + '@mui/system@6.1.9': + resolution: {integrity: sha512-8x+RucnNp21gfFYsklCaZf0COXbv3+v0lrVuXONxvPEkESi2rwLlOi8UPJfcz6LxZOAX3v3oQ7qw18vnpgueRg==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -1910,8 +1952,8 @@ packages: '@types/react': optional: true - '@mui/utils@6.1.6': - resolution: {integrity: sha512-sBS6D9mJECtELASLM+18WUcXF6RH3zNxBRFeyCRg8wad6NbyNrdxLuwK+Ikvc38sTZwBzAz691HmSofLqHd9sQ==} + '@mui/utils@6.1.9': + resolution: {integrity: sha512-N7uzBp7p2or+xanXn3aH2OTINC6F/Ru/U8h6amhRZEev8bJhKN86rIDIoxZZ902tj+09LXtH83iLxFMjMHyqNA==} engines: {node: '>=14.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -1924,6 +1966,10 @@ packages: resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==} engines: {node: ^14.21.3 || >=16} + '@noble/hashes@1.6.1': + resolution: {integrity: sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w==} + engines: {node: ^14.21.3 || >=16} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1968,10 +2014,10 @@ packages: '@penumbra-zone/configs@1.1.0': resolution: {integrity: sha512-NssgBu3c1YfQALkTNHC3Y+vAJ+HqSAsTJPLKWftPS6KCOLmPvcncI23nIBZrSYoLh3W06aFV/Ab26UAp2hRMiA==} - '@penumbra-zone/crypto-web@28.0.0': - resolution: {integrity: sha512-p6ivGf7vsERJMt3a0S0vJJw3lDV+bIyCdtwv7dUXXUChGc89hL9JBwdq6YsGWNj9o2ARJUMfq6dENFVxLDikzA==} + '@penumbra-zone/crypto-web@29.0.1': + resolution: {integrity: sha512-U7+rtQ8LJo+bMqumUqBkDolhJDwexOHmBqPFgsgmLIQVjBfahDc+jjBUv1ecV80Y3Vxu4W35l2rq6jve0gi6yg==} peerDependencies: - '@penumbra-zone/types': 26.1.0 + '@penumbra-zone/types': 26.2.1 '@penumbra-zone/getters@20.0.0': resolution: {integrity: sha512-P0Cb/woPUT6gzbQUi2hMvfQ70K09wfObZKYVl6m8X2nMPP6/vEiXN09UITpWaHb1KVqN3JDHVBMZlu85MpmLBA==} @@ -1984,55 +2030,45 @@ packages: resolution: {integrity: sha512-1K+/8bh53Kse4u/I1afUQuRrTnZhLLA6JWIV+mFiXX8An2J2CGIVDjp1mSJkUSzFjFDUzUX052kvYHCtZYK3QA==} hasBin: true - '@penumbra-zone/perspective@36.0.0': - resolution: {integrity: sha512-JDgPjtN1bFMZQr6Wl9Syzl+FhPkuSOBDDpGBx+frSsbPUcD/YuIncsM+y4KdNPqtlJZk7+9kvD2mFvdBE8DMJQ==} + '@penumbra-zone/perspective@39.0.0': + resolution: {integrity: sha512-7ZltD1hOBd81TNo9hU0tley14gLkztJXJ9F2HrPc93xktEYRMelFgFR9lGElyNCrWklqPksSsTgneJwi9F0JZQ==} peerDependencies: '@bufbuild/protobuf': ^1.10.0 '@penumbra-zone/bech32m': 10.0.0 '@penumbra-zone/getters': 20.0.0 '@penumbra-zone/protobuf': 6.3.0 - '@penumbra-zone/wasm': 32.0.0 + '@penumbra-zone/wasm': 33.1.0 '@penumbra-zone/protobuf@6.3.0': resolution: {integrity: sha512-ZaApZtsXrX3GeAJEdMuKPPqnvxp74qFmL5ugOz7srP78Y6udZmLj6Gzo16bIL4JflXFYq99n+kB2jtWidPWSyQ==} peerDependencies: '@bufbuild/protobuf': ^1.10.0 - '@penumbra-zone/query@37.0.0': - resolution: {integrity: sha512-0Qe7ejODV8N8YbQ526kRpdohKFmiWqisXkdNpaILmfg9shBCmqibZ6Xkt1u2RvU1habLOQAL51Us+8jeTzyg4Q==} - peerDependencies: - '@penumbra-zone/bech32m': 10.0.0 - '@penumbra-zone/crypto-web': 28.0.0 - '@penumbra-zone/getters': 20.0.0 - '@penumbra-zone/protobuf': 6.3.0 - '@penumbra-zone/types': 26.1.0 - '@penumbra-zone/wasm': 32.0.0 - - '@penumbra-zone/services@41.0.1': - resolution: {integrity: sha512-XmbX6etnibijIqSTEILSd7V61Wk8QRlLFUHFoU1u0hH5MW+VZmj29+zVa8/5cUpmh50vemXQXg2xLnI/tPQJjg==} + '@penumbra-zone/services@44.0.0': + resolution: {integrity: sha512-XzyGQ+Sxxpf4FOS9E5eQCnyeZMXXidAifI6XCBGsamvTd3/vz1jInj8S6yiLcbKaCRA7yf1Z+jCxjee76ZVHTQ==} peerDependencies: '@bufbuild/protobuf': ^1.10.0 '@connectrpc/connect': ^1.4.0 '@penumbra-zone/bech32m': 10.0.0 - '@penumbra-zone/crypto-web': 28.0.0 + '@penumbra-zone/crypto-web': 29.0.1 '@penumbra-zone/getters': 20.0.0 '@penumbra-zone/protobuf': 6.3.0 - '@penumbra-zone/query': 37.0.0 - '@penumbra-zone/storage': 36.0.1 + '@penumbra-zone/query': 40.0.0 + '@penumbra-zone/storage': 39.0.0 '@penumbra-zone/transport-dom': 7.5.0 - '@penumbra-zone/types': 26.1.0 - '@penumbra-zone/wasm': 32.0.0 + '@penumbra-zone/types': 26.2.1 + '@penumbra-zone/wasm': 33.1.0 - '@penumbra-zone/storage@36.0.1': - resolution: {integrity: sha512-zFv8NWGj9qKeLCdql0208MSmBmW06lXOl9Ga71n9Z6ILd1XqMIQgGFAvMh54fgAt+IFBynwuZAYhKZmIzz5iPg==} + '@penumbra-zone/storage@39.0.0': + resolution: {integrity: sha512-jMw3EYgTNAxbfZx8VVcCsysm1YDsyl+VERNeK5O3SoBhe5Z/qnWofrKPd6ES8oaMP/l4jvFPhdkdH4VZx2YKXQ==} peerDependencies: '@bufbuild/protobuf': ^1.10.0 '@penumbra-labs/registry': ^12.0.0 '@penumbra-zone/bech32m': 10.0.0 '@penumbra-zone/getters': 20.0.0 '@penumbra-zone/protobuf': 6.3.0 - '@penumbra-zone/types': 26.1.0 - '@penumbra-zone/wasm': 32.0.0 + '@penumbra-zone/types': 26.2.1 + '@penumbra-zone/wasm': 33.1.0 '@penumbra-zone/transport-chrome@8.0.1': resolution: {integrity: sha512-Bk5/6N60hkeDwtx/ebP5u5DgZWNdRh6FQHgOXNP93FJjg4oobNOkjdoH0Gdqevj+sawGnyXFCyC6WeHB6D2LTA==} @@ -2044,14 +2080,6 @@ packages: '@penumbra-zone/transport-dom@7.5.0': resolution: {integrity: sha512-8xFIEDeXODl18AITfiIrJJoE8Y6y/+apO+BhrqCmXP+yqGo8LBzcW3iWDQkOc6Go2c1MGJT97B25r079Km1kuA==} - '@penumbra-zone/types@26.1.0': - resolution: {integrity: sha512-4L4txEGDN+7zsh0Tw/E81S9z3S5n3r4i0tqTE5Q7ZlCveb08DvJqU/23kTvofjveDH/jcW/dsuqEXKDAD3Nc3g==} - peerDependencies: - '@bufbuild/protobuf': ^1.10.0 - '@penumbra-zone/bech32m': 10.0.0 - '@penumbra-zone/getters': 20.0.0 - '@penumbra-zone/protobuf': 6.3.0 - '@penumbra-zone/types@26.2.1': resolution: {integrity: sha512-fC8W58Re4kimd7AKLnYHmG+cffHBBeVaYObJQqeyoRv7phBsYs0p6TeI5kwpvkVkOs3Z6H7fIlKpBga0WjFv0w==} peerDependencies: @@ -2060,13 +2088,13 @@ packages: '@penumbra-zone/getters': 20.0.0 '@penumbra-zone/protobuf': 6.3.0 - '@penumbra-zone/wasm@32.0.0': - resolution: {integrity: sha512-eYEyuiI6bm/r/FzcvvI364F0MRy5Lr/A7Z47E45akon8ey8uUUtgGS6ZLFloXxDccHs8N0nf5RvM2C5bE+Ob8w==} + '@penumbra-zone/wasm@33.1.0': + resolution: {integrity: sha512-43SqgY/Ygcq8kKY8df4sbXRkdtA57no7cb3YQOChBxIqg/rd4z4Tbf0Pex1CYYOJphHcYcUvH9+Az/O0rutdfw==} peerDependencies: '@bufbuild/protobuf': ^1.10.0 '@penumbra-zone/bech32m': 10.0.0 '@penumbra-zone/protobuf': 6.3.0 - '@penumbra-zone/types': 26.1.0 + '@penumbra-zone/types': 26.2.1 '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} @@ -2734,8 +2762,8 @@ packages: cpu: [arm] os: [android] - '@rollup/rollup-android-arm-eabi@4.24.3': - resolution: {integrity: sha512-ufb2CH2KfBWPJok95frEZZ82LtDl0A6QKTa8MoM+cWwDZvVGl5/jNb79pIhRvAalUu+7LD91VYR0nwRD799HkQ==} + '@rollup/rollup-android-arm-eabi@4.28.0': + resolution: {integrity: sha512-wLJuPLT6grGZsy34g4N1yRfYeouklTgPhH1gWXCYspenKYD0s3cR99ZevOGw5BexMNywkbV3UkjADisozBmpPQ==} cpu: [arm] os: [android] @@ -2744,8 +2772,8 @@ packages: cpu: [arm64] os: [android] - '@rollup/rollup-android-arm64@4.24.3': - resolution: {integrity: sha512-iAHpft/eQk9vkWIV5t22V77d90CRofgR2006UiCjHcHJFVI1E0oBkQIAbz+pLtthFw3hWEmVB4ilxGyBf48i2Q==} + '@rollup/rollup-android-arm64@4.28.0': + resolution: {integrity: sha512-eiNkznlo0dLmVG/6wf+Ifi/v78G4d4QxRhuUl+s8EWZpDewgk7PX3ZyECUXU0Zq/Ca+8nU8cQpNC4Xgn2gFNDA==} cpu: [arm64] os: [android] @@ -2754,8 +2782,8 @@ packages: cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-arm64@4.24.3': - resolution: {integrity: sha512-QPW2YmkWLlvqmOa2OwrfqLJqkHm7kJCIMq9kOz40Zo9Ipi40kf9ONG5Sz76zszrmIZZ4hgRIkez69YnTHgEz1w==} + '@rollup/rollup-darwin-arm64@4.28.0': + resolution: {integrity: sha512-lmKx9yHsppblnLQZOGxdO66gT77bvdBtr/0P+TPOseowE7D9AJoBw8ZDULRasXRWf1Z86/gcOdpBrV6VDUY36Q==} cpu: [arm64] os: [darwin] @@ -2764,18 +2792,18 @@ packages: cpu: [x64] os: [darwin] - '@rollup/rollup-darwin-x64@4.24.3': - resolution: {integrity: sha512-KO0pN5x3+uZm1ZXeIfDqwcvnQ9UEGN8JX5ufhmgH5Lz4ujjZMAnxQygZAVGemFWn+ZZC0FQopruV4lqmGMshow==} + '@rollup/rollup-darwin-x64@4.28.0': + resolution: {integrity: sha512-8hxgfReVs7k9Js1uAIhS6zq3I+wKQETInnWQtgzt8JfGx51R1N6DRVy3F4o0lQwumbErRz52YqwjfvuwRxGv1w==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.24.3': - resolution: {integrity: sha512-CsC+ZdIiZCZbBI+aRlWpYJMSWvVssPuWqrDy/zi9YfnatKKSLFCe6fjna1grHuo/nVaHG+kiglpRhyBQYRTK4A==} + '@rollup/rollup-freebsd-arm64@4.28.0': + resolution: {integrity: sha512-lA1zZB3bFx5oxu9fYud4+g1mt+lYXCoch0M0V/xhqLoGatbzVse0wlSQ1UYOWKpuSu3gyN4qEc0Dxf/DII1bhQ==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.24.3': - resolution: {integrity: sha512-F0nqiLThcfKvRQhZEzMIXOQG4EeX61im61VYL1jo4eBxv4aZRmpin6crnBJQ/nWnCsjH5F6J3W6Stdm0mBNqBg==} + '@rollup/rollup-freebsd-x64@4.28.0': + resolution: {integrity: sha512-aI2plavbUDjCQB/sRbeUZWX9qp12GfYkYSJOrdYTL/C5D53bsE2/nBPuoiJKoWp5SN78v2Vr8ZPnB+/VbQ2pFA==} cpu: [x64] os: [freebsd] @@ -2784,8 +2812,8 @@ packages: cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-gnueabihf@4.24.3': - resolution: {integrity: sha512-KRSFHyE/RdxQ1CSeOIBVIAxStFC/hnBgVcaiCkQaVC+EYDtTe4X7z5tBkFyRoBgUGtB6Xg6t9t2kulnX6wJc6A==} + '@rollup/rollup-linux-arm-gnueabihf@4.28.0': + resolution: {integrity: sha512-WXveUPKtfqtaNvpf0iOb0M6xC64GzUX/OowbqfiCSXTdi/jLlOmH0Ba94/OkiY2yTGTwteo4/dsHRfh5bDCZ+w==} cpu: [arm] os: [linux] @@ -2794,8 +2822,8 @@ packages: cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.24.3': - resolution: {integrity: sha512-h6Q8MT+e05zP5BxEKz0vi0DhthLdrNEnspdLzkoFqGwnmOzakEHSlXfVyA4HJ322QtFy7biUAVFPvIDEDQa6rw==} + '@rollup/rollup-linux-arm-musleabihf@4.28.0': + resolution: {integrity: sha512-yLc3O2NtOQR67lI79zsSc7lk31xjwcaocvdD1twL64PK1yNaIqCeWI9L5B4MFPAVGEVjH5k1oWSGuYX1Wutxpg==} cpu: [arm] os: [linux] @@ -2804,8 +2832,8 @@ packages: cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.24.3': - resolution: {integrity: sha512-fKElSyXhXIJ9pqiYRqisfirIo2Z5pTTve5K438URf08fsypXrEkVmShkSfM8GJ1aUyvjakT+fn2W7Czlpd/0FQ==} + '@rollup/rollup-linux-arm64-gnu@4.28.0': + resolution: {integrity: sha512-+P9G9hjEpHucHRXqesY+3X9hD2wh0iNnJXX/QhS/J5vTdG6VhNYMxJ2rJkQOxRUd17u5mbMLHM7yWGZdAASfcg==} cpu: [arm64] os: [linux] @@ -2814,8 +2842,8 @@ packages: cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.24.3': - resolution: {integrity: sha512-YlddZSUk8G0px9/+V9PVilVDC6ydMz7WquxozToozSnfFK6wa6ne1ATUjUvjin09jp34p84milxlY5ikueoenw==} + '@rollup/rollup-linux-arm64-musl@4.28.0': + resolution: {integrity: sha512-1xsm2rCKSTpKzi5/ypT5wfc+4bOGa/9yI/eaOLW0oMs7qpC542APWhl4A37AENGZ6St6GBMWhCCMM6tXgTIplw==} cpu: [arm64] os: [linux] @@ -2824,8 +2852,8 @@ packages: cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.24.3': - resolution: {integrity: sha512-yNaWw+GAO8JjVx3s3cMeG5Esz1cKVzz8PkTJSfYzE5u7A+NvGmbVFEHP+BikTIyYWuz0+DX9kaA3pH9Sqxp69g==} + '@rollup/rollup-linux-powerpc64le-gnu@4.28.0': + resolution: {integrity: sha512-zgWxMq8neVQeXL+ouSf6S7DoNeo6EPgi1eeqHXVKQxqPy1B2NvTbaOUWPn/7CfMKL7xvhV0/+fq/Z/J69g1WAQ==} cpu: [ppc64] os: [linux] @@ -2834,8 +2862,8 @@ packages: cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.24.3': - resolution: {integrity: sha512-lWKNQfsbpv14ZCtM/HkjCTm4oWTKTfxPmr7iPfp3AHSqyoTz5AgLemYkWLwOBWc+XxBbrU9SCokZP0WlBZM9lA==} + '@rollup/rollup-linux-riscv64-gnu@4.28.0': + resolution: {integrity: sha512-VEdVYacLniRxbRJLNtzwGt5vwS0ycYshofI7cWAfj7Vg5asqj+pt+Q6x4n+AONSZW/kVm+5nklde0qs2EUwU2g==} cpu: [riscv64] os: [linux] @@ -2844,8 +2872,8 @@ packages: cpu: [s390x] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.24.3': - resolution: {integrity: sha512-HoojGXTC2CgCcq0Woc/dn12wQUlkNyfH0I1ABK4Ni9YXyFQa86Fkt2Q0nqgLfbhkyfQ6003i3qQk9pLh/SpAYw==} + '@rollup/rollup-linux-s390x-gnu@4.28.0': + resolution: {integrity: sha512-LQlP5t2hcDJh8HV8RELD9/xlYtEzJkm/aWGsauvdO2ulfl3QYRjqrKW+mGAIWP5kdNCBheqqqYIGElSRCaXfpw==} cpu: [s390x] os: [linux] @@ -2854,8 +2882,8 @@ packages: cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.24.3': - resolution: {integrity: sha512-mnEOh4iE4USSccBOtcrjF5nj+5/zm6NcNhbSEfR3Ot0pxBwvEn5QVUXcuOwwPkapDtGZ6pT02xLoPaNv06w7KQ==} + '@rollup/rollup-linux-x64-gnu@4.28.0': + resolution: {integrity: sha512-Nl4KIzteVEKE9BdAvYoTkW19pa7LR/RBrT6F1dJCV/3pbjwDcaOq+edkP0LXuJ9kflW/xOK414X78r+K84+msw==} cpu: [x64] os: [linux] @@ -2864,8 +2892,8 @@ packages: cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.24.3': - resolution: {integrity: sha512-rMTzawBPimBQkG9NKpNHvquIUTQPzrnPxPbCY1Xt+mFkW7pshvyIS5kYgcf74goxXOQk0CP3EoOC1zcEezKXhw==} + '@rollup/rollup-linux-x64-musl@4.28.0': + resolution: {integrity: sha512-eKpJr4vBDOi4goT75MvW+0dXcNUqisK4jvibY9vDdlgLx+yekxSm55StsHbxUsRxSTt3JEQvlr3cGDkzcSP8bw==} cpu: [x64] os: [linux] @@ -2874,8 +2902,8 @@ packages: cpu: [arm64] os: [win32] - '@rollup/rollup-win32-arm64-msvc@4.24.3': - resolution: {integrity: sha512-2lg1CE305xNvnH3SyiKwPVsTVLCg4TmNCF1z7PSHX2uZY2VbUpdkgAllVoISD7JO7zu+YynpWNSKAtOrX3AiuA==} + '@rollup/rollup-win32-arm64-msvc@4.28.0': + resolution: {integrity: sha512-Vi+WR62xWGsE/Oj+mD0FNAPY2MEox3cfyG0zLpotZdehPFXwz6lypkGs5y38Jd/NVSbOD02aVad6q6QYF7i8Bg==} cpu: [arm64] os: [win32] @@ -2884,8 +2912,8 @@ packages: cpu: [ia32] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.24.3': - resolution: {integrity: sha512-9SjYp1sPyxJsPWuhOCX6F4jUMXGbVVd5obVpoVEi8ClZqo52ViZewA6eFz85y8ezuOA+uJMP5A5zo6Oz4S5rVQ==} + '@rollup/rollup-win32-ia32-msvc@4.28.0': + resolution: {integrity: sha512-kN/Vpip8emMLn/eOza+4JwqDZBL6MPNpkdaEsgUtW1NYN3DZvZqSQrbKzJcTL6hd8YNmFTn7XGWMwccOcJBL0A==} cpu: [ia32] os: [win32] @@ -2894,8 +2922,8 @@ packages: cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.24.3': - resolution: {integrity: sha512-HGZgRFFYrMrP3TJlq58nR1xy8zHKId25vhmm5S9jETEfDf6xybPxsavFTJaufe2zgOGYJBskGlj49CwtEuFhWQ==} + '@rollup/rollup-win32-x64-msvc@4.28.0': + resolution: {integrity: sha512-Bvno2/aZT6usSa7lRDL2+hMjVAGjuqaymF1ApZm31JXzniR/hvr14jpU+/z4X6Gt5BPlzosscyJZGUvguXIqeQ==} cpu: [x64] os: [win32] @@ -3034,6 +3062,9 @@ packages: '@storybook/csf@0.1.11': resolution: {integrity: sha512-dHYFQH3mA+EtnCkHXzicbLgsvzYjcDJ1JWsogbItZogkPHgSJM/Wr71uMkcvw8v9mmCyP4NpXJuu6bPoVsOnzg==} + '@storybook/csf@0.1.12': + resolution: {integrity: sha512-9/exVhabisyIVL0VxTCxo01Tdm8wefIXKXfltAPTSr8cbLn5JAxGQ6QV3mjdecLGEOucfoVhAKtJfVHxEK1iqw==} + '@storybook/global@5.0.0': resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} @@ -3172,8 +3203,8 @@ packages: '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - '@swc/types@0.1.12': - resolution: {integrity: sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==} + '@swc/types@0.1.17': + resolution: {integrity: sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==} '@szmarczak/http-timer@5.0.1': resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} @@ -3608,8 +3639,8 @@ packages: '@vitest/pretty-format@2.1.1': resolution: {integrity: sha512-SjxPFOtuINDUW8/UkElJYQSFtnWX7tMksSGW0vfjxMneFqxVr8YJ979QpMbDW7g+BIiq88RAGDjf7en6rvLPPQ==} - '@vitest/pretty-format@2.1.4': - resolution: {integrity: sha512-L95zIAkEuTDbUX1IsjRl+vyBSLh3PwLLgKpghl37aCK9Jvw0iP+wKwIFhfjdUtA2myLgjrG6VU6JCFLv8q/3Ww==} + '@vitest/pretty-format@2.1.8': + resolution: {integrity: sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==} '@vitest/runner@1.6.0': resolution: {integrity: sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==} @@ -3641,48 +3672,93 @@ packages: '@webassemblyjs/ast@1.12.1': resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==} + '@webassemblyjs/ast@1.14.1': + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} + '@webassemblyjs/floating-point-hex-parser@1.11.6': resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==} + '@webassemblyjs/floating-point-hex-parser@1.13.2': + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} + '@webassemblyjs/helper-api-error@1.11.6': resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==} + '@webassemblyjs/helper-api-error@1.13.2': + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} + '@webassemblyjs/helper-buffer@1.12.1': resolution: {integrity: sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==} + '@webassemblyjs/helper-buffer@1.14.1': + resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} + '@webassemblyjs/helper-numbers@1.11.6': resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==} + '@webassemblyjs/helper-numbers@1.13.2': + resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} + '@webassemblyjs/helper-wasm-bytecode@1.11.6': resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==} + '@webassemblyjs/helper-wasm-bytecode@1.13.2': + resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} + '@webassemblyjs/helper-wasm-section@1.12.1': resolution: {integrity: sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==} + '@webassemblyjs/helper-wasm-section@1.14.1': + resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} + '@webassemblyjs/ieee754@1.11.6': resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==} + '@webassemblyjs/ieee754@1.13.2': + resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} + '@webassemblyjs/leb128@1.11.6': resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==} + '@webassemblyjs/leb128@1.13.2': + resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} + '@webassemblyjs/utf8@1.11.6': resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==} + '@webassemblyjs/utf8@1.13.2': + resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} + '@webassemblyjs/wasm-edit@1.12.1': resolution: {integrity: sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==} + '@webassemblyjs/wasm-edit@1.14.1': + resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} + '@webassemblyjs/wasm-gen@1.12.1': resolution: {integrity: sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==} + '@webassemblyjs/wasm-gen@1.14.1': + resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} + '@webassemblyjs/wasm-opt@1.12.1': resolution: {integrity: sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==} + '@webassemblyjs/wasm-opt@1.14.1': + resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} + '@webassemblyjs/wasm-parser@1.12.1': resolution: {integrity: sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==} + '@webassemblyjs/wasm-parser@1.14.1': + resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} + '@webassemblyjs/wast-printer@1.12.1': resolution: {integrity: sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==} + '@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'} @@ -4181,8 +4257,8 @@ packages: caniuse-lite@1.0.30001658: resolution: {integrity: sha512-N2YVqWbJELVdrnsW5p+apoQyYt51aBMSsBZki1XZEfeBCexcM/sf4xiAHcXQBkuOwJBXtWF7aW1sYX6tKebPHw==} - caniuse-lite@1.0.30001676: - resolution: {integrity: sha512-Qz6zwGCiPghQXGJvgQAem79esjitvJ+CxSbSQkW9H/UX5hg8XM88d4lp2W+MEQ81j+Hip58Il+jGVdazk1z9cw==} + caniuse-lite@1.0.30001686: + resolution: {integrity: sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==} chai@4.5.0: resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} @@ -4796,8 +4872,8 @@ packages: electron-to-chromium@1.5.18: resolution: {integrity: sha512-1OfuVACu+zKlmjsNdcJuVQuVE61sZOLbNM4JAQ1Rvh6EOj0/EUKhMJjRH73InPlXSh8HIJk1cVZ8pyOV/FMdUQ==} - electron-to-chromium@1.5.50: - resolution: {integrity: sha512-eMVObiUQ2LdgeO1F/ySTXsvqvxb6ZH2zPGaMYsWzRDdOddUa77tdmI0ltg+L16UpbWdhPmuF3wIQYyQq65WfZw==} + electron-to-chromium@1.5.68: + resolution: {integrity: sha512-FgMdJlma0OzUYlbrtZ4AeXjKxKPk6KT8WOP8BjcqxWtlg8qyJQjRzPJzUtUn5GBg1oQ26hFs7HOOHJMYiJRnvQ==} elliptic@6.5.7: resolution: {integrity: sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==} @@ -5450,6 +5526,9 @@ packages: get-tsconfig@4.8.0: resolution: {integrity: sha512-Pgba6TExTZ0FJAn1qkJAjIeKoDJ3CsI2ChuLohJnZl/tTU8MVrq3b+2t5UOPfRa4RMsorClBjJALkJUMjG1PAw==} + get-tsconfig@4.8.1: + resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} + get-uri@6.0.3: resolution: {integrity: sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==} engines: {node: '>= 14'} @@ -5584,10 +5663,18 @@ packages: resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} engines: {node: '>= 0.4'} + has-proto@1.1.0: + resolution: {integrity: sha512-QLdzI9IIO1Jg7f9GT1gXpPpXArAn6cS31R1eEZqz08Gc+uQ8/XiqHWt17Fiw+2p6oTTIq5GXEpQkAlA88YRl/Q==} + engines: {node: '>= 0.4'} + has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + has-tostringtag@1.0.2: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} @@ -5838,15 +5925,16 @@ packages: resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} engines: {node: '>= 0.4'} - is-bigint@1.0.4: - resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} - is-boolean-object@1.1.2: - resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + is-boolean-object@1.2.0: + resolution: {integrity: sha512-kR5g0+dXf/+kXnqI+lu0URKYPKgICtHGGNCDSB10AaUFj3o/HkB3u7WfpRBJGFopxxY0oH3ux7ZsDjLtK7xqvw==} engines: {node: '>= 0.4'} is-bun-module@1.3.0: @@ -5940,8 +6028,8 @@ packages: resolution: {integrity: sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - is-number-object@1.0.7: - resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + is-number-object@1.1.0: + resolution: {integrity: sha512-KVSZV0Dunv9DTPkhXwcZ3Q+tUc9TsaE1ZwX5J2WMvsSGS6Md8TFPun5uwh0yRdrNerI6vf/tbJxqSx4c1ZI1Lw==} engines: {node: '>= 0.4'} is-number@7.0.0: @@ -5995,16 +6083,16 @@ packages: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - is-string@1.0.7: - resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + is-string@1.1.0: + resolution: {integrity: sha512-PlfzajuF9vSo5wErv3MJAKD/nqf9ngAs1NFQYm16nUYFO2IzxJ2hcm+IOCg+EEopdykNNUhVq5cz35cAUxU8+g==} engines: {node: '>= 0.4'} is-subdir@1.2.0: resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} engines: {node: '>=4'} - is-symbol@1.0.4: - resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + is-symbol@1.1.0: + resolution: {integrity: sha512-qS8KkNNXUZ/I+nX6QT8ZS1/Yx0A444yhzdTKxCzKkNjQ9sHErBxJnJAgh+f5YhusYECEcjo4XcyH87hn6+ks0A==} engines: {node: '>= 0.4'} is-typed-array@1.1.13: @@ -6367,8 +6455,8 @@ packages: magic-string@0.30.11: resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} - magic-string@0.30.12: - resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} + magic-string@0.30.14: + resolution: {integrity: sha512-5c99P1WKTed11ZC0HMJOj6CDIue6F8ySu+bJL+85q1zBEIY8IklrJ1eiKC2NDRh3Ct3FcvmJPyQHb9erXMTJNw==} make-dir@2.1.0: resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} @@ -6571,6 +6659,11 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + nanoid@3.3.8: + resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -7112,8 +7205,8 @@ packages: resolution: {integrity: sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==} engines: {node: ^10 || ^12 || >=14} - postcss@8.4.47: - resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} + postcss@8.4.49: + resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: @@ -7539,8 +7632,8 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - rollup@4.24.3: - resolution: {integrity: sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==} + rollup@4.28.0: + resolution: {integrity: sha512-G9GOrmgWHBma4YfCcX8PjH0qhXSdH8B4HDE2o4/jaxj93S4DPCIDoLcXz99eWMji4hB29UFCEd7B2gwGJDR9cQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -7819,6 +7912,9 @@ packages: std-env@3.7.0: resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + std-env@3.8.0: + resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} + stdin-discarder@0.2.2: resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} engines: {node: '>=18'} @@ -8099,8 +8195,8 @@ packages: resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} engines: {node: '>=14.0.0'} - tinypool@1.0.1: - resolution: {integrity: sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==} + tinypool@1.0.2: + resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} engines: {node: ^18.0.0 || >=20.0.0} tinyrainbow@1.2.0: @@ -8214,6 +8310,9 @@ packages: tslib@2.7.0: resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsx@4.19.0: resolution: {integrity: sha512-bV30kM7bsLZKZIOCHeMNVMJ32/LuJzLVajkQI/qf92J2Qr08ueLQvW00PUZGiuLPP760UINwupgUj8qrSCPUKg==} engines: {node: '>=18.0.0'} @@ -8525,8 +8624,8 @@ packages: engines: {node: ^18.0.0 || >=20.0.0} hasBin: true - vite@5.4.10: - resolution: {integrity: sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==} + vite@5.4.11: + resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -8741,8 +8840,9 @@ packages: when@3.7.7: resolution: {integrity: sha512-9lFZp/KHoqH6bPKjbWqa+3Dg/K/r2v0X/3/G2x4DBGchVS2QX2VXL3cZV994WQVnTM1/PD71Az25nAzryEUugw==} - which-boxed-primitive@1.0.2: - resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + which-boxed-primitive@1.1.0: + resolution: {integrity: sha512-Ei7Miu/AXe2JJ4iNF5j/UphAgRoma4trE6PtisM09bPygb3egMH3YLW/befsWb1A1AxvNSFidOFTB18XtnIIng==} + engines: {node: '>= 0.4'} which-builtin-type@1.2.0: resolution: {integrity: sha512-I+qLGQ/vucCby4tf5HsLmGueEla4ZhwTBSqaooS+Y0BuxN4Cp+okmGuV+8mXZ84KDI9BA+oklo+RzKg0ONdSUA==} @@ -8756,6 +8856,10 @@ packages: resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} + which-typed-array@1.1.16: + resolution: {integrity: sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==} + engines: {node: '>= 0.4'} + which@1.2.4: resolution: {integrity: sha512-zDRAqDSBudazdfM9zpiI30Fu9ve47htYXcGi3ln0wfKu2a7SmrT6F3VDoYONu//48V8Vz4TdCRNPjtvyRO3yBA==} hasBin: true @@ -9974,7 +10078,7 @@ snapshots: '@cosmjs/encoding': 0.32.4 '@cosmjs/math': 0.32.4 '@cosmjs/utils': 0.32.4 - '@noble/hashes': 1.5.0 + '@noble/hashes': 1.6.1 bn.js: 5.2.1 elliptic: 6.5.7 libsodium-wrappers-sumo: 0.7.15 @@ -10104,6 +10208,14 @@ snapshots: '@emotion/weak-memoize': 0.4.0 stylis: 4.2.0 + '@emotion/cache@11.13.5': + dependencies: + '@emotion/memoize': 0.9.0 + '@emotion/sheet': 1.4.0 + '@emotion/utils': 1.4.2 + '@emotion/weak-memoize': 0.4.0 + stylis: 4.2.0 + '@emotion/hash@0.9.2': {} '@emotion/is-prop-valid@1.2.2': @@ -10147,12 +10259,12 @@ snapshots: '@emotion/utils': 1.4.0 csstype: 3.1.3 - '@emotion/serialize@1.3.2': + '@emotion/serialize@1.3.3': dependencies: '@emotion/hash': 0.9.2 '@emotion/memoize': 0.9.0 '@emotion/unitless': 0.10.0 - '@emotion/utils': 1.4.1 + '@emotion/utils': 1.4.2 csstype: 3.1.3 '@emotion/sheet@1.4.0': {} @@ -10182,7 +10294,7 @@ snapshots: '@emotion/utils@1.4.0': {} - '@emotion/utils@1.4.1': {} + '@emotion/utils@1.4.2': {} '@emotion/weak-memoize@0.4.0': {} @@ -10343,6 +10455,11 @@ snapshots: eslint: 9.16.0(jiti@1.21.6) eslint-visitor-keys: 3.4.3 + '@eslint-community/eslint-utils@4.4.1(eslint@9.16.0(jiti@1.21.6))': + dependencies: + eslint: 9.16.0(jiti@1.21.6) + eslint-visitor-keys: 3.4.3 + '@eslint-community/regexpp@4.12.1': {} '@eslint/compat@1.2.3(eslint@9.16.0(jiti@1.21.6))': @@ -10479,23 +10596,23 @@ snapshots: dependencies: '@sinclair/typebox': 0.27.8 - '@joshwooding/vite-plugin-react-docgen-typescript@0.3.1(typescript@5.5.4)(vite@5.4.10(@types/node@22.5.4)(terser@5.34.1))': + '@joshwooding/vite-plugin-react-docgen-typescript@0.3.1(typescript@5.5.4)(vite@5.4.11(@types/node@22.5.4)(terser@5.34.1))': dependencies: glob: 7.2.3 glob-promise: 4.2.2(glob@7.2.3) magic-string: 0.27.0 react-docgen-typescript: 2.2.2(typescript@5.5.4) - vite: 5.4.10(@types/node@22.5.4)(terser@5.34.1) + vite: 5.4.11(@types/node@22.5.4)(terser@5.34.1) optionalDependencies: typescript: 5.5.4 - '@joshwooding/vite-plugin-react-docgen-typescript@0.3.1(typescript@5.6.2)(vite@5.4.10(@types/node@22.7.4)(terser@5.34.1))': + '@joshwooding/vite-plugin-react-docgen-typescript@0.3.1(typescript@5.6.2)(vite@5.4.11(@types/node@22.7.4)(terser@5.34.1))': dependencies: glob: 7.2.3 glob-promise: 4.2.2(glob@7.2.3) magic-string: 0.27.0 react-docgen-typescript: 2.2.2(typescript@5.6.2) - vite: 5.4.10(@types/node@22.7.4)(terser@5.34.1) + vite: 5.4.11(@types/node@22.7.4)(terser@5.34.1) optionalDependencies: typescript: 5.6.2 @@ -10559,15 +10676,15 @@ snapshots: outvariant: 1.4.3 strict-event-emitter: 0.5.1 - '@mui/core-downloads-tracker@6.1.6': {} + '@mui/core-downloads-tracker@6.1.9': {} '@mui/material@6.1.1(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.26.0 - '@mui/core-downloads-tracker': 6.1.6 - '@mui/system': 6.1.6(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1) + '@mui/core-downloads-tracker': 6.1.9 + '@mui/system': 6.1.9(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1) '@mui/types': 7.2.19(@types/react@18.3.5) - '@mui/utils': 6.1.6(@types/react@18.3.5)(react@18.3.1) + '@mui/utils': 6.1.9(@types/react@18.3.5)(react@18.3.1) '@popperjs/core': 2.11.8 '@types/react-transition-group': 4.4.11 clsx: 2.1.1 @@ -10582,20 +10699,20 @@ snapshots: '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1) '@types/react': 18.3.5 - '@mui/private-theming@6.1.6(@types/react@18.3.5)(react@18.3.1)': + '@mui/private-theming@6.1.9(@types/react@18.3.5)(react@18.3.1)': dependencies: '@babel/runtime': 7.26.0 - '@mui/utils': 6.1.6(@types/react@18.3.5)(react@18.3.1) + '@mui/utils': 6.1.9(@types/react@18.3.5)(react@18.3.1) prop-types: 15.8.1 react: 18.3.1 optionalDependencies: '@types/react': 18.3.5 - '@mui/styled-engine@6.1.6(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1)': + '@mui/styled-engine@6.1.9(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.26.0 - '@emotion/cache': 11.13.1 - '@emotion/serialize': 1.3.2 + '@emotion/cache': 11.13.5 + '@emotion/serialize': 1.3.3 '@emotion/sheet': 1.4.0 csstype: 3.1.3 prop-types: 15.8.1 @@ -10604,13 +10721,13 @@ snapshots: '@emotion/react': 11.13.3(@types/react@18.3.5)(react@18.3.1) '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1) - '@mui/system@6.1.6(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1)': + '@mui/system@6.1.9(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1)': dependencies: '@babel/runtime': 7.26.0 - '@mui/private-theming': 6.1.6(@types/react@18.3.5)(react@18.3.1) - '@mui/styled-engine': 6.1.6(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1) + '@mui/private-theming': 6.1.9(@types/react@18.3.5)(react@18.3.1) + '@mui/styled-engine': 6.1.9(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1) '@mui/types': 7.2.19(@types/react@18.3.5) - '@mui/utils': 6.1.6(@types/react@18.3.5)(react@18.3.1) + '@mui/utils': 6.1.9(@types/react@18.3.5)(react@18.3.1) clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 @@ -10624,7 +10741,7 @@ snapshots: optionalDependencies: '@types/react': 18.3.5 - '@mui/utils@6.1.6(@types/react@18.3.5)(react@18.3.1)': + '@mui/utils@6.1.9(@types/react@18.3.5)(react@18.3.1)': dependencies: '@babel/runtime': 7.26.0 '@mui/types': 7.2.19(@types/react@18.3.5) @@ -10638,6 +10755,8 @@ snapshots: '@noble/hashes@1.5.0': {} + '@noble/hashes@1.6.1': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -10705,9 +10824,9 @@ snapshots: - typescript - vitest - '@penumbra-zone/crypto-web@28.0.0(@penumbra-zone/types@26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))': + '@penumbra-zone/crypto-web@29.0.1(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))': dependencies: - '@penumbra-zone/types': 26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) + '@penumbra-zone/types': 26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) bip39: 3.1.0 crypto-js: 4.2.0 @@ -10719,54 +10838,41 @@ snapshots: '@penumbra-zone/keys@4.2.1': {} - '@penumbra-zone/perspective@36.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/wasm@32.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))))': + '@penumbra-zone/perspective@39.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/wasm@33.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))))': dependencies: '@bufbuild/protobuf': 1.10.0 '@penumbra-zone/bech32m': 10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) '@penumbra-zone/getters': 20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) '@penumbra-zone/protobuf': 6.3.0(@bufbuild/protobuf@1.10.0) - '@penumbra-zone/wasm': 32.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) + '@penumbra-zone/wasm': 33.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) '@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)': dependencies: '@bufbuild/protobuf': 1.10.0 - '@penumbra-zone/query@37.0.0(htymxraugqbluqqla3g523ff4i)': - dependencies: - '@bufbuild/protobuf': 1.10.0 - '@connectrpc/connect': 1.4.0(@bufbuild/protobuf@1.10.0) - '@connectrpc/connect-web': 1.4.0(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0)) - '@penumbra-zone/bech32m': 10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) - '@penumbra-zone/crypto-web': 28.0.0(@penumbra-zone/types@26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) - '@penumbra-zone/getters': 20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) - '@penumbra-zone/protobuf': 6.3.0(@bufbuild/protobuf@1.10.0) - '@penumbra-zone/types': 26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) - '@penumbra-zone/wasm': 32.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) - exponential-backoff: 3.1.1 - - '@penumbra-zone/services@41.0.1(bea7luxaeaz2agxedzi5yqnhfm)': + '@penumbra-zone/services@44.0.0(54wyt4x6rbd5bfc2l4nqok2nh4)': dependencies: '@bufbuild/protobuf': 1.10.0 '@connectrpc/connect': 1.4.0(@bufbuild/protobuf@1.10.0) '@penumbra-zone/bech32m': 10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) - '@penumbra-zone/crypto-web': 28.0.0(@penumbra-zone/types@26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) + '@penumbra-zone/crypto-web': 29.0.1(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) '@penumbra-zone/getters': 20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) '@penumbra-zone/protobuf': 6.3.0(@bufbuild/protobuf@1.10.0) - '@penumbra-zone/query': 37.0.0(htymxraugqbluqqla3g523ff4i) - '@penumbra-zone/storage': 36.0.1(22nytnrbt7ixf4wow4zyq4xyze) + '@penumbra-zone/query': link:packages/query + '@penumbra-zone/storage': 39.0.0(mazdjjpndxgwbkfdli2rf6n6ne) '@penumbra-zone/transport-dom': 7.5.0 - '@penumbra-zone/types': 26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) - '@penumbra-zone/wasm': 32.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) + '@penumbra-zone/types': 26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) + '@penumbra-zone/wasm': 33.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) - '@penumbra-zone/storage@36.0.1(22nytnrbt7ixf4wow4zyq4xyze)': + '@penumbra-zone/storage@39.0.0(mazdjjpndxgwbkfdli2rf6n6ne)': dependencies: '@bufbuild/protobuf': 1.10.0 '@penumbra-labs/registry': 12.0.0 '@penumbra-zone/bech32m': 10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) '@penumbra-zone/getters': 20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) '@penumbra-zone/protobuf': 6.3.0(@bufbuild/protobuf@1.10.0) - '@penumbra-zone/types': 26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) - '@penumbra-zone/wasm': 32.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) + '@penumbra-zone/types': 26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) + '@penumbra-zone/wasm': 33.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))) idb: 8.0.0 '@penumbra-zone/transport-chrome@8.0.1(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/transport-dom@7.5.0)': @@ -10780,16 +10886,6 @@ snapshots: '@bufbuild/protobuf': 1.10.0 '@connectrpc/connect': 1.4.0(@bufbuild/protobuf@1.10.0) - '@penumbra-zone/types@26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))': - dependencies: - '@bufbuild/protobuf': 1.10.0 - '@penumbra-zone/bech32m': 10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) - '@penumbra-zone/getters': 20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) - '@penumbra-zone/protobuf': 6.3.0(@bufbuild/protobuf@1.10.0) - bignumber.js: 9.1.2 - idb: 8.0.0 - zod: 3.23.8 - '@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))': dependencies: '@bufbuild/protobuf': 1.10.0 @@ -10802,16 +10898,7 @@ snapshots: lodash: 4.17.21 zod: 3.23.8 - '@penumbra-zone/wasm@32.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))': - dependencies: - '@bufbuild/protobuf': 1.10.0 - '@penumbra-zone/bech32m': 10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) - '@penumbra-zone/protobuf': 6.3.0(@bufbuild/protobuf@1.10.0) - '@penumbra-zone/types': 26.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) - optionalDependencies: - '@penumbra-zone/keys': 4.2.1 - - '@penumbra-zone/wasm@32.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))': + '@penumbra-zone/wasm@33.1.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@26.2.1(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@20.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)))': dependencies: '@bufbuild/protobuf': 1.10.0 '@penumbra-zone/bech32m': 10.0.0(@penumbra-zone/protobuf@6.3.0(@bufbuild/protobuf@1.10.0)) @@ -11464,114 +11551,114 @@ snapshots: '@remix-run/router@1.19.1': {} - '@rollup/pluginutils@5.1.0(rollup@4.24.3)': + '@rollup/pluginutils@5.1.0(rollup@4.28.0)': dependencies: '@types/estree': 1.0.5 estree-walker: 2.0.2 picomatch: 2.3.1 optionalDependencies: - rollup: 4.24.3 + rollup: 4.28.0 '@rollup/rollup-android-arm-eabi@4.21.2': optional: true - '@rollup/rollup-android-arm-eabi@4.24.3': + '@rollup/rollup-android-arm-eabi@4.28.0': optional: true '@rollup/rollup-android-arm64@4.21.2': optional: true - '@rollup/rollup-android-arm64@4.24.3': + '@rollup/rollup-android-arm64@4.28.0': optional: true '@rollup/rollup-darwin-arm64@4.21.2': optional: true - '@rollup/rollup-darwin-arm64@4.24.3': + '@rollup/rollup-darwin-arm64@4.28.0': optional: true '@rollup/rollup-darwin-x64@4.21.2': optional: true - '@rollup/rollup-darwin-x64@4.24.3': + '@rollup/rollup-darwin-x64@4.28.0': optional: true - '@rollup/rollup-freebsd-arm64@4.24.3': + '@rollup/rollup-freebsd-arm64@4.28.0': optional: true - '@rollup/rollup-freebsd-x64@4.24.3': + '@rollup/rollup-freebsd-x64@4.28.0': optional: true '@rollup/rollup-linux-arm-gnueabihf@4.21.2': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.24.3': + '@rollup/rollup-linux-arm-gnueabihf@4.28.0': optional: true '@rollup/rollup-linux-arm-musleabihf@4.21.2': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.24.3': + '@rollup/rollup-linux-arm-musleabihf@4.28.0': optional: true '@rollup/rollup-linux-arm64-gnu@4.21.2': optional: true - '@rollup/rollup-linux-arm64-gnu@4.24.3': + '@rollup/rollup-linux-arm64-gnu@4.28.0': optional: true '@rollup/rollup-linux-arm64-musl@4.21.2': optional: true - '@rollup/rollup-linux-arm64-musl@4.24.3': + '@rollup/rollup-linux-arm64-musl@4.28.0': optional: true '@rollup/rollup-linux-powerpc64le-gnu@4.21.2': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.24.3': + '@rollup/rollup-linux-powerpc64le-gnu@4.28.0': optional: true '@rollup/rollup-linux-riscv64-gnu@4.21.2': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.24.3': + '@rollup/rollup-linux-riscv64-gnu@4.28.0': optional: true '@rollup/rollup-linux-s390x-gnu@4.21.2': optional: true - '@rollup/rollup-linux-s390x-gnu@4.24.3': + '@rollup/rollup-linux-s390x-gnu@4.28.0': optional: true '@rollup/rollup-linux-x64-gnu@4.21.2': optional: true - '@rollup/rollup-linux-x64-gnu@4.24.3': + '@rollup/rollup-linux-x64-gnu@4.28.0': optional: true '@rollup/rollup-linux-x64-musl@4.21.2': optional: true - '@rollup/rollup-linux-x64-musl@4.24.3': + '@rollup/rollup-linux-x64-musl@4.28.0': optional: true '@rollup/rollup-win32-arm64-msvc@4.21.2': optional: true - '@rollup/rollup-win32-arm64-msvc@4.24.3': + '@rollup/rollup-win32-arm64-msvc@4.28.0': optional: true '@rollup/rollup-win32-ia32-msvc@4.21.2': optional: true - '@rollup/rollup-win32-ia32-msvc@4.24.3': + '@rollup/rollup-win32-ia32-msvc@4.28.0': optional: true '@rollup/rollup-win32-x64-msvc@4.21.2': optional: true - '@rollup/rollup-win32-x64-msvc@4.24.3': + '@rollup/rollup-win32-x64-msvc@4.28.0': optional: true '@rtsao/scc@1.1.0': {} @@ -11723,7 +11810,7 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@storybook/builder-vite@8.2.9(storybook@8.2.9(@babel/preset-env@7.25.4(@babel/core@7.25.2)))(typescript@5.6.2)(vite@5.4.10(@types/node@22.7.4)(terser@5.34.1))(webpack-sources@3.2.3)': + '@storybook/builder-vite@8.2.9(storybook@8.2.9(@babel/preset-env@7.25.4(@babel/core@7.25.2)))(typescript@5.6.2)(vite@5.4.11(@types/node@22.7.4)(terser@5.34.1))(webpack-sources@3.2.3)': dependencies: '@storybook/csf-plugin': 8.2.9(storybook@8.2.9(@babel/preset-env@7.25.4(@babel/core@7.25.2)))(webpack-sources@3.2.3) '@types/find-cache-dir': 3.2.1 @@ -11735,14 +11822,14 @@ snapshots: magic-string: 0.30.11 storybook: 8.2.9(@babel/preset-env@7.25.4(@babel/core@7.25.2)) ts-dedent: 2.2.0 - vite: 5.4.10(@types/node@22.7.4)(terser@5.34.1) + vite: 5.4.11(@types/node@22.7.4)(terser@5.34.1) optionalDependencies: typescript: 5.6.2 transitivePeerDependencies: - supports-color - webpack-sources - '@storybook/builder-vite@8.2.9(storybook@8.3.4)(typescript@5.5.4)(vite@5.4.10(@types/node@22.5.4)(terser@5.34.1))(webpack-sources@3.2.3)': + '@storybook/builder-vite@8.2.9(storybook@8.3.4)(typescript@5.5.4)(vite@5.4.11(@types/node@22.5.4)(terser@5.34.1))(webpack-sources@3.2.3)': dependencies: '@storybook/csf-plugin': 8.2.9(storybook@8.3.4)(webpack-sources@3.2.3) '@types/find-cache-dir': 3.2.1 @@ -11754,7 +11841,7 @@ snapshots: magic-string: 0.30.11 storybook: 8.3.4 ts-dedent: 2.2.0 - vite: 5.4.10(@types/node@22.5.4)(terser@5.34.1) + vite: 5.4.11(@types/node@22.5.4)(terser@5.34.1) optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: @@ -11809,7 +11896,7 @@ snapshots: '@storybook/core@8.3.4': dependencies: - '@storybook/csf': 0.1.11 + '@storybook/csf': 0.1.12 '@types/express': 4.17.21 better-opn: 3.0.2 browser-assert: 1.2.1 @@ -11849,6 +11936,10 @@ snapshots: dependencies: type-fest: 2.19.0 + '@storybook/csf@0.1.12': + dependencies: + type-fest: 2.19.0 + '@storybook/global@5.0.0': {} '@storybook/icons@1.2.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': @@ -11899,11 +11990,11 @@ snapshots: react-dom: 18.3.1(react@18.3.1) storybook: 8.3.4 - '@storybook/react-vite@8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.24.3)(storybook@8.2.9(@babel/preset-env@7.25.4(@babel/core@7.25.2)))(typescript@5.6.2)(vite@5.4.10(@types/node@22.7.4)(terser@5.34.1))(webpack-sources@3.2.3)': + '@storybook/react-vite@8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.28.0)(storybook@8.2.9(@babel/preset-env@7.25.4(@babel/core@7.25.2)))(typescript@5.6.2)(vite@5.4.11(@types/node@22.7.4)(terser@5.34.1))(webpack-sources@3.2.3)': dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.3.1(typescript@5.6.2)(vite@5.4.10(@types/node@22.7.4)(terser@5.34.1)) - '@rollup/pluginutils': 5.1.0(rollup@4.24.3) - '@storybook/builder-vite': 8.2.9(storybook@8.2.9(@babel/preset-env@7.25.4(@babel/core@7.25.2)))(typescript@5.6.2)(vite@5.4.10(@types/node@22.7.4)(terser@5.34.1))(webpack-sources@3.2.3) + '@joshwooding/vite-plugin-react-docgen-typescript': 0.3.1(typescript@5.6.2)(vite@5.4.11(@types/node@22.7.4)(terser@5.34.1)) + '@rollup/pluginutils': 5.1.0(rollup@4.28.0) + '@storybook/builder-vite': 8.2.9(storybook@8.2.9(@babel/preset-env@7.25.4(@babel/core@7.25.2)))(typescript@5.6.2)(vite@5.4.11(@types/node@22.7.4)(terser@5.34.1))(webpack-sources@3.2.3) '@storybook/react': 8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.2.9(@babel/preset-env@7.25.4(@babel/core@7.25.2)))(typescript@5.6.2) find-up: 5.0.0 magic-string: 0.30.11 @@ -11913,7 +12004,7 @@ snapshots: resolve: 1.22.8 storybook: 8.2.9(@babel/preset-env@7.25.4(@babel/core@7.25.2)) tsconfig-paths: 4.2.0 - vite: 5.4.10(@types/node@22.7.4)(terser@5.34.1) + vite: 5.4.11(@types/node@22.7.4)(terser@5.34.1) transitivePeerDependencies: - '@preact/preset-vite' - rollup @@ -11922,11 +12013,11 @@ snapshots: - vite-plugin-glimmerx - webpack-sources - '@storybook/react-vite@8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.24.3)(storybook@8.3.4)(typescript@5.5.4)(vite@5.4.10(@types/node@22.5.4)(terser@5.34.1))(webpack-sources@3.2.3)': + '@storybook/react-vite@8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.28.0)(storybook@8.3.4)(typescript@5.5.4)(vite@5.4.11(@types/node@22.5.4)(terser@5.34.1))(webpack-sources@3.2.3)': dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.3.1(typescript@5.5.4)(vite@5.4.10(@types/node@22.5.4)(terser@5.34.1)) - '@rollup/pluginutils': 5.1.0(rollup@4.24.3) - '@storybook/builder-vite': 8.2.9(storybook@8.3.4)(typescript@5.5.4)(vite@5.4.10(@types/node@22.5.4)(terser@5.34.1))(webpack-sources@3.2.3) + '@joshwooding/vite-plugin-react-docgen-typescript': 0.3.1(typescript@5.5.4)(vite@5.4.11(@types/node@22.5.4)(terser@5.34.1)) + '@rollup/pluginutils': 5.1.0(rollup@4.28.0) + '@storybook/builder-vite': 8.2.9(storybook@8.3.4)(typescript@5.5.4)(vite@5.4.11(@types/node@22.5.4)(terser@5.34.1))(webpack-sources@3.2.3) '@storybook/react': 8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.3.4)(typescript@5.5.4) find-up: 5.0.0 magic-string: 0.30.11 @@ -11936,7 +12027,7 @@ snapshots: resolve: 1.22.8 storybook: 8.3.4 tsconfig-paths: 4.2.0 - vite: 5.4.10(@types/node@22.5.4)(terser@5.34.1) + vite: 5.4.11(@types/node@22.5.4)(terser@5.34.1) transitivePeerDependencies: - '@preact/preset-vite' - rollup @@ -12062,7 +12153,7 @@ snapshots: '@swc/core@1.7.28': dependencies: '@swc/counter': 0.1.3 - '@swc/types': 0.1.12 + '@swc/types': 0.1.17 optionalDependencies: '@swc/core-darwin-arm64': 1.7.28 '@swc/core-darwin-x64': 1.7.28 @@ -12079,7 +12170,7 @@ snapshots: '@swc/counter@0.1.3': optional: true - '@swc/types@0.1.12': + '@swc/types@0.1.17': dependencies: '@swc/counter': 0.1.3 optional: true @@ -12525,7 +12616,7 @@ snapshots: '@typescript-eslint/utils@7.18.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.5.4)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.16.0(jiti@1.21.6)) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.16.0(jiti@1.21.6)) '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) @@ -12590,14 +12681,14 @@ snapshots: tinyrainbow: 1.2.0 optional: true - '@vitest/mocker@2.1.1(@vitest/spy@2.1.1)(msw@2.4.2(graphql@16.9.0)(typescript@5.6.2))(vite@5.4.10(@types/node@22.7.4)(terser@5.34.1))': + '@vitest/mocker@2.1.1(@vitest/spy@2.1.1)(msw@2.4.2(graphql@16.9.0)(typescript@5.6.2))(vite@5.4.11(@types/node@22.7.4)(terser@5.34.1))': dependencies: '@vitest/spy': 2.1.1 estree-walker: 3.0.3 - magic-string: 0.30.12 + magic-string: 0.30.14 optionalDependencies: msw: 2.4.2(graphql@16.9.0)(typescript@5.6.2) - vite: 5.4.10(@types/node@22.7.4)(terser@5.34.1) + vite: 5.4.11(@types/node@22.7.4)(terser@5.34.1) optional: true '@vitest/pretty-format@2.0.5': @@ -12609,7 +12700,7 @@ snapshots: tinyrainbow: 1.2.0 optional: true - '@vitest/pretty-format@2.1.4': + '@vitest/pretty-format@2.1.8': dependencies: tinyrainbow: 1.2.0 optional: true @@ -12635,7 +12726,7 @@ snapshots: '@vitest/snapshot@2.1.1': dependencies: '@vitest/pretty-format': 2.1.1 - magic-string: 0.30.12 + magic-string: 0.30.14 pathe: 1.1.2 optional: true @@ -12674,20 +12765,39 @@ snapshots: '@webassemblyjs/helper-numbers': 1.11.6 '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/ast@1.14.1': + dependencies: + '@webassemblyjs/helper-numbers': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/floating-point-hex-parser@1.11.6': {} + '@webassemblyjs/floating-point-hex-parser@1.13.2': {} + '@webassemblyjs/helper-api-error@1.11.6': {} + '@webassemblyjs/helper-api-error@1.13.2': {} + '@webassemblyjs/helper-buffer@1.12.1': {} + '@webassemblyjs/helper-buffer@1.14.1': {} + '@webassemblyjs/helper-numbers@1.11.6': dependencies: '@webassemblyjs/floating-point-hex-parser': 1.11.6 '@webassemblyjs/helper-api-error': 1.11.6 '@xtuc/long': 4.2.2 + '@webassemblyjs/helper-numbers@1.13.2': + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.13.2 + '@webassemblyjs/helper-api-error': 1.13.2 + '@xtuc/long': 4.2.2 + '@webassemblyjs/helper-wasm-bytecode@1.11.6': {} + '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} + '@webassemblyjs/helper-wasm-section@1.12.1': dependencies: '@webassemblyjs/ast': 1.12.1 @@ -12695,16 +12805,33 @@ snapshots: '@webassemblyjs/helper-wasm-bytecode': 1.11.6 '@webassemblyjs/wasm-gen': 1.12.1 + '@webassemblyjs/helper-wasm-section@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/ieee754@1.11.6': dependencies: '@xtuc/ieee754': 1.2.0 + '@webassemblyjs/ieee754@1.13.2': + dependencies: + '@xtuc/ieee754': 1.2.0 + '@webassemblyjs/leb128@1.11.6': dependencies: '@xtuc/long': 4.2.2 + '@webassemblyjs/leb128@1.13.2': + dependencies: + '@xtuc/long': 4.2.2 + '@webassemblyjs/utf8@1.11.6': {} + '@webassemblyjs/utf8@1.13.2': {} + '@webassemblyjs/wasm-edit@1.12.1': dependencies: '@webassemblyjs/ast': 1.12.1 @@ -12716,6 +12843,17 @@ snapshots: '@webassemblyjs/wasm-parser': 1.12.1 '@webassemblyjs/wast-printer': 1.12.1 + '@webassemblyjs/wasm-edit@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/helper-wasm-section': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-opt': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wast-printer': 1.14.1 + '@webassemblyjs/wasm-gen@1.12.1': dependencies: '@webassemblyjs/ast': 1.12.1 @@ -12724,6 +12862,14 @@ snapshots: '@webassemblyjs/leb128': 1.11.6 '@webassemblyjs/utf8': 1.11.6 + '@webassemblyjs/wasm-gen@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + '@webassemblyjs/wasm-opt@1.12.1': dependencies: '@webassemblyjs/ast': 1.12.1 @@ -12731,6 +12877,13 @@ snapshots: '@webassemblyjs/wasm-gen': 1.12.1 '@webassemblyjs/wasm-parser': 1.12.1 + '@webassemblyjs/wasm-opt@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wasm-parser@1.12.1': dependencies: '@webassemblyjs/ast': 1.12.1 @@ -12740,11 +12893,25 @@ snapshots: '@webassemblyjs/leb128': 1.11.6 '@webassemblyjs/utf8': 1.11.6 + '@webassemblyjs/wasm-parser@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-api-error': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + '@webassemblyjs/wast-printer@1.12.1': dependencies: '@webassemblyjs/ast': 1.12.1 '@xtuc/long': 4.2.2 + '@webassemblyjs/wast-printer@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@xtuc/long': 4.2.2 + '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.94.0)': dependencies: webpack: 5.94.0(@swc/core@1.7.28)(esbuild@0.23.1)(webpack-cli@5.1.4) @@ -12987,7 +13154,7 @@ snapshots: es-abstract: 1.23.5 es-object-atoms: 1.0.0 get-intrinsic: 1.2.4 - is-string: 1.0.7 + is-string: 1.1.0 array-union@2.1.0: {} @@ -13149,7 +13316,7 @@ snapshots: bip39@3.1.0: dependencies: - '@noble/hashes': 1.5.0 + '@noble/hashes': 1.6.1 bl@4.1.0: dependencies: @@ -13240,8 +13407,8 @@ snapshots: browserslist@4.24.0: dependencies: - caniuse-lite: 1.0.30001676 - electron-to-chromium: 1.5.50 + caniuse-lite: 1.0.30001686 + electron-to-chromium: 1.5.68 node-releases: 2.0.18 update-browserslist-db: 1.1.1(browserslist@4.24.0) @@ -13318,7 +13485,7 @@ snapshots: caniuse-lite@1.0.30001658: {} - caniuse-lite@1.0.30001676: {} + caniuse-lite@1.0.30001686: {} chai@4.5.0: dependencies: @@ -13965,7 +14132,7 @@ snapshots: electron-to-chromium@1.5.18: {} - electron-to-chromium@1.5.50: {} + electron-to-chromium@1.5.68: {} elliptic@6.5.7: dependencies: @@ -14035,8 +14202,8 @@ snapshots: globalthis: 1.0.4 gopd: 1.1.0 has-property-descriptors: 1.0.2 - has-proto: 1.0.3 - has-symbols: 1.0.3 + has-proto: 1.1.0 + has-symbols: 1.1.0 hasown: 2.0.2 internal-slot: 1.0.7 is-array-buffer: 3.0.4 @@ -14045,7 +14212,7 @@ snapshots: is-negative-zero: 2.0.3 is-regex: 1.2.0 is-shared-array-buffer: 1.0.3 - is-string: 1.0.7 + is-string: 1.1.0 is-typed-array: 1.1.13 is-weakref: 1.0.2 object-inspect: 1.13.3 @@ -14062,7 +14229,7 @@ snapshots: typed-array-byte-offset: 1.0.3 typed-array-length: 1.0.7 unbox-primitive: 1.0.2 - which-typed-array: 1.1.15 + which-typed-array: 1.1.16 es-define-property@1.0.0: dependencies: @@ -14082,8 +14249,8 @@ snapshots: globalthis: 1.0.4 gopd: 1.1.0 has-property-descriptors: 1.0.2 - has-proto: 1.0.3 - has-symbols: 1.0.3 + has-proto: 1.1.0 + has-symbols: 1.1.0 internal-slot: 1.0.7 iterator.prototype: 1.1.3 safe-array-concat: 1.1.2 @@ -14108,7 +14275,7 @@ snapshots: dependencies: is-callable: 1.2.7 is-date-object: 1.0.5 - is-symbol: 1.0.4 + is-symbol: 1.1.0 es6-error@4.1.1: {} @@ -14217,7 +14384,7 @@ snapshots: eslint: 9.16.0(jiti@1.21.6) eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.16.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.16.0(jiti@1.21.6)) fast-glob: 3.3.2 - get-tsconfig: 4.8.0 + get-tsconfig: 4.8.1 is-bun-module: 1.3.0 is-glob: 4.0.3 optionalDependencies: @@ -14247,12 +14414,12 @@ snapshots: doctrine: 3.0.0 eslint: 9.16.0(jiti@1.21.6) eslint-import-resolver-node: 0.3.9 - get-tsconfig: 4.8.0 + get-tsconfig: 4.8.1 is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.3 stable-hash: 0.0.4 - tslib: 2.7.0 + tslib: 2.8.1 transitivePeerDependencies: - supports-color - typescript @@ -14338,7 +14505,7 @@ snapshots: eslint-plugin-tailwindcss@3.17.5(tailwindcss@3.4.10(ts-node@10.9.2(@swc/core@1.7.28)(@types/node@22.5.4)(typescript@5.5.4))): dependencies: fast-glob: 3.3.2 - postcss: 8.4.47 + postcss: 8.4.49 tailwindcss: 3.4.10(ts-node@10.9.2(@swc/core@1.7.28)(@types/node@22.5.4)(typescript@5.5.4)) eslint-plugin-turbo@2.3.3(eslint@9.16.0(jiti@1.21.6)): @@ -14925,6 +15092,10 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 + get-tsconfig@4.8.1: + dependencies: + resolve-pkg-maps: 1.0.0 + get-uri@6.0.3: dependencies: basic-ftp: 5.0.5 @@ -15105,8 +15276,14 @@ snapshots: has-proto@1.0.3: {} + has-proto@1.1.0: + dependencies: + call-bind: 1.0.7 + has-symbols@1.0.3: {} + has-symbols@1.1.0: {} + has-tostringtag@1.0.2: dependencies: has-symbols: 1.0.3 @@ -15376,7 +15553,7 @@ snapshots: dependencies: has-tostringtag: 1.0.2 - is-bigint@1.0.4: + is-bigint@1.1.0: dependencies: has-bigints: 1.0.2 @@ -15384,7 +15561,7 @@ snapshots: dependencies: binary-extensions: 2.3.0 - is-boolean-object@1.1.2: + is-boolean-object@1.2.0: dependencies: call-bind: 1.0.7 has-tostringtag: 1.0.2 @@ -15458,8 +15635,9 @@ snapshots: is-npm@6.0.0: {} - is-number-object@1.0.7: + is-number-object@1.1.0: dependencies: + call-bind: 1.0.7 has-tostringtag: 1.0.2 is-number@7.0.0: {} @@ -15497,17 +15675,20 @@ snapshots: is-stream@3.0.0: {} - is-string@1.0.7: + is-string@1.1.0: dependencies: + call-bind: 1.0.7 has-tostringtag: 1.0.2 is-subdir@1.2.0: dependencies: better-path-resolve: 1.0.0 - is-symbol@1.0.4: + is-symbol@1.1.0: dependencies: - has-symbols: 1.0.3 + call-bind: 1.0.7 + has-symbols: 1.1.0 + safe-regex-test: 1.0.3 is-typed-array@1.1.13: dependencies: @@ -15566,7 +15747,7 @@ snapshots: dependencies: define-properties: 1.2.1 get-intrinsic: 1.2.4 - has-symbols: 1.0.3 + has-symbols: 1.1.0 reflect.getprototypeof: 1.0.7 set-function-name: 2.0.2 @@ -15874,7 +16055,7 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 - magic-string@0.30.12: + magic-string@0.30.14: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 optional: true @@ -16076,6 +16257,8 @@ snapshots: nanoid@3.3.7: {} + nanoid@3.3.8: {} + natural-compare@1.4.0: {} ncp@2.0.0: @@ -16194,7 +16377,7 @@ snapshots: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - has-symbols: 1.0.3 + has-symbols: 1.1.0 object-keys: 1.1.1 object.entries@1.1.8: @@ -16665,9 +16848,9 @@ snapshots: picocolors: 1.1.0 source-map-js: 1.2.0 - postcss@8.4.47: + postcss@8.4.49: dependencies: - nanoid: 3.3.7 + nanoid: 3.3.8 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -17176,28 +17359,28 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.21.2 fsevents: 2.3.3 - rollup@4.24.3: + rollup@4.28.0: dependencies: '@types/estree': 1.0.6 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.24.3 - '@rollup/rollup-android-arm64': 4.24.3 - '@rollup/rollup-darwin-arm64': 4.24.3 - '@rollup/rollup-darwin-x64': 4.24.3 - '@rollup/rollup-freebsd-arm64': 4.24.3 - '@rollup/rollup-freebsd-x64': 4.24.3 - '@rollup/rollup-linux-arm-gnueabihf': 4.24.3 - '@rollup/rollup-linux-arm-musleabihf': 4.24.3 - '@rollup/rollup-linux-arm64-gnu': 4.24.3 - '@rollup/rollup-linux-arm64-musl': 4.24.3 - '@rollup/rollup-linux-powerpc64le-gnu': 4.24.3 - '@rollup/rollup-linux-riscv64-gnu': 4.24.3 - '@rollup/rollup-linux-s390x-gnu': 4.24.3 - '@rollup/rollup-linux-x64-gnu': 4.24.3 - '@rollup/rollup-linux-x64-musl': 4.24.3 - '@rollup/rollup-win32-arm64-msvc': 4.24.3 - '@rollup/rollup-win32-ia32-msvc': 4.24.3 - '@rollup/rollup-win32-x64-msvc': 4.24.3 + '@rollup/rollup-android-arm-eabi': 4.28.0 + '@rollup/rollup-android-arm64': 4.28.0 + '@rollup/rollup-darwin-arm64': 4.28.0 + '@rollup/rollup-darwin-x64': 4.28.0 + '@rollup/rollup-freebsd-arm64': 4.28.0 + '@rollup/rollup-freebsd-x64': 4.28.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.28.0 + '@rollup/rollup-linux-arm-musleabihf': 4.28.0 + '@rollup/rollup-linux-arm64-gnu': 4.28.0 + '@rollup/rollup-linux-arm64-musl': 4.28.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.28.0 + '@rollup/rollup-linux-riscv64-gnu': 4.28.0 + '@rollup/rollup-linux-s390x-gnu': 4.28.0 + '@rollup/rollup-linux-x64-gnu': 4.28.0 + '@rollup/rollup-linux-x64-musl': 4.28.0 + '@rollup/rollup-win32-arm64-msvc': 4.28.0 + '@rollup/rollup-win32-ia32-msvc': 4.28.0 + '@rollup/rollup-win32-x64-msvc': 4.28.0 fsevents: 2.3.3 rrweb-cssom@0.6.0: {} @@ -17226,7 +17409,7 @@ snapshots: dependencies: call-bind: 1.0.7 get-intrinsic: 1.2.4 - has-symbols: 1.0.3 + has-symbols: 1.1.0 isarray: 2.0.5 safe-buffer@5.1.2: {} @@ -17497,6 +17680,9 @@ snapshots: std-env@3.7.0: {} + std-env@3.8.0: + optional: true + stdin-discarder@0.2.2: {} storybook@8.2.9(@babel/preset-env@7.25.4(@babel/core@7.25.2)): @@ -17572,7 +17758,7 @@ snapshots: es-object-atoms: 1.0.0 get-intrinsic: 1.2.4 gopd: 1.1.0 - has-symbols: 1.0.3 + has-symbols: 1.1.0 internal-slot: 1.0.7 regexp.prototype.flags: 1.5.3 set-function-name: 2.0.2 @@ -17719,7 +17905,7 @@ snapshots: synckit@0.9.2: dependencies: '@pkgr/core': 0.1.1 - tslib: 2.7.0 + tslib: 2.8.1 syncpack@13.0.0(typescript@5.5.4): dependencies: @@ -17907,7 +18093,7 @@ snapshots: tinypool@0.8.4: {} - tinypool@1.0.1: + tinypool@1.0.2: optional: true tinyrainbow@1.2.0: {} @@ -18034,6 +18220,8 @@ snapshots: tslib@2.7.0: {} + tslib@2.8.1: {} + tsx@4.19.0: dependencies: esbuild: 0.23.1 @@ -18102,7 +18290,7 @@ snapshots: call-bind: 1.0.7 for-each: 0.3.3 gopd: 1.1.0 - has-proto: 1.0.3 + has-proto: 1.1.0 is-typed-array: 1.1.13 typed-array-byte-offset@1.0.3: @@ -18111,7 +18299,7 @@ snapshots: call-bind: 1.0.7 for-each: 0.3.3 gopd: 1.1.0 - has-proto: 1.0.3 + has-proto: 1.1.0 is-typed-array: 1.1.13 reflect.getprototypeof: 1.0.7 @@ -18154,8 +18342,8 @@ snapshots: dependencies: call-bind: 1.0.7 has-bigints: 1.0.2 - has-symbols: 1.0.3 - which-boxed-primitive: 1.0.2 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.0 undici-types@5.26.5: {} @@ -18338,7 +18526,7 @@ snapshots: cac: 6.7.14 debug: 4.3.7 pathe: 1.1.2 - vite: 5.4.10(@types/node@22.7.4)(terser@5.34.1) + vite: 5.4.11(@types/node@22.7.4)(terser@5.34.1) transitivePeerDependencies: - '@types/node' - less @@ -18351,21 +18539,21 @@ snapshots: - terser optional: true - vite@5.4.10(@types/node@22.5.4)(terser@5.34.1): + vite@5.4.11(@types/node@22.5.4)(terser@5.34.1): dependencies: esbuild: 0.21.5 - postcss: 8.4.47 - rollup: 4.24.3 + postcss: 8.4.49 + rollup: 4.28.0 optionalDependencies: '@types/node': 22.5.4 fsevents: 2.3.3 terser: 5.34.1 - vite@5.4.10(@types/node@22.7.4)(terser@5.34.1): + vite@5.4.11(@types/node@22.7.4)(terser@5.34.1): dependencies: esbuild: 0.21.5 - postcss: 8.4.47 - rollup: 4.24.3 + postcss: 8.4.49 + rollup: 4.28.0 optionalDependencies: '@types/node': 22.7.4 fsevents: 2.3.3 @@ -18420,22 +18608,22 @@ snapshots: vitest@2.1.1(@types/node@22.7.4)(@vitest/browser@2.0.5)(jsdom@25.0.0)(msw@2.4.2(graphql@16.9.0)(typescript@5.6.2))(terser@5.34.1): dependencies: '@vitest/expect': 2.1.1 - '@vitest/mocker': 2.1.1(@vitest/spy@2.1.1)(msw@2.4.2(graphql@16.9.0)(typescript@5.6.2))(vite@5.4.10(@types/node@22.7.4)(terser@5.34.1)) - '@vitest/pretty-format': 2.1.4 + '@vitest/mocker': 2.1.1(@vitest/spy@2.1.1)(msw@2.4.2(graphql@16.9.0)(typescript@5.6.2))(vite@5.4.11(@types/node@22.7.4)(terser@5.34.1)) + '@vitest/pretty-format': 2.1.8 '@vitest/runner': 2.1.1 '@vitest/snapshot': 2.1.1 '@vitest/spy': 2.1.1 '@vitest/utils': 2.1.1 chai: 5.1.2 debug: 4.3.7 - magic-string: 0.30.12 + magic-string: 0.30.14 pathe: 1.1.2 - std-env: 3.7.0 + std-env: 3.8.0 tinybench: 2.9.0 tinyexec: 0.3.1 - tinypool: 1.0.1 + tinypool: 1.0.2 tinyrainbow: 1.2.0 - vite: 5.4.10(@types/node@22.7.4)(terser@5.34.1) + vite: 5.4.11(@types/node@22.7.4)(terser@5.34.1) vite-node: 2.1.1(@types/node@22.7.4)(terser@5.34.1) why-is-node-running: 2.3.0 optionalDependencies: @@ -18594,9 +18782,9 @@ snapshots: webpack@5.95.0(@swc/core@1.7.28)(esbuild@0.21.5): dependencies: '@types/estree': 1.0.6 - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/wasm-edit': 1.12.1 - '@webassemblyjs/wasm-parser': 1.12.1 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 acorn: 8.14.0 acorn-import-attributes: 1.9.5(acorn@8.14.0) browserslist: 4.24.0 @@ -18634,13 +18822,13 @@ snapshots: when@3.7.7: {} - which-boxed-primitive@1.0.2: + which-boxed-primitive@1.1.0: dependencies: - is-bigint: 1.0.4 - is-boolean-object: 1.1.2 - is-number-object: 1.0.7 - is-string: 1.0.7 - is-symbol: 1.0.4 + is-bigint: 1.1.0 + is-boolean-object: 1.2.0 + is-number-object: 1.1.0 + is-string: 1.1.0 + is-symbol: 1.1.0 which-builtin-type@1.2.0: dependencies: @@ -18654,9 +18842,9 @@ snapshots: is-regex: 1.2.0 is-weakref: 1.0.2 isarray: 2.0.5 - which-boxed-primitive: 1.0.2 + which-boxed-primitive: 1.1.0 which-collection: 1.0.2 - which-typed-array: 1.1.15 + which-typed-array: 1.1.16 which-collection@1.0.2: dependencies: @@ -18673,6 +18861,14 @@ snapshots: gopd: 1.0.1 has-tostringtag: 1.0.2 + which-typed-array@1.1.16: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.1.0 + has-tostringtag: 1.0.2 + which@1.2.4: dependencies: is-absolute: 0.1.7