From 5ce235ee23561116b1e0d46e9dd193c46283b5b0 Mon Sep 17 00:00:00 2001 From: Max Korsunov Date: Wed, 25 Sep 2024 15:47:13 +0200 Subject: [PATCH] feat: implement sync status popover --- next.config.mjs | 8 + package.json | 8 +- pnpm-lock.yaml | 326 ++++++++++++++++---- src/app/v2/layout.tsx | 2 + src/components/copiedTx.tsx | 2 +- src/components/header/index.tsx | 4 +- src/components/header/mobile-nav.tsx | 4 +- src/components/header/status-popover.tsx | 68 ++++ src/components/header/sync-bar.tsx | 18 ++ src/pages/block/[block_height].tsx | 2 +- src/state/status/getSyncPercent.ts | 20 ++ src/state/status/index.ts | 65 ++++ src/{constants => utils}/configConstants.ts | 0 src/utils/token/tokenFetch.tsx | 2 +- styles/v2.css | 5 + 15 files changed, 458 insertions(+), 76 deletions(-) create mode 100644 src/components/header/status-popover.tsx create mode 100644 src/components/header/sync-bar.tsx create mode 100644 src/state/status/getSyncPercent.ts create mode 100644 src/state/status/index.ts rename src/{constants => utils}/configConstants.ts (100%) diff --git a/next.config.mjs b/next.config.mjs index 1a394f6b..68327b7f 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -2,6 +2,14 @@ const nextConfig = { transpilePackages: ["@penumbra-zone/protobuf"], + experimental: { + swcPlugins: [ + [ + "@preact-signals/safe-react/swc", + { mode: "auto" } + ], + ], + }, webpack: (config) => { config.module.rules.push({ test: /\.svg$/i, diff --git a/package.json b/package.json index 45c5d5b9..c4c81356 100644 --- a/package.json +++ b/package.json @@ -28,11 +28,13 @@ "@emotion/styled": "^11.13.0", "@grpc/proto-loader": "^0.7.13", "@penumbra-labs/registry": "^11.3.1", - "@penumbra-zone/client": "^18.1.0", - "@penumbra-zone/protobuf": "^6.0.0", + "@penumbra-zone/client": "^19.0.0", + "@penumbra-zone/protobuf": "^6.1.0", "@penumbra-zone/transport-dom": "^7.5.0", - "@penumbra-zone/ui": "^9.0.0", + "@penumbra-zone/ui": "^10.0.0", "@penumbra-zone/wasm": "^26.2.0", + "@preact-signals/safe-react": "^0.7.0", + "@preact/signals-react": "^2.2.0", "@radix-ui/react-icons": "^1.3.0", "@rehooks/component-size": "^1.0.3", "@styled-icons/octicons": "^10.47.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a0eb288d..be509bde 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,20 +39,26 @@ importers: specifier: ^11.3.1 version: 11.3.1 '@penumbra-zone/client': - specifier: ^18.1.0 - version: 18.1.0(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/transport-dom@7.5.0) + specifier: ^19.0.0 + version: 19.0.0(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/transport-dom@7.5.0) '@penumbra-zone/protobuf': - specifier: ^6.0.0 - version: 6.0.0(@bufbuild/protobuf@1.10.0) + specifier: ^6.1.0 + version: 6.1.0(@bufbuild/protobuf@1.10.0) '@penumbra-zone/transport-dom': specifier: ^7.5.0 version: 7.5.0 '@penumbra-zone/ui': - specifier: ^9.0.0 - version: 9.1.1(22ahnkytf72hixbg7m46epplfq) + specifier: ^10.0.0 + version: 10.0.0(zk5auaacq632y64evccopof44u) '@penumbra-zone/wasm': specifier: ^26.2.0 - version: 26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@23.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))) + version: 26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@24.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0))) + '@preact-signals/safe-react': + specifier: ^0.7.0 + version: 0.7.0(@babel/core@7.25.2)(@swc/helpers@0.5.5)(react@18.3.1) + '@preact/signals-react': + specifier: ^2.2.0 + version: 2.2.0(react@18.3.1) '@radix-ui/react-icons': specifier: ^1.3.0 version: 1.3.0(react@18.3.1) @@ -285,6 +291,10 @@ packages: resolution: {integrity: sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==} engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.24.3': + resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.24.7': resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} engines: {node: '>=6.9.0'} @@ -1810,17 +1820,17 @@ packages: '@penumbra-labs/registry@11.3.1': resolution: {integrity: sha512-0hBfPZW4Y3my6RzYSBGI3cwutW+C7KJXn5OLXOhhXPsH+VlexrxvKIWc8nJeUwRCTtBkRR0lUSwuIhnaw0tsyQ==} - '@penumbra-zone/bech32m@7.0.0': - resolution: {integrity: sha512-OqSH4G8pQ/mjy/7EfS9KlxF8Pdr3h/Ib8ZDOjDyQJB4/L+ZYkK3bWFGrFpAI8XDoc0phoMXkL77fZEpR18JoAg==} + '@penumbra-zone/bech32m@8.0.0': + resolution: {integrity: sha512-1MBJClwos7QGFlY/MH7HOfsY1F99FR/OqeYmkL+1NuTCEHrUENi/pS+WOx56rmVIokqSfRPj8zQCh6gd7aQVuw==} peerDependencies: - '@penumbra-zone/protobuf': 6.0.0 + '@penumbra-zone/protobuf': 6.1.0 - '@penumbra-zone/client@18.1.0': - resolution: {integrity: sha512-khXFquqIpDmXUCwQpP6RfYQnkNI4ekDqz+SP/XCo+7W1xHKJiApXnHDKBA/VsOZ1Q/qGak/R1xfq6z9aV58xSA==} + '@penumbra-zone/client@19.0.0': + resolution: {integrity: sha512-SQOEPJ6XYxzPhoxMG4RKz/dC2zHwW6ldOTpEsJxp1nBIa0gvBjkD7olo2OoX/y3aUBKC5xUxuf44JE9L7p1vLg==} peerDependencies: '@bufbuild/protobuf': ^1.10.0 '@connectrpc/connect': ^1.4.0 - '@penumbra-zone/protobuf': 6.0.0 + '@penumbra-zone/protobuf': 6.1.0 '@penumbra-zone/transport-dom': 7.5.0 '@penumbra-zone/getters@17.0.0': @@ -1834,36 +1844,36 @@ packages: resolution: {integrity: sha512-1K+/8bh53Kse4u/I1afUQuRrTnZhLLA6JWIV+mFiXX8An2J2CGIVDjp1mSJkUSzFjFDUzUX052kvYHCtZYK3QA==} hasBin: true - '@penumbra-zone/perspective@30.0.0': - resolution: {integrity: sha512-jgxWYCURzX5IosFCN70MSFWHbLo+3l0g83PFnDlvmswygDJdwObvOzV3rpSVnlVBXAQ9/ZKVAoA3Z6g7Bgr0mg==} + '@penumbra-zone/perspective@31.0.0': + resolution: {integrity: sha512-pBp+Y/VQygEUa63+akigFz+HJEL1jWx333NdAay7tmw6M98eu6+Q8Dc3HbyUK8fokuOzmBNt5V7/oab+FE4iRw==} peerDependencies: '@bufbuild/protobuf': ^1.10.0 - '@penumbra-zone/bech32m': 7.0.0 - '@penumbra-zone/getters': 17.0.0 - '@penumbra-zone/protobuf': 6.0.0 - '@penumbra-zone/wasm': 28.0.0 + '@penumbra-zone/bech32m': 8.0.0 + '@penumbra-zone/getters': 18.0.0 + '@penumbra-zone/protobuf': 6.1.0 + '@penumbra-zone/wasm': 29.0.0 - '@penumbra-zone/protobuf@6.0.0': - resolution: {integrity: sha512-x+g2plwEnYwzB692oAIzA9yzqcbsJt1f1lYmPNJpWOqNA9wC3OPDOfzQa7rgP4v6+KNd5IbRfRNyGPd/6zxYNg==} + '@penumbra-zone/protobuf@6.1.0': + resolution: {integrity: sha512-0aVpa0VvodqGERXRNfD0Q3VawfjH77E86e/aDIc/7FjhZB+9TGvhfVVFFBaaRWwOmueQxH2iT5IY/3p+eXQGXA==} peerDependencies: '@bufbuild/protobuf': ^1.10.0 '@penumbra-zone/transport-dom@7.5.0': resolution: {integrity: sha512-8xFIEDeXODl18AITfiIrJJoE8Y6y/+apO+BhrqCmXP+yqGo8LBzcW3iWDQkOc6Go2c1MGJT97B25r079Km1kuA==} - '@penumbra-zone/types@23.0.0': - resolution: {integrity: sha512-AaIK1A/T6mClpx12Uc5zOdAFzSHLOJS7HvB4A+n+Vo6rylcECz7JM4LV5XmkuWLe9dEW6fDir1XqiKdLQzGi0Q==} + '@penumbra-zone/types@24.0.0': + resolution: {integrity: sha512-iD7K0e34gVrkNvfAOoEUctFMtAfXfofynOSngNqDGqZmu3MMRmKfBFiSAfouloJpf+1lT7h92AJo1vmpUV2VIw==} peerDependencies: '@bufbuild/protobuf': ^1.10.0 - '@penumbra-zone/bech32m': 7.0.0 - '@penumbra-zone/getters': 17.0.0 - '@penumbra-zone/protobuf': 6.0.0 + '@penumbra-zone/bech32m': 8.0.0 + '@penumbra-zone/getters': 18.0.0 + '@penumbra-zone/protobuf': 6.1.0 - '@penumbra-zone/ui@9.1.1': - resolution: {integrity: sha512-ICy1MknA1Thp6zGeTc6MJOjLNolkHPRH+XUXhCCP+QMNKt9xAdvbw9rVq81MlXJaPGGf1p6nmzu03b99sv7esw==} + '@penumbra-zone/ui@10.0.0': + resolution: {integrity: sha512-osBziKnIxN7ORBJhG5YhQ+DfoDvGTIsnwhL2LcA22kJY4Z1DrD1p1Xf42u080dvyj2zsJXd5I7uEUzzC2CWWsA==} peerDependencies: '@bufbuild/protobuf': ^1.10.0 - '@penumbra-zone/protobuf': 6.0.0 + '@penumbra-zone/protobuf': 6.1.0 framer-motion: ^11.2.4 lucide-react: ^0.378.0 postcss: ^8.4.38 @@ -1890,6 +1900,20 @@ packages: '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + '@preact-signals/safe-react@0.7.0': + resolution: {integrity: sha512-qazgHHnI70eNmeEbZT8NVXvxPWmMLHe1yUOzjNTtbkA4J7sVbfaG2i93BrXiLqUq9l6Tuz1PB+9/wJ9is/X+Gw==} + peerDependencies: + '@babel/core': ^7.0.0 + react: ^16.14.0 || 17.x || 18.x + + '@preact/signals-core@1.8.0': + resolution: {integrity: sha512-OBvUsRZqNmjzCZXWLxkZfhcgT+Fk8DDcT/8vD6a1xhDemodyy87UJRJfASMuSD8FaAIeGgGm85ydXhm7lr4fyA==} + + '@preact/signals-react@2.2.0': + resolution: {integrity: sha512-EPYlhXqqcOUxz2gTQGt4rtK6X7Jr04517DcJVZ4I5a7Gxy39haK24uFeVWtiU/tnEReRFcxpQN6poYra1jf68A==} + peerDependencies: + react: ^16.14.0 || 17.x || 18.x + '@protobufjs/aspromise@1.1.2': resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} @@ -2730,12 +2754,84 @@ packages: resolution: {integrity: sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==} engines: {node: '>=14'} + '@swc/core-darwin-arm64@1.4.17': + resolution: {integrity: sha512-HVl+W4LezoqHBAYg2JCqR+s9ife9yPfgWSj37iIawLWzOmuuJ7jVdIB7Ee2B75bEisSEKyxRlTl6Y1Oq3owBgw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.4.17': + resolution: {integrity: sha512-WYRO9Fdzq4S/he8zjW5I95G1zcvyd9yyD3Tgi4/ic84P5XDlSMpBDpBLbr/dCPjmSg7aUXxNQqKqGkl6dQxYlA==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.4.17': + resolution: {integrity: sha512-cgbvpWOvtMH0XFjvwppUCR+Y+nf6QPaGu6AQ5hqCP+5Lv2zO5PG0RfasC4zBIjF53xgwEaaWmGP5/361P30X8Q==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.4.17': + resolution: {integrity: sha512-l7zHgaIY24cF9dyQ/FOWbmZDsEj2a9gRFbmgx2u19e3FzOPuOnaopFj0fRYXXKCmtdx+anD750iBIYnTR+pq/Q==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-arm64-musl@1.4.17': + resolution: {integrity: sha512-qhH4gr9gAlVk8MBtzXbzTP3BJyqbAfUOATGkyUtohh85fPXQYuzVlbExix3FZXTwFHNidGHY8C+ocscI7uDaYw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-x64-gnu@1.4.17': + resolution: {integrity: sha512-vRDFATL1oN5oZMImkwbgSHEkp8xG1ofEASBypze01W1Tqto8t+yo6gsp69wzCZBlxldsvPpvFZW55Jq0Rn+UnA==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-linux-x64-musl@1.4.17': + resolution: {integrity: sha512-zQNPXAXn3nmPqv54JVEN8k2JMEcMTQ6veVuU0p5O+A7KscJq+AGle/7ZQXzpXSfUCXlLMX4wvd+rwfGhh3J4cw==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-win32-arm64-msvc@1.4.17': + resolution: {integrity: sha512-z86n7EhOwyzxwm+DLE5NoLkxCTme2lq7QZlDjbQyfCxOt6isWz8rkW5QowTX8w9Rdmk34ncrjSLvnHOeLY17+w==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.4.17': + resolution: {integrity: sha512-JBwuSTJIgiJJX6wtr4wmXbfvOswHFj223AumUrK544QV69k60FJ9q2adPW9Csk+a8wm1hLxq4HKa2K334UHJ/g==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.4.17': + resolution: {integrity: sha512-jFkOnGQamtVDBm3MF5Kq1lgW8vx4Rm1UvJWRUfg+0gx7Uc3Jp3QMFeMNw/rDNQYRDYPG3yunCC+2463ycd5+dg==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.4.17': + resolution: {integrity: sha512-tq+mdWvodMBNBBZbwFIMTVGYHe9N7zvEaycVVjfvAx20k1XozHbHhRv+9pEVFJjwRxLdXmtvFZd3QZHRAOpoNQ==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': ^0.5.0 + peerDependenciesMeta: + '@swc/helpers': + optional: true + '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} '@swc/helpers@0.5.5': resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} + '@swc/types@0.1.12': + resolution: {integrity: sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==} + '@textea/json-viewer@3.5.0': resolution: {integrity: sha512-codh4YXkWPtMjucpn1krGxyJLQA2QhpfM0y3Sur7D/mONOnESoI5ZLmX3ZFo9heXPndDQgzCHsjpErvkN5+hxw==} peerDependencies: @@ -4293,6 +4389,9 @@ packages: hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + hotscript@1.0.13: + resolution: {integrity: sha512-C++tTF1GqkGYecL+2S1wJTfoH6APGAsbb7PAWQ3iVIwgG/EFseAfEVOKFgAFq4yK3+6j1EjUD4UQ9dRJHX/sSQ==} + https-proxy-agent@5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} @@ -5047,6 +5146,12 @@ packages: react-fast-compare@3.2.2: resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} + react-fast-hoc@0.3.2: + resolution: {integrity: sha512-YmR0TCcljZqXT9R/9bm9XxqNX18HjXT+Han/4ER0Ewsxc/1qX+kLbG9q9HhLcluFbN4diTt9z4C30OgWOmbh7g==} + peerDependencies: + hotscript: ^1.0.12 + react: '>=17' + react-focus-lock@2.13.2: resolution: {integrity: sha512-T/7bsofxYqnod2xadvuwjGKHOoL5GH7/EIPI5UyEvaU/c2CcphvGI371opFtuY/SYdbMsNiuF4HsHQ50nA/TKQ==} peerDependencies: @@ -5927,6 +6032,10 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-imports@7.24.3': + dependencies: + '@babel/types': 7.25.6 + '@babel/helper-module-imports@7.24.7': dependencies: '@babel/traverse': 7.25.6 @@ -7844,36 +7953,36 @@ snapshots: '@penumbra-labs/registry@11.3.1': {} - '@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))': + '@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0))': dependencies: - '@penumbra-zone/protobuf': 6.0.0(@bufbuild/protobuf@1.10.0) + '@penumbra-zone/protobuf': 6.1.0(@bufbuild/protobuf@1.10.0) bech32: 2.0.0 - '@penumbra-zone/client@18.1.0(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/transport-dom@7.5.0)': + '@penumbra-zone/client@19.0.0(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/transport-dom@7.5.0)': dependencies: '@bufbuild/protobuf': 1.10.0 '@connectrpc/connect': 1.4.0(@bufbuild/protobuf@1.10.0) - '@penumbra-zone/protobuf': 6.0.0(@bufbuild/protobuf@1.10.0) + '@penumbra-zone/protobuf': 6.1.0(@bufbuild/protobuf@1.10.0) '@penumbra-zone/transport-dom': 7.5.0 - '@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))': + '@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0))': dependencies: '@bufbuild/protobuf': 1.10.0 - '@penumbra-zone/bech32m': 7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)) - '@penumbra-zone/protobuf': 6.0.0(@bufbuild/protobuf@1.10.0) + '@penumbra-zone/bech32m': 8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)) + '@penumbra-zone/protobuf': 6.1.0(@bufbuild/protobuf@1.10.0) '@penumbra-zone/keys@4.2.1': optional: true - '@penumbra-zone/perspective@30.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/wasm@26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@23.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))))': + '@penumbra-zone/perspective@31.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/wasm@26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@24.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0))))': dependencies: '@bufbuild/protobuf': 1.10.0 - '@penumbra-zone/bech32m': 7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)) - '@penumbra-zone/getters': 17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)) - '@penumbra-zone/protobuf': 6.0.0(@bufbuild/protobuf@1.10.0) - '@penumbra-zone/wasm': 26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@23.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))) + '@penumbra-zone/bech32m': 8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)) + '@penumbra-zone/getters': 17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)) + '@penumbra-zone/protobuf': 6.1.0(@bufbuild/protobuf@1.10.0) + '@penumbra-zone/wasm': 26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@24.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0))) - '@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)': + '@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)': dependencies: '@bufbuild/protobuf': 1.10.0 @@ -7882,25 +7991,25 @@ snapshots: '@bufbuild/protobuf': 1.10.0 '@connectrpc/connect': 1.4.0(@bufbuild/protobuf@1.10.0) - '@penumbra-zone/types@23.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))': + '@penumbra-zone/types@24.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0))': dependencies: '@bufbuild/protobuf': 1.10.0 - '@penumbra-zone/bech32m': 7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)) - '@penumbra-zone/getters': 17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)) - '@penumbra-zone/protobuf': 6.0.0(@bufbuild/protobuf@1.10.0) + '@penumbra-zone/bech32m': 8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)) + '@penumbra-zone/getters': 17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)) + '@penumbra-zone/protobuf': 6.1.0(@bufbuild/protobuf@1.10.0) bignumber.js: 9.1.2 idb: 8.0.0 zod: 3.23.8 - '@penumbra-zone/ui@9.1.1(22ahnkytf72hixbg7m46epplfq)': + '@penumbra-zone/ui@10.0.0(zk5auaacq632y64evccopof44u)': dependencies: '@bufbuild/protobuf': 1.10.0 '@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) - '@penumbra-zone/bech32m': 7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)) - '@penumbra-zone/perspective': 30.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/wasm@26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@23.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))) - '@penumbra-zone/protobuf': 6.0.0(@bufbuild/protobuf@1.10.0) - '@penumbra-zone/types': 23.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)) + '@penumbra-zone/bech32m': 8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)) + '@penumbra-zone/perspective': 31.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/wasm@26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@24.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))) + '@penumbra-zone/protobuf': 6.1.0(@bufbuild/protobuf@1.10.0) + '@penumbra-zone/types': 24.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)) '@radix-ui/react-avatar': 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) '@radix-ui/react-checkbox': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-dialog': 1.0.5(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -7957,12 +8066,12 @@ snapshots: - immer - supports-color - '@penumbra-zone/wasm@26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@23.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))': + '@penumbra-zone/wasm@26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@24.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))': dependencies: '@bufbuild/protobuf': 1.10.0 - '@penumbra-zone/bech32m': 7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)) - '@penumbra-zone/protobuf': 6.0.0(@bufbuild/protobuf@1.10.0) - '@penumbra-zone/types': 23.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)) + '@penumbra-zone/bech32m': 8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)) + '@penumbra-zone/protobuf': 6.1.0(@bufbuild/protobuf@1.10.0) + '@penumbra-zone/types': 24.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@8.0.0(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.1.0(@bufbuild/protobuf@1.10.0)) optionalDependencies: '@penumbra-zone/keys': 4.2.1 @@ -7973,6 +8082,31 @@ snapshots: '@popperjs/core@2.11.8': {} + '@preact-signals/safe-react@0.7.0(@babel/core@7.25.2)(@swc/helpers@0.5.5)(react@18.3.1)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-imports': 7.24.3 + '@babel/helper-plugin-utils': 7.24.8 + '@preact/signals-core': 1.8.0 + debug: 4.3.7 + hotscript: 1.0.13 + react: 18.3.1 + react-fast-hoc: 0.3.2(hotscript@1.0.13)(react@18.3.1) + use-sync-external-store: 1.2.2(react@18.3.1) + optionalDependencies: + '@swc/core': 1.4.17(@swc/helpers@0.5.5) + transitivePeerDependencies: + - '@swc/helpers' + - supports-color + + '@preact/signals-core@1.8.0': {} + + '@preact/signals-react@2.2.0(react@18.3.1)': + dependencies: + '@preact/signals-core': 1.8.0 + react: 18.3.1 + use-sync-external-store: 1.2.2(react@18.3.1) + '@protobufjs/aspromise@1.1.2': {} '@protobufjs/base64@1.1.2': {} @@ -8868,6 +9002,54 @@ snapshots: - supports-color - typescript + '@swc/core-darwin-arm64@1.4.17': + optional: true + + '@swc/core-darwin-x64@1.4.17': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.4.17': + optional: true + + '@swc/core-linux-arm64-gnu@1.4.17': + optional: true + + '@swc/core-linux-arm64-musl@1.4.17': + optional: true + + '@swc/core-linux-x64-gnu@1.4.17': + optional: true + + '@swc/core-linux-x64-musl@1.4.17': + optional: true + + '@swc/core-win32-arm64-msvc@1.4.17': + optional: true + + '@swc/core-win32-ia32-msvc@1.4.17': + optional: true + + '@swc/core-win32-x64-msvc@1.4.17': + optional: true + + '@swc/core@1.4.17(@swc/helpers@0.5.5)': + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.12 + optionalDependencies: + '@swc/core-darwin-arm64': 1.4.17 + '@swc/core-darwin-x64': 1.4.17 + '@swc/core-linux-arm-gnueabihf': 1.4.17 + '@swc/core-linux-arm64-gnu': 1.4.17 + '@swc/core-linux-arm64-musl': 1.4.17 + '@swc/core-linux-x64-gnu': 1.4.17 + '@swc/core-linux-x64-musl': 1.4.17 + '@swc/core-win32-arm64-msvc': 1.4.17 + '@swc/core-win32-ia32-msvc': 1.4.17 + '@swc/core-win32-x64-msvc': 1.4.17 + '@swc/helpers': 0.5.5 + optional: true + '@swc/counter@0.1.3': {} '@swc/helpers@0.5.5': @@ -8875,6 +9057,11 @@ snapshots: '@swc/counter': 0.1.3 tslib: 2.7.0 + '@swc/types@0.1.12': + dependencies: + '@swc/counter': 0.1.3 + optional: true + '@textea/json-viewer@3.5.0(@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/material@5.16.7(@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))(@types/react@18.3.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@emotion/react': 11.13.3(@types/react@18.3.5)(react@18.3.1) @@ -10224,8 +10411,8 @@ snapshots: '@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.6.2) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@9.10.0(jiti@1.21.6)))(eslint@8.57.0) - eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@9.10.0(jiti@1.21.6)))(eslint@8.57.0))(eslint@8.57.0) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.0) + eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.10.0(eslint@8.57.0) eslint-plugin-react: 7.35.2(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) @@ -10268,19 +10455,19 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@9.10.0(jiti@1.21.6)))(eslint@8.57.0): + eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.0): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.3.7 enhanced-resolve: 5.17.1 eslint: 8.57.0 - eslint-module-utils: 2.11.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@9.10.0(jiti@1.21.6)))(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.11.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.0))(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.8.0 is-bun-module: 1.2.1 is-glob: 4.0.3 optionalDependencies: - eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0) + eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) eslint-plugin-import-x: 0.5.3(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2) transitivePeerDependencies: - '@typescript-eslint/parser' @@ -10309,14 +10496,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.11.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@9.10.0(jiti@1.21.6)))(eslint@8.57.0))(eslint@8.57.0): + eslint-module-utils@2.11.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.0))(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.6.2) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@9.10.0(jiti@1.21.6)))(eslint@8.57.0) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.0) transitivePeerDependencies: - supports-color @@ -10365,7 +10552,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@9.10.0(jiti@1.21.6)))(eslint@8.57.0))(eslint@8.57.0): + eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -10376,7 +10563,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.11.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@9.10.0(jiti@1.21.6)))(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.11.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.0))(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -10413,7 +10600,7 @@ snapshots: safe-regex-test: 1.0.3 string.prototype.includes: 2.0.0 - eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@9.10.0(jiti@1.21.6)))(eslint@9.10.0(jiti@1.21.6))(prettier@3.3.3): + eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@9.10.0(jiti@1.21.6))(prettier@3.3.3): dependencies: eslint: 9.10.0(jiti@1.21.6) prettier: 3.3.3 @@ -10906,6 +11093,8 @@ snapshots: dependencies: react-is: 16.13.1 + hotscript@1.0.13: {} + https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 @@ -11555,7 +11744,7 @@ snapshots: eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@9.10.0(jiti@1.21.6)) eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0) eslint-plugin-import-x: 0.5.3(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2) - eslint-plugin-prettier: 5.2.1(eslint-config-prettier@9.1.0(eslint@9.10.0(jiti@1.21.6)))(eslint@9.10.0(jiti@1.21.6))(prettier@3.3.3) + eslint-plugin-prettier: 5.2.1(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@9.10.0(jiti@1.21.6))(prettier@3.3.3) eslint-plugin-react: 7.35.2(eslint@9.10.0(jiti@1.21.6)) eslint-plugin-react-hooks: 5.1.0-rc-c3cdbec0a7-20240708(eslint@9.10.0(jiti@1.21.6)) eslint-plugin-react-refresh: 0.4.11(eslint@9.10.0(jiti@1.21.6)) @@ -11641,6 +11830,11 @@ snapshots: react-fast-compare@3.2.2: {} + react-fast-hoc@0.3.2(hotscript@1.0.13)(react@18.3.1): + dependencies: + hotscript: 1.0.13 + react: 18.3.1 + react-focus-lock@2.13.2(@types/react@18.3.5)(react@18.3.1): dependencies: '@babel/runtime': 7.25.6 diff --git a/src/app/v2/layout.tsx b/src/app/v2/layout.tsx index 05c7859c..b3365de2 100644 --- a/src/app/v2/layout.tsx +++ b/src/app/v2/layout.tsx @@ -4,11 +4,13 @@ import { ReactNode } from 'react'; import { PenumbraUIProvider } from '@penumbra-zone/ui/PenumbraUIProvider'; import { Display } from '@penumbra-zone/ui/Display'; import { Header } from '@/components/header'; +import { SyncBar } from '@/components/header/sync-bar.tsx'; const V2Layout = ({ children }: { children: ReactNode }) => { return ( +
{children} diff --git a/src/components/copiedTx.tsx b/src/components/copiedTx.tsx index de7116f5..8e72926a 100644 --- a/src/components/copiedTx.tsx +++ b/src/components/copiedTx.tsx @@ -3,7 +3,7 @@ import React, { FC, useState } from "react"; import { CopyIcon } from "@radix-ui/react-icons"; import { HStack } from "@chakra-ui/react"; -import { Constants } from "@/constants/configConstants"; +import { Constants } from "@/utils/configConstants.ts"; interface CopyTxToClipboardProps { txHash: string; diff --git a/src/components/header/index.tsx b/src/components/header/index.tsx index 00ffb933..050a7701 100644 --- a/src/components/header/index.tsx +++ b/src/components/header/index.tsx @@ -1,6 +1,6 @@ import { Density } from '@penumbra-zone/ui/Density'; import { HeaderLogo } from './logo.tsx'; -// import { StatusPopover } from './status-popover.tsx'; +import { StatusPopover } from './status-popover.tsx'; import { MobileNav } from './mobile-nav.tsx'; import { DesktopNav } from './desktop-nav.tsx'; import { Connection } from './connection.tsx'; @@ -14,7 +14,7 @@ export const Header = () => {
- {/* */} +
diff --git a/src/components/header/mobile-nav.tsx b/src/components/header/mobile-nav.tsx index f933de4d..5e7bc998 100644 --- a/src/components/header/mobile-nav.tsx +++ b/src/components/header/mobile-nav.tsx @@ -5,7 +5,7 @@ import { Button } from '@penumbra-zone/ui/Button'; import { Dialog } from '@penumbra-zone/ui/Dialog'; import { Display } from '@penumbra-zone/ui/Display'; import { MenuItem } from '@penumbra-zone/ui/MenuItem'; -// import { StatusPopover } from './status-popover.tsx'; +import { StatusPopover } from './status-popover.tsx'; import { HeaderLogo } from './logo.tsx'; import { HEADER_LINKS } from './links.ts'; import { Connection } from './connection.tsx'; @@ -31,7 +31,7 @@ export const MobileNav = () => {
- {/* */} + + + + +
+
+ Status + {pill.value} + {penumbraStatusError.value} +
+ {penumbraStatus.value && ( +
+ Block Height + + {penumbraStatus.value.latestKnownBlockHeight !== penumbraStatus.value.fullSyncHeight + ? `${penumbraStatus.value.fullSyncHeight} of ${penumbraStatus.value.latestKnownBlockHeight}` + : `${penumbraStatus.value.latestKnownBlockHeight}`} + +
+ )} +
+
+
+ + ); +}; diff --git a/src/components/header/sync-bar.tsx b/src/components/header/sync-bar.tsx new file mode 100644 index 00000000..92cad348 --- /dev/null +++ b/src/components/header/sync-bar.tsx @@ -0,0 +1,18 @@ +import { Progress } from '@penumbra-zone/ui/Progress'; +import { penumbraStatus, penumbraStatusError } from '@/state/status'; + +export const SyncBar = () => { + return ( +
+ {!penumbraStatus.value ? ( + + ) : ( + + )} +
+ ); +}; diff --git a/src/pages/block/[block_height].tsx b/src/pages/block/[block_height].tsx index ce911fc2..a3ee33b1 100644 --- a/src/pages/block/[block_height].tsx +++ b/src/pages/block/[block_height].tsx @@ -16,7 +16,7 @@ import { BlockDetailedSummaryData } from "@/utils/types/block"; import { BlockInfo, LiquidityPositionEvent } from "@/utils/indexer/types/lps"; import { SwapExecutionWithBlockHeight } from "@/utils/protos/types/DexQueryServiceClientInterface"; import { LoadingSpinner } from "@/components/util/loadingSpinner"; -import { Constants } from "@/constants/configConstants"; +import { Constants } from "@/utils/configConstants.ts"; import { formatTimestampShort } from "@/components/blockTimestamp"; import { AddIcon, MinusIcon } from "@chakra-ui/icons"; import { innerToBech32Address } from "@/utils/math/bech32"; diff --git a/src/state/status/getSyncPercent.ts b/src/state/status/getSyncPercent.ts new file mode 100644 index 00000000..24ae9bfa --- /dev/null +++ b/src/state/status/getSyncPercent.ts @@ -0,0 +1,20 @@ +export const getSyncPercent = ( + fullSyncHeight: bigint, + latestKnownBlockHeight: bigint, +): { syncPercent: number, syncPercentStringified: string } => { + let percentSyncedNumber = 0; + if (latestKnownBlockHeight) { + percentSyncedNumber = Number(fullSyncHeight) / Number(latestKnownBlockHeight); + if (percentSyncedNumber > 1) { + percentSyncedNumber = 1; + } + } + + // Round down to ensure whole numbers + const roundedPercentSyncedNumber = Math.floor(percentSyncedNumber * 100); + + return { + syncPercent: roundedPercentSyncedNumber / 100, + syncPercentStringified: `${roundedPercentSyncedNumber}%`, + } +}; diff --git a/src/state/status/index.ts b/src/state/status/index.ts new file mode 100644 index 00000000..2abf270e --- /dev/null +++ b/src/state/status/index.ts @@ -0,0 +1,65 @@ +import { signal } from '@preact-signals/safe-react'; +import { ViewService } from '@penumbra-zone/protobuf'; +import { penumbra } from '@/utils/penumbra/penumbra'; +import { getSyncPercent } from '@/state/status/getSyncPercent'; + +interface StatusState { + /** Indicates that the account needs syncing with the blockchain */ + syncing: boolean; + /** Indicates that the account is almost in sync with the blockchain (amount of unsynced blocks is less than 10) */ + updating?: boolean; + /** The amount of synced blocks */ + fullSyncHeight: bigint; + /** The total amount of blocks in the blockchain */ + latestKnownBlockHeight?: bigint; + /** A number between 0 and 1 indicating the sync progress */ + syncPercent: number; + /** A stringified sync percentage, e.g. '100%' or '17%' */ + syncPercentStringified: string; +} + +export const penumbraStatus = signal(); +export const penumbraStatusError = signal(); + +/** + * Initial status request doesn't return `latestKnownBlockHeight`. + * Instead, it returns `catchingUp` to know if the sync is in progress + */ +const getPenumbraStatus = async (): Promise => { + const status = await penumbra.service(ViewService).status({}); + return { + syncing: status.catchingUp, + fullSyncHeight: status.fullSyncHeight, + latestKnownBlockHeight: status.catchingUp ? undefined : status.fullSyncHeight, + syncPercent: status.catchingUp ? 0 : 1, + syncPercentStringified: status.catchingUp ? '0%' : '100%', + }; +}; + +/** + * Receives the status stream from the view service + * and stores it in the `penumbraStatus` signal. + */ +export const streamPenumbraStatus = async () => { + try { + penumbraStatus.value = await getPenumbraStatus(); + penumbraStatusError.value = undefined; + + const stream = penumbra.service(ViewService).statusStream({}); + for await (const status of stream) { + const syncPercents = getSyncPercent(status.fullSyncHeight, status.latestKnownBlockHeight); + + penumbraStatusError.value = undefined; + penumbraStatus.value = { + syncing: status.fullSyncHeight !== status.latestKnownBlockHeight, + fullSyncHeight: status.fullSyncHeight, + latestKnownBlockHeight: status.latestKnownBlockHeight, + ...syncPercents, + }; + } + } catch (error) { + penumbraStatus.value = undefined; + penumbraStatusError.value = error instanceof Error ? `${error.name}: ${error.message}` : 'Streaming error'; + setTimeout(() => void streamPenumbraStatus(), 1000); + } +}; diff --git a/src/constants/configConstants.ts b/src/utils/configConstants.ts similarity index 100% rename from src/constants/configConstants.ts rename to src/utils/configConstants.ts diff --git a/src/utils/token/tokenFetch.tsx b/src/utils/token/tokenFetch.tsx index 98df7f7b..85f40233 100644 --- a/src/utils/token/tokenFetch.tsx +++ b/src/utils/token/tokenFetch.tsx @@ -1,5 +1,5 @@ import { uint8ArrayToBase64, base64ToUint8Array } from "../math/base64"; -import { Constants } from "../../constants/configConstants"; +import { Constants } from "../configConstants.ts"; import { AssetId, AssetImage, diff --git a/styles/v2.css b/styles/v2.css index 1de6571d..98fd39bd 100644 --- a/styles/v2.css +++ b/styles/v2.css @@ -17,3 +17,8 @@ a { * { box-sizing: border-box; } + +body > section { + position: relative; + z-index: 0; +}