Skip to content

test(frontend): cover Soroban network mismatch, simulation timeout and malformed RPC responses - #2195

Merged
K1NGD4VID merged 2 commits into
LabsCrypt:mainfrom
Banx17:fix/issue-2143
Oct 25, 2026
Merged

K1NGD4VID merged 2 commits into
LabsCrypt:mainfrom
Banx17:fix/issue-2143

Conversation

@Banx17

@Banx17 Banx17 commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Closes #2143.

Adds frontend/src/app/utils/soroban.networkMismatch.test.ts, a regression suite for the two XDR builders in frontend/src/app/utils/soroban.ts (buildUnsignedLoanRequestXdr and buildUnsignedRepaymentXdr). Every case runs against both builders, with the RPC server stubbed so the suite stays offline and deterministic.

The contract the suite pins is fail closed: the builder must reject (so transactionErrors/mapTransactionError can keep classifying the failure) and must never return an unsigned XDR that was not simulated on the wallet's network.

Acceptance criteria coverage

Area Tests
Network mismatch the returned XDR is bound to the network the wallet will sign for: its signature base carries that network's id (derived from the SDK, not a re-implemented hash) and not the other network's; the same invocation hashes differently on TESTNET vs PUBLIC; a signature verifies only on the network the XDR was built for (public-key verification against the cross-network hash fails); an explicit networkPassphrase beats NEXT_PUBLIC_STELLAR_NETWORK_PASSPHRASE; the shared DEFAULT_NETWORK_PASSPHRASE is used when neither is given; a mismatch reported by the RPC propagates as a rejection with no XDR returned.
Simulation timeout a timed-out simulation rejects after exactly one attempt and never serializes the unprepared transaction; a still-pending simulation keeps the promise unsettled (and resolves normally once released), proving the builder genuinely awaits prepareTransaction instead of racing it.
Malformed RPC responses a malformed getAccount payload rejects before simulation; a failed account lookup rejects before simulation; a null simulation response and a non-transaction simulation payload are rejected instead of serialized; a malformed JSON-RPC error object is propagated by identity.
Authorization invocations ship with no pre-filled auth entries (3 contract args, the wallet signs), and HostError: Error(Auth, InvalidAction) raised during simulation propagates untouched.
Input validation NaN / Infinity / 1e21 amounts and unparseable contract ids are rejected before simulating; the u32 term and u64 loan-id boundaries are accepted; a fractional loan id throws SyntaxError instead of being truncated, and a negative loan id is rejected as unsigned.

Changes

  • frontend/src/app/utils/soroban.networkMismatch.test.ts — new suite, 42 assertions-level tests (21 per builder).
  • .github/workflows/ci.yml — the existing "Frontend regression tests" step now also runs this suite, so a network/simulation regression fails CI instead of only local runs.

Test plan

cd frontend
npx jest src/app/utils/soroban.networkMismatch.test.ts --runInBand   # 42 passed
npx jest src/app/hooks/useLoanStream.test.tsx \
         src/app/components/providers/SessionExpiryHandler.test.tsx \
         src/app/utils/soroban.networkMismatch.test.ts --runInBand   # 55 passed (CI step)
npx eslint src/app/utils/soroban.networkMismatch.test.ts             # clean
npx prettier --check src/app/utils/soroban.networkMismatch.test.ts   # clean

Notes

  • No production code changed; the suite is additive and asserts the behaviour soroban.ts already has, so it fails if the builders regress (dropped networkPassphrase, serializing before/without simulation, swallowing RPC errors).
  • Pre-existing and unrelated to this PR: frontend/src/app/components/providers/WalletProvider.tsx:249 references NETWORK_PASSPHRASES without importing it, so soroban.networkSigner.test.tsx fails with ReferenceError: NETWORK_PASSPHRASES is not defined on main. Left untouched to keep this PR scoped; happy to fix it separately if you want.

Comment thread frontend/src/app/utils/soroban.networkMismatch.test.ts Fixed
Adds regression coverage for LabsCrypt#2143 around the XDR builders in
`frontend/src/app/utils/soroban.ts`. The suite pins the fail-closed
contract of both `buildUnsignedLoanRequestXdr` and
`buildUnsignedRepaymentXdr`:

- the returned XDR is bound to the passphrase it was built with: the
  signature base carries sha256(passphrase), the same invocation hashes
  differently on TESTNET and PUBLIC, and a signature only verifies on the
  network it was produced for;
- an explicit `networkPassphrase` wins over the ambient
  NEXT_PUBLIC_STELLAR_NETWORK_PASSPHRASE, and the shared default is used
  when neither is supplied;
- a network mismatch reported by the RPC propagates as a rejection and no
  unsigned XDR is returned;
- a simulation timeout (or a simulation that is still pending) rejects
  after exactly one attempt instead of falling back to the unprepared
  transaction;
- malformed account and simulation responses (null, non-transaction,
  failed lookup, JSON-RPC error payloads) are rejected untouched;
- invocations carry no pre-filled auth entries, simulation-time
  authorization failures propagate, and invalid amounts / contract ids /
  loan ids are rejected before simulating.

CI now runs this suite alongside the existing loan-stream and
session-expiry regression suites.
@K1NGD4VID
K1NGD4VID merged commit 2b4db32 into LabsCrypt:main Oct 25, 2026
17 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.

[test] Cover frontend Soroban network mismatch

3 participants