thirdweb 5.107.1 → 5.108.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.
- package/dist/cjs/exports/x402.js +8 -1
- package/dist/cjs/exports/x402.js.map +1 -1
- package/dist/cjs/react/core/utils/defaultTokens.js +2 -8
- package/dist/cjs/react/core/utils/defaultTokens.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/BridgeOrchestrator.js +18 -14
- package/dist/cjs/react/web/ui/Bridge/BridgeOrchestrator.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/BuyWidget.js +15 -6
- package/dist/cjs/react/web/ui/Bridge/BuyWidget.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/x402/common.js +173 -0
- package/dist/cjs/x402/common.js.map +1 -0
- package/dist/cjs/x402/encode.js +71 -0
- package/dist/cjs/x402/encode.js.map +1 -0
- package/dist/cjs/x402/facilitator.js +83 -2
- package/dist/cjs/x402/facilitator.js.map +1 -1
- package/dist/cjs/x402/fetchWithPayment.js +7 -15
- package/dist/cjs/x402/fetchWithPayment.js.map +1 -1
- package/dist/cjs/x402/schemas.js +50 -0
- package/dist/cjs/x402/schemas.js.map +1 -0
- package/dist/cjs/x402/settle-payment.js +174 -0
- package/dist/cjs/x402/settle-payment.js.map +1 -0
- package/dist/cjs/x402/sign.js +148 -0
- package/dist/cjs/x402/sign.js.map +1 -0
- package/dist/cjs/x402/types.js +5 -0
- package/dist/cjs/x402/types.js.map +1 -0
- package/dist/cjs/x402/verify-payment.js +121 -0
- package/dist/cjs/x402/verify-payment.js.map +1 -0
- package/dist/esm/exports/x402.js +3 -0
- package/dist/esm/exports/x402.js.map +1 -1
- package/dist/esm/react/core/utils/defaultTokens.js +2 -8
- package/dist/esm/react/core/utils/defaultTokens.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/BridgeOrchestrator.js +18 -14
- package/dist/esm/react/web/ui/Bridge/BridgeOrchestrator.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/BuyWidget.js +15 -6
- package/dist/esm/react/web/ui/Bridge/BuyWidget.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/x402/common.js +170 -0
- package/dist/esm/x402/common.js.map +1 -0
- package/dist/esm/x402/encode.js +66 -0
- package/dist/esm/x402/encode.js.map +1 -0
- package/dist/esm/x402/facilitator.js +83 -2
- package/dist/esm/x402/facilitator.js.map +1 -1
- package/dist/esm/x402/fetchWithPayment.js +8 -16
- package/dist/esm/x402/fetchWithPayment.js.map +1 -1
- package/dist/esm/x402/schemas.js +46 -0
- package/dist/esm/x402/schemas.js.map +1 -0
- package/dist/esm/x402/settle-payment.js +171 -0
- package/dist/esm/x402/settle-payment.js.map +1 -0
- package/dist/esm/x402/sign.js +145 -0
- package/dist/esm/x402/sign.js.map +1 -0
- package/dist/esm/x402/types.js +2 -0
- package/dist/esm/x402/types.js.map +1 -0
- package/dist/esm/x402/verify-payment.js +118 -0
- package/dist/esm/x402/verify-payment.js.map +1 -0
- package/dist/types/exports/x402.d.ts +4 -0
- package/dist/types/exports/x402.d.ts.map +1 -1
- package/dist/types/react/core/utils/defaultTokens.d.ts +2 -7
- package/dist/types/react/core/utils/defaultTokens.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/BridgeOrchestrator.d.ts +4 -3
- package/dist/types/react/web/ui/Bridge/BridgeOrchestrator.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/BuyWidget.d.ts +7 -3
- package/dist/types/react/web/ui/Bridge/BuyWidget.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/x402/common.d.ts +16 -0
- package/dist/types/x402/common.d.ts.map +1 -0
- package/dist/types/x402/encode.d.ts +23 -0
- package/dist/types/x402/encode.d.ts.map +1 -0
- package/dist/types/x402/facilitator.d.ts +44 -3
- package/dist/types/x402/facilitator.d.ts.map +1 -1
- package/dist/types/x402/fetchWithPayment.d.ts +1 -1
- package/dist/types/x402/fetchWithPayment.d.ts.map +1 -1
- package/dist/types/x402/schemas.d.ts +164 -0
- package/dist/types/x402/schemas.d.ts.map +1 -0
- package/dist/types/x402/settle-payment.d.ts +117 -0
- package/dist/types/x402/settle-payment.d.ts.map +1 -0
- package/dist/types/x402/sign.d.ts +12 -0
- package/dist/types/x402/sign.d.ts.map +1 -0
- package/dist/types/x402/types.d.ts +71 -0
- package/dist/types/x402/types.d.ts.map +1 -0
- package/dist/types/x402/verify-payment.d.ts +69 -0
- package/dist/types/x402/verify-payment.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/exports/x402.ts +8 -0
- package/src/react/core/utils/defaultTokens.ts +2 -8
- package/src/react/web/ui/Bridge/BridgeOrchestrator.tsx +42 -31
- package/src/react/web/ui/Bridge/BuyWidget.tsx +24 -9
- package/src/version.ts +1 -1
- package/src/x402/common.ts +242 -0
- package/src/x402/encode.ts +81 -0
- package/src/x402/facilitator.ts +114 -6
- package/src/x402/fetchWithPayment.ts +13 -27
- package/src/x402/schemas.ts +76 -0
- package/src/x402/settle-payment.ts +186 -0
- package/src/x402/sign.ts +206 -0
- package/src/x402/types.ts +90 -0
- package/src/x402/verify-payment.ts +133 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.wrapFetchWithPayment = wrapFetchWithPayment;
|
|
4
|
-
const client_1 = require("x402/client");
|
|
5
4
|
const types_1 = require("x402/types");
|
|
6
|
-
const viem_js_1 = require("../adapters/viem.js");
|
|
7
5
|
const utils_js_1 = require("../chains/utils.js");
|
|
6
|
+
const schemas_js_1 = require("./schemas.js");
|
|
7
|
+
const sign_js_1 = require("./sign.js");
|
|
8
8
|
/**
|
|
9
9
|
* Enables the payment of APIs using the x402 payment protocol.
|
|
10
10
|
*
|
|
@@ -44,7 +44,7 @@ const utils_js_1 = require("../chains/utils.js");
|
|
|
44
44
|
*
|
|
45
45
|
* @bridge x402
|
|
46
46
|
*/
|
|
47
|
-
function wrapFetchWithPayment(fetch,
|
|
47
|
+
function wrapFetchWithPayment(fetch, _client, wallet, maxValue = BigInt(1 * 10 ** 6)) {
|
|
48
48
|
return async (input, init) => {
|
|
49
49
|
const response = await fetch(input, init);
|
|
50
50
|
if (response.status !== 402) {
|
|
@@ -52,7 +52,7 @@ function wrapFetchWithPayment(fetch, client, wallet, maxValue = BigInt(1 * 10 **
|
|
|
52
52
|
}
|
|
53
53
|
const { x402Version, accepts } = (await response.json());
|
|
54
54
|
const parsedPaymentRequirements = accepts
|
|
55
|
-
.map((x) =>
|
|
55
|
+
.map((x) => schemas_js_1.RequestedPaymentRequirementsSchema.parse(x))
|
|
56
56
|
.filter((x) => x.scheme === "exact"); // TODO (402): accept other schemes
|
|
57
57
|
const account = wallet.getAccount();
|
|
58
58
|
let chain = wallet.getChain();
|
|
@@ -63,10 +63,7 @@ function wrapFetchWithPayment(fetch, client, wallet, maxValue = BigInt(1 * 10 **
|
|
|
63
63
|
if (BigInt(selectedPaymentRequirements.maxAmountRequired) > maxValue) {
|
|
64
64
|
throw new Error("Payment amount exceeds maximum allowed");
|
|
65
65
|
}
|
|
66
|
-
const paymentChainId =
|
|
67
|
-
if (!paymentChainId) {
|
|
68
|
-
throw new Error(`No chain found for the selected payment requirement: ${selectedPaymentRequirements.network}`);
|
|
69
|
-
}
|
|
66
|
+
const paymentChainId = (0, schemas_js_1.networkToChainId)(selectedPaymentRequirements.network);
|
|
70
67
|
// switch to the payment chain if it's not the current chain
|
|
71
68
|
if (paymentChainId !== chain.id) {
|
|
72
69
|
await wallet.switchChain((0, utils_js_1.getCachedChain)(paymentChainId));
|
|
@@ -75,12 +72,7 @@ function wrapFetchWithPayment(fetch, client, wallet, maxValue = BigInt(1 * 10 **
|
|
|
75
72
|
throw new Error(`Failed to switch chain (${paymentChainId})`);
|
|
76
73
|
}
|
|
77
74
|
}
|
|
78
|
-
const
|
|
79
|
-
wallet: wallet,
|
|
80
|
-
chain,
|
|
81
|
-
client,
|
|
82
|
-
});
|
|
83
|
-
const paymentHeader = await (0, client_1.createPaymentHeader)(walletClient, x402Version, selectedPaymentRequirements);
|
|
75
|
+
const paymentHeader = await (0, sign_js_1.createPaymentHeader)(account, x402Version, selectedPaymentRequirements);
|
|
84
76
|
const initParams = init || {};
|
|
85
77
|
if (initParams.__is402Retry) {
|
|
86
78
|
throw new Error("Payment already attempted");
|
|
@@ -102,7 +94,7 @@ function defaultPaymentRequirementsSelector(paymentRequirements, chainId, scheme
|
|
|
102
94
|
if (!paymentRequirements.length) {
|
|
103
95
|
throw new Error("No valid payment requirements found in server 402 response");
|
|
104
96
|
}
|
|
105
|
-
const currentWalletNetwork = types_1.ChainIdToNetwork[chainId]
|
|
97
|
+
const currentWalletNetwork = types_1.ChainIdToNetwork[chainId] || `eip155:${chainId}`;
|
|
106
98
|
// find the payment requirements matching the connected wallet chain
|
|
107
99
|
const matchingPaymentRequirements = paymentRequirements.find((x) => x.network === currentWalletNetwork && x.scheme === scheme);
|
|
108
100
|
if (matchingPaymentRequirements) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetchWithPayment.js","sourceRoot":"","sources":["../../../src/x402/fetchWithPayment.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"fetchWithPayment.js","sourceRoot":"","sources":["../../../src/x402/fetchWithPayment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RequestedPaymentRequirementsSchema = exports.RequestedPaymentPayloadSchema = void 0;
|
|
4
|
+
exports.networkToChainId = networkToChainId;
|
|
5
|
+
const types_1 = require("x402/types");
|
|
6
|
+
const zod_1 = require("zod");
|
|
7
|
+
const FacilitatorNetworkSchema = zod_1.z.union([
|
|
8
|
+
zod_1.z.literal("base-sepolia"),
|
|
9
|
+
zod_1.z.literal("base"),
|
|
10
|
+
zod_1.z.literal("avalanche-fuji"),
|
|
11
|
+
zod_1.z.literal("avalanche"),
|
|
12
|
+
zod_1.z.literal("iotex"),
|
|
13
|
+
zod_1.z.literal("solana-devnet"),
|
|
14
|
+
zod_1.z.literal("solana"),
|
|
15
|
+
zod_1.z.literal("sei"),
|
|
16
|
+
zod_1.z.literal("sei-testnet"),
|
|
17
|
+
zod_1.z.string().refine((value) => value.startsWith("eip155:"), {
|
|
18
|
+
message: "Invalid network",
|
|
19
|
+
}),
|
|
20
|
+
]);
|
|
21
|
+
exports.RequestedPaymentPayloadSchema = types_1.PaymentPayloadSchema.extend({
|
|
22
|
+
network: FacilitatorNetworkSchema,
|
|
23
|
+
});
|
|
24
|
+
exports.RequestedPaymentRequirementsSchema = types_1.PaymentRequirementsSchema.extend({
|
|
25
|
+
network: FacilitatorNetworkSchema,
|
|
26
|
+
});
|
|
27
|
+
const FacilitatorSettleResponseSchema = types_1.SettleResponseSchema.extend({
|
|
28
|
+
network: FacilitatorNetworkSchema,
|
|
29
|
+
});
|
|
30
|
+
function networkToChainId(network) {
|
|
31
|
+
if (network.startsWith("eip155:")) {
|
|
32
|
+
const chainId = parseInt(network.split(":")[1] ?? "0");
|
|
33
|
+
if (!Number.isNaN(chainId) && chainId > 0) {
|
|
34
|
+
return chainId;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
throw new Error(`Invalid network: ${network}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const mappedChainId = types_1.EvmNetworkToChainId.get(network);
|
|
41
|
+
if (!mappedChainId) {
|
|
42
|
+
throw new Error(`Invalid network: ${network}`);
|
|
43
|
+
}
|
|
44
|
+
// TODO (402): support solana networks
|
|
45
|
+
if (mappedChainId === 101 || mappedChainId === 103) {
|
|
46
|
+
throw new Error("Solana networks not supported yet.");
|
|
47
|
+
}
|
|
48
|
+
return mappedChainId;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../src/x402/schemas.ts"],"names":[],"mappings":";;;AAyDA,4CAkBC;AA3ED,sCAOoB;AACpB,6BAAwB;AAExB,MAAM,wBAAwB,GAAG,OAAC,CAAC,KAAK,CAAC;IACvC,OAAC,CAAC,OAAO,CAAC,cAAc,CAAC;IACzB,OAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACjB,OAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC;IAC3B,OAAC,CAAC,OAAO,CAAC,WAAW,CAAC;IACtB,OAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IAClB,OAAC,CAAC,OAAO,CAAC,eAAe,CAAC;IAC1B,OAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;IACnB,OAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IAChB,OAAC,CAAC,OAAO,CAAC,aAAa,CAAC;IACxB,OAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE;QACxD,OAAO,EAAE,iBAAiB;KAC3B,CAAC;CACH,CAAC,CAAC;AAIU,QAAA,6BAA6B,GAAG,4BAAoB,CAAC,MAAM,CAAC;IACvE,OAAO,EAAE,wBAAwB;CAClC,CAAC,CAAC;AAYU,QAAA,kCAAkC,GAC7C,iCAAyB,CAAC,MAAM,CAAC;IAC/B,OAAO,EAAE,wBAAwB;CAClC,CAAC,CAAC;AAML,MAAM,+BAA+B,GAAG,4BAAoB,CAAC,MAAM,CAAC;IAClE,OAAO,EAAE,wBAAwB;CAClC,CAAC,CAAC;AAKH,SAAgB,gBAAgB,CAAC,OAAe;IAC9C,IAAI,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;QACvD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YAC1C,OAAO,OAAO,CAAC;QACjB,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IACD,MAAM,aAAa,GAAG,2BAAmB,CAAC,GAAG,CAAC,OAAkB,CAAC,CAAC;IAClE,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,sCAAsC;IACtC,IAAI,aAAa,KAAK,GAAG,IAAI,aAAa,KAAK,GAAG,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.settlePayment = settlePayment;
|
|
4
|
+
const json_js_1 = require("../utils/json.js");
|
|
5
|
+
const common_js_1 = require("./common.js");
|
|
6
|
+
const encode_js_1 = require("./encode.js");
|
|
7
|
+
const types_js_1 = require("./types.js");
|
|
8
|
+
/**
|
|
9
|
+
* Verifies and processes X402 payments for protected resources.
|
|
10
|
+
*
|
|
11
|
+
* This function implements the X402 payment protocol, verifying payment proofs
|
|
12
|
+
* and settling payments through a facilitator service. It handles the complete
|
|
13
|
+
* payment flow from validation to settlement.
|
|
14
|
+
*
|
|
15
|
+
* @param args - Configuration object containing payment verification parameters
|
|
16
|
+
* @returns A promise that resolves to either a successful payment result (200) or payment required error (402)
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
*
|
|
20
|
+
* ### Next.js API route example
|
|
21
|
+
*
|
|
22
|
+
* ```ts
|
|
23
|
+
* // Usage in a Next.js API route
|
|
24
|
+
* import { settlePayment, facilitator } from "thirdweb/x402";
|
|
25
|
+
* import { createThirdwebClient } from "thirdweb";
|
|
26
|
+
*
|
|
27
|
+
* const client = createThirdwebClient({
|
|
28
|
+
* secretKey: process.env.THIRDWEB_SECRET_KEY,
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* const thirdwebFacilitator = facilitator({
|
|
32
|
+
* client,
|
|
33
|
+
* serverWalletAddress: "0x1234567890123456789012345678901234567890",
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* export async function GET(request: Request) {
|
|
37
|
+
* const paymentData = request.headers.get("x-payment");
|
|
38
|
+
*
|
|
39
|
+
* // verify and process the payment
|
|
40
|
+
* const result = await settlePayment({
|
|
41
|
+
* resourceUrl: "https://api.example.com/premium-content",
|
|
42
|
+
* method: "GET",
|
|
43
|
+
* paymentData,
|
|
44
|
+
* payTo: "0x1234567890123456789012345678901234567890",
|
|
45
|
+
* network: "eip155:84532", // CAIP2 format: "eip155:<chain_id>"
|
|
46
|
+
* price: "$0.10", // or { amount: "100000", asset: { address: "0x...", decimals: 6 } }
|
|
47
|
+
* facilitator: thirdwebFacilitator,
|
|
48
|
+
* routeConfig: {
|
|
49
|
+
* description: "Access to premium API content",
|
|
50
|
+
* mimeType: "application/json",
|
|
51
|
+
* maxTimeoutSeconds: 300,
|
|
52
|
+
* },
|
|
53
|
+
* });
|
|
54
|
+
*
|
|
55
|
+
* if (result.status === 200) {
|
|
56
|
+
* // Payment verified and settled successfully
|
|
57
|
+
* return Response.json({ data: "premium content" });
|
|
58
|
+
* } else {
|
|
59
|
+
* // Payment required
|
|
60
|
+
* return Response.json(result.responseBody, {
|
|
61
|
+
* status: result.status,
|
|
62
|
+
* headers: result.responseHeaders,
|
|
63
|
+
* });
|
|
64
|
+
* }
|
|
65
|
+
* }
|
|
66
|
+
* ```
|
|
67
|
+
*
|
|
68
|
+
* ### Express middleware example
|
|
69
|
+
*
|
|
70
|
+
* ```ts
|
|
71
|
+
* // Usage in Express middleware
|
|
72
|
+
* import express from "express";
|
|
73
|
+
* import { settlePayment, facilitator } from "thirdweb/x402";
|
|
74
|
+
* import { createThirdwebClient } from "thirdweb";
|
|
75
|
+
*
|
|
76
|
+
* const client = createThirdwebClient({
|
|
77
|
+
* secretKey: process.env.THIRDWEB_SECRET_KEY,
|
|
78
|
+
* });
|
|
79
|
+
*
|
|
80
|
+
* const thirdwebFacilitator = facilitator({
|
|
81
|
+
* client,
|
|
82
|
+
* serverWalletAddress: "0x1234567890123456789012345678901234567890",
|
|
83
|
+
* });
|
|
84
|
+
*
|
|
85
|
+
* const app = express();
|
|
86
|
+
*
|
|
87
|
+
* async function paymentMiddleware(req, res, next) {
|
|
88
|
+
* // verify and process the payment
|
|
89
|
+
* const result = await settlePayment({
|
|
90
|
+
* resourceUrl: `${req.protocol}://${req.get('host')}${req.originalUrl}`,
|
|
91
|
+
* method: req.method,
|
|
92
|
+
* paymentData: req.headers["x-payment"],
|
|
93
|
+
* payTo: "0x1234567890123456789012345678901234567890",
|
|
94
|
+
* network: "eip155:8453", // CAIP2 format: "eip155:<chain_id>"
|
|
95
|
+
* price: "$0.05",
|
|
96
|
+
* facilitator: thirdwebFacilitator,
|
|
97
|
+
* });
|
|
98
|
+
*
|
|
99
|
+
* if (result.status === 200) {
|
|
100
|
+
* // Set payment receipt headers and continue
|
|
101
|
+
* Object.entries(result.responseHeaders).forEach(([key, value]) => {
|
|
102
|
+
* res.setHeader(key, value);
|
|
103
|
+
* });
|
|
104
|
+
* next();
|
|
105
|
+
* } else {
|
|
106
|
+
* // Return payment required response
|
|
107
|
+
* res.status(result.status)
|
|
108
|
+
* .set(result.responseHeaders)
|
|
109
|
+
* .json(result.responseBody);
|
|
110
|
+
* }
|
|
111
|
+
* }
|
|
112
|
+
*
|
|
113
|
+
* app.get("/api/premium", paymentMiddleware, (req, res) => {
|
|
114
|
+
* res.json({ message: "This is premium content!" });
|
|
115
|
+
* });
|
|
116
|
+
* ```
|
|
117
|
+
*
|
|
118
|
+
* @public
|
|
119
|
+
* @beta
|
|
120
|
+
* @bridge x402
|
|
121
|
+
*/
|
|
122
|
+
async function settlePayment(args) {
|
|
123
|
+
const { routeConfig = {}, facilitator } = args;
|
|
124
|
+
const { errorMessages } = routeConfig;
|
|
125
|
+
const decodePaymentResult = await (0, common_js_1.decodePaymentRequest)(args);
|
|
126
|
+
if (decodePaymentResult.status !== 200) {
|
|
127
|
+
return decodePaymentResult;
|
|
128
|
+
}
|
|
129
|
+
const { selectedPaymentRequirements, decodedPayment, paymentRequirements } = decodePaymentResult;
|
|
130
|
+
// Settle payment
|
|
131
|
+
try {
|
|
132
|
+
const settlement = await facilitator.settle(decodedPayment, selectedPaymentRequirements);
|
|
133
|
+
if (settlement.success) {
|
|
134
|
+
return {
|
|
135
|
+
status: 200,
|
|
136
|
+
paymentReceipt: settlement,
|
|
137
|
+
responseHeaders: {
|
|
138
|
+
"Access-Control-Expose-Headers": "X-PAYMENT-RESPONSE",
|
|
139
|
+
"X-PAYMENT-RESPONSE": (0, encode_js_1.safeBase64Encode)((0, json_js_1.stringify)(settlement)),
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
return {
|
|
145
|
+
status: 402,
|
|
146
|
+
responseHeaders: {
|
|
147
|
+
"Content-Type": "application/json",
|
|
148
|
+
},
|
|
149
|
+
responseBody: {
|
|
150
|
+
x402Version: types_js_1.x402Version,
|
|
151
|
+
error: errorMessages?.settlementFailed ||
|
|
152
|
+
settlement.errorReason ||
|
|
153
|
+
"Settlement failed",
|
|
154
|
+
accepts: paymentRequirements,
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
return {
|
|
161
|
+
status: 402,
|
|
162
|
+
responseHeaders: {
|
|
163
|
+
"Content-Type": "application/json",
|
|
164
|
+
},
|
|
165
|
+
responseBody: {
|
|
166
|
+
x402Version: types_js_1.x402Version,
|
|
167
|
+
error: errorMessages?.settlementFailed ||
|
|
168
|
+
(error instanceof Error ? error.message : "Settlement error"),
|
|
169
|
+
accepts: paymentRequirements,
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=settle-payment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settle-payment.js","sourceRoot":"","sources":["../../../src/x402/settle-payment.ts"],"names":[],"mappings":";;AA2HA,sCA8DC;AAzLD,8CAA6C;AAC7C,2CAAmD;AACnD,2CAA+C;AAC/C,yCAIoB;AAEpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiHG;AACI,KAAK,UAAU,aAAa,CACjC,IAAiB;IAEjB,MAAM,EAAE,WAAW,GAAG,EAAE,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IAC/C,MAAM,EAAE,aAAa,EAAE,GAAG,WAAW,CAAC;IAEtC,MAAM,mBAAmB,GAAG,MAAM,IAAA,gCAAoB,EAAC,IAAI,CAAC,CAAC;IAE7D,IAAI,mBAAmB,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvC,OAAO,mBAAmB,CAAC;IAC7B,CAAC;IAED,MAAM,EAAE,2BAA2B,EAAE,cAAc,EAAE,mBAAmB,EAAE,GACxE,mBAAmB,CAAC;IAEtB,iBAAiB;IACjB,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,WAAW,CAAC,MAAM,CACzC,cAAc,EACd,2BAA2B,CAC5B,CAAC;QAEF,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;YACvB,OAAO;gBACL,MAAM,EAAE,GAAG;gBACX,cAAc,EAAE,UAAU;gBAC1B,eAAe,EAAE;oBACf,+BAA+B,EAAE,oBAAoB;oBACrD,oBAAoB,EAAE,IAAA,4BAAgB,EAAC,IAAA,mBAAS,EAAC,UAAU,CAAC,CAAC;iBAC9D;aACF,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO;gBACL,MAAM,EAAE,GAAG;gBACX,eAAe,EAAE;oBACf,cAAc,EAAE,kBAAkB;iBACnC;gBACD,YAAY,EAAE;oBACZ,WAAW,EAAX,sBAAW;oBACX,KAAK,EACH,aAAa,EAAE,gBAAgB;wBAC/B,UAAU,CAAC,WAAW;wBACtB,mBAAmB;oBACrB,OAAO,EAAE,mBAAmB;iBAC7B;aACF,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,MAAM,EAAE,GAAG;YACX,eAAe,EAAE;gBACf,cAAc,EAAE,kBAAkB;aACnC;YACD,YAAY,EAAE;gBACZ,WAAW,EAAX,sBAAW;gBACX,KAAK,EACH,aAAa,EAAE,gBAAgB;oBAC/B,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC;gBAC/D,OAAO,EAAE,mBAAmB;aAC7B;SACF,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createPaymentHeader = createPaymentHeader;
|
|
4
|
+
const address_js_1 = require("../utils/address.js");
|
|
5
|
+
const hex_js_1 = require("../utils/encoding/hex.js");
|
|
6
|
+
const encode_js_1 = require("./encode.js");
|
|
7
|
+
const schemas_js_1 = require("./schemas.js");
|
|
8
|
+
/**
|
|
9
|
+
* Prepares an unsigned payment header with the given sender address and payment requirements.
|
|
10
|
+
*
|
|
11
|
+
* @param from - The sender's address from which the payment will be made
|
|
12
|
+
* @param x402Version - The version of the X402 protocol to use
|
|
13
|
+
* @param paymentRequirements - The payment requirements containing scheme and network information
|
|
14
|
+
* @returns An unsigned payment payload containing authorization details
|
|
15
|
+
*/
|
|
16
|
+
function preparePaymentHeader(from, x402Version, paymentRequirements) {
|
|
17
|
+
const nonce = createNonce();
|
|
18
|
+
const validAfter = BigInt(Math.floor(Date.now() / 1000) - 600).toString();
|
|
19
|
+
const validBefore = BigInt(Math.floor(Date.now() / 1000 + paymentRequirements.maxTimeoutSeconds)).toString();
|
|
20
|
+
return {
|
|
21
|
+
x402Version,
|
|
22
|
+
scheme: paymentRequirements.scheme,
|
|
23
|
+
network: paymentRequirements.network,
|
|
24
|
+
payload: {
|
|
25
|
+
signature: undefined,
|
|
26
|
+
authorization: {
|
|
27
|
+
from,
|
|
28
|
+
to: paymentRequirements.payTo,
|
|
29
|
+
value: paymentRequirements.maxAmountRequired,
|
|
30
|
+
validAfter: validAfter.toString(),
|
|
31
|
+
validBefore: validBefore.toString(),
|
|
32
|
+
nonce,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Signs a payment header using the provided client and payment requirements.
|
|
39
|
+
*
|
|
40
|
+
* @param client - The signer wallet instance used to sign the payment header
|
|
41
|
+
* @param paymentRequirements - The payment requirements containing scheme and network information
|
|
42
|
+
* @param unsignedPaymentHeader - The unsigned payment payload to be signed
|
|
43
|
+
* @returns A promise that resolves to the signed payment payload
|
|
44
|
+
*/
|
|
45
|
+
async function signPaymentHeader(account, paymentRequirements, unsignedPaymentHeader) {
|
|
46
|
+
const { signature } = await signAuthorization(account, unsignedPaymentHeader.payload.authorization, paymentRequirements);
|
|
47
|
+
return {
|
|
48
|
+
...unsignedPaymentHeader,
|
|
49
|
+
payload: {
|
|
50
|
+
...unsignedPaymentHeader.payload,
|
|
51
|
+
signature,
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Creates a complete payment payload by preparing and signing a payment header.
|
|
57
|
+
*
|
|
58
|
+
* @param client - The signer wallet instance used to create and sign the payment
|
|
59
|
+
* @param x402Version - The version of the X402 protocol to use
|
|
60
|
+
* @param paymentRequirements - The payment requirements containing scheme and network information
|
|
61
|
+
* @returns A promise that resolves to the complete signed payment payload
|
|
62
|
+
*/
|
|
63
|
+
async function createPayment(account, x402Version, paymentRequirements) {
|
|
64
|
+
const from = (0, address_js_1.getAddress)(account.address);
|
|
65
|
+
const unsignedPaymentHeader = preparePaymentHeader(from, x402Version, paymentRequirements);
|
|
66
|
+
return signPaymentHeader(account, paymentRequirements, unsignedPaymentHeader);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Creates and encodes a payment header for the given client and payment requirements.
|
|
70
|
+
*
|
|
71
|
+
* @param client - The signer wallet instance used to create the payment header
|
|
72
|
+
* @param x402Version - The version of the X402 protocol to use
|
|
73
|
+
* @param paymentRequirements - The payment requirements containing scheme and network information
|
|
74
|
+
* @returns A promise that resolves to the encoded payment header string
|
|
75
|
+
*/
|
|
76
|
+
async function createPaymentHeader(account, x402Version, paymentRequirements) {
|
|
77
|
+
const payment = await createPayment(account, x402Version, paymentRequirements);
|
|
78
|
+
return (0, encode_js_1.encodePayment)(payment);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Signs an EIP-3009 authorization for USDC transfer
|
|
82
|
+
*
|
|
83
|
+
* @param walletClient - The wallet client that will sign the authorization
|
|
84
|
+
* @param params - The authorization parameters containing transfer details
|
|
85
|
+
* @param params.from - The address tokens will be transferred from
|
|
86
|
+
* @param params.to - The address tokens will be transferred to
|
|
87
|
+
* @param params.value - The amount of USDC tokens to transfer (in base units)
|
|
88
|
+
* @param params.validAfter - Unix timestamp after which the authorization becomes valid
|
|
89
|
+
* @param params.validBefore - Unix timestamp before which the authorization is valid
|
|
90
|
+
* @param params.nonce - Random 32-byte nonce to prevent replay attacks
|
|
91
|
+
* @param paymentRequirements - The payment requirements containing asset and network information
|
|
92
|
+
* @param paymentRequirements.asset - The address of the USDC contract
|
|
93
|
+
* @param paymentRequirements.network - The network where the USDC contract exists
|
|
94
|
+
* @param paymentRequirements.extra - The extra information containing the name and version of the ERC20 contract
|
|
95
|
+
* @returns The signature for the authorization
|
|
96
|
+
*/
|
|
97
|
+
async function signAuthorization(account, { from, to, value, validAfter, validBefore, nonce, }, { asset, network, extra }) {
|
|
98
|
+
const chainId = (0, schemas_js_1.networkToChainId)(network);
|
|
99
|
+
const name = extra?.name;
|
|
100
|
+
const version = extra?.version;
|
|
101
|
+
// TODO (402): detect permit vs transfer on asset contract
|
|
102
|
+
const data = {
|
|
103
|
+
types: {
|
|
104
|
+
TransferWithAuthorization: [
|
|
105
|
+
{ name: "from", type: "address" },
|
|
106
|
+
{ name: "to", type: "address" },
|
|
107
|
+
{ name: "value", type: "uint256" },
|
|
108
|
+
{ name: "validAfter", type: "uint256" },
|
|
109
|
+
{ name: "validBefore", type: "uint256" },
|
|
110
|
+
{ name: "nonce", type: "bytes32" },
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
domain: {
|
|
114
|
+
name,
|
|
115
|
+
version,
|
|
116
|
+
chainId,
|
|
117
|
+
verifyingContract: (0, address_js_1.getAddress)(asset),
|
|
118
|
+
},
|
|
119
|
+
primaryType: "TransferWithAuthorization",
|
|
120
|
+
message: {
|
|
121
|
+
from: (0, address_js_1.getAddress)(from),
|
|
122
|
+
to: (0, address_js_1.getAddress)(to),
|
|
123
|
+
value,
|
|
124
|
+
validAfter,
|
|
125
|
+
validBefore,
|
|
126
|
+
nonce: nonce,
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
const signature = await account.signTypedData(data);
|
|
130
|
+
return {
|
|
131
|
+
signature,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Generates a random 32-byte nonce for use in authorization signatures
|
|
136
|
+
*
|
|
137
|
+
* @returns A random 32-byte nonce as a hex string
|
|
138
|
+
*/
|
|
139
|
+
function createNonce() {
|
|
140
|
+
const cryptoObj = typeof globalThis.crypto !== "undefined" &&
|
|
141
|
+
typeof globalThis.crypto.getRandomValues === "function"
|
|
142
|
+
? globalThis.crypto
|
|
143
|
+
: // Dynamic require is needed to support node.js
|
|
144
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
145
|
+
require("crypto").webcrypto;
|
|
146
|
+
return (0, hex_js_1.toHex)(cryptoObj.getRandomValues(new Uint8Array(32)));
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=sign.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sign.js","sourceRoot":"","sources":["../../../src/x402/sign.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/x402/types.ts"],"names":[],"mappings":";;;AAea,QAAA,WAAW,GAAG,CAAC,CAAC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.verifyPayment = verifyPayment;
|
|
4
|
+
const common_js_1 = require("./common.js");
|
|
5
|
+
const types_js_1 = require("./types.js");
|
|
6
|
+
/**
|
|
7
|
+
* Verifies X402 payments for protected resources. This function only verifies the payment,
|
|
8
|
+
* you should use `settlePayment` to settle the payment.
|
|
9
|
+
*
|
|
10
|
+
* @param args - Configuration object containing payment verification parameters
|
|
11
|
+
* @returns A promise that resolves to either a successful verification result (200) or payment required error (402)
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* // Usage in a Next.js API route
|
|
16
|
+
* import { verifyPayment, facilitator } from "thirdweb/x402";
|
|
17
|
+
* import { createThirdwebClient } from "thirdweb";
|
|
18
|
+
*
|
|
19
|
+
* const client = createThirdwebClient({
|
|
20
|
+
* secretKey: process.env.THIRDWEB_SECRET_KEY,
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* const thirdwebFacilitator = facilitator({
|
|
24
|
+
* client,
|
|
25
|
+
* serverWalletAddress: "0x1234567890123456789012345678901234567890",
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* export async function GET(request: Request) {
|
|
29
|
+
* const paymentData = request.headers.get("x-payment");
|
|
30
|
+
*
|
|
31
|
+
* const paymentArgs = {
|
|
32
|
+
* resourceUrl: "https://api.example.com/premium-content",
|
|
33
|
+
* method: "GET",
|
|
34
|
+
* paymentData,
|
|
35
|
+
* payTo: "0x1234567890123456789012345678901234567890",
|
|
36
|
+
* network: "eip155:84532", // CAIP2 format: "eip155:<chain_id>"
|
|
37
|
+
* price: "$0.10", // or { amount: "100000", asset: { address: "0x...", decimals: 6 } }
|
|
38
|
+
* facilitator: thirdwebFacilitator,
|
|
39
|
+
* routeConfig: {
|
|
40
|
+
* description: "Access to premium API content",
|
|
41
|
+
* mimeType: "application/json",
|
|
42
|
+
* maxTimeoutSeconds: 300,
|
|
43
|
+
* },
|
|
44
|
+
* };
|
|
45
|
+
*
|
|
46
|
+
* // verify the payment
|
|
47
|
+
* const result = await verifyPayment(paymentArgs);
|
|
48
|
+
*
|
|
49
|
+
* if (result.status === 200) {
|
|
50
|
+
* // Payment verified, but not settled yet
|
|
51
|
+
* // you can do the work that requires payment first
|
|
52
|
+
* const result = await doSomething();
|
|
53
|
+
* // then settle the payment
|
|
54
|
+
* const settleResult = await settlePayment(paymentArgs);
|
|
55
|
+
*
|
|
56
|
+
* // then return the result
|
|
57
|
+
* return Response.json(result);
|
|
58
|
+
* } else {
|
|
59
|
+
* // verification failed, return payment required
|
|
60
|
+
* return Response.json(result.responseBody, {
|
|
61
|
+
* status: result.status,
|
|
62
|
+
* headers: result.responseHeaders,
|
|
63
|
+
* });
|
|
64
|
+
* }
|
|
65
|
+
* }
|
|
66
|
+
* ```
|
|
67
|
+
*
|
|
68
|
+
* @public
|
|
69
|
+
* @beta
|
|
70
|
+
* @bridge x402
|
|
71
|
+
*/
|
|
72
|
+
async function verifyPayment(args) {
|
|
73
|
+
const { routeConfig = {}, facilitator } = args;
|
|
74
|
+
const { errorMessages } = routeConfig;
|
|
75
|
+
const decodePaymentResult = await (0, common_js_1.decodePaymentRequest)(args);
|
|
76
|
+
if (decodePaymentResult.status !== 200) {
|
|
77
|
+
return decodePaymentResult;
|
|
78
|
+
}
|
|
79
|
+
const { selectedPaymentRequirements, decodedPayment, paymentRequirements } = decodePaymentResult;
|
|
80
|
+
// Verify payment
|
|
81
|
+
try {
|
|
82
|
+
const verification = await facilitator.verify(decodedPayment, selectedPaymentRequirements);
|
|
83
|
+
if (verification.isValid) {
|
|
84
|
+
return {
|
|
85
|
+
status: 200,
|
|
86
|
+
decodedPayment,
|
|
87
|
+
selectedPaymentRequirements,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
return {
|
|
92
|
+
status: 402,
|
|
93
|
+
responseHeaders: {
|
|
94
|
+
"Content-Type": "application/json",
|
|
95
|
+
},
|
|
96
|
+
responseBody: {
|
|
97
|
+
x402Version: types_js_1.x402Version,
|
|
98
|
+
error: errorMessages?.verificationFailed ||
|
|
99
|
+
verification.invalidReason ||
|
|
100
|
+
"Verification failed",
|
|
101
|
+
accepts: paymentRequirements,
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
return {
|
|
108
|
+
status: 402,
|
|
109
|
+
responseHeaders: {
|
|
110
|
+
"Content-Type": "application/json",
|
|
111
|
+
},
|
|
112
|
+
responseBody: {
|
|
113
|
+
x402Version: types_js_1.x402Version,
|
|
114
|
+
error: errorMessages?.verificationFailed ||
|
|
115
|
+
(error instanceof Error ? error.message : "Verification error"),
|
|
116
|
+
accepts: paymentRequirements,
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=verify-payment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-payment.js","sourceRoot":"","sources":["../../../src/x402/verify-payment.ts"],"names":[],"mappings":";;AAyEA,sCA2DC;AApID,2CAAmD;AACnD,yCAIoB;AAEpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AACI,KAAK,UAAU,aAAa,CACjC,IAAiB;IAEjB,MAAM,EAAE,WAAW,GAAG,EAAE,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IAC/C,MAAM,EAAE,aAAa,EAAE,GAAG,WAAW,CAAC;IAEtC,MAAM,mBAAmB,GAAG,MAAM,IAAA,gCAAoB,EAAC,IAAI,CAAC,CAAC;IAE7D,IAAI,mBAAmB,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvC,OAAO,mBAAmB,CAAC;IAC7B,CAAC;IAED,MAAM,EAAE,2BAA2B,EAAE,cAAc,EAAE,mBAAmB,EAAE,GACxE,mBAAmB,CAAC;IAEtB,iBAAiB;IACjB,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,MAAM,WAAW,CAAC,MAAM,CAC3C,cAAc,EACd,2BAA2B,CAC5B,CAAC;QAEF,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;YACzB,OAAO;gBACL,MAAM,EAAE,GAAG;gBACX,cAAc;gBACd,2BAA2B;aAC5B,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO;gBACL,MAAM,EAAE,GAAG;gBACX,eAAe,EAAE;oBACf,cAAc,EAAE,kBAAkB;iBACnC;gBACD,YAAY,EAAE;oBACZ,WAAW,EAAX,sBAAW;oBACX,KAAK,EACH,aAAa,EAAE,kBAAkB;wBACjC,YAAY,CAAC,aAAa;wBAC1B,qBAAqB;oBACvB,OAAO,EAAE,mBAAmB;iBAC7B;aACF,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,MAAM,EAAE,GAAG;YACX,eAAe,EAAE;gBACf,cAAc,EAAE,kBAAkB;aACnC;YACD,YAAY,EAAE;gBACZ,WAAW,EAAX,sBAAW;gBACX,KAAK,EACH,aAAa,EAAE,kBAAkB;oBACjC,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC;gBACjE,OAAO,EAAE,mBAAmB;aAC7B;SACF,CAAC;IACJ,CAAC;AACH,CAAC"}
|
package/dist/esm/exports/x402.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
export { decodePayment, encodePayment } from "../x402/encode.js";
|
|
1
2
|
export { facilitator, } from "../x402/facilitator.js";
|
|
2
3
|
export { wrapFetchWithPayment } from "../x402/fetchWithPayment.js";
|
|
4
|
+
export { settlePayment } from "../x402/settle-payment.js";
|
|
5
|
+
export { verifyPayment } from "../x402/verify-payment.js";
|
|
3
6
|
//# sourceMappingURL=x402.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"x402.js","sourceRoot":"","sources":["../../../src/exports/x402.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,GAEZ,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC"}
|
|
1
|
+
{"version":3,"file":"x402.js","sourceRoot":"","sources":["../../../src/exports/x402.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EACL,WAAW,GAEZ,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAM1D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -260,15 +260,9 @@ const DEFAULT_TOKENS = {
|
|
|
260
260
|
symbol: "USDC",
|
|
261
261
|
},
|
|
262
262
|
],
|
|
263
|
-
"
|
|
263
|
+
"421614": [
|
|
264
264
|
{
|
|
265
|
-
address: "
|
|
266
|
-
icon: wrappedEthIcon,
|
|
267
|
-
name: "Wrapped Ether",
|
|
268
|
-
symbol: "WETH",
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
address: "0xfd064A18f3BF249cf1f87FC203E90D8f650f2d63",
|
|
265
|
+
address: "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d",
|
|
272
266
|
icon: usdcIcon,
|
|
273
267
|
name: "USD Coin",
|
|
274
268
|
symbol: "USDC",
|