Skip to content

CP-13626: Fusion Refunded UI#3655

Merged
atn4z7 merged 10 commits intomainfrom
refunded-ui
Mar 18, 2026
Merged

CP-13626: Fusion Refunded UI#3655
atn4z7 merged 10 commits intomainfrom
refunded-ui

Conversation

@atn4z7
Copy link
Collaborator

@atn4z7 atn4z7 commented Mar 18, 2026

Description

Ticket: CP-13626

Swap Activity Notifications — UI Polish & Refunded State

  • Refunded state: Added full UI support for refunded transfers — dedicated icon (restart_alt), list item title showing refunded amount/token, and detail screen showing "Swap partial failure" with refund note on the target card
  • All swap items are now tappable with a chevron (completed, failed, refunded, in-progress all navigate to the detail screen); removed the RetrySwapButton from the list
  • Removed was/were pluralization from swap item titles
  • Detail screen improvements matching design:
    • Swap successful title renders on two lines
    • Failed swaps show filled error icon; incomplete chain leg shows outlined error icon
    • Error reason displayed below cards for failed swaps
    • "Hide" / "Dismiss" button wording by status (completed → Hide, in-progress → Hide, failed → Dismiss)
    • Dismiss button uses tertiary style (plain text)
    • Confirmations row with green/gray progress bar added to SwapStatusCard
    • Note row on target card for refunded swaps
  • Renamed isSwapCompletedOrFailedisSwapTerminal to accurately reflect that it now includes refunded
  • Removed bigInt_to_string.js polyfill — it was overriding BigInt.prototype.toJSON which caused JSON.stringify to emit plain strings before stringifyTransfer's replacer could tag them as {__type:"bigint"}. Removing the polyfill lets stringifyTransfer/parseTransfer from the Fusion SDK work correctly, ensuring BigInt fields (amountIn, amountOut, fees[].amount, etc.) persist and rehydrate with full precision.
  • Cross-chain swaps now navigate directly to the swap detail screen after submission, so users can track confirmation progress immediately

Screenshots/Videos

Swap Details
Simulator Screenshot - iPhone 16 Pro - 2026-03-17 at 19 14 11
Simulator Screenshot - iPhone 16 Pro - 2026-03-17 at 19 20 15
Simulator Screenshot - iPhone 16 Pro - 2026-03-17 at 20 06 36

Notification Items
Simulator Screenshot - iPhone 16 Pro - 2026-03-17 at 19 13 37
Simulator Screenshot - iPhone 16 Pro - 2026-03-17 at 19 43 51

Testing

  • In-progress swap: Start a cross-chain swap → confirm the notification item shows "Swapping X to Y in progress...", a chevron, and tapping opens the detail screen immediately
  • Cross-chain swap navigation: Submit a cross-chain swap → confirm the app navigates directly to the swap detail screen (showing in-progress state) without requiring the user to tap the notification item
  • Detail screen — in progress: Verify the "Confirmations" row shows a green/gray progress bar; button reads "Hide"
  • Completed swap: Confirm title reads {amount} {from} swapped for {to} (no was/were), chevron is shown, tapping opens detail; button reads "Hide"
  • Failed swap: Confirm subtitle reads "Failed" in red, chevron shown, tapping opens detail; error reason text shown below cards; error icon is filled (!); dismiss button is plain text ("Dismiss")
  • Refunded swap: Confirm list item title reads {amount} {token} refunded to your wallet, restart_alt icon, no subtitle, chevron shown; detail screen title reads "Swap partial failure"; target card shows "Incomplete" status with outlined error icon and a refund note
  • Persistence across restarts: Perform a swap, force-quit and reopen the app — confirm the swap item still appears with correct data (validates BigInt serialization fix)
  • Clear all: Confirm "Clear all" still only clears terminal (completed/failed/refunded) items and animates them out

Checklist

Please check all that apply (if applicable)

  • I have performed a self-review of my code
  • I have verified the code works
  • I have included screenshots / videos of android and ios
  • I have added testing steps
  • I have added/updated necessary unit tests
  • I have updated the documentation

Copilot AI review requested due to automatic review settings March 18, 2026 01:09
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Implements “refunded / partial failure” support in the Fusion swap UI (notifications list + swap detail), including new status mapping, display copy, and persistence updates needed for bigint-safe transfer storage.

