thirdweb 5.94.1 → 5.95.0-nightly-4c1f384a635054a8cfaaa487e3ba7ada63b221ec-20250415110008

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 (166) hide show
  1. package/dist/cjs/exports/insight.js +5 -0
  2. package/dist/cjs/exports/insight.js.map +1 -0
  3. package/dist/cjs/exports/thirdweb.js +6 -2
  4. package/dist/cjs/exports/thirdweb.js.map +1 -1
  5. package/dist/cjs/extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.js +104 -0
  6. package/dist/cjs/extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.js.map +1 -0
  7. package/dist/cjs/extensions/thirdweb/write/publish.js +9 -4
  8. package/dist/cjs/extensions/thirdweb/write/publish.js.map +1 -1
  9. package/dist/cjs/insight/get-nfts.js +45 -0
  10. package/dist/cjs/insight/get-nfts.js.map +1 -0
  11. package/dist/cjs/insight/get-tokens.js +46 -0
  12. package/dist/cjs/insight/get-tokens.js.map +1 -0
  13. package/dist/cjs/insight/get-transactions.js +44 -0
  14. package/dist/cjs/insight/get-transactions.js.map +1 -0
  15. package/dist/cjs/insight/index.js +10 -0
  16. package/dist/cjs/insight/index.js.map +1 -0
  17. package/dist/cjs/react/web/ui/ConnectWallet/Details.js +4 -14
  18. package/dist/cjs/react/web/ui/ConnectWallet/Details.js.map +1 -1
  19. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/Stepper.js +2 -2
  20. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/Stepper.js.map +1 -1
  21. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js +1 -1
  22. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js.map +1 -1
  23. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.js +2 -2
  24. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.js.map +1 -1
  25. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js +31 -3
  26. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js.map +1 -1
  27. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/ErrorText.js +12 -0
  28. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/ErrorText.js.map +1 -0
  29. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.js +1 -1
  30. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.js.map +1 -1
  31. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.js +4 -4
  32. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.js.map +1 -1
  33. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js +31 -3
  34. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js.map +1 -1
  35. package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewAssets.js +1 -1
  36. package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewAssets.js.map +1 -1
  37. package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewNFTs.js +74 -32
  38. package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewNFTs.js.map +1 -1
  39. package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewTokens.js +46 -6
  40. package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewTokens.js.map +1 -1
  41. package/dist/cjs/react/web/ui/MediaRenderer/useResolvedMediaType.js +4 -1
  42. package/dist/cjs/react/web/ui/MediaRenderer/useResolvedMediaType.js.map +1 -1
  43. package/dist/cjs/react/web/utils/errors.js +5 -4
  44. package/dist/cjs/react/web/utils/errors.js.map +1 -1
  45. package/dist/cjs/transaction/transaction-store.js +11 -10
  46. package/dist/cjs/transaction/transaction-store.js.map +1 -1
  47. package/dist/cjs/utils/fetch.js +5 -4
  48. package/dist/cjs/utils/fetch.js.map +1 -1
  49. package/dist/cjs/version.js +1 -1
  50. package/dist/cjs/version.js.map +1 -1
  51. package/dist/cjs/wallets/injected/index.js +15 -0
  52. package/dist/cjs/wallets/injected/index.js.map +1 -1
  53. package/dist/esm/exports/insight.js +2 -0
  54. package/dist/esm/exports/insight.js.map +1 -0
  55. package/dist/esm/exports/thirdweb.js +4 -0
  56. package/dist/esm/exports/thirdweb.js.map +1 -1
  57. package/dist/esm/extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.js +98 -0
  58. package/dist/esm/extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.js.map +1 -0
  59. package/dist/esm/extensions/thirdweb/write/publish.js +9 -4
  60. package/dist/esm/extensions/thirdweb/write/publish.js.map +1 -1
  61. package/dist/esm/insight/get-nfts.js +42 -0
  62. package/dist/esm/insight/get-nfts.js.map +1 -0
  63. package/dist/esm/insight/get-tokens.js +43 -0
  64. package/dist/esm/insight/get-tokens.js.map +1 -0
  65. package/dist/esm/insight/get-transactions.js +41 -0
  66. package/dist/esm/insight/get-transactions.js.map +1 -0
  67. package/dist/esm/insight/index.js +4 -0
  68. package/dist/esm/insight/index.js.map +1 -0
  69. package/dist/esm/react/web/ui/ConnectWallet/Details.js +4 -14
  70. package/dist/esm/react/web/ui/ConnectWallet/Details.js.map +1 -1
  71. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/Stepper.js +2 -2
  72. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/Stepper.js.map +1 -1
  73. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js +1 -1
  74. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js.map +1 -1
  75. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.js +3 -3
  76. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.js.map +1 -1
  77. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js +32 -4
  78. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js.map +1 -1
  79. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/ErrorText.js +9 -0
  80. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/ErrorText.js.map +1 -0
  81. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.js +2 -2
  82. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.js.map +1 -1
  83. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.js +4 -4
  84. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.js.map +1 -1
  85. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js +32 -4
  86. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js.map +1 -1
  87. package/dist/esm/react/web/ui/ConnectWallet/screens/ViewAssets.js +1 -1
  88. package/dist/esm/react/web/ui/ConnectWallet/screens/ViewAssets.js.map +1 -1
  89. package/dist/esm/react/web/ui/ConnectWallet/screens/ViewNFTs.js +75 -33
  90. package/dist/esm/react/web/ui/ConnectWallet/screens/ViewNFTs.js.map +1 -1
  91. package/dist/esm/react/web/ui/ConnectWallet/screens/ViewTokens.js +46 -6
  92. package/dist/esm/react/web/ui/ConnectWallet/screens/ViewTokens.js.map +1 -1
  93. package/dist/esm/react/web/ui/MediaRenderer/useResolvedMediaType.js +4 -1
  94. package/dist/esm/react/web/ui/MediaRenderer/useResolvedMediaType.js.map +1 -1
  95. package/dist/esm/react/web/utils/errors.js +5 -3
  96. package/dist/esm/react/web/utils/errors.js.map +1 -1
  97. package/dist/esm/transaction/transaction-store.js +11 -10
  98. package/dist/esm/transaction/transaction-store.js.map +1 -1
  99. package/dist/esm/utils/fetch.js +5 -4
  100. package/dist/esm/utils/fetch.js.map +1 -1
  101. package/dist/esm/version.js +1 -1
  102. package/dist/esm/version.js.map +1 -1
  103. package/dist/esm/wallets/injected/index.js +15 -0
  104. package/dist/esm/wallets/injected/index.js.map +1 -1
  105. package/dist/types/exports/insight.d.ts +2 -0
  106. package/dist/types/exports/insight.d.ts.map +1 -0
  107. package/dist/types/exports/thirdweb.d.ts +4 -0
  108. package/dist/types/exports/thirdweb.d.ts.map +1 -1
  109. package/dist/types/extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.d.ts +64 -0
  110. package/dist/types/extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.d.ts.map +1 -0
  111. package/dist/types/extensions/thirdweb/write/publish.d.ts.map +1 -1
  112. package/dist/types/insight/get-nfts.d.ts +25 -0
  113. package/dist/types/insight/get-nfts.d.ts.map +1 -0
  114. package/dist/types/insight/get-tokens.d.ts +25 -0
  115. package/dist/types/insight/get-tokens.d.ts.map +1 -0
  116. package/dist/types/insight/get-transactions.d.ts +25 -0
  117. package/dist/types/insight/get-transactions.d.ts.map +1 -0
  118. package/dist/types/insight/index.d.ts +4 -0
  119. package/dist/types/insight/index.d.ts.map +1 -0
  120. package/dist/types/react/web/ui/ConnectWallet/Details.d.ts.map +1 -1
  121. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.d.ts.map +1 -1
  122. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.d.ts.map +1 -1
  123. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.d.ts.map +1 -1
  124. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/ErrorText.d.ts +5 -0
  125. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/ErrorText.d.ts.map +1 -0
  126. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.d.ts.map +1 -1
  127. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.d.ts.map +1 -1
  128. package/dist/types/react/web/ui/ConnectWallet/screens/ViewNFTs.d.ts.map +1 -1
  129. package/dist/types/react/web/ui/ConnectWallet/screens/ViewTokens.d.ts.map +1 -1
  130. package/dist/types/react/web/ui/MediaRenderer/useResolvedMediaType.d.ts +1 -1
  131. package/dist/types/react/web/ui/MediaRenderer/useResolvedMediaType.d.ts.map +1 -1
  132. package/dist/types/react/web/utils/errors.d.ts +2 -2
  133. package/dist/types/react/web/utils/errors.d.ts.map +1 -1
  134. package/dist/types/transaction/transaction-store.d.ts.map +1 -1
  135. package/dist/types/utils/fetch.d.ts +1 -1
  136. package/dist/types/utils/fetch.d.ts.map +1 -1
  137. package/dist/types/version.d.ts +1 -1
  138. package/dist/types/version.d.ts.map +1 -1
  139. package/dist/types/wallets/injected/index.d.ts.map +1 -1
  140. package/package.json +8 -2
  141. package/src/exports/insight.ts +1 -0
  142. package/src/exports/thirdweb.ts +5 -0
  143. package/src/extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.ts +104 -0
  144. package/src/extensions/thirdweb/write/publish.ts +12 -4
  145. package/src/insight/get-nfts.ts +62 -0
  146. package/src/insight/get-tokens.ts +63 -0
  147. package/src/insight/get-transactions.ts +66 -0
  148. package/src/insight/index.ts +3 -0
  149. package/src/react/web/ui/ConnectWallet/Details.tsx +15 -33
  150. package/src/react/web/ui/ConnectWallet/screens/Buy/Stepper.tsx +2 -2
  151. package/src/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.tsx +8 -3
  152. package/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.tsx +10 -8
  153. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.tsx +41 -11
  154. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/ErrorText.tsx +23 -0
  155. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.tsx +13 -8
  156. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.tsx +4 -4
  157. package/src/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.tsx +43 -9
  158. package/src/react/web/ui/ConnectWallet/screens/ViewAssets.tsx +1 -1
  159. package/src/react/web/ui/ConnectWallet/screens/ViewNFTs.tsx +107 -55
  160. package/src/react/web/ui/ConnectWallet/screens/ViewTokens.tsx +94 -11
  161. package/src/react/web/ui/MediaRenderer/useResolvedMediaType.ts +4 -1
  162. package/src/react/web/utils/errors.ts +11 -4
  163. package/src/transaction/transaction-store.ts +11 -22
  164. package/src/utils/fetch.ts +6 -5
  165. package/src/version.ts +1 -1
  166. package/src/wallets/injected/index.ts +16 -0
