@zauthx402/sdk 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index-CzB2rK59.d.mts → index-C2FGNEe1.d.mts} +8 -2
- package/dist/{index-CzB2rK59.d.ts → index-C2FGNEe1.d.ts} +8 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +193 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +193 -21
- package/dist/index.mjs.map +1 -1
- package/dist/middleware/index.d.mts +1 -1
- package/dist/middleware/index.d.ts +1 -1
- package/dist/middleware/index.js +193 -21
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/index.mjs +193 -21
- package/dist/middleware/index.mjs.map +1 -1
- package/package.json +7 -2
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { d as ZauthMiddlewareOptions, b as createZauthMiddleware, z as zauthProvider } from '../index-
|
|
1
|
+
export { d as ZauthMiddlewareOptions, b as createZauthMiddleware, z as zauthProvider } from '../index-C2FGNEe1.mjs';
|
|
2
2
|
import 'express';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { d as ZauthMiddlewareOptions, b as createZauthMiddleware, z as zauthProvider } from '../index-
|
|
1
|
+
export { d as ZauthMiddlewareOptions, b as createZauthMiddleware, z as zauthProvider } from '../index-C2FGNEe1.js';
|
|
2
2
|
import 'express';
|
package/dist/middleware/index.js
CHANGED
|
@@ -60,9 +60,9 @@ var require_constants = __commonJS({
|
|
|
60
60
|
}
|
|
61
61
|
});
|
|
62
62
|
|
|
63
|
-
//
|
|
63
|
+
// node_modules/node-gyp-build/node-gyp-build.js
|
|
64
64
|
var require_node_gyp_build = __commonJS({
|
|
65
|
-
"
|
|
65
|
+
"node_modules/node-gyp-build/node-gyp-build.js"(exports$1, module) {
|
|
66
66
|
var fs = __require("fs");
|
|
67
67
|
var path = __require("path");
|
|
68
68
|
var os = __require("os");
|
|
@@ -229,9 +229,9 @@ var require_node_gyp_build = __commonJS({
|
|
|
229
229
|
}
|
|
230
230
|
});
|
|
231
231
|
|
|
232
|
-
//
|
|
232
|
+
// node_modules/node-gyp-build/index.js
|
|
233
233
|
var require_node_gyp_build2 = __commonJS({
|
|
234
|
-
"
|
|
234
|
+
"node_modules/node-gyp-build/index.js"(exports$1, module) {
|
|
235
235
|
var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
236
236
|
if (typeof runtimeRequire.addon === "function") {
|
|
237
237
|
module.exports = runtimeRequire.addon.bind(runtimeRequire);
|
|
@@ -241,9 +241,9 @@ var require_node_gyp_build2 = __commonJS({
|
|
|
241
241
|
}
|
|
242
242
|
});
|
|
243
243
|
|
|
244
|
-
//
|
|
244
|
+
// node_modules/bufferutil/fallback.js
|
|
245
245
|
var require_fallback = __commonJS({
|
|
246
|
-
"
|
|
246
|
+
"node_modules/bufferutil/fallback.js"(exports$1, module) {
|
|
247
247
|
var mask = (source, mask2, output, offset, length) => {
|
|
248
248
|
for (var i = 0; i < length; i++) {
|
|
249
249
|
output[offset + i] = source[i] ^ mask2[i & 3];
|
|
@@ -259,9 +259,9 @@ var require_fallback = __commonJS({
|
|
|
259
259
|
}
|
|
260
260
|
});
|
|
261
261
|
|
|
262
|
-
//
|
|
262
|
+
// node_modules/bufferutil/index.js
|
|
263
263
|
var require_bufferutil = __commonJS({
|
|
264
|
-
"
|
|
264
|
+
"node_modules/bufferutil/index.js"(exports$1, module) {
|
|
265
265
|
try {
|
|
266
266
|
module.exports = require_node_gyp_build2()(__dirname);
|
|
267
267
|
} catch (e) {
|
|
@@ -775,9 +775,9 @@ var require_permessage_deflate = __commonJS({
|
|
|
775
775
|
}
|
|
776
776
|
});
|
|
777
777
|
|
|
778
|
-
//
|
|
778
|
+
// node_modules/utf-8-validate/fallback.js
|
|
779
779
|
var require_fallback2 = __commonJS({
|
|
780
|
-
"
|
|
780
|
+
"node_modules/utf-8-validate/fallback.js"(exports$1, module) {
|
|
781
781
|
function isValidUTF8(buf) {
|
|
782
782
|
const len = buf.length;
|
|
783
783
|
let i = 0;
|
|
@@ -811,9 +811,9 @@ var require_fallback2 = __commonJS({
|
|
|
811
811
|
}
|
|
812
812
|
});
|
|
813
813
|
|
|
814
|
-
//
|
|
814
|
+
// node_modules/utf-8-validate/index.js
|
|
815
815
|
var require_utf_8_validate = __commonJS({
|
|
816
|
-
"
|
|
816
|
+
"node_modules/utf-8-validate/index.js"(exports$1, module) {
|
|
817
817
|
try {
|
|
818
818
|
module.exports = require_node_gyp_build2()(__dirname);
|
|
819
819
|
} catch (e) {
|
|
@@ -3933,6 +3933,7 @@ var DEFAULT_CONFIG = {
|
|
|
3933
3933
|
refund: {
|
|
3934
3934
|
enabled: false,
|
|
3935
3935
|
privateKey: process.env.ZAUTH_REFUND_PRIVATE_KEY,
|
|
3936
|
+
solanaPrivateKey: process.env.ZAUTH_SOLANA_PRIVATE_KEY,
|
|
3936
3937
|
network: "base",
|
|
3937
3938
|
triggers: {
|
|
3938
3939
|
serverError: true,
|
|
@@ -3963,6 +3964,7 @@ function resolveConfig(config) {
|
|
|
3963
3964
|
enabled: config.refund?.enabled ?? DEFAULT_CONFIG.refund.enabled,
|
|
3964
3965
|
signer: config.refund?.signer,
|
|
3965
3966
|
privateKey: config.refund?.privateKey ?? DEFAULT_CONFIG.refund.privateKey,
|
|
3967
|
+
solanaPrivateKey: config.refund?.solanaPrivateKey ?? DEFAULT_CONFIG.refund.solanaPrivateKey,
|
|
3966
3968
|
network: config.refund?.network ?? DEFAULT_CONFIG.refund.network,
|
|
3967
3969
|
triggers: {
|
|
3968
3970
|
...DEFAULT_CONFIG.refund.triggers,
|
|
@@ -4535,17 +4537,68 @@ function decodePaymentHeader(paymentHeader) {
|
|
|
4535
4537
|
decoded = paymentHeader;
|
|
4536
4538
|
}
|
|
4537
4539
|
const parsed = JSON.parse(decoded);
|
|
4538
|
-
|
|
4540
|
+
let payer = parsed.payload?.authorization?.from || // x402 V2 EVM
|
|
4539
4541
|
parsed.payer || parsed.from || parsed.payload?.from || parsed.x?.signature?.address || null;
|
|
4542
|
+
if (!payer && parsed.payload?.transaction) {
|
|
4543
|
+
payer = extractSolanaFeePayer(parsed.payload.transaction);
|
|
4544
|
+
}
|
|
4540
4545
|
const amount = parsed.payload?.authorization?.value || // x402 V2
|
|
4541
4546
|
parsed.amount || parsed.payload?.amount || null;
|
|
4542
|
-
|
|
4547
|
+
let network = parsed.payload?.authorization?.network || // x402 V2 EVM
|
|
4543
4548
|
parsed.network || parsed.payload?.network || null;
|
|
4549
|
+
if (!network && parsed.payload?.transaction && payer) {
|
|
4550
|
+
network = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
|
|
4551
|
+
}
|
|
4544
4552
|
return { payer, amount, network };
|
|
4545
4553
|
} catch {
|
|
4546
4554
|
return null;
|
|
4547
4555
|
}
|
|
4548
4556
|
}
|
|
4557
|
+
function extractSolanaFeePayer(base64Transaction) {
|
|
4558
|
+
try {
|
|
4559
|
+
const txBytes = typeof Buffer !== "undefined" ? Buffer.from(base64Transaction, "base64") : Uint8Array.from(atob(base64Transaction), (c) => c.charCodeAt(0));
|
|
4560
|
+
let offset = 0;
|
|
4561
|
+
const numSignatures = txBytes[offset];
|
|
4562
|
+
offset += 1;
|
|
4563
|
+
offset += numSignatures * 64;
|
|
4564
|
+
const firstByte = txBytes[offset];
|
|
4565
|
+
if ((firstByte & 128) !== 0) {
|
|
4566
|
+
offset += 1;
|
|
4567
|
+
}
|
|
4568
|
+
offset += 3;
|
|
4569
|
+
const numAccounts = txBytes[offset];
|
|
4570
|
+
offset += 1;
|
|
4571
|
+
if (numAccounts > 0 && offset + 32 <= txBytes.length) {
|
|
4572
|
+
const feePayerBytes = txBytes.slice(offset, offset + 32);
|
|
4573
|
+
return base58Encode(feePayerBytes);
|
|
4574
|
+
}
|
|
4575
|
+
return null;
|
|
4576
|
+
} catch {
|
|
4577
|
+
return null;
|
|
4578
|
+
}
|
|
4579
|
+
}
|
|
4580
|
+
function base58Encode(bytes) {
|
|
4581
|
+
const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
4582
|
+
const BASE = 58;
|
|
4583
|
+
let num = BigInt(0);
|
|
4584
|
+
for (const byte of bytes) {
|
|
4585
|
+
num = num * BigInt(256) + BigInt(byte);
|
|
4586
|
+
}
|
|
4587
|
+
let result = "";
|
|
4588
|
+
while (num > 0) {
|
|
4589
|
+
const remainder = Number(num % BigInt(BASE));
|
|
4590
|
+
num = num / BigInt(BASE);
|
|
4591
|
+
result = ALPHABET[remainder] + result;
|
|
4592
|
+
}
|
|
4593
|
+
for (const byte of bytes) {
|
|
4594
|
+
if (byte === 0) {
|
|
4595
|
+
result = "1" + result;
|
|
4596
|
+
} else {
|
|
4597
|
+
break;
|
|
4598
|
+
}
|
|
4599
|
+
}
|
|
4600
|
+
return result || "1";
|
|
4601
|
+
}
|
|
4549
4602
|
|
|
4550
4603
|
// src/validator.ts
|
|
4551
4604
|
function validateResponse(body, statusCode, config) {
|
|
@@ -4695,6 +4748,8 @@ var RefundExecutor = class {
|
|
|
4695
4748
|
// YYYY-MM-DD
|
|
4696
4749
|
lastCapResetMonth = (/* @__PURE__ */ new Date()).toISOString().slice(0, 7);
|
|
4697
4750
|
// YYYY-MM
|
|
4751
|
+
// Track processed refundIds to prevent double execution within same session
|
|
4752
|
+
processedRefundIds = /* @__PURE__ */ new Set();
|
|
4698
4753
|
constructor(client, config, debug = false) {
|
|
4699
4754
|
this.client = client;
|
|
4700
4755
|
this.config = config;
|
|
@@ -4787,6 +4842,11 @@ var RefundExecutor = class {
|
|
|
4787
4842
|
case "rejection_ack":
|
|
4788
4843
|
this.log("Refund rejection acknowledged", { refundId: msg.refundId });
|
|
4789
4844
|
break;
|
|
4845
|
+
case "executing_ack":
|
|
4846
|
+
if (this.debug) {
|
|
4847
|
+
this.log("Refund executing acknowledged", { refundId: msg.refundId, status: msg.status });
|
|
4848
|
+
}
|
|
4849
|
+
break;
|
|
4790
4850
|
case "pong":
|
|
4791
4851
|
break;
|
|
4792
4852
|
default:
|
|
@@ -4801,6 +4861,10 @@ var RefundExecutor = class {
|
|
|
4801
4861
|
*/
|
|
4802
4862
|
async processSingleRefund(refund) {
|
|
4803
4863
|
try {
|
|
4864
|
+
if (this.processedRefundIds.has(refund.id)) {
|
|
4865
|
+
this.log("Refund already processed in this session", { refundId: refund.id });
|
|
4866
|
+
return;
|
|
4867
|
+
}
|
|
4804
4868
|
const endpointConfig = this.getEndpointConfig(refund.url);
|
|
4805
4869
|
if (endpointConfig?.enabled === false) {
|
|
4806
4870
|
this.log("Refunds disabled for endpoint", { url: refund.url });
|
|
@@ -4859,8 +4923,13 @@ var RefundExecutor = class {
|
|
|
4859
4923
|
return;
|
|
4860
4924
|
}
|
|
4861
4925
|
}
|
|
4926
|
+
this.sendMessage({
|
|
4927
|
+
type: "refund_executing",
|
|
4928
|
+
refundId: refund.id
|
|
4929
|
+
});
|
|
4862
4930
|
const result = await this.executeRefundTx(refund);
|
|
4863
4931
|
if (result.success) {
|
|
4932
|
+
this.processedRefundIds.add(refund.id);
|
|
4864
4933
|
this.sendMessage({
|
|
4865
4934
|
type: "refund_confirmed",
|
|
4866
4935
|
refundId: refund.id,
|
|
@@ -5059,14 +5128,98 @@ var RefundExecutor = class {
|
|
|
5059
5128
|
}
|
|
5060
5129
|
}
|
|
5061
5130
|
/**
|
|
5062
|
-
* Execute Solana refund
|
|
5131
|
+
* Execute Solana refund using @solana/kit v2 libraries
|
|
5063
5132
|
*/
|
|
5064
|
-
async executeSolanaRefund(
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5133
|
+
async executeSolanaRefund(refund, amountRaw) {
|
|
5134
|
+
try {
|
|
5135
|
+
const solanaPrivateKey = this.config.solanaPrivateKey;
|
|
5136
|
+
if (!solanaPrivateKey) {
|
|
5137
|
+
return {
|
|
5138
|
+
success: false,
|
|
5139
|
+
error: "No Solana private key configured (set ZAUTH_SOLANA_PRIVATE_KEY)",
|
|
5140
|
+
retryable: false
|
|
5141
|
+
};
|
|
5142
|
+
}
|
|
5143
|
+
const { createKeyPairSignerFromPrivateKeyBytes } = await import('@solana/signers');
|
|
5144
|
+
const {
|
|
5145
|
+
createSolanaRpc,
|
|
5146
|
+
address,
|
|
5147
|
+
pipe,
|
|
5148
|
+
createTransactionMessage,
|
|
5149
|
+
setTransactionMessageFeePayer,
|
|
5150
|
+
setTransactionMessageLifetimeUsingBlockhash,
|
|
5151
|
+
appendTransactionMessageInstructions,
|
|
5152
|
+
signTransactionMessageWithSigners,
|
|
5153
|
+
getBase64EncodedWireTransaction
|
|
5154
|
+
} = await import('@solana/kit');
|
|
5155
|
+
const {
|
|
5156
|
+
findAssociatedTokenPda,
|
|
5157
|
+
getTransferInstruction,
|
|
5158
|
+
TOKEN_PROGRAM_ADDRESS
|
|
5159
|
+
} = await import('@solana-program/token');
|
|
5160
|
+
const bs58 = await import('bs58');
|
|
5161
|
+
const USDC_MINT = address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
|
|
5162
|
+
const rpcUrl = process.env.SOLANA_RPC_URL || "https://api.mainnet-beta.solana.com";
|
|
5163
|
+
const rpc = createSolanaRpc(rpcUrl);
|
|
5164
|
+
let signer;
|
|
5165
|
+
try {
|
|
5166
|
+
const secretKey = bs58.default.decode(solanaPrivateKey);
|
|
5167
|
+
const privateKeyBytes = secretKey.slice(0, 32);
|
|
5168
|
+
signer = await createKeyPairSignerFromPrivateKeyBytes(privateKeyBytes);
|
|
5169
|
+
} catch {
|
|
5170
|
+
return {
|
|
5171
|
+
success: false,
|
|
5172
|
+
error: "Invalid Solana private key format (expected base58)",
|
|
5173
|
+
retryable: false
|
|
5174
|
+
};
|
|
5175
|
+
}
|
|
5176
|
+
const recipientAddress = address(refund.recipientAddress);
|
|
5177
|
+
const [senderAta] = await findAssociatedTokenPda({
|
|
5178
|
+
mint: USDC_MINT,
|
|
5179
|
+
owner: signer.address,
|
|
5180
|
+
tokenProgram: TOKEN_PROGRAM_ADDRESS
|
|
5181
|
+
});
|
|
5182
|
+
const [recipientAta] = await findAssociatedTokenPda({
|
|
5183
|
+
mint: USDC_MINT,
|
|
5184
|
+
owner: recipientAddress,
|
|
5185
|
+
tokenProgram: TOKEN_PROGRAM_ADDRESS
|
|
5186
|
+
});
|
|
5187
|
+
const transferIx = getTransferInstruction({
|
|
5188
|
+
source: senderAta,
|
|
5189
|
+
destination: recipientAta,
|
|
5190
|
+
authority: signer,
|
|
5191
|
+
amount: BigInt(amountRaw)
|
|
5192
|
+
});
|
|
5193
|
+
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
|
|
5194
|
+
const tx = pipe(
|
|
5195
|
+
createTransactionMessage({ version: 0 }),
|
|
5196
|
+
(tx2) => setTransactionMessageFeePayer(signer.address, tx2),
|
|
5197
|
+
(tx2) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx2),
|
|
5198
|
+
(tx2) => appendTransactionMessageInstructions([transferIx], tx2)
|
|
5199
|
+
);
|
|
5200
|
+
const signedTx = await signTransactionMessageWithSigners(tx);
|
|
5201
|
+
const base64Tx = getBase64EncodedWireTransaction(signedTx);
|
|
5202
|
+
const txSignature = await rpc.sendTransaction(base64Tx, { encoding: "base64" }).send();
|
|
5203
|
+
this.log("Solana refund sent", {
|
|
5204
|
+
txHash: txSignature,
|
|
5205
|
+
to: refund.recipientAddress,
|
|
5206
|
+
amount: amountRaw
|
|
5207
|
+
});
|
|
5208
|
+
return {
|
|
5209
|
+
success: true,
|
|
5210
|
+
txHash: txSignature,
|
|
5211
|
+
amountRaw,
|
|
5212
|
+
gasCostCents: 0
|
|
5213
|
+
// Solana fees are negligible
|
|
5214
|
+
};
|
|
5215
|
+
} catch (error) {
|
|
5216
|
+
this.log("Solana refund failed", { error: error.message });
|
|
5217
|
+
return {
|
|
5218
|
+
success: false,
|
|
5219
|
+
error: error.message,
|
|
5220
|
+
retryable: true
|
|
5221
|
+
};
|
|
5222
|
+
}
|
|
5070
5223
|
}
|
|
5071
5224
|
/**
|
|
5072
5225
|
* Get endpoint-specific config by matching URL patterns
|
|
@@ -5106,6 +5259,25 @@ function createZauthMiddleware(options) {
|
|
|
5106
5259
|
if (config.debug) {
|
|
5107
5260
|
console.log("[zauthSDK] Refund executor started");
|
|
5108
5261
|
}
|
|
5262
|
+
client.updateRefundConfig({
|
|
5263
|
+
enabled: true,
|
|
5264
|
+
maxRefundUsdCents: Math.round((config.refund.maxRefundUsd || 1) * 100),
|
|
5265
|
+
dailyCapCents: config.refund.dailyCapUsd ? Math.round(config.refund.dailyCapUsd * 100) : void 0,
|
|
5266
|
+
monthlyCapCents: config.refund.monthlyCapUsd ? Math.round(config.refund.monthlyCapUsd * 100) : void 0,
|
|
5267
|
+
triggers: {
|
|
5268
|
+
serverError: config.refund.triggers?.serverError ?? true,
|
|
5269
|
+
timeout: config.refund.triggers?.timeout ?? true,
|
|
5270
|
+
emptyResponse: config.refund.triggers?.emptyResponse ?? true,
|
|
5271
|
+
schemaValidation: config.refund.triggers?.schemaValidation ?? false,
|
|
5272
|
+
minMeaningfulness: config.refund.triggers?.minMeaningfulness ?? 0.3
|
|
5273
|
+
}
|
|
5274
|
+
}).then((result) => {
|
|
5275
|
+
if (config.debug) {
|
|
5276
|
+
console.log("[zauthSDK] Refund config registered with server", { success: result.success });
|
|
5277
|
+
}
|
|
5278
|
+
}).catch((err) => {
|
|
5279
|
+
console.error("[zauthSDK] Failed to register refund config:", err.message);
|
|
5280
|
+
});
|
|
5109
5281
|
}
|
|
5110
5282
|
function shouldMonitorRoute(req) {
|
|
5111
5283
|
if (options.shouldMonitor) {
|