thirdweb 5.108.4-nightly-2c84ac408999dbff007733f76c8f0f13818258b5-20250928000351 → 5.108.5-nightly-ce9220ea00e5a58bf3f6997733b4b69df981cba8-20250930000345
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/auth/verify-typed-data.js +18 -0
- package/dist/cjs/auth/verify-typed-data.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/swap-widget/select-token-ui.js +9 -5
- package/dist/cjs/react/web/ui/Bridge/swap-widget/select-token-ui.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/swap-widget/use-tokens.js +4 -2
- package/dist/cjs/react/web/ui/Bridge/swap-widget/use-tokens.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/x402/common.js +60 -4
- package/dist/cjs/x402/common.js.map +1 -1
- package/dist/cjs/x402/facilitator.js +12 -4
- package/dist/cjs/x402/facilitator.js.map +1 -1
- package/dist/cjs/x402/fetchWithPayment.js +4 -4
- package/dist/cjs/x402/fetchWithPayment.js.map +1 -1
- package/dist/cjs/x402/schemas.js +29 -1
- package/dist/cjs/x402/schemas.js.map +1 -1
- package/dist/cjs/x402/types.js.map +1 -1
- package/dist/esm/auth/verify-typed-data.js +18 -0
- package/dist/esm/auth/verify-typed-data.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/swap-widget/select-token-ui.js +9 -5
- package/dist/esm/react/web/ui/Bridge/swap-widget/select-token-ui.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/swap-widget/use-tokens.js +4 -2
- package/dist/esm/react/web/ui/Bridge/swap-widget/use-tokens.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/x402/common.js +60 -4
- package/dist/esm/x402/common.js.map +1 -1
- package/dist/esm/x402/facilitator.js +12 -4
- package/dist/esm/x402/facilitator.js.map +1 -1
- package/dist/esm/x402/fetchWithPayment.js +4 -4
- package/dist/esm/x402/fetchWithPayment.js.map +1 -1
- package/dist/esm/x402/schemas.js +29 -1
- package/dist/esm/x402/schemas.js.map +1 -1
- package/dist/esm/x402/types.js.map +1 -1
- package/dist/scripts/bridge-widget.js +84 -84
- package/dist/types/auth/verify-typed-data.d.ts +2 -2
- package/dist/types/auth/verify-typed-data.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/swap-widget/select-token-ui.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/swap-widget/use-tokens.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/x402/common.d.ts.map +1 -1
- package/dist/types/x402/facilitator.d.ts +7 -3
- package/dist/types/x402/facilitator.d.ts.map +1 -1
- package/dist/types/x402/fetchWithPayment.d.ts.map +1 -1
- package/dist/types/x402/schemas.d.ts +248 -0
- package/dist/types/x402/schemas.d.ts.map +1 -1
- package/dist/types/x402/types.d.ts +6 -4
- package/dist/types/x402/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/auth/verify-typed-data.ts +20 -2
- package/src/react/web/ui/Bridge/swap-widget/select-token-ui.tsx +9 -5
- package/src/react/web/ui/Bridge/swap-widget/use-tokens.ts +5 -2
- package/src/version.ts +1 -1
- package/src/x402/common.ts +87 -8
- package/src/x402/facilitator.ts +26 -7
- package/src/x402/fetchWithPayment.ts +8 -4
- package/src/x402/schemas.ts +39 -0
- package/src/x402/types.ts +10 -3
package/src/x402/common.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { getContract } from "../contract/contract.js";
|
|
|
8
8
|
import { isPermitSupported } from "../extensions/erc20/__generated__/IERC20Permit/write/permit.js";
|
|
9
9
|
import { isTransferWithAuthorizationSupported } from "../extensions/erc20/__generated__/USDC/write/transferWithAuthorization.js";
|
|
10
10
|
import { getAddress } from "../utils/address.js";
|
|
11
|
+
import { toUnits } from "../utils/units.js";
|
|
11
12
|
import { decodePayment } from "./encode.js";
|
|
12
13
|
import type { ThirdwebX402Facilitator } from "./facilitator.js";
|
|
13
14
|
import {
|
|
@@ -16,6 +17,7 @@ import {
|
|
|
16
17
|
type RequestedPaymentRequirements,
|
|
17
18
|
} from "./schemas.js";
|
|
18
19
|
import {
|
|
20
|
+
type DefaultAsset,
|
|
19
21
|
type ERC20TokenAmount,
|
|
20
22
|
type PaymentArgs,
|
|
21
23
|
type PaymentRequiredResult,
|
|
@@ -199,12 +201,11 @@ async function processPriceToAtomicAmount(
|
|
|
199
201
|
chainId: number,
|
|
200
202
|
facilitator: ThirdwebX402Facilitator,
|
|
201
203
|
): Promise<
|
|
202
|
-
|
|
203
|
-
| { error: string }
|
|
204
|
+
{ maxAmountRequired: string; asset: DefaultAsset } | { error: string }
|
|
204
205
|
> {
|
|
205
206
|
// Handle USDC amount (string) or token amount (ERC20TokenAmount)
|
|
206
207
|
let maxAmountRequired: string;
|
|
207
|
-
let asset:
|
|
208
|
+
let asset: DefaultAsset;
|
|
208
209
|
|
|
209
210
|
if (typeof price === "string" || typeof price === "number") {
|
|
210
211
|
// USDC amount in dollars
|
|
@@ -222,11 +223,32 @@ async function processPriceToAtomicAmount(
|
|
|
222
223
|
};
|
|
223
224
|
}
|
|
224
225
|
asset = defaultAsset;
|
|
225
|
-
maxAmountRequired = (
|
|
226
|
+
maxAmountRequired = toUnits(
|
|
227
|
+
parsedUsdAmount.toString(),
|
|
228
|
+
defaultAsset.decimals,
|
|
229
|
+
).toString();
|
|
226
230
|
} else {
|
|
227
231
|
// Token amount in atomic units
|
|
228
232
|
maxAmountRequired = price.amount;
|
|
229
|
-
|
|
233
|
+
const tokenExtras = await getOrDetectTokenExtras({
|
|
234
|
+
facilitator,
|
|
235
|
+
partialAsset: price.asset,
|
|
236
|
+
chainId,
|
|
237
|
+
});
|
|
238
|
+
if (!tokenExtras) {
|
|
239
|
+
return {
|
|
240
|
+
error: `Unable to find token information for ${price.asset.address} on chain ${chainId}. Please specify the asset decimals and eip712 information in the asset options.`,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
asset = {
|
|
244
|
+
address: price.asset.address,
|
|
245
|
+
decimals: tokenExtras.decimals,
|
|
246
|
+
eip712: {
|
|
247
|
+
name: tokenExtras.name,
|
|
248
|
+
version: tokenExtras.version,
|
|
249
|
+
primaryType: tokenExtras.primaryType,
|
|
250
|
+
},
|
|
251
|
+
};
|
|
230
252
|
}
|
|
231
253
|
|
|
232
254
|
return {
|
|
@@ -238,13 +260,12 @@ async function processPriceToAtomicAmount(
|
|
|
238
260
|
async function getDefaultAsset(
|
|
239
261
|
chainId: number,
|
|
240
262
|
facilitator: ThirdwebX402Facilitator,
|
|
241
|
-
): Promise<
|
|
263
|
+
): Promise<DefaultAsset | undefined> {
|
|
242
264
|
const supportedAssets = await facilitator.supported();
|
|
243
265
|
const matchingAsset = supportedAssets.kinds.find(
|
|
244
266
|
(supported) => supported.network === `eip155:${chainId}`,
|
|
245
267
|
);
|
|
246
|
-
const assetConfig = matchingAsset?.extra
|
|
247
|
-
?.defaultAsset as ERC20TokenAmount["asset"];
|
|
268
|
+
const assetConfig = matchingAsset?.extra?.defaultAsset as DefaultAsset;
|
|
248
269
|
return assetConfig;
|
|
249
270
|
}
|
|
250
271
|
|
|
@@ -287,3 +308,61 @@ export async function getSupportedSignatureType(args: {
|
|
|
287
308
|
}
|
|
288
309
|
return undefined;
|
|
289
310
|
}
|
|
311
|
+
|
|
312
|
+
async function getOrDetectTokenExtras(args: {
|
|
313
|
+
facilitator: ThirdwebX402Facilitator;
|
|
314
|
+
partialAsset: ERC20TokenAmount["asset"];
|
|
315
|
+
chainId: number;
|
|
316
|
+
}): Promise<
|
|
317
|
+
| {
|
|
318
|
+
name: string;
|
|
319
|
+
version: string;
|
|
320
|
+
decimals: number;
|
|
321
|
+
primaryType: SupportedSignatureType;
|
|
322
|
+
}
|
|
323
|
+
| undefined
|
|
324
|
+
> {
|
|
325
|
+
const { facilitator, partialAsset, chainId } = args;
|
|
326
|
+
if (
|
|
327
|
+
partialAsset.eip712?.name &&
|
|
328
|
+
partialAsset.eip712?.version &&
|
|
329
|
+
partialAsset.decimals !== undefined
|
|
330
|
+
) {
|
|
331
|
+
return {
|
|
332
|
+
name: partialAsset.eip712.name,
|
|
333
|
+
version: partialAsset.eip712.version,
|
|
334
|
+
decimals: partialAsset.decimals,
|
|
335
|
+
primaryType: partialAsset.eip712.primaryType,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
// read from facilitator
|
|
339
|
+
const response = await facilitator
|
|
340
|
+
.supported({
|
|
341
|
+
chainId,
|
|
342
|
+
tokenAddress: partialAsset.address,
|
|
343
|
+
})
|
|
344
|
+
.catch(() => {
|
|
345
|
+
return {
|
|
346
|
+
kinds: [],
|
|
347
|
+
};
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
const exactScheme = response.kinds?.find((kind) => kind.scheme === "exact");
|
|
351
|
+
if (!exactScheme) {
|
|
352
|
+
return undefined;
|
|
353
|
+
}
|
|
354
|
+
const supportedAsset = exactScheme.extra?.supportedAssets?.find(
|
|
355
|
+
(asset) =>
|
|
356
|
+
asset.address.toLowerCase() === partialAsset.address.toLowerCase(),
|
|
357
|
+
);
|
|
358
|
+
if (!supportedAsset) {
|
|
359
|
+
return undefined;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return {
|
|
363
|
+
name: supportedAsset.eip712.name,
|
|
364
|
+
version: supportedAsset.eip712.version,
|
|
365
|
+
decimals: supportedAsset.decimals,
|
|
366
|
+
primaryType: supportedAsset.eip712.primaryType as SupportedSignatureType,
|
|
367
|
+
};
|
|
368
|
+
}
|
package/src/x402/facilitator.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { VerifyResponse } from "x402/types";
|
|
2
2
|
import type { ThirdwebClient } from "../client/client.js";
|
|
3
3
|
import { stringify } from "../utils/json.js";
|
|
4
4
|
import { withCache } from "../utils/promise/withCache.js";
|
|
5
5
|
import type {
|
|
6
6
|
FacilitatorSettleResponse,
|
|
7
|
+
FacilitatorSupportedResponse,
|
|
7
8
|
RequestedPaymentPayload,
|
|
8
9
|
RequestedPaymentRequirements,
|
|
9
10
|
} from "./schemas.js";
|
|
@@ -11,6 +12,7 @@ import type {
|
|
|
11
12
|
export type ThirdwebX402FacilitatorConfig = {
|
|
12
13
|
client: ThirdwebClient;
|
|
13
14
|
serverWalletAddress: string;
|
|
15
|
+
waitUtil?: "simulated" | "submitted" | "confirmed";
|
|
14
16
|
vaultAccessToken?: string;
|
|
15
17
|
baseUrl?: string;
|
|
16
18
|
};
|
|
@@ -36,7 +38,10 @@ export type ThirdwebX402Facilitator = {
|
|
|
36
38
|
payload: RequestedPaymentPayload,
|
|
37
39
|
paymentRequirements: RequestedPaymentRequirements,
|
|
38
40
|
) => Promise<FacilitatorSettleResponse>;
|
|
39
|
-
supported: (
|
|
41
|
+
supported: (filters?: {
|
|
42
|
+
chainId: number;
|
|
43
|
+
tokenAddress?: string;
|
|
44
|
+
}) => Promise<FacilitatorSupportedResponse>;
|
|
40
45
|
};
|
|
41
46
|
|
|
42
47
|
const DEFAULT_BASE_URL = "https://api.thirdweb.com/v1/payments/x402";
|
|
@@ -176,6 +181,7 @@ export function facilitator(
|
|
|
176
181
|
x402Version: payload.x402Version,
|
|
177
182
|
paymentPayload: payload,
|
|
178
183
|
paymentRequirements: paymentRequirements,
|
|
184
|
+
...(config.waitUtil ? { waitUtil: config.waitUtil } : {}),
|
|
179
185
|
}),
|
|
180
186
|
});
|
|
181
187
|
|
|
@@ -193,14 +199,27 @@ export function facilitator(
|
|
|
193
199
|
*
|
|
194
200
|
* @returns A promise that resolves to the supported payment kinds
|
|
195
201
|
*/
|
|
196
|
-
async supported(
|
|
202
|
+
async supported(filters?: {
|
|
203
|
+
chainId: number;
|
|
204
|
+
tokenAddress?: string;
|
|
205
|
+
}): Promise<FacilitatorSupportedResponse> {
|
|
197
206
|
const url = config.baseUrl ?? DEFAULT_BASE_URL;
|
|
198
207
|
return withCache(
|
|
199
208
|
async () => {
|
|
200
209
|
let headers = { "Content-Type": "application/json" };
|
|
201
210
|
const authHeaders = await facilitator.createAuthHeaders();
|
|
202
211
|
headers = { ...headers, ...authHeaders.supported };
|
|
203
|
-
const
|
|
212
|
+
const supportedUrl = new URL(`${url}/supported`);
|
|
213
|
+
if (filters?.chainId) {
|
|
214
|
+
supportedUrl.searchParams.set(
|
|
215
|
+
"chainId",
|
|
216
|
+
filters.chainId.toString(),
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
if (filters?.tokenAddress) {
|
|
220
|
+
supportedUrl.searchParams.set("tokenAddress", filters.tokenAddress);
|
|
221
|
+
}
|
|
222
|
+
const res = await fetch(supportedUrl.toString(), { headers });
|
|
204
223
|
|
|
205
224
|
if (res.status !== 200) {
|
|
206
225
|
throw new Error(
|
|
@@ -209,11 +228,11 @@ export function facilitator(
|
|
|
209
228
|
}
|
|
210
229
|
|
|
211
230
|
const data = await res.json();
|
|
212
|
-
return data as
|
|
231
|
+
return data as FacilitatorSupportedResponse;
|
|
213
232
|
},
|
|
214
233
|
{
|
|
215
|
-
cacheKey: `supported-payment-kinds-${url}`,
|
|
216
|
-
cacheTime: 1000 * 60 * 60 *
|
|
234
|
+
cacheKey: `supported-payment-kinds-${url}-${filters?.chainId}-${filters?.tokenAddress}2`,
|
|
235
|
+
cacheTime: 1000 * 60 * 60 * 1, // 1 hour
|
|
217
236
|
},
|
|
218
237
|
);
|
|
219
238
|
},
|
|
@@ -61,9 +61,10 @@ export function wrapFetchWithPayment(
|
|
|
61
61
|
return response;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
const { x402Version, accepts } = (await response.json()) as {
|
|
64
|
+
const { x402Version, accepts, error } = (await response.json()) as {
|
|
65
65
|
x402Version: number;
|
|
66
66
|
accepts: unknown[];
|
|
67
|
+
error?: string;
|
|
67
68
|
};
|
|
68
69
|
const parsedPaymentRequirements = accepts
|
|
69
70
|
.map((x) => RequestedPaymentRequirementsSchema.parse(x))
|
|
@@ -83,6 +84,12 @@ export function wrapFetchWithPayment(
|
|
|
83
84
|
"exact",
|
|
84
85
|
);
|
|
85
86
|
|
|
87
|
+
if (!selectedPaymentRequirements) {
|
|
88
|
+
throw new Error(
|
|
89
|
+
`No suitable payment requirements found for chain ${chain.id}. ${error}`,
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
86
93
|
if (BigInt(selectedPaymentRequirements.maxAmountRequired) > maxValue) {
|
|
87
94
|
throw new Error(
|
|
88
95
|
`Payment amount exceeds maximum allowed (currently set to ${maxValue} in base units)`,
|
|
@@ -154,9 +161,6 @@ function defaultPaymentRequirementsSelector(
|
|
|
154
161
|
const firstPaymentRequirement = paymentRequirements.find(
|
|
155
162
|
(x) => x.scheme === scheme,
|
|
156
163
|
);
|
|
157
|
-
if (!firstPaymentRequirement) {
|
|
158
|
-
throw new Error("No suitable payment requirements found");
|
|
159
|
-
}
|
|
160
164
|
return firstPaymentRequirement;
|
|
161
165
|
}
|
|
162
166
|
}
|
package/src/x402/schemas.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
PaymentPayloadSchema,
|
|
6
6
|
PaymentRequirementsSchema,
|
|
7
7
|
SettleResponseSchema,
|
|
8
|
+
SupportedPaymentKindsResponseSchema,
|
|
8
9
|
} from "x402/types";
|
|
9
10
|
import { z } from "zod";
|
|
10
11
|
import type { Chain } from "../chains/types.js";
|
|
@@ -56,6 +57,44 @@ export type FacilitatorSettleResponse = z.infer<
|
|
|
56
57
|
typeof FacilitatorSettleResponseSchema
|
|
57
58
|
>;
|
|
58
59
|
|
|
60
|
+
export const SupportedSignatureTypeSchema = z.enum([
|
|
61
|
+
"TransferWithAuthorization",
|
|
62
|
+
"Permit",
|
|
63
|
+
]);
|
|
64
|
+
|
|
65
|
+
export const FacilitatorSupportedAssetSchema = z.object({
|
|
66
|
+
address: z.string(),
|
|
67
|
+
decimals: z.number(),
|
|
68
|
+
eip712: z.object({
|
|
69
|
+
name: z.string(),
|
|
70
|
+
version: z.string(),
|
|
71
|
+
primaryType: SupportedSignatureTypeSchema,
|
|
72
|
+
}),
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const FacilitatorSupportedResponseSchema =
|
|
76
|
+
SupportedPaymentKindsResponseSchema.extend({
|
|
77
|
+
kinds: z.array(
|
|
78
|
+
z.object({
|
|
79
|
+
x402Version: z.literal(1),
|
|
80
|
+
scheme: z.literal("exact"),
|
|
81
|
+
network: FacilitatorNetworkSchema,
|
|
82
|
+
extra: z
|
|
83
|
+
.object({
|
|
84
|
+
defaultAsset: FacilitatorSupportedAssetSchema.optional(),
|
|
85
|
+
supportedAssets: z
|
|
86
|
+
.array(FacilitatorSupportedAssetSchema)
|
|
87
|
+
.optional(),
|
|
88
|
+
})
|
|
89
|
+
.optional(),
|
|
90
|
+
}),
|
|
91
|
+
),
|
|
92
|
+
}).describe("Supported payment kinds for this facilitator");
|
|
93
|
+
|
|
94
|
+
export type FacilitatorSupportedResponse = z.infer<
|
|
95
|
+
typeof FacilitatorSupportedResponseSchema
|
|
96
|
+
>;
|
|
97
|
+
|
|
59
98
|
export function networkToChainId(network: string | Chain): number {
|
|
60
99
|
if (typeof network === "object") {
|
|
61
100
|
return network.id;
|
package/src/x402/types.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Money, PaymentMiddlewareConfig } from "x402/types";
|
|
2
|
+
import type z from "zod";
|
|
2
3
|
import type { Chain } from "../chains/types.js";
|
|
3
4
|
import type { Address } from "../utils/address.js";
|
|
4
5
|
import type { Prettify } from "../utils/type-utils.js";
|
|
@@ -6,8 +7,10 @@ import type { ThirdwebX402Facilitator } from "./facilitator.js";
|
|
|
6
7
|
import type {
|
|
7
8
|
FacilitatorNetwork,
|
|
8
9
|
FacilitatorSettleResponse,
|
|
10
|
+
FacilitatorSupportedAssetSchema,
|
|
9
11
|
RequestedPaymentPayload,
|
|
10
12
|
RequestedPaymentRequirements,
|
|
13
|
+
SupportedSignatureTypeSchema,
|
|
11
14
|
} from "./schemas.js";
|
|
12
15
|
|
|
13
16
|
export const x402Version = 1;
|
|
@@ -86,17 +89,21 @@ export type VerifyPaymentResult = Prettify<
|
|
|
86
89
|
| PaymentRequiredResult
|
|
87
90
|
>;
|
|
88
91
|
|
|
89
|
-
export type SupportedSignatureType =
|
|
92
|
+
export type SupportedSignatureType = z.infer<
|
|
93
|
+
typeof SupportedSignatureTypeSchema
|
|
94
|
+
>;
|
|
90
95
|
|
|
91
96
|
export type ERC20TokenAmount = {
|
|
92
97
|
amount: string;
|
|
93
98
|
asset: {
|
|
94
99
|
address: `0x${string}`;
|
|
95
|
-
decimals
|
|
96
|
-
eip712
|
|
100
|
+
decimals?: number;
|
|
101
|
+
eip712?: {
|
|
97
102
|
name: string;
|
|
98
103
|
version: string;
|
|
99
104
|
primaryType: SupportedSignatureType;
|
|
100
105
|
};
|
|
101
106
|
};
|
|
102
107
|
};
|
|
108
|
+
|
|
109
|
+
export type DefaultAsset = z.infer<typeof FacilitatorSupportedAssetSchema>;
|