Skip to content

Roadmap

What has already been verified, what comes next, and what we have decided not to do. Only items with evidence behind them — not "we might." Each entry states what exists today and what does not, so the size of the remaining work is visible.

Phases

Phase Duration Goal Status
MVP · testnet 2 months Ship the P0 features on testnet Done
Productize · launch 2 months Private mainnet deployment, first users Upcoming
Growth Ongoing Scale against transaction metrics Later

"Next" below maps to the productize phase; "After that" maps to growth.

So far — verified in P0

These are not plans. Each was confirmed working on the live networks. The evidence is in the P0 verification record and the MVP final review.

Feature How it was verified
Wallet sign-in Browser E2E → confirmed PostgreSQL session row
XMTP 1:1 messaging Real A↔B and B↔C round trips
Group conversations of three or more A/B/C group send and receive. Details below
Dojang badges and three-way inbox routing Live GIWA Sepolia lookups
On-chain evidence A real GIWA Sepolia transaction
Encrypted evidence archive Restorable only by signing wallets

Group conversations of three or more

A 1:1 is internally a two-member MLS group, so there is a single code path, and adding people takes that same path. CreateGroup requires at least two peers besides yourself, so a group is three people at minimum.

CreateGroup.execute(peerAddresses)
  drop self, deduplicate, sort
  reject if peers.length < 2      -> a group is at least three people
  check reachability with canMessage()
  create the XMTP MLS group

If any address cannot receive XMTP messages, UnreachableParticipantsError names the offending addresses and no group is created. This avoids leaving a half-formed group behind.

Test What it covers
messaging-three-users.spec.ts A/B/C group send and receive over the live XMTP dev network
app-three-users.spec.ts Three sign-ins, 1:1 round trips, request-inbox routing and evidence blocking for unverified peers (3 scenarios, 57.4s)
app-group-evidence.spec.ts Group conversation from evidence proposal through on-chain submission
late-group-stream.spec.ts Stream delivery for a participant who joins late

Evidence holds in groups exactly as it does in 1:1 — groups are arguably the point.

Layer Participant constraint
CreateGroup Two peers besides yourself (three minimum)
Evidence API participants between 2 and 32
Evidence contract Reverts with TooFewParticipants below two

Inbox routing treats groups explicitly. A group lands in the main inbox only when every participant other than yourself is verified; if even one is not, it goes to the request inbox. Likewise, evidence can only be proposed in a group where everyone is verified.

Next — where the groundwork already exists

Every item here was recorded as a limit during P0, and most are in the state of having a working backend with one screen or path missing. That makes them the first bundle of the productize phase.

Refreshing logs you out

The session cookie is valid for 7 days, but app state lives only in memory, so a refresh returns you to onboarding. To the user it reads as "I got logged out." This friction has to go before launch.

There is no evidence rejection button

This is unfinished work, not dead code. The backend API (POST /:id/rejection), the domain state transition, and the tests all exist, and Flow 5 in the user flows already includes [reject]. Only the UI wiring is missing. Today, instead of rejecting, you wait out the one-hour expiry.

Peer signatures are detected by 5-second polling

A peer's signature shows up on the evidence screen up to 5 seconds late. Announcing the signature over an XMTP control message would remove the polling entirely. The control-message path is already used for evidence proposals, so this adds one more kind.

Signature collection as groups grow

Evidence requires every participant to sign, so the larger the group, the more a single straggler holds up everyone. We need a flow that shows who is outstanding and nudges them. Three-person groups are verified, but this problem grows with headcount.

Switching devices shows an empty history

MLS keys differ per installation, so a new installation cannot decrypt messages sent before it joined. This is a consequence of end-to-end encryption rather than a bug, but to the user it looks like "my conversation disappeared."

XMTP offers a path for transferring history between devices (historySyncUrl, syncAll). However, an existing installation has to still be alive to hand it over, so once storage has been cleared there is no recovery. The first decision is how much to guarantee. Details are in Message History.

Explaining the 10-installation limit

