0xtrails 0.9.2 → 0.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/{ccip-g6lDdnrD.js → ccip-lAtzqne5.js} +1 -1
  2. package/dist/config.d.ts +1 -0
  3. package/dist/config.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/error.d.ts.map +1 -1
  7. package/dist/{index-D-QngA_s.js → index-D5AG6huo.js} +22290 -21786
  8. package/dist/index.js +3 -3
  9. package/dist/intents.d.ts +1 -1
  10. package/dist/intents.d.ts.map +1 -1
  11. package/dist/mutations.d.ts +5 -2
  12. package/dist/mutations.d.ts.map +1 -1
  13. package/dist/tokens.d.ts.map +1 -1
  14. package/dist/transactionIntent/constants.d.ts +1 -0
  15. package/dist/transactionIntent/constants.d.ts.map +1 -1
  16. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts +3 -1
  17. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -1
  18. package/dist/transactionIntent/deposits/standardDeposit.d.ts +4 -1
  19. package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -1
  20. package/dist/transactionIntent/handlers/crossChain.d.ts.map +1 -1
  21. package/dist/transactionIntent/handlers/sameChainSameToken.d.ts.map +1 -1
  22. package/dist/transactionIntent/quote/normalizeQuote.d.ts.map +1 -1
  23. package/dist/transactionIntent/types.d.ts +2 -0
  24. package/dist/transactionIntent/types.d.ts.map +1 -1
  25. package/dist/transactionIntent/utils/resilientDepositTracker.d.ts +25 -0
  26. package/dist/transactionIntent/utils/resilientDepositTracker.d.ts.map +1 -0
  27. package/dist/widget/components/AccountIntentTransactionHistory.d.ts.map +1 -1
  28. package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
  29. package/dist/widget/components/ConfigDisplay.d.ts.map +1 -1
  30. package/dist/widget/components/DynamicInputStyles.d.ts +2 -2
  31. package/dist/widget/components/Earn.d.ts.map +1 -1
  32. package/dist/widget/components/EarnPools.d.ts.map +1 -1
  33. package/dist/widget/components/Fund.d.ts.map +1 -1
  34. package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
  35. package/dist/widget/components/Receipt.d.ts.map +1 -1
  36. package/dist/widget/components/SlippageToleranceSettings.d.ts.map +1 -1
  37. package/dist/widget/components/TransactionDetails.d.ts.map +1 -1
  38. package/dist/widget/components/UserPreferences.d.ts.map +1 -1
  39. package/dist/widget/components/WalletConnect.d.ts.map +1 -1
  40. package/dist/widget/css/compiled.css +1 -1
  41. package/dist/widget/hooks/useQuote.d.ts +2 -0
  42. package/dist/widget/hooks/useQuote.d.ts.map +1 -1
  43. package/dist/widget/index.js +1 -1
  44. package/dist/widget/providers/TrailsProvider.d.ts +2 -0
  45. package/dist/widget/providers/TrailsProvider.d.ts.map +1 -1
  46. package/dist/widget/widget.d.ts +1 -0
  47. package/dist/widget/widget.d.ts.map +1 -1
  48. package/package.json +2 -2
  49. package/src/config.ts +1 -0
  50. package/src/constants.ts +1 -0
  51. package/src/error.ts +6 -1
  52. package/src/intents.ts +22 -1
  53. package/src/prices.ts +1 -1
  54. package/src/tokens.ts +4 -3
  55. package/src/transactionIntent/constants.ts +2 -0
  56. package/src/transactionIntent/deposits/depositOrchestrator.ts +7 -0
  57. package/src/transactionIntent/deposits/standardDeposit.ts +194 -37
  58. package/src/transactionIntent/handlers/crossChain.ts +152 -105
  59. package/src/transactionIntent/handlers/sameChainSameToken.ts +1 -0
  60. package/src/transactionIntent/quote/normalizeQuote.ts +7 -4
  61. package/src/transactionIntent/types.ts +2 -0
  62. package/src/transactionIntent/utils/resilientDepositTracker.ts +281 -0
  63. package/src/widget/compiled.css +1 -1
  64. package/src/widget/components/AccountIntentTransactionHistory.tsx +170 -87
  65. package/src/widget/components/ClassicSwap.tsx +7 -1
  66. package/src/widget/components/ConfigDisplay.tsx +5 -0
  67. package/src/widget/components/Earn.tsx +14 -1
  68. package/src/widget/components/EarnPools.tsx +180 -59
  69. package/src/widget/components/Fund.tsx +3 -1
  70. package/src/widget/components/PoolWithdraw.tsx +1 -1
  71. package/src/widget/components/QuoteDetails.tsx +12 -35
  72. package/src/widget/components/Receipt.tsx +66 -40
  73. package/src/widget/components/SlippageToleranceSettings.tsx +86 -44
  74. package/src/widget/components/TransactionDetails.tsx +138 -218
  75. package/src/widget/components/UserPreferences.tsx +114 -41
  76. package/src/widget/components/WalletConnect.tsx +111 -48
  77. package/src/widget/hooks/useQuote.ts +389 -352
  78. package/src/widget/providers/TrailsProvider.tsx +5 -0
  79. package/src/widget/widget.tsx +2 -0
