@sip-protocol/sdk 0.9.0 → 0.10.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 (64) hide show
  1. package/LICENSE +21 -0
  2. package/dist/{TransportWebUSB-YQMAGJAJ.mjs → TransportWebUSB-2KITI5HD.mjs} +24 -12
  3. package/dist/browser.d.mts +4 -4
  4. package/dist/browser.d.ts +4 -4
  5. package/dist/browser.js +1346 -838
  6. package/dist/browser.mjs +13 -3
  7. package/dist/{chunk-64AYA5F5.mjs → chunk-G3TBBG2K.mjs} +221 -146
  8. package/dist/{chunk-4GRJ5MAW.mjs → chunk-KXETSSKP.mjs} +4 -0
  9. package/dist/{chunk-6EU6WQFK.mjs → chunk-PT2DNA7E.mjs} +257 -235
  10. package/dist/{constants-LHAAUC2T.mjs → constants-DCJYTIU3.mjs} +5 -1
  11. package/dist/{dist-2OGQ7FED.mjs → dist-PYEXZNFD.mjs} +609 -221
  12. package/dist/{index-DeE1ZzA4.d.mts → index-B1d8pihL.d.mts} +117 -33
  13. package/dist/{index-DXh2IGkz.d.ts → index-UQhQJZbM.d.ts} +117 -33
  14. package/dist/index.d.mts +3 -3
  15. package/dist/index.d.ts +3 -3
  16. package/dist/index.js +1339 -831
  17. package/dist/index.mjs +13 -3
  18. package/dist/{interface-Bf7w1PLW.d.mts → interface-CQi0-WfS.d.mts} +2 -2
  19. package/dist/{interface-Bf7w1PLW.d.ts → interface-CQi0-WfS.d.ts} +2 -2
  20. package/dist/{noir-kzbLVTei.d.mts → noir-CwPIyBLj.d.mts} +1 -1
  21. package/dist/{noir-kzbLVTei.d.ts → noir-CwPIyBLj.d.ts} +1 -1
  22. package/dist/proofs/halo2.d.mts +1 -1
  23. package/dist/proofs/halo2.d.ts +1 -1
  24. package/dist/proofs/kimchi.d.mts +1 -1
  25. package/dist/proofs/kimchi.d.ts +1 -1
  26. package/dist/proofs/noir.d.mts +1 -1
  27. package/dist/proofs/noir.d.ts +1 -1
  28. package/dist/{solana-U3MEGU7W.mjs → solana-ZWNIQTSU.mjs} +6 -6
  29. package/package.json +32 -32
  30. package/src/adapters/gelato-relay.ts +386 -0
  31. package/src/adapters/index.ts +28 -0
  32. package/src/adapters/oneinch.ts +126 -0
  33. package/src/chains/ethereum/privacy-adapter.ts +8 -5
  34. package/src/chains/ethereum/stealth.ts +17 -14
  35. package/src/chains/near/privacy-adapter.ts +8 -5
  36. package/src/chains/near/resolver.ts +22 -8
  37. package/src/chains/near/stealth.ts +9 -9
  38. package/src/chains/solana/constants.ts +13 -1
  39. package/src/chains/solana/ephemeral-keys.ts +3 -257
  40. package/src/chains/solana/index.ts +2 -3
  41. package/src/chains/solana/providers/helius-enhanced.ts +6 -6
  42. package/src/chains/solana/providers/webhook.ts +2 -2
  43. package/src/chains/solana/scan.ts +9 -8
  44. package/src/chains/solana/stealth-scanner.ts +3 -3
  45. package/src/chains/solana/types.ts +18 -4
  46. package/src/cosmos/ibc-stealth.ts +6 -6
  47. package/src/index.ts +6 -0
  48. package/src/move/aptos.ts +15 -9
  49. package/src/move/sui.ts +15 -9
  50. package/src/nft/private-nft.ts +10 -6
  51. package/src/privacy-backends/shadowwire.ts +13 -0
  52. package/src/stealth/ed25519.ts +173 -12
  53. package/src/stealth/index.ts +47 -4
  54. package/src/stealth/secp256k1.ts +144 -7
  55. package/src/stealth.ts +7 -0
  56. package/src/wallet/ethereum/privacy-adapter.ts +1 -1
  57. package/src/wallet/hardware/ledger-privacy.ts +2 -2
  58. package/src/wallet/near/adapter.ts +2 -2
  59. package/src/wallet/near/meteor-wallet.ts +2 -2
  60. package/src/wallet/near/my-near-wallet.ts +2 -2
  61. package/src/wallet/near/wallet-selector.ts +2 -2
  62. package/src/wallet/solana/privacy-adapter.ts +9 -9
  63. package/dist/chunk-5EKF243P.mjs +0 -33809
  64. package/dist/chunk-YWGJ77A2.mjs +0 -33806