Every clear-storage-and-sign-in-again burns a slot, and at the limit sign-in hangs. Today the symptom is "pressing sign in never advances," with no way to tell why. At minimum we should surface the remaining slots and how to revoke.

After that — decisions needed first

For these, deciding what to give up matters more than the engineering difficulty.

Migrating to the XMTP production network

We are on dev today, so there is no interop with production XMTP apps and XMTP does not guarantee data retention on dev. Migrating opens cross-app interoperability, but neither identity nor messages carry across environments, so existing conversations do not continue. When to cut over is the decision. XMTP is itself migrating to a decentralized network, so the schedule needs watching (see where the network stands).

Rendering evidence cards in other apps

Today we use text prefixed with gasok:evidence:v1: instead of a custom codec. Open the conversation in another XMTP app and you see the raw text, not an evidence card. Defining a proper content type fixes it, but it only means anything once other apps support that type.

Smart account wallet support

P0 supports EOA signatures only. Accepting EIP-1271 smart accounts means extending the contract verification path, and evidence archive restoration has to change with it. The restore key is derived from a wallet signature, which relies on signature determinism (RFC 6979) — and that can break for smart accounts.

The 32-participant ceiling

That number comes from the evidence API and is tied to contract gas costs. Supporting larger groups means revisiting where the ceiling comes from.

Past evidence after membership changes

When people join or leave, the participant set changes, but evidence is signed against the set as it stood at proposal time. How to present past evidence after membership changes is undecided.

Dojang verification renewal

Faucet attestations expire 30 days after issuance. Because the contract re-queries Dojang at submission time, an expired attestation means submission is rejected even with every signature collected. We need a flow that warns before expiry and routes users to reissue.

Cross-platform

Today it is a mobile-shaped web app. The boundary for expanding into native apps is recorded in mobile/README.md. Because the frontend is split into domain / application / infrastructure / presentation and presentation never calls an SDK directly, the lower three layers are structured to port as is.

Revenue direction

The first priority is a gas fee share. We take a portion of the gas spent on transfers, payments, and signatures that happen inside the app. Nothing is separately charged to the user; it rides on transactions that already occur, which is the lowest initial UX friction.

Early on, though, transaction volume itself is low, which caps revenue. So we look at stacking several layers rather than a single source. The candidates under consideration follow, with on/off-ramp spread as the second priority.

Candidate Detail
On/off-ramp spread Currency spread when fiat payments are supported
Premium subscription Advanced spam filtering, bulk evidence storage, group management
B2B · API Dojang-based trust routing and risk filtering offered as an SDK
Evidence lookup service Evidence content lookup, per query or by subscription
Gas sponsorship Partners cover onboarding gas in exchange for exposure

Decided against

Not started at this stage.

Item Reason
Risk detection integration A real-time API spec for messenger use has to be agreed first
Transfers, payments, on/off ramps After the revenue model is validated
Legal weight of evidence Concept only. Legal counsel is a later phase
Choosing a messaging protocol XMTP alone is sufficient

Known risks

Risk Response
Decentralized messaging turns out slow or expensive Make it a user choice so UX does not degrade. XMTP's mainnet transition is in progress, so we keep watching the schedule
Legal weight of evidence is uncertain Concept only at this stage; legal counsel later
Cost of XMTP generational change v2 went read-only after four years and v2 conversations were not migrated. We accept the operational cost of following such changes
Acquiring the first users Needs a separate channel strategy

Debt to settle

Separate from the roadmap, these sit in the code and need a decision.

  • 006_evidence_content.sql is unused. No code touches the table and columns it creates, and it overlaps in purpose with 005's evidence_archives. We need to decide whether it replaces 005 or serves a different purpose (see Database).
  • PoC mode (VITE_CHAT_POC=1) is covered by the real app. Dropping it would remove roughly 1,000 lines.
  • The contract's EIP-712 domain is GasokConversationEvidence. Renaming requires redeployment, and redeploying invalidates every signature collected so far.