Description
The streaming/vesting contract module (contracts/token-factory/src/streaming.rs) and the vault backend routes (backend/src/routes/vaults.ts) are in place, but the VaultDashboard.tsx component in frontend/src/components/Vaults/ lacks the ability to display active vesting schedules with a visual progress indicator, or to let a beneficiary claim a matured vault. This issue implements the end-to-end vesting claim flow — from schedule display to on-chain transaction.
Requirements and Context
- Backend endpoints already exist:
GET /api/vaults/beneficiary/:address and GET /api/vaults/:id in backend/src/routes/vaults.ts.
- The
StreamProjectionService in backend/src/services/streamProjectionService.ts maintains vault state derived from on-chain events.
- The
useVaultContract hook in frontend/src/hooks/useVaultContract.ts must be extended (or a new useVaultClaim hook created) to invoke the on-chain claim_stream contract function.
- A vesting progress bar must show percentage elapsed based on
(currentLedger - startLedger) / (endLedger - startLedger) — not wall-clock time, since Stellar uses ledger numbers.
- Only the designated recipient address may claim — the UI must disable the claim button for connected wallets that are not the beneficiary.
Suggested Execution
Branch naming convention:
feat/vesting-schedule-claim-flow
Implement Changes
- Extend
frontend/src/components/Vaults/VaultDashboard.tsx to fetch the connected wallet's beneficiary vaults via GET /api/vaults/beneficiary/:address and render each as a VaultCard showing: token, creator, amount, unlock progress bar, and status badge.
- Create
frontend/src/components/Vaults/VaultCard.tsx with a ledger-based progress bar (percentage filled) and a Claim button that is enabled only when the vault is fully vested and the connected wallet matches the recipient.
- Extend
useVaultContract.ts with a claimVault(streamId: number) function that signs and submits the claim_stream Soroban transaction.
- Add a success toast and a confetti animation (reuse
useConfetti hook) on successful claim.
Test and Commit
- Write unit tests for the ledger-based progress calculation utility function.
- Add integration tests for
VaultCard with mocked API responses covering: not-yet-vested vault (claim button disabled), matured vault (claim button enabled), and already-claimed vault (status badge).
- Test the
claimVault hook with a mocked Soroban client to verify the correct transaction parameters.
- Ensure
VaultDashboard renders an accessible empty state when the wallet has no vaults.
Example Commit Message
feat(frontend): add vesting schedule progress display and on-chain claim flow to vault dashboard
Closes #<issue-number>
Guidelines
- Keep PRs focused: one logical change per PR.
- The progress bar must be computed from ledger numbers fetched from the Stellar Horizon API — do not use
Date.now() as a proxy.
- Follow the existing vault route patterns in
backend/src/routes/vaults.ts for any new backend routes needed.
- Request a review from at least one maintainer before merging.
Description
The streaming/vesting contract module (
contracts/token-factory/src/streaming.rs) and the vault backend routes (backend/src/routes/vaults.ts) are in place, but theVaultDashboard.tsxcomponent infrontend/src/components/Vaults/lacks the ability to display active vesting schedules with a visual progress indicator, or to let a beneficiary claim a matured vault. This issue implements the end-to-end vesting claim flow — from schedule display to on-chain transaction.Requirements and Context
GET /api/vaults/beneficiary/:addressandGET /api/vaults/:idinbackend/src/routes/vaults.ts.StreamProjectionServiceinbackend/src/services/streamProjectionService.tsmaintains vault state derived from on-chain events.useVaultContracthook infrontend/src/hooks/useVaultContract.tsmust be extended (or a newuseVaultClaimhook created) to invoke the on-chainclaim_streamcontract function.(currentLedger - startLedger) / (endLedger - startLedger)— not wall-clock time, since Stellar uses ledger numbers.Suggested Execution
Branch naming convention:
Implement Changes
frontend/src/components/Vaults/VaultDashboard.tsxto fetch the connected wallet's beneficiary vaults viaGET /api/vaults/beneficiary/:addressand render each as aVaultCardshowing: token, creator, amount, unlock progress bar, and status badge.frontend/src/components/Vaults/VaultCard.tsxwith a ledger-based progress bar (percentage filled) and aClaimbutton that is enabled only when the vault is fully vested and the connected wallet matches the recipient.useVaultContract.tswith aclaimVault(streamId: number)function that signs and submits theclaim_streamSoroban transaction.useConfettihook) on successful claim.Test and Commit
VaultCardwith mocked API responses covering: not-yet-vested vault (claim button disabled), matured vault (claim button enabled), and already-claimed vault (status badge).claimVaulthook with a mocked Soroban client to verify the correct transaction parameters.VaultDashboardrenders an accessible empty state when the wallet has no vaults.Example Commit Message
Guidelines
Date.now()as a proxy.backend/src/routes/vaults.tsfor any new backend routes needed.