thirdweb 5.41.0 → 5.42.0

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 (180) hide show
  1. package/dist/cjs/adapters/wallet-adapter.js +12 -1
  2. package/dist/cjs/adapters/wallet-adapter.js.map +1 -1
  3. package/dist/cjs/client/client.js +19 -1
  4. package/dist/cjs/client/client.js.map +1 -1
  5. package/dist/cjs/exports/extensions/common.js +3 -1
  6. package/dist/cjs/exports/extensions/common.js.map +1 -1
  7. package/dist/cjs/exports/extensions/erc1155.js +2 -1
  8. package/dist/cjs/exports/extensions/erc1155.js.map +1 -1
  9. package/dist/cjs/exports/react.js +7 -2
  10. package/dist/cjs/exports/react.js.map +1 -1
  11. package/dist/cjs/exports/utils.js +3 -1
  12. package/dist/cjs/exports/utils.js.map +1 -1
  13. package/dist/cjs/exports/wallets/in-app.js.map +1 -1
  14. package/dist/cjs/exports/wallets.js.map +1 -1
  15. package/dist/cjs/exports/wallets.native.js.map +1 -1
  16. package/dist/cjs/react/core/hooks/others/useChainQuery.js +19 -3
  17. package/dist/cjs/react/core/hooks/others/useChainQuery.js.map +1 -1
  18. package/dist/cjs/react/core/hooks/transaction/transaction-button-utils.js.map +1 -1
  19. package/dist/cjs/react/web/ui/AutoConnect/AutoConnect.js +5 -0
  20. package/dist/cjs/react/web/ui/AutoConnect/AutoConnect.js.map +1 -1
  21. package/dist/cjs/react/web/ui/ConnectWallet/ConnectButton.js +196 -2
  22. package/dist/cjs/react/web/ui/ConnectWallet/ConnectButton.js.map +1 -1
  23. package/dist/cjs/react/web/ui/ConnectWallet/Modal/ConnectEmbed.js +109 -3
  24. package/dist/cjs/react/web/ui/ConnectWallet/Modal/ConnectEmbed.js.map +1 -1
  25. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/DirectPaymentModeScreen.js +1 -1
  26. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/DirectPaymentModeScreen.js.map +1 -1
  27. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js +1 -1
  28. package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js.map +1 -1
  29. package/dist/cjs/react/web/ui/prebuilt/thirdweb/BuyDirectListingButton/index.js +127 -0
  30. package/dist/cjs/react/web/ui/prebuilt/thirdweb/BuyDirectListingButton/index.js.map +1 -0
  31. package/dist/cjs/react/web/ui/prebuilt/thirdweb/ClaimButton/index.js +70 -3
  32. package/dist/cjs/react/web/ui/prebuilt/thirdweb/ClaimButton/index.js.map +1 -1
  33. package/dist/cjs/react/web/wallets/shared/ConnectWalletSocialOptions.js +19 -7
  34. package/dist/cjs/react/web/wallets/shared/ConnectWalletSocialOptions.js.map +1 -1
  35. package/dist/cjs/storage/download.js +44 -4
  36. package/dist/cjs/storage/download.js.map +1 -1
  37. package/dist/cjs/utils/contract/parse-abi-params.js +87 -0
  38. package/dist/cjs/utils/contract/parse-abi-params.js.map +1 -0
  39. package/dist/cjs/version.js +1 -1
  40. package/dist/cjs/wallets/create-wallet.js +73 -0
  41. package/dist/cjs/wallets/create-wallet.js.map +1 -1
  42. package/dist/cjs/wallets/in-app/core/wallet/index.js +2 -3
  43. package/dist/cjs/wallets/in-app/core/wallet/index.js.map +1 -1
  44. package/dist/cjs/wallets/in-app/web/ecosystem.js +29 -3
  45. package/dist/cjs/wallets/in-app/web/ecosystem.js.map +1 -1
  46. package/dist/cjs/wallets/in-app/web/in-app.js +100 -5
  47. package/dist/cjs/wallets/in-app/web/in-app.js.map +1 -1
  48. package/dist/cjs/wallets/smart/smart-wallet.js +71 -5
  49. package/dist/cjs/wallets/smart/smart-wallet.js.map +1 -1
  50. package/dist/esm/adapters/wallet-adapter.js +12 -1
  51. package/dist/esm/adapters/wallet-adapter.js.map +1 -1
  52. package/dist/esm/client/client.js +19 -1
  53. package/dist/esm/client/client.js.map +1 -1
  54. package/dist/esm/exports/extensions/common.js +1 -0
  55. package/dist/esm/exports/extensions/common.js.map +1 -1
  56. package/dist/esm/exports/extensions/erc1155.js +1 -1
  57. package/dist/esm/exports/extensions/erc1155.js.map +1 -1
  58. package/dist/esm/exports/react.js +3 -0
  59. package/dist/esm/exports/react.js.map +1 -1
  60. package/dist/esm/exports/utils.js +1 -0
  61. package/dist/esm/exports/utils.js.map +1 -1
  62. package/dist/esm/exports/wallets/in-app.js.map +1 -1
  63. package/dist/esm/exports/wallets.js.map +1 -1
  64. package/dist/esm/exports/wallets.native.js.map +1 -1
  65. package/dist/esm/react/core/hooks/others/useChainQuery.js +19 -3
  66. package/dist/esm/react/core/hooks/others/useChainQuery.js.map +1 -1
  67. package/dist/esm/react/core/hooks/transaction/transaction-button-utils.js.map +1 -1
  68. package/dist/esm/react/web/ui/AutoConnect/AutoConnect.js +5 -0
  69. package/dist/esm/react/web/ui/AutoConnect/AutoConnect.js.map +1 -1
  70. package/dist/esm/react/web/ui/ConnectWallet/ConnectButton.js +196 -2
  71. package/dist/esm/react/web/ui/ConnectWallet/ConnectButton.js.map +1 -1
  72. package/dist/esm/react/web/ui/ConnectWallet/Modal/ConnectEmbed.js +109 -3
  73. package/dist/esm/react/web/ui/ConnectWallet/Modal/ConnectEmbed.js.map +1 -1
  74. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/DirectPaymentModeScreen.js +2 -2
  75. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/DirectPaymentModeScreen.js.map +1 -1
  76. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js +2 -2
  77. package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js.map +1 -1
  78. package/dist/esm/react/web/ui/prebuilt/thirdweb/BuyDirectListingButton/index.js +124 -0
  79. package/dist/esm/react/web/ui/prebuilt/thirdweb/BuyDirectListingButton/index.js.map +1 -0
  80. package/dist/esm/react/web/ui/prebuilt/thirdweb/ClaimButton/index.js +69 -3
  81. package/dist/esm/react/web/ui/prebuilt/thirdweb/ClaimButton/index.js.map +1 -1
  82. package/dist/esm/react/web/wallets/shared/ConnectWalletSocialOptions.js +19 -7
  83. package/dist/esm/react/web/wallets/shared/ConnectWalletSocialOptions.js.map +1 -1
  84. package/dist/esm/storage/download.js +44 -4
  85. package/dist/esm/storage/download.js.map +1 -1
  86. package/dist/esm/utils/contract/parse-abi-params.js +84 -0
  87. package/dist/esm/utils/contract/parse-abi-params.js.map +1 -0
  88. package/dist/esm/version.js +1 -1
  89. package/dist/esm/wallets/create-wallet.js +73 -0
  90. package/dist/esm/wallets/create-wallet.js.map +1 -1
  91. package/dist/esm/wallets/in-app/core/wallet/index.js +2 -3
  92. package/dist/esm/wallets/in-app/core/wallet/index.js.map +1 -1
  93. package/dist/esm/wallets/in-app/web/ecosystem.js +29 -3
  94. package/dist/esm/wallets/in-app/web/ecosystem.js.map +1 -1
  95. package/dist/esm/wallets/in-app/web/in-app.js +100 -5
  96. package/dist/esm/wallets/in-app/web/in-app.js.map +1 -1
  97. package/dist/esm/wallets/smart/smart-wallet.js +71 -5
  98. package/dist/esm/wallets/smart/smart-wallet.js.map +1 -1
  99. package/dist/types/adapters/wallet-adapter.d.ts +12 -1
  100. package/dist/types/adapters/wallet-adapter.d.ts.map +1 -1
  101. package/dist/types/client/client.d.ts +19 -1
  102. package/dist/types/client/client.d.ts.map +1 -1
  103. package/dist/types/exports/extensions/common.d.ts +1 -0
  104. package/dist/types/exports/extensions/common.d.ts.map +1 -1
  105. package/dist/types/exports/extensions/erc1155.d.ts +1 -1
  106. package/dist/types/exports/extensions/erc1155.d.ts.map +1 -1
  107. package/dist/types/exports/react.d.ts +2 -0
  108. package/dist/types/exports/react.d.ts.map +1 -1
  109. package/dist/types/exports/utils.d.ts +2 -0
  110. package/dist/types/exports/utils.d.ts.map +1 -1
  111. package/dist/types/exports/wallets/in-app.d.ts +1 -0
  112. package/dist/types/exports/wallets/in-app.d.ts.map +1 -1
  113. package/dist/types/exports/wallets.d.ts +4 -2
  114. package/dist/types/exports/wallets.d.ts.map +1 -1
  115. package/dist/types/exports/wallets.native.d.ts +3 -2
  116. package/dist/types/exports/wallets.native.d.ts.map +1 -1
  117. package/dist/types/react/core/hooks/others/useChainQuery.d.ts +21 -4
  118. package/dist/types/react/core/hooks/others/useChainQuery.d.ts.map +1 -1
  119. package/dist/types/react/core/hooks/transaction/transaction-button-utils.d.ts +1 -0
  120. package/dist/types/react/core/hooks/transaction/transaction-button-utils.d.ts.map +1 -1
  121. package/dist/types/react/web/ui/AutoConnect/AutoConnect.d.ts +5 -0
  122. package/dist/types/react/web/ui/AutoConnect/AutoConnect.d.ts.map +1 -1
  123. package/dist/types/react/web/ui/ConnectWallet/ConnectButton.d.ts +196 -2
  124. package/dist/types/react/web/ui/ConnectWallet/ConnectButton.d.ts.map +1 -1
  125. package/dist/types/react/web/ui/ConnectWallet/Modal/ConnectEmbed.d.ts +109 -3
  126. package/dist/types/react/web/ui/ConnectWallet/Modal/ConnectEmbed.d.ts.map +1 -1
  127. package/dist/types/react/web/ui/PayEmbed.d.ts +1 -1
  128. package/dist/types/react/web/ui/prebuilt/thirdweb/BuyDirectListingButton/index.d.ts +63 -0
  129. package/dist/types/react/web/ui/prebuilt/thirdweb/BuyDirectListingButton/index.d.ts.map +1 -0
  130. package/dist/types/react/web/ui/prebuilt/thirdweb/ClaimButton/index.d.ts +21 -0
  131. package/dist/types/react/web/ui/prebuilt/thirdweb/ClaimButton/index.d.ts.map +1 -1
  132. package/dist/types/react/web/wallets/shared/ConnectWalletSocialOptions.d.ts.map +1 -1
  133. package/dist/types/storage/download.d.ts +43 -3
  134. package/dist/types/storage/download.d.ts.map +1 -1
  135. package/dist/types/utils/contract/parse-abi-params.d.ts +29 -0
  136. package/dist/types/utils/contract/parse-abi-params.d.ts.map +1 -0
  137. package/dist/types/version.d.ts +1 -1
  138. package/dist/types/wallets/create-wallet.d.ts +73 -0
  139. package/dist/types/wallets/create-wallet.d.ts.map +1 -1
  140. package/dist/types/wallets/ecosystem/types.d.ts +5 -4
  141. package/dist/types/wallets/ecosystem/types.d.ts.map +1 -1
  142. package/dist/types/wallets/in-app/core/wallet/index.d.ts.map +1 -1
  143. package/dist/types/wallets/in-app/web/ecosystem.d.ts +29 -3
  144. package/dist/types/wallets/in-app/web/ecosystem.d.ts.map +1 -1
  145. package/dist/types/wallets/in-app/web/in-app.d.ts +100 -5
  146. package/dist/types/wallets/in-app/web/in-app.d.ts.map +1 -1
  147. package/dist/types/wallets/smart/smart-wallet.d.ts +71 -5
  148. package/dist/types/wallets/smart/smart-wallet.d.ts.map +1 -1
  149. package/package.json +1 -1
  150. package/src/adapters/wallet-adapter.ts +12 -1
  151. package/src/client/client.ts +19 -1
  152. package/src/exports/extensions/common.ts +5 -0
  153. package/src/exports/extensions/erc1155.ts +1 -0
  154. package/src/exports/react.ts +7 -0
  155. package/src/exports/utils.ts +3 -0
  156. package/src/exports/wallets/in-app.ts +6 -0
  157. package/src/exports/wallets.native.ts +8 -1
  158. package/src/exports/wallets.ts +13 -1
  159. package/src/react/core/hooks/others/useChainQuery.ts +24 -4
  160. package/src/react/core/hooks/transaction/transaction-button-utils.ts +1 -0
  161. package/src/react/web/ui/AutoConnect/AutoConnect.tsx +5 -0
  162. package/src/react/web/ui/ConnectWallet/ConnectButton.tsx +196 -2
  163. package/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx +109 -3
  164. package/src/react/web/ui/ConnectWallet/screens/Buy/DirectPaymentModeScreen.tsx +2 -2
  165. package/src/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.tsx +2 -2
  166. package/src/react/web/ui/PayEmbed.tsx +1 -1
  167. package/src/react/web/ui/prebuilt/thirdweb/BuyDirectListingButton/BuyDirectListingButton.test.tsx +27 -0
  168. package/src/react/web/ui/prebuilt/thirdweb/BuyDirectListingButton/index.tsx +200 -0
  169. package/src/react/web/ui/prebuilt/thirdweb/ClaimButton/index.tsx +78 -5
  170. package/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx +19 -8
  171. package/src/storage/download.ts +47 -4
  172. package/src/utils/contract/parse-abi-params.test.ts +160 -0
  173. package/src/utils/contract/parse-abi-params.ts +90 -0
  174. package/src/version.ts +1 -1
  175. package/src/wallets/create-wallet.ts +73 -0
  176. package/src/wallets/ecosystem/types.ts +9 -5
  177. package/src/wallets/in-app/core/wallet/index.ts +2 -3
  178. package/src/wallets/in-app/web/ecosystem.ts +29 -3
  179. package/src/wallets/in-app/web/in-app.ts +100 -5
  180. package/src/wallets/smart/smart-wallet.ts +71 -5
