feat(app): refuse a subscription before the investor signs - #166
luchobonatti wants to merge 2 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The PR description’s “either side” open-request refusal does not match the implemented subscription-only check, and two user-facing blocks reference “subscribe” while blocking both tabs.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
Open (2)
What changed in this PR
This PR updates the vault action UX so “Subscribe” is blocked before the wallet signing step when the vault is paused or when the investor already has an open subscription in the current epoch, while keeping the “Redeem” tab reachable when only subscribing is blocked.
Changes:
- Adds a
useVaultPausedReact Query hook to read the AsyncVault’spaused()state and classify it for UI gating. - Introduces subscribe-specific gating in
vaultAccess(pause state + open-subscription detection) and threads it intoVaultPreview. - Extends
ActionPanelmessage-blocking to be scoping-aware (sides: ["subscribe"] | ["redeem"] | both) and expands test coverage across the new states.
| File | Description |
|---|---|
| app/src/pages/VaultPreview.tsx | Wires pause/open-subscription gating into the panel block resolution. |
| app/src/pages/VaultPreview.test.tsx | Adds integration tests for paused vault behavior and open-subscription pre-sign blocking. |
| app/src/pages/vaultAccess.ts | Adds subscribe gate logic, isSubscriptionOpen, and message-block scoping via sides. |
| app/src/pages/vaultAccess.test.ts | Adds unit coverage for subscribe gate precedence, scoping, and isSubscriptionOpen. |
| app/src/hooks/useVaultPaused.ts | New hook for reading/classifying the vault pause state via paused(). |
| app/src/hooks/useVaultPaused.test.ts | Unit tests for pause-state classification behavior. |
| app/src/components/vault/ActionPanel.tsx | Adds side-scoped message blocking so only the relevant tab is blocked. |
| app/src/components/vault/ActionPanel.test.tsx | Tests for “both-sides” vs “single-side” message blocking behavior. |
| app-lib/contracts.ts | Extends AsyncVaultApi typing to include paused: Call<boolean>. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| export function isSubscriptionOpen(requests: InvestorRequestsRead): boolean { | ||
| if (requests.status !== "loaded") return false | ||
| return requests.requests.some( | ||
| (request) => | ||
| request.side === "deposit" && request.epochStatus.tag === "Open", | ||
| ) |
| case "checking": | ||
| return { | ||
| kind: "message", | ||
| reason: "Checking whether this address may subscribe.", | ||
| sides: ["subscribe", "redeem"], | ||
| } |
4c664f0 to
9fdff37
Compare
9fdff37 to
9483b1f
Compare


Summary
Refs #86
Subscribing while paused, or with a request already open, failed only after the wallet opened. Both refusals now show before anything is pressed.
Second of three stacked PRs, based on #162. Cancel closes #86 in the third.
Criterion 1 is met differently: the contracts check only their own side, so an open redemption does not block a subscription.
Changes
Acceptance criteria
Last three: third PR.
Test plan
Automated tests
npm run test— 336 passing, up from 314 on #162. Covers the pause read in all four states, an open subscription, refusal precedence, and the Redeem tab surviving a blocked subscribe.Manual verification
Local network, seeded with
npm run deploy -w scripts/harnessthennpm run test:happy-path:Breaking changes
None.
Checklist
Screenshots
None.