@@ -54,19 +54,28 @@ export const SlippageToleranceSettings: React.FC<
54
54
  > = ({ className = "" }) => {
55
55
  const [displayValue, setDisplayValue] = useState("")
56
56
  const [showTooltip, setShowTooltip] = useState(false)
57
+ const [mode, setMode] = useState<"auto" | "custom">("auto")
57
58
 
58
59
  // Initialize display value from local storage or config
59
60
  useEffect(() => {
60
61
  try {
61
62
  const stored = localStorage.getItem(SLIPPAGE_STORAGE_KEY)
62
63
  if (stored) {
63
- setDisplayValue(decimalToPercentage(stored))
64
+ if (stored === SLIPPAGE_AUTO) {
65
+ setMode("auto")
66
+ setDisplayValue(SLIPPAGE_AUTO)
67
+ } else {
68
+ setMode("custom")
69
+ setDisplayValue(decimalToPercentage(stored))
70
+ }
64
71
  } else {
65
72
  // Default to AUTO mode
73
+ setMode("auto")
66
74
  setDisplayValue(SLIPPAGE_AUTO)
67
75
  }
68
76
  } catch (_error) {
69
77
  // Fallback to AUTO if localStorage fails
78
+ setMode("auto")
70
79
  setDisplayValue(SLIPPAGE_AUTO)
71
80
  }
72
81
  }, [])
@@ -134,6 +143,7 @@ export const SlippageToleranceSettings: React.FC<
134
143
  }
135
144
 
136
145
  const handleAutoClick = () => {
146
+ setMode("auto")
137
147
  setDisplayValue(SLIPPAGE_AUTO)
138
148
  try {
139
149
  localStorage.setItem(SLIPPAGE_STORAGE_KEY, SLIPPAGE_AUTO)
@@ -142,7 +152,26 @@ export const SlippageToleranceSettings: React.FC<
142
152
  }
143
153
  }
144
154
 
