0xtrails 0.1.3 → 0.1.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 (111) hide show
  1. package/dist/address.d.ts.map +1 -1
  2. package/dist/analytics.d.ts +18 -0
  3. package/dist/analytics.d.ts.map +1 -1
  4. package/dist/apiClient.d.ts +1 -1
  5. package/dist/apiClient.d.ts.map +1 -1
  6. package/dist/{ccip-CWd4g9uZ.js → ccip-dLSEJjCf.js} +55 -55
  7. package/dist/cctpqueue.d.ts +1 -1
  8. package/dist/cctpqueue.d.ts.map +1 -1
  9. package/dist/constants.d.ts +1 -0
  10. package/dist/constants.d.ts.map +1 -1
  11. package/dist/decoders.d.ts +58 -0
  12. package/dist/decoders.d.ts.map +1 -0
  13. package/dist/ens.d.ts +6 -0
  14. package/dist/ens.d.ts.map +1 -1
  15. package/dist/error.d.ts +7 -0
  16. package/dist/error.d.ts.map +1 -1
  17. package/dist/{index-BTUBzx4R.js → index-BXbaLmtt.js} +25694 -24507
  18. package/dist/index.js +2 -2
  19. package/dist/intents.d.ts +4 -4
  20. package/dist/intents.d.ts.map +1 -1
  21. package/dist/metaTxns.d.ts +1 -1
  22. package/dist/metaTxns.d.ts.map +1 -1
  23. package/dist/mode.d.ts +1 -1
  24. package/dist/mode.d.ts.map +1 -1
  25. package/dist/preconditions.d.ts +1 -1
  26. package/dist/preconditions.d.ts.map +1 -1
  27. package/dist/prepareSend.d.ts +30 -24
  28. package/dist/prepareSend.d.ts.map +1 -1
  29. package/dist/prices.d.ts +1 -1
  30. package/dist/prices.d.ts.map +1 -1
  31. package/dist/proxyCaller.d.ts +0 -1
  32. package/dist/proxyCaller.d.ts.map +1 -1
  33. package/dist/tokenBalances.d.ts +1 -1
  34. package/dist/tokenBalances.d.ts.map +1 -1
  35. package/dist/tokens.d.ts.map +1 -1
  36. package/dist/trails.d.ts +1 -1
  37. package/dist/trails.d.ts.map +1 -1
  38. package/dist/transactions.d.ts +4 -0
  39. package/dist/transactions.d.ts.map +1 -1
  40. package/dist/utils.d.ts +6 -0
  41. package/dist/utils.d.ts.map +1 -1
  42. package/dist/widget/components/DebugScreensDropdown.d.ts.map +1 -1
  43. package/dist/widget/components/ErrorDisplay.d.ts +9 -0
  44. package/dist/widget/components/ErrorDisplay.d.ts.map +1 -0
  45. package/dist/widget/components/FundSendForm.d.ts +1 -1
  46. package/dist/widget/components/FundSendForm.d.ts.map +1 -1
  47. package/dist/widget/components/OriginTransferInformation.d.ts +10 -0
  48. package/dist/widget/components/OriginTransferInformation.d.ts.map +1 -0
  49. package/dist/widget/components/PaySendForm.d.ts +1 -1
  50. package/dist/widget/components/PaySendForm.d.ts.map +1 -1
  51. package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
  52. package/dist/widget/components/Receipt.d.ts.map +1 -1
  53. package/dist/widget/components/Receive.d.ts +12 -0
  54. package/dist/widget/components/Receive.d.ts.map +1 -0
  55. package/dist/widget/components/Swap.d.ts +5 -1
  56. package/dist/widget/components/Swap.d.ts.map +1 -1
  57. package/dist/widget/components/SwapDisplay.d.ts +9 -0
  58. package/dist/widget/components/SwapDisplay.d.ts.map +1 -0
  59. package/dist/widget/components/TransferPendingVertical.d.ts +2 -0
  60. package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
  61. package/dist/widget/components/YellowWarningAnimation.d.ts +2 -0
  62. package/dist/widget/components/YellowWarningAnimation.d.ts.map +1 -0
  63. package/dist/widget/hooks/useDebugScreens.d.ts +22 -0
  64. package/dist/widget/hooks/useDebugScreens.d.ts.map +1 -0
  65. package/dist/widget/hooks/useSendForm.d.ts +7 -3
  66. package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
  67. package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
  68. package/dist/widget/index.js +1 -1
  69. package/dist/widget/widget.d.ts.map +1 -1
  70. package/package.json +16 -15
  71. package/src/address.ts +3 -0
  72. package/src/analytics.ts +105 -4
  73. package/src/apiClient.ts +1 -1
  74. package/src/cctpqueue.ts +1 -1
  75. package/src/constants.ts +3 -0
  76. package/src/decoders.ts +310 -0
  77. package/src/ens.ts +16 -1
  78. package/src/error.ts +86 -1
  79. package/src/intents.ts +10 -2
  80. package/src/metaTxns.ts +1 -1
  81. package/src/mode.ts +1 -1
  82. package/src/preconditions.ts +1 -1
  83. package/src/prepareSend.ts +432 -114
  84. package/src/prices.ts +5 -1
  85. package/src/proxyCaller.ts +2 -14
  86. package/src/tokenBalances.ts +21 -17
  87. package/src/tokens.ts +62 -3
  88. package/src/trails.ts +2 -2
  89. package/src/transactions.ts +35 -18
  90. package/src/utils.ts +28 -0
  91. package/src/widget/compiled.css +2 -2
  92. package/src/widget/components/DebugScreensDropdown.tsx +3 -0
  93. package/src/widget/components/ErrorDisplay.tsx +150 -0
  94. package/src/widget/components/FundSendForm.tsx +62 -9
  95. package/src/widget/components/OriginTransferInformation.tsx +59 -0
  96. package/src/widget/components/PaySendForm.tsx +65 -12
  97. package/src/widget/components/QRCodeDeposit.tsx +5 -5
  98. package/src/widget/components/QrCode.tsx +1 -1
  99. package/src/widget/components/QuoteDetails.tsx +93 -25
  100. package/src/widget/components/Receipt.tsx +296 -103
  101. package/src/widget/components/Receive.tsx +146 -0
  102. package/src/widget/components/RecentTokens.tsx +1 -1
  103. package/src/widget/components/Swap.tsx +206 -85
  104. package/src/widget/components/SwapDisplay.tsx +68 -0
  105. package/src/widget/components/TokenSelector.tsx +1 -1
  106. package/src/widget/components/TransferPendingVertical.tsx +162 -112
  107. package/src/widget/components/YellowWarningAnimation.tsx +146 -0
  108. package/src/widget/hooks/useDebugScreens.ts +583 -0
  109. package/src/widget/hooks/useSendForm.ts +46 -4
  110. package/src/widget/hooks/useTokenList.ts +8 -27
  111. package/src/widget/widget.tsx +201 -484
