Skip to content

feat: add Stellar, mobile, and UI Kit bounty fixes#708

Open
gshaowei6 wants to merge 11 commits into
ancore-org:mainfrom
gshaowei6:feat/stellar-mobile-ui-bounties
Open

feat: add Stellar, mobile, and UI Kit bounty fixes#708
gshaowei6 wants to merge 11 commits into
ancore-org:mainfrom
gshaowei6:feat/stellar-mobile-ui-bounties

Conversation

@gshaowei6
Copy link
Copy Markdown

@gshaowei6 gshaowei6 commented May 29, 2026

Description

Adds the requested Stellar, mobile wallet, and UI Kit improvements in one pass:

This also fixes build/test stability issues that blocked local verification: UI Kit declaration exports, mobile Jest matcher usage, local-time snapshot stability, an unused mobile history retry stub, an extension schedule test whose fixed future-date assumption had expired, dashboard test setup parity, relayer request logging types, and deterministic fiat locale fallback.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual/local verification performed

Commands run locally on Windows:

  • pnpm --filter @ancore/types build
  • pnpm --filter @ancore/types lint
  • pnpm --filter @ancore/stellar build
  • pnpm --filter @ancore/stellar lint
  • pnpm --filter @ancore/stellar test
  • pnpm --filter @ancore/mobile-wallet build
  • pnpm --filter @ancore/mobile-wallet lint
  • pnpm --filter @ancore/mobile-wallet test
  • pnpm --filter @ancore/ui-kit build
  • pnpm --filter @ancore/ui-kit lint
  • pnpm --filter @ancore/ui-kit test
  • pnpm --filter @ancore/extension-wallet build
  • pnpm --filter @ancore/extension-wallet test
  • pnpm --filter @ancore/extension-wallet lint exits 0 with existing warnings in unrelated files.
  • pnpm --filter @ancore/relayer build
  • pnpm --filter @ancore/relayer lint exits 0 with the existing server.ts warning.
  • pnpm --filter @ancore/relayer test
  • pnpm --filter @ancore/web-dashboard build
  • pnpm --filter @ancore/web-dashboard lint exits 0 with existing warnings in unrelated files.
  • pnpm --filter @ancore/web-dashboard test
  • pnpm --filter @ancore/core-sdk build
  • pnpm --filter @ancore/core-sdk lint exits 0 with existing warnings in unrelated files.
  • pnpm --filter @ancore/core-sdk test
  • pnpm format:check
  • Repository pre-push hook completed build, test, lint, and format checks successfully.

Follow-up review validation:

  • pnpm --filter @ancore/stellar test -- --runInBand packages/stellar/src/__tests__/client.test.ts
  • pnpm --filter @ancore/stellar build
  • pnpm --filter @ancore/stellar lint
  • pnpm --filter @ancore/mobile-wallet test -- TransactionHistoryList
  • pnpm --filter @ancore/mobile-wallet build
  • pnpm --filter @ancore/mobile-wallet lint
  • pnpm --filter @ancore/ui-kit build
  • pnpm --filter @ancore/ui-kit test
  • pnpm --filter @ancore/ui-kit lint
  • pnpm --filter @ancore/relayer build
  • pnpm --filter @ancore/relayer lint
  • pnpm --filter @ancore/relayer test
  • pnpm format:check

Security Considerations

No secrets, signing material, storage encryption, or contract logic are changed. The Stellar changes improve Horizon error classification and transaction submission error reporting. The mobile URI parser validates inputs and does not submit transactions.

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Comments added for complex logic
  • Documentation updated where relevant through Storybook coverage
  • Tests pass locally
  • No new warnings introduced in the touched package test suites

Summary by CodeRabbit

  • New Features

    • Added payment URI parser for Stellar payment schemes
    • Added Field form component with improved accessibility and customizable label support
    • Added warning toast notifications variant
    • Added support for Futurenet network alongside existing networks
    • Added rate-limiting for failed unlock attempts with retry feedback
  • Bug Fixes

    • Improved locale handling in fiat amount formatting with fallback support
    • Enhanced transaction error handling with detailed operation result information
  • Improvements

    • Enhanced accessibility compliance across components
    • Improved timestamp formatting consistency in transaction history
    • Refined logging and error redaction for sensitive data
    • Better transaction retry logic and error classification

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 29, 2026

Review Change Stack

Caution

Review failed

Failed to post review comments

📝 Walkthrough

Walkthrough

