thirdweb 5.33.0 → 5.34.0-nightly-f6ff5a78fc2d65f0f250b154f1405210ca57ce0a-20240707000358

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 (78) hide show
  1. package/dist/cjs/extensions/erc721/read/getOwnedTokenIds.js +13 -4
  2. package/dist/cjs/extensions/erc721/read/getOwnedTokenIds.js.map +1 -1
  3. package/dist/cjs/react/core/hooks/transaction/useSendTransaction.js +2 -3
  4. package/dist/cjs/react/core/hooks/transaction/useSendTransaction.js.map +1 -1
  5. package/dist/cjs/react/core/utils/defaultTokens.js.map +1 -1
  6. package/dist/cjs/react/web/hooks/transaction/useSendTransaction.js +8 -5
  7. package/dist/cjs/react/web/hooks/transaction/useSendTransaction.js.map +1 -1
  8. package/dist/cjs/react/web/ui/ConnectWallet/ConnectButton.js +1 -1
  9. package/dist/cjs/react/web/ui/ConnectWallet/ConnectButton.js.map +1 -1
  10. package/dist/cjs/react/web/ui/ConnectWallet/Details.js +24 -4
  11. package/dist/cjs/react/web/ui/ConnectWallet/Details.js.map +1 -1
  12. package/dist/cjs/react/web/ui/ConnectWallet/icons/ImageIcon.js +12 -0
  13. package/dist/cjs/react/web/ui/ConnectWallet/icons/ImageIcon.js.map +1 -0
  14. package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewFunds.js +12 -30
  15. package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewFunds.js.map +1 -1
  16. package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewNFTs.js +142 -0
  17. package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewNFTs.js.map +1 -0
  18. package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewTokens.js +48 -0
  19. package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewTokens.js.map +1 -0
  20. package/dist/cjs/version.js +1 -1
  21. package/dist/cjs/version.js.map +1 -1
  22. package/dist/esm/extensions/erc721/read/getOwnedTokenIds.js +14 -5
  23. package/dist/esm/extensions/erc721/read/getOwnedTokenIds.js.map +1 -1
  24. package/dist/esm/react/core/hooks/transaction/useSendTransaction.js +2 -3
  25. package/dist/esm/react/core/hooks/transaction/useSendTransaction.js.map +1 -1
  26. package/dist/esm/react/core/utils/defaultTokens.js.map +1 -1
  27. package/dist/esm/react/web/hooks/transaction/useSendTransaction.js +8 -5
  28. package/dist/esm/react/web/hooks/transaction/useSendTransaction.js.map +1 -1
  29. package/dist/esm/react/web/ui/ConnectWallet/ConnectButton.js +1 -1
  30. package/dist/esm/react/web/ui/ConnectWallet/ConnectButton.js.map +1 -1
  31. package/dist/esm/react/web/ui/ConnectWallet/Details.js +24 -4
  32. package/dist/esm/react/web/ui/ConnectWallet/Details.js.map +1 -1
  33. package/dist/esm/react/web/ui/ConnectWallet/icons/ImageIcon.js +8 -0
  34. package/dist/esm/react/web/ui/ConnectWallet/icons/ImageIcon.js.map +1 -0
  35. package/dist/esm/react/web/ui/ConnectWallet/screens/ViewFunds.js +13 -31
  36. package/dist/esm/react/web/ui/ConnectWallet/screens/ViewFunds.js.map +1 -1
  37. package/dist/esm/react/web/ui/ConnectWallet/screens/ViewNFTs.js +139 -0
  38. package/dist/esm/react/web/ui/ConnectWallet/screens/ViewNFTs.js.map +1 -0
  39. package/dist/esm/react/web/ui/ConnectWallet/screens/ViewTokens.js +45 -0
  40. package/dist/esm/react/web/ui/ConnectWallet/screens/ViewTokens.js.map +1 -0
  41. package/dist/esm/version.js +1 -1
  42. package/dist/esm/version.js.map +1 -1
  43. package/dist/types/extensions/erc721/read/getOwnedTokenIds.d.ts.map +1 -1
  44. package/dist/types/react/core/hooks/connection/ConnectButtonProps.d.ts +25 -1
  45. package/dist/types/react/core/hooks/connection/ConnectButtonProps.d.ts.map +1 -1
  46. package/dist/types/react/core/hooks/transaction/useSendTransaction.d.ts +2 -1
  47. package/dist/types/react/core/hooks/transaction/useSendTransaction.d.ts.map +1 -1
  48. package/dist/types/react/core/utils/defaultTokens.d.ts +2 -0
  49. package/dist/types/react/core/utils/defaultTokens.d.ts.map +1 -1
  50. package/dist/types/react/web/hooks/transaction/useSendTransaction.d.ts.map +1 -1
  51. package/dist/types/react/web/ui/ConnectWallet/Details.d.ts +28 -1
  52. package/dist/types/react/web/ui/ConnectWallet/Details.d.ts.map +1 -1
  53. package/dist/types/react/web/ui/ConnectWallet/icons/ImageIcon.d.ts +6 -0
  54. package/dist/types/react/web/ui/ConnectWallet/icons/ImageIcon.d.ts.map +1 -0
  55. package/dist/types/react/web/ui/ConnectWallet/screens/ViewFunds.d.ts +5 -2
  56. package/dist/types/react/web/ui/ConnectWallet/screens/ViewFunds.d.ts.map +1 -1
  57. package/dist/types/react/web/ui/ConnectWallet/screens/ViewNFTs.d.ts +13 -0
  58. package/dist/types/react/web/ui/ConnectWallet/screens/ViewNFTs.d.ts.map +1 -0
  59. package/dist/types/react/web/ui/ConnectWallet/screens/ViewTokens.d.ts +11 -0
  60. package/dist/types/react/web/ui/ConnectWallet/screens/ViewTokens.d.ts.map +1 -0
  61. package/dist/types/react/web/ui/ConnectWallet/screens/types.d.ts +1 -1
  62. package/dist/types/react/web/ui/ConnectWallet/screens/types.d.ts.map +1 -1
  63. package/dist/types/version.d.ts +1 -1
  64. package/dist/types/version.d.ts.map +1 -1
  65. package/package.json +1 -1
  66. package/src/extensions/erc721/read/getOwnedTokenIds.ts +30 -5
  67. package/src/react/core/hooks/connection/ConnectButtonProps.ts +29 -1
  68. package/src/react/core/hooks/transaction/useSendTransaction.ts +4 -4
  69. package/src/react/core/utils/defaultTokens.ts +3 -0
  70. package/src/react/web/hooks/transaction/useSendTransaction.tsx +19 -4
  71. package/src/react/web/ui/ConnectWallet/ConnectButton.tsx +1 -0
  72. package/src/react/web/ui/ConnectWallet/Details.tsx +76 -3
  73. package/src/react/web/ui/ConnectWallet/icons/ImageIcon.tsx +25 -0
  74. package/src/react/web/ui/ConnectWallet/screens/ViewFunds.tsx +32 -87
  75. package/src/react/web/ui/ConnectWallet/screens/ViewNFTs.tsx +255 -0
  76. package/src/react/web/ui/ConnectWallet/screens/ViewTokens.tsx +125 -0
  77. package/src/react/web/ui/ConnectWallet/screens/types.ts +2 -0
  78. package/src/version.ts +1 -1
