Skip to content

refactor(app): split the transaction modal's copy and map errors by name - #427

Merged
hpmaxi merged 4 commits into
feedbackfrom
feat/415-transaction-modal-copy
Nov 2, 2026
Merged

hpmaxi merged 4 commits into
feedbackfrom
feat/415-transaction-modal-copy

Conversation

@luchobonatti

Copy link
Copy Markdown
Member

Summary

Closes #415

TransactionModal.tsx held every action's copy as hand-written switches over raw contract error numbers. Copy is now data, and contract errors match by the name the generated clients carry. Stacked on #421: it needs the real clients in tests.

Changes

  • Contract errors resolve to their name at runtime from the generated clients' spec.errorCases(); no code→name table in the app.
  • One describeStatus turns a status into heading and body for every action; per-action copy is data, split by investor, cycle and admin.
  • TransactionModal.tsx goes from 2,158 to 239 lines.
  • The modal tests are split by section; tests take error codes from each client's error table by name.
  • AdminTransferPending now shows its hand-over message for the vault and oracle too; "already paused" and ExpectedPause copy no longer show on oracle actions.

Acceptance criteria

  • Contract error messages are keyed by the error name from the generated clients, not by numeric literals in app code.
  • A single describeStatus handles the six TransactionStatus cases for every action.
  • The copy lives outside TransactionModal.tsx, split by investor, cycle and admin actions.
  • TransactionModal.tsx is under 300 lines.
  • Every heading, body and error message is unchanged, apart from the AdminTransferPending and oracle pause fixes above.
  • ADMIN_VERBS, ShareLink and the exported modal types keep their exports.

Test plan

Automated tests

  1. stellar contract build && npm run build:clients, then npm run typecheck, npm run lint, npm run format:check, npx vitest run: all pass (2,291 tests).
  2. Modal tests: 177 it, 27 it.each, 413 expect before and after the split; no asserted string changed.

Manual verification

  1. Local network, harness deploy and seed: every modal action ran through the app (investor, cycle, emergency, configuration, governance, compliance, 2-of-2 multisig via /sign).
  2. Cancel a deposit after its epoch is priced from the CLI: the modal shows "A price is available, so this request can no longer be cancelled…".

Breaking changes

None.

Checklist

  • Self-reviewed my own diff
  • Tests added or updated
  • Docs updated (if applicable)
  • No unrelated changes bundled in

Screenshots

None.

@luchobonatti luchobonatti self-assigned this Nov 2, 2026
@luchobonatti
luchobonatti requested review from hpmaxi and a balanced review from Copilot November 2, 2026 19:29
@vercel

vercel Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
strata-vault-kit-app Ready Ready Preview Nov 2, 2026 9:13pm UTC

Request Review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Note

Copilot was unable to complete this review at the selected tier due to model policy or plan restrictions.

🟡 Changes recommended

The change introduces new cross-workspace test dependencies by importing helpers from app/src into app-lib tests, which increases coupling and undermines app-lib test isolation, so the helper logic should be inlined or moved into an app-lib-local test utility.

2 open issues
What changed in this PR

This pull request refactors the vault TransactionModal by moving action/status copy into dedicated modules and changing contract error handling from hard-coded numeric codes to generated error names resolved from client specs, with corresponding updates across hooks and tests.

