0xtrails 0.6.0 → 0.6.2
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-Dw5AN7oU.js → ccip-CZfykYU7.js} +4 -4
- package/dist/chains.d.ts +9 -2
- package/dist/chains.d.ts.map +1 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/contractUtils.d.ts +2 -1
- package/dist/contractUtils.d.ts.map +1 -1
- package/dist/{index-BtVUTbEZ.js → index-S9pphnT9.js} +29732 -36767
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +300 -242
- package/dist/prepareSend.d.ts.map +1 -1
- package/dist/transactionIntent/handlers/crossChain.d.ts.map +1 -1
- package/dist/transactionIntent/handlers/sameChainSameToken.d.ts.map +1 -1
- package/dist/transactionIntent/types.d.ts +3 -1
- package/dist/transactionIntent/types.d.ts.map +1 -1
- package/dist/widget/components/ChainImage.d.ts.map +1 -1
- package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
- package/dist/widget/components/DepositTracker.d.ts +12 -0
- package/dist/widget/components/DepositTracker.d.ts.map +1 -0
- package/dist/widget/components/Disconnect.d.ts.map +1 -1
- package/dist/widget/components/FeeBreakdown.d.ts.map +1 -1
- package/dist/widget/components/QRCodeDeposit.d.ts.map +1 -1
- package/dist/widget/components/QRCodeOptions.d.ts +9 -0
- package/dist/widget/components/QRCodeOptions.d.ts.map +1 -0
- package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
- package/dist/widget/components/Receipt.d.ts.map +1 -1
- package/dist/widget/components/ThemeProvider.d.ts.map +1 -1
- package/dist/widget/components/Toast.d.ts.map +1 -1
- package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
- package/dist/widget/components/WalletConnectionPending.d.ts.map +1 -1
- package/dist/widget/css/compiled.css +1 -1
- package/dist/widget/css/index.css +103 -38
- 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/useIntentTransactionHistory.d.ts.map +1 -1
- package/dist/widget/hooks/useQuote.d.ts.map +1 -1
- package/dist/widget/hooks/useSelectedFeeOption.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.map +1 -1
- package/package.json +6 -9
- package/src/chains.ts +37 -4
- package/src/constants.ts +1 -0
- package/src/contractUtils.ts +8 -7
- package/src/estimate.ts +2 -2
- package/src/index.ts +2 -0
- package/src/intents.ts +2 -2
- package/src/paymasterSend.ts +2 -2
- package/src/prepareSend.ts +34 -3
- package/src/sendUserOp.ts +2 -2
- package/src/tokens.ts +2 -2
- package/src/transactionIntent/deposits/gaslessDeposit.ts +2 -2
- package/src/transactionIntent/handlers/crossChain.ts +51 -2
- package/src/transactionIntent/handlers/sameChainSameToken.ts +52 -2
- package/src/transactionIntent/quote/normalizeQuote.ts +2 -2
- package/src/transactionIntent/types.ts +9 -1
- package/src/widget/compiled.css +1 -1
- package/src/widget/components/ChainImage.tsx +10 -7
- package/src/widget/components/ChainList.tsx +1 -1
- package/src/widget/components/ClassicSwap.tsx +8 -4
- package/src/widget/components/ConnectedWallets.tsx +1 -1
- package/src/widget/components/DepositTracker.tsx +298 -0
- package/src/widget/components/Disconnect.tsx +24 -3
- package/src/widget/components/FeeBreakdown.tsx +3 -3
- package/src/widget/components/QRCodeDeposit.tsx +29 -19
- package/src/widget/components/QRCodeOptions.tsx +65 -0
- package/src/widget/components/QuoteDetails.tsx +694 -803
- package/src/widget/components/Receipt.tsx +76 -40
- package/src/widget/components/ThemeProvider.tsx +7 -12
- package/src/widget/components/Toast.tsx +3 -2
- package/src/widget/components/TokenSelector.tsx +1 -1
- package/src/widget/components/Tooltip.tsx +1 -1
- package/src/widget/components/TransferPendingVertical.tsx +11 -2
- package/src/widget/components/WalletConnectionPending.tsx +28 -5
- package/src/widget/hooks/useCheckout.ts +10 -2
- package/src/widget/hooks/useCurrentScreen.tsx +1 -0
- package/src/widget/hooks/useDebugScreens.ts +1 -0
- package/src/widget/hooks/useIntentTransactionHistory.ts +114 -143
- package/src/widget/hooks/useQuote.ts +92 -6
- package/src/widget/hooks/useSelectedFeeOption.tsx +86 -29
- package/src/widget/hooks/useSendForm.ts +43 -7
- package/src/widget/index.css +103 -38
- package/src/widget/widget.tsx +48 -5
- package/dist/0xtrails.css +0 -1
|
@@ -11,7 +11,11 @@ import {
|
|
|
11
11
|
zeroAddress,
|
|
12
12
|
} from "viem"
|
|
13
13
|
import { useAccount } from "wagmi"
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
getChainInfo,
|
|
16
|
+
useSupportedChains,
|
|
17
|
+
useChainRpcClient,
|
|
18
|
+
} from "../../chains.js"
|
|
15
19
|
import { getFullErrorMessage, getPrettifiedErrorMessage } from "../../error.js"
|
|
16
20
|
import {
|
|
17
21
|
prepareSend,
|
|
@@ -263,14 +267,26 @@ export function useSendForm({
|
|
|
263
267
|
chainId: selectedDestinationChain?.id,
|
|
264
268
|
})
|
|
265
269
|
|
|
270
|
+
// Get RPC clients for known chainIds using hooks (reads from TrailsProvider context)
|
|
271
|
+
const destinationChainPublicClient = useChainRpcClient(
|
|
272
|
+
selectedDestinationChain?.id,
|
|
273
|
+
)
|
|
274
|
+
const originChainPublicClient = useChainRpcClient(selectedToken?.chainId)
|
|
275
|
+
|
|
266
276
|
// Check if recipient is a contract address
|
|
267
277
|
useEffect(() => {
|
|
268
278
|
const checkRecipientContract = async () => {
|
|
269
|
-
if (
|
|
279
|
+
if (
|
|
280
|
+
recipient &&
|
|
281
|
+
isAddress(recipient) &&
|
|
282
|
+
selectedDestinationChain?.id &&
|
|
283
|
+
destinationChainPublicClient
|
|
284
|
+
) {
|
|
270
285
|
try {
|
|
271
286
|
const isContract = await getIsContract(
|
|
272
287
|
recipient as `0x${string}`,
|
|
273
288
|
selectedDestinationChain.id,
|
|
289
|
+
destinationChainPublicClient,
|
|
274
290
|
)
|
|
275
291
|
logger.console.log("[trails-sdk] isRecipientContract:", isContract)
|
|
276
292
|
setIsRecipientContract(isContract)
|
|
@@ -287,16 +303,21 @@ export function useSendForm({
|
|
|
287
303
|
}
|
|
288
304
|
|
|
289
305
|
checkRecipientContract()
|
|
290
|
-
}, [recipient, selectedDestinationChain?.id])
|
|
306
|
+
}, [recipient, selectedDestinationChain?.id, destinationChainPublicClient])
|
|
291
307
|
|
|
292
308
|
// Check if sender is a contract address on origin chain
|
|
293
309
|
useEffect(() => {
|
|
294
310
|
const checkSenderContractOnOrigin = async () => {
|
|
295
|
-
if (
|
|
311
|
+
if (
|
|
312
|
+
account?.address &&
|
|
313
|
+
selectedToken?.chainId &&
|
|
314
|
+
originChainPublicClient
|
|
315
|
+
) {
|
|
296
316
|
try {
|
|
297
317
|
const isContract = await getIsContract(
|
|
298
318
|
account.address as `0x${string}`,
|
|
299
319
|
selectedToken.chainId,
|
|
320
|
+
originChainPublicClient,
|
|
300
321
|
)
|
|
301
322
|
logger.console.log(
|
|
302
323
|
"[trails-sdk] isSenderContractOnOrigin:",
|
|
@@ -316,16 +337,21 @@ export function useSendForm({
|
|
|
316
337
|
}
|
|
317
338
|
|
|
318
339
|
checkSenderContractOnOrigin()
|
|
319
|
-
}, [account?.address, selectedToken?.chainId])
|
|
340
|
+
}, [account?.address, selectedToken?.chainId, originChainPublicClient])
|
|
320
341
|
|
|
321
342
|
// Check if sender is a contract address on destination chain
|
|
322
343
|
useEffect(() => {
|
|
323
344
|
const checkSenderContractOnDestination = async () => {
|
|
324
|
-
if (
|
|
345
|
+
if (
|
|
346
|
+
account?.address &&
|
|
347
|
+
selectedDestinationChain?.id &&
|
|
348
|
+
destinationChainPublicClient
|
|
349
|
+
) {
|
|
325
350
|
try {
|
|
326
351
|
const isContract = await getIsContract(
|
|
327
352
|
account.address as `0x${string}`,
|
|
328
353
|
selectedDestinationChain.id,
|
|
354
|
+
destinationChainPublicClient,
|
|
329
355
|
)
|
|
330
356
|
logger.console.log(
|
|
331
357
|
"[trails-sdk] isSenderContractOnDestination:",
|
|
@@ -345,7 +371,11 @@ export function useSendForm({
|
|
|
345
371
|
}
|
|
346
372
|
|
|
347
373
|
checkSenderContractOnDestination()
|
|
348
|
-
}, [
|
|
374
|
+
}, [
|
|
375
|
+
account?.address,
|
|
376
|
+
selectedDestinationChain?.id,
|
|
377
|
+
destinationChainPublicClient,
|
|
378
|
+
])
|
|
349
379
|
|
|
350
380
|
const isCustomToken = useMemo(() => toToken?.startsWith("0x"), [toToken])
|
|
351
381
|
|
|
@@ -886,6 +916,8 @@ export function useSendForm({
|
|
|
886
916
|
walletId,
|
|
887
917
|
sequenceIndexerUrl,
|
|
888
918
|
sequenceProjectAccessKey: trailsApiKey,
|
|
919
|
+
originPublicClient: originChainPublicClient ?? undefined,
|
|
920
|
+
destinationPublicClient: destinationChainPublicClient ?? undefined,
|
|
889
921
|
}
|
|
890
922
|
|
|
891
923
|
logger.console.log(
|
|
@@ -975,14 +1007,18 @@ export function useSendForm({
|
|
|
975
1007
|
selectedFeeOption,
|
|
976
1008
|
walletId,
|
|
977
1009
|
buildQuoteInputsFingerprint,
|
|
1010
|
+
originChainPublicClient,
|
|
1011
|
+
destinationChainPublicClient,
|
|
978
1012
|
])
|
|
979
1013
|
|
|
980
1014
|
// Auto-fetch quotes when inputs change (debounced)
|
|
981
1015
|
// biome-ignore lint/correctness/useExhaustiveDependencies: getQuote is intentionally excluded to prevent infinite loop
|
|
982
1016
|
useEffect(() => {
|
|
983
1017
|
// Only trigger if we have the essential inputs
|
|
1018
|
+
// Block empty string or exactly "0"
|
|
984
1019
|
if (
|
|
985
1020
|
!amount ||
|
|
1021
|
+
amount === "0" ||
|
|
986
1022
|
!destinationTokenAddress ||
|
|
987
1023
|
!isValidRecipient ||
|
|
988
1024
|
!selectedDestToken?.symbol ||
|
package/src/widget/index.css
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
@config "../../tailwind.config.ts";
|
|
2
|
-
@import "@0xsequence/design-system/preset";
|
|
3
2
|
@import "tailwindcss";
|
|
4
3
|
@tailwind base;
|
|
5
4
|
@tailwind components;
|
|
6
5
|
@tailwind utilities;
|
|
7
6
|
|
|
8
|
-
|
|
9
7
|
*:focus {
|
|
10
8
|
outline: none;
|
|
11
9
|
}
|
|
@@ -13,7 +11,10 @@
|
|
|
13
11
|
/* Trails Widget Theme Variables - Easy to customize */
|
|
14
12
|
:root {
|
|
15
13
|
/* Font Family - Customizable font for the entire widget */
|
|
16
|
-
--trails-font-family: ui-sans-serif, system-ui, -apple-system,
|
|
14
|
+
--trails-font-family: ui-sans-serif, system-ui, -apple-system,
|
|
15
|
+
BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans",
|
|
16
|
+
sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
|
|
17
|
+
"Noto Color Emoji";
|
|
17
18
|
|
|
18
19
|
/* Border Radius - Customizable border radius for the widget */
|
|
19
20
|
--trails-border-radius-widget: 32px; /* Main widget container border radius */
|
|
@@ -30,20 +31,36 @@
|
|
|
30
31
|
|
|
31
32
|
/* Primary Colors - These apply to both themes */
|
|
32
33
|
--trails-primary: rgb(21 93 252); /* #155DFC - Change this to customize */
|
|
33
|
-
--trails-primary-hover: rgb(
|
|
34
|
+
--trails-primary-hover: rgb(
|
|
35
|
+
17 75 202
|
|
36
|
+
); /* Darker shade of #155DFC - Change this for hover state */
|
|
34
37
|
--trails-primary-disabled: rgb(212 212 216); /* #D4D4D8 - Disabled state */
|
|
35
|
-
--trails-primary-disabled-text: rgb(
|
|
38
|
+
--trails-primary-disabled-text: rgb(
|
|
39
|
+
107 114 128
|
|
40
|
+
); /* gray-500 - Disabled text */
|
|
36
41
|
|
|
37
42
|
/* Modal Button Colors - Customizable modal trigger button */
|
|
38
|
-
--trails-modal-button-bg: var(
|
|
39
|
-
|
|
43
|
+
--trails-modal-button-bg: var(
|
|
44
|
+
--trails-primary,
|
|
45
|
+
rgb(21 93 252)
|
|
46
|
+
); /* Defaults to primary color */
|
|
47
|
+
--trails-modal-button-hover-bg: var(
|
|
48
|
+
--trails-primary-hover,
|
|
49
|
+
rgb(17 75 202)
|
|
50
|
+
); /* Defaults to primary hover */
|
|
40
51
|
--trails-modal-button-text: rgb(255 255 255); /* white text */
|
|
41
52
|
--trails-modal-button-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); /* subtle shadow */
|
|
42
53
|
|
|
43
54
|
/* Percentage Button Colors - Customizable percentage buttons */
|
|
44
|
-
--trails-percentage-button-bg: rgb(
|
|
45
|
-
|
|
46
|
-
|
|
55
|
+
--trails-percentage-button-bg: rgb(
|
|
56
|
+
228 228 231
|
|
57
|
+
); /* #E4E4E7 - Light gray background */
|
|
58
|
+
--trails-percentage-button-text: rgb(
|
|
59
|
+
113 113 123
|
|
60
|
+
); /* #71717B - Dark gray text */
|
|
61
|
+
--trails-percentage-button-hover-bg: rgb(
|
|
62
|
+
212 212 216
|
|
63
|
+
); /* #D4D4D8 - Slightly darker on hover */
|
|
47
64
|
}
|
|
48
65
|
|
|
49
66
|
/* Utility Classes that use CSS Variables */
|
|
@@ -127,8 +144,6 @@
|
|
|
127
144
|
background-color: var(--trails-percentage-button-hover-bg);
|
|
128
145
|
}
|
|
129
146
|
|
|
130
|
-
|
|
131
|
-
|
|
132
147
|
/* Font Family Utility Class */
|
|
133
148
|
.trails-font {
|
|
134
149
|
font-family: var(--trails-font-family);
|
|
@@ -197,8 +212,14 @@
|
|
|
197
212
|
}
|
|
198
213
|
|
|
199
214
|
.trails-dropdown:focus {
|
|
200
|
-
border-color: var(
|
|
201
|
-
|
|
215
|
+
border-color: var(
|
|
216
|
+
--trails-dropdown-focus-border,
|
|
217
|
+
var(--trails-dropdown-border)
|
|
218
|
+
);
|
|
219
|
+
--tw-ring-color: var(
|
|
220
|
+
--trails-dropdown-focus-border,
|
|
221
|
+
var(--trails-dropdown-border)
|
|
222
|
+
);
|
|
202
223
|
}
|
|
203
224
|
|
|
204
225
|
.trails-dropdown-item {
|
|
@@ -242,7 +263,9 @@
|
|
|
242
263
|
--trails-bg-primary: rgb(255 255 255); /* white */
|
|
243
264
|
--trails-bg-secondary: rgb(244 244 245); /* #F4F4F5 */
|
|
244
265
|
--trails-bg-secondary-hover: rgb(228 228 231); /* #E4E4E7 */
|
|
245
|
-
--trails-bg-secondary-focus-border: rgb(
|
|
266
|
+
--trails-bg-secondary-focus-border: rgb(
|
|
267
|
+
244 244 245
|
|
268
|
+
); /* #F4F4F5 - same as secondary bg */
|
|
246
269
|
--trails-bg-tertiary: rgb(243 244 246); /* gray-100 */
|
|
247
270
|
--trails-bg-card: rgb(255 255 255); /* white */
|
|
248
271
|
--trails-bg-overlay: rgb(255 255 255); /* white */
|
|
@@ -277,11 +300,19 @@
|
|
|
277
300
|
--trails-dropdown-hover-bg: rgb(249 250 251); /* gray-50 */
|
|
278
301
|
--trails-dropdown-selected-bg: rgb(243 244 246); /* gray-100 */
|
|
279
302
|
--trails-dropdown-selected-text: rgb(17 24 39); /* gray-900 */
|
|
280
|
-
--trails-dropdown-focus-border: rgb(
|
|
303
|
+
--trails-dropdown-focus-border: rgb(
|
|
304
|
+
21 93 252
|
|
305
|
+
); /* #155DFC - matches input focus border */
|
|
281
306
|
|
|
282
307
|
/* Modal Button Colors - Light Mode */
|
|
283
|
-
--trails-modal-button-bg: var(
|
|
284
|
-
|
|
308
|
+
--trails-modal-button-bg: var(
|
|
309
|
+
--trails-primary,
|
|
310
|
+
rgb(21 93 252)
|
|
311
|
+
); /* #155DFC for light mode */
|
|
312
|
+
--trails-modal-button-hover-bg: var(
|
|
313
|
+
--trails-primary-hover,
|
|
314
|
+
rgb(17 75 202)
|
|
315
|
+
); /* Darker shade of #155DFC for light mode */
|
|
285
316
|
--trails-modal-button-text: rgb(255 255 255); /* white text */
|
|
286
317
|
--trails-modal-button-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); /* subtle shadow for light mode */
|
|
287
318
|
|
|
@@ -319,13 +350,18 @@
|
|
|
319
350
|
--trails-error-border: rgb(254 202 202); /* red-200 */
|
|
320
351
|
|
|
321
352
|
/* Shadow */
|
|
322
|
-
--trails-shadow:
|
|
323
|
-
0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
|
353
|
+
--trails-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
|
324
354
|
|
|
325
355
|
/* Percentage Button Colors - Light Mode */
|
|
326
|
-
--trails-percentage-button-bg: rgb(
|
|
327
|
-
|
|
328
|
-
|
|
356
|
+
--trails-percentage-button-bg: rgb(
|
|
357
|
+
228 228 231
|
|
358
|
+
); /* #E4E4E7 - Light gray background */
|
|
359
|
+
--trails-percentage-button-text: rgb(
|
|
360
|
+
113 113 123
|
|
361
|
+
); /* #71717B - Dark gray text */
|
|
362
|
+
--trails-percentage-button-hover-bg: rgb(
|
|
363
|
+
212 212 216
|
|
364
|
+
); /* #D4D4D8 - Slightly darker on hover */
|
|
329
365
|
}
|
|
330
366
|
|
|
331
367
|
/* Dark Mode Theme Variables */
|
|
@@ -334,7 +370,9 @@
|
|
|
334
370
|
--trails-bg-primary: rgb(17 24 39); /* gray-900 */
|
|
335
371
|
--trails-bg-secondary: rgb(31 41 55); /* gray-800 */
|
|
336
372
|
--trails-bg-secondary-hover: rgb(55 65 81); /* gray-700 */
|
|
337
|
-
--trails-bg-secondary-focus-border: rgb(
|
|
373
|
+
--trails-bg-secondary-focus-border: rgb(
|
|
374
|
+
31 41 55
|
|
375
|
+
); /* gray-800 - same as secondary bg */
|
|
338
376
|
--trails-bg-tertiary: rgb(55 65 81); /* gray-700 */
|
|
339
377
|
--trails-bg-card: rgb(31 41 55); /* gray-800 */
|
|
340
378
|
--trails-bg-overlay: rgb(17 24 39); /* gray-900 */
|
|
@@ -369,20 +407,30 @@
|
|
|
369
407
|
--trails-dropdown-hover-bg: rgb(55 65 81); /* gray-700 */
|
|
370
408
|
--trails-dropdown-selected-bg: rgb(55 65 81); /* gray-700 */
|
|
371
409
|
--trails-dropdown-selected-text: rgb(255 255 255); /* white */
|
|
372
|
-
--trails-dropdown-focus-border: rgb(
|
|
410
|
+
--trails-dropdown-focus-border: rgb(
|
|
411
|
+
21 93 252
|
|
412
|
+
); /* #155DFC - matches input focus border */
|
|
373
413
|
|
|
374
414
|
/* Modal Button Colors - Dark Mode */
|
|
375
|
-
--trails-modal-button-bg: var(
|
|
376
|
-
|
|
415
|
+
--trails-modal-button-bg: var(
|
|
416
|
+
--trails-primary,
|
|
417
|
+
rgb(21 93 252)
|
|
418
|
+
); /* #155DFC for dark mode */
|
|
419
|
+
--trails-modal-button-hover-bg: var(
|
|
420
|
+
--trails-primary-hover,
|
|
421
|
+
rgb(17 75 202)
|
|
422
|
+
); /* Darker shade of #155DFC for dark mode */
|
|
377
423
|
--trails-modal-button-text: rgb(255 255 255); /* white text */
|
|
378
424
|
--trails-modal-button-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.1); /* subtle shadow for dark mode */
|
|
379
425
|
|
|
380
|
-
|
|
426
|
+
/* Token List Colors */
|
|
381
427
|
--trails-list-bg: rgb(31 41 55); /* gray-800 background for token list */
|
|
382
428
|
--trails-list-border: rgb(55 65 81); /* gray-700 border - good balance */
|
|
383
429
|
--trails-list-hover-bg: rgb(55 65 81); /* gray-700 hover */
|
|
384
430
|
--trails-list-item-bg: transparent; /* transparent background for list items */
|
|
385
|
-
--trails-list-item-selected-bg: rgb(
|
|
431
|
+
--trails-list-item-selected-bg: rgb(
|
|
432
|
+
30 58 138
|
|
433
|
+
); /* blue-800 selected for dark mode */
|
|
386
434
|
|
|
387
435
|
/* Widget Border - Customizable widget border */
|
|
388
436
|
--trails-widget-border: none; /* Default widget border */
|
|
@@ -411,13 +459,18 @@
|
|
|
411
459
|
--trails-error-border: rgb(239 68 68 / 0.3); /* red-500 with opacity */
|
|
412
460
|
|
|
413
461
|
/* Shadow */
|
|
414
|
-
--trails-shadow:
|
|
415
|
-
0 1px 3px 0 rgb(0 0 0 / 0.3), 0 1px 2px -1px rgb(0 0 0 / 0.3);
|
|
462
|
+
--trails-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.3), 0 1px 2px -1px rgb(0 0 0 / 0.3);
|
|
416
463
|
|
|
417
464
|
/* Percentage Button Colors - Dark Mode */
|
|
418
|
-
--trails-percentage-button-bg: rgb(
|
|
419
|
-
|
|
420
|
-
|
|
465
|
+
--trails-percentage-button-bg: rgb(
|
|
466
|
+
55 65 81
|
|
467
|
+
); /* gray-700 - Dark gray background */
|
|
468
|
+
--trails-percentage-button-text: rgb(
|
|
469
|
+
209 213 219
|
|
470
|
+
); /* gray-300 - Light gray text */
|
|
471
|
+
--trails-percentage-button-hover-bg: rgb(
|
|
472
|
+
75 85 99
|
|
473
|
+
); /* gray-600 - Slightly lighter on hover */
|
|
421
474
|
}
|
|
422
475
|
|
|
423
476
|
/* Custom Scrollbar Styles */
|
|
@@ -489,7 +542,10 @@
|
|
|
489
542
|
|
|
490
543
|
/* Dark mode primary button */
|
|
491
544
|
.dark .bg-blue-500 {
|
|
492
|
-
background-color: var(
|
|
545
|
+
background-color: var(
|
|
546
|
+
--trails-primary,
|
|
547
|
+
rgb(21 93 252)
|
|
548
|
+
); /* #155DFC for dark mode */
|
|
493
549
|
}
|
|
494
550
|
|
|
495
551
|
/* Light mode hover */
|
|
@@ -499,7 +555,10 @@
|
|
|
499
555
|
|
|
500
556
|
/* Dark mode hover */
|
|
501
557
|
.dark .hover\:bg-blue-600:hover {
|
|
502
|
-
background-color: var(
|
|
558
|
+
background-color: var(
|
|
559
|
+
--trails-primary-hover,
|
|
560
|
+
rgb(17 75 202)
|
|
561
|
+
); /* Darker shade of #155DFC for dark mode */
|
|
503
562
|
}
|
|
504
563
|
|
|
505
564
|
/* Light mode disabled background */
|
|
@@ -542,7 +601,10 @@
|
|
|
542
601
|
|
|
543
602
|
/* Modal Button Utility Classes */
|
|
544
603
|
.trails-modal-button {
|
|
545
|
-
background-color: var(
|
|
604
|
+
background-color: var(
|
|
605
|
+
--trails-modal-button-bg,
|
|
606
|
+
var(--trails-primary, rgb(59 130 246))
|
|
607
|
+
);
|
|
546
608
|
color: var(--trails-modal-button-text, rgb(255 255 255));
|
|
547
609
|
box-shadow: var(--trails-modal-button-shadow, 0 1px 2px 0 rgb(0 0 0 / 0.05));
|
|
548
610
|
transition: all 0.2s ease-in-out;
|
|
@@ -550,5 +612,8 @@
|
|
|
550
612
|
}
|
|
551
613
|
|
|
552
614
|
.trails-modal-button:hover {
|
|
553
|
-
background-color: var(
|
|
615
|
+
background-color: var(
|
|
616
|
+
--trails-modal-button-hover-bg,
|
|
617
|
+
var(--trails-primary-hover, rgb(37 99 235))
|
|
618
|
+
);
|
|
554
619
|
}
|
package/src/widget/widget.tsx
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import "@0xsequence/design-system/preset"
|
|
2
1
|
import { AaveClient, AaveProvider } from "@aave/react"
|
|
3
2
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
|
|
4
3
|
import { AnimatePresence, motion } from "motion/react"
|
|
@@ -16,7 +15,7 @@ import React, {
|
|
|
16
15
|
} from "react"
|
|
17
16
|
import { createPortal } from "react-dom"
|
|
18
17
|
import type { Chain, WalletClient } from "viem"
|
|
19
|
-
import { createWalletClient, custom, http, isAddress } from "viem"
|
|
18
|
+
import { createWalletClient, custom, defineChain, http, isAddress } from "viem"
|
|
20
19
|
import type { Connector } from "wagmi"
|
|
21
20
|
import {
|
|
22
21
|
createConfig,
|
|
@@ -88,6 +87,7 @@ import type { MeshConnectProps } from "./components/MeshConnectIframe.js"
|
|
|
88
87
|
import Modal from "./components/Modal.js"
|
|
89
88
|
import { Pay } from "./components/Pay.js"
|
|
90
89
|
import QRCodeDeposit from "./components/QRCodeDeposit.js"
|
|
90
|
+
import QRCodeOptions from "./components/QRCodeOptions.js"
|
|
91
91
|
import QRCodeWalletSelect from "./components/QRCodeWalletSelect.js"
|
|
92
92
|
import Receipt from "./components/Receipt.js"
|
|
93
93
|
import { Receive } from "./components/Receive.js"
|
|
@@ -306,9 +306,34 @@ const useWalletManager = (
|
|
|
306
306
|
const activeProvider = await connector.getProvider()
|
|
307
307
|
|
|
308
308
|
if (activeProvider && address && chainId) {
|
|
309
|
-
|
|
309
|
+
let chain = getChainInfo(chainId)
|
|
310
|
+
|
|
311
|
+
// If chain is not supported, create a minimal chain object.
|
|
312
|
+
// This allows walletClient to be created even on unsupported networks.
|
|
313
|
+
// The Problem:
|
|
314
|
+
// When Metamask is on a network not supported by the wagmi config, useWalletManager
|
|
315
|
+
// in widget.tsx calls getChainInfo(chainId), which returns null for unsupported chains.
|
|
316
|
+
// The function then returns early without creating a walletClient, so walletClient?.account is undefined,
|
|
317
|
+
// causing the "Connect your wallet" message in the button.
|
|
310
318
|
if (!chain) {
|
|
311
|
-
|
|
319
|
+
logger.console.warn(
|
|
320
|
+
`[trails-sdk] Chain ${chainId} not found in supported chains, creating minimal chain object`,
|
|
321
|
+
)
|
|
322
|
+
// Create a minimal chain definition for unsupported chains
|
|
323
|
+
chain = defineChain({
|
|
324
|
+
id: chainId,
|
|
325
|
+
name: `Chain ${chainId}`,
|
|
326
|
+
nativeCurrency: {
|
|
327
|
+
name: "Ether",
|
|
328
|
+
symbol: "ETH",
|
|
329
|
+
decimals: 18,
|
|
330
|
+
},
|
|
331
|
+
rpcUrls: {
|
|
332
|
+
default: {
|
|
333
|
+
http: [],
|
|
334
|
+
},
|
|
335
|
+
},
|
|
336
|
+
}) as Chain
|
|
312
337
|
}
|
|
313
338
|
|
|
314
339
|
const client = createWalletClient({
|
|
@@ -969,6 +994,13 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
969
994
|
address,
|
|
970
995
|
)
|
|
971
996
|
|
|
997
|
+
// Clear fee option preference from localStorage when wallet changes
|
|
998
|
+
try {
|
|
999
|
+
localStorage.removeItem("trails-fee-option-preference")
|
|
1000
|
+
} catch {
|
|
1001
|
+
// Ignore localStorage errors (e.g., in private browsing mode)
|
|
1002
|
+
}
|
|
1003
|
+
|
|
972
1004
|
// Check if we're on screens that should reset when account changes
|
|
973
1005
|
const screensToReset = [
|
|
974
1006
|
"send-form",
|
|
@@ -1334,7 +1366,8 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1334
1366
|
setPrepareSendQuote(null)
|
|
1335
1367
|
setTotalCompletionSeconds(null)
|
|
1336
1368
|
clearHistory()
|
|
1337
|
-
//
|
|
1369
|
+
// Clear selected fee option, but localStorage preference is preserved
|
|
1370
|
+
// Auto-selection will use the preference when fee options render next time
|
|
1338
1371
|
clearSelectedFeeOption()
|
|
1339
1372
|
}, [
|
|
1340
1373
|
setSelectedFundMethod,
|
|
@@ -1642,6 +1675,16 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
|
|
|
1642
1675
|
setCurrentScreen("home")
|
|
1643
1676
|
}}
|
|
1644
1677
|
onSelectQrCode={() => {
|
|
1678
|
+
setCurrentScreen("qrcode-options")
|
|
1679
|
+
}}
|
|
1680
|
+
/>
|
|
1681
|
+
)
|
|
1682
|
+
case "qrcode-options":
|
|
1683
|
+
return (
|
|
1684
|
+
<QRCodeOptions
|
|
1685
|
+
onBack={handleBack}
|
|
1686
|
+
onSelectWalletConnect={handleSelectWalletConnect}
|
|
1687
|
+
onSelectQRCode={() => {
|
|
1645
1688
|
setSelectedFundMethod("qr-code")
|
|
1646
1689
|
setCurrentScreen("home")
|
|
1647
1690
|
}}
|
package/dist/0xtrails.css
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
@source "./";:root,[data-theme=dark]{--seq-color-positive: #1fc266;--seq-color-negative: #c2501f;--seq-color-info: #0076cc;--seq-color-warning: #f4b03e;--seq-color-primary: rgba(255, 255, 255, 1);--seq-color-secondary: rgba(255, 255, 255, .8);--seq-color-muted: rgba(255, 255, 255, .5);--seq-color-inverse: rgba(0, 0, 0, 1);--seq-color-background-primary: rgba(0, 0, 0, 1);--seq-color-background-secondary: rgba(255, 255, 255, .1);--seq-color-background-contrast: rgba(0, 0, 0, .5);--seq-color-background-muted: rgba(255, 255, 255, .05);--seq-color-background-control: rgba(255, 255, 255, .25);--seq-color-background-inverse: rgba(255, 255, 255, 1);--seq-color-background-backdrop: rgba(34, 34, 34, .9);--seq-color-background-overlay: rgba(0, 0, 0, .7);--seq-color-background-raised: rgba(54, 54, 54, .7);--seq-color-border-normal: rgba(255, 255, 255, .25);--seq-color-border-focus: rgba(255, 255, 255, .5);--seq-color-border-error: rgba(255, 69, 0, 1);--seq-color-button-glass: rgba(255, 255, 255, .15);--seq-color-button-emphasis: rgba(0, 0, 0, .5);--seq-color-button-inverse: rgba(255, 255, 255, .8);--seq-color-gradient-backdrop: linear-gradient( 243.18deg, rgba(86, 52, 189, .85) 0%, rgba(49, 41, 223, .85) 63.54%, rgba(7, 98, 149, .85) 100% );--seq-color-gradient-primary: linear-gradient( 89.69deg, #4411e1 .27%, #7537f9 99.73% );--seq-color-gradient-secondary: linear-gradient( 32.51deg, #951990 -15.23%, #3a35b1 48.55%, #20a8b0 100% );--seq-color-gradient-skeleton: linear-gradient( -45deg, transparent, var(--seq-color-background-secondary), transparent )}[data-theme=light]{--seq-color-positive: #1fc266;--seq-color-negative: #c2501f;--seq-color-info: #0076cc;--seq-color-warning: #f4b03e;--seq-color-primary: rgba(0, 0, 0, 1);--seq-color-secondary: rgba(0, 0, 0, .8);--seq-color-muted: rgba(0, 0, 0, .5);--seq-color-inverse: rgba(255, 255, 255, 1);--seq-color-background-primary: rgba(244, 244, 244, 1);--seq-color-background-secondary: rgba(0, 0, 0, .1);--seq-color-background-contrast: rgba(244, 244, 244, .5);--seq-color-background-muted: rgba(0, 0, 0, .05);--seq-color-background-control: rgba(0, 0, 0, .25);--seq-color-background-inverse: rgba(0, 0, 0, 1);--seq-color-background-backdrop: rgba(221, 221, 221, .9);--seq-color-background-overlay: rgba(244, 244, 244, .7);--seq-color-background-raised: rgba(192, 192, 192, .7);--seq-color-border-normal: rgba(0, 0, 0, .25);--seq-color-border-focus: rgba(0, 0, 0, .5);--seq-color-border-error: rgba(255, 69, 0, 1);--seq-color-button-glass: rgba(0, 0, 0, .15);--seq-color-button-emphasis: rgba(255, 255, 255, .5);--seq-color-button-inverse: rgba(0, 0, 0, .8);--seq-color-gradient-backdrop: linear-gradient( 243.18deg, rgba(86, 52, 189, .85) 0%, rgba(49, 41, 223, .85) 63.54%, rgba(7, 98, 149, .85) 100% );--seq-color-gradient-primary: linear-gradient( 89.69deg, #4411e1 .27%, #7537f9 99.73% );--seq-color-gradient-secondary: linear-gradient( 32.51deg, #951990 -15.23%, #3a35b1 48.55%, #20a8b0 100% );--seq-color-gradient-skeleton: linear-gradient( -45deg, transparent, var(--seq-color-background-secondary), transparent )}@theme inline{ --font-body: "Inter", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; --font-mono: "Roboto", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; --color-primary: var(--seq-color-primary); --color-secondary: var(--seq-color-secondary); --color-muted: var(--seq-color-muted); --color-inverse: var(--seq-color-inverse); --color-positive: var(--seq-color-positive); --color-negative: var(--seq-color-negative); --color-info: var(--seq-color-info); --color-warning: var(--seq-color-warning); --color-background-primary: var(--seq-color-background-primary); --color-background-secondary: var(--seq-color-background-secondary); --color-background-contrast: var(--seq-color-background-contrast); --color-background-muted: var(--seq-color-background-muted); --color-background-control: var(--seq-color-background-control); --color-background-inverse: var(--seq-color-background-inverse); --color-background-backdrop: var(--seq-color-background-backdrop); --color-background-overlay: var(--seq-color-background-overlay); --color-background-raised: var(--seq-color-background-raised); --color-border-normal: var(--seq-color-border-normal); --color-border-focus: var(--seq-color-border-focus); --color-border-error: var(--seq-color-border-error); --color-button-glass: var(--seq-color-button-glass); --color-button-emphasis: var(--seq-color-button-emphasis); --color-button-inverse: var(--seq-color-button-inverse); --background-image-gradient-backdrop: var(--seq-color-gradient-backdrop); --background-image-gradient-primary: var(--seq-color-gradient-primary); --background-image-gradient-secondary: var(--seq-color-gradient-secondary); --background-image-gradient-skeleton: var(--seq-color-gradient-skeleton); --animate-skeleton: skeleton 1s ease infinite; --animate-swipe-out: swipe-out .2s ease-out; @keyframes skeleton { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } @keyframes swipe-out { from { transform: translateX(var(--radix-toast-swipe-end-x)); } to { transform: translateX(100%); } } }
|