@@ -4,8 +4,13 @@ import {
4
4
  type ThirdwebContract,
5
5
  getContract,
6
6
  } from "../../../../../../contract/contract.js";
7
+ import { getContractMetadata } from "../../../../../../extensions/common/read/getContractMetadata.js";
8
+ import { getNFT } from "../../../../../../extensions/erc1155/read/getNFT.js";
7
9
  import type { PreparedTransaction } from "../../../../../../transaction/prepare-transaction.js";
10
+ import type { BaseTransactionOptions } from "../../../../../../transaction/types.js";
8
11
  import type { Account } from "../../../../../../wallets/interfaces/wallet.js";
12
+ import { useReadContract } from "../../../../../core/hooks/contract/useReadContract.js";
13
+ import { useSendAndConfirmTransaction } from "../../../../../core/hooks/transaction/useSendAndConfirmTransaction.js";
9
14
  import { useActiveAccount } from "../../../../../core/hooks/wallets/useActiveAccount.js";
10
15
  import { TransactionButton } from "../../../TransactionButton/index.js";
11
16
  import type {
@@ -28,6 +33,7 @@ import type {
28
33
  * @param props
29
34
  * @returns A wrapper for TransactionButton
30
35
  *
36
+ * @component
31
37
  * @example
32
38
  *
33
39
  * ```tsx
@@ -77,22 +83,66 @@ import type {
77
83
  * Claim now
78
84
  * </ClaimButton>
79
85
  *
86
+ * // Attach custom Pay metadata
87
+ * <ClaimButton
88
+ * payModal={{
89
+ * metadata: {
90
+ * name: "Van Gogh Starry Night",
91
+ * image: "https://unsplash.com/starry-night.png"
92
+ * }
93
+ * }}
94
+ * >...</ClaimButton>
95
+ *
80
96
  * ```
81
97
  */
82
98
  export function ClaimButton(props: ClaimButtonProps) {
83
- const { children, contractAddress, client, chain, claimParams } = props;
99
+ const { children, contractAddress, client, chain, claimParams, payModal } =
100
+ props;
101
+ const defaultPayModalMetadata = payModal ? payModal.metadata : undefined;
84
102
  const contract = getContract({
85
103
  address: contractAddress,
86
104
  client,
87
105
  chain,
88
106
  });
107
+
108
+ const { data: payMetadata } = useReadContract(getPayMetadata, {
109
+ contract,
110
+ tokenId: claimParams.type === "ERC1155" ? claimParams.tokenId : undefined,
111
+ queryOptions: {
112
+ enabled: !defaultPayModalMetadata,
113
+ },
114
+ });
89
115
  const account = useActiveAccount();
90
- // TODO (pay): fetch nft metadata and set it as the payOptions metadata
116
+ const { mutateAsync } = useSendAndConfirmTransaction();
91
117
  return (
92
118
  <TransactionButton
93
- transaction={async () =>
94
- await getClaimTransaction({ contract, account, claimParams })
95
- }
119
+ payModal={{
120
+ metadata: defaultPayModalMetadata || payMetadata,
121
+ ...payModal,
122
+ }}
123
+ transaction={async () => {
124
+ if (!account) {
125
+ throw new Error("No account detected");
126
+ }
127
+ const [claimTx, { getApprovalForTransaction }] = await Promise.all([
128
+ getClaimTransaction({
129
+ contract,
130
+ account,
131
+ claimParams,
132
+ }),
133
+ import(
134
+ "../../../../../../extensions/erc20/write/getApprovalForTransaction.js"
135
+ ),
136
+ ]);
137
+ const approveTx = await getApprovalForTransaction({
138
+ transaction: claimTx,
139
+ account,
140
+ });
141
+ if (approveTx) {
142
+ await mutateAsync(approveTx);
143
+ }
144
+ return claimTx;
145
+ }}
96
146
  {...props}
97
147
  >
98
148
  {children}
@@ -100,6 +150,29 @@ export function ClaimButton(props: ClaimButtonProps) {
100
150
  );
101
151
  }
102
152
 
153
+ /**
154
+ * @internal
155
+ */
156
+ export async function getPayMetadata(
157
+ options: BaseTransactionOptions<{ tokenId?: bigint }>,
158
+ ): Promise<{ name?: string; image?: string }> {
159
+ const { contract, tokenId } = options;
160
+ const [contractMetadata, nft] = await Promise.all([
161
+ getContractMetadata(options),
162
+ tokenId ? getNFT({ contract, tokenId }) : undefined,
163
+ ]);
164
+ if (tokenId) {
165
+ return {
166
+ image: nft?.metadata?.image,
167
+ name: nft?.metadata?.name,
168
+ };
169
+ }
170
+ return {
171
+ image: contractMetadata?.image,
172
+ name: contractMetadata?.name,
173
+ };
174
+ }
175
+
103
176
  /**
104
177
  * @internal Export for test
105
178
  */
@@ -234,7 +234,7 @@ export const ConnectWalletSocialOptions = (
234
234
  props.select();
235
235
  }
236
236
 
237
- const showOnlyIcons = socialLogins.length > 1;
237
+ const showOnlyIcons = socialLogins.length > 2;
238
238
 
239
239
  return (
240
240
  <Container
@@ -247,22 +247,33 @@ export const ConnectWalletSocialOptions = (
247
247
  {/* Social Login */}
248
248
  {hasSocialLogins && (
249
249
  <Container
250
- flex={showOnlyIcons ? "row" : "column"}
250
+ flex="row"
251
251
  center="x"
252
- gap="sm"
252
+ gap={socialLogins.length > 4 ? "xs" : "sm"}
253
253
  style={{
254
254
  justifyContent: "space-between",
255
+ display: "grid",
256
+ gridTemplateColumns: `repeat(${socialLogins.length}, 1fr)`,
255
257
  }}
256
258
  >
257
259
  {socialLogins.map((loginMethod) => {
258
- const imgIconSize = showOnlyIcons ? iconSize.lg : iconSize.md;
260
+ const imgIconSize = (() => {
261
+ if (!showOnlyIcons) {
262
+ return iconSize.md;
263
+ } else {
264
+ if (socialLogins.length > 4) {
265
+ return iconSize.md;
266
+ }
267
+ return iconSize.lg;
268
+ }
269
+ })();
270
+
259
271
  return (
260
272
  <SocialButton
261
273
  aria-label={`Login with ${loginMethod}`}
262
274
  data-variant={showOnlyIcons ? "icon" : "full"}
263
275
  key={loginMethod}
264
276
  variant={"outline"}
265
- fullWidth={!showOnlyIcons}
266
277
  onClick={() => {
267
278
  handleSocialLogin(loginMethod as SocialAuthOption);
268
279
  }}
@@ -274,7 +285,7 @@ export const ConnectWalletSocialOptions = (
274
285
  client={props.client}
275
286
  />
276
287
  {!showOnlyIcons &&
277
- loginMethodsLabel[loginMethod as SocialAuthOption]}
288
+ `${socialLogins.length === 1 ? "Continue with " : ""}${loginMethodsLabel[loginMethod as SocialAuthOption]}`}
278
289
  </SocialButton>
279
290
  );
280
291
  })}
@@ -379,11 +390,12 @@ export const ConnectWalletSocialOptions = (
379
390
  };
380
391
 
381
392
  const SocialButton = /* @__PURE__ */ styled(Button)({
393
+ flexGrow: 1,
382
394
  "&[data-variant='full']": {
383
395
  display: "flex",
384
396
  justifyContent: "flex-start",
385
397
  padding: spacing.md,
386
- gap: spacing.md,
398
+ gap: spacing.sm,
387
399
  fontSize: fontSize.md,
388
400
  fontWeight: 500,
389
401
  transition: "background-color 0.2s ease",
@@ -393,6 +405,5 @@ const SocialButton = /* @__PURE__ */ styled(Button)({
393
405
  },
394
406
  "&[data-variant='icon']": {
395
407
  padding: spacing.sm,
396
- flexGrow: 1,
397
408
  },
398
409
  });
@@ -9,18 +9,58 @@ export type DownloadOptions = Prettify<
9
9
  >;
10
10
 
11
11
  /**
12
- * Downloads a file from the specified URI.
12
+ * @description Downloads a file from the specified IPFS, Arweave, or HTTP URI.
13
+ *
14
+ * `download` will parse the provided URI based on its scheme (ipfs://, ar://, https://) and convert it to a URL to fetch the file from thirdweb's storage service.
15
+ *
13
16
  * @param options - The download options.
14
- * @returns A Promise that resolves to the downloaded file.
15
- * @throws An error if the URI scheme is invalid.
17
+ * @param options.client - The Thirdweb client. See [createThirdwebClient](https://portal.thirdweb.com/references/typescript/v5/createThirdwebClient).
18
+ * @param options.uri - The URI of the file to download. Can be IPFS, Arweave, or HTTP.
19
+ * @param [options.requestTimeoutMs] - The maximum time in milliseconds to wait for the request to complete. Defaults to 60 seconds (60,000 milliseconds).
20
+ *
21
+ * @returns Asynchronously returns the network response from fetching the file.
22
+ * @throws An error if the URI scheme is invalid or if the request fails.
23
+ *
16
24
  * @example
25
+ * Download a file from IPFS:
17
26
  * ```ts
18
27
  * import { download } from "thirdweb/storage";
28
+ * import { createThirdwebClient } from "@thirdweb-dev/sdk";
29
+ *
30
+ * const client = createThirdwebClient({ clientId: "YOUR_CLIENT_ID" });
31
+ *
19
32
  * const file = await download({
20
33
  * client,
21
34
  * uri: "ipfs://Qm...",
22
35
  * });
23
36
  * ```
37
+ *
38
+ * Download a file from Arweave:
39
+ * ```ts
40
+ * import { download } from "thirdweb/storage";
41
+ * import { createThirdwebClient } from "@thirdweb-dev/sdk";
42
+ *
43
+ * const client = createThirdwebClient({ clientId: "YOUR_CLIENT_ID" });
44
+ *
45
+ * const file = await download({
46
+ * client,
47
+ * uri: "ar://{arweave-transaction-id}",
48
+ * });
49
+ * ```
50
+ *
51
+ * Download a file from HTTP:
52
+ * ```ts
53
+ * import { download } from "thirdweb/storage";
54
+ * import { createThirdwebClient } from "@thirdweb-dev/sdk";
55
+ *
56
+ * const client = createThirdwebClient({ clientId: "YOUR_CLIENT_ID" });
57
+ *
58
+ * const file = await download({
59
+ * client,
60
+ * uri: "https://example.com/file.txt",
61
+ * });
62
+ * ```
63
+ *
24
64
  * @storage
25
65
  */
26
66
  export async function download(options: DownloadOptions) {
@@ -31,11 +71,14 @@ export async function download(options: DownloadOptions) {
31
71
  } else {
32
72
  url = resolveScheme(options);
33
73
  }
74
+
34
75
  const res = await getClientFetch(options.client)(url, {
35
76
  keepalive: options.client.config?.storage?.fetch?.keepalive,
36
77
  headers: options.client.config?.storage?.fetch?.headers,
37
- requestTimeoutMs: options.client.config?.storage?.fetch?.requestTimeoutMs,
78
+ requestTimeoutMs:
79
+ options.client.config?.storage?.fetch?.requestTimeoutMs ?? 60000,
38
80
  });
81
+
39
82
  if (!res.ok) {
40
83
  res.body?.cancel();
41
84
  throw new Error(`Failed to download file: ${res.statusText}`);
@@ -0,0 +1,160 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { toHex } from "../encoding/hex.js";
3
+ import { parseAbiParams } from "./parse-abi-params.js";
4
+
5
+ describe("parseAbiParams", () => {
6
+ describe("parseAbiParams", () => {
7
+ it("should convert address and uint256 correctly", () => {
8
+ const types = ["address", "uint256"];
9
+ const values = ["0x1234567890abcdef1234567890abcdef12345678", "1200000"];
10
+ const expected = [
11
+ "0x1234567890abcdef1234567890abcdef12345678",
12
+ BigInt(1200000),
13
+ ];
14
+ expect(parseAbiParams(types, values)).toEqual(expected);
15
+ });
16
+
17
+ it("should convert address and bool correctly", () => {
18
+ const types = ["address", "bool"];
19
+ const values = ["0x1234567890abcdef1234567890abcdef12345678", "true"];
20
+ const expected = ["0x1234567890abcdef1234567890abcdef12345678", true];
21
+ expect(parseAbiParams(types, values)).toEqual(expected);
22
+ });
23
+
24
+ it("should convert bytes32 correctly", () => {
25
+ const types = ["bytes32"];
26
+ const values = [
27
+ "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
28
+ ];
29
+ const expected = [
30
+ "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
31
+ ];
32
+ expect(parseAbiParams(types, values)).toEqual(expected);
33
+ });
34
+
35
+ it("should throw an error for invalid hex in bytes32", () => {
36
+ const types = ["bytes32"];
37
+ const values = ["invalidHex"];
38
+ expect(() => parseAbiParams(types, values)).toThrowError(
39
+ "invalidHex is not a valid hex string",
40
+ );
41
+ });
42
+
43
+ it("should convert uint256 correctly", () => {
44
+ const types = ["uint256"];
45
+ const values = ["1200000"];
46
+ const expected = [BigInt(1200000)];
47
+ expect(parseAbiParams(types, values)).toEqual(expected);
48
+ });
49
+
50
+ it("should throw an error for invalid address", () => {
51
+ const types = ["address"];
52
+ const values = ["invalidAddress"];
53
+ expect(() => parseAbiParams(types, values)).toThrowError(
54
+ "invalidAddress is not a valid address",
55
+ );
56
+ });
57
+
58
+ it("should throw an error for mismatched number of types and values", () => {
59
+ const types = ["address", "uint256"];
60
+ const values = ["0x1234567890abcdef1234567890abcdef12345678"];
61
+ expect(() => parseAbiParams(types, values)).toThrowError(
62
+ "Passed the wrong number of constructor arguments: 1, expected 2",
63
+ );
64
+ });
65
+
66
+ it("should convert tuple correctly", () => {
67
+ const types = ["tuple"];
68
+ const values = [
69
+ '["0x1234567890abcdef1234567890abcdef12345678", "1200000"]',
70
+ ];
71
+ const expected = [
72
+ ["0x1234567890abcdef1234567890abcdef12345678", "1200000"],
73
+ ];
74
+ expect(parseAbiParams(types, values)).toEqual(expected);
75
+ });
76
+
77
+ it("should convert array of addresses correctly", () => {
78
+ const types = ["address[]"];
79
+ const values = [
80
+ '["0x1234567890abcdef1234567890abcdef12345678", "0xabcdef1234567890abcdef1234567890abcdef12"]',
81
+ ];
82
+ const expected = [
83
+ [
84
+ "0x1234567890abcdef1234567890abcdef12345678",
85
+ "0xabcdef1234567890abcdef1234567890abcdef12",
86
+ ],
87
+ ];
88
+ expect(parseAbiParams(types, values)).toEqual(expected);
89
+ });
90
+
91
+ it('should convert boolean correctly for "true"', () => {
92
+ const types = ["bool"];
93
+ const values = ["true"];
94
+ const expected = [true];
95
+ expect(parseAbiParams(types, values)).toEqual(expected);
96
+ });
97
+
98
+ it('should convert boolean correctly for "false"', () => {
99
+ const types = ["bool"];
100
+ const values = ["false"];
101
+ const expected = [false];
102
+ expect(parseAbiParams(types, values)).toEqual(expected);
103
+ });
104
+
105
+ it("should convert boolean correctly for boolean true", () => {
106
+ const types = ["bool"];
107
+ const values = [true];
108
+ const expected = [true];
109
+ expect(parseAbiParams(types, values)).toEqual(expected);
110
+ });
111
+
112
+ it("should convert boolean correctly for boolean false", () => {
113
+ const types = ["bool"];
114
+ const values = [false];
115
+ const expected = [false];
116
+ expect(parseAbiParams(types, values)).toEqual(expected);
117
+ });
118
+
119
+ it("should throw an error for invalid boolean value", () => {
120
+ const types = ["bool"];
121
+ const values = ["notBoolean"];
122
+ expect(() => parseAbiParams(types, values)).toThrowError(
123
+ "Invalid boolean value. Expecting either 'true' or 'false'",
124
+ );
125
+ });
126
+
127
+ it("should just return the value if already json-parsed", () => {
128
+ const types = ["tuple"];
129
+ const values = [{ cat: "orange" }];
130
+ expect(parseAbiParams(types, values)).toEqual(values);
131
+ });
132
+
133
+ it("should throw error if not a hex string", () => {
134
+ const values = ["orange cat"];
135
+ expect(() => parseAbiParams(["bytes64"], values)).toThrowError(
136
+ "orange cat is not a valid hex string",
137
+ );
138
+
139
+ expect(() => parseAbiParams(["bytes32"], values)).toThrowError(
140
+ "orange cat is not a valid hex string",
141
+ );
142
+ });
143
+
144
+ it("should throw error if cannot convert to BigInt", () => {
145
+ expect(() => parseAbiParams(["uint256"], [true])).toThrowError(
146
+ "Cannot convert type boolean to BigInt",
147
+ );
148
+
149
+ expect(() => parseAbiParams(["uint256"], ["cat"])).toThrowError(
150
+ "Cannot convert cat to a BigInt",
151
+ );
152
+ });
153
+
154
+ it("should return value unaltered if already a hex", () => {
155
+ const value = toHex("cat");
156
+ const result = parseAbiParams(["bytes64"], [value]);
157
+ expect(result).toStrictEqual([value]);
158
+ });
159
+ });
160
+ });
@@ -0,0 +1,90 @@
1
+ import { isAddress } from "../address.js";
2
+ import { isHex, padHex } from "../encoding/hex.js";
3
+
4
+ /**
5
+ * Converts an array of parameter values to their respective types based on the provided type array.
6
+ *
7
+ * This utility function is particularly useful for ensuring that parameter values are correctly formatted
8
+ * according to the expected types before they are used in further processing or passed to a Solidity smart contract.
9
+ *
10
+ * @param {string[]} constructorParamTypes - An array of type strings indicating the expected types of the values,
11
+ * following Solidity type conventions (e.g., "address", "uint256", "bool").
12
+ * @param {unknown[]} constructorParamValues - An array of values to be converted according to the types.
13
+ * @returns - An array of values converted to their respective types.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { parseAbiParams } from "thirdweb/utils";
18
+ *
19
+ * const example1 = parseAbiParams(
20
+ * ["address", "uint256"],
21
+ * ["0x.....", "1200000"]
22
+ * ); // result: ["0x......", 1200000n]
23
+ *
24
+ * const example2 = parseAbiParams(
25
+ * ["address", "bool"],
26
+ * ["0x.....", "true"]
27
+ * ); // result: ["0x......", true]
28
+ * ```
29
+ * @utils
30
+ */
31
+ export function parseAbiParams(
32
+ constructorParamTypes: string[],
33
+ constructorParamValues: unknown[],
34
+ ): Array<string | bigint | boolean> {
35
+ // Make sure they have the same length
36
+ if (constructorParamTypes.length !== constructorParamValues.length) {
37
+ throw new Error(
38
+ `Passed the wrong number of constructor arguments: ${constructorParamValues.length}, expected ${constructorParamTypes.length}`,
39
+ );
40
+ }
41
+ return constructorParamTypes.map((type, index) => {
42
+ const value = constructorParamValues[index];
43
+ if (type === "tuple" || type.endsWith("[]")) {
44
+ if (typeof value === "string") {
45
+ return JSON.parse(value);
46
+ }
47
+ return value;
48
+ }
49
+ if (type === "bytes32") {
50
+ if (!isHex(value)) {
51
+ throw new Error(`${value} is not a valid hex string`);
52
+ }
53
+ return padHex(value);
54
+ }
55
+ if (type.startsWith("bytes")) {
56
+ if (!isHex(value)) {
57
+ throw new Error(`${value} is not a valid hex string`);
58
+ }
59
+ return value;
60
+ }
61
+ if (type === "address") {
62
+ if (typeof value !== "string" || !isAddress(value)) {
63
+ throw new Error(`${value} is not a valid address`);
64
+ }
65
+ return value;
66
+ }
67
+ if (type.startsWith("uint") || type.startsWith("int")) {
68
+ if (typeof value !== "string" && typeof value !== "number") {
69
+ throw new Error(`Cannot convert type ${typeof value} to BigInt`);
70
+ }
71
+ try {
72
+ const val = BigInt(value);
73
+ return val;
74
+ } catch (err) {
75
+ throw new Error((err as Error).message);
76
+ }
77
+ }
78
+ if (type.startsWith("bool")) {
79
+ if (value === "false" || value === false) {
80
+ return false;
81
+ }
82
+ if (value === "true" || value === true) {
83
+ return true;
84
+ }
85
+ throw new Error(
86
+ "Invalid boolean value. Expecting either 'true' or 'false'",
87
+ );
88
+ }
89
+ });
90
+ }
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = "5.41.0";
1
+ export const version = "5.42.0";
@@ -30,9 +30,31 @@ import { createWalletEmitter } from "./wallet-emitter.js";
30
30
 
31
31
  /**
32
32
  * Creates a wallet based on the provided ID and arguments.
33
+ *
34
+ * - Supports 350+ wallets
35
+ * - Handles both injected browser wallets and WalletConnect sessions
36
+ *
37
+ * [View all available wallets](https://portal.thirdweb.com/typescript/v5/supported-wallets)
38
+ *
33
39
  * @param args - The arguments for creating the wallet.
40
+ * @param args.id - The ID of the wallet to create, this will be autocompleted by your IDE.
41
+ * [View all available wallets](https://portal.thirdweb.com/typescript/v5/supported-wallets)
42
+ * @param args.createOptions - The options for creating the wallet.
43
+ * The arguments are different for each wallet type.
44
+ * Refer to the [WalletCreationOptions](https://portal.thirdweb.com/references/typescript/v5/WalletCreationOptions) type for more details.
34
45
  * @returns - The created wallet.
35
46
  * @example
47
+ *
48
+ * ## Connecting the wallet
49
+ *
50
+ * Once created, you can connect the wallet to your app by calling the `connect` method.
51
+ *
52
+ * The `connect` method returns a promise that resolves to the connected account.
53
+ *
54
+ * Each wallet type can have different connect options. [View the different connect options](https://portal.thirdweb.com/references/typescript/v5/WalletConnectionOption)
55
+ *
56
+ * ## Connecting to an injected wallet
57
+ *
36
58
  * ```ts
37
59
  * import { createWallet } from "thirdweb/wallets";
38
60
  *
@@ -42,6 +64,57 @@ import { createWalletEmitter } from "./wallet-emitter.js";
42
64
  * client,
43
65
  * });
44
66
  * ```
67
+ *
68
+ * You can check if a wallet is installed by calling the [injectedProvider](https://portal.thirdweb.com/references/typescript/v5/injectedProvider) method.
69
+ *
70
+ * ## Connecting via WalletConnect modal
71
+ *
72
+ * ```ts
73
+ * import { createWallet } from "thirdweb/wallets";
74
+ *
75
+ * const metamaskWallet = createWallet("io.metamask");
76
+ *
77
+ * await metamask.connect({
78
+ * client,
79
+ * walletConnect: {
80
+ * projectId: "YOUR_PROJECT_ID",
81
+ * showQrModal: true,
82
+ * appMetadata: {
83
+ * name: "My App",
84
+ * url: "https://my-app.com",
85
+ * description: "my app description",
86
+ * logoUrl: "https://path/to/my-app/logo.svg",
87
+ * },
88
+ * },
89
+ * });
90
+ * ```
91
+ * [View ConnectWallet connection options](https://portal.thirdweb.com/references/typescript/v5/WCConnectOptions)
92
+ *
93
+ * ## Connecting with coinbase wallet
94
+ *
95
+ * ```ts
96
+ * import { createWallet } from "thirdweb/wallets";
97
+ *
98
+ * const cbWallet = createWallet("com.coinbase.wallet", {
99
+ * appMetadata: {
100
+ * name: "My App",
101
+ * url: "https://my-app.com",
102
+ * description: "my app description",
103
+ * logoUrl: "https://path/to/my-app/logo.svg",
104
+ * },
105
+ * walletConfig: {
106
+ * // options: 'all' | 'smartWalletOnly' | 'eoaOnly'
107
+ * options: 'all',
108
+ * },
109
+ * });
110
+ *
111
+ * const account = await cbWallet.connect({
112
+ * client,
113
+ * });
114
+ * ```
115
+ *
116
+ * [View Coinbase wallet creation options](https://portal.thirdweb.com/references/typescript/v5/CoinbaseWalletCreationOptions)
117
+ *
45
118
  * @wallet
46
119
  */
47
120
  export function createWallet<const ID extends WalletId>(
@@ -1,3 +1,4 @@
1
+ import type { Prettify } from "../../utils/type-utils.js";
1
2
  import type {
2
3
  InAppWalletAutoConnectOptions,
3
4
  InAppWalletConnectionOptions,
@@ -11,8 +12,11 @@ export type EcosystemWalletCreationOptions = {
11
12
  };
12
13
  };
13
14
 
14
- export type EcosystemWalletConnectionOptions = InAppWalletConnectionOptions & {
15
- ecosystem: Ecosystem;
16
- };
17
- export type EcosystemWalletAutoConnectOptions =
18
- InAppWalletAutoConnectOptions & { ecosystem: Ecosystem };
15
+ export type EcosystemWalletConnectionOptions = Prettify<
16
+ InAppWalletConnectionOptions & {
17
+ ecosystem: Ecosystem;
18
+ }
19
+ >;
20
+ export type EcosystemWalletAutoConnectOptions = Prettify<
21
+ InAppWalletAutoConnectOptions & { ecosystem: Ecosystem }
22
+ >;
@@ -44,10 +44,9 @@ export async function connectInAppWallet(
44
44
  connector.authenticateWithRedirect
45
45
  ) {
46
46
  const strategy = options.strategy;
47
- if (!socialAuthOptions.includes(strategy as SocialAuthOption)) {
48
- throw new Error("This authentication method does not support redirects");
47
+ if (socialAuthOptions.includes(strategy as SocialAuthOption)) {
48
+ connector.authenticateWithRedirect(strategy as SocialAuthOption);
49
49
  }
50
- connector.authenticateWithRedirect(strategy as SocialAuthOption);
51
50
  }
52
51
  // If we don't have authenticateWithRedirect then it's likely react native, so the default is to redirect and we can carry on
53
52
  // IF WE EVER ADD MORE CONNECTOR TYPES, this could cause redirect to be ignored despite being specified