Skip to content

[#1255] Refactor ClaimPanel → ClaimCard (v5 breakdown + deadline)#1293

Merged
realproject7 merged 5 commits into
mainfrom
task/1255-claim-card-v5
May 26, 2026
Merged

[#1255] Refactor ClaimPanel → ClaimCard (v5 breakdown + deadline)#1293
realproject7 merged 5 commits into
mainfrom
task/1255-claim-card-v5

Conversation

@realproject7

Copy link
Copy Markdown
Owner

Summary

Full v5 ClaimCard with 3 settlement variants:

  • Normal: breakdown from /projection (spend × multiplier = weighted spend), claim amount from /proof (authoritative), on-chain claimDeadline() countdown with post-deadline disable
  • Final-burn: burn tx deep link, sub_bronze/zero_recipient/default copy
  • Not eligible: clean message for non-activated wallets

Source-of-truth rule

  • Claim amount = /proof.amount (authoritative, never overridden)
  • Breakdown = /projection (explanatory)
  • Deadline = on-chain MerkleClaim.claimDeadline() (single source of truth)

ClaimPanel

Now a thin wrapper: <ClaimCard mode="normal" />

Version

1.39.0 → 1.40.0 (feature)

Closes #1255

🤖 Generated with Claude Code

ClaimCard handles 3 settlement variants: normal (proof + breakdown
+ claim), final-burn (burn tx link), not-eligible.

Normal variant: breakdown from /projection (spend × multiplier),
claim amount from /proof (authoritative), on-chain claimDeadline
countdown with post-deadline disable. ClaimPanel becomes thin
wrapper around ClaimCard mode="normal".

Closes #1255

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented May 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
plotlink Ignored Ignored May 26, 2026 10:26am

Request Review

@realproject7 realproject7 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@re2 review — APPROVE ✅

Checked against issue #1255 acceptance criteria:

Criterion Status
Breakdown from /projection (spend × multiplier = weighted spend)
Claim amount from /proof (authoritative, never overridden)
claimDeadline from on-chain MerkleClaim.claimDeadline() useReadContract
Post-deadline: button disabled + "Claim Window Closed"
Real-time countdown (days + hours) ✅ 1s interval
All 3 variants (normal, final-burn, not eligible)
Already claimed: shows "Claimed" + explorer link
ClaimPanel → thin wrapper <ClaimCard mode="normal" /> ✅ net -234 lines
Version 1.39.0 → 1.40.0 (feature)

Code review notes:

  • Source-of-truth correct: /proof.amount for claim tx, /projection for display breakdown, on-chain for deadline
  • Component split clean: ClaimCardFinalBurnCard | NormalClaimCardClaimCardInner
  • Uses EXPLORER_URL from constants (not hardcoded basescan)
  • useReadContract for claimed() gated on proofData.eligible — avoids unnecessary RPC calls
  • Claim tx: writeContractonSuccess captures hash → useWaitForTransactionReceipt confirms
  • staleTime: Infinity on proof query — correct, proofs are immutable once finalized

No blocking issues found.

@project7-interns project7-interns left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES

Summary

The refactor keeps the proof-backed claim path and adds the v5 breakdown/deadline UI, but it misses the explicit source-of-truth guard for finalized proof vs live projection divergence.

Findings

  • [high] Live projection breakdown is shown unconditionally, even when it can diverge from the finalized claim amount.
    • File: src/components/airdrop/ClaimCard.tsx:170
    • #1255 explicitly says /proof.amount is authoritative and /projection is explanatory only; if /projection.weighted_spend and /proof.amount imply a material mismatch (>1% delta), the claim amount must remain visible/actionable but the breakdown must be hidden or marked stale/unavailable. This implementation renders the projection breakdown whenever projection exists and never compares it against proofData.amount, so users can see a confident breakdown that does not explain the actual on-chain claim.
    • Suggestion: compare the projected claim implied by projection data to proofData.amount; when the delta is over the tolerance, keep the claim UI enabled using /proof.amount but suppress the breakdown or show a clear stale/unavailable message.

Decision

Requesting changes until the projection/proof divergence guard from #1255 is implemented. CI was still pending at review time.

When /projection implied amount diverges >1% from /proof amount,
breakdown is marked stale/unavailable instead of showing potentially
misleading numbers. Claim button remains actionable with /proof
amount (authoritative). Normal case shows full breakdown.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@project7-interns project7-interns left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES

Summary

The divergence guard has been added, but the comparison uses incompatible units and will incorrectly mark valid breakdowns stale.

Findings

  • [high] Projection/proof divergence check compares PLOT amount to a unitless share fraction.
    • File: src/components/airdrop/ClaimCard.tsx:171
    • proofAmountNum is the finalized claim amount in PLOT after formatUnits, while impliedAmount is weighted_spend / community_total, a fractional share between 0 and 1. For a valid claim of, say, 100 PLOT with a 0.0005 pool share, this computes almost 100% delta and hides the normal breakdown even when it is correct. #1255 requires hiding/marking stale only for material divergence, not for every normal claim.
    • Suggestion: compare /proof.amount to a projected claim amount in the same units, e.g. use the relevant projection.projected_share.<tier> value for the finalized settlement tier if available, or omit the delta check and mark breakdown stale only when the endpoint cannot provide a same-unit projected amount. Keep the claim button driven by /proof.amount.

Decision

Requesting changes until the divergence guard compares values in the same units and preserves the normal breakdown for matching claims. CI was still pending at review time.

…laim

Remove broken unit-mismatch comparison. Breakdown always shown as
explanatory ("How your share was calculated") with clear note that
final claim amount is from the on-chain settlement. Claim button
always driven by /proof.amount (authoritative).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@project7-interns project7-interns left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES

Summary

The unit-mismatch comparison was removed, but the PR still does not satisfy #1255’s divergence handling requirement. Without a same-unit check, the UI should not present live projection math as “how your share was calculated.”

Findings

  • [high] Projection breakdown is still presented as authoritative calculation when divergence cannot be checked.
    • File: src/components/airdrop/ClaimCard.tsx:172
    • #1255 requires that when /projection and /proof.amount materially diverge, the proof amount stays actionable and the breakdown is hidden or marked stale/unavailable. The updated code no longer attempts the invalid comparison, but it now always renders the projection block as “How your share was calculated” and only adds a small note that the final claim amount is from settlement. If the client cannot compare in the same units, this block must be explicitly marked as live/explanatory and not final, or shown as unavailable/stale, so users are not told stale projection math is how their finalized claim was calculated.
    • Suggestion: either fetch enough finalized context to compare against /proof.amount, or change the projection block heading/copy to make it clearly “Live contribution breakdown (may not reflect final settlement)” and keep /proof.amount as the only finalized claim amount.

Decision

Requesting changes until the breakdown is clearly marked non-final/stale when no same-unit divergence check is possible. CI was still pending at review time.

Breakdown header now reads "Live contribution breakdown (may not
reflect final settlement)" — explicitly non-final. Claim amount
from /proof remains the only finalized value.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@project7-interns project7-interns left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES

Summary

The latest copy fix resolves the prior breakdown-label issue, but the PR still fails required lint/typecheck on the current head.

Findings

  • [high] lint-and-typecheck fails due an unescaped apostrophe in JSX.
    • File: src/components/airdrop/ClaimCard.tsx:139
    • ESLint reports react/no-unescaped-entities for You weren't eligible for this campaign. This blocks CI.
    • Suggestion: use You weren&apos;t eligible for this campaign. or equivalent escaped text.

Decision

Requesting changes until the lint failure is fixed and CI is green. The prior projection/proof copy concern is resolved by the new “Live contribution breakdown (may not reflect final settlement)” label.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@project7-interns project7-interns left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE

Summary

The requested fixes are resolved. The live projection breakdown is now explicitly labeled as non-final, the finalized claim amount remains driven by /proof.amount, and the lint failure has been fixed.

Findings

  • None blocking.

Decision

Approving PR #1293. The ClaimCard refactor now satisfies #1255 for settlement variants, proof-backed claiming, explanatory projection breakdown, on-chain deadline display/disable behavior, and latest CI is green.

@realproject7 realproject7 merged commit 28a3446 into main May 26, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[T3.6] Refactor ClaimPanel.tsx → ClaimCard.tsx (v5 breakdown copy)

2 participants