Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,15 @@ npm run flowchain:demo
npm run flowchain:export
```

Run the merged-surface smoke path when Foundry, Python, Visual Studio Build
Tools C++ workload, dashboard dependencies, and crypto dependencies are
Run the private/local acceptance smoke path when Foundry, Python, Visual Studio
Build Tools C++ workload, dashboard dependencies, and crypto dependencies are
installed:

```powershell
npm install --prefix apps/dashboard
npm install --prefix crypto
npm run flowchain:smoke
npm run flowchain:full-smoke
```

Run the existing dashboard as the local workbench:
Expand Down
10 changes: 7 additions & 3 deletions apps/dashboard/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,18 @@ fixtures/dashboard/generated/hardware-heartbeats.json

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

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.
The workbench adds local setup/API status plus object views for node status, peers, blocks, transactions, mempool, accounts, balances, faucet events, wallet public metadata, agents, models, receipts, memory cells, artifacts, verifier modules/reports, challenges, finality, private/local bridge deposits/credits/withdrawals, hardware signals, 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 plus the local command/service that should provide it.

Browser actions are hidden unless the local control-plane advertises the matching POST endpoint through `/health` or `/state`. The dashboard never asks for private keys in the browser.

Workbench object coverage:

```text
node/chain status, blocks, transactions, rootfields, agents, models, work receipts,
node/chain status, peers, blocks, transactions, mempool, accounts, balances,
faucet events, wallet public metadata, rootfields, agents, models, work receipts,
memory cells, artifacts, verifier modules, verifier reports, challenges, finality,
provenance/source, hardware signals, raw JSON
bridge deposits, bridge credits, bridge withdrawals, provenance/source,
hardware signals, raw JSON
```

## Status Vocabulary
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,25 @@
}
},
"baseAnchors": {
"0x2e2c83de6aab8190d169ad3348c62ce0cf0d4dcd6e83932c7beda822b4736a64": {
"0xd1112ed01fdf86d0caa079d7668a5c3e0482f6da36d8831f1e12a21bf2a77885": {
"agentAccountRoot": "0xcf31230bfff347f79e19a55f4d1ff5fa486b0b1ad4754ce22b93de4b259a3ca7",
"anchorId": "0x2e2c83de6aab8190d169ad3348c62ce0cf0d4dcd6e83932c7beda822b4736a64",
"anchorId": "0xd1112ed01fdf86d0caa079d7668a5c3e0482f6da36d8831f1e12a21bf2a77885",
"appchainChainId": "flowmemory-local-devnet-v0",
"artifactAvailabilityProofRoot": "0xfb4b693c45014aae0947f35696e9d864e7b26ac6fd39c1df5edb3e0dcf9bd928",
"artifactCommitmentRoot": "0xb772a9f7273032fd3ba2da8b6476d4715bbbafbd2a7eed21ecd0d558bde3beab",
"blockRangeEnd": 1,
"blockRangeStart": 1,
"challengeRoot": "0x16da3d2bf2dcd801bc5deb3987dc01342cb957031ad01408ea77bf5d1583656f",
"finalityReceiptRoot": "0x8b8f5ff0d8c0a2f799958098165e8a6ff3c8f822f57147d1e1e7d2199ae1e347",
"faucetRecordRoot": "0x2277503a52fab3f9e49b40debfb7d641abee75cf268aa56da403fdcf4fad6cee",
"finalityReceiptRoot": "0x990b60fd5f91eb725b65d36a1324e00be255daaa4bc0fbbe163343c3934b120a",
"finalityStatus": "local-placeholder",
"localTestUnitBalanceRoot": "0x167041ef195b5dde2d2cade6ecb26c9a0a596e9ed21ff7bfb02d33c9d2be8d15",
"memoryCellRoot": "0x1b4e91099dd8d867201bd880437197ae6c031e538341aaa3cd2046e5706a2c25",
"modelPassportRoot": "0x326aa6b0b372d29d24d747fe0879adfd7aaea206373b24ae2ab77d56357e9529",
"operatorKeyReferenceRoot": "0x8457aa3ed0f4238834a8f3925f25ccca805828d8427c3ef67590a45659b22a40",
"previousAnchorId": "0x0000000000000000000000000000000000000000000000000000000000000000",
"rootfieldStateRoot": "0xb72a851dca1103410484e3272945bae5e87fc39b8f32f77d2991959b60d3bfbf",
"stateRoot": "0xd92ec8176ad55060b37898d4235612d0874ae5da6a5edbf69717b704c484e016",
"stateRoot": "0xd4bf806a2f91cd8255b2c55db91cb59c9f941d9ec92614dcb86dbd926184630c",
"verifierModuleRoot": "0xd6ddd8a2d0f5812d64679656c69983a2e0aecd36bd36199d900245658ae4626c",
"verifierReportRoot": "0x4facd21e55423e182eba87355482a35daa93f53190fbd3a8d2969f9d55bc5373",
"workReceiptRoot": "0x8b3ef5650c9eea2f608ad9c7cb73df3c289fc0ac72ed04f46e6ae4bce0a1f023"
Expand All @@ -66,6 +68,17 @@
"status": "resolved"
}
},
"faucetRecords": {
"faucet:demo:001": {
"accountId": "local-balance:demo:agent-alpha",
"amountUnits": 1000,
"creditedAtBlock": 1,
"faucetRecordId": "faucet:demo:001",
"noValue": true,
"reason": "local-smoke-no-value-test-units",
"recipient": "agent:demo:alpha"
}
},
"finalityReceipts": {
"finality:demo:001": {
"challengeCount": 1,
Expand All @@ -75,7 +88,7 @@
"finalizedBy": "operator:local-demo",
"receiptId": "receipt:demo:001",
"rootfieldId": "rootfield:demo:alpha",
"stateRoot": "0x5b55ae15cf9ff5f7c18f8dce05da5ed0f780e4103607819129ce09f1ed7744a7"
"stateRoot": "0x2cff83eaf83ea3ae2e9b248ca6ac2b32e23fa3f9ca067c4a9c93e72ef5679d33"
}
},
"genesisConfig": {
Expand All @@ -93,15 +106,28 @@
"operatorKeyReferenceId": "operator-key:local-devnet:alpha",
"schema": "flowmemory.local_devnet.config.v0"
},
"localTestUnitBalances": {
"local-balance:demo:agent-alpha": {
"accountId": "local-balance:demo:agent-alpha",
"lastFaucetRecordId": "faucet:demo:001",
"noValue": true,
"owner": "agent:demo:alpha",
"totalFaucetUnits": 1000,
"units": 1000,
"updatedAtBlock": 1
}
},
"mapRoots": {
"agentAccountRoot": "0xcf31230bfff347f79e19a55f4d1ff5fa486b0b1ad4754ce22b93de4b259a3ca7",
"artifactAvailabilityProofRoot": "0xfb4b693c45014aae0947f35696e9d864e7b26ac6fd39c1df5edb3e0dcf9bd928",
"artifactCommitmentRoot": "0xb772a9f7273032fd3ba2da8b6476d4715bbbafbd2a7eed21ecd0d558bde3beab",
"baseAnchorRoot": "0xd61259ffaad6d352bd8f2e1b498c46b9d62b3c77ff22eeacd028bbb0cc66c5bd",
"baseAnchorRoot": "0x0f455d919de2d313e88c276b687975249bf3ce53c9cedc27c012a85bcbf0b946",
"challengeRoot": "0x16da3d2bf2dcd801bc5deb3987dc01342cb957031ad01408ea77bf5d1583656f",
"finalityReceiptRoot": "0x8b8f5ff0d8c0a2f799958098165e8a6ff3c8f822f57147d1e1e7d2199ae1e347",
"faucetRecordRoot": "0x2277503a52fab3f9e49b40debfb7d641abee75cf268aa56da403fdcf4fad6cee",
"finalityReceiptRoot": "0x990b60fd5f91eb725b65d36a1324e00be255daaa4bc0fbbe163343c3934b120a",
"importedObservationRoot": "0x99cb1b939d5a09f800f72e4c5a2b92988571126e1f6f93549f4893b3f7de7880",
"importedVerifierReportRoot": "0x6070b1015f000dd509c7b276d2ad68d8a9d188ef1a961c2f573346eb75ea5ad7",
"localTestUnitBalanceRoot": "0x167041ef195b5dde2d2cade6ecb26c9a0a596e9ed21ff7bfb02d33c9d2be8d15",
"memoryCellRoot": "0x1b4e91099dd8d867201bd880437197ae6c031e538341aaa3cd2046e5706a2c25",
"modelPassportRoot": "0x326aa6b0b372d29d24d747fe0879adfd7aaea206373b24ae2ab77d56357e9529",
"operatorKeyReferenceRoot": "0x8457aa3ed0f4238834a8f3925f25ccca805828d8427c3ef67590a45659b22a40",
Expand Down Expand Up @@ -164,7 +190,7 @@
}
},
"schema": "flowmemory.dashboard_state.local_devnet.v0",
"stateRoot": "0x75373cc47666ed9bcad605ce0f5d0aeb1bc8100a1087840d755205aef8a6bb50",
"stateRoot": "0x55cab7c41a999da527bdd026a772edb5e4804b070014cccc72622e09ce3e699f",
"verifierModules": {
"verifier:local-demo": {
"active": true,
Expand Down
58 changes: 47 additions & 11 deletions apps/dashboard/public/data/flowchain-local-devnet-state.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"genesisHash": "0x0f23c892cbd2d00c10839d97ddab833698a83f8df8d6df27ceac03cfdd4b7bc9",
"nextBlockNumber": 3,
"logicalTime": 1778688002,
"parentHash": "0x54ba8fe6b5d3781a91ebd45a2ab215dd51ff2f835afe1c72d1843384fffb3919",
"parentHash": "0xeca4065a019501355c54c1d7ecc4859e4be6355c9ccaa2ce7188822bebc88c82",
"operatorKeyReferences": {
"operator-key:local-devnet:alpha": {
"schema": "flowmemory.local_devnet.operator_key_reference.v0",
Expand Down Expand Up @@ -59,6 +59,28 @@
"active": true
}
},
"localTestUnitBalances": {
"local-balance:demo:agent-alpha": {
"accountId": "local-balance:demo:agent-alpha",
"owner": "agent:demo:alpha",
"units": 1000,
"totalFaucetUnits": 1000,
"lastFaucetRecordId": "faucet:demo:001",
"updatedAtBlock": 1,
"noValue": true
}
},
"faucetRecords": {
"faucet:demo:001": {
"faucetRecordId": "faucet:demo:001",
"accountId": "local-balance:demo:agent-alpha",
"recipient": "agent:demo:alpha",
"amountUnits": 1000,
"reason": "local-smoke-no-value-test-units",
"creditedAtBlock": 1,
"noValue": true
}
},
"modelPassports": {
"model:demo:local-alpha": {
"modelPassportId": "model:demo:local-alpha",
Expand Down Expand Up @@ -105,7 +127,7 @@
"finalityStatus": "finalized",
"challengeCount": 1,
"finalizedAtBlock": 1,
"stateRoot": "0x5b55ae15cf9ff5f7c18f8dce05da5ed0f780e4103607819129ce09f1ed7744a7"
"stateRoot": "0x2cff83eaf83ea3ae2e9b248ca6ac2b32e23fa3f9ca067c4a9c93e72ef5679d33"
}
},
"artifactCommitments": {
Expand Down Expand Up @@ -163,22 +185,24 @@
"importedObservations": {},
"importedVerifierReports": {},
"baseAnchors": {
"0x2e2c83de6aab8190d169ad3348c62ce0cf0d4dcd6e83932c7beda822b4736a64": {
"anchorId": "0x2e2c83de6aab8190d169ad3348c62ce0cf0d4dcd6e83932c7beda822b4736a64",
"0xd1112ed01fdf86d0caa079d7668a5c3e0482f6da36d8831f1e12a21bf2a77885": {
"anchorId": "0xd1112ed01fdf86d0caa079d7668a5c3e0482f6da36d8831f1e12a21bf2a77885",
"appchainChainId": "flowmemory-local-devnet-v0",
"blockRangeStart": 1,
"blockRangeEnd": 1,
"stateRoot": "0xd92ec8176ad55060b37898d4235612d0874ae5da6a5edbf69717b704c484e016",
"stateRoot": "0xd4bf806a2f91cd8255b2c55db91cb59c9f941d9ec92614dcb86dbd926184630c",
"workReceiptRoot": "0x8b3ef5650c9eea2f608ad9c7cb73df3c289fc0ac72ed04f46e6ae4bce0a1f023",
"verifierReportRoot": "0x4facd21e55423e182eba87355482a35daa93f53190fbd3a8d2969f9d55bc5373",
"rootfieldStateRoot": "0xb72a851dca1103410484e3272945bae5e87fc39b8f32f77d2991959b60d3bfbf",
"artifactCommitmentRoot": "0xb772a9f7273032fd3ba2da8b6476d4715bbbafbd2a7eed21ecd0d558bde3beab",
"operatorKeyReferenceRoot": "0x8457aa3ed0f4238834a8f3925f25ccca805828d8427c3ef67590a45659b22a40",
"agentAccountRoot": "0xcf31230bfff347f79e19a55f4d1ff5fa486b0b1ad4754ce22b93de4b259a3ca7",
"localTestUnitBalanceRoot": "0x167041ef195b5dde2d2cade6ecb26c9a0a596e9ed21ff7bfb02d33c9d2be8d15",
"faucetRecordRoot": "0x2277503a52fab3f9e49b40debfb7d641abee75cf268aa56da403fdcf4fad6cee",
"modelPassportRoot": "0x326aa6b0b372d29d24d747fe0879adfd7aaea206373b24ae2ab77d56357e9529",
"memoryCellRoot": "0x1b4e91099dd8d867201bd880437197ae6c031e538341aaa3cd2046e5706a2c25",
"challengeRoot": "0x16da3d2bf2dcd801bc5deb3987dc01342cb957031ad01408ea77bf5d1583656f",
"finalityReceiptRoot": "0x8b8f5ff0d8c0a2f799958098165e8a6ff3c8f822f57147d1e1e7d2199ae1e347",
"finalityReceiptRoot": "0x990b60fd5f91eb725b65d36a1324e00be255daaa4bc0fbbe163343c3934b120a",
"artifactAvailabilityProofRoot": "0xfb4b693c45014aae0947f35696e9d864e7b26ac6fd39c1df5edb3e0dcf9bd928",
"verifierModuleRoot": "0xd6ddd8a2d0f5812d64679656c69983a2e0aecd36bd36199d900245658ae4626c",
"previousAnchorId": "0x0000000000000000000000000000000000000000000000000000000000000000",
Expand All @@ -195,6 +219,8 @@
"0x2cffda58c783dc026978b06a681587b19d9536ae4e158a69be855da1200f3189",
"0x75e63a0257621b8ef7412c6455a19d848996905e21f5ba79ccb0870d6e82eb25",
"0x6f55c155425b968de01092be7d276f0c24430a2994910881938bc13c72f8892f",
"0xafd3991af8b9e4eadfa3810f82d74701b7518269ae7ba5d0e3e450844445b03b",
"0xec7019403fec03ea2ea4b090bc5ee1c63017ed9834bff5fb87ce2fe5d5794919",
"0x05abb39c720d8ee1cd9253e32efaa595f5d5b2fcef4a908f61ab4a6bfa315359",
"0xb9f435aceb1bedb86dce821743769b28c02a42002c9cd41f2df1ea0279462ab2",
"0x27aeba6c55c764222964764cb2bfbb69fb6fa56cb84714d6e98240ceb6e9d01d",
Expand Down Expand Up @@ -222,6 +248,16 @@
"status": "applied",
"error": null
},
{
"txId": "0xafd3991af8b9e4eadfa3810f82d74701b7518269ae7ba5d0e3e450844445b03b",
"status": "applied",
"error": null
},
{
"txId": "0xec7019403fec03ea2ea4b090bc5ee1c63017ed9834bff5fb87ce2fe5d5794919",
"status": "applied",
"error": null
},
{
"txId": "0x05abb39c720d8ee1cd9253e32efaa595f5d5b2fcef4a908f61ab4a6bfa315359",
"status": "applied",
Expand Down Expand Up @@ -273,13 +309,13 @@
"error": null
}
],
"stateRoot": "0xd92ec8176ad55060b37898d4235612d0874ae5da6a5edbf69717b704c484e016",
"blockHash": "0x1e6f848e67c93fcd23091891ec704f5ed58989956789acd3368bce883ad493f9"
"stateRoot": "0xd4bf806a2f91cd8255b2c55db91cb59c9f941d9ec92614dcb86dbd926184630c",
"blockHash": "0x78c6b0c6b56eae99d2d693878a2239620c713cff50fcb94ba6df3fc6ed08be56"
},
{
"schema": "flowmemory.local_devnet.block.v0",
"blockNumber": 2,
"parentHash": "0x1e6f848e67c93fcd23091891ec704f5ed58989956789acd3368bce883ad493f9",
"parentHash": "0x78c6b0c6b56eae99d2d693878a2239620c713cff50fcb94ba6df3fc6ed08be56",
"logicalTime": 1778688001,
"txIds": [
"0x8f719c880f17b5d4fb6d9efd54ac276d0dd8050d11c2c7870c36a79b66bc49d7"
Expand All @@ -291,8 +327,8 @@
"error": null
}
],
"stateRoot": "0x75373cc47666ed9bcad605ce0f5d0aeb1bc8100a1087840d755205aef8a6bb50",
"blockHash": "0x54ba8fe6b5d3781a91ebd45a2ab215dd51ff2f835afe1c72d1843384fffb3919"
"stateRoot": "0x55cab7c41a999da527bdd026a772edb5e4804b070014cccc72622e09ce3e699f",
"blockHash": "0xeca4065a019501355c54c1d7ecc4859e4be6355c9ccaa2ce7188822bebc88c82"
}
],
"pendingTxs": []
Expand Down
16 changes: 8 additions & 8 deletions apps/dashboard/public/data/flowmemory-dashboard-v0.json
Original file line number Diff line number Diff line change
Expand Up @@ -1993,12 +1993,12 @@
],
"devnetBlocks": [
{
"id": "0x1e6f848e67c93fcd23091891ec704f5ed58989956789acd3368bce883ad493f9",
"id": "0x78c6b0c6b56eae99d2d693878a2239620c713cff50fcb94ba6df3fc6ed08be56",
"blockNumber": 1,
"blockHash": "0x1e6f848e67c93fcd23091891ec704f5ed58989956789acd3368bce883ad493f9",
"blockHash": "0x78c6b0c6b56eae99d2d693878a2239620c713cff50fcb94ba6df3fc6ed08be56",
"parentHash": "0x0f23c892cbd2d00c10839d97ddab833698a83f8df8d6df27ceac03cfdd4b7bc9",
"stateRoot": "0xd92ec8176ad55060b37898d4235612d0874ae5da6a5edbf69717b704c484e016",
"receiptsRoot": "0x6393961b24d5db9f2984a39a98e827850b771f05c7f18005addb9a530af5a9b7",
"stateRoot": "0xd4bf806a2f91cd8255b2c55db91cb59c9f941d9ec92614dcb86dbd926184630c",
"receiptsRoot": "0x2f98caf4b28b2209cdf1f9beb1c23f8732c538657cc7a1d8855878b5400efabd",
"timestamp": "2026-05-13T16:00:00.000Z",
"observationCount": 8,
"reportCount": 8,
Expand All @@ -2015,11 +2015,11 @@
}
},
{
"id": "0x54ba8fe6b5d3781a91ebd45a2ab215dd51ff2f835afe1c72d1843384fffb3919",
"id": "0xeca4065a019501355c54c1d7ecc4859e4be6355c9ccaa2ce7188822bebc88c82",
"blockNumber": 2,
"blockHash": "0x54ba8fe6b5d3781a91ebd45a2ab215dd51ff2f835afe1c72d1843384fffb3919",
"parentHash": "0x1e6f848e67c93fcd23091891ec704f5ed58989956789acd3368bce883ad493f9",
"stateRoot": "0x75373cc47666ed9bcad605ce0f5d0aeb1bc8100a1087840d755205aef8a6bb50",
"blockHash": "0xeca4065a019501355c54c1d7ecc4859e4be6355c9ccaa2ce7188822bebc88c82",
"parentHash": "0x78c6b0c6b56eae99d2d693878a2239620c713cff50fcb94ba6df3fc6ed08be56",
"stateRoot": "0x55cab7c41a999da527bdd026a772edb5e4804b070014cccc72622e09ce3e699f",
"receiptsRoot": "0xa0407b9a8a55106d549e0f19b92fceaa7f7a25697e94ebf8a1fa74af7b9168f4",
"timestamp": "2026-05-13T16:00:01.000Z",
"observationCount": 8,
Expand Down
10 changes: 9 additions & 1 deletion apps/dashboard/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { AlertTriangle, RefreshCw } from "lucide-react";
import { AppShell } from "./components/AppShell";
import { DEFAULT_CANARY_DASHBOARD_DATA_PATH, fetchDashboardData } from "./data/loadDashboardData";
import type { DashboardData } from "./data/types";
import { buildWorkbenchSnapshot, fetchWorkbenchSnapshot, type WorkbenchSnapshot } from "./data/workbench";
import { DEFAULT_CONTROL_PLANE_URL, buildWorkbenchSnapshot, fetchWorkbenchSnapshot, type WorkbenchSnapshot } from "./data/workbench";
import { AlertsView } from "./views/AlertsView";
import { CanaryDeploymentView } from "./views/CanaryDeploymentView";
import { DevnetBlocksView } from "./views/DevnetBlocksView";
Expand All @@ -25,6 +25,10 @@ function LoadingState() {
<div className="skeleton-line skeleton-title" />
<div className="skeleton-line" />
<div className="skeleton-line skeleton-short" />
<p className="boot-hint">
Loading dashboard fixtures and probing {DEFAULT_CONTROL_PLANE_URL}/health plus /state. If this stays offline,
start the local service with <code>npm run flowchain:start</code>.
</p>
<div className="boot-grid">
<div />
<div />
Expand All @@ -43,6 +47,10 @@ function ErrorState({ message, onRetry }: { message: string; onRetry: () => void
<div>
<h1>Dashboard fixture failed to load</h1>
<p>{message}</p>
<p>
Run <code>npm run launch:v0</code> or <code>npm run sync:fixtures --prefix apps/dashboard</code> to refresh
local dashboard data, then retry.
</p>
<button className="button button-primary" type="button" onClick={onRetry}>
<RefreshCw size={16} aria-hidden="true" />
Retry fixture load
Expand Down
Loading
Loading