Summary
JobsContext.tsx's submitMilestone/disputeMilestone/voteOnMilestone/finalizeMilestone each fire a real transaction against packages/tholos-sdk, then optimistically set the local milestone status by assuming the call succeeded exactly as expected. None of them read the contract back. docs/src/INTEGRATION.md (lines 146-160) documents the correct pattern for this exact situation: poll get_assertion_state(id), or watch events, neither of which this app does.
Scope
- Add a way to read real assertion state (
get_assertion_state) into lib/tholos.ts, alongside the existing assert_outcome/dispute/resolve/finalize calls.
- After each action in
JobsContext.tsx, or on a polling interval for any milestone with an assertionId, reconcile local status from the real read instead of assuming success.
- A milestone whose challenge window has passed uncontested should reflect that it's now eligible for
finalize, driven by the real state, not by silence in the local optimistic status.
Proposed approach
Add getAssertionState(id) to lib/tholos.ts wrapping the SDK's get_assertion_state. In JobsContext.tsx, after a successful action call, immediately re-read state and set status from that read rather than a hardcoded guess (e.g. voteOnMilestone currently sets released/returned from the return value of resolveAssertion alone). For milestones with an assertionId and no terminal status yet, poll on an interval (or on demand via a refresh action) so status advances even without the user having just taken an action, e.g. once someone else's finalize call lands, or once a challenge window quietly expires.
Summary
JobsContext.tsx'ssubmitMilestone/disputeMilestone/voteOnMilestone/finalizeMilestoneeach fire a real transaction againstpackages/tholos-sdk, then optimistically set the local milestone status by assuming the call succeeded exactly as expected. None of them read the contract back.docs/src/INTEGRATION.md(lines 146-160) documents the correct pattern for this exact situation: pollget_assertion_state(id), or watch events, neither of which this app does.Scope
get_assertion_state) intolib/tholos.ts, alongside the existingassert_outcome/dispute/resolve/finalizecalls.JobsContext.tsx, or on a polling interval for any milestone with anassertionId, reconcile local status from the real read instead of assuming success.finalize, driven by the real state, not by silence in the local optimistic status.Proposed approach
Add
getAssertionState(id)tolib/tholos.tswrapping the SDK'sget_assertion_state. InJobsContext.tsx, after a successful action call, immediately re-read state and set status from that read rather than a hardcoded guess (e.g.voteOnMilestonecurrently setsreleased/returnedfrom the return value ofresolveAssertionalone). For milestones with anassertionIdand no terminal status yet, poll on an interval (or on demand via a refresh action) so status advances even without the user having just taken an action, e.g. once someone else'sfinalizecall lands, or once a challenge window quietly expires.