This PR integrates multiple feature enhancements across the monorepo: a new Field form-wrapper component with accessibility testing infrastructure; improved Stellar SDK error handling for RPC failures and transaction XDR submission; mobile wallet payment URI parsing and futurenet network support; UI-kit polish with toast variants and component accessibility tests; and relayer infrastructure improvements including typed request logging, unified redaction markers, and futurenet network recognition. Supporting changes include web dashboard hook improvements, extension wallet configuration adjustments, contract documentation updates, and build script refinements.

Changes

Form Component Infrastructure and Accessibility

Layer / File(s) Summary
Field Component Foundation with A11y Testing and Storybook
packages/ui-kit/src/components/Form/Field.tsx, packages/ui-kit/src/components/Form/Field.stories.tsx, packages/ui-kit/src/__tests__/Form/Field.test.tsx, packages/ui-kit/src/__tests__/test-utils/a11y.ts, packages/ui-kit/package.json, packages/ui-kit/src/components/Form/index.ts, packages/ui-kit/src/index.ts
New Field component supports render-prop or cloned-element usage patterns with generated input IDs, merged aria-describedby attributes, and alert role for error text. Includes axe-core test utilities (runA11yCheck, expectNoA11yViolations) with configurable rule merging and violation mapping.
Extension Wallet TransferNoteInput Field Integration
apps/extension-wallet/src/components/TransferNoteInput.tsx
TransferNoteInput refactored to use Field component for label/error/ARIA presentation, adding optional label prop while preserving textarea character counters, near-limit warnings, and blur-time truncation.

Stellar SDK Error Handling and Transaction Submission

Layer / File(s) Summary
Stellar Client RPC Error Handling and Retryability
packages/stellar/src/client.ts
Generalized getErrorStatusCode to extract status from multiple error shapes (NetworkError, direct statusCode/status, nested response.status). Enhanced isRetryableRpcError treats 429 and 5xx as retryable with defensive defaults.
Stellar Account Loading and Transaction Submission with XDR Support
packages/stellar/src/client.ts
Account retrieval detects 404 status for not-found errors. submitTransaction accepts Transaction or signed XDR strings, decoding via TransactionBuilder.fromXDR with client network passphrase. TransactionError treated as non-retryable while other failures retry per status classification.
Stellar TransactionError Structure and Horizon Error Parsing
packages/stellar/src/errors.ts
TransactionError expanded with operationResultCodes and statusCode public fields. New TransactionErrorOptions interface and fromHorizonError factory parse Horizon error payloads extracting transaction/operation result codes and result XDR.
Stellar Client Test Coverage for XDR Decoding and Error Handling
packages/stellar/src/__tests__/client.test.ts
Test suite mocks TransactionBuilder.fromXDR for decode verification, uses stricter never-typed invalid-network tests, verifies retry-exhaustion context preservation, and asserts comprehensive TransactionError field preservation including operation result codes and status code.

Mobile Wallet Deep Linking and Network Configuration

Layer / File(s) Summary
Mobile Wallet Payment URI Parser and Linking Module
apps/mobile-wallet/src/linking/paymentUri.ts, apps/mobile-wallet/src/linking/index.ts, apps/mobile-wallet/src/linking/__tests__/paymentUri.test.ts, apps/mobile-wallet/src/index.ts
Introduces parsePaymentUri supporting stellar: and web+stellar: schemes with strict 55-char Stellar public key validation for destination and optional numeric amount checks. Returns ParsedPaymentUri or null with comprehensive test coverage.
Mobile Wallet Environment Configuration for Futurenet Network
apps/mobile-wallet/src/config/environment.ts, apps/mobile-wallet/src/config/__tests__/environment.test.ts
Added futurenet RPC URL and network passphrase defaults. Extended environment helpers to recognize futurenet, updated error messages to list futurenet as supported network option.
Mobile Wallet Transaction History Formatting and Timestamps
apps/mobile-wallet/src/components/TransactionHistoryList.tsx, apps/mobile-wallet/src/screens/history/__tests__/TransactionHistoryList.test.tsx
TransactionHistoryList accepts optional formatTimestamp prop with default toLocaleString('en-US'). UI labels changed from ellipsis to three-dot ellipsis. Snapshot tests use deterministic formatSnapshotTimestamp helper.
Mobile Wallet Biometric Unlock and Pagination Hooks
apps/mobile-wallet/src/security/hooks/useBiometricUnlock.ts, apps/mobile-wallet/src/screens/history/usePaginatedTransactionHistory.ts
BiometricUnlock dependency arrays fixed to include startCountdown and stopCountdown. Pagination hook captures backoffTimeoutRef before cleanup to avoid stale reference access.

UI-Kit and Component Refinements