Changes:

  • Extracts modal copy into app/src/components/vault/transactionCopy/* and centralizes status rendering via a single describeStatus.
  • Resolves and propagates contract failures as { code, name }, deriving name at runtime from generated client specs (spec.errorCases()), and updates app-lib plumbing accordingly.
  • Splits/updates tests to validate copy and refusals using name-derived errors (with shared render/error helpers), while preserving existing exports and behavior (with noted copy fixes in the PR description).
File Summary
app/​src/​test/​renderTransactionModal.tsx Adds shared render helpers for TransactionModal-related test suites.
app/​src/​test/​contractErrorCode.ts Adds a test helper to derive numeric error codes from generated error tables by name.
app/​src/​pages/​vaultRequests.ts Updates imports/usage to align with extracted transaction copy.
app/​src/​pages/​vaultRequests.test.ts Updates tests to align with extracted transaction copy/constants.
app/​src/​pages/​VaultPreview.test.tsx Updates tests to construct/verify contract errors using name-derived codes.
app/​src/​hooks/​useVaultPaused.test.ts Updates contract-error fixtures/types to include optional error name.
app/​src/​hooks/​useTokenSymbols.test.ts Updates contract-error fixtures/types to include optional error name.
app/​src/​hooks/​useSignPending.ts Propagates {code, name} for refused simulations into signing pending state.
app/​src/​hooks/​useSignPending.test.ts Updates refused-simulation tests to expect {code, name} and derive codes by name.
app/​src/​hooks/​useSharePosition.test.ts Updates contract-error fixtures/types to include optional error name.
app/​src/​hooks/​useRequestRedeem.test.ts Updates refusal simulation strings/assertions to use name-derived codes and {code, name}.
app/​src/​hooks/​useRequestDeposit.test.ts Updates refusal simulation strings/assertions to use name-derived codes and {code, name}.
app/​src/​hooks/​useOracleState.test.ts Updates contract-error fixtures/types to include optional error name.
app/​src/​hooks/​useNavPrice.ts Switches “NoRecord”/error handling to key off error name rather than numeric code.
app/​src/​hooks/​useNavPrice.test.ts Updates NAV tests to derive “NoRecord” (and other) codes by error name.
app/​src/​hooks/​useIsAllowed.test.ts Updates contract-error fixtures/types to include optional error name.
app/​src/​hooks/​useFund.test.ts Updates refusal simulation strings/assertions to include {code, name} and name-derived codes.
app/​src/​hooks/​useFulfillEpoch.test.ts Updates refusal simulation strings/assertions to include {code, name} and name-derived codes.
app/​src/​hooks/​useFinalizeWindDownRound.test.ts Updates refusal simulation strings/assertions to include {code, name} and name-derived codes.
app/​src/​hooks/​useDepositBalance.test.ts Updates contract-error fixtures/types to include optional error name.
app/​src/​hooks/​useDeployToCustodian.test.ts Updates refusal simulation strings/assertions to include {code, name} and name-derived codes.
app/​src/​hooks/​useCycleState.ts Switches “NoRecord”/error handling to key off error name rather than numeric code.
app/​src/​hooks/​useCycleState.test.ts Updates oracle/cycle tests to derive codes by error name and include {code, name}.
app/​src/​hooks/​useContractTransaction.ts Refactors transaction failure parsing/typing to carry {code, name} for contract errors.
app/​src/​hooks/​useContractTransaction.test.ts Updates transaction failure tests to use name-derived codes and {code, name}.
app/​src/​hooks/​useComplianceState.test.ts Updates refusal simulation strings/assertions to use name-derived codes and {code, name}.
app/​src/​hooks/​useCloseEpoch.test.ts Updates refusal simulation strings/assertions to include {code, name} and name-derived codes.
app/​src/​hooks/​useClaimWindDown.test.ts Updates refusal simulation strings/assertions to include {code, name} and name-derived codes.
app/​src/​hooks/​useClaimRedeem.test.ts Updates refusal simulation strings/assertions to include {code, name} and name-derived codes.
app/​src/​hooks/​useClaimDeposit.test.ts Updates refusal simulation strings/assertions to include {code, name} and name-derived codes.
app/​src/​hooks/​useCancelRedeem.test.ts Updates refusal simulation strings/assertions to include {code, name} and name-derived codes.
app/​src/​hooks/​useCancelDeposit.test.ts Updates refusal simulation strings/assertions to include {code, name} and name-derived codes.
app/​src/​hooks/​useAttest.test.ts Updates refusal simulation strings/assertions to include {code, name} and name-derived codes.
app/​src/​hooks/​useAdminTransaction.test.ts Updates admin refusal scenarios to carry {code, name} and use name-derived codes.
app/​src/​hooks/​useActivateWindDown.test.ts Updates refusal simulation strings/assertions to include {code, name} and name-derived codes.
app/​src/​components/​vault/​transactionCopy/​types.ts Introduces shared types/models for transaction copy, statuses, and refusal mapping.
app/​src/​components/​vault/​transactionCopy/​investorOutcomes.test.tsx Adds/updates investor outcome copy tests under the new copy structure.
app/​src/​components/​vault/​transactionCopy/​investor.ts Adds investor action copy + refusal reasons keyed by error name.
app/​src/​components/​vault/​transactionCopy/​investor.test.tsx Adds/updates investor transaction copy and refusal mapping tests.
app/​src/​components/​vault/​transactionCopy/​index.ts Adds a dispatcher/entry point to describe transactions using the new copy modules.
app/​src/​components/​vault/​transactionCopy/​governance.test.tsx Adds/updates governance transaction copy and refusal mapping tests.
app/​src/​components/​vault/​transactionCopy/​emergency.test.tsx Adds/updates emergency transaction copy and refusal mapping tests.
app/​src/​components/​vault/​transactionCopy/​describe.ts Implements shared describeStatus and contract-failure description logic.
app/​src/​components/​vault/​transactionCopy/​cycle.ts Adds cycle/operator action copy + refusal reasons keyed by error name.
app/​src/​components/​vault/​transactionCopy/​cycle.test.tsx Adds/updates cycle transaction copy and refusal mapping tests.
app/​src/​components/​vault/​transactionCopy/​configuration.test.tsx Adds/updates configuration transaction copy and refusal mapping tests.
app/​src/​components/​vault/​transactionCopy/​compliance.test.tsx Adds/updates compliance transaction copy and refusal mapping tests.
app/​src/​components/​vault/​transactionCopy/​admin.ts Adds admin action copy + refusal reasons keyed by error name.
app-lib/​readContract.ts Updates contract-read error parsing to return {code, name} and resolve names from specs.
app-lib/​readContract.test.ts Updates readContract tests to reflect {code, name} error shapes and name-based behavior.
app-lib/​multisig.ts Updates multisig refusal plumbing/types to carry {code, name}.
app-lib/​multisig.test.ts Updates multisig tests to use name-derived codes and {code, name}.
app-lib/​contracts.ts Adds helper(s) for accessing generated specs used for error-name resolution.
app-lib/​contractErrors.ts Implements runtime error code→name resolution by aggregating generated client error cases.
app-lib/​contractErrors.test.ts Adds tests covering error-case aggregation and name resolution behavior.

Review effort: Balanced

Comment thread app-lib/multisig.test.ts
Comment on lines +26 to +29
import {
contractErrorCode,
simulationError,
} from "../app/src/test/contractErrorCode"
Comment on lines +4 to +7
import {
contractErrorCode,
simulationError,
} from "../app/src/test/contractErrorCode"
Base automatically changed from chore/ci-clients-before-tests to feedback November 2, 2026 21:13
Contract errors are resolved at runtime from the error cases the
generated clients carry, so failures expose the error's name next to
its code. Tests derive codes from each client's error table by name.

Refs #415
Per-action copy moves to transactionCopy/ as data read by one
describeStatus, and contract errors match by name. The modal tests are
split by section. Fixes AdminTransferPending for the vault and oracle,
and pause errors no longer show on oracle actions.

Closes #415
@hpmaxi
hpmaxi force-pushed the feat/415-transaction-modal-copy branch from 9bc2c4d to 080b1a3 Compare November 2, 2026 21:13
@hpmaxi
hpmaxi merged commit 34dde17 into feedback Nov 2, 2026
10 checks passed

This branch was successfully deployed

1 active deployment
Preview — 080b1a3c Deployed Nov 2, 2026 by vercel[bot]
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.

3 participants