@wtflabs/x402-fetch 0.0.1-beta.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/README.md +210 -0
- package/dist/cjs/index.d.ts +48 -0
- package/dist/cjs/index.js +111 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/esm/index.d.mts +48 -0
- package/dist/esm/index.mjs +95 -0
- package/dist/esm/index.mjs.map +1 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# x402-fetch
|
|
2
|
+
|
|
3
|
+
A utility package that extends the native `fetch` API to automatically handle 402 Payment Required responses using the x402 payment protocol. This package enables seamless integration of payment functionality into your applications when making HTTP requests.
|
|
4
|
+
|
|
5
|
+
## Supported Authorization Types
|
|
6
|
+
|
|
7
|
+
This package supports multiple EVM authorization standards:
|
|
8
|
+
|
|
9
|
+
- **EIP-3009** (default): `transferWithAuthorization` - gasless token transfers
|
|
10
|
+
- **EIP-2612 Permit**: Standard permit functionality for ERC-20 tokens
|
|
11
|
+
- **Permit2**: Uniswap's universal token approval system
|
|
12
|
+
|
|
13
|
+
The authorization type is automatically selected based on the server's payment requirements (`paymentType` field).
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install x402-fetch
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { createWalletClient, http } from "viem";
|
|
25
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
26
|
+
import { wrapFetchWithPayment } from "x402-fetch";
|
|
27
|
+
import { baseSepolia } from "viem/chains";
|
|
28
|
+
|
|
29
|
+
// Create a wallet client
|
|
30
|
+
const account = privateKeyToAccount("0xYourPrivateKey");
|
|
31
|
+
const client = createWalletClient({
|
|
32
|
+
account,
|
|
33
|
+
transport: http(),
|
|
34
|
+
chain: baseSepolia,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Wrap the fetch function with payment handling
|
|
38
|
+
const fetchWithPay = wrapFetchWithPayment(fetch, client);
|
|
39
|
+
|
|
40
|
+
// Make a request that may require payment
|
|
41
|
+
const response = await fetchWithPay("https://api.example.com/paid-endpoint", {
|
|
42
|
+
method: "GET",
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const data = await response.json();
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 多链支持
|
|
49
|
+
|
|
50
|
+
x402-fetch 现在支持灵活的多 EVM 链配置!使用新的 `createEvmSigner` API:
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { createEvmSigner, wrapFetchWithPayment } from 'x402-fetch';
|
|
54
|
+
|
|
55
|
+
// 方式 1:使用链名称
|
|
56
|
+
const bscSigner = createEvmSigner('bsc', '0xYourPrivateKey');
|
|
57
|
+
|
|
58
|
+
// 方式 2:使用 viem chain 对象
|
|
59
|
+
import { polygon } from 'viem/chains';
|
|
60
|
+
const polygonSigner = createEvmSigner(polygon, '0xYourPrivateKey');
|
|
61
|
+
|
|
62
|
+
// 方式 3:自定义配置(包括自定义 RPC)
|
|
63
|
+
const customSigner = createEvmSigner({
|
|
64
|
+
chainId: 56,
|
|
65
|
+
name: 'BSC',
|
|
66
|
+
rpcUrl: 'https://my-custom-rpc.com',
|
|
67
|
+
}, '0xYourPrivateKey');
|
|
68
|
+
|
|
69
|
+
// 为每条链创建独立的 fetch wrapper
|
|
70
|
+
const fetchBsc = wrapFetchWithPayment(fetch, bscSigner);
|
|
71
|
+
const fetchPolygon = wrapFetchWithPayment(fetch, polygonSigner);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**[📖 查看完整的多链使用指南](./MULTI_CHAIN_USAGE.md)**
|
|
75
|
+
|
|
76
|
+
## API
|
|
77
|
+
|
|
78
|
+
### `wrapFetchWithPayment(fetch, walletClient, maxValue?, paymentRequirementsSelector?)`
|
|
79
|
+
|
|
80
|
+
Wraps the native fetch API to handle 402 Payment Required responses automatically.
|
|
81
|
+
|
|
82
|
+
#### Parameters
|
|
83
|
+
|
|
84
|
+
- `fetch`: The fetch function to wrap (typically `globalThis.fetch`)
|
|
85
|
+
- `walletClient`: The wallet client used to sign payment messages (must implement the x402 wallet interface)
|
|
86
|
+
- `maxValue`: Optional maximum allowed payment amount in base units (defaults to 0.1 USDC)
|
|
87
|
+
- `paymentRequirementsSelector`: Optional function to select payment requirements from the response (defaults to `selectPaymentRequirements`)
|
|
88
|
+
|
|
89
|
+
#### Returns
|
|
90
|
+
|
|
91
|
+
A wrapped fetch function that automatically handles 402 responses by:
|
|
92
|
+
1. Making the initial request
|
|
93
|
+
2. If a 402 response is received, parsing the payment requirements
|
|
94
|
+
3. Verifying the payment amount is within the allowed maximum
|
|
95
|
+
4. Creating a payment header using the provided wallet client
|
|
96
|
+
5. Retrying the request with the payment header
|
|
97
|
+
|
|
98
|
+
## Examples
|
|
99
|
+
|
|
100
|
+
### Basic Usage
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
import { config } from "dotenv";
|
|
104
|
+
import { createWalletClient, http } from "viem";
|
|
105
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
106
|
+
import { wrapFetchWithPayment } from "x402-fetch";
|
|
107
|
+
import { baseSepolia } from "viem/chains";
|
|
108
|
+
|
|
109
|
+
config();
|
|
110
|
+
|
|
111
|
+
const { PRIVATE_KEY, API_URL } = process.env;
|
|
112
|
+
|
|
113
|
+
const account = privateKeyToAccount(PRIVATE_KEY as `0x${string}`);
|
|
114
|
+
const client = createWalletClient({
|
|
115
|
+
account,
|
|
116
|
+
transport: http(),
|
|
117
|
+
chain: baseSepolia,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const fetchWithPay = wrapFetchWithPayment(fetch, client);
|
|
121
|
+
|
|
122
|
+
// Make a request to a paid API endpoint
|
|
123
|
+
fetchWithPay(API_URL, {
|
|
124
|
+
method: "GET",
|
|
125
|
+
})
|
|
126
|
+
.then(async response => {
|
|
127
|
+
const data = await response.json();
|
|
128
|
+
console.log(data);
|
|
129
|
+
})
|
|
130
|
+
.catch(error => {
|
|
131
|
+
console.error(error);
|
|
132
|
+
});
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Server-Side: Specifying Payment Type
|
|
136
|
+
|
|
137
|
+
The server specifies which payment type the client should use in the 402 response:
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
// EIP-2612 Permit example
|
|
141
|
+
app.post("/api/protected", async (c) => {
|
|
142
|
+
const paymentHeader = c.req.header("X-PAYMENT");
|
|
143
|
+
|
|
144
|
+
if (!paymentHeader) {
|
|
145
|
+
return c.json({
|
|
146
|
+
x402Version: 1,
|
|
147
|
+
accepts: [{
|
|
148
|
+
scheme: "exact",
|
|
149
|
+
network: "base-sepolia",
|
|
150
|
+
maxAmountRequired: "100000",
|
|
151
|
+
resource: "http://localhost:3000/api/protected",
|
|
152
|
+
description: "Access to protected resource",
|
|
153
|
+
mimeType: "application/json",
|
|
154
|
+
payTo: "0x...",
|
|
155
|
+
maxTimeoutSeconds: 3600,
|
|
156
|
+
asset: "0x...", // Token address
|
|
157
|
+
paymentType: "permit", // Specify permit
|
|
158
|
+
}]
|
|
159
|
+
}, 402);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Verify and settle payment...
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
// Permit2 example
|
|
168
|
+
app.post("/api/protected", async (c) => {
|
|
169
|
+
const paymentHeader = c.req.header("X-PAYMENT");
|
|
170
|
+
|
|
171
|
+
if (!paymentHeader) {
|
|
172
|
+
return c.json({
|
|
173
|
+
x402Version: 1,
|
|
174
|
+
accepts: [{
|
|
175
|
+
scheme: "exact",
|
|
176
|
+
network: "base-sepolia",
|
|
177
|
+
maxAmountRequired: "100000",
|
|
178
|
+
resource: "http://localhost:3000/api/protected",
|
|
179
|
+
description: "Access to protected resource",
|
|
180
|
+
mimeType: "application/json",
|
|
181
|
+
payTo: "0x...",
|
|
182
|
+
maxTimeoutSeconds: 3600,
|
|
183
|
+
asset: "0x...", // Token address
|
|
184
|
+
paymentType: "permit2", // Specify permit2
|
|
185
|
+
}]
|
|
186
|
+
}, 402);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Verify and settle payment...
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Payment Type Selection
|
|
194
|
+
|
|
195
|
+
The client automatically detects and uses the appropriate payment type:
|
|
196
|
+
|
|
197
|
+
1. **Server specifies `paymentType: "permit"`** → Client uses EIP-2612 Permit
|
|
198
|
+
2. **Server specifies `paymentType: "permit2"`** → Client uses Permit2
|
|
199
|
+
3. **Server specifies `paymentType: "eip3009"` or omits it** → Client uses EIP-3009 (default)
|
|
200
|
+
|
|
201
|
+
### Authorization Type Comparison
|
|
202
|
+
|
|
203
|
+
| Feature | EIP-3009 | EIP-2612 Permit | Permit2 |
|
|
204
|
+
|---------|----------|-----------------|---------|
|
|
205
|
+
| Gas efficiency | High | High | High |
|
|
206
|
+
| Token support | Limited (tokens with EIP-3009) | Wide (most ERC-20) | Universal |
|
|
207
|
+
| Approval management | Per-transaction | Per-spender | Universal router |
|
|
208
|
+
| Nonce management | Custom | On-chain | Advanced |
|
|
209
|
+
| Best for | Specialized tokens | Standard ERC-20 | DeFi integrations |
|
|
210
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Signer, MultiNetworkSigner, X402Config } from 'x402/types';
|
|
2
|
+
export { ConnectedClient, EvmChainConfig, MultiNetworkSigner, Signer, X402Config, createConnectedClient, createSigner, withChain } from 'x402/types';
|
|
3
|
+
import { PaymentRequirementsSelector } from 'x402/client';
|
|
4
|
+
export { PaymentRequirementsSelector } from 'x402/client';
|
|
5
|
+
export { decodeXPaymentResponse } from 'x402/shared';
|
|
6
|
+
export { Chain, Hex } from 'viem';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Enables the payment of APIs using the x402 payment protocol.
|
|
10
|
+
*
|
|
11
|
+
* This function wraps the native fetch API to automatically handle 402 Payment Required responses
|
|
12
|
+
* by creating and sending a payment header. It will:
|
|
13
|
+
* 1. Make the initial request
|
|
14
|
+
* 2. If a 402 response is received, parse the payment requirements
|
|
15
|
+
* 3. Verify the payment amount is within the allowed maximum
|
|
16
|
+
* 4. Create a payment header using the provided wallet client
|
|
17
|
+
* 5. Retry the request with the payment header
|
|
18
|
+
*
|
|
19
|
+
* @param fetch - The fetch function to wrap (typically globalThis.fetch)
|
|
20
|
+
* @param walletClient - The wallet client used to sign payment messages
|
|
21
|
+
* @param maxValue - The maximum allowed payment amount in base units (defaults to 0.1 USDC)
|
|
22
|
+
* @param paymentRequirementsSelector - A function that selects the payment requirements from the response
|
|
23
|
+
* @param config - Optional configuration for X402 operations (e.g., custom RPC URLs)
|
|
24
|
+
* @returns A wrapped fetch function that handles 402 responses automatically
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const wallet = new SignerWallet(...);
|
|
29
|
+
* const fetchWithPay = wrapFetchWithPayment(fetch, wallet);
|
|
30
|
+
*
|
|
31
|
+
* // With custom RPC configuration
|
|
32
|
+
* const fetchWithPay = wrapFetchWithPayment(fetch, wallet, undefined, undefined, {
|
|
33
|
+
* svmConfig: { rpcUrl: "http://localhost:8899" }
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* // Make a request that may require payment
|
|
37
|
+
* const response = await fetchWithPay('https://api.example.com/paid-endpoint');
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @throws {Error} If the payment amount exceeds the maximum allowed value
|
|
41
|
+
* @throws {Error} If the request configuration is missing
|
|
42
|
+
* @throws {Error} If a payment has already been attempted for this request
|
|
43
|
+
* @throws {Error} If there's an error creating the payment header
|
|
44
|
+
*/
|
|
45
|
+
declare function wrapFetchWithPayment(fetch: typeof globalThis.fetch, walletClient: Signer | MultiNetworkSigner, maxValue?: bigint, // Default to 0.10 USDC
|
|
46
|
+
paymentRequirementsSelector?: PaymentRequirementsSelector, config?: X402Config): (input: RequestInfo, init?: RequestInit) => Promise<Response>;
|
|
47
|
+
|
|
48
|
+
export { wrapFetchWithPayment };
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
createConnectedClient: () => import_types2.createConnectedClient,
|
|
24
|
+
createSigner: () => import_types2.createSigner,
|
|
25
|
+
decodeXPaymentResponse: () => import_shared.decodeXPaymentResponse,
|
|
26
|
+
withChain: () => import_types2.withChain,
|
|
27
|
+
wrapFetchWithPayment: () => wrapFetchWithPayment
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(src_exports);
|
|
30
|
+
var import_types = require("x402/types");
|
|
31
|
+
var import_client = require("x402/client");
|
|
32
|
+
var import_schemes = require("x402/schemes");
|
|
33
|
+
var import_shared = require("x402/shared");
|
|
34
|
+
var import_types2 = require("x402/types");
|
|
35
|
+
function wrapFetchWithPayment(fetch, walletClient, maxValue = BigInt(0.1 * 10 ** 6), paymentRequirementsSelector = import_client.selectPaymentRequirements, config) {
|
|
36
|
+
return async (input, init) => {
|
|
37
|
+
var _a;
|
|
38
|
+
const response = await fetch(input, init);
|
|
39
|
+
if (response.status !== 402) {
|
|
40
|
+
return response;
|
|
41
|
+
}
|
|
42
|
+
const { x402Version, accepts } = await response.json();
|
|
43
|
+
const parsedPaymentRequirements = accepts.map((x) => import_types.PaymentRequirementsSchema.parse(x));
|
|
44
|
+
const network = (0, import_types.isMultiNetworkSigner)(walletClient) ? void 0 : import_types.evm.isSignerWallet(walletClient) ? import_types.ChainIdToNetwork[(_a = walletClient.chain) == null ? void 0 : _a.id] : (0, import_types.isSvmSignerWallet)(walletClient) ? ["solana", "solana-devnet"] : void 0;
|
|
45
|
+
const selectedPaymentRequirements = paymentRequirementsSelector(
|
|
46
|
+
parsedPaymentRequirements,
|
|
47
|
+
network,
|
|
48
|
+
"exact"
|
|
49
|
+
);
|
|
50
|
+
if (BigInt(selectedPaymentRequirements.maxAmountRequired) > maxValue) {
|
|
51
|
+
throw new Error("Payment amount exceeds maximum allowed");
|
|
52
|
+
}
|
|
53
|
+
const paymentType = selectedPaymentRequirements.paymentType || "eip3009";
|
|
54
|
+
let paymentHeader;
|
|
55
|
+
const isEvmNetwork = network && !["solana", "solana-devnet"].includes(network[0]);
|
|
56
|
+
if (paymentType === "permit" && isEvmNetwork) {
|
|
57
|
+
if (!import_types.evm.isSignerWallet(walletClient)) {
|
|
58
|
+
throw new Error("Permit authorization requires an EVM signer wallet");
|
|
59
|
+
}
|
|
60
|
+
paymentHeader = await import_schemes.exact.evm.permit.createPaymentHeader(
|
|
61
|
+
walletClient,
|
|
62
|
+
x402Version,
|
|
63
|
+
selectedPaymentRequirements
|
|
64
|
+
);
|
|
65
|
+
} else if (paymentType === "permit2" && isEvmNetwork) {
|
|
66
|
+
if (!import_types.evm.isSignerWallet(walletClient)) {
|
|
67
|
+
throw new Error("Permit2 authorization requires an EVM signer wallet");
|
|
68
|
+
}
|
|
69
|
+
paymentHeader = await import_schemes.exact.evm.permit2.createPaymentHeader(
|
|
70
|
+
walletClient,
|
|
71
|
+
x402Version,
|
|
72
|
+
selectedPaymentRequirements
|
|
73
|
+
);
|
|
74
|
+
} else if (paymentType === "eip3009" || !paymentType) {
|
|
75
|
+
paymentHeader = await (0, import_client.createPaymentHeader)(
|
|
76
|
+
walletClient,
|
|
77
|
+
x402Version,
|
|
78
|
+
selectedPaymentRequirements,
|
|
79
|
+
config
|
|
80
|
+
);
|
|
81
|
+
} else {
|
|
82
|
+
throw new Error(`Unsupported payment type: ${paymentType}`);
|
|
83
|
+
}
|
|
84
|
+
if (!init) {
|
|
85
|
+
throw new Error("Missing fetch request configuration");
|
|
86
|
+
}
|
|
87
|
+
if (init.__is402Retry) {
|
|
88
|
+
throw new Error("Payment already attempted");
|
|
89
|
+
}
|
|
90
|
+
const newInit = {
|
|
91
|
+
...init,
|
|
92
|
+
headers: {
|
|
93
|
+
...init.headers || {},
|
|
94
|
+
"X-PAYMENT": paymentHeader,
|
|
95
|
+
"Access-Control-Expose-Headers": "X-PAYMENT-RESPONSE"
|
|
96
|
+
},
|
|
97
|
+
__is402Retry: true
|
|
98
|
+
};
|
|
99
|
+
const secondResponse = await fetch(input, newInit);
|
|
100
|
+
return secondResponse;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
104
|
+
0 && (module.exports = {
|
|
105
|
+
createConnectedClient,
|
|
106
|
+
createSigner,
|
|
107
|
+
decodeXPaymentResponse,
|
|
108
|
+
withChain,
|
|
109
|
+
wrapFetchWithPayment
|
|
110
|
+
});
|
|
111
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["import {\n ChainIdToNetwork,\n PaymentRequirementsSchema,\n Signer,\n evm,\n MultiNetworkSigner,\n isMultiNetworkSigner,\n isSvmSignerWallet,\n Network,\n X402Config,\n} from \"x402/types\";\nimport {\n createPaymentHeader,\n PaymentRequirementsSelector,\n selectPaymentRequirements,\n} from \"x402/client\";\nimport { exact } from \"x402/schemes\";\n\n/**\n * Enables the payment of APIs using the x402 payment protocol.\n *\n * This function wraps the native fetch API to automatically handle 402 Payment Required responses\n * by creating and sending a payment header. It will:\n * 1. Make the initial request\n * 2. If a 402 response is received, parse the payment requirements\n * 3. Verify the payment amount is within the allowed maximum\n * 4. Create a payment header using the provided wallet client\n * 5. Retry the request with the payment header\n *\n * @param fetch - The fetch function to wrap (typically globalThis.fetch)\n * @param walletClient - The wallet client used to sign payment messages\n * @param maxValue - The maximum allowed payment amount in base units (defaults to 0.1 USDC)\n * @param paymentRequirementsSelector - A function that selects the payment requirements from the response\n * @param config - Optional configuration for X402 operations (e.g., custom RPC URLs)\n * @returns A wrapped fetch function that handles 402 responses automatically\n *\n * @example\n * ```typescript\n * const wallet = new SignerWallet(...);\n * const fetchWithPay = wrapFetchWithPayment(fetch, wallet);\n *\n * // With custom RPC configuration\n * const fetchWithPay = wrapFetchWithPayment(fetch, wallet, undefined, undefined, {\n * svmConfig: { rpcUrl: \"http://localhost:8899\" }\n * });\n *\n * // Make a request that may require payment\n * const response = await fetchWithPay('https://api.example.com/paid-endpoint');\n * ```\n *\n * @throws {Error} If the payment amount exceeds the maximum allowed value\n * @throws {Error} If the request configuration is missing\n * @throws {Error} If a payment has already been attempted for this request\n * @throws {Error} If there's an error creating the payment header\n */\nexport function wrapFetchWithPayment(\n fetch: typeof globalThis.fetch,\n walletClient: Signer | MultiNetworkSigner,\n maxValue: bigint = BigInt(0.1 * 10 ** 6), // Default to 0.10 USDC\n paymentRequirementsSelector: PaymentRequirementsSelector = selectPaymentRequirements,\n config?: X402Config,\n) {\n return async (input: RequestInfo, init?: RequestInit) => {\n const response = await fetch(input, init);\n\n if (response.status !== 402) {\n return response;\n }\n\n const { x402Version, accepts } = (await response.json()) as {\n x402Version: number;\n accepts: unknown[];\n };\n const parsedPaymentRequirements = accepts.map(x => PaymentRequirementsSchema.parse(x));\n\n const network = isMultiNetworkSigner(walletClient)\n ? undefined\n : evm.isSignerWallet(walletClient as typeof evm.EvmSigner)\n ? ChainIdToNetwork[(walletClient as typeof evm.EvmSigner).chain?.id]\n : isSvmSignerWallet(walletClient)\n ? ([\"solana\", \"solana-devnet\"] as Network[])\n : undefined;\n\n const selectedPaymentRequirements = paymentRequirementsSelector(\n parsedPaymentRequirements,\n network,\n \"exact\",\n );\n\n if (BigInt(selectedPaymentRequirements.maxAmountRequired) > maxValue) {\n throw new Error(\"Payment amount exceeds maximum allowed\");\n }\n\n // 获取支付类型,默认为 eip3009\n const paymentType = selectedPaymentRequirements.paymentType || \"eip3009\";\n\n // 根据支付类型创建支付头\n let paymentHeader: string;\n\n // 仅对 EVM 网络支持 permit 和 permit2\n const isEvmNetwork = network && ![\"solana\", \"solana-devnet\"].includes(network[0]);\n\n if (paymentType === \"permit\" && isEvmNetwork) {\n // 使用 EIP-2612 Permit\n if (!evm.isSignerWallet(walletClient as typeof evm.EvmSigner)) {\n throw new Error(\"Permit authorization requires an EVM signer wallet\");\n }\n paymentHeader = await exact.evm.permit.createPaymentHeader(\n walletClient as typeof evm.EvmSigner,\n x402Version,\n selectedPaymentRequirements,\n );\n } else if (paymentType === \"permit2\" && isEvmNetwork) {\n // 使用 Permit2\n if (!evm.isSignerWallet(walletClient as typeof evm.EvmSigner)) {\n throw new Error(\"Permit2 authorization requires an EVM signer wallet\");\n }\n paymentHeader = await exact.evm.permit2.createPaymentHeader(\n walletClient as typeof evm.EvmSigner,\n x402Version,\n selectedPaymentRequirements,\n );\n } else if (paymentType === \"eip3009\" || !paymentType) {\n // 默认使用 EIP-3009(统一的 createPaymentHeader)\n paymentHeader = await createPaymentHeader(\n walletClient,\n x402Version,\n selectedPaymentRequirements,\n config,\n );\n } else {\n throw new Error(`Unsupported payment type: ${paymentType}`);\n }\n\n if (!init) {\n throw new Error(\"Missing fetch request configuration\");\n }\n\n if ((init as { __is402Retry?: boolean }).__is402Retry) {\n throw new Error(\"Payment already attempted\");\n }\n\n const newInit = {\n ...init,\n headers: {\n ...(init.headers || {}),\n \"X-PAYMENT\": paymentHeader,\n \"Access-Control-Expose-Headers\": \"X-PAYMENT-RESPONSE\",\n },\n __is402Retry: true,\n };\n\n const secondResponse = await fetch(input, newInit);\n return secondResponse;\n };\n}\n\nexport { decodeXPaymentResponse } from \"x402/shared\";\nexport {\n createSigner,\n createConnectedClient,\n withChain,\n type Signer,\n type ConnectedClient,\n type MultiNetworkSigner,\n type X402Config,\n type EvmChainConfig\n} from \"x402/types\";\nexport { type PaymentRequirementsSelector } from \"x402/client\";\nexport type { Hex, Chain } from \"viem\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAUO;AACP,oBAIO;AACP,qBAAsB;AA6ItB,oBAAuC;AACvC,IAAAA,gBASO;AAhHA,SAAS,qBACd,OACA,cACA,WAAmB,OAAO,MAAM,MAAM,CAAC,GACvC,8BAA2D,yCAC3D,QACA;AACA,SAAO,OAAO,OAAoB,SAAuB;AA9D3D;AA+DI,UAAM,WAAW,MAAM,MAAM,OAAO,IAAI;AAExC,QAAI,SAAS,WAAW,KAAK;AAC3B,aAAO;AAAA,IACT;AAEA,UAAM,EAAE,aAAa,QAAQ,IAAK,MAAM,SAAS,KAAK;AAItD,UAAM,4BAA4B,QAAQ,IAAI,OAAK,uCAA0B,MAAM,CAAC,CAAC;AAErF,UAAM,cAAU,mCAAqB,YAAY,IAC7C,SACA,iBAAI,eAAe,YAAoC,IACrD,+BAAkB,kBAAsC,UAAtC,mBAA6C,EAAE,QACjE,gCAAkB,YAAY,IAC3B,CAAC,UAAU,eAAe,IAC3B;AAER,UAAM,8BAA8B;AAAA,MAClC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,QAAI,OAAO,4BAA4B,iBAAiB,IAAI,UAAU;AACpE,YAAM,IAAI,MAAM,wCAAwC;AAAA,IAC1D;AAGA,UAAM,cAAc,4BAA4B,eAAe;AAG/D,QAAI;AAGJ,UAAM,eAAe,WAAW,CAAC,CAAC,UAAU,eAAe,EAAE,SAAS,QAAQ,CAAC,CAAC;AAEhF,QAAI,gBAAgB,YAAY,cAAc;AAE5C,UAAI,CAAC,iBAAI,eAAe,YAAoC,GAAG;AAC7D,cAAM,IAAI,MAAM,oDAAoD;AAAA,MACtE;AACA,sBAAgB,MAAM,qBAAM,IAAI,OAAO;AAAA,QACrC;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,WAAW,gBAAgB,aAAa,cAAc;AAEpD,UAAI,CAAC,iBAAI,eAAe,YAAoC,GAAG;AAC7D,cAAM,IAAI,MAAM,qDAAqD;AAAA,MACvE;AACA,sBAAgB,MAAM,qBAAM,IAAI,QAAQ;AAAA,QACtC;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,WAAW,gBAAgB,aAAa,CAAC,aAAa;AAEpD,sBAAgB,UAAM;AAAA,QACpB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AACL,YAAM,IAAI,MAAM,6BAA6B,WAAW,EAAE;AAAA,IAC5D;AAEA,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,qCAAqC;AAAA,IACvD;AAEA,QAAK,KAAoC,cAAc;AACrD,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AAEA,UAAM,UAAU;AAAA,MACd,GAAG;AAAA,MACH,SAAS;AAAA,QACP,GAAI,KAAK,WAAW,CAAC;AAAA,QACrB,aAAa;AAAA,QACb,iCAAiC;AAAA,MACnC;AAAA,MACA,cAAc;AAAA,IAChB;AAEA,UAAM,iBAAiB,MAAM,MAAM,OAAO,OAAO;AACjD,WAAO;AAAA,EACT;AACF;","names":["import_types"]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Signer, MultiNetworkSigner, X402Config } from 'x402/types';
|
|
2
|
+
export { ConnectedClient, EvmChainConfig, MultiNetworkSigner, Signer, X402Config, createConnectedClient, createSigner, withChain } from 'x402/types';
|
|
3
|
+
import { PaymentRequirementsSelector } from 'x402/client';
|
|
4
|
+
export { PaymentRequirementsSelector } from 'x402/client';
|
|
5
|
+
export { decodeXPaymentResponse } from 'x402/shared';
|
|
6
|
+
export { Chain, Hex } from 'viem';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Enables the payment of APIs using the x402 payment protocol.
|
|
10
|
+
*
|
|
11
|
+
* This function wraps the native fetch API to automatically handle 402 Payment Required responses
|
|
12
|
+
* by creating and sending a payment header. It will:
|
|
13
|
+
* 1. Make the initial request
|
|
14
|
+
* 2. If a 402 response is received, parse the payment requirements
|
|
15
|
+
* 3. Verify the payment amount is within the allowed maximum
|
|
16
|
+
* 4. Create a payment header using the provided wallet client
|
|
17
|
+
* 5. Retry the request with the payment header
|
|
18
|
+
*
|
|
19
|
+
* @param fetch - The fetch function to wrap (typically globalThis.fetch)
|
|
20
|
+
* @param walletClient - The wallet client used to sign payment messages
|
|
21
|
+
* @param maxValue - The maximum allowed payment amount in base units (defaults to 0.1 USDC)
|
|
22
|
+
* @param paymentRequirementsSelector - A function that selects the payment requirements from the response
|
|
23
|
+
* @param config - Optional configuration for X402 operations (e.g., custom RPC URLs)
|
|
24
|
+
* @returns A wrapped fetch function that handles 402 responses automatically
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const wallet = new SignerWallet(...);
|
|
29
|
+
* const fetchWithPay = wrapFetchWithPayment(fetch, wallet);
|
|
30
|
+
*
|
|
31
|
+
* // With custom RPC configuration
|
|
32
|
+
* const fetchWithPay = wrapFetchWithPayment(fetch, wallet, undefined, undefined, {
|
|
33
|
+
* svmConfig: { rpcUrl: "http://localhost:8899" }
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* // Make a request that may require payment
|
|
37
|
+
* const response = await fetchWithPay('https://api.example.com/paid-endpoint');
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @throws {Error} If the payment amount exceeds the maximum allowed value
|
|
41
|
+
* @throws {Error} If the request configuration is missing
|
|
42
|
+
* @throws {Error} If a payment has already been attempted for this request
|
|
43
|
+
* @throws {Error} If there's an error creating the payment header
|
|
44
|
+
*/
|
|
45
|
+
declare function wrapFetchWithPayment(fetch: typeof globalThis.fetch, walletClient: Signer | MultiNetworkSigner, maxValue?: bigint, // Default to 0.10 USDC
|
|
46
|
+
paymentRequirementsSelector?: PaymentRequirementsSelector, config?: X402Config): (input: RequestInfo, init?: RequestInit) => Promise<Response>;
|
|
47
|
+
|
|
48
|
+
export { wrapFetchWithPayment };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import {
|
|
3
|
+
ChainIdToNetwork,
|
|
4
|
+
PaymentRequirementsSchema,
|
|
5
|
+
evm,
|
|
6
|
+
isMultiNetworkSigner,
|
|
7
|
+
isSvmSignerWallet
|
|
8
|
+
} from "x402/types";
|
|
9
|
+
import {
|
|
10
|
+
createPaymentHeader,
|
|
11
|
+
selectPaymentRequirements
|
|
12
|
+
} from "x402/client";
|
|
13
|
+
import { exact } from "x402/schemes";
|
|
14
|
+
import { decodeXPaymentResponse } from "x402/shared";
|
|
15
|
+
import {
|
|
16
|
+
createSigner,
|
|
17
|
+
createConnectedClient,
|
|
18
|
+
withChain
|
|
19
|
+
} from "x402/types";
|
|
20
|
+
function wrapFetchWithPayment(fetch, walletClient, maxValue = BigInt(0.1 * 10 ** 6), paymentRequirementsSelector = selectPaymentRequirements, config) {
|
|
21
|
+
return async (input, init) => {
|
|
22
|
+
var _a;
|
|
23
|
+
const response = await fetch(input, init);
|
|
24
|
+
if (response.status !== 402) {
|
|
25
|
+
return response;
|
|
26
|
+
}
|
|
27
|
+
const { x402Version, accepts } = await response.json();
|
|
28
|
+
const parsedPaymentRequirements = accepts.map((x) => PaymentRequirementsSchema.parse(x));
|
|
29
|
+
const network = isMultiNetworkSigner(walletClient) ? void 0 : evm.isSignerWallet(walletClient) ? ChainIdToNetwork[(_a = walletClient.chain) == null ? void 0 : _a.id] : isSvmSignerWallet(walletClient) ? ["solana", "solana-devnet"] : void 0;
|
|
30
|
+
const selectedPaymentRequirements = paymentRequirementsSelector(
|
|
31
|
+
parsedPaymentRequirements,
|
|
32
|
+
network,
|
|
33
|
+
"exact"
|
|
34
|
+
);
|
|
35
|
+
if (BigInt(selectedPaymentRequirements.maxAmountRequired) > maxValue) {
|
|
36
|
+
throw new Error("Payment amount exceeds maximum allowed");
|
|
37
|
+
}
|
|
38
|
+
const paymentType = selectedPaymentRequirements.paymentType || "eip3009";
|
|
39
|
+
let paymentHeader;
|
|
40
|
+
const isEvmNetwork = network && !["solana", "solana-devnet"].includes(network[0]);
|
|
41
|
+
if (paymentType === "permit" && isEvmNetwork) {
|
|
42
|
+
if (!evm.isSignerWallet(walletClient)) {
|
|
43
|
+
throw new Error("Permit authorization requires an EVM signer wallet");
|
|
44
|
+
}
|
|
45
|
+
paymentHeader = await exact.evm.permit.createPaymentHeader(
|
|
46
|
+
walletClient,
|
|
47
|
+
x402Version,
|
|
48
|
+
selectedPaymentRequirements
|
|
49
|
+
);
|
|
50
|
+
} else if (paymentType === "permit2" && isEvmNetwork) {
|
|
51
|
+
if (!evm.isSignerWallet(walletClient)) {
|
|
52
|
+
throw new Error("Permit2 authorization requires an EVM signer wallet");
|
|
53
|
+
}
|
|
54
|
+
paymentHeader = await exact.evm.permit2.createPaymentHeader(
|
|
55
|
+
walletClient,
|
|
56
|
+
x402Version,
|
|
57
|
+
selectedPaymentRequirements
|
|
58
|
+
);
|
|
59
|
+
} else if (paymentType === "eip3009" || !paymentType) {
|
|
60
|
+
paymentHeader = await createPaymentHeader(
|
|
61
|
+
walletClient,
|
|
62
|
+
x402Version,
|
|
63
|
+
selectedPaymentRequirements,
|
|
64
|
+
config
|
|
65
|
+
);
|
|
66
|
+
} else {
|
|
67
|
+
throw new Error(`Unsupported payment type: ${paymentType}`);
|
|
68
|
+
}
|
|
69
|
+
if (!init) {
|
|
70
|
+
throw new Error("Missing fetch request configuration");
|
|
71
|
+
}
|
|
72
|
+
if (init.__is402Retry) {
|
|
73
|
+
throw new Error("Payment already attempted");
|
|
74
|
+
}
|
|
75
|
+
const newInit = {
|
|
76
|
+
...init,
|
|
77
|
+
headers: {
|
|
78
|
+
...init.headers || {},
|
|
79
|
+
"X-PAYMENT": paymentHeader,
|
|
80
|
+
"Access-Control-Expose-Headers": "X-PAYMENT-RESPONSE"
|
|
81
|
+
},
|
|
82
|
+
__is402Retry: true
|
|
83
|
+
};
|
|
84
|
+
const secondResponse = await fetch(input, newInit);
|
|
85
|
+
return secondResponse;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
export {
|
|
89
|
+
createConnectedClient,
|
|
90
|
+
createSigner,
|
|
91
|
+
decodeXPaymentResponse,
|
|
92
|
+
withChain,
|
|
93
|
+
wrapFetchWithPayment
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["import {\n ChainIdToNetwork,\n PaymentRequirementsSchema,\n Signer,\n evm,\n MultiNetworkSigner,\n isMultiNetworkSigner,\n isSvmSignerWallet,\n Network,\n X402Config,\n} from \"x402/types\";\nimport {\n createPaymentHeader,\n PaymentRequirementsSelector,\n selectPaymentRequirements,\n} from \"x402/client\";\nimport { exact } from \"x402/schemes\";\n\n/**\n * Enables the payment of APIs using the x402 payment protocol.\n *\n * This function wraps the native fetch API to automatically handle 402 Payment Required responses\n * by creating and sending a payment header. It will:\n * 1. Make the initial request\n * 2. If a 402 response is received, parse the payment requirements\n * 3. Verify the payment amount is within the allowed maximum\n * 4. Create a payment header using the provided wallet client\n * 5. Retry the request with the payment header\n *\n * @param fetch - The fetch function to wrap (typically globalThis.fetch)\n * @param walletClient - The wallet client used to sign payment messages\n * @param maxValue - The maximum allowed payment amount in base units (defaults to 0.1 USDC)\n * @param paymentRequirementsSelector - A function that selects the payment requirements from the response\n * @param config - Optional configuration for X402 operations (e.g., custom RPC URLs)\n * @returns A wrapped fetch function that handles 402 responses automatically\n *\n * @example\n * ```typescript\n * const wallet = new SignerWallet(...);\n * const fetchWithPay = wrapFetchWithPayment(fetch, wallet);\n *\n * // With custom RPC configuration\n * const fetchWithPay = wrapFetchWithPayment(fetch, wallet, undefined, undefined, {\n * svmConfig: { rpcUrl: \"http://localhost:8899\" }\n * });\n *\n * // Make a request that may require payment\n * const response = await fetchWithPay('https://api.example.com/paid-endpoint');\n * ```\n *\n * @throws {Error} If the payment amount exceeds the maximum allowed value\n * @throws {Error} If the request configuration is missing\n * @throws {Error} If a payment has already been attempted for this request\n * @throws {Error} If there's an error creating the payment header\n */\nexport function wrapFetchWithPayment(\n fetch: typeof globalThis.fetch,\n walletClient: Signer | MultiNetworkSigner,\n maxValue: bigint = BigInt(0.1 * 10 ** 6), // Default to 0.10 USDC\n paymentRequirementsSelector: PaymentRequirementsSelector = selectPaymentRequirements,\n config?: X402Config,\n) {\n return async (input: RequestInfo, init?: RequestInit) => {\n const response = await fetch(input, init);\n\n if (response.status !== 402) {\n return response;\n }\n\n const { x402Version, accepts } = (await response.json()) as {\n x402Version: number;\n accepts: unknown[];\n };\n const parsedPaymentRequirements = accepts.map(x => PaymentRequirementsSchema.parse(x));\n\n const network = isMultiNetworkSigner(walletClient)\n ? undefined\n : evm.isSignerWallet(walletClient as typeof evm.EvmSigner)\n ? ChainIdToNetwork[(walletClient as typeof evm.EvmSigner).chain?.id]\n : isSvmSignerWallet(walletClient)\n ? ([\"solana\", \"solana-devnet\"] as Network[])\n : undefined;\n\n const selectedPaymentRequirements = paymentRequirementsSelector(\n parsedPaymentRequirements,\n network,\n \"exact\",\n );\n\n if (BigInt(selectedPaymentRequirements.maxAmountRequired) > maxValue) {\n throw new Error(\"Payment amount exceeds maximum allowed\");\n }\n\n // 获取支付类型,默认为 eip3009\n const paymentType = selectedPaymentRequirements.paymentType || \"eip3009\";\n\n // 根据支付类型创建支付头\n let paymentHeader: string;\n\n // 仅对 EVM 网络支持 permit 和 permit2\n const isEvmNetwork = network && ![\"solana\", \"solana-devnet\"].includes(network[0]);\n\n if (paymentType === \"permit\" && isEvmNetwork) {\n // 使用 EIP-2612 Permit\n if (!evm.isSignerWallet(walletClient as typeof evm.EvmSigner)) {\n throw new Error(\"Permit authorization requires an EVM signer wallet\");\n }\n paymentHeader = await exact.evm.permit.createPaymentHeader(\n walletClient as typeof evm.EvmSigner,\n x402Version,\n selectedPaymentRequirements,\n );\n } else if (paymentType === \"permit2\" && isEvmNetwork) {\n // 使用 Permit2\n if (!evm.isSignerWallet(walletClient as typeof evm.EvmSigner)) {\n throw new Error(\"Permit2 authorization requires an EVM signer wallet\");\n }\n paymentHeader = await exact.evm.permit2.createPaymentHeader(\n walletClient as typeof evm.EvmSigner,\n x402Version,\n selectedPaymentRequirements,\n );\n } else if (paymentType === \"eip3009\" || !paymentType) {\n // 默认使用 EIP-3009(统一的 createPaymentHeader)\n paymentHeader = await createPaymentHeader(\n walletClient,\n x402Version,\n selectedPaymentRequirements,\n config,\n );\n } else {\n throw new Error(`Unsupported payment type: ${paymentType}`);\n }\n\n if (!init) {\n throw new Error(\"Missing fetch request configuration\");\n }\n\n if ((init as { __is402Retry?: boolean }).__is402Retry) {\n throw new Error(\"Payment already attempted\");\n }\n\n const newInit = {\n ...init,\n headers: {\n ...(init.headers || {}),\n \"X-PAYMENT\": paymentHeader,\n \"Access-Control-Expose-Headers\": \"X-PAYMENT-RESPONSE\",\n },\n __is402Retry: true,\n };\n\n const secondResponse = await fetch(input, newInit);\n return secondResponse;\n };\n}\n\nexport { decodeXPaymentResponse } from \"x402/shared\";\nexport {\n createSigner,\n createConnectedClient,\n withChain,\n type Signer,\n type ConnectedClient,\n type MultiNetworkSigner,\n type X402Config,\n type EvmChainConfig\n} from \"x402/types\";\nexport { type PaymentRequirementsSelector } from \"x402/client\";\nexport type { Hex, Chain } from \"viem\";\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EAEA;AAAA,EAEA;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EAEA;AAAA,OACK;AACP,SAAS,aAAa;AA6ItB,SAAS,8BAA8B;AACvC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAMK;AAhHA,SAAS,qBACd,OACA,cACA,WAAmB,OAAO,MAAM,MAAM,CAAC,GACvC,8BAA2D,2BAC3D,QACA;AACA,SAAO,OAAO,OAAoB,SAAuB;AA9D3D;AA+DI,UAAM,WAAW,MAAM,MAAM,OAAO,IAAI;AAExC,QAAI,SAAS,WAAW,KAAK;AAC3B,aAAO;AAAA,IACT;AAEA,UAAM,EAAE,aAAa,QAAQ,IAAK,MAAM,SAAS,KAAK;AAItD,UAAM,4BAA4B,QAAQ,IAAI,OAAK,0BAA0B,MAAM,CAAC,CAAC;AAErF,UAAM,UAAU,qBAAqB,YAAY,IAC7C,SACA,IAAI,eAAe,YAAoC,IACrD,kBAAkB,kBAAsC,UAAtC,mBAA6C,EAAE,IACjE,kBAAkB,YAAY,IAC3B,CAAC,UAAU,eAAe,IAC3B;AAER,UAAM,8BAA8B;AAAA,MAClC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,QAAI,OAAO,4BAA4B,iBAAiB,IAAI,UAAU;AACpE,YAAM,IAAI,MAAM,wCAAwC;AAAA,IAC1D;AAGA,UAAM,cAAc,4BAA4B,eAAe;AAG/D,QAAI;AAGJ,UAAM,eAAe,WAAW,CAAC,CAAC,UAAU,eAAe,EAAE,SAAS,QAAQ,CAAC,CAAC;AAEhF,QAAI,gBAAgB,YAAY,cAAc;AAE5C,UAAI,CAAC,IAAI,eAAe,YAAoC,GAAG;AAC7D,cAAM,IAAI,MAAM,oDAAoD;AAAA,MACtE;AACA,sBAAgB,MAAM,MAAM,IAAI,OAAO;AAAA,QACrC;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,WAAW,gBAAgB,aAAa,cAAc;AAEpD,UAAI,CAAC,IAAI,eAAe,YAAoC,GAAG;AAC7D,cAAM,IAAI,MAAM,qDAAqD;AAAA,MACvE;AACA,sBAAgB,MAAM,MAAM,IAAI,QAAQ;AAAA,QACtC;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,WAAW,gBAAgB,aAAa,CAAC,aAAa;AAEpD,sBAAgB,MAAM;AAAA,QACpB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AACL,YAAM,IAAI,MAAM,6BAA6B,WAAW,EAAE;AAAA,IAC5D;AAEA,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,qCAAqC;AAAA,IACvD;AAEA,QAAK,KAAoC,cAAc;AACrD,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AAEA,UAAM,UAAU;AAAA,MACd,GAAG;AAAA,MACH,SAAS;AAAA,QACP,GAAI,KAAK,WAAW,CAAC;AAAA,QACrB,aAAa;AAAA,QACb,iCAAiC;AAAA,MACnC;AAAA,MACA,cAAc;AAAA,IAChB;AAEA,UAAM,iBAAiB,MAAM,MAAM,OAAO,OAAO;AACjD,WAAO;AAAA,EACT;AACF;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@wtflabs/x402-fetch",
|
|
3
|
+
"version": "0.0.1-beta.0",
|
|
4
|
+
"main": "./dist/cjs/index.js",
|
|
5
|
+
"module": "./dist/esm/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"start": "tsx --env-file=.env index.ts",
|
|
9
|
+
"test": "vitest run",
|
|
10
|
+
"test:watch": "vitest",
|
|
11
|
+
"build": "tsup",
|
|
12
|
+
"watch": "tsc --watch",
|
|
13
|
+
"format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"",
|
|
14
|
+
"format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"",
|
|
15
|
+
"lint": "eslint . --ext .ts --fix",
|
|
16
|
+
"lint:check": "eslint . --ext .ts"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [],
|
|
19
|
+
"license": "Apache-2.0",
|
|
20
|
+
"author": "Coinbase Inc.",
|
|
21
|
+
"repository": "https://github.com/coinbase/x402",
|
|
22
|
+
"description": "x402 Payment Protocol",
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/node": "^22.13.4",
|
|
25
|
+
"@eslint/js": "^9.24.0",
|
|
26
|
+
"eslint": "^9.24.0",
|
|
27
|
+
"eslint-plugin-jsdoc": "^50.6.9",
|
|
28
|
+
"eslint-plugin-prettier": "^5.2.6",
|
|
29
|
+
"@typescript-eslint/eslint-plugin": "^8.29.1",
|
|
30
|
+
"@typescript-eslint/parser": "^8.29.1",
|
|
31
|
+
"eslint-plugin-import": "^2.31.0",
|
|
32
|
+
"prettier": "3.5.2",
|
|
33
|
+
"tsup": "^8.4.0",
|
|
34
|
+
"tsx": "^4.19.2",
|
|
35
|
+
"typescript": "^5.7.3",
|
|
36
|
+
"vite-tsconfig-paths": "^5.1.4",
|
|
37
|
+
"vitest": "^3.0.5",
|
|
38
|
+
"vite": "^6.2.6"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"viem": "^2.21.26",
|
|
42
|
+
"zod": "^3.24.2",
|
|
43
|
+
"x402": "workspace:^"
|
|
44
|
+
},
|
|
45
|
+
"exports": {
|
|
46
|
+
".": {
|
|
47
|
+
"import": {
|
|
48
|
+
"types": "./dist/esm/index.d.mts",
|
|
49
|
+
"default": "./dist/esm/index.mjs"
|
|
50
|
+
},
|
|
51
|
+
"require": {
|
|
52
|
+
"types": "./dist/cjs/index.d.ts",
|
|
53
|
+
"default": "./dist/cjs/index.js"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"files": [
|
|
58
|
+
"dist"
|
|
59
|
+
]
|
|
60
|
+
}
|