Changes:

  • Bump @avalabs/fusion-sdk to 0.11.0 and adapt fee estimation/tests to the updated API (totalUpfrontFee).
  • Add “refunded” handling across swap notifications: status mapping, list item/title/icon updates, and swap detail UI (notes, confirmations, error reason).
  • Rework Zustand MMKV persistence exports and add a custom persist adapter for Fusion transfers using stringifyTransfer/parseTransfer to preserve bigints.

Reviewed changes

Copilot reviewed 32 out of 34 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
yarn.lock Updates lockfile for fusion-sdk bump.
packages/k2-alpine/src/theme/tokens/Icons.ts Registers new Restart custom icon.
packages/k2-alpine/src/assets/icons/restart_alt.svg Adds restart SVG used for refunded swaps.
packages/core-mobile/polyfills/index.js Removes BigInt JSON polyfill import from polyfills entrypoint.
packages/core-mobile/polyfills/bigInt_to_string.js Deletes BigInt toJSON global polyfill.
packages/core-mobile/patches/reactotron-core-client+2.9.9.patch Patches reactotron serialization behavior related to BigInt toJSON.
packages/core-mobile/package.json Bumps fusion-sdk dependency version.
packages/core-mobile/app/utils/mmkv/storages.ts Renames/exports MMKV instance and standardized Zustand persist adapter.
packages/core-mobile/app/store/posthog/slice.ts Adjusts Solana swap gating logic.
packages/core-mobile/app/new/features/track/store.ts Switches persisted storage adapter import/name.
packages/core-mobile/app/new/features/swap/services/FusionService.test.ts Updates tests for fee estimation return shape.
packages/core-mobile/app/new/features/swap/screens/SwapScreen.tsx Navigates to swap detail notification for successful cross-chain swaps.
packages/core-mobile/app/new/features/swap/hooks/useZustandStore.ts Adds custom persist adapter for Fusion transfers using stringify/parse helpers.
packages/core-mobile/app/new/features/swap/hooks/useZustandStore.test.ts Adds unit tests for Fusion transfer persistence + store actions.
packages/core-mobile/app/new/features/swap/hooks/useFeeEstimation.ts Uses totalUpfrontFee for fee estimation calculations.
packages/core-mobile/app/new/features/swap/contexts/SwapContext.tsx Tracks successTransferId to support post-success routing behavior.
packages/core-mobile/app/new/features/portfolio/store.ts Switches persisted storage adapter import/name.
packages/core-mobile/app/new/features/portfolio/assets/components/TokenActivityListItemTitle.tsx Improves swap title generation for cross-chain / ambiguous token visibility cases.
packages/core-mobile/app/new/features/notifications/utils.ts Adds refunded as terminal state and maps it into UI statuses.
packages/core-mobile/app/new/features/notifications/utils.test.ts Adds tests for refunded status mapping + terminal-state behavior.
packages/core-mobile/app/new/features/notifications/types.ts Extends swap notification status union with refunded and incomplete.
packages/core-mobile/app/new/features/notifications/screens/SwapActivityDetailScreen.tsx Adds refunded/confirmations/error reason display and updates titles/buttons.
packages/core-mobile/app/new/features/notifications/screens/NotificationsScreen.tsx Allows navigating into swap activity detail from list items.
packages/core-mobile/app/new/features/notifications/hooks/useSwapActivityDisplay.ts Adds refund note, error reason, and confirmation progress fields.
packages/core-mobile/app/new/features/notifications/components/SwapStatusIcon.tsx Updates status icon rendering (failed/incomplete styling).
packages/core-mobile/app/new/features/notifications/components/SwapStatusCard.tsx Adds confirmations progress UI and optional note row.
packages/core-mobile/app/new/features/notifications/components/SwapIcon.tsx Adds refunded icon variant (restart icon).
packages/core-mobile/app/new/features/notifications/components/RetrySwapButton.tsx Removes inline retry button accessory from list items.
packages/core-mobile/app/new/features/notifications/components/FusionTransferItem.tsx Updates list item title/subtitle/accessory/timestamp behavior incl. refunded.
packages/core-mobile/app/new/features/ledger/store.ts Switches persisted storage adapter import/name.
packages/core-mobile/app/new/features/appReview/store.ts Switches persisted storage adapter import/name.
packages/core-mobile/app/new/features/activity/store.ts Switches persisted storage adapter import/name.
packages/core-mobile/app/new/features/accountSettings/store.ts Switches persisted storage adapter import/name.
packages/core-mobile/app/new/common/utils/createZustandStore.ts Updates default persist adapter to zustandPersistStorage.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Copilot AI review requested due to automatic review settings March 18, 2026 13:18
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates Core Mobile’s Fusion swap activity/notification UX to support a new refunded (partial failure) terminal state, including improved persistence of Fusion transfers and SDK alignment.