@@ -0,0 +1,6 @@
1
+ import type { IconFC } from "./types.js";
2
+ /**
3
+ * @internal
4
+ */
5
+ export declare const ImageIcon: IconFC;
6
+ //# sourceMappingURL=ImageIcon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageIcon.d.ts","sourceRoot":"","sources":["../../../../../../../src/react/web/ui/ConnectWallet/icons/ImageIcon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,MAmBvB,CAAC"}
@@ -1,11 +1,14 @@
1
1
  import type { ThirdwebClient } from "../../../../../client/client.js";
2
- import { type SupportedTokens } from "../../../../core/utils/defaultTokens.js";
2
+ import type { SupportedNFTs, SupportedTokens } from "../../../../core/utils/defaultTokens.js";
3
+ import type { WalletDetailsModalScreen } from "./types.js";
3
4
  /**
4
5
  * @internal
5
6
  */
6
7
  export declare function ViewFunds(props: {
7
8
  supportedTokens?: SupportedTokens;
9
+ supportedNFTs?: SupportedNFTs;
8
10
  onBack: () => void;
11
+ setScreen: (screen: WalletDetailsModalScreen) => void;
9
12
  client: ThirdwebClient;
10
- }): import("react/jsx-runtime.js").JSX.Element | null;
13
+ }): import("react/jsx-runtime.js").JSX.Element;
11
14
  //# sourceMappingURL=ViewFunds.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ViewFunds.d.ts","sourceRoot":"","sources":["../../../../../../../src/react/web/ui/ConnectWallet/screens/ViewFunds.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAGtE,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,yCAAyC,CAAC;AAejD;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE;IAC/B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,cAAc,CAAC;CACxB,qDAkDA"}