package/dist/browser.mjs CHANGED
@@ -458,7 +458,7 @@ import {
458
458
  verifyOracleSignature,
459
459
  verifyOwnership,
460
460
  walletRegistry
461
- } from "./chunk-5EKF243P.mjs";
461
+ } from "./chunk-PT2DNA7E.mjs";
462
462
  import {
463
463
  DEFAULT_NETWORK_CONFIG,
464
464
  DEFAULT_PROXY_TIMEOUT,
@@ -473,7 +473,9 @@ import {
473
473
  addBlindings,
474
474
  addCommitments,
475
475
  checkEd25519StealthAddress,
476
+ checkEd25519StealthAddressV1,
476
477
  checkProxyAvailability,
478
+ checkSecp256k1StealthAddressV1,
477
479
  checkStealthAddress,
478
480
  claimStealthPayment,
479
481
  commit,
@@ -487,7 +489,10 @@ import {
487
489
  createWebhookHandler,
488
490
  decodeStealthMetaAddress,
489
491
  deriveEd25519StealthPrivateKey,
492
+ deriveEd25519StealthPrivateKeyV1,
493
+ deriveSecp256k1StealthPrivateKeyV1,
490
494
  deriveStealthPrivateKey,
495
+ deriveStealthPrivateKeyV1,
491
496
  detectTorPort,
492
497
  ed25519PublicKeyToNearAddress,
493
498
  ed25519PublicKeyToSolanaAddress,
@@ -545,7 +550,7 @@ import {
545
550
  verifyWebhookSignature,
546
551
  withSecureBuffer,
547
552
  withSecureBufferSync
548
- } from "./chunk-64AYA5F5.mjs";
553
+ } from "./chunk-G3TBBG2K.mjs";
549
554
  import {
550
555
  Halo2Provider,
551
556
  KimchiProvider,
@@ -598,7 +603,7 @@ import {
598
603
  getExplorerUrl,
599
604
  getSolanaTokenDecimals,
600
605
  getTokenMint
601
- } from "./chunk-4GRJ5MAW.mjs";
606
+ } from "./chunk-KXETSSKP.mjs";
602
607
  import "./chunk-XGB3TDIC.mjs";
603
608
 
604
609
  // src/proofs/browser.ts
@@ -2348,9 +2353,11 @@ export {
2348
2353
  calculateSIPComparison,
2349
2354
  checkAptosStealthAddress,
2350
2355
  checkEd25519StealthAddress,
2356
+ checkEd25519StealthAddressV1,
2351
2357
  checkMobileWASMCompatibility,
2352
2358
  checkNEARStealthAddress,
2353
2359
  checkProxyAvailability,
2360
+ checkSecp256k1StealthAddressV1,
2354
2361
  checkStealthAddress,
2355
2362
  checkSuiStealthAddress,
2356
2363
  claimStealthPayment,
@@ -2458,11 +2465,14 @@ export {
2458
2465
  defaultRegistry,
2459
2466
  deriveAptosStealthPrivateKey,
2460
2467
  deriveEd25519StealthPrivateKey,
2468
+ deriveEd25519StealthPrivateKeyV1,
2461
2469
  deriveNEARChildViewingKey,
2462
2470
  deriveNEARStealthPrivateKey,
2463
2471
  deriveObliviousNullifier,
2464
2472
  deriveOracleId,
2473
+ deriveSecp256k1StealthPrivateKeyV1,
2465
2474
  deriveStealthPrivateKey,
2475
+ deriveStealthPrivateKeyV1,
2466
2476
  deriveSuiStealthPrivateKey,
2467
2477
  deriveTraditionalNullifier,
2468
2478
  deriveViewingKey,
@@ -11,21 +11,23 @@ import {
11
11
  HELIUS_DAS_PAGE_LIMIT,
12
12
  HELIUS_MAX_PAGES,
13
13
  MEMO_PROGRAM_ID,
14
- SIP_MEMO_PREFIX,
14
+ SIP_MEMO_PREFIX_ANY,
15
15
  SOLANA_ADDRESS_MAX_LENGTH,
16
16
  SOLANA_ADDRESS_MIN_LENGTH,
17
17
  SOLANA_TOKEN_MINTS,
18
18
  VIEW_TAG_MAX,
19
19
  getExplorerUrl,
20
20
  sanitizeUrl
21
- } from "./chunk-4GRJ5MAW.mjs";
21
+ } from "./chunk-KXETSSKP.mjs";
22
22
 
23
23
  // src/chains/solana/types.ts
24
24
  function parseAnnouncement(memo) {
25
- if (!memo.startsWith("SIP:1:")) {
25
+ const versionMatch = /^SIP:([12]):/.exec(memo);
26
+ if (!versionMatch) {
26
27
  return null;
27
28
  }
28
- const parts = memo.slice(6).split(":");
29
+ const version = versionMatch[1];
30
+ const parts = memo.slice(versionMatch[0].length).split(":");
29
31
  if (parts.length < 2) {
30
32
  return null;
31
33
  }
@@ -46,13 +48,14 @@ function parseAnnouncement(memo) {
46
48
  return null;
47
49
  }
48
50
  return {
51
+ version,
49
52
  ephemeralPublicKey,
50
53
  viewTag,
51
54
  stealthAddress
52
55
  };
53
56
  }
54
57
  function createAnnouncementMemo(ephemeralPublicKey, viewTag, stealthAddress) {
55
- const parts = ["SIP:1", ephemeralPublicKey, viewTag];
58
+ const parts = ["SIP:2", ephemeralPublicKey, viewTag];
56
59
  if (stealthAddress) {
57
60
  parts.push(stealthAddress);
58
61
  }
@@ -626,16 +629,16 @@ function generateEd25519StealthAddress(recipientMetaAddress) {
626
629
  if (ephemeralScalar === 0n) {
627
630
  throw new Error("CRITICAL: Zero ephemeral scalar after reduction - investigate RNG");
628
631
  }
629
- const spendingPoint = ed25519.ExtendedPoint.fromHex(spendingKeyBytes);
630
- const sharedSecretPoint = spendingPoint.multiply(ephemeralScalar);
632
+ const viewingPoint = ed25519.ExtendedPoint.fromHex(viewingKeyBytes);
633
+ const sharedSecretPoint = viewingPoint.multiply(ephemeralScalar);
631
634
  const sharedSecretHash = sha256(sharedSecretPoint.toRawBytes());
632
635
  const hashScalar = bytesToBigInt(sharedSecretHash) % ED25519_ORDER;
633
636
  if (hashScalar === 0n) {
634
637
  throw new Error("CRITICAL: Zero hash scalar after reduction - investigate hash computation");
635
638
  }
636
639
  const hashTimesG = ed25519.ExtendedPoint.BASE.multiply(hashScalar);
637
- const viewingPoint = ed25519.ExtendedPoint.fromHex(viewingKeyBytes);
638
- const stealthPoint = viewingPoint.add(hashTimesG);
640
+ const spendingPoint = ed25519.ExtendedPoint.fromHex(spendingKeyBytes);
641
+ const stealthPoint = spendingPoint.add(hashTimesG);
639
642
  const stealthAddressBytes = stealthPoint.toRawBytes();
640
643
  const viewTag = sharedSecretHash[0];
641
644
  return {
@@ -651,6 +654,57 @@ function generateEd25519StealthAddress(recipientMetaAddress) {
651
654
  }
652
655
  }
653
656
  function deriveEd25519StealthPrivateKey(stealthAddress, spendingPrivateKey, viewingPrivateKey) {
657
+ validateEd25519StealthAddress(stealthAddress);
658
+ if (!isValidPrivateKey(spendingPrivateKey)) {
659
+ throw new ValidationError(
660
+ "must be a valid 32-byte hex string",
661
+ "spendingPrivateKey"
662
+ );
663
+ }
664
+ if (!isValidPrivateKey(viewingPrivateKey)) {
665
+ throw new ValidationError(
666
+ "must be a valid 32-byte hex string",
667
+ "viewingPrivateKey"
668
+ );
669
+ }
670
+ const spendingPrivBytes = hexToBytes(spendingPrivateKey.slice(2));
671
+ const viewingPrivBytes = hexToBytes(viewingPrivateKey.slice(2));
672
+ const ephemeralPubBytes = hexToBytes(stealthAddress.ephemeralPublicKey.slice(2));
673
+ try {
674
+ const rawViewingScalar = getEd25519Scalar(viewingPrivBytes);
675
+ const viewingScalar = rawViewingScalar % ED25519_ORDER;
676
+ if (viewingScalar === 0n) {
677
+ throw new Error("CRITICAL: Zero viewing scalar after reduction - investigate key derivation");
678
+ }
679
+ const ephemeralPoint = ed25519.ExtendedPoint.fromHex(ephemeralPubBytes);
680
+ const sharedSecretPoint = ephemeralPoint.multiply(viewingScalar);
681
+ const sharedSecretHash = sha256(sharedSecretPoint.toRawBytes());
682
+ const rawSpendingScalar = getEd25519Scalar(spendingPrivBytes);
683
+ const spendingScalar = rawSpendingScalar % ED25519_ORDER;
684
+ if (spendingScalar === 0n) {
685
+ throw new Error("CRITICAL: Zero spending scalar after reduction - investigate key derivation");
686
+ }
687
+ const hashScalar = bytesToBigInt(sharedSecretHash) % ED25519_ORDER;
688
+ if (hashScalar === 0n) {
689
+ throw new Error("CRITICAL: Zero hash scalar after reduction - investigate hash computation");
690
+ }
691
+ const stealthPrivateScalar = (spendingScalar + hashScalar) % ED25519_ORDER;
692
+ if (stealthPrivateScalar === 0n) {
693
+ throw new Error("CRITICAL: Zero stealth scalar after reduction - investigate key derivation");
694
+ }
695
+ const stealthPrivateKey = bigIntToBytesLE(stealthPrivateScalar, 32);
696
+ const result = {
697
+ stealthAddress: stealthAddress.address,
698
+ ephemeralPublicKey: stealthAddress.ephemeralPublicKey,
699
+ privateKey: `0x${bytesToHex(stealthPrivateKey)}`
700
+ };
701
+ secureWipe(stealthPrivateKey);
702
+ return result;
703
+ } finally {
704
+ secureWipeAll(spendingPrivBytes, viewingPrivBytes);
705
+ }
706
+ }
707
+ function deriveEd25519StealthPrivateKeyV1(stealthAddress, spendingPrivateKey, viewingPrivateKey) {
654
708
  validateEd25519StealthAddress(stealthAddress);
655
709
  if (!isValidPrivateKey(spendingPrivateKey)) {
656
710
  throw new ValidationError(
@@ -701,7 +755,50 @@ function deriveEd25519StealthPrivateKey(stealthAddress, spendingPrivateKey, view
701
755
  secureWipeAll(spendingPrivBytes, viewingPrivBytes);
702
756
  }
703
757
  }
704
- function checkEd25519StealthAddress(stealthAddress, spendingPrivateKey, viewingPrivateKey) {
758
+ function checkEd25519StealthAddress(stealthAddress, viewingPrivateKey, spendingPublicKey) {
759
+ validateEd25519StealthAddress(stealthAddress);
760
+ if (!isValidPrivateKey(viewingPrivateKey)) {
761
+ throw new ValidationError(
762
+ "must be a valid 32-byte hex string",
763
+ "viewingPrivateKey"
764
+ );
765
+ }
766
+ if (!isValidEd25519PublicKey(spendingPublicKey)) {
767
+ throw new ValidationError(
768
+ "must be a valid ed25519 public key (32 bytes)",
769
+ "spendingPublicKey"
770
+ );
771
+ }
772
+ const viewingPrivBytes = hexToBytes(viewingPrivateKey.slice(2));
773
+ const spendingPubBytes = hexToBytes(spendingPublicKey.slice(2));
774
+ const ephemeralPubBytes = hexToBytes(stealthAddress.ephemeralPublicKey.slice(2));
775
+ try {
776
+ const rawViewingScalar = getEd25519Scalar(viewingPrivBytes);
777
+ const viewingScalar = rawViewingScalar % ED25519_ORDER;
778
+ if (viewingScalar === 0n) {
779
+ throw new Error("CRITICAL: Zero viewing scalar after reduction - investigate key derivation");
780
+ }
781
+ const ephemeralPoint = ed25519.ExtendedPoint.fromHex(ephemeralPubBytes);
782
+ const sharedSecretPoint = ephemeralPoint.multiply(viewingScalar);
783
+ const sharedSecretHash = sha256(sharedSecretPoint.toRawBytes());
784
+ if (sharedSecretHash[0] !== stealthAddress.viewTag) {
785
+ return false;
786
+ }
787
+ const hashScalar = bytesToBigInt(sharedSecretHash) % ED25519_ORDER;
788
+ if (hashScalar === 0n) {
789
+ throw new Error("CRITICAL: Zero hash scalar after reduction - investigate hash computation");
790
+ }
791
+ const hashTimesG = ed25519.ExtendedPoint.BASE.multiply(hashScalar);
792
+ const spendingPoint = ed25519.ExtendedPoint.fromHex(spendingPubBytes);
793
+ const expectedPoint = spendingPoint.add(hashTimesG);
794
+ const expectedPubKeyBytes = expectedPoint.toRawBytes();
795
+ const providedAddress = hexToBytes(stealthAddress.address.slice(2));
796
+ return bytesToHex(expectedPubKeyBytes) === bytesToHex(providedAddress);
797
+ } finally {
798
+ secureWipe(viewingPrivBytes);
799
+ }
800
+ }
801
+ function checkEd25519StealthAddressV1(stealthAddress, spendingPrivateKey, viewingPrivateKey) {
705
802
  validateEd25519StealthAddress(stealthAddress);
706
803
  if (!isValidPrivateKey(spendingPrivateKey)) {
707
804
  throw new ValidationError(
@@ -830,13 +927,13 @@ function generateSecp256k1StealthAddress(recipientMetaAddress) {
830
927
  const viewingKeyBytes = hexToBytes(recipientMetaAddress.viewingKey.slice(2));
831
928
  const sharedSecretPoint = secp256k1.getSharedSecret(
832
929
  ephemeralPrivateKey,
833
- spendingKeyBytes
930
+ viewingKeyBytes
834
931
  );
835
932
  const sharedSecretHash = sha256(sharedSecretPoint);
836
933
  const hashTimesG = secp256k1.getPublicKey(sharedSecretHash, true);
837
- const viewingKeyPoint = secp256k1.ProjectivePoint.fromHex(viewingKeyBytes);
934
+ const spendingKeyPoint = secp256k1.ProjectivePoint.fromHex(spendingKeyBytes);
838
935
  const hashTimesGPoint = secp256k1.ProjectivePoint.fromHex(hashTimesG);
839
- const stealthPoint = viewingKeyPoint.add(hashTimesGPoint);
936
+ const stealthPoint = spendingKeyPoint.add(hashTimesGPoint);
840
937
  const stealthAddressBytes = stealthPoint.toRawBytes(true);
841
938
  const viewTag = sharedSecretHash[0];
842
939
  return {
@@ -852,6 +949,44 @@ function generateSecp256k1StealthAddress(recipientMetaAddress) {
852
949
  }
853
950
  }
854
951
  function deriveSecp256k1StealthPrivateKey(stealthAddress, spendingPrivateKey, viewingPrivateKey) {
952
+ validateSecp256k1StealthAddress(stealthAddress);
953
+ if (!isValidPrivateKey(spendingPrivateKey)) {
954
+ throw new ValidationError(
955
+ "must be a valid 32-byte hex string",
956
+ "spendingPrivateKey"
957
+ );
958
+ }
959
+ if (!isValidPrivateKey(viewingPrivateKey)) {
960
+ throw new ValidationError(
961
+ "must be a valid 32-byte hex string",
962
+ "viewingPrivateKey"
963
+ );
964
+ }
965
+ const spendingPrivBytes = hexToBytes(spendingPrivateKey.slice(2));
966
+ const viewingPrivBytes = hexToBytes(viewingPrivateKey.slice(2));
967
+ const ephemeralPubBytes = hexToBytes(stealthAddress.ephemeralPublicKey.slice(2));
968
+ try {
969
+ const sharedSecretPoint = secp256k1.getSharedSecret(
970
+ viewingPrivBytes,
971
+ ephemeralPubBytes
972
+ );
973
+ const sharedSecretHash = sha256(sharedSecretPoint);
974
+ const spendingScalar = bytesToBigInt(spendingPrivBytes);
975
+ const hashScalar = bytesToBigInt(sharedSecretHash);
976
+ const stealthPrivateScalar = (spendingScalar + hashScalar) % secp256k1.CURVE.n;
977
+ const stealthPrivateKey = bigIntToBytes(stealthPrivateScalar, 32);
978
+ const result = {
979
+ stealthAddress: stealthAddress.address,
980
+ ephemeralPublicKey: stealthAddress.ephemeralPublicKey,
981
+ privateKey: `0x${bytesToHex(stealthPrivateKey)}`
982
+ };
983
+ secureWipe(stealthPrivateKey);
984
+ return result;
985
+ } finally {
986
+ secureWipeAll(spendingPrivBytes, viewingPrivBytes);
987
+ }
988
+ }
989
+ function deriveSecp256k1StealthPrivateKeyV1(stealthAddress, spendingPrivateKey, viewingPrivateKey) {
855
990
  validateSecp256k1StealthAddress(stealthAddress);
856
991
  if (!isValidPrivateKey(spendingPrivateKey)) {
857
992
  throw new ValidationError(
@@ -889,7 +1024,43 @@ function deriveSecp256k1StealthPrivateKey(stealthAddress, spendingPrivateKey, vi
889
1024
  secureWipeAll(spendingPrivBytes, viewingPrivBytes);
890
1025
  }
891
1026
  }
892
- function checkSecp256k1StealthAddress(stealthAddress, spendingPrivateKey, viewingPrivateKey) {
1027
+ function checkSecp256k1StealthAddress(stealthAddress, viewingPrivateKey, spendingPublicKey) {
1028
+ validateSecp256k1StealthAddress(stealthAddress);
1029
+ if (!isValidPrivateKey(viewingPrivateKey)) {
1030
+ throw new ValidationError(
1031
+ "must be a valid 32-byte hex string",
1032
+ "viewingPrivateKey"
1033
+ );
1034
+ }
1035
+ if (!isValidCompressedPublicKey(spendingPublicKey)) {
1036
+ throw new ValidationError(
1037
+ "must be a valid compressed secp256k1 public key (33 bytes, starting with 02 or 03)",
1038
+ "spendingPublicKey"
1039
+ );
1040
+ }
1041
+ const viewingPrivBytes = hexToBytes(viewingPrivateKey.slice(2));
1042
+ const spendingPubBytes = hexToBytes(spendingPublicKey.slice(2));
1043
+ const ephemeralPubBytes = hexToBytes(stealthAddress.ephemeralPublicKey.slice(2));
1044
+ try {
1045
+ const sharedSecretPoint = secp256k1.getSharedSecret(
1046
+ viewingPrivBytes,
1047
+ ephemeralPubBytes
1048
+ );
1049
+ const sharedSecretHash = sha256(sharedSecretPoint);
1050
+ if (sharedSecretHash[0] !== stealthAddress.viewTag) {
1051
+ return false;
1052
+ }
1053
+ const hashTimesG = secp256k1.getPublicKey(sharedSecretHash, true);
1054
+ const expectedPoint = secp256k1.ProjectivePoint.fromHex(spendingPubBytes).add(
1055
+ secp256k1.ProjectivePoint.fromHex(hashTimesG)
1056
+ );
1057
+ const providedAddress = hexToBytes(stealthAddress.address.slice(2));
1058
+ return bytesToHex(expectedPoint.toRawBytes(true)) === bytesToHex(providedAddress);
1059
+ } finally {
1060
+ secureWipe(viewingPrivBytes);
1061
+ }
1062
+ }
1063
+ function checkSecp256k1StealthAddressV1(stealthAddress, spendingPrivateKey, viewingPrivateKey) {
893
1064
  validateSecp256k1StealthAddress(stealthAddress);
894
1065
  if (!isValidPrivateKey(spendingPrivateKey)) {
895
1066
  throw new ValidationError(
@@ -1213,12 +1384,19 @@ function deriveStealthPrivateKey(stealthAddress, spendingPrivateKey, viewingPriv
1213
1384
  }
1214
1385
  return deriveSecp256k1StealthPrivateKey(stealthAddress, spendingPrivateKey, viewingPrivateKey);
1215
1386
  }
1216
- function checkStealthAddress(stealthAddress, spendingPrivateKey, viewingPrivateKey) {
1387
+ function deriveStealthPrivateKeyV1(stealthAddress, spendingPrivateKey, viewingPrivateKey) {
1388
+ const addressHex = stealthAddress.address.slice(2);
1389
+ if (addressHex.length === 64) {
1390
+ return deriveEd25519StealthPrivateKeyV1(stealthAddress, spendingPrivateKey, viewingPrivateKey);
1391
+ }
1392
+ return deriveSecp256k1StealthPrivateKeyV1(stealthAddress, spendingPrivateKey, viewingPrivateKey);
1393
+ }
1394
+ function checkStealthAddress(stealthAddress, viewingPrivateKey, spendingPublicKey) {
1217
1395
  const addressHex = stealthAddress.address.slice(2);
1218
1396
  if (addressHex.length === 64) {
1219
- return checkEd25519StealthAddress(stealthAddress, spendingPrivateKey, viewingPrivateKey);
1397
+ return checkEd25519StealthAddress(stealthAddress, viewingPrivateKey, spendingPublicKey);
1220
1398
  }
1221
- return checkSecp256k1StealthAddress(stealthAddress, spendingPrivateKey, viewingPrivateKey);
1399
+ return checkSecp256k1StealthAddress(stealthAddress, viewingPrivateKey, spendingPublicKey);
1222
1400
  }
1223
1401
 
1224
1402
  // src/chains/solana/transfer.ts
@@ -2281,7 +2459,7 @@ async function scanForPayments(params) {
2281
2459
  });
2282
2460
  if (!tx?.meta?.logMessages) continue;
2283
2461
  for (const log of tx.meta.logMessages) {
2284
- if (!log.includes(SIP_MEMO_PREFIX)) continue;
2462
+ if (!log.includes(SIP_MEMO_PREFIX_ANY)) continue;
2285
2463
  const memoMatch = log.match(/Program log: (.+)/);
2286
2464
  if (!memoMatch) continue;
2287
2465
  const memoContent = memoMatch[1];
@@ -2371,7 +2549,8 @@ async function claimStealthPayment(params) {
2371
2549
  viewingPrivateKey,
2372
2550
  spendingPrivateKey,
2373
2551
  destinationAddress,
2374
- mint
2552
+ mint,
2553
+ version = "2"
2375
2554
  } = params;
2376
2555
  const stealthPubkeyForBalance = new PublicKey4(stealthAddress);
2377
2556
  const solBalance = await connection.getBalance(stealthPubkeyForBalance);
@@ -2388,17 +2567,13 @@ async function claimStealthPayment(params) {
2388
2567
  viewTag: 0
2389
2568
  // Not needed for derivation
2390
2569
  };
2391
- const recovery = deriveEd25519StealthPrivateKey(
2392
- stealthAddressObj,
2393
- spendingPrivateKey,
2394
- viewingPrivateKey
2395
- );
2570
+ const recovery = version === "1" ? deriveEd25519StealthPrivateKeyV1(stealthAddressObj, spendingPrivateKey, viewingPrivateKey) : deriveEd25519StealthPrivateKey(stealthAddressObj, spendingPrivateKey, viewingPrivateKey);
2396
2571
  const stealthPrivKeyBytes = hexToBytes2(recovery.privateKey.slice(2));
2397
2572
  const stealthPubkey = new PublicKey4(stealthAddress);
2398
2573
  const expectedPubKeyBytes = stealthPubkey.toBytes();
2399
2574
  const scalarBigInt = bytesToBigIntLE2(stealthPrivKeyBytes);
2400
- const ED25519_ORDER4 = 2n ** 252n + 27742317777372353535851937790883648493n;
2401
- let validScalar = scalarBigInt % ED25519_ORDER4;
2575
+ const ED25519_ORDER3 = 2n ** 252n + 27742317777372353535851937790883648493n;
2576
+ let validScalar = scalarBigInt % ED25519_ORDER3;
2402
2577
  if (validScalar === 0n) validScalar = 1n;
2403
2578
  const derivedPubKeyBytes = ed255192.ExtendedPoint.BASE.multiply(validScalar).toRawBytes();
2404
2579
  if (!derivedPubKeyBytes.every((b, i) => b === expectedPubKeyBytes[i])) {
@@ -2583,7 +2758,7 @@ var StealthScanner = class {
2583
2758
  });
2584
2759
  if (!tx?.meta?.logMessages) continue;
2585
2760
  for (const log of tx.meta.logMessages) {
2586
- if (!log.includes(SIP_MEMO_PREFIX)) continue;
2761
+ if (!log.includes(SIP_MEMO_PREFIX_ANY)) continue;
2587
2762
  const memoMatch = log.match(/Program log: (.+)/);
2588
2763
  if (!memoMatch) continue;
2589
2764
  const announcement = parseAnnouncement(memoMatch[1]);
@@ -2636,7 +2811,7 @@ var StealthScanner = class {
2636
2811
  async (logs) => {
2637
2812
  try {
2638
2813
  for (const log of logs.logs) {
2639
- if (!log.includes(SIP_MEMO_PREFIX)) continue;
2814
+ if (!log.includes(SIP_MEMO_PREFIX_ANY)) continue;
2640
2815
  const memoMatch = log.match(/Program log: (.+)/);
2641
2816
  if (!memoMatch) continue;
2642
2817
  const announcement = parseAnnouncement(memoMatch[1]);
@@ -2832,26 +3007,6 @@ function generateManagedEphemeralKeypair() {
2832
3007
  secureWipe(privateKeyBytes);
2833
3008
  disposed = true;
2834
3009
  }
2835
- },
2836
- useForStealthAddress(recipientSpendingKey, recipientViewingKey) {
2837
- if (disposed) {
2838
- throw new Error("Ephemeral keypair has been disposed");
2839
- }
2840
- try {
2841
- const result = computeStealthAddress(
2842
- privateKeyBytes,
2843
- publicKeyBytes,
2844
- recipientSpendingKey,
2845
- recipientViewingKey
2846
- );
2847
- return {
2848
- ...result,
2849
- ephemeralPublicKey: publicKeyHex,
2850
- ephemeralPublicKeyBase58: publicKeyBase58
2851
- };
2852
- } finally {
2853
- managed.dispose();
2854
- }
2855
3010
  }
2856
3011
  };
2857
3012
  return managed;
@@ -2909,89 +3064,6 @@ function wipeEphemeralPrivateKey(privateKeyHex) {
2909
3064
  const bytes = hexToBytes3(privateKeyHex.slice(2));
2910
3065
  secureWipe(bytes);
2911
3066
  }
2912
- var ED25519_ORDER2 = 2n ** 252n + 27742317777372353535851937790883648493n;
2913
- function bytesToBigIntLE3(bytes) {
2914
- let result = 0n;
2915
- for (let i = bytes.length - 1; i >= 0; i--) {
2916
- result = result << 8n | BigInt(bytes[i]);
2917
- }
2918
- return result;
2919
- }
2920
- function getEd25519Scalar2(privateKey) {
2921
- const hash = sha2562(privateKey);
2922
- hash[0] &= 248;
2923
- hash[31] &= 127;
2924
- hash[31] |= 64;
2925
- return bytesToBigIntLE3(hash.slice(0, 32));
2926
- }
2927
- function computeStealthAddress(ephemeralPrivateBytes, _ephemeralPublicBytes, recipientSpendingKey, recipientViewingKey) {
2928
- const spendingKeyBytes = hexToBytes3(recipientSpendingKey.slice(2));
2929
- const viewingKeyBytes = hexToBytes3(recipientViewingKey.slice(2));
2930
- const rawEphemeralScalar = getEd25519Scalar2(ephemeralPrivateBytes);
2931
- const ephemeralScalar = rawEphemeralScalar % ED25519_ORDER2;
2932
- if (ephemeralScalar === 0n) {
2933
- throw new Error("Invalid ephemeral scalar");
2934
- }
2935
- const spendingPoint = ed255193.ExtendedPoint.fromHex(spendingKeyBytes);
2936
- const sharedSecretPoint = spendingPoint.multiply(ephemeralScalar);
2937
- const sharedSecretBytes = sharedSecretPoint.toRawBytes();
2938
- const sharedSecretHash = sha2562(sharedSecretBytes);
2939
- const viewTag = sharedSecretHash[0];
2940
- const hashScalar = bytesToBigIntLE3(sharedSecretHash) % ED25519_ORDER2;
2941
- if (hashScalar === 0n) {
2942
- throw new Error("Invalid hash scalar");
2943
- }
2944
- const hashTimesG = ed255193.ExtendedPoint.BASE.multiply(hashScalar);
2945
- const viewingPoint = ed255193.ExtendedPoint.fromHex(viewingKeyBytes);
2946
- const stealthPoint = viewingPoint.add(hashTimesG);
2947
- const stealthAddressBytes = stealthPoint.toRawBytes();
2948
- const stealthAddress = `0x${bytesToHex2(stealthAddressBytes)}`;
2949
- const stealthAddressBase58 = ed25519PublicKeyToSolanaAddress(stealthAddress);
2950
- return {
2951
- sharedSecret: `0x${bytesToHex2(sharedSecretHash)}`,
2952
- viewTag,
2953
- stealthAddress,
2954
- stealthAddressBase58
2955
- };
2956
- }
2957
- function formatEphemeralAnnouncement(ephemeralPublicKeyBase58, viewTag, stealthAddressBase58) {
2958
- const viewTagHex = viewTag.toString(16).padStart(2, "0");
2959
- const parts = ["SIP:1", ephemeralPublicKeyBase58, viewTagHex];
2960
- if (stealthAddressBase58) {
2961
- parts.push(stealthAddressBase58);
2962
- }
2963
- return parts.join(":");
2964
- }
2965
- function parseEphemeralAnnouncement(announcement) {
2966
- if (!announcement.startsWith("SIP:1:")) {
2967
- return null;
2968
- }
2969
- const parts = announcement.slice(6).split(":");
2970
- if (parts.length < 2) {
2971
- return null;
2972
- }
2973
- const ephemeralPublicKeyBase58 = parts[0];
2974
- const viewTagHex = parts[1];
2975
- const stealthAddressBase58 = parts[2];
2976
- if (!ephemeralPublicKeyBase58 || ephemeralPublicKeyBase58.length < 32 || ephemeralPublicKeyBase58.length > 44) {
2977
- return null;
2978
- }
2979
- if (!viewTagHex || viewTagHex.length > 2 || !/^[0-9a-fA-F]+$/.test(viewTagHex)) {
2980
- return null;
2981
- }
2982
- const viewTag = parseInt(viewTagHex, 16);
2983
- if (viewTag < 0 || viewTag > 255) {
2984
- return null;
2985
- }
2986
- if (stealthAddressBase58 && (stealthAddressBase58.length < 32 || stealthAddressBase58.length > 44)) {
2987
- return null;
2988
- }
2989
- return {
2990
- ephemeralPublicKeyBase58,
2991
- viewTag,
2992
- stealthAddressBase58
2993
- };
2994
- }
2995
3067
 
2996
3068
  // src/chains/solana/privacy-adapter.ts
2997
3069
  import { PublicKey as PublicKey9 } from "@solana/web3.js";
@@ -4059,7 +4131,7 @@ async function processRawTransaction(tx, viewingPrivateKey, spendingPublicKey, o
4059
4131
  return { found: false, signature };
4060
4132
  }
4061
4133
  for (const log of tx.meta.logMessages) {
4062
- if (!log.includes(SIP_MEMO_PREFIX)) continue;
4134
+ if (!log.includes(SIP_MEMO_PREFIX_ANY)) continue;
4063
4135
  const memoMatch = log.match(/Program log: (.+)/);
4064
4136
  if (!memoMatch) continue;
4065
4137
  const memoContent = memoMatch[1];
@@ -4350,7 +4422,7 @@ var HeliusEnhanced = class {
4350
4422
  * Extract SIP metadata from a transaction
4351
4423
  *
4352
4424
  * Parses memo program instructions to find SIP announcements.
4353
- * SIP memo format: SIP:1:<ephemeral_pubkey_base58>:<view_tag_hex>
4425
+ * SIP memo format: SIP:<version>:<ephemeral_pubkey_base58>:<view_tag_hex>
4354
4426
  *
4355
4427
  * @param tx - Enhanced transaction
4356
4428
  * @returns SIP metadata if found
@@ -4361,9 +4433,9 @@ var HeliusEnhanced = class {
4361
4433
  isSIPTransaction: false
4362
4434
  };
4363
4435
  const description = tx.description || "";
4364
- if (description.includes(SIP_MEMO_PREFIX) || description.includes("SIP:")) {
4436
+ if (description.includes(SIP_MEMO_PREFIX_ANY)) {
4365
4437
  metadata.isSIPTransaction = true;
4366
- const sipMemoMatch = description.match(/SIP:1:([A-Za-z0-9]{32,44}):([0-9a-fA-F]{2})/);
4438
+ const sipMemoMatch = description.match(/SIP:[12]:([A-Za-z0-9]{32,44}):([0-9a-fA-F]{1,2})/);
4367
4439
  if (sipMemoMatch) {
4368
4440
  metadata.ephemeralPubKey = sipMemoMatch[1];
4369
4441
  metadata.viewTag = parseInt(sipMemoMatch[2], 16);
@@ -5006,7 +5078,7 @@ import { sha256 as sha2565 } from "@noble/hashes/sha2";
5006
5078
  import { bytesToHex as bytesToHex4, randomBytes as randomBytes5 } from "@noble/hashes/utils";
5007
5079
  var H_DOMAIN = "SIP-SOLANA-PEDERSEN-GENERATOR-H-v1";
5008
5080
  var G = ed255195.ExtendedPoint.BASE;
5009
- var ED25519_ORDER3 = 2n ** 252n + 27742317777372353535851937790883648493n;
5081
+ var ED25519_ORDER2 = 2n ** 252n + 27742317777372353535851937790883648493n;
5010
5082
  var ED25519_COFACTOR = 8n;
5011
5083
  var MAX_SPL_AMOUNT = 2n ** 64n - 1n;
5012
5084
  var H = generateH();
@@ -5042,18 +5114,18 @@ function commitSolana(value, blinding) {
5042
5114
  if (value < 0n) {
5043
5115
  throw new ValidationError("must be non-negative", "value");
5044
5116
  }
5045
- if (value >= ED25519_ORDER3) {
5117
+ if (value >= ED25519_ORDER2) {
5046
5118
  throw new ValidationError(
5047
5119
  "must be less than curve order",
5048
5120
  "value",
5049
- { curveOrder: ED25519_ORDER3.toString(16) }
5121
+ { curveOrder: ED25519_ORDER2.toString(16) }
5050
5122
  );
5051
5123
  }
5052
5124
  const r = blinding ?? randomBytes5(32);
5053
5125
  if (r.length !== 32) {
5054
5126
  throw new ValidationError("must be 32 bytes", "blinding", { received: r.length });
5055
5127
  }
5056
- const rScalar = bytesToBigInt2(r) % ED25519_ORDER3;
5128
+ const rScalar = bytesToBigInt2(r) % ED25519_ORDER2;
5057
5129
  if (rScalar === 0n) {
5058
5130
  return commitSolana(value, randomBytes5(32));
5059
5131
  }
@@ -5076,7 +5148,7 @@ function verifyOpeningSolana(commitment, value, blinding) {
5076
5148
  const commitmentBytes = hexToBytes4(commitment.slice(2));
5077
5149
  const C = ed255195.ExtendedPoint.fromHex(commitmentBytes);
5078
5150
  const blindingBytes = hexToBytes4(blinding.slice(2));
5079
- const rScalar = bytesToBigInt2(blindingBytes) % ED25519_ORDER3;
5151
+ const rScalar = bytesToBigInt2(blindingBytes) % ED25519_ORDER2;
5080
5152
  let expected;
5081
5153
  if (value === 0n) {
5082
5154
  expected = H.multiply(rScalar);
@@ -5189,14 +5261,14 @@ function subtractCommitmentsSolana(c1, c2) {
5189
5261
  function addBlindingsSolana(b1, b2) {
5190
5262
  const r1 = bytesToBigInt2(hexToBytes4(b1.slice(2)));
5191
5263
  const r2 = bytesToBigInt2(hexToBytes4(b2.slice(2)));
5192
- const sum = (r1 + r2) % ED25519_ORDER3;
5264
+ const sum = (r1 + r2) % ED25519_ORDER2;
5193
5265
  const sumBytes = bigIntToBytes2(sum, 32);
5194
5266
  return `0x${bytesToHex4(sumBytes)}`;
5195
5267
  }
5196
5268
  function subtractBlindingsSolana(b1, b2) {
5197
5269
  const r1 = bytesToBigInt2(hexToBytes4(b1.slice(2)));
5198
5270
  const r2 = bytesToBigInt2(hexToBytes4(b2.slice(2)));
5199
- const diff = (r1 - r2 + ED25519_ORDER3) % ED25519_ORDER3;
5271
+ const diff = (r1 - r2 + ED25519_ORDER2) % ED25519_ORDER2;
5200
5272
  const diffBytes = bigIntToBytes2(diff, 32);
5201
5273
  return `0x${bytesToHex4(diffBytes)}`;
5202
5274
  }
@@ -5805,7 +5877,7 @@ async function createProxyAgent(config, options = {}) {
5805
5877
  const parsed = parseProxyConfig(config === "tor" ? `socks5://${TOR_HOST}:${TOR_PORTS[0]}` : config);
5806
5878
  try {
5807
5879
  if (parsed.type === "socks5" || parsed.type === "socks4" || config === "tor") {
5808
- const { SocksProxyAgent } = await import("./dist-2OGQ7FED.mjs");
5880
+ const { SocksProxyAgent } = await import("./dist-PYEXZNFD.mjs");
5809
5881
  return new SocksProxyAgent(proxyUrl, { timeout });
5810
5882
  }
5811
5883
  if (parsed.type === "http" || parsed.type === "https") {
@@ -7665,7 +7737,11 @@ export {
7665
7737
  generateEd25519StealthMetaAddress,
7666
7738
  generateEd25519StealthAddress,
7667
7739
  deriveEd25519StealthPrivateKey,
7740
+ deriveEd25519StealthPrivateKeyV1,
7668
7741
  checkEd25519StealthAddress,
7742
+ checkEd25519StealthAddressV1,
7743
+ deriveSecp256k1StealthPrivateKeyV1,
7744
+ checkSecp256k1StealthAddressV1,
7669
7745
  publicKeyToEthAddress,
7670
7746
  encodeStealthMetaAddress,
7671
7747
  decodeStealthMetaAddress,
@@ -7680,6 +7756,7 @@ export {
7680
7756
  generateStealthMetaAddress,
7681
7757
  generateStealthAddress,
7682
7758
  deriveStealthPrivateKey,
7759
+ deriveStealthPrivateKeyV1,
7683
7760
  checkStealthAddress,
7684
7761
  commit,
7685
7762
  verifyOpening,
@@ -7727,8 +7804,6 @@ export {
7727
7804
  batchGenerateManagedEphemeralKeypairs,
7728
7805
  disposeEphemeralKeypairs,
7729
7806
  wipeEphemeralPrivateKey,
7730
- formatEphemeralAnnouncement,
7731
- parseEphemeralAnnouncement,
7732
7807
  HeliusProvider,
7733
7808
  GenericProvider,
7734
7809
  createProvider,
@@ -7748,7 +7823,7 @@ export {
7748
7823
  generateMnemonic,
7749
7824
  isValidMnemonic,
7750
7825
  getDerivationPath,
7751
- ED25519_ORDER3 as ED25519_ORDER,
7826
+ ED25519_ORDER2 as ED25519_ORDER,
7752
7827
  MAX_SPL_AMOUNT,
7753
7828
  commitSolana,
7754
7829
  verifyOpeningSolana,