155
+ const handleCustomClick = () => {
156
+ setMode("custom")
157
+ // Set a default custom value if currently in auto mode
158
+ if (displayValue === SLIPPAGE_AUTO) {
159
+ const defaultCustom = "1"
160
+ setDisplayValue(defaultCustom)
161
+ const decimalValue = percentageToDecimal(defaultCustom)
162
+ try {
163
+ localStorage.setItem(SLIPPAGE_STORAGE_KEY, decimalValue)
164
+ } catch (error) {
165
+ console.warn(
166
+ "Failed to save slippage tolerance to localStorage:",
167
+ error,
168
+ )
169
+ }
170
+ }
171
+ }
172
+
145
173
  const handlePresetClick = (percentage: number) => {
174
+ setMode("custom")
146
175
  const percentageStr = percentage.toString()
147
176
  setDisplayValue(percentageStr)
148
177
  const decimalValue = percentageToDecimal(percentageStr)
@@ -156,9 +185,7 @@ export const SlippageToleranceSettings: React.FC<
156
185
  return (
157
186
  <div className={`space-y-3 ${className}`}>
158
187
  <div className="flex items-center space-x-2">
159
- <div className="text-sm font-medium trails-text-primary">
160
- Slippage Tolerance
161
- </div>
188
+ <div className="text-sm font-medium trails-text-primary">Slippage</div>
162
189
  <div className="relative">
163
190
  <button
164
191
  type="button"
@@ -179,56 +206,71 @@ export const SlippageToleranceSettings: React.FC<
179
206
  </div>
180
207
  </div>
181
208
 
182
- {/* Preset buttons */}
183
- <div className="flex items-center space-x-2">
209
+ {/* Mode toggle buttons */}
210
+ <div className="flex items-center gap-2">
184
211
  <button
185
212
  type="button"
186
213
  onClick={handleAutoClick}
187
- className={`px-2 py-1 text-xs font-medium trails-border-radius-container border border-solid transition-colors cursor-pointer ${
188
- displayValue === SLIPPAGE_AUTO
189
- ? "bg-blue-500 text-white border-blue-500"
190
- : "border-gray-300 text-gray-600 dark:border-gray-600 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 hover:trails-hover-bg hover:border-gray-400 dark:hover:border-gray-500"
214
+ className={`px-3 py-1.5 rounded-full text-xs font-medium transition-colors ${
215
+ mode === "auto"
216
+ ? "bg-[#DBEAFE] text-[#2563EB]"
217
+ : "bg-transparent text-gray-900 dark:text-gray-100 hover:text-gray-700 dark:hover:text-gray-300 cursor-pointer"
191
218
  }`}
192
219
  >
193
220
  Auto
194
221
  </button>
195
- {[0.5, 1, 3, 5].map((preset) => (
196
- <button
197
- key={preset}
198
- type="button"
199
- onClick={() => handlePresetClick(preset)}
200
- className={`px-2 py-1 text-xs font-medium trails-border-radius-container border border-solid transition-colors cursor-pointer ${
201
- parseFloat(displayValue) === preset
202
- ? "bg-blue-500 text-white border-blue-500"
203
- : "border-gray-300 text-gray-600 dark:border-gray-600 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 hover:trails-hover-bg hover:border-gray-400 dark:hover:border-gray-500"
204
- }`}
205
- >
206
- {preset}%
207
- </button>
208
- ))}
222
+ <button
223
+ type="button"
224
+ onClick={handleCustomClick}
225
+ className={`px-3 py-1.5 rounded-full text-xs font-medium transition-colors ${
226
+ mode === "custom"
227
+ ? "bg-[#DBEAFE] text-[#2563EB]"
228
+ : "bg-transparent text-gray-900 dark:text-gray-100 hover:text-gray-700 dark:hover:text-gray-300 cursor-pointer"
229
+ }`}
230
+ >
231
+ Custom
232
+ </button>
209
233
  </div>
210
234
 
211
- {/* Custom input */}
212
- <div className="flex items-center space-x-2">
213
- <div className="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap">
214
- Custom:
215
- </div>
216
- <div className="relative w-16">
217
- <input
218
- type="text"
219
- value={displayValue}
220
- onChange={handleInputChange}
221
- onBlur={handleInputBlur}
222
- onKeyDown={handleKeyDown}
223
- placeholder="5"
224
- className="w-full px-2 py-1.5 text-sm border border-solid border-gray-200 dark:border-gray-700 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 trails-input pr-6"
225
- style={{ borderRadius: "10px" }}
226
- />
227
- <div className="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
228
- <span className="text-xs text-gray-500 dark:text-gray-400">%</span>
235
+ {/* Custom input and preset buttons - only show when custom mode is selected */}
236
+ {mode === "custom" && (
237
+ <>
238
+ {/* Custom input with preset buttons */}
239
+ <div className="flex items-center gap-2">
240
+ <div className="relative w-16">
241
+ <input
242
+ type="text"
243
+ value={displayValue !== SLIPPAGE_AUTO ? displayValue : ""}
244
+ onChange={handleInputChange}
245
+ onBlur={handleInputBlur}
246
+ onKeyDown={handleKeyDown}
247
+ placeholder="5"
248
+ className="w-full px-3 py-1.5 text-xs border border-solid border-gray-200 dark:border-gray-700 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 trails-input pr-6 rounded-full"
249
+ />
250
+ <div className="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
251
+ <span className="text-xs text-gray-500 dark:text-gray-400">
252
+ %
253
+ </span>
254
+ </div>
255
+ </div>
256
+ {/* Preset percentage buttons */}
257
+ {[0.5, 1, 3, 5].map((preset) => (
258
+ <button
259
+ key={preset}
260
+ type="button"
261
+ onClick={() => handlePresetClick(preset)}
262
+ className={`px-2 py-1 text-xs font-medium rounded-full border transition-colors cursor-pointer ${
263
+ parseFloat(displayValue) === preset
264
+ ? "bg-gray-200 dark:bg-gray-700 text-gray-900 dark:text-gray-100 border-gray-400 dark:border-gray-500"
265
+ : "bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-400 border-gray-300 dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700"
266
+ }`}
267
+ >
268
+ {preset}%
269
+ </button>
270
+ ))}
229
271
  </div>
230
- </div>
231
- </div>
272
+ </>
273
+ )}
232
274
  </div>
233
275
  )
234
276
  }
@@ -1,12 +1,11 @@
1
1
  import type React from "react"
2
- import { useState } from "react"
3
2
  import type { IntentTransaction } from "../../transactions.js"
4
3
  import { TokenImage } from "./TokenImage.js"
5
4
  import { ChainImage } from "./ChainImage.js"
6
5
  import { getExplorerUrlForAddress, getExplorerUrl } from "../../explorer.js"
7
6
  import { truncateAddress } from "../../utils.js"
8
7
  import { formatRawAmount } from "../../tokenBalances.js"
9
- import { logger } from "../../logger.js"
8
+ import { useTrails } from "../providers/TrailsProvider.js"
10
9
 
11
10
  interface TransactionDetailsProps {
12
11
  transaction: IntentTransaction
@@ -17,43 +16,7 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
17
16
  transaction,
18
17
  className = "",
19
18
  }) => {
20
- const [copiedIntentId, setCopiedIntentId] = useState<string | null>(null)
21
-
22
- const handleCopyIntentId = async (intentId: string, e: React.MouseEvent) => {
23
- e.preventDefault()
24
- e.stopPropagation()
25
- try {
26
- await navigator.clipboard.writeText(intentId)
27
- setCopiedIntentId(intentId)
28
- setTimeout(() => setCopiedIntentId(null), 2000) // Clear after 2 seconds
29
- logger.console.log(
30
- "[trails-sdk] Successfully copied intent ID:",
31
- intentId,
32
- )
33
- } catch (error) {
34
- logger.console.error("[trails-sdk] Failed to copy intent ID:", error)
35
- // Fallback for older browsers or when clipboard API is not available
36
- try {
37
- const textArea = document.createElement("textarea")
38
- textArea.value = intentId
39
- document.body.appendChild(textArea)
40
- textArea.select()
41
- document.execCommand("copy")
42
- document.body.removeChild(textArea)
43
- setCopiedIntentId(intentId)
44
- setTimeout(() => setCopiedIntentId(null), 2000)
45
- logger.console.log(
46
- "[trails-sdk] Successfully copied intent ID using fallback:",
47
- intentId,
48
- )
49
- } catch (fallbackError) {
50
- logger.console.error(
51
- "[trails-sdk] Fallback copy also failed:",
52
- fallbackError,
53
- )
54
- }
55
- }
56
- }
19
+ const { trailsAppUrl } = useTrails()
57
20
 
58
21
  return (
59
22
  <div className={`space-y-2 text-sm ${className}`}>
@@ -63,71 +26,28 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
63
26
  <span className="text-xs text-gray-600 dark:text-gray-400">
64
27
  Intent ID:
65
28
  </span>
66
- <div className="flex items-center gap-1">
67
- <a
68
- href={`https://app.trails.build/explorer/receipt/${transaction.intentId}`}
69
- target="_blank"
70
- rel="noopener noreferrer"
71
- className="text-xs font-mono text-gray-900 dark:text-gray-100 hover:underline"
72
- title="View on Trails Explorer"
73
- >
74
- {truncateAddress(transaction.intentId)}
75
- </a>
76
- <button
77
- type="button"
78
- onClick={(e) => {
79
- if (transaction.intentId) {
80
- handleCopyIntentId(transaction.intentId, e)
81
- }
82
- }}
83
- onMouseDown={(e) => e.stopPropagation()}
84
- onMouseUp={(e) => e.stopPropagation()}
85
- className={`p-0.5 rounded transition-all duration-200 cursor-pointer z-10 relative ${
86
- copiedIntentId === transaction.intentId
87
- ? "bg-green-100 dark:bg-green-900/30"
88
- : "hover:bg-gray-200 dark:hover:bg-gray-600"
89
- }`}
90
- title={
91
- copiedIntentId === transaction.intentId
92
- ? "Copied!"
93
- : "Copy full intent ID"
94
- }
29
+ <a
30
+ href={`${trailsAppUrl}/intent/${transaction.intentId}`}
31
+ target="_blank"
32
+ rel="noopener noreferrer"
33
+ className="text-xs font-mono text-gray-900 dark:text-gray-100 hover:underline flex items-center gap-1"
34
+ title="View on Trails"
35
+ >
36
+ {truncateAddress(transaction.intentId)}
37
+ <svg
38
+ className="w-3 h-3"
39
+ fill="none"
40
+ stroke="currentColor"
41
+ viewBox="0 0 24 24"
95
42
  >
96
- {copiedIntentId === transaction.intentId ? (
97
- <svg
98
- className="w-3 h-3 text-green-600 dark:text-green-400"
99
- fill="none"
100
- viewBox="0 0 24 24"
101
- stroke="currentColor"
102
- aria-label="Copied"
103
- >
104
- <title>Copied</title>
105
- <path
106
- strokeLinecap="round"
107
- strokeLinejoin="round"
108
- strokeWidth={2}
109
- d="M5 13l4 4L19 7"
110
- />
111
- </svg>
112
- ) : (
113
- <svg
114
- className="w-3 h-3 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
115
- fill="none"
116
- viewBox="0 0 24 24"
117
- stroke="currentColor"
118
- aria-label="Copy"
119
- >
120
- <title>Copy</title>
121
- <path
122
- strokeLinecap="round"
123
- strokeLinejoin="round"
124
- strokeWidth={2}
125
- d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"
126
- />
127
- </svg>
128
- )}
129
- </button>
130
- </div>
43
+ <path
44
+ strokeLinecap="round"
45
+ strokeLinejoin="round"
46
+ strokeWidth={2}
47
+ d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
48
+ />
49
+ </svg>
50
+ </a>
131
51
  </div>
132
52
  )}
133
53
 
@@ -144,7 +64,7 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
144
64
  })}