Layer / File(s) Summary
UI-Kit Toast Variants and Transaction Item Component
packages/ui-kit/src/components/Toast/NotificationProvider.tsx, packages/ui-kit/src/components/TransactionItem.tsx, packages/ui-kit/src/components/address-display.tsx
ToastVariant expanded to include 'warning' and ToastItem type alias added. TransactionItem address separator changed from arrow to HTML entity. AddressDisplay parameter destructuring reformatted to multi-line pattern.
UI-Kit Button and Input Accessibility Tests
packages/ui-kit/src/components/ui/button.test.tsx, packages/ui-kit/src/components/ui/input.test.tsx
Component tests extended with axe accessibility checks via expectNoA11yViolations, verifying components render without accessibility violations.

Extension Wallet and Web Dashboard Infrastructure

Layer / File(s) Summary
Extension Wallet Configuration and Schedule Test Fixes
apps/extension-wallet/src/config/urls.ts, apps/extension-wallet/src/config/__tests__/urls.test.ts, apps/extension-wallet/src/hooks/__tests__/useSendTransaction.schedule.test.ts
RELAYER_URLS.production formatting adjusted. Schedule test updated to compute timezone-aware startAt using timezone offset correction and ISO string slicing.
Extension Wallet Unlock Rate Limiting Test Formatting
apps/extension-wallet/src/background/__tests__/service-worker.test.ts
Rate-limiting test "resets failure counter after successful unlock" scenario reformatted with adjusted await placement while preserving assertions and retry-after-clear expectations.
Web Dashboard Account State and Split Bill Hooks
apps/web-dashboard/src/hooks/useAccountState.ts, apps/web-dashboard/src/hooks/useSplitBill.ts
useAccountState adds mountedRef to prevent state updates after unmount during async flow. useSplitBill signature reformatted with getBill callback simplified.
Web Dashboard Page Layout and Format Tests
apps/web-dashboard/src/pages/SplitBill.tsx, apps/web-dashboard/src/components/__tests__/formatDate.test.ts
BILL_STATUS_CONFIG reformatted to multi-line structure. formatRelative test uses deterministic Intl.RelativeTimeFormat comparison instead of regex-based relative-word check.
Web Dashboard Services and Test Setup
apps/web-dashboard/src/services/bulk-payouts.ts, apps/web-dashboard/src/services/__tests__/bulk-payouts.test.ts, apps/web-dashboard/src/test/setup.ts
bulk-payouts formatting adjusted. setup.ts re-exports shared Vitest configuration instead of direct jest-dom import.

Relayer Service Infrastructure and Stellar Network Support

Layer / File(s) Summary
Relayer Logging Infrastructure and Request Middleware
services/relayer/src/middleware/requestLogger.ts, services/relayer/src/handlers/executeRelay.ts, services/relayer/src/handlers/validateRelay.ts
Request middleware refactored from global Express interface augmentation to explicit LoggedRequest type with typed casting. Module-level noopLogger added for fallback when request logger unavailable.
Relayer Logging Redaction and Markers
services/relayer/src/logging/logger.ts, services/relayer/src/logging/__tests__/logger.test.ts, services/relayer/src/logging/index.ts
Logging redaction truncation marker standardized to Unicode escape \u2026 via shared TRUNCATION_MARKER constant. Redaction helpers refactored to use constant. Logger re-exported as alias in index.
Relayer Stellar Network Configuration with Futurenet Support
services/relayer/src/services/stellarSubmitter.ts, services/relayer/tests/unit/stellarSubmitter.test.ts
NETWORK_PASSPHRASES extended to include futurenet. resolveStellarNetwork recognizes futurenet as valid input. Tests verify futurenet network and passphrase handling with testnet fallback for unknown values.
Relayer OpenAPI Contract Tests Formatting
services/relayer/tests/contract/openapi-contract.test.ts
Supertest request construction reformatted from multi-line chains to single-line style for authorization assertions.

Supporting Documentation and Utility Updates

