@paynodelabs/sdk-js 2.1.0 → 2.1.1
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifier.d.ts","sourceRoot":"","sources":["../../src/utils/verifier.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,gBAAgB,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAA0B,MAAM,eAAe,CAAC;AAEzE,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEvE,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,oGAAoG;IACpG,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAqC;IACrD,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,KAAK,CAAC,CAAmB;IACjC,OAAO,CAAC,cAAc,CAAc;gBAExB,MAAM,EAAE,qBAAqB;IAyCzC,OAAO,CAAC,MAAM,CAAC,UAAU,CAEvB;IAEI,MAAM,CACV,cAAc,EAAE,qBAAqB,EACrC,QAAQ,EAAE,eAAe,EACzB,KAAK,CAAC,EAAE,GAAG,GACV,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,gBAAgB,CAAA;KAAE,CAAC;IA8BpD,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,gBAAgB,CAAA;KAAE,CAAC;IA0ElH;;;OAGG;IACG,+BAA+B,CACnC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE;QACR,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;KACjC,EACD,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAC9B,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,gBAAgB,CAAA;KAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"verifier.d.ts","sourceRoot":"","sources":["../../src/utils/verifier.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,gBAAgB,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAA0B,MAAM,eAAe,CAAC;AAEzE,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEvE,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,oGAAoG;IACpG,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAqC;IACrD,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,KAAK,CAAC,CAAmB;IACjC,OAAO,CAAC,cAAc,CAAc;gBAExB,MAAM,EAAE,qBAAqB;IAyCzC,OAAO,CAAC,MAAM,CAAC,UAAU,CAEvB;IAEI,MAAM,CACV,cAAc,EAAE,qBAAqB,EACrC,QAAQ,EAAE,eAAe,EACzB,KAAK,CAAC,EAAE,GAAG,GACV,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,gBAAgB,CAAA;KAAE,CAAC;IA8BpD,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,gBAAgB,CAAA;KAAE,CAAC;IA0ElH;;;OAGG;IACG,+BAA+B,CACnC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE;QACR,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;KACjC,EACD,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAC9B,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,gBAAgB,CAAA;KAAE,CAAC;CA0G3D"}
|
package/dist/utils/verifier.js
CHANGED
|
@@ -152,6 +152,9 @@ class PayNodeVerifier {
|
|
|
152
152
|
* 耗时: < 50ms (仅需一次 RPC Read)
|
|
153
153
|
*/
|
|
154
154
|
async verifyTransferWithAuthorization(tokenAddr, payload, expected, extra = {}) {
|
|
155
|
+
let isLocked = false;
|
|
156
|
+
const { signature, authorization } = payload;
|
|
157
|
+
const nonce = authorization?.nonce;
|
|
155
158
|
try {
|
|
156
159
|
// 1. Security Checks
|
|
157
160
|
if (BigInt(expected.value) < constants_1.MIN_PAYMENT_AMOUNT) {
|
|
@@ -160,8 +163,7 @@ class PayNodeVerifier {
|
|
|
160
163
|
if (!this.acceptedTokens.has(tokenAddr.toLowerCase())) {
|
|
161
164
|
return { isValid: false, error: new errors_1.PayNodeException(errors_1.ErrorCode.TokenNotAccepted) };
|
|
162
165
|
}
|
|
163
|
-
const {
|
|
164
|
-
const { from, to, value, validAfter, validBefore, nonce } = authorization;
|
|
166
|
+
const { from, to, value, validAfter, validBefore } = authorization;
|
|
165
167
|
const expectedValue = BigInt(expected.value);
|
|
166
168
|
const payloadValue = BigInt(value);
|
|
167
169
|
// 2. 基础字段与金额校验 (防粉尘攻击)
|
|
@@ -205,8 +207,9 @@ class PayNodeVerifier {
|
|
|
205
207
|
if (this.store) {
|
|
206
208
|
const isNew = await this.store.checkAndSet(nonce, 86400); // 锁定 24 小时
|
|
207
209
|
if (!isNew) {
|
|
208
|
-
return { isValid: false, error: new errors_1.PayNodeException(errors_1.ErrorCode.DuplicateTransaction, "Nonce already used
|
|
210
|
+
return { isValid: false, error: new errors_1.PayNodeException(errors_1.ErrorCode.DuplicateTransaction, "Nonce already used or transaction already consumed") };
|
|
209
211
|
}
|
|
212
|
+
isLocked = true;
|
|
210
213
|
}
|
|
211
214
|
// ================= 核心补全:RPC 状态只读校验 (<50ms) =================
|
|
212
215
|
const tokenContract = new ethers_1.ethers.Contract(tokenAddr, [
|
|
@@ -222,14 +225,13 @@ class PayNodeVerifier {
|
|
|
222
225
|
]);
|
|
223
226
|
// 5. 校验真实余额 (防止空钱包签署有效签名)
|
|
224
227
|
if (BigInt(balance) < payloadValue) {
|
|
225
|
-
|
|
226
|
-
if (this.store)
|
|
228
|
+
if (isLocked && this.store)
|
|
227
229
|
await this.store.delete(nonce);
|
|
228
230
|
return { isValid: false, error: new errors_1.PayNodeException(errors_1.ErrorCode.InvalidReceipt, "Insufficient token balance") };
|
|
229
231
|
}
|
|
230
232
|
// 6. 校验链上 Nonce 状态 (防止该签名已被打包结算)
|
|
231
233
|
if (isNonceUsedOnChain) {
|
|
232
|
-
if (this.store)
|
|
234
|
+
if (isLocked && this.store)
|
|
233
235
|
await this.store.delete(nonce);
|
|
234
236
|
return { isValid: false, error: new errors_1.PayNodeException(errors_1.ErrorCode.DuplicateTransaction, "Nonce already consumed on-chain") };
|
|
235
237
|
}
|
|
@@ -237,6 +239,10 @@ class PayNodeVerifier {
|
|
|
237
239
|
return { isValid: true };
|
|
238
240
|
}
|
|
239
241
|
catch (e) {
|
|
242
|
+
if (isLocked && this.store)
|
|
243
|
+
await this.store.delete(nonce);
|
|
244
|
+
if (e instanceof errors_1.PayNodeException)
|
|
245
|
+
return { isValid: false, error: e };
|
|
240
246
|
return { isValid: false, error: new errors_1.PayNodeException(errors_1.ErrorCode.InternalError, e.message) };
|
|
241
247
|
}
|
|
242
248
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paynodelabs/sdk-js",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.1",
|
|
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",
|
|
@@ -43,4 +43,4 @@
|
|
|
43
43
|
"overrides": {
|
|
44
44
|
"brace-expansion": "^5.0.5"
|
|
45
45
|
}
|
|
46
|
-
}
|
|
46
|
+
}
|