145
65
  target="_blank"
146
66
  rel="noopener noreferrer"
147
- className="text-xs hover:underline flex items-center gap-1 text-gray-900 dark:text-gray-100"
67
+ className="text-xs font-mono hover:underline flex items-center gap-1 text-gray-900 dark:text-gray-100"
148
68
  >
149
69
  <ChainImage chainId={transaction.originChainId} size={16} />
150
70
  {truncateAddress(transaction.depositTransactionHash)}
@@ -165,6 +85,73 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
165
85
  </div>
166
86
  )}
167
87
 
88
+ {/* Origin Token - Moved before Origin Intent */}
89
+ {transaction.originToken && (
90
+ <div className="flex justify-between items-start">
91
+ <span className="text-xs text-gray-600 dark:text-gray-400">
92
+ Origin Token:
93
+ </span>
94
+ <div className="text-right">
95
+ {transaction.originTokenAddress &&
96
+ transaction.originTokenAddress !==
97
+ "0x0000000000000000000000000000000000000000" ? (
98
+ <a
99
+ href={getExplorerUrlForAddress({
100
+ address: transaction.originTokenAddress,
101
+ chainId: transaction.originToken.chainId,
102
+ })}
103
+ target="_blank"
104
+ rel="noopener noreferrer"
105
+ className="flex items-center gap-1 justify-end hover:underline text-xs font-mono text-gray-900 dark:text-gray-100"
106
+ >
107
+ <TokenImage
108
+ symbol={transaction.originToken.symbol}
109
+ imageUrl={transaction.originToken.imageUrl}
110
+ chainId={transaction.originToken.chainId}
111
+ size={16}
112
+ />
113
+ <span className="font-mono">
114
+ {formatRawAmount(
115
+ transaction.originTokenAmount || "0",
116
+ transaction.originToken.decimals,
117
+ )}{" "}
118
+ {transaction.originToken.symbol}
119
+ </span>
120
+ <svg
121
+ className="w-3 h-3"
122
+ fill="none"
123
+ stroke="currentColor"
124
+ viewBox="0 0 24 24"
125
+ >
126
+ <path
127
+ strokeLinecap="round"
128
+ strokeLinejoin="round"
129
+ strokeWidth={2}
130
+ d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
131
+ />
132
+ </svg>
133
+ </a>
134
+ ) : (
135
+ <div className="flex items-center gap-1 justify-end text-xs font-mono text-gray-900 dark:text-gray-100">
136
+ <TokenImage
137
+ symbol={transaction.originToken.symbol}
138
+ imageUrl={transaction.originToken.imageUrl}
139
+ chainId={transaction.originToken.chainId}
140
+ size={16}
141
+ />
142
+ <span className="font-mono">
143
+ {formatRawAmount(
144
+ transaction.originTokenAmount || "0",
145
+ transaction.originToken.decimals,
146
+ )}{" "}
147
+ {transaction.originToken.symbol}
148
+ </span>
149
+ </div>
150
+ )}
151
+ </div>
152
+ </div>
153
+ )}
154
+
168
155
  {/* Origin Intent Deposit Tx Hash */}
