@zauthx402/sdk 0.1.6 → 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.
@@ -1,2 +1,2 @@
1
- export { d as ZauthMiddlewareOptions, b as createZauthMiddleware, z as zauthProvider } from '../index-CylVkunV.mjs';
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-CylVkunV.js';
1
+ export { d as ZauthMiddlewareOptions, b as createZauthMiddleware, z as zauthProvider } from '../index-C2FGNEe1.js';
2
2
  import 'express';
@@ -60,9 +60,9 @@ var require_constants = __commonJS({
60
60
  }
61
61
  });
62
62
 
63
- // ../../node_modules/node-gyp-build/node-gyp-build.js
63
+ // node_modules/node-gyp-build/node-gyp-build.js
64
64
  var require_node_gyp_build = __commonJS({
65
- "../../node_modules/node-gyp-build/node-gyp-build.js"(exports$1, module) {
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
- // ../../node_modules/node-gyp-build/index.js
232
+ // node_modules/node-gyp-build/index.js
233
233
  var require_node_gyp_build2 = __commonJS({
234
- "../../node_modules/node-gyp-build/index.js"(exports$1, module) {
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
- // ../../node_modules/bufferutil/fallback.js
244
+ // node_modules/bufferutil/fallback.js
245
245
  var require_fallback = __commonJS({
246
- "../../node_modules/bufferutil/fallback.js"(exports$1, module) {
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
- // ../../node_modules/bufferutil/index.js
262
+ // node_modules/bufferutil/index.js
263
263
  var require_bufferutil = __commonJS({
264
- "../../node_modules/bufferutil/index.js"(exports$1, module) {
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
- // ../../node_modules/utf-8-validate/fallback.js
778
+ // node_modules/utf-8-validate/fallback.js
779
779
  var require_fallback2 = __commonJS({
780
- "../../node_modules/utf-8-validate/fallback.js"(exports$1, module) {
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
- // ../../node_modules/utf-8-validate/index.js
814
+ // node_modules/utf-8-validate/index.js
815
815
  var require_utf_8_validate = __commonJS({
816
- "../../node_modules/utf-8-validate/index.js"(exports$1, module) {
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
- const payer = parsed.payload?.authorization?.from || // x402 V2
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
- const network = parsed.payload?.authorization?.network || // x402 V2
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) {
@@ -5075,14 +5128,98 @@ var RefundExecutor = class {
5075
5128
  }
5076
5129
  }
5077
5130
  /**
5078
- * Execute Solana refund
5131
+ * Execute Solana refund using @solana/kit v2 libraries
5079
5132
  */
5080
- async executeSolanaRefund(_refund, _amountRaw) {
5081
- return {
5082
- success: false,
5083
- error: "Solana refunds not yet implemented",
5084
- retryable: false
5085
- };
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
+ }
5086
5223
  }
5087
5224
  /**
5088
5225
  * Get endpoint-specific config by matching URL patterns