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.
Files changed (88) hide show
  1. package/dist/{ccip-Dw5AN7oU.js → ccip-CZfykYU7.js} +4 -4
  2. package/dist/chains.d.ts +9 -2
  3. package/dist/chains.d.ts.map +1 -1
  4. package/dist/constants.d.ts +1 -0
  5. package/dist/constants.d.ts.map +1 -1
  6. package/dist/contractUtils.d.ts +2 -1
  7. package/dist/contractUtils.d.ts.map +1 -1
  8. package/dist/{index-BtVUTbEZ.js → index-S9pphnT9.js} +29732 -36767
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +300 -242
  12. package/dist/prepareSend.d.ts.map +1 -1
  13. package/dist/transactionIntent/handlers/crossChain.d.ts.map +1 -1
  14. package/dist/transactionIntent/handlers/sameChainSameToken.d.ts.map +1 -1
  15. package/dist/transactionIntent/types.d.ts +3 -1
  16. package/dist/transactionIntent/types.d.ts.map +1 -1
  17. package/dist/widget/components/ChainImage.d.ts.map +1 -1
  18. package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
  19. package/dist/widget/components/DepositTracker.d.ts +12 -0
  20. package/dist/widget/components/DepositTracker.d.ts.map +1 -0
  21. package/dist/widget/components/Disconnect.d.ts.map +1 -1
  22. package/dist/widget/components/FeeBreakdown.d.ts.map +1 -1
  23. package/dist/widget/components/QRCodeDeposit.d.ts.map +1 -1
  24. package/dist/widget/components/QRCodeOptions.d.ts +9 -0
  25. package/dist/widget/components/QRCodeOptions.d.ts.map +1 -0
  26. package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
  27. package/dist/widget/components/Receipt.d.ts.map +1 -1
  28. package/dist/widget/components/ThemeProvider.d.ts.map +1 -1
  29. package/dist/widget/components/Toast.d.ts.map +1 -1
  30. package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
  31. package/dist/widget/components/WalletConnectionPending.d.ts.map +1 -1
  32. package/dist/widget/css/compiled.css +1 -1
  33. package/dist/widget/css/index.css +103 -38
  34. package/dist/widget/hooks/useCheckout.d.ts.map +1 -1
  35. package/dist/widget/hooks/useCurrentScreen.d.ts +1 -1
  36. package/dist/widget/hooks/useCurrentScreen.d.ts.map +1 -1
  37. package/dist/widget/hooks/useDebugScreens.d.ts +1 -1
  38. package/dist/widget/hooks/useDebugScreens.d.ts.map +1 -1
  39. package/dist/widget/hooks/useIntentTransactionHistory.d.ts.map +1 -1
  40. package/dist/widget/hooks/useQuote.d.ts.map +1 -1
  41. package/dist/widget/hooks/useSelectedFeeOption.d.ts.map +1 -1
  42. package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
  43. package/dist/widget/index.js +1 -1
  44. package/dist/widget/widget.d.ts.map +1 -1
  45. package/package.json +6 -9
  46. package/src/chains.ts +37 -4
  47. package/src/constants.ts +1 -0
  48. package/src/contractUtils.ts +8 -7
  49. package/src/estimate.ts +2 -2
  50. package/src/index.ts +2 -0
  51. package/src/intents.ts +2 -2
  52. package/src/paymasterSend.ts +2 -2
  53. package/src/prepareSend.ts +34 -3
  54. package/src/sendUserOp.ts +2 -2
  55. package/src/tokens.ts +2 -2
  56. package/src/transactionIntent/deposits/gaslessDeposit.ts +2 -2
  57. package/src/transactionIntent/handlers/crossChain.ts +51 -2
  58. package/src/transactionIntent/handlers/sameChainSameToken.ts +52 -2
  59. package/src/transactionIntent/quote/normalizeQuote.ts +2 -2
  60. package/src/transactionIntent/types.ts +9 -1
  61. package/src/widget/compiled.css +1 -1
  62. package/src/widget/components/ChainImage.tsx +10 -7
  63. package/src/widget/components/ChainList.tsx +1 -1
  64. package/src/widget/components/ClassicSwap.tsx +8 -4
  65. package/src/widget/components/ConnectedWallets.tsx +1 -1
  66. package/src/widget/components/DepositTracker.tsx +298 -0
  67. package/src/widget/components/Disconnect.tsx +24 -3
  68. package/src/widget/components/FeeBreakdown.tsx +3 -3
  69. package/src/widget/components/QRCodeDeposit.tsx +29 -19
  70. package/src/widget/components/QRCodeOptions.tsx +65 -0
  71. package/src/widget/components/QuoteDetails.tsx +694 -803
  72. package/src/widget/components/Receipt.tsx +76 -40
  73. package/src/widget/components/ThemeProvider.tsx +7 -12
  74. package/src/widget/components/Toast.tsx +3 -2
  75. package/src/widget/components/TokenSelector.tsx +1 -1
  76. package/src/widget/components/Tooltip.tsx +1 -1
  77. package/src/widget/components/TransferPendingVertical.tsx +11 -2
  78. package/src/widget/components/WalletConnectionPending.tsx +28 -5
  79. package/src/widget/hooks/useCheckout.ts +10 -2
  80. package/src/widget/hooks/useCurrentScreen.tsx +1 -0
  81. package/src/widget/hooks/useDebugScreens.ts +1 -0
  82. package/src/widget/hooks/useIntentTransactionHistory.ts +114 -143
  83. package/src/widget/hooks/useQuote.ts +92 -6
  84. package/src/widget/hooks/useSelectedFeeOption.tsx +86 -29
  85. package/src/widget/hooks/useSendForm.ts +43 -7
  86. package/src/widget/index.css +103 -38
  87. package/src/widget/widget.tsx +48 -5
  88. package/dist/0xtrails.css +0 -1