169
156
  {transaction.originIntentDepositTxHash &&
170
157
  transaction.originIntentDepositTxExplorerUrl &&
@@ -177,7 +164,7 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
177
164
  href={transaction.originIntentDepositTxExplorerUrl}
178
165
  target="_blank"
179
166
  rel="noopener noreferrer"
180
- className="text-xs hover:underline flex items-center gap-1 text-gray-900 dark:text-gray-100"
167
+ className="text-xs font-mono hover:underline flex items-center gap-1 text-gray-900 dark:text-gray-100"
181
168
  >
182
169
  <ChainImage chainId={transaction.originChainId} size={16} />
183
170
  {truncateAddress(transaction.originIntentDepositTxHash)}
@@ -210,7 +197,7 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
210
197
  href={transaction.destinationIntentDepositTxExplorerUrl}
211
198
  target="_blank"
212
199
  rel="noopener noreferrer"
213
- className="text-xs hover:underline flex items-center gap-1 text-gray-900 dark:text-gray-100"
200
+ className="text-xs font-mono hover:underline flex items-center gap-1 text-gray-900 dark:text-gray-100"
214
201
  >
215
202
  <ChainImage chainId={transaction.destinationChainId} size={16} />
216
203
  {truncateAddress(transaction.destinationIntentDepositTxHash)}
@@ -231,7 +218,7 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
231
218
  </div>
232
219
  )}
