thirdweb 5.121.2 → 5.121.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/dist/cjs/insight/get-nfts.js +2 -2
  2. package/dist/cjs/insight/get-nfts.js.map +1 -1
  3. package/dist/cjs/react/core/hooks/x402/useFetchWithPaymentCore.js +1 -0
  4. package/dist/cjs/react/core/hooks/x402/useFetchWithPaymentCore.js.map +1 -1
  5. package/dist/cjs/react/native/hooks/x402/useFetchWithPayment.js +1 -1
  6. package/dist/cjs/react/web/hooks/x402/useFetchWithPayment.js +2 -2
  7. package/dist/cjs/react/web/hooks/x402/useFetchWithPayment.js.map +1 -1
  8. package/dist/cjs/react/web/ui/x402/PaymentErrorModal.js +4 -4
  9. package/dist/cjs/react/web/ui/x402/PaymentErrorModal.js.map +1 -1
  10. package/dist/cjs/version.js +1 -1
  11. package/dist/cjs/x402/encode.js +41 -2
  12. package/dist/cjs/x402/encode.js.map +1 -1
  13. package/dist/cjs/x402/fetchWithPayment.js +56 -33
  14. package/dist/cjs/x402/fetchWithPayment.js.map +1 -1
  15. package/dist/cjs/x402/schemas.js +134 -2
  16. package/dist/cjs/x402/schemas.js.map +1 -1
  17. package/dist/cjs/x402/sign.js +56 -15
  18. package/dist/cjs/x402/sign.js.map +1 -1
  19. package/dist/esm/insight/get-nfts.js +2 -2
  20. package/dist/esm/insight/get-nfts.js.map +1 -1
  21. package/dist/esm/react/core/hooks/x402/useFetchWithPaymentCore.js +2 -1
  22. package/dist/esm/react/core/hooks/x402/useFetchWithPaymentCore.js.map +1 -1
  23. package/dist/esm/react/native/hooks/x402/useFetchWithPayment.js +1 -1
  24. package/dist/esm/react/web/hooks/x402/useFetchWithPayment.js +2 -2
  25. package/dist/esm/react/web/hooks/x402/useFetchWithPayment.js.map +1 -1
  26. package/dist/esm/react/web/ui/x402/PaymentErrorModal.js +5 -5
  27. package/dist/esm/react/web/ui/x402/PaymentErrorModal.js.map +1 -1
  28. package/dist/esm/version.js +1 -1
  29. package/dist/esm/x402/encode.js +40 -2
  30. package/dist/esm/x402/encode.js.map +1 -1
  31. package/dist/esm/x402/fetchWithPayment.js +57 -35
  32. package/dist/esm/x402/fetchWithPayment.js.map +1 -1
  33. package/dist/esm/x402/schemas.js +129 -1
  34. package/dist/esm/x402/schemas.js.map +1 -1
  35. package/dist/esm/x402/sign.js +57 -16
  36. package/dist/esm/x402/sign.js.map +1 -1
  37. package/dist/scripts/bridge-widget.js +64 -64
  38. package/dist/types/react/core/hooks/x402/useFetchWithPaymentCore.d.ts +1 -0
  39. package/dist/types/react/core/hooks/x402/useFetchWithPaymentCore.d.ts.map +1 -1
  40. package/dist/types/react/native/hooks/x402/useFetchWithPayment.d.ts +1 -1
  41. package/dist/types/react/web/hooks/x402/useFetchWithPayment.d.ts +1 -1
  42. package/dist/types/react/web/hooks/x402/useFetchWithPayment.d.ts.map +1 -1
  43. package/dist/types/react/web/ui/x402/PaymentErrorModal.d.ts +1 -0
  44. package/dist/types/react/web/ui/x402/PaymentErrorModal.d.ts.map +1 -1
  45. package/dist/types/version.d.ts +1 -1
  46. package/dist/types/x402/encode.d.ts +7 -0
  47. package/dist/types/x402/encode.d.ts.map +1 -1
  48. package/dist/types/x402/fetchWithPayment.d.ts +10 -1
  49. package/dist/types/x402/fetchWithPayment.d.ts.map +1 -1
  50. package/dist/types/x402/schemas.d.ts +60 -2
  51. package/dist/types/x402/schemas.d.ts.map +1 -1
  52. package/dist/types/x402/sign.d.ts +13 -1
  53. package/dist/types/x402/sign.d.ts.map +1 -1
  54. package/package.json +17 -16
  55. package/src/contract/actions/resolve-abi.test.ts +3 -5
  56. package/src/extensions/airdrop/write/airdropERC721WithSignature.test.ts +4 -5
  57. package/src/extensions/erc1155/drop1155.test.ts +1 -1
  58. package/src/extensions/erc1155/write/sigMint1155.test.ts +189 -187
  59. package/src/extensions/erc20/drop20.test.ts +1 -1
  60. package/src/extensions/erc721/write/sigMint721.test.ts +4 -6
  61. package/src/extensions/modules/ClaimableERC1155/claimableERC1155.test.ts +180 -178
  62. package/src/extensions/modules/ClaimableERC20/claimableERC20.test.ts +1 -1
  63. package/src/extensions/modules/ClaimableERC721/claimableERC721.test.ts +1 -1
  64. package/src/extensions/prebuilts/process-ref-deployments.test.ts +1 -1
  65. package/src/insight/get-nfts.ts +2 -2
  66. package/src/react/core/account/provider.test.tsx +1 -0
  67. package/src/react/core/hooks/others/useWalletBalance.test.tsx +1 -0
  68. package/src/react/core/hooks/pay/useBuyWithFiatQuotesForProviders.test.tsx +1 -0
  69. package/src/react/core/hooks/useStepExecutor.test.tsx +1 -0
  70. package/src/react/core/hooks/wallets/useAddConnectedWallet.test.tsx +1 -0
  71. package/src/react/core/hooks/wallets/useAutoConnectCore.test.tsx +1 -0
  72. package/src/react/core/hooks/wallets/useConnect.test.tsx +1 -0
  73. package/src/react/core/hooks/wallets/useSetActiveWallet.test.tsx +1 -0
  74. package/src/react/core/hooks/wallets/useSwitchActiveWalletChain.test.tsx +1 -0
  75. package/src/react/core/hooks/x402/useFetchWithPaymentCore.ts +6 -1
  76. package/src/react/core/providers/connection-manager.test.tsx +1 -0
  77. package/src/react/core/wallet/provider.test.tsx +1 -0
  78. package/src/react/native/hooks/wallets/useUnlinkProfile.test.tsx +1 -0
  79. package/src/react/native/hooks/x402/useFetchWithPayment.ts +1 -1
  80. package/src/react/web/hooks/wallets/useUnlinkProfile.test.tsx +1 -0
  81. package/src/react/web/hooks/x402/useFetchWithPayment.tsx +3 -1
  82. package/src/react/web/ui/AutoConnect/AutoConnect.test.tsx +1 -0
  83. package/src/react/web/ui/Bridge/StepRunner.test.tsx +1 -0
  84. package/src/react/web/ui/Bridge/common/token-query.test.tsx +1 -0
  85. package/src/react/web/ui/ConnectWallet/ConnectButton.test.tsx +1 -0
  86. package/src/react/web/ui/ConnectWallet/Details.test.tsx +1 -0
  87. package/src/react/web/ui/ConnectWallet/NetworkSelector.test.tsx +1 -0
  88. package/src/react/web/ui/ConnectWallet/screens/Buy/fiat/currencies.test.tsx +1 -0
  89. package/src/react/web/ui/ConnectWallet/screens/LinkedProfilesScreen.test.tsx +1 -0
  90. package/src/react/web/ui/ConnectWallet/screens/ManageWalletScreen.test.tsx +1 -0
  91. package/src/react/web/ui/ConnectWallet/screens/PrivateKey.test.tsx +1 -0
  92. package/src/react/web/ui/ConnectWallet/screens/ReceiveFunds.test.tsx +1 -0
  93. package/src/react/web/ui/ConnectWallet/screens/SendFunds.test.tsx +1 -0
  94. package/src/react/web/ui/ConnectWallet/screens/SignatureScreen.test.tsx +1 -0
  95. package/src/react/web/ui/ConnectWallet/screens/StartScreen.test.tsx +1 -0
  96. package/src/react/web/ui/MediaRenderer/MediaRenderer.test.tsx +1 -0
  97. package/src/react/web/ui/MediaRenderer/icons.test.tsx +1 -0
  98. package/src/react/web/ui/MediaRenderer/useResolvedMediaType.test.tsx +1 -0
  99. package/src/react/web/ui/SiteEmbed.test.tsx +1 -0
  100. package/src/react/web/ui/SiteLink.test.tsx +1 -0
  101. package/src/react/web/ui/TransactionButton/TransactionButton.test.tsx +1 -0
  102. package/src/react/web/ui/components/ChainIcon.test.tsx +1 -0
  103. package/src/react/web/ui/hooks/useCopyClipboard.test.tsx +1 -0
  104. package/src/react/web/ui/hooks/useDebouncedValue.test.tsx +1 -0
  105. package/src/react/web/ui/hooks/useShowMore.test.tsx +28 -12
  106. package/src/react/web/ui/prebuilt/Account/address.test.tsx +1 -0
  107. package/src/react/web/ui/prebuilt/Account/avatar.test.tsx +1 -0
  108. package/src/react/web/ui/prebuilt/Account/balance.test.tsx +1 -0
  109. package/src/react/web/ui/prebuilt/Account/name.test.tsx +1 -0
  110. package/src/react/web/ui/prebuilt/Chain/icon.test.tsx +1 -0
  111. package/src/react/web/ui/prebuilt/Chain/name.test.tsx +1 -0
  112. package/src/react/web/ui/prebuilt/Chain/provider.test.tsx +1 -0
  113. package/src/react/web/ui/prebuilt/NFT/description.test.tsx +1 -0
  114. package/src/react/web/ui/prebuilt/NFT/media.test.tsx +1 -0
  115. package/src/react/web/ui/prebuilt/NFT/name.test.tsx +1 -0
  116. package/src/react/web/ui/prebuilt/NFT/provider.test.tsx +1 -0
  117. package/src/react/web/ui/prebuilt/Token/name.test.tsx +1 -0
  118. package/src/react/web/ui/prebuilt/Token/provider.test.tsx +1 -0
  119. package/src/react/web/ui/prebuilt/Token/symbol.test.tsx +1 -0
  120. package/src/react/web/ui/prebuilt/Wallet/icon.test.tsx +1 -0
  121. package/src/react/web/ui/prebuilt/Wallet/name.test.tsx +1 -0
  122. package/src/react/web/ui/prebuilt/thirdweb/BuyDirectListingButton/BuyDirectListingButton.test.tsx +1 -0
  123. package/src/react/web/ui/prebuilt/thirdweb/ClaimButton/ClaimButton.test.tsx +1 -0
  124. package/src/react/web/ui/prebuilt/thirdweb/CreateDirectListingButton/CreateDirectListingButton.test.tsx +1 -0
  125. package/src/react/web/ui/x402/PaymentErrorModal.tsx +9 -4
  126. package/src/react/web/utils/canFitWideModal.test.tsx +1 -0
  127. package/src/react/web/wallets/in-app/CountrySelector.test.tsx +1 -0
  128. package/src/react/web/wallets/in-app/InputSelectionUI.test.tsx +1 -0
  129. package/src/react/web/wallets/shared/ConnectWalletSocialOptions.test.tsx +1 -0
  130. package/src/version.ts +1 -1
  131. package/src/wallets/in-app/web/lib/auth/redirect-state.test.tsx +1 -0
  132. package/src/wallets/in-app/web/lib/get-url-token.test.tsx +1 -0
  133. package/src/wallets/in-app/web/utils/iFrameCommunication/IframeCommunicator.test.tsx +1 -0
  134. package/src/x402/encode.ts +46 -2
  135. package/src/x402/fetchWithPayment.test.ts +1173 -104
  136. package/src/x402/fetchWithPayment.ts +72 -54
  137. package/src/x402/schemas.test.ts +123 -0
  138. package/src/x402/schemas.ts +199 -6
  139. package/src/x402/sign.ts +86 -10
