phase 5: wasm core, GalaxyClient skeleton, Connect-Web stubs

Compile `ui/core` to WebAssembly via TinyGo (903 KB) and expose four
canonical-bytes / signature-verification functions on
`globalThis.galaxyCore` from `ui/wasm/main.go`. The TypeScript-side
`Core` interface plus a `WasmCore` adapter (browser + JSDOM loader)
bridge those into a typed shape, and a `GalaxyClient` skeleton wires
`Core.signRequest` → injected `Signer` → typed Connect client →
`Core.verifyPayloadHash` / `verifyResponse`.

Wire `ui/buf.gen.yaml` against the local
`@bufbuild/protoc-gen-es` v2 binary (devDependency) so the codegen
step does not depend on the buf.build BSR. Vitest covers the bridge
end-to-end: per-method WasmCore tests under JSDOM, byte-for-byte
canon parity against the gateway fixtures committed in Phase 3, and
a `GalaxyClient` orchestration test using
`createRouterTransport`. The committed `core.wasm` snapshot tracks
TinyGo output so contributors run `make wasm` only when `ui/core/`
changes; CI consumes the snapshot directly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Ilia Denisov
2026-05-07 12:58:37 +02:00
parent cd61868881
commit fbc0260720
25 changed files with 7284 additions and 36 deletions
+85
View File
@@ -8,6 +8,18 @@ importers:
frontend:
devDependencies:
'@bufbuild/protobuf':
specifier: ^2.12.0
version: 2.12.0
'@bufbuild/protoc-gen-es':
specifier: ^2.12.0
version: 2.12.0(@bufbuild/protobuf@2.12.0)
'@connectrpc/connect':
specifier: ^2.1.1
version: 2.1.1(@bufbuild/protobuf@2.12.0)
'@connectrpc/connect-web':
specifier: ^2.1.1
version: 2.1.1(@bufbuild/protobuf@2.12.0)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.12.0))
'@playwright/test':
specifier: ^1.59.1
version: 1.59.1
@@ -74,6 +86,33 @@ packages:
resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==}
engines: {node: '>=6.9.0'}
'@bufbuild/protobuf@2.12.0':
resolution: {integrity: sha512-B/XlCaFIP8LOwzo+bz5uFzATYokcwCKQcghqnlfwSmM5eX/qTkvDBnDPs+gXtX/RyjxJ4DRikECcPJbyALA8FA==}
'@bufbuild/protoc-gen-es@2.12.0':
resolution: {integrity: sha512-d9htF6jEkSwPbp9d/vSmZOBF7eeG18AvTMKmVg4I23afnrQOxL2w3WOXa9TaufMCyu24QakEUb4vux8apI5e7A==}
engines: {node: '>=20'}
hasBin: true
peerDependencies:
'@bufbuild/protobuf': 2.12.0
peerDependenciesMeta:
'@bufbuild/protobuf':
optional: true
'@bufbuild/protoplugin@2.12.0':
resolution: {integrity: sha512-ORlDITp8AFUXzIhLRoMCG+ud+D3MPKWb5HQXBoskMMnjeyEjE1H1qLonVNPyOr8lkx3xSfYUo8a0dvOZJVAzow==}
'@connectrpc/connect-web@2.1.1':
resolution: {integrity: sha512-J8317Q2MaFRCT1jzVR1o06bZhDIBmU0UAzWx6xOIXzOq8+k71/+k7MUF7AwcBUX+34WIvbm5syRgC5HXQA8fOg==}
peerDependencies:
'@bufbuild/protobuf': ^2.7.0
'@connectrpc/connect': 2.1.1
'@connectrpc/connect@2.1.1':
resolution: {integrity: sha512-JzhkaTvM73m2K1URT6tv53k2RwngSmCXLZJgK580qNQOXRzZRR/BCMfZw3h+90JpnG6XksP5bYT+cz0rpUzUWQ==}
peerDependencies:
'@bufbuild/protobuf': ^2.7.0
'@csstools/color-helpers@5.1.0':
resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==}
engines: {node: '>=18'}
@@ -329,6 +368,11 @@ packages:
'@types/trusted-types@2.0.7':
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
'@typescript/vfs@1.6.4':
resolution: {integrity: sha512-PJFXFS4ZJKiJ9Qiuix6Dz/OwEIqHD7Dme1UwZhTK11vR+5dqW2ACbdndWQexBzCx+CPuMe5WBYQWCsFyGlQLlQ==}
peerDependencies:
typescript: '*'
'@vitest/expect@4.1.5':
resolution: {integrity: sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw==}
@@ -874,6 +918,11 @@ packages:
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
typescript@5.4.5:
resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==}
engines: {node: '>=14.17'}
hasBin: true
typescript@5.9.3:
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
engines: {node: '>=14.17'}
@@ -1044,6 +1093,33 @@ snapshots:
'@babel/runtime@7.29.2': {}
'@bufbuild/protobuf@2.12.0': {}
'@bufbuild/protoc-gen-es@2.12.0(@bufbuild/protobuf@2.12.0)':
dependencies:
'@bufbuild/protoplugin': 2.12.0
optionalDependencies:
'@bufbuild/protobuf': 2.12.0
transitivePeerDependencies:
- supports-color
'@bufbuild/protoplugin@2.12.0':
dependencies:
'@bufbuild/protobuf': 2.12.0
'@typescript/vfs': 1.6.4(typescript@5.4.5)
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
'@connectrpc/connect-web@2.1.1(@bufbuild/protobuf@2.12.0)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.12.0))':
dependencies:
'@bufbuild/protobuf': 2.12.0
'@connectrpc/connect': 2.1.1(@bufbuild/protobuf@2.12.0)
'@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.12.0)':
dependencies:
'@bufbuild/protobuf': 2.12.0
'@csstools/color-helpers@5.1.0': {}
'@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)':
@@ -1261,6 +1337,13 @@ snapshots:
'@types/trusted-types@2.0.7': {}
'@typescript/vfs@1.6.4(typescript@5.4.5)':
dependencies:
debug: 4.4.3
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
'@vitest/expect@4.1.5':
dependencies:
'@standard-schema/spec': 1.1.0
@@ -1765,6 +1848,8 @@ snapshots:
tslib@2.8.1: {}
typescript@5.4.5: {}
typescript@5.9.3: {}
undici-types@6.21.0: {}