233
220
 
234
- {/* Origin Intent */}
221
+ {/* Origin Intent - Moved after Origin Token */}
235
222
  {transaction.originIntentAddress && (
236
223
  <div className="flex justify-between items-center">
237
224
  <span className="text-xs text-gray-600 dark:text-gray-400">
@@ -247,7 +234,7 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
247
234
  })}
248
235
  target="_blank"
249
236
  rel="noopener noreferrer"
250
- className="text-xs hover:underline flex items-center gap-1 text-gray-900 dark:text-gray-100"
237
+ className="text-xs font-mono hover:underline flex items-center gap-1 text-gray-900 dark:text-gray-100"
251
238
  >
252
239
  {transaction.originChainId && (
253
240
  <ChainImage chainId={transaction.originChainId} size={16} />
@@ -270,73 +257,6 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
270
257
  </div>
271
258
  )}
272
259
 
273
- {/* Origin Token */}
274
- {transaction.originToken && (
275
- <div className="flex justify-between items-start">
276
- <span className="text-xs text-gray-600 dark:text-gray-400">
277
- Origin Token:
278
- </span>
279
- <div className="text-right">
280
- {transaction.originTokenAddress &&
281
- transaction.originTokenAddress !==
282
- "0x0000000000000000000000000000000000000000" ? (
283
- <a
284
- href={getExplorerUrlForAddress({
285
- address: transaction.originTokenAddress,
286
- chainId: transaction.originToken.chainId,
287
- })}
288
- target="_blank"
289
- rel="noopener noreferrer"
290
- className="flex items-center gap-1 justify-end hover:underline text-xs text-gray-900 dark:text-gray-100"
291
- >
292
- <TokenImage
293
- symbol={transaction.originToken.symbol}
294
- imageUrl={transaction.originToken.imageUrl}
295
- chainId={transaction.originToken.chainId}
296
- size={16}
297
- />
298
- <span>
299
- {formatRawAmount(
300
- transaction.originTokenAmount || "0",
301
- transaction.originToken.decimals,
302
- )}{" "}
303
- {transaction.originToken.symbol}
304
- </span>
305
- <svg
306
- className="w-3 h-3"
307
- fill="none"
308
- stroke="currentColor"
309
- viewBox="0 0 24 24"
310
- >
311
- <path
312
- strokeLinecap="round"
313
- strokeLinejoin="round"
314
- strokeWidth={2}
315
- d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
316
- />
317
- </svg>
318
- </a>
319
- ) : (
320
- <div className="flex items-center gap-1 justify-end text-xs text-gray-900 dark:text-gray-100">
321
- <TokenImage
322
- symbol={transaction.originToken.symbol}
323
- imageUrl={transaction.originToken.imageUrl}
324
- chainId={transaction.originToken.chainId}
325
- size={16}
326
- />
327
- <span>
328
- {formatRawAmount(
329
- transaction.originTokenAmount || "0",
330
- transaction.originToken.decimals,
331
- )}{" "}
332
- {transaction.originToken.symbol}
333
- </span>
334
- </div>
335
- )}
336
- </div>
337
- </div>
338
- )}
339
-
340
260
  {/* Origin Intent Action Tx Hash */}