1
+ {"version":3,"file":"ViewFunds.d.ts","sourceRoot":"","sources":["../../../../../../../src/react/web/ui/ConnectWallet/screens/ViewFunds.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEtE,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EAChB,MAAM,yCAAyC,CAAC;AAOjD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAE3D;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE;IAC/B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,SAAS,EAAE,CAAC,MAAM,EAAE,wBAAwB,KAAK,IAAI,CAAC;IACtD,MAAM,EAAE,cAAc,CAAC;CACxB,8CA8CA"}
@@ -0,0 +1,13 @@
1
+ import type { ThirdwebClient } from "../../../../../client/client.js";
2
+ import type { Theme } from "../../../../core/design-system/index.js";
3
+ import type { SupportedNFTs } from "../../../../core/utils/defaultTokens.js";
4
+ /**
5
+ * @internal
6
+ */
7
+ export declare function ViewNFTs(props: {
8
+ supportedNFTs?: SupportedNFTs;
9
+ theme: Theme | "light" | "dark";
10
+ onBack: () => void;
11
+ client: ThirdwebClient;
12
+ }): import("react/jsx-runtime.js").JSX.Element | null;
13
+ //# sourceMappingURL=ViewNFTs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ViewNFTs.d.ts","sourceRoot":"","sources":["../../../../../../../src/react/web/ui/ConnectWallet/screens/ViewNFTs.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAMtE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yCAAyC,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAoD7E;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE;IAC9B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,KAAK,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC;IAChC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,cAAc,CAAC;CACxB,qDAqFA"}
@@ -0,0 +1,11 @@
1
+ import type { ThirdwebClient } from "../../../../../client/client.js";
2
+ import { type SupportedTokens } from "../../../../core/utils/defaultTokens.js";
3
+ /**
4
+ * @internal
5
+ */
6
+ export declare function ViewTokens(props: {
7
+ supportedTokens?: SupportedTokens;
8
+ onBack: () => void;
9
+ client: ThirdwebClient;
10
+ }): import("react/jsx-runtime.js").JSX.Element | null;
11
+ //# sourceMappingURL=ViewTokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ViewTokens.d.ts","sourceRoot":"","sources":["../../../../../../../src/react/web/ui/ConnectWallet/screens/ViewTokens.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAGtE,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,yCAAyC,CAAC;AAejD;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,cAAc,CAAC;CACxB,qDAkDA"}
@@ -56,5 +56,5 @@ export type WelcomeScreen = {
56
56
  height?: number;
57
57
  };
58
58
  } | (() => React.ReactNode);
59
- export type WalletDetailsModalScreen = "main" | "export" | "send" | "receive" | "buy" | "network-switcher" | "pending-tx" | "view-funds" | "private-key" | "manage-wallet" | "wallet-connect-receiver" | "wallet-manager";
59
+ export type WalletDetailsModalScreen = "main" | "export" | "send" | "receive" | "buy" | "network-switcher" | "pending-tx" | "view-funds" | "view-tokens" | "view-nfts" | "private-key" | "manage-wallet" | "wallet-connect-receiver" | "wallet-manager";
60
60
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../../src/react/web/ui/ConnectWallet/screens/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,MAAM,aAAa,GACrB;IACE;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,GAAG,CAAC,EAAE;QACJ;;WAEG;QACH,GAAG,EAAE,MAAM,CAAC;QACZ;;WAEG;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;QACf;;WAEG;QACH,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH,GACD,CAAC,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC;AAE5B,MAAM,MAAM,wBAAwB,GAChC,MAAM,GACN,QAAQ,GACR,MAAM,GACN,SAAS,GACT,KAAK,GACL,kBAAkB,GAClB,YAAY,GACZ,YAAY,GACZ,aAAa,GACb,eAAe,GACf,yBAAyB,GACzB,gBAAgB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../../src/react/web/ui/ConnectWallet/screens/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,MAAM,aAAa,GACrB;IACE;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,GAAG,CAAC,EAAE;QACJ;;WAEG;QACH,GAAG,EAAE,MAAM,CAAC;QACZ;;WAEG;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;QACf;;WAEG;QACH,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH,GACD,CAAC,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC;AAE5B,MAAM,MAAM,wBAAwB,GAChC,MAAM,GACN,QAAQ,GACR,MAAM,GACN,SAAS,GACT,KAAK,GACL,kBAAkB,GAClB,YAAY,GACZ,YAAY,GACZ,aAAa,GACb,WAAW,GACX,aAAa,GACb,eAAe,GACf,yBAAyB,GACzB,gBAAgB,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare const version = "5.33.0";
1
+ export declare const version = "5.34.0-nightly-f6ff5a78fc2d65f0f250b154f1405210ca57ce0a-20240707000358";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,WAAW,CAAC"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,2EAA2E,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thirdweb",
3
- "version": "5.33.0",
3
+ "version": "5.34.0-nightly-f6ff5a78fc2d65f0f250b154f1405210ca57ce0a-20240707000358",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/thirdweb-dev/js.git#main"
@@ -3,7 +3,14 @@ import {
3
3
  type BalanceOfParams,
4
4
  balanceOf,
5
5
  } from "../__generated__/IERC721A/read/balanceOf.js";