@@ -0,0 +1,63 @@
1
+ import {
2
+ type GetV1TokensErc20ByOwnerAddressData,
3
+ type GetV1TokensErc20ByOwnerAddressResponse,
4
+ getV1TokensErc20ByOwnerAddress,
5
+ } from "@thirdweb-dev/insight";
6
+ import { stringify } from "viem";
7
+ import type { Chain } from "../chains/types.js";
8
+ import type { ThirdwebClient } from "../client/client.js";
9
+ import { getThirdwebDomains } from "../utils/domains.js";
10
+ import { getClientFetch } from "../utils/fetch.js";
11
+
12
+ export type OwnedToken = GetV1TokensErc20ByOwnerAddressResponse["data"][number];
13
+
14
+ /**
15
+ * Get ERC20 tokens owned by an address
16
+ * @example
17
+ * ```ts
18
+ * import { Insight } from "thirdweb";
19
+ *
20
+ * const tokens = await Insight.getOwnedTokens({
21
+ * client,
22
+ * chains: [sepolia],
23
+ * ownerAddress: "0x1234567890123456789012345678901234567890",
24
+ * });
25
+ * ```
26
+ * @insight
27
+ */
28
+ export async function getOwnedTokens(args: {
29
+ client: ThirdwebClient;
30
+ chains: Chain[];
31
+ ownerAddress: string;
32
+ queryOptions?: Omit<GetV1TokensErc20ByOwnerAddressData["query"], "chain">;
33
+ }): Promise<OwnedToken[]> {
34
+ const {
35
+ client,
36
+ chains,
37
+ ownerAddress,
38
+ queryOptions = {
39
+ chain: chains.map((chain) => chain.id),
40
+ include_spam: "false",
41
+ metadata: "true",
42
+ limit: 100,
43
+ page: 1,
44
+ },
45
+ } = args;
46
+
47
+ const result = await getV1TokensErc20ByOwnerAddress({
48
+ baseUrl: `https://${getThirdwebDomains().insight}`,
49
+ fetch: getClientFetch(client),
50
+ path: {
51
+ ownerAddress: ownerAddress,
52
+ },
53
+ query: {
54
+ ...queryOptions,
55
+ chain: chains.map((chain) => chain.id),
56
+ },
57
+ });
58
+
59
+ if (!result.data || result.error) {
60
+ throw new Error(result.error ? stringify(result.error) : "Unknown error");
61
+ }
62
+ return result.data.data;
63
+ }
@@ -0,0 +1,66 @@
1
+ import {
2
+ type GetV1WalletsByWalletAddressTransactionsData,
3
+ type GetV1WalletsByWalletAddressTransactionsResponse,
4
+ getV1WalletsByWalletAddressTransactions,
5
+ } from "@thirdweb-dev/insight";
6
+ import type { Chain } from "../chains/types.js";
7
+ import type { ThirdwebClient } from "../client/client.js";
8
+ import { getThirdwebDomains } from "../utils/domains.js";
9
+ import { getClientFetch } from "../utils/fetch.js";
10
+
11
+ export type Transaction = NonNullable<
12
+ GetV1WalletsByWalletAddressTransactionsResponse["data"]
13
+ >[number];
14
+
15
+ /**
16
+ * Get transactions for a wallet
17
+ * @example
18
+ * ```ts
19
+ * import { Insight } from "thirdweb";
20
+ *
21
+ * const transactions = await Insight.getTransactions({
22
+ * client,
23
+ * walletAddress: "0x1234567890123456789012345678901234567890",
24
+ * chains: [sepolia],
25
+ * });
26
+ * ```
27
+ * @insight
28
+ */
29
+ export async function getTransactions(args: {
30
+ client: ThirdwebClient;
31
+ walletAddress: string;
32
+ chains: Chain[];
33
+ queryOptions?: Omit<
34
+ GetV1WalletsByWalletAddressTransactionsData["query"],
35
+ "chain"
36
+ >;
37
+ }): Promise<Transaction[]> {
38
+ const threeMonthsAgoInSeconds = Math.floor(
39
+ (Date.now() - 3 * 30 * 24 * 60 * 60 * 1000) / 1000,
40
+ );
41
+ const {
42
+ client,
43
+ walletAddress,
44
+ chains,
45
+ queryOptions = {
46
+ filter_block_timestamp_gte: threeMonthsAgoInSeconds,
47
+ limit: 100,
48
+ page: 1,
49
+ },
50
+ } = args;
51
+ const result = await getV1WalletsByWalletAddressTransactions({
52
+ baseUrl: `https://${getThirdwebDomains().insight}`,
53
+ fetch: getClientFetch(client),
54
+ query: {
55
+ ...queryOptions,
56
+ chain: chains.map((chain) => chain.id),
57
+ },
58
+ path: {
59
+ wallet_address: walletAddress,
60
+ },
61
+ });
62
+ if (result.error) {
63
+ throw new Error(result.error.error);
64
+ }
65
+ return result.data.data || [];
66
+ }
@@ -0,0 +1,3 @@
1
+ export { getOwnedNFTs, type OwnedNFT } from "./get-nfts.js";
2
+ export { getOwnedTokens, type OwnedToken } from "./get-tokens.js";
3
+ export { getTransactions, type Transaction } from "./get-transactions.js";
@@ -703,11 +703,7 @@ export function DetailsModal(props: {
703
703
  }}
