aptos-x402 1.0.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.
Files changed (67) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +716 -0
  3. package/dist/aptos-utils.d.ts +46 -0
  4. package/dist/aptos-utils.d.ts.map +1 -0
  5. package/dist/aptos-utils.js +144 -0
  6. package/dist/aptos-utils.js.map +1 -0
  7. package/dist/facilitator-client.d.ts +89 -0
  8. package/dist/facilitator-client.d.ts.map +1 -0
  9. package/dist/facilitator-client.js +140 -0
  10. package/dist/facilitator-client.js.map +1 -0
  11. package/dist/index.d.ts +58 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +62 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/server/index.d.ts +8 -0
  16. package/dist/server/index.d.ts.map +1 -0
  17. package/dist/server/index.js +8 -0
  18. package/dist/server/index.js.map +1 -0
  19. package/dist/server/next.d.ts +44 -0
  20. package/dist/server/next.d.ts.map +1 -0
  21. package/dist/server/next.js +210 -0
  22. package/dist/server/next.js.map +1 -0
  23. package/dist/types/config.d.ts +43 -0
  24. package/dist/types/config.d.ts.map +1 -0
  25. package/dist/types/config.js +6 -0
  26. package/dist/types/config.js.map +1 -0
  27. package/dist/types/index.d.ts +9 -0
  28. package/dist/types/index.d.ts.map +1 -0
  29. package/dist/types/index.js +7 -0
  30. package/dist/types/index.js.map +1 -0
  31. package/dist/types/protocol.d.ts +119 -0
  32. package/dist/types/protocol.d.ts.map +1 -0
  33. package/dist/types/protocol.js +12 -0
  34. package/dist/types/protocol.js.map +1 -0
  35. package/dist/utils.d.ts +3 -0
  36. package/dist/utils.d.ts.map +1 -0
  37. package/dist/utils.js +6 -0
  38. package/dist/utils.js.map +1 -0
  39. package/dist/x402-axios.d.ts +117 -0
  40. package/dist/x402-axios.d.ts.map +1 -0
  41. package/dist/x402-axios.js +310 -0
  42. package/dist/x402-axios.js.map +1 -0
  43. package/dist/x402-client.d.ts +56 -0
  44. package/dist/x402-client.d.ts.map +1 -0
  45. package/dist/x402-client.js +209 -0
  46. package/dist/x402-client.js.map +1 -0
  47. package/dist/x402-fetch.d.ts +59 -0
  48. package/dist/x402-fetch.d.ts.map +1 -0
  49. package/dist/x402-fetch.js +167 -0
  50. package/dist/x402-fetch.js.map +1 -0
  51. package/dist/x402-middleware.d.ts +9 -0
  52. package/dist/x402-middleware.d.ts.map +1 -0
  53. package/dist/x402-middleware.js +177 -0
  54. package/dist/x402-middleware.js.map +1 -0
  55. package/dist/x402-protocol-types.d.ts +115 -0
  56. package/dist/x402-protocol-types.d.ts.map +1 -0
  57. package/dist/x402-protocol-types.js +12 -0
  58. package/dist/x402-protocol-types.js.map +1 -0
  59. package/dist/x402-request.d.ts +57 -0
  60. package/dist/x402-request.d.ts.map +1 -0
  61. package/dist/x402-request.js +167 -0
  62. package/dist/x402-request.js.map +1 -0
  63. package/dist/x402-types.d.ts +18 -0
  64. package/dist/x402-types.d.ts.map +1 -0
  65. package/dist/x402-types.js +6 -0
  66. package/dist/x402-types.js.map +1 -0
  67. package/package.json +99 -0
