@sip-protocol/sdk 0.11.1 → 0.12.0

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.
Files changed (39) hide show
  1. package/dist/{TransportWebUSB-2KITI5HD.mjs → TransportWebUSB-TXDZJBGS.mjs} +12 -12
  2. package/dist/browser.d.mts +1 -1
  3. package/dist/browser.d.ts +1 -1
  4. package/dist/browser.js +864 -545
  5. package/dist/browser.mjs +13 -3
  6. package/dist/{chunk-L4RKPNIJ.mjs → chunk-4EHEBTKP.mjs} +132 -87
  7. package/dist/{chunk-7IUKXWDN.mjs → chunk-MKTCJPFH.mjs} +331 -94
  8. package/dist/{chunk-IBZVA5Y7.mjs → chunk-NMC5RNMV.mjs} +2 -2
  9. package/dist/{chunk-XGB3TDIC.mjs → chunk-S3F4CPQ5.mjs} +5 -1
  10. package/dist/{constants-DCJYTIU3.mjs → constants-NCGOQF7S.mjs} +1 -1
  11. package/dist/{dist-PYEXZNFD.mjs → dist-4KSUM2PU.mjs} +2 -2
  12. package/dist/{dist-IFHPYLDX.mjs → dist-4O5YILSN.mjs} +2 -2
  13. package/dist/{fulfillment_proof-ANHVPKTB.mjs → fulfillment_proof-WCEE5GGO.mjs} +1 -1
  14. package/dist/{funding_proof-ICFZ5LHY.mjs → funding_proof-X5IP4SG5.mjs} +1 -1
  15. package/dist/{index-DH5XRHYV.d.mts → index-B_fGN4Fk.d.mts} +796 -597
  16. package/dist/{index-mw7KGX5M.d.ts → index-rqQpCeVM.d.ts} +796 -597
  17. package/dist/index.d.mts +1 -1
  18. package/dist/index.d.ts +1 -1
  19. package/dist/index.js +864 -545
  20. package/dist/index.mjs +13 -3
  21. package/dist/proofs/halo2.mjs +1 -1
  22. package/dist/proofs/kimchi.mjs +1 -1
  23. package/dist/proofs/noir.mjs +1 -1
  24. package/dist/{solana-7QOA3HBZ.mjs → solana-VKZI66MK.mjs} +12 -2
  25. package/dist/{validity_proof-3POXLPNY.mjs → validity_proof-2GVV6GA6.mjs} +1 -1
  26. package/package.json +6 -5
  27. package/src/chains/solana/gasless-cashout.ts +331 -0
  28. package/src/chains/solana/index.ts +16 -0
  29. package/src/chains/solana/privacy-adapter.ts +1 -0
  30. package/src/chains/solana/providers/webhook.ts +1 -0
  31. package/src/chains/solana/relayer-fee.ts +39 -0
  32. package/src/chains/solana/scan.ts +11 -70
  33. package/src/chains/solana/stealth-scanner.ts +8 -0
  34. package/src/chains/solana/stealth-signer.ts +145 -0
  35. package/src/chains/solana/types.ts +2 -0
  36. package/src/index.ts +14 -0
  37. package/src/proofs/parallel/concurrency.ts +2 -2
  38. package/src/solana/jito-relayer.ts +40 -8
  39. package/src/wallet/solana/privacy-adapter.ts +29 -66
