Skip to content

Commit e036501

Browse files
committed
Add FlowChain local testnet workbench
1 parent 328f14a commit e036501

11 files changed

Lines changed: 2170 additions & 30 deletions

File tree

apps/dashboard/README.md

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# FlowMemory Dashboard V0
1+
# FlowMemory Dashboard / FlowChain Workbench V0
22

3-
Local operator/explorer app for inspecting FlowMemory V0 fixture output. It is intentionally fixture-backed and does not claim production live data, wallet support, token pricing, or hosted deployment.
3+
Local operator/explorer app for inspecting FlowMemory V0 fixture output and the FlowChain private/local testnet workbench surface. It is intentionally local-first and does not claim value-bearing wallet support, token pricing, or hosted deployment.
44

55
## Run Locally
66

@@ -25,6 +25,28 @@ npm test
2525
npm run build
2626
```
2727

28+
From the repo root, the same checks are:
29+
30+
```powershell
31+
npm test --prefix apps/dashboard
32+
npm run build --prefix apps/dashboard
33+
```
34+
35+
The first route is the FlowChain workbench. It tries the local control-plane API at:
36+
37+
```text
38+
http://127.0.0.1:8787
39+
```
40+
41+
Override that endpoint when needed:
42+
43+
```powershell
44+
$env:VITE_FLOWCHAIN_CONTROL_PLANE_URL="http://127.0.0.1:8787"
45+
npm run dev
46+
```
47+
48+
If the API is not running, the workbench marks the control-plane as offline, shows stale fixture fallback where appropriate, and keeps rendering deterministic local data. This app is for private/local validation and canary review only; it does not initiate value-bearing wallet flows.
49+
2850
## Data Boundary
2951

3052
The canonical dashboard fixture is generated by the launch-core command and lives at:
@@ -33,13 +55,27 @@ The canonical dashboard fixture is generated by the launch-core command and live
3355
fixtures/dashboard/flowmemory-dashboard-v0.json
3456
```
3557

58+
The guarded Base canary review fixture is separate:
59+
60+
```text
61+
fixtures/dashboard/flowmemory-dashboard-base-canary-v0.json
62+
```
63+
3664
The app loads its runtime copy from:
3765

3866
```text
3967
apps/dashboard/public/data/flowmemory-dashboard-v0.json
68+
apps/dashboard/public/data/flowmemory-dashboard-base-canary-v0.json
4069
```
4170

42-
The `dev` and `build` scripts run `npm run sync:fixtures`, which copies the canonical fixture into the Vite public data folder before the app starts or builds.
71+
The `dev` and `build` scripts run `npm run sync:fixtures`, which copies the canonical dashboard fixture and the existing launch-core devnet state into the Vite public data folder before the app starts or builds.
72+
73+
Workbench fixture fallback paths:
74+
75+
```text
76+
apps/dashboard/public/data/flowchain-local-devnet-state.json
77+
apps/dashboard/public/data/flowchain-local-devnet-dashboard-state.json
78+
```
4379

4480
Generated local source outputs land under the fixture boundary first:
4581

@@ -54,7 +90,9 @@ fixtures/dashboard/generated/hardware-heartbeats.json
5490

5591
## Current Views
5692

93+
- FlowChain workbench
5794
- Overview
95+
- Base canary review
5896
- Flow Memory / Rootflow
5997
- FlowPulse stream
6098
- Rootfields
@@ -67,6 +105,16 @@ fixtures/dashboard/generated/hardware-heartbeats.json
67105

68106
Every displayed record carries source subsystem, fixture/local origin, chain context, ID/hash, status, and last-updated metadata when available.
69107

108+
The workbench adds local setup/API status plus object views for blocks, transactions, agents, models, receipts, memory cells, artifacts, verifier reports, challenges, finality, provenance, and raw JSON. When a current fixture does not yet contain a private-testnet object type, the view stays empty and names the expected control-plane endpoint.
109+
110+
Workbench object coverage:
111+
112+
```text
113+
node/chain status, blocks, transactions, rootfields, agents, models, work receipts,
114+
memory cells, artifacts, verifier modules, verifier reports, challenges, finality,
115+
provenance/source, hardware signals, raw JSON
116+
```
117+
70118
## Status Vocabulary
71119

