diff --git a/components/grid-visualizer/src/app/page.tsx b/components/grid-visualizer/src/app/page.tsx index 14b950119..1826296b1 100644 --- a/components/grid-visualizer/src/app/page.tsx +++ b/components/grid-visualizer/src/app/page.tsx @@ -34,6 +34,7 @@ export default function Home() { setReceiveNetwork, setSourceFundingMode, setSourceRail, + setDestRail, setSettlementRail, swap, setSourceRegion, @@ -188,8 +189,10 @@ export default function Home() { openPicker('receive')} onNetworkChange={setReceiveNetwork} + onRailChange={setDestRail} /> @@ -259,6 +262,7 @@ export default function Home() { sourceRegion={state.sourceRegion} destRegion={state.destRegion} sourceRail={state.sourceRail} + destRail={state.destRail} settlementRail={state.settlementRail} expanded={flowExpanded} onToggle={toggleFlow} @@ -268,6 +272,7 @@ export default function Home() { receive={state.receive!} fundingModel={fundingModel} sourceRail={state.sourceRail} + destRail={state.destRail} audience={state.audience} onAudienceChange={setAudience} expanded={codeExpanded} diff --git a/components/grid-visualizer/src/components/CodePanel/CodePanel.tsx b/components/grid-visualizer/src/components/CodePanel/CodePanel.tsx index 02b66abdb..0686c145c 100644 --- a/components/grid-visualizer/src/components/CodePanel/CodePanel.tsx +++ b/components/grid-visualizer/src/components/CodePanel/CodePanel.tsx @@ -19,6 +19,7 @@ interface CodePanelProps { receive: CurrencySelection; fundingModel: 'jit' | 'pre-funded'; sourceRail?: string | null; + destRail?: string | null; audience: 'human' | 'agent'; onAudienceChange: (audience: 'human' | 'agent') => void; expanded: boolean; @@ -271,16 +272,17 @@ export function CodePanel({ receive, fundingModel, sourceRail, + destRail, audience, onAudienceChange, expanded, }: CodePanelProps) { const steps = useMemo( - () => generateSteps(send, receive, fundingModel, sourceRail), - [send, receive, fundingModel, sourceRail], + () => generateSteps(send, receive, fundingModel, sourceRail, destRail), + [send, receive, fundingModel, sourceRail, destRail], ); - const stepsKey = `${send.code}-${send.accountType}-${send.isInternal}-${receive.code}-${receive.accountType}-${receive.isInternal}-${fundingModel}-${sourceRail}-${audience}`; + const stepsKey = `${send.code}-${send.accountType}-${send.isInternal}-${receive.code}-${receive.accountType}-${receive.isInternal}-${fundingModel}-${sourceRail}-${destRail}-${audience}`; const isHuman = audience === 'human'; return ( diff --git a/components/grid-visualizer/src/components/CurrencyPicker/CurrencyPicker.tsx b/components/grid-visualizer/src/components/CurrencyPicker/CurrencyPicker.tsx index fe550d0ca..3e1669fbd 100644 --- a/components/grid-visualizer/src/components/CurrencyPicker/CurrencyPicker.tsx +++ b/components/grid-visualizer/src/components/CurrencyPicker/CurrencyPicker.tsx @@ -5,7 +5,7 @@ import { Command } from '@lightsparkdev/origin'; import type { CommandItem, CommandGroup } from '@lightsparkdev/origin'; import { IconMagnifyingGlass } from '@central-icons-react/round-outlined-radius-3-stroke-1.5/IconMagnifyingGlass'; import { useCommandNav } from '@/hooks/useCommandNav'; -import { currencies } from '@/data/currencies'; +import { currencies, railDisplayName } from '@/data/currencies'; import { cryptoAssets } from '@/data/crypto'; import type { CurrencySelection } from '@/lib/code-generator'; import styles from './CurrencyPicker.module.scss'; @@ -63,7 +63,7 @@ function lookupSelection(id: string): CurrencySelection | null { function getRailsText(sel: CurrencySelection | null): string { if (!sel) return ''; const fiat = currencies.find((c) => c.code === sel.code); - if (fiat) return fiat.allRails.join(', '); + if (fiat) return fiat.allRails.map(railDisplayName).join(', '); const crypto = cryptoAssets.find((a) => a.symbol === sel.code); if (crypto) return crypto.accountTypes.map((t) => t.network).join(', '); return ''; @@ -76,7 +76,7 @@ function buildFiatItem( return { id: c.code, label: c.name, - keywords: [c.code, c.accountType, ...c.allRails], + keywords: [c.code, c.accountType, ...c.allRails, ...c.allRails.map(railDisplayName)], icon: ( // eslint-disable-next-line @next/next/no-img-element void; @@ -267,11 +268,12 @@ export function FlowPanel({ sourceRegion, destRegion, sourceRail, + destRail, settlementRail, expanded, onToggle, }: FlowPanelProps) { - const path = useMemo(() => buildFlowPath(send, receive, sourceRegion, destRegion, sourceRail, settlementRail), [send, receive, sourceRegion, destRegion, sourceRail, settlementRail]); + const path = useMemo(() => buildFlowPath(send, receive, sourceRegion, destRegion, sourceRail, destRail, settlementRail), [send, receive, sourceRegion, destRegion, sourceRail, destRail, settlementRail]); const pathKey = path.nodes.map((n) => n.id + n.label + n.isInternal + n.actionCards.map((a) => a.text).join(',')).join('|'); const contentRef = useRef(null); const flowRef = useRef(null); diff --git a/components/grid-visualizer/src/components/InputCard/InputCard.tsx b/components/grid-visualizer/src/components/InputCard/InputCard.tsx index 4842fa8a1..37bf34cd7 100644 --- a/components/grid-visualizer/src/components/InputCard/InputCard.tsx +++ b/components/grid-visualizer/src/components/InputCard/InputCard.tsx @@ -4,7 +4,7 @@ import { useState, useRef, useCallback, useEffect } from 'react'; import { createPortal } from 'react-dom'; import type { CurrencySelection } from '@/lib/code-generator'; import { cryptoAssets, type CryptoAccountType } from '@/data/crypto'; -import { currencies } from '@/data/currencies'; +import { currencies, railDisplayName } from '@/data/currencies'; import { IconPlusLarge } from '@central-icons-react/round-outlined-radius-3-stroke-1.5/IconPlusLarge'; import { IconChevronBottom } from '@central-icons-react/round-outlined-radius-3-stroke-1.5/IconChevronBottom'; import { IconArrowsRepeat } from '@central-icons-react/round-outlined-radius-3-stroke-1.5/IconArrowsRepeat'; @@ -247,7 +247,7 @@ function RailDropdown({ > Rail - {selectedRail} + {railDisplayName(selectedRail)} @@ -285,7 +285,7 @@ function RailDropdown({ }} type="button" > - {rail} + {railDisplayName(rail)} ))} @@ -395,7 +395,7 @@ export function InputCard({
Rail - {fiatRail} + {railDisplayName(fiatRail)}
) : null} diff --git a/components/grid-visualizer/src/data/currencies.ts b/components/grid-visualizer/src/data/currencies.ts index 5b7ed99d0..0b8ed0ee6 100644 --- a/components/grid-visualizer/src/data/currencies.ts +++ b/components/grid-visualizer/src/data/currencies.ts @@ -14,6 +14,39 @@ export interface FiatCurrency { examplePerson: ExamplePerson; } +// instantRails/allRails hold PaymentRail enum members because they are sent to +// the API as-is. These are the human-readable forms for UI text only — never +// send a display name to the API. +const railDisplayNames: Record = { + ACH: 'ACH', + ACH_COLOMBIA: 'ACH Colombia', + BANK_TRANSFER: 'Bank Transfer', + BRE_B: 'Bre-B', + CIPS: 'CIPS', + FAST: 'FAST', + FASTER_PAYMENTS: 'Faster Payments', + FEDNOW: 'FedNow', + INSTAPAY: 'InstaPay', + MOBILE_MONEY: 'Mobile Money', + NEFT: 'NEFT', + PAYNOW: 'PayNow', + PESONET: 'PESONet', + PIX: 'PIX', + RTGS: 'RTGS', + RTP: 'RTP', + SEPA: 'SEPA', + SEPA_INSTANT: 'SEPA Instant', + SPEI: 'SPEI', + SWIFT: 'SWIFT', + UNIONPAY: 'UnionPay', + UPI: 'UPI', + WIRE: 'Wire', +}; + +export function railDisplayName(rail: string): string { + return railDisplayNames[rail] ?? rail.replace(/_/g, ' '); +} + export const currencies: FiatCurrency[] = [ { code: 'USD', @@ -21,8 +54,8 @@ export const currencies: FiatCurrency[] = [ countryCode: 'us', accountType: 'USD_ACCOUNT', accountLabel: 'US Bank Account', - instantRails: ['RTP', 'FedNow'], - allRails: ['ACH', 'Wire', 'RTP', 'FedNow'], + instantRails: ['RTP', 'FEDNOW'], + allRails: ['ACH', 'WIRE', 'RTP', 'FEDNOW'], examplePerson: { fullName: 'Jane Doe', nationality: 'US' }, }, { @@ -31,8 +64,8 @@ export const currencies: FiatCurrency[] = [ countryCode: 'eu', accountType: 'EUR_ACCOUNT', accountLabel: 'IBAN', - instantRails: ['SEPA Instant'], - allRails: ['SEPA', 'SEPA Instant'], + instantRails: ['SEPA_INSTANT'], + allRails: ['SEPA', 'SEPA_INSTANT'], examplePerson: { fullName: 'Anna Müller', nationality: 'DE' }, }, { @@ -41,8 +74,8 @@ export const currencies: FiatCurrency[] = [ countryCode: 'gb', accountType: 'GBP_ACCOUNT', accountLabel: 'UK Bank Account', - instantRails: ['Faster Payments'], - allRails: ['Faster Payments'], + instantRails: ['FASTER_PAYMENTS'], + allRails: ['FASTER_PAYMENTS'], examplePerson: { fullName: 'James Wilson', nationality: 'GB' }, }, { @@ -81,8 +114,8 @@ export const currencies: FiatCurrency[] = [ countryCode: 'dk', accountType: 'DKK_ACCOUNT', accountLabel: 'IBAN', - instantRails: ['SEPA Instant'], - allRails: ['SEPA', 'SEPA Instant'], + instantRails: ['SEPA_INSTANT'], + allRails: ['SEPA', 'SEPA_INSTANT'], examplePerson: { fullName: 'Lars Jensen', nationality: 'DK' }, }, { @@ -92,7 +125,7 @@ export const currencies: FiatCurrency[] = [ accountType: 'NGN_ACCOUNT', accountLabel: 'Nigerian Bank Account', instantRails: [], - allRails: ['Bank Transfer'], + allRails: ['BANK_TRANSFER'], examplePerson: { fullName: 'Chioma Okafor', nationality: 'NG' }, }, { @@ -102,7 +135,7 @@ export const currencies: FiatCurrency[] = [ accountType: 'CAD_ACCOUNT', accountLabel: 'Canadian Bank Account', instantRails: [], - allRails: ['Bank Transfer'], + allRails: ['BANK_TRANSFER'], examplePerson: { fullName: 'Sophie Tremblay', nationality: 'CA' }, }, { @@ -112,7 +145,7 @@ export const currencies: FiatCurrency[] = [ accountType: 'PHP_ACCOUNT', accountLabel: 'Philippine Bank Account', instantRails: [], - allRails: ['Bank Transfer'], + allRails: ['BANK_TRANSFER'], examplePerson: { fullName: 'Maria Santos', nationality: 'PH' }, }, { @@ -121,8 +154,8 @@ export const currencies: FiatCurrency[] = [ countryCode: 'sg', accountType: 'SGD_ACCOUNT', accountLabel: 'Singapore Bank Account', - instantRails: ['PayNow', 'FAST'], - allRails: ['PayNow', 'FAST', 'Bank Transfer'], + instantRails: ['PAYNOW', 'FAST'], + allRails: ['PAYNOW', 'FAST', 'BANK_TRANSFER'], examplePerson: { fullName: 'Wei Lin Tan', nationality: 'SG' }, }, { @@ -132,7 +165,7 @@ export const currencies: FiatCurrency[] = [ accountType: 'HKD_ACCOUNT', accountLabel: 'Hong Kong Bank Account', instantRails: [], - allRails: ['Bank Transfer'], + allRails: ['BANK_TRANSFER'], examplePerson: { fullName: 'Emily Chan', nationality: 'HK' }, }, { @@ -142,7 +175,7 @@ export const currencies: FiatCurrency[] = [ accountType: 'IDR_ACCOUNT', accountLabel: 'Indonesian Bank Account', instantRails: [], - allRails: ['Bank Transfer'], + allRails: ['BANK_TRANSFER'], examplePerson: { fullName: 'Siti Rahayu', nationality: 'ID' }, }, { @@ -152,7 +185,7 @@ export const currencies: FiatCurrency[] = [ accountType: 'KES_ACCOUNT', accountLabel: 'M-Pesa', instantRails: [], - allRails: ['Mobile Money'], + allRails: ['MOBILE_MONEY'], examplePerson: { fullName: 'Wanjiku Kamau', nationality: 'KE' }, }, { @@ -162,7 +195,7 @@ export const currencies: FiatCurrency[] = [ accountType: 'MYR_ACCOUNT', accountLabel: 'Malaysian Bank Account', instantRails: [], - allRails: ['Bank Transfer'], + allRails: ['BANK_TRANSFER'], examplePerson: { fullName: 'Nurul Aisyah', nationality: 'MY' }, }, { @@ -172,7 +205,7 @@ export const currencies: FiatCurrency[] = [ accountType: 'RWF_ACCOUNT', accountLabel: 'Mobile Money', instantRails: [], - allRails: ['Mobile Money'], + allRails: ['MOBILE_MONEY'], examplePerson: { fullName: 'Jean Uwimana', nationality: 'RW' }, }, { @@ -182,7 +215,7 @@ export const currencies: FiatCurrency[] = [ accountType: 'THB_ACCOUNT', accountLabel: 'Thai Bank Account', instantRails: [], - allRails: ['Bank Transfer'], + allRails: ['BANK_TRANSFER'], examplePerson: { fullName: 'Somchai Prasert', nationality: 'TH' }, }, { @@ -192,7 +225,7 @@ export const currencies: FiatCurrency[] = [ accountType: 'TZS_ACCOUNT', accountLabel: 'Mobile Money', instantRails: [], - allRails: ['Mobile Money'], + allRails: ['MOBILE_MONEY'], examplePerson: { fullName: 'Halima Mwanga', nationality: 'TZ' }, }, { @@ -202,7 +235,7 @@ export const currencies: FiatCurrency[] = [ accountType: 'VND_ACCOUNT', accountLabel: 'Vietnamese Bank Account', instantRails: [], - allRails: ['Bank Transfer'], + allRails: ['BANK_TRANSFER'], examplePerson: { fullName: 'Nguyen Thi Lan', nationality: 'VN' }, }, { @@ -212,7 +245,7 @@ export const currencies: FiatCurrency[] = [ accountType: 'ZAR_ACCOUNT', accountLabel: 'South African Bank Account', instantRails: [], - allRails: ['Bank Transfer'], + allRails: ['BANK_TRANSFER'], examplePerson: { fullName: 'Thabo Nkosi', nationality: 'ZA' }, }, { @@ -222,7 +255,7 @@ export const currencies: FiatCurrency[] = [ accountType: 'ZMW_ACCOUNT', accountLabel: 'Mobile Money', instantRails: [], - allRails: ['Mobile Money'], + allRails: ['MOBILE_MONEY'], examplePerson: { fullName: 'Mwila Tembo', nationality: 'ZM' }, }, { @@ -232,7 +265,7 @@ export const currencies: FiatCurrency[] = [ accountType: 'MWK_ACCOUNT', accountLabel: 'Mobile Money', instantRails: [], - allRails: ['Mobile Money'], + allRails: ['MOBILE_MONEY'], examplePerson: { fullName: 'Chimwemwe Banda', nationality: 'MW' }, }, { @@ -242,7 +275,7 @@ export const currencies: FiatCurrency[] = [ accountType: 'UGX_ACCOUNT', accountLabel: 'Mobile Money', instantRails: [], - allRails: ['Mobile Money'], + allRails: ['MOBILE_MONEY'], examplePerson: { fullName: 'Grace Namugga', nationality: 'UG' }, }, { @@ -252,7 +285,7 @@ export const currencies: FiatCurrency[] = [ accountType: 'XOF_ACCOUNT', accountLabel: 'Mobile Money', instantRails: [], - allRails: ['Mobile Money'], + allRails: ['MOBILE_MONEY'], examplePerson: { fullName: 'Amadou Diallo', nationality: 'SN' }, }, { @@ -262,7 +295,7 @@ export const currencies: FiatCurrency[] = [ accountType: 'SLV_ACCOUNT', accountLabel: 'El Salvador Bank/Mobile', instantRails: [], - allRails: ['Bank Transfer', 'Mobile Money'], + allRails: ['BANK_TRANSFER', 'MOBILE_MONEY'], examplePerson: { fullName: 'Carlos Morales', nationality: 'SV' }, }, { @@ -272,7 +305,7 @@ export const currencies: FiatCurrency[] = [ accountType: 'CNY_ACCOUNT', accountLabel: 'Chinese Bank Account', instantRails: [], - allRails: ['Bank Transfer', 'Mobile Money'], + allRails: ['BANK_TRANSFER', 'MOBILE_MONEY'], examplePerson: { fullName: 'Wei Zhang', nationality: 'CN' }, }, ]; diff --git a/components/grid-visualizer/src/hooks/useFlowBuilder.ts b/components/grid-visualizer/src/hooks/useFlowBuilder.ts index b4e63dcba..7781388a1 100644 --- a/components/grid-visualizer/src/hooks/useFlowBuilder.ts +++ b/components/grid-visualizer/src/hooks/useFlowBuilder.ts @@ -15,6 +15,7 @@ export interface FlowBuilderState { destRegion: string | null; // fiat code — only used when destination is crypto sourceFundingMode: SourceFundingMode; sourceRail: string | null; // selected fiat rail e.g. 'RTP' — null for crypto + destRail: string | null; // selected fiat rail — sent as the quote's destination.paymentRail settlementRail: string; // asset Grid settles over between switches, e.g. 'BTC' | 'USDC' | 'USDB' audience: 'human' | 'agent'; pickerTarget: 'send' | 'receive' | null; @@ -27,6 +28,7 @@ type Action = | { type: 'SET_RECEIVE_NETWORK'; payload: CryptoAccountType } | { type: 'SET_SOURCE_FUNDING_MODE'; payload: SourceFundingMode } | { type: 'SET_SOURCE_RAIL'; payload: string } + | { type: 'SET_DEST_RAIL'; payload: string } | { type: 'SET_SETTLEMENT_RAIL'; payload: string } | { type: 'SET_SOURCE_REGION'; payload: string } | { type: 'SET_DEST_REGION'; payload: string } @@ -43,6 +45,7 @@ const initialState: FlowBuilderState = { destRegion: null, sourceFundingMode: 'external', sourceRail: null, + destRail: null, settlementRail: DEFAULT_SETTLEMENT_RAIL, audience: 'human', pickerTarget: null, @@ -70,7 +73,8 @@ function reducer(state: FlowBuilderState, action: Action): FlowBuilderState { const destRegion = receive.type === 'crypto' ? (receive.code === 'BTC' ? (state.destRegion ?? null) : 'USD') : null; - return { ...state, receive, destRegion, pickerTarget: null }; + const destRail = receive.type === 'fiat' ? getDefaultRail(receive.code) : null; + return { ...state, receive, destRegion, destRail, pickerTarget: null }; } case 'SET_SEND_NETWORK': { if (!state.send) return state; @@ -119,6 +123,8 @@ function reducer(state: FlowBuilderState, action: Action): FlowBuilderState { } case 'SET_SOURCE_RAIL': return { ...state, sourceRail: action.payload }; + case 'SET_DEST_RAIL': + return { ...state, destRail: action.payload }; case 'SET_SETTLEMENT_RAIL': return { ...state, settlementRail: action.payload }; case 'SET_SOURCE_REGION': @@ -133,16 +139,18 @@ function reducer(state: FlowBuilderState, action: Action): FlowBuilderState { return { ...state, pickerTarget: null }; case 'SWAP': { const newSend = state.receive; + const newReceive = state.send; const sourceFundingMode: SourceFundingMode = newSend?.type === 'crypto' ? 'realtime' : 'external'; return { ...state, send: newSend, - receive: state.send, + receive: newReceive, sourceRegion: state.destRegion, destRegion: state.sourceRegion, sourceRail: newSend?.type === 'fiat' ? getDefaultRail(newSend.code) : null, + destRail: newReceive?.type === 'fiat' ? getDefaultRail(newReceive.code) : null, sourceFundingMode, }; } @@ -228,6 +236,11 @@ export function useFlowBuilder() { [], ); + const setDestRail = useCallback( + (rail: string) => dispatch({ type: 'SET_DEST_RAIL', payload: rail }), + [], + ); + const setSettlementRail = useCallback( (asset: string) => dispatch({ type: 'SET_SETTLEMENT_RAIL', payload: asset }), [], @@ -271,6 +284,7 @@ export function useFlowBuilder() { setReceiveNetwork, setSourceFundingMode, setSourceRail, + setDestRail, setSettlementRail, setSourceRegion, setDestRegion, diff --git a/components/grid-visualizer/src/lib/code-generator.ts b/components/grid-visualizer/src/lib/code-generator.ts index c93930cdf..4c7c34161 100644 --- a/components/grid-visualizer/src/lib/code-generator.ts +++ b/components/grid-visualizer/src/lib/code-generator.ts @@ -1,5 +1,5 @@ import { accountTypeSpecs } from '@/data/account-types'; -import { currencies } from '@/data/currencies'; +import { currencies, railDisplayName } from '@/data/currencies'; export interface ExamplePerson { fullName: string; @@ -67,11 +67,11 @@ function getJitPaymentMethod(source: CurrencySelection, sourceRail: string | nul return 'crypto transfer'; } if (sourceRail) { - return `${sourceRail} transfer`; + return `${railDisplayName(sourceRail)} transfer`; } const fiat = currencies.find((c) => c.code === source.code); if (fiat && fiat.instantRails.length > 0) { - return `${fiat.instantRails[0]} transfer`; + return `${railDisplayName(fiat.instantRails[0])} transfer`; } return 'bank transfer'; } @@ -88,6 +88,7 @@ export function generateSteps( destination: CurrencySelection, fundingModel: 'jit' | 'pre-funded', sourceRail?: string | null, + destRail?: string | null, ): ApiStep[] { const jitFunding = fundingModel === 'jit'; const steps: ApiStep[] = []; @@ -267,6 +268,14 @@ export function generateSteps( destinationType: 'ACCOUNT', accountId: 'ExternalAccount:', }; + // Singular `paymentRail` is a request field on the quote destination and + // is optional — omitted, Grid picks a default. The plural `paymentRails` + // is response-only (it reports what an account supports) and must never + // be sent. Internal destinations are excluded: funds credited to a Grid + // balance never traverse an external rail. + if (destination.type === 'fiat' && destRail) { + quoteDest.paymentRail = destRail; + } } else { quoteDest = { destinationType: 'ACCOUNT', diff --git a/components/grid-visualizer/src/lib/flow-path.ts b/components/grid-visualizer/src/lib/flow-path.ts index 09222ef5e..e6b3b3775 100644 --- a/components/grid-visualizer/src/lib/flow-path.ts +++ b/components/grid-visualizer/src/lib/flow-path.ts @@ -1,5 +1,5 @@ import type { CurrencySelection } from './code-generator'; -import { currencies } from '@/data/currencies'; +import { currencies, railDisplayName } from '@/data/currencies'; import { getSettlementRail } from '@/data/settlement-rails'; export type ActionColor = 'fiat' | 'btc' | 'stable'; @@ -89,6 +89,7 @@ export function buildFlowPath( sourceRegion?: string | null, destRegion?: string | null, sourceRail?: string | null, + destRail?: string | null, settlementRail?: string | null, ): FlowPath { const nodes: FlowNode[] = []; @@ -266,15 +267,18 @@ export function buildFlowPath( if (curr.type === 'endpoint' && !curr.isInternal && next.type === 'switch') { const srcFiatData = source.type === 'fiat' ? currencies.find((c) => c.code === source.code) : null; - const srcRail = sourceRail - ?? (srcFiatData - ? (srcFiatData.instantRails[0] ?? srcFiatData.allRails[0] ?? source.accountLabel) - : (source.network ?? source.accountLabel)); + const srcRailValue = sourceRail + ?? (srcFiatData ? (srcFiatData.instantRails[0] ?? srcFiatData.allRails[0]) : null); + const srcRail = srcRailValue + ? railDisplayName(srcRailValue) + : (source.network ?? source.accountLabel); text = `Funds in via ${srcRail}`; } else if (curr.type === 'switch' && next.type === 'endpoint' && !next.isInternal) { const dstFiatData = destination.type === 'fiat' ? currencies.find((c) => c.code === destination.code) : null; - const dstRail = dstFiatData - ? (dstFiatData.instantRails[0] ?? dstFiatData.allRails[0] ?? destination.accountLabel) + const dstRailValue = destRail + ?? (dstFiatData ? (dstFiatData.instantRails[0] ?? dstFiatData.allRails[0]) : null); + const dstRail = dstRailValue + ? railDisplayName(dstRailValue) : (destination.network ?? destination.accountLabel); text = `Funds out via ${dstRail}`; } else if (curr.type === 'switch' && next.type === 'switch') {