@sip-protocol/sdk 0.3.2 → 0.5.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/dist/browser.d.mts +2 -2
  2. package/dist/browser.d.ts +2 -2
  3. package/dist/browser.js +2881 -295
  4. package/dist/browser.mjs +62 -2
  5. package/dist/chunk-AOZIY3GU.mjs +12995 -0
  6. package/dist/chunk-BCLIX5T2.mjs +12940 -0
  7. package/dist/chunk-DMHBKRWV.mjs +14712 -0
  8. package/dist/chunk-FKXPHKYD.mjs +12955 -0
  9. package/dist/chunk-HGU6HZRC.mjs +231 -0
  10. package/dist/chunk-J4Q4NJ2U.mjs +13544 -0
  11. package/dist/chunk-OPQ2GQIO.mjs +13013 -0
  12. package/dist/chunk-W2B7T6WU.mjs +14714 -0
  13. package/dist/index-5jAdWMA-.d.ts +8973 -0
  14. package/dist/index-B9Vkpaao.d.mts +8973 -0
  15. package/dist/index-BcWNakUD.d.ts +7990 -0
  16. package/dist/index-BsKY3Hr0.d.mts +7990 -0
  17. package/dist/index.d.mts +2 -2
  18. package/dist/index.d.ts +2 -2
  19. package/dist/index.js +2852 -266
  20. package/dist/index.mjs +62 -2
  21. package/dist/proofs/noir.mjs +1 -1
  22. package/package.json +2 -1
  23. package/src/adapters/near-intents.ts +8 -0
  24. package/src/bitcoin/index.ts +51 -0
  25. package/src/bitcoin/silent-payments.ts +865 -0
  26. package/src/bitcoin/taproot.ts +590 -0
  27. package/src/compliance/compliance-manager.ts +87 -0
  28. package/src/compliance/conditional-threshold.ts +379 -0
  29. package/src/compliance/conditional.ts +382 -0
  30. package/src/compliance/derivation.ts +489 -0
  31. package/src/compliance/index.ts +50 -8
  32. package/src/compliance/pdf.ts +365 -0
  33. package/src/compliance/reports.ts +644 -0
  34. package/src/compliance/threshold.ts +529 -0
  35. package/src/compliance/types.ts +223 -0
  36. package/src/cosmos/ibc-stealth.ts +825 -0
  37. package/src/cosmos/index.ts +83 -0
  38. package/src/cosmos/stealth.ts +487 -0
  39. package/src/errors.ts +8 -0
  40. package/src/index.ts +80 -1
  41. package/src/move/aptos.ts +369 -0
  42. package/src/move/index.ts +35 -0
  43. package/src/move/sui.ts +367 -0
  44. package/src/oracle/types.ts +8 -0
  45. package/src/settlement/backends/direct-chain.ts +8 -0
  46. package/src/stealth.ts +3 -3
  47. package/src/validation.ts +42 -1
  48. package/src/wallet/aptos/adapter.ts +422 -0
  49. package/src/wallet/aptos/index.ts +10 -0
  50. package/src/wallet/aptos/mock.ts +410 -0
  51. package/src/wallet/aptos/types.ts +278 -0
  52. package/src/wallet/bitcoin/adapter.ts +470 -0
  53. package/src/wallet/bitcoin/index.ts +38 -0
  54. package/src/wallet/bitcoin/mock.ts +516 -0
  55. package/src/wallet/bitcoin/types.ts +274 -0
  56. package/src/wallet/cosmos/adapter.ts +484 -0
  57. package/src/wallet/cosmos/index.ts +63 -0
  58. package/src/wallet/cosmos/mock.ts +596 -0
  59. package/src/wallet/cosmos/types.ts +462 -0
  60. package/src/wallet/index.ts +127 -0
  61. package/src/wallet/sui/adapter.ts +471 -0
  62. package/src/wallet/sui/index.ts +10 -0
  63. package/src/wallet/sui/mock.ts +439 -0
  64. package/src/wallet/sui/types.ts +245 -0
package/dist/index.js CHANGED
@@ -31,9 +31,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
33
  ATTESTATION_VERSION: () => ATTESTATION_VERSION,
34
+ AptosStealthService: () => AptosStealthService,
35
+ AuditorKeyDerivation: () => AuditorKeyDerivation,
36
+ AuditorType: () => AuditorType,
34
37
  BaseWalletAdapter: () => BaseWalletAdapter,
35
38
  CHAIN_NUMERIC_IDS: () => CHAIN_NUMERIC_IDS,
39
+ COSMOS_CHAIN_PREFIXES: () => CHAIN_PREFIXES,
36
40
  ComplianceManager: () => ComplianceManager,
41
+ ComplianceReporter: () => ComplianceReporter,
42
+ ConditionalDisclosure: () => ConditionalDisclosure,
43
+ CosmosStealthService: () => CosmosStealthService,
37
44
  CryptoError: () => CryptoError,
38
45
  DEFAULT_THRESHOLD: () => DEFAULT_THRESHOLD,
39
46
  DEFAULT_TOTAL_ORACLES: () => DEFAULT_TOTAL_ORACLES,
