Skip to content

Adapt Dotify for Product DevNet - #108

Merged
knzeng-e merged 2 commits into
devfrom
feat/product-devnet-adaptation
Aug 3, 2026
Merged

Adapt Dotify for Product DevNet#108
knzeng-e merged 2 commits into
devfrom
feat/product-devnet-adaptation

Conversation

@knzeng-e

@knzeng-e knzeng-e commented Jul 26, 2026

Copy link
Copy Markdown
Owner

Outcome

Adds the first Product DevNet-compatible Dotify slice while preserving the standalone Netlify/Fly web path. The same UI can now run as a regular browser app or as a Product-hosted .dot app, with explicit host detection, a Product account identity option, canonical Product room links, and documented deployment/config boundaries.

This is a baseline, not the full Product SDK port. It intentionally keeps contract writes, protected key access, room media, and upload custody on the current proven Dotify boundaries until the Product host adapters prove stronger guarantees.

Issue and context

Refs #85.

Local scope docs:

  • docs/backlog/polkadot-product-readiness-and-killer-dapp-roadmap.md
  • docs/explanation/product-devnet-architecture.md
  • docs/operations/product-devnet-deployment.md
  • docs/reference/environment-variables.md

Issue #85 asks Dotify to run as a first-class Polkadot Product through a host-mediated boundary while keeping ordinary browser access. Before this PR, Dotify assumed the standalone web environment: injected EVM wallets, direct Vite envs, Fly API/signaling, Netlify hosting, and Socket.IO/WebRTC rooms.

The Product DevNet changes the host contract. Product accounts are app-scoped host identities, not EIP-1193 wallets. Product publication uses pad/Bulletin/DotNS-style static assets, and host capabilities may be missing outside the Product container. Dotify's north star still requires a room to feel like sharing a link, so Product mode cannot make wallet or host approval mandatory for room guests.

The deploy target is now dotify-test01.dot / https://dotify-test01.dev-dot.li because dotify.dot currently requires full personhood on Product DevNet. The docs keep that reason explicit so operators do not retry the blocked name by accident.

Architecture and key concepts

The PR introduces an adaptive host layer instead of replacing the current production path.

flowchart LR
  UI[Dotify React UI] --> Wallet[WalletProvider]
  UI --> Rooms[Room links + room state]
  Wallet --> WebWallet[Standalone EVM wallet]
  Wallet --> ProductHost[Product Host adapter]
  ProductHost --> ProductSDK["@parity/product-sdk Host APIs"]
  UI --> API[Fly catalog/key/upload API]
  UI --> Signal[Fly signaling]
  API --> Runtime[Paseo Asset Hub EVM SmartRuntime]
  Signal --> WebRTC[Host-to-guest room stream]
Loading

Key boundaries:

  • web/src/features/productHost/productHost.ts is the only Product SDK adapter in this slice.
  • Product host code is lazy-loaded and never blocks standalone first sound.
  • A Product account is treated as presence identity only. It is not promoted to an EVM signer.
  • Protected key delivery, artist publishing, payments, and contract writes still require the existing passkey/session or EVM wallet authority.
  • Product room links use the public Product URL configured by VITE_PUBLIC_APP_URL, so shared links are stable outside the host container.
  • Fly API/signaling origin checks now support comma-separated Netlify/Product origins.

How it works

In standalone browser mode, Dotify behaves as before. The existing wallet modal still offers the injected EVM path, catalog loading still uses the configured API/read model, and rooms still use the Fly signaling server.

In Product mode, VITE_PRODUCT_HOST_MODE controls host behavior:

  • off: never probe Product host APIs;
  • auto: detect Product host support and show Product identity when available;
  • required: fail explicitly when the host is missing or unsupported.

When a user clicks the Product option in the wallet modal, Dotify requests the app-scoped Product account through the host. The resulting SS58 identity is converted into a deterministic H160-shaped local identity so existing session/room UI can show a stable participant identity. The wallet provider deliberately leaves createEvmClient absent for this method, which keeps publish/payment/protected-key flows from accidentally treating the Product account as an EVM private key.

The Product build uses web/vite.product.config.ts, web/.env.product-devnet, and web/polkadot-app-deploy.config.ts. Publication is prepared with npm run build:product-devnet and npm run deploy:product-devnet, but the PR does not deploy anything by itself.

Design decisions and tradeoffs

The chosen design is dual-mode because Dotify already has a working production spine on Netlify/Fly and because Product SDK/Host APIs are still a moving, prototype-grade boundary. A hard switch to Product SDK would risk breaking first sound, room joins, and protected key custody.

Alternatives considered:

  • Full Product runtime port now: deferred because Product SDK contract helpers target pallet-revive/PolkaVM CDM flows, while Dotify's current writes use Hardhat Solidity ABIs and viem on Asset Hub EVM.
  • Statement Store rooms now: deferred because Statement Store payload/TTL/user budget limits fit small signed presence, not SDP/ICE, audio transport, full chat, media metadata, or walletless guests.
  • Product account as wallet signer: rejected for this slice because the host account is not an EIP-1193 wallet and must not silently authorize EVM writes or key access.
  • Product replacing Fly API/signaling: deferred because backend-held content-key custody and WebRTC signaling are still the authoritative production boundaries.

Security, failure, and operations

Security invariants:

  • No browser secrets are introduced.
  • No hidden fallback signer is introduced.
  • Product host absence fails explicitly in required mode.
  • Product identity cannot publish tracks, make payments, or request protected keys through EVM-only code paths.
  • Room guests remain wallet-free and never receive content keys or source files.
  • API and signaling CORS allowlists are explicit and include Product only through configured origins.