Changes:

  • Bump @avalabs/fusion-sdk to 0.11.0 and update fee estimation usage to totalUpfrontFee.
  • Add refunded/partial-failure handling across notifications list + swap detail UI (statuses, icons, notes, confirmations).
  • Improve swap transfer persistence by adding BigInt-safe serialization for persisted Fusion transfers and standardizing Zustand MMKV storage exports.

Reviewed changes

Copilot reviewed 32 out of 34 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
yarn.lock Locks updated dependency graph for Fusion SDK bump.
packages/k2-alpine/src/theme/tokens/Icons.ts Registers new Icons.Custom.Restart icon token.
packages/k2-alpine/src/assets/icons/restart_alt.svg Adds restart icon asset used for refunded swap UI.
packages/core-mobile/polyfills/index.js Removes BigInt-to-JSON polyfill import from polyfill bundle.
packages/core-mobile/polyfills/bigInt_to_string.js Deletes BigInt toJSON prototype patch polyfill.
packages/core-mobile/patches/reactotron-core-client+2.9.9.patch Adjusts Reactotron serialization patch (disables BigInt toJSON injection).
packages/core-mobile/package.json Bumps @avalabs/fusion-sdk to 0.11.0.
packages/core-mobile/app/utils/mmkv/storages.ts Renames MMKV instance export and introduces zustandPersistStorage adapter.
packages/core-mobile/app/store/posthog/slice.ts Removes Keystone-specific Solana swap block in selector.
packages/core-mobile/app/new/features/track/store.ts Migrates persisted storage usage to zustandPersistStorage.
packages/core-mobile/app/new/features/swap/services/FusionService.test.ts Updates fee estimate mock shape for new SDK field name.
packages/core-mobile/app/new/features/swap/screens/SwapScreen.tsx Navigates to swap detail after success for cross-chain swaps using stored transfer info.
packages/core-mobile/app/new/features/swap/hooks/useZustandStore.ts Adds custom persist storage for Fusion transfers using stringifyTransfer/parseTransfer to preserve BigInts.
packages/core-mobile/app/new/features/swap/hooks/useZustandStore.test.ts Adds unit tests for Fusion transfer persistence + store actions.
packages/core-mobile/app/new/features/swap/hooks/useFeeEstimation.ts Switches fee estimate field from totalFee to totalUpfrontFee.
packages/core-mobile/app/new/features/swap/contexts/SwapContext.tsx Tracks successTransferId for post-success navigation decisions.
packages/core-mobile/app/new/features/portfolio/store.ts Migrates persisted storage usage to zustandPersistStorage.
packages/core-mobile/app/new/features/portfolio/assets/components/TokenActivityListItemTitle.tsx Improves swap title fallback logic for cross-chain/visibility edge cases.
packages/core-mobile/app/new/features/notifications/utils.ts Renames terminal check to isSwapTerminal and adds refunded status mapping.
packages/core-mobile/app/new/features/notifications/utils.test.ts Expands tests to cover refunded/incomplete/terminal behavior.
packages/core-mobile/app/new/features/notifications/types.ts Extends NotificationSwapStatus with refunded and incomplete.
packages/core-mobile/app/new/features/notifications/screens/SwapActivityDetailScreen.tsx Adds refunded titles/notes, confirmations, error reason UI; adjusts footer actions.
packages/core-mobile/app/new/features/notifications/screens/NotificationsScreen.tsx Uses new terminal logic and makes swap items navigable to detail screen.
packages/core-mobile/app/new/features/notifications/hooks/useSwapActivityDisplay.ts Adds refund note, errorReason, and confirmation progress mapping for UI.
packages/core-mobile/app/new/features/notifications/components/SwapStatusIcon.tsx Updates icon rendering for new target-leg incomplete state.
packages/core-mobile/app/new/features/notifications/components/SwapStatusCard.tsx Displays confirmations progress + note; supports incomplete status label/coloring.
packages/core-mobile/app/new/features/notifications/components/SwapIcon.tsx Adds refunded icon treatment (restart) in swap list items.
packages/core-mobile/app/new/features/notifications/components/RetrySwapButton.tsx Removes inline retry button from list items.
packages/core-mobile/app/new/features/notifications/components/FusionTransferItem.tsx Adjusts titles/subtitles/accessories to support refunded state and new UX.
packages/core-mobile/app/new/features/ledger/store.ts Migrates persisted storage usage to zustandPersistStorage.
packages/core-mobile/app/new/features/appReview/store.ts Migrates persisted storage usage to zustandPersistStorage.
packages/core-mobile/app/new/features/activity/store.ts Migrates persisted storage usage to zustandPersistStorage and keeps migration logic.
packages/core-mobile/app/new/features/accountSettings/store.ts Migrates persisted storage usage to zustandPersistStorage.
packages/core-mobile/app/new/common/utils/createZustandStore.ts Updates default persist storage to zustandPersistStorage.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Copy link
Contributor