72120
Dashboard V0 visually distinguishes:
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{
2+
"artifactCommitments": {
3+
"artifact:demo:001": {
4+
"artifactId": "artifact:demo:001",
5+
"commitment": "0x4de1ac0e70ce73c0a03df255d1ea2a7bbcb40f05c60f1b0c1b73e0b4577c537a",
6+
"rootfieldId": "rootfield:demo:alpha",
7+
"uriHint": "fixture://artifact/demo/001"
8+
}
9+
},
10+
"baseAnchors": {
11+
"0x08530e63dacb23a630bbbbd56ffc4dead54aca6d7e7ee7d920d7376eb9340ae7": {
12+
"anchorId": "0x08530e63dacb23a630bbbbd56ffc4dead54aca6d7e7ee7d920d7376eb9340ae7",
13+
"appchainChainId": "flowmemory-local-devnet-v0",
14+
"artifactCommitmentRoot": "0xb772a9f7273032fd3ba2da8b6476d4715bbbafbd2a7eed21ecd0d558bde3beab",
15+
"blockRangeEnd": 1,
16+
"blockRangeStart": 1,
17+
"finalityStatus": "local-placeholder",
18+
"previousAnchorId": "0x0000000000000000000000000000000000000000000000000000000000000000",
19+
"rootfieldStateRoot": "0xb72a851dca1103410484e3272945bae5e87fc39b8f32f77d2991959b60d3bfbf",
20+
"stateRoot": "0x76ec5260c34184b6bb54ca406a43fc1f9591a47f37f71583a7620ef4a4065aff",
21+
"verifierReportRoot": "0x4facd21e55423e182eba87355482a35daa93f53190fbd3a8d2969f9d55bc5373",
22+
"workReceiptRoot": "0x8b3ef5650c9eea2f608ad9c7cb73df3c289fc0ac72ed04f46e6ae4bce0a1f023"
23+
}
24+
},
25+
"blockHeight": 2,
26+
"rootfields": {
27+
"rootfield:demo:alpha": {
28+
"active": true,
29+
"latestRoot": "0xbdb66f777635a2426a834652f8efee40db4f3e0b9ddd2af15f15fd065a7fe4f4",
30+
"metadataHash": "0x514006e494877d3d6a69848ed6264b152ebe6b73b1112d8ff1b9b48860509a2f",
31+
"owner": "operator:local-demo",
32+
"pulseCount": 2,
33+
"rootCount": 1,
34+
"rootfieldId": "rootfield:demo:alpha",
35+
"schemaHash": "0x5909a6dc30ffe1fcd89eebc118f6d2096c4d4c3ccdcc851dc0e4386fe997c6d7"
36+
}
37+
},
38+
"schema": "flowmemory.dashboard_state.local_devnet.v0",
39+
"stateRoot": "0x3e1f5fddd84f9d460ee30a380ff700b17611891b8c03eb320edf1baefe003ef9",
40+
"verifierReports": {
41+
"report:demo:001": {
42+
"reasonCodes": [],
43+
"receiptId": "receipt:demo:001",
44+
"reportDigest": "0xe75619ea62e7a6d9593debe0123d366ae0f0104cff86d9a69391fb5c1e074f4c",
45+
"reportId": "report:demo:001",
46+
"rootfieldId": "rootfield:demo:alpha",
47+
"status": "verified",
48+
"verifierId": "verifier:local-demo"
49+
}
50+
},
51+
"workReceipts": {
52+
"receipt:demo:001": {
53+
"artifactCommitment": "0x4de1ac0e70ce73c0a03df255d1ea2a7bbcb40f05c60f1b0c1b73e0b4577c537a",
54+
"inputRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
55+
"outputRoot": "0xbdb66f777635a2426a834652f8efee40db4f3e0b9ddd2af15f15fd065a7fe4f4",
56+
"receiptId": "receipt:demo:001",
57+
"rootfieldId": "rootfield:demo:alpha",
58+
"ruleSet": "flowmemory.work.rule_set.local_demo.v0",
59+
"workerId": "worker:local-demo"
60+
}
61+
}
62+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
{
2+
"schema": "flowmemory.local_devnet.state.v0",
3+
"chainId": "flowmemory-local-devnet-v0",
4+
"genesisHash": "0x0f23c892cbd2d00c10839d97ddab833698a83f8df8d6df27ceac03cfdd4b7bc9",
5+
"nextBlockNumber": 3,
6+
"logicalTime": 1778688002,
7+
"parentHash": "0x7515374a9b020a6d271820031738a5190cb0fc374adcd74a88a32c0fd0d5c7a6",
8+
"rootfields": {
9+
"rootfield:demo:alpha": {
10+
"rootfieldId": "rootfield:demo:alpha",
11+
"owner": "operator:local-demo",
12+
"schemaHash": "0x5909a6dc30ffe1fcd89eebc118f6d2096c4d4c3ccdcc851dc0e4386fe997c6d7",
13+
"metadataHash": "0x514006e494877d3d6a69848ed6264b152ebe6b73b1112d8ff1b9b48860509a2f",
14+
"latestRoot": "0xbdb66f777635a2426a834652f8efee40db4f3e0b9ddd2af15f15fd065a7fe4f4",
15+
"pulseCount": 2,
16+
"rootCount": 1,
17+
"active": true
18+
}
19+
},
20+
"artifactCommitments": {
21+
"artifact:demo:001": {
22+
"artifactId": "artifact:demo:001",
23+
"rootfieldId": "rootfield:demo:alpha",
24+
"commitment": "0x4de1ac0e70ce73c0a03df255d1ea2a7bbcb40f05c60f1b0c1b73e0b4577c537a",
25+
"uriHint": "fixture://artifact/demo/001"
26+
}
27+
},
28+
"workReceipts": {
29+
"receipt:demo:001": {
30+
"receiptId": "receipt:demo:001",
31+
"rootfieldId": "rootfield:demo:alpha",
32+
"workerId": "worker:local-demo",
33+
"inputRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
34+
"outputRoot": "0xbdb66f777635a2426a834652f8efee40db4f3e0b9ddd2af15f15fd065a7fe4f4",
35+
"artifactCommitment": "0x4de1ac0e70ce73c0a03df255d1ea2a7bbcb40f05c60f1b0c1b73e0b4577c537a",
36+
"ruleSet": "flowmemory.work.rule_set.local_demo.v0"
37+
}
38+
},
39+
"verifierReports": {
40+
"report:demo:001": {
41+
"reportId": "report:demo:001",
42+
"rootfieldId": "rootfield:demo:alpha",
43+
"receiptId": "receipt:demo:001",
44+
"verifierId": "verifier:local-demo",
45+
"reportDigest": "0xe75619ea62e7a6d9593debe0123d366ae0f0104cff86d9a69391fb5c1e074f4c",
46+
"status": "verified",
47+
"reasonCodes": []
48+
}
49+
},
50+
"importedObservations": {},
51+
"importedVerifierReports": {},
52+
"baseAnchors": {
53+
"0x08530e63dacb23a630bbbbd56ffc4dead54aca6d7e7ee7d920d7376eb9340ae7": {
54+
"anchorId": "0x08530e63dacb23a630bbbbd56ffc4dead54aca6d7e7ee7d920d7376eb9340ae7",
55+
"appchainChainId": "flowmemory-local-devnet-v0",
56+
"blockRangeStart": 1,
57+
"blockRangeEnd": 1,
58+
"stateRoot": "0x76ec5260c34184b6bb54ca406a43fc1f9591a47f37f71583a7620ef4a4065aff",
59+
"workReceiptRoot": "0x8b3ef5650c9eea2f608ad9c7cb73df3c289fc0ac72ed04f46e6ae4bce0a1f023",
60+
"verifierReportRoot": "0x4facd21e55423e182eba87355482a35daa93f53190fbd3a8d2969f9d55bc5373",
61+
"rootfieldStateRoot": "0xb72a851dca1103410484e3272945bae5e87fc39b8f32f77d2991959b60d3bfbf",
62+
"artifactCommitmentRoot": "0xb772a9f7273032fd3ba2da8b6476d4715bbbafbd2a7eed21ecd0d558bde3beab",
63+
"previousAnchorId": "0x0000000000000000000000000000000000000000000000000000000000000000",
64+
"finalityStatus": "local-placeholder"
65+
}
66+
},
67+
"blocks": [
68+
{
69+
"schema": "flowmemory.local_devnet.block.v0",
70+
"blockNumber": 1,
71+
"parentHash": "0x0f23c892cbd2d00c10839d97ddab833698a83f8df8d6df27ceac03cfdd4b7bc9",
72+
"logicalTime": 1778688000,
73+
"txIds": [
74+
"0x2cffda58c783dc026978b06a681587b19d9536ae4e158a69be855da1200f3189",
75+
"0xb9f435aceb1bedb86dce821743769b28c02a42002c9cd41f2df1ea0279462ab2",
76+
"0xef6df43993478d8f14d609732c7260fa08861ecc17e74137b83beda8d50931d2",
77+
"0x73b81134901c2ce13e575f161d82a404c6f7cd1ef2e8ee17beb6697062175c46",
78+
"0x3ac0b196a212a0e77d0a0c4b60e2283d2994b09993971b95427996700f5b92aa"
79+
],
80+
"receipts": [
81+
{
82+
"txId": "0x2cffda58c783dc026978b06a681587b19d9536ae4e158a69be855da1200f3189",
83+
"status": "applied",
84+
"error": null
85+
},
86+
{
87+
"txId": "0xb9f435aceb1bedb86dce821743769b28c02a42002c9cd41f2df1ea0279462ab2",
88+
"status": "applied",
89+
"error": null
90+
},
91+
{
92+
"txId": "0xef6df43993478d8f14d609732c7260fa08861ecc17e74137b83beda8d50931d2",
93+
"status": "applied",
94+
"error": null
95+
},
96+
{
97+
"txId": "0x73b81134901c2ce13e575f161d82a404c6f7cd1ef2e8ee17beb6697062175c46",
98+
"status": "applied",
99+
"error": null
100+
},
101+
{
102+
"txId": "0x3ac0b196a212a0e77d0a0c4b60e2283d2994b09993971b95427996700f5b92aa",
103+
"status": "applied",
104+
"error": null
105+
}
106+
],
107+
"stateRoot": "0x76ec5260c34184b6bb54ca406a43fc1f9591a47f37f71583a7620ef4a4065aff",
108+
"blockHash": "0xf76ac3652230cae4a4b5afcd54b0dcec9219f20ad71e21c497264668fb30f235"
109+
},
110+
{
111+
"schema": "flowmemory.local_devnet.block.v0",
112+
"blockNumber": 2,
113+
"parentHash": "0xf76ac3652230cae4a4b5afcd54b0dcec9219f20ad71e21c497264668fb30f235",
114+
"logicalTime": 1778688001,
115+
"txIds": [
116+
"0x8f719c880f17b5d4fb6d9efd54ac276d0dd8050d11c2c7870c36a79b66bc49d7"
117+
],
118+
"receipts": [
119+
{
120+
"txId": "0x8f719c880f17b5d4fb6d9efd54ac276d0dd8050d11c2c7870c36a79b66bc49d7",
121+
"status": "applied",
122+
"error": null
123+
}
124+
],
125+
"stateRoot": "0x3e1f5fddd84f9d460ee30a380ff700b17611891b8c03eb320edf1baefe003ef9",
126+
"blockHash": "0x7515374a9b020a6d271820031738a5190cb0fc374adcd74a88a32c0fd0d5c7a6"
127+
}
128+
],
129+
"pendingTxs": []
130+
}

apps/dashboard/scripts/sync-fixtures.mjs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,35 @@ import { fileURLToPath } from "node:url";
55
const scriptDir = dirname(fileURLToPath(import.meta.url));
66
const repoRoot = resolve(scriptDir, "../../..");
77
const destinationDir = resolve(repoRoot, "apps/dashboard/public/data");
8-
const fixtures = [
9-
"flowmemory-dashboard-v0.json",
10-
"flowmemory-dashboard-base-canary-v0.json",
8+
const fixtureCopies = [
9+
{
10+
label: "dashboard fixture",
11+
source: resolve(repoRoot, "fixtures/dashboard/flowmemory-dashboard-v0.json"),
12+
destination: resolve(destinationDir, "flowmemory-dashboard-v0.json"),
13+
},
14+
{
15+
label: "Base canary dashboard fixture",
16+
source: resolve(repoRoot, "fixtures/dashboard/flowmemory-dashboard-base-canary-v0.json"),
17+
destination: resolve(destinationDir, "flowmemory-dashboard-base-canary-v0.json"),
18+
},
19+
{
20+
label: "FlowChain local devnet state",
21+
source: resolve(repoRoot, "fixtures/launch-core/generated/devnet/state.json"),
22+
destination: resolve(destinationDir, "flowchain-local-devnet-state.json"),
23+
},
24+
{
25+
label: "FlowChain local devnet dashboard state",
26+
source: resolve(repoRoot, "fixtures/launch-core/generated/devnet/dashboard-state.json"),
27+
destination: resolve(destinationDir, "flowchain-local-devnet-dashboard-state.json"),
28+
},
1129
];
1230

1331
mkdirSync(destinationDir, { recursive: true });
1432

15-
for (const fixture of fixtures) {
16-
const source = resolve(repoRoot, "fixtures/dashboard", fixture);
17-
const destination = resolve(destinationDir, fixture);
18-
if (existsSync(source)) {
19-
copyFileSync(source, destination);
20-
console.log(`Synced dashboard fixture: ${destination}`);
33+
for (const fixture of fixtureCopies) {
34+
if (!existsSync(fixture.source)) {
35+
throw new Error(`Missing ${fixture.label}: ${fixture.source}`);
2136
}
37+
copyFileSync(fixture.source, fixture.destination);
38+
console.log(`Synced ${fixture.label}: ${fixture.destination}`);
2239
}

0 commit comments

Comments
 (0)