package/src/x402/sign.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { hexToBigInt } from "viem";
2
- import type { ExactEvmPayloadAuthorization } from "x402/types";
2
+ import type { ExactEvmPayload, ExactEvmPayloadAuthorization } from "x402/types";
3
3
  import { getCachedChain } from "../chains/utils.js";
4
4
  import type { ThirdwebClient } from "../client/client.js";
5
5
  import { getContract } from "../contract/contract.js";
@@ -18,6 +18,7 @@ import {
18
18
  } from "./permitSignatureStorage.js";
19
19
  import {
20
20
  extractEvmChainId,
21
+ isAtomicAmount,
21
22
  networkToCaip2ChainId,
22
23
  type RequestedPaymentPayload,
23
24
  type RequestedPaymentRequirements,
@@ -25,12 +26,45 @@ import {
25
26
  } from "./schemas.js";
26
27
  import type { ERC20TokenAmount } from "./types.js";
27
28
 
29
+ /**
30
+ * x402 v2 payload fields echoed back to the server.
31
+ */
32
+ type PaymentPayloadV2Context = {
33
+ /** The selected payment requirement exactly as sent by the server */
34
+ accepted: Record<string, unknown>;
35
+ /** The resource being paid for */
36
+ resource?: Record<string, unknown>;
37
+ };
38
+
39
+ /**
40
+ * Builds the payload fields shared by every payment payload for the given requirements.
41
+ * v2 payloads additionally carry `accepted` and `resource`.
42
+ */
43
+ function paymentPayloadEnvelope(
44
+ x402Version: number,
45
+ paymentRequirements: RequestedPaymentRequirements,
46
+ v2Context: PaymentPayloadV2Context | undefined,
47
+ ): Omit<RequestedPaymentPayload, "payload"> {
48
+ return {
49
+ x402Version,
50
+ scheme: paymentRequirements.scheme,
51
+ network: paymentRequirements.network,
52
+ ...(x402Version === 2 && v2Context
53
+ ? {
54
+ accepted: v2Context.accepted,
55
+ ...(v2Context.resource ? { resource: v2Context.resource } : {}),
56
+ }
57
+ : {}),
58
+ };
59
+ }
60
+
28
61
  /**
29
62
  * Prepares an unsigned payment header with the given sender address and payment requirements.
30
63
  *
31
64
  * @param from - The sender's address from which the payment will be made
32
65
  * @param x402Version - The version of the X402 protocol to use
33
66
  * @param paymentRequirements - The payment requirements containing scheme and network information
67
+ * @param v2Context - The x402 v2 fields to include in the payload
34
68
  * @returns An unsigned payment payload containing authorization details
35
69
  */
36
70
  function preparePaymentHeader(
@@ -38,6 +72,7 @@ function preparePaymentHeader(
38
72
  x402Version: number,
39
73
  paymentRequirements: RequestedPaymentRequirements,
40
74
  nonce: Hex,
75
+ v2Context: PaymentPayloadV2Context | undefined,
41
76
  ): UnsignedPaymentPayload {
42
77
  const validAfter = BigInt(
43
78
  Math.floor(Date.now() / 1000) - 86400, // 24h before in case weird block timestamp behavior
@@ -47,9 +82,7 @@ function preparePaymentHeader(
47
82
  ).toString();
48
83
 
49
84
  return {
50
- x402Version,
51
- scheme: paymentRequirements.scheme,
52
- network: paymentRequirements.network,
85
+ ...paymentPayloadEnvelope(x402Version, paymentRequirements, v2Context),
53
86
  payload: {
54
87
  signature: undefined,
55
88
  authorization: {
@@ -71,6 +104,7 @@ function preparePaymentHeader(
71
104
  * @param paymentRequirements - The payment requirements containing scheme and network information
72
105
  * @param unsignedPaymentHeader - The unsigned payment payload to be signed
73
106
  * @param storage - Optional storage for caching permit signatures (for "upto" scheme)
107
+ * @param v2Context - The x402 v2 fields to include in the payload
74
108
  * @returns A promise that resolves to the signed payment payload
75
109
  */
76
110
  async function signPaymentHeader(
@@ -79,6 +113,8 @@ async function signPaymentHeader(
79
113
  paymentRequirements: RequestedPaymentRequirements,
80
114
  x402Version: number,
81
115
  storage?: AsyncStorage,
116
+ v2Context?: PaymentPayloadV2Context,
117
+ maxValue?: bigint,
82
118
  ): Promise<RequestedPaymentPayload> {
83
119
  const from = getAddress(account.address);
84
120
  const caip2ChainId = networkToCaip2ChainId(paymentRequirements.network);
@@ -114,8 +150,23 @@ async function signPaymentHeader(
114
150
  // Try to reuse cached signature for "upto" scheme
115
151
  if (shouldCache && storage) {
116
152
  const cached = await getPermitSignatureFromCache(storage, cacheParams);
153
+ const cachedPayload = cached?.payload?.payload as
154
+ | ExactEvmPayload
155
+ | undefined;
156
+ const cachedAuthorization = cachedPayload?.authorization;
157
+ const cachedValue = cachedAuthorization?.value;
158
+ const amount = BigInt(paymentRequirements.maxAmountRequired);
117
159
 
118
- if (cached) {
160
+ if (
161
+ cached &&
162
+ cachedPayload &&
163
+ isSameAddress(cachedAuthorization?.from, from) &&
164
+ isSameAddress(cachedAuthorization?.to, spender) &&
165
+ isAtomicAmount(cached.deadline) &&
166
+ isAtomicAmount(cachedValue) &&
167
+ BigInt(cachedValue) >= amount &&
168
+ (maxValue === undefined || BigInt(cachedValue) <= maxValue)
169
+ ) {
119
170
  // Validate deadline hasn't passed
120
171
  const now = BigInt(Math.floor(Date.now() / 1000));
121
172
  if (BigInt(cached.deadline) > now) {
@@ -130,19 +181,30 @@ async function signPaymentHeader(
130
181
  spender,
131
182
  });
132
183
 
133
- // Determine threshold - use minAmountRequired if present, else maxAmountRequired
184
+ // Determine threshold - use minAmountRequired if it is within (0, amount], else the amount
134
185
  const extra = paymentRequirements.extra as
135
186
  | (ERC20TokenAmount["asset"]["eip712"] & {
136
187
  minAmountRequired?: string;
137
188
  })
138
189
  | undefined;
139
- const threshold = extra?.minAmountRequired
190
+ const minAmount = isAtomicAmount(extra?.minAmountRequired)
140
191
  ? BigInt(extra.minAmountRequired)
141
- : BigInt(paymentRequirements.maxAmountRequired);
192
+ : undefined;
193
+ const threshold =
194
+ minAmount !== undefined && minAmount > 0n && minAmount <= amount
195
+ ? minAmount
196
+ : amount;
142
197
 
143
- // If allowance >= threshold, reuse signature
198
+ // If allowance >= threshold, reuse the signature in the current envelope
144
199
  if (currentAllowance >= threshold) {
145
- return cached.payload;
200
+ return {
201
+ ...paymentPayloadEnvelope(
202
+ x402Version,
203
+ paymentRequirements,
204
+ v2Context,
205
+ ),
206
+ payload: cachedPayload,
207
+ };
146
208
  }
147
209
  }
148
210
  }
@@ -162,6 +224,7 @@ async function signPaymentHeader(
162
224
  x402Version,
163
225
  paymentRequirements,
164
226
  toHex(nonce, { size: 32 }), // permit nonce
227
+ v2Context,
165
228
  );
166
229
  const { signature } = await signERC2612Permit(
167
230
  account,
@@ -198,6 +261,7 @@ async function signPaymentHeader(
198
261
  x402Version,
199
262
  paymentRequirements,
200
263
  nonce, // random nonce
264
+ v2Context,
201
265
  );
202
266
  const { signature } = await signERC3009Authorization(
203
267
  account,
@@ -226,6 +290,8 @@ async function signPaymentHeader(
226
290
  * @param x402Version - The version of the X402 protocol to use
227
291
  * @param paymentRequirements - The payment requirements containing scheme and network information
228
292
  * @param storage - Optional storage for caching permit signatures (for "upto" scheme)
293
+ * @param v2Context - The x402 v2 fields to include in the payload
294
+ * @param maxValue - The maximum allowed payment amount
229
295
  * @returns A promise that resolves to the encoded payment header string
230
296
  */
231
297
  export async function createPaymentHeader(
@@ -234,6 +300,8 @@ export async function createPaymentHeader(
234
300
  paymentRequirements: RequestedPaymentRequirements,
235
301
  x402Version: number,
236
302
  storage?: AsyncStorage,
303
+ v2Context?: PaymentPayloadV2Context,
304
+ maxValue?: bigint,
237
305
  ): Promise<string> {
238
306
  const payment = await signPaymentHeader(
239
307
  client,
@@ -241,10 +309,18 @@ export async function createPaymentHeader(
241
309
  paymentRequirements,
242
310
  x402Version,
243
311
  storage,
312
+ v2Context,
313
+ maxValue,
244
314
  );
245
315
  return encodePayment(payment);
246
316
  }
247
317
 
318
+ function isSameAddress(value: unknown, address: string): boolean {
319
+ return (
320
+ typeof value === "string" && value.toLowerCase() === address.toLowerCase()
321
+ );
322
+ }
323
+
248
324
  /**
249
325
  * Signs an EIP-3009 authorization for USDC transfer
250
326
  *