6
- import { tokenOfOwnerByIndex } from "../__generated__/IERC721Enumerable/read/tokenOfOwnerByIndex.js";
6
+ import {
7
+ isTokensOfOwnerSupported,
8
+ tokensOfOwner,
9
+ } from "../__generated__/IERC721AQueryable/read/tokensOfOwner.js";
10
+ import {
11
+ isTokenOfOwnerByIndexSupported,
12
+ tokenOfOwnerByIndex,
13
+ } from "../__generated__/IERC721Enumerable/read/tokenOfOwnerByIndex.js";
7
14
 
8
15
  export type GetOwnedTokenIdsParams = BalanceOfParams;
9
16
 
@@ -27,11 +34,29 @@ export async function getOwnedTokenIds(
27
34
  ): Promise<bigint[]> {
28
35
  const balanceOfResult = await balanceOf(options);
29
36
 
30
- const promises: ReturnType<typeof tokenOfOwnerByIndex>[] = [];
37
+ const supportsTokensOfOwnerByIndex = await isTokenOfOwnerByIndexSupported(
38
+ options.contract,
39
+ );
40
+
41
+ if (supportsTokensOfOwnerByIndex) {
42
+ const promises: ReturnType<typeof tokenOfOwnerByIndex>[] = [];
43
+
44
+ for (let i = 0n; i < balanceOfResult; i++) {
45
+ promises.push(tokenOfOwnerByIndex({ ...options, index: i }));
46
+ }
47
+
48
+ return Promise.all(promises);
49
+ }
50
+
51
+ const supportsTokensOfOwner = await isTokensOfOwnerSupported(
52
+ options.contract,
53
+ );
31
54
 
32
- for (let i = 0n; i < balanceOfResult; i++) {
33
- promises.push(tokenOfOwnerByIndex({ ...options, index: i }));
55
+ if (supportsTokensOfOwner) {
56
+ return (await tokensOfOwner({ ...options })).map((token) => token); // Unfortunate map to make this return a mutable array
34
57
  }
35
58
 
36
- return Promise.all(promises);
59
+ throw new Error(
60
+ `The contract at ${options.contract.address} on chain ${options.contract.chain.id} does not support the tokenOfOwnerByIndex or tokensOfOwner interface`,
61
+ );
37
62
  }
@@ -7,7 +7,10 @@ import type { NetworkSelectorProps } from "../../../web/ui/ConnectWallet/Network
7
7
  import type { WelcomeScreen } from "../../../web/ui/ConnectWallet/screens/types.js";
8
8
  import type { LocaleId } from "../../../web/ui/types.js";
9
9
  import type { Theme } from "../../design-system/index.js";
10
- import type { SupportedTokens } from "../../utils/defaultTokens.js";
10
+ import type {
11
+ SupportedNFTs,
12
+ SupportedTokens,
13
+ } from "../../utils/defaultTokens.js";
11
14
  import type { SiweAuthOptions } from "../auth/useSiweAuth.js";
12
15
 
13
16
  export type PayUIOptions = {
@@ -674,6 +677,31 @@ export type ConnectButtonProps = {
674
677
  */
675
678
  supportedTokens?: SupportedTokens;
676
679
 
680
+ /**
681
+ * Customize the NFTs shown in the "View Funds" screen in Details Modal for various networks.
682
+ *
683
+ * By default, The "View Funds" screen shows a few popular tokens for default chains and the native token. For other chains it only shows the native token.
684
+ * @example
685
+ *
686
+ * supportedTokens prop allows you to customize this list as shown below which shows "Pudgy Penguins" help when users wallet is connected to Ethereum mainnet.
687
+ *
688
+ * ```tsx
689
+ * import { ConnectButton } from 'thirdweb/react';
690
+ *
691
+ * function Example() {
692
+ * return (
693
+ * <ConnectButton
694
+ * supportedNFTs={{
695
+ * // when connected to Ethereum mainnet - show Pudgy Penguins
696
+ * 1: ['0xBd3531dA5CF5857e7CfAA92426877b022e612cf8'],
697
+ * }}
698
+ * />
699
+ * );
700
+ * }
701
+ * ```
702
+ */
703
+ supportedNFTs?: SupportedNFTs;
704
+
677
705
  /**
678
706
  * Called on connection of a wallet - including auto connect.
679
707
  * The callback is called with the connected wallet as an argument.
@@ -70,9 +70,10 @@ export type SendTransactionConfig = {
70
70
  type ShowModalData = {
71
71
  tx: PreparedTransaction;
72
72
  sendTx: () => void;
73
- rejectTx: () => void;
73
+ rejectTx: (reason: Error) => void;
74
74
  totalCostWei: bigint;
75
75
  walletBalance: GetWalletBalanceResult;
76
+ resolveTx: (data: WaitForReceiptOptions) => void;
76
77
  };
77
78
 
78
79
  /**
@@ -171,9 +172,8 @@ export function useSendTransactionCore(args: {
171
172
  showPayModal({
172
173
  tx,
173
174
  sendTx,
174
- rejectTx: () => {
175
- reject(new Error("Not enough balance"));
176
- },
175
+ rejectTx: reject,
176
+ resolveTx: resolve,
177
177
  totalCostWei,
178
178
  walletBalance,
179
179
  });
@@ -1,3 +1,5 @@
1
+ import type { Address } from "../../../utils/address.js";
2
+
1
3
  export type TokenInfo = {
2
4
  name: string;
3
5
  symbol: string;
@@ -30,6 +32,7 @@ const fantomIcon =
30
32
  "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMzIgMzIiPjxkZWZzPjxzdHlsZT4uY2xzLTF7ZmlsbDojZmZmO2ZpbGwtcnVsZTpldmVub2RkO30uY2xzLTJ7ZmlsbDojMTNiNWVjO30uY2xzLTN7bWFzazp1cmwoI21hc2spO308L3N0eWxlPjxtYXNrIGlkPSJtYXNrIiB4PSIxMCIgeT0iNiIgd2lkdGg9IjkzLjEiIGhlaWdodD0iMjAiIG1hc2tVbml0cz0idXNlclNwYWNlT25Vc2UiPjxnIGlkPSJhIj48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0xMCw2aDkzLjFWMjZIMTBaIi8+PC9nPjwvbWFzaz48L2RlZnM+PHRpdGxlPmZhPC90aXRsZT48ZyBpZD0iTGF5ZXJfMiIgZGF0YS1uYW1lPSJMYXllciAyIj48ZyBpZD0iTGF5ZXJfMS0yIiBkYXRhLW5hbWU9IkxheWVyIDEiPjxjaXJjbGUgY2xhc3M9ImNscy0yIiBjeD0iMTYiIGN5PSIxNiIgcj0iMTYiLz48ZyBjbGFzcz0iY2xzLTMiPjxwYXRoIGNsYXNzPSJjbHMtMSIgZD0iTTE3LjIsMTIuOWwzLjYtMi4xVjE1Wm0zLjYsOUwxNiwyNC43bC00LjgtMi44VjE3TDE2LDE5LjgsMjAuOCwxN1pNMTEuMiwxMC44bDMuNiwyLjFMMTEuMiwxNVptNS40LDMuMUwyMC4yLDE2bC0zLjYsMi4xWm0tMS4yLDQuMkwxMS44LDE2bDMuNi0yLjFabTQuOC04LjNMMTYsMTIuMiwxMS44LDkuOCwxNiw3LjNaTTEwLDkuNFYyMi41bDYsMy40LDYtMy40VjkuNEwxNiw2WiIvPjwvZz48L2c+PC9nPjwvc3ZnPg==";
31
33
 
32
34
  export type SupportedTokens = Record<number, TokenInfo[]>;
35
+ export type SupportedNFTs = Record<number, Address[]>;
33
36
 
34
37
  /**
35
38
  * Default tokens shown in [`ConnectButton`](https://portal.thirdweb.com/react/v4/components/ConnectButton)'s SendFunds screen for each network.
@@ -1,6 +1,7 @@
1
1
  import { CheckCircledIcon } from "@radix-ui/react-icons";
2
2
  import { useCallback, useContext, useEffect, useRef, useState } from "react";
3
3
  import type { ThirdwebClient } from "../../../../client/client.js";
4
+ import type { WaitForReceiptOptions } from "../../../../transaction/actions/wait-for-tx-receipt.js";
4
5
  import type { PreparedTransaction } from "../../../../transaction/prepare-transaction.js";
5
6
  import type { Wallet } from "../../../../wallets/interfaces/wallet.js";
6
7
  import { CustomThemeProvider } from "../../../core/design-system/CustomThemeProvider.js";
@@ -80,8 +81,11 @@ export function useSendTransaction(config: SendTransactionConfig = {}) {
80
81
  onComplete={data.sendTx}
81
82
  onClose={() => {
82
83
  setRootEl(null);
83
- data.rejectTx();
84
+ data.rejectTx(
85
+ new Error("User rejected transaction by closing modal"),
86
+ );
84
87
  }}
88
+ onTxSent={data.resolveTx}
85
89
  client={data.tx.client}
86
90
  localeId={payModal?.locale || "en_US"}
87
91
  supportedTokens={payModal?.supportedTokens}
@@ -115,6 +119,7 @@ type ModalProps = {
115
119
  nativeTokenSymbol: string;
116
120
  tx: PreparedTransaction;
117
121
  payOptions: PayUIOptions;
122
+ onTxSent: (data: WaitForReceiptOptions) => void;
118
123
  };
119
124
 
120
125
  function TxModal(props: ModalProps) {
@@ -146,7 +151,13 @@ function ModalContent(props: ModalProps) {
146
151
  }
147
152
 
148
153
  if (screen === "execute-tx") {
149
- return <ExecutingTxScreen tx={props.tx} closeModal={props.onClose} />;
154
+ return (
155
+ <ExecutingTxScreen
156
+ tx={props.tx}
157
+ closeModal={props.onClose}
158
+ onTxSent={props.onTxSent}
159
+ />
160
+ );
150
161
  }
151
162
 
152
163
  if (screen === "tx-history") {
@@ -194,6 +205,7 @@ function ModalContent(props: ModalProps) {
194
205
  function ExecutingTxScreen(props: {
195
206
  tx: PreparedTransaction;
196
207
  closeModal: () => void;
208
+ onTxSent: (data: WaitForReceiptOptions) => void;
197
209
  }) {
198
210
  const sendTxCore = useSendTransaction({
199
211
  payModal: false,
@@ -205,13 +217,16 @@ function ExecutingTxScreen(props: {
205
217
  const sendTx = useCallback(async () => {
206
218
  setStatus("loading");
207
219
  try {
208
- await sendTxCore.mutateAsync(props.tx);
220
+ const txData = await sendTxCore.mutateAsync(props.tx);
221
+ props.onTxSent(txData);
209
222
  setStatus("sent");
210
223
  } catch (e) {
224
+ // Do not reject the transaction here, because the user may want to try again
225
+ // we only reject on modal close
211
226
  console.error(e);
212
227
  setStatus("failed");
213
228
  }
214
- }, [sendTxCore, props.tx]);
229
+ }, [sendTxCore, props.tx, props.onTxSent]);
215
230
 
216
231
  const done = useRef(false);
217
232
  useEffect(() => {
@@ -292,6 +292,7 @@ function ConnectButtonInner(
292
292
  detailsButton={props.detailsButton}
293
293
  detailsModal={props.detailsModal}
294
294
  supportedTokens={supportedTokens}
295
+ supportedNFTs={props.supportedNFTs}
295
296
  onDisconnect={(info) => {
296
297
  // logout on explicit disconnect!
297
298
  if (siweAuth.requiresAuth) {
@@ -43,7 +43,10 @@ import {
43
43
  useChainName,
44
44
  } from "../../../core/hooks/others/useChainQuery.js";
45
45
  import { SetRootElementContext } from "../../../core/providers/RootElementContext.js";
46
- import type { SupportedTokens } from "../../../core/utils/defaultTokens.js";
46
+ import type {
47
+ SupportedNFTs,
48
+ SupportedTokens,
49
+ } from "../../../core/utils/defaultTokens.js";
47
50
  import { hasSmartAccount } from "../../../core/utils/isSmartWallet.js";
48
51
  import { useConnectedWalletDetails } from "../../../core/utils/wallet.js";
49
52
  import { useActiveAccount } from "../../hooks/wallets/useActiveAccount.js";
@@ -86,6 +89,8 @@ import { PrivateKey } from "./screens/PrivateKey.js";
86
89
  import { ReceiveFunds } from "./screens/ReceiveFunds.js";
87
90
  import { SendFunds } from "./screens/SendFunds.js";
88
91
  import { ViewFunds } from "./screens/ViewFunds.js";
92
+ import { ViewNFTs } from "./screens/ViewNFTs.js";
93
+ import { ViewTokens } from "./screens/ViewTokens.js";
89
94
  import { WalletConnectReceiverScreen } from "./screens/WalletConnectReceiverScreen.js";
90
95
  import type { WalletDetailsModalScreen } from "./screens/types.js";
91
96
 
@@ -105,6 +110,7 @@ export const ConnectedWalletDetails: React.FC<{
105
110
  detailsModal?: ConnectButton_detailsModalOptions;
106
111
  theme: "light" | "dark" | Theme;
107
112
  supportedTokens?: SupportedTokens;
113
+ supportedNFTs?: SupportedNFTs;
108
114
  chains: Chain[];
109
115
  chain?: Chain;
110
116
  switchButton: ConnectButtonProps["switchButton"];
@@ -139,6 +145,7 @@ export const ConnectedWalletDetails: React.FC<{
139
145
  detailsModal={props.detailsModal}
140
146
  theme={props.theme}
141
147
  supportedTokens={props.supportedTokens}
148
+ supportedNFTs={props.supportedNFTs}
142
149
  closeModal={closeModal}
143
150
  onDisconnect={props.onDisconnect}
144
151
  chains={props.chains}
@@ -238,6 +245,7 @@ function DetailsModal(props: {
238
245
  detailsModal?: ConnectButton_detailsModalOptions;
239
246
  theme: "light" | "dark" | Theme;
240
247
  supportedTokens?: SupportedTokens;
248
+ supportedNFTs?: SupportedNFTs;
241
249
  closeModal: () => void;
242
250
  onDisconnect: (info: {
243
251
  wallet: Wallet;
@@ -527,7 +535,9 @@ function DetailsModal(props: {
527
535
  }}
528
536
  >
529
537
  <CoinsIcon size={iconSize.md} />
530
- <Text color="primaryText">View Funds</Text>
538
+ <Text color="primaryText">
539
+ {props.supportedNFTs ? "View Assets" : "View Funds"}
540
+ </Text>
531
541
  </MenuButton>
532
542
 
533
543
  {/* Manage Wallet */}
@@ -682,8 +692,44 @@ function DetailsModal(props: {
682
692
  />
683
693
  );
684
694
  } else if (screen === "view-funds") {
695
+ if (props.supportedNFTs) {
696
+ content = (
697
+ <ViewFunds
698
+ supportedTokens={props.supportedTokens}
699
+ supportedNFTs={props.supportedNFTs}
700
+ onBack={() => {
701
+ setScreen("main");
702
+ }}
703
+ setScreen={setScreen}
704
+ client={client}
705
+ />
706
+ );
707
+ } else {
708
+ // Always show tokens (has the native token at least)
709
+ content = (
710
+ <ViewTokens
711
+ supportedTokens={props.supportedTokens}
712
+ onBack={() => {
713
+ setScreen("main");
714
+ }}
715
+ client={client}
716
+ />
717
+ );
718
+ }
719
+ } else if (screen === "view-nfts") {
685
720
  content = (
686
- <ViewFunds
721
+ <ViewNFTs
722
+ theme={props.theme}
723
+ supportedNFTs={props.supportedNFTs}
724
+ onBack={() => {
725
+ setScreen("main");
726
+ }}
727
+ client={client}
728
+ />
729
+ );
730
+ } else if (screen === "view-tokens") {
731
+ content = (
732
+ <ViewTokens
687
733
  supportedTokens={props.supportedTokens}
688
734
  onBack={() => {
689
735
  setScreen("main");
@@ -1082,6 +1128,32 @@ export type UseWalletDetailsModalOptions = {
1082
1128
  * ```
1083
1129
  */
1084
1130
  supportedTokens?: SupportedTokens;
1131
+ /**
1132
+ * Customize the NFTs shown in the "View Funds" screen in Details Modal for various networks.
1133
+ *
1134
+ * By default, The "View Funds" screen shows a few popular tokens for default chains and the native token. For other chains it only shows the native token.
1135
+ * @example
1136
+ *
1137
+ * supportedTokens prop allows you to customize this list as shown below which shows "Pudgy Penguins" when a users wallet is connected to Ethereum mainnet.
1138
+ *
1139
+ * ```tsx
1140
+ * import { ConnectButton } from 'thirdweb/react';
1141
+ *
1142
+ * function Example() {
1143
+ * return (
1144
+ * <ConnectButton
1145
+ * supportedNFTs={{
1146
+ * // when connected to Ethereum mainnet - show Pudgy Penguins
1147
+ * 1: [
1148
+ * '0xBd3531dA5CF5857e7CfAA92426877b022e612cf8',
1149
+ * ],
1150
+ * }}
1151
+ * />
1152
+ * );
1153
+ * }
1154
+ * ```
1155
+ */
1156
+ supportedNFTs?: SupportedNFTs;
1085
1157
  /**
1086
1158
  * By default - Details Modal UI uses the `en-US` locale for english language users.
1087
1159
  *
@@ -1240,6 +1312,7 @@ export function useWalletDetailsModal() {
1240
1312
  displayBalanceToken={props.displayBalanceToken}
1241
1313
  theme={props.theme || "dark"}
1242
1314
  supportedTokens={props.supportedTokens}
1315
+ supportedNFTs={props.supportedNFTs}
1243
1316
  closeModal={closeModal}
1244
1317
  onDisconnect={(info) => {
1245
1318
  props.onDisconnect?.(info);
@@ -0,0 +1,25 @@
1
+ import type { IconFC } from "./types.js";
2
+
3
+ /**
4
+ * @internal
5
+ */
6
+ export const ImageIcon: IconFC = (props) => {
7
+ return (
8
+ <svg
9
+ xmlns="http://www.w3.org/2000/svg"
10
+ width={props.size}
11
+ height={props.size}
12
+ viewBox="0 0 24 24"
13
+ fill="none"
14
+ stroke="currentColor"
15
+ strokeWidth="2"
16
+ strokeLinecap="round"
17
+ strokeLinejoin="round"
18
+ role="presentation"
19
+ >
20
+ <rect width="18" height="18" x="3" y="3" rx="2" ry="2" />
21
+ <circle cx="9" cy="9" r="2" />
22
+ <path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" />
23
+ </svg>
24
+ );
25
+ };
@@ -1,43 +1,27 @@
1
- import type { Chain } from "../../../../../chains/types.js";
2
1
  import type { ThirdwebClient } from "../../../../../client/client.js";
3
- import { fontSize } from "../../../../core/design-system/index.js";
4
- import { useWalletBalance } from "../../../../core/hooks/others/useWalletBalance.js";
5
- import {
6
- type SupportedTokens,
7
- defaultTokens,
2
+ import { fontSize, iconSize } from "../../../../core/design-system/index.js";
3
+ import type {
4
+ SupportedNFTs,
5
+ SupportedTokens,
8
6
  } from "../../../../core/utils/defaultTokens.js";
9
- import { useActiveAccount } from "../../../hooks/wallets/useActiveAccount.js";
10
- import { useActiveWalletChain } from "../../../hooks/wallets/useActiveWalletChain.js";
11
- import { Skeleton } from "../../components/Skeleton.js";
12
7
  import { Spacer } from "../../components/Spacer.js";
13
- import { TokenIcon } from "../../components/TokenIcon.js";
14
8
  import { Container, Line, ModalHeader } from "../../components/basic.js";
15
9
  import { Text } from "../../components/text.js";
16
- import { formatTokenBalance } from "./formatTokenBalance.js";
17
- import {
18
- type ERC20OrNativeToken,
19
- NATIVE_TOKEN,
20
- isNativeToken,
21
- } from "./nativeToken.js";
10
+ import { MenuButton } from "../MenuButton.js";
11
+ import { CoinsIcon } from "../icons/CoinsIcon.js";
12
+ import { ImageIcon } from "../icons/ImageIcon.js";
13
+ import type { WalletDetailsModalScreen } from "./types.js";
22
14
 
23
15
  /**
24
16
  * @internal
25
17
  */
26
18
  export function ViewFunds(props: {
27
19
  supportedTokens?: SupportedTokens;
20
+ supportedNFTs?: SupportedNFTs;
28
21
  onBack: () => void;
22
+ setScreen: (screen: WalletDetailsModalScreen) => void;
29
23
  client: ThirdwebClient;
30
24
  }) {
31
- const activeChain = useActiveWalletChain();
32
- const supportedTokens = props.supportedTokens || defaultTokens;
33
-
34
- if (!activeChain) {
35
- return null;
36
- }
37
-
38
- const tokenList =
39
- (activeChain?.id ? supportedTokens[activeChain.id] : undefined) || [];
40
-
41
25
  return (
42
26
  <Container
43
27
  style={{
@@ -57,69 +41,30 @@ export function ViewFunds(props: {
57
41
  >
58
42
  <Spacer y="md" />
59
43
 
60
- <TokenInfo
61
- token={NATIVE_TOKEN}
62
- chain={activeChain}
63
- client={props.client}
64
- />
65
-
66
- {tokenList.map((token) => {
67
- return (
68
- <TokenInfo
69
- token={token}
70
- key={token.address}
71
- chain={activeChain}
72
- client={props.client}
73
- />
74
- );
75
- })}
44
+ <MenuButton
45
+ onClick={() => {
46
+ props.setScreen("view-tokens");
47
+ }}
48
+ style={{
49
+ fontSize: fontSize.sm,
50
+ }}
51
+ >
52
+ <CoinsIcon size={iconSize.md} />
53
+ <Text color="primaryText">View Tokens</Text>
54
+ </MenuButton>
55
+ <MenuButton
56
+ onClick={() => {
57
+ props.setScreen("view-nfts");
58
+ }}
59
+ style={{
60
+ fontSize: fontSize.sm,
61
+ }}
62
+ >
63
+ <ImageIcon size={iconSize.md} />
64
+ <Text color="primaryText">View NFTs</Text>
65
+ </MenuButton>
76
66
  <Spacer y="lg" />
77
67
  </Container>
78
68
  </Container>
79
69
  );
80
70
  }
81
-
82
- function TokenInfo(props: {
83
- token: ERC20OrNativeToken;
84
- chain: Chain;
85
- client: ThirdwebClient;
86
- }) {
87
- const account = useActiveAccount();
88
- const tokenBalanceQuery = useWalletBalance({
89
- address: account?.address,
90
- chain: props.chain,
91
- tokenAddress: isNativeToken(props.token) ? undefined : props.token.address,
92
- client: props.client,
93
- });
94
-
95
- const tokenName = isNativeToken(props.token)
96
- ? tokenBalanceQuery.data?.name
97
- : props.token.name;
98
-
99
- return (
100
- <Container flex="row" gap="sm" p="sm">
101
- <TokenIcon
102
- token={props.token}
103
- chain={props.chain}
104
- size="lg"
105
- client={props.client}
106
- />
107
-
108
- <Container flex="column" gap="xxs">
109
- {tokenName ? (
110
- <Text size="sm" color="primaryText">
111
- {tokenName}
112
- </Text>
113
- ) : (
114
- <Skeleton height={fontSize.md} width="150px" />
115
- )}
116
-
117
- {tokenBalanceQuery.data ? (
118
- <Text size="xs"> {formatTokenBalance(tokenBalanceQuery.data)}</Text>
119
- ) : (
120
- <Skeleton height={fontSize.xs} width="100px" />
121
- )}
122
- </Container>
123
- </Container>
124
- );
125
- }