@paynodelabs/sdk-js 2.2.0 → 2.2.2
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 +16 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +40 -15
- package/dist/constants.d.ts +2 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +3 -2
- package/dist/errors/index.d.ts +1 -1
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/middleware/x402.js +3 -3
- package/dist/types/x402.d.ts +1 -1
- package/dist/utils/payload.d.ts +17 -0
- package/dist/utils/payload.d.ts.map +1 -0
- package/dist/utils/payload.js +54 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://docs.paynode.dev)
|
|
4
4
|
[](https://www.npmjs.com/package/@paynodelabs/sdk-js)
|
|
5
5
|
|
|
6
|
-
The official TypeScript/JavaScript SDK for the **PayNode Protocol (v2.2.
|
|
6
|
+
The official TypeScript/JavaScript SDK for the **PayNode Protocol (v2.2.1)**. PayNode is a stateless, non-custodial M2M payment gateway that standardizes the HTTP 402 "Payment Required" flow for AI Agents, with support for both on-chain receipts and off-chain signatures (EIP-3009).
|
|
7
7
|
|
|
8
8
|
## 📖 Read the Docs
|
|
9
9
|
|
|
@@ -33,7 +33,7 @@ async function main() {
|
|
|
33
33
|
main();
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
### Key Features (v2.2.
|
|
36
|
+
### Key Features (v2.2.1)
|
|
37
37
|
- **Zero-Wait Checkout**: API response speed drops from 5 seconds to **under 50ms** by using local signatures instead of waiting for on-chain inclusion.
|
|
38
38
|
- **Double-Spend Protection**:
|
|
39
39
|
- **L1 (Memory)**: High-speed local replay protection via `IdempotencyStore`.
|
|
@@ -104,4 +104,18 @@ To publish a new version of the SDK:
|
|
|
104
104
|
|
|
105
105
|
---
|
|
106
106
|
|
|
107
|
+
## Versioning Guide
|
|
108
|
+
|
|
109
|
+
PayNode uses two distinct versioning schemes:
|
|
110
|
+
|
|
111
|
+
| Version Type | Description | Current Value |
|
|
112
|
+
| :--- | :--- | :--- |
|
|
113
|
+
| **Protocol Version** | On-chain contracts & core x402 data schema. | `1.4.0` |
|
|
114
|
+
| **SDK/Product Version** | Software package version (npm/SemVer). | `2.2.2` |
|
|
115
|
+
|
|
116
|
+
> [!NOTE]
|
|
117
|
+
> Protocol Version changes imply breaking changes in verification or contract interfaces. SDK Version changes may include features, fixes, or performance improvements without altering protocol logic.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
107
121
|
_Built for the Autonomous AI Economy by PayNodeLabs._
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,eAAe,EAEhB,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,cAAe,SAAQ,WAAW;IACjD,IAAI,CAAC,EAAE,GAAG,CAAC;CACZ;AAID,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,QAAQ,CAA0B;IAC1C,OAAO,CAAC,OAAO,CAAW;IAC1B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAoC;IAErD,OAAO,CAAC,SAAS,CAMf;IAEF,OAAO,CAAC,UAAU,CAAsB;gBAE5B,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,GAAG,MAAM,EAAkB,EAAE,UAAU,GAAE,MAAU;YAepF,eAAe;IAoCvB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,eAAe,EAEhB,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,cAAe,SAAQ,WAAW;IACjD,IAAI,CAAC,EAAE,GAAG,CAAC;CACZ;AAID,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,QAAQ,CAA0B;IAC1C,OAAO,CAAC,OAAO,CAAW;IAC1B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAoC;IAErD,OAAO,CAAC,SAAS,CAMf;IAEF,OAAO,CAAC,UAAU,CAAsB;gBAE5B,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,GAAG,MAAM,EAAkB,EAAE,UAAU,GAAE,MAAU;YAepF,eAAe;IAoCvB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC;YAuEjE,aAAa;IAkKrB,6BAA6B,CACjC,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAC9B,OAAO,CAAC,eAAe,CAAC;IA+CrB,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAqBpH,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,MAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IA8BrJ,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAE,MAAa,EAAE,OAAO,GAAE,MAAY;;;;;;YAyChH,UAAU;CAYzB"}
|
package/dist/client.js
CHANGED
|
@@ -63,11 +63,17 @@ class PayNodeAgentClient {
|
|
|
63
63
|
}
|
|
64
64
|
async requestGate(url, options = {}) {
|
|
65
65
|
const fetchOptions = { ...options };
|
|
66
|
+
const network = await this.provider.getNetwork();
|
|
67
|
+
const paynodeNetwork = Number(network.chainId) === 8453 ? 'mainnet' : 'testnet';
|
|
68
|
+
fetchOptions.headers = {
|
|
69
|
+
'X-PayNode-Network': paynodeNetwork,
|
|
70
|
+
...fetchOptions.headers
|
|
71
|
+
};
|
|
66
72
|
if (options.json && !fetchOptions.body) {
|
|
67
73
|
fetchOptions.body = JSON.stringify(options.json);
|
|
68
74
|
fetchOptions.headers = {
|
|
69
|
-
|
|
70
|
-
|
|
75
|
+
...fetchOptions.headers,
|
|
76
|
+
'Content-Type': 'application/json'
|
|
71
77
|
};
|
|
72
78
|
}
|
|
73
79
|
try {
|
|
@@ -78,20 +84,28 @@ class PayNodeAgentClient {
|
|
|
78
84
|
const b64Required = response.headers.get('PAYMENT-REQUIRED') || response.headers.get('X-402-Required');
|
|
79
85
|
const orderId = response.headers.get('X-402-Order-Id');
|
|
80
86
|
let body = null;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
else if (b64Required) {
|
|
87
|
+
let headerBody = null;
|
|
88
|
+
if (b64Required) {
|
|
85
89
|
try {
|
|
86
90
|
const decoded = typeof globalThis.Buffer !== 'undefined'
|
|
87
91
|
? globalThis.Buffer.from(b64Required, 'base64').toString()
|
|
88
92
|
: atob(b64Required);
|
|
89
|
-
|
|
93
|
+
headerBody = JSON.parse(decoded);
|
|
90
94
|
}
|
|
91
95
|
catch (e) {
|
|
92
96
|
console.debug('⚠️ [PayNode-JS] Failed to parse PAYMENT-REQUIRED header:', e);
|
|
93
97
|
}
|
|
94
98
|
}
|
|
99
|
+
if (contentType && contentType.includes('application/json')) {
|
|
100
|
+
try {
|
|
101
|
+
body = await response.clone().json();
|
|
102
|
+
}
|
|
103
|
+
catch (e) { /* ignore */ }
|
|
104
|
+
}
|
|
105
|
+
// Robustness: Merge header info into body if body is missing critical bits
|
|
106
|
+
if (headerBody && (!body || !body.x402Version)) {
|
|
107
|
+
body = { ...body, ...headerBody };
|
|
108
|
+
}
|
|
95
109
|
if (body && body.x402Version === 2) {
|
|
96
110
|
console.log(`🚀 [PayNode-JS] x402 v2 detected. Handling autonomous payment...`);
|
|
97
111
|
if (orderId && !body.orderId)
|
|
@@ -118,6 +132,7 @@ class PayNodeAgentClient {
|
|
|
118
132
|
if (!requirement) {
|
|
119
133
|
throw new errors_1.PayNodeException(errors_1.ErrorCode.TransactionFailed, `No compatible payment requirement found for network ${caip2ChainId}`);
|
|
120
134
|
}
|
|
135
|
+
console.log(`💡 [PayNode-JS] Selected payment method: ${requirement.type || 'onchain'} on ${requirement.network}`);
|
|
121
136
|
// 🛡️ Token Whitelist Check (Case-insensitive)
|
|
122
137
|
const chainTokens = constants_1.ACCEPTED_TOKENS[chainId]?.map(t => t.toLowerCase());
|
|
123
138
|
if (chainTokens && !chainTokens.includes(requirement.asset.toLowerCase())) {
|
|
@@ -148,7 +163,7 @@ class PayNodeAgentClient {
|
|
|
148
163
|
},
|
|
149
164
|
payload: authorization,
|
|
150
165
|
_paynode: {
|
|
151
|
-
version:
|
|
166
|
+
version: constants_1.SDK_VERSION,
|
|
152
167
|
type: 'eip3009',
|
|
153
168
|
orderId: orderId
|
|
154
169
|
}
|
|
@@ -192,7 +207,7 @@ class PayNodeAgentClient {
|
|
|
192
207
|
},
|
|
193
208
|
payload: { txHash },
|
|
194
209
|
_paynode: {
|
|
195
|
-
version:
|
|
210
|
+
version: constants_1.SDK_VERSION,
|
|
196
211
|
type: 'onchain',
|
|
197
212
|
orderId: orderId
|
|
198
213
|
}
|
|
@@ -202,6 +217,7 @@ class PayNodeAgentClient {
|
|
|
202
217
|
const b64Payload = typeof globalThis.Buffer !== 'undefined'
|
|
203
218
|
? globalThis.Buffer.from(payloadJson).toString('base64')
|
|
204
219
|
: btoa(payloadJson);
|
|
220
|
+
const paynodeNetwork = chainId === 8453 ? 'mainnet' : 'testnet';
|
|
205
221
|
const retryOptions = {
|
|
206
222
|
...options,
|
|
207
223
|
headers: {
|
|
@@ -209,7 +225,8 @@ class PayNodeAgentClient {
|
|
|
209
225
|
'Content-Type': 'application/json',
|
|
210
226
|
'PAYMENT-SIGNATURE': b64Payload,
|
|
211
227
|
'X-402-Payload': b64Payload, // Keep for backward compatibility
|
|
212
|
-
'X-402-Order-Id': orderId
|
|
228
|
+
'X-402-Order-Id': orderId,
|
|
229
|
+
'X-PayNode-Network': paynodeNetwork
|
|
213
230
|
}
|
|
214
231
|
};
|
|
215
232
|
const retryResponse = await this._fetchWithRetry(url, retryOptions);
|
|
@@ -220,9 +237,15 @@ class PayNodeAgentClient {
|
|
|
220
237
|
const settleHeader = retryResponse.headers.get('PAYMENT-RESPONSE') || retryResponse.headers.get('X-PAYMENT-RESPONSE');
|
|
221
238
|
if (settleHeader) {
|
|
222
239
|
try {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
240
|
+
let decoded;
|
|
241
|
+
if (settleHeader.trim().startsWith('{')) {
|
|
242
|
+
decoded = settleHeader;
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
decoded = typeof globalThis.Buffer !== 'undefined'
|
|
246
|
+
? globalThis.Buffer.from(settleHeader, 'base64').toString()
|
|
247
|
+
: atob(settleHeader);
|
|
248
|
+
}
|
|
226
249
|
const settleData = JSON.parse(decoded);
|
|
227
250
|
if (settleData.success) {
|
|
228
251
|
console.log(`✅ [PayNode-JS] Settlement confirmed: ${settleData.transaction}`);
|
|
@@ -239,10 +262,12 @@ class PayNodeAgentClient {
|
|
|
239
262
|
}
|
|
240
263
|
async signTransferWithAuthorization(tokenAddr, to, amount, validAfter, validBefore, nonce, extra = {}) {
|
|
241
264
|
const network = await this.provider.getNetwork();
|
|
265
|
+
const chainId = Number(network.chainId);
|
|
266
|
+
const defaultName = chainId === 8453 ? "USDC" : "USD Coin";
|
|
242
267
|
const domain = {
|
|
243
|
-
name: extra.name ||
|
|
268
|
+
name: extra.name || defaultName,
|
|
244
269
|
version: extra.version || "2",
|
|
245
|
-
chainId:
|
|
270
|
+
chainId: chainId,
|
|
246
271
|
verifyingContract: tokenAddr
|
|
247
272
|
};
|
|
248
273
|
const types = {
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Generated by scripts/sync-config.py */
|
|
1
|
+
/** Generated by meta/scripts/sync-config.py */
|
|
2
2
|
export declare const PAYNODE_ROUTER_ADDRESS = "0x4A73696ccF76E7381b044cB95127B3784369Ed63";
|
|
3
3
|
export declare const PAYNODE_ROUTER_ADDRESS_SANDBOX = "0x24cD8b68aaC209217ff5a6ef1Bf55a59f2c8Ca6F";
|
|
4
4
|
export declare const BASE_USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
@@ -6,6 +6,7 @@ export declare const BASE_USDC_ADDRESS_SANDBOX = "0x65c088EfBDB0E03185Dbe8e258Ad
|
|
|
6
6
|
export declare const PROTOCOL_TREASURY = "0x598bF63F5449876efafa7b36b77Deb2070621C0E";
|
|
7
7
|
export declare const PROTOCOL_FEE_BPS = 100;
|
|
8
8
|
export declare const MIN_PAYMENT_AMOUNT: bigint;
|
|
9
|
+
export declare const SDK_VERSION = "2.2.2";
|
|
9
10
|
export declare const BASE_RPC_URLS: string[];
|
|
10
11
|
export declare const BASE_RPC_URLS_SANDBOX: string[];
|
|
11
12
|
export declare const ACCEPTED_TOKENS: Record<number, string[]>;
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,eAAO,MAAM,sBAAsB,+CAA+C,CAAC;AACnF,eAAO,MAAM,8BAA8B,+CAA+C,CAAC;AAC3F,eAAO,MAAM,iBAAiB,+CAA+C,CAAC;AAC9E,eAAO,MAAM,yBAAyB,+CAA+C,CAAC;AACtF,eAAO,MAAM,iBAAiB,+CAA+C,CAAC;AAC9E,eAAO,MAAM,gBAAgB,MAAM,CAAC;AACpC,eAAO,MAAM,kBAAkB,QAAe,CAAC;AAC/C,eAAO,MAAM,WAAW,UAAU,CAAC;AAEnC,eAAO,MAAM,aAAa,UAAmF,CAAC;AAC9G,eAAO,MAAM,qBAAqB,UAA0E,CAAC;AAE7G,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAGpD,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAA25K,CAAC"}
|
package/dist/constants.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PAYNODE_ROUTER_ABI = exports.ACCEPTED_TOKENS = exports.BASE_RPC_URLS_SANDBOX = exports.BASE_RPC_URLS = exports.MIN_PAYMENT_AMOUNT = exports.PROTOCOL_FEE_BPS = exports.PROTOCOL_TREASURY = exports.BASE_USDC_ADDRESS_SANDBOX = exports.BASE_USDC_ADDRESS = exports.PAYNODE_ROUTER_ADDRESS_SANDBOX = exports.PAYNODE_ROUTER_ADDRESS = void 0;
|
|
4
|
-
/** Generated by scripts/sync-config.py */
|
|
3
|
+
exports.PAYNODE_ROUTER_ABI = exports.ACCEPTED_TOKENS = exports.BASE_RPC_URLS_SANDBOX = exports.BASE_RPC_URLS = exports.SDK_VERSION = exports.MIN_PAYMENT_AMOUNT = exports.PROTOCOL_FEE_BPS = exports.PROTOCOL_TREASURY = exports.BASE_USDC_ADDRESS_SANDBOX = exports.BASE_USDC_ADDRESS = exports.PAYNODE_ROUTER_ADDRESS_SANDBOX = exports.PAYNODE_ROUTER_ADDRESS = void 0;
|
|
4
|
+
/** Generated by meta/scripts/sync-config.py */
|
|
5
5
|
exports.PAYNODE_ROUTER_ADDRESS = "0x4A73696ccF76E7381b044cB95127B3784369Ed63";
|
|
6
6
|
exports.PAYNODE_ROUTER_ADDRESS_SANDBOX = "0x24cD8b68aaC209217ff5a6ef1Bf55a59f2c8Ca6F";
|
|
7
7
|
exports.BASE_USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
@@ -9,6 +9,7 @@ exports.BASE_USDC_ADDRESS_SANDBOX = "0x65c088EfBDB0E03185Dbe8e258Ad0cf4Ab7946b0"
|
|
|
9
9
|
exports.PROTOCOL_TREASURY = "0x598bF63F5449876efafa7b36b77Deb2070621C0E";
|
|
10
10
|
exports.PROTOCOL_FEE_BPS = 100;
|
|
11
11
|
exports.MIN_PAYMENT_AMOUNT = BigInt(1000);
|
|
12
|
+
exports.SDK_VERSION = "2.2.2";
|
|
12
13
|
exports.BASE_RPC_URLS = ["https://mainnet.base.org", "https://base.meowrpc.com", "https://1rpc.io/base"];
|
|
13
14
|
exports.BASE_RPC_URLS_SANDBOX = ["https://sepolia.base.org", "https://base-sepolia-rpc.publicnode.com"];
|
|
14
15
|
exports.ACCEPTED_TOKENS = {
|
package/dist/errors/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,oBAAY,SAAS;IACnB,QAAQ,cAAc;IACtB,iBAAiB,uBAAuB;IACxC,YAAY,mBAAmB;IAC/B,gBAAgB,uBAAuB;IACvC,iBAAiB,uBAAuB;IACxC,oBAAoB,0BAA0B;IAC9C,cAAc,oBAAoB;IAClC,aAAa,mBAAmB;IAChC,mBAAmB,0BAA0B;IAC7C,aAAa,mBAAmB;IAChC,aAAa,mBAAmB;IAChC,cAAc,oBAAoB;CACnC;AAED,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAajD,CAAC;AAEF,qBAAa,gBAAiB,SAAQ,KAAK;IACtB,IAAI,EAAE,SAAS;IAA2B,OAAO,CAAC,EAAE,GAAG;gBAAvD,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,EAAS,OAAO,CAAC,EAAE,GAAG,YAAA;CAM3E"}
|
package/dist/errors/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PayNodeException = exports.ERROR_MESSAGES = exports.ErrorCode = void 0;
|
|
4
|
-
/** Generated by scripts/sync-config.py */
|
|
4
|
+
/** Generated by meta/scripts/sync-config.py */
|
|
5
5
|
var ErrorCode;
|
|
6
6
|
(function (ErrorCode) {
|
|
7
7
|
ErrorCode["RpcError"] = "rpc_error";
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.ethers = void 0;
|
|
17
18
|
__exportStar(require("./middleware/x402"), exports);
|
|
18
19
|
__exportStar(require("./utils/verifier"), exports);
|
|
19
20
|
__exportStar(require("./utils/idempotency"), exports);
|
|
@@ -21,4 +22,7 @@ __exportStar(require("./utils/webhook"), exports);
|
|
|
21
22
|
__exportStar(require("./client"), exports);
|
|
22
23
|
__exportStar(require("./errors"), exports);
|
|
23
24
|
__exportStar(require("./constants"), exports);
|
|
25
|
+
__exportStar(require("./utils/payload"), exports);
|
|
24
26
|
__exportStar(require("./types/x402"), exports);
|
|
27
|
+
var ethers_1 = require("ethers");
|
|
28
|
+
Object.defineProperty(exports, "ethers", { enumerable: true, get: function () { return ethers_1.ethers; } });
|
package/dist/middleware/x402.js
CHANGED
|
@@ -30,7 +30,7 @@ const x402Gate = (options) => {
|
|
|
30
30
|
fractionPart = fractionPart.slice(0, decimals).padEnd(decimals, '0');
|
|
31
31
|
rawAmount = BigInt(integerPart + fractionPart);
|
|
32
32
|
}
|
|
33
|
-
const defaultOrderIdGen = (req) => `
|
|
33
|
+
const defaultOrderIdGen = (req) => `pn_sdk_${Date.now()}`;
|
|
34
34
|
return async (req, res, next) => {
|
|
35
35
|
// ... rest of the logic
|
|
36
36
|
const getHeader = (name) => {
|
|
@@ -63,7 +63,7 @@ const x402Gate = (options) => {
|
|
|
63
63
|
inferredType = "onchain";
|
|
64
64
|
}
|
|
65
65
|
unifiedPayload = {
|
|
66
|
-
version: "2.2.
|
|
66
|
+
version: "2.2.2",
|
|
67
67
|
type: parsed._paynode?.type || inferredType,
|
|
68
68
|
orderId: internalOrderId,
|
|
69
69
|
router: parsed.accepted?.router,
|
|
@@ -71,7 +71,7 @@ const x402Gate = (options) => {
|
|
|
71
71
|
};
|
|
72
72
|
orderId = internalOrderId;
|
|
73
73
|
}
|
|
74
|
-
else if (parsed.version === "2.2.
|
|
74
|
+
else if (typeof parsed.version === 'string' && (parsed.version.startsWith("2.3") || parsed.version.startsWith("2.2"))) {
|
|
75
75
|
// Legacy PayNode format
|
|
76
76
|
unifiedPayload = parsed;
|
|
77
77
|
if (unifiedPayload?.orderId) {
|
package/dist/types/x402.d.ts
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { UnifiedPaymentPayload } from '../types/x402';
|
|
2
|
+
export declare class X402PayloadHelper {
|
|
3
|
+
/**
|
|
4
|
+
* Normalizes a raw payment payload (usually from PAYMENT-SIGNATURE or X-402-Payload headers)
|
|
5
|
+
* into the UnifiedPaymentPayload format used internally by PayNode.
|
|
6
|
+
*
|
|
7
|
+
* Supports:
|
|
8
|
+
* - standard X402 V2 format
|
|
9
|
+
* - legacy PayNode internal format (base64 encoded JSON)
|
|
10
|
+
*
|
|
11
|
+
* @param authHeader The base64 encoded payload header
|
|
12
|
+
* @param fallbackOrderId Optional orderId to use if missing from payload
|
|
13
|
+
* @returns UnifiedPaymentPayload
|
|
14
|
+
*/
|
|
15
|
+
static normalize(authHeader: string, fallbackOrderId?: string): UnifiedPaymentPayload;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=payload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../../src/utils/payload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEtD,qBAAa,iBAAiB;IAC5B;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,qBAAqB;CAuCtF"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.X402PayloadHelper = void 0;
|
|
4
|
+
class X402PayloadHelper {
|
|
5
|
+
/**
|
|
6
|
+
* Normalizes a raw payment payload (usually from PAYMENT-SIGNATURE or X-402-Payload headers)
|
|
7
|
+
* into the UnifiedPaymentPayload format used internally by PayNode.
|
|
8
|
+
*
|
|
9
|
+
* Supports:
|
|
10
|
+
* - standard X402 V2 format
|
|
11
|
+
* - legacy PayNode internal format (base64 encoded JSON)
|
|
12
|
+
*
|
|
13
|
+
* @param authHeader The base64 encoded payload header
|
|
14
|
+
* @param fallbackOrderId Optional orderId to use if missing from payload
|
|
15
|
+
* @returns UnifiedPaymentPayload
|
|
16
|
+
*/
|
|
17
|
+
static normalize(authHeader, fallbackOrderId) {
|
|
18
|
+
try {
|
|
19
|
+
const decoded = Buffer.from(authHeader, 'base64').toString('utf-8');
|
|
20
|
+
const parsed = JSON.parse(decoded);
|
|
21
|
+
// 1. Handle Official X402 V2 Standard Format
|
|
22
|
+
if (parsed.x402Version === 2 && parsed.accepted) {
|
|
23
|
+
let inferredType = "onchain";
|
|
24
|
+
// Inference logic: signature/authorization presence implies EIP-3009 (USDC Permit/TransferWithAuth)
|
|
25
|
+
if (parsed.payload?.signature || parsed.payload?.authorization) {
|
|
26
|
+
inferredType = "eip3009";
|
|
27
|
+
}
|
|
28
|
+
else if (parsed.payload?.txHash) {
|
|
29
|
+
inferredType = "onchain";
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
version: "2.2.2",
|
|
33
|
+
type: parsed._paynode?.type || inferredType,
|
|
34
|
+
orderId: parsed._paynode?.orderId || fallbackOrderId || "",
|
|
35
|
+
router: parsed.accepted?.router || parsed.router,
|
|
36
|
+
payload: parsed.payload
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
// 2. Handle Legacy or already Unified Format
|
|
40
|
+
if (typeof parsed.version === 'string' && (parsed.version.startsWith("2.2") || parsed.version.startsWith("2.3"))) {
|
|
41
|
+
return {
|
|
42
|
+
...parsed,
|
|
43
|
+
orderId: parsed.orderId || parsed.order_id || fallbackOrderId || ""
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
// 3. Fallback for raw internal format
|
|
47
|
+
return parsed;
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
throw new Error(`Failed to normalize PayNode payload: ${e instanceof Error ? e.message : String(e)}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.X402PayloadHelper = X402PayloadHelper;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paynodelabs/sdk-js",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"description": "The official JavaScript/TypeScript SDK for PayNode x402 protocol on Base L2.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"author": "PayNodeLabs",
|
|
26
26
|
"license": "MIT",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"ethers": "^6.
|
|
28
|
+
"ethers": "^6.16.0",
|
|
29
29
|
"ioredis": "^5.10.1"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|