0xtrails 0.8.3 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ccip-Bs-QcZXm.js → ccip-BKavX04a.js} +1 -1
- package/dist/gasless.d.ts.map +1 -1
- package/dist/{index-C_EsqqSn.js → index-D5kULpIU.js} +13339 -13299
- package/dist/index.js +3 -3
- package/dist/widget/components/ClassicSwap.d.ts +1 -0
- package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
- package/dist/widget/components/DynamicSizeInputField.d.ts.map +1 -1
- package/dist/widget/components/Fund.d.ts.map +1 -1
- package/dist/widget/components/FundSwap.d.ts +1 -0
- package/dist/widget/components/FundSwap.d.ts.map +1 -1
- package/dist/widget/components/Pay.d.ts.map +1 -1
- package/dist/widget/components/Swap.d.ts +1 -0
- package/dist/widget/components/Swap.d.ts.map +1 -1
- package/dist/widget/components/WidgetProviders.d.ts.map +1 -1
- package/dist/widget/hooks/useDefaultDestinationToken.d.ts +20 -0
- package/dist/widget/hooks/useDefaultDestinationToken.d.ts.map +1 -0
- package/dist/widget/hooks/{useDefaultTokenSelection.d.ts → useDefaultOriginToken.d.ts} +4 -16
- package/dist/widget/hooks/useDefaultOriginToken.d.ts.map +1 -0
- package/dist/widget/index.js +1 -1
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/gasless.ts +62 -32
- package/src/widget/components/ClassicSwap.tsx +135 -35
- package/src/widget/components/DynamicSizeInputField.tsx +2 -0
- package/src/widget/components/Fund.tsx +12 -11
- package/src/widget/components/FundSwap.tsx +1 -0
- package/src/widget/components/Pay.tsx +15 -14
- package/src/widget/components/Swap.tsx +1 -0
- package/src/widget/components/WidgetProviders.tsx +1 -6
- package/src/widget/hooks/useDefaultDestinationToken.tsx +173 -0
- package/src/widget/hooks/{useDefaultTokenSelection.tsx → useDefaultOriginToken.tsx} +58 -191
- package/src/widget/widget.tsx +2 -0
- package/dist/widget/hooks/useDefaultTokenSelection.d.ts.map +0 -1
|
@@ -18,7 +18,8 @@ import { useSelectedRecipient } from "../hooks/useSelectedRecipient.js"
|
|
|
18
18
|
import { useOriginSelectedToken } from "../hooks/useOriginSelectedToken.js"
|
|
19
19
|
import { useDestinationSelectedToken } from "../hooks/useDestinationSelectedToken.js"
|
|
20
20
|
import { useBalanceVisible } from "../hooks/useBalanceVisible.js"
|
|
21
|
-
import {
|
|
21
|
+
import { useDefaultOriginToken } from "../hooks/useDefaultOriginToken.js"
|
|
22
|
+
import { useDefaultDestinationToken } from "../hooks/useDefaultDestinationToken.js"
|
|
22
23
|
import { ChainList } from "./ChainList.js"
|
|
23
24
|
import { PercentageMaxButtons } from "./PercentageMaxButtons.js"
|
|
24
25
|
import { TokenSelectorButton } from "./TokenSelectorButton.js"
|
|
@@ -71,6 +72,7 @@ interface ClassicSwapProps {
|
|
|
71
72
|
onTrackToken?: (token: any) => void
|
|
72
73
|
title?: string
|
|
73
74
|
isSequenceWallet?: boolean
|
|
75
|
+
exactInputOnly?: boolean // When true, disables destination amount editing (exact input only)
|
|
74
76
|
}
|
|
75
77
|
|
|
76
78
|
export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
@@ -101,6 +103,7 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
101
103
|
onTrackToken,
|
|
102
104
|
title = "Swap",
|
|
103
105
|
isSequenceWallet = false,
|
|
106
|
+
exactInputOnly = false,
|
|
104
107
|
}) => {
|
|
105
108
|
const { mode } = useMode()
|
|
106
109
|
const { isBalanceVisible } = useBalanceVisible()
|
|
@@ -113,12 +116,26 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
113
116
|
const { selectedRecipient, setSelectedRecipient } = useSelectedRecipient()
|
|
114
117
|
const [isFlipped, setIsFlipped] = useState(false)
|
|
115
118
|
|
|
116
|
-
//
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
119
|
+
// Track manual selections to prevent auto-selection override
|
|
120
|
+
const [hasManualOriginSelection, setHasManualOriginSelection] =
|
|
121
|
+
useState(false)
|
|
122
|
+
const [hasManualDestinationSelection, setHasManualDestinationSelection] =
|
|
123
|
+
useState(false)
|
|
124
|
+
|
|
125
|
+
// Use a ref to track user actions to prevent race conditions with async state updates
|
|
126
|
+
const userActionRef = useRef({
|
|
127
|
+
hasManualOriginSelection: false,
|
|
128
|
+
hasManualDestinationSelection: false,
|
|
129
|
+
lastOriginSelectionTime: 0,
|
|
130
|
+
lastDestinationSelectionTime: 0,
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
// Use separated default token selection hooks
|
|
134
|
+
const { defaultOriginToken, isLoading: isLoadingOriginDefaults } =
|
|
135
|
+
useDefaultOriginToken()
|
|
136
|
+
|
|
137
|
+
const { defaultDestinationToken, isLoading: isLoadingDestinationDefaults } =
|
|
138
|
+
useDefaultDestinationToken(originToken)
|
|
122
139
|
|
|
123
140
|
const [originChainId, setOriginChainId] = useState<number | null | undefined>(
|
|
124
141
|
initialSelectedToken?.chainId || originToken?.chainId,
|
|
@@ -242,24 +259,33 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
242
259
|
}, [])
|
|
243
260
|
|
|
244
261
|
// Handle buy amount input changes
|
|
245
|
-
const handleBuyAmountChange = useCallback(
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
262
|
+
const handleBuyAmountChange = useCallback(
|
|
263
|
+
(value: string) => {
|
|
264
|
+
// Prevent switching to EXACT_OUTPUT if exactInputOnly mode is enabled
|
|
265
|
+
if (exactInputOnly) return
|
|
266
|
+
|
|
267
|
+
setTradeType(TradeType.EXACT_OUTPUT)
|
|
268
|
+
setBuyAmount(value)
|
|
269
|
+
setSellAmount("")
|
|
270
|
+
setLastInputType("buy")
|
|
271
|
+
},
|
|
272
|
+
[exactInputOnly],
|
|
273
|
+
)
|
|
251
274
|
|
|
252
275
|
// Handle buy input focus - only copy displayed value to state for editing
|
|
253
276
|
// Don't switch trade type or clear sellAmount here - that happens in handleBuyAmountChange
|
|
254
277
|
// This prevents unnecessary requotes when user just focuses without editing
|
|
255
278
|
const handleBuyInputFocus = useCallback(() => {
|
|
279
|
+
// Skip if exactInputOnly mode is enabled
|
|
280
|
+
if (exactInputOnly) return
|
|
281
|
+
|
|
256
282
|
// When focusing on buy field in EXACT_INPUT mode, copy the calculated value
|
|
257
283
|
// to buyAmount state so user can edit it. The actual mode switch happens
|
|
258
284
|
// when the user starts typing (in handleBuyAmountChange)
|
|
259
285
|
if (tradeType === TradeType.EXACT_INPUT && toAmountDisplay && !buyAmount) {
|
|
260
286
|
setBuyAmount(toAmountDisplay)
|
|
261
287
|
}
|
|
262
|
-
}, [tradeType, toAmountDisplay, buyAmount])
|
|
288
|
+
}, [tradeType, toAmountDisplay, buyAmount, exactInputOnly])
|
|
263
289
|
|
|
264
290
|
// Update amounts when quote is received
|
|
265
291
|
useEffect(() => {
|
|
@@ -285,9 +311,9 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
285
311
|
}
|
|
286
312
|
}, [amountRaw, onAmountUpdate])
|
|
287
313
|
|
|
288
|
-
// Auto-select origin token using
|
|
314
|
+
// Auto-select origin token using separated hook
|
|
289
315
|
useEffect(() => {
|
|
290
|
-
if (!originToken && !
|
|
316
|
+
if (!originToken && !isLoadingOriginDefaults && defaultOriginToken) {
|
|
291
317
|
logger.console.log(
|
|
292
318
|
"[trails-sdk] Auto-selecting origin token:",
|
|
293
319
|
defaultOriginToken,
|
|
@@ -295,13 +321,33 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
295
321
|
setOriginToken(defaultOriginToken as any)
|
|
296
322
|
setOriginChainId(defaultOriginToken.chainId)
|
|
297
323
|
}
|
|
298
|
-
}, [originToken,
|
|
324
|
+
}, [originToken, isLoadingOriginDefaults, defaultOriginToken, setOriginToken])
|
|
299
325
|
|
|
300
|
-
// Auto-select destination token using
|
|
326
|
+
// Auto-select destination token using separated hook
|
|
301
327
|
// Note: In swap mode, we still auto-select a destination even if toToken is provided,
|
|
302
328
|
// since the user needs a starting point to modify
|
|
329
|
+
// IMPORTANT: Only auto-select if user hasn't made manual selections to prevent override
|
|
303
330
|
useEffect(() => {
|
|
304
|
-
|
|
331
|
+
// Prevent race conditions by checking both state and ref
|
|
332
|
+
const hasRecentOriginSelection =
|
|
333
|
+
userActionRef.current.hasManualOriginSelection ||
|
|
334
|
+
hasManualOriginSelection ||
|
|
335
|
+
(userActionRef.current.lastOriginSelectionTime > 0 &&
|
|
336
|
+
Date.now() - userActionRef.current.lastOriginSelectionTime < 1000) // 1 second cooldown
|
|
337
|
+
|
|
338
|
+
const hasRecentDestSelection =
|
|
339
|
+
userActionRef.current.hasManualDestinationSelection ||
|
|
340
|
+
hasManualDestinationSelection ||
|
|
341
|
+
(userActionRef.current.lastDestinationSelectionTime > 0 &&
|
|
342
|
+
Date.now() - userActionRef.current.lastDestinationSelectionTime < 1000) // 1 second cooldown
|
|
343
|
+
|
|
344
|
+
if (
|
|
345
|
+
!destinationToken &&
|
|
346
|
+
!isLoadingDestinationDefaults &&
|
|
347
|
+
defaultDestinationToken &&
|
|
348
|
+
!hasRecentDestSelection &&
|
|
349
|
+
!hasRecentOriginSelection // Don't auto-select destination if user recently selected origin
|
|
350
|
+
) {
|
|
305
351
|
logger.console.log(
|
|
306
352
|
"[trails-sdk] Auto-selecting destination token:",
|
|
307
353
|
defaultDestinationToken,
|
|
@@ -317,8 +363,10 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
317
363
|
}
|
|
318
364
|
}, [
|
|
319
365
|
destinationToken,
|
|
320
|
-
|
|
366
|
+
isLoadingDestinationDefaults,
|
|
321
367
|
defaultDestinationToken,
|
|
368
|
+
hasManualDestinationSelection,
|
|
369
|
+
hasManualOriginSelection,
|
|
322
370
|
setDestinationToken,
|
|
323
371
|
setSelectedDestToken,
|
|
324
372
|
setSelectedDestinationChain,
|
|
@@ -384,18 +432,35 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
384
432
|
setSelectedDestinationChain(newChain)
|
|
385
433
|
}
|
|
386
434
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
435
|
+
// Flipping is an intentional user action, so maintain manual selection state
|
|
436
|
+
// Both tokens are still manually selected, just swapped
|
|
437
|
+
if (hasManualOriginSelection || hasManualDestinationSelection) {
|
|
438
|
+
setHasManualOriginSelection(true)
|
|
439
|
+
setHasManualDestinationSelection(true)
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if (exactInputOnly) {
|
|
443
|
+
// When exactInputOnly is enabled, always maintain EXACT_INPUT mode
|
|
444
|
+
// Move the sell amount to the new origin (what was destination)
|
|
445
|
+
setSellAmount(tempSellAmount)
|
|
446
|
+
setBuyAmount("") // Clear buy amount to get fresh quote
|
|
397
447
|
setTradeType(TradeType.EXACT_INPUT)
|
|
398
448
|
setLastInputType("sell")
|
|
449
|
+
} else {
|
|
450
|
+
// Normal flip behavior - switch trade types
|
|
451
|
+
if (tradeType === TradeType.EXACT_INPUT) {
|
|
452
|
+
// Move the user-entered sell amount into the buy field and treat it as exact output
|
|
453
|
+
setBuyAmount(tempSellAmount)
|
|
454
|
+
setSellAmount("")
|
|
455
|
+
setTradeType(TradeType.EXACT_OUTPUT)
|
|
456
|
+
setLastInputType("buy")
|
|
457
|
+
} else {
|
|
458
|
+
// If we were in EXACT_OUTPUT, use the current buy amount as the new sell amount
|
|
459
|
+
setSellAmount(tempBuyAmount)
|
|
460
|
+
setBuyAmount("")
|
|
461
|
+
setTradeType(TradeType.EXACT_INPUT)
|
|
462
|
+
setLastInputType("sell")
|
|
463
|
+
}
|
|
399
464
|
}
|
|
400
465
|
}, [
|
|
401
466
|
originToken,
|
|
@@ -412,12 +477,19 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
412
477
|
buyAmount,
|
|
413
478
|
toAmountDisplay,
|
|
414
479
|
amount,
|
|
480
|
+
hasManualOriginSelection,
|
|
481
|
+
hasManualDestinationSelection,
|
|
482
|
+
exactInputOnly,
|
|
415
483
|
])
|
|
416
484
|
|
|
417
485
|
// Handle source token selection from full-screen selector
|
|
418
486
|
const handleSourceTokenSelectorSelect = useCallback(
|
|
419
487
|
(token: Token) => {
|
|
420
|
-
if
|
|
488
|
+
// Only flip if it's the exact same token (same contract address AND chain ID)
|
|
489
|
+
if (
|
|
490
|
+
token.contractAddress === destinationToken?.contractAddress &&
|
|
491
|
+
token.chainId === destinationToken?.chainId
|
|
492
|
+
) {
|
|
421
493
|
handleFlip()
|
|
422
494
|
}
|
|
423
495
|
|
|
@@ -435,6 +507,11 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
435
507
|
setOriginChainId(token.chainId)
|
|
436
508
|
setShowSourceTokenSelector(false)
|
|
437
509
|
|
|
510
|
+
// Mark as manual selection to prevent auto-selection override
|
|
511
|
+
setHasManualOriginSelection(true)
|
|
512
|
+
userActionRef.current.hasManualOriginSelection = true
|
|
513
|
+
userActionRef.current.lastOriginSelectionTime = Date.now()
|
|
514
|
+
|
|
438
515
|
onTrackToken?.(token)
|
|
439
516
|
logger.console.log("[trails-sdk] selected origin token", token)
|
|
440
517
|
},
|
|
@@ -445,6 +522,7 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
445
522
|
originToken,
|
|
446
523
|
handleFlip,
|
|
447
524
|
destinationToken?.contractAddress,
|
|
525
|
+
destinationToken?.chainId,
|
|
448
526
|
destinationToken,
|
|
449
527
|
],
|
|
450
528
|
)
|
|
@@ -452,7 +530,11 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
452
530
|
// Handle destination token selection from full-screen selector
|
|
453
531
|
const handleDestinationTokenSelectorSelect = useCallback(
|
|
454
532
|
(token: Token) => {
|
|
455
|
-
if
|
|
533
|
+
// Only flip if it's the exact same token (same contract address AND chain ID)
|
|
534
|
+
if (
|
|
535
|
+
token.contractAddress === originToken?.contractAddress &&
|
|
536
|
+
token.chainId === originToken?.chainId
|
|
537
|
+
) {
|
|
456
538
|
handleFlip()
|
|
457
539
|
}
|
|
458
540
|
|
|
@@ -466,6 +548,12 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
466
548
|
}
|
|
467
549
|
|
|
468
550
|
setShowDestinationTokenSelector(false)
|
|
551
|
+
|
|
552
|
+
// Mark as manual selection to prevent auto-selection override
|
|
553
|
+
setHasManualDestinationSelection(true)
|
|
554
|
+
userActionRef.current.hasManualDestinationSelection = true
|
|
555
|
+
userActionRef.current.lastDestinationSelectionTime = Date.now()
|
|
556
|
+
|
|
469
557
|
onTrackToken?.(token)
|
|
470
558
|
logger.console.log("[trails-sdk] selected destination token", token)
|
|
471
559
|
},
|
|
@@ -475,6 +563,7 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
475
563
|
setSelectedDestinationChain,
|
|
476
564
|
onTrackToken,
|
|
477
565
|
originToken?.contractAddress,
|
|
566
|
+
originToken?.chainId,
|
|
478
567
|
handleFlip,
|
|
479
568
|
],
|
|
480
569
|
)
|
|
@@ -482,7 +571,11 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
482
571
|
// Handle recent token selection
|
|
483
572
|
const handleRecentTokenSelect = useCallback(
|
|
484
573
|
(token: any) => {
|
|
485
|
-
if
|
|
574
|
+
// Only flip if it's the exact same token (same contract address AND chain ID)
|
|
575
|
+
if (
|
|
576
|
+
token.contractAddress === originToken?.contractAddress &&
|
|
577
|
+
token.chainId === originToken?.chainId
|
|
578
|
+
) {
|
|
486
579
|
handleFlip()
|
|
487
580
|
}
|
|
488
581
|
|
|
@@ -498,6 +591,7 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
498
591
|
handleSourceTokenSelectorSelect,
|
|
499
592
|
handleDestinationTokenSelectorSelect,
|
|
500
593
|
originToken?.contractAddress,
|
|
594
|
+
originToken?.chainId,
|
|
501
595
|
handleFlip,
|
|
502
596
|
],
|
|
503
597
|
)
|
|
@@ -752,15 +846,21 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
752
846
|
? buyAmount
|
|
753
847
|
: buyAmount || toAmountDisplay || ""
|
|
754
848
|
}
|
|
755
|
-
onChange={
|
|
756
|
-
|
|
849
|
+
onChange={
|
|
850
|
+
exactInputOnly
|
|
851
|
+
? undefined
|
|
852
|
+
: (e) => handleBuyAmountChange(e.target.value)
|
|
853
|
+
}
|
|
854
|
+
onFocus={exactInputOnly ? undefined : handleBuyInputFocus}
|
|
757
855
|
isLoading={
|
|
758
856
|
isLoadingQuote && tradeType === TradeType.EXACT_INPUT
|
|
759
857
|
}
|
|
760
858
|
readOnly={
|
|
859
|
+
exactInputOnly ||
|
|
761
860
|
(tradeType === TradeType.EXACT_INPUT && isLoadingQuote) ||
|
|
762
861
|
!!toAmount
|
|
763
862
|
}
|
|
863
|
+
disabled={exactInputOnly}
|
|
764
864
|
showPlaceholderStyle={!amount}
|
|
765
865
|
variant="default"
|
|
766
866
|
/>
|
|
@@ -34,6 +34,7 @@ export const DynamicSizeInputField = forwardRef<
|
|
|
34
34
|
showPlaceholderStyle = false,
|
|
35
35
|
onFocus,
|
|
36
36
|
onBlur,
|
|
37
|
+
disabled,
|
|
37
38
|
...restProps
|
|
38
39
|
},
|
|
39
40
|
ref,
|
|
@@ -88,6 +89,7 @@ export const DynamicSizeInputField = forwardRef<
|
|
|
88
89
|
onChange={handleChange}
|
|
89
90
|
onFocus={onFocus}
|
|
90
91
|
onBlur={onBlur}
|
|
92
|
+
disabled={disabled}
|
|
91
93
|
placeholder={placeholder}
|
|
92
94
|
autoComplete="off"
|
|
93
95
|
className={
|
|
@@ -14,7 +14,8 @@ import { useSwapAmount } from "../hooks/useSwapAmount.js"
|
|
|
14
14
|
import { useMode } from "../hooks/useMode.js"
|
|
15
15
|
import { useBalanceVisible } from "../hooks/useBalanceVisible.js"
|
|
16
16
|
import { useCurrentScreen } from "../hooks/useCurrentScreen.js"
|
|
17
|
-
import {
|
|
17
|
+
import { useDefaultOriginToken } from "../hooks/useDefaultOriginToken.js"
|
|
18
|
+
import { useDefaultDestinationToken } from "../hooks/useDefaultDestinationToken.js"
|
|
18
19
|
import { useTargetAmount } from "../hooks/useTargetAmount.js"
|
|
19
20
|
import { TokenImage } from "./TokenImage.js"
|
|
20
21
|
import { Identicon } from "./Identicon.js"
|
|
@@ -109,12 +110,12 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
109
110
|
const { setCurrentScreen } = useCurrentScreen()
|
|
110
111
|
const { targetAmountUsd } = useTargetAmount()
|
|
111
112
|
|
|
112
|
-
// Use
|
|
113
|
-
const {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
113
|
+
// Use separated default token selection hooks
|
|
114
|
+
const { defaultOriginToken, isLoading: isLoadingOriginDefaults } =
|
|
115
|
+
useDefaultOriginToken()
|
|
116
|
+
|
|
117
|
+
const { defaultDestinationToken, isLoading: isLoadingDestinationDefaults } =
|
|
118
|
+
useDefaultDestinationToken(originToken)
|
|
118
119
|
|
|
119
120
|
// Local state for fund-specific functionality
|
|
120
121
|
const [isInputTypeUsd, setIsInputTypeUsd] = useState(false)
|
|
@@ -176,14 +177,14 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
176
177
|
|
|
177
178
|
// Auto-select origin and destination tokens using new hook
|
|
178
179
|
useEffect(() => {
|
|
179
|
-
if (!originToken && !
|
|
180
|
+
if (!originToken && !isLoadingOriginDefaults && defaultOriginToken) {
|
|
180
181
|
logger.console.log(
|
|
181
182
|
"[trails-sdk] Auto-selecting origin token:",
|
|
182
183
|
defaultOriginToken,
|
|
183
184
|
)
|
|
184
185
|
setOriginToken(defaultOriginToken as any)
|
|
185
186
|
}
|
|
186
|
-
}, [originToken,
|
|
187
|
+
}, [originToken, isLoadingOriginDefaults, defaultOriginToken, setOriginToken])
|
|
187
188
|
|
|
188
189
|
// Auto-select destination token using new hook
|
|
189
190
|
useEffect(() => {
|
|
@@ -191,7 +192,7 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
191
192
|
!globalDestinationToken &&
|
|
192
193
|
!toToken &&
|
|
193
194
|
originToken &&
|
|
194
|
-
!
|
|
195
|
+
!isLoadingDestinationDefaults &&
|
|
195
196
|
defaultDestinationToken
|
|
196
197
|
) {
|
|
197
198
|
logger.console.log(
|
|
@@ -214,7 +215,7 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
214
215
|
originToken,
|
|
215
216
|
globalDestinationToken,
|
|
216
217
|
toToken,
|
|
217
|
-
|
|
218
|
+
isLoadingDestinationDefaults,
|
|
218
219
|
defaultDestinationToken,
|
|
219
220
|
setDestinationToken,
|
|
220
221
|
setSelectedDestToken,
|
|
@@ -14,7 +14,8 @@ import { useSwapAmount } from "../hooks/useSwapAmount.js"
|
|
|
14
14
|
import { useTokenList } from "../hooks/useTokenList.js"
|
|
15
15
|
import { useMode } from "../hooks/useMode.js"
|
|
16
16
|
import { useCurrentScreen } from "../hooks/useCurrentScreen.js"
|
|
17
|
-
import {
|
|
17
|
+
import { useDefaultOriginToken } from "../hooks/useDefaultOriginToken.js"
|
|
18
|
+
import { useDefaultDestinationToken } from "../hooks/useDefaultDestinationToken.js"
|
|
18
19
|
import { usePayMessage } from "../hooks/usePayMessage.js"
|
|
19
20
|
import { useTargetAmount } from "../hooks/useTargetAmount.js"
|
|
20
21
|
import { TokenImage } from "./TokenImage.js"
|
|
@@ -120,19 +121,19 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
120
121
|
const { setCurrentScreen } = useCurrentScreen()
|
|
121
122
|
const { targetAmountUsd } = useTargetAmount()
|
|
122
123
|
|
|
123
|
-
// Use
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
124
|
+
// Use global origin token state or initial prop
|
|
125
|
+
const originToken = globalOriginToken || initialOriginToken
|
|
126
|
+
|
|
127
|
+
// Use separated default token selection hooks
|
|
128
|
+
const { defaultOriginToken, isLoading: isLoadingOriginDefaults } =
|
|
129
|
+
useDefaultOriginToken()
|
|
130
|
+
|
|
131
|
+
const { defaultDestinationToken, isLoading: isLoadingDestinationDefaults } =
|
|
132
|
+
useDefaultDestinationToken(originToken)
|
|
129
133
|
|
|
130
134
|
// Use pay message hook for payment request display
|
|
131
135
|
const { message: payMessage } = usePayMessage()
|
|
132
136
|
|
|
133
|
-
// Use global origin token state or initial prop
|
|
134
|
-
const originToken = globalOriginToken || initialOriginToken
|
|
135
|
-
|
|
136
137
|
// Local state for pay-specific functionality
|
|
137
138
|
const [tokenAmountForBackend, setTokenAmountForBackend] = useState("")
|
|
138
139
|
const [inputDisplayValue, setInputDisplayValue] = useState("")
|
|
@@ -230,14 +231,14 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
230
231
|
|
|
231
232
|
// Auto-select origin token using new hook
|
|
232
233
|
useEffect(() => {
|
|
233
|
-
if (!originToken && !
|
|
234
|
+
if (!originToken && !isLoadingOriginDefaults && defaultOriginToken) {
|
|
234
235
|
logger.console.log(
|
|
235
236
|
"[trails-sdk] Auto-selecting origin token:",
|
|
236
237
|
defaultOriginToken,
|
|
237
238
|
)
|
|
238
239
|
setOriginToken(defaultOriginToken as any)
|
|
239
240
|
}
|
|
240
|
-
}, [originToken,
|
|
241
|
+
}, [originToken, isLoadingOriginDefaults, defaultOriginToken, setOriginToken])
|
|
241
242
|
|
|
242
243
|
// Initialize destination token from props or auto-select
|
|
243
244
|
useEffect(() => {
|
|
@@ -347,7 +348,7 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
347
348
|
// Prefer global destination token if set
|
|
348
349
|
const destTokenToUse = globalDestinationToken || defaultDestinationToken
|
|
349
350
|
|
|
350
|
-
if (destTokenToUse && !
|
|
351
|
+
if (destTokenToUse && !isLoadingDestinationDefaults) {
|
|
351
352
|
logger.console.log("[trails-sdk] Initializing destination token:", {
|
|
352
353
|
symbol: destTokenToUse.symbol,
|
|
353
354
|
chainId: destTokenToUse.chainId,
|
|
@@ -375,7 +376,7 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
375
376
|
toToken,
|
|
376
377
|
globalDestinationToken,
|
|
377
378
|
defaultDestinationToken,
|
|
378
|
-
|
|
379
|
+
isLoadingDestinationDefaults,
|
|
379
380
|
selectedDestToken?.symbol,
|
|
380
381
|
setDestinationToken,
|
|
381
382
|
setSelectedDestToken,
|
|
@@ -15,7 +15,6 @@ import { BalanceVisibleProvider } from "../hooks/useBalanceVisible.js"
|
|
|
15
15
|
import { ThemeProvider as ThemePreferenceProvider } from "../hooks/useTheme.js"
|
|
16
16
|
import { SelectedFundMethodProvider } from "../hooks/useSelectedFundMethod.js"
|
|
17
17
|
import { EarnPoolProvider } from "../hooks/useEarnPool.js"
|
|
18
|
-
import { DefaultTokenSelectionProvider } from "../hooks/useDefaultTokenSelection.js"
|
|
19
18
|
|
|
20
19
|
// Default props for hook modal (minimal required config)
|
|
21
20
|
const DEFAULT_HOOK_MODAL_PROPS: TrailsWidgetProps = {
|
|
@@ -52,11 +51,7 @@ export function WidgetProviders({
|
|
|
52
51
|
<BalanceVisibleProvider>
|
|
53
52
|
<ThemePreferenceProvider>
|
|
54
53
|
<SelectedFundMethodProvider>
|
|
55
|
-
<EarnPoolProvider>
|
|
56
|
-
<DefaultTokenSelectionProvider>
|
|
57
|
-
{children}
|
|
58
|
-
</DefaultTokenSelectionProvider>
|
|
59
|
-
</EarnPoolProvider>
|
|
54
|
+
<EarnPoolProvider>{children}</EarnPoolProvider>
|
|
60
55
|
</SelectedFundMethodProvider>
|
|
61
56
|
</ThemePreferenceProvider>
|
|
62
57
|
</BalanceVisibleProvider>
|