@@ -15,6 +15,7 @@ import { ChainImage } from "./ChainImage.js"
15
15
  import { getChainInfo } from "../../chains.js"
16
16
  import { useMode } from "../hooks/useMode.js"
17
17
  import { ScreenHeader } from "./ScreenHeader.js"
18
+ import { getExplorerUrl } from "../../explorer.js"
18
19
 
19
20
  interface ReceiptProps {
20
21
  onSendAnother: () => void
@@ -63,11 +64,26 @@ function useTxTimeDiff(firstTx?: TransactionState, lastTx?: TransactionState) {
63
64
 
64
65
  // Custom hook to compute finalExplorerUrl and completionTimeSeconds
65
66
  function useReceipt(transactionStates?: TransactionState[]) {
66
- const lastTx = transactionStates?.[transactionStates.length - 1]
67
- const finalExplorerUrl = lastTx?.explorerUrl
68
- const finalChainId = lastTx?.chainId
69
-
70
- // Only consider confirmed transactions
67
+ // Find the latest transaction with a hash (regardless of state)
68
+ // This ensures we can link to explorer even for failed/refunded transactions
69
+ const latestTxWithHash = (transactionStates || [])
70
+ .slice()
71
+ .reverse()
72
+ .find((tx) => tx.transactionHash && tx.chainId)
73
+
74
+ // Generate explorer URL if we have a hash but no URL
75
+ const finalExplorerUrl =
76
+ latestTxWithHash?.explorerUrl ||
77
+ (latestTxWithHash?.transactionHash && latestTxWithHash?.chainId
78
+ ? getExplorerUrl({
79
+ txHash: latestTxWithHash.transactionHash,
80
+ chainId: latestTxWithHash.chainId,
81
+ })
82
+ : null)
83
+
84
+ const finalChainId = latestTxWithHash?.chainId
85
+
86
+ // Only consider confirmed transactions for completion time
71
87
  const confirmedTxs = (transactionStates || []).filter(
72
88
  (tx) => tx.state === "confirmed",
73
89
  )
@@ -172,9 +188,12 @@ export const Receipt: React.FC<ReceiptProps> = ({
172
188
  <QuoteDetails quote={quote} showContent={true} compact={true}>
173
189
  {transactionStates.length > 0 && (
174
190
  <>
175
- <div className="font-medium text-gray-700 dark:text-gray-300">
176
- Transactions:
191
+ <div className="h-px bg-gray-200 dark:bg-gray-800 my-4" />
192
+
193
+ <div className="text-sm font-semibold text-gray-900 dark:text-white mb-2">
194
+ Transactions
177
195
  </div>
196
+
178
197
  <div className="space-y-2">
179
198
  {transactionStates.map((state, i) => (
180
199
  <div
@@ -182,8 +201,8 @@ export const Receipt: React.FC<ReceiptProps> = ({
182
201
  className="p-2 rounded bg-gray-100 dark:bg-gray-700/50"
183
202
  >
184
203
  <div className="flex justify-between items-center">
185
- <span className="text-gray-600 dark:text-gray-400">
186
- {state.label}:
204
+ <span className="text-xs text-gray-600 dark:text-gray-400">
205
+ {state.label}
187
206
  </span>
188
207
  <span
189
208
  className={`px-2 py-0.5 rounded-full text-xs ${
@@ -197,14 +216,14 @@ export const Receipt: React.FC<ReceiptProps> = ({
197
216
  </span>
198
217
  </div>
199
218
  <div className="mt-1 flex justify-between items-center">
200
- <span className="text-gray-600 dark:text-gray-400">
201
- Hash:
219
+ <span className="text-xs text-gray-600 dark:text-gray-400">
220
+ Hash
202
221
  </span>
203
222
  <a
204
223
  href={state.explorerUrl}
205
224
  target="_blank"
206
225
  rel="noopener noreferrer"
207
- className="flex items-center gap-1 hover:underline text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
226
+ className="text-xs flex items-center gap-1 hover:underline text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
208
227
  >
209
228
  {hasMetaTxError(state) && (
210
229
  <svg
@@ -251,7 +270,12 @@ export const Receipt: React.FC<ReceiptProps> = ({
251
270
  </div>
252
271
  )
253
272
 
254
- if (!finalExplorerUrl && !showRefundInfo) {
273
+ // Only show error state if we truly have no transaction hash at all
274
+ const hasAnyTransactionHash = transactionStates.some(
275
+ (tx) => tx.transactionHash,
276
+ )
277
+
278
+ if (!finalExplorerUrl && !showRefundInfo && !hasAnyTransactionHash) {
255
279
  return (
256
280
  <div className="flex flex-col justify-center min-h-full space-y-6">
257
281
  <ScreenHeader />
@@ -327,7 +351,11 @@ export const Receipt: React.FC<ReceiptProps> = ({
327
351
  </div>
328
352
 
329
353
  <div
330
- className={`transition-all duration-500 ease-out ${showContent ? "opacity-100 translate-y-0" : "opacity-0 translate-y-4"}`}
354
+ className={`transition-all duration-500 ease-out ${
355
+ showContent
356
+ ? "opacity-100 translate-y-0"
357
+ : "opacity-0 translate-y-4"
358
+ }`}
331
359
  >
332
360
  <h2 className="mt-4 text-2xl font-bold text-gray-900 dark:text-white">
333
361
  {showRefundInfo ? "Unable to process." : "Completed"}
@@ -414,33 +442,39 @@ export const Receipt: React.FC<ReceiptProps> = ({
414
442
  </div>
415
443
  </div>
416
444
 
417
- <div
418
- className={`text-center transition-all duration-500 ease-out delay-100 ${showContent ? "opacity-100 translate-y-0" : "opacity-0 translate-y-4"}`}
419
- >
420
- <a
421
- href={finalExplorerUrl}
422
- target="_blank"
423
- rel="noopener noreferrer"
424
- className="inline-flex items-center gap-1 px-3 py-1.5 rounded-md font-medium transition-colors border border-solid text-sm bg-white border-gray-200 text-black hover:bg-gray-50 hover:text-gray-900 dark:bg-gray-900 dark:border-gray-700 dark:text-blue-300 dark:hover:bg-gray-800 dark:hover:text-blue-200"
445
+ {finalExplorerUrl && (
446
+ <div
447
+ className={`text-center transition-all duration-500 ease-out delay-100 ${
448
+ showContent
449
+ ? "opacity-100 translate-y-0"
450
+ : "opacity-0 translate-y-4"
451
+ }`}
425
452
  >
426
- {finalChainId && <ChainImage chainId={finalChainId} size={16} />}
427
- View on Explorer
428
- <svg
429
- className="w-4 h-4 ml-1 text-black dark:text-blue-300"
430
- fill="none"
431
- viewBox="0 0 24 24"
432
- stroke="currentColor"
453
+ <a
454
+ href={finalExplorerUrl}
455
+ target="_blank"
456
+ rel="noopener noreferrer"
457
+ className="inline-flex items-center gap-1 px-3 py-1.5 rounded-md font-medium transition-colors border border-solid text-sm bg-white border-gray-200 text-black hover:bg-gray-50 hover:text-gray-900 dark:bg-gray-900 dark:border-gray-700 dark:text-blue-300 dark:hover:bg-gray-800 dark:hover:text-blue-200"
433
458
  >
434
- <title>External Link</title>
435
- <path
436
- strokeLinecap="round"
437
- strokeLinejoin="round"
438
- strokeWidth={2}
439
- d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
440
- />
441
- </svg>
442
- </a>
443
- </div>
459
+ {finalChainId && <ChainImage chainId={finalChainId} size={16} />}
460
+ View on Explorer
461
+ <svg
462
+ className="w-4 h-4 ml-1 text-black dark:text-blue-300"
463
+ fill="none"
464
+ viewBox="0 0 24 24"
465
+ stroke="currentColor"
466
+ >
467
+ <title>External Link</title>
468
+ <path
469
+ strokeLinecap="round"
470
+ strokeLinejoin="round"
471
+ strokeWidth={2}
472
+ d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
473
+ />
474
+ </svg>
475
+ </a>
476
+ </div>
477
+ )}
444
478
 
445
479
  {showRefundInfo && refundMessage && (
446
480
  <div
@@ -485,7 +519,9 @@ export const Receipt: React.FC<ReceiptProps> = ({
485
519
  )}
486
520
 
487
521
  <div
488
- className={`space-y-3 transition-all duration-500 ease-out delay-200 ${showContent ? "opacity-100 translate-y-0" : "opacity-0 translate-y-4"}`}
522
+ className={`space-y-3 transition-all duration-500 ease-out delay-200 ${
523
+ showContent ? "opacity-100 translate-y-0" : "opacity-0 translate-y-4"
524
+ }`}
489
525
  >
490
526
  {onSendAnother && (
491
527
  <div className="flex justify-center">
@@ -1,7 +1,6 @@
1
1
  import type React from "react"
2
2
  import { createContext, useContext, useEffect, useState } from "react"
3
3
  import type { Theme } from "../../theme.js"
4
- import { ThemeProvider as DesignSystemThemeProvider } from "@0xsequence/design-system"
5
4
  import { logger } from "../../logger.js"
6
5
  import { DEFAULT_THEME } from "../../constants.js"
7
6
 
@@ -98,18 +97,14 @@ export const ThemeProvider: React.FC<ThemeProviderProps> = ({
98
97
  }
99
98
 
100
99
  return (
101
- <DesignSystemThemeProvider theme={theme === "dark" ? "dark" : "light"}>
102
- <ThemeContext.Provider
103
- value={{ theme, setTheme, isDark, getActiveTheme }}
100
+ <ThemeContext.Provider value={{ theme, setTheme, isDark, getActiveTheme }}>
101
+ <div
102
+ className={isDark ? "dark" : ""}
103
+ data-theme={isDark ? "dark" : "light"}
104
104
  >
105
- <div
106
- className={isDark ? "dark" : ""}
107
- data-theme={isDark ? "dark" : "light"}
108
- >
109
- {children}
110
- </div>
111
- </ThemeContext.Provider>
112
- </DesignSystemThemeProvider>
105
+ {children}
106
+ </div>
107
+ </ThemeContext.Provider>
113
108
  )
114
109
  }
115
110
 
@@ -18,6 +18,7 @@ import {
18
18
  } from "../../toast.js"
19
19
  import { useWidgetProps } from "../hooks/useWidgetProps.js"
20
20
  import { useTheme } from "./ThemeProvider.js"
21
+ import { TRAILS_SUPPORT_URL } from "../../constants.js"
21
22
  import css from "../compiled.css?inline"
22
23
 
23
24
  const TRAILS_ICON_URL = "https://trails.build/web-app-manifest-192x192.png"
@@ -300,10 +301,10 @@ function ToastItem({ toast, onRemove }: ToastItemProps) {
300
301
  </p>
301
302
  {toast.type === "error" && (
302
303
  <a
303
- href="https://support.trails.build/en/"
304
+ href={TRAILS_SUPPORT_URL}
304
305
  target="_blank"
305
306
  rel="noopener noreferrer"
306
- className="mt-2 text-xs text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 underline inline-block"
307
+ className="mt-2 text-xs text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 hover:underline inline-block"
307
308
  >
308
309
  Visit support
309
310
  </a>
@@ -1,7 +1,7 @@
1
1
  import { ChevronLeft, Copy } from "lucide-react"
2
2
  import type React from "react"
3
3
  import { useState, useMemo } from "react"
4
- import { AnimatePresence, motion } from "framer-motion"
4
+ import { AnimatePresence, motion } from "motion/react"
5
5
  import { zeroAddress } from "viem"
6
6
  import type { Token, TokenFormatted } from "../hooks/useTokenList.js"
7
7
  import { useTokenList } from "../hooks/useTokenList.js"
@@ -1,5 +1,5 @@
1
1
  import type React from "react"
2
- import { TooltipPrimitive } from "@0xsequence/design-system"
2
+ import * as TooltipPrimitive from "@radix-ui/react-tooltip"
3
3
  import { useTheme } from "./ThemeProvider.js"
4
4
 
5
5
  interface TooltipProps {
@@ -10,6 +10,7 @@ import { OriginTransferInformation } from "./OriginTransferInformation.js"
10
10
  import { ScreenHeader } from "./ScreenHeader.js"
11
11
  import { ChevronRight } from "lucide-react"
12
12
  import { useMode } from "../hooks/useMode.js"
13
+ import { TRAILS_SUPPORT_URL } from "../../constants.js"
13
14
 
14
15
  // Checkmark icon for completed steps
15
16
  const CheckmarkIcon = () => (
@@ -521,8 +522,16 @@ export const TransferPending: React.FC<TransferPendingProps> = ({
521
522
  Transaction taking longer than expected
522
523
  </p>
523
524
  <p className="mt-1 text-xs text-yellow-700 dark:text-yellow-400">
524
- This transaction is taking longer than expected. Please reach
525
- out to support for help if the issue persists.
525
+ This transaction is taking longer than expected.{" "}
526
+ <a
527
+ href={TRAILS_SUPPORT_URL}
528
+ target="_blank"
529
+ rel="noopener noreferrer"
530
+ className="text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 hover:underline"
531
+ >
532
+ Visit support
533
+ </a>{" "}
534
+ for help if the issue persists.
526
535
  </p>
527
536
  </div>
528
537
  </div>
@@ -2,6 +2,7 @@ import { ChevronLeft } from "lucide-react"
2
2
  import type React from "react"
3
3
  import { useEffect, useState } from "react"
4
4
  import { useWallets } from "../../wallets.js"
5
+ import { TRAILS_SUPPORT_URL } from "../../constants.js"
5
6
 
6
7
  interface WalletConnectionPendingProps {
7
8
  onBack?: () => void
@@ -93,9 +94,23 @@ export const WalletConnectionPending: React.FC<
93
94
  {error ? "Connection failed" : `Waiting for ${walletName}…`}
94
95
  </h2>
95
96
  <p className="mt-2 text-sm text-gray-600 dark:text-gray-300">
96
- {error
97
- ? "There was an issue connecting to your wallet. Please try again."
98
- : "Please approve the connection request in your wallet"}
97
+ {error ? (
98
+ <>
99
+ There was an issue connecting to your wallet. Please try
100
+ again.{" "}
101
+ <a
102
+ href={TRAILS_SUPPORT_URL}
103
+ target="_blank"
104
+ rel="noopener noreferrer"
105
+ className="text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 hover:underline"
106
+ >
107
+ Visit support
108
+ </a>{" "}
109
+ if the issue persists.
110
+ </>
111
+ ) : (
112
+ "Please approve the connection request in your wallet"
113
+ )}
99
114
  </p>
100
115
  </div>
101
116
  </div>
@@ -126,8 +141,16 @@ export const WalletConnectionPending: React.FC<
126
141
  Connection is taking longer than expected
127
142
  </p>
128
143
  <p className="mt-1 text-xs text-yellow-700 dark:text-yellow-400">
129
- This connection request is taking longer than expected.
130
- Please reach out to support for help if the issue persists.
144
+ This connection request is taking longer than expected.{" "}
145
+ <a
146
+ href={TRAILS_SUPPORT_URL}
147
+ target="_blank"
148
+ rel="noopener noreferrer"
149
+ className="text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 hover:underline"
150
+ >
151
+ Visit support
152
+ </a>{" "}
153
+ for help if the issue persists.
131
154
  </p>
132
155
  </div>
133
156
  </div>
@@ -1,7 +1,11 @@
1
1
  import { useCallback, useRef } from "react"
2
2
  import { getSessionId } from "../../analytics.js"
3
3
  import { logger } from "../../logger.js"
4
- import { updatePersistentToast } from "../../toast.js"
4
+ import {
5
+ updatePersistentToast,
6
+ showToast,
7
+ removePersistentToast,
8
+ } from "../../toast.js"
5
9
  import {
6
10
  getPrettifiedErrorMessage,
7
11
  getIsUserRejectionError,
@@ -239,10 +243,14 @@ export function useCheckout({
239
243
  // Invalidate token balances cache to trigger a refresh
240
244
  invalidateTokenBalancesCache(accountAddress)
241
245
 
242
- updatePersistentToast(
246
+ // Dismiss any persistent toast before showing success toast
247
+ removePersistentToast()
248
+
249
+ showToast(
243
250
  "Transaction Complete",
244
251
  "Your transaction has been successfully processed",
245
252
  "success",
253
+ 5000, // 5 seconds
246
254
  )
247
255
  } else {
248
256
  // Default to error for any non-success status (including 'fail' and any unexpected values)
@@ -27,6 +27,7 @@ export type Screen =
27
27
  | "chain-list"
28
28
  | "disconnect"
29
29
  | "home"
30
+ | "qrcode-options"
30
31
 
31
32
  interface CurrentScreenContextType {
32
33
  currentScreen: Screen
@@ -28,6 +28,7 @@ type Screen =
28
28
  | "account-settings"
29
29
  | "user-preferences"
30
30
  | "chain-list"
31
+ | "qrcode-options"
31
32
 
32
33
  interface UseDebugScreensProps {
33
34
  setCurrentScreen: (screen: Screen) => void