Rootmark
Portaldot Hacker House 2026 - Track 1 · Modular Cloud & Middleware · Chain 420420777
Portaldot V3 · Hackathon build

Rootmark

Verifiable middleware for the Portaldot chain. One query surface across EVM and ink!, every record carries a Merkle proof checked against an on-chain root.

Live · rootmark-seven.vercel.app GitHub · Sketchify-Dev/rootmark Chain 420420777
What it is
Middleware, not a dApp. Any app can query without running its own indexer, and check the answer without trusting it.
Where it lives
Next.js API plus indexer. Anchor on EVM `PortalAnchor`, Emitter for test flow, WASM anchor ready.
Why now
Portaldot V3 exposes one chain in two VMs. No shared index, no checkable read. Rootmark fills that gap.
01 · Problem addressed

The chain is split, the reads are trusted.

Two VMs, two event worlds
Solidity logs on the EVM side, typed ink! events on the WASM side. No shared shape, no shared query.
No checkable index
Apps read from someone's database. If that database invents a transfer, the client has no way to know.
Middleware is the bottleneck
Track 1 exists because cloud and middleware decide whether the chain is usable. Right now, the usable path is trust.

Result: builders either run a bespoke indexer for one VM, or ship an app that cannot prove what it shows.

02 · Why Portaldot is essential

One chain, two execution environments, one root.

Portaldot V3 is the only chain in this stack that runs ink! and EVM together, chain 420420777, with test-evm-rpc-v3 and test-node-v3 as the two doors into the same state. Rootmark is native to that design: tail both heads, normalize into one record, commit one root.

What Portaldot gives us
A single blockspace where a batch can cover both VMs. The anchor contract is the settlement for truth, not for value.
What Rootmark gives Portaldot
A reusable query plus proof layer any team can point an app at, without reindexing both VMs themselves.
03 · Architecture

Tails both heads, proves every read.

EVM headeth_getBlockByNumber plus receipts, decoded against known ABIs, anonymous topics preserved.
WASM headsystem.events at blockHash, typed decoding including `Anchored`.
IndexerNormalize into EventRecord { vm, chainId, blockNumber, blockHash, txHash, contract, event, args, leaf }, hash leaf with keccak256(canonicalJson), build Merkle tree (duplicate last on odd), batch size 25, ready after 90s.
AnchorCommit root per batchId to PortalAnchor.anchor on EVM and anchor on WASM. Read back with getAnchor or contract storage. Recompute in the browser with applyProof.
API plus Console
GET /api/v1/events, /proof/:id, /anchors, /contracts, /filters, /health · Console query plus Verify panel, Anchors batches, Contracts live state.
04 · Proof of product functionality

Live on V3, verifiable in one click.

On-chain
PortalAnchor 0x92B79C5cD9CC8235e3e2718a739BE825e2bd5430
deploy tx 0x6e33aa…2923 block 204392 · Emitter 0x178B9ED9…C31E · first anchored batch 0xa66a8338… root 0x624facad… anchor tx 0xf1cb…6cc8 block 204768
Live site
rootmark-seven.vercel.app - landing numbers, /console query plus Verify, /anchors batches, /contracts live reads, /api/v1/health plus /proof/:id. Try record 11 to 13, each returns verified: true against contract storage.
Reproduce
npm run typecheck && npm test && npm run build - 38 tests, honest seed, ledger-paper premium UI.
Judge path
PORTALDOT_MNEMONIC="..." npm run indexer then npm run emit -- --note "judge run" plus npm run dev. New Ping appears within seconds, new batch anchors on chain.
Local mirror
npm run local-evm - ganache chain 420420777, default mnemonic junk, no faucet needed.
05 · Live walk, 30 seconds

Query, inspect, verify.

1
Query
Filter by vm, contract, event, address, block range. Cursor paging. One shape across both VMs.
2
Inspect
Open any row. Leaf hash, sibling path, batch root, block span, tx link.
3
Verify
Panel recomputes the root in the browser and compares with `PortalAnchor` storage. Green means the indexer did not invent it.

If the proof fails, the UI says so. No hidden fallback.

Watch it (30 s)
https://youtu.be/HhubgdyP3U8 - real screens, real testnet: query, cursor clicks Verify, batch #00 against PortalAnchor on chain 420420777.
06 · What is real and what is not

Honest about the deploy.

What the live site is
Stateless on Vercel. Ships a fixed snapshot of 26 records and 8 batches seeded on cold start, plus the on-chain-tip batch `#00` (`0x3aa9…`, 4 records) read live from `PortalAnchor`. Every count is real. The 8 snapshot batches are unsigned by design; the 4 real roots live in PortalAnchor storage, tip 0x3aa9be70 in block 204947.
What needs a local run
Picking up new chain records and writing new roots. That is `npm run indexer` with a funded key, by design. Vercel functions cannot keep SQLite between requests, so anchoring locally is the honest path.

No fake metrics, no mock roots, no generated reviews. The pending batches are `unsigned` because no writer transaction has been mined, not hidden.

07 · Why we keep building

From demo to shared service.

Durable index
Move off local SQLite to a shared store (Turso or Neon) so the public site self-extends. One cron plus one writer, same Merkle pipeline.
Finality plus reorgs
Lag by finality, track reorgs, mark affected batches. Fine on a quiet testnet, required on a busy chain.
Client SDK
Publish `verify(record, proof, onChainRoot)` for any frontend, plus typed filters for the API.
WASM anchor live
Deploy the ink! anchor once the native account is funded, anchor both sides per batch.
Zero-trust reads by default
Default all reads to verified. Cache roots, not trust.
08 · Ask

Support to make this the shared layer.

We built the piece Track 1 is missing: a query layer you can check. With continued support we make it durable, handle finality, and ship the WASM anchor plus SDK so every Portaldot team gets verifiable reads without running their own indexer.

What we need
Testnet runway plus review time with the Portaldot team - to set the durable store, finalize WASM anchoring, and align the proof shape with what ecosystem clients need.
What you get
A public good for the chain. One endpoint, one proof format, any app benefits.
09 · Links

Everything is one click away.

Live
https://rootmark-seven.vercel.app
plus /console /anchors /contracts /api/v1/health
demo https://youtu.be/HhubgdyP3U8
Code
https://github.com/Sketchify-Dev/rootmark
master, MIT, `contracts/deployments.json` is the source of truth
Run it
npm install && npm run typecheck && npm test && npm run build · npm run wallet · PORTALDOT_MNEMONIC="..." npm run indexer · npm run dev

Portaldot Hacker House 2026 · Track 1 · Team Sketchify · Rootmark - verifiable middleware, the ruled sheet is older than the chain, the check is new.