@@ -1,4 +1,4 @@
1
- import type { TokenPrice } from "@0xsequence/api"
1
+ import type { TokenPrice } from "@0xsequence/trails-api"
2
2
  import type React from "react"
3
3
  import { useCallback, useEffect, useMemo, useState } from "react"
4
4
  import {
@@ -11,7 +11,7 @@ import {
11
11
  } from "viem"
12
12
  import { useAPIClient } from "../../apiClient.js"
13
13
  import { getChainInfo, useSupportedChains } from "../../chains.js"
14
- import { getFullErrorMessage } from "../../error.js"
14
+ import { getFullErrorMessage, getPrettifiedErrorMessage } from "../../error.js"
15
15
  import {
16
16
  prepareSend,
17
17
  TradeType,
@@ -115,7 +115,7 @@ export type UseSendProps = {
115
115
  tradeType?: TradeType
116
116
  quoteProvider?: string
117
117
  fundMethod?: string
118
- mode?: "pay" | "fund" | "earn" | "swap"
118
+ mode?: "pay" | "fund" | "earn" | "swap" | "receive"
119
119
  onNavigateToMeshConnect?: (
120
120
  props: {
121
121
  toTokenSymbol: string
@@ -126,6 +126,7 @@ export type UseSendProps = {
126
126
  quote?: PrepareSendQuote | null,
127
127
  ) => void
128
128
  checkoutOnHandlers?: CheckoutOnHandlers
129
+ refetchTrigger?: number
129
130
  }
130
131
 
131
132
  export type UseSendReturn = {
@@ -171,6 +172,9 @@ export type UseSendReturn = {
171
172
  isValidCustomToken: boolean
172
173
  prepareSendQuote: PrepareSendQuote | null
173
174
  toAmountDisplay: string
175
+ quoteError: string | null
176
+ quoteErrorPrettified: string | null
177
+ isSameTokenWithoutCustomCalldata: boolean
174
178
  }
175
179
 
176
180
  export function useSendForm({
@@ -198,6 +202,7 @@ export function useSendForm({
198
202
  mode,
199
203
  onNavigateToMeshConnect,
200
204
  checkoutOnHandlers,
205
+ refetchTrigger = 0,
201
206
  }: UseSendProps): UseSendReturn {
202
207
  // Auto-set quoteProvider to "lifi" if either from or to chain is etherlink
203
208
  const effectiveQuoteProvider = useMemo(() => {
@@ -218,6 +223,10 @@ export function useSendForm({
218
223
  const [recipientInput, setRecipientInput] = useState(toRecipient ?? "")
219
224
  const [recipient, setRecipient] = useState(toRecipient ?? "")
220
225
  const [error, setError] = useState<string | null>(null)
226
+ const [quoteError, setQuoteError] = useState<string | null>(null)
227
+ const [quoteErrorPrettified, setQuoteErrorPrettified] = useState<
228
+ string | null
229
+ >(null)
221
230
  const { supportedChains } = useSupportedChains()
222
231
  const { ensAddress } = useResolveEnsAddress({
223
232
  textInput: recipientInput,
@@ -524,6 +533,7 @@ export function useSendForm({
524
533
  amountRaw === "0" ||
525
534
  !selectedToken
526
535
  ) {
536
+ setQuoteError(null)
527
537
  setPrepareSendResult(null)
528
538
  return
529
539
  }
@@ -531,6 +541,7 @@ export function useSendForm({
531
541
  try {
532
542
  setIsLoadingQuote(true)
533
543
  setError(null)
544
+ setQuoteError(null)
534
545
 
535
546
  const originRelayer = getRelayer(undefined, selectedToken.chainId)
536
547
  const destinationRelayer = getRelayer(
@@ -626,6 +637,7 @@ export function useSendForm({
626
637
  destinationTokenAddress,
627
638
  swapAmount: amountRaw,
628
639
  tradeType,
640
+ originTokenSymbol: selectedToken.symbol,
629
641
  destinationTokenSymbol: selectedDestToken.symbol,
630
642
  fee: "0",
631
643
  client: walletClient,
@@ -660,6 +672,7 @@ export function useSendForm({
660
672
  setIsLoadingQuote(false)
661
673
  } catch (error) {
662
674
  console.error("[trails-sdk] Error getting quote:", error)
675
+ setQuoteError(getFullErrorMessage(error))
663
676
  setPrepareSendResult(null)
664
677
  setIsLoadingQuote(false)
665
678
  }
@@ -723,6 +736,7 @@ export function useSendForm({
723
736
  selectedDestToken?.symbol,
724
737
  selectedDestinationChain?.id,
725
738
  toCalldata,
739
+ refetchTrigger,
726
740
  ])
727
741
 
728
742
  // Calculate destination amount from quote if available
@@ -762,7 +776,7 @@ export function useSendForm({
762
776
  quote.originAmountFormatted,
763
777
  ).toString() // MeshConnect will deposit origin token amount
764
778
  const toChainId = quote?.originChain?.id // MeshConnect will deposit to origin chain
765
- const toRecipientAddress = quote.originAddress // MeshConnect will deposit to origin address
779
+ const toRecipientAddress = quote.originDepositAddress // MeshConnect will deposit to origin address
766
780
 
767
781
  console.log("[trails-sdk] Navigating to mesh-connect with props:", {
768
782
  toTokenSymbol,
@@ -975,6 +989,31 @@ export function useSendForm({
975
989
  fundMethod,
976
990
  ])
977
991
 
992
+ useEffect(() => {
993
+ if (quoteError) {
994
+ setQuoteErrorPrettified(getPrettifiedErrorMessage(quoteError))
995
+ } else {
996
+ setQuoteErrorPrettified(null)
997
+ }
998
+ }, [quoteError])
999
+
1000
+ // Check if origin and destination tokens are the same (same contract address on same chain)
1001
+ // Only block same-token transactions when there's no custom calldata
1002
+ const isSameTokenWithoutCustomCalldata = useMemo(() => {
1003
+ if (!selectedToken || !destinationTokenAddress) return false
1004
+ const isSameChainAndToken =
1005
+ selectedToken.contractAddress.toLowerCase() ===
1006
+ destinationTokenAddress.toLowerCase() &&
1007
+ selectedToken.chainId === selectedDestinationChain?.id
1008
+ // Allow same-token transactions if there's custom calldata (e.g., NFT minting)
1009
+ return isSameChainAndToken && !toCalldata
1010
+ }, [
1011
+ selectedToken,
1012
+ destinationTokenAddress,
1013
+ selectedDestinationChain,
1014
+ toCalldata,
1015
+ ])
1016
+
978
1017
  return {
979
1018
  amount,
980
1019
  amountRaw,
@@ -1018,5 +1057,8 @@ export function useSendForm({
1018
1057
  destinationTokenAddress,
1019
1058
  isValidCustomToken,
1020
1059
  prepareSendQuote: prepareSendResult?.quote ?? null,
1060
+ quoteError,
1061
+ quoteErrorPrettified,
1062
+ isSameTokenWithoutCustomCalldata,
1021
1063
  }
1022
1064
  }
@@ -15,7 +15,7 @@ import {
15
15
  useHasSufficientBalanceUsd,
16
16
  useTokenBalances,
17
17
  } from "../../tokenBalances.js"
18
- import { getFormatttedTokenName, getSupportedTokens } from "../../tokens.js"
18
+ import { getFormatttedTokenName, useSupportedTokens } from "../../tokens.js"
19
19
  import { useIndexerGatewayClient } from "../../indexerClient.js"
20
20
 
21
21
  export interface Token {
@@ -82,9 +82,6 @@ export function useTokenList({
82
82
  }: UseTokenListProps): UseTokenListReturn {
83
83
  const [selectedToken, setSelectedToken] = useState<Token | null>(null)
84
84
  const [searchQuery, setSearchQuery] = useState("")
85
- const [supportedTokens, setSupportedTokens] = useState<any[]>([])
86
- const [isLoadingSupportedTokens, setIsLoadingSupportedTokens] =
87
- useState(false)
88
85
  const { address } = useAccount()
89
86
  const indexerGatewayClient = useIndexerGatewayClient()
90
87
  const {
@@ -93,6 +90,10 @@ export function useTokenList({
93
90
  balanceError,
94
91
  } = useTokenBalances(address as Address.Address, indexerGatewayClient)
95
92
 
93
+ // Use cached supported tokens hook
94
+ const { supportedTokens, isLoadingTokens: isLoadingSupportedTokens } =
95
+ useSupportedTokens()
96
+
96
97
  // Determine loading state based on fund method and allSupportedTokens
97
98
  const isLoadingTokens =
98
99
  fundMethod === "qr-code" || fundMethod === "exchange"
@@ -114,27 +115,7 @@ export function useTokenList({
114
115
  const showContinueButton = false
115
116
  const { supportedChains: supportedToChains } = useSupportedChains()
116
117
 
117
- // Fetch all supported tokens when fundMethod is "qr-code" or "exchange" or when allSupportedTokens is true
118
- useEffect(() => {
119
- if (
120
- fundMethod === "qr-code" ||
121
- fundMethod === "exchange" ||
122
- allSupportedTokens
123
- ) {
124
- setIsLoadingSupportedTokens(true)
125
- getSupportedTokens()
126
- .then((tokens) => {
127
- // Store supported tokens for use in filteredTokensFormatted
128
- setSupportedTokens(tokens)
129
- })
130
- .catch((error) => {
131
- console.error("[trails-sdk] Failed to fetch supported tokens:", error)
132
- })
133
- .finally(() => {
134
- setIsLoadingSupportedTokens(false)
135
- })
136
- }
137
- }, [fundMethod, allSupportedTokens])
118
+ // Note: Supported tokens are now fetched via useSupportedTokens hook with caching
138
119
 
139
120
  const supportedChainIds = useMemo(() => {
140
121
  return new Set(supportedToChains.map((c) => c.id))
@@ -144,7 +125,7 @@ export function useTokenList({
144
125
  // If fundMethod is "qr-code" or "exchange", use filtered supported tokens
145
126
  if (fundMethod === "qr-code" || fundMethod === "exchange") {
146
127
  // Filter to only show specific tokens for QR code and exchange modes
147
- const filteredTokens = supportedTokens.filter((token) => {
128
+ const filteredTokens = supportedTokens.filter((token: any) => {
148
129
  const symbol = token.symbol.toUpperCase()
149
130
  return ["ETH", "POL", "USDC", "USDT", "DAI", "BAT", "WETH"].includes(
150
131
  symbol,
@@ -152,7 +133,7 @@ export function useTokenList({
152
133
  })
153
134
 
154
135
  // Convert SupportedToken to TokenBalanceExtended format
155
- return filteredTokens.map((token) => {
136
+ return filteredTokens.map((token: any) => {
156
137
  // Check if it's a native token (like ETH)
157
138
  if (
158
139
  token.contractAddress === "0x0000000000000000000000000000000000000000"