Operational boundaries:

  • CATALOG_SNAPSHOT_PATH remains optional to boot, but recommended on a durable Fly volume for production catalog persistence.
  • VITE_PUBLIC_APP_URL should be https://dotify-test01.dev-dot.li for Product publication so room links do not leak an internal/container URL.
  • Product deployment still requires operator actions outside this PR: Asset Hub funds, EVM mapping, Bulletin storage authorization, .dot ownership/registration, and pad --env devnet publication.
  • Rollback is source-level: redeploy Netlify/Fly from the previous commit or republish the previous Product version.

Review guide

Suggested order

  1. web/src/features/productHost/productHost.ts and productHost.test.ts - verify lazy host detection, Product account connection, identity derivation, and fail-closed errors.
  2. web/src/app/providers/WalletProvider.tsx, web/src/hooks/useWallet.ts, web/src/components/WalletModal.tsx - verify Product identity is surfaced without becoming an EVM signer.
  3. web/src/hooks/useSession.ts, web/src/features/rooms/roomState.test.ts, web/src/shared/config/deploymentSafety.ts - verify Product-origin room links and public URL validation.
  4. services/api/src/config.ts, services/api/src/app.ts, services/api/src/cors.test.ts, services/api/fly.toml, web/fly.signal.toml - verify multi-origin CORS behavior.
  5. web/vite.product.config.ts, web/.env.product-devnet, web/polkadot-app-deploy.config.ts, web/package.json - verify Product build/deploy wiring and pinned tooling.
  6. Docs under docs/explanation, docs/operations, docs/reference, docs/backlog, plus docs/index.html - verify the public architecture story does not overclaim delivered Product-native capabilities.

Verify carefully

  • Can Product host absence ever fall back to demo secrets or a hidden signer?
  • Can a Product-only identity reach an artist publish, payment, or protected-key request path that expects EVM authority?
  • Do Product room links use the canonical public app URL rather than the current browser/container origin?
  • Are API/signaling origin lists explicit and still restrictive for unrelated origins?
  • Does the PR state clearly what remains before [Product SDK][P1] Prove Product host compatibility before integration #85 can close?

Validation

Evidence What it proves
git diff --check No whitespace errors in the final diff.
cd web && npm run fmt:check Frontend touched files match Prettier formatting.
cd web && npm run lint ESLint has 0 errors; 3 existing React hook dependency warnings remain in App.tsx and ArtistShell.tsx.
cd web && npm run test:unit 27 frontend test files / 182 tests pass, including Product host and room link behavior.
cd web && npm run test:signal 49 signaling tests pass, including room joining, access metadata, WebRTC authorization, and social-layer limits.
cd services/api && npm test 75 API tests pass, including the multi-origin CORS coverage for dotify-test01.dev-dot.li.
cd web && npm run build Existing standalone production web build still compiles.
cd web && npm run build:product-devnet Product DevNet build emits dist-product with relative asset paths and the dotify-test01.dot profile.
cd services/api && npm run build API TypeScript build still compiles.
node scripts/backlog-sync.mjs --check --offline Backlog sync check passes; existing warnings remain for active item 24 without GitHub mapping and duplicate backlog doc 08.

Known limitations and follow-ups

This PR should remain Refs #85, not Closes #85.

Remaining before #85 can close:

  • Extract typed runtime read/write ports.
  • Add a generated CDM/PAPI adapter for Product-native contract operations.
  • Add backend Product signature verification for protected key/session flows.
  • Prototype Product resource allocation.
  • Prototype Statement Store presence with strict size, TTL, signer, and privacy limits.
  • Run real Product host/Desktop/Web smoke evidence after operator deployment.

Metadata checklist

  • Backlog issue linked with correct close/reference semantics: Refs [Product SDK][P1] Prove Product host compatibility before integration #85
  • Local backlog document linked
  • Added to Project 5 (Dotify sprints)
  • Project Priority, Track, Phase, Type, and Backlog doc mirror the issue
  • Workflow status matches draft/review state
  • Assignee set: knzeng-e
  • Applicable labels set: dotify-backlog, product-sdk
  • Applicable milestone set, or confirmed none exists
  • Reviewers requested when ownership is known
  • Draft/ready state is intentional

@netlify

netlify Bot commented Jul 26, 2026

Copy link
Copy Markdown

Deploy Preview for muzinga ready!

Name Link
🔨 Latest commit b9d4302
🔍 Latest deploy log https://app.netlify.com/projects/muzinga/deploys/6a6676e9bb98320008372eff
😎 Deploy Preview https://deploy-preview-108--muzinga.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@knzeng-e knzeng-e added dotify-backlog Tracked by docs/backlog/backlog.json and Project 5 product-sdk Polkadot Product SDK / Host / Playground integration labels Jul 26, 2026 — with ChatGPT Codex Connector
@knzeng-e knzeng-e self-assigned this Jul 26, 2026
@knzeng-e knzeng-e moved this from Todo to In Progress in Dotify sprints Jul 26, 2026
@knzeng-e
knzeng-e changed the base branch from main to dev August 3, 2026 13:33
@knzeng-e
knzeng-e marked this pull request as ready for review August 3, 2026 13:33
@knzeng-e
knzeng-e merged commit 9799c1f into dev Aug 3, 2026
12 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in Dotify sprints Aug 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dotify-backlog Tracked by docs/backlog/backlog.json and Project 5 product-sdk Polkadot Product SDK / Host / Playground integration

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant