0xtrails 0.1.13 → 0.2.1
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/aave.d.ts.map +1 -1
- package/dist/analytics.d.ts +12 -2
- package/dist/analytics.d.ts.map +1 -1
- package/dist/apiClient.d.ts +1 -1
- package/dist/apiClient.d.ts.map +1 -1
- package/dist/{ccip-D3gTQONK.js → ccip-BbfANth7.js} +12 -12
- package/dist/cctp.d.ts.map +1 -1
- package/dist/cctpqueue.d.ts +3 -3
- package/dist/cctpqueue.d.ts.map +1 -1
- package/dist/chains.d.ts.map +1 -1
- package/dist/config.d.ts +18 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/constants.d.ts +6 -5
- package/dist/constants.d.ts.map +1 -1
- package/dist/contractUtils.d.ts +2 -0
- package/dist/contractUtils.d.ts.map +1 -1
- package/dist/customChains.d.ts +24 -0
- package/dist/customChains.d.ts.map +1 -0
- package/dist/gasless.d.ts +19 -7
- package/dist/gasless.d.ts.map +1 -1
- package/dist/{index-CnUM7lKf.js → index-WpIVoh3X.js} +36741 -31761
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +405 -394
- package/dist/indexerClient.d.ts +10 -0
- package/dist/indexerClient.d.ts.map +1 -1
- package/dist/intentEntrypoint.d.ts +122 -0
- package/dist/intentEntrypoint.d.ts.map +1 -0
- package/dist/intents.d.ts +5 -3
- package/dist/intents.d.ts.map +1 -1
- package/dist/metaTxnMonitor.d.ts.map +1 -1
- package/dist/morpho.d.ts.map +1 -1
- package/dist/pools.d.ts +3 -1
- package/dist/pools.d.ts.map +1 -1
- package/dist/prepareSend.d.ts +18 -9
- package/dist/prepareSend.d.ts.map +1 -1
- package/dist/prices.d.ts +1 -1
- package/dist/prices.d.ts.map +1 -1
- package/dist/relaySdk.d.ts.map +1 -1
- package/dist/relayer.d.ts.map +1 -1
- package/dist/toast.d.ts +9 -0
- package/dist/toast.d.ts.map +1 -0
- package/dist/tokenBalances.d.ts +6 -2
- package/dist/tokenBalances.d.ts.map +1 -1
- package/dist/tokens.d.ts.map +1 -1
- package/dist/trails.d.ts +6 -5
- package/dist/trails.d.ts.map +1 -1
- package/dist/trailsClient.d.ts +12 -0
- package/dist/trailsClient.d.ts.map +1 -0
- package/dist/trailsRouter.d.ts +22 -0
- package/dist/trailsRouter.d.ts.map +1 -0
- package/dist/transactions.d.ts +8 -1
- package/dist/transactions.d.ts.map +1 -1
- package/dist/wallets.d.ts.map +1 -1
- package/dist/widget/components/AccountActionsDropdown.d.ts.map +1 -1
- package/dist/widget/components/AccountIntentTransactionHistory.d.ts.map +1 -1
- package/dist/widget/components/AccountSettings.d.ts +7 -0
- package/dist/widget/components/AccountSettings.d.ts.map +1 -0
- package/dist/widget/components/ChainList.d.ts +0 -1
- package/dist/widget/components/ChainList.d.ts.map +1 -1
- package/dist/widget/components/ClassicSwap.d.ts +46 -0
- package/dist/widget/components/ClassicSwap.d.ts.map +1 -0
- package/dist/widget/components/ConfigDisplay.d.ts.map +1 -1
- package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
- package/dist/widget/components/ConnectedWallets.d.ts +9 -0
- package/dist/widget/components/ConnectedWallets.d.ts.map +1 -0
- package/dist/widget/components/DebugMenu.d.ts.map +1 -1
- package/dist/widget/components/DebugScreensList.d.ts.map +1 -1
- package/dist/widget/components/DebugToast.d.ts +3 -0
- package/dist/widget/components/DebugToast.d.ts.map +1 -0
- package/dist/widget/components/Earn.d.ts.map +1 -1
- package/dist/widget/components/EarnPools.d.ts.map +1 -1
- package/dist/widget/components/FeeOption.d.ts +22 -0
- package/dist/widget/components/FeeOption.d.ts.map +1 -0
- package/dist/widget/components/FeeOptions.d.ts +13 -17
- package/dist/widget/components/FeeOptions.d.ts.map +1 -1
- package/dist/widget/components/Fund.d.ts +44 -0
- package/dist/widget/components/Fund.d.ts.map +1 -0
- package/dist/widget/components/FundMethods.d.ts +1 -1
- package/dist/widget/components/FundMethods.d.ts.map +1 -1
- package/dist/widget/components/FundSendForm.d.ts.map +1 -1
- package/dist/widget/components/Identicon.d.ts +9 -0
- package/dist/widget/components/Identicon.d.ts.map +1 -0
- package/dist/widget/components/MeshConnectExchanges.d.ts +5 -2
- package/dist/widget/components/MeshConnectExchanges.d.ts.map +1 -1
- package/dist/widget/components/MeshConnectFlow.d.ts +2 -0
- package/dist/widget/components/MeshConnectFlow.d.ts.map +1 -1
- package/dist/widget/components/NativeGasOption.d.ts +12 -0
- package/dist/widget/components/NativeGasOption.d.ts.map +1 -0
- package/dist/widget/components/Pay.d.ts +46 -0
- package/dist/widget/components/Pay.d.ts.map +1 -0
- package/dist/widget/components/PaySendForm.d.ts.map +1 -1
- package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
- package/dist/widget/components/Receive.d.ts.map +1 -1
- package/dist/widget/components/RecentTokens.d.ts.map +1 -1
- package/dist/widget/components/Recipients.d.ts +9 -0
- package/dist/widget/components/Recipients.d.ts.map +1 -0
- package/dist/widget/components/RefundWarning.d.ts +9 -0
- package/dist/widget/components/RefundWarning.d.ts.map +1 -0
- package/dist/widget/components/SimpleSwap.d.ts.map +1 -1
- package/dist/widget/components/Swap.d.ts.map +1 -1
- package/dist/widget/components/SwapSettings.d.ts +1 -5
- package/dist/widget/components/SwapSettings.d.ts.map +1 -1
- package/dist/widget/components/ThemeProvider.d.ts.map +1 -1
- package/dist/widget/components/ThemeSyncer.d.ts +6 -0
- package/dist/widget/components/ThemeSyncer.d.ts.map +1 -0
- package/dist/widget/components/Toast.d.ts +24 -0
- package/dist/widget/components/Toast.d.ts.map +1 -0
- package/dist/widget/components/TokenList.d.ts.map +1 -1
- package/dist/widget/components/TokenSelector.d.ts.map +1 -1
- package/dist/widget/components/TransactionDetails.d.ts.map +1 -1
- package/dist/widget/components/TruncatedAddress.d.ts +2 -0
- package/dist/widget/components/TruncatedAddress.d.ts.map +1 -1
- package/dist/widget/components/UserPreferences.d.ts +7 -0
- package/dist/widget/components/UserPreferences.d.ts.map +1 -0
- package/dist/widget/hooks/useBack.d.ts +2 -0
- package/dist/widget/hooks/useBack.d.ts.map +1 -1
- package/dist/widget/hooks/useBalanceVisible.d.ts +1 -0
- package/dist/widget/hooks/useBalanceVisible.d.ts.map +1 -1
- package/dist/widget/hooks/useCheckout.d.ts.map +1 -1
- package/dist/widget/hooks/useCurrentScreen.d.ts +1 -1
- package/dist/widget/hooks/useCurrentScreen.d.ts.map +1 -1
- package/dist/widget/hooks/useDebugScreens.d.ts +1 -1
- package/dist/widget/hooks/useDebugScreens.d.ts.map +1 -1
- package/dist/widget/hooks/useDefaultTokenSelection.d.ts +54 -0
- package/dist/widget/hooks/useDefaultTokenSelection.d.ts.map +1 -0
- package/dist/widget/hooks/useIntentTransactionHistory.d.ts.map +1 -1
- package/dist/widget/hooks/usePayMessage.d.ts +34 -0
- package/dist/widget/hooks/usePayMessage.d.ts.map +1 -0
- package/dist/widget/hooks/useRecipients.d.ts +17 -0
- package/dist/widget/hooks/useRecipients.d.ts.map +1 -0
- package/dist/widget/hooks/useSelectedFeeToken.d.ts +32 -0
- package/dist/widget/hooks/useSelectedFeeToken.d.ts.map +1 -0
- package/dist/widget/hooks/useSelectedMeshExchange.d.ts +14 -0
- package/dist/widget/hooks/useSelectedMeshExchange.d.ts.map +1 -0
- package/dist/widget/hooks/useSelectedRecipient.d.ts +12 -0
- package/dist/widget/hooks/useSelectedRecipient.d.ts.map +1 -0
- package/dist/widget/hooks/useSendForm.d.ts +10 -13
- package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
- package/dist/widget/hooks/useSwapAmount.d.ts +13 -0
- package/dist/widget/hooks/useSwapAmount.d.ts.map +1 -0
- package/dist/widget/hooks/useSwapSettings.d.ts +16 -0
- package/dist/widget/hooks/useSwapSettings.d.ts.map +1 -0
- package/dist/widget/hooks/useTargetAmount.d.ts +5 -0
- package/dist/widget/hooks/useTargetAmount.d.ts.map +1 -0
- package/dist/widget/hooks/useTheme.d.ts +14 -0
- package/dist/widget/hooks/useTheme.d.ts.map +1 -0
- package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
- package/dist/widget/index.js +2 -2
- package/dist/widget/widget.d.ts +9 -0
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +38 -36
- package/src/aave.ts +6 -1
- package/src/analytics.ts +109 -53
- package/src/apiClient.ts +1 -1
- package/src/cctp.ts +6 -2
- package/src/cctpqueue.ts +7 -7
- package/src/chains.ts +18 -0
- package/src/config.ts +63 -17
- package/src/constants.ts +20 -16
- package/src/contractUtils.ts +33 -2
- package/src/customChains.ts +24 -0
- package/src/gasless.ts +162 -109
- package/src/index.ts +11 -1
- package/src/indexerClient.ts +73 -1
- package/src/intentEntrypoint.ts +218 -0
- package/src/intents.ts +85 -54
- package/src/metaTxnMonitor.ts +1 -0
- package/src/morpho.ts +13 -2
- package/src/pools.ts +68 -86
- package/src/prepareSend.ts +1719 -967
- package/src/prices.ts +51 -7
- package/src/relaySdk.ts +6 -4
- package/src/relayer.ts +6 -3
- package/src/toast.ts +110 -0
- package/src/tokenBalances.ts +112 -20
- package/src/tokens.ts +70 -7
- package/src/trails.ts +81 -80
- package/src/trailsClient.ts +48 -0
- package/src/{proxyCaller.ts → trailsRouter.ts} +25 -20
- package/src/transactions.ts +30 -88
- package/src/umd.tsx +1 -1
- package/src/wallets.ts +2 -1
- package/src/widget/assets/sequence-logo.svg +15 -0
- package/src/widget/compiled.css +2 -2
- package/src/widget/components/AccountActionsDropdown.tsx +18 -159
- package/src/widget/components/AccountIntentTransactionHistory.tsx +346 -63
- package/src/widget/components/AccountSettings.tsx +102 -0
- package/src/widget/components/ChainFilterDropdown.tsx +1 -1
- package/src/widget/components/ChainList.tsx +10 -20
- package/src/widget/components/ClassicSwap.tsx +921 -0
- package/src/widget/components/ConfigDisplay.tsx +41 -5
- package/src/widget/components/ConnectWallet.tsx +168 -11
- package/src/widget/components/ConnectedWallets.tsx +342 -0
- package/src/widget/components/DebugMenu.tsx +2 -0
- package/src/widget/components/DebugScreensList.tsx +3 -0
- package/src/widget/components/DebugToast.tsx +63 -0
- package/src/widget/components/Earn.tsx +112 -143
- package/src/widget/components/EarnPools.tsx +2 -4
- package/src/widget/components/EarnPoolsFilters.tsx +6 -6
- package/src/widget/components/FeeOption.tsx +78 -0
- package/src/widget/components/FeeOptions.tsx +192 -127
- package/src/widget/components/Fund.tsx +1236 -0
- package/src/widget/components/FundMethods.tsx +4 -4
- package/src/widget/components/FundSendForm.tsx +1 -34
- package/src/widget/components/Identicon.tsx +158 -0
- package/src/widget/components/MeshConnectExchanges.tsx +32 -3
- package/src/widget/components/MeshConnectFlow.tsx +23 -4
- package/src/widget/components/NativeGasOption.tsx +99 -0
- package/src/widget/components/Pay.tsx +1092 -0
- package/src/widget/components/PaySendForm.tsx +1 -38
- package/src/widget/components/QuoteDetails.tsx +1 -30
- package/src/widget/components/Receipt.tsx +1 -1
- package/src/widget/components/Receive.tsx +4 -2
- package/src/widget/components/RecentTokens.tsx +2 -1
- package/src/widget/components/Recipients.tsx +448 -0
- package/src/widget/components/RefundWarning.tsx +61 -0
- package/src/widget/components/ScreenHeader.tsx +1 -1
- package/src/widget/components/SimpleSwap.tsx +74 -58
- package/src/widget/components/Swap.tsx +35 -853
- package/src/widget/components/SwapSettings.tsx +5 -11
- package/src/widget/components/ThemeProvider.tsx +32 -0
- package/src/widget/components/ThemeSyncer.tsx +47 -0
- package/src/widget/components/Toast.tsx +315 -0
- package/src/widget/components/TokenList.tsx +2 -34
- package/src/widget/components/TokenSelector.tsx +14 -3
- package/src/widget/components/TransactionDetails.tsx +153 -13
- package/src/widget/components/TransferPendingVertical.tsx +1 -1
- package/src/widget/components/TruncatedAddress.tsx +5 -1
- package/src/widget/components/UserPreferences.tsx +155 -0
- package/src/widget/components/WalletList.tsx +1 -1
- package/src/widget/hooks/useBack.tsx +4 -0
- package/src/widget/hooks/useBalanceVisible.tsx +40 -2
- package/src/widget/hooks/useCheckout.ts +13 -0
- package/src/widget/hooks/useCurrentScreen.tsx +4 -0
- package/src/widget/hooks/useDebugScreens.ts +12 -2
- package/src/widget/hooks/useDefaultTokenSelection.tsx +471 -0
- package/src/widget/hooks/useIntentTransactionHistory.ts +212 -0
- package/src/widget/hooks/usePayMessage.tsx +370 -0
- package/src/widget/hooks/useRecipients.ts +168 -0
- package/src/widget/hooks/useSelectedFeeToken.tsx +299 -0
- package/src/widget/hooks/useSelectedMeshExchange.tsx +46 -0
- package/src/widget/hooks/useSelectedRecipient.tsx +48 -0
- package/src/widget/hooks/useSendForm.ts +257 -49
- package/src/widget/hooks/useSwapAmount.tsx +50 -0
- package/src/widget/hooks/useSwapSettings.tsx +100 -0
- package/src/widget/hooks/useTargetAmount.ts +23 -0
- package/src/widget/hooks/useTheme.tsx +80 -0
- package/src/widget/hooks/useTokenList.ts +20 -11
- package/src/widget/index.css +45 -21
- package/src/widget/widget.tsx +294 -136
- package/dist/address.d.ts +0 -2
- package/dist/address.d.ts.map +0 -1
- package/dist/proxyCaller.d.ts +0 -21
- package/dist/proxyCaller.d.ts.map +0 -1
- package/src/address.ts +0 -6
|
@@ -39,6 +39,9 @@ import { useResolveEnsAddress } from "../../ens.js"
|
|
|
39
39
|
import { etherlink } from "viem/chains"
|
|
40
40
|
import { logger } from "../../logger.js"
|
|
41
41
|
import { getIsContract } from "../../contractUtils.js"
|
|
42
|
+
import { useTrailsClient } from "../../trailsClient.js"
|
|
43
|
+
import { useTokenList } from "./useTokenList.js"
|
|
44
|
+
import { useSelectedFeeToken } from "./useSelectedFeeToken.js"
|
|
42
45
|
|
|
43
46
|
export interface Token {
|
|
44
47
|
id: number
|
|
@@ -116,19 +119,14 @@ export type UseSendProps = {
|
|
|
116
119
|
}
|
|
117
120
|
|
|
118
121
|
export type FeeOption = {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
tokenID: string | null
|
|
128
|
-
}
|
|
129
|
-
to: string
|
|
130
|
-
value: string
|
|
131
|
-
gasLimit: number
|
|
122
|
+
tokenAddress: string
|
|
123
|
+
tokenSymbol: string
|
|
124
|
+
tokenDecimals: number
|
|
125
|
+
amount: string
|
|
126
|
+
amountUSD: number
|
|
127
|
+
notEnoughBalance?: boolean
|
|
128
|
+
tokenImageUrl?: string
|
|
129
|
+
chainId?: number
|
|
132
130
|
}
|
|
133
131
|
|
|
134
132
|
export type UseSendReturn = {
|
|
@@ -178,6 +176,8 @@ export type UseSendReturn = {
|
|
|
178
176
|
quoteErrorPrettified: string | null
|
|
179
177
|
isSameTokenWithoutCustomCalldata: boolean
|
|
180
178
|
isRecipientContract: boolean
|
|
179
|
+
isSenderContractOnOrigin: boolean
|
|
180
|
+
isSenderContractOnDestination: boolean
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
export function useSendForm({
|
|
@@ -277,6 +277,7 @@ export function useSendForm({
|
|
|
277
277
|
recipient as `0x${string}`,
|
|
278
278
|
selectedDestinationChain.id,
|
|
279
279
|
)
|
|
280
|
+
logger.console.log("[trails-sdk] isRecipientContract:", isContract)
|
|
280
281
|
setIsRecipientContract(isContract)
|
|
281
282
|
} catch (error) {
|
|
282
283
|
logger.console.error(
|
|
@@ -293,6 +294,64 @@ export function useSendForm({
|
|
|
293
294
|
checkRecipientContract()
|
|
294
295
|
}, [recipient, selectedDestinationChain?.id])
|
|
295
296
|
|
|
297
|
+
// Check if sender is a contract address on origin chain
|
|
298
|
+
useEffect(() => {
|
|
299
|
+
const checkSenderContractOnOrigin = async () => {
|
|
300
|
+
if (account?.address && selectedToken?.chainId) {
|
|
301
|
+
try {
|
|
302
|
+
const isContract = await getIsContract(
|
|
303
|
+
account.address as `0x${string}`,
|
|
304
|
+
selectedToken.chainId,
|
|
305
|
+
)
|
|
306
|
+
logger.console.log(
|
|
307
|
+
"[trails-sdk] isSenderContractOnOrigin:",
|
|
308
|
+
isContract,
|
|
309
|
+
)
|
|
310
|
+
setIsSenderContractOnOrigin(isContract)
|
|
311
|
+
} catch (error) {
|
|
312
|
+
logger.console.error(
|
|
313
|
+
"[trails-sdk] Error checking if sender is contract on origin:",
|
|
314
|
+
error,
|
|
315
|
+
)
|
|
316
|
+
setIsSenderContractOnOrigin(false)
|
|
317
|
+
}
|
|
318
|
+
} else {
|
|
319
|
+
setIsSenderContractOnOrigin(false)
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
checkSenderContractOnOrigin()
|
|
324
|
+
}, [account?.address, selectedToken?.chainId])
|
|
325
|
+
|
|
326
|
+
// Check if sender is a contract address on destination chain
|
|
327
|
+
useEffect(() => {
|
|
328
|
+
const checkSenderContractOnDestination = async () => {
|
|
329
|
+
if (account?.address && selectedDestinationChain?.id) {
|
|
330
|
+
try {
|
|
331
|
+
const isContract = await getIsContract(
|
|
332
|
+
account.address as `0x${string}`,
|
|
333
|
+
selectedDestinationChain.id,
|
|
334
|
+
)
|
|
335
|
+
logger.console.log(
|
|
336
|
+
"[trails-sdk] isSenderContractOnDestination:",
|
|
337
|
+
isContract,
|
|
338
|
+
)
|
|
339
|
+
setIsSenderContractOnDestination(isContract)
|
|
340
|
+
} catch (error) {
|
|
341
|
+
logger.console.error(
|
|
342
|
+
"[trails-sdk] Error checking if sender is contract on destination:",
|
|
343
|
+
error,
|
|
344
|
+
)
|
|
345
|
+
setIsSenderContractOnDestination(false)
|
|
346
|
+
}
|
|
347
|
+
} else {
|
|
348
|
+
setIsSenderContractOnDestination(false)
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
checkSenderContractOnDestination()
|
|
353
|
+
}, [account?.address, selectedDestinationChain?.id])
|
|
354
|
+
|
|
296
355
|
const isCustomToken = useMemo(() => toToken?.startsWith("0x"), [toToken])
|
|
297
356
|
|
|
298
357
|
const {
|
|
@@ -354,7 +413,7 @@ export function useSendForm({
|
|
|
354
413
|
token = supportedTokens.find(
|
|
355
414
|
(token) =>
|
|
356
415
|
(isToTokenAddress // Match by specified destination token address or symbol
|
|
357
|
-
? token.contractAddress === toToken
|
|
416
|
+
? token.contractAddress.toLowerCase() === toToken.toLowerCase()
|
|
358
417
|
: token.symbol === toToken) &&
|
|
359
418
|
(toChainId // Match by specified destination chain id
|
|
360
419
|
? token.chainId === toChainId
|
|
@@ -372,22 +431,38 @@ export function useSendForm({
|
|
|
372
431
|
}, [selectedDestToken, defaultDestToken])
|
|
373
432
|
|
|
374
433
|
const apiClient = useAPIClient()
|
|
434
|
+
const trailsClient = useTrailsClient()
|
|
435
|
+
|
|
436
|
+
// Get user's token balances for balance checking
|
|
437
|
+
const { filteredTokensFormatted } = useTokenList({
|
|
438
|
+
onContinue: () => {}, // Not used for balance checking
|
|
439
|
+
onError: () => {}, // Not used for balance checking
|
|
440
|
+
fundMethod: undefined,
|
|
441
|
+
allSupportedTokens: true, // Get all tokens for balance checking
|
|
442
|
+
})
|
|
375
443
|
|
|
376
444
|
const destTokenAddress = useTokenAddress({
|
|
377
445
|
chainId: selectedDestinationChain?.id,
|
|
378
446
|
tokenSymbol: selectedDestToken?.symbol,
|
|
379
447
|
})
|
|
380
448
|
|
|
449
|
+
const destTokenPricesInput = useMemo(() => {
|
|
450
|
+
const input =
|
|
451
|
+
selectedDestToken && destTokenAddress && selectedDestinationChain?.id
|
|
452
|
+
? [
|
|
453
|
+
{
|
|
454
|
+
tokenId: selectedDestToken.symbol,
|
|
455
|
+
contractAddress: destTokenAddress,
|
|
456
|
+
chainId: selectedDestinationChain.id,
|
|
457
|
+
},
|
|
458
|
+
]
|
|
459
|
+
: []
|
|
460
|
+
|
|
461
|
+
return input
|
|
462
|
+
}, [selectedDestToken, destTokenAddress, selectedDestinationChain?.id])
|
|
463
|
+
|
|
381
464
|
const { tokenPrices: destTokenPrices } = useTokenPrices(
|
|
382
|
-
|
|
383
|
-
? [
|
|
384
|
-
{
|
|
385
|
-
tokenId: selectedDestToken.symbol,
|
|
386
|
-
contractAddress: destTokenAddress,
|
|
387
|
-
chainId: selectedDestinationChain.id,
|
|
388
|
-
},
|
|
389
|
-
]
|
|
390
|
-
: [],
|
|
465
|
+
destTokenPricesInput,
|
|
391
466
|
apiClient,
|
|
392
467
|
)
|
|
393
468
|
|
|
@@ -421,7 +496,7 @@ export function useSendForm({
|
|
|
421
496
|
const newToken = supportedTokens.find(
|
|
422
497
|
(token) =>
|
|
423
498
|
(isToTokenAddress // Match by specified destination token address or symbol
|
|
424
|
-
? token.contractAddress === toToken
|
|
499
|
+
? token.contractAddress.toLowerCase() === toToken.toLowerCase()
|
|
425
500
|
: token.symbol === toToken) &&
|
|
426
501
|
(toChainId // Match by specified destination chain id
|
|
427
502
|
? token.chainId === toChainId
|
|
@@ -479,12 +554,13 @@ export function useSendForm({
|
|
|
479
554
|
[onTransactionStateChange],
|
|
480
555
|
)
|
|
481
556
|
|
|
482
|
-
const balanceFormatted =
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
557
|
+
const balanceFormatted =
|
|
558
|
+
selectedToken?.balance && selectedToken?.contractInfo?.decimals
|
|
559
|
+
? formatRawAmount(
|
|
560
|
+
selectedToken.balance,
|
|
561
|
+
selectedToken.contractInfo?.decimals!,
|
|
562
|
+
)
|
|
563
|
+
: "0"
|
|
488
564
|
const balanceUsdDisplay = selectedToken?.balanceUsdFormatted ?? ""
|
|
489
565
|
const isValidRecipient = Boolean(recipient && isAddress(recipient))
|
|
490
566
|
|
|
@@ -498,10 +574,19 @@ export function useSendForm({
|
|
|
498
574
|
return formatUsdAmountDisplay(amountUsd)
|
|
499
575
|
}, [amount, destTokenPrices, sourceTokenPrices, tradeType])
|
|
500
576
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
577
|
+
// Use the fee token selection hook
|
|
578
|
+
const {
|
|
579
|
+
selectedFeeToken,
|
|
580
|
+
setSelectedFeeToken,
|
|
581
|
+
processedFeeOptions: feeOptions,
|
|
582
|
+
setRawFeeOptions,
|
|
583
|
+
} = useSelectedFeeToken()
|
|
584
|
+
|
|
504
585
|
const [isRecipientContract, setIsRecipientContract] = useState(false)
|
|
586
|
+
const [isSenderContractOnOrigin, setIsSenderContractOnOrigin] =
|
|
587
|
+
useState(false)
|
|
588
|
+
const [isSenderContractOnDestination, setIsSenderContractOnDestination] =
|
|
589
|
+
useState(false)
|
|
505
590
|
|
|
506
591
|
const { hasParam } = useQueryParams()
|
|
507
592
|
const isDryMode = hasParam("dryMode", "true")
|
|
@@ -520,7 +605,39 @@ export function useSendForm({
|
|
|
520
605
|
|
|
521
606
|
// Calculate raw amount (in wei/smallest unit)
|
|
522
607
|
const amountRaw = useMemo(() => {
|
|
523
|
-
if (
|
|
608
|
+
if (
|
|
609
|
+
!amount &&
|
|
610
|
+
!(selectedToken?.contractInfo?.decimals || selectedDestToken?.decimals)
|
|
611
|
+
) {
|
|
612
|
+
logger.console.warn("[trails-sdk] Missing token decimals for quote", {
|
|
613
|
+
amount,
|
|
614
|
+
selectedToken,
|
|
615
|
+
selectedDestToken,
|
|
616
|
+
tradeType,
|
|
617
|
+
})
|
|
618
|
+
return "0"
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
if (
|
|
622
|
+
tradeType === TradeType.EXACT_INPUT &&
|
|
623
|
+
!selectedToken?.contractInfo?.decimals
|
|
624
|
+
) {
|
|
625
|
+
logger.console.warn(
|
|
626
|
+
"[trails-sdk] Missing source token decimals for quote",
|
|
627
|
+
{
|
|
628
|
+
selectedToken,
|
|
629
|
+
tradeType,
|
|
630
|
+
},
|
|
631
|
+
)
|
|
632
|
+
return "0"
|
|
633
|
+
} else if (!selectedDestToken?.decimals) {
|
|
634
|
+
logger.console.warn(
|
|
635
|
+
"[trails-sdk] Missing destination token decimals for quote",
|
|
636
|
+
{
|
|
637
|
+
selectedDestToken,
|
|
638
|
+
tradeType,
|
|
639
|
+
},
|
|
640
|
+
)
|
|
524
641
|
return "0"
|
|
525
642
|
}
|
|
526
643
|
|
|
@@ -528,7 +645,7 @@ export function useSendForm({
|
|
|
528
645
|
// For EXACT_OUTPUT: use destination token decimals (user enters destination amount)
|
|
529
646
|
const decimals =
|
|
530
647
|
tradeType === TradeType.EXACT_INPUT
|
|
531
|
-
? selectedToken
|
|
648
|
+
? selectedToken?.contractInfo?.decimals
|
|
532
649
|
: selectedDestToken?.decimals
|
|
533
650
|
|
|
534
651
|
if (!decimals) {
|
|
@@ -569,6 +686,18 @@ export function useSendForm({
|
|
|
569
686
|
amountRaw === "0" ||
|
|
570
687
|
!selectedToken
|
|
571
688
|
) {
|
|
689
|
+
logger.console.log(
|
|
690
|
+
"[trails-sdk] Skipping quote because of missing inputs",
|
|
691
|
+
{
|
|
692
|
+
amount,
|
|
693
|
+
destinationTokenAddress,
|
|
694
|
+
isValidRecipient,
|
|
695
|
+
selectedDestToken,
|
|
696
|
+
selectedDestinationChain,
|
|
697
|
+
amountRaw,
|
|
698
|
+
selectedToken,
|
|
699
|
+
},
|
|
700
|
+
)
|
|
572
701
|
setQuoteError(null)
|
|
573
702
|
setPrepareSendResult(null)
|
|
574
703
|
return
|
|
@@ -589,7 +718,13 @@ export function useSendForm({
|
|
|
589
718
|
const destinationTokenDecimals = selectedDestToken.decimals
|
|
590
719
|
|
|
591
720
|
if (!sourceTokenDecimals || !destinationTokenDecimals) {
|
|
592
|
-
logger.console.warn("[trails-sdk] Missing token decimals for quote"
|
|
721
|
+
logger.console.warn("[trails-sdk] Missing token decimals for quote", {
|
|
722
|
+
sourceTokenDecimals,
|
|
723
|
+
destinationTokenDecimals,
|
|
724
|
+
selectedToken,
|
|
725
|
+
selectedDestToken,
|
|
726
|
+
tradeType,
|
|
727
|
+
})
|
|
593
728
|
setPrepareSendResult(null)
|
|
594
729
|
setIsLoadingQuote(false)
|
|
595
730
|
return
|
|
@@ -669,7 +804,10 @@ export function useSendForm({
|
|
|
669
804
|
originChainId: selectedToken.chainId,
|
|
670
805
|
originTokenBalance:
|
|
671
806
|
fundMethod === "qr-code" || fundMethod === "exchange"
|
|
672
|
-
?
|
|
807
|
+
? parseUnits(
|
|
808
|
+
"100",
|
|
809
|
+
selectedToken.contractInfo?.decimals ?? 18,
|
|
810
|
+
).toString() // needs to be an amount that is greater than the minimum amount for the swap
|
|
673
811
|
: selectedToken.balance,
|
|
674
812
|
destinationChainId: selectedDestinationChain.id,
|
|
675
813
|
recipient,
|
|
@@ -681,6 +819,7 @@ export function useSendForm({
|
|
|
681
819
|
fee: "0",
|
|
682
820
|
client: walletClient,
|
|
683
821
|
apiClient,
|
|
822
|
+
trailsClient,
|
|
684
823
|
originRelayer,
|
|
685
824
|
destinationRelayer,
|
|
686
825
|
destinationCalldata: toCalldata,
|
|
@@ -701,8 +840,16 @@ export function useSendForm({
|
|
|
701
840
|
mode,
|
|
702
841
|
fundMethod,
|
|
703
842
|
checkoutOnHandlers,
|
|
843
|
+
selectedFeeToken,
|
|
704
844
|
}
|
|
705
845
|
|
|
846
|
+
logger.console.log(
|
|
847
|
+
"[trails-sdk] [FEE-SELECT] getQuote using selectedFeeToken:",
|
|
848
|
+
{
|
|
849
|
+
selectedFeeToken,
|
|
850
|
+
},
|
|
851
|
+
)
|
|
852
|
+
|
|
706
853
|
const result = await prepareSend(options)
|
|
707
854
|
|
|
708
855
|
logger.console.log("[trails-sdk] prepareSend quote:", result.quote)
|
|
@@ -721,6 +868,7 @@ export function useSendForm({
|
|
|
721
868
|
account,
|
|
722
869
|
walletClient,
|
|
723
870
|
apiClient,
|
|
871
|
+
trailsClient,
|
|
724
872
|
selectedDestToken?.decimals,
|
|
725
873
|
recipient,
|
|
726
874
|
destinationTokenAddress,
|
|
@@ -746,6 +894,7 @@ export function useSendForm({
|
|
|
746
894
|
amountRaw,
|
|
747
895
|
checkoutOnHandlers,
|
|
748
896
|
mode,
|
|
897
|
+
selectedFeeToken,
|
|
749
898
|
])
|
|
750
899
|
|
|
751
900
|
// Auto-fetch quotes when inputs change (debounced)
|
|
@@ -776,6 +925,11 @@ export function useSendForm({
|
|
|
776
925
|
selectedDestinationChain?.id,
|
|
777
926
|
toCalldata,
|
|
778
927
|
refetchTrigger,
|
|
928
|
+
selectedToken?.contractAddress,
|
|
929
|
+
selectedToken?.chainId,
|
|
930
|
+
selectedToken?.balance,
|
|
931
|
+
selectedToken?.tokenPriceUsd,
|
|
932
|
+
// selectedFeeToken is passed to send() at execution time, not needed here
|
|
779
933
|
])
|
|
780
934
|
|
|
781
935
|
// Calculate destination amount from quote if available
|
|
@@ -791,9 +945,31 @@ export function useSendForm({
|
|
|
791
945
|
return formatAmountDisplay(quotedDestinationAmount || "0")
|
|
792
946
|
}, [quotedDestinationAmount])
|
|
793
947
|
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
948
|
+
// Set raw fee options in the hook whenever prepareSendResult or tokens change
|
|
949
|
+
useEffect(() => {
|
|
950
|
+
const apiFeeOptions = prepareSendResult?.feeOptions?.feeOptions ?? []
|
|
951
|
+
logger.console.log(
|
|
952
|
+
"[trails-sdk] [FEE-SELECT] useSendForm setting raw fee options:",
|
|
953
|
+
{
|
|
954
|
+
prepareSendResult,
|
|
955
|
+
feeOptions: prepareSendResult?.feeOptions,
|
|
956
|
+
apiFeeOptions,
|
|
957
|
+
length: apiFeeOptions.length,
|
|
958
|
+
},
|
|
959
|
+
)
|
|
960
|
+
|
|
961
|
+
setRawFeeOptions(
|
|
962
|
+
apiFeeOptions,
|
|
963
|
+
selectedToken?.chainId,
|
|
964
|
+
filteredTokensFormatted,
|
|
965
|
+
)
|
|
966
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
967
|
+
}, [
|
|
968
|
+
prepareSendResult,
|
|
969
|
+
selectedToken?.chainId,
|
|
970
|
+
filteredTokensFormatted,
|
|
971
|
+
setRawFeeOptions,
|
|
972
|
+
])
|
|
797
973
|
|
|
798
974
|
const processSend = useCallback(async () => {
|
|
799
975
|
try {
|
|
@@ -877,7 +1053,17 @@ export function useSendForm({
|
|
|
877
1053
|
|
|
878
1054
|
async function handleSend() {
|
|
879
1055
|
logger.console.log(
|
|
880
|
-
"[trails-sdk]
|
|
1056
|
+
"[trails-sdk] [FEE-SELECT] [GASLESS-FLOW] handleSend called, about to call send()",
|
|
1057
|
+
)
|
|
1058
|
+
logger.console.log(
|
|
1059
|
+
"[trails-sdk] [FEE-SELECT] [GASLESS-FLOW] selectedFeeToken value at send() call time:",
|
|
1060
|
+
{
|
|
1061
|
+
selectedFeeToken,
|
|
1062
|
+
isNull: selectedFeeToken === null,
|
|
1063
|
+
isUndefined: selectedFeeToken === undefined,
|
|
1064
|
+
type: typeof selectedFeeToken,
|
|
1065
|
+
stringified: JSON.stringify(selectedFeeToken),
|
|
1066
|
+
},
|
|
881
1067
|
)
|
|
882
1068
|
// Wait for full send to complete
|
|
883
1069
|
const {
|
|
@@ -886,7 +1072,7 @@ export function useSendForm({
|
|
|
886
1072
|
destinationMetaTxnReceipt,
|
|
887
1073
|
} = await send({
|
|
888
1074
|
onOriginSend,
|
|
889
|
-
|
|
1075
|
+
selectedFeeToken, // Pass current value at execution time
|
|
890
1076
|
})
|
|
891
1077
|
logger.console.log("[trails-sdk] send() completed, receipts:", {
|
|
892
1078
|
originUserTxReceipt,
|
|
@@ -947,7 +1133,7 @@ export function useSendForm({
|
|
|
947
1133
|
onError,
|
|
948
1134
|
fundMethod,
|
|
949
1135
|
onNavigateToMeshConnect,
|
|
950
|
-
selectedFeeToken
|
|
1136
|
+
selectedFeeToken, // Include so handleSend captures latest value
|
|
951
1137
|
])
|
|
952
1138
|
|
|
953
1139
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
@@ -991,9 +1177,13 @@ export function useSendForm({
|
|
|
991
1177
|
const checksummedRecipient = getAddress(recipient)
|
|
992
1178
|
const checksummedAccount = getAddress(account.address)
|
|
993
1179
|
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
1180
|
+
logger.console.log("[trails-sdk] buttonText:", {
|
|
1181
|
+
mode,
|
|
1182
|
+
fundMethod,
|
|
1183
|
+
isSameChain,
|
|
1184
|
+
isSameToken,
|
|
1185
|
+
checksummedRecipient,
|
|
1186
|
+
})
|
|
997
1187
|
|
|
998
1188
|
if (fundMethod === "exchange") {
|
|
999
1189
|
return `Continue to Exchange`
|
|
@@ -1003,6 +1193,14 @@ export function useSendForm({
|
|
|
1003
1193
|
return `Continue to QR Code`
|
|
1004
1194
|
}
|
|
1005
1195
|
|
|
1196
|
+
if (!fundMethod || fundMethod === "wallet") {
|
|
1197
|
+
return `Continue on wallet`
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
if (mode === "swap") {
|
|
1201
|
+
return `Swap ${amountDisplay} ${tokenSymbol}`
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1006
1204
|
if (mode === "earn") {
|
|
1007
1205
|
return `Deposit ${destinationAmountDisplay} ${destinationTokenSymbol}`
|
|
1008
1206
|
}
|
|
@@ -1054,7 +1252,7 @@ export function useSendForm({
|
|
|
1054
1252
|
}, [quoteError])
|
|
1055
1253
|
|
|
1056
1254
|
// Check if origin and destination tokens are the same (same contract address on same chain)
|
|
1057
|
-
// Only block same-token transactions when there's no custom calldata
|
|
1255
|
+
// Only block same-token transactions when there's no custom calldata AND recipient is the same as sender
|
|
1058
1256
|
const isSameTokenWithoutCustomCalldata = useMemo(() => {
|
|
1059
1257
|
if (
|
|
1060
1258
|
!selectedToken ||
|
|
@@ -1069,14 +1267,22 @@ export function useSendForm({
|
|
|
1069
1267
|
selectedToken.contractAddress.toLowerCase() ===
|
|
1070
1268
|
destinationTokenAddress.toLowerCase() &&
|
|
1071
1269
|
selectedToken.chainId === selectedDestinationChain?.id
|
|
1072
|
-
|
|
1073
|
-
|
|
1270
|
+
|
|
1271
|
+
// Allow same-token transactions if:
|
|
1272
|
+
// 1. There's custom calldata (e.g., NFT minting)
|
|
1273
|
+
// 2. Recipient is different from sender (simple transfer to another address)
|
|
1274
|
+
const recipientIsSameAsSender =
|
|
1275
|
+
recipient?.toLowerCase() === account?.address?.toLowerCase()
|
|
1276
|
+
|
|
1277
|
+
return isSameChainAndToken && !toCalldata && recipientIsSameAsSender
|
|
1074
1278
|
}, [
|
|
1075
1279
|
selectedToken,
|
|
1076
1280
|
destinationTokenAddress,
|
|
1077
1281
|
selectedDestinationChain,
|
|
1078
1282
|
toCalldata,
|
|
1079
1283
|
selectedToken?.chainId,
|
|
1284
|
+
recipient,
|
|
1285
|
+
account?.address,
|
|
1080
1286
|
])
|
|
1081
1287
|
|
|
1082
1288
|
return {
|
|
@@ -1126,5 +1332,7 @@ export function useSendForm({
|
|
|
1126
1332
|
quoteErrorPrettified,
|
|
1127
1333
|
isSameTokenWithoutCustomCalldata,
|
|
1128
1334
|
isRecipientContract,
|
|
1335
|
+
isSenderContractOnOrigin,
|
|
1336
|
+
isSenderContractOnDestination,
|
|
1129
1337
|
}
|
|
1130
1338
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
createContext,
|
|
3
|
+
useContext,
|
|
4
|
+
useState,
|
|
5
|
+
type ReactNode,
|
|
6
|
+
} from "react"
|
|
7
|
+
|
|
8
|
+
interface SwapAmountContextType {
|
|
9
|
+
amount: string
|
|
10
|
+
setAmount: (amount: string) => void
|
|
11
|
+
clearAmount: () => void
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const SwapAmountContext = createContext<SwapAmountContextType | undefined>(
|
|
15
|
+
undefined,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
interface SwapAmountProviderProps {
|
|
19
|
+
children: ReactNode
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const SwapAmountProvider: React.FC<SwapAmountProviderProps> = ({
|
|
23
|
+
children,
|
|
24
|
+
}) => {
|
|
25
|
+
const [amount, setAmount] = useState<string>("")
|
|
26
|
+
|
|
27
|
+
const clearAmount = () => {
|
|
28
|
+
setAmount("")
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<SwapAmountContext.Provider
|
|
33
|
+
value={{
|
|
34
|
+
amount,
|
|
35
|
+
setAmount,
|
|
36
|
+
clearAmount,
|
|
37
|
+
}}
|
|
38
|
+
>
|
|
39
|
+
{children}
|
|
40
|
+
</SwapAmountContext.Provider>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const useSwapAmount = () => {
|
|
45
|
+
const context = useContext(SwapAmountContext)
|
|
46
|
+
if (context === undefined) {
|
|
47
|
+
throw new Error("useSwapAmount must be used within a SwapAmountProvider")
|
|
48
|
+
}
|
|
49
|
+
return context
|
|
50
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
createContext,
|
|
3
|
+
useContext,
|
|
4
|
+
useState,
|
|
5
|
+
useCallback,
|
|
6
|
+
type ReactNode,
|
|
7
|
+
} from "react"
|
|
8
|
+
import { logger } from "../../logger.js"
|
|
9
|
+
|
|
10
|
+
interface SwapSettingsContextType {
|
|
11
|
+
isSimpleSwapMode: boolean
|
|
12
|
+
setIsSimpleSwapMode: (simple: boolean) => void
|
|
13
|
+
setIsSimpleSwapModeWithStorage: (simple: boolean) => void
|
|
14
|
+
toggleSimpleSwapMode: () => void
|
|
15
|
+
resetSwapSettings: () => void
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const SwapSettingsContext = createContext<SwapSettingsContextType | undefined>(
|
|
19
|
+
undefined,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
interface SwapSettingsProviderProps {
|
|
23
|
+
children: ReactNode
|
|
24
|
+
initialSimpleMode?: boolean
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const SIMPLE_SWAP_MODE_KEY = "trails-simple-swap-mode"
|
|
28
|
+
|
|
29
|
+
export const SwapSettingsProvider: React.FC<SwapSettingsProviderProps> = ({
|
|
30
|
+
children,
|
|
31
|
+
initialSimpleMode = false,
|
|
32
|
+
}) => {
|
|
33
|
+
// Initialize state from localStorage or use initialSimpleMode as fallback
|
|
34
|
+
const [isSimpleSwapMode, setIsSimpleSwapMode] = useState<boolean>(() => {
|
|
35
|
+
try {
|
|
36
|
+
const stored = localStorage.getItem(SIMPLE_SWAP_MODE_KEY)
|
|
37
|
+
return stored !== null ? JSON.parse(stored) : initialSimpleMode
|
|
38
|
+
} catch (error) {
|
|
39
|
+
logger.console.warn(
|
|
40
|
+
"Failed to read simple swap mode from localStorage:",
|
|
41
|
+
error,
|
|
42
|
+
)
|
|
43
|
+
return initialSimpleMode
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
// Function that updates state and saves to localStorage (for user preferences)
|
|
48
|
+
const setIsSimpleSwapModeWithStorage = useCallback((simple: boolean) => {
|
|
49
|
+
setIsSimpleSwapMode(simple)
|
|
50
|
+
try {
|
|
51
|
+
localStorage.setItem(SIMPLE_SWAP_MODE_KEY, JSON.stringify(simple))
|
|
52
|
+
} catch (error) {
|
|
53
|
+
logger.console.warn(
|
|
54
|
+
"Failed to save simple swap mode to localStorage:",
|
|
55
|
+
error,
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
}, [])
|
|
59
|
+
|
|
60
|
+
const toggleSimpleSwapMode = useCallback(() => {
|
|
61
|
+
const newMode = !isSimpleSwapMode
|
|
62
|
+
setIsSimpleSwapModeWithStorage(newMode)
|
|
63
|
+
}, [isSimpleSwapMode, setIsSimpleSwapModeWithStorage])
|
|
64
|
+
|
|
65
|
+
const resetSwapSettings = useCallback(() => {
|
|
66
|
+
try {
|
|
67
|
+
localStorage.removeItem(SIMPLE_SWAP_MODE_KEY)
|
|
68
|
+
setIsSimpleSwapMode(false) // Default: advanced swap mode
|
|
69
|
+
} catch (error) {
|
|
70
|
+
logger.console.warn("Failed to reset swap settings:", error)
|
|
71
|
+
setIsSimpleSwapMode(false) // Still reset state even if localStorage fails
|
|
72
|
+
}
|
|
73
|
+
}, [])
|
|
74
|
+
|
|
75
|
+
const value: SwapSettingsContextType = {
|
|
76
|
+
isSimpleSwapMode,
|
|
77
|
+
setIsSimpleSwapMode, // This one doesn't save to localStorage
|
|
78
|
+
setIsSimpleSwapModeWithStorage, // This one saves to localStorage
|
|
79
|
+
toggleSimpleSwapMode,
|
|
80
|
+
resetSwapSettings,
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<SwapSettingsContext.Provider value={value}>
|
|
85
|
+
{children}
|
|
86
|
+
</SwapSettingsContext.Provider>
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export const useSwapSettings = (): SwapSettingsContextType => {
|
|
91
|
+
const context = useContext(SwapSettingsContext)
|
|
92
|
+
|
|
93
|
+
if (context === undefined) {
|
|
94
|
+
throw new Error(
|
|
95
|
+
"useSwapSettings must be used within a SwapSettingsProvider",
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return context
|
|
100
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useAmountUsd } from "./useAmountUsd.js"
|
|
2
|
+
import { useWidgetProps } from "./useWidgetProps.js"
|
|
3
|
+
|
|
4
|
+
export function useTargetAmount(): {
|
|
5
|
+
targetAmountUsd: number | null
|
|
6
|
+
targetAmountUsdFormatted: string
|
|
7
|
+
} {
|
|
8
|
+
const { toAmount, toToken, toChainId } = useWidgetProps()
|
|
9
|
+
|
|
10
|
+
const {
|
|
11
|
+
amountUsd: targetAmountUsd,
|
|
12
|
+
amountUsdFormatted: targetAmountUsdFormatted,
|
|
13
|
+
} = useAmountUsd({
|
|
14
|
+
amount: toAmount,
|
|
15
|
+
token: toToken,
|
|
16
|
+
chainId: Number(toChainId),
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
targetAmountUsd,
|
|
21
|
+
targetAmountUsdFormatted,
|
|
22
|
+
}
|
|
23
|
+
}
|