Layer / File(s) Summary
AI Agent Server Tests and Health Endpoint
services/ai-agent/src/server.test.ts
Test coverage reworked to add POST /v1/intents/validate integration tests. Health endpoint assertions expanded to validate service, version, numeric uptime, and parseable timestamp.
Core SDK Fiat Amount Formatting with Locale Resolution
packages/core-sdk/src/fiat-formatter.ts
formatFiatAmount normalizes locale via Intl.NumberFormat.supportedLocalesOf with fallback to 'en-US'. resolveSupportedLocale helper added with defensive error handling.
Account Abstraction Permissions and Session Key Refactoring
packages/account-abstraction/src/permissions.ts, packages/account-abstraction/src/add-session-key.ts, packages/account-abstraction/src/__tests__/permissions.test.ts
Permission encoding/decoding filter predicates condensed to single-line format. Session key resolution signature and invocation formatting adjusted without semantic changes.
Contract Documentation and README Formatting
contracts/account/README.md, contracts/validation-modules/README.md
Session permissions and complexity tables reformatted for improved markdown alignment without changing field meanings or operation values.
Build and Generation Scripts Updates
scripts/check-wasm-size.js, scripts/generate-openapi-types.ts
WASM size budget check uses plain ? status markers instead of emoji. OpenAPI types generator documentation and catch handler syntax adjusted.
PR Description and README Project Documentation
PR_DESCRIPTION.md, README.md
PR_DESCRIPTION documents four scoped changes. README WASM budget section whitespace cleaned.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • ancore-org/ancore#707: Changes to packages/stellar/src/client.ts and error handling for Horizon 429 responses align with retrieved PR's Horizon rate-limit retry work.
  • ancore-org/ancore#695: Main PR's modifications to apps/web-dashboard/src/hooks/useSplitBill.ts and apps/web-dashboard/src/pages/SplitBill.tsx directly touch the split-bill hook/page introduced in the retrieved PR.
  • ancore-org/ancore#728: Both PRs extend services/relayer/src/services/stellarSubmitter.ts to add futurenet network recognition and passphrase mapping.

Suggested reviewers

  • wheval

🐰 A Rabbit's Ode to the Changes

Form fields now dance with aria, so fine,
Stellar XDR strings in queues align,
Mobile URIs parse, futurenet gleams bright,
Toast warnings whisper, a11y's just right,
Relayers log true with markers so neat,
An infrastructure refresh—complete! 🎉

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch feat/stellar-mobile-ui-bounties

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (4)
packages/stellar/src/__tests__/client.test.ts (1)

460-474: LGTM!

Consider adding a case where TransactionBuilder.fromXDR throws (malformed XDR) to lock in the corrected behavior from the client-side decode fix.

Want me to draft that test once the decode-hoisting change lands?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/stellar/src/__tests__/client.test.ts` around lines 460 - 474, Add a
new test case to StellarClient's submitTransaction spec that simulates
TransactionBuilder.fromXDR throwing for malformed XDR and asserts that
client.submitTransaction rejects with that error; specifically, reuse the
existing test setup (StellarClient instantiation, getHorizonMock(client)) but
make mockTransactionFromXDR.mockImplementationOnce(() => { throw new
Error('malformed XDR') }) and then await
expect(client.submitTransaction('bad-xdr' as unknown as
Transaction)).rejects.toThrow('malformed XDR'), and also assert that
horizon.submitTransaction is not called—this verifies the client correctly
surfaces decode errors before attempting submission.
apps/mobile-wallet/src/screens/history/usePaginatedTransactionHistory.ts (1)

22-22: 💤 Low value

Vestigial retryCount state after backoff removal.

With retry/backoff logic gone, retryCount is always 0 (initialized at line 55, reset to 0 on error) and never incremented. It's still spread into the returned object via ...state, so consumers may read a perpetually-zero field. Consider dropping it from State and the error handler to avoid confusion.

Also applies to: 114-114

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/mobile-wallet/src/screens/history/usePaginatedTransactionHistory.ts` at
line 22, Remove the vestigial retryCount property and all references to it in
usePaginatedTransactionHistory: delete retryCount from the State type, from the
initial state object, and from any error handler resets that set retryCount = 0;
also remove it from any places that read or spread state (e.g., the returned
"...state" payload) so consumers no longer see a perpetually-zero field and
state shape stays consistent.
apps/mobile-wallet/src/linking/__tests__/paymentUri.test.ts (1)

19-24: 💤 Low value

Consider asserting the amount=1 case explicitly. The combined test labels this an "invalid amount" check, but stellar:pay?amount=1 returns null because the destination is missing, not because of the amount. A dedicated vector with a valid destination plus an invalid amount (e.g. amount=1.123456789 or amount=-1) would better cover the isValidAmount branch.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/mobile-wallet/src/linking/__tests__/paymentUri.test.ts` around lines 19
- 24, The test currently conflates a missing-destination case with
invalid-amount behavior; update the test for parsePaymentUri to (1) keep an
explicit assertion that 'stellar:pay?amount=1' returns null due to missing
destination, and (2) add a separate assertion that a URI with a valid
destination and an invalid amount (e.g.
`stellar:pay?destination=${DESTINATION}&amount=1.123456789` or `amount=-1`)
returns null so the isValidAmount branch is exercised; locate and modify the
test in paymentUri.test.ts where parsePaymentUri is used to add the distinct
invalid-amount vector.
apps/extension-wallet/src/hooks/__tests__/useSendTransaction.schedule.test.ts (1)

16-18: ⚡ Quick win

Consider adding a comment explaining the timezone offset logic.

The offset adjustment correctly compensates for toISOString()'s UTC conversion to produce a local-time string for the datetime-local input. However, the logic is not immediately obvious.

📝 Optional clarifying comment
+    // Adjust for timezone to get local time string from toISOString()
+    // datetime-local expects YYYY-MM-DDTHH:mm in local time without TZ suffix
     const future = new Date(Date.now() + 2 * 60 * 60 * 1000);
     const offsetMs = future.getTimezoneOffset() * 60 * 1000;
     const startAt = new Date(future.getTime() - offsetMs).toISOString().slice(0, 16);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/extension-wallet/src/hooks/__tests__/useSendTransaction.schedule.test.ts`