@B0Y3R-AVA B0Y3R-AVA left a comment

Choose a reason for hiding this comment

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

few more nits as i think constants for swap statuses could clean up some of the ui logic nicely

Comment on lines +28 to +30
const isCompleted = status === 'completed'
const isFailed = status === 'failed'
const isIncomplete = status === 'incomplete'
Copy link
Contributor

Choose a reason for hiding this comment

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

seeing use of these status screens everywhere, would love for these to be consts defined in one place

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

switched to enum

Comment on lines 86 to 90
color: isCompleted
? colors.$textSuccess
: isFailed
: isFailed || isIncomplete
? colors.$textDanger
: colors.$textSecondary
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT this is starting to get messy, worth moving to above and using a switch to build out an object?

`
const COMPLETED = 'completed'
const INCOMPLETE = 'incomplete'
const FAILED = 'failed'

const titleColorAndText: { title: string, color: string } = {}

switch(status):
case COMPLETED:
titleColorAndText = {title: 'Complete', color: colors.$textSuccess}
case FAILED
titleColorAndText = {title: 'Failed', color: colors.$textDanger}
case INCOMPLETE:
titleColorAndText = {title: 'Failed', color: colors.$textDanger}
default:
titleColorAndText = {title: 'Pending...', color: colors.$textSecondary}
`

That way we can use textAndTitleColor.text and textAndTitleColor.color here

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

Copilot AI review requested due to automatic review settings March 18, 2026 16:56
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds full UI support for refunded Fusion swaps (list + detail), improves swap activity interactions (all items navigable), and fixes BigInt persistence by switching Fusion transfer storage to SDK-backed stringifyTransfer/parseTransfer serialization (plus associated dependency/polyfill adjustments).

Changes:

  • Add “refunded” swap state across notifications list + swap detail UI (icons, titles, status mapping, notes, confirmations, error display).
  • Make all swap activity items tappable (chevron) and adjust detail-screen footer actions/styles by status.
  • Fix swap transfer persistence (BigInt-safe) by removing BigInt.prototype.toJSON overrides and persisting Fusion transfers via Fusion SDK stringifyTransfer/parseTransfer; bump Fusion SDK to 0.11.0.

Reviewed changes

Copilot reviewed 32 out of 34 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
yarn.lock Bumps @avalabs/fusion-sdk resolution to 0.11.0.
packages/core-mobile/package.json Bumps @avalabs/fusion-sdk to 0.11.0.
packages/k2-alpine/src/theme/tokens/Icons.ts Registers new Restart icon token.
packages/k2-alpine/src/assets/icons/restart_alt.svg Adds refunded-state icon asset.
packages/core-mobile/polyfills/index.js Removes BigInt JSON polyfill import.
packages/core-mobile/polyfills/bigInt_to_string.js Deletes BigInt.prototype.toJSON override polyfill.
packages/core-mobile/patches/reactotron-core-client+2.9.9.patch Disables Reactotron’s BigInt toJSON override to preserve custom BigInt tagging.
packages/core-mobile/app/utils/mmkv/storages.ts Renames/exports MMKV-backed Zustand storage adapters (zustandStorageMMKV, zustandPersistStorage).
packages/core-mobile/app/store/posthog/slice.ts Adjusts Solana swap gating logic (removes Keystone special-case from swap gate).
packages/core-mobile/app/new/common/utils/createZustandStore.ts Updates default persist storage to zustandPersistStorage.
packages/core-mobile/app/new/features/track/store.ts Uses new zustandPersistStorage adapter.
packages/core-mobile/app/new/features/portfolio/store.ts Uses new zustandPersistStorage adapter.
packages/core-mobile/app/new/features/ledger/store.ts Uses new zustandPersistStorage adapter.
packages/core-mobile/app/new/features/appReview/store.ts Uses new zustandPersistStorage adapter.
packages/core-mobile/app/new/features/activity/store.ts Uses new zustandPersistStorage adapter.
packages/core-mobile/app/new/features/accountSettings/store.ts Uses new zustandPersistStorage adapter.
packages/core-mobile/app/new/features/swap/hooks/useFeeEstimation.ts Updates fee estimate field name to totalUpfrontFee.
packages/core-mobile/app/new/features/swap/services/FusionService.test.ts Updates tests for new fee estimate shape (totalUpfrontFee).
packages/core-mobile/app/new/features/swap/contexts/SwapContext.tsx Tracks successTransferId to enable post-submit navigation behavior.
packages/core-mobile/app/new/features/swap/screens/SwapScreen.tsx Navigates directly to swap detail after successful cross-chain submission.
packages/core-mobile/app/new/features/swap/hooks/useZustandStore.ts Adds custom MMKV persist adapter for Fusion transfers using stringifyTransfer/parseTransfer.
packages/core-mobile/app/new/features/swap/hooks/useZustandStore.test.ts Adds unit tests validating BigInt-safe persistence and store actions.
packages/core-mobile/app/new/features/portfolio/assets/components/TokenActivityListItemTitle.tsx Improves swap title rendering for edge cases (missing output, identical symbols).
packages/core-mobile/app/new/features/notifications/types.ts Replaces swap status string union with NotificationSwapStatus enum (adds Refunded/Incomplete).
packages/core-mobile/app/new/features/notifications/utils.ts Renames terminal helper to isSwapTerminal and adds refunded/incomplete status mapping.
packages/core-mobile/app/new/features/notifications/utils.test.ts Updates/extends tests for refunded + enum-based statuses.
packages/core-mobile/app/new/features/notifications/screens/NotificationsScreen.tsx Makes swap items always tappable; updates terminal logic for swipe/clear-all.
packages/core-mobile/app/new/features/notifications/components/RetrySwapButton.tsx Removes list-item retry button (navigation now via detail screen).
packages/core-mobile/app/new/features/notifications/components/FusionTransferItem.tsx Updates titles/subtitles/icons/chevron behavior; adds refunded title formatting.
packages/core-mobile/app/new/features/notifications/components/SwapIcon.tsx Adds refunded icon rendering (Restart).
packages/core-mobile/app/new/features/notifications/components/SwapStatusIcon.tsx Distinguishes failed (filled) vs incomplete (outline) status icons.
packages/core-mobile/app/new/features/notifications/components/SwapStatusCard.tsx Adds confirmations progress bar + optional note row; status rendering via enum.
packages/core-mobile/app/new/features/notifications/hooks/useSwapActivityDisplay.ts Adds refund note, error reason, and confirmations data for detail UI.
packages/core-mobile/app/new/features/notifications/screens/SwapActivityDetailScreen.tsx Updates titles (2-line), footer actions (Hide/Dismiss), confirmations/note rows, and error reason display.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Copy link
Contributor

@onghwan onghwan left a comment

Choose a reason for hiding this comment

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

dev-tested

@atn4z7 atn4z7 merged commit acedf4b into main Mar 18, 2026
4 checks passed
@atn4z7 atn4z7 deleted the refunded-ui branch March 18, 2026 21:13
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.

4 participants