341
261
  {transaction.originIntentTxHash &&
342
262
  transaction.originIntentTxExplorerUrl &&
@@ -349,7 +269,7 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
349
269
  href={transaction.originIntentTxExplorerUrl}
350
270
  target="_blank"
351
271
  rel="noopener noreferrer"
352
- className="text-xs hover:underline flex items-center gap-1 text-gray-900 dark:text-gray-100"
272
+ className="text-xs font-mono hover:underline flex items-center gap-1 text-gray-900 dark:text-gray-100"
353
273
  >
354
274
  <ChainImage chainId={transaction.originChainId} size={16} />
355
275
  {truncateAddress(transaction.originIntentTxHash)}
@@ -370,42 +290,7 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
370
290
  </div>
371
291
  )}
372
292
 
373
- {/* Destination Intent */}
374
- {transaction.destinationIntentAddress &&
375
- transaction.destinationChainId && (
376
- <div className="flex justify-between items-center">
377
- <span className="text-xs text-gray-600 dark:text-gray-400">
378
- Destination Intent:
379
- </span>
380
- <a
381
- href={getExplorerUrlForAddress({
382
- address: transaction.destinationIntentAddress,
383
- chainId: transaction.destinationChainId,
384
- })}
385
- target="_blank"
386
- rel="noopener noreferrer"
387
- className="text-xs hover:underline flex items-center gap-1 text-gray-900 dark:text-gray-100"
388
- >
389
- <ChainImage chainId={transaction.destinationChainId} size={16} />
390
- {truncateAddress(transaction.destinationIntentAddress)}
391
- <svg
392
- className="w-3 h-3"
393
- fill="none"
394
- stroke="currentColor"
395
- viewBox="0 0 24 24"
396
- >
397
- <path
398
- strokeLinecap="round"
399
- strokeLinejoin="round"
400
- strokeWidth={2}
401
- d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
402
- />
403
- </svg>
404
- </a>
405
- </div>
406
- )}
407
-
408
- {/* Destination Token */}
293
+ {/* Destination Token - Moved before Destination Intent */}
409
294
  {transaction.destinationToken && (
410
295
  <div className="flex justify-between items-start">
411
296
  <span className="text-xs text-gray-600 dark:text-gray-400">
@@ -422,7 +307,7 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
422
307
  })}