around lines 16 - 18, Add a clarifying inline comment above the timezone
adjustment in the test that explains why we compute offsetMs and subtract it
from future before calling toISOString() — e.g., state that toISOString()
returns UTC and this subtraction converts the Date to the local timezone so
slicing to 16 chars yields a value suitable for a datetime-local input; place
the comment near the variables future, offsetMs and startAt to make intent
obvious to future readers.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/mobile-wallet/src/components/TransactionHistoryList.tsx`:
- Line 37: The UI strings and separator in TransactionHistoryList are rendering
a literal '?' instead of the intended ellipsis or middle-dot; update the JSX in
the TransactionHistoryList component so all loading labels use an ellipsis
character (…) (e.g., "Loading transactions…" / "Refreshing…" / "Loading more…")
and replace the asset↔timestamp separator '?' with a middle-dot (·) in the
transaction row rendering code (the JSX that composes amount/asset and
timestamp). Ensure you change the occurrences referenced (the return that
renders "Loading transactions?", plus the similar strings and the separator used
when mapping transaction rows).

In `@apps/mobile-wallet/src/linking/paymentUri.ts`:
- Line 7: The DESTINATION_RE currently allows invalid base32 characters because
it uses [A-Z0-9]; update the regex used by DESTINATION_RE to restrict the
character class to RFC4648 base32 characters (A-Z2-7) and keep the length
requirement (55 chars) and leading 'G' the same so only valid Stellar public
keys match; modify the constant DESTINATION_RE accordingly.

In `@apps/mobile-wallet/src/navigation/__tests__/onboarding.test.tsx`:
- Line 1: Replace the Jest-oriented import in the test setup so Vitest registers
DOM matchers: in the onboarding.test.tsx file, change the top-level import of
"`@testing-library/jest-dom`" to the Vitest entrypoint
"`@testing-library/jest-dom/vitest`" so the Vitest runner picks up and registers
the jest-dom matchers for tests like those in this file.

In `@packages/stellar/src/client.ts`:
- Around line 447-487: Hoist XDR decoding out of the withRetry callback by
calling resolveSignedTransaction(transaction) before entering withRetry to
ensure decoding errors are not retried, and provide a custom isRetryable
predicate on retryOptions (or pass augmented options into withRetry) that
returns false for TransactionError instances representing permanent failure
codes and for decoding/validation errors (so TransactionError and XDR-decoding
errors are not retried); update submitTransaction to use the decoded Transaction
and augmented retryOptions when calling withRetry, keeping existing handling of
RetryExhaustedError / error.lastError logic intact.

In `@packages/ui-kit/src/components/Form/Field.tsx`:
- Around line 39-43: The controlProps object in Field.tsx currently sets id,
aria-describedby and aria-invalid but omits the required state for assistive
tech; update controlProps (the variable defined with id: inputId,
'aria-describedby': describedBy, 'aria-invalid': ...) to also include
'aria-required': required ? true : childProps?.['aria-required'] and when the
incoming childProps represent a native control, forward the boolean required
prop as well (merge required into childProps for native inputs) so screen
readers receive both aria-required and the native required attribute.

In `@packages/ui-kit/src/components/TransactionItem.tsx`:
- Line 70: In TransactionItem, the address display uses a stray "?" between
addresses; update the JSX that renders formatAddress(transaction.from) ?
formatAddress(transaction.to) to use a proper separator (e.g., a hyphen, arrow,
or "→") or conditional logic to only show a separator when both transaction.from
and transaction.to exist—modify the expression in the component rendering (where
formatAddress is called) to concatenate or render the chosen separator instead
of the literal "?" so the row shows a clear from → to format.

---

Nitpick comments:
In
`@apps/extension-wallet/src/hooks/__tests__/useSendTransaction.schedule.test.ts`:
- Around line 16-18: Add a clarifying inline comment above the timezone
adjustment in the test that explains why we compute offsetMs and subtract it
from future before calling toISOString() — e.g., state that toISOString()
returns UTC and this subtraction converts the Date to the local timezone so
slicing to 16 chars yields a value suitable for a datetime-local input; place
the comment near the variables future, offsetMs and startAt to make intent
obvious to future readers.

In `@apps/mobile-wallet/src/linking/__tests__/paymentUri.test.ts`:
- Around line 19-24: The test currently conflates a missing-destination case
with invalid-amount behavior; update the test for parsePaymentUri to (1) keep an
explicit assertion that 'stellar:pay?amount=1' returns null due to missing
destination, and (2) add a separate assertion that a URI with a valid
destination and an invalid amount (e.g.
`stellar:pay?destination=${DESTINATION}&amount=1.123456789` or `amount=-1`)
returns null so the isValidAmount branch is exercised; locate and modify the
test in paymentUri.test.ts where parsePaymentUri is used to add the distinct
invalid-amount vector.

In `@apps/mobile-wallet/src/screens/history/usePaginatedTransactionHistory.ts`:
- Line 22: Remove the vestigial retryCount property and all references to it in
usePaginatedTransactionHistory: delete retryCount from the State type, from the
initial state object, and from any error handler resets that set retryCount = 0;
also remove it from any places that read or spread state (e.g., the returned
"...state" payload) so consumers no longer see a perpetually-zero field and
state shape stays consistent.

In `@packages/stellar/src/__tests__/client.test.ts`:
- Around line 460-474: Add a new test case to StellarClient's submitTransaction
spec that simulates TransactionBuilder.fromXDR throwing for malformed XDR and
asserts that client.submitTransaction rejects with that error; specifically,
reuse the existing test setup (StellarClient instantiation,
getHorizonMock(client)) but make
mockTransactionFromXDR.mockImplementationOnce(() => { throw new Error('malformed
XDR') }) and then await expect(client.submitTransaction('bad-xdr' as unknown as
Transaction)).rejects.toThrow('malformed XDR'), and also assert that
horizon.submitTransaction is not called—this verifies the client correctly
surfaces decode errors before attempting submission.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cdf9d5fc-bd50-4b62-9e0a-e861c273b2f7

📥 Commits

Reviewing files that changed from the base of the PR and between 97de62a and c32897b.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (30)
  • apps/extension-wallet/src/components/TransferNoteInput.tsx
  • apps/extension-wallet/src/hooks/__tests__/useSendTransaction.schedule.test.ts
  • apps/mobile-wallet/src/components/TransactionHistoryList.tsx
  • apps/mobile-wallet/src/index.ts
  • apps/mobile-wallet/src/linking/__tests__/paymentUri.test.ts
  • apps/mobile-wallet/src/linking/index.ts
  • apps/mobile-wallet/src/linking/paymentUri.ts
  • apps/mobile-wallet/src/navigation/__tests__/onboarding.test.tsx
  • apps/mobile-wallet/src/screens/history/__tests__/TransactionHistoryList.test.tsx
  • apps/mobile-wallet/src/screens/history/usePaginatedTransactionHistory.ts
  • apps/mobile-wallet/src/security/hooks/useBiometricUnlock.ts
  • packages/stellar/src/__tests__/client.test.ts
  • packages/stellar/src/client.ts
  • packages/stellar/src/errors.ts
  • packages/stellar/src/fee-stats.ts
  • packages/types/src/index.ts
  • packages/ui-kit/package.json
  • packages/ui-kit/src/__tests__/Form/Field.test.tsx
  • packages/ui-kit/src/__tests__/test-utils/a11y.ts
  • packages/ui-kit/src/components/Form/Field.stories.tsx
  • packages/ui-kit/src/components/Form/Field.tsx
  • packages/ui-kit/src/components/Form/index.ts
  • packages/ui-kit/src/components/Toast/NotificationProvider.tsx
  • packages/ui-kit/src/components/Toast/Toast.tsx
  • packages/ui-kit/src/components/Toast/ToastContainer.tsx
  • packages/ui-kit/src/components/TransactionItem.tsx
  • packages/ui-kit/src/components/ui/button.test.tsx
  • packages/ui-kit/src/components/ui/input.test.tsx
  • packages/ui-kit/src/index.ts
  • packages/ui-kit/tsconfig.json

Comment thread apps/mobile-wallet/src/components/TransactionHistoryList.tsx Outdated
Comment thread apps/mobile-wallet/src/linking/paymentUri.ts Outdated
Comment thread apps/mobile-wallet/src/navigation/__tests__/onboarding.test.tsx Outdated
Comment thread packages/stellar/src/client.ts Outdated
Comment thread packages/ui-kit/src/components/Form/Field.tsx Outdated
Comment thread packages/ui-kit/src/components/TransactionItem.tsx Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/stellar/src/client.ts (1)

484-491: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve RetryExhaustedError for exhausted 429s here too.

This catch unwraps every NetworkError, so a rate-limited submitTransaction() loses the retry-exhaustion signal that getAccount() now preserves for statusCode === 429. That makes a retried-and-exhausted 429 indistinguishable from a single network failure.

🐛 Proposed fix
     if (error instanceof RetryExhaustedError && error.lastError) {
       if (
         error.lastError instanceof TransactionError ||
-        error.lastError instanceof NetworkError
+        (error.lastError instanceof NetworkError && error.lastError.statusCode !== 429)
       ) {
         throw error.lastError;
       }
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/stellar/src/client.ts` around lines 484 - 491, The catch currently
unwraps all NetworkError instances from a RetryExhaustedError and throws them,
which loses the retry-exhausted signal for rate-limited 429s; change the logic
in the catch block (around RetryExhaustedError, lastError, NetworkError,
TransactionError in submitTransaction) to only throw error.lastError when it is
a TransactionError or a NetworkError whose statusCode is NOT 429, and otherwise
rethrow the original RetryExhaustedError so exhausted 429s are preserved
(consistent with getAccount).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core-sdk/src/fiat-formatter.ts`:
- Around line 12-15: The doc comment for the locale fallback is incorrect:
resolveSupportedLocale() currently returns 'en-US' immediately when resolution
fails, so update the comment on fiat-formatter.ts (the JSDoc around the
locale/default lines and any related comments at lines ~56-58) to state that the
function falls back directly to 'en-US', or alternatively restore the intended
behavior by modifying resolveSupportedLocale() to attempt a
system/default-locale fallback before returning 'en-US'; reference the
resolveSupportedLocale() function and the JSDoc block for the locale/default to
locate where to change either the documentation or the fallback logic.

In `@packages/stellar/src/client.ts`:
- Around line 447-450: The call to resolveSignedTransaction in submitTransaction
currently runs before the method's try/catch so XDR decode errors escape as raw
SDK exceptions; move the resolveSignedTransaction(transaction) call inside
submitTransaction's try block (the same try that catches network/submit errors)
and, on any error from resolveSignedTransaction, wrap/throw a NetworkError (or
the same public error type used elsewhere in submitTransaction) that includes
the original error details so malformed XDR is normalized by submitTransaction's
documented error path.

In `@services/relayer/src/logging/__tests__/logger.test.ts`:
- Around line 36-38: The test description for the case using redactAccountId is
inaccurate: it mentions "ellipsis" but the assertion expects a question mark;
update the it(...) description to reflect the actual behavior (e.g., "truncates
to first 8 chars + question mark for longer values" or "replaces truncated chars
with '?' for longer values") so the test description matches the assertion
referencing redactAccountId.
- Around line 55-58: The test description for the unit that calls
redactSessionKey is inaccurate: it says "ellipsis" while the assertion expects a
question mark; update the it(...) description to reflect the actual expectation
(e.g., "truncates to first 8 chars + question mark for longer values") so the
test text matches the assertion using redactSessionKey.
- Around line 187-198: The tests expect redaction to append a '?' but the logger
implementation (redactAccountId and redactSessionKey in
services/relayer/src/logging/logger.ts) appends an ellipsis '…'; update either
the tests or the redaction functions so they match: modify redactAccountId and
redactSessionKey to append '?' after truncating to the first 8 characters (so
entries like 'GBXXX123?' and 'abcdef12?'), or alternatively change the
expectations in services/relayer/src/logging/__tests__/logger.test.ts to assert
the ellipsis version; ensure the chosen change is applied consistently for both
accountId and sessionKey references used by createRequestLogger and the tests.

---

Outside diff comments:
In `@packages/stellar/src/client.ts`:
- Around line 484-491: The catch currently unwraps all NetworkError instances
from a RetryExhaustedError and throws them, which loses the retry-exhausted
signal for rate-limited 429s; change the logic in the catch block (around
RetryExhaustedError, lastError, NetworkError, TransactionError in
submitTransaction) to only throw error.lastError when it is a TransactionError
or a NetworkError whose statusCode is NOT 429, and otherwise rethrow the
original RetryExhaustedError so exhausted 429s are preserved (consistent with
getAccount).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c8d028d4-147e-4b5e-afbe-a2e4295c20a8

📥 Commits

Reviewing files that changed from the base of the PR and between c32897b and 167f547.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (32)
  • README.md
  • apps/extension-wallet/src/config/__tests__/urls.test.ts
  • apps/extension-wallet/src/config/urls.ts
  • apps/extension-wallet/src/hooks/__tests__/useSendTransaction.schedule.test.ts
  • apps/mobile-wallet/src/linking/__tests__/paymentUri.test.ts
  • apps/mobile-wallet/src/linking/index.ts
  • apps/mobile-wallet/src/linking/paymentUri.ts
  • apps/mobile-wallet/src/screens/history/usePaginatedTransactionHistory.ts
  • apps/web-dashboard/src/hooks/useAccountState.ts
  • apps/web-dashboard/src/hooks/useSplitBill.ts
  • apps/web-dashboard/src/pages/SplitBill.tsx
  • apps/web-dashboard/src/services/__tests__/bulk-payouts.test.ts
  • apps/web-dashboard/src/services/bulk-payouts.ts
  • apps/web-dashboard/src/services/scheduler-client.ts
  • apps/web-dashboard/src/test/setup.ts
  • contracts/validation-modules/README.md
  • packages/account-abstraction/src/transaction-builder.ts
  • packages/core-sdk/src/fiat-formatter.ts
  • packages/stellar/src/__tests__/client.test.ts
  • packages/stellar/src/client.ts
  • packages/ui-kit/package.json
  • packages/ui-kit/src/__tests__/Form/Field.test.tsx
  • packages/ui-kit/src/__tests__/test-utils/a11y.ts
  • packages/ui-kit/src/components/Form/Field.stories.tsx
  • packages/ui-kit/src/components/Form/Field.tsx
  • scripts/check-wasm-size.js
  • services/relayer/src/handlers/executeRelay.ts
  • services/relayer/src/handlers/validateRelay.ts
  • services/relayer/src/logging/__tests__/logger.test.ts
  • services/relayer/src/logging/index.ts
  • services/relayer/src/middleware/__tests__/requestLogger.test.ts
  • services/relayer/src/middleware/requestLogger.ts
💤 Files with no reviewable changes (1)
  • apps/mobile-wallet/src/screens/history/usePaginatedTransactionHistory.ts
✅ Files skipped from review due to trivial changes (6)
  • apps/web-dashboard/src/services/tests/bulk-payouts.test.ts
  • packages/account-abstraction/src/transaction-builder.ts
  • apps/web-dashboard/src/services/bulk-payouts.ts
  • apps/extension-wallet/src/config/tests/urls.test.ts
  • apps/web-dashboard/src/pages/SplitBill.tsx
  • apps/extension-wallet/src/config/urls.ts
🚧 Files skipped from review as they are similar to previous changes (9)
  • packages/ui-kit/src/components/Form/Field.stories.tsx
  • apps/mobile-wallet/src/linking/tests/paymentUri.test.ts
  • apps/mobile-wallet/src/linking/index.ts
  • packages/ui-kit/src/tests/Form/Field.test.tsx
  • packages/ui-kit/src/tests/test-utils/a11y.ts
  • apps/extension-wallet/src/hooks/tests/useSendTransaction.schedule.test.ts
  • packages/ui-kit/src/components/Form/Field.tsx
  • apps/mobile-wallet/src/linking/paymentUri.ts
  • packages/stellar/src/tests/client.test.ts

Comment thread packages/core-sdk/src/fiat-formatter.ts Outdated
Comment thread packages/stellar/src/client.ts Outdated
Comment thread services/relayer/src/logging/__tests__/logger.test.ts Outdated
Comment thread services/relayer/src/logging/__tests__/logger.test.ts Outdated
Comment thread services/relayer/src/logging/__tests__/logger.test.ts Outdated
@gshaowei6
Copy link
Copy Markdown
Author

Updated after review. CodeRabbit's actionable threads are addressed and resolved; the remaining jest-dom/vitest suggestion was kept as-is because apps/mobile-wallet uses Jest via jest.config.cjs, and the /vitest entry fails under that runner. I also refreshed the PR description with the current verification list. Follow-up checks run locally include stellar client tests/build/lint, mobile-wallet TransactionHistoryList test/build/lint, ui-kit build/test/lint, relayer build/test/lint, and pnpm format:check.

Copy link
Copy Markdown
Contributor

@wheval wheval left a comment

Choose a reason for hiding this comment

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

Great job so far, can you fix conflicts and tag me once its fixed @gshaowei6

…i-bounties

# Conflicts:
#	apps/mobile-wallet/src/screens/history/usePaginatedTransactionHistory.ts
#	packages/stellar/src/client.ts
#	packages/stellar/src/fee-stats.ts
#	packages/ui-kit/tsconfig.json
#	pnpm-lock.yaml
@gshaowei6 gshaowei6 force-pushed the feat/stellar-mobile-ui-bounties branch from 22e87ce to 6d8b796 Compare May 31, 2026 08:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants