@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.
@@ -542,10 +542,14 @@ interface RefundConfig {
542
542
  */
543
543
  signer?: RefundSigner;
544
544
  /**
545
- * Private key for refund transactions (deprecated, use signer)
545
+ * Private key for EVM refund transactions (hex format)
546
546
  * @deprecated Use signer instead
547
547
  */
548
548
  privateKey?: string;
549
+ /**
550
+ * Private key for Solana refund transactions (base58 format)
551
+ */
552
+ solanaPrivateKey?: string;
549
553
  /**
550
554
  * Default network for refunds (can be overridden per-endpoint)
551
555
  * @default 'base'
@@ -743,6 +747,7 @@ interface ResolvedRefundConfig {
743
747
  enabled: boolean;
744
748
  signer?: RefundSigner;
745
749
  privateKey?: string;
750
+ solanaPrivateKey?: string;
746
751
  network: X402Network;
747
752
  triggers: Required<RefundTriggers>;
748
753
  maxRefundUsd: number;
@@ -1055,7 +1060,7 @@ declare class RefundExecutor {
1055
1060
  */
1056
1061
  private executeEvmRefund;
1057
1062
  /**
1058
- * Execute Solana refund
1063
+ * Execute Solana refund using @solana/kit v2 libraries
1059
1064
  */
1060
1065
  private executeSolanaRefund;
1061
1066
  /**
@@ -542,10 +542,14 @@ interface RefundConfig {
542
542
  */
543
543
  signer?: RefundSigner;
544
544
  /**
545
- * Private key for refund transactions (deprecated, use signer)
545
+ * Private key for EVM refund transactions (hex format)
546
546
  * @deprecated Use signer instead
547
547
  */
548
548
  privateKey?: string;
549
+ /**
550
+ * Private key for Solana refund transactions (base58 format)
551
+ */
552
+ solanaPrivateKey?: string;
549
553
  /**
550
554
  * Default network for refunds (can be overridden per-endpoint)
551
555
  * @default 'base'
@@ -743,6 +747,7 @@ interface ResolvedRefundConfig {
743
747
  enabled: boolean;
744
748
  signer?: RefundSigner;
745
749
  privateKey?: string;
750
+ solanaPrivateKey?: string;
746
751
  network: X402Network;
747
752
  triggers: Required<RefundTriggers>;
748
753
  maxRefundUsd: number;
@@ -1055,7 +1060,7 @@ declare class RefundExecutor {
1055
1060
  */
1056
1061
  private executeEvmRefund;
1057
1062
  /**
1058
- * Execute Solana refund
1063
+ * Execute Solana refund using @solana/kit v2 libraries
1059
1064
  */
1060
1065
  private executeSolanaRefund;
1061
1066
  /**
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { V as ValidationConfig, a as ValidationResult } from './index-CylVkunV.mjs';
2
- export { Q as BatchingConfig, K as ConfirmRefundRequest, L as ConfirmRefundResponse, a6 as DEFAULT_CONFIG, W as EndpointRefundConfig, E as EndpointStatus, B as ErrorEvent, F as EventBatch, G as EventSubmitResponse, _ as ExecutedRefund, H as HealthCheckEvent, P as PaymentEvent, I as PendingRefund, J as PendingRefundsResponse, a2 as ProviderMiddlewareConfig, a0 as RefundCondition, S as RefundConfig, $ as RefundError, y as RefundEvent, R as RefundHandler, Y as RefundPollingConfig, A as RefundReason, f as RefundRequest, g as RefundResult, T as RefundSigner, U as RefundTriggers, M as RejectRefundRequest, N as RejectRefundResponse, w as RequestEvent, a5 as ResolvedConfig, a4 as ResolvedRefundConfig, a3 as ResolvedValidationConfig, x as ResponseEvent, a1 as TelemetryConfig, C as ValidationCheck, X as X402Network, p as X402PaymentInfo, n as X402PaymentPayload, j as X402PaymentRequirement, o as X402PaymentResponse, m as X402Response, k as X402ResponseV1, l as X402ResponseV2, h as X402Scheme, i as X402Version, Z as ZauthClient, O as ZauthConfig, D as ZauthEvent, v as ZauthEventBase, d as ZauthMiddlewareOptions, c as createClient, e as createRefundHandler, b as createZauthMiddleware, t as decodePaymentResponse, u as encodePaymentPayload, r as getPaymentRequirements, s as getPriceUsdc, q as parseX402Response, a7 as resolveConfig, z as zauthProvider } from './index-CylVkunV.mjs';
1
+ import { V as ValidationConfig, a as ValidationResult } from './index-C2FGNEe1.mjs';
2
+ export { Q as BatchingConfig, K as ConfirmRefundRequest, L as ConfirmRefundResponse, a6 as DEFAULT_CONFIG, W as EndpointRefundConfig, E as EndpointStatus, B as ErrorEvent, F as EventBatch, G as EventSubmitResponse, _ as ExecutedRefund, H as HealthCheckEvent, P as PaymentEvent, I as PendingRefund, J as PendingRefundsResponse, a2 as ProviderMiddlewareConfig, a0 as RefundCondition, S as RefundConfig, $ as RefundError, y as RefundEvent, R as RefundHandler, Y as RefundPollingConfig, A as RefundReason, f as RefundRequest, g as RefundResult, T as RefundSigner, U as RefundTriggers, M as RejectRefundRequest, N as RejectRefundResponse, w as RequestEvent, a5 as ResolvedConfig, a4 as ResolvedRefundConfig, a3 as ResolvedValidationConfig, x as ResponseEvent, a1 as TelemetryConfig, C as ValidationCheck, X as X402Network, p as X402PaymentInfo, n as X402PaymentPayload, j as X402PaymentRequirement, o as X402PaymentResponse, m as X402Response, k as X402ResponseV1, l as X402ResponseV2, h as X402Scheme, i as X402Version, Z as ZauthClient, O as ZauthConfig, D as ZauthEvent, v as ZauthEventBase, d as ZauthMiddlewareOptions, c as createClient, e as createRefundHandler, b as createZauthMiddleware, t as decodePaymentResponse, u as encodePaymentPayload, r as getPaymentRequirements, s as getPriceUsdc, q as parseX402Response, a7 as resolveConfig, z as zauthProvider } from './index-C2FGNEe1.mjs';
3
3
  import 'express';
4
4
 
5
5
  /**
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { V as ValidationConfig, a as ValidationResult } from './index-CylVkunV.js';
2
- export { Q as BatchingConfig, K as ConfirmRefundRequest, L as ConfirmRefundResponse, a6 as DEFAULT_CONFIG, W as EndpointRefundConfig, E as EndpointStatus, B as ErrorEvent, F as EventBatch, G as EventSubmitResponse, _ as ExecutedRefund, H as HealthCheckEvent, P as PaymentEvent, I as PendingRefund, J as PendingRefundsResponse, a2 as ProviderMiddlewareConfig, a0 as RefundCondition, S as RefundConfig, $ as RefundError, y as RefundEvent, R as RefundHandler, Y as RefundPollingConfig, A as RefundReason, f as RefundRequest, g as RefundResult, T as RefundSigner, U as RefundTriggers, M as RejectRefundRequest, N as RejectRefundResponse, w as RequestEvent, a5 as ResolvedConfig, a4 as ResolvedRefundConfig, a3 as ResolvedValidationConfig, x as ResponseEvent, a1 as TelemetryConfig, C as ValidationCheck, X as X402Network, p as X402PaymentInfo, n as X402PaymentPayload, j as X402PaymentRequirement, o as X402PaymentResponse, m as X402Response, k as X402ResponseV1, l as X402ResponseV2, h as X402Scheme, i as X402Version, Z as ZauthClient, O as ZauthConfig, D as ZauthEvent, v as ZauthEventBase, d as ZauthMiddlewareOptions, c as createClient, e as createRefundHandler, b as createZauthMiddleware, t as decodePaymentResponse, u as encodePaymentPayload, r as getPaymentRequirements, s as getPriceUsdc, q as parseX402Response, a7 as resolveConfig, z as zauthProvider } from './index-CylVkunV.js';
1
+ import { V as ValidationConfig, a as ValidationResult } from './index-C2FGNEe1.js';
2
+ export { Q as BatchingConfig, K as ConfirmRefundRequest, L as ConfirmRefundResponse, a6 as DEFAULT_CONFIG, W as EndpointRefundConfig, E as EndpointStatus, B as ErrorEvent, F as EventBatch, G as EventSubmitResponse, _ as ExecutedRefund, H as HealthCheckEvent, P as PaymentEvent, I as PendingRefund, J as PendingRefundsResponse, a2 as ProviderMiddlewareConfig, a0 as RefundCondition, S as RefundConfig, $ as RefundError, y as RefundEvent, R as RefundHandler, Y as RefundPollingConfig, A as RefundReason, f as RefundRequest, g as RefundResult, T as RefundSigner, U as RefundTriggers, M as RejectRefundRequest, N as RejectRefundResponse, w as RequestEvent, a5 as ResolvedConfig, a4 as ResolvedRefundConfig, a3 as ResolvedValidationConfig, x as ResponseEvent, a1 as TelemetryConfig, C as ValidationCheck, X as X402Network, p as X402PaymentInfo, n as X402PaymentPayload, j as X402PaymentRequirement, o as X402PaymentResponse, m as X402Response, k as X402ResponseV1, l as X402ResponseV2, h as X402Scheme, i as X402Version, Z as ZauthClient, O as ZauthConfig, D as ZauthEvent, v as ZauthEventBase, d as ZauthMiddlewareOptions, c as createClient, e as createRefundHandler, b as createZauthMiddleware, t as decodePaymentResponse, u as encodePaymentPayload, r as getPaymentRequirements, s as getPriceUsdc, q as parseX402Response, a7 as resolveConfig, z as zauthProvider } from './index-C2FGNEe1.js';
3
3
  import 'express';
4
4
 
5
5
  /**
package/dist/index.js CHANGED
@@ -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,
@@ -4593,17 +4595,68 @@ function decodePaymentHeader(paymentHeader) {
4593
4595
  decoded = paymentHeader;
4594
4596
  }
4595
4597
  const parsed = JSON.parse(decoded);
4596
- const payer = parsed.payload?.authorization?.from || // x402 V2
4598
+ let payer = parsed.payload?.authorization?.from || // x402 V2 EVM
4597
4599
  parsed.payer || parsed.from || parsed.payload?.from || parsed.x?.signature?.address || null;
4600
+ if (!payer && parsed.payload?.transaction) {
4601
+ payer = extractSolanaFeePayer(parsed.payload.transaction);
4602
+ }
4598
4603
  const amount = parsed.payload?.authorization?.value || // x402 V2
4599
4604
  parsed.amount || parsed.payload?.amount || null;
4600
- const network = parsed.payload?.authorization?.network || // x402 V2
4605
+ let network = parsed.payload?.authorization?.network || // x402 V2 EVM
4601
4606
  parsed.network || parsed.payload?.network || null;
4607
+ if (!network && parsed.payload?.transaction && payer) {
4608
+ network = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
4609
+ }
4602
4610
  return { payer, amount, network };
4603
4611
  } catch {
4604
4612
  return null;
4605
4613
  }
4606
4614
  }
4615
+ function extractSolanaFeePayer(base64Transaction) {
4616
+ try {
4617
+ const txBytes = typeof Buffer !== "undefined" ? Buffer.from(base64Transaction, "base64") : Uint8Array.from(atob(base64Transaction), (c) => c.charCodeAt(0));
4618
+ let offset = 0;
4619
+ const numSignatures = txBytes[offset];
4620
+ offset += 1;
4621
+ offset += numSignatures * 64;
4622
+ const firstByte = txBytes[offset];
4623
+ if ((firstByte & 128) !== 0) {
4624
+ offset += 1;
4625
+ }
4626
+ offset += 3;
4627
+ const numAccounts = txBytes[offset];
4628
+ offset += 1;
4629
+ if (numAccounts > 0 && offset + 32 <= txBytes.length) {
4630
+ const feePayerBytes = txBytes.slice(offset, offset + 32);
4631
+ return base58Encode(feePayerBytes);
4632
+ }
4633
+ return null;
4634
+ } catch {
4635
+ return null;
4636
+ }
4637
+ }
4638
+ function base58Encode(bytes) {
4639
+ const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
4640
+ const BASE = 58;
4641
+ let num = BigInt(0);
4642
+ for (const byte of bytes) {
4643
+ num = num * BigInt(256) + BigInt(byte);
4644
+ }
4645
+ let result = "";
4646
+ while (num > 0) {
4647
+ const remainder = Number(num % BigInt(BASE));
4648
+ num = num / BigInt(BASE);
4649
+ result = ALPHABET[remainder] + result;
4650
+ }
4651
+ for (const byte of bytes) {
4652
+ if (byte === 0) {
4653
+ result = "1" + result;
4654
+ } else {
4655
+ break;
4656
+ }
4657
+ }
4658
+ return result || "1";
4659
+ }
4607
4660
  function detectX402Version(body) {
4608
4661
  if (!body || typeof body !== "object") {
4609
4662
  return null;
@@ -5345,14 +5398,98 @@ var RefundExecutor = class {
5345
5398
  }
5346
5399
  }
5347
5400
  /**
5348
- * Execute Solana refund
5401
+ * Execute Solana refund using @solana/kit v2 libraries
5349
5402
  */
5350
- async executeSolanaRefund(_refund, _amountRaw) {
5351
- return {
5352
- success: false,
5353
- error: "Solana refunds not yet implemented",
5354
- retryable: false
5355
- };
5403
+ async executeSolanaRefund(refund, amountRaw) {
5404
+ try {
5405
+ const solanaPrivateKey = this.config.solanaPrivateKey;
5406
+ if (!solanaPrivateKey) {
5407
+ return {
5408
+ success: false,
5409
+ error: "No Solana private key configured (set ZAUTH_SOLANA_PRIVATE_KEY)",
5410
+ retryable: false
5411
+ };
5412
+ }
5413
+ const { createKeyPairSignerFromPrivateKeyBytes } = await import('@solana/signers');
5414
+ const {
5415
+ createSolanaRpc,
5416
+ address,
5417
+ pipe,
5418
+ createTransactionMessage,
5419
+ setTransactionMessageFeePayer,
5420
+ setTransactionMessageLifetimeUsingBlockhash,
5421
+ appendTransactionMessageInstructions,
5422
+ signTransactionMessageWithSigners,
5423
+ getBase64EncodedWireTransaction
5424
+ } = await import('@solana/kit');
5425
+ const {
5426
+ findAssociatedTokenPda,
5427
+ getTransferInstruction,
5428
+ TOKEN_PROGRAM_ADDRESS
5429
+ } = await import('@solana-program/token');
5430
+ const bs58 = await import('bs58');
5431
+ const USDC_MINT = address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
5432
+ const rpcUrl = process.env.SOLANA_RPC_URL || "https://api.mainnet-beta.solana.com";
5433
+ const rpc = createSolanaRpc(rpcUrl);
5434
+ let signer;
5435
+ try {
5436
+ const secretKey = bs58.default.decode(solanaPrivateKey);
5437
+ const privateKeyBytes = secretKey.slice(0, 32);
5438
+ signer = await createKeyPairSignerFromPrivateKeyBytes(privateKeyBytes);
5439
+ } catch {
5440
+ return {
5441
+ success: false,
5442
+ error: "Invalid Solana private key format (expected base58)",
5443
+ retryable: false
5444
+ };
5445
+ }
5446
+ const recipientAddress = address(refund.recipientAddress);
5447
+ const [senderAta] = await findAssociatedTokenPda({
5448
+ mint: USDC_MINT,
5449
+ owner: signer.address,
5450
+ tokenProgram: TOKEN_PROGRAM_ADDRESS
5451
+ });
5452
+ const [recipientAta] = await findAssociatedTokenPda({
5453
+ mint: USDC_MINT,
5454
+ owner: recipientAddress,
5455
+ tokenProgram: TOKEN_PROGRAM_ADDRESS
5456
+ });
5457
+ const transferIx = getTransferInstruction({
5458
+ source: senderAta,
5459
+ destination: recipientAta,
5460
+ authority: signer,
5461
+ amount: BigInt(amountRaw)
5462
+ });
5463
+ const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
5464
+ const tx = pipe(
5465
+ createTransactionMessage({ version: 0 }),
5466
+ (tx2) => setTransactionMessageFeePayer(signer.address, tx2),
5467
+ (tx2) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx2),
5468
+ (tx2) => appendTransactionMessageInstructions([transferIx], tx2)
5469
+ );
5470
+ const signedTx = await signTransactionMessageWithSigners(tx);
5471
+ const base64Tx = getBase64EncodedWireTransaction(signedTx);
5472
+ const txSignature = await rpc.sendTransaction(base64Tx, { encoding: "base64" }).send();
5473
+ this.log("Solana refund sent", {
5474
+ txHash: txSignature,
5475
+ to: refund.recipientAddress,
5476
+ amount: amountRaw
5477
+ });
5478
+ return {
5479
+ success: true,
5480
+ txHash: txSignature,
5481
+ amountRaw,
5482
+ gasCostCents: 0
5483
+ // Solana fees are negligible
5484
+ };
5485
+ } catch (error) {
5486
+ this.log("Solana refund failed", { error: error.message });
5487
+ return {
5488
+ success: false,
5489
+ error: error.message,
5490
+ retryable: true
5491
+ };
5492
+ }
5356
5493
  }
5357
5494
  /**
5358
5495
  * Get endpoint-specific config by matching URL patterns