@@ -2395,9 +2395,8 @@ function detectCluster3(endpoint) {
2395
2395
 
2396
2396
  // src/chains/solana/scan.ts
2397
2397
  import {
2398
- PublicKey as PublicKey4,
2399
- Transaction as Transaction4,
2400
- Keypair
2398
+ PublicKey as PublicKey5,
2399
+ Transaction as Transaction5
2401
2400
  } from "@solana/web3.js";
2402
2401
  import {
2403
2402
  getAssociatedTokenAddress as getAssociatedTokenAddress3,
@@ -2434,9 +2433,70 @@ function parseTokenTransferFromBalances(preBalances, postBalances) {
2434
2433
  return null;
2435
2434
  }
2436
2435
 
2437
- // src/chains/solana/scan.ts
2438
- import { hexToBytes as hexToBytes2 } from "@noble/hashes/utils";
2436
+ // src/chains/solana/stealth-signer.ts
2437
+ import { PublicKey as PublicKey4 } from "@solana/web3.js";
2439
2438
  import { ed25519 as ed255192 } from "@noble/curves/ed25519";
2439
+ import { sha512 as sha5122 } from "@noble/hashes/sha512";
2440
+ import { hexToBytes as hexToBytes2 } from "@noble/hashes/utils";
2441
+ function modL(value) {
2442
+ const reduced = value % ED25519_ORDER;
2443
+ return reduced >= 0n ? reduced : reduced + ED25519_ORDER;
2444
+ }
2445
+ function signEd25519WithScalar(message, scalar) {
2446
+ const a = modL(bytesToBigIntLE(scalar));
2447
+ if (a === 0n) {
2448
+ throw new Error("Invalid stealth scalar: reduces to zero");
2449
+ }
2450
+ const A = ed255192.ExtendedPoint.BASE.multiply(a).toRawBytes();
2451
+ const prefix = sha5122(scalar).slice(32, 64);
2452
+ const r = modL(bytesToBigIntLE(sha5122(new Uint8Array([...prefix, ...message]))));
2453
+ if (r === 0n) {
2454
+ throw new Error("Invalid nonce: reduces to zero");
2455
+ }
2456
+ const R = ed255192.ExtendedPoint.BASE.multiply(r).toRawBytes();
2457
+ const k = modL(bytesToBigIntLE(sha5122(new Uint8Array([...R, ...A, ...message]))));
2458
+ const S = modL(r + k * a);
2459
+ return new Uint8Array([...R, ...bigIntToBytesLE(S, 32)]);
2460
+ }
2461
+ function deriveStealthSigner(params) {
2462
+ const {
2463
+ stealthAddress,
2464
+ ephemeralPublicKey,
2465
+ viewingPrivateKey,
2466
+ spendingPrivateKey,
2467
+ version = "2"
2468
+ } = params;
2469
+ const stealthAddressHex = solanaAddressToEd25519PublicKey(stealthAddress);
2470
+ const ephemeralPubKeyHex = solanaAddressToEd25519PublicKey(ephemeralPublicKey);
2471
+ const stealthAddressObj = {
2472
+ address: stealthAddressHex,
2473
+ ephemeralPublicKey: ephemeralPubKeyHex,
2474
+ viewTag: 0
2475
+ };
2476
+ const recovery = version === "1" ? deriveEd25519StealthPrivateKeyV1(stealthAddressObj, spendingPrivateKey, viewingPrivateKey) : deriveEd25519StealthPrivateKey(stealthAddressObj, spendingPrivateKey, viewingPrivateKey);
2477
+ const scalar = hexToBytes2(recovery.privateKey.slice(2));
2478
+ const publicKey = new PublicKey4(stealthAddress);
2479
+ const expectedPubKeyBytes = publicKey.toBytes();
2480
+ const derivedPubKeyBytes = ed255192.ExtendedPoint.BASE.multiply(modL(bytesToBigIntLE(scalar))).toRawBytes();
2481
+ if (!derivedPubKeyBytes.every((b, i) => b === expectedPubKeyBytes[i])) {
2482
+ throw new Error(
2483
+ "Stealth key derivation failed: derived scalar does not produce expected public key. This may indicate incorrect spending/viewing keys or corrupted announcement data."
2484
+ );
2485
+ }
2486
+ return {
2487
+ publicKey,
2488
+ signMessage(message) {
2489
+ return signEd25519WithScalar(message, scalar);
2490
+ },
2491
+ signTransaction(transaction) {
2492
+ const message = transaction.serializeMessage();
2493
+ const signature = signEd25519WithScalar(message, scalar);
2494
+ transaction.addSignature(publicKey, Buffer.from(signature));
2495
+ }
2496
+ };
2497
+ }
2498
+
2499
+ // src/chains/solana/scan.ts
2440
2500
  async function scanForPayments(params) {
2441
2501
  const {
2442
2502
  connection,
@@ -2448,7 +2508,7 @@ async function scanForPayments(params) {
2448
2508
  provider
2449
2509
  } = params;
2450
2510
  const results = [];
2451
- const memoProgram = new PublicKey4(MEMO_PROGRAM_ID);
2511
+ const memoProgram = new PublicKey5(MEMO_PROGRAM_ID);
2452
2512
  try {
2453
2513
  const signatures = await connection.getSignaturesForAddress(
2454
2514
  memoProgram,
@@ -2527,6 +2587,7 @@ async function scanForPayments(params) {
2527
2587
  results.push({
2528
2588
  stealthAddress: announcement.stealthAddress || "",
2529
2589
  ephemeralPublicKey: announcement.ephemeralPublicKey,
2590
+ version: announcement.version,
2530
2591
  amount,
2531
2592
  mint: transferInfo.mint,
2532
2593
  tokenSymbol,
@@ -2558,51 +2619,34 @@ async function claimStealthPayment(params) {
2558
2619
  mint,
2559
2620
  version = "2"
2560
2621
  } = params;
2561
- const stealthPubkeyForBalance = new PublicKey4(stealthAddress);
2622
+ const stealthPubkeyForBalance = new PublicKey5(stealthAddress);
2562
2623
  const solBalance = await connection.getBalance(stealthPubkeyForBalance);
2563
2624
  if (BigInt(solBalance) < MIN_SOL_FOR_FEES) {
2564
2625
  throw new Error(
2565
2626
  `Insufficient SOL for transaction fees. Stealth address has ${solBalance} lamports, needs at least ${MIN_SOL_FOR_FEES} lamports (~0.000005 SOL). Fund the stealth address with SOL before claiming.`
2566
2627
  );
2567
2628
  }
2568
- const stealthAddressHex = solanaAddressToEd25519PublicKey(stealthAddress);
2569
- const ephemeralPubKeyHex = solanaAddressToEd25519PublicKey(ephemeralPublicKey);
2570
- const stealthAddressObj = {
2571
- address: stealthAddressHex,
2572
- ephemeralPublicKey: ephemeralPubKeyHex,
2573
- viewTag: 0
2574
- // Not needed for derivation
2575
- };
2576
- const recovery = version === "1" ? deriveEd25519StealthPrivateKeyV1(stealthAddressObj, spendingPrivateKey, viewingPrivateKey) : deriveEd25519StealthPrivateKey(stealthAddressObj, spendingPrivateKey, viewingPrivateKey);
2577
- const stealthPrivKeyBytes = hexToBytes2(recovery.privateKey.slice(2));
2578
- const stealthPubkey = new PublicKey4(stealthAddress);
2579
- const expectedPubKeyBytes = stealthPubkey.toBytes();
2580
- const scalarBigInt = bytesToBigIntLE2(stealthPrivKeyBytes);
2581
- const ED25519_ORDER3 = 2n ** 252n + 27742317777372353535851937790883648493n;
2582
- let validScalar = scalarBigInt % ED25519_ORDER3;
2583
- if (validScalar === 0n) validScalar = 1n;
2584
- const derivedPubKeyBytes = ed255192.ExtendedPoint.BASE.multiply(validScalar).toRawBytes();
2585
- if (!derivedPubKeyBytes.every((b, i) => b === expectedPubKeyBytes[i])) {
2586
- throw new Error(
2587
- "Stealth key derivation failed: derived private key does not produce expected public key. This may indicate incorrect spending/viewing keys or corrupted announcement data."
2588
- );
2589
- }
2590
- const stealthKeypair = Keypair.fromSecretKey(
2591
- new Uint8Array([...stealthPrivKeyBytes, ...expectedPubKeyBytes])
2592
- );
2629
+ const stealthSigner = deriveStealthSigner({
2630
+ stealthAddress,
2631
+ ephemeralPublicKey,
2632
+ viewingPrivateKey,
2633
+ spendingPrivateKey,
2634
+ version
2635
+ });
2636
+ const stealthPubkey = new PublicKey5(stealthAddress);
2593
2637
  const stealthATA = await getAssociatedTokenAddress3(
2594
2638
  mint,
2595
2639
  stealthPubkey,
2596
2640
  true
2597
2641
  );
2598
- const destinationPubkey = new PublicKey4(destinationAddress);
2642
+ const destinationPubkey = new PublicKey5(destinationAddress);
2599
2643
  const destinationATA = await getAssociatedTokenAddress3(
2600
2644
  mint,
2601
2645
  destinationPubkey
2602
2646
  );
2603
2647
  const stealthAccount = await getAccount3(connection, stealthATA);
2604
2648
  const amount = stealthAccount.amount;
2605
- const transaction = new Transaction4();
2649
+ const transaction = new Transaction5();
2606
2650
  transaction.add(
2607
2651
  createTransferInstruction3(
2608
2652
  stealthATA,
@@ -2615,7 +2659,7 @@ async function claimStealthPayment(params) {
2615
2659
  transaction.recentBlockhash = blockhash;
2616
2660
  transaction.lastValidBlockHeight = lastValidBlockHeight;
2617
2661
  transaction.feePayer = stealthPubkey;
2618
- transaction.sign(stealthKeypair);
2662
+ stealthSigner.signTransaction(transaction);
2619
2663
  const txSignature = await connection.sendRawTransaction(
2620
2664
  transaction.serialize(),
2621
2665
  {
@@ -2647,7 +2691,7 @@ async function getStealthBalance(connection, stealthAddress, mint, provider) {
2647
2691
  }
2648
2692
  }
2649
2693
  try {
2650
- const stealthPubkey = new PublicKey4(stealthAddress);
2694
+ const stealthPubkey = new PublicKey5(stealthAddress);
2651
2695
  const ata = await getAssociatedTokenAddress3(mint, stealthPubkey, true);
2652
2696
  const account = await getAccount3(connection, ata);
2653
2697
  return account.amount;
@@ -2667,16 +2711,9 @@ function detectCluster4(endpoint) {
2667
2711
  }
2668
2712
  return "mainnet-beta";
2669
2713
  }
2670
- function bytesToBigIntLE2(bytes) {
2671
- let result = 0n;
2672
- for (let i = bytes.length - 1; i >= 0; i--) {
2673
- result = result << 8n | BigInt(bytes[i]);
2674
- }
2675
- return result;
2676
- }
2677
2714
 
2678
2715
  // src/chains/solana/stealth-scanner.ts
2679
- import { PublicKey as PublicKey5 } from "@solana/web3.js";
2716
+ import { PublicKey as PublicKey6 } from "@solana/web3.js";
2680
2717
  var StealthScanner = class {
2681
2718
  connection;
2682
2719
  provider;
@@ -2743,7 +2780,7 @@ var StealthScanner = class {
2743
2780
  let scannedCount = 0;
2744
2781
  let lastSignature;
2745
2782
  let lastSlot;
2746
- const memoProgram = new PublicKey5(MEMO_PROGRAM_ID);
2783
+ const memoProgram = new PublicKey6(MEMO_PROGRAM_ID);
2747
2784
  try {
2748
2785
  const signatures = await this.connection.getSignaturesForAddress(
2749
2786
  memoProgram,
@@ -2811,7 +2848,7 @@ var StealthScanner = class {
2811
2848
  }
2812
2849
  this.paymentCallback = onPayment;
2813
2850
  this.errorCallback = onError ?? null;
2814
- const memoProgram = new PublicKey5(MEMO_PROGRAM_ID);
2851
+ const memoProgram = new PublicKey6(MEMO_PROGRAM_ID);
2815
2852
  this.subscriptionId = this.connection.onLogs(
2816
2853
  memoProgram,
2817
2854
  async (logs) => {
@@ -2913,6 +2950,7 @@ var StealthScanner = class {
2913
2950
  return {
2914
2951
  stealthAddress: announcement.stealthAddress || "",
2915
2952
  ephemeralPublicKey: announcement.ephemeralPublicKey,
2953
+ version: announcement.version,
2916
2954
  viewTag: viewTagNumber,
2917
2955
  amount,
2918
2956
  mint: transferInfo.mint,
@@ -3072,7 +3110,7 @@ function wipeEphemeralPrivateKey(privateKeyHex) {
3072
3110
  }
3073
3111
 
3074
3112
  // src/chains/solana/privacy-adapter.ts
3075
- import { PublicKey as PublicKey9 } from "@solana/web3.js";
3113
+ import { PublicKey as PublicKey10 } from "@solana/web3.js";
3076
3114
 
3077
3115
  // src/chains/solana/providers/helius.ts
3078
3116
  var DEFAULT_FETCH_TIMEOUT_MS = 3e4;
@@ -3282,7 +3320,7 @@ var HeliusProvider = class {
3282
3320
  // src/chains/solana/providers/generic.ts
3283
3321
  import {
3284
3322
  Connection as Connection3,
3285
- PublicKey as PublicKey6
3323
+ PublicKey as PublicKey7
3286
3324
  } from "@solana/web3.js";
3287
3325
  import {
3288
3326
  TOKEN_PROGRAM_ID as TOKEN_PROGRAM_ID3,
@@ -3298,7 +3336,7 @@ var CLUSTER_ENDPOINTS = {
3298
3336
  };
3299
3337
  function validateSolanaAddress(address, paramName) {
3300
3338
  try {
3301
- return new PublicKey6(address);
3339
+ return new PublicKey7(address);
3302
3340
  } catch {
3303
3341
  throw new ValidationError("invalid Solana address format", paramName, void 0, "SIP_2007" /* INVALID_ADDRESS */);
3304
3342
  }
@@ -3405,7 +3443,7 @@ var GenericProvider = class {
3405
3443
  // src/chains/solana/providers/quicknode.ts
3406
3444
  import {
3407
3445
  Connection as Connection4,
3408
- PublicKey as PublicKey7
3446
+ PublicKey as PublicKey8
3409
3447
  } from "@solana/web3.js";
3410
3448
  import {
3411
3449
  TOKEN_PROGRAM_ID as TOKEN_PROGRAM_ID4,
@@ -3419,7 +3457,7 @@ import Client, {
3419
3457
  import { base58 } from "@scure/base";
3420
3458
  function validateSolanaAddress2(address, paramName) {
3421
3459
  try {
3422
- return new PublicKey7(address);
3460
+ return new PublicKey8(address);
3423
3461
  } catch {
3424
3462
  throw new ValidationError("invalid Solana address format", paramName, void 0, "SIP_2007" /* INVALID_ADDRESS */);
3425
3463
  }
@@ -3534,7 +3572,7 @@ var QuickNodeProvider = class {
3534
3572
  return cached;
3535
3573
  }
3536
3574
  try {
3537
- const mintPubkey = new PublicKey7(mint);
3575
+ const mintPubkey = new PublicKey8(mint);
3538
3576
  const mintInfo = await getMint2(this.connection, mintPubkey);
3539
3577
  const decimals = mintInfo.decimals;
3540
3578
  this.mintDecimalsCache.set(mint, decimals);
@@ -3582,7 +3620,7 @@ var QuickNodeProvider = class {
3582
3620
  try {
3583
3621
  const data = accountData.data;
3584
3622
  if (data && data.length >= 72) {
3585
- const mint = new PublicKey7(data.slice(0, 32)).toBase58();
3623
+ const mint = new PublicKey8(data.slice(0, 32)).toBase58();
3586
3624
  const amount = BigInt(
3587
3625
  "0x" + Buffer.from(data.slice(64, 72)).reverse().toString("hex")
3588
3626
  );
@@ -3682,7 +3720,7 @@ var QuickNodeProvider = class {
3682
3720
  // src/chains/solana/providers/triton.ts
3683
3721
  import {
3684
3722
  Connection as Connection5,
3685
- PublicKey as PublicKey8
3723
+ PublicKey as PublicKey9
3686
3724
  } from "@solana/web3.js";
3687
3725
  import {
3688
3726
  TOKEN_PROGRAM_ID as TOKEN_PROGRAM_ID5,
@@ -3704,7 +3742,7 @@ var TRITON_GRPC_ENDPOINTS = {
3704
3742
  };
3705
3743
  function validateSolanaAddress3(address, paramName) {
3706
3744
  try {
3707
- return new PublicKey8(address);
3745
+ return new PublicKey9(address);
3708
3746
  } catch {
3709
3747
  throw new ValidationError("invalid Solana address format", paramName, void 0, "SIP_2007" /* INVALID_ADDRESS */);
3710
3748
  }
@@ -3810,7 +3848,7 @@ var TritonProvider = class {
3810
3848
  return cached;
3811
3849
  }
3812
3850
  try {
3813
- const mintPubkey = new PublicKey8(mint);
3851
+ const mintPubkey = new PublicKey9(mint);
3814
3852
  const mintInfo = await getMint3(this.connection, mintPubkey);
3815
3853
  const decimals = mintInfo.decimals;
3816
3854
  this.mintDecimalsCache.set(mint, decimals);
@@ -3861,7 +3899,7 @@ var TritonProvider = class {
3861
3899
  try {
3862
3900
  const data = accountData.data;
3863
3901
  if (data && data.length >= 72) {
3864
- const mint = new PublicKey8(data.slice(0, 32)).toBase58();
3902
+ const mint = new PublicKey9(data.slice(0, 32)).toBase58();
3865
3903
  const amount = BigInt(
3866
3904
  "0x" + Buffer.from(data.slice(64, 72)).reverse().toString("hex")
3867
3905
  );
@@ -4188,6 +4226,7 @@ async function processRawTransaction(tx, viewingPrivateKey, spendingPublicKey, o
4188
4226
  const payment = {
4189
4227
  stealthAddress: announcement.stealthAddress || "",
4190
4228
  ephemeralPublicKey: announcement.ephemeralPublicKey,
4229
+ version: announcement.version,
4191
4230
  amount: transferInfo?.amount ?? 0n,
4192
4231
  mint: transferInfo?.mint ?? "",
4193
4232
  tokenSymbol: transferInfo?.mint ? getTokenSymbol(transferInfo.mint) : void 0,
@@ -4855,7 +4894,8 @@ var SolanaPrivacyAdapter = class {
4855
4894
  viewingPrivateKey: params.viewingPrivateKey,
4856
4895
  spendingPrivateKey: params.spendingPrivateKey,
4857
4896
  destinationAddress: params.destinationAddress,
4858
- mint: new PublicKey9(params.payment.mint)
4897
+ mint: new PublicKey10(params.payment.mint),
4898
+ version: params.payment.version
4859
4899
  });
4860
4900
  }
4861
4901
  /**
@@ -4920,7 +4960,7 @@ import {
4920
4960
  } from "@scure/bip39";
4921
4961
  import { wordlist as english } from "@scure/bip39/wordlists/english.js";
4922
4962
  import { ed25519 as ed255194 } from "@noble/curves/ed25519";
4923
- import { sha256 as sha2564, sha512 as sha5122 } from "@noble/hashes/sha2";
4963
+ import { sha256 as sha2564, sha512 as sha5123 } from "@noble/hashes/sha2";
4924
4964
  import { hmac as hmac2 } from "@noble/hashes/hmac";
4925
4965
  var SOLANA_DEFAULT_PATH = "m/44'/501'/0'/0'";
4926
4966
  var VIEWING_KEY_CONTEXT = "SIP-viewing-key-v1";
@@ -4962,7 +5002,7 @@ function validateDerivationPath(path) {
4962
5002
  return true;
4963
5003
  }
4964
5004
  function slip0010DeriveEd25519(seed, path) {
4965
- const I = hmac2(sha5122, "ed25519 seed", seed);
5005
+ const I = hmac2(sha5123, "ed25519 seed", seed);
4966
5006
  let key = new Uint8Array(I.slice(0, 32));
4967
5007
  let chainCode = new Uint8Array(I.slice(32, 64));
4968
5008
  const components = path.split("/").slice(1);
@@ -4981,7 +5021,7 @@ function slip0010DeriveEd25519(seed, path) {
4981
5021
  data[0] = 0;
4982
5022
  data.set(key, 1);
4983
5023
  new DataView(data.buffer).setUint32(33, hardenedIndex, false);
4984
- const derivedI = hmac2(sha5122, chainCode, data);
5024
+ const derivedI = hmac2(sha5123, chainCode, data);
4985
5025
  key = new Uint8Array(derivedI.slice(0, 32));
4986
5026
  chainCode = new Uint8Array(derivedI.slice(32, 64));
4987
5027
  }
@@ -5607,7 +5647,7 @@ import {
5607
5647
  } from "@solana/kit";
5608
5648
  import {
5609
5649
  Connection as Connection8,
5610
- Transaction as Transaction5,
5650
+ Transaction as Transaction6,
5611
5651
  ComputeBudgetProgram
5612
5652
  } from "@solana/web3.js";
5613
5653
 
@@ -5625,7 +5665,7 @@ import {
5625
5665
  } from "@solana/compat";
5626
5666
  import {
5627
5667
  Connection as Connection7,
5628
- PublicKey as PublicKey10
5668
+ PublicKey as PublicKey11
5629
5669
  } from "@solana/web3.js";
5630
5670
  function toAddress(pubkey) {
5631
5671
  if (typeof pubkey === "string") {
@@ -5634,7 +5674,7 @@ function toAddress(pubkey) {
5634
5674
  return fromLegacyPublicKey(pubkey);
5635
5675
  }
5636
5676
  function toPublicKey(addr) {
5637
- return new PublicKey10(addr);
5677
+ return new PublicKey11(addr);
5638
5678
  }
5639
5679
  function createAddress(base583) {
5640
5680
  return kitAddress(base583);
@@ -5692,18 +5732,18 @@ function isAddress(value) {
5692
5732
  return typeof value === "string" && value.length >= 32 && value.length <= 44;
5693
5733
  }
5694
5734
  function isPublicKey(value) {
5695
- return value instanceof PublicKey10;
5735
+ return value instanceof PublicKey11;
5696
5736
  }
5697
5737
  function normalizeAddress(input) {
5698
5738
  let base583;
5699
- if (input instanceof PublicKey10) {
5739
+ if (input instanceof PublicKey11) {
5700
5740
  base583 = input.toBase58();
5701
5741
  } else {
5702
5742
  base583 = input;
5703
5743
  }
5704
5744
  return {
5705
5745
  address: kitAddress(base583),
5706
- publicKey: new PublicKey10(base583),
5746
+ publicKey: new PublicKey11(base583),
5707
5747
  base58: base583
5708
5748
  };
5709
5749
  }
@@ -5883,11 +5923,11 @@ async function createProxyAgent(config, options = {}) {
5883
5923
  const parsed = parseProxyConfig(config === "tor" ? `socks5://${TOR_HOST}:${TOR_PORTS[0]}` : config);
5884
5924
  try {
5885
5925
  if (parsed.type === "socks5" || parsed.type === "socks4" || config === "tor") {
5886
- const { SocksProxyAgent } = await import("./dist-PYEXZNFD.mjs");
5926
+ const { SocksProxyAgent } = await import("./dist-4KSUM2PU.mjs");
5887
5927
  return new SocksProxyAgent(proxyUrl, { timeout });
5888
5928
  }
5889
5929
  if (parsed.type === "http" || parsed.type === "https") {
5890
- const { HttpsProxyAgent } = await import("./dist-IFHPYLDX.mjs");
5930
+ const { HttpsProxyAgent } = await import("./dist-4O5YILSN.mjs");
5891
5931
  return new HttpsProxyAgent(proxyUrl, { timeout });
5892
5932
  }
5893
5933
  } catch (error) {
@@ -6176,7 +6216,7 @@ var SolanaRPCClient = class _SolanaRPCClient {
6176
6216
  ...sendOptions
6177
6217
  } = options;
6178
6218
  let txToSend = transaction;
6179
- if (this.usePriorityFees && !skipPriorityFee && transaction instanceof Transaction5) {
6219
+ if (this.usePriorityFees && !skipPriorityFee && transaction instanceof Transaction6) {
6180
6220
  txToSend = await this.addPriorityFee(
6181
6221
  transaction,
6182
6222
  priorityFeeMicroLamports,
@@ -6319,7 +6359,7 @@ var SolanaRPCClient = class _SolanaRPCClient {
6319
6359
  const estimate = await this.estimatePriorityFee(transaction);
6320
6360
  feeToUse = estimate.microLamportsPerComputeUnit;
6321
6361
  }
6322
- const modifiedTx = new Transaction5();
6362
+ const modifiedTx = new Transaction6();
6323
6363
  modifiedTx.add(
6324
6364
  ComputeBudgetProgram.setComputeUnitLimit({
6325
6365
  units: computeUnitLimit ?? 2e5
@@ -6616,8 +6656,8 @@ function createClusterClient(cluster, options = {}) {
6616
6656
 
6617
6657
  // src/chains/solana/transaction-builder.ts
6618
6658
  import {
6619
- PublicKey as PublicKey12,
6620
- Transaction as Transaction6,
6659
+ PublicKey as PublicKey13,
6660
+ Transaction as Transaction7,
6621
6661
  TransactionInstruction as TransactionInstruction4,
6622
6662
  TransactionMessage,
6623
6663
  VersionedTransaction as VersionedTransaction2,
@@ -6681,7 +6721,7 @@ var ShieldedTransactionBuilder = class {
6681
6721
  }
6682
6722
  const { stealthAddress } = generateEd25519StealthAddress(recipientMetaAddress);
6683
6723
  const stealthAddressBase58 = ed25519PublicKeyToSolanaAddress(stealthAddress.address);
6684
- const stealthPubkey = new PublicKey12(stealthAddressBase58);
6724
+ const stealthPubkey = new PublicKey13(stealthAddressBase58);
6685
6725
  const ephemeralPubkeyBase58 = ed25519PublicKeyToSolanaAddress(stealthAddress.ephemeralPublicKey);
6686
6726
  const stealthATA = await getAssociatedTokenAddress7(mint, stealthPubkey, true);
6687
6727
  const instructions = [];
@@ -6722,7 +6762,7 @@ var ShieldedTransactionBuilder = class {
6722
6762
  instructions.push(
6723
6763
  new TransactionInstruction4({
6724
6764
  keys: [],
6725
- programId: new PublicKey12(MEMO_PROGRAM_ID),
6765
+ programId: new PublicKey13(MEMO_PROGRAM_ID),
6726
6766
  data: Buffer.from(memoContent, "utf-8")
6727
6767
  })
6728
6768
  );
@@ -6754,7 +6794,7 @@ var ShieldedTransactionBuilder = class {
6754
6794
  }
6755
6795
  const { stealthAddress } = generateEd25519StealthAddress(recipientMetaAddress);
6756
6796
  const stealthAddressBase58 = ed25519PublicKeyToSolanaAddress(stealthAddress.address);
6757
- const stealthPubkey = new PublicKey12(stealthAddressBase58);
6797
+ const stealthPubkey = new PublicKey13(stealthAddressBase58);
6758
6798
  const ephemeralPubkeyBase58 = ed25519PublicKeyToSolanaAddress(stealthAddress.ephemeralPublicKey);
6759
6799
  const instructions = [];
6760
6800
  if (this.priorityFee > 0) {
@@ -6779,7 +6819,7 @@ var ShieldedTransactionBuilder = class {
6779
6819
  instructions.push(
6780
6820
  new TransactionInstruction4({
6781
6821
  keys: [],
6782
- programId: new PublicKey12(MEMO_PROGRAM_ID),
6822
+ programId: new PublicKey13(MEMO_PROGRAM_ID),
6783
6823
  data: Buffer.from(memoContent, "utf-8")
6784
6824
  })
6785
6825
  );
@@ -6822,7 +6862,7 @@ var ShieldedTransactionBuilder = class {
6822
6862
  }
6823
6863
  const { stealthAddress } = generateEd25519StealthAddress(transfer.recipientMetaAddress);
6824
6864
  const stealthAddressBase58 = ed25519PublicKeyToSolanaAddress(stealthAddress.address);
6825
- const stealthPubkey = new PublicKey12(stealthAddressBase58);
6865
+ const stealthPubkey = new PublicKey13(stealthAddressBase58);
6826
6866
  const ephemeralPubkeyBase58 = ed25519PublicKeyToSolanaAddress(stealthAddress.ephemeralPublicKey);
6827
6867
  const stealthATA = await getAssociatedTokenAddress7(mint, stealthPubkey, true);
6828
6868
  try {
@@ -6863,7 +6903,7 @@ var ShieldedTransactionBuilder = class {
6863
6903
  instructions.push(
6864
6904
  new TransactionInstruction4({
6865
6905
  keys: [],
6866
- programId: new PublicKey12(MEMO_PROGRAM_ID),
6906
+ programId: new PublicKey13(MEMO_PROGRAM_ID),
6867
6907
  data: Buffer.from(memoContent, "utf-8")
6868
6908
  })
6869
6909
  );
@@ -6911,7 +6951,7 @@ var ShieldedTransactionBuilder = class {
6911
6951
  estimatedFee
6912
6952
  };
6913
6953
  } else {
6914
- const transaction = new Transaction6();
6954
+ const transaction = new Transaction7();
6915
6955
  transaction.recentBlockhash = blockhash;
6916
6956
  transaction.lastValidBlockHeight = lastValidBlockHeight;
6917
6957
  transaction.feePayer = this.feePayer;
@@ -6958,7 +6998,7 @@ var ShieldedTransactionBuilder = class {
6958
6998
  if (isVersioned) {
6959
6999
  return VersionedTransaction2.deserialize(buffer);
6960
7000
  } else {
6961
- return Transaction6.from(buffer);
7001
+ return Transaction7.from(buffer);
6962
7002
  }
6963
7003
  }
6964
7004
  // ─── Configuration ────────────────────────────────────────────────────────────
@@ -7040,8 +7080,8 @@ function calculatePriorityFee(priority) {
7040
7080
 
7041
7081
  // src/chains/solana/anchor-transfer.ts
7042
7082
  import {
7043
- PublicKey as PublicKey13,
7044
- Transaction as Transaction7,
7083
+ PublicKey as PublicKey14,
7084
+ Transaction as Transaction8,
7045
7085
  TransactionInstruction as TransactionInstruction5,
7046
7086
  SystemProgram as SystemProgram3
7047
7087
  } from "@solana/web3.js";
@@ -7249,13 +7289,13 @@ function bigIntToBytes3(value, length) {
7249
7289
  }
7250
7290
 
7251
7291
  // src/chains/solana/anchor-transfer.ts
7252
- var SIP_PRIVACY_PROGRAM_ID = new PublicKey13(
7292
+ var SIP_PRIVACY_PROGRAM_ID = new PublicKey14(
7253
7293
  "S1PMFspo4W6BYKHWkHNF7kZ3fnqibEXg3LQjxepS9at"
7254
7294
  );
7255
- var CONFIG_PDA = new PublicKey13(
7295
+ var CONFIG_PDA = new PublicKey14(
7256
7296
  "BVawZkppFewygA5nxdrLma4ThKx8Th7bW4KTCkcWTZwZ"
7257
7297
  );
7258
- var FEE_COLLECTOR = new PublicKey13(
7298
+ var FEE_COLLECTOR = new PublicKey14(
7259
7299
  "S1P6j1yeTm6zkewQVeihrTZvmfoHABRkHDhabWTuWMd"
7260
7300
  );
7261
7301
  var TRANSFER_RECORD_SEED = Buffer.from("transfer_record");
@@ -7293,7 +7333,7 @@ async function shieldedTransfer(params) {
7293
7333
  const stealthResult = generateEd25519StealthAddress(recipientMeta);
7294
7334
  const stealthAddr = stealthResult.stealthAddress;
7295
7335
  const stealthPubkey = ed25519PublicKeyToSolanaAddress(stealthAddr.address);
7296
- const stealthAccountPubkey = new PublicKey13(stealthPubkey);
7336
+ const stealthAccountPubkey = new PublicKey14(stealthPubkey);
7297
7337
  const { commitment, blinding } = commit(amount);
7298
7338
  const commitmentBytes = hexToBytes7(commitment.slice(2));
7299
7339
  if (commitmentBytes.length !== 33) {
@@ -7317,7 +7357,7 @@ async function shieldedTransfer(params) {
7317
7357
  throw new ValidationError("SIP Privacy program not initialized", "config");
7318
7358
  }
7319
7359
  const totalTransfers = configAccount.data.readBigUInt64LE(43);
7320
- const [transferRecordPda] = PublicKey13.findProgramAddressSync(
7360
+ const [transferRecordPda] = PublicKey14.findProgramAddressSync(
7321
7361
  [
7322
7362
  TRANSFER_RECORD_SEED,
7323
7363
  sender.toBuffer(),
@@ -7346,7 +7386,7 @@ async function shieldedTransfer(params) {
7346
7386
  programId: SIP_PRIVACY_PROGRAM_ID,
7347
7387
  data: instructionData
7348
7388
  });
7349
- const transaction = new Transaction7();
7389
+ const transaction = new Transaction8();
7350
7390
  transaction.add(instruction);
7351
7391
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
7352
7392
  transaction.recentBlockhash = blockhash;
@@ -7452,8 +7492,8 @@ function encryptAmount(amount, viewingKey) {
7452
7492
 
7453
7493
  // src/chains/solana/sunspot-verifier.ts
7454
7494
  import {
7455
- PublicKey as PublicKey14,
7456
- Transaction as Transaction8,
7495
+ PublicKey as PublicKey15,
7496
+ Transaction as Transaction9,
7457
7497
  TransactionInstruction as TransactionInstruction6,
7458
7498
  ComputeBudgetProgram as ComputeBudgetProgram3
7459
7499
  } from "@solana/web3.js";
@@ -7572,7 +7612,7 @@ var SunspotVerifier = class {
7572
7612
  proofBytes,
7573
7613
  ...publicInputBytes.map((b) => Buffer.from(b))
7574
7614
  ]);
7575
- const transaction = new Transaction8();
7615
+ const transaction = new Transaction9();
7576
7616
  transaction.add(
7577
7617
  ComputeBudgetProgram3.setComputeUnitLimit({
7578
7618
  units: this.config.computeUnits
@@ -7692,7 +7732,7 @@ function formatOwnershipInputs(params) {
7692
7732
  ];
7693
7733
  }
7694
7734
  function toPublicKey2(input) {
7695
- return typeof input === "string" ? new PublicKey14(input) : input;
7735
+ return typeof input === "string" ? new PublicKey15(input) : input;
7696
7736
  }
7697
7737
  function toBytes(input) {
7698
7738
  if (typeof input === "string") {
@@ -7710,6 +7750,198 @@ function bigintToBytes32(value) {
7710
7750
  return bytes;
7711
7751
  }
7712
7752
 
7753
+ // src/chains/solana/gasless-cashout.ts
7754
+ import {
7755
+ PublicKey as PublicKey16,
7756
+ Transaction as Transaction10
7757
+ } from "@solana/web3.js";
7758
+ import {
7759
+ getAssociatedTokenAddress as getAssociatedTokenAddress8,
7760
+ createTransferInstruction as createTransferInstruction5,
7761
+ createAssociatedTokenAccountIdempotentInstruction,
7762
+ getAccount as getAccount7
7763
+ } from "@solana/spl-token";
7764
+
7765
+ // src/chains/solana/relayer-fee.ts
7766
+ function computeRelayerFee(amount, config) {
7767
+ if (!Number.isInteger(config.bps) || config.bps < 0) {
7768
+ throw new Error("bps must be a non-negative integer");
7769
+ }
7770
+ if (amount < 0n) {
7771
+ throw new Error("amount must be a non-negative bigint");
7772
+ }
7773
+ if (typeof config.flatFloor !== "bigint" || config.flatFloor < 0n) {
7774
+ throw new Error("flatFloor must be a non-negative bigint");
7775
+ }
7776
+ const bpsFee = amount * BigInt(config.bps) / 10000n;
7777
+ return bpsFee > config.flatFloor ? bpsFee : config.flatFloor;
7778
+ }
7779
+
7780
+ // src/chains/solana/gasless-cashout.ts
7781
+ async function buildGaslessCashout(params) {
7782
+ const {
7783
+ connection,
7784
+ stealthAddress,
7785
+ ephemeralPublicKey,
7786
+ viewingPrivateKey,
7787
+ spendingPrivateKey,
7788
+ destinationAddress,
7789
+ mint,
7790
+ relayerPublicKey,
7791
+ relayerFeeAccount,
7792
+ feeConfig,
7793
+ version = "2"
7794
+ } = params;
7795
+ const stealthSigner = deriveStealthSigner({
7796
+ stealthAddress,
7797
+ ephemeralPublicKey,
7798
+ viewingPrivateKey,
7799
+ spendingPrivateKey,
7800
+ version
7801
+ });
7802
+ const stealthPubkey = stealthSigner.publicKey;
7803
+ const stealthATA = await getAssociatedTokenAddress8(mint, stealthPubkey, true);
7804
+ const destinationPubkey = new PublicKey16(destinationAddress);
7805
+ const destinationATA = await getAssociatedTokenAddress8(mint, destinationPubkey);
7806
+ if (destinationATA.equals(stealthATA)) {
7807
+ throw new Error(
7808
+ "destinationAddress resolves to the stealth token account; choose a different destination"
7809
+ );
7810
+ }
7811
+ let feeAccount;
7812
+ try {
7813
+ feeAccount = await getAccount7(connection, relayerFeeAccount);
7814
+ } catch {
7815
+ throw new Error("relayerFeeAccount does not exist or is not a token account");
7816
+ }
7817
+ if (!feeAccount.mint.equals(mint)) {
7818
+ throw new Error("relayerFeeAccount is not an associated token account for the given mint");
7819
+ }
7820
+ let balanceResp;
7821
+ try {
7822
+ balanceResp = await connection.getTokenAccountBalance(stealthATA);
7823
+ } catch {
7824
+ throw new Error(
7825
+ `Stealth token account ${stealthATA.toBase58()} for mint ${mint.toBase58()} does not exist or holds no balance; nothing to cash out`
7826
+ );
7827
+ }
7828
+ const grossAmount = BigInt(balanceResp.value.amount);
7829
+ const relayerFee = computeRelayerFee(grossAmount, feeConfig);
7830
+ if (relayerFee >= grossAmount) {
7831
+ throw new Error(
7832
+ `Relayer fee (${relayerFee}) equals or exceeds the claim amount (${grossAmount}); nothing left to forward`
7833
+ );
7834
+ }
7835
+ const netAmount = grossAmount - relayerFee;
7836
+ const transaction = new Transaction10();
7837
+ transaction.add(
7838
+ createAssociatedTokenAccountIdempotentInstruction(
7839
+ relayerPublicKey,
7840
+ // payer (relayer pays rent)
7841
+ destinationATA,
7842
+ destinationPubkey,
7843
+ mint
7844
+ )
7845
+ );
7846
+ transaction.add(
7847
+ createTransferInstruction5(stealthATA, relayerFeeAccount, stealthPubkey, relayerFee)
7848
+ );
7849
+ transaction.add(
7850
+ createTransferInstruction5(stealthATA, destinationATA, stealthPubkey, netAmount)
7851
+ );
7852
+ const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
7853
+ transaction.recentBlockhash = blockhash;
7854
+ transaction.lastValidBlockHeight = lastValidBlockHeight;
7855
+ transaction.feePayer = relayerPublicKey;
7856
+ stealthSigner.signTransaction(transaction);
7857
+ return {
7858
+ transaction,
7859
+ stealthAddress,
7860
+ destinationAddress,
7861
+ grossAmount,
7862
+ relayerFee,
7863
+ netAmount,
7864
+ blockhash,
7865
+ lastValidBlockHeight
7866
+ };
7867
+ }
7868
+ function detectCluster5(endpoint) {
7869
+ if (endpoint.includes("devnet")) {
7870
+ return "devnet";
7871
+ }
7872
+ if (endpoint.includes("testnet")) {
7873
+ return "testnet";
7874
+ }
7875
+ if (endpoint.includes("localhost") || endpoint.includes("127.0.0.1")) {
7876
+ return "localnet";
7877
+ }
7878
+ return "mainnet-beta";
7879
+ }
7880
+ async function submitGaslessCashout(params) {
7881
+ const { connection, build, relayerKeypair, jitoRelayer, tipLamports } = params;
7882
+ const { transaction, netAmount, relayerFee, destinationAddress } = build;
7883
+ if (!transaction.feePayer || !transaction.feePayer.equals(relayerKeypair.publicKey)) {
7884
+ throw new Error("relayerKeypair does not match the transaction fee-payer");
7885
+ }
7886
+ const relayerAlreadySigned = transaction.signatures.some(
7887
+ (s) => s.publicKey.equals(relayerKeypair.publicKey) && s.signature !== null
7888
+ );
7889
+ if (!relayerAlreadySigned) {
7890
+ transaction.partialSign(relayerKeypair);
7891
+ }
7892
+ const cluster = detectCluster5(connection.rpcEndpoint);
7893
+ if (jitoRelayer) {
7894
+ const relayed = await jitoRelayer.relayTransaction({
7895
+ transaction,
7896
+ tipLamports,
7897
+ tipPayer: relayerKeypair,
7898
+ waitForConfirmation: true
7899
+ });
7900
+ if (relayed.status !== "confirmed") {
7901
+ throw new Error(
7902
+ `Gasless cash-out via Jito did not confirm (status: ${relayed.status})` + (relayed.error ? `: ${relayed.error}` : "")
7903
+ );
7904
+ }
7905
+ if (!relayed.signature) {
7906
+ throw new Error("Gasless cash-out via Jito returned an empty transaction signature");
7907
+ }
7908
+ return {
7909
+ txSignature: relayed.signature,
7910
+ destinationAddress,
7911
+ amount: netAmount,
7912
+ relayerFee,
7913
+ explorerUrl: getExplorerUrl(relayed.signature, cluster),
7914
+ // Report the TRUE path: the relayer may have fallen back to direct submission.
7915
+ viaJito: relayed.relayed
7916
+ };
7917
+ }
7918
+ const txSignature = await connection.sendRawTransaction(transaction.serialize(), {
7919
+ skipPreflight: false,
7920
+ preflightCommitment: "confirmed"
7921
+ });
7922
+ const confirmation = await connection.confirmTransaction(
7923
+ {
7924
+ signature: txSignature,
7925
+ blockhash: build.blockhash,
7926
+ lastValidBlockHeight: build.lastValidBlockHeight
7927
+ },
7928
+ "confirmed"
7929
+ );
7930
+ if (confirmation.value.err) {
7931
+ throw new Error(
7932
+ `Gasless cash-out landed but failed on-chain: ${JSON.stringify(confirmation.value.err)}`
7933
+ );
7934
+ }
7935
+ return {
7936
+ txSignature,
7937
+ destinationAddress,
7938
+ amount: netAmount,
7939
+ relayerFee,
7940
+ explorerUrl: getExplorerUrl(txSignature, cluster),
7941
+ viaJito: false
7942
+ };
7943
+ }
7944
+
7713
7945
  export {
7714
7946
  isValidChainId,
7715
7947
  isValidPrivacyLevel,
@@ -7797,6 +8029,8 @@ export {
7797
8029
  formatLamports,
7798
8030
  parseSOLToLamports,
7799
8031
  getSOLBalance,
8032
+ signEd25519WithScalar,
8033
+ deriveStealthSigner,
7800
8034
  scanForPayments,
7801
8035
  claimStealthPayment,
7802
8036
  getStealthBalance,
@@ -7911,5 +8145,8 @@ export {
7911
8145
  SunspotVerifier,
7912
8146
  createVerifyInstructionData,
7913
8147
  formatFundingInputs,
7914
- formatOwnershipInputs
8148
+ formatOwnershipInputs,
8149
+ computeRelayerFee,
8150
+ buildGaslessCashout,
8151
+ submitGaslessCashout
7915
8152
  };