@@ -46,7 +53,7 @@ __export(index_exports, {
46
53
  HardwareWalletError: () => HardwareWalletError,
47
54
  IntentBuilder: () => IntentBuilder,
48
55
  IntentError: () => IntentError,
49
- IntentStatus: () => import_types37.IntentStatus,
56
+ IntentStatus: () => import_types55.IntentStatus,
50
57
  LedgerWalletAdapter: () => LedgerWalletAdapter,
51
58
  MockEthereumAdapter: () => MockEthereumAdapter,
52
59
  MockLedgerAdapter: () => MockLedgerAdapter,
@@ -55,27 +62,27 @@ __export(index_exports, {
55
62
  MockSolver: () => MockSolver,
56
63
  MockTrezorAdapter: () => MockTrezorAdapter,
57
64
  MockWalletAdapter: () => MockWalletAdapter,
58
- NATIVE_TOKENS: () => import_types37.NATIVE_TOKENS,
65
+ NATIVE_TOKENS: () => import_types55.NATIVE_TOKENS,
59
66
  NEARIntentsAdapter: () => NEARIntentsAdapter,
60
67
  NEARIntentsBackend: () => NEARIntentsBackend,
61
68
  NetworkError: () => NetworkError,
62
69
  ORACLE_DOMAIN: () => ORACLE_DOMAIN,
63
70
  OneClickClient: () => OneClickClient,
64
- OneClickDepositMode: () => import_types41.OneClickDepositMode,
65
- OneClickErrorCode: () => import_types41.OneClickErrorCode,
66
- OneClickSwapStatus: () => import_types41.OneClickSwapStatus,
67
- OneClickSwapType: () => import_types41.OneClickSwapType,
71
+ OneClickDepositMode: () => import_types59.OneClickDepositMode,
72
+ OneClickErrorCode: () => import_types59.OneClickErrorCode,
73
+ OneClickSwapStatus: () => import_types59.OneClickSwapStatus,
74
+ OneClickSwapType: () => import_types59.OneClickSwapType,
68
75
  PaymentBuilder: () => PaymentBuilder,
69
- PaymentStatus: () => import_types38.PaymentStatus,
70
- PrivacyLevel: () => import_types37.PrivacyLevel,
76
+ PaymentStatus: () => import_types56.PaymentStatus,
77
+ PrivacyLevel: () => import_types55.PrivacyLevel,
71
78
  ProofError: () => ProofError,
72
79
  ProofGenerationError: () => ProofGenerationError,
73
80
  ProofNotImplementedError: () => ProofNotImplementedError,
74
- ProposalStatus: () => import_types39.ProposalStatus,
75
- ReportStatus: () => import_types40.ReportStatus,
81
+ ProposalStatus: () => import_types57.ProposalStatus,
82
+ ReportStatus: () => import_types58.ReportStatus,
76
83
  SIP: () => SIP,
77
84
  SIPError: () => SIPError,
78
- SIP_VERSION: () => import_types37.SIP_VERSION,
85
+ SIP_VERSION: () => import_types55.SIP_VERSION,
79
86
  STABLECOIN_ADDRESSES: () => STABLECOIN_ADDRESSES,
80
87
  STABLECOIN_DECIMALS: () => STABLECOIN_DECIMALS,
81
88
  STABLECOIN_INFO: () => STABLECOIN_INFO,
@@ -84,12 +91,13 @@ __export(index_exports, {
84
91
  SmartRouter: () => SmartRouter,
85
92
  SolanaWalletAdapter: () => SolanaWalletAdapter,
86
93
  SwapStatus: () => SwapStatus,
94
+ ThresholdViewingKey: () => ThresholdViewingKey,
87
95
  Treasury: () => Treasury,
88
96
  TrezorWalletAdapter: () => TrezorWalletAdapter,
89
97
  ValidationError: () => ValidationError,
90
98
  WalletError: () => WalletError,
91
- WalletErrorCode: () => import_types36.WalletErrorCode,
92
- ZcashErrorCode: () => import_types42.ZcashErrorCode,
99
+ WalletErrorCode: () => import_types54.WalletErrorCode,
100
+ ZcashErrorCode: () => import_types60.ZcashErrorCode,
93
101
  ZcashNativeBackend: () => ZcashNativeBackend,
94
102
  ZcashRPCClient: () => ZcashRPCClient,
95
103
  ZcashRPCError: () => ZcashRPCError,
@@ -98,17 +106,21 @@ __export(index_exports, {
98
106
  addBlindings: () => addBlindings,
99
107
  addCommitments: () => addCommitments,
100
108
  addOracle: () => addOracle,
109
+ aptosAddressToAuthKey: () => aptosAddressToAuthKey,
101
110
  attachProofs: () => attachProofs,
102
111
  base58ToHex: () => base58ToHex,
103
- browserBytesToHex: () => bytesToHex7,
104
- browserHexToBytes: () => hexToBytes5,
112
+ browserBytesToHex: () => bytesToHex11,
113
+ browserHexToBytes: () => hexToBytes9,
114
+ checkAptosStealthAddress: () => checkAptosStealthAddress,
105
115
  checkEd25519StealthAddress: () => checkEd25519StealthAddress,
106
116
  checkStealthAddress: () => checkStealthAddress,
107
117
  commit: () => commit,
108
118
  commitZero: () => commitZero,
109
119
  computeAttestationHash: () => computeAttestationHash,
120
+ computeTweakedKey: () => computeTweakedKey,
110
121
  createCommitment: () => createCommitment,
111
122
  createEthereumAdapter: () => createEthereumAdapter,
123
+ createKeySpendOnlyOutput: () => createKeySpendOnlyOutput,
112
124
  createLedgerAdapter: () => createLedgerAdapter,
113
125
  createMockEthereumAdapter: () => createMockEthereumAdapter,
114
126
  createMockEthereumProvider: () => createMockEthereumProvider,
@@ -127,6 +139,7 @@ __export(index_exports, {
127
139
  createShieldedPayment: () => createShieldedPayment,
128
140
  createSmartRouter: () => createSmartRouter,
129
141
  createSolanaAdapter: () => createSolanaAdapter,
142
+ createTaprootOutput: () => createTaprootOutput,
130
143
  createTrezorAdapter: () => createTrezorAdapter,
131
144
  createWalletFactory: () => createWalletFactory,
132
145
  createZcashClient: () => createZcashClient,
@@ -134,8 +147,10 @@ __export(index_exports, {
134
147
  createZcashShieldedService: () => createZcashShieldedService,
135
148
  createZcashSwapService: () => createZcashSwapService,
136
149
  decodeStealthMetaAddress: () => decodeStealthMetaAddress,
150
+ decodeTaprootAddress: () => decodeTaprootAddress,
137
151
  decryptMemo: () => decryptMemo,
138
152
  decryptWithViewing: () => decryptWithViewing,
153
+ deriveAptosStealthPrivateKey: () => deriveAptosStealthPrivateKey,
139
154
  deriveEd25519StealthPrivateKey: () => deriveEd25519StealthPrivateKey,
140
155
  deriveOracleId: () => deriveOracleId,
141
156
  deriveStealthPrivateKey: () => deriveStealthPrivateKey,
@@ -145,6 +160,7 @@ __export(index_exports, {
145
160
  deserializePayment: () => deserializePayment,
146
161
  detectEthereumWallets: () => detectEthereumWallets,
147
162
  detectSolanaWallets: () => detectSolanaWallets,
163
+ ed25519PublicKeyToAptosAddress: () => ed25519PublicKeyToAptosAddress,
148
164
  ed25519PublicKeyToNearAddress: () => ed25519PublicKeyToNearAddress,
149
165
  ed25519PublicKeyToSolanaAddress: () => ed25519PublicKeyToSolanaAddress,
150
166
  encodeStealthMetaAddress: () => encodeStealthMetaAddress,
@@ -153,10 +169,14 @@ __export(index_exports, {
153
169
  formatStablecoinAmount: () => formatStablecoinAmount,
154
170
  fromHex: () => fromHex,
155
171
  fromStablecoinUnits: () => fromStablecoinUnits,
172
+ generateAptosStealthAddress: () => generateAptosStealthAddress,
156
173
  generateBlinding: () => generateBlinding,
174
+ generateCosmosStealthAddress: () => generateCosmosStealthAddress,
175
+ generateCosmosStealthMetaAddress: () => generateCosmosStealthMetaAddress,
157
176
  generateEd25519StealthAddress: () => generateEd25519StealthAddress,
158
177
  generateEd25519StealthMetaAddress: () => generateEd25519StealthMetaAddress,
159
178
  generateIntentId: () => generateIntentId,
179
+ generatePdfReport: () => generatePdfReport,
160
180
  generateRandomBytes: () => generateRandomBytes,
161
181
  generateStealthAddress: () => generateStealthAddress,
162
182
  generateStealthMetaAddress: () => generateStealthMetaAddress,
@@ -183,6 +203,7 @@ __export(index_exports, {
183
203
  getStablecoinsForChain: () => getStablecoinsForChain,
184
204
  getSupportedStablecoins: () => getSupportedStablecoins,
185
205
  getTimeRemaining: () => getTimeRemaining,
206
+ getXOnlyPublicKey: () => getXOnlyPublicKey,
186
207
  hasEnoughOracles: () => hasEnoughOracles,
187
208
  hasErrorCode: () => hasErrorCode,
188
209
  hasRequiredProofs: () => hasRequiredProofs,
@@ -193,14 +214,16 @@ __export(index_exports, {
193
214
  isExpired: () => isExpired,
194
215
  isNonNegativeAmount: () => isNonNegativeAmount,
195
216
  isPaymentExpired: () => isPaymentExpired,
196
- isPrivate: () => import_types37.isPrivate,
217
+ isPrivate: () => import_types55.isPrivate,
197
218
  isPrivateWalletAdapter: () => isPrivateWalletAdapter,
198
219
  isSIPError: () => isSIPError,
199
220
  isStablecoin: () => isStablecoin,
200
221
  isStablecoinOnChain: () => isStablecoinOnChain,
201
222
  isValidAmount: () => isValidAmount,
223
+ isValidAptosAddress: () => isValidAptosAddress,
202
224
  isValidChainId: () => isValidChainId,
203
225
  isValidCompressedPublicKey: () => isValidCompressedPublicKey,
226
+ isValidCosmosAddress: () => isValidCosmosAddress,
204
227
  isValidEd25519PublicKey: () => isValidEd25519PublicKey,
205
228
  isValidHex: () => isValidHex,
206
229
  isValidHexLength: () => isValidHexLength,
@@ -212,12 +235,17 @@ __export(index_exports, {
212
235
  isValidSlippage: () => isValidSlippage,
213
236
  isValidSolanaAddress: () => isValidSolanaAddress,
214
237
  isValidStealthMetaAddress: () => isValidStealthMetaAddress,
238
+ isValidTaprootAddress: () => isValidTaprootAddress,
215
239
  nearAddressToEd25519PublicKey: () => nearAddressToEd25519PublicKey,
216
240
  normalizeAddress: () => normalizeAddress,
217
241
  notConnectedError: () => notConnectedError,
218
242
  publicKeyToEthAddress: () => publicKeyToEthAddress,
219
243
  registerWallet: () => registerWallet,
220
244
  removeOracle: () => removeOracle,
245
+ schnorrSign: () => schnorrSign,
246
+ schnorrSignHex: () => schnorrSignHex,
247
+ schnorrVerify: () => schnorrVerify,
248
+ schnorrVerifyHex: () => schnorrVerifyHex,
221
249
  secureWipe: () => secureWipe,
222
250
  secureWipeAll: () => secureWipeAll,
223
251
  serializeAttestationMessage: () => serializeAttestationMessage,
@@ -226,14 +254,16 @@ __export(index_exports, {
226
254
  signAttestationMessage: () => signAttestationMessage,
227
255
  solanaAddressToEd25519PublicKey: () => solanaAddressToEd25519PublicKey,
228
256
  solanaPublicKeyToHex: () => solanaPublicKeyToHex,
257
+ stealthKeyToCosmosAddress: () => stealthKeyToCosmosAddress,
229
258
  subtractBlindings: () => subtractBlindings,
230
259
  subtractCommitments: () => subtractCommitments,
231
260
  supportsSharedArrayBuffer: () => supportsSharedArrayBuffer,
232
- supportsViewingKey: () => import_types37.supportsViewingKey,
261
+ supportsViewingKey: () => import_types55.supportsViewingKey,
233
262
  supportsWebBluetooth: () => supportsWebBluetooth,
234
263
  supportsWebHID: () => supportsWebHID,
235
264
  supportsWebUSB: () => supportsWebUSB,
236
265
  supportsWebWorkers: () => supportsWebWorkers,
266
+ taprootAddress: () => taprootAddress,
237
267
  toHex: () => toHex,
238
268
  toStablecoinUnits: () => toStablecoinUnits,
239
269
  trackIntent: () => trackIntent,
@@ -279,6 +309,14 @@ var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
279
309
  ErrorCode2["SIGNATURE_FAILED"] = "SIP_3005";
280
310
  ErrorCode2["INVALID_CURVE_POINT"] = "SIP_3006";
281
311
  ErrorCode2["INVALID_SCALAR"] = "SIP_3007";
312
+ ErrorCode2["INVALID_KEY_SIZE"] = "SIP_3008";
313
+ ErrorCode2["INVALID_ENCRYPTED_DATA"] = "SIP_3009";
314
+ ErrorCode2["INVALID_COMMITMENT"] = "SIP_3010";
315
+ ErrorCode2["INVALID_TIME_LOCK"] = "SIP_3011";
316
+ ErrorCode2["INVALID_SHARE"] = "SIP_3012";
317
+ ErrorCode2["INVALID_THRESHOLD"] = "SIP_3013";
318
+ ErrorCode2["CRYPTO_OPERATION_FAILED"] = "SIP_3014";
319
+ ErrorCode2["INVALID_FORMAT"] = "SIP_3015";
282
320
  ErrorCode2["PROOF_FAILED"] = "SIP_4000";
283
321
  ErrorCode2["PROOF_GENERATION_FAILED"] = "SIP_4001";
284
322
  ErrorCode2["PROOF_VERIFICATION_FAILED"] = "SIP_4002";
@@ -474,7 +512,16 @@ var VALID_CHAIN_IDS = [
474
512
  "polygon",
475
513
  "arbitrum",
476
514
  "optimism",
477
- "base"
515
+ "base",
516
+ "bitcoin",
517
+ "aptos",
518
+ "sui",
519
+ "cosmos",
520
+ "osmosis",
521
+ "injective",
522
+ "celestia",
523
+ "sei",
524
+ "dydx"
478
525
  ];
479
526
  function isValidChainId(chain) {
480
527
  return VALID_CHAIN_IDS.includes(chain);
@@ -671,6 +718,12 @@ function isValidNearAddressFormat(address) {
671
718
  if (address.includes("..")) return false;
672
719
  return true;
673
720
  }
721
+ function isValidCosmosAddressFormat(address) {
722
+ if (typeof address !== "string") return false;
723
+ if (address.length < 39 || address.length > 90) return false;
724
+ const bech32Pattern = /^[a-z]+1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]{38,}$/;
725
+ return bech32Pattern.test(address);
726
+ }
674
727
  function getChainAddressType(chain) {
675
728
  switch (chain) {
676
729
  case "ethereum":
@@ -685,6 +738,13 @@ function getChainAddressType(chain) {
685
738
  return "near";
686
739
  case "zcash":
687
740
  return "zcash";
741
+ case "cosmos":
742
+ case "osmosis":
743
+ case "injective":
744
+ case "celestia":
745
+ case "sei":
746
+ case "dydx":
747
+ return "cosmos";
688
748
  default:
689
749
  return "unknown";
690
750
  }
@@ -728,6 +788,15 @@ function validateAddressForChain(address, chain, field = "address") {
728
788
  );
729
789
  }
730
790
  break;
791
+ case "cosmos":
792
+ if (!isValidCosmosAddressFormat(address)) {
793
+ throw new ValidationError(
794
+ `Invalid address format for ${chain}. Expected Cosmos bech32 address, got: ${address.slice(0, 20)}...`,
795
+ field,
796
+ { chain, expectedFormat: "bech32" }
797
+ );
798
+ }
799
+ break;
731
800
  default:
732
801
  break;
733
802
  }
@@ -779,7 +848,7 @@ function secureWipeAll(...buffers) {
779
848
  function generateStealthMetaAddress(chain, label) {
780
849
  if (!isValidChainId(chain)) {
781
850
  throw new ValidationError(
782
- `invalid chain '${chain}', must be one of: solana, ethereum, near, zcash, polygon, arbitrum, optimism, base`,
851
+ `invalid chain '${chain}', must be one of: solana, ethereum, near, zcash, polygon, arbitrum, optimism, base, bitcoin, aptos, sui, cosmos, osmosis, injective, celestia, sei, dydx`,
783
852
  "chain"
784
853
  );
785
854
  }
@@ -1059,7 +1128,7 @@ function toChecksumAddress(address) {
1059
1128
  return checksummed;
1060
1129
  }
1061
1130
  var ED25519_ORDER = 2n ** 252n + 27742317777372353535851937790883648493n;
1062
- var ED25519_CHAINS = ["solana", "near"];
1131
+ var ED25519_CHAINS = ["solana", "near", "aptos", "sui"];
1063
1132
  function isEd25519Chain(chain) {
1064
1133
  return ED25519_CHAINS.includes(chain);
1065
1134
  }
@@ -1144,7 +1213,7 @@ function bigIntToBytesLE(value, length) {
1144
1213
  function generateEd25519StealthMetaAddress(chain, label) {
1145
1214
  if (!isValidChainId(chain)) {
1146
1215
  throw new ValidationError(
1147
- `invalid chain '${chain}', must be one of: solana, ethereum, near, zcash, polygon, arbitrum, optimism, base`,
1216
+ `invalid chain '${chain}', must be one of: solana, ethereum, near, zcash, polygon, arbitrum, optimism, base, bitcoin, aptos, sui, cosmos, osmosis, injective, celestia, sei, dydx`,
1148
1217
  "chain"
1149
1218
  );
1150
1219
  }
@@ -2514,7 +2583,15 @@ var CHAIN_BLOCKCHAIN_MAP = {
2514
2583
  arbitrum: "evm",
2515
2584
  optimism: "evm",
2516
2585
  base: "evm",
2517
- bitcoin: "bitcoin"
2586
+ bitcoin: "bitcoin",
2587
+ aptos: "aptos",
2588
+ sui: "sui",
2589
+ cosmos: "cosmos",
2590
+ osmosis: "cosmos",
2591
+ injective: "cosmos",
2592
+ celestia: "cosmos",
2593
+ sei: "cosmos",
2594
+ dydx: "cosmos"
2518
2595
  };
2519
2596
  var NEARIntentsAdapter = class {
2520
2597
  client;
@@ -3274,6 +3351,448 @@ function createProductionSIP(config) {
3274
3351
  });
3275
3352
  }
3276
3353
 
3354
+ // src/move/aptos.ts
3355
+ var import_sha32 = require("@noble/hashes/sha3");
3356
+ var import_utils7 = require("@noble/hashes/utils");
3357
+ var APTOS_SINGLE_ED25519_SCHEME = 0;
3358
+ function ed25519PublicKeyToAptosAddress(publicKey) {
3359
+ if (!isValidHex(publicKey)) {
3360
+ throw new ValidationError(
3361
+ "publicKey must be a valid hex string with 0x prefix",
3362
+ "publicKey"
3363
+ );
3364
+ }
3365
+ if (!isValidEd25519PublicKey(publicKey)) {
3366
+ throw new ValidationError(
3367
+ "publicKey must be 32 bytes (64 hex characters)",
3368
+ "publicKey"
3369
+ );
3370
+ }
3371
+ const publicKeyBytes = (0, import_utils7.hexToBytes)(publicKey.slice(2));
3372
+ const authKeyInput = new Uint8Array(publicKeyBytes.length + 1);
3373
+ authKeyInput.set(publicKeyBytes, 0);
3374
+ authKeyInput[publicKeyBytes.length] = APTOS_SINGLE_ED25519_SCHEME;
3375
+ const addressHash = (0, import_sha32.sha3_256)(authKeyInput);
3376
+ return `0x${(0, import_utils7.bytesToHex)(addressHash)}`;
3377
+ }
3378
+ function isValidAptosAddress(address) {
3379
+ if (typeof address !== "string" || address.length === 0) {
3380
+ return false;
3381
+ }
3382
+ if (!address.startsWith("0x")) {
3383
+ return false;
3384
+ }
3385
+ const hexPart = address.slice(2);
3386
+ if (hexPart.length !== 64) {
3387
+ return false;
3388
+ }
3389
+ return /^[0-9a-fA-F]{64}$/.test(hexPart);
3390
+ }
3391
+ function aptosAddressToAuthKey(address) {
3392
+ if (!isValidAptosAddress(address)) {
3393
+ throw new ValidationError(
3394
+ "Invalid Aptos address format (must be 0x-prefixed 64 hex characters)",
3395
+ "address"
3396
+ );
3397
+ }
3398
+ return address.toLowerCase();
3399
+ }
3400
+ function generateAptosStealthAddress(recipientMetaAddress) {
3401
+ if (recipientMetaAddress.chain !== "aptos") {
3402
+ throw new ValidationError(
3403
+ `Expected chain 'aptos', got '${recipientMetaAddress.chain}'`,
3404
+ "recipientMetaAddress.chain"
3405
+ );
3406
+ }
3407
+ const { stealthAddress, sharedSecret } = generateEd25519StealthAddress(recipientMetaAddress);
3408
+ const aptosAddress = ed25519PublicKeyToAptosAddress(stealthAddress.address);
3409
+ return {
3410
+ stealthAddress: aptosAddress,
3411
+ stealthPublicKey: stealthAddress.address,
3412
+ ephemeralPublicKey: stealthAddress.ephemeralPublicKey,
3413
+ viewTag: stealthAddress.viewTag,
3414
+ sharedSecret
3415
+ };
3416
+ }
3417
+ function deriveAptosStealthPrivateKey(stealthAddress, spendingPrivateKey, viewingPrivateKey) {
3418
+ const recovery = deriveEd25519StealthPrivateKey(
3419
+ stealthAddress,
3420
+ spendingPrivateKey,
3421
+ viewingPrivateKey
3422
+ );
3423
+ const aptosAddress = ed25519PublicKeyToAptosAddress(recovery.stealthAddress);
3424
+ return {
3425
+ ...recovery,
3426
+ aptosAddress
3427
+ };
3428
+ }
3429
+ function checkAptosStealthAddress(stealthAddress, spendingPrivateKey, viewingPrivateKey) {
3430
+ return checkEd25519StealthAddress(
3431
+ stealthAddress,
3432
+ spendingPrivateKey,
3433
+ viewingPrivateKey
3434
+ );
3435
+ }
3436
+ var AptosStealthService = class {
3437
+ /**
3438
+ * Generate a stealth address for an Aptos recipient
3439
+ *
3440
+ * @param recipientMetaAddress - Recipient's stealth meta-address
3441
+ * @returns Complete stealth address result
3442
+ */
3443
+ generateStealthAddress(recipientMetaAddress) {
3444
+ return generateAptosStealthAddress(recipientMetaAddress);
3445
+ }
3446
+ /**
3447
+ * Convert an ed25519 public key to Aptos address format
3448
+ *
3449
+ * @param publicKey - 32-byte ed25519 public key
3450
+ * @returns Aptos address string
3451
+ */
3452
+ stealthKeyToAptosAddress(publicKey) {
3453
+ return ed25519PublicKeyToAptosAddress(publicKey);
3454
+ }
3455
+ /**
3456
+ * Derive the private key for a stealth address
3457
+ *
3458
+ * @param stealthAddress - Stealth address data
3459
+ * @param spendingPrivateKey - Recipient's spending private key
3460
+ * @param viewingPrivateKey - Recipient's viewing private key
3461
+ * @returns Recovery data with derived private key
3462
+ */
3463
+ deriveStealthPrivateKey(stealthAddress, spendingPrivateKey, viewingPrivateKey) {
3464
+ return deriveAptosStealthPrivateKey(stealthAddress, spendingPrivateKey, viewingPrivateKey);
3465
+ }
3466
+ /**
3467
+ * Check if a stealth address belongs to this recipient
3468
+ *
3469
+ * @param stealthAddress - Stealth address to check
3470
+ * @param spendingPrivateKey - Recipient's spending private key
3471
+ * @param viewingPrivateKey - Recipient's viewing private key
3472
+ * @returns true if the address belongs to this recipient
3473
+ */
3474
+ checkStealthAddress(stealthAddress, spendingPrivateKey, viewingPrivateKey) {
3475
+ return checkAptosStealthAddress(stealthAddress, spendingPrivateKey, viewingPrivateKey);
3476
+ }
3477
+ /**
3478
+ * Validate an Aptos address format
3479
+ *
3480
+ * @param address - Address to validate
3481
+ * @returns true if valid format
3482
+ */
3483
+ isValidAddress(address) {
3484
+ return isValidAptosAddress(address);
3485
+ }
3486
+ };
3487
+
3488
+ // src/move/sui.ts
3489
+ var import_blake2b = require("@noble/hashes/blake2b");
3490
+ var import_utils8 = require("@noble/hashes/utils");
3491
+
3492
+ // src/cosmos/stealth.ts
3493
+ var import_sha2566 = require("@noble/hashes/sha256");
3494
+ var import_ripemd160 = require("@noble/hashes/ripemd160");
3495
+ var import_utils9 = require("@noble/hashes/utils");
3496
+ var import_base = require("@scure/base");
3497
+ var CHAIN_PREFIXES = {
3498
+ cosmos: "cosmos",
3499
+ osmosis: "osmo",
3500
+ injective: "inj",
3501
+ celestia: "celestia",
3502
+ sei: "sei",
3503
+ dydx: "dydx"
3504
+ };
3505
+ var CosmosStealthService = class {
3506
+ /**
3507
+ * Generate a stealth meta-address for a Cosmos chain
3508
+ *
3509
+ * @param chain - Cosmos chain identifier
3510
+ * @param label - Optional human-readable label
3511
+ * @returns Stealth meta-address and private keys
3512
+ * @throws {ValidationError} If chain is invalid
3513
+ *
3514
+ * @example
3515
+ * ```typescript
3516
+ * const service = new CosmosStealthService()
3517
+ * const { metaAddress, spendingPrivateKey, viewingPrivateKey } =
3518
+ * service.generateStealthMetaAddress('cosmos', 'My Cosmos Wallet')
3519
+ * ```
3520
+ */
3521
+ generateStealthMetaAddress(chain, label) {
3522
+ if (!this.isValidCosmosChain(chain)) {
3523
+ throw new ValidationError(
3524
+ `invalid Cosmos chain '${chain}', must be one of: ${Object.keys(CHAIN_PREFIXES).join(", ")}`,
3525
+ "chain"
3526
+ );
3527
+ }
3528
+ const result = generateStealthMetaAddress("ethereum", label);
3529
+ return {
3530
+ ...result,
3531
+ metaAddress: {
3532
+ ...result.metaAddress,
3533
+ chain
3534
+ // Will be updated in types package
3535
+ }
3536
+ };
3537
+ }
3538
+ /**
3539
+ * Generate a one-time stealth address for a Cosmos chain
3540
+ *
3541
+ * @param spendingPubKey - Recipient's spending public key (33-byte compressed)
3542
+ * @param viewingPubKey - Recipient's viewing public key (33-byte compressed)
3543
+ * @param chain - Cosmos chain identifier
3544
+ * @returns Cosmos stealth address with bech32 encoding
3545
+ * @throws {ValidationError} If keys or chain are invalid
3546
+ *
3547
+ * @example
3548
+ * ```typescript
3549
+ * const service = new CosmosStealthService()
3550
+ * const result = service.generateStealthAddress(
3551
+ * spendingKey,
3552
+ * viewingKey,
3553
+ * 'osmosis'
3554
+ * )
3555
+ * console.log(result.stealthAddress) // "osmo1..."
3556
+ * ```
3557
+ */
3558
+ generateStealthAddress(spendingPubKey, viewingPubKey, chain) {
3559
+ if (!this.isValidCosmosChain(chain)) {
3560
+ throw new ValidationError(
3561
+ `invalid Cosmos chain '${chain}', must be one of: ${Object.keys(CHAIN_PREFIXES).join(", ")}`,
3562
+ "chain"
3563
+ );
3564
+ }
3565
+ if (spendingPubKey.length !== 33) {
3566
+ throw new ValidationError(
3567
+ "spendingPubKey must be 33 bytes (compressed secp256k1)",
3568
+ "spendingPubKey"
3569
+ );
3570
+ }
3571
+ if (viewingPubKey.length !== 33) {
3572
+ throw new ValidationError(
3573
+ "viewingPubKey must be 33 bytes (compressed secp256k1)",
3574
+ "viewingPubKey"
3575
+ );
3576
+ }
3577
+ const metaAddress = {
3578
+ spendingKey: `0x${(0, import_utils9.bytesToHex)(spendingPubKey)}`,
3579
+ viewingKey: `0x${(0, import_utils9.bytesToHex)(viewingPubKey)}`,
3580
+ chain: "ethereum"
3581
+ // Use ethereum for secp256k1 generation
3582
+ };
3583
+ const { stealthAddress, sharedSecret } = generateStealthAddress(metaAddress);
3584
+ const cosmosAddress = this.stealthKeyToCosmosAddress(
3585
+ (0, import_utils9.hexToBytes)(stealthAddress.address.slice(2)),
3586
+ CHAIN_PREFIXES[chain]
3587
+ );
3588
+ return {
3589
+ stealthAddress: cosmosAddress,
3590
+ stealthPublicKey: stealthAddress.address,
3591
+ ephemeralPublicKey: stealthAddress.ephemeralPublicKey,
3592
+ viewTag: stealthAddress.viewTag,
3593
+ viewKeyHash: sharedSecret
3594
+ };
3595
+ }
3596
+ /**
3597
+ * Generate stealth address from StealthMetaAddress
3598
+ *
3599
+ * Convenience method that accepts a StealthMetaAddress directly.
3600
+ *
3601
+ * @param recipientMetaAddress - Recipient's stealth meta-address
3602
+ * @param chain - Cosmos chain identifier
3603
+ * @returns Cosmos stealth address with bech32 encoding
3604
+ * @throws {ValidationError} If meta-address or chain are invalid
3605
+ *
3606
+ * @example
3607
+ * ```typescript
3608
+ * const service = new CosmosStealthService()
3609
+ * const result = service.generateStealthAddressFromMeta(metaAddress, 'cosmos')
3610
+ * ```
3611
+ */
3612
+ generateStealthAddressFromMeta(recipientMetaAddress, chain) {
3613
+ const spendingPubKey = (0, import_utils9.hexToBytes)(recipientMetaAddress.spendingKey.slice(2));
3614
+ const viewingPubKey = (0, import_utils9.hexToBytes)(recipientMetaAddress.viewingKey.slice(2));
3615
+ return this.generateStealthAddress(spendingPubKey, viewingPubKey, chain);
3616
+ }
3617
+ /**
3618
+ * Convert stealth public key to Cosmos bech32 address
3619
+ *
3620
+ * Algorithm:
3621
+ * 1. SHA256 hash of compressed public key
3622
+ * 2. RIPEMD160 hash of SHA256 hash
3623
+ * 3. Bech32 encode with chain prefix
3624
+ *
3625
+ * @param publicKey - Compressed secp256k1 public key (33 bytes)
3626
+ * @param prefix - Bech32 address prefix (e.g., "cosmos", "osmo")
3627
+ * @returns Bech32-encoded address
3628
+ * @throws {ValidationError} If public key is invalid
3629
+ *
3630
+ * @example
3631
+ * ```typescript
3632
+ * const service = new CosmosStealthService()
3633
+ * const address = service.stealthKeyToCosmosAddress(pubKey, 'cosmos')
3634
+ * // Returns: "cosmos1abc..."
3635
+ * ```
3636
+ */
3637
+ stealthKeyToCosmosAddress(publicKey, prefix) {
3638
+ if (publicKey.length !== 33) {
3639
+ throw new ValidationError(
3640
+ "public key must be 33 bytes (compressed secp256k1)",
3641
+ "publicKey"
3642
+ );
3643
+ }
3644
+ const sha256Hash = (0, import_sha2566.sha256)(publicKey);
3645
+ const hash160 = (0, import_ripemd160.ripemd160)(sha256Hash);
3646
+ const words = import_base.bech32.toWords(hash160);
3647
+ return import_base.bech32.encode(prefix, words);
3648
+ }
3649
+ /**
3650
+ * Derive stealth private key for recipient to claim funds
3651
+ *
3652
+ * @param stealthAddress - The stealth address to recover (as StealthAddress)
3653
+ * @param spendingPrivateKey - Recipient's spending private key
3654
+ * @param viewingPrivateKey - Recipient's viewing private key
3655
+ * @returns Recovery data with derived private key
3656
+ * @throws {ValidationError} If any input is invalid
3657
+ *
3658
+ * @example
3659
+ * ```typescript
3660
+ * const service = new CosmosStealthService()
3661
+ * const recovery = service.deriveStealthPrivateKey(
3662
+ * stealthAddress,
3663
+ * spendingPrivKey,
3664
+ * viewingPrivKey
3665
+ * )
3666
+ * // Use recovery.privateKey to spend funds
3667
+ * ```
3668
+ */
3669
+ deriveStealthPrivateKey(stealthAddress, spendingPrivateKey, viewingPrivateKey) {
3670
+ return deriveStealthPrivateKey(
3671
+ stealthAddress,
3672
+ spendingPrivateKey,
3673
+ viewingPrivateKey
3674
+ );
3675
+ }
3676
+ /**
3677
+ * Check if a string is a valid Cosmos chain identifier
3678
+ */
3679
+ isValidCosmosChain(chain) {
3680
+ return chain in CHAIN_PREFIXES;
3681
+ }
3682
+ /**
3683
+ * Decode a Cosmos bech32 address to raw hash
3684
+ *
3685
+ * @param address - Bech32-encoded address
3686
+ * @returns Decoded address hash (20 bytes)
3687
+ * @throws {ValidationError} If address is invalid
3688
+ *
3689
+ * @example
3690
+ * ```typescript
3691
+ * const service = new CosmosStealthService()
3692
+ * const { prefix, hash } = service.decodeBech32Address('cosmos1abc...')
3693
+ * ```
3694
+ */
3695
+ decodeBech32Address(address) {
3696
+ try {
3697
+ const decoded = import_base.bech32.decode(address);
3698
+ const hash2 = import_base.bech32.fromWords(decoded.words);
3699
+ if (hash2.length !== 20) {
3700
+ throw new ValidationError(
3701
+ `invalid address hash length: ${hash2.length}, expected 20`,
3702
+ "address"
3703
+ );
3704
+ }
3705
+ return {
3706
+ prefix: decoded.prefix,
3707
+ hash: new Uint8Array(hash2)
3708
+ };
3709
+ } catch (error) {
3710
+ if (error instanceof ValidationError) {
3711
+ throw error;
3712
+ }
3713
+ throw new ValidationError(
3714
+ `invalid bech32 address: ${error instanceof Error ? error.message : "unknown error"}`,
3715
+ "address"
3716
+ );
3717
+ }
3718
+ }
3719
+ /**
3720
+ * Validate a Cosmos bech32 address format
3721
+ *
3722
+ * @param address - Address to validate
3723
+ * @param expectedChain - Optional chain to validate prefix against
3724
+ * @returns true if valid, false otherwise
3725
+ *
3726
+ * @example
3727
+ * ```typescript
3728
+ * const service = new CosmosStealthService()
3729
+ * service.isValidCosmosAddress('cosmos1abc...', 'cosmos') // true
3730
+ * service.isValidCosmosAddress('osmo1xyz...', 'cosmos') // false (wrong prefix)
3731
+ * ```
3732
+ */
3733
+ isValidCosmosAddress(address, expectedChain) {
3734
+ try {
3735
+ const { prefix, hash: hash2 } = this.decodeBech32Address(address);
3736
+ if (hash2.length !== 20) {
3737
+ return false;
3738
+ }
3739
+ if (expectedChain) {
3740
+ return prefix === CHAIN_PREFIXES[expectedChain];
3741
+ }
3742
+ return Object.values(CHAIN_PREFIXES).includes(prefix);
3743
+ } catch {
3744
+ return false;
3745
+ }
3746
+ }
3747
+ /**
3748
+ * Get the chain ID from a bech32 address prefix
3749
+ *
3750
+ * @param address - Bech32-encoded address
3751
+ * @returns Chain ID or null if unknown prefix
3752
+ *
3753
+ * @example
3754
+ * ```typescript
3755
+ * const service = new CosmosStealthService()
3756
+ * service.getChainFromAddress('cosmos1abc...') // 'cosmos'
3757
+ * service.getChainFromAddress('osmo1xyz...') // 'osmosis'
3758
+ * ```
3759
+ */
3760
+ getChainFromAddress(address) {
3761
+ try {
3762
+ const { prefix } = this.decodeBech32Address(address);
3763
+ for (const [chain, chainPrefix] of Object.entries(CHAIN_PREFIXES)) {
3764
+ if (chainPrefix === prefix) {
3765
+ return chain;
3766
+ }
3767
+ }
3768
+ return null;
3769
+ } catch {
3770
+ return null;
3771
+ }
3772
+ }
3773
+ };
3774
+ function generateCosmosStealthMetaAddress(chain, label) {
3775
+ const service = new CosmosStealthService();
3776
+ return service.generateStealthMetaAddress(chain, label);
3777
+ }
3778
+ function generateCosmosStealthAddress(spendingPubKey, viewingPubKey, chain) {
3779
+ const service = new CosmosStealthService();
3780
+ return service.generateStealthAddress(spendingPubKey, viewingPubKey, chain);
3781
+ }
3782
+ function stealthKeyToCosmosAddress(publicKey, prefix) {
3783
+ const service = new CosmosStealthService();
3784
+ return service.stealthKeyToCosmosAddress(publicKey, prefix);
3785
+ }
3786
+ function isValidCosmosAddress(address, expectedChain) {
3787
+ const service = new CosmosStealthService();
3788
+ return service.isValidCosmosAddress(address, expectedChain);
3789
+ }
3790
+
3791
+ // src/cosmos/ibc-stealth.ts
3792
+ var import_utils10 = require("@noble/hashes/utils");
3793
+ var import_secp256k13 = require("@noble/curves/secp256k1");
3794
+ var import_sha2567 = require("@noble/hashes/sha256");
3795
+
3277
3796
  // src/proofs/interface.ts
3278
3797
  var ProofGenerationError = class extends Error {
3279
3798
  proofType;
@@ -3287,8 +3806,8 @@ var ProofGenerationError = class extends Error {
3287
3806
  };
3288
3807
 
3289
3808
  // src/proofs/mock.ts
3290
- var import_sha2566 = require("@noble/hashes/sha256");
3291
- var import_utils7 = require("@noble/hashes/utils");
3809
+ var import_sha2568 = require("@noble/hashes/sha256");
3810
+ var import_utils11 = require("@noble/hashes/utils");
3292
3811
  var MOCK_PROOF_PREFIX = "0x4d4f434b";
3293
3812
  var WARNING_MESSAGE = `
3294
3813
  \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
@@ -3453,22 +3972,22 @@ var MockProofProvider = class {
3453
3972
  { type: proofType, params },
3454
3973
  (_, v) => typeof v === "bigint" ? v.toString() : v
3455
3974
  );
3456
- const hash2 = (0, import_sha2566.sha256)(new TextEncoder().encode(input));
3457
- const random = (0, import_utils7.randomBytes)(16);
3975
+ const hash2 = (0, import_sha2568.sha256)(new TextEncoder().encode(input));
3976
+ const random = (0, import_utils11.randomBytes)(16);
3458
3977
  const combined = new Uint8Array(4 + hash2.length + random.length);
3459
3978
  combined.set(new TextEncoder().encode("MOCK"), 0);
3460
3979
  combined.set(hash2, 4);
3461
3980
  combined.set(random, 4 + hash2.length);
3462
- return `${MOCK_PROOF_PREFIX}${(0, import_utils7.bytesToHex)(combined.slice(4))}`;
3981
+ return `${MOCK_PROOF_PREFIX}${(0, import_utils11.bytesToHex)(combined.slice(4))}`;
3463
3982
  }
3464
3983
  hashToHex(data) {
3465
- const hash2 = (0, import_sha2566.sha256)(new TextEncoder().encode(data));
3466
- return `0x${(0, import_utils7.bytesToHex)(hash2)}`;
3984
+ const hash2 = (0, import_sha2568.sha256)(new TextEncoder().encode(data));
3985
+ return `0x${(0, import_utils11.bytesToHex)(hash2)}`;
3467
3986
  }
3468
3987
  };
3469
3988
 
3470
3989
  // src/proofs/browser-utils.ts
3471
- function hexToBytes5(hex) {
3990
+ function hexToBytes9(hex) {
3472
3991
  const h = hex.startsWith("0x") ? hex.slice(2) : hex;
3473
3992
  if (h.length === 0) return new Uint8Array(0);
3474
3993
  if (h.length % 2 !== 0) {
@@ -3480,7 +3999,7 @@ function hexToBytes5(hex) {
3480
3999
  }
3481
4000
  return bytes;
3482
4001
  }
3483
- function bytesToHex7(bytes) {
4002
+ function bytesToHex11(bytes) {
3484
4003
  return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
3485
4004
  }
3486
4005
  function isBrowser() {
@@ -3522,18 +4041,34 @@ var CHAIN_NUMERIC_IDS = {
3522
4041
  // Non-standard, SIP-specific
3523
4042
  near: 502,
3524
4043
  // Non-standard, SIP-specific
3525
- zcash: 503
4044
+ zcash: 503,
4045
+ // Non-standard, SIP-specific
4046
+ aptos: 504,
4047
+ // Non-standard, SIP-specific
4048
+ sui: 505,
4049
+ // Non-standard, SIP-specific
4050
+ cosmos: 506,
4051
+ // Non-standard, SIP-specific (Cosmos Hub)
4052
+ osmosis: 507,
4053
+ // Non-standard, SIP-specific
4054
+ injective: 508,
4055
+ // Non-standard, SIP-specific
4056
+ celestia: 509,
4057
+ // Non-standard, SIP-specific
4058
+ sei: 510,
4059
+ // Non-standard, SIP-specific
4060
+ dydx: 511
3526
4061
  // Non-standard, SIP-specific
3527
4062
  };
3528
4063
 
3529
4064
  // src/oracle/verification.ts
3530
4065
  var import_ed255192 = require("@noble/curves/ed25519");
3531
- var import_sha2568 = require("@noble/hashes/sha256");
3532
- var import_utils9 = require("@noble/hashes/utils");
4066
+ var import_sha25610 = require("@noble/hashes/sha256");
4067
+ var import_utils13 = require("@noble/hashes/utils");
3533
4068
 
3534
4069
  // src/oracle/serialization.ts
3535
- var import_sha2567 = require("@noble/hashes/sha256");
3536
- var import_utils8 = require("@noble/hashes/utils");
4070
+ var import_sha2569 = require("@noble/hashes/sha256");
4071
+ var import_utils12 = require("@noble/hashes/utils");
3537
4072
  function serializeAttestationMessage(message) {
3538
4073
  const buffer = new Uint8Array(197);
3539
4074
  const view = new DataView(buffer.buffer);
@@ -3576,19 +4111,19 @@ function deserializeAttestationMessage(bytes) {
3576
4111
  const version = bytes[offset++];
3577
4112
  const chainId = view.getUint32(offset, false);
3578
4113
  offset += 4;
3579
- const intentHash = `0x${(0, import_utils8.bytesToHex)(bytes.slice(offset, offset + 32))}`;
4114
+ const intentHash = `0x${(0, import_utils12.bytesToHex)(bytes.slice(offset, offset + 32))}`;
3580
4115
  offset += 32;
3581
- const recipient = `0x${(0, import_utils8.bytesToHex)(bytes.slice(offset, offset + 32))}`;
4116
+ const recipient = `0x${(0, import_utils12.bytesToHex)(bytes.slice(offset, offset + 32))}`;
3582
4117
  offset += 32;
3583
4118
  const amount = bytesToBigint(bytes.slice(offset, offset + 16));
3584
4119
  offset += 16;
3585
- const assetId = `0x${(0, import_utils8.bytesToHex)(bytes.slice(offset, offset + 32))}`;
4120
+ const assetId = `0x${(0, import_utils12.bytesToHex)(bytes.slice(offset, offset + 32))}`;
3586
4121
  offset += 32;
3587
- const txHash = `0x${(0, import_utils8.bytesToHex)(bytes.slice(offset, offset + 32))}`;
4122
+ const txHash = `0x${(0, import_utils12.bytesToHex)(bytes.slice(offset, offset + 32))}`;
3588
4123
  offset += 32;
3589
4124
  const blockNumber = view.getBigUint64(offset, false);
3590
4125
  offset += 8;
3591
- const blockHash = `0x${(0, import_utils8.bytesToHex)(bytes.slice(offset, offset + 32))}`;
4126
+ const blockHash = `0x${(0, import_utils12.bytesToHex)(bytes.slice(offset, offset + 32))}`;
3592
4127
  offset += 32;
3593
4128
  const timestamp = Number(view.getBigUint64(offset, false));
3594
4129
  return {
@@ -3605,12 +4140,12 @@ function deserializeAttestationMessage(bytes) {
3605
4140
  };
3606
4141
  }
3607
4142
  function computeAttestationHash(message) {
3608
- const domain = (0, import_utils8.utf8ToBytes)(ORACLE_DOMAIN);
4143
+ const domain = (0, import_utils12.utf8ToBytes)(ORACLE_DOMAIN);
3609
4144
  const messageBytes = serializeAttestationMessage(message);
3610
4145
  const toHash = new Uint8Array(domain.length + messageBytes.length);
3611
4146
  toHash.set(domain, 0);
3612
4147
  toHash.set(messageBytes, domain.length);
3613
- return (0, import_sha2567.sha256)(toHash);
4148
+ return (0, import_sha2569.sha256)(toHash);
3614
4149
  }
3615
4150
  function getChainNumericId(chain) {
3616
4151
  const id = CHAIN_NUMERIC_IDS[chain];
@@ -3621,7 +4156,7 @@ function getChainNumericId(chain) {
3621
4156
  }
3622
4157
  function normalizeToBytes(hex, length, field) {
3623
4158
  const stripped = hex.startsWith("0x") ? hex.slice(2) : hex;
3624
- const bytes = (0, import_utils8.hexToBytes)(stripped);
4159
+ const bytes = (0, import_utils12.hexToBytes)(stripped);
3625
4160
  if (bytes.length === length) {
3626
4161
  return bytes;
3627
4162
  }
@@ -3654,9 +4189,9 @@ function bytesToBigint(bytes) {
3654
4189
 
3655
4190
  // src/oracle/verification.ts
3656
4191
  function deriveOracleId(publicKey) {
3657
- const keyBytes = typeof publicKey === "string" ? (0, import_utils9.hexToBytes)(publicKey.startsWith("0x") ? publicKey.slice(2) : publicKey) : publicKey;
3658
- const hash2 = (0, import_sha2568.sha256)(keyBytes);
3659
- return `0x${(0, import_utils9.bytesToHex)(hash2)}`;
4192
+ const keyBytes = typeof publicKey === "string" ? (0, import_utils13.hexToBytes)(publicKey.startsWith("0x") ? publicKey.slice(2) : publicKey) : publicKey;
4193
+ const hash2 = (0, import_sha25610.sha256)(keyBytes);
4194
+ return `0x${(0, import_utils13.bytesToHex)(hash2)}`;
3660
4195
  }
3661
4196
  function verifyAttestation(attestation, registry) {
3662
4197
  const { message, signatures } = attestation;
@@ -3686,10 +4221,10 @@ function verifyAttestation(attestation, registry) {
3686
4221
  continue;
3687
4222
  }
3688
4223
  try {
3689
- const publicKeyBytes = (0, import_utils9.hexToBytes)(
4224
+ const publicKeyBytes = (0, import_utils13.hexToBytes)(
3690
4225
  oracle.publicKey.startsWith("0x") ? oracle.publicKey.slice(2) : oracle.publicKey
3691
4226
  );
3692
- const signatureBytes = (0, import_utils9.hexToBytes)(
4227
+ const signatureBytes = (0, import_utils13.hexToBytes)(
3693
4228
  sig.signature.startsWith("0x") ? sig.signature.slice(2) : sig.signature
3694
4229
  );
3695
4230
  const isValid = import_ed255192.ed25519.verify(signatureBytes, messageHash, publicKeyBytes);
@@ -3714,10 +4249,10 @@ function verifyAttestation(attestation, registry) {
3714
4249
  }
3715
4250
  function verifyOracleSignature(signature, messageHash, oracle) {
3716
4251
  try {
3717
- const publicKeyBytes = (0, import_utils9.hexToBytes)(
4252
+ const publicKeyBytes = (0, import_utils13.hexToBytes)(
3718
4253
  oracle.publicKey.startsWith("0x") ? oracle.publicKey.slice(2) : oracle.publicKey
3719
4254
  );
3720
- const signatureBytes = (0, import_utils9.hexToBytes)(
4255
+ const signatureBytes = (0, import_utils13.hexToBytes)(
3721
4256
  signature.signature.startsWith("0x") ? signature.signature.slice(2) : signature.signature
3722
4257
  );
3723
4258
  return import_ed255192.ed25519.verify(signatureBytes, messageHash, publicKeyBytes);
@@ -3731,7 +4266,7 @@ function signAttestationMessage(messageHash, privateKey) {
3731
4266
  const oracleId = deriveOracleId(publicKey);
3732
4267
  return {
3733
4268
  oracleId,
3734
- signature: `0x${(0, import_utils9.bytesToHex)(signature)}`
4269
+ signature: `0x${(0, import_utils13.bytesToHex)(signature)}`
3735
4270
  };
3736
4271
  }
3737
4272
  function createOracleRegistry(config = {}) {
@@ -3783,14 +4318,14 @@ function hasEnoughOracles(registry) {
3783
4318
  }
3784
4319
 
3785
4320
  // src/index.ts
3786
- var import_types37 = require("@sip-protocol/types");
3787
- var import_types38 = require("@sip-protocol/types");
3788
- var import_types39 = require("@sip-protocol/types");
3789
- var import_types40 = require("@sip-protocol/types");
4321
+ var import_types55 = require("@sip-protocol/types");
4322
+ var import_types56 = require("@sip-protocol/types");
4323
+ var import_types57 = require("@sip-protocol/types");
4324
+ var import_types58 = require("@sip-protocol/types");
3790
4325
 
3791
4326
  // src/solver/mock-solver.ts
3792
4327
  var import_types7 = require("@sip-protocol/types");
3793
- var import_utils10 = require("@noble/hashes/utils");
4328
+ var import_utils14 = require("@noble/hashes/utils");
3794
4329
  var MockSolver = class {
3795
4330
  info;
3796
4331
  capabilities;
@@ -3872,7 +4407,7 @@ var MockSolver = class {
3872
4407
  const spreadAmount = baseOutput * BigInt(Math.floor(this.spreadPercent * 1e4)) / 10000n;
3873
4408
  const outputAmount = baseOutput + spreadAmount;
3874
4409
  const feeAmount = outputAmount * BigInt(Math.floor(this.feePercent * 1e4)) / 10000n;
3875
- const quoteId = `quote-${(0, import_utils10.bytesToHex)((0, import_utils10.randomBytes)(8))}`;
4410
+ const quoteId = `quote-${(0, import_utils14.bytesToHex)((0, import_utils14.randomBytes)(8))}`;
3876
4411
  const now = Math.floor(Date.now() / 1e3);
3877
4412
  const quote = {
3878
4413
  quoteId,
@@ -3883,7 +4418,7 @@ var MockSolver = class {
3883
4418
  expiry: now + 60,
3884
4419
  // Quote valid for 1 minute
3885
4420
  fee: feeAmount,
3886
- signature: `0x${(0, import_utils10.bytesToHex)((0, import_utils10.randomBytes)(64))}`,
4421
+ signature: `0x${(0, import_utils14.bytesToHex)((0, import_utils14.randomBytes)(64))}`,
3887
4422
  // Mock signature
3888
4423
  validUntil: now + 60,
3889
4424
  estimatedGas: 200000n
@@ -3920,7 +4455,7 @@ var MockSolver = class {
3920
4455
  error: status.error
3921
4456
  };
3922
4457
  }
3923
- const txHash = `0x${(0, import_utils10.bytesToHex)((0, import_utils10.randomBytes)(32))}`;
4458
+ const txHash = `0x${(0, import_utils14.bytesToHex)((0, import_utils14.randomBytes)(32))}`;
3924
4459
  status.status = "completed";
3925
4460
  status.txHash = txHash;
3926
4461
  return {
@@ -3930,10 +4465,10 @@ var MockSolver = class {
3930
4465
  txHash: intent.privacyLevel === "transparent" ? txHash : void 0,
3931
4466
  fulfillmentProof: {
3932
4467
  type: "fulfillment",
3933
- proof: `0x${(0, import_utils10.bytesToHex)((0, import_utils10.randomBytes)(128))}`,
4468
+ proof: `0x${(0, import_utils14.bytesToHex)((0, import_utils14.randomBytes)(128))}`,
3934
4469
  publicInputs: [
3935
- `0x${(0, import_utils10.bytesToHex)(new TextEncoder().encode(intent.intentId))}`,
3936
- `0x${(0, import_utils10.bytesToHex)(new TextEncoder().encode(quote.quoteId))}`
4470
+ `0x${(0, import_utils14.bytesToHex)(new TextEncoder().encode(intent.intentId))}`,
4471
+ `0x${(0, import_utils14.bytesToHex)(new TextEncoder().encode(quote.quoteId))}`
3937
4472
  ]
3938
4473
  },
3939
4474
  fulfilledAt: Math.floor(Date.now() / 1e3)
@@ -3971,7 +4506,7 @@ function createMockSolver(config) {
3971
4506
  }
3972
4507
 
3973
4508
  // src/index.ts
3974
- var import_types41 = require("@sip-protocol/types");
4509
+ var import_types59 = require("@sip-protocol/types");
3975
4510
 
3976
4511
  // src/settlement/interface.ts
3977
4512
  var SwapStatus = /* @__PURE__ */ ((SwapStatus2) => {
@@ -5077,7 +5612,7 @@ function createZcashNativeBackend(config) {
5077
5612
 
5078
5613
  // src/settlement/backends/direct-chain.ts
5079
5614
  var import_types10 = require("@sip-protocol/types");
5080
- var import_utils11 = require("@noble/hashes/utils");
5615
+ var import_utils15 = require("@noble/hashes/utils");
5081
5616
  var DEFAULT_GAS_FEES = {
5082
5617
  ethereum: 21000n * 50n * 1000000000n,
5083
5618
  // 21k gas * 50 gwei = 0.00105 ETH
@@ -5095,8 +5630,24 @@ var DEFAULT_GAS_FEES = {
5095
5630
  // 21k gas * 0.001 gwei ETH = 21 gwei = 21e6 wei
5096
5631
  base: 2100000000n,
5097
5632
  // 21k gas * 0.1 gwei ETH = 2100 gwei = 2.1e9 wei
5098
- bitcoin: 10000n
5633
+ bitcoin: 10000n,
5099
5634
  // 10000 sats = 0.0001 BTC (estimate for 1 input, 2 outputs)
5635
+ aptos: 100n,
5636
+ // 0.000001 APT in octas (gas units)
5637
+ sui: 1000n,
5638
+ // 0.000001 SUI in MIST
5639
+ cosmos: 5000n,
5640
+ // 0.005 ATOM in uatom
5641
+ osmosis: 5000n,
5642
+ // 0.005 OSMO in uosmo
5643
+ injective: 5000n,
5644
+ // 0.000005 INJ in inj (18 decimals)
5645
+ celestia: 5000n,
5646
+ // 0.005 TIA in utia
5647
+ sei: 5000n,
5648
+ // 0.005 SEI in usei
5649
+ dydx: 5000n
5650
+ // 0.000005 DYDX in dydx (18 decimals)
5100
5651
  };
5101
5652
 
5102
5653
  // src/zcash/rpc-client.ts
@@ -6381,33 +6932,321 @@ function createZcashSwapService(config) {
6381
6932
  var import_types14 = require("@sip-protocol/types");
6382
6933
 
6383
6934
  // src/index.ts
6384
- var import_types42 = require("@sip-protocol/types");
6385
-
6386
- // src/payment/payment.ts
6387
- var import_types15 = require("@sip-protocol/types");
6388
- var import_sha2569 = require("@noble/hashes/sha256");
6389
- var import_utils12 = require("@noble/hashes/utils");
6390
- var import_chacha2 = require("@noble/ciphers/chacha.js");
6391
- var import_hkdf2 = require("@noble/hashes/hkdf");
6935
+ var import_types60 = require("@sip-protocol/types");
6392
6936
 
6393
- // src/payment/stablecoins.ts
6394
- var STABLECOIN_INFO = {
6395
- USDC: {
6396
- symbol: "USDC",
6397
- name: "USD Coin",
6398
- issuer: "Circle",
6399
- type: "fiat-backed",
6400
- description: "Fully-reserved US dollar stablecoin by Circle"
6401
- },
6402
- USDT: {
6403
- symbol: "USDT",
6404
- name: "Tether USD",
6405
- issuer: "Tether",
6406
- type: "fiat-backed",
6407
- description: "Largest stablecoin by market cap"
6408
- },
6409
- DAI: {
6410
- symbol: "DAI",
6937
+ // src/bitcoin/taproot.ts
6938
+ var import_secp256k14 = require("@noble/curves/secp256k1");
6939
+ var import_sha25611 = require("@noble/hashes/sha256");
6940
+ var import_utils16 = require("@noble/hashes/utils");
6941
+ var BECH32_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
6942
+ var BECH32_GENERATOR = [996825010, 642813549, 513874426, 1027748829, 705979059];
6943
+ function taggedHash(tag, data) {
6944
+ const tagHash = (0, import_sha25611.sha256)(new TextEncoder().encode(tag));
6945
+ const taggedData = new Uint8Array(tagHash.length * 2 + data.length);
6946
+ taggedData.set(tagHash, 0);
6947
+ taggedData.set(tagHash, tagHash.length);
6948
+ taggedData.set(data, tagHash.length * 2);
6949
+ return (0, import_sha25611.sha256)(taggedData);
6950
+ }
6951
+ function schnorrSign(message, privateKey, auxRand) {
6952
+ if (message.length !== 32) {
6953
+ throw new ValidationError("message must be 32 bytes", "message");
6954
+ }
6955
+ if (privateKey.length !== 32) {
6956
+ throw new ValidationError("privateKey must be 32 bytes", "privateKey");
6957
+ }
6958
+ if (auxRand && auxRand.length !== 32) {
6959
+ throw new ValidationError("auxRand must be 32 bytes if provided", "auxRand");
6960
+ }
6961
+ return import_secp256k14.schnorr.sign(message, privateKey, auxRand);
6962
+ }
6963
+ function schnorrVerify(signature, message, publicKey) {
6964
+ if (signature.length !== 64) {
6965
+ throw new ValidationError("signature must be 64 bytes", "signature");
6966
+ }
6967
+ if (message.length !== 32) {
6968
+ throw new ValidationError("message must be 32 bytes", "message");
6969
+ }
6970
+ if (publicKey.length !== 32) {
6971
+ throw new ValidationError("publicKey must be 32 bytes (x-only)", "publicKey");
6972
+ }
6973
+ try {
6974
+ return import_secp256k14.schnorr.verify(signature, message, publicKey);
6975
+ } catch {
6976
+ return false;
6977
+ }
6978
+ }
6979
+ function getXOnlyPublicKey(privateKey) {
6980
+ if (privateKey.length !== 32) {
6981
+ throw new ValidationError("privateKey must be 32 bytes", "privateKey");
6982
+ }
6983
+ const publicKey = import_secp256k14.secp256k1.getPublicKey(privateKey, false);
6984
+ return publicKey.slice(1, 33);
6985
+ }
6986
+ function computeTweakedKey(internalKey, merkleRoot) {
6987
+ if (internalKey.length !== 32) {
6988
+ throw new ValidationError("internalKey must be 32 bytes (x-only)", "internalKey");
6989
+ }
6990
+ if (merkleRoot && merkleRoot.length !== 32) {
6991
+ throw new ValidationError("merkleRoot must be 32 bytes if provided", "merkleRoot");
6992
+ }
6993
+ const tweakData = merkleRoot ? new Uint8Array([...internalKey, ...merkleRoot]) : internalKey;
6994
+ const tweak = taggedHash("TapTweak", tweakData);
6995
+ const tweakScalar = BigInt("0x" + (0, import_utils16.bytesToHex)(tweak)) % import_secp256k14.secp256k1.CURVE.n;
6996
+ const internalPoint = import_secp256k14.secp256k1.ProjectivePoint.fromHex(
6997
+ "02" + (0, import_utils16.bytesToHex)(internalKey)
6998
+ );
6999
+ const tweakPoint = import_secp256k14.secp256k1.ProjectivePoint.BASE.multiply(tweakScalar);
7000
+ const tweakedPoint = internalPoint.add(tweakPoint);
7001
+ const tweakedKeyBytes = tweakedPoint.toRawBytes(false);
7002
+ const xOnly = tweakedKeyBytes.slice(1, 33);
7003
+ const yCoord = tweakedKeyBytes.slice(33, 65);
7004
+ const yBigInt = BigInt("0x" + (0, import_utils16.bytesToHex)(yCoord));
7005
+ const parity = Number(yBigInt & 1n);
7006
+ return {
7007
+ tweakedKey: xOnly,
7008
+ parity
7009
+ };
7010
+ }
7011
+ function createTaprootOutput(internalKey, scripts) {
7012
+ if (internalKey.length !== 32) {
7013
+ throw new ValidationError("internalKey must be 32 bytes (x-only)", "internalKey");
7014
+ }
7015
+ let merkleRoot;
7016
+ if (scripts && scripts.length > 0) {
7017
+ if (scripts.length === 1) {
7018
+ const script = scripts[0];
7019
+ const leafData = new Uint8Array([
7020
+ script.leafVersion,
7021
+ script.script.length,
7022
+ ...script.script
7023
+ ]);
7024
+ merkleRoot = taggedHash("TapLeaf", leafData);
7025
+ } else {
7026
+ throw new ValidationError(
7027
+ "Multiple tapscripts not yet implemented - use single script or no scripts",
7028
+ "scripts"
7029
+ );
7030
+ }
7031
+ }
7032
+ const { tweakedKey, parity } = computeTweakedKey(internalKey, merkleRoot);
7033
+ return {
7034
+ tweakedKey: `0x${(0, import_utils16.bytesToHex)(tweakedKey)}`,
7035
+ internalKey: `0x${(0, import_utils16.bytesToHex)(internalKey)}`,
7036
+ merkleRoot: merkleRoot ? `0x${(0, import_utils16.bytesToHex)(merkleRoot)}` : void 0,
7037
+ parity
7038
+ };
7039
+ }
7040
+ function bech32Polymod(values) {
7041
+ let chk = 1;
7042
+ for (const value of values) {
7043
+ const top = chk >> 25;
7044
+ chk = (chk & 33554431) << 5 ^ value;
7045
+ for (let i = 0; i < 5; i++) {
7046
+ if (top >> i & 1) {
7047
+ chk ^= BECH32_GENERATOR[i];
7048
+ }
7049
+ }
7050
+ }
7051
+ return chk;
7052
+ }
7053
+ function bech32HrpExpand(hrp) {
7054
+ const result = [];
7055
+ for (let i = 0; i < hrp.length; i++) {
7056
+ result.push(hrp.charCodeAt(i) >> 5);
7057
+ }
7058
+ result.push(0);
7059
+ for (let i = 0; i < hrp.length; i++) {
7060
+ result.push(hrp.charCodeAt(i) & 31);
7061
+ }
7062
+ return result;
7063
+ }
7064
+ function bech32VerifyChecksum(hrp, data) {
7065
+ return bech32Polymod([...bech32HrpExpand(hrp), ...data]) === 734539939;
7066
+ }
7067
+ function bech32CreateChecksum(hrp, data) {
7068
+ const values = [...bech32HrpExpand(hrp), ...data, 0, 0, 0, 0, 0, 0];
7069
+ const polymod = bech32Polymod(values) ^ 734539939;
7070
+ const checksum = [];
7071
+ for (let i = 0; i < 6; i++) {
7072
+ checksum.push(polymod >> 5 * (5 - i) & 31);
7073
+ }
7074
+ return checksum;
7075
+ }
7076
+ function convertBits(data, fromBits, toBits, pad) {
7077
+ let acc = 0;
7078
+ let bits = 0;
7079
+ const result = [];
7080
+ const maxv = (1 << toBits) - 1;
7081
+ for (const value of data) {
7082
+ if (value < 0 || value >> fromBits !== 0) {
7083
+ return null;
7084
+ }
7085
+ acc = acc << fromBits | value;
7086
+ bits += fromBits;
7087
+ while (bits >= toBits) {
7088
+ bits -= toBits;
7089
+ result.push(acc >> bits & maxv);
7090
+ }
7091
+ }
7092
+ if (pad) {
7093
+ if (bits > 0) {
7094
+ result.push(acc << toBits - bits & maxv);
7095
+ }
7096
+ } else if (bits >= fromBits || acc << toBits - bits & maxv) {
7097
+ return null;
7098
+ }
7099
+ return result;
7100
+ }
7101
+ function taprootAddress(tweakedKey, network = "mainnet") {
7102
+ if (tweakedKey.length !== 32) {
7103
+ throw new ValidationError("tweakedKey must be 32 bytes", "tweakedKey");
7104
+ }
7105
+ const hrp = network === "mainnet" ? "bc" : network === "testnet" ? "tb" : "bcrt";
7106
+ const version = 1;
7107
+ const words = convertBits(tweakedKey, 8, 5, true);
7108
+ if (!words) {
7109
+ throw new ValidationError("Failed to convert tweaked key to bech32 format", "tweakedKey");
7110
+ }
7111
+ const data = [version, ...words];
7112
+ const checksum = bech32CreateChecksum(hrp, data);
7113
+ const combined = [...data, ...checksum];
7114
+ let result = hrp + "1";
7115
+ for (const value of combined) {
7116
+ result += BECH32_CHARSET[value];
7117
+ }
7118
+ return result;
7119
+ }
7120
+ function decodeTaprootAddress(address) {
7121
+ if (typeof address !== "string" || address.length < 14 || address.length > 90) {
7122
+ throw new ValidationError("Invalid Taproot address format", "address");
7123
+ }
7124
+ const addressLower = address.toLowerCase();
7125
+ const sepIndex = addressLower.lastIndexOf("1");
7126
+ if (sepIndex === -1 || sepIndex + 7 > addressLower.length) {
7127
+ throw new ValidationError("Invalid Taproot address: no separator", "address");
7128
+ }
7129
+ const hrp = addressLower.slice(0, sepIndex);
7130
+ const dataStr = addressLower.slice(sepIndex + 1);
7131
+ let network;
7132
+ if (hrp === "bc") {
7133
+ network = "mainnet";
7134
+ } else if (hrp === "tb") {
7135
+ network = "testnet";
7136
+ } else if (hrp === "bcrt") {
7137
+ network = "regtest";
7138
+ } else {
7139
+ throw new ValidationError(`Unknown HRP: ${hrp}`, "address");
7140
+ }
7141
+ const data = [];
7142
+ for (const char of dataStr) {
7143
+ const index = BECH32_CHARSET.indexOf(char);
7144
+ if (index === -1) {
7145
+ throw new ValidationError(`Invalid bech32 character: ${char}`, "address");
7146
+ }
7147
+ data.push(index);
7148
+ }
7149
+ if (!bech32VerifyChecksum(hrp, data)) {
7150
+ throw new ValidationError("Invalid Taproot address checksum", "address");
7151
+ }
7152
+ const version = data[0];
7153
+ if (version !== 1) {
7154
+ throw new ValidationError(`Expected witness version 1 (Taproot), got ${version}`, "address");
7155
+ }
7156
+ const program = convertBits(new Uint8Array(data.slice(1, -6)), 5, 8, false);
7157
+ if (!program || program.length !== 32) {
7158
+ throw new ValidationError("Invalid Taproot program length", "address");
7159
+ }
7160
+ return {
7161
+ tweakedKey: new Uint8Array(program),
7162
+ network
7163
+ };
7164
+ }
7165
+ function createKeySpendOnlyOutput(privateKey, network = "mainnet") {
7166
+ if (!isValidPrivateKey(privateKey)) {
7167
+ throw new ValidationError("privateKey must be a valid 32-byte hex string", "privateKey");
7168
+ }
7169
+ const privKeyBytes = (0, import_utils16.hexToBytes)(privateKey.slice(2));
7170
+ const internalKey = getXOnlyPublicKey(privKeyBytes);
7171
+ const output = createTaprootOutput(internalKey);
7172
+ const tweakedKeyBytes = (0, import_utils16.hexToBytes)(output.tweakedKey.slice(2));
7173
+ const address = taprootAddress(tweakedKeyBytes, network);
7174
+ return {
7175
+ output,
7176
+ address,
7177
+ internalPrivateKey: privateKey
7178
+ };
7179
+ }
7180
+ function isValidTaprootAddress(address) {
7181
+ try {
7182
+ decodeTaprootAddress(address);
7183
+ return true;
7184
+ } catch {
7185
+ return false;
7186
+ }
7187
+ }
7188
+ function schnorrSignHex(message, privateKey, auxRand) {
7189
+ if (!isValidHex(message)) {
7190
+ throw new ValidationError("message must be a hex string", "message");
7191
+ }
7192
+ if (!isValidPrivateKey(privateKey)) {
7193
+ throw new ValidationError("privateKey must be a valid 32-byte hex string", "privateKey");
7194
+ }
7195
+ if (auxRand && !isValidHex(auxRand)) {
7196
+ throw new ValidationError("auxRand must be a hex string", "auxRand");
7197
+ }
7198
+ const messageBytes = (0, import_utils16.hexToBytes)(message.slice(2));
7199
+ const privateKeyBytes = (0, import_utils16.hexToBytes)(privateKey.slice(2));
7200
+ const auxRandBytes = auxRand ? (0, import_utils16.hexToBytes)(auxRand.slice(2)) : void 0;
7201
+ const signature = schnorrSign(messageBytes, privateKeyBytes, auxRandBytes);
7202
+ return `0x${(0, import_utils16.bytesToHex)(signature)}`;
7203
+ }
7204
+ function schnorrVerifyHex(signature, message, publicKey) {
7205
+ if (!isValidHex(signature)) {
7206
+ throw new ValidationError("signature must be a hex string", "signature");
7207
+ }
7208
+ if (!isValidHex(message)) {
7209
+ throw new ValidationError("message must be a hex string", "message");
7210
+ }
7211
+ if (!isValidHex(publicKey)) {
7212
+ throw new ValidationError("publicKey must be a hex string", "publicKey");
7213
+ }
7214
+ const signatureBytes = (0, import_utils16.hexToBytes)(signature.slice(2));
7215
+ const messageBytes = (0, import_utils16.hexToBytes)(message.slice(2));
7216
+ const publicKeyBytes = (0, import_utils16.hexToBytes)(publicKey.slice(2));
7217
+ return schnorrVerify(signatureBytes, messageBytes, publicKeyBytes);
7218
+ }
7219
+
7220
+ // src/bitcoin/silent-payments.ts
7221
+ var import_secp256k15 = require("@noble/curves/secp256k1");
7222
+ var import_sha25612 = require("@noble/hashes/sha256");
7223
+ var import_utils17 = require("@noble/hashes/utils");
7224
+
7225
+ // src/payment/payment.ts
7226
+ var import_types15 = require("@sip-protocol/types");
7227
+ var import_sha25613 = require("@noble/hashes/sha256");
7228
+ var import_utils18 = require("@noble/hashes/utils");
7229
+ var import_chacha2 = require("@noble/ciphers/chacha.js");
7230
+ var import_hkdf2 = require("@noble/hashes/hkdf");
7231
+
7232
+ // src/payment/stablecoins.ts
7233
+ var STABLECOIN_INFO = {
7234
+ USDC: {
7235
+ symbol: "USDC",
7236
+ name: "USD Coin",
7237
+ issuer: "Circle",
7238
+ type: "fiat-backed",
7239
+ description: "Fully-reserved US dollar stablecoin by Circle"
7240
+ },
7241
+ USDT: {
7242
+ symbol: "USDT",
7243
+ name: "Tether USD",
7244
+ issuer: "Tether",
7245
+ type: "fiat-backed",
7246
+ description: "Largest stablecoin by market cap"
7247
+ },
7248
+ DAI: {
7249
+ symbol: "DAI",
6411
7250
  name: "Dai Stablecoin",
6412
7251
  issuer: "MakerDAO",
6413
7252
  type: "crypto-backed",
@@ -6882,8 +7721,8 @@ async function createShieldedPayment(params, options) {
6882
7721
  let viewingKeyHash;
6883
7722
  if (viewingKey) {
6884
7723
  const keyHex = viewingKey.startsWith("0x") ? viewingKey.slice(2) : viewingKey;
6885
- const keyBytes = (0, import_utils12.hexToBytes)(keyHex);
6886
- viewingKeyHash = `0x${(0, import_utils12.bytesToHex)((0, import_sha2569.sha256)(keyBytes))}`;
7724
+ const keyBytes = (0, import_utils18.hexToBytes)(keyHex);
7725
+ viewingKeyHash = `0x${(0, import_utils18.bytesToHex)((0, import_sha25613.sha256)(keyBytes))}`;
6887
7726
  }
6888
7727
  const privacyConfig = getPrivacyConfig(
6889
7728
  privacy,
@@ -6923,7 +7762,7 @@ async function createShieldedPayment(params, options) {
6923
7762
  if (privacy !== import_types15.PrivacyLevel.TRANSPARENT && proofProvider?.isReady) {
6924
7763
  const hexToUint8 = (hex) => {
6925
7764
  const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
6926
- return (0, import_utils12.hexToBytes)(cleanHex);
7765
+ return (0, import_utils18.hexToBytes)(cleanHex);
6927
7766
  };
6928
7767
  const fundingResult = await proofProvider.generateFundingProof({
6929
7768
  balance: amount,
@@ -6950,17 +7789,17 @@ async function createShieldedPayment(params, options) {
6950
7789
  }
6951
7790
  function encryptMemo(memo, viewingKey) {
6952
7791
  const keyHex = viewingKey.startsWith("0x") ? viewingKey.slice(2) : viewingKey;
6953
- const keyBytes = (0, import_utils12.hexToBytes)(keyHex);
6954
- const encKey = (0, import_hkdf2.hkdf)(import_sha2569.sha256, keyBytes, new Uint8Array(0), new Uint8Array(0), 32);
7792
+ const keyBytes = (0, import_utils18.hexToBytes)(keyHex);
7793
+ const encKey = (0, import_hkdf2.hkdf)(import_sha25613.sha256, keyBytes, new Uint8Array(0), new Uint8Array(0), 32);
6955
7794
  try {
6956
- const nonce = (0, import_utils12.randomBytes)(24);
7795
+ const nonce = (0, import_utils18.randomBytes)(24);
6957
7796
  const cipher = (0, import_chacha2.xchacha20poly1305)(encKey, nonce);
6958
7797
  const plaintext = new TextEncoder().encode(memo);
6959
7798
  const ciphertext = cipher.encrypt(plaintext);
6960
7799
  const result = new Uint8Array(nonce.length + ciphertext.length);
6961
7800
  result.set(nonce);
6962
7801
  result.set(ciphertext, nonce.length);
6963
- return `0x${(0, import_utils12.bytesToHex)(result)}`;
7802
+ return `0x${(0, import_utils18.bytesToHex)(result)}`;
6964
7803
  } finally {
6965
7804
  secureWipe(keyBytes);
6966
7805
  secureWipe(encKey);
@@ -6968,11 +7807,11 @@ function encryptMemo(memo, viewingKey) {
6968
7807
  }
6969
7808
  function decryptMemo(encryptedMemo, viewingKey) {
6970
7809
  const keyHex = viewingKey.startsWith("0x") ? viewingKey.slice(2) : viewingKey;
6971
- const keyBytes = (0, import_utils12.hexToBytes)(keyHex);
6972
- const encKey = (0, import_hkdf2.hkdf)(import_sha2569.sha256, keyBytes, new Uint8Array(0), new Uint8Array(0), 32);
7810
+ const keyBytes = (0, import_utils18.hexToBytes)(keyHex);
7811
+ const encKey = (0, import_hkdf2.hkdf)(import_sha25613.sha256, keyBytes, new Uint8Array(0), new Uint8Array(0), 32);
6973
7812
  try {
6974
7813
  const dataHex = encryptedMemo.startsWith("0x") ? encryptedMemo.slice(2) : encryptedMemo;
6975
- const data = (0, import_utils12.hexToBytes)(dataHex);
7814
+ const data = (0, import_utils18.hexToBytes)(dataHex);
6976
7815
  const nonce = data.slice(0, 24);
6977
7816
  const ciphertext = data.slice(24);
6978
7817
  const cipher = (0, import_chacha2.xchacha20poly1305)(encKey, nonce);
@@ -7020,9 +7859,9 @@ function getPaymentSummary(payment) {
7020
7859
 
7021
7860
  // src/treasury/treasury.ts
7022
7861
  var import_types16 = require("@sip-protocol/types");
7023
- var import_secp256k13 = require("@noble/curves/secp256k1");
7024
- var import_sha25610 = require("@noble/hashes/sha256");
7025
- var import_utils13 = require("@noble/hashes/utils");
7862
+ var import_secp256k16 = require("@noble/curves/secp256k1");
7863
+ var import_sha25614 = require("@noble/hashes/sha256");
7864
+ var import_utils19 = require("@noble/hashes/utils");
7026
7865
  var DEFAULT_PROPOSAL_TTL = 7 * 24 * 60 * 60;
7027
7866
  var Treasury = class _Treasury {
7028
7867
  config;
@@ -7513,12 +8352,12 @@ var Treasury = class _Treasury {
7513
8352
  }
7514
8353
  };
7515
8354
  function generateTreasuryId() {
7516
- const bytes = (0, import_utils13.randomBytes)(16);
7517
- return `treasury_${(0, import_utils13.bytesToHex)(bytes)}`;
8355
+ const bytes = (0, import_utils19.randomBytes)(16);
8356
+ return `treasury_${(0, import_utils19.bytesToHex)(bytes)}`;
7518
8357
  }
7519
8358
  function generateProposalId() {
7520
- const bytes = (0, import_utils13.randomBytes)(16);
7521
- return `prop_${(0, import_utils13.bytesToHex)(bytes)}`;
8359
+ const bytes = (0, import_utils19.randomBytes)(16);
8360
+ return `prop_${(0, import_utils19.bytesToHex)(bytes)}`;
7522
8361
  }
7523
8362
  function computeProposalHash(proposal) {
7524
8363
  const data = JSON.stringify({
@@ -7530,13 +8369,13 @@ function computeProposalHash(proposal) {
7530
8369
  createdAt: proposal.createdAt,
7531
8370
  expiresAt: proposal.expiresAt
7532
8371
  }, (_, value) => typeof value === "bigint" ? value.toString() : value);
7533
- return (0, import_sha25610.sha256)(new TextEncoder().encode(data));
8372
+ return (0, import_sha25614.sha256)(new TextEncoder().encode(data));
7534
8373
  }
7535
8374
  function signMessage(messageHash, privateKey) {
7536
8375
  const keyHex = privateKey.startsWith("0x") ? privateKey.slice(2) : privateKey;
7537
- const keyBytes = (0, import_utils13.hexToBytes)(keyHex);
8376
+ const keyBytes = (0, import_utils19.hexToBytes)(keyHex);
7538
8377
  try {
7539
- const signature = import_secp256k13.secp256k1.sign(messageHash, keyBytes);
8378
+ const signature = import_secp256k16.secp256k1.sign(messageHash, keyBytes);
7540
8379
  return `0x${signature.toCompactHex()}`;
7541
8380
  } finally {
7542
8381
  secureWipe(keyBytes);
@@ -7546,9 +8385,9 @@ function verifySignature(messageHash, signature, publicKey) {
7546
8385
  const sigHex = signature.startsWith("0x") ? signature.slice(2) : signature;
7547
8386
  const pubKeyHex = publicKey.startsWith("0x") ? publicKey.slice(2) : publicKey;
7548
8387
  try {
7549
- const sigBytes = (0, import_utils13.hexToBytes)(sigHex);
7550
- const pubKeyBytes = (0, import_utils13.hexToBytes)(pubKeyHex);
7551
- return import_secp256k13.secp256k1.verify(sigBytes, messageHash, pubKeyBytes);
8388
+ const sigBytes = (0, import_utils19.hexToBytes)(sigHex);
8389
+ const pubKeyBytes = (0, import_utils19.hexToBytes)(pubKeyHex);
8390
+ return import_secp256k16.secp256k1.verify(sigBytes, messageHash, pubKeyBytes);
7552
8391
  } catch {
7553
8392
  return false;
7554
8393
  }
@@ -7706,7 +8545,7 @@ function validateBatchProposalParams(params, config) {
7706
8545
 
7707
8546
  // src/compliance/compliance-manager.ts
7708
8547
  var import_types17 = require("@sip-protocol/types");
7709
- var import_utils14 = require("@noble/hashes/utils");
8548
+ var import_utils20 = require("@noble/hashes/utils");
7710
8549
  var DEFAULTS2 = {
7711
8550
  riskThreshold: 70,
7712
8551
  highValueThreshold: 10000000000n,
@@ -8127,6 +8966,79 @@ var ComplianceManager = class _ComplianceManager {
8127
8966
  getAllReports() {
8128
8967
  return Array.from(this.reports.values());
8129
8968
  }
8969
+ // ─── Dashboard Data API ──────────────────────────────────────────────────────
8970
+ /**
8971
+ * Get list of auditors for dashboard UI
8972
+ *
8973
+ * Returns a simplified view of auditors with essential info.
8974
+ * Alias for getAllAuditors() but returns AuditorRegistration directly.
8975
+ *
8976
+ * @returns Array of auditor registrations
8977
+ */
8978
+ getAuditorList() {
8979
+ return this.getAllAuditors();
8980
+ }
8981
+ /**
8982
+ * Get pending disclosure requests for dashboard
8983
+ *
8984
+ * Returns disclosure requests waiting for approval/denial.
8985
+ * This is for disclosure REQUESTS, not disclosed transactions.
8986
+ *
8987
+ * @returns Array of pending disclosure requests
8988
+ */
8989
+ getPendingDisclosures() {
8990
+ return this.getPendingRequests();
8991
+ }
8992
+ /**
8993
+ * Get disclosure history for a specific auditor
8994
+ *
8995
+ * Returns all disclosed transactions that were shared with this auditor,
8996
+ * sorted by disclosure date (most recent first).
8997
+ *
8998
+ * @param auditorId - Auditor ID to get history for
8999
+ * @returns Array of disclosed transactions for this auditor
9000
+ */
9001
+ getDisclosureHistory(auditorId) {
9002
+ return this.getDisclosedTransactions(auditorId).sort((a, b) => b.disclosedAt - a.disclosedAt);
9003
+ }
9004
+ /**
9005
+ * Get compliance metrics for dashboard
9006
+ *
9007
+ * Calculates key compliance metrics including:
9008
+ * - Total auditors (active + inactive)
9009
+ * - Total disclosures made
9010
+ * - Pending disclosure requests
9011
+ * - Approval rate (approved / total resolved requests)
9012
+ * - Average processing time for disclosure requests
9013
+ *
9014
+ * @returns Compliance metrics object
9015
+ */
9016
+ getComplianceMetrics() {
9017
+ const allAuditors = this.getAllAuditors();
9018
+ const allDisclosures = this.getDisclosedTransactions();
9019
+ const pendingRequests = this.getPendingRequests();
9020
+ const allRequests = Array.from(this.disclosureRequests.values());
9021
+ const resolvedRequests = allRequests.filter((r) => r.status !== "pending");
9022
+ const approvedRequests = resolvedRequests.filter((r) => r.status === "approved");
9023
+ const approvalRate = resolvedRequests.length > 0 ? approvedRequests.length / resolvedRequests.length : 0;
9024
+ let averageProcessingTime;
9025
+ if (resolvedRequests.length > 0) {
9026
+ const totalProcessingTime = resolvedRequests.reduce((sum, req) => {
9027
+ if (req.resolvedAt) {
9028
+ return sum + (req.resolvedAt - req.requestedAt);
9029
+ }
9030
+ return sum;
9031
+ }, 0);
9032
+ averageProcessingTime = totalProcessingTime / resolvedRequests.length;
9033
+ }
9034
+ return {
9035
+ totalAuditors: allAuditors.length,
9036
+ totalDisclosures: allDisclosures.length,
9037
+ pendingDisclosures: pendingRequests.length,
9038
+ approvalRate,
9039
+ averageProcessingTime
9040
+ };
9041
+ }
8130
9042
  // ─── Audit Log ───────────────────────────────────────────────────────────────
8131
9043
  /**
8132
9044
  * Get audit log entries
@@ -8325,147 +9237,1767 @@ var ComplianceManager = class _ComplianceManager {
8325
9237
  highRisk,
8326
9238
  flaggedTransactions: flagged
8327
9239
  }
8328
- };
8329
- if (includeTransactions) {
8330
- data.transactions = transactions;
9240
+ };
9241
+ if (includeTransactions) {
9242
+ data.transactions = transactions;
9243
+ }
9244
+ return data;
9245
+ }
9246
+ generateCSV(transactions) {
9247
+ const headers = [
9248
+ "Transaction ID",
9249
+ "Disclosure ID",
9250
+ "Type",
9251
+ "Direction",
9252
+ "Token",
9253
+ "Amount",
9254
+ "Sender",
9255
+ "Recipient",
9256
+ "Chain",
9257
+ "Privacy Level",
9258
+ "Timestamp",
9259
+ "TX Hash",
9260
+ "Block",
9261
+ "Risk Score",
9262
+ "Purpose",
9263
+ "Memo"
9264
+ ];
9265
+ const rows = transactions.map((tx) => [
9266
+ tx.transactionId,
9267
+ tx.disclosureId,
9268
+ tx.type,
9269
+ tx.direction,
9270
+ tx.token.symbol,
9271
+ tx.amount.toString(),
9272
+ tx.sender,
9273
+ tx.recipient,
9274
+ tx.chain,
9275
+ tx.privacyLevel,
9276
+ new Date(tx.timestamp * 1e3).toISOString(),
9277
+ tx.txHash,
9278
+ tx.blockNumber.toString(),
9279
+ tx.riskScore?.toString() ?? "",
9280
+ tx.purpose ?? "",
9281
+ tx.memo ?? ""
9282
+ ]);
9283
+ const escapeForCSV = (val) => {
9284
+ let escaped = val;
9285
+ if (/^[=+\-@|\t]/.test(escaped)) {
9286
+ escaped = `'${escaped}`;
9287
+ }
9288
+ return `"${escaped.replace(/"/g, '""')}"`;
9289
+ };
9290
+ const csvRows = [headers, ...rows].map((row) => row.map(escapeForCSV).join(","));
9291
+ return csvRows.join("\n");
9292
+ }
9293
+ };
9294
+ function generateId(prefix) {
9295
+ return `${prefix}_${(0, import_utils20.bytesToHex)((0, import_utils20.randomBytes)(12))}`;
9296
+ }
9297
+ function validateRegisterAuditorParams(params) {
9298
+ if (!params.organization?.trim()) {
9299
+ throw new ValidationError(
9300
+ "organization is required",
9301
+ "organization",
9302
+ void 0,
9303
+ "SIP_2008" /* MISSING_REQUIRED */
9304
+ );
9305
+ }
9306
+ if (!params.contactName?.trim()) {
9307
+ throw new ValidationError(
9308
+ "contact name is required",
9309
+ "contactName",
9310
+ void 0,
9311
+ "SIP_2008" /* MISSING_REQUIRED */
9312
+ );
9313
+ }
9314
+ if (!params.contactEmail?.trim()) {
9315
+ throw new ValidationError(
9316
+ "contact email is required",
9317
+ "contactEmail",
9318
+ void 0,
9319
+ "SIP_2008" /* MISSING_REQUIRED */
9320
+ );
9321
+ }
9322
+ if (!params.publicKey?.trim()) {
9323
+ throw new ValidationError(
9324
+ "public key is required",
9325
+ "publicKey",
9326
+ void 0,
9327
+ "SIP_2008" /* MISSING_REQUIRED */
9328
+ );
9329
+ }
9330
+ if (!params.scope) {
9331
+ throw new ValidationError(
9332
+ "audit scope is required",
9333
+ "scope",
9334
+ void 0,
9335
+ "SIP_2008" /* MISSING_REQUIRED */
9336
+ );
9337
+ }
9338
+ }
9339
+ function validateReportParams(params) {
9340
+ if (!params.title?.trim()) {
9341
+ throw new ValidationError(
9342
+ "report title is required",
9343
+ "title",
9344
+ void 0,
9345
+ "SIP_2008" /* MISSING_REQUIRED */
9346
+ );
9347
+ }
9348
+ if (!params.type) {
9349
+ throw new ValidationError(
9350
+ "report type is required",
9351
+ "type",
9352
+ void 0,
9353
+ "SIP_2008" /* MISSING_REQUIRED */
9354
+ );
9355
+ }
9356
+ if (!params.format) {
9357
+ throw new ValidationError(
9358
+ "report format is required",
9359
+ "format",
9360
+ void 0,
9361
+ "SIP_2008" /* MISSING_REQUIRED */
9362
+ );
9363
+ }
9364
+ if (params.startDate === void 0 || params.startDate === null || params.endDate === void 0 || params.endDate === null) {
9365
+ throw new ValidationError(
9366
+ "date range is required",
9367
+ "dateRange",
9368
+ void 0,
9369
+ "SIP_2008" /* MISSING_REQUIRED */
9370
+ );
9371
+ }
9372
+ if (params.startDate >= params.endDate) {
9373
+ throw new ValidationError(
9374
+ "start date must be before end date",
9375
+ "dateRange",
9376
+ void 0,
9377
+ "SIP_2001" /* INVALID_INPUT */
9378
+ );
9379
+ }
9380
+ }
9381
+
9382
+ // src/compliance/reports.ts
9383
+ var import_sha25615 = require("@noble/hashes/sha256");
9384
+ var import_utils21 = require("@noble/hashes/utils");
9385
+
9386
+ // src/compliance/pdf.ts
9387
+ function generatePdfReport(report, options = {}) {
9388
+ const {
9389
+ title = "SIP Protocol Audit Report",
9390
+ organization = "",
9391
+ includeTransactions = true,
9392
+ maxTransactions = 100
9393
+ } = options;
9394
+ const content = buildPdfContent(report, {
9395
+ title,
9396
+ organization,
9397
+ includeTransactions,
9398
+ maxTransactions
9399
+ });
9400
+ return generatePdfBinary(content, title);
9401
+ }
9402
+ function buildPdfContent(report, options) {
9403
+ const lines = [];
9404
+ lines.push(options.title);
9405
+ if (options.organization && options.organization.trim() !== "") {
9406
+ lines.push(`Organization: ${options.organization}`);
9407
+ }
9408
+ lines.push(`Report ID: ${report.reportId}`);
9409
+ lines.push(
9410
+ `Generated: ${report.generatedAt.toISOString().replace("T", " ").slice(0, 19)} UTC`
9411
+ );
9412
+ lines.push("");
9413
+ lines.push("Report Period");
9414
+ lines.push(` Start: ${formatDate(report.period.start)}`);
9415
+ lines.push(` End: ${formatDate(report.period.end)}`);
9416
+ lines.push("");
9417
+ lines.push("Summary Statistics");
9418
+ lines.push(` Total Transactions: ${report.summary.transactionCount}`);
9419
+ lines.push(
9420
+ ` Total Volume: ${formatBigInt(report.summary.totalVolume)}`
9421
+ );
9422
+ lines.push(
9423
+ ` Unique Counterparties: ${report.summary.uniqueCounterparties}`
9424
+ );
9425
+ lines.push("");
9426
+ if (options.includeTransactions && report.transactions.length > 0) {
9427
+ lines.push("Transaction Details");
9428
+ lines.push("");
9429
+ const txToShow = Math.min(
9430
+ report.transactions.length,
9431
+ options.maxTransactions
9432
+ );
9433
+ for (let i = 0; i < txToShow; i++) {
9434
+ const tx = report.transactions[i];
9435
+ lines.push(`Transaction ${i + 1}/${report.transactions.length}`);
9436
+ lines.push(` ID: ${tx.id}`);
9437
+ lines.push(` Sender: ${truncateAddress(tx.sender)}`);
9438
+ lines.push(` Recipient: ${truncateAddress(tx.recipient)}`);
9439
+ lines.push(` Amount: ${formatAmount(tx.amount)}`);
9440
+ lines.push(
9441
+ ` Timestamp: ${formatTimestamp(tx.timestamp)}`
9442
+ );
9443
+ if (tx.txHash) {
9444
+ lines.push(` Tx Hash: ${truncateHash(tx.txHash)}`);
9445
+ }
9446
+ if (tx.metadata && Object.keys(tx.metadata).length > 0) {
9447
+ lines.push(` Metadata: ${JSON.stringify(tx.metadata)}`);
9448
+ }
9449
+ lines.push("");
9450
+ }
9451
+ if (report.transactions.length > options.maxTransactions) {
9452
+ lines.push(
9453
+ `... and ${report.transactions.length - options.maxTransactions} more transactions`
9454
+ );
9455
+ lines.push("");
9456
+ }
9457
+ }
9458
+ lines.push("---");
9459
+ lines.push(
9460
+ "This report was generated by SIP Protocol compliance tools."
9461
+ );
9462
+ lines.push("For verification, please contact your compliance officer.");
9463
+ return lines.join("\n");
9464
+ }
9465
+ function generatePdfBinary(content, title) {
9466
+ const objects = [];
9467
+ objects.push(
9468
+ "1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj"
9469
+ );
9470
+ objects.push(
9471
+ "2 0 obj\n<< /Type /Pages /Kids [3 0 R] /Count 1 >>\nendobj"
9472
+ );
9473
+ objects.push(
9474
+ "3 0 obj\n<< /Type /Page /Parent 2 0 R /Resources 4 0 R /MediaBox [0 0 612 792] /Contents 5 0 R >>\nendobj"
9475
+ );
9476
+ objects.push(
9477
+ "4 0 obj\n<< /Font << /F1 << /Type /Font /Subtype /Type1 /BaseFont /Courier >> >> >>\nendobj"
9478
+ );
9479
+ const contentStream = buildContentStream(content);
9480
+ objects.push(
9481
+ `5 0 obj
9482
+ << /Length ${contentStream.length} >>
9483
+ stream
9484
+ ${contentStream}
9485
+ endstream
9486
+ endobj`
9487
+ );
9488
+ const now = /* @__PURE__ */ new Date();
9489
+ const pdfDate = formatPdfDate(now);
9490
+ objects.push(
9491
+ `6 0 obj
9492
+ << /Title (${title}) /Author (SIP Protocol) /Creator (SIP SDK) /CreationDate (${pdfDate}) >>
9493
+ endobj`
9494
+ );
9495
+ const pdfParts = [];
9496
+ pdfParts.push("%PDF-1.4\n%\xE2\xE3\xCF\xD3\n");
9497
+ const xrefOffsets = [0];
9498
+ let currentOffset = pdfParts.join("").length;
9499
+ for (const obj of objects) {
9500
+ xrefOffsets.push(currentOffset);
9501
+ pdfParts.push(obj + "\n");
9502
+ currentOffset = pdfParts.join("").length;
9503
+ }
9504
+ const xrefStart = currentOffset;
9505
+ pdfParts.push("xref\n");
9506
+ pdfParts.push(`0 ${xrefOffsets.length}
9507
+ `);
9508
+ for (let i = 0; i < xrefOffsets.length; i++) {
9509
+ if (i === 0) {
9510
+ pdfParts.push("0000000000 65535 f \n");
9511
+ } else {
9512
+ const offset = String(xrefOffsets[i]).padStart(10, "0");
9513
+ pdfParts.push(`${offset} 00000 n
9514
+ `);
9515
+ }
9516
+ }
9517
+ pdfParts.push("trailer\n");
9518
+ pdfParts.push(
9519
+ `<< /Size ${xrefOffsets.length} /Root 1 0 R /Info 6 0 R >>
9520
+ `
9521
+ );
9522
+ pdfParts.push("startxref\n");
9523
+ pdfParts.push(`${xrefStart}
9524
+ `);
9525
+ pdfParts.push("%%EOF");
9526
+ const pdfString = pdfParts.join("");
9527
+ const encoder = new TextEncoder();
9528
+ return encoder.encode(pdfString);
9529
+ }
9530
+ function buildContentStream(text) {
9531
+ const lines = text.split("\n");
9532
+ const commands = [];
9533
+ commands.push("BT");
9534
+ commands.push("/F1 10 Tf");
9535
+ commands.push("12 TL");
9536
+ let y = 742;
9537
+ for (const line of lines) {
9538
+ commands.push(`50 ${y} Td`);
9539
+ const escaped = escapePdfString(line);
9540
+ commands.push(`(${escaped}) Tj`);
9541
+ y -= 12;
9542
+ if (y < 50) {
9543
+ break;
9544
+ }
9545
+ }
9546
+ commands.push("ET");
9547
+ return commands.join("\n");
9548
+ }
9549
+ function escapePdfString(str) {
9550
+ return str.replace(/\\/g, "\\\\").replace(/\(/g, "\\(").replace(/\)/g, "\\)").replace(/\r/g, "\\r").replace(/\n/g, "\\n");
9551
+ }
9552
+ function formatPdfDate(date) {
9553
+ const year = date.getUTCFullYear();
9554
+ const month = String(date.getUTCMonth() + 1).padStart(2, "0");
9555
+ const day = String(date.getUTCDate()).padStart(2, "0");
9556
+ const hour = String(date.getUTCHours()).padStart(2, "0");
9557
+ const minute = String(date.getUTCMinutes()).padStart(2, "0");
9558
+ const second = String(date.getUTCSeconds()).padStart(2, "0");
9559
+ return `D:${year}${month}${day}${hour}${minute}${second}Z`;
9560
+ }
9561
+ function formatDate(date) {
9562
+ return date.toISOString().split("T")[0];
9563
+ }
9564
+ function formatBigInt(value) {
9565
+ return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
9566
+ }
9567
+ function formatAmount(amount) {
9568
+ try {
9569
+ const num = BigInt(amount);
9570
+ return formatBigInt(num);
9571
+ } catch {
9572
+ return amount;
9573
+ }
9574
+ }
9575
+ function formatTimestamp(timestamp) {
9576
+ const date = new Date(timestamp * 1e3);
9577
+ return date.toISOString().replace("T", " ").slice(0, 19) + " UTC";
9578
+ }
9579
+ function truncateAddress(address) {
9580
+ if (address.length <= 12) {
9581
+ return address;
9582
+ }
9583
+ return `${address.slice(0, 6)}...${address.slice(-4)}`;
9584
+ }
9585
+ function truncateHash(hash2) {
9586
+ if (hash2.length <= 16) {
9587
+ return hash2;
9588
+ }
9589
+ return `${hash2.slice(0, 8)}...${hash2.slice(-8)}`;
9590
+ }
9591
+
9592
+ // src/compliance/reports.ts
9593
+ var ComplianceReporter = class {
9594
+ /**
9595
+ * Generate an audit report from encrypted transactions
9596
+ *
9597
+ * Decrypts transactions using the provided viewing key, filters by date range,
9598
+ * and generates a comprehensive report with summary statistics.
9599
+ *
9600
+ * @param params - Report generation parameters
9601
+ * @returns Audit report with decrypted transactions and statistics
9602
+ * @throws {ValidationError} If parameters are invalid
9603
+ * @throws {CryptoError} If decryption fails
9604
+ */
9605
+ async generateAuditReport(params) {
9606
+ this.validateParams(params);
9607
+ const viewingKey = this.normalizeViewingKey(params.viewingKey);
9608
+ const decryptedTransactions = this.decryptTransactions(
9609
+ params.transactions,
9610
+ viewingKey,
9611
+ params.startDate,
9612
+ params.endDate
9613
+ );
9614
+ const summary = this.calculateSummary(decryptedTransactions);
9615
+ const period = this.determinePeriod(
9616
+ decryptedTransactions,
9617
+ params.startDate,
9618
+ params.endDate
9619
+ );
9620
+ const reportId = `audit_${generateRandomBytes(16).slice(2)}`;
9621
+ return {
9622
+ reportId,
9623
+ generatedAt: /* @__PURE__ */ new Date(),
9624
+ period,
9625
+ transactions: decryptedTransactions,
9626
+ summary
9627
+ };
9628
+ }
9629
+ /**
9630
+ * Validate report generation parameters
9631
+ */
9632
+ validateParams(params) {
9633
+ if (!params.viewingKey) {
9634
+ throw new ValidationError(
9635
+ "viewingKey is required",
9636
+ "viewingKey",
9637
+ void 0,
9638
+ "SIP_2008" /* MISSING_REQUIRED */
9639
+ );
9640
+ }
9641
+ if (!params.transactions) {
9642
+ throw new ValidationError(
9643
+ "transactions array is required",
9644
+ "transactions",
9645
+ void 0,
9646
+ "SIP_2008" /* MISSING_REQUIRED */
9647
+ );
9648
+ }
9649
+ if (!Array.isArray(params.transactions)) {
9650
+ throw new ValidationError(
9651
+ "transactions must be an array",
9652
+ "transactions",
9653
+ { received: typeof params.transactions },
9654
+ "SIP_2001" /* INVALID_INPUT */
9655
+ );
9656
+ }
9657
+ if (params.format !== "json" && params.format !== "pdf") {
9658
+ throw new ValidationError(
9659
+ "only JSON and PDF formats are supported",
9660
+ "format",
9661
+ { received: params.format },
9662
+ "SIP_2001" /* INVALID_INPUT */
9663
+ );
9664
+ }
9665
+ if (params.startDate && params.endDate) {
9666
+ if (params.startDate > params.endDate) {
9667
+ throw new ValidationError(
9668
+ "startDate must be before endDate",
9669
+ "startDate",
9670
+ {
9671
+ startDate: params.startDate.toISOString(),
9672
+ endDate: params.endDate.toISOString()
9673
+ },
9674
+ "SIP_2001" /* INVALID_INPUT */
9675
+ );
9676
+ }
9677
+ }
9678
+ }
9679
+ /**
9680
+ * Normalize viewing key to ViewingKey object
9681
+ */
9682
+ normalizeViewingKey(viewingKey) {
9683
+ if (typeof viewingKey === "string") {
9684
+ const keyHex = viewingKey.startsWith("0x") ? viewingKey.slice(2) : viewingKey;
9685
+ const keyBytes = (0, import_utils21.hexToBytes)(keyHex);
9686
+ const hashBytes = (0, import_sha25615.sha256)(keyBytes);
9687
+ return {
9688
+ key: `0x${keyHex}`,
9689
+ path: "m/0",
9690
+ hash: `0x${(0, import_utils21.bytesToHex)(hashBytes)}`
9691
+ };
9692
+ }
9693
+ return viewingKey;
9694
+ }
9695
+ /**
9696
+ * Decrypt transactions and filter by date range
9697
+ */
9698
+ decryptTransactions(encrypted, viewingKey, startDate, endDate) {
9699
+ const decrypted = [];
9700
+ const errors = [];
9701
+ for (let i = 0; i < encrypted.length; i++) {
9702
+ try {
9703
+ const txData = decryptWithViewing(encrypted[i], viewingKey);
9704
+ if (startDate || endDate) {
9705
+ const txDate = new Date(txData.timestamp * 1e3);
9706
+ if (startDate && txDate < startDate) {
9707
+ continue;
9708
+ }
9709
+ if (endDate && txDate > endDate) {
9710
+ continue;
9711
+ }
9712
+ }
9713
+ decrypted.push({
9714
+ id: `tx_${i}`,
9715
+ sender: txData.sender,
9716
+ recipient: txData.recipient,
9717
+ amount: txData.amount,
9718
+ timestamp: txData.timestamp
9719
+ });
9720
+ } catch (error) {
9721
+ errors.push({ index: i, error });
9722
+ }
9723
+ }
9724
+ if (decrypted.length === 0 && encrypted.length > 0) {
9725
+ throw new CryptoError(
9726
+ `Failed to decrypt any transactions. First error: ${errors[0]?.error.message}`,
9727
+ "SIP_3002" /* DECRYPTION_FAILED */,
9728
+ {
9729
+ context: {
9730
+ totalTransactions: encrypted.length,
9731
+ failedCount: errors.length
9732
+ }
9733
+ }
9734
+ );
9735
+ }
9736
+ return decrypted;
9737
+ }
9738
+ /**
9739
+ * Calculate summary statistics
9740
+ */
9741
+ calculateSummary(transactions) {
9742
+ let totalVolume = 0n;
9743
+ const counterparties = /* @__PURE__ */ new Set();
9744
+ for (const tx of transactions) {
9745
+ try {
9746
+ const amount = BigInt(tx.amount);
9747
+ totalVolume += amount;
9748
+ } catch (error) {
9749
+ console.warn(`Skipping invalid amount in transaction ${tx.id}: ${tx.amount}`);
9750
+ }
9751
+ counterparties.add(tx.sender);
9752
+ counterparties.add(tx.recipient);
9753
+ }
9754
+ return {
9755
+ totalVolume,
9756
+ transactionCount: transactions.length,
9757
+ uniqueCounterparties: counterparties.size
9758
+ };
9759
+ }
9760
+ /**
9761
+ * Determine report period from transactions and params
9762
+ */
9763
+ determinePeriod(transactions, startDate, endDate) {
9764
+ if (startDate && endDate) {
9765
+ return { start: startDate, end: endDate };
9766
+ }
9767
+ if (transactions.length === 0) {
9768
+ const now = /* @__PURE__ */ new Date();
9769
+ return { start: now, end: now };
9770
+ }
9771
+ let minTimestamp = transactions[0].timestamp;
9772
+ let maxTimestamp = transactions[0].timestamp;
9773
+ for (const tx of transactions) {
9774
+ if (tx.timestamp < minTimestamp) {
9775
+ minTimestamp = tx.timestamp;
9776
+ }
9777
+ if (tx.timestamp > maxTimestamp) {
9778
+ maxTimestamp = tx.timestamp;
9779
+ }
9780
+ }
9781
+ return {
9782
+ start: startDate || new Date(minTimestamp * 1e3),
9783
+ end: endDate || new Date(maxTimestamp * 1e3)
9784
+ };
9785
+ }
9786
+ /**
9787
+ * Export audit report to PDF format
9788
+ *
9789
+ * Generates a professionally formatted PDF document from an audit report.
9790
+ * Works in both Node.js and browser environments.
9791
+ *
9792
+ * @param report - The audit report to export
9793
+ * @param options - PDF export options
9794
+ * @returns PDF document as Uint8Array
9795
+ *
9796
+ * @example
9797
+ * ```typescript
9798
+ * const reporter = new ComplianceReporter()
9799
+ * const report = await reporter.generateAuditReport({...})
9800
+ *
9801
+ * const pdfBytes = reporter.exportToPdf(report, {
9802
+ * title: 'Q1 2025 Audit Report',
9803
+ * organization: 'ACME Corp',
9804
+ * })
9805
+ *
9806
+ * // Save to file (Node.js)
9807
+ * fs.writeFileSync('report.pdf', pdfBytes)
9808
+ * ```
9809
+ */
9810
+ exportToPdf(report, options) {
9811
+ return generatePdfReport(report, options);
9812
+ }
9813
+ /**
9814
+ * Export transactions to regulatory compliance formats
9815
+ *
9816
+ * Decrypts and exports transactions in formats required by regulators:
9817
+ * - FATF: Financial Action Task Force Travel Rule format
9818
+ * - FINCEN: FinCEN Suspicious Activity Report (SAR) format
9819
+ * - CSV: Generic comma-separated values format
9820
+ *
9821
+ * @param params - Export parameters
9822
+ * @returns Regulatory export in the specified format
9823
+ * @throws {ValidationError} If parameters are invalid
9824
+ * @throws {CryptoError} If decryption fails
9825
+ *
9826
+ * @example
9827
+ * ```typescript
9828
+ * const reporter = new ComplianceReporter()
9829
+ *
9830
+ * // FATF Travel Rule export
9831
+ * const fatfExport = await reporter.exportForRegulator({
9832
+ * viewingKey: myViewingKey,
9833
+ * transactions: encryptedTxs,
9834
+ * jurisdiction: 'EU',
9835
+ * format: 'FATF',
9836
+ * currency: 'EUR',
9837
+ * })
9838
+ *
9839
+ * // FINCEN SAR export (US only)
9840
+ * const fincenExport = await reporter.exportForRegulator({
9841
+ * viewingKey: myViewingKey,
9842
+ * transactions: suspiciousTxs,
9843
+ * jurisdiction: 'US',
9844
+ * format: 'FINCEN',
9845
+ * })
9846
+ *
9847
+ * // CSV export
9848
+ * const csvExport = await reporter.exportForRegulator({
9849
+ * viewingKey: myViewingKey,
9850
+ * transactions: encryptedTxs,
9851
+ * jurisdiction: 'SG',
9852
+ * format: 'CSV',
9853
+ * })
9854
+ * ```
9855
+ */
9856
+ async exportForRegulator(params) {
9857
+ this.validateRegulatoryParams(params);
9858
+ const viewingKey = this.normalizeViewingKey(params.viewingKey);
9859
+ const decryptedTransactions = this.decryptTransactions(
9860
+ params.transactions,
9861
+ viewingKey,
9862
+ params.startDate,
9863
+ params.endDate
9864
+ );
9865
+ const reportId = `reg_${generateRandomBytes(16).slice(2)}`;
9866
+ switch (params.format) {
9867
+ case "FATF":
9868
+ return this.exportToFATF(
9869
+ reportId,
9870
+ decryptedTransactions,
9871
+ params.jurisdiction,
9872
+ params.currency || "USD"
9873
+ );
9874
+ case "FINCEN":
9875
+ return this.exportToFINCEN(
9876
+ reportId,
9877
+ decryptedTransactions,
9878
+ params.startDate,
9879
+ params.endDate,
9880
+ params.currency || "USD"
9881
+ );
9882
+ case "CSV":
9883
+ return this.exportToCSV(
9884
+ reportId,
9885
+ decryptedTransactions,
9886
+ params.jurisdiction,
9887
+ params.currency || "USD"
9888
+ );
9889
+ default:
9890
+ throw new ValidationError(
9891
+ `unsupported format: ${params.format}`,
9892
+ "format",
9893
+ { received: params.format },
9894
+ "SIP_2001" /* INVALID_INPUT */
9895
+ );
9896
+ }
9897
+ }
9898
+ /**
9899
+ * Validate regulatory export parameters
9900
+ */
9901
+ validateRegulatoryParams(params) {
9902
+ if (!params.viewingKey) {
9903
+ throw new ValidationError(
9904
+ "viewingKey is required",
9905
+ "viewingKey",
9906
+ void 0,
9907
+ "SIP_2008" /* MISSING_REQUIRED */
9908
+ );
9909
+ }
9910
+ if (!params.transactions) {
9911
+ throw new ValidationError(
9912
+ "transactions array is required",
9913
+ "transactions",
9914
+ void 0,
9915
+ "SIP_2008" /* MISSING_REQUIRED */
9916
+ );
9917
+ }
9918
+ if (!Array.isArray(params.transactions)) {
9919
+ throw new ValidationError(
9920
+ "transactions must be an array",
9921
+ "transactions",
9922
+ { received: typeof params.transactions },
9923
+ "SIP_2001" /* INVALID_INPUT */
9924
+ );
9925
+ }
9926
+ if (!params.jurisdiction) {
9927
+ throw new ValidationError(
9928
+ "jurisdiction is required",
9929
+ "jurisdiction",
9930
+ void 0,
9931
+ "SIP_2008" /* MISSING_REQUIRED */
9932
+ );
9933
+ }
9934
+ const validJurisdictions = ["US", "EU", "UK", "SG"];
9935
+ if (!validJurisdictions.includes(params.jurisdiction)) {
9936
+ throw new ValidationError(
9937
+ `invalid jurisdiction. Must be one of: ${validJurisdictions.join(", ")}`,
9938
+ "jurisdiction",
9939
+ { received: params.jurisdiction },
9940
+ "SIP_2001" /* INVALID_INPUT */
9941
+ );
9942
+ }
9943
+ if (!params.format) {
9944
+ throw new ValidationError(
9945
+ "format is required",
9946
+ "format",
9947
+ void 0,
9948
+ "SIP_2008" /* MISSING_REQUIRED */
9949
+ );
9950
+ }
9951
+ const validFormats = ["FATF", "FINCEN", "CSV"];
9952
+ if (!validFormats.includes(params.format)) {
9953
+ throw new ValidationError(
9954
+ `invalid format. Must be one of: ${validFormats.join(", ")}`,
9955
+ "format",
9956
+ { received: params.format },
9957
+ "SIP_2001" /* INVALID_INPUT */
9958
+ );
9959
+ }
9960
+ if (params.format === "FINCEN" && params.jurisdiction !== "US") {
9961
+ throw new ValidationError(
9962
+ "FINCEN format is only available for US jurisdiction",
9963
+ "format",
9964
+ { jurisdiction: params.jurisdiction, format: params.format },
9965
+ "SIP_2001" /* INVALID_INPUT */
9966
+ );
9967
+ }
9968
+ if (params.startDate && params.endDate) {
9969
+ if (params.startDate > params.endDate) {
9970
+ throw new ValidationError(
9971
+ "startDate must be before endDate",
9972
+ "startDate",
9973
+ {
9974
+ startDate: params.startDate.toISOString(),
9975
+ endDate: params.endDate.toISOString()
9976
+ },
9977
+ "SIP_2001" /* INVALID_INPUT */
9978
+ );
9979
+ }
9980
+ }
9981
+ }
9982
+ /**
9983
+ * Export to FATF Travel Rule format
9984
+ */
9985
+ exportToFATF(reportId, transactions, jurisdiction, currency) {
9986
+ const fatfTransactions = transactions.map((tx) => ({
9987
+ originatorAccount: tx.sender,
9988
+ beneficiaryAccount: tx.recipient,
9989
+ amount: tx.amount,
9990
+ currency,
9991
+ transactionRef: tx.id,
9992
+ timestamp: new Date(tx.timestamp * 1e3).toISOString()
9993
+ }));
9994
+ return {
9995
+ reportId,
9996
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
9997
+ jurisdiction,
9998
+ transactions: fatfTransactions
9999
+ };
10000
+ }
10001
+ /**
10002
+ * Export to FINCEN SAR format
10003
+ */
10004
+ exportToFINCEN(reportId, transactions, startDate, endDate, currency = "USD") {
10005
+ let totalAmount = 0n;
10006
+ for (const tx of transactions) {
10007
+ try {
10008
+ totalAmount += BigInt(tx.amount);
10009
+ } catch (error) {
10010
+ }
10011
+ }
10012
+ const period = this.determinePeriod(transactions, startDate, endDate);
10013
+ const fincenTransactions = transactions.map((tx) => ({
10014
+ transactionDate: new Date(tx.timestamp * 1e3).toISOString(),
10015
+ amount: tx.amount,
10016
+ currency,
10017
+ narrativeSummary: `Transfer from ${tx.sender} to ${tx.recipient}`,
10018
+ transactionRef: tx.id,
10019
+ parties: {
10020
+ sender: tx.sender,
10021
+ recipient: tx.recipient
10022
+ }
10023
+ }));
10024
+ return {
10025
+ reportId,
10026
+ filingType: "SAR",
10027
+ reportDate: (/* @__PURE__ */ new Date()).toISOString(),
10028
+ jurisdiction: "US",
10029
+ summary: {
10030
+ transactionCount: transactions.length,
10031
+ totalAmount: totalAmount.toString(),
10032
+ period: {
10033
+ start: period.start.toISOString(),
10034
+ end: period.end.toISOString()
10035
+ }
10036
+ },
10037
+ transactions: fincenTransactions
10038
+ };
10039
+ }
10040
+ /**
10041
+ * Export to CSV format
10042
+ */
10043
+ exportToCSV(reportId, transactions, jurisdiction, currency) {
10044
+ const headers = [
10045
+ "Transaction ID",
10046
+ "Timestamp",
10047
+ "Sender",
10048
+ "Recipient",
10049
+ "Amount",
10050
+ "Currency"
10051
+ ];
10052
+ const rows = transactions.map((tx) => [
10053
+ tx.id,
10054
+ new Date(tx.timestamp * 1e3).toISOString(),
10055
+ tx.sender,
10056
+ tx.recipient,
10057
+ tx.amount,
10058
+ currency
10059
+ ]);
10060
+ return {
10061
+ reportId,
10062
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
10063
+ jurisdiction,
10064
+ headers,
10065
+ rows
10066
+ };
10067
+ }
10068
+ };
10069
+
10070
+ // src/compliance/conditional.ts
10071
+ var import_sha25616 = require("@noble/hashes/sha256");
10072
+ var import_utils22 = require("@noble/hashes/utils");
10073
+ var import_chacha3 = require("@noble/ciphers/chacha.js");
10074
+ var ConditionalDisclosure = class {
10075
+ /**
10076
+ * Create a time-locked disclosure
10077
+ *
10078
+ * Encrypts the viewing key with a deterministic key derived from
10079
+ * the commitment and reveal time. The key can only be reconstructed
10080
+ * after the specified time/block height.
10081
+ *
10082
+ * @param params - Time-lock parameters
10083
+ * @returns Time-lock result with encrypted key
10084
+ * @throws {ValidationError} If parameters are invalid
10085
+ * @throws {CryptoError} If encryption fails
10086
+ */
10087
+ createTimeLocked(params) {
10088
+ if (!params.viewingKey || !params.viewingKey.startsWith("0x")) {
10089
+ throw new ValidationError(
10090
+ "Invalid viewing key format",
10091
+ "viewingKey",
10092
+ { viewingKey: params.viewingKey },
10093
+ "SIP_2006" /* INVALID_KEY */
10094
+ );
10095
+ }
10096
+ if (!params.commitment || !params.commitment.startsWith("0x")) {
10097
+ throw new ValidationError(
10098
+ "Invalid commitment format",
10099
+ "commitment",
10100
+ { commitment: params.commitment },
10101
+ "SIP_3010" /* INVALID_COMMITMENT */
10102
+ );
10103
+ }
10104
+ let revealAfterSeconds;
10105
+ let type;
10106
+ if (params.revealAfter instanceof Date) {
10107
+ revealAfterSeconds = Math.floor(params.revealAfter.getTime() / 1e3);
10108
+ type = "timestamp";
10109
+ } else if (typeof params.revealAfter === "number") {
10110
+ if (params.revealAfter > 1e10) {
10111
+ revealAfterSeconds = Math.floor(params.revealAfter / 1e3);
10112
+ type = "timestamp";
10113
+ } else {
10114
+ revealAfterSeconds = params.revealAfter;
10115
+ type = "blockheight";
10116
+ }
10117
+ if (revealAfterSeconds <= 0) {
10118
+ throw new ValidationError(
10119
+ "Reveal time/block height must be positive",
10120
+ "revealAfter",
10121
+ { revealAfter: revealAfterSeconds },
10122
+ "SIP_3011" /* INVALID_TIME_LOCK */
10123
+ );
10124
+ }
10125
+ } else {
10126
+ throw new ValidationError(
10127
+ "Invalid revealAfter type (must be Date or number)",
10128
+ "revealAfter",
10129
+ { revealAfter: params.revealAfter },
10130
+ "SIP_3011" /* INVALID_TIME_LOCK */
10131
+ );
10132
+ }
10133
+ try {
10134
+ const encryptionKey = this._deriveEncryptionKey(
10135
+ params.commitment,
10136
+ revealAfterSeconds
10137
+ );
10138
+ const nonce = (0, import_utils22.randomBytes)(24);
10139
+ const viewingKeyBytes = (0, import_utils22.hexToBytes)(params.viewingKey.slice(2));
10140
+ const cipher = (0, import_chacha3.xchacha20poly1305)(encryptionKey, nonce);
10141
+ const encryptedKey = cipher.encrypt(viewingKeyBytes);
10142
+ const commitmentData = new Uint8Array([
10143
+ ...viewingKeyBytes,
10144
+ ...this._numberToBytes(revealAfterSeconds)
10145
+ ]);
10146
+ const commitmentHash = (0, import_sha25616.sha256)(commitmentData);
10147
+ return {
10148
+ encryptedKey: "0x" + (0, import_utils22.bytesToHex)(encryptedKey),
10149
+ nonce: "0x" + (0, import_utils22.bytesToHex)(nonce),
10150
+ revealAfter: revealAfterSeconds,
10151
+ verificationCommitment: "0x" + (0, import_utils22.bytesToHex)(commitmentHash),
10152
+ encryptionCommitment: params.commitment,
10153
+ type
10154
+ };
10155
+ } catch (error) {
10156
+ if (error instanceof ValidationError) {
10157
+ throw error;
10158
+ }
10159
+ throw new CryptoError(
10160
+ "Failed to create time-locked disclosure",
10161
+ "SIP_3001" /* ENCRYPTION_FAILED */,
10162
+ {
10163
+ cause: error instanceof Error ? error : void 0,
10164
+ operation: "createTimeLocked"
10165
+ }
10166
+ );
10167
+ }
10168
+ }
10169
+ /**
10170
+ * Check if a time-lock is unlocked and retrieve the viewing key
10171
+ *
10172
+ * @param timeLock - Time-lock result to check
10173
+ * @param currentTimeOrBlock - Current time (Date/number) or block height (number)
10174
+ * @returns Unlock result with viewing key if unlocked
10175
+ * @throws {ValidationError} If time-lock format is invalid
10176
+ * @throws {CryptoError} If decryption fails
10177
+ */
10178
+ checkUnlocked(timeLock, currentTimeOrBlock) {
10179
+ if (!timeLock.encryptedKey || !timeLock.encryptedKey.startsWith("0x")) {
10180
+ throw new ValidationError(
10181
+ "Invalid encrypted key format",
10182
+ "encryptedKey",
10183
+ { encryptedKey: timeLock.encryptedKey },
10184
+ "SIP_3009" /* INVALID_ENCRYPTED_DATA */
10185
+ );
10186
+ }
10187
+ if (!timeLock.nonce || !timeLock.nonce.startsWith("0x")) {
10188
+ throw new ValidationError(
10189
+ "Invalid nonce format",
10190
+ "nonce",
10191
+ { nonce: timeLock.nonce },
10192
+ "SIP_3009" /* INVALID_ENCRYPTED_DATA */
10193
+ );
10194
+ }
10195
+ if (!timeLock.verificationCommitment || !timeLock.verificationCommitment.startsWith("0x")) {
10196
+ throw new ValidationError(
10197
+ "Invalid verification commitment format",
10198
+ "verificationCommitment",
10199
+ { commitment: timeLock.verificationCommitment },
10200
+ "SIP_3010" /* INVALID_COMMITMENT */
10201
+ );
10202
+ }
10203
+ if (!timeLock.encryptionCommitment || !timeLock.encryptionCommitment.startsWith("0x")) {
10204
+ throw new ValidationError(
10205
+ "Invalid encryption commitment format",
10206
+ "encryptionCommitment",
10207
+ { commitment: timeLock.encryptionCommitment },
10208
+ "SIP_3010" /* INVALID_COMMITMENT */
10209
+ );
10210
+ }
10211
+ let currentValue;
10212
+ if (currentTimeOrBlock instanceof Date) {
10213
+ currentValue = Math.floor(currentTimeOrBlock.getTime() / 1e3);
10214
+ } else if (typeof currentTimeOrBlock === "number") {
10215
+ currentValue = currentTimeOrBlock;
10216
+ } else {
10217
+ currentValue = Math.floor(Date.now() / 1e3);
10218
+ }
10219
+ const unlocked = currentValue >= timeLock.revealAfter;
10220
+ if (!unlocked) {
10221
+ return { unlocked: false };
10222
+ }
10223
+ try {
10224
+ const encryptionKey = this._deriveEncryptionKey(
10225
+ timeLock.encryptionCommitment,
10226
+ timeLock.revealAfter
10227
+ );
10228
+ const nonce = (0, import_utils22.hexToBytes)(timeLock.nonce.slice(2));
10229
+ const encryptedData = (0, import_utils22.hexToBytes)(timeLock.encryptedKey.slice(2));
10230
+ const cipher = (0, import_chacha3.xchacha20poly1305)(encryptionKey, nonce);
10231
+ const decryptedBytes = cipher.decrypt(encryptedData);
10232
+ const viewingKey = "0x" + (0, import_utils22.bytesToHex)(decryptedBytes);
10233
+ return {
10234
+ unlocked: true,
10235
+ viewingKey
10236
+ };
10237
+ } catch (error) {
10238
+ if (error instanceof ValidationError || error instanceof CryptoError) {
10239
+ throw error;
10240
+ }
10241
+ throw new CryptoError(
10242
+ "Failed to decrypt time-locked viewing key",
10243
+ "SIP_3002" /* DECRYPTION_FAILED */,
10244
+ {
10245
+ cause: error instanceof Error ? error : void 0,
10246
+ operation: "checkUnlocked"
10247
+ }
10248
+ );
10249
+ }
10250
+ }
10251
+ /**
10252
+ * Verify a time-lock commitment
10253
+ *
10254
+ * Verifies that the verification commitment in the time-lock matches the hash
10255
+ * of the provided viewing key and reveal time.
10256
+ *
10257
+ * @param timeLock - Time-lock to verify
10258
+ * @param viewingKey - Viewing key to verify against
10259
+ * @returns True if commitment is valid
10260
+ */
10261
+ verifyCommitment(timeLock, viewingKey) {
10262
+ try {
10263
+ const viewingKeyBytes = (0, import_utils22.hexToBytes)(viewingKey.slice(2));
10264
+ const commitmentData = new Uint8Array([
10265
+ ...viewingKeyBytes,
10266
+ ...this._numberToBytes(timeLock.revealAfter)
10267
+ ]);
10268
+ const expectedCommitment = (0, import_sha25616.sha256)(commitmentData);
10269
+ const actualCommitment = (0, import_utils22.hexToBytes)(timeLock.verificationCommitment.slice(2));
10270
+ if (expectedCommitment.length !== actualCommitment.length) {
10271
+ return false;
10272
+ }
10273
+ let diff = 0;
10274
+ for (let i = 0; i < expectedCommitment.length; i++) {
10275
+ diff |= expectedCommitment[i] ^ actualCommitment[i];
10276
+ }
10277
+ return diff === 0;
10278
+ } catch {
10279
+ return false;
10280
+ }
10281
+ }
10282
+ /**
10283
+ * Derive deterministic encryption key from commitment and reveal time
10284
+ *
10285
+ * @private
10286
+ */
10287
+ _deriveEncryptionKey(commitment, revealAfter) {
10288
+ const commitmentBytes = (0, import_utils22.hexToBytes)(commitment.slice(2));
10289
+ const timeBytes = this._numberToBytes(revealAfter);
10290
+ const combined = new Uint8Array([...commitmentBytes, ...timeBytes]);
10291
+ const key = (0, import_sha25616.sha256)(combined);
10292
+ if (key.length !== 32) {
10293
+ throw new CryptoError(
10294
+ "Derived key must be 32 bytes",
10295
+ "SIP_3008" /* INVALID_KEY_SIZE */,
10296
+ {
10297
+ context: { actualSize: key.length, expectedSize: 32 },
10298
+ operation: "_deriveEncryptionKey"
10299
+ }
10300
+ );
10301
+ }
10302
+ return key;
10303
+ }
10304
+ /**
10305
+ * Convert number to 8-byte big-endian representation
10306
+ *
10307
+ * @private
10308
+ */
10309
+ _numberToBytes(num) {
10310
+ const bytes = new Uint8Array(8);
10311
+ const view = new DataView(bytes.buffer);
10312
+ view.setBigUint64(0, BigInt(Math.floor(num)), false);
10313
+ return bytes;
10314
+ }
10315
+ };
10316
+
10317
+ // src/compliance/conditional-threshold.ts
10318
+ var import_secp256k17 = require("@noble/curves/secp256k1");
10319
+ var import_sha25617 = require("@noble/hashes/sha256");
10320
+ var import_utils23 = require("@noble/hashes/utils");
10321
+ var CURVE_ORDER2 = import_secp256k17.secp256k1.CURVE.n;
10322
+
10323
+ // src/compliance/threshold.ts
10324
+ var import_sha25618 = require("@noble/hashes/sha256");
10325
+ var import_utils24 = require("@noble/hashes/utils");
10326
+ var FIELD_PRIME = 2n ** 256n - 189n;
10327
+ var ThresholdViewingKey = class {
10328
+ /**
10329
+ * Create threshold shares from a viewing key
10330
+ *
10331
+ * @param params - Configuration parameters
10332
+ * @returns Threshold shares with commitment
10333
+ * @throws ValidationError if parameters are invalid
10334
+ *
10335
+ * @example
10336
+ * ```typescript
10337
+ * const threshold = ThresholdViewingKey.create({
10338
+ * threshold: 3,
10339
+ * totalShares: 5,
10340
+ * viewingKey: '0xabc123...',
10341
+ * })
10342
+ * ```
10343
+ */
10344
+ static create(params) {
10345
+ this.validateParams(params.threshold, params.totalShares);
10346
+ this.validateViewingKey(params.viewingKey);
10347
+ const secret = this.viewingKeyToSecret(params.viewingKey);
10348
+ const keyLength = params.viewingKey.slice(2).length;
10349
+ const coefficients = this.generateCoefficients(params.threshold, secret);
10350
+ const commitment = this.createCommitment(secret, coefficients);
10351
+ const shares = [];
10352
+ for (let i = 1; i <= params.totalShares; i++) {
10353
+ const x = BigInt(i);
10354
+ const y = this.evaluatePolynomial(coefficients, x);
10355
+ shares.push(this.encodeShare(x, y, keyLength, commitment));
10356
+ }
10357
+ return {
10358
+ shares,
10359
+ commitment,
10360
+ threshold: params.threshold,
10361
+ totalShares: params.totalShares
10362
+ };
10363
+ }
10364
+ /**
10365
+ * Reconstruct viewing key from threshold shares
10366
+ *
10367
+ * @param shares - Array of encoded shares (must be >= threshold)
10368
+ * @returns Reconstructed viewing key
10369
+ * @throws ValidationError if insufficient or invalid shares
10370
+ *
10371
+ * @example
10372
+ * ```typescript
10373
+ * const viewingKey = ThresholdViewingKey.reconstruct([
10374
+ * 'share1',
10375
+ * 'share2',
10376
+ * 'share3',
10377
+ * ])
10378
+ * ```
10379
+ */
10380
+ static reconstruct(shares) {
10381
+ if (!shares || shares.length === 0) {
10382
+ throw new ValidationError(
10383
+ "at least one share is required",
10384
+ "shares",
10385
+ { received: shares },
10386
+ "SIP_2008" /* MISSING_REQUIRED */
10387
+ );
10388
+ }
10389
+ const decodedShares = shares.map((s) => this.decodeShare(s));
10390
+ const commitment = decodedShares[0].commitment;
10391
+ const keyLength = decodedShares[0].keyLength;
10392
+ for (const share of decodedShares) {
10393
+ if (share.commitment !== commitment) {
10394
+ throw new ValidationError(
10395
+ "shares must all have the same commitment",
10396
+ "shares",
10397
+ { commitment },
10398
+ "SIP_3012" /* INVALID_SHARE */
10399
+ );
10400
+ }
10401
+ if (share.keyLength !== keyLength) {
10402
+ throw new ValidationError(
10403
+ "shares must all have the same key length",
10404
+ "shares",
10405
+ { keyLength },
10406
+ "SIP_3012" /* INVALID_SHARE */
10407
+ );
10408
+ }
10409
+ }
10410
+ const xCoords = new Set(decodedShares.map((s) => s.x.toString()));
10411
+ if (xCoords.size !== decodedShares.length) {
10412
+ throw new ValidationError(
10413
+ "shares must have unique x-coordinates",
10414
+ "shares",
10415
+ void 0,
10416
+ "SIP_3012" /* INVALID_SHARE */
10417
+ );
10418
+ }
10419
+ const secret = this.lagrangeInterpolate(decodedShares);
10420
+ return this.secretToViewingKey(secret, keyLength);
10421
+ }
10422
+ /**
10423
+ * Verify a share without revealing the viewing key
10424
+ *
10425
+ * @param share - Encoded share to verify
10426
+ * @param expectedCommitment - Expected commitment hash
10427
+ * @returns True if share is valid
10428
+ *
10429
+ * @example
10430
+ * ```typescript
10431
+ * const isValid = ThresholdViewingKey.verifyShare(
10432
+ * 'share1',
10433
+ * 'commitment_hash'
10434
+ * )
10435
+ * ```
10436
+ */
10437
+ static verifyShare(share, expectedCommitment) {
10438
+ try {
10439
+ const decoded = this.decodeShare(share);
10440
+ return decoded.commitment === expectedCommitment;
10441
+ } catch {
10442
+ return false;
10443
+ }
10444
+ }
10445
+ // ─── Private Helper Methods ─────────────────────────────────────────────────
10446
+ /**
10447
+ * Validate threshold and total shares parameters
10448
+ */
10449
+ static validateParams(threshold, totalShares) {
10450
+ if (!Number.isInteger(threshold) || threshold < 2) {
10451
+ throw new ValidationError(
10452
+ "threshold must be an integer >= 2",
10453
+ "threshold",
10454
+ { received: threshold },
10455
+ "SIP_3013" /* INVALID_THRESHOLD */
10456
+ );
10457
+ }
10458
+ if (!Number.isInteger(totalShares) || totalShares < threshold) {
10459
+ throw new ValidationError(
10460
+ "totalShares must be an integer >= threshold",
10461
+ "totalShares",
10462
+ { received: totalShares, threshold },
10463
+ "SIP_3013" /* INVALID_THRESHOLD */
10464
+ );
10465
+ }
10466
+ if (totalShares > 255) {
10467
+ throw new ValidationError(
10468
+ "totalShares must be <= 255",
10469
+ "totalShares",
10470
+ { received: totalShares },
10471
+ "SIP_3013" /* INVALID_THRESHOLD */
10472
+ );
10473
+ }
10474
+ }
10475
+ /**
10476
+ * Validate viewing key format
10477
+ */
10478
+ static validateViewingKey(viewingKey) {
10479
+ if (!viewingKey || typeof viewingKey !== "string") {
10480
+ throw new ValidationError(
10481
+ "viewingKey is required",
10482
+ "viewingKey",
10483
+ { received: viewingKey },
10484
+ "SIP_2008" /* MISSING_REQUIRED */
10485
+ );
10486
+ }
10487
+ if (!viewingKey.startsWith("0x")) {
10488
+ throw new ValidationError(
10489
+ "viewingKey must be hex-encoded (start with 0x)",
10490
+ "viewingKey",
10491
+ { received: viewingKey },
10492
+ "SIP_3015" /* INVALID_FORMAT */
10493
+ );
10494
+ }
10495
+ if (viewingKey.length < 66) {
10496
+ throw new ValidationError(
10497
+ "viewingKey must be at least 32 bytes",
10498
+ "viewingKey",
10499
+ { received: viewingKey.length },
10500
+ "SIP_3015" /* INVALID_FORMAT */
10501
+ );
10502
+ }
10503
+ }
10504
+ /**
10505
+ * Convert viewing key to secret (bigint)
10506
+ */
10507
+ static viewingKeyToSecret(viewingKey) {
10508
+ const bytes = (0, import_utils24.hexToBytes)(viewingKey.slice(2));
10509
+ let secret = 0n;
10510
+ for (let i = 0; i < bytes.length; i++) {
10511
+ secret = secret << 8n | BigInt(bytes[i]);
10512
+ }
10513
+ return this.mod(secret, FIELD_PRIME);
10514
+ }
10515
+ /**
10516
+ * Convert secret (bigint) back to viewing key
10517
+ * @param secret - The secret as bigint
10518
+ * @param hexLength - Length of the hex string (without 0x prefix)
10519
+ */
10520
+ static secretToViewingKey(secret, hexLength) {
10521
+ let hex = secret.toString(16);
10522
+ hex = hex.padStart(hexLength, "0");
10523
+ return `0x${hex}`;
10524
+ }
10525
+ /**
10526
+ * Generate random polynomial coefficients
10527
+ * Polynomial: f(x) = a₀ + a₁x + a₂x² + ... + aₙ₋₁xⁿ⁻¹
10528
+ * where a₀ = secret
10529
+ */
10530
+ static generateCoefficients(threshold, secret) {
10531
+ const coefficients = [secret];
10532
+ for (let i = 1; i < threshold; i++) {
10533
+ const randomCoeff = this.randomFieldElement();
10534
+ coefficients.push(randomCoeff);
10535
+ }
10536
+ return coefficients;
10537
+ }
10538
+ /**
10539
+ * Generate a random field element
10540
+ */
10541
+ static randomFieldElement() {
10542
+ const bytes = (0, import_utils24.randomBytes)(32);
10543
+ let value = 0n;
10544
+ for (let i = 0; i < bytes.length; i++) {
10545
+ value = value << 8n | BigInt(bytes[i]);
10546
+ }
10547
+ return this.mod(value, FIELD_PRIME);
10548
+ }
10549
+ /**
10550
+ * Evaluate polynomial at point x
10551
+ * f(x) = a₀ + a₁x + a₂x² + ... + aₙ₋₁xⁿ⁻¹
10552
+ */
10553
+ static evaluatePolynomial(coefficients, x) {
10554
+ let result = 0n;
10555
+ let xPower = 1n;
10556
+ for (const coeff of coefficients) {
10557
+ result = this.mod(result + this.mod(coeff * xPower, FIELD_PRIME), FIELD_PRIME);
10558
+ xPower = this.mod(xPower * x, FIELD_PRIME);
10559
+ }
10560
+ return result;
10561
+ }
10562
+ /**
10563
+ * Create commitment hash from secret and coefficients
10564
+ */
10565
+ static createCommitment(secret, coefficients) {
10566
+ const data = [secret, ...coefficients].map((c) => c.toString(16).padStart(64, "0")).join("");
10567
+ const hash2 = (0, import_sha25618.sha256)((0, import_utils24.hexToBytes)(data));
10568
+ return (0, import_utils24.bytesToHex)(hash2);
10569
+ }
10570
+ /**
10571
+ * Encode share as string: "x:y:len:commitment"
10572
+ */
10573
+ static encodeShare(x, y, keyLength, commitment) {
10574
+ const xHex = x.toString(16).padStart(2, "0");
10575
+ const yHex = y.toString(16).padStart(64, "0");
10576
+ const lenHex = keyLength.toString(16).padStart(4, "0");
10577
+ return `${xHex}:${yHex}:${lenHex}:${commitment}`;
10578
+ }
10579
+ /**
10580
+ * Decode share from string
10581
+ */
10582
+ static decodeShare(share) {
10583
+ if (!share || typeof share !== "string") {
10584
+ throw new ValidationError(
10585
+ "share must be a non-empty string",
10586
+ "share",
10587
+ { received: share },
10588
+ "SIP_3012" /* INVALID_SHARE */
10589
+ );
10590
+ }
10591
+ const parts = share.split(":");
10592
+ if (parts.length !== 4) {
10593
+ throw new ValidationError(
10594
+ 'share must have format "x:y:len:commitment"',
10595
+ "share",
10596
+ { received: share },
10597
+ "SIP_3012" /* INVALID_SHARE */
10598
+ );
10599
+ }
10600
+ const [xHex, yHex, lenHex, commitment] = parts;
10601
+ try {
10602
+ const x = BigInt(`0x${xHex}`);
10603
+ const y = BigInt(`0x${yHex}`);
10604
+ const keyLength = parseInt(lenHex, 16);
10605
+ if (x <= 0n) {
10606
+ throw new ValidationError(
10607
+ "share x-coordinate must be positive",
10608
+ "share",
10609
+ { x },
10610
+ "SIP_3012" /* INVALID_SHARE */
10611
+ );
10612
+ }
10613
+ if (keyLength < 64) {
10614
+ throw new ValidationError(
10615
+ "key length must be at least 64 (32 bytes)",
10616
+ "share",
10617
+ { keyLength },
10618
+ "SIP_3012" /* INVALID_SHARE */
10619
+ );
10620
+ }
10621
+ return { x, y, keyLength, commitment };
10622
+ } catch (error) {
10623
+ throw new ValidationError(
10624
+ "failed to decode share",
10625
+ "share",
10626
+ { error: error.message },
10627
+ "SIP_3012" /* INVALID_SHARE */
10628
+ );
8331
10629
  }
8332
- return data;
8333
10630
  }
8334
- generateCSV(transactions) {
8335
- const headers = [
8336
- "Transaction ID",
8337
- "Disclosure ID",
8338
- "Type",
8339
- "Direction",
8340
- "Token",
8341
- "Amount",
8342
- "Sender",
8343
- "Recipient",
8344
- "Chain",
8345
- "Privacy Level",
8346
- "Timestamp",
8347
- "TX Hash",
8348
- "Block",
8349
- "Risk Score",
8350
- "Purpose",
8351
- "Memo"
8352
- ];
8353
- const rows = transactions.map((tx) => [
8354
- tx.transactionId,
8355
- tx.disclosureId,
8356
- tx.type,
8357
- tx.direction,
8358
- tx.token.symbol,
8359
- tx.amount.toString(),
8360
- tx.sender,
8361
- tx.recipient,
8362
- tx.chain,
8363
- tx.privacyLevel,
8364
- new Date(tx.timestamp * 1e3).toISOString(),
8365
- tx.txHash,
8366
- tx.blockNumber.toString(),
8367
- tx.riskScore?.toString() ?? "",
8368
- tx.purpose ?? "",
8369
- tx.memo ?? ""
8370
- ]);
8371
- const escapeForCSV = (val) => {
8372
- let escaped = val;
8373
- if (/^[=+\-@|\t]/.test(escaped)) {
8374
- escaped = `'${escaped}`;
10631
+ /**
10632
+ * Lagrange interpolation to reconstruct secret
10633
+ * Evaluates polynomial at x=0 to get f(0) = secret
10634
+ */
10635
+ static lagrangeInterpolate(shares) {
10636
+ let secret = 0n;
10637
+ for (let i = 0; i < shares.length; i++) {
10638
+ const xi = shares[i].x;
10639
+ const yi = shares[i].y;
10640
+ let numerator = 1n;
10641
+ let denominator = 1n;
10642
+ for (let j = 0; j < shares.length; j++) {
10643
+ if (i === j) continue;
10644
+ const xj = shares[j].x;
10645
+ numerator = this.mod(numerator * this.mod(-xj, FIELD_PRIME), FIELD_PRIME);
10646
+ denominator = this.mod(denominator * this.mod(xi - xj, FIELD_PRIME), FIELD_PRIME);
8375
10647
  }
8376
- return `"${escaped.replace(/"/g, '""')}"`;
8377
- };
8378
- const csvRows = [headers, ...rows].map((row) => row.map(escapeForCSV).join(","));
8379
- return csvRows.join("\n");
10648
+ const coeff = this.mod(numerator * this.modInverse(denominator, FIELD_PRIME), FIELD_PRIME);
10649
+ secret = this.mod(secret + this.mod(yi * coeff, FIELD_PRIME), FIELD_PRIME);
10650
+ }
10651
+ return secret;
8380
10652
  }
8381
- };
8382
- function generateId(prefix) {
8383
- return `${prefix}_${(0, import_utils14.bytesToHex)((0, import_utils14.randomBytes)(12))}`;
8384
- }
8385
- function validateRegisterAuditorParams(params) {
8386
- if (!params.organization?.trim()) {
8387
- throw new ValidationError(
8388
- "organization is required",
8389
- "organization",
8390
- void 0,
8391
- "SIP_2008" /* MISSING_REQUIRED */
8392
- );
10653
+ /**
10654
+ * Modular arithmetic: a mod m
10655
+ */
10656
+ static mod(a, m) {
10657
+ return (a % m + m) % m;
8393
10658
  }
8394
- if (!params.contactName?.trim()) {
8395
- throw new ValidationError(
8396
- "contact name is required",
8397
- "contactName",
8398
- void 0,
8399
- "SIP_2008" /* MISSING_REQUIRED */
8400
- );
10659
+ /**
10660
+ * Modular multiplicative inverse using Extended Euclidean Algorithm
10661
+ * Returns x such that (a * x) mod m = 1
10662
+ */
10663
+ static modInverse(a, m) {
10664
+ const a0 = this.mod(a, m);
10665
+ if (a0 === 0n) {
10666
+ throw new CryptoError(
10667
+ "modular inverse does not exist (a = 0)",
10668
+ "SIP_3014" /* CRYPTO_OPERATION_FAILED */,
10669
+ { operation: "modInverse" }
10670
+ );
10671
+ }
10672
+ let [old_r, r] = [a0, m];
10673
+ let [old_s, s] = [1n, 0n];
10674
+ while (r !== 0n) {
10675
+ const quotient = old_r / r;
10676
+ [old_r, r] = [r, old_r - quotient * r];
10677
+ [old_s, s] = [s, old_s - quotient * s];
10678
+ }
10679
+ if (old_r !== 1n) {
10680
+ throw new CryptoError(
10681
+ "modular inverse does not exist (gcd != 1)",
10682
+ "SIP_3014" /* CRYPTO_OPERATION_FAILED */,
10683
+ { operation: "modInverse" }
10684
+ );
10685
+ }
10686
+ return this.mod(old_s, m);
8401
10687
  }
8402
- if (!params.contactEmail?.trim()) {
8403
- throw new ValidationError(
8404
- "contact email is required",
8405
- "contactEmail",
8406
- void 0,
8407
- "SIP_2008" /* MISSING_REQUIRED */
8408
- );
10688
+ };
10689
+
10690
+ // src/compliance/derivation.ts
10691
+ var import_sha25619 = require("@noble/hashes/sha256");
10692
+ var import_sha5123 = require("@noble/hashes/sha512");
10693
+ var import_hmac2 = require("@noble/hashes/hmac");
10694
+ var import_utils25 = require("@noble/hashes/utils");
10695
+ var AuditorType = /* @__PURE__ */ ((AuditorType2) => {
10696
+ AuditorType2[AuditorType2["PRIMARY"] = 0] = "PRIMARY";
10697
+ AuditorType2[AuditorType2["REGULATORY"] = 1] = "REGULATORY";
10698
+ AuditorType2[AuditorType2["INTERNAL"] = 2] = "INTERNAL";
10699
+ AuditorType2[AuditorType2["TAX"] = 3] = "TAX";
10700
+ return AuditorType2;
10701
+ })(AuditorType || {});
10702
+ var AuditorKeyDerivation = class {
10703
+ /**
10704
+ * SIP Protocol coin type (BIP-44 registered)
10705
+ *
10706
+ * Note: This is a placeholder. In production, register with SLIP-44:
10707
+ * https://github.com/satoshilabs/slips/blob/master/slip-0044.md
10708
+ */
10709
+ static COIN_TYPE = 1234;
10710
+ /**
10711
+ * BIP-44 purpose field
10712
+ */
10713
+ static PURPOSE = 44;
10714
+ /**
10715
+ * Hardened derivation flag (2^31)
10716
+ */
10717
+ static HARDENED = 2147483648;
10718
+ /**
10719
+ * Generate BIP-44 derivation path
10720
+ *
10721
+ * @param auditorType - Type of auditor key
10722
+ * @param account - Account index (default: 0)
10723
+ * @returns BIP-44 style path string
10724
+ *
10725
+ * @example
10726
+ * ```typescript
10727
+ * AuditorKeyDerivation.derivePath(AuditorType.REGULATORY)
10728
+ * // Returns: "m/44'/1234'/0'/1"
10729
+ *
10730
+ * AuditorKeyDerivation.derivePath(AuditorType.TAX, 5)
10731
+ * // Returns: "m/44'/1234'/5'/3"
10732
+ * ```
10733
+ */
10734
+ static derivePath(auditorType, account = 0) {
10735
+ this.validateAuditorType(auditorType);
10736
+ this.validateAccount(account);
10737
+ return `m/${this.PURPOSE}'/${this.COIN_TYPE}'/${account}'/${auditorType}`;
8409
10738
  }
8410
- if (!params.publicKey?.trim()) {
8411
- throw new ValidationError(
8412
- "public key is required",
8413
- "publicKey",
8414
- void 0,
8415
- "SIP_2008" /* MISSING_REQUIRED */
8416
- );
10739
+ /**
10740
+ * Derive a viewing key for an auditor
10741
+ *
10742
+ * Uses BIP-32 style hierarchical deterministic key derivation:
10743
+ * 1. Derive master key from seed
10744
+ * 2. Harden purpose (44')
10745
+ * 3. Harden coin type (1234')
10746
+ * 4. Harden account index
10747
+ * 5. Derive auditor type (non-hardened)
10748
+ *
10749
+ * @param params - Derivation parameters
10750
+ * @returns Derived viewing key with metadata
10751
+ *
10752
+ * @throws {ValidationError} If parameters are invalid
10753
+ *
10754
+ * @example
10755
+ * ```typescript
10756
+ * const regulatoryKey = AuditorKeyDerivation.deriveViewingKey({
10757
+ * masterSeed: randomBytes(32),
10758
+ * auditorType: AuditorType.REGULATORY,
10759
+ * })
10760
+ *
10761
+ * console.log(regulatoryKey.path) // "m/44'/1234'/0'/1"
10762
+ * console.log(regulatoryKey.viewingKey.key) // "0x..."
10763
+ * ```
10764
+ */
10765
+ static deriveViewingKey(params) {
10766
+ const { masterSeed, auditorType, account = 0 } = params;
10767
+ this.validateMasterSeed(masterSeed);
10768
+ this.validateAuditorType(auditorType);
10769
+ this.validateAccount(account);
10770
+ const path = this.derivePath(auditorType, account);
10771
+ const indices = [
10772
+ this.PURPOSE | this.HARDENED,
10773
+ // 44' (hardened)
10774
+ this.COIN_TYPE | this.HARDENED,
10775
+ // 1234' (hardened)
10776
+ account | this.HARDENED,
10777
+ // account' (hardened)
10778
+ auditorType
10779
+ // auditorType (non-hardened)
10780
+ ];
10781
+ const masterData = (0, import_hmac2.hmac)(import_sha5123.sha512, (0, import_utils25.utf8ToBytes)("SIP-MASTER-SEED"), masterSeed);
10782
+ let currentKey = new Uint8Array(masterData.slice(0, 32));
10783
+ let chainCode = new Uint8Array(masterData.slice(32, 64));
10784
+ try {
10785
+ for (let i = 0; i < indices.length; i++) {
10786
+ const index = indices[i];
10787
+ const derived = this.deriveChildKey(currentKey, chainCode, index);
10788
+ if (i > 0) {
10789
+ secureWipe(currentKey);
10790
+ }
10791
+ currentKey = new Uint8Array(derived.key);
10792
+ chainCode = new Uint8Array(derived.chainCode);
10793
+ }
10794
+ const keyHex = `0x${(0, import_utils25.bytesToHex)(currentKey)}`;
10795
+ const hashBytes = (0, import_sha25619.sha256)(currentKey);
10796
+ const hash2 = `0x${(0, import_utils25.bytesToHex)(hashBytes)}`;
10797
+ const viewingKey = {
10798
+ key: keyHex,
10799
+ path,
10800
+ hash: hash2
10801
+ };
10802
+ return {
10803
+ path,
10804
+ viewingKey,
10805
+ auditorType,
10806
+ account
10807
+ };
10808
+ } finally {
10809
+ secureWipe(currentKey);
10810
+ secureWipe(chainCode);
10811
+ }
8417
10812
  }
8418
- if (!params.scope) {
8419
- throw new ValidationError(
8420
- "audit scope is required",
8421
- "scope",
8422
- void 0,
8423
- "SIP_2008" /* MISSING_REQUIRED */
8424
- );
10813
+ /**
10814
+ * Derive multiple viewing keys at once
10815
+ *
10816
+ * Efficiently derives keys for multiple auditor types from the same
10817
+ * master seed. This is more efficient than calling deriveViewingKey
10818
+ * multiple times as it reuses intermediate derivations.
10819
+ *
10820
+ * @param params - Derivation parameters
10821
+ * @returns Array of derived viewing keys
10822
+ *
10823
+ * @example
10824
+ * ```typescript
10825
+ * const keys = AuditorKeyDerivation.deriveMultiple({
10826
+ * masterSeed: randomBytes(32),
10827
+ * auditorTypes: [
10828
+ * AuditorType.PRIMARY,
10829
+ * AuditorType.REGULATORY,
10830
+ * AuditorType.INTERNAL,
10831
+ * ],
10832
+ * })
10833
+ *
10834
+ * // keys[0] -> PRIMARY key (m/44'/1234'/0'/0)
10835
+ * // keys[1] -> REGULATORY key (m/44'/1234'/0'/1)
10836
+ * // keys[2] -> INTERNAL key (m/44'/1234'/0'/2)
10837
+ * ```
10838
+ */
10839
+ static deriveMultiple(params) {
10840
+ const { masterSeed, auditorTypes, account = 0 } = params;
10841
+ this.validateMasterSeed(masterSeed);
10842
+ this.validateAccount(account);
10843
+ if (!auditorTypes || auditorTypes.length === 0) {
10844
+ throw new ValidationError(
10845
+ "at least one auditor type is required",
10846
+ "auditorTypes",
10847
+ { received: auditorTypes },
10848
+ "SIP_2008" /* MISSING_REQUIRED */
10849
+ );
10850
+ }
10851
+ for (const type of auditorTypes) {
10852
+ this.validateAuditorType(type);
10853
+ }
10854
+ const uniqueTypes = Array.from(new Set(auditorTypes));
10855
+ const commonIndices = [
10856
+ this.PURPOSE | this.HARDENED,
10857
+ // 44' (hardened)
10858
+ this.COIN_TYPE | this.HARDENED,
10859
+ // 1234' (hardened)
10860
+ account | this.HARDENED
10861
+ // account' (hardened)
10862
+ ];
10863
+ const masterData = (0, import_hmac2.hmac)(import_sha5123.sha512, (0, import_utils25.utf8ToBytes)("SIP-MASTER-SEED"), masterSeed);
10864
+ let commonKey = new Uint8Array(masterData.slice(0, 32));
10865
+ let commonChainCode = new Uint8Array(masterData.slice(32, 64));
10866
+ try {
10867
+ for (let i = 0; i < commonIndices.length; i++) {
10868
+ const index = commonIndices[i];
10869
+ const derived = this.deriveChildKey(commonKey, commonChainCode, index);
10870
+ if (i > 0) {
10871
+ secureWipe(commonKey);
10872
+ }
10873
+ commonKey = new Uint8Array(derived.key);
10874
+ commonChainCode = new Uint8Array(derived.chainCode);
10875
+ }
10876
+ const results = [];
10877
+ for (const auditorType of uniqueTypes) {
10878
+ const derived = this.deriveChildKey(commonKey, commonChainCode, auditorType);
10879
+ try {
10880
+ const keyHex = `0x${(0, import_utils25.bytesToHex)(derived.key)}`;
10881
+ const hashBytes = (0, import_sha25619.sha256)(derived.key);
10882
+ const hash2 = `0x${(0, import_utils25.bytesToHex)(hashBytes)}`;
10883
+ const path = this.derivePath(auditorType, account);
10884
+ const viewingKey = {
10885
+ key: keyHex,
10886
+ path,
10887
+ hash: hash2
10888
+ };
10889
+ results.push({
10890
+ path,
10891
+ viewingKey,
10892
+ auditorType,
10893
+ account
10894
+ });
10895
+ } finally {
10896
+ secureWipe(derived.key);
10897
+ secureWipe(derived.chainCode);
10898
+ }
10899
+ }
10900
+ return results;
10901
+ } finally {
10902
+ secureWipe(commonKey);
10903
+ secureWipe(commonChainCode);
10904
+ }
8425
10905
  }
8426
- }
8427
- function validateReportParams(params) {
8428
- if (!params.title?.trim()) {
8429
- throw new ValidationError(
8430
- "report title is required",
8431
- "title",
8432
- void 0,
8433
- "SIP_2008" /* MISSING_REQUIRED */
8434
- );
10906
+ /**
10907
+ * Get human-readable name for auditor type
10908
+ *
10909
+ * @param auditorType - Auditor type enum value
10910
+ * @returns Friendly name string
10911
+ */
10912
+ static getAuditorTypeName(auditorType) {
10913
+ switch (auditorType) {
10914
+ case 0 /* PRIMARY */:
10915
+ return "Primary";
10916
+ case 1 /* REGULATORY */:
10917
+ return "Regulatory";
10918
+ case 2 /* INTERNAL */:
10919
+ return "Internal";
10920
+ case 3 /* TAX */:
10921
+ return "Tax Authority";
10922
+ default:
10923
+ return `Unknown (${auditorType})`;
10924
+ }
8435
10925
  }
8436
- if (!params.type) {
8437
- throw new ValidationError(
8438
- "report type is required",
8439
- "type",
8440
- void 0,
8441
- "SIP_2008" /* MISSING_REQUIRED */
8442
- );
10926
+ // ─── Private Helpers ─────────────────────────────────────────────────────────
10927
+ /**
10928
+ * Derive a child key using BIP-32 HMAC-SHA512 derivation
10929
+ *
10930
+ * @param parentKey - Parent key bytes (32 bytes)
10931
+ * @param chainCode - Parent chain code (32 bytes)
10932
+ * @param index - Child index (use | HARDENED for hardened derivation)
10933
+ * @returns Derived key and chain code
10934
+ */
10935
+ static deriveChildKey(parentKey, chainCode, index) {
10936
+ const isHardened = (index & this.HARDENED) !== 0;
10937
+ const data = new Uint8Array(37);
10938
+ if (isHardened) {
10939
+ data[0] = 0;
10940
+ data.set(parentKey, 1);
10941
+ } else {
10942
+ data[0] = 1;
10943
+ data.set(parentKey, 1);
10944
+ }
10945
+ const indexView = new DataView(data.buffer, 33, 4);
10946
+ indexView.setUint32(0, index, false);
10947
+ const hmacResult = (0, import_hmac2.hmac)(import_sha5123.sha512, chainCode, data);
10948
+ const childKey = new Uint8Array(hmacResult.slice(0, 32));
10949
+ const childChainCode = new Uint8Array(hmacResult.slice(32, 64));
10950
+ return {
10951
+ key: childKey,
10952
+ chainCode: childChainCode
10953
+ };
8443
10954
  }
8444
- if (!params.format) {
8445
- throw new ValidationError(
8446
- "report format is required",
8447
- "format",
8448
- void 0,
8449
- "SIP_2008" /* MISSING_REQUIRED */
8450
- );
10955
+ /**
10956
+ * Validate master seed
10957
+ */
10958
+ static validateMasterSeed(seed) {
10959
+ if (!seed || seed.length < 32) {
10960
+ throw new ValidationError(
10961
+ "master seed must be at least 32 bytes",
10962
+ "masterSeed",
10963
+ { received: seed?.length ?? 0 },
10964
+ "SIP_2001" /* INVALID_INPUT */
10965
+ );
10966
+ }
8451
10967
  }
8452
- if (params.startDate === void 0 || params.startDate === null || params.endDate === void 0 || params.endDate === null) {
8453
- throw new ValidationError(
8454
- "date range is required",
8455
- "dateRange",
8456
- void 0,
8457
- "SIP_2008" /* MISSING_REQUIRED */
8458
- );
10968
+ /**
10969
+ * Validate auditor type
10970
+ */
10971
+ static validateAuditorType(type) {
10972
+ const validTypes = [
10973
+ 0 /* PRIMARY */,
10974
+ 1 /* REGULATORY */,
10975
+ 2 /* INTERNAL */,
10976
+ 3 /* TAX */
10977
+ ];
10978
+ if (!validTypes.includes(type)) {
10979
+ throw new ValidationError(
10980
+ `invalid auditor type: ${type}`,
10981
+ "auditorType",
10982
+ { received: type, valid: validTypes },
10983
+ "SIP_2001" /* INVALID_INPUT */
10984
+ );
10985
+ }
8459
10986
  }
8460
- if (params.startDate >= params.endDate) {
8461
- throw new ValidationError(
8462
- "start date must be before end date",
8463
- "dateRange",
8464
- void 0,
8465
- "SIP_2001" /* INVALID_INPUT */
8466
- );
10987
+ /**
10988
+ * Validate account index
10989
+ */
10990
+ static validateAccount(account) {
10991
+ if (!Number.isInteger(account) || account < 0 || account >= this.HARDENED) {
10992
+ throw new ValidationError(
10993
+ `account must be a non-negative integer less than ${this.HARDENED}`,
10994
+ "account",
10995
+ { received: account },
10996
+ "SIP_2001" /* INVALID_INPUT */
10997
+ );
10998
+ }
8467
10999
  }
8468
- }
11000
+ };
8469
11001
 
8470
11002
  // src/wallet/errors.ts
8471
11003
  var import_types18 = require("@sip-protocol/types");
@@ -10624,6 +13156,30 @@ function createMockEthereumProvider(config = {}) {
10624
13156
  return provider;
10625
13157
  }
10626
13158
 
13159
+ // src/wallet/cosmos/adapter.ts
13160
+ var import_types29 = require("@sip-protocol/types");
13161
+
13162
+ // src/wallet/cosmos/mock.ts
13163
+ var import_types31 = require("@sip-protocol/types");
13164
+
13165
+ // src/wallet/bitcoin/adapter.ts
13166
+ var import_types34 = require("@sip-protocol/types");
13167
+
13168
+ // src/wallet/bitcoin/mock.ts
13169
+ var import_types36 = require("@sip-protocol/types");
13170
+
13171
+ // src/wallet/aptos/adapter.ts
13172
+ var import_types39 = require("@sip-protocol/types");
13173
+
13174
+ // src/wallet/aptos/mock.ts
13175
+ var import_types41 = require("@sip-protocol/types");
13176
+
13177
+ // src/wallet/sui/adapter.ts
13178
+ var import_types43 = require("@sip-protocol/types");
13179
+
13180
+ // src/wallet/sui/mock.ts
13181
+ var import_types45 = require("@sip-protocol/types");
13182
+
10627
13183
  // src/wallet/hardware/types.ts
10628
13184
  var DerivationPath = {
10629
13185
  /** Ethereum: m/44'/60'/0'/0/index */
@@ -10699,7 +13255,7 @@ function getAvailableTransports() {
10699
13255
  }
10700
13256
 
10701
13257
  // src/wallet/hardware/ledger.ts
10702
- var import_types29 = require("@sip-protocol/types");
13258
+ var import_types47 = require("@sip-protocol/types");
10703
13259
  var LedgerWalletAdapter = class extends BaseWalletAdapter {
10704
13260
  chain;
10705
13261
  name = "ledger";
@@ -10852,7 +13408,7 @@ var LedgerWalletAdapter = class extends BaseWalletAdapter {
10852
13408
  async getBalance() {
10853
13409
  throw new WalletError(
10854
13410
  "Hardware wallets do not track balances. Use an RPC provider.",
10855
- import_types29.WalletErrorCode.UNSUPPORTED_OPERATION
13411
+ import_types47.WalletErrorCode.UNSUPPORTED_OPERATION
10856
13412
  );
10857
13413
  }
10858
13414
  /**
@@ -10863,7 +13419,7 @@ var LedgerWalletAdapter = class extends BaseWalletAdapter {
10863
13419
  async getTokenBalance(_asset) {
10864
13420
  throw new WalletError(
10865
13421
  "Hardware wallets do not track balances. Use an RPC provider.",
10866
- import_types29.WalletErrorCode.UNSUPPORTED_OPERATION
13422
+ import_types47.WalletErrorCode.UNSUPPORTED_OPERATION
10867
13423
  );
10868
13424
  }
10869
13425
  // ─── Account Management ─────────────────────────────────────────────────────
@@ -11151,7 +13707,7 @@ function createLedgerAdapter(config) {
11151
13707
  }
11152
13708
 
11153
13709
  // src/wallet/hardware/trezor.ts
11154
- var import_types31 = require("@sip-protocol/types");
13710
+ var import_types49 = require("@sip-protocol/types");
11155
13711
  var TrezorWalletAdapter = class extends BaseWalletAdapter {
11156
13712
  chain;
11157
13713
  name = "trezor";
@@ -11297,7 +13853,7 @@ var TrezorWalletAdapter = class extends BaseWalletAdapter {
11297
13853
  async getBalance() {
11298
13854
  throw new WalletError(
11299
13855
  "Hardware wallets do not track balances. Use an RPC provider.",
11300
- import_types31.WalletErrorCode.UNSUPPORTED_OPERATION
13856
+ import_types49.WalletErrorCode.UNSUPPORTED_OPERATION
11301
13857
  );
11302
13858
  }
11303
13859
  /**
@@ -11308,7 +13864,7 @@ var TrezorWalletAdapter = class extends BaseWalletAdapter {
11308
13864
  async getTokenBalance(_asset) {
11309
13865
  throw new WalletError(
11310
13866
  "Hardware wallets do not track balances. Use an RPC provider.",
11311
- import_types31.WalletErrorCode.UNSUPPORTED_OPERATION
13867
+ import_types49.WalletErrorCode.UNSUPPORTED_OPERATION
11312
13868
  );
11313
13869
  }
11314
13870
  // ─── Account Management ─────────────────────────────────────────────────────
@@ -11589,8 +14145,8 @@ function createTrezorAdapter(config) {
11589
14145
  }
11590
14146
 
11591
14147
  // src/wallet/hardware/mock.ts
11592
- var import_types33 = require("@sip-protocol/types");
11593
- var import_utils15 = require("@noble/hashes/utils");
14148
+ var import_types51 = require("@sip-protocol/types");
14149
+ var import_utils26 = require("@noble/hashes/utils");
11594
14150
  var MockLedgerAdapter = class extends BaseWalletAdapter {
11595
14151
  chain;
11596
14152
  name = "mock-ledger";
@@ -11737,7 +14293,7 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
11737
14293
  async getBalance() {
11738
14294
  throw new WalletError(
11739
14295
  "Hardware wallets do not track balances",
11740
- import_types33.WalletErrorCode.UNSUPPORTED_OPERATION
14296
+ import_types51.WalletErrorCode.UNSUPPORTED_OPERATION
11741
14297
  );
11742
14298
  }
11743
14299
  /**
@@ -11746,7 +14302,7 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
11746
14302
  async getTokenBalance(_asset) {
11747
14303
  throw new WalletError(
11748
14304
  "Hardware wallets do not track balances",
11749
- import_types33.WalletErrorCode.UNSUPPORTED_OPERATION
14305
+ import_types51.WalletErrorCode.UNSUPPORTED_OPERATION
11750
14306
  );
11751
14307
  }
11752
14308
  /**
@@ -11835,15 +14391,15 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
11835
14391
  }
11836
14392
  }
11837
14393
  generateMockAddress(index) {
11838
- const bytes = (0, import_utils15.randomBytes)(20);
14394
+ const bytes = (0, import_utils26.randomBytes)(20);
11839
14395
  bytes[0] = index;
11840
- return `0x${(0, import_utils15.bytesToHex)(bytes)}`;
14396
+ return `0x${(0, import_utils26.bytesToHex)(bytes)}`;
11841
14397
  }
11842
14398
  generateMockPublicKey(index) {
11843
- const bytes = (0, import_utils15.randomBytes)(33);
14399
+ const bytes = (0, import_utils26.randomBytes)(33);
11844
14400
  bytes[0] = 2;
11845
14401
  bytes[1] = index;
11846
- return `0x${(0, import_utils15.bytesToHex)(bytes)}`;
14402
+ return `0x${(0, import_utils26.bytesToHex)(bytes)}`;
11847
14403
  }
11848
14404
  generateMockSignature(data) {
11849
14405
  const sig = new Uint8Array(65);
@@ -11852,7 +14408,7 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
11852
14408
  sig[32 + i] = (data[i % data.length] ?? 0) ^ i * 11;
11853
14409
  }
11854
14410
  sig[64] = 27;
11855
- return `0x${(0, import_utils15.bytesToHex)(sig)}`;
14411
+ return `0x${(0, import_utils26.bytesToHex)(sig)}`;
11856
14412
  }
11857
14413
  delay(ms) {
11858
14414
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -11976,13 +14532,13 @@ var MockTrezorAdapter = class extends BaseWalletAdapter {
11976
14532
  async getBalance() {
11977
14533
  throw new WalletError(
11978
14534
  "Hardware wallets do not track balances",
11979
- import_types33.WalletErrorCode.UNSUPPORTED_OPERATION
14535
+ import_types51.WalletErrorCode.UNSUPPORTED_OPERATION
11980
14536
  );
11981
14537
  }
11982
14538
  async getTokenBalance(_asset) {
11983
14539
  throw new WalletError(
11984
14540
  "Hardware wallets do not track balances",
11985
- import_types33.WalletErrorCode.UNSUPPORTED_OPERATION
14541
+ import_types51.WalletErrorCode.UNSUPPORTED_OPERATION
11986
14542
  );
11987
14543
  }
11988
14544
  async getAccounts(startIndex = 0, count = 5) {
@@ -12041,15 +14597,15 @@ var MockTrezorAdapter = class extends BaseWalletAdapter {
12041
14597
  }
12042
14598
  }
12043
14599
  generateMockAddress(index) {
12044
- const bytes = (0, import_utils15.randomBytes)(20);
14600
+ const bytes = (0, import_utils26.randomBytes)(20);
12045
14601
  bytes[0] = index + 100;
12046
- return `0x${(0, import_utils15.bytesToHex)(bytes)}`;
14602
+ return `0x${(0, import_utils26.bytesToHex)(bytes)}`;
12047
14603
  }
12048
14604
  generateMockPublicKey(index) {
12049
- const bytes = (0, import_utils15.randomBytes)(33);
14605
+ const bytes = (0, import_utils26.randomBytes)(33);
12050
14606
  bytes[0] = 3;
12051
14607
  bytes[1] = index + 100;
12052
- return `0x${(0, import_utils15.bytesToHex)(bytes)}`;
14608
+ return `0x${(0, import_utils26.bytesToHex)(bytes)}`;
12053
14609
  }
12054
14610
  generateMockSignature(data) {
12055
14611
  const sig = new Uint8Array(65);
@@ -12058,7 +14614,7 @@ var MockTrezorAdapter = class extends BaseWalletAdapter {
12058
14614
  sig[32 + i] = (data[i % data.length] ?? 0) ^ i * 17;
12059
14615
  }
12060
14616
  sig[64] = 28;
12061
- return `0x${(0, import_utils15.bytesToHex)(sig)}`;
14617
+ return `0x${(0, import_utils26.bytesToHex)(sig)}`;
12062
14618
  }
12063
14619
  delay(ms) {
12064
14620
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -12072,13 +14628,20 @@ function createMockTrezorAdapter(config) {
12072
14628
  }
12073
14629
 
12074
14630
  // src/wallet/index.ts
12075
- var import_types36 = require("@sip-protocol/types");
14631
+ var import_types54 = require("@sip-protocol/types");
12076
14632
  // Annotate the CommonJS export names for ESM import in node:
12077
14633
  0 && (module.exports = {
12078
14634
  ATTESTATION_VERSION,
14635
+ AptosStealthService,
14636
+ AuditorKeyDerivation,
14637
+ AuditorType,
12079
14638
  BaseWalletAdapter,
12080
14639
  CHAIN_NUMERIC_IDS,
14640
+ COSMOS_CHAIN_PREFIXES,
12081
14641
  ComplianceManager,
14642
+ ComplianceReporter,
14643
+ ConditionalDisclosure,
14644
+ CosmosStealthService,
12082
14645
  CryptoError,
12083
14646
  DEFAULT_THRESHOLD,
12084
14647
  DEFAULT_TOTAL_ORACLES,
@@ -12129,6 +14692,7 @@ var import_types36 = require("@sip-protocol/types");
12129
14692
  SmartRouter,
12130
14693
  SolanaWalletAdapter,
12131
14694
  SwapStatus,
14695
+ ThresholdViewingKey,
12132
14696
  Treasury,
12133
14697
  TrezorWalletAdapter,
12134
14698
  ValidationError,
@@ -12143,17 +14707,21 @@ var import_types36 = require("@sip-protocol/types");
12143
14707
  addBlindings,
12144
14708
  addCommitments,
12145
14709
  addOracle,
14710
+ aptosAddressToAuthKey,
12146
14711
  attachProofs,
12147
14712
  base58ToHex,
12148
14713
  browserBytesToHex,
12149
14714
  browserHexToBytes,
14715
+ checkAptosStealthAddress,
12150
14716
  checkEd25519StealthAddress,
12151
14717
  checkStealthAddress,
12152
14718
  commit,
12153
14719
  commitZero,
12154
14720
  computeAttestationHash,
14721
+ computeTweakedKey,
12155
14722
  createCommitment,
12156
14723
  createEthereumAdapter,
14724
+ createKeySpendOnlyOutput,
12157
14725
  createLedgerAdapter,
12158
14726
  createMockEthereumAdapter,
12159
14727
  createMockEthereumProvider,
@@ -12172,6 +14740,7 @@ var import_types36 = require("@sip-protocol/types");
12172
14740
  createShieldedPayment,
12173
14741
  createSmartRouter,
12174
14742
  createSolanaAdapter,
14743
+ createTaprootOutput,
12175
14744
  createTrezorAdapter,
12176
14745
  createWalletFactory,
12177
14746
  createZcashClient,
@@ -12179,8 +14748,10 @@ var import_types36 = require("@sip-protocol/types");
12179
14748
  createZcashShieldedService,
12180
14749
  createZcashSwapService,
12181
14750
  decodeStealthMetaAddress,
14751
+ decodeTaprootAddress,
12182
14752
  decryptMemo,
12183
14753
  decryptWithViewing,
14754
+ deriveAptosStealthPrivateKey,
12184
14755
  deriveEd25519StealthPrivateKey,
12185
14756
  deriveOracleId,
12186
14757
  deriveStealthPrivateKey,
@@ -12190,6 +14761,7 @@ var import_types36 = require("@sip-protocol/types");
12190
14761
  deserializePayment,
12191
14762
  detectEthereumWallets,
12192
14763
  detectSolanaWallets,
14764
+ ed25519PublicKeyToAptosAddress,
12193
14765
  ed25519PublicKeyToNearAddress,
12194
14766
  ed25519PublicKeyToSolanaAddress,
12195
14767
  encodeStealthMetaAddress,
@@ -12198,10 +14770,14 @@ var import_types36 = require("@sip-protocol/types");
12198
14770
  formatStablecoinAmount,
12199
14771
  fromHex,
12200
14772
  fromStablecoinUnits,
14773
+ generateAptosStealthAddress,
12201
14774
  generateBlinding,
14775
+ generateCosmosStealthAddress,
14776
+ generateCosmosStealthMetaAddress,
12202
14777
  generateEd25519StealthAddress,
12203
14778
  generateEd25519StealthMetaAddress,
12204
14779
  generateIntentId,
14780
+ generatePdfReport,
12205
14781
  generateRandomBytes,
12206
14782
  generateStealthAddress,
12207
14783
  generateStealthMetaAddress,
@@ -12228,6 +14804,7 @@ var import_types36 = require("@sip-protocol/types");
12228
14804
  getStablecoinsForChain,
12229
14805
  getSupportedStablecoins,
12230
14806
  getTimeRemaining,
14807
+ getXOnlyPublicKey,
12231
14808
  hasEnoughOracles,
12232
14809
  hasErrorCode,
12233
14810
  hasRequiredProofs,
@@ -12244,8 +14821,10 @@ var import_types36 = require("@sip-protocol/types");
12244
14821
  isStablecoin,
12245
14822
  isStablecoinOnChain,
12246
14823
  isValidAmount,
14824
+ isValidAptosAddress,
12247
14825
  isValidChainId,
12248
14826
  isValidCompressedPublicKey,
14827
+ isValidCosmosAddress,
12249
14828
  isValidEd25519PublicKey,
12250
14829
  isValidHex,
12251
14830
  isValidHexLength,
@@ -12257,12 +14836,17 @@ var import_types36 = require("@sip-protocol/types");
12257
14836
  isValidSlippage,
12258
14837
  isValidSolanaAddress,
12259
14838
  isValidStealthMetaAddress,
14839
+ isValidTaprootAddress,
12260
14840
  nearAddressToEd25519PublicKey,
12261
14841
  normalizeAddress,
12262
14842
  notConnectedError,
12263
14843
  publicKeyToEthAddress,
12264
14844
  registerWallet,
12265
14845
  removeOracle,
14846
+ schnorrSign,
14847
+ schnorrSignHex,
14848
+ schnorrVerify,
14849
+ schnorrVerifyHex,
12266
14850
  secureWipe,
12267
14851
  secureWipeAll,
12268
14852
  serializeAttestationMessage,
@@ -12271,6 +14855,7 @@ var import_types36 = require("@sip-protocol/types");
12271
14855
  signAttestationMessage,
12272
14856
  solanaAddressToEd25519PublicKey,
12273
14857
  solanaPublicKeyToHex,
14858
+ stealthKeyToCosmosAddress,
12274
14859
  subtractBlindings,
12275
14860
  subtractCommitments,
12276
14861
  supportsSharedArrayBuffer,
@@ -12279,6 +14864,7 @@ var import_types36 = require("@sip-protocol/types");
12279
14864
  supportsWebHID,
12280
14865
  supportsWebUSB,
12281
14866
  supportsWebWorkers,
14867
+ taprootAddress,
12282
14868
  toHex,
12283
14869
  toStablecoinUnits,
12284
14870
  trackIntent,