0xtrails 0.2.2 → 0.2.5
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 +8 -0
- package/dist/aave.d.ts.map +1 -1
- package/dist/{ccip-ConT1gDe.js → ccip-CXlshvBY.js} +1 -1
- package/dist/chains.d.ts +5 -1
- package/dist/chains.d.ts.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/constants.d.ts +5 -4
- package/dist/constants.d.ts.map +1 -1
- package/dist/error.d.ts +1 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/estimate.d.ts +52 -0
- package/dist/estimate.d.ts.map +1 -1
- package/dist/{index-CMh8uEbV.js → index-_QuyGrjU.js} +86304 -83380
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/intentEntrypoint.d.ts +0 -8
- package/dist/intentEntrypoint.d.ts.map +1 -1
- package/dist/intents.d.ts +40 -0
- package/dist/intents.d.ts.map +1 -1
- package/dist/metaTxnMonitor.d.ts +5 -4
- package/dist/metaTxnMonitor.d.ts.map +1 -1
- package/dist/metaTxns.d.ts +3 -3
- package/dist/metaTxns.d.ts.map +1 -1
- package/dist/morpho.d.ts +8 -0
- package/dist/morpho.d.ts.map +1 -1
- package/dist/prepareSend.d.ts +16 -6
- package/dist/prepareSend.d.ts.map +1 -1
- package/dist/queryParams.d.ts.map +1 -1
- package/dist/relayer.d.ts +10 -7
- package/dist/relayer.d.ts.map +1 -1
- package/dist/sequenceWallet.d.ts +3 -2
- package/dist/sequenceWallet.d.ts.map +1 -1
- package/dist/tokenBalances.d.ts +7 -0
- package/dist/tokenBalances.d.ts.map +1 -1
- package/dist/tokens.d.ts +2 -1
- package/dist/tokens.d.ts.map +1 -1
- package/dist/trails.d.ts +2 -2
- package/dist/trails.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/AccountSettings.d.ts.map +1 -1
- package/dist/widget/components/ClassicSwap.d.ts +2 -0
- package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
- package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
- package/dist/widget/components/ConnectedWallets.d.ts +4 -0
- package/dist/widget/components/ConnectedWallets.d.ts.map +1 -1
- package/dist/widget/components/Earn.d.ts.map +1 -1
- package/dist/widget/components/EarnPools.d.ts.map +1 -1
- package/dist/widget/components/Fund.d.ts +1 -0
- package/dist/widget/components/Fund.d.ts.map +1 -1
- package/dist/widget/components/FundMethods.d.ts.map +1 -1
- package/dist/widget/components/{FundSendForm.d.ts → FundSwap.d.ts} +11 -5
- package/dist/widget/components/FundSwap.d.ts.map +1 -0
- package/dist/widget/components/FundingMethodSelectorButton.d.ts +4 -0
- package/dist/widget/components/FundingMethodSelectorButton.d.ts.map +1 -0
- package/dist/widget/components/Modal.d.ts.map +1 -1
- package/dist/widget/components/Pay.d.ts +1 -0
- package/dist/widget/components/Pay.d.ts.map +1 -1
- package/dist/widget/components/PercentageMaxButtons.d.ts +12 -0
- package/dist/widget/components/PercentageMaxButtons.d.ts.map +1 -0
- package/dist/widget/components/{PaySendForm.d.ts → PoolDeposit.d.ts} +11 -34
- package/dist/widget/components/PoolDeposit.d.ts.map +1 -0
- package/dist/widget/components/{SimpleSwap.d.ts → PoolWithdraw.d.ts} +16 -8
- package/dist/widget/components/PoolWithdraw.d.ts.map +1 -0
- package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
- package/dist/widget/components/Receive.d.ts.map +1 -1
- package/dist/widget/components/RecipientSelectorButton.d.ts +4 -0
- package/dist/widget/components/RecipientSelectorButton.d.ts.map +1 -0
- package/dist/widget/components/Recipients.d.ts.map +1 -1
- package/dist/widget/components/RefundWarning.d.ts +1 -0
- package/dist/widget/components/RefundWarning.d.ts.map +1 -1
- package/dist/widget/components/RequiredPropsError.d.ts +8 -0
- package/dist/widget/components/RequiredPropsError.d.ts.map +1 -0
- package/dist/widget/components/ScreenHeader.d.ts.map +1 -1
- package/dist/widget/components/SlippageToleranceSettings.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/SwapSettings.d.ts.map +1 -1
- package/dist/widget/components/TokenImage.d.ts +1 -0
- package/dist/widget/components/TokenImage.d.ts.map +1 -1
- package/dist/widget/components/TokenList.d.ts.map +1 -1
- package/dist/widget/components/TokenSelector.d.ts.map +1 -1
- package/dist/widget/components/TokenSelectorButton.d.ts +16 -0
- package/dist/widget/components/TokenSelectorButton.d.ts.map +1 -0
- package/dist/widget/components/UserPreferences.d.ts.map +1 -1
- package/dist/widget/components/WaasFeeOptions.d.ts +8 -0
- package/dist/widget/components/WaasFeeOptions.d.ts.map +1 -0
- package/dist/widget/components/WalletConfirmation.d.ts.map +1 -1
- package/dist/widget/components/WalletList.d.ts.map +1 -1
- package/dist/widget/css/compiled.css +2 -0
- package/dist/widget/css/index.css +554 -0
- package/dist/widget/hooks/useBack.d.ts +6 -0
- package/dist/widget/hooks/useBack.d.ts.map +1 -1
- package/dist/widget/hooks/useCheckout.d.ts +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/useDefaultTokenSelection.d.ts +3 -3
- package/dist/widget/hooks/useDefaultTokenSelection.d.ts.map +1 -1
- package/dist/widget/hooks/useInitialRedirect.d.ts +7 -0
- package/dist/widget/hooks/useInitialRedirect.d.ts.map +1 -0
- package/dist/widget/hooks/usePayMessage.d.ts.map +1 -1
- package/dist/widget/hooks/useSelectedFeeToken.d.ts.map +1 -1
- package/dist/widget/hooks/useSelectedFundMethod.d.ts +12 -0
- package/dist/widget/hooks/useSelectedFundMethod.d.ts.map +1 -0
- package/dist/widget/hooks/useSelectedRecipient.d.ts.map +1 -1
- package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
- package/dist/widget/index.js +1 -1
- package/dist/widget/widget.d.ts +4 -4
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +30 -23
- package/src/aave.ts +32 -0
- package/src/chains.ts +23 -3
- package/src/config.ts +12 -4
- package/src/constants.ts +11 -16
- package/src/error.ts +20 -2
- package/src/estimate.ts +416 -5
- package/src/index.ts +8 -3
- package/src/intentEntrypoint.ts +0 -15
- package/src/intents.ts +161 -11
- package/src/metaTxnMonitor.ts +28 -22
- package/src/metaTxns.ts +3 -3
- package/src/morpho.ts +32 -0
- package/src/prepareSend.ts +710 -458
- package/src/queryParams.ts +2 -1
- package/src/relayer.ts +15 -16
- package/src/sequenceWallet.ts +7 -3
- package/src/tokenBalances.ts +47 -0
- package/src/tokens.ts +17 -1
- package/src/trails.ts +2 -2
- package/src/wallets.ts +8 -0
- package/src/widget/compiled.css +2 -2
- package/src/widget/components/AccountActionsDropdown.tsx +9 -15
- package/src/widget/components/AccountIntentTransactionHistory.tsx +1 -1
- package/src/widget/components/AccountSettings.tsx +10 -27
- package/src/widget/components/ChainFilterDropdown.tsx +1 -1
- package/src/widget/components/ChainList.tsx +1 -1
- package/src/widget/components/ClassicSwap.tsx +111 -155
- package/src/widget/components/ConnectWallet.tsx +10 -39
- package/src/widget/components/ConnectedWallets.tsx +113 -58
- package/src/widget/components/Earn.tsx +73 -589
- package/src/widget/components/EarnPools.tsx +2 -1
- package/src/widget/components/Fund.tsx +81 -109
- package/src/widget/components/FundMethods.tsx +82 -159
- package/src/widget/components/FundSwap.tsx +52 -0
- package/src/widget/components/FundingMethodSelectorButton.tsx +60 -0
- package/src/widget/components/Modal.tsx +6 -2
- package/src/widget/components/Pay.tsx +198 -200
- package/src/widget/components/PercentageMaxButtons.tsx +77 -0
- package/src/widget/components/PoolDeposit.tsx +593 -0
- package/src/widget/components/PoolWithdraw.tsx +903 -0
- package/src/widget/components/QuoteDetails.tsx +22 -8
- package/src/widget/components/Receive.tsx +1 -3
- package/src/widget/components/RecipientSelectorButton.tsx +42 -0
- package/src/widget/components/Recipients.tsx +64 -156
- package/src/widget/components/RefundWarning.tsx +5 -1
- package/src/widget/components/RequiredPropsError.tsx +33 -0
- package/src/widget/components/ScreenHeader.tsx +5 -1
- package/src/widget/components/SlippageToleranceSettings.tsx +2 -1
- package/src/widget/components/Swap.tsx +2 -43
- package/src/widget/components/SwapSettings.tsx +3 -15
- package/src/widget/components/TokenImage.tsx +21 -4
- package/src/widget/components/TokenList.tsx +0 -1
- package/src/widget/components/TokenSelector.tsx +2 -1
- package/src/widget/components/TokenSelectorButton.tsx +75 -0
- package/src/widget/components/UserPreferences.tsx +6 -24
- package/src/widget/components/WaasFeeOptions.tsx +331 -0
- package/src/widget/components/WalletConfirmation.tsx +55 -3
- package/src/widget/components/WalletList.tsx +7 -5
- package/src/widget/hooks/useBack.tsx +113 -9
- package/src/widget/hooks/useCheckout.ts +36 -20
- package/src/widget/hooks/useCurrentScreen.tsx +1 -0
- package/src/widget/hooks/useDefaultTokenSelection.tsx +104 -28
- package/src/widget/hooks/useInitialRedirect.tsx +70 -0
- package/src/widget/hooks/usePayMessage.tsx +86 -11
- package/src/widget/hooks/useSelectedFeeToken.tsx +10 -16
- package/src/widget/hooks/useSelectedFundMethod.tsx +41 -0
- package/src/widget/hooks/useSelectedRecipient.tsx +10 -0
- package/src/widget/hooks/useSendForm.ts +34 -12
- package/src/widget/hooks/useTokenList.ts +1 -1
- package/src/widget/index.css +27 -0
- package/src/widget/widget.tsx +245 -208
- package/dist/widget/components/FundSendForm.d.ts.map +0 -1
- package/dist/widget/components/PaySendForm.d.ts.map +0 -1
- package/dist/widget/components/SimpleSwap.d.ts.map +0 -1
- package/dist/widget/hooks/useSwapSettings.d.ts +0 -16
- package/dist/widget/hooks/useSwapSettings.d.ts.map +0 -1
- package/src/widget/components/FundSendForm.tsx +0 -903
- package/src/widget/components/PaySendForm.tsx +0 -869
- package/src/widget/components/SimpleSwap.tsx +0 -983
- package/src/widget/hooks/useSwapSettings.tsx +0 -100
- /package/dist/{style.css → 0xtrails.css} +0 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { useEffect, useState } from "react"
|
|
2
|
+
import { useCurrentScreen, type Screen } from "./useCurrentScreen.js"
|
|
3
|
+
import { useBack } from "./useBack.js"
|
|
4
|
+
import { logger } from "../../logger.js"
|
|
5
|
+
import type { Mode } from "../../mode.js"
|
|
6
|
+
|
|
7
|
+
export function useInitialRedirect(
|
|
8
|
+
isConnected: boolean,
|
|
9
|
+
currentMode: Mode,
|
|
10
|
+
getInitialScreenForMode: (mode: Mode) => Screen,
|
|
11
|
+
) {
|
|
12
|
+
const { setCurrentScreen } = useCurrentScreen()
|
|
13
|
+
const { getBreadcrumbHistory } = useBack()
|
|
14
|
+
const [hasConnectedBefore, setHasConnectedBefore] = useState(false)
|
|
15
|
+
const [isInitialScreenSet, setIsInitialScreenSet] = useState(false)
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!isConnected || isInitialScreenSet) {
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Check if this is the first time connecting (no previous wallet connected)
|
|
23
|
+
const isFirstTimeConnection = !hasConnectedBefore
|
|
24
|
+
|
|
25
|
+
if (isFirstTimeConnection) {
|
|
26
|
+
// First time connecting - go to appropriate mode screen
|
|
27
|
+
const initialScreen = getInitialScreenForMode(currentMode)
|
|
28
|
+
logger.console.log(
|
|
29
|
+
"[trails-sdk] First time connection, redirecting to:",
|
|
30
|
+
initialScreen,
|
|
31
|
+
)
|
|
32
|
+
setCurrentScreen(initialScreen)
|
|
33
|
+
setHasConnectedBefore(true)
|
|
34
|
+
} else {
|
|
35
|
+
// Subsequent connections - check if user came from account-settings
|
|
36
|
+
const breadcrumbHistory = getBreadcrumbHistory()
|
|
37
|
+
const lastBreadcrumbScreen =
|
|
38
|
+
breadcrumbHistory.length > 0
|
|
39
|
+
? breadcrumbHistory[breadcrumbHistory.length - 1]
|
|
40
|
+
: null
|
|
41
|
+
|
|
42
|
+
if (lastBreadcrumbScreen === "account-settings") {
|
|
43
|
+
// User came from account-settings, return there
|
|
44
|
+
logger.console.log(
|
|
45
|
+
"[trails-sdk] Returning to account-settings after wallet connection",
|
|
46
|
+
)
|
|
47
|
+
setCurrentScreen("account-settings")
|
|
48
|
+
} else {
|
|
49
|
+
// User came from elsewhere, go to appropriate mode screen
|
|
50
|
+
const initialScreen = getInitialScreenForMode(currentMode)
|
|
51
|
+
logger.console.log(
|
|
52
|
+
"[trails-sdk] Subsequent connection, redirecting to:",
|
|
53
|
+
initialScreen,
|
|
54
|
+
)
|
|
55
|
+
setCurrentScreen(initialScreen)
|
|
56
|
+
}
|
|
57
|
+
setIsInitialScreenSet(true)
|
|
58
|
+
}
|
|
59
|
+
}, [
|
|
60
|
+
isConnected,
|
|
61
|
+
currentMode,
|
|
62
|
+
hasConnectedBefore,
|
|
63
|
+
getInitialScreenForMode,
|
|
64
|
+
setCurrentScreen,
|
|
65
|
+
getBreadcrumbHistory,
|
|
66
|
+
isInitialScreenSet,
|
|
67
|
+
])
|
|
68
|
+
|
|
69
|
+
return { hasConnectedBefore, isInitialScreenSet }
|
|
70
|
+
}
|
|
@@ -8,6 +8,7 @@ import { truncateAddress } from "../../utils.js"
|
|
|
8
8
|
import { getExplorerUrlForAddress } from "../../explorer.js"
|
|
9
9
|
import ChainImage from "../components/ChainImage.js"
|
|
10
10
|
import TokenImage from "../components/TokenImage.js"
|
|
11
|
+
import { Identicon } from "../components/Identicon.js"
|
|
11
12
|
import { logger } from "../../logger.js"
|
|
12
13
|
|
|
13
14
|
export interface PayMessagePart {
|
|
@@ -85,25 +86,23 @@ export function usePayMessage(): UsePayMessageReturn {
|
|
|
85
86
|
})
|
|
86
87
|
|
|
87
88
|
const parsed = useMemo(() => {
|
|
88
|
-
//
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const template = payMessage || defaultMessage
|
|
89
|
+
// If no payMessage provided, return empty parts (default layout handled separately)
|
|
90
|
+
if (!payMessage) {
|
|
91
|
+
return []
|
|
92
|
+
}
|
|
94
93
|
|
|
95
94
|
// Parse the template into parts
|
|
96
95
|
const parts: PayMessagePart[] = []
|
|
97
96
|
const regex = /\{([^}]+)\}/g
|
|
98
97
|
let lastIndex = 0
|
|
99
|
-
let match: RegExpExecArray | null = regex.exec(
|
|
98
|
+
let match: RegExpExecArray | null = regex.exec(payMessage)
|
|
100
99
|
|
|
101
100
|
while (match !== null) {
|
|
102
101
|
// Add text before the placeholder
|
|
103
102
|
if (match.index > lastIndex) {
|
|
104
103
|
parts.push({
|
|
105
104
|
type: "text",
|
|
106
|
-
value:
|
|
105
|
+
value: payMessage.substring(lastIndex, match.index),
|
|
107
106
|
})
|
|
108
107
|
}
|
|
109
108
|
|
|
@@ -176,14 +175,14 @@ export function usePayMessage(): UsePayMessageReturn {
|
|
|
176
175
|
}
|
|
177
176
|
|
|
178
177
|
lastIndex = regex.lastIndex
|
|
179
|
-
match = regex.exec(
|
|
178
|
+
match = regex.exec(payMessage)
|
|
180
179
|
}
|
|
181
180
|
|
|
182
181
|
// Add remaining text
|
|
183
|
-
if (lastIndex <
|
|
182
|
+
if (lastIndex < payMessage.length) {
|
|
184
183
|
parts.push({
|
|
185
184
|
type: "text",
|
|
186
|
-
value:
|
|
185
|
+
value: payMessage.substring(lastIndex),
|
|
187
186
|
})
|
|
188
187
|
}
|
|
189
188
|
|
|
@@ -206,6 +205,78 @@ export function usePayMessage(): UsePayMessageReturn {
|
|
|
206
205
|
|
|
207
206
|
// Render the message
|
|
208
207
|
const message = useMemo(() => {
|
|
208
|
+
// If no payMessage provided, render default layout
|
|
209
|
+
if (!payMessage) {
|
|
210
|
+
return (
|
|
211
|
+
<div className="flex flex-col items-center justify-center px-8 py-4 space-y-4 min-w-full">
|
|
212
|
+
{/* App image above the amount if it exists */}
|
|
213
|
+
{appImageUrl && (
|
|
214
|
+
<img
|
|
215
|
+
src={appImageUrl}
|
|
216
|
+
alt={appName || "App"}
|
|
217
|
+
className="w-12 h-12 rounded-lg"
|
|
218
|
+
onError={(e) => {
|
|
219
|
+
logger.console.error(
|
|
220
|
+
`Error loading app image: ${e}, appImageUrl: ${appImageUrl}`,
|
|
221
|
+
)
|
|
222
|
+
// Hide image on error
|
|
223
|
+
e.currentTarget.style.display = "none"
|
|
224
|
+
}}
|
|
225
|
+
/>
|
|
226
|
+
)}
|
|
227
|
+
|
|
228
|
+
{/* Large amount in center */}
|
|
229
|
+
<div className="font-bold text-center">
|
|
230
|
+
{(() => {
|
|
231
|
+
const amountToShow = targetAmountUsdFormatted || toAmount || "0"
|
|
232
|
+
const tokenSymbol = tokenInfo?.symbol || ""
|
|
233
|
+
const displayText = targetAmountUsdFormatted
|
|
234
|
+
? amountToShow
|
|
235
|
+
: `${amountToShow} ${tokenSymbol}`.trim()
|
|
236
|
+
|
|
237
|
+
// Dynamic font size based on text length
|
|
238
|
+
const textLength = displayText.length
|
|
239
|
+
let fontSize = "text-6xl" // Default large size
|
|
240
|
+
|
|
241
|
+
if (textLength > 12) {
|
|
242
|
+
fontSize = "text-2xl"
|
|
243
|
+
} else if (textLength > 10) {
|
|
244
|
+
fontSize = "text-3xl"
|
|
245
|
+
} else if (textLength > 8) {
|
|
246
|
+
fontSize = "text-4xl"
|
|
247
|
+
} else if (textLength > 6) {
|
|
248
|
+
fontSize = "text-5xl"
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return <div className={fontSize}>{displayText}</div>
|
|
252
|
+
})()}
|
|
253
|
+
</div>
|
|
254
|
+
|
|
255
|
+
{/* Recipient info below */}
|
|
256
|
+
{toAddress && (
|
|
257
|
+
<div className="flex items-center space-x-2 text-center">
|
|
258
|
+
<span className="text-sm text-gray-600 dark:text-gray-400">
|
|
259
|
+
to
|
|
260
|
+
</span>
|
|
261
|
+
<Identicon value={toAddress} size={20} />
|
|
262
|
+
<a
|
|
263
|
+
href={getExplorerUrlForAddress({
|
|
264
|
+
address: toAddress,
|
|
265
|
+
chainId: toChainId ? Number(toChainId) : 1,
|
|
266
|
+
})}
|
|
267
|
+
target="_blank"
|
|
268
|
+
rel="noopener noreferrer"
|
|
269
|
+
className="text-sm hover:underline cursor-pointer text-blue-600 dark:text-blue-400"
|
|
270
|
+
>
|
|
271
|
+
{truncateAddress(toAddress)}
|
|
272
|
+
</a>
|
|
273
|
+
</div>
|
|
274
|
+
)}
|
|
275
|
+
</div>
|
|
276
|
+
)
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Render user-provided message with handlebar interpolation
|
|
209
280
|
return (
|
|
210
281
|
<>
|
|
211
282
|
{parsed.map((part) => {
|
|
@@ -354,6 +425,7 @@ export function usePayMessage(): UsePayMessageReturn {
|
|
|
354
425
|
</>
|
|
355
426
|
)
|
|
356
427
|
}, [
|
|
428
|
+
payMessage,
|
|
357
429
|
parsed,
|
|
358
430
|
appName,
|
|
359
431
|
appUrl,
|
|
@@ -361,6 +433,9 @@ export function usePayMessage(): UsePayMessageReturn {
|
|
|
361
433
|
appDescription,
|
|
362
434
|
tokenInfo,
|
|
363
435
|
toChainId,
|
|
436
|
+
toAddress,
|
|
437
|
+
targetAmountUsdFormatted,
|
|
438
|
+
toAmount,
|
|
364
439
|
])
|
|
365
440
|
|
|
366
441
|
return {
|
|
@@ -65,22 +65,16 @@ export const SelectedFeeTokenProvider: React.FC<
|
|
|
65
65
|
const [availableTokens, setAvailableTokens] = useState<TokenWithBalance[]>([])
|
|
66
66
|
|
|
67
67
|
// Wrapper to log all state changes to selectedFeeToken
|
|
68
|
-
const setSelectedFeeTokenInternal = useCallback(
|
|
69
|
-
(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
},
|
|
79
|
-
)
|
|
80
|
-
setSelectedFeeTokenInternalRaw(token)
|
|
81
|
-
},
|
|
82
|
-
[selectedFeeToken],
|
|
83
|
-
)
|
|
68
|
+
const setSelectedFeeTokenInternal = useCallback((token: FeeOption | null) => {
|
|
69
|
+
logger.console.log(
|
|
70
|
+
"[trails-sdk] [FEE-SELECT] selectedFeeToken state changing:",
|
|
71
|
+
{
|
|
72
|
+
to: token,
|
|
73
|
+
toNull: token === null,
|
|
74
|
+
},
|
|
75
|
+
)
|
|
76
|
+
setSelectedFeeTokenInternalRaw(token)
|
|
77
|
+
}, [])
|
|
84
78
|
|
|
85
79
|
// Wrapper to track when user makes an explicit selection
|
|
86
80
|
const setSelectedFeeToken = useCallback(
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { createContext, useContext, useState, type ReactNode } from "react"
|
|
2
|
+
|
|
3
|
+
interface SelectedFundMethodContextType {
|
|
4
|
+
selectedFundMethod: string
|
|
5
|
+
setSelectedFundMethod: (method: string) => void
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const SelectedFundMethodContext = createContext<
|
|
9
|
+
SelectedFundMethodContextType | undefined
|
|
10
|
+
>(undefined)
|
|
11
|
+
|
|
12
|
+
interface SelectedFundMethodProviderProps {
|
|
13
|
+
children: ReactNode
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const SelectedFundMethodProvider = ({
|
|
17
|
+
children,
|
|
18
|
+
}: SelectedFundMethodProviderProps) => {
|
|
19
|
+
const [selectedFundMethod, setSelectedFundMethod] = useState<string>("wallet")
|
|
20
|
+
|
|
21
|
+
const value: SelectedFundMethodContextType = {
|
|
22
|
+
selectedFundMethod,
|
|
23
|
+
setSelectedFundMethod,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<SelectedFundMethodContext.Provider value={value}>
|
|
28
|
+
{children}
|
|
29
|
+
</SelectedFundMethodContext.Provider>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const useSelectedFundMethod = (): SelectedFundMethodContextType => {
|
|
34
|
+
const context = useContext(SelectedFundMethodContext)
|
|
35
|
+
if (context === undefined) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
"useSelectedFundMethod must be used within a SelectedFundMethodProvider",
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
return context
|
|
41
|
+
}
|
|
@@ -2,8 +2,10 @@ import React, {
|
|
|
2
2
|
createContext,
|
|
3
3
|
useContext,
|
|
4
4
|
useState,
|
|
5
|
+
useEffect,
|
|
5
6
|
type ReactNode,
|
|
6
7
|
} from "react"
|
|
8
|
+
import { useAccount } from "wagmi"
|
|
7
9
|
|
|
8
10
|
interface SelectedRecipientContextType {
|
|
9
11
|
selectedRecipient: string | null
|
|
@@ -21,10 +23,18 @@ interface SelectedRecipientProviderProps {
|
|
|
21
23
|
export const SelectedRecipientProvider: React.FC<
|
|
22
24
|
SelectedRecipientProviderProps
|
|
23
25
|
> = ({ children }) => {
|
|
26
|
+
const { address } = useAccount()
|
|
24
27
|
const [selectedRecipient, setSelectedRecipient] = useState<string | null>(
|
|
25
28
|
null,
|
|
26
29
|
)
|
|
27
30
|
|
|
31
|
+
// Set recipient to address only if address exists and no recipient is selected
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (address && !selectedRecipient) {
|
|
34
|
+
setSelectedRecipient(address)
|
|
35
|
+
}
|
|
36
|
+
}, [address, selectedRecipient])
|
|
37
|
+
|
|
28
38
|
return (
|
|
29
39
|
<SelectedRecipientContext.Provider
|
|
30
40
|
value={{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { TokenPrice } from "@0xsequence/trails-api"
|
|
2
2
|
import type React from "react"
|
|
3
|
-
import { useCallback, useEffect, useMemo, useState } from "react"
|
|
3
|
+
import { useCallback, useEffect, useMemo, useState, useRef } from "react"
|
|
4
4
|
import {
|
|
5
5
|
type Account,
|
|
6
6
|
getAddress,
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
type WalletClient,
|
|
10
10
|
zeroAddress,
|
|
11
11
|
} from "viem"
|
|
12
|
+
import { useAccount } from "wagmi"
|
|
12
13
|
import { useAPIClient } from "../../apiClient.js"
|
|
13
14
|
import { getChainInfo, useSupportedChains } from "../../chains.js"
|
|
14
15
|
import { getFullErrorMessage, getPrettifiedErrorMessage } from "../../error.js"
|
|
@@ -207,6 +208,10 @@ export function useSendForm({
|
|
|
207
208
|
checkoutOnHandlers,
|
|
208
209
|
refetchTrigger = 0,
|
|
209
210
|
}: UseSendProps): UseSendReturn {
|
|
211
|
+
// Get the active wallet ID from wagmi
|
|
212
|
+
const { connector } = useAccount()
|
|
213
|
+
const walletId = connector?.id
|
|
214
|
+
|
|
210
215
|
// Auto-set quoteProvider to "lifi" if either from or to chain is etherlink
|
|
211
216
|
const effectiveQuoteProvider = useMemo(() => {
|
|
212
217
|
if (!quoteProvider || quoteProvider === "auto") {
|
|
@@ -441,6 +446,12 @@ export function useSendForm({
|
|
|
441
446
|
allSupportedTokens: true, // Get all tokens for balance checking
|
|
442
447
|
})
|
|
443
448
|
|
|
449
|
+
// Use ref to store latest filteredTokensFormatted without triggering re-renders
|
|
450
|
+
const filteredTokensFormattedRef = useRef(filteredTokensFormatted)
|
|
451
|
+
useEffect(() => {
|
|
452
|
+
filteredTokensFormattedRef.current = filteredTokensFormatted
|
|
453
|
+
}, [filteredTokensFormatted])
|
|
454
|
+
|
|
444
455
|
const destTokenAddress = useTokenAddress({
|
|
445
456
|
chainId: selectedDestinationChain?.id,
|
|
446
457
|
tokenSymbol: selectedDestToken?.symbol,
|
|
@@ -798,6 +809,9 @@ export function useSendForm({
|
|
|
798
809
|
nativeTokenPriceUsd = nativePrice?.price?.value ?? 0
|
|
799
810
|
}
|
|
800
811
|
|
|
812
|
+
// Disable gasless for sequence-waas wallet
|
|
813
|
+
const effectiveGasless = walletId === "sequence-waas" ? false : gasless
|
|
814
|
+
|
|
801
815
|
const options = {
|
|
802
816
|
account,
|
|
803
817
|
originTokenAddress: selectedToken.contractAddress,
|
|
@@ -834,13 +848,14 @@ export function useSendForm({
|
|
|
834
848
|
paymasterUrls?.find(
|
|
835
849
|
(p) => p.chainId.toString() === selectedToken.chainId.toString(),
|
|
836
850
|
)?.url ?? undefined,
|
|
837
|
-
gasless,
|
|
851
|
+
gasless: effectiveGasless,
|
|
838
852
|
originNativeTokenPriceUsd: nativeTokenPriceUsd,
|
|
839
853
|
quoteProvider: effectiveQuoteProvider,
|
|
840
854
|
mode,
|
|
841
855
|
fundMethod,
|
|
842
856
|
checkoutOnHandlers,
|
|
843
857
|
selectedFeeToken,
|
|
858
|
+
walletId,
|
|
844
859
|
}
|
|
845
860
|
|
|
846
861
|
logger.console.log(
|
|
@@ -895,6 +910,7 @@ export function useSendForm({
|
|
|
895
910
|
checkoutOnHandlers,
|
|
896
911
|
mode,
|
|
897
912
|
selectedFeeToken,
|
|
913
|
+
walletId,
|
|
898
914
|
])
|
|
899
915
|
|
|
900
916
|
// Auto-fetch quotes when inputs change (debounced)
|
|
@@ -945,7 +961,7 @@ export function useSendForm({
|
|
|
945
961
|
return formatAmountDisplay(quotedDestinationAmount || "0")
|
|
946
962
|
}, [quotedDestinationAmount])
|
|
947
963
|
|
|
948
|
-
// Set raw fee options in the hook whenever prepareSendResult
|
|
964
|
+
// Set raw fee options in the hook whenever prepareSendResult changes
|
|
949
965
|
useEffect(() => {
|
|
950
966
|
const apiFeeOptions = prepareSendResult?.feeOptions?.feeOptions ?? []
|
|
951
967
|
logger.console.log(
|
|
@@ -961,15 +977,9 @@ export function useSendForm({
|
|
|
961
977
|
setRawFeeOptions(
|
|
962
978
|
apiFeeOptions,
|
|
963
979
|
selectedToken?.chainId,
|
|
964
|
-
|
|
980
|
+
filteredTokensFormattedRef.current,
|
|
965
981
|
)
|
|
966
|
-
|
|
967
|
-
}, [
|
|
968
|
-
prepareSendResult,
|
|
969
|
-
selectedToken?.chainId,
|
|
970
|
-
filteredTokensFormatted,
|
|
971
|
-
setRawFeeOptions,
|
|
972
|
-
])
|
|
982
|
+
}, [prepareSendResult, selectedToken?.chainId, setRawFeeOptions])
|
|
973
983
|
|
|
974
984
|
const processSend = useCallback(async () => {
|
|
975
985
|
try {
|
|
@@ -1194,7 +1204,19 @@ export function useSendForm({
|
|
|
1194
1204
|
}
|
|
1195
1205
|
|
|
1196
1206
|
if (!fundMethod || fundMethod === "wallet") {
|
|
1197
|
-
|
|
1207
|
+
if (mode === "pay") {
|
|
1208
|
+
return `Pay`
|
|
1209
|
+
} else if (mode === "fund") {
|
|
1210
|
+
return `Fund`
|
|
1211
|
+
} else if (mode === "swap") {
|
|
1212
|
+
return `Swap`
|
|
1213
|
+
} else if (mode === "earn") {
|
|
1214
|
+
return `Deposit`
|
|
1215
|
+
} else if (mode === "receive") {
|
|
1216
|
+
return `Pay`
|
|
1217
|
+
} else {
|
|
1218
|
+
return `Continue on wallet`
|
|
1219
|
+
}
|
|
1198
1220
|
}
|
|
1199
1221
|
|
|
1200
1222
|
if (mode === "swap") {
|
|
@@ -405,7 +405,7 @@ export function useTokenList({
|
|
|
405
405
|
return sortedTokens
|
|
406
406
|
}
|
|
407
407
|
|
|
408
|
-
const query = searchQuery.
|
|
408
|
+
const query = searchQuery.trim().toLowerCase()
|
|
409
409
|
const queryParts = query.split(/\s+/).filter((part) => part.length > 0)
|
|
410
410
|
|
|
411
411
|
const matchingTokens = sortedTokens.filter(
|
package/src/widget/index.css
CHANGED
|
@@ -39,6 +39,11 @@
|
|
|
39
39
|
--trails-modal-button-hover-bg: var(--trails-primary-hover, rgb(17 75 202)); /* Defaults to primary hover */
|
|
40
40
|
--trails-modal-button-text: rgb(255 255 255); /* white text */
|
|
41
41
|
--trails-modal-button-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); /* subtle shadow */
|
|
42
|
+
|
|
43
|
+
/* Percentage Button Colors - Customizable percentage buttons */
|
|
44
|
+
--trails-percentage-button-bg: rgb(228 228 231); /* #E4E4E7 - Light gray background */
|
|
45
|
+
--trails-percentage-button-text: rgb(113 113 123); /* #71717B - Dark gray text */
|
|
46
|
+
--trails-percentage-button-hover-bg: rgb(212 212 216); /* #D4D4D8 - Slightly darker on hover */
|
|
42
47
|
}
|
|
43
48
|
|
|
44
49
|
/* Utility Classes that use CSS Variables */
|
|
@@ -110,6 +115,18 @@
|
|
|
110
115
|
color: var(--trails-hover-text);
|
|
111
116
|
}
|
|
112
117
|
|
|
118
|
+
.trails-bg-percentage-button {
|
|
119
|
+
background-color: var(--trails-percentage-button-bg);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.trails-text-percentage-button {
|
|
123
|
+
color: var(--trails-percentage-button-text);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.trails-hover-percentage-button:hover {
|
|
127
|
+
background-color: var(--trails-percentage-button-hover-bg);
|
|
128
|
+
}
|
|
129
|
+
|
|
113
130
|
|
|
114
131
|
|
|
115
132
|
/* Font Family Utility Class */
|
|
@@ -304,6 +321,11 @@
|
|
|
304
321
|
/* Shadow */
|
|
305
322
|
--trails-shadow:
|
|
306
323
|
0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
|
324
|
+
|
|
325
|
+
/* Percentage Button Colors - Light Mode */
|
|
326
|
+
--trails-percentage-button-bg: rgb(228 228 231); /* #E4E4E7 - Light gray background */
|
|
327
|
+
--trails-percentage-button-text: rgb(113 113 123); /* #71717B - Dark gray text */
|
|
328
|
+
--trails-percentage-button-hover-bg: rgb(212 212 216); /* #D4D4D8 - Slightly darker on hover */
|
|
307
329
|
}
|
|
308
330
|
|
|
309
331
|
/* Dark Mode Theme Variables */
|
|
@@ -391,6 +413,11 @@
|
|
|
391
413
|
/* Shadow */
|
|
392
414
|
--trails-shadow:
|
|
393
415
|
0 1px 3px 0 rgb(0 0 0 / 0.3), 0 1px 2px -1px rgb(0 0 0 / 0.3);
|
|
416
|
+
|
|
417
|
+
/* Percentage Button Colors - Dark Mode */
|
|
418
|
+
--trails-percentage-button-bg: rgb(55 65 81); /* gray-700 - Dark gray background */
|
|
419
|
+
--trails-percentage-button-text: rgb(209 213 219); /* gray-300 - Light gray text */
|
|
420
|
+
--trails-percentage-button-hover-bg: rgb(75 85 99); /* gray-600 - Slightly lighter on hover */
|
|
394
421
|
}
|
|
395
422
|
|
|
396
423
|
/* Custom Scrollbar Styles */
|