423
308
  target="_blank"
424
309
  rel="noopener noreferrer"
425
- className="flex items-center gap-1 justify-end hover:underline text-xs text-gray-900 dark:text-gray-100"
310
+ className="flex items-center gap-1 justify-end hover:underline text-xs font-mono text-gray-900 dark:text-gray-100"
426
311
  >
427
312
  <TokenImage
428
313
  symbol={transaction.destinationToken.symbol}
@@ -430,7 +315,7 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
430
315
  chainId={transaction.destinationToken.chainId}
431
316
  size={16}
432
317
  />
433
- <span>
318
+ <span className="font-mono">
434
319
  {formatRawAmount(
435
320
  transaction.destinationTokenAmount || "0",
436
321
  transaction.destinationToken.decimals,
@@ -452,14 +337,14 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
452
337
  </svg>
453
338
  </a>
454
339
  ) : (
455
- <div className="flex items-center gap-1 justify-end text-xs text-gray-900 dark:text-gray-100">
340
+ <div className="flex items-center gap-1 justify-end text-xs font-mono text-gray-900 dark:text-gray-100">
456
341
  <TokenImage
457
342
  symbol={transaction.destinationToken.symbol}
458
343
  imageUrl={transaction.destinationToken.imageUrl}
459
344
  chainId={transaction.destinationToken.chainId}
460
345
  size={16}
461
346
  />
462
- <span>
347
+ <span className="font-mono">
463
348
  {formatRawAmount(
464
349
  transaction.destinationTokenAmount || "0",
465
350
  transaction.destinationToken.decimals,
@@ -472,6 +357,41 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
472
357
  </div>
473
358
  )}
474
359
 
360
+ {/* Destination Intent - Moved after Destination Token */}
361
+ {transaction.destinationIntentAddress &&
362
+ transaction.destinationChainId && (
363
+ <div className="flex justify-between items-center">
364
+ <span className="text-xs text-gray-600 dark:text-gray-400">
365
+ Destination Intent:
366
+ </span>
367
+ <a
368
+ href={getExplorerUrlForAddress({
369
+ address: transaction.destinationIntentAddress,
370
+ chainId: transaction.destinationChainId,
371
+ })}
372
+ target="_blank"
373
+ rel="noopener noreferrer"
374
+ className="text-xs font-mono hover:underline flex items-center gap-1 text-gray-900 dark:text-gray-100"
375
+ >
376
+ <ChainImage chainId={transaction.destinationChainId} size={16} />
377
+ {truncateAddress(transaction.destinationIntentAddress)}
378
+ <svg
379
+ className="w-3 h-3"
380
+ fill="none"
381
+ stroke="currentColor"
382
+ viewBox="0 0 24 24"
383
+ >
384
+ <path
385
+ strokeLinecap="round"
386
+ strokeLinejoin="round"
387
+ strokeWidth={2}
388
+ d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
389
+ />
390
+ </svg>
391
+ </a>
392
+ </div>
393
+ )}
394
+
475
395
  {/* Destination To Address */}
476
396
  {transaction.destinationToAddress &&
477
397
  transaction.destinationToAddress !==
@@ -487,7 +407,7 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
487
407
  })}
488
408
  target="_blank"
489
409
  rel="noopener noreferrer"
490
- className="text-xs hover:underline flex items-center gap-1 text-gray-900 dark:text-gray-100"
410
+ className="text-xs font-mono hover:underline flex items-center gap-1 text-gray-900 dark:text-gray-100"
491
411
  >
492
412
  {transaction.destinationChainId && (
493
413
  <ChainImage
@@ -525,7 +445,7 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
525
445
  href={transaction.destinationIntentTxExplorerUrl}
526
446
  target="_blank"
527
447
  rel="noopener noreferrer"
528
- className="text-xs hover:underline flex items-center gap-1 text-gray-900 dark:text-gray-100"
448
+ className="text-xs font-mono hover:underline flex items-center gap-1 text-gray-900 dark:text-gray-100"
529
449
  >
530
450
  <ChainImage chainId={transaction.destinationChainId} size={16} />
531
451
  {truncateAddress(transaction.destinationIntentTxHash)}