704
704
  >
705
705
  <CoinsIcon size={iconSize.md} />
706
- <Text color="primaryText">
707
- {props.supportedNFTs
708
- ? locale.viewFunds.viewAssets
709
- : locale.viewFunds.title}
710
- </Text>
706
+ <Text color="primaryText">{locale.viewFunds.viewAssets}</Text>
711
707
  </MenuButton>
712
708
  )}
713
709
 
@@ -841,34 +837,20 @@ export function DetailsModal(props: {
841
837
  />
842
838
  );
843
839
  } else if (screen === "view-assets") {
844
- if (props.supportedNFTs) {
845
- content = (
846
- <ViewAssets
847
- supportedTokens={props.supportedTokens}
848
- supportedNFTs={props.supportedNFTs}
849
- onBack={() => {
850
- setScreen("main");
851
- }}
852
- theme={props.theme}
853
- setScreen={setScreen}
854
- client={client}
855
- connectLocale={locale}
856
- assetTabs={props.detailsModal?.assetTabs}
857
- />
858
- );
859
- } else {
860
- // Always show tokens (has the native token at least)
861
- content = (
862
- <ViewTokens
863
- supportedTokens={props.supportedTokens}
864
- onBack={() => {
865
- setScreen("main");
866
- }}
867
- client={client}
868
- connectLocale={locale}
869
- />
870
- );
871
- }
840
+ content = (
841
+ <ViewAssets
842
+ supportedTokens={props.supportedTokens}
843
+ supportedNFTs={props.supportedNFTs}
844
+ onBack={() => {
845
+ setScreen("main");
846
+ }}
847
+ theme={props.theme}
848
+ setScreen={setScreen}
849
+ client={client}
850
+ connectLocale={locale}
851
+ assetTabs={props.detailsModal?.assetTabs}
852
+ />
853
+ );
872
854
  } else if (screen === "view-nfts") {
873
855
  content = (
874
856
  <ViewNFTs
@@ -72,8 +72,8 @@ const pulseAnimation = keyframes`
72
72
  const PulsingDot = /* @__PURE__ */ StyledDiv(() => {
73
73
  return {
74
74
  background: "currentColor",
75
- width: "9px",
76
- height: "9px",
75
+ width: "10px",
76
+ height: "10px",
77
77
  borderRadius: "50%",
78
78
  '&[data-active="true"]': {
79
79
  animation: `${pulseAnimation} 1s infinite`,
@@ -186,9 +186,14 @@ export function TransactionModeScreen(props: {
186
186
  ) : activeAccount ? (
187
187
  <Container flex="column" gap="sm">
188
188
  {insufficientFunds && (
189
- <Text size="sm" color="danger" style={{ textAlign: "center" }}>
190
- Insufficient funds
191
- </Text>
189
+ <div>
190
+ <Text color="danger" size="xs" center multiline>
191
+ Insufficient Funds
192
+ </Text>
193
+ <Text size="xs" center multiline>
194
+ Select another token or pay with a debit card.
195
+ </Text>
196
+ </div>
192
197
  )}
193
198
  <Container
194
199
  flex="row"
@@ -13,10 +13,7 @@ import {
13
13
  import type { PayUIOptions } from "../../../../../../core/hooks/connection/ConnectButtonProps.js";
14
14
  import { useBuyWithFiatQuote } from "../../../../../../core/hooks/pay/useBuyWithFiatQuote.js";
15
15
  import { PREFERRED_FIAT_PROVIDER_STORAGE_KEY } from "../../../../../../core/utils/storage.js";
16
- import {
17
- defaultMessage,
18
- getErrorMessage,
19
- } from "../../../../../utils/errors.js";
16
+ import { getErrorMessage } from "../../../../../utils/errors.js";
20
17
  import {
21
18
  Drawer,
22
19
  DrawerOverlay,
@@ -180,7 +177,7 @@ export function FiatScreenContent(props: {
180
177
  )}
181
178
 
182
179
  <Container flex="column" gap="sm">
183
- <Text size="sm">Pay with credit card</Text>
180
+ <Text size="sm">Pay with a debit card</Text>
184
181
  <div>
185
182
  <PayWithCreditCard
186
183
  isLoading={fiatQuoteQuery.isLoading}
@@ -242,9 +239,14 @@ export function FiatScreenContent(props: {
242
239
  />
243
240
  </Text>
244
241
  ) : (
245
- <Text color="danger" size="sm" center multiline>
246
- {errorMsg.message || defaultMessage}
247
- </Text>
242
+ <div>
243
+ <Text color="danger" size="xs" center multiline>
244
+ {errorMsg.title}
245
+ </Text>
246
+ <Text size="xs" center multiline>
247
+ {errorMsg.message}
248
+ </Text>
249
+ </div>
248
250
  )}
249
251
  </div>
250
252
  )}
@@ -1,5 +1,4 @@
1
- import { CrossCircledIcon } from "@radix-ui/react-icons";
2
- import { useState } from "react";
1
+ import { useMemo, useState } from "react";
3
2
  import { trackPayEvent } from "../../../../../../../analytics/track/pay.js";
4
3
  import type { Chain } from "../../../../../../../chains/types.js";
5
4
  import type { ThirdwebClient } from "../../../../../../../client/client.js";
@@ -13,7 +12,6 @@ import {
13
12
  waitForReceipt,
14
13
  } from "../../../../../../../transaction/actions/wait-for-tx-receipt.js";
15
14
  import { useCustomTheme } from "../../../../../../core/design-system/CustomThemeProvider.js";
16
- import { iconSize } from "../../../../../../core/design-system/index.js";
17
15
  import { Spacer } from "../../../../components/Spacer.js";
18
16
  import { Spinner } from "../../../../components/Spinner.js";
19
17
  import { StepBar } from "../../../../components/StepBar.js";
@@ -25,6 +23,7 @@ import { StyledDiv } from "../../../../design-system/elements.js";
25
23
  import type { ERC20OrNativeToken } from "../../nativeToken.js";
26
24
  import { Step } from "../Stepper.js";
27
25
  import type { PayerInfo } from "../types.js";
26
+ import { ErrorText } from "./ErrorText.js";
28
27
  import { SwapSummary } from "./SwapSummary.js";
29
28
  import { addPendingTx } from "./pendingSwapTx.js";
30
29
 
@@ -59,6 +58,7 @@ export function SwapConfirmationScreen(props: {
59
58
  const initialStep = needsApprovalStep ? "approval" : "swap";
60
59
 
61
60
  const [step, setStep] = useState<"approval" | "swap">(initialStep);
61
+ const [error, setError] = useState<string | undefined>();
62
62
  const [status, setStatus] = useState<
63
63
  "pending" | "success" | "error" | "idle"
64
64
  >("idle");
@@ -66,6 +66,38 @@ export function SwapConfirmationScreen(props: {
66
66
  const receiver = props.quote.swapDetails.toAddress;
67
67
  const sender = props.quote.swapDetails.fromAddress;
68
68
 
69
+ const uiErrorMessage = useMemo(() => {
70
+ if (step === "approval" && status === "error" && error) {
71
+ if (error.toLowerCase().includes("user rejected")) {
72
+ return {
73
+ title: "Failed to Approve",
74
+ message: "Your wallet rejected the approval request.",
75
+ };
76
+ }
77
+ return {
78
+ title: "Failed to Approve",
79
+ message:
80
+ "Your wallet failed to approve the transaction for an unknown reason. Please try again or contact support.",
81
+ };
82
+ }
83
+
84
+ if (step === "swap" && status === "error" && error) {
85
+ if (error.toLowerCase().includes("user rejected")) {
86
+ return {
87
+ title: "Failed to Confirm",
88
+ message: "Your wallet rejected the confirmation request.",
89
+ };
90
+ }
91
+ return {
92
+ title: "Failed to Confirm",
93
+ message:
94
+ "Your wallet failed to confirm the transaction for an unknown reason. Please try again or contact support.",
95
+ };
96
+ }
97
+
98
+ return undefined;
99
+ }, [error, step, status]);
100
+
69
101
  return (
70
102
  <Container p="lg">
71
103
  <ModalHeader title={props.title} onBack={props.onBack} />
@@ -128,15 +160,12 @@ export function SwapConfirmationScreen(props: {
128
160
  </>
129
161
  )}
130
162
 
131
- {status === "error" && (
163
+ {uiErrorMessage && (
132
164
  <>
133
- <Container flex="row" gap="xs" center="both" color="danger">
134
- <CrossCircledIcon width={iconSize.sm} height={iconSize.sm} />
135
- <Text color="danger" size="sm">
136
- {step === "approval" ? "Failed to Approve" : "Failed to Confirm"}
137
- </Text>
138
- </Container>
139
-
165
+ <ErrorText
166
+ title={uiErrorMessage.title}
167
+ message={uiErrorMessage.message}
168
+ />
140
169
  <Spacer y="md" />
141
170
  </>
142
171
  )}
@@ -224,6 +253,7 @@ export function SwapConfirmationScreen(props: {
224
253
  setStatus("idle");
225
254
  } catch (e) {
226
255
  console.error(e);
256
+ setError((e as Error).message);
227
257
  setStatus("error");
228
258
  }
229
259
  }
@@ -0,0 +1,23 @@
1
+ import { CrossCircledIcon } from "@radix-ui/react-icons";
2
+ import { iconSize } from "../../../../../../core/design-system/index.js";
3
+ import { Container } from "../../../../components/basic.js";
4
+ import { Text } from "../../../../components/text.js";
5
+
6
+ export function ErrorText(props: {
7
+ title: string;
8
+ message: string;
9
+ }) {
10
+ return (
11
+ <Container gap="xxs" flex="column">
12
+ <Container flex="row" gap="xxs" center="both" color="danger">
13
+ <CrossCircledIcon width={iconSize.sm} height={iconSize.sm} />
14
+ <Text color="danger" size="sm">
15
+ {props.title}
16
+ </Text>
17
+ </Container>
18
+ <Text center size="xs">
19
+ {props.message}
20
+ </Text>
21
+ </Container>
22
+ );
23
+ }
@@ -12,10 +12,7 @@ import type { Account } from "../../../../../../../wallets/interfaces/wallet.js"
12
12
  import type { PayUIOptions } from "../../../../../../core/hooks/connection/ConnectButtonProps.js";
13
13
  import { useWalletBalance } from "../../../../../../core/hooks/others/useWalletBalance.js";
14
14
  import { useBuyWithCryptoQuote } from "../../../../../../core/hooks/pay/useBuyWithCryptoQuote.js";
15
- import {
16
- defaultMessage,
17
- getErrorMessage,
18
- } from "../../../../../utils/errors.js";
15
+ import { getErrorMessage } from "../../../../../utils/errors.js";
19
16
  import type { PayEmbedConnectOptions } from "../../../../PayEmbed.js";
20
17
  import {
21
18
  Drawer,
@@ -301,9 +298,14 @@ export function SwapScreenContent(props: {
301
298
  />
302
299
  </Text>
303
300
  ) : (
304
- <Text color="danger" size="xs" center multiline>
305
- {errorMsg.message || defaultMessage}
306
- </Text>
301
+ <div>
302
+ <Text color="danger" size="xs" center multiline>
303
+ {errorMsg.title}
304
+ </Text>
305
+ <Text size="xs" center multiline>
306
+ {errorMsg.message}
307
+ </Text>
308
+ </div>
307
309
  )}
308
310
  </div>
309
311
  )}
@@ -311,7 +313,10 @@ export function SwapScreenContent(props: {
311
313
  {!errorMsg && isNotEnoughBalance && (
312
314
  <div>
313
315
  <Text color="danger" size="xs" center multiline>
314
- Insufficient funds
316
+ Insufficient Funds
317
+ </Text>
318
+ <Text size="xs" center multiline>
319
+ Select another token or pay with a debit card.
315
320
  </Text>
316
321
  </div>
317
322
  )}
@@ -176,11 +176,11 @@ export function TokenSelectorScreen(props: {
176
176
  enabled: !!props.sourceSupportedTokens && !!chainInfo.data,
177
177
  });
178
178
 
179
- if (walletsAndBalances.isLoading || !walletsAndBalances.data) {
179
+ if (walletsAndBalances.isLoading || chainInfo.isLoading) {
180
180
  return <LoadingScreen />;
181
181
  }
182
182
 
183
- const filteredWallets = Array.from(walletsAndBalances.data.entries() || [])
183
+ const filteredWallets = Array.from(walletsAndBalances.data?.entries() || [])
184
184
  .filter(([w]) => !props.hiddenWallets?.includes(w.id))
185
185
  .filter(([, balances]) => {
186
186
  const hasEnoughBalance = balances.some((b) => b.balance.value > 0);
@@ -276,7 +276,7 @@ export function TokenSelectorScreen(props: {
276
276
  >
277
277
  <CardStackIcon width={iconSize.md} height={iconSize.md} />
278
278
  <Text size="sm" color="primaryText">
279
- Pay with credit card
279
+ Pay with a debit card
280
280
  </Text>
281
281
  </Container>
282
282
  </Button>
@@ -362,7 +362,7 @@ function WalletRowWithBalances(props: {
362
362
  ) : (
363
363
  <Container style={{ padding: spacing.sm }}>
364
364
  <Text size="sm" color="secondaryText">
365
- Insufficient funds
365
+ Insufficient Funds
366
366
  </Text>
367
367
  </Container>
368
368
  )}
@@ -1,6 +1,6 @@
1
1
  import { CheckCircledIcon } from "@radix-ui/react-icons";
2
2
  import { useQuery } from "@tanstack/react-query";
3
- import { useState } from "react";
3
+ import { useMemo, useState } from "react";
4
4
  import type { Chain } from "../../../../../../../chains/types.js";
5
5
  import { getCachedChain } from "../../../../../../../chains/utils.js";
6
6
  import type { ThirdwebClient } from "../../../../../../../client/client.js";
@@ -34,6 +34,7 @@ import { type ERC20OrNativeToken, isNativeToken } from "../../nativeToken.js";
34
34
  import { Step } from "../Stepper.js";
35
35
  import type { PayerInfo } from "../types.js";
36
36
  import { ConnectorLine } from "./ConfirmationScreen.js";
37
+ import { ErrorText } from "./ErrorText.js";
37
38
  import { SwapSummary } from "./SwapSummary.js";
38
39
 
39
40
  type TransferConfirmationScreenProps = {
@@ -109,6 +110,42 @@ export function TransferConfirmationScreen(
109
110
  refetchInterval: 30 * 1000,
110
111
  });
111
112
 
113
+ const uiErrorMessage = useMemo(() => {
114
+ if (step === "approve" && status.id === "error" && status.error) {
115
+ if (status.error.toLowerCase().includes("user rejected")) {
116
+ return {
117
+ title: "Failed to Approve",
118
+ message: "Your wallet rejected the approval request.",
119
+ };
120
+ }
121
+ return {
122
+ title: "Failed to Approve",
123
+ message:
124
+ "Your wallet failed to approve the transaction for an unknown reason. Please try again or contact support.",
125
+ };
126
+ }
127
+
128
+ if (
129
+ (step === "transfer" || step === "execute") &&
130
+ status.id === "error" &&
131
+ status.error
132
+ ) {
133
+ if (status.error.toLowerCase().includes("user rejected")) {
134
+ return {
135
+ title: "Failed to Confirm",
136
+ message: "Your wallet rejected the confirmation request.",
137
+ };
138
+ }
139
+ return {
140
+ title: "Failed to Confirm",
141
+ message:
142
+ "Your wallet failed to confirm the transaction for an unknown reason. Please try again or contact support.",
143
+ };
144
+ }
145
+
146
+ return undefined;
147
+ }, [step, status]);
148
+
112
149
  if (transferQuery.isLoading) {
113
150
  return (
114
151
  <Container p="lg">
@@ -190,15 +227,12 @@ export function TransferConfirmationScreen(
190
227
  </>
191
228
  )}
192
229
 
193
- {status.id === "error" && (
230
+ {uiErrorMessage && (
194
231
  <>
195
- <Container flex="row" gap="xs" center="both" color="danger">
196
- <Text color="danger" size="sm" style={{ textAlign: "center" }}>
197
- {step === "transfer"
198
- ? `${status.error || "Failed to Transfer"}`
199
- : "Failed to Execute"}
200
- </Text>
201
- </Container>
232
+ <ErrorText
233
+ title={uiErrorMessage.title}
234
+ message={uiErrorMessage.message}
235
+ />
202
236
  <Spacer y="md" />
203
237
  </>
204
238
  )}
@@ -82,7 +82,7 @@ export function ViewAssets(props: {
82
82
  >
83
83
  <Container p="lg">
84
84
  <ModalHeader
85
- title={connectLocale.viewFunds.title}
85
+ title={connectLocale.viewFunds.viewAssets}
86
86
  onBack={props.onBack}
87
87
  />
88
88
  </Container>