@@ -0,0 +1,310 @@
1
+ /**
2
+ * x402-axios for Aptos
3
+ *
4
+ * Axios-compatible wrapper with x402 payment support
5
+ *
6
+ * Usage:
7
+ * ```typescript
8
+ * import { x402axios } from '@adipundir/aptos-x402';
9
+ *
10
+ * // Works exactly like axios
11
+ * const response = await x402axios.get('https://api.example.com/data');
12
+ *
13
+ * // With x402 payment support
14
+ * const response = await x402axios.get('https://api.example.com/protected/data', {
15
+ * privateKey: '0x...'
16
+ * });
17
+ *
18
+ * console.log(response.data);
19
+ * ```
20
+ */
21
+ import { Account, Aptos, AptosConfig, Network, Ed25519PrivateKey, } from "@aptos-labs/ts-sdk";
22
+ /**
23
+ * Decode X-Payment-Response header
24
+ */
25
+ export function decodeXPaymentResponse(header) {
26
+ if (!header)
27
+ return null;
28
+ try {
29
+ return JSON.parse(Buffer.from(header, 'base64').toString('utf-8'));
30
+ }
31
+ catch (error) {
32
+ return null;
33
+ }
34
+ }
35
+ /**
36
+ * Build URL with baseURL and params
37
+ */
38
+ function buildURL(config) {
39
+ let url = config.url || '';
40
+ if (config.baseURL) {
41
+ url = config.baseURL.replace(/\/$/, '') + '/' + url.replace(/^\//, '');
42
+ }
43
+ if (config.params) {
44
+ const searchParams = new URLSearchParams();
45
+ Object.entries(config.params).forEach(([key, value]) => {
46
+ if (value !== null && value !== undefined) {
47
+ searchParams.append(key, String(value));
48
+ }
49
+ });
50
+ const queryString = searchParams.toString();
51
+ if (queryString) {
52
+ url += (url.includes('?') ? '&' : '?') + queryString;
53
+ }
54
+ }
55
+ return url;
56
+ }
57
+ /**
58
+ * Transform request data based on config
59
+ */
60
+ function transformRequestData(data, config) {
61
+ if (!data)
62
+ return data;
63
+ if (config.transformRequest && config.transformRequest.length > 0) {
64
+ return config.transformRequest.reduce((acc, transformer) => {
65
+ return transformer(acc, config.headers);
66
+ }, data);
67
+ }
68
+ // Default transformation
69
+ if (typeof data === 'object' && !(data instanceof FormData) && !(data instanceof Blob)) {
70
+ return JSON.stringify(data);
71
+ }
72
+ return data;
73
+ }
74
+ /**
75
+ * Transform response data based on config
76
+ */
77
+ function transformResponseData(data, config) {
78
+ if (config.transformResponse && config.transformResponse.length > 0) {
79
+ return config.transformResponse.reduce((acc, transformer) => {
80
+ return transformer(acc);
81
+ }, data);
82
+ }
83
+ return data;
84
+ }
85
+ /**
86
+ * Main x402-axios function - works exactly like axios
87
+ */
88
+ async function x402axiosMain(configOrUrl, config) {
89
+ // Handle both axios-style calls: axios(url) and axios(url, config)
90
+ const finalConfig = typeof configOrUrl === 'string'
91
+ ? { ...config, url: configOrUrl }
92
+ : configOrUrl;
93
+ const { privateKey, account, method = 'GET', data, headers = {}, timeout, validateStatus = (status) => status >= 200 && status < 300, responseType = 'json', ...otherConfig } = finalConfig;
94
+ const url = buildURL(finalConfig);
95
+ console.log('[x402-axios] Making request to:', url);
96
+ // Step 1: Make initial request (no payment)
97
+ const init = {
98
+ method,
99
+ headers: {
100
+ 'Content-Type': 'application/json',
101
+ ...headers,
102
+ },
103
+ ...otherConfig,
104
+ };
105
+ // Add body for methods that support it
106
+ if (data && (method === 'POST' || method === 'PUT' || method === 'PATCH')) {
107
+ init.body = transformRequestData(data, finalConfig);
108
+ }
109
+ // Add timeout if specified
110
+ if (timeout) {
111
+ const controller = new AbortController();
112
+ setTimeout(() => controller.abort(), timeout);
113
+ init.signal = controller.signal;
114
+ }
115
+ let response = await fetch(url, init);
116
+ // Handle response based on responseType
117
+ let responseData;
118
+ if (responseType === 'json') {
119
+ responseData = await response.json();
120
+ }
121
+ else if (responseType === 'text') {
122
+ responseData = await response.text();
123
+ }
124
+ else if (responseType === 'blob') {
125
+ responseData = await response.blob();
126
+ }
127
+ else if (responseType === 'arraybuffer') {
128
+ responseData = await response.arrayBuffer();
129
+ }
130
+ else {
131
+ responseData = await response.text();
132
+ }
133
+ console.log(`[x402-axios] Initial response: ${response.status}`);
134
+ // If not 402, return immediately (no payment required)
135
+ if (response.status !== 402) {
136
+ console.log('[x402-axios] No payment required');
137
+ const transformedData = transformResponseData(responseData, finalConfig);
138
+ return {
139
+ data: transformedData,
140
+ status: response.status,
141
+ statusText: response.statusText,
142
+ headers: Object.fromEntries(response.headers.entries()),
143
+ config: finalConfig,
144
+ };
145
+ }
146
+ console.log('[x402-axios] Received 402 Payment Required');
147
+ // Step 2: Extract payment requirements from 402 response
148
+ const paymentReqs = responseData.accepts?.[0] || responseData;
149
+ const recipient = paymentReqs.payTo || paymentReqs.paymentAddress;
150
+ const amount = paymentReqs.maxAmountRequired || paymentReqs.price;
151
+ const networkId = paymentReqs.network;
152
+ if (!networkId) {
153
+ throw new Error('Network not specified in 402 payment requirements');
154
+ }
155
+ const scheme = paymentReqs.scheme || 'exact';
156
+ if (!recipient || !amount) {
157
+ throw new Error('Invalid 402 response: missing payment requirements');
158
+ }
159
+ console.log('[x402-axios] Payment requirements:', {
160
+ scheme,
161
+ network: networkId,
162
+ amount: `${amount} Octas`,
163
+ recipient: recipient.slice(0, 10) + '...',
164
+ });
165
+ // Step 3: Determine network from 402 response
166
+ const networkMap = {
167
+ 'aptos-testnet': Network.TESTNET,
168
+ 'aptos-mainnet': Network.MAINNET,
169
+ };
170
+ const network = networkMap[networkId] || Network.TESTNET;
171
+ console.log('[x402-axios] Network mapping:', {
172
+ networkId,
173
+ mappedNetwork: network,
174
+ networkMap
175
+ });
176
+ // Step 4: Initialize Aptos client based on discovered network
177
+ const aptosConfig = new AptosConfig({ network });
178
+ const aptos = new Aptos(aptosConfig);
179
+ console.log('[x402-axios] Aptos client initialized with network:', network);
180
+ // Create account from private key or use provided account
181
+ let aptosAccount;
182
+ if (account) {
183
+ aptosAccount = account;
184
+ }
185
+ else if (privateKey) {
186
+ const privateKeyObj = new Ed25519PrivateKey(privateKey);
187
+ aptosAccount = Account.fromPrivateKey({ privateKey: privateKeyObj });
188
+ }
189
+ else {
190
+ throw new Error('Either privateKey or account must be provided');
191
+ }
192
+ console.log(`[x402-axios] Building transaction for ${amount} Octas to ${recipient.slice(0, 10)}...`);
193
+ // Step 5: Build transaction based on scheme
194
+ let transaction;
195
+ if (scheme === 'exact') {
196
+ transaction = await aptos.transaction.build.simple({
197
+ sender: aptosAccount.accountAddress,
198
+ data: {
199
+ function: "0x1::aptos_account::transfer",
200
+ functionArguments: [recipient, amount],
201
+ },
202
+ });
203
+ }
204
+ else {
205
+ throw new Error(`Unsupported payment scheme: ${scheme}`);
206
+ }
207
+ console.log('[x402-axios] Signing transaction...');
208
+ // Step 6: Sign transaction
209
+ const senderAuthenticator = aptos.transaction.sign({
210
+ signer: aptosAccount,
211
+ transaction
212
+ });
213
+ // Step 7: Serialize transaction and signature separately
214
+ const transactionBytes = transaction.bcsToBytes();
215
+ const signatureBytes = senderAuthenticator.bcsToBytes();
216
+ const transactionBase64 = Buffer.from(transactionBytes).toString('base64');
217
+ const signatureBase64 = Buffer.from(signatureBytes).toString('base64');
218
+ // Step 8: Create x402 PaymentPayload
219
+ const paymentPayload = {
220
+ x402Version: 1,
221
+ scheme,
222
+ network: networkId,
223
+ payload: {
224
+ transaction: transactionBase64,
225
+ signature: signatureBase64,
226
+ },
227
+ };
228
+ // Step 9: Encode as base64 for X-PAYMENT header
229
+ const paymentHeader = Buffer.from(JSON.stringify(paymentPayload)).toString('base64');
230
+ console.log(`[x402-axios] Retrying with payment (header: ${paymentHeader.length} chars)...`);
231
+ // Step 10: Retry request with X-PAYMENT header
232
+ const paidInit = {
233
+ ...init,
234
+ headers: {
235
+ ...init.headers,
236
+ 'X-PAYMENT': paymentHeader,
237
+ },
238
+ };
239
+ response = await fetch(url, paidInit);
240
+ // Handle response based on responseType
241
+ if (responseType === 'json') {
242
+ responseData = await response.json();
243
+ }
244
+ else if (responseType === 'text') {
245
+ responseData = await response.text();
246
+ }
247
+ else if (responseType === 'blob') {
248
+ responseData = await response.blob();
249
+ }
250
+ else if (responseType === 'arraybuffer') {
251
+ responseData = await response.arrayBuffer();
252
+ }
253
+ else {
254
+ responseData = await response.text();
255
+ }
256
+ console.log(`[x402-axios] Payment response: ${response.status}`);
257
+ // Step 11: Extract payment info from X-Payment-Response header
258
+ let paymentInfo;
259
+ const paymentResponseHeader = response.headers.get('x-payment-response');
260
+ if (paymentResponseHeader) {
261
+ const decoded = decodeXPaymentResponse(paymentResponseHeader);
262
+ if (decoded?.settlement?.txHash) {
263
+ paymentInfo = {
264
+ transactionHash: decoded.settlement.txHash,
265
+ amount: amount,
266
+ recipient: recipient,
267
+ settled: decoded.settlement.success === true,
268
+ };
269
+ console.log(`[x402-axios] Payment settled: ${paymentInfo.transactionHash}`);
270
+ }
271
+ }
272
+ const transformedData = transformResponseData(responseData, finalConfig);
273
+ return {
274
+ data: transformedData,
275
+ status: response.status,
276
+ statusText: response.statusText,
277
+ headers: Object.fromEntries(response.headers.entries()),
278
+ config: finalConfig,
279
+ paymentInfo,
280
+ };
281
+ }
282
+ // Axios-like convenience methods
283
+ export const x402axios = Object.assign(async function (configOrUrl, config) {
284
+ return x402axiosMain(configOrUrl, config);
285
+ }, {
286
+ get: (url, config) => x402axiosMain({ ...config, url, method: 'GET' }),
287
+ post: (url, data, config) => x402axiosMain({ ...config, url, method: 'POST', data }),
288
+ put: (url, data, config) => x402axiosMain({ ...config, url, method: 'PUT', data }),
289
+ patch: (url, data, config) => x402axiosMain({ ...config, url, method: 'PATCH', data }),
290
+ delete: (url, config) => x402axiosMain({ ...config, url, method: 'DELETE' }),
291
+ head: (url, config) => x402axiosMain({ ...config, url, method: 'HEAD' }),
292
+ options: (url, config) => x402axiosMain({ ...config, url, method: 'OPTIONS' }),
293
+ // Create instance with default config
294
+ create: (defaultConfig) => {
295
+ const instance = Object.assign(async function (configOrUrl, config) {
296
+ const mergedConfig = { ...defaultConfig, ...(typeof configOrUrl === 'string' ? { ...config, url: configOrUrl } : configOrUrl) };
297
+ return x402axiosMain(mergedConfig);
298
+ }, {
299
+ get: (url, config) => x402axiosMain({ ...defaultConfig, ...config, url, method: 'GET' }),
300
+ post: (url, data, config) => x402axiosMain({ ...defaultConfig, ...config, url, method: 'POST', data }),
301
+ put: (url, data, config) => x402axiosMain({ ...defaultConfig, ...config, url, method: 'PUT', data }),
302
+ patch: (url, data, config) => x402axiosMain({ ...defaultConfig, ...config, url, method: 'PATCH', data }),
303
+ delete: (url, config) => x402axiosMain({ ...defaultConfig, ...config, url, method: 'DELETE' }),
304
+ head: (url, config) => x402axiosMain({ ...defaultConfig, ...config, url, method: 'HEAD' }),
305
+ options: (url, config) => x402axiosMain({ ...defaultConfig, ...config, url, method: 'OPTIONS' }),
306
+ });
307
+ return instance;
308
+ },
309
+ });
310
+ //# sourceMappingURL=x402-axios.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x402-axios.js","sourceRoot":"","sources":["../lib/x402-axios.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * x402 Client for Aptos
3
+ *
4
+ * Simple client that automatically handles x402 payment flow:
5
+ * 1. Make request to protected resource
6
+ * 2. If 402, create and sign payment transaction
7
+ * 3. Retry with X-PAYMENT header
8
+ * 4. Return response
9
+ */
10
+ import { Aptos, Network } from "@aptos-labs/ts-sdk";
11
+ export interface X402ClientConfig {
12
+ privateKey: string;
13
+ network?: Network;
14
+ nodeUrl?: string;
15
+ }
16
+ export interface X402Response {
17
+ status: number;
18
+ data: any;
19
+ headers: Record<string, string>;
20
+ paymentDetails?: {
21
+ transactionHash: string;
22
+ amount: string;
23
+ recipient: string;
24
+ settled: boolean;
25
+ };
26
+ }
27
+ /**
28
+ * Create an x402 client for Aptos
29
+ */
30
+ export declare function createX402Client(config: X402ClientConfig): {
31
+ request: (url: string, options?: RequestInit) => Promise<X402Response>;
32
+ get: (url: string, options?: RequestInit) => Promise<X402Response>;
33
+ post: (url: string, body?: any, options?: RequestInit) => Promise<X402Response>;
34
+ getBalance: () => Promise<number>;
35
+ getAddress: () => string;
36
+ account: import("@aptos-labs/ts-sdk").Ed25519Account;
37
+ aptos: Aptos;
38
+ };
39
+ /**
40
+ * Example usage:
41
+ *
42
+ * ```typescript
43
+ * import { createX402Client } from './lib/x402-client';
44
+ *
45
+ * const client = createX402Client({
46
+ * privateKey: process.env.DEMO_PRIVATE_KEY!,
47
+ * network: Network.TESTNET,
48
+ * });
49
+ *
50
+ * // Make a request - payment is handled automatically
51
+ * const response = await client.get('http://localhost:3000/api/protected/weather');
52
+ * console.log(response.data);
53
+ * console.log('Payment details:', response.paymentDetails);
54
+ * ```
55
+ */
56
+ //# sourceMappingURL=x402-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x402-client.d.ts","sourceRoot":"","sources":["../lib/x402-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAEL,KAAK,EAEL,OAAO,EAER,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,GAAG,CAAC;IACV,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,cAAc,CAAC,EAAE;QACf,eAAe,EAAE,MAAM,CAAC;QACxB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;CACH;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB;mBAmBhD,MAAM,YACF,WAAW,KACnB,OAAO,CAAC,YAAY,CAAC;eAiJA,MAAM,YAAW,WAAW,KAAQ,OAAO,CAAC,YAAY,CAAC;gBAQ1E,MAAM,SACJ,GAAG,YACD,WAAW,KACnB,OAAO,CAAC,YAAY,CAAC;sBAeK,OAAO,CAAC,MAAM,CAAC;sBASrB,MAAM;;;EAa9B;AAED;;;;;;;;;;;;;;;;GAgBG"}
@@ -0,0 +1,209 @@
1
+ /**
2
+ * x402 Client for Aptos
3
+ *
4
+ * Simple client that automatically handles x402 payment flow:
5
+ * 1. Make request to protected resource
6
+ * 2. If 402, create and sign payment transaction
7
+ * 3. Retry with X-PAYMENT header
8
+ * 4. Return response
9
+ */
10
+ import { Account, Aptos, AptosConfig, Network, Ed25519PrivateKey, } from "@aptos-labs/ts-sdk";
11
+ /**
12
+ * Create an x402 client for Aptos
13
+ */
14
+ export function createX402Client(config) {
15
+ const network = config.network || Network.TESTNET;
16
+ const aptosConfig = config.nodeUrl
17
+ ? new AptosConfig({ network, fullnode: config.nodeUrl })
18
+ : new AptosConfig({ network });
19
+ const aptos = new Aptos(aptosConfig);
20
+ // Create account from private key
21
+ const privateKey = new Ed25519PrivateKey(config.privateKey);
22
+ const account = Account.fromPrivateKey({ privateKey });
23
+ console.log(`[x402 Client] Initialized for address: ${account.accountAddress.toString()}`);
24
+ /**
25
+ * Make a request to an x402-protected endpoint
26
+ * Automatically handles 402 Payment Required and retries with payment
27
+ */
28
+ async function request(url, options = {}) {
29
+ console.log(`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
30
+ console.log(`[x402 Client] Starting x402 payment flow`);
31
+ console.log(`[x402 Client] URL: ${url}`);
32
+ console.log(`[x402 Client] Method: ${options.method || "GET"}`);
33
+ console.log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`);
34
+ // Step 1: Make initial request (without payment)
35
+ console.log(`[x402 Client] Step 1: Making initial request...`);
36
+ const initialResponse = await fetch(url, options);
37
+ const initialHeaders = Object.fromEntries(initialResponse.headers.entries());
38
+ console.log(`[x402 Client] Initial response status: ${initialResponse.status}`);
39
+ // If not 402, return immediately (resource is not payment-protected)
40
+ if (initialResponse.status !== 402) {
41
+ console.log(`[x402 Client] ✅ No payment required, returning response`);
42
+ const data = await initialResponse.json().catch(() => ({}));
43
+ return {
44
+ status: initialResponse.status,
45
+ data,
46
+ headers: initialHeaders,
47
+ };
48
+ }
49
+ console.log(`\n[x402 Client] 💳 Step 2: Received 402 Payment Required`);
50
+ // Step 2: Parse payment requirements from 402 response body
51
+ const paymentRequirements = await initialResponse.json();
52
+ console.log(`[x402 Client] Payment requirements:`, JSON.stringify(paymentRequirements, null, 2));
53
+ if (!paymentRequirements.price || !paymentRequirements.paymentAddress) {
54
+ throw new Error("Invalid 402 response: missing payment requirements");
55
+ }
56
+ console.log(`\n[x402 Client] 🔨 Step 3: Creating payment transaction`);
57
+ console.log(`[x402 Client] Building Aptos transfer transaction...`);
58
+ console.log(`[x402 Client] Function: 0x1::aptos_account::transfer`);
59
+ console.log(`[x402 Client] Recipient: ${paymentRequirements.paymentAddress}`);
60
+ console.log(`[x402 Client] Amount: ${paymentRequirements.price} Octas`);
61
+ const transaction = await aptos.transaction.build.simple({
62
+ sender: account.accountAddress,
63
+ data: {
64
+ function: "0x1::aptos_account::transfer",
65
+ functionArguments: [
66
+ paymentRequirements.paymentAddress,
67
+ paymentRequirements.price,
68
+ ],
69
+ },
70
+ });
71
+ console.log(`[x402 Client] ✅ Transaction built successfully\n`);
72
+ // Step 4: Sign transaction (but don't submit - facilitator will submit it)
73
+ console.log(`[x402 Client] ✍️ Step 4: Signing transaction`);
74
+ console.log(`[x402 Client] Using account: ${account.accountAddress.toString()}`);
75
+ console.log(`[x402 Client] Signing with Ed25519 private key...`);
76
+ const signedTx = aptos.transaction.sign({
77
+ signer: account,
78
+ transaction
79
+ });
80
+ console.log(`[x402 Client] ✅ Transaction signed successfully\n`);
81
+ // Step 5: Serialize using BCS (Binary Canonical Serialization)
82
+ // This is the Aptos standard for transaction serialization
83
+ console.log(`[x402 Client] 📦 Step 5: Serializing transaction (BCS)`);
84
+ console.log(`[x402 Client] Using Binary Canonical Serialization (Aptos standard)...`);
85
+ const signedTxBytes = signedTx.bcsToBytes();
86
+ console.log(`[x402 Client] ✅ Serialized to ${signedTxBytes.length} bytes\n`);
87
+ // Step 6: Encode as base64 for HTTP transport (per x402 spec)
88
+ console.log(`[x402 Client] 🔐 Step 6: Encoding for HTTP transport`);
89
+ console.log(`[x402 Client] Encoding as base64 for X-PAYMENT header (per x402 spec)...`);
90
+ const signedTxBase64 = Buffer.from(signedTxBytes).toString("base64");
91
+ console.log(`[x402 Client] ✅ Encoded to ${signedTxBase64.length} characters`);
92
+ console.log(`[x402 Client] Preview: ${signedTxBase64.substring(0, 80)}...`);
93
+ console.log(`[x402 Client] This will be sent in X-PAYMENT header\n`);
94
+ // Step 7: Retry request with X-PAYMENT header (per x402 spec)
95
+ // The signed transaction is sent in the X-PAYMENT header as base64
96
+ console.log(`[x402 Client] 🔄 Step 7: Retrying request with payment`);
97
+ const requestHeaders = {
98
+ ...options.headers,
99
+ "X-PAYMENT": signedTxBase64,
100
+ };
101
+ console.log(`[x402 Client] Headers being sent:`);
102
+ console.log(`[x402 Client] X-PAYMENT: ${signedTxBase64.substring(0, 50)}... (${signedTxBase64.length} chars)`);
103
+ console.log(`[x402 Client] Making request to: ${url}\n`);
104
+ const paidResponse = await fetch(url, {
105
+ ...options,
106
+ headers: requestHeaders,
107
+ });
108
+ console.log(`[x402 Client] ✅ Response received: ${paidResponse.status} ${paidResponse.statusText}\n`);
109
+ const paidHeaders = Object.fromEntries(paidResponse.headers.entries());
110
+ const data = await paidResponse.json().catch(() => ({}));
111
+ // Step 8: Parse X-Payment-Response header (per x402 spec)
112
+ // The facilitator returns payment settlement details in this header
113
+ console.log(`[x402 Client] 📋 Step 8: Checking payment settlement`);
114
+ let paymentDetails;
115
+ if (paidHeaders["x-payment-response"]) {
116
+ console.log(`[x402 Client] Found X-Payment-Response header in response`);
117
+ try {
118
+ paymentDetails = JSON.parse(paidHeaders["x-payment-response"]);
119
+ console.log(`[x402 Client] ✅ Payment settled on blockchain!`);
120
+ console.log(`[x402 Client] Settlement details:`);
121
+ console.log(`[x402 Client] Transaction Hash: ${paymentDetails.transactionHash}`);
122
+ console.log(`[x402 Client] Amount: ${paymentDetails.amount} Octas`);
123
+ console.log(`[x402 Client] Recipient: ${paymentDetails.recipient}`);
124
+ console.log(`[x402 Client] Status: ${paymentDetails.settled ? "Confirmed" : "Pending"}`);
125
+ }
126
+ catch (error) {
127
+ console.warn(`[x402 Client] ⚠️ Failed to parse X-Payment-Response header`);
128
+ }
129
+ }
130
+ else {
131
+ console.warn(`[x402 Client] ⚠️ No X-Payment-Response header found in response`);
132
+ }
133
+ if (!paidResponse.ok) {
134
+ console.error(`[x402 Client] ❌ Request failed after payment`);
135
+ throw new Error(`Request failed: ${paidResponse.status} ${paidResponse.statusText}`);
136
+ }
137
+ console.log(`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
138
+ console.log(`[x402 Client] ✅ Payment flow completed successfully!`);
139
+ console.log(`[x402 Client] ✅ Protected resource delivered`);
140
+ console.log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`);
141
+ return {
142
+ status: paidResponse.status,
143
+ data,
144
+ headers: paidHeaders,
145
+ paymentDetails,
146
+ };
147
+ }
148
+ /**
149
+ * GET request to x402-protected endpoint
150
+ */
151
+ async function get(url, options = {}) {
152
+ return request(url, { ...options, method: "GET" });
153
+ }
154
+ /**
155
+ * POST request to x402-protected endpoint
156
+ */
157
+ async function post(url, body, options = {}) {
158
+ return request(url, {
159
+ ...options,
160
+ method: "POST",
161
+ headers: {
162
+ "Content-Type": "application/json",
163
+ ...options.headers,
164
+ },
165
+ body: body ? JSON.stringify(body) : undefined,
166
+ });
167
+ }
168
+ /**
169
+ * Get account balance
170
+ */
171
+ async function getBalance() {
172
+ return await aptos.getAccountAPTAmount({
173
+ accountAddress: account.accountAddress,
174
+ });
175
+ }
176
+ /**
177
+ * Get account address
178
+ */
179
+ function getAddress() {
180
+ return account.accountAddress.toString();
181
+ }
182
+ return {
183
+ request,
184
+ get,
185
+ post,
186
+ getBalance,
187
+ getAddress,
188
+ account,
189
+ aptos,
190
+ };
191
+ }
192
+ /**
193
+ * Example usage:
194
+ *
195
+ * ```typescript
196
+ * import { createX402Client } from './lib/x402-client';
197
+ *
198
+ * const client = createX402Client({
199
+ * privateKey: process.env.DEMO_PRIVATE_KEY!,
200
+ * network: Network.TESTNET,
201
+ * });
202
+ *
203
+ * // Make a request - payment is handled automatically
204
+ * const response = await client.get('http://localhost:3000/api/protected/weather');
205
+ * console.log(response.data);
206
+ * console.log('Payment details:', response.paymentDetails);
207
+ * ```
208
+ */
209
+ //# sourceMappingURL=x402-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x402-client.js","sourceRoot":"","sources":["../lib/x402-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * x402 Fetch Wrapper for Aptos
3
+ *
4
+ * Drop-in replacement for fetch() that automatically handles x402 payments
5
+ *
6
+ * Usage:
7
+ * ```typescript
8
+ * import { createX402Fetch } from '@adipundir/aptos-x402';
9
+ *
10
+ * const fetch402 = createX402Fetch({
11
+ * privateKey: process.env.PRIVATE_KEY!,
12
+ * network: 'testnet'
13
+ * });
14
+ *
15
+ * // Use it like regular fetch - payment is automatic!
16
+ * const response = await fetch402('https://api.example.com/premium-data');
17
+ * const data = await response.json();
18
+ * ```
19
+ */
20
+ export interface X402FetchConfig {
21
+ /** Private key for signing transactions (hex string starting with 0x) */
22
+ privateKey: string;
23
+ /** Aptos network (testnet, mainnet, devnet) */
24
+ network?: 'testnet' | 'mainnet' | 'devnet';
25
+ /** Custom node URL (optional) */
26
+ nodeUrl?: string;
27
+ /** Enable debug logging */
28
+ debug?: boolean;
29
+ }
30
+ export interface X402PaymentInfo {
31
+ /** Transaction hash on Aptos blockchain */
32
+ transactionHash: string;
33
+ /** Amount paid in Octas */
34
+ amountOctas: string;
35
+ /** Amount paid in APT */
36
+ amountAPT: number;
37
+ /** Recipient address */
38
+ recipient: string;
39
+ /** Network where payment was settled */
40
+ network: string;
41
+ /** Whether payment was settled successfully */
42
+ settled: boolean;
43
+ }
44
+ export interface X402Response extends Response {
45
+ /** Payment information if a payment was made */
46
+ paymentInfo?: X402PaymentInfo;
47
+ }
48
+ /**
49
+ * Create an x402-enabled fetch function
50
+ */
51
+ export declare function createX402Fetch(config: X402FetchConfig): typeof fetch;
52
+ /**
53
+ * Get account balance helper
54
+ */
55
+ export declare function getAccountBalance(config: X402FetchConfig): Promise<{
56
+ octas: number;
57
+ apt: number;
58
+ }>;
59
+ //# sourceMappingURL=x402-fetch.d.ts.map