thirdweb 5.121.1 → 5.121.3
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.
- package/dist/cjs/react/core/hooks/x402/useFetchWithPaymentCore.js +1 -0
- package/dist/cjs/react/core/hooks/x402/useFetchWithPaymentCore.js.map +1 -1
- package/dist/cjs/react/native/hooks/x402/useFetchWithPayment.js +1 -1
- package/dist/cjs/react/web/hooks/x402/useFetchWithPayment.js +2 -2
- package/dist/cjs/react/web/hooks/x402/useFetchWithPayment.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/common/token-query.js +4 -1
- package/dist/cjs/react/web/ui/Bridge/common/token-query.js.map +1 -1
- package/dist/cjs/react/web/ui/x402/PaymentErrorModal.js +4 -4
- package/dist/cjs/react/web/ui/x402/PaymentErrorModal.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/x402/encode.js +41 -2
- package/dist/cjs/x402/encode.js.map +1 -1
- package/dist/cjs/x402/fetchWithPayment.js +56 -33
- package/dist/cjs/x402/fetchWithPayment.js.map +1 -1
- package/dist/cjs/x402/schemas.js +134 -2
- package/dist/cjs/x402/schemas.js.map +1 -1
- package/dist/cjs/x402/sign.js +56 -15
- package/dist/cjs/x402/sign.js.map +1 -1
- package/dist/esm/react/core/hooks/x402/useFetchWithPaymentCore.js +2 -1
- package/dist/esm/react/core/hooks/x402/useFetchWithPaymentCore.js.map +1 -1
- package/dist/esm/react/native/hooks/x402/useFetchWithPayment.js +1 -1
- package/dist/esm/react/web/hooks/x402/useFetchWithPayment.js +2 -2
- package/dist/esm/react/web/hooks/x402/useFetchWithPayment.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/common/token-query.js +4 -1
- package/dist/esm/react/web/ui/Bridge/common/token-query.js.map +1 -1
- package/dist/esm/react/web/ui/x402/PaymentErrorModal.js +5 -5
- package/dist/esm/react/web/ui/x402/PaymentErrorModal.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/x402/encode.js +40 -2
- package/dist/esm/x402/encode.js.map +1 -1
- package/dist/esm/x402/fetchWithPayment.js +57 -35
- package/dist/esm/x402/fetchWithPayment.js.map +1 -1
- package/dist/esm/x402/schemas.js +129 -1
- package/dist/esm/x402/schemas.js.map +1 -1
- package/dist/esm/x402/sign.js +57 -16
- package/dist/esm/x402/sign.js.map +1 -1
- package/dist/scripts/bridge-widget.js +3 -3
- package/dist/types/react/core/hooks/x402/useFetchWithPaymentCore.d.ts +1 -0
- package/dist/types/react/core/hooks/x402/useFetchWithPaymentCore.d.ts.map +1 -1
- package/dist/types/react/native/hooks/x402/useFetchWithPayment.d.ts +1 -1
- package/dist/types/react/web/hooks/x402/useFetchWithPayment.d.ts +1 -1
- package/dist/types/react/web/hooks/x402/useFetchWithPayment.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/common/token-query.d.ts.map +1 -1
- package/dist/types/react/web/ui/x402/PaymentErrorModal.d.ts +1 -0
- package/dist/types/react/web/ui/x402/PaymentErrorModal.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/x402/encode.d.ts +7 -0
- package/dist/types/x402/encode.d.ts.map +1 -1
- package/dist/types/x402/fetchWithPayment.d.ts +10 -1
- package/dist/types/x402/fetchWithPayment.d.ts.map +1 -1
- package/dist/types/x402/schemas.d.ts +60 -2
- package/dist/types/x402/schemas.d.ts.map +1 -1
- package/dist/types/x402/sign.d.ts +13 -1
- package/dist/types/x402/sign.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/contract/actions/resolve-abi.test.ts +3 -5
- package/src/extensions/airdrop/write/airdropERC721WithSignature.test.ts +4 -5
- package/src/extensions/erc1155/drop1155.test.ts +1 -1
- package/src/extensions/erc1155/write/sigMint1155.test.ts +189 -187
- package/src/extensions/erc20/drop20.test.ts +1 -1
- package/src/extensions/erc721/write/sigMint721.test.ts +4 -6
- package/src/extensions/modules/ClaimableERC1155/claimableERC1155.test.ts +180 -178
- package/src/extensions/modules/ClaimableERC20/claimableERC20.test.ts +1 -1
- package/src/extensions/modules/ClaimableERC721/claimableERC721.test.ts +1 -1
- package/src/extensions/prebuilts/process-ref-deployments.test.ts +1 -1
- package/src/react/core/hooks/x402/useFetchWithPaymentCore.ts +6 -1
- package/src/react/native/hooks/x402/useFetchWithPayment.ts +1 -1
- package/src/react/web/hooks/x402/useFetchWithPayment.tsx +3 -1
- package/src/react/web/ui/Bridge/common/token-query.test.tsx +117 -0
- package/src/react/web/ui/Bridge/common/token-query.ts +4 -1
- package/src/react/web/ui/x402/PaymentErrorModal.tsx +9 -4
- package/src/version.ts +1 -1
- package/src/x402/encode.ts +46 -2
- package/src/x402/fetchWithPayment.test.ts +1173 -104
- package/src/x402/fetchWithPayment.ts +72 -54
- package/src/x402/schemas.test.ts +123 -0
- package/src/x402/schemas.ts +199 -6
- 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 (
|
|
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
|
|
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
|
|
190
|
+
const minAmount = isAtomicAmount(extra?.minAmountRequired)
|
|
140
191
|
? BigInt(extra.minAmountRequired)
|
|
141
|
-
:
|
|
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
|
|
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
|
*
|