Skip to content

feat(claimable-balance-readiness): evaluate claim eligibility from Horizon predicates - #488

Merged
egekoca merged 2 commits into
RevenantLabs:mainfrom
chainsmt:feat/claimable-balance-readiness
Sep 30, 2026
Merged

egekoca merged 2 commits into
RevenantLabs:mainfrom
chainsmt:feat/claimable-balance-readiness

Conversation

@chainsmt

@chainsmt chainsmt commented Sep 29, 2026 •

Copy link
Copy Markdown

Closes #465

Summary

Adds a self-contained Claimable Balance Claim Readiness feature under features/claimable-balance-readiness/. It answers a narrow question: at a user-chosen UTC time, does this named claimant appear eligible to claim this existing claimable balance — and why — without ever building or submitting a claim transaction.

Horizon is only used to load GET /claimable_balances/{id}. Predicate evaluation is entirely local.

Motivation

Horizon already returns claimants and nested predicates, but the UI did not explain branch-by-branch readiness at an arbitrary evaluation time. Relative predicates also need creation-time context; guessing that context produces false yes/no answers. This slice makes that uncertainty explicit as indeterminate.

What this PR does

  • Validates balance ID and claimant (G…) before any Horizon call (invalid_balance_id, invalid_claimant, invalid_time).
  • Normalizes nested predicates in lib/predicate-tree.ts and evaluates them in lib/claim-evaluator.ts for:
    • unconditional
    • absolute before/after
    • relative before/after
    • AND / OR / NOT
  • Resolves relative-time context from the balance creation/last_modified_time path in lib/time-context.ts. If that context cannot be established reliably, returns indeterminate instead of inventing an answer.
  • Distinguishes:
    • balance_not_found (Horizon 404 / missing resource)
    • found balance where the address is simply not listed as a claimant (ineligible / not a claimant)
    • eligible / ineligible / indeterminate verdicts from the selected claimant’s tree
  • Renders the full claimant list, nested predicate tree, and readiness verdict with explanations exposed to screen readers (branch-by-branch).
  • Maps transport/decode failures through claimableBalanceReadiness.errors.ts into actionable copy.ts strings (unsupported_predicate, request_failed, etc.).
  • Ships the full RevyHub feature contract: schema, hook state machine, panel/form/result/empty UI, MSW handlers, fixtures, unit + a11y + e2e specs (including an indeterminate journey).

Architecture notes

  • Slice-only PR: all changes stay inside features/claimable-balance-readiness/. Registry routing is generated; no shared navigation edits.
  • Uses Result<T, Code> for expected failures; user-facing English lives only in copy.ts.
  • Amounts remain string/BigInt-safe where displayed; secrets are never accepted.

Acceptance criteria coverage

  • Validate balance ID and claimant before the request
  • Evaluate unconditional, absolute-time, relative-time, AND, OR, NOT
  • Show selected evaluation time and creation-time context used for relative predicates
  • Explain ineligible claimant separately from a missing balance
  • Expose full branch-by-branch explanation to screen readers

Out of scope

  • No claim operation creation, signing, or submission
  • No wallet / private key ownership
  • No changes outside this feature directory

Test plan

  • npm run verify:features -- claimable-balance-readiness (35-file contract)
  • npm test -- features/claimable-balance-readiness (55 tests)
  • Manual: /tools/claimable-balance-readiness — eligible claimant path
  • Manual: address not on claimant list vs 404 balance
  • Manual: relative predicate with missing creation time → indeterminate

@drips-wave

drips-wave Bot commented Sep 29, 2026

Copy link
Copy Markdown

@chainsmt Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@egekoca
egekoca merged commit f729126 into RevenantLabs:main Sep 30, 2026
1 check 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.

[Assets & Trustlines] Claimable Balance Claim Readiness

2 participants