Skip to content

Commit 2205f69

Browse files
committed
Handle optional swap destination wallet from swap-to-address core
The swap-to-address change in edge-core-js makes EdgeSwapRequest.toWallet and EdgeTxActionSwap.payoutWalletId optional (a private send has no destination wallet). Narrow toWallet to its always-present value in the wallet-to-wallet swap scenes, and tolerate a missing payoutWalletId in the transaction-action mappers, so these consumers compile against the new core.
1 parent 10e3630 commit 2205f69

8 files changed

Lines changed: 69 additions & 21 deletions

eslint.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ export default [
229229
'src/components/rows/EdgeRow.tsx',
230230

231231
'src/components/rows/PaymentMethodRow.tsx',
232-
'src/components/rows/SwapProviderRow.tsx',
232+
233233
'src/components/rows/TxCryptoAmountRow.tsx',
234234

235235
'src/components/scenes/ChangeMiningFeeScene.tsx',

src/actions/CategoriesActions.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,9 @@ export const getTxActionDisplayInfo = (
382382
? lstrings.transaction_details_swap_to_subcat_1s
383383
: lstrings.transaction_details_swap_from_subcat_1s
384384
const walletName =
385-
account.currencyWallets[action.payoutWalletId]?.name ??
386-
displayName
385+
(action.payoutWalletId != null
386+
? account.currencyWallets[action.payoutWalletId]?.name
387+
: undefined) ?? displayName
387388
edgeCategory = {
388389
category: 'transfer',
389390
subcategory: sprintf(toFromStr, walletName)

src/components/rows/SwapProviderRow.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@ export const SwapProviderRow: React.FC<Props> = (props: Props) => {
1818
const { quote } = props
1919
const { request, toNativeAmount, fromNativeAmount } = quote
2020
const { quoteFor } = request
21-
const { fromWallet, fromTokenId, toWallet, toTokenId } = request
21+
const { fromWallet, fromTokenId, toTokenId } = request
22+
// A wallet-to-wallet swap quote always carries a destination wallet; only a
23+
// swap-to-address request (its own flow) omits it.
24+
const toWallet = request.toWallet
25+
if (toWallet == null) {
26+
throw new Error('Swap quote is missing a destination wallet')
27+
}
2228
const theme = useTheme()
2329
const styles = getStyles(theme)
2430

src/components/scenes/SwapConfirmationScene.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,11 @@ export const SwapConfirmationScene: React.FC<Props> = (props: Props) => {
127127
const { quoteFor } = request
128128

129129
const priceImpact = React.useMemo(() => {
130-
const { fromWallet, fromTokenId, toWallet, toTokenId } = request
130+
const { fromWallet, fromTokenId, toTokenId } = request
131+
const toWallet = request.toWallet
132+
if (toWallet == null) {
133+
throw new Error('Swap quote is missing a destination wallet')
134+
}
131135

132136
const fromExchangeDenom = getExchangeDenom(
133137
fromWallet.currencyConfig,
@@ -282,7 +286,11 @@ export const SwapConfirmationScene: React.FC<Props> = (props: Props) => {
282286
request
283287
} = selectedQuote
284288
// Both fromCurrencyCode and toCurrencyCode will exist, since we set them:
285-
const { toWallet, toTokenId, fromWallet, fromTokenId } = request
289+
const { toTokenId, fromWallet, fromTokenId } = request
290+
const toWallet = request.toWallet
291+
if (toWallet == null) {
292+
throw new Error('Swap quote is missing a destination wallet')
293+
}
286294

287295
try {
288296
dispatch(logEvent('Exchange_Shift_Start'))
@@ -556,7 +564,11 @@ const getSwapInfo = (
556564
// Currency conversion tools:
557565
// Both fromCurrencyCode and toCurrencyCode will exist, since we set them:
558566
const { request } = quote
559-
const { fromWallet, toWallet, fromTokenId, toTokenId } = request
567+
const { fromWallet, fromTokenId, toTokenId } = request
568+
const toWallet = request.toWallet
569+
if (toWallet == null) {
570+
throw new Error('Swap quote is missing a destination wallet')
571+
}
560572

561573
// Format from amount:
562574
const fromDisplayDenomination = selectDisplayDenom(

src/components/scenes/SwapCreateScene.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,12 @@ export const SwapCreateScene: React.FC<Props> = props => {
228228
}
229229

230230
const getQuote = (swapRequest: EdgeSwapRequest): void => {
231+
// This scene only builds wallet-to-wallet swap requests, which always carry
232+
// a destination wallet (swap-to-address has its own flow).
233+
const toWallet = swapRequest.toWallet
234+
if (toWallet == null) {
235+
throw new Error('Swap request is missing a destination wallet')
236+
}
231237
if (exchangeInfo != null) {
232238
const disableSrc = checkDisableAsset(
233239
exchangeInfo.swap.disableAssets.source,
@@ -247,15 +253,15 @@ export const SwapCreateScene: React.FC<Props> = props => {
247253

248254
const disableDest = checkDisableAsset(
249255
exchangeInfo.swap.disableAssets.destination,
250-
swapRequest.toWallet.id,
256+
toWallet.id,
251257
toTokenId
252258
)
253259
if (disableDest) {
254260
showToast(
255261
sprintf(
256262
lstrings.swap_token_no_enabled_exchanges_2s,
257263
toCurrencyCode,
258-
swapRequest.toWallet.currencyInfo.displayName
264+
toWallet.currencyInfo.displayName
259265
)
260266
)
261267
return

src/components/scenes/SwapProcessingScene.tsx

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,22 @@ export const SwapProcessingScene: React.FC<Props> = (props: Props) => {
4949
swapRequest.fromTokenId
5050
)
5151
const toDenomination = useDisplayDenom(
52-
swapRequest.toWallet.currencyConfig,
53-
swapRequest.toTokenId
52+
// Wallet-to-wallet swaps always have a destination wallet here; fall back to
53+
// the source config only so this hook stays unconditional. Pair that
54+
// fallback with a null tokenId so the lookup never asks the source config
55+
// for a token it does not have (the result is unused once the guard below
56+
// throws on a missing destination wallet).
57+
(swapRequest.toWallet ?? swapRequest.fromWallet).currencyConfig,
58+
swapRequest.toWallet != null ? swapRequest.toTokenId : null
5459
)
5560

61+
// This scene only processes wallet-to-wallet swap requests, which always
62+
// carry a destination wallet (swap-to-address has its own flow).
63+
const toWallet = swapRequest.toWallet
64+
if (toWallet == null) {
65+
throw new Error('Swap request is missing a destination wallet')
66+
}
67+
5668
const doWork = async (isCancelled: () => boolean): Promise<void> => {
5769
const quotes = await account.fetchSwapQuotes(
5870
swapRequest,
@@ -70,7 +82,7 @@ export const SwapProcessingScene: React.FC<Props> = (props: Props) => {
7082
const fromWallet = swapRequest.fromWallet
7183
const fromAddresses = await fromWallet.getAddresses({ tokenId: null })
7284
const fromAddress = fromAddresses[0]?.publicAddress
73-
const targetPluginId = swapRequest.toWallet.currencyInfo.pluginId
85+
const targetPluginId = toWallet.currencyInfo.pluginId
7486

7587
let matchingWalletId: string | undefined
7688
for (const walletId of Object.keys(account.currencyWallets)) {
@@ -89,8 +101,8 @@ export const SwapProcessingScene: React.FC<Props> = (props: Props) => {
89101
}
90102
}
91103

92-
let finalToWalletId: string = swapRequest.toWallet.id
93-
let finalToWallet = swapRequest.toWallet
104+
let finalToWalletId: string
105+
let finalToWallet: typeof toWallet
94106
let isWalletCreated = false
95107
if (matchingWalletId == null) {
96108
// If not found, split from the source chain wallet to the destination
@@ -165,7 +177,7 @@ export const SwapProcessingScene: React.FC<Props> = (props: Props) => {
165177
params: {
166178
fromWalletId: swapRequest.fromWallet.id,
167179
fromTokenId: swapRequest.fromTokenId,
168-
toWalletId: swapRequest.toWallet.id,
180+
toWalletId: toWallet.id,
169181
toTokenId: swapRequest.toTokenId
170182
}
171183
})
@@ -189,7 +201,7 @@ export const SwapProcessingScene: React.FC<Props> = (props: Props) => {
189201
params: {
190202
fromWalletId: swapRequest.fromWallet.id,
191203
fromTokenId: swapRequest.fromTokenId,
192-
toWalletId: swapRequest.toWallet.id,
204+
toWalletId: toWallet.id,
193205
toTokenId: swapRequest.toTokenId,
194206
errorDisplayInfo
195207
}
@@ -313,7 +325,9 @@ function processSwapQuoteError({
313325
swapRequest.fromTokenId
314326
)
315327
const toCurrencyCode = getCurrencyCode(
316-
swapRequest.toWallet,
328+
// Wallet-to-wallet swaps always have a destination wallet here; the
329+
// fallback only keeps the type honest for swap-to-address requests.
330+
swapRequest.toWallet ?? swapRequest.fromWallet,
317331
swapRequest.toTokenId
318332
)
319333

@@ -362,10 +376,11 @@ function trackSwapError(error: unknown, swapRequest: EdgeSwapRequest): void {
362376
swapRequest.fromTokenId
363377
),
364378
swapToCurrency: getCurrencyCode(
365-
swapRequest.toWallet,
379+
swapRequest.toWallet ?? swapRequest.fromWallet,
366380
swapRequest.toTokenId
367381
),
368-
swapToWalletKind: swapRequest.toWallet.currencyInfo.pluginId,
382+
swapToWalletKind: (swapRequest.toWallet ?? swapRequest.fromWallet)
383+
.currencyInfo.pluginId,
369384
swapDirectionType: swapRequest.quoteFor
370385
})
371386
// Unsearchable context data:

src/components/scenes/TransactionDetailsScene.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,9 @@ const convertActionToSwapData = (
771771
payoutCurrencyCode,
772772
payoutTokenId: toAsset.tokenId,
773773
payoutNativeAmount: action.toAsset.nativeAmount ?? '0',
774-
payoutWalletId,
774+
// A swap-to-address (private send) has no payout wallet; EdgeTxSwap still
775+
// types this as required, so fall back to an empty id.
776+
payoutWalletId: payoutWalletId ?? '',
775777
refundAddress
776778
}
777779
return out

src/components/themed/ExchangeQuoteComponent.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,13 @@ interface Props {
2727
export const ExchangeQuote: React.FC<Props> = props => {
2828
const { fromTo, priceImpact, quote, showFeeWarning } = props
2929
const { request, fromNativeAmount, toNativeAmount, networkFee } = quote
30-
const { fromWallet, fromTokenId, toWallet, toTokenId } = request
30+
const { fromWallet, fromTokenId, toTokenId } = request
31+
// A wallet-to-wallet swap quote always carries a destination wallet; only a
32+
// swap-to-address request (its own flow) omits it.
33+
const toWallet = request.toWallet
34+
if (toWallet == null) {
35+
throw new Error('Swap quote is missing a destination wallet')
36+
}
3137

3238
const theme = useTheme()
3339
const styles = getStyles(theme)

0 commit comments

Comments
 (0)