Skip to content

fix(tips): make Product finalized-event readback compatible with DevNet - #238

Merged
knzeng-e merged 2 commits into
devfrom
fix/product-tip-finalized-log-query
Oct 4, 2026
Merged

knzeng-e merged 2 commits into
devfrom
fix/product-tip-finalized-log-query

Conversation

@knzeng-e

@knzeng-e knzeng-e commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner

Outcome

Product-host tips can recover a finalized contribution by its exact intent ID on the current DevNet RPC. The Product executable is version 0.1.36 so hosts can invalidate the stale 0.1.35 bundle.

Issue and context

Refs #229. Local scope: docs/backlog/native-gifts-tips.md.

PR #237 separated Product's native extrinsic hash from an EVM transaction hash, but its finalized-event read-back used viem.getLogs with only the indexed id argument. Viem emits trailing null topic placeholders for the other indexed event fields. The public Product DevNet EVM RPC rejects that filter with -32602 FilterTopic, so a submitted tip stays uncertain even when the user asks to check status. Product Desktop also continued loading the old executable because the manifest version had not advanced.

Architecture and key concepts

The contribution intent ID remains the reconciliation key. Product reports native extrinsic finalization; Dotify independently asks the public EVM read model for a finalized ContributionReceived(id) and its same-block ContributionShare(id) events. Only those events can produce a verified, dated receipt. An uncertain journal entry is never resubmitted automatically.

How it works

  1. Derive the two concrete ABI topics (event selector, id) with generated contract ABI tooling.
  2. Query eth_getLogs directly with exactly those topics through the finalized block. This avoids the RPC-incompatible null placeholders while retaining indexed filtering.
  3. Query shares only in the received event's block, decode the existing receipt model, and let the contribution flow verify sender and amount against its persisted reservation.
  4. Publish Product manifest version 0.1.36 for the cache-sensitive behavior change.

Design decisions and tradeoffs

The filter still uses viem.encodeEventTopics and the generated ABI; it does not hard-code event signatures or scan unrelated logs. Direct JSON-RPC is localized to this read path because the higher-level helper creates an invalid filter for this endpoint. The query starts at block zero; a deployment-block checkpoint could reduce historical scan cost later, once the runtime registry records it reliably.

Security, failure, and operations

  • No event means no success claim and no automatic retry payment. An RPC failure remains visible as uncertain status.
  • The local contribution journal is preserved across reload; do not clear Product Desktop cache before backing it up. Four earlier Product-host intents remain unresolved and were not replayed by this PR.
  • The Product CDM adapter still requires an explicit build flag. No keys, frontend secrets, new payment policy, contract change, or demo signer are introduced.
  • Candidate 0.1.36 from commit 9c2a476 was published to dotify-test01.dot at CID bafybeiczbltdtr2rttbmvpeme7q45lxf5pmhyvy3o2ogl6jq74o4bxmo2u. Bulletin root, DotNS contenthash and executable manifest finalized. Product Desktop loaded that exact SHA and appVersion after reload; a fresh user-authorized tip still requires manual validation.

Review guide

Suggested order

  1. web/src/features/donations/contributions.ts: inspect concrete topic construction, finalized-block bound, same-block share read and fail-closed decoding.
  2. web/src/features/donations/contributions.reader.test.ts: verify exact RPC filter shape and no fabricated receipt.
  3. web/polkadot-app-deploy.config.ts and docs/operations/deployment-configuration.md: verify cache version and operational instructions.

Verify carefully

  • Can a log for another intent, runtime or unfinalized block be accepted?
  • Can a failed read-back cause a second contribution submission?
  • Does the Product host actually load SHA 9c2a476 and appVersion 0.1.36 after reload?
  • Can the finality/read-model delay exceed the bounded polling window without misleading success feedback?

Validation

Evidence What it proves
npm run test:unit 98 files, 765 tests pass, including contribution recovery and no-resend behavior.
npm run build TypeScript and ordinary production build pass.
VITE_DOTIFY_RUNTIME_ADAPTER=product-cdm VITE_DOTIFY_DEBUG_PANEL=true npm run build:product-devnet:frozen Product CDM candidate builds with commit SHA and recovery message embedded.
npx eslint . --ignore-pattern '.data/**' Source lint passes with two pre-existing React hook warnings. Raw npm run lint traverses a local .data/ archive and fails on minified historical bundles, unrelated to this change.
Read-only DevNet RPC queries eth_getLogs accepts [selector,id]; all four historical intent IDs have zero ContributionReceived events through finalized block 14,017,679.
Product DevNet deployment CID, DotNS contenthash and executable manifest finalized.
Product Desktop 0.1.36 You > Production readiness shows exact SHA 9c2a476b0e4973a93643a2e6006a6476b57e563e and [0, 1, 36]; the existing Product account reconnects without a new payment.
PR #238 CI at 742c979 All eight W01 jobs pass, including Web checks, Product DevNet build and Playwright core flows. This second commit only applies Prettier formatting; the deployed runtime behavior is unchanged.

Known limitations and follow-ups

  • No new funded Product-host tip was sent for this change. A human must inspect the amount and perform the final signature; a successful on-host receipt remains the acceptance gate.
  • Historical pending intents have no matching contribution event in the inspected finalized range; that is not proof of no native debit. Preserve their journal and reconcile before any retry.
  • The Desktop host refreshed to 0.1.36 without clearing its contribution journal. This does not prove that a new Product contribution finalizes end to end.
  • Issue Native gifts, work tips and artist earnings #229 remains open for broader production activation and real-host validation.

Metadata checklist

@knzeng-e knzeng-e self-assigned this Oct 4, 2026
@knzeng-e knzeng-e added bug Something isn't working P1 product-sdk Polkadot Product SDK / Host / Playground integration labels Oct 4, 2026
@knzeng-e
knzeng-e marked this pull request as ready for review October 4, 2026 02:28
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-04T02:31:22.735627Z 742c979 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@knzeng-e
knzeng-e merged commit 201ecfe into dev Oct 4, 2026
8 checks passed
@knzeng-e
knzeng-e deleted the fix/product-tip-finalized-log-query branch October 4, 2026 02:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working P1 product-sdk Polkadot Product SDK / Host / Playground integration

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant