@sip-protocol/sdk 0.7.1 → 0.7.3

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 (50) hide show
  1. package/dist/browser.d.mts +1 -1
  2. package/dist/browser.d.ts +1 -1
  3. package/dist/browser.js +2926 -341
  4. package/dist/browser.mjs +48 -2
  5. package/dist/chunk-2XIVXWHA.mjs +1930 -0
  6. package/dist/chunk-3M3HNQCW.mjs +18253 -0
  7. package/dist/chunk-7RFRWDCW.mjs +1504 -0
  8. package/dist/chunk-F6F73W35.mjs +16166 -0
  9. package/dist/chunk-OFDBEIEK.mjs +16166 -0
  10. package/dist/chunk-SF7YSLF5.mjs +1515 -0
  11. package/dist/chunk-WWUSGOXE.mjs +17129 -0
  12. package/dist/index-8MQz13eJ.d.mts +13746 -0
  13. package/dist/index-B71aXVzk.d.ts +13264 -0
  14. package/dist/index-DIBZHOOQ.d.ts +13746 -0
  15. package/dist/index-pOIIuwfV.d.mts +13264 -0
  16. package/dist/index.d.mts +1 -1
  17. package/dist/index.d.ts +1 -1
  18. package/dist/index.js +2911 -326
  19. package/dist/index.mjs +48 -2
  20. package/dist/solana-4O4K45VU.mjs +46 -0
  21. package/dist/solana-NDABAZ6P.mjs +56 -0
  22. package/dist/solana-ZYO63LY5.mjs +46 -0
  23. package/package.json +3 -3
  24. package/src/chains/solana/index.ts +24 -0
  25. package/src/chains/solana/providers/generic.ts +160 -0
  26. package/src/chains/solana/providers/helius.ts +249 -0
  27. package/src/chains/solana/providers/index.ts +54 -0
  28. package/src/chains/solana/providers/interface.ts +178 -0
  29. package/src/chains/solana/providers/webhook.ts +519 -0
  30. package/src/chains/solana/scan.ts +88 -8
  31. package/src/chains/solana/types.ts +20 -1
  32. package/src/compliance/index.ts +14 -0
  33. package/src/compliance/range-sas.ts +591 -0
  34. package/src/index.ts +99 -0
  35. package/src/privacy-backends/index.ts +86 -0
  36. package/src/privacy-backends/interface.ts +263 -0
  37. package/src/privacy-backends/privacycash-types.ts +278 -0
  38. package/src/privacy-backends/privacycash.ts +460 -0
  39. package/src/privacy-backends/registry.ts +278 -0
  40. package/src/privacy-backends/router.ts +346 -0
  41. package/src/privacy-backends/sip-native.ts +253 -0
  42. package/src/proofs/noir.ts +1 -1
  43. package/src/surveillance/algorithms/address-reuse.ts +143 -0
  44. package/src/surveillance/algorithms/cluster.ts +247 -0
  45. package/src/surveillance/algorithms/exchange.ts +295 -0
  46. package/src/surveillance/algorithms/temporal.ts +337 -0
  47. package/src/surveillance/analyzer.ts +442 -0
  48. package/src/surveillance/index.ts +64 -0
  49. package/src/surveillance/scoring.ts +372 -0
  50. package/src/surveillance/types.ts +264 -0
package/dist/browser.js CHANGED
@@ -1552,7 +1552,8 @@ async function scanForPayments(params) {
1552
1552
  spendingPublicKey,
1553
1553
  fromSlot,
1554
1554
  toSlot,
1555
- limit = 100
1555
+ limit = 100,
1556
+ provider
1556
1557
  } = params;
1557
1558
  const results = [];
1558
1559
  const memoProgram = new import_web32.PublicKey(MEMO_PROGRAM_ID);
@@ -1596,12 +1597,26 @@ async function scanForPayments(params) {
1596
1597
  if (isOurs) {
1597
1598
  const transferInfo = parseTokenTransfer(tx);
1598
1599
  if (transferInfo) {
1600
+ let amount = transferInfo.amount;
1601
+ const tokenSymbol = getTokenSymbol(transferInfo.mint);
1602
+ if (provider && announcement.stealthAddress) {
1603
+ try {
1604
+ const balance = await provider.getTokenBalance(
1605
+ announcement.stealthAddress,
1606
+ transferInfo.mint
1607
+ );
1608
+ if (balance > 0n) {
1609
+ amount = balance;
1610
+ }
1611
+ } catch {
1612
+ }
1613
+ }
1599
1614
  results.push({
1600
1615
  stealthAddress: announcement.stealthAddress || "",
1601
1616
  ephemeralPublicKey: announcement.ephemeralPublicKey,
1602
- amount: transferInfo.amount,
1617
+ amount,
1603
1618
  mint: transferInfo.mint,
1604
- tokenSymbol: getTokenSymbol(transferInfo.mint),
1619
+ tokenSymbol,
1605
1620
  txSignature: sigInfo.signature,
1606
1621
  slot: sigInfo.slot,
1607
1622
  timestamp: sigInfo.blockTime || 0
@@ -1644,8 +1659,19 @@ async function claimStealthPayment(params) {
1644
1659
  );
1645
1660
  const stealthPrivKeyBytes = (0, import_utils9.hexToBytes)(recovery.privateKey.slice(2));
1646
1661
  const stealthPubkey = new import_web32.PublicKey(stealthAddress);
1662
+ const expectedPubKeyBytes = stealthPubkey.toBytes();
1663
+ const scalarBigInt = bytesToBigIntLE2(stealthPrivKeyBytes);
1664
+ const ED25519_ORDER2 = 2n ** 252n + 27742317777372353535851937790883648493n;
1665
+ let validScalar = scalarBigInt % ED25519_ORDER2;
1666
+ if (validScalar === 0n) validScalar = 1n;
1667
+ const derivedPubKeyBytes = import_ed255192.ed25519.ExtendedPoint.BASE.multiply(validScalar).toRawBytes();
1668
+ if (!derivedPubKeyBytes.every((b, i) => b === expectedPubKeyBytes[i])) {
1669
+ throw new Error(
1670
+ "Stealth key derivation failed: derived private key does not produce expected public key. This may indicate incorrect spending/viewing keys or corrupted announcement data."
1671
+ );
1672
+ }
1647
1673
  const stealthKeypair = import_web32.Keypair.fromSecretKey(
1648
- new Uint8Array([...stealthPrivKeyBytes, ...stealthPubkey.toBytes()])
1674
+ new Uint8Array([...stealthPrivKeyBytes, ...expectedPubKeyBytes])
1649
1675
  );
1650
1676
  const stealthATA = await (0, import_spl_token2.getAssociatedTokenAddress)(
1651
1677
  mint,
@@ -1696,7 +1722,13 @@ async function claimStealthPayment(params) {
1696
1722
  explorerUrl: getExplorerUrl(txSignature, cluster)
1697
1723
  };
1698
1724
  }
1699
- async function getStealthBalance(connection, stealthAddress, mint) {
1725
+ async function getStealthBalance(connection, stealthAddress, mint, provider) {
1726
+ if (provider) {
1727
+ try {
1728
+ return await provider.getTokenBalance(stealthAddress, mint.toBase58());
1729
+ } catch {
1730
+ }
1731
+ }
1700
1732
  try {
1701
1733
  const stealthPubkey = new import_web32.PublicKey(stealthAddress);
1702
1734
  const ata = await (0, import_spl_token2.getAssociatedTokenAddress)(mint, stealthPubkey, true);
@@ -1746,7 +1778,14 @@ function detectCluster2(endpoint) {
1746
1778
  }
1747
1779
  return "mainnet-beta";
1748
1780
  }
1749
- var import_web32, import_spl_token2, import_utils9;
1781
+ function bytesToBigIntLE2(bytes) {
1782
+ let result = 0n;
1783
+ for (let i = bytes.length - 1; i >= 0; i--) {
1784
+ result = result << 8n | BigInt(bytes[i]);
1785
+ }
1786
+ return result;
1787
+ }
1788
+ var import_web32, import_spl_token2, import_utils9, import_ed255192;
1750
1789
  var init_scan = __esm({
1751
1790
  "src/chains/solana/scan.ts"() {
1752
1791
  "use strict";
@@ -1756,6 +1795,428 @@ var init_scan = __esm({
1756
1795
  init_types();
1757
1796
  init_constants();
1758
1797
  import_utils9 = require("@noble/hashes/utils");
1798
+ import_ed255192 = require("@noble/curves/ed25519");
1799
+ }
1800
+ });
1801
+
1802
+ // src/chains/solana/providers/helius.ts
1803
+ var HeliusProvider;
1804
+ var init_helius = __esm({
1805
+ "src/chains/solana/providers/helius.ts"() {
1806
+ "use strict";
1807
+ HeliusProvider = class {
1808
+ name = "helius";
1809
+ apiKey;
1810
+ cluster;
1811
+ rpcUrl;
1812
+ restUrl;
1813
+ constructor(config) {
1814
+ if (!config.apiKey) {
1815
+ throw new Error("Helius API key is required. Get one at https://dev.helius.xyz");
1816
+ }
1817
+ this.apiKey = config.apiKey;
1818
+ this.cluster = config.cluster ?? "mainnet-beta";
1819
+ this.rpcUrl = this.cluster === "devnet" ? `https://devnet.helius-rpc.com/?api-key=${this.apiKey}` : `https://mainnet.helius-rpc.com/?api-key=${this.apiKey}`;
1820
+ this.restUrl = this.cluster === "devnet" ? `https://api-devnet.helius.xyz/v0` : `https://api.helius.xyz/v0`;
1821
+ }
1822
+ /**
1823
+ * Get all token assets owned by an address using DAS API
1824
+ *
1825
+ * Uses getAssetsByOwner for comprehensive asset information including
1826
+ * NFTs and fungible tokens with metadata.
1827
+ */
1828
+ async getAssetsByOwner(owner) {
1829
+ const assets = [];
1830
+ let page = 1;
1831
+ const limit = 1e3;
1832
+ let hasMore = true;
1833
+ while (hasMore) {
1834
+ const response = await fetch(this.rpcUrl, {
1835
+ method: "POST",
1836
+ headers: { "Content-Type": "application/json" },
1837
+ body: JSON.stringify({
1838
+ jsonrpc: "2.0",
1839
+ id: `sip-${Date.now()}`,
1840
+ method: "getAssetsByOwner",
1841
+ params: {
1842
+ ownerAddress: owner,
1843
+ page,
1844
+ limit,
1845
+ displayOptions: {
1846
+ showFungible: true,
1847
+ showNativeBalance: false
1848
+ }
1849
+ }
1850
+ })
1851
+ });
1852
+ if (!response.ok) {
1853
+ throw new Error(`Helius API error: ${response.status} ${response.statusText}`);
1854
+ }
1855
+ const data = await response.json();
1856
+ if (data.error) {
1857
+ throw new Error(`Helius RPC error: ${data.error.message} (code: ${data.error.code})`);
1858
+ }
1859
+ if (data.result?.items) {
1860
+ for (const item of data.result.items) {
1861
+ if (item.interface !== "FungibleToken" && item.interface !== "FungibleAsset") {
1862
+ continue;
1863
+ }
1864
+ const tokenInfo = item.token_info;
1865
+ if (!tokenInfo?.balance) continue;
1866
+ const balanceValue = typeof tokenInfo.balance === "string" ? BigInt(tokenInfo.balance) : BigInt(Math.floor(tokenInfo.balance));
1867
+ assets.push({
1868
+ mint: item.id,
1869
+ amount: balanceValue,
1870
+ decimals: tokenInfo.decimals ?? 0,
1871
+ symbol: tokenInfo.symbol ?? item.content?.metadata?.symbol,
1872
+ name: item.content?.metadata?.name,
1873
+ logoUri: item.content?.links?.image
1874
+ });
1875
+ }
1876
+ }
1877
+ hasMore = data.result?.items?.length === limit;
1878
+ page++;
1879
+ if (page > 100) {
1880
+ console.warn("[HeliusProvider] Reached page limit (100), stopping pagination");
1881
+ break;
1882
+ }
1883
+ }
1884
+ return assets;
1885
+ }
1886
+ /**
1887
+ * Get token balance for a specific mint using Balances API
1888
+ *
1889
+ * More efficient than getAssetsByOwner when you only need one token's balance.
1890
+ */
1891
+ async getTokenBalance(owner, mint) {
1892
+ try {
1893
+ const url = `${this.restUrl}/addresses/${owner}/balances?api-key=${this.apiKey}`;
1894
+ const response = await fetch(url);
1895
+ if (!response.ok) {
1896
+ const assets = await this.getAssetsByOwner(owner);
1897
+ const asset = assets.find((a) => a.mint === mint);
1898
+ return asset?.amount ?? 0n;
1899
+ }
1900
+ const data = await response.json();
1901
+ const token = data.tokens?.find((t) => t.mint === mint);
1902
+ return token ? BigInt(token.amount) : 0n;
1903
+ } catch (error) {
1904
+ console.warn("[HeliusProvider] getTokenBalance error, falling back to DAS:", error);
1905
+ const assets = await this.getAssetsByOwner(owner);
1906
+ const asset = assets.find((a) => a.mint === mint);
1907
+ return asset?.amount ?? 0n;
1908
+ }
1909
+ }
1910
+ /**
1911
+ * Check if provider supports real-time subscriptions
1912
+ *
1913
+ * Helius supports webhooks for real-time notifications,
1914
+ * but that requires server-side setup. Client-side subscriptions
1915
+ * are not directly supported.
1916
+ */
1917
+ supportsSubscriptions() {
1918
+ return false;
1919
+ }
1920
+ };
1921
+ }
1922
+ });
1923
+
1924
+ // src/chains/solana/providers/generic.ts
1925
+ function validateSolanaAddress(address, paramName) {
1926
+ try {
1927
+ return new import_web33.PublicKey(address);
1928
+ } catch {
1929
+ throw new Error(`Invalid Solana address for ${paramName}: ${address}`);
1930
+ }
1931
+ }
1932
+ var import_web33, import_spl_token3, CLUSTER_ENDPOINTS, GenericProvider;
1933
+ var init_generic = __esm({
1934
+ "src/chains/solana/providers/generic.ts"() {
1935
+ "use strict";
1936
+ import_web33 = require("@solana/web3.js");
1937
+ import_spl_token3 = require("@solana/spl-token");
1938
+ CLUSTER_ENDPOINTS = {
1939
+ "mainnet-beta": "https://api.mainnet-beta.solana.com",
1940
+ devnet: "https://api.devnet.solana.com",
1941
+ testnet: "https://api.testnet.solana.com"
1942
+ };
1943
+ GenericProvider = class {
1944
+ name = "generic";
1945
+ connection;
1946
+ constructor(config) {
1947
+ if (config.connection) {
1948
+ this.connection = config.connection;
1949
+ } else {
1950
+ const endpoint = config.endpoint ?? CLUSTER_ENDPOINTS[config.cluster ?? "mainnet-beta"];
1951
+ this.connection = new import_web33.Connection(endpoint, "confirmed");
1952
+ }
1953
+ }
1954
+ /**
1955
+ * Get all token assets owned by an address using getParsedTokenAccountsByOwner
1956
+ *
1957
+ * Note: This is less efficient than Helius DAS API for large wallets,
1958
+ * but works with any RPC endpoint.
1959
+ */
1960
+ async getAssetsByOwner(owner) {
1961
+ const ownerPubkey = validateSolanaAddress(owner, "owner");
1962
+ const accounts = await this.connection.getParsedTokenAccountsByOwner(
1963
+ ownerPubkey,
1964
+ { programId: import_spl_token3.TOKEN_PROGRAM_ID }
1965
+ );
1966
+ const assets = [];
1967
+ for (const { account } of accounts.value) {
1968
+ const parsed = account.data.parsed;
1969
+ if (parsed.type !== "account") continue;
1970
+ const info = parsed.info;
1971
+ const amount = BigInt(info.tokenAmount.amount);
1972
+ if (amount === 0n) continue;
1973
+ assets.push({
1974
+ mint: info.mint,
1975
+ amount,
1976
+ decimals: info.tokenAmount.decimals,
1977
+ // Generic RPC doesn't provide symbol/name, those need metadata lookup
1978
+ symbol: void 0,
1979
+ name: void 0,
1980
+ logoUri: void 0
1981
+ });
1982
+ }
1983
+ return assets;
1984
+ }
1985
+ /**
1986
+ * Get token balance for a specific mint
1987
+ *
1988
+ * Uses getAccount on the associated token address.
1989
+ */
1990
+ async getTokenBalance(owner, mint) {
1991
+ const ownerPubkey = validateSolanaAddress(owner, "owner");
1992
+ const mintPubkey = validateSolanaAddress(mint, "mint");
1993
+ try {
1994
+ const ata = await (0, import_spl_token3.getAssociatedTokenAddress)(
1995
+ mintPubkey,
1996
+ ownerPubkey,
1997
+ true
1998
+ // allowOwnerOffCurve for PDAs
1999
+ );
2000
+ const account = await (0, import_spl_token3.getAccount)(this.connection, ata);
2001
+ return account.amount;
2002
+ } catch {
2003
+ return 0n;
2004
+ }
2005
+ }
2006
+ /**
2007
+ * Check if provider supports real-time subscriptions
2008
+ *
2009
+ * Generic RPC supports WebSocket subscriptions but they're not
2010
+ * efficient for monitoring token transfers. Returns false.
2011
+ */
2012
+ supportsSubscriptions() {
2013
+ return false;
2014
+ }
2015
+ /**
2016
+ * Get the underlying Connection object
2017
+ *
2018
+ * Useful for advanced operations that need direct RPC access.
2019
+ */
2020
+ getConnection() {
2021
+ return this.connection;
2022
+ }
2023
+ };
2024
+ }
2025
+ });
2026
+
2027
+ // src/chains/solana/providers/interface.ts
2028
+ function createProvider(type, config) {
2029
+ switch (type) {
2030
+ case "helius":
2031
+ return new HeliusProvider(config);
2032
+ case "generic":
2033
+ return new GenericProvider(config);
2034
+ case "quicknode":
2035
+ case "triton":
2036
+ throw new Error(
2037
+ `Provider '${type}' is not yet implemented. Use 'helius' or 'generic' for now. See https://github.com/sip-protocol/sip-protocol/issues/${type === "quicknode" ? "494" : "495"}`
2038
+ );
2039
+ default:
2040
+ throw new Error(`Unknown provider type: ${type}`);
2041
+ }
2042
+ }
2043
+ var init_interface = __esm({
2044
+ "src/chains/solana/providers/interface.ts"() {
2045
+ "use strict";
2046
+ init_helius();
2047
+ init_generic();
2048
+ }
2049
+ });
2050
+
2051
+ // src/chains/solana/providers/webhook.ts
2052
+ function createWebhookHandler(config) {
2053
+ const { viewingPrivateKey, spendingPublicKey, onPaymentFound, onError } = config;
2054
+ if (!viewingPrivateKey || !viewingPrivateKey.startsWith("0x")) {
2055
+ throw new ValidationError("viewingPrivateKey must be a valid hex string starting with 0x", "viewingPrivateKey");
2056
+ }
2057
+ if (!spendingPublicKey || !spendingPublicKey.startsWith("0x")) {
2058
+ throw new ValidationError("spendingPublicKey must be a valid hex string starting with 0x", "spendingPublicKey");
2059
+ }
2060
+ if (typeof onPaymentFound !== "function") {
2061
+ throw new ValidationError("onPaymentFound callback is required", "onPaymentFound");
2062
+ }
2063
+ return async (payload) => {
2064
+ const transactions = Array.isArray(payload) ? payload : [payload];
2065
+ const results = [];
2066
+ for (const tx of transactions) {
2067
+ try {
2068
+ if (isRawTransaction(tx)) {
2069
+ const result = await processRawTransaction(
2070
+ tx,
2071
+ viewingPrivateKey,
2072
+ spendingPublicKey,
2073
+ onPaymentFound
2074
+ );
2075
+ results.push(result);
2076
+ } else {
2077
+ results.push({
2078
+ found: false,
2079
+ signature: tx.signature
2080
+ });
2081
+ }
2082
+ } catch (error) {
2083
+ onError?.(error, isRawTransaction(tx) ? tx : void 0);
2084
+ results.push({
2085
+ found: false,
2086
+ signature: getSignature(tx)
2087
+ });
2088
+ }
2089
+ }
2090
+ return results;
2091
+ };
2092
+ }
2093
+ async function processRawTransaction(tx, viewingPrivateKey, spendingPublicKey, onPaymentFound) {
2094
+ const signature = tx.transaction?.signatures?.[0] ?? "unknown";
2095
+ if (tx.meta?.err) {
2096
+ return { found: false, signature };
2097
+ }
2098
+ if (!tx.meta?.logMessages) {
2099
+ return { found: false, signature };
2100
+ }
2101
+ for (const log2 of tx.meta.logMessages) {
2102
+ if (!log2.includes(SIP_MEMO_PREFIX)) continue;
2103
+ const memoMatch = log2.match(/Program log: (.+)/);
2104
+ if (!memoMatch) continue;
2105
+ const memoContent = memoMatch[1];
2106
+ const announcement = parseAnnouncement(memoContent);
2107
+ if (!announcement) continue;
2108
+ const ephemeralPubKeyHex = solanaAddressToEd25519PublicKey(
2109
+ announcement.ephemeralPublicKey
2110
+ );
2111
+ const viewTagNumber = parseInt(announcement.viewTag, 16);
2112
+ if (!Number.isFinite(viewTagNumber) || viewTagNumber < 0 || viewTagNumber > 255) {
2113
+ continue;
2114
+ }
2115
+ const stealthAddressToCheck = {
2116
+ address: announcement.stealthAddress ? solanaAddressToEd25519PublicKey(announcement.stealthAddress) : "0x" + "00".repeat(32),
2117
+ ephemeralPublicKey: ephemeralPubKeyHex,
2118
+ viewTag: viewTagNumber
2119
+ };
2120
+ let isOurs = false;
2121
+ try {
2122
+ isOurs = checkEd25519StealthAddress(
2123
+ stealthAddressToCheck,
2124
+ viewingPrivateKey,
2125
+ spendingPublicKey
2126
+ );
2127
+ } catch {
2128
+ continue;
2129
+ }
2130
+ if (isOurs) {
2131
+ const transferInfo = parseTokenTransferFromWebhook(tx);
2132
+ const payment = {
2133
+ stealthAddress: announcement.stealthAddress || "",
2134
+ ephemeralPublicKey: announcement.ephemeralPublicKey,
2135
+ amount: transferInfo?.amount ?? 0n,
2136
+ mint: transferInfo?.mint ?? "",
2137
+ tokenSymbol: transferInfo?.mint ? getTokenSymbol2(transferInfo.mint) : void 0,
2138
+ txSignature: signature,
2139
+ slot: tx.slot,
2140
+ timestamp: tx.blockTime
2141
+ };
2142
+ try {
2143
+ await onPaymentFound(payment);
2144
+ } catch {
2145
+ }
2146
+ return { found: true, payment, signature };
2147
+ }
2148
+ }
2149
+ return { found: false, signature };
2150
+ }
2151
+ function parseTokenTransferFromWebhook(tx) {
2152
+ const { preTokenBalances, postTokenBalances } = tx.meta;
2153
+ if (!postTokenBalances || !preTokenBalances) {
2154
+ return null;
2155
+ }
2156
+ for (const post of postTokenBalances) {
2157
+ const pre = preTokenBalances.find(
2158
+ (p) => p.accountIndex === post.accountIndex
2159
+ );
2160
+ const postAmount = BigInt(post.uiTokenAmount.amount);
2161
+ const preAmount = pre ? BigInt(pre.uiTokenAmount.amount) : 0n;
2162
+ if (postAmount > preAmount) {
2163
+ return {
2164
+ mint: post.mint,
2165
+ amount: postAmount - preAmount
2166
+ };
2167
+ }
2168
+ }
2169
+ return null;
2170
+ }
2171
+ function getTokenSymbol2(mint) {
2172
+ for (const [symbol, address] of Object.entries(SOLANA_TOKEN_MINTS)) {
2173
+ if (address === mint) {
2174
+ return symbol;
2175
+ }
2176
+ }
2177
+ return void 0;
2178
+ }
2179
+ function isRawTransaction(tx) {
2180
+ return typeof tx === "object" && tx !== null && "meta" in tx && "transaction" in tx && Array.isArray(tx.transaction?.signatures);
2181
+ }
2182
+ function getSignature(tx) {
2183
+ if ("signature" in tx && typeof tx.signature === "string") {
2184
+ return tx.signature;
2185
+ }
2186
+ if (isRawTransaction(tx)) {
2187
+ return tx.transaction?.signatures?.[0] ?? "unknown";
2188
+ }
2189
+ return "unknown";
2190
+ }
2191
+ async function processWebhookTransaction(transaction, viewingPrivateKey, spendingPublicKey) {
2192
+ const result = await processRawTransaction(
2193
+ transaction,
2194
+ viewingPrivateKey,
2195
+ spendingPublicKey,
2196
+ () => {
2197
+ }
2198
+ // No-op callback
2199
+ );
2200
+ return result.found ? result.payment ?? null : null;
2201
+ }
2202
+ var init_webhook = __esm({
2203
+ "src/chains/solana/providers/webhook.ts"() {
2204
+ "use strict";
2205
+ init_stealth();
2206
+ init_types();
2207
+ init_constants();
2208
+ init_errors();
2209
+ }
2210
+ });
2211
+
2212
+ // src/chains/solana/providers/index.ts
2213
+ var init_providers = __esm({
2214
+ "src/chains/solana/providers/index.ts"() {
2215
+ "use strict";
2216
+ init_interface();
2217
+ init_helius();
2218
+ init_generic();
2219
+ init_webhook();
1759
2220
  }
1760
2221
  });
1761
2222
 
@@ -1764,6 +2225,8 @@ var solana_exports = {};
1764
2225
  __export(solana_exports, {
1765
2226
  ATA_RENT_LAMPORTS: () => ATA_RENT_LAMPORTS,
1766
2227
  ESTIMATED_TX_FEE_LAMPORTS: () => ESTIMATED_TX_FEE_LAMPORTS,
2228
+ GenericProvider: () => GenericProvider,
2229
+ HeliusProvider: () => HeliusProvider,
1767
2230
  MEMO_PROGRAM_ID: () => MEMO_PROGRAM_ID,
1768
2231
  SIP_MEMO_PREFIX: () => SIP_MEMO_PREFIX,
1769
2232
  SOLANA_EXPLORER_URLS: () => SOLANA_EXPLORER_URLS,
@@ -1772,6 +2235,8 @@ __export(solana_exports, {
1772
2235
  SOLANA_TOKEN_MINTS: () => SOLANA_TOKEN_MINTS,
1773
2236
  claimStealthPayment: () => claimStealthPayment,
1774
2237
  createAnnouncementMemo: () => createAnnouncementMemo,
2238
+ createProvider: () => createProvider,
2239
+ createWebhookHandler: () => createWebhookHandler,
1775
2240
  estimatePrivateTransferFee: () => estimatePrivateTransferFee,
1776
2241
  getExplorerUrl: () => getExplorerUrl,
1777
2242
  getStealthBalance: () => getStealthBalance,
@@ -1779,6 +2244,7 @@ __export(solana_exports, {
1779
2244
  getTokenMint: () => getTokenMint,
1780
2245
  hasTokenAccount: () => hasTokenAccount,
1781
2246
  parseAnnouncement: () => parseAnnouncement,
2247
+ processWebhookTransaction: () => processWebhookTransaction,
1782
2248
  scanForPayments: () => scanForPayments,
1783
2249
  sendPrivateSPLTransfer: () => sendPrivateSPLTransfer
1784
2250
  });
@@ -1789,6 +2255,8 @@ var init_solana = __esm({
1789
2255
  init_types();
1790
2256
  init_transfer();
1791
2257
  init_scan();
2258
+ init_providers();
2259
+ init_providers();
1792
2260
  }
1793
2261
  });
1794
2262
 
@@ -4947,6 +5415,8 @@ var browser_exports = {};
4947
5415
  __export(browser_exports, {
4948
5416
  ATTESTATION_VERSION: () => ATTESTATION_VERSION,
4949
5417
  AptosStealthService: () => AptosStealthService,
5418
+ AttestationGatedDisclosure: () => AttestationGatedDisclosure,
5419
+ AttestationSchema: () => AttestationSchema,
4950
5420
  AuditorKeyDerivation: () => AuditorKeyDerivation,
4951
5421
  AuditorType: () => AuditorType,
4952
5422
  BaseWalletAdapter: () => BaseWalletAdapter,
@@ -4965,11 +5435,14 @@ __export(browser_exports, {
4965
5435
  ErrorCode: () => ErrorCode,
4966
5436
  EthereumChainId: () => EthereumChainId,
4967
5437
  EthereumWalletAdapter: () => EthereumWalletAdapter,
5438
+ GenericProvider: () => GenericProvider,
4968
5439
  HardwareErrorCode: () => HardwareErrorCode,
4969
5440
  HardwareWalletError: () => HardwareWalletError,
5441
+ HeliusProvider: () => HeliusProvider,
4970
5442
  IntentBuilder: () => IntentBuilder,
4971
5443
  IntentError: () => IntentError,
4972
- IntentStatus: () => import_types58.IntentStatus,
5444
+ IntentStatus: () => import_types59.IntentStatus,
5445
+ KNOWN_EXCHANGES: () => KNOWN_EXCHANGES,
4973
5446
  LedgerWalletAdapter: () => LedgerWalletAdapter,
4974
5447
  MEMO_PROGRAM_ID: () => MEMO_PROGRAM_ID,
4975
5448
  MockEthereumAdapter: () => MockEthereumAdapter,
@@ -4979,31 +5452,34 @@ __export(browser_exports, {
4979
5452
  MockSolver: () => MockSolver,
4980
5453
  MockTrezorAdapter: () => MockTrezorAdapter,
4981
5454
  MockWalletAdapter: () => MockWalletAdapter,
4982
- NATIVE_TOKENS: () => import_types58.NATIVE_TOKENS,
5455
+ NATIVE_TOKENS: () => import_types59.NATIVE_TOKENS,
4983
5456
  NEARIntentsAdapter: () => NEARIntentsAdapter,
4984
5457
  NEARIntentsBackend: () => NEARIntentsBackend,
4985
5458
  NetworkError: () => NetworkError,
4986
5459
  ORACLE_DOMAIN: () => ORACLE_DOMAIN,
4987
5460
  OneClickClient: () => OneClickClient,
4988
- OneClickDepositMode: () => import_types62.OneClickDepositMode,
4989
- OneClickErrorCode: () => import_types62.OneClickErrorCode,
4990
- OneClickSwapStatus: () => import_types62.OneClickSwapStatus,
4991
- OneClickSwapType: () => import_types62.OneClickSwapType,
5461
+ OneClickDepositMode: () => import_types63.OneClickDepositMode,
5462
+ OneClickErrorCode: () => import_types63.OneClickErrorCode,
5463
+ OneClickSwapStatus: () => import_types63.OneClickSwapStatus,
5464
+ OneClickSwapType: () => import_types63.OneClickSwapType,
4992
5465
  PaymentBuilder: () => PaymentBuilder,
4993
- PaymentStatus: () => import_types59.PaymentStatus,
4994
- PrivacyLevel: () => import_types58.PrivacyLevel,
5466
+ PaymentStatus: () => import_types60.PaymentStatus,
5467
+ PrivacyBackendRegistry: () => PrivacyBackendRegistry,
5468
+ PrivacyLevel: () => import_types59.PrivacyLevel,
5469
+ PrivacySmartRouter: () => SmartRouter2,
4995
5470
  PrivateNFT: () => PrivateNFT,
4996
5471
  PrivateVoting: () => PrivateVoting,
4997
5472
  ProofError: () => ProofError,
4998
5473
  ProofGenerationError: () => ProofGenerationError,
4999
5474
  ProofNotImplementedError: () => ProofNotImplementedError,
5000
5475
  ProofWorker: () => ProofWorker,
5001
- ProposalStatus: () => import_types60.ProposalStatus,
5002
- ReportStatus: () => import_types61.ReportStatus,
5476
+ ProposalStatus: () => import_types61.ProposalStatus,
5477
+ ReportStatus: () => import_types62.ReportStatus,
5003
5478
  SIP: () => SIP,
5004
5479
  SIPError: () => SIPError,
5480
+ SIPNativeBackend: () => SIPNativeBackend,
5005
5481
  SIP_MEMO_PREFIX: () => SIP_MEMO_PREFIX,
5006
- SIP_VERSION: () => import_types58.SIP_VERSION,
5482
+ SIP_VERSION: () => import_types59.SIP_VERSION,
5007
5483
  SOLANA_EXPLORER_URLS: () => SOLANA_EXPLORER_URLS,
5008
5484
  SOLANA_RPC_ENDPOINTS: () => SOLANA_RPC_ENDPOINTS,
5009
5485
  SOLANA_TOKEN_DECIMALS: () => SOLANA_TOKEN_DECIMALS,
@@ -5018,14 +5494,15 @@ __export(browser_exports, {
5018
5494
  SolanaSameChainExecutor: () => SolanaSameChainExecutor,
5019
5495
  SolanaWalletAdapter: () => SolanaWalletAdapter,
5020
5496
  SuiStealthService: () => SuiStealthService,
5497
+ SurveillanceAnalyzer: () => SurveillanceAnalyzer,
5021
5498
  SwapStatus: () => SwapStatus,
5022
5499
  ThresholdViewingKey: () => ThresholdViewingKey,
5023
5500
  Treasury: () => Treasury,
5024
5501
  TrezorWalletAdapter: () => TrezorWalletAdapter,
5025
5502
  ValidationError: () => ValidationError,
5026
5503
  WalletError: () => WalletError,
5027
- WalletErrorCode: () => import_types57.WalletErrorCode,
5028
- ZcashErrorCode: () => import_types63.ZcashErrorCode,
5504
+ WalletErrorCode: () => import_types58.WalletErrorCode,
5505
+ ZcashErrorCode: () => import_types64.ZcashErrorCode,
5029
5506
  ZcashNativeBackend: () => ZcashNativeBackend,
5030
5507
  ZcashRPCClient: () => ZcashRPCClient,
5031
5508
  ZcashRPCError: () => ZcashRPCError,
@@ -5034,11 +5511,15 @@ __export(browser_exports, {
5034
5511
  addBlindings: () => addBlindings,
5035
5512
  addCommitments: () => addCommitments,
5036
5513
  addOracle: () => addOracle,
5514
+ analyzeAddressReuse: () => analyzeAddressReuse,
5515
+ analyzeTemporalPatterns: () => analyzeTemporalPatterns,
5037
5516
  aptosAddressToAuthKey: () => aptosAddressToAuthKey,
5038
5517
  attachProofs: () => attachProofs,
5039
5518
  base58ToHex: () => base58ToHex,
5040
- browserBytesToHex: () => bytesToHex12,
5519
+ browserBytesToHex: () => bytesToHex11,
5041
5520
  browserHexToBytes: () => hexToBytes10,
5521
+ calculatePrivacyScore: () => calculatePrivacyScore,
5522
+ calculateSIPComparison: () => calculateSIPComparison,
5042
5523
  checkAptosStealthAddress: () => checkAptosStealthAddress,
5043
5524
  checkEd25519StealthAddress: () => checkEd25519StealthAddress,
5044
5525
  checkMobileWASMCompatibility: () => checkMobileWASMCompatibility,
@@ -5054,6 +5535,7 @@ __export(browser_exports, {
5054
5535
  createEthereumAdapter: () => createEthereumAdapter,
5055
5536
  createKeySpendOnlyOutput: () => createKeySpendOnlyOutput,
5056
5537
  createLedgerAdapter: () => createLedgerAdapter,
5538
+ createMockAttestation: () => createMockAttestation,
5057
5539
  createMockEthereumAdapter: () => createMockEthereumAdapter,
5058
5540
  createMockEthereumProvider: () => createMockEthereumProvider,
5059
5541
  createMockLedgerAdapter: () => createMockLedgerAdapter,
@@ -5068,6 +5550,7 @@ __export(browser_exports, {
5068
5550
  createPrivateOwnership: () => createPrivateOwnership,
5069
5551
  createPrivateVoting: () => createPrivateVoting,
5070
5552
  createProductionSIP: () => createProductionSIP,
5553
+ createProvider: () => createProvider,
5071
5554
  createSIP: () => createSIP,
5072
5555
  createSameChainExecutor: () => createSameChainExecutor,
5073
5556
  createSealedBidAuction: () => createSealedBidAuction,
@@ -5075,9 +5558,11 @@ __export(browser_exports, {
5075
5558
  createShieldedPayment: () => createShieldedPayment,
5076
5559
  createSmartRouter: () => createSmartRouter,
5077
5560
  createSolanaAdapter: () => createSolanaAdapter,
5561
+ createSurveillanceAnalyzer: () => createSurveillanceAnalyzer,
5078
5562
  createTaprootOutput: () => createTaprootOutput,
5079
5563
  createTrezorAdapter: () => createTrezorAdapter,
5080
5564
  createWalletFactory: () => createWalletFactory,
5565
+ createWebhookHandler: () => createWebhookHandler,
5081
5566
  createWorkerBlobURL: () => createWorkerBlobURL,
5082
5567
  createZcashClient: () => createZcashClient,
5083
5568
  createZcashNativeBackend: () => createZcashNativeBackend,
@@ -5087,6 +5572,7 @@ __export(browser_exports, {
5087
5572
  decodeTaprootAddress: () => decodeTaprootAddress,
5088
5573
  decryptMemo: () => decryptMemo,
5089
5574
  decryptWithViewing: () => decryptWithViewing,
5575
+ defaultRegistry: () => defaultRegistry,
5090
5576
  deriveAptosStealthPrivateKey: () => deriveAptosStealthPrivateKey,
5091
5577
  deriveEd25519StealthPrivateKey: () => deriveEd25519StealthPrivateKey,
5092
5578
  deriveOracleId: () => deriveOracleId,
@@ -5096,7 +5582,9 @@ __export(browser_exports, {
5096
5582
  deserializeAttestationMessage: () => deserializeAttestationMessage,
5097
5583
  deserializeIntent: () => deserializeIntent,
5098
5584
  deserializePayment: () => deserializePayment,
5585
+ detectClusters: () => detectClusters,
5099
5586
  detectEthereumWallets: () => detectEthereumWallets,
5587
+ detectExchangeExposure: () => detectExchangeExposure,
5100
5588
  detectMobileBrowser: () => detectMobileBrowser,
5101
5589
  detectMobilePlatform: () => detectMobilePlatform,
5102
5590
  detectSolanaWallets: () => detectSolanaWallets,
@@ -5108,6 +5596,7 @@ __export(browser_exports, {
5108
5596
  encryptForViewing: () => encryptForViewing,
5109
5597
  estimatePrivateTransferFee: () => estimatePrivateTransferFee,
5110
5598
  featureNotSupportedError: () => featureNotSupportedError,
5599
+ fetchAttestation: () => fetchAttestation,
5111
5600
  formatStablecoinAmount: () => formatStablecoinAmount,
5112
5601
  fromHex: () => fromHex,
5113
5602
  fromStablecoinUnits: () => fromStablecoinUnits,
@@ -5166,7 +5655,7 @@ __export(browser_exports, {
5166
5655
  isExpired: () => isExpired,
5167
5656
  isNonNegativeAmount: () => isNonNegativeAmount,
5168
5657
  isPaymentExpired: () => isPaymentExpired,
5169
- isPrivate: () => import_types58.isPrivate,
5658
+ isPrivate: () => import_types59.isPrivate,
5170
5659
  isPrivateWalletAdapter: () => isPrivateWalletAdapter,
5171
5660
  isSIPError: () => isSIPError,
5172
5661
  isSameChainSupported: () => isSameChainSupported,
@@ -5196,6 +5685,7 @@ __export(browser_exports, {
5196
5685
  normalizeSuiAddress: () => normalizeSuiAddress,
5197
5686
  notConnectedError: () => notConnectedError,
5198
5687
  parseAnnouncement: () => parseAnnouncement,
5688
+ processWebhookTransaction: () => processWebhookTransaction,
5199
5689
  proveOwnership: () => proveOwnership,
5200
5690
  publicKeyToEthAddress: () => publicKeyToEthAddress,
5201
5691
  registerWallet: () => registerWallet,
@@ -5219,7 +5709,7 @@ __export(browser_exports, {
5219
5709
  subtractCommitments: () => subtractCommitments,
5220
5710
  supportsSharedArrayBuffer: () => supportsSharedArrayBuffer,
5221
5711
  supportsTouch: () => supportsTouch,
5222
- supportsViewingKey: () => import_types58.supportsViewingKey,
5712
+ supportsViewingKey: () => import_types59.supportsViewingKey,
5223
5713
  supportsWASMBulkMemory: () => supportsWASMBulkMemory,
5224
5714
  supportsWASMSimd: () => supportsWASMSimd,
5225
5715
  supportsWebBluetooth: () => supportsWebBluetooth,
@@ -5239,6 +5729,7 @@ __export(browser_exports, {
5239
5729
  validateScalar: () => validateScalar,
5240
5730
  validateViewingKey: () => validateViewingKey,
5241
5731
  verifyAttestation: () => verifyAttestation,
5732
+ verifyAttestationSignature: () => verifyAttestationSignature,
5242
5733
  verifyCommitment: () => verifyCommitment,
5243
5734
  verifyOpening: () => verifyOpening,
5244
5735
  verifyOracleSignature: () => verifyOracleSignature,
@@ -5254,7 +5745,7 @@ module.exports = __toCommonJS(browser_exports);
5254
5745
  init_errors();
5255
5746
 
5256
5747
  // src/sip.ts
5257
- var import_types7 = require("@sip-protocol/types");
5748
+ var import_types8 = require("@sip-protocol/types");
5258
5749
 
5259
5750
  // src/intent.ts
5260
5751
  var import_types = require("@sip-protocol/types");
@@ -7173,7 +7664,7 @@ var SIP = class {
7173
7664
  this.config = {
7174
7665
  ...config,
7175
7666
  mode: config.mode ?? "demo",
7176
- defaultPrivacy: config.defaultPrivacy ?? import_types7.PrivacyLevel.SHIELDED
7667
+ defaultPrivacy: config.defaultPrivacy ?? import_types8.PrivacyLevel.SHIELDED
7177
7668
  };
7178
7669
  this.proofProvider = config.proofProvider;
7179
7670
  if (config.intentsAdapter) {
@@ -7378,8 +7869,8 @@ var SIP = class {
7378
7869
  "intentsAdapter"
7379
7870
  );
7380
7871
  }
7381
- const metaAddr = recipientMetaAddress ?? (params.privacy !== import_types7.PrivacyLevel.TRANSPARENT ? this.stealthKeys?.metaAddress : void 0);
7382
- if (params.privacy !== import_types7.PrivacyLevel.TRANSPARENT && !metaAddr) {
7872
+ const metaAddr = recipientMetaAddress ?? (params.privacy !== import_types8.PrivacyLevel.TRANSPARENT ? this.stealthKeys?.metaAddress : void 0);
7873
+ if (params.privacy !== import_types8.PrivacyLevel.TRANSPARENT && !metaAddr) {
7383
7874
  throw new ValidationError(
7384
7875
  "Stealth meta-address required for privacy modes. Call generateStealthKeys() or provide recipientMetaAddress.",
7385
7876
  "recipientMetaAddress"
@@ -7470,10 +7961,10 @@ var SIP = class {
7470
7961
  }
7471
7962
  );
7472
7963
  this.pendingSwaps.delete(quote.intentId);
7473
- const isSuccess = finalStatus.status === import_types7.OneClickSwapStatus.SUCCESS;
7964
+ const isSuccess = finalStatus.status === import_types8.OneClickSwapStatus.SUCCESS;
7474
7965
  return {
7475
7966
  intentId: intent.intentId,
7476
- status: isSuccess ? import_types7.IntentStatus.FULFILLED : import_types7.IntentStatus.FAILED,
7967
+ status: isSuccess ? import_types8.IntentStatus.FULFILLED : import_types8.IntentStatus.FAILED,
7477
7968
  outputAmount: quote.outputAmount,
7478
7969
  txHash: finalStatus.settlementTxHash ?? depositTxHash,
7479
7970
  fulfilledAt: Math.floor(Date.now() / 1e3),
@@ -7540,9 +8031,9 @@ var SIP = class {
7540
8031
  await new Promise((resolve) => setTimeout(resolve, 2e3));
7541
8032
  return {
7542
8033
  intentId: intent.intentId,
7543
- status: import_types7.IntentStatus.FULFILLED,
8034
+ status: import_types8.IntentStatus.FULFILLED,
7544
8035
  outputAmount: quote.outputAmount,
7545
- txHash: intent.privacyLevel === import_types7.PrivacyLevel.TRANSPARENT ? `0x${Date.now().toString(16)}` : void 0,
8036
+ txHash: intent.privacyLevel === import_types8.PrivacyLevel.TRANSPARENT ? `0x${Date.now().toString(16)}` : void 0,
7546
8037
  fulfilledAt: Math.floor(Date.now() / 1e3)
7547
8038
  };
7548
8039
  }
@@ -7584,7 +8075,7 @@ var SIP = class {
7584
8075
  }
7585
8076
  const { sendPrivateSPLTransfer: sendPrivateSPLTransfer2 } = await Promise.resolve().then(() => (init_solana(), solana_exports));
7586
8077
  const { PublicKey: SolanaPublicKey } = await import("@solana/web3.js");
7587
- const { getAssociatedTokenAddress: getAssociatedTokenAddress3 } = await import("@solana/spl-token");
8078
+ const { getAssociatedTokenAddress: getAssociatedTokenAddress4 } = await import("@solana/spl-token");
7588
8079
  const { SOLANA_TOKEN_MINTS: SOLANA_TOKEN_MINTS2 } = await Promise.resolve().then(() => (init_constants(), constants_exports));
7589
8080
  let mint;
7590
8081
  if (params.token in SOLANA_TOKEN_MINTS2) {
@@ -7592,7 +8083,7 @@ var SIP = class {
7592
8083
  } else {
7593
8084
  mint = new SolanaPublicKey(params.token);
7594
8085
  }
7595
- const senderTokenAccount = await getAssociatedTokenAddress3(
8086
+ const senderTokenAccount = await getAssociatedTokenAddress4(
7596
8087
  mint,
7597
8088
  params.sender
7598
8089
  );
@@ -8423,7 +8914,7 @@ function hexToBytes10(hex) {
8423
8914
  }
8424
8915
  return bytes;
8425
8916
  }
8426
- function bytesToHex12(bytes) {
8917
+ function bytesToHex11(bytes) {
8427
8918
  return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
8428
8919
  }
8429
8920
  function isBrowser() {
@@ -8486,7 +8977,7 @@ var CHAIN_NUMERIC_IDS = {
8486
8977
  };
8487
8978
 
8488
8979
  // src/oracle/verification.ts
8489
- var import_ed255192 = require("@noble/curves/ed25519");
8980
+ var import_ed255193 = require("@noble/curves/ed25519");
8490
8981
  var import_sha25610 = require("@noble/hashes/sha256");
8491
8982
  var import_utils14 = require("@noble/hashes/utils");
8492
8983
 
@@ -8652,7 +9143,7 @@ function verifyAttestation(attestation, registry) {
8652
9143
  const signatureBytes = (0, import_utils14.hexToBytes)(
8653
9144
  sig.signature.startsWith("0x") ? sig.signature.slice(2) : sig.signature
8654
9145
  );
8655
- const isValid = import_ed255192.ed25519.verify(signatureBytes, messageHash, publicKeyBytes);
9146
+ const isValid = import_ed255193.ed25519.verify(signatureBytes, messageHash, publicKeyBytes);
8656
9147
  if (isValid) {
8657
9148
  validCount++;
8658
9149
  validOracles.push(sig.oracleId);
@@ -8680,14 +9171,14 @@ function verifyOracleSignature(signature, messageHash, oracle) {
8680
9171
  const signatureBytes = (0, import_utils14.hexToBytes)(
8681
9172
  signature.signature.startsWith("0x") ? signature.signature.slice(2) : signature.signature
8682
9173
  );
8683
- return import_ed255192.ed25519.verify(signatureBytes, messageHash, publicKeyBytes);
9174
+ return import_ed255193.ed25519.verify(signatureBytes, messageHash, publicKeyBytes);
8684
9175
  } catch {
8685
9176
  return false;
8686
9177
  }
8687
9178
  }
8688
9179
  function signAttestationMessage(messageHash, privateKey) {
8689
- const signature = import_ed255192.ed25519.sign(messageHash, privateKey);
8690
- const publicKey = import_ed255192.ed25519.getPublicKey(privateKey);
9180
+ const signature = import_ed255193.ed25519.sign(messageHash, privateKey);
9181
+ const publicKey = import_ed255193.ed25519.getPublicKey(privateKey);
8691
9182
  const oracleId = deriveOracleId(publicKey);
8692
9183
  return {
8693
9184
  oracleId,
@@ -8743,13 +9234,13 @@ function hasEnoughOracles(registry) {
8743
9234
  }
8744
9235
 
8745
9236
  // src/index.ts
8746
- var import_types58 = require("@sip-protocol/types");
8747
9237
  var import_types59 = require("@sip-protocol/types");
8748
9238
  var import_types60 = require("@sip-protocol/types");
8749
9239
  var import_types61 = require("@sip-protocol/types");
9240
+ var import_types62 = require("@sip-protocol/types");
8750
9241
 
8751
9242
  // src/solver/mock-solver.ts
8752
- var import_types10 = require("@sip-protocol/types");
9243
+ var import_types11 = require("@sip-protocol/types");
8753
9244
  var import_utils15 = require("@noble/hashes/utils");
8754
9245
  var MockSolver = class {
8755
9246
  info;
@@ -8875,7 +9366,7 @@ var MockSolver = class {
8875
9366
  status.error = "Simulated failure for testing";
8876
9367
  return {
8877
9368
  intentId: intent.intentId,
8878
- status: import_types10.IntentStatus.FAILED,
9369
+ status: import_types11.IntentStatus.FAILED,
8879
9370
  fulfilledAt: Math.floor(Date.now() / 1e3),
8880
9371
  error: status.error
8881
9372
  };
@@ -8885,7 +9376,7 @@ var MockSolver = class {
8885
9376
  status.txHash = txHash;
8886
9377
  return {
8887
9378
  intentId: intent.intentId,
8888
- status: import_types10.IntentStatus.FULFILLED,
9379
+ status: import_types11.IntentStatus.FULFILLED,
8889
9380
  outputAmount: quote.outputAmount,
8890
9381
  txHash: intent.privacyLevel === "transparent" ? txHash : void 0,
8891
9382
  fulfillmentProof: {
@@ -8931,7 +9422,7 @@ function createMockSolver(config) {
8931
9422
  }
8932
9423
 
8933
9424
  // src/index.ts
8934
- var import_types62 = require("@sip-protocol/types");
9425
+ var import_types63 = require("@sip-protocol/types");
8935
9426
 
8936
9427
  // src/settlement/interface.ts
8937
9428
  var SwapStatus = /* @__PURE__ */ ((SwapStatus2) => {
@@ -9338,21 +9829,21 @@ function createSmartRouter(registry) {
9338
9829
  }
9339
9830
 
9340
9831
  // src/settlement/backends/near-intents.ts
9341
- var import_types11 = require("@sip-protocol/types");
9832
+ var import_types12 = require("@sip-protocol/types");
9342
9833
  init_errors();
9343
9834
  function mapOneClickStatus(status) {
9344
9835
  switch (status) {
9345
- case import_types11.OneClickSwapStatus.PENDING_DEPOSIT:
9836
+ case import_types12.OneClickSwapStatus.PENDING_DEPOSIT:
9346
9837
  return "pending_deposit" /* PENDING_DEPOSIT */;
9347
- case import_types11.OneClickSwapStatus.PROCESSING:
9838
+ case import_types12.OneClickSwapStatus.PROCESSING:
9348
9839
  return "in_progress" /* IN_PROGRESS */;
9349
- case import_types11.OneClickSwapStatus.SUCCESS:
9840
+ case import_types12.OneClickSwapStatus.SUCCESS:
9350
9841
  return "success" /* SUCCESS */;
9351
- case import_types11.OneClickSwapStatus.FAILED:
9842
+ case import_types12.OneClickSwapStatus.FAILED:
9352
9843
  return "failed" /* FAILED */;
9353
- case import_types11.OneClickSwapStatus.INCOMPLETE_DEPOSIT:
9844
+ case import_types12.OneClickSwapStatus.INCOMPLETE_DEPOSIT:
9354
9845
  return "failed" /* FAILED */;
9355
- case import_types11.OneClickSwapStatus.REFUNDED:
9846
+ case import_types12.OneClickSwapStatus.REFUNDED:
9356
9847
  return "refunded" /* REFUNDED */;
9357
9848
  default:
9358
9849
  return "pending_deposit" /* PENDING_DEPOSIT */;
@@ -9390,9 +9881,9 @@ var NEARIntentsBackend = class {
9390
9881
  "zcash"
9391
9882
  ],
9392
9883
  supportedPrivacyLevels: [
9393
- import_types11.PrivacyLevel.TRANSPARENT,
9394
- import_types11.PrivacyLevel.SHIELDED,
9395
- import_types11.PrivacyLevel.COMPLIANT
9884
+ import_types12.PrivacyLevel.TRANSPARENT,
9885
+ import_types12.PrivacyLevel.SHIELDED,
9886
+ import_types12.PrivacyLevel.COMPLIANT
9396
9887
  ],
9397
9888
  supportsCancellation: false,
9398
9889
  supportsRefunds: true,
@@ -9649,13 +10140,13 @@ var NEARIntentsBackend = class {
9649
10140
  if (!params.privacyLevel) {
9650
10141
  throw new ValidationError("privacyLevel is required", "privacyLevel");
9651
10142
  }
9652
- if (params.privacyLevel !== import_types11.PrivacyLevel.TRANSPARENT && !params.recipientMetaAddress) {
10143
+ if (params.privacyLevel !== import_types12.PrivacyLevel.TRANSPARENT && !params.recipientMetaAddress) {
9653
10144
  throw new ValidationError(
9654
10145
  "recipientMetaAddress is required for shielded/compliant privacy modes",
9655
10146
  "recipientMetaAddress"
9656
10147
  );
9657
10148
  }
9658
- if (params.privacyLevel === import_types11.PrivacyLevel.TRANSPARENT && !params.senderAddress) {
10149
+ if (params.privacyLevel === import_types12.PrivacyLevel.TRANSPARENT && !params.senderAddress) {
9659
10150
  throw new ValidationError(
9660
10151
  "senderAddress is required for transparent mode",
9661
10152
  "senderAddress"
@@ -9694,7 +10185,7 @@ function createNEARIntentsBackend(config) {
9694
10185
  }
9695
10186
 
9696
10187
  // src/settlement/backends/zcash-native.ts
9697
- var import_types12 = require("@sip-protocol/types");
10188
+ var import_types13 = require("@sip-protocol/types");
9698
10189
  init_errors();
9699
10190
  var ZcashNativeBackend = class {
9700
10191
  name = "zcash-native";
@@ -9713,9 +10204,9 @@ var ZcashNativeBackend = class {
9713
10204
  supportedSourceChains: ["zcash"],
9714
10205
  supportedDestinationChains: ["zcash"],
9715
10206
  supportedPrivacyLevels: [
9716
- import_types12.PrivacyLevel.TRANSPARENT,
9717
- import_types12.PrivacyLevel.SHIELDED,
9718
- import_types12.PrivacyLevel.COMPLIANT
10207
+ import_types13.PrivacyLevel.TRANSPARENT,
10208
+ import_types13.PrivacyLevel.SHIELDED,
10209
+ import_types13.PrivacyLevel.COMPLIANT
9719
10210
  ],
9720
10211
  supportsCancellation: false,
9721
10212
  supportsRefunds: false,
@@ -9754,7 +10245,7 @@ var ZcashNativeBackend = class {
9754
10245
  const minAmountOut = amountOut * BigInt(99) / BigInt(100);
9755
10246
  let depositAddress;
9756
10247
  let recipientAddress;
9757
- if (privacyLevel === import_types12.PrivacyLevel.SHIELDED || privacyLevel === import_types12.PrivacyLevel.COMPLIANT) {
10248
+ if (privacyLevel === import_types13.PrivacyLevel.SHIELDED || privacyLevel === import_types13.PrivacyLevel.COMPLIANT) {
9758
10249
  if (typeof recipientMetaAddress === "string") {
9759
10250
  recipientAddress = recipientMetaAddress;
9760
10251
  } else if (recipientMetaAddress) {
@@ -10039,7 +10530,7 @@ function createZcashNativeBackend(config) {
10039
10530
  }
10040
10531
 
10041
10532
  // src/settlement/backends/direct-chain.ts
10042
- var import_types13 = require("@sip-protocol/types");
10533
+ var import_types14 = require("@sip-protocol/types");
10043
10534
  init_stealth();
10044
10535
  init_errors();
10045
10536
  var import_utils16 = require("@noble/hashes/utils");
@@ -10081,7 +10572,7 @@ var DEFAULT_GAS_FEES = {
10081
10572
  };
10082
10573
 
10083
10574
  // src/zcash/rpc-client.ts
10084
- var import_types14 = require("@sip-protocol/types");
10575
+ var import_types15 = require("@sip-protocol/types");
10085
10576
  init_errors();
10086
10577
  var DEFAULT_CONFIG = {
10087
10578
  host: "127.0.0.1",
@@ -10102,19 +10593,19 @@ var ZcashRPCError = class extends Error {
10102
10593
  * Check if error is due to insufficient funds
10103
10594
  */
10104
10595
  isInsufficientFunds() {
10105
- return this.code === import_types14.ZcashErrorCode.WALLET_INSUFFICIENT_FUNDS;
10596
+ return this.code === import_types15.ZcashErrorCode.WALLET_INSUFFICIENT_FUNDS;
10106
10597
  }
10107
10598
  /**
10108
10599
  * Check if error is due to invalid address
10109
10600
  */
10110
10601
  isInvalidAddress() {
10111
- return this.code === import_types14.ZcashErrorCode.INVALID_ADDRESS_OR_KEY;
10602
+ return this.code === import_types15.ZcashErrorCode.INVALID_ADDRESS_OR_KEY;
10112
10603
  }
10113
10604
  /**
10114
10605
  * Check if error is due to wallet being locked
10115
10606
  */
10116
10607
  isWalletLocked() {
10117
- return this.code === import_types14.ZcashErrorCode.WALLET_UNLOCK_NEEDED;
10608
+ return this.code === import_types15.ZcashErrorCode.WALLET_UNLOCK_NEEDED;
10118
10609
  }
10119
10610
  };
10120
10611
  var ZcashRPCClient = class {
@@ -10501,7 +10992,7 @@ function createZcashClient(config) {
10501
10992
  }
10502
10993
 
10503
10994
  // src/zcash/shielded-service.ts
10504
- var import_types15 = require("@sip-protocol/types");
10995
+ var import_types16 = require("@sip-protocol/types");
10505
10996
  init_errors();
10506
10997
  var ZcashShieldedService = class _ZcashShieldedService {
10507
10998
  client;
@@ -10688,7 +11179,7 @@ var ZcashShieldedService = class _ZcashShieldedService {
10688
11179
  * Higher-level method that handles privacy level mapping.
10689
11180
  */
10690
11181
  async sendWithPrivacy(to, amount, privacyLevel, memo) {
10691
- if (privacyLevel === import_types15.PrivacyLevel.TRANSPARENT) {
11182
+ if (privacyLevel === import_types16.PrivacyLevel.TRANSPARENT) {
10692
11183
  throw new ValidationError(
10693
11184
  "Transparent mode not supported for Zcash shielded service. Use standard RPC client.",
10694
11185
  "privacyLevel",
@@ -10782,7 +11273,7 @@ var ZcashShieldedService = class _ZcashShieldedService {
10782
11273
  const viewingKey = await this.exportViewingKey();
10783
11274
  return {
10784
11275
  viewingKey,
10785
- privacyLevel: import_types15.PrivacyLevel.COMPLIANT,
11276
+ privacyLevel: import_types16.PrivacyLevel.COMPLIANT,
10786
11277
  disclaimer: "This viewing key provides read-only access to transaction history. It cannot be used to spend funds. Share only with authorized auditors."
10787
11278
  };
10788
11279
  }
@@ -10868,11 +11359,11 @@ var ZcashShieldedService = class _ZcashShieldedService {
10868
11359
  */
10869
11360
  mapPrivacyLevelToPolicy(level) {
10870
11361
  switch (level) {
10871
- case import_types15.PrivacyLevel.TRANSPARENT:
11362
+ case import_types16.PrivacyLevel.TRANSPARENT:
10872
11363
  return "NoPrivacy";
10873
- case import_types15.PrivacyLevel.SHIELDED:
11364
+ case import_types16.PrivacyLevel.SHIELDED:
10874
11365
  return "FullPrivacy";
10875
- case import_types15.PrivacyLevel.COMPLIANT:
11366
+ case import_types16.PrivacyLevel.COMPLIANT:
10876
11367
  return "FullPrivacy";
10877
11368
  default:
10878
11369
  return "FullPrivacy";
@@ -10925,7 +11416,7 @@ function createZcashShieldedService(config) {
10925
11416
  }
10926
11417
 
10927
11418
  // src/zcash/swap-service.ts
10928
- var import_types16 = require("@sip-protocol/types");
11419
+ var import_types17 = require("@sip-protocol/types");
10929
11420
  init_errors();
10930
11421
  var MOCK_PRICES = {
10931
11422
  ETH: 2500,
@@ -11039,7 +11530,7 @@ var ZcashSwapService = class {
11039
11530
  validUntil,
11040
11531
  depositAddress: this.generateMockDepositAddress(sourceChain),
11041
11532
  estimatedTime: this.getEstimatedTime(sourceChain),
11042
- privacyLevel: import_types16.PrivacyLevel.SHIELDED
11533
+ privacyLevel: import_types17.PrivacyLevel.SHIELDED
11043
11534
  };
11044
11535
  this.quotes.set(quoteId, quote);
11045
11536
  return quote;
@@ -11082,7 +11573,7 @@ var ZcashSwapService = class {
11082
11573
  depositAddress: "",
11083
11574
  // Will be set by bridge
11084
11575
  estimatedTime: this.getEstimatedTime(params.sourceChain),
11085
- privacyLevel: import_types16.PrivacyLevel.SHIELDED
11576
+ privacyLevel: import_types17.PrivacyLevel.SHIELDED
11086
11577
  };
11087
11578
  this.quotes.set(quote.quoteId, quote);
11088
11579
  return quote;
@@ -11365,10 +11856,10 @@ function createZcashSwapService(config) {
11365
11856
  init_errors();
11366
11857
 
11367
11858
  // src/zcash/index.ts
11368
- var import_types17 = require("@sip-protocol/types");
11859
+ var import_types18 = require("@sip-protocol/types");
11369
11860
 
11370
11861
  // src/index.ts
11371
- var import_types63 = require("@sip-protocol/types");
11862
+ var import_types64 = require("@sip-protocol/types");
11372
11863
 
11373
11864
  // src/bitcoin/taproot.ts
11374
11865
  var import_secp256k14 = require("@noble/curves/secp256k1");
@@ -11663,7 +12154,7 @@ init_errors();
11663
12154
  init_validation();
11664
12155
 
11665
12156
  // src/payment/payment.ts
11666
- var import_types18 = require("@sip-protocol/types");
12157
+ var import_types19 = require("@sip-protocol/types");
11667
12158
  var import_sha25613 = require("@noble/hashes/sha256");
11668
12159
  var import_utils19 = require("@noble/hashes/utils");
11669
12160
  var import_chacha2 = require("@noble/ciphers/chacha.js");
@@ -11854,7 +12345,7 @@ var PaymentBuilder = class {
11854
12345
  _amount;
11855
12346
  _recipientMetaAddress;
11856
12347
  _recipientAddress;
11857
- _privacy = import_types18.PrivacyLevel.SHIELDED;
12348
+ _privacy = import_types19.PrivacyLevel.SHIELDED;
11858
12349
  _viewingKey;
11859
12350
  _sourceChain;
11860
12351
  _destinationChain;
@@ -12137,7 +12628,7 @@ async function createShieldedPayment(params, options) {
12137
12628
  } else {
12138
12629
  resolvedToken = token;
12139
12630
  }
12140
- if (privacy !== import_types18.PrivacyLevel.TRANSPARENT && !recipientMetaAddress) {
12631
+ if (privacy !== import_types19.PrivacyLevel.TRANSPARENT && !recipientMetaAddress) {
12141
12632
  throw new ValidationError(
12142
12633
  "recipientMetaAddress is required for shielded/compliant privacy modes",
12143
12634
  "recipientMetaAddress",
@@ -12145,7 +12636,7 @@ async function createShieldedPayment(params, options) {
12145
12636
  "SIP_2008" /* MISSING_REQUIRED */
12146
12637
  );
12147
12638
  }
12148
- if (privacy === import_types18.PrivacyLevel.TRANSPARENT && !recipientAddress) {
12639
+ if (privacy === import_types19.PrivacyLevel.TRANSPARENT && !recipientAddress) {
12149
12640
  throw new ValidationError(
12150
12641
  "recipientAddress is required for transparent mode",
12151
12642
  "recipientAddress",
@@ -12153,7 +12644,7 @@ async function createShieldedPayment(params, options) {
12153
12644
  "SIP_2008" /* MISSING_REQUIRED */
12154
12645
  );
12155
12646
  }
12156
- if (privacy === import_types18.PrivacyLevel.COMPLIANT && !viewingKey) {
12647
+ if (privacy === import_types19.PrivacyLevel.COMPLIANT && !viewingKey) {
12157
12648
  throw new ValidationError(
12158
12649
  "viewingKey is required for compliant mode",
12159
12650
  "viewingKey",
@@ -12175,7 +12666,7 @@ async function createShieldedPayment(params, options) {
12175
12666
  const now = Math.floor(Date.now() / 1e3);
12176
12667
  const payment = {
12177
12668
  paymentId,
12178
- version: import_types18.SIP_VERSION,
12669
+ version: import_types19.SIP_VERSION,
12179
12670
  privacyLevel: privacy,
12180
12671
  createdAt: now,
12181
12672
  expiry: now + ttl,
@@ -12186,7 +12677,7 @@ async function createShieldedPayment(params, options) {
12186
12677
  purpose,
12187
12678
  viewingKeyHash
12188
12679
  };
12189
- if (privacy !== import_types18.PrivacyLevel.TRANSPARENT && recipientMetaAddress) {
12680
+ if (privacy !== import_types19.PrivacyLevel.TRANSPARENT && recipientMetaAddress) {
12190
12681
  const metaAddress = decodeStealthMetaAddress(recipientMetaAddress);
12191
12682
  const { stealthAddress } = generateStealthAddress(metaAddress);
12192
12683
  payment.recipientStealth = stealthAddress;
@@ -12203,7 +12694,7 @@ async function createShieldedPayment(params, options) {
12203
12694
  payment.recipientAddress = recipientAddress;
12204
12695
  payment.memo = memo;
12205
12696
  }
12206
- if (privacy !== import_types18.PrivacyLevel.TRANSPARENT && proofProvider?.isReady) {
12697
+ if (privacy !== import_types19.PrivacyLevel.TRANSPARENT && proofProvider?.isReady) {
12207
12698
  const hexToUint8 = (hex) => {
12208
12699
  const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
12209
12700
  return (0, import_utils19.hexToBytes)(cleanHex);
@@ -12269,7 +12760,7 @@ function decryptMemo(encryptedMemo, viewingKey) {
12269
12760
  function trackPayment(payment) {
12270
12761
  return {
12271
12762
  ...payment,
12272
- status: import_types18.PaymentStatus.DRAFT
12763
+ status: import_types19.PaymentStatus.DRAFT
12273
12764
  };
12274
12765
  }
12275
12766
  function isPaymentExpired(payment) {
@@ -12302,7 +12793,7 @@ function getPaymentSummary(payment) {
12302
12793
  }
12303
12794
 
12304
12795
  // src/treasury/treasury.ts
12305
- var import_types19 = require("@sip-protocol/types");
12796
+ var import_types20 = require("@sip-protocol/types");
12306
12797
  var import_secp256k16 = require("@noble/curves/secp256k1");
12307
12798
  var import_sha25614 = require("@noble/hashes/sha256");
12308
12799
  var import_utils20 = require("@noble/hashes/utils");
@@ -12338,7 +12829,7 @@ var Treasury = class _Treasury {
12338
12829
  ...m,
12339
12830
  addedAt: now
12340
12831
  })),
12341
- defaultPrivacy: params.defaultPrivacy ?? import_types19.PrivacyLevel.SHIELDED,
12832
+ defaultPrivacy: params.defaultPrivacy ?? import_types20.PrivacyLevel.SHIELDED,
12342
12833
  masterViewingKey,
12343
12834
  dailyLimit: params.dailyLimit,
12344
12835
  transactionLimit: params.transactionLimit,
@@ -12417,7 +12908,7 @@ var Treasury = class _Treasury {
12417
12908
  proposalId,
12418
12909
  treasuryId: this.config.treasuryId,
12419
12910
  type: "payment",
12420
- status: import_types19.ProposalStatus.PENDING,
12911
+ status: import_types20.ProposalStatus.PENDING,
12421
12912
  proposer: "",
12422
12913
  // Should be set by caller
12423
12914
  title: params.title,
@@ -12450,7 +12941,7 @@ var Treasury = class _Treasury {
12450
12941
  proposalId,
12451
12942
  treasuryId: this.config.treasuryId,
12452
12943
  type: "batch_payment",
12453
- status: import_types19.ProposalStatus.PENDING,
12944
+ status: import_types20.ProposalStatus.PENDING,
12454
12945
  proposer: "",
12455
12946
  title: params.title,
12456
12947
  description: params.description,
@@ -12484,7 +12975,7 @@ var Treasury = class _Treasury {
12484
12975
  * Get pending proposals
12485
12976
  */
12486
12977
  getPendingProposals() {
12487
- return this.getAllProposals().filter((p) => p.status === import_types19.ProposalStatus.PENDING);
12978
+ return this.getAllProposals().filter((p) => p.status === import_types20.ProposalStatus.PENDING);
12488
12979
  }
12489
12980
  /**
12490
12981
  * Sign a proposal
@@ -12515,7 +13006,7 @@ var Treasury = class _Treasury {
12515
13006
  "SIP_2001" /* INVALID_INPUT */
12516
13007
  );
12517
13008
  }
12518
- if (proposal.status !== import_types19.ProposalStatus.PENDING) {
13009
+ if (proposal.status !== import_types20.ProposalStatus.PENDING) {
12519
13010
  throw new ValidationError(
12520
13011
  `proposal is not pending: ${proposal.status}`,
12521
13012
  "proposalId",
@@ -12525,7 +13016,7 @@ var Treasury = class _Treasury {
12525
13016
  }
12526
13017
  const now = Math.floor(Date.now() / 1e3);
12527
13018
  if (now > proposal.expiresAt) {
12528
- proposal.status = import_types19.ProposalStatus.EXPIRED;
13019
+ proposal.status = import_types20.ProposalStatus.EXPIRED;
12529
13020
  throw new ValidationError(
12530
13021
  "proposal has expired",
12531
13022
  "proposalId",
@@ -12557,9 +13048,9 @@ var Treasury = class _Treasury {
12557
13048
  const approvals = proposal.signatures.filter((s) => s.approved).length;
12558
13049
  const rejections = proposal.signatures.filter((s) => !s.approved).length;
12559
13050
  if (approvals >= proposal.requiredSignatures) {
12560
- proposal.status = import_types19.ProposalStatus.APPROVED;
13051
+ proposal.status = import_types20.ProposalStatus.APPROVED;
12561
13052
  } else if (rejections > this.config.totalSigners - proposal.requiredSignatures) {
12562
- proposal.status = import_types19.ProposalStatus.REJECTED;
13053
+ proposal.status = import_types20.ProposalStatus.REJECTED;
12563
13054
  }
12564
13055
  return proposal;
12565
13056
  }
@@ -12576,7 +13067,7 @@ var Treasury = class _Treasury {
12576
13067
  "SIP_2001" /* INVALID_INPUT */
12577
13068
  );
12578
13069
  }
12579
- if (proposal.status !== import_types19.ProposalStatus.APPROVED) {
13070
+ if (proposal.status !== import_types20.ProposalStatus.APPROVED) {
12580
13071
  throw new ValidationError(
12581
13072
  `proposal is not approved: ${proposal.status}`,
12582
13073
  "proposalId",
@@ -12589,8 +13080,8 @@ var Treasury = class _Treasury {
12589
13080
  const payment = await createShieldedPayment({
12590
13081
  token: proposal.payment.token,
12591
13082
  amount: proposal.payment.amount,
12592
- recipientMetaAddress: proposal.payment.privacy !== import_types19.PrivacyLevel.TRANSPARENT ? proposal.payment.recipient : void 0,
12593
- recipientAddress: proposal.payment.privacy === import_types19.PrivacyLevel.TRANSPARENT ? proposal.payment.recipient : void 0,
13083
+ recipientMetaAddress: proposal.payment.privacy !== import_types20.PrivacyLevel.TRANSPARENT ? proposal.payment.recipient : void 0,
13084
+ recipientAddress: proposal.payment.privacy === import_types20.PrivacyLevel.TRANSPARENT ? proposal.payment.recipient : void 0,
12594
13085
  privacy: proposal.payment.privacy,
12595
13086
  viewingKey: this.config.masterViewingKey?.key,
12596
13087
  sourceChain: this.config.chain,
@@ -12603,8 +13094,8 @@ var Treasury = class _Treasury {
12603
13094
  const payment = await createShieldedPayment({
12604
13095
  token: proposal.batchPayment.token,
12605
13096
  amount: recipient.amount,
12606
- recipientMetaAddress: proposal.batchPayment.privacy !== import_types19.PrivacyLevel.TRANSPARENT ? recipient.address : void 0,
12607
- recipientAddress: proposal.batchPayment.privacy === import_types19.PrivacyLevel.TRANSPARENT ? recipient.address : void 0,
13097
+ recipientMetaAddress: proposal.batchPayment.privacy !== import_types20.PrivacyLevel.TRANSPARENT ? recipient.address : void 0,
13098
+ recipientAddress: proposal.batchPayment.privacy === import_types20.PrivacyLevel.TRANSPARENT ? recipient.address : void 0,
12608
13099
  privacy: proposal.batchPayment.privacy,
12609
13100
  viewingKey: this.config.masterViewingKey?.key,
12610
13101
  sourceChain: this.config.chain,
@@ -12614,7 +13105,7 @@ var Treasury = class _Treasury {
12614
13105
  payments.push(payment);
12615
13106
  }
12616
13107
  }
12617
- proposal.status = import_types19.ProposalStatus.EXECUTED;
13108
+ proposal.status = import_types20.ProposalStatus.EXECUTED;
12618
13109
  proposal.executedAt = Math.floor(Date.now() / 1e3);
12619
13110
  proposal.resultPayments = payments;
12620
13111
  return payments;
@@ -12643,7 +13134,7 @@ var Treasury = class _Treasury {
12643
13134
  "SIP_2001" /* INVALID_INPUT */
12644
13135
  );
12645
13136
  }
12646
- if (proposal.status !== import_types19.ProposalStatus.PENDING) {
13137
+ if (proposal.status !== import_types20.ProposalStatus.PENDING) {
12647
13138
  throw new ValidationError(
12648
13139
  `proposal is not pending: ${proposal.status}`,
12649
13140
  "proposalId",
@@ -12651,7 +13142,7 @@ var Treasury = class _Treasury {
12651
13142
  "SIP_2001" /* INVALID_INPUT */
12652
13143
  );
12653
13144
  }
12654
- proposal.status = import_types19.ProposalStatus.CANCELLED;
13145
+ proposal.status = import_types20.ProposalStatus.CANCELLED;
12655
13146
  return proposal;
12656
13147
  }
12657
13148
  // ─── Auditor Access ──────────────────────────────────────────────────────────
@@ -12748,7 +13239,7 @@ var Treasury = class _Treasury {
12748
13239
  getCommittedAmount(token) {
12749
13240
  let committed = 0n;
12750
13241
  for (const proposal of this.proposals.values()) {
12751
- if (proposal.status !== import_types19.ProposalStatus.PENDING) continue;
13242
+ if (proposal.status !== import_types20.ProposalStatus.PENDING) continue;
12752
13243
  if (proposal.type === "payment" && proposal.payment) {
12753
13244
  if (proposal.payment.token.symbol === token.symbol && proposal.payment.token.chain === token.chain) {
12754
13245
  committed += proposal.payment.amount;
@@ -12991,7 +13482,7 @@ function validateBatchProposalParams(params, config) {
12991
13482
  }
12992
13483
 
12993
13484
  // src/compliance/compliance-manager.ts
12994
- var import_types20 = require("@sip-protocol/types");
13485
+ var import_types21 = require("@sip-protocol/types");
12995
13486
  var import_utils21 = require("@noble/hashes/utils");
12996
13487
  init_errors();
12997
13488
  var DEFAULTS2 = {
@@ -13360,7 +13851,7 @@ var ComplianceManager = class _ComplianceManager {
13360
13851
  title: params.title,
13361
13852
  description: params.description,
13362
13853
  format: params.format,
13363
- status: import_types20.ReportStatus.GENERATING,
13854
+ status: import_types21.ReportStatus.GENERATING,
13364
13855
  requestedBy,
13365
13856
  requestedAt: now,
13366
13857
  startDate: params.startDate,
@@ -13389,10 +13880,10 @@ var ComplianceManager = class _ComplianceManager {
13389
13880
  } else if (params.format === "csv") {
13390
13881
  report.content = this.generateCSV(transactions);
13391
13882
  }
13392
- report.status = import_types20.ReportStatus.COMPLETED;
13883
+ report.status = import_types21.ReportStatus.COMPLETED;
13393
13884
  report.generatedAt = Math.floor(Date.now() / 1e3);
13394
13885
  } catch (error) {
13395
- report.status = import_types20.ReportStatus.FAILED;
13886
+ report.status = import_types21.ReportStatus.FAILED;
13396
13887
  report.error = error instanceof Error ? error.message : "Unknown error";
13397
13888
  }
13398
13889
  this.addAuditLog(requestedBy, "report_generated", {
@@ -15463,54 +15954,359 @@ var AuditorKeyDerivation = class {
15463
15954
  }
15464
15955
  };
15465
15956
 
15466
- // src/auction/sealed-bid.ts
15957
+ // src/compliance/range-sas.ts
15958
+ var import_sha25620 = require("@noble/hashes/sha256");
15959
+ var import_hmac3 = require("@noble/hashes/hmac");
15960
+ var import_sha5124 = require("@noble/hashes/sha512");
15467
15961
  var import_utils27 = require("@noble/hashes/utils");
15468
15962
  init_errors();
15469
- var SealedBidAuction = class {
15963
+ init_secure_memory();
15964
+ var AttestationSchema = /* @__PURE__ */ ((AttestationSchema2) => {
15965
+ AttestationSchema2["RANGE_KYC_V1"] = "range-kyc-v1";
15966
+ AttestationSchema2["RANGE_ACCREDITED_INVESTOR"] = "range-accredited-investor";
15967
+ AttestationSchema2["RANGE_INSTITUTIONAL"] = "range-institutional";
15968
+ AttestationSchema2["RANGE_REGULATOR"] = "range-regulator";
15969
+ AttestationSchema2["CUSTOM"] = "custom";
15970
+ return AttestationSchema2;
15971
+ })(AttestationSchema || {});
15972
+ var DEFAULT_MAX_CACHE_SIZE = 1e3;
15973
+ var AttestationGatedDisclosure = class {
15974
+ config;
15975
+ derivedKeys = /* @__PURE__ */ new Map();
15976
+ cacheOrder = [];
15977
+ // LRU tracking
15470
15978
  /**
15471
- * Create a sealed bid for an auction
15472
- *
15473
- * Generates a cryptographically binding commitment to a bid amount.
15474
- * The commitment can be published publicly without revealing the bid.
15979
+ * Create a new attestation-gated disclosure manager
15475
15980
  *
15476
- * **Important:** Keep the returned `BidReceipt` secret! It contains the bid
15477
- * amount and salt needed to reveal the bid later. Only publish the commitment.
15981
+ * @param config - Configuration options
15982
+ */
15983
+ constructor(config) {
15984
+ if (!config.masterViewingKey) {
15985
+ throw new ValidationError(
15986
+ "masterViewingKey is required",
15987
+ "masterViewingKey",
15988
+ void 0,
15989
+ "SIP_2008" /* MISSING_REQUIRED */
15990
+ );
15991
+ }
15992
+ this.config = {
15993
+ masterViewingKey: config.masterViewingKey,
15994
+ allowedSchemas: config.allowedSchemas ?? [],
15995
+ allowedIssuers: config.allowedIssuers ?? [],
15996
+ verifyOnChain: config.verifyOnChain ?? false,
15997
+ rangeApiEndpoint: config.rangeApiEndpoint ?? "https://api.range.org/v1",
15998
+ minAttestationAge: config.minAttestationAge ?? 0,
15999
+ maxAttestationAge: config.maxAttestationAge ?? 0,
16000
+ // 0 = no limit
16001
+ maxCacheSize: config.maxCacheSize ?? DEFAULT_MAX_CACHE_SIZE,
16002
+ customVerifier: config.customVerifier ?? (async () => true)
16003
+ };
16004
+ }
16005
+ /**
16006
+ * Derive a viewing key for a verified auditor
15478
16007
  *
15479
- * @param params - Bid creation parameters
15480
- * @returns Complete bid receipt (keep secret!) and sealed bid (publish this)
15481
- * @throws {ValidationError} If auctionId is empty, amount is non-positive, or salt is invalid
16008
+ * @param attestation - The auditor's Range SAS attestation
16009
+ * @param scope - Optional scope restrictions for the viewing key
16010
+ * @returns Derivation result with viewing key if granted
15482
16011
  *
15483
16012
  * @example
15484
16013
  * ```typescript
15485
- * const auction = new SealedBidAuction()
15486
- *
15487
- * // Create a bid for 50 ETH
15488
- * const receipt = auction.createBid({
15489
- * auctionId: 'auction-xyz',
15490
- * amount: 50n * 10n**18n,
15491
- * })
15492
- *
15493
- * // Public data (safe to publish)
15494
- * console.log({
15495
- * auctionId: receipt.auctionId,
15496
- * commitment: receipt.commitment,
15497
- * timestamp: receipt.timestamp,
16014
+ * const result = await disclosure.deriveViewingKeyForAuditor(attestation, {
16015
+ * startTime: Date.now() / 1000 - 30 * 24 * 60 * 60, // Last 30 days
16016
+ * endTime: Date.now() / 1000,
15498
16017
  * })
15499
16018
  *
15500
- * // Secret data (store securely, needed for reveal)
15501
- * secureStorage.save({
15502
- * amount: receipt.amount,
15503
- * salt: receipt.salt,
15504
- * })
16019
+ * if (result.granted) {
16020
+ * // Share result.viewingKey with auditor
16021
+ * }
15505
16022
  * ```
15506
16023
  */
15507
- createBid(params) {
15508
- if (typeof params.auctionId !== "string" || params.auctionId.length === 0) {
15509
- throw new ValidationError(
15510
- "auctionId must be a non-empty string",
15511
- "auctionId",
15512
- { received: params.auctionId }
15513
- );
16024
+ async deriveViewingKeyForAuditor(attestation, scope) {
16025
+ const verification = await this.verifyAttestation(attestation);
16026
+ if (!verification.valid) {
16027
+ return {
16028
+ granted: false,
16029
+ reason: verification.errors.join("; ")
16030
+ };
16031
+ }
16032
+ const cacheKey = this.getCacheKey(attestation);
16033
+ const cached = this.derivedKeys.get(cacheKey);
16034
+ if (cached) {
16035
+ this.updateCacheOrder(cacheKey);
16036
+ return {
16037
+ granted: true,
16038
+ viewingKey: cached,
16039
+ scope,
16040
+ expiresAt: attestation.expiresAt
16041
+ // 0 = never expires, undefined = not set
16042
+ };
16043
+ }
16044
+ const viewingKey = this.deriveKeyFromAttestation(attestation);
16045
+ this.cacheKey(cacheKey, viewingKey);
16046
+ return {
16047
+ granted: true,
16048
+ viewingKey,
16049
+ scope,
16050
+ expiresAt: attestation.expiresAt
16051
+ // 0 = never expires, undefined = not set
16052
+ };
16053
+ }
16054
+ /**
16055
+ * Verify a Range SAS attestation
16056
+ *
16057
+ * @param attestation - The attestation to verify
16058
+ * @returns Verification result
16059
+ */
16060
+ async verifyAttestation(attestation) {
16061
+ const errors = [];
16062
+ if (!attestation || typeof attestation !== "object") {
16063
+ return {
16064
+ valid: false,
16065
+ errors: ["Attestation must be an object"]
16066
+ };
16067
+ }
16068
+ if (!attestation.uid || typeof attestation.uid !== "string" || attestation.uid.trim() === "") {
16069
+ errors.push("Attestation uid is required and must be a non-empty string");
16070
+ }
16071
+ if (!attestation.subject || typeof attestation.subject !== "string" || attestation.subject.trim() === "") {
16072
+ errors.push("Attestation subject is required and must be a non-empty string");
16073
+ }
16074
+ if (!attestation.schema || typeof attestation.schema !== "string" || attestation.schema.trim() === "") {
16075
+ errors.push("Attestation schema is required and must be a non-empty string");
16076
+ }
16077
+ if (!attestation.issuer || typeof attestation.issuer !== "string" || attestation.issuer.trim() === "") {
16078
+ errors.push("Attestation issuer is required and must be a non-empty string");
16079
+ }
16080
+ if (errors.length > 0) {
16081
+ return { valid: false, errors };
16082
+ }
16083
+ if (attestation.revoked) {
16084
+ errors.push("Attestation has been revoked");
16085
+ }
16086
+ const now = Date.now() / 1e3;
16087
+ if (attestation.expiresAt > 0 && attestation.expiresAt < now) {
16088
+ errors.push("Attestation has expired");
16089
+ }
16090
+ const age = now - attestation.timestamp;
16091
+ if (age < this.config.minAttestationAge) {
16092
+ errors.push(`Attestation too new (age: ${age}s, required: ${this.config.minAttestationAge}s)`);
16093
+ }
16094
+ if (this.config.maxAttestationAge > 0 && age > this.config.maxAttestationAge) {
16095
+ errors.push(`Attestation too old (age: ${Math.floor(age)}s, max: ${this.config.maxAttestationAge}s)`);
16096
+ }
16097
+ if (this.config.allowedSchemas.length > 0) {
16098
+ if (!this.config.allowedSchemas.includes(attestation.schema)) {
16099
+ errors.push(`Schema '${attestation.schema}' not in allowed list`);
16100
+ }
16101
+ }
16102
+ if (this.config.allowedIssuers.length > 0) {
16103
+ if (!this.config.allowedIssuers.includes(attestation.issuer)) {
16104
+ errors.push(`Issuer '${attestation.issuer}' not in allowed list`);
16105
+ }
16106
+ }
16107
+ if (errors.length === 0 && this.config.customVerifier) {
16108
+ try {
16109
+ const customValid = await this.config.customVerifier(attestation);
16110
+ if (!customValid) {
16111
+ errors.push("Custom verification failed");
16112
+ }
16113
+ } catch (e) {
16114
+ errors.push(`Custom verification error: ${e instanceof Error ? e.message : "unknown"}`);
16115
+ }
16116
+ }
16117
+ return {
16118
+ valid: errors.length === 0,
16119
+ errors,
16120
+ metadata: {
16121
+ verificationMethod: this.config.verifyOnChain ? "on-chain" : "api",
16122
+ schemaVersion: attestation.schema
16123
+ }
16124
+ };
16125
+ }
16126
+ /**
16127
+ * Revoke a previously derived viewing key
16128
+ *
16129
+ * @param attestation - The attestation whose key should be revoked
16130
+ * @returns Whether revocation was successful
16131
+ */
16132
+ revokeViewingKey(attestation) {
16133
+ const key = this.getCacheKey(attestation);
16134
+ const deleted = this.derivedKeys.delete(key);
16135
+ if (deleted) {
16136
+ const index = this.cacheOrder.indexOf(key);
16137
+ if (index !== -1) {
16138
+ this.cacheOrder.splice(index, 1);
16139
+ }
16140
+ }
16141
+ return deleted;
16142
+ }
16143
+ /**
16144
+ * Check if a viewing key has been derived for an attestation
16145
+ *
16146
+ * @param attestation - The attestation to check
16147
+ * @returns Whether a key exists
16148
+ */
16149
+ hasViewingKey(attestation) {
16150
+ const key = this.getCacheKey(attestation);
16151
+ return this.derivedKeys.has(key);
16152
+ }
16153
+ /**
16154
+ * Get the current cache size
16155
+ *
16156
+ * @returns Number of cached viewing keys
16157
+ */
16158
+ getCacheSize() {
16159
+ return this.derivedKeys.size;
16160
+ }
16161
+ /**
16162
+ * Clear all cached viewing keys
16163
+ */
16164
+ clearCache() {
16165
+ this.derivedKeys.clear();
16166
+ this.cacheOrder.length = 0;
16167
+ }
16168
+ // ─── Private Methods ────────────────────────────────────────────────────────
16169
+ /**
16170
+ * Add a key to cache with LRU eviction
16171
+ */
16172
+ cacheKey(key, viewingKey) {
16173
+ while (this.derivedKeys.size >= this.config.maxCacheSize && this.cacheOrder.length > 0) {
16174
+ const oldest = this.cacheOrder.shift();
16175
+ if (oldest) {
16176
+ this.derivedKeys.delete(oldest);
16177
+ }
16178
+ }
16179
+ this.derivedKeys.set(key, viewingKey);
16180
+ this.cacheOrder.push(key);
16181
+ }
16182
+ /**
16183
+ * Update LRU order for a cache key (move to end)
16184
+ */
16185
+ updateCacheOrder(key) {
16186
+ const index = this.cacheOrder.indexOf(key);
16187
+ if (index !== -1) {
16188
+ this.cacheOrder.splice(index, 1);
16189
+ this.cacheOrder.push(key);
16190
+ }
16191
+ }
16192
+ /**
16193
+ * Derive a viewing key from an attestation
16194
+ */
16195
+ deriveKeyFromAttestation(attestation) {
16196
+ const masterKeyHex = this.config.masterViewingKey.key.startsWith("0x") ? this.config.masterViewingKey.key.slice(2) : this.config.masterViewingKey.key;
16197
+ const masterKeyBytes = (0, import_utils27.hexToBytes)(masterKeyHex);
16198
+ const derivationData = (0, import_utils27.utf8ToBytes)(
16199
+ `SIP-RANGE-SAS:${attestation.uid}:${attestation.subject}:${attestation.schema}:${attestation.signature}`
16200
+ );
16201
+ const derived = (0, import_hmac3.hmac)(import_sha5124.sha512, masterKeyBytes, derivationData);
16202
+ const keyBytes = derived.slice(0, 32);
16203
+ try {
16204
+ const key = `0x${(0, import_utils27.bytesToHex)(keyBytes)}`;
16205
+ const hashBytes = (0, import_sha25620.sha256)(keyBytes);
16206
+ const hash2 = `0x${(0, import_utils27.bytesToHex)(hashBytes)}`;
16207
+ return {
16208
+ key,
16209
+ path: `${this.config.masterViewingKey.path}/sas/${attestation.uid.slice(0, 8)}`,
16210
+ hash: hash2
16211
+ };
16212
+ } finally {
16213
+ secureWipe(masterKeyBytes);
16214
+ secureWipe(derived);
16215
+ secureWipe(keyBytes);
16216
+ }
16217
+ }
16218
+ /**
16219
+ * Get cache key for an attestation
16220
+ *
16221
+ * Includes schema and issuer to prevent cache poisoning attacks where
16222
+ * an attacker could evict legitimate cache entries with same uid:subject.
16223
+ */
16224
+ getCacheKey(attestation) {
16225
+ return `${attestation.uid}:${attestation.subject}:${attestation.schema}:${attestation.issuer}`;
16226
+ }
16227
+ };
16228
+ function createMockAttestation(overrides = {}) {
16229
+ const now = Math.floor(Date.now() / 1e3);
16230
+ return {
16231
+ uid: `sas_${Math.random().toString(36).slice(2, 10)}`,
16232
+ schema: "range-kyc-v1" /* RANGE_KYC_V1 */,
16233
+ issuer: "range-protocol",
16234
+ subject: "11111111111111111111111111111112",
16235
+ // System program (placeholder)
16236
+ data: {
16237
+ level: "institutional",
16238
+ jurisdiction: "US",
16239
+ verifiedAt: now
16240
+ },
16241
+ timestamp: now,
16242
+ expiresAt: now + 365 * 24 * 60 * 60,
16243
+ // 1 year
16244
+ signature: "0x" + "00".repeat(64),
16245
+ revoked: false,
16246
+ ...overrides
16247
+ };
16248
+ }
16249
+ async function verifyAttestationSignature(_attestation) {
16250
+ console.warn(
16251
+ "[Range SAS] verifyAttestationSignature is a STUB - always returns true. Implement real Ed25519 signature verification before production use."
16252
+ );
16253
+ return true;
16254
+ }
16255
+ async function fetchAttestation(uid, apiEndpoint = "https://api.range.org/v1") {
16256
+ console.warn(
16257
+ `[Range SAS] fetchAttestation is a STUB - returning null for ${uid}. Would fetch from ${apiEndpoint}. Implement Range API integration before production use.`
16258
+ );
16259
+ return null;
16260
+ }
16261
+
16262
+ // src/auction/sealed-bid.ts
16263
+ var import_utils28 = require("@noble/hashes/utils");
16264
+ init_errors();
16265
+ var SealedBidAuction = class {
16266
+ /**
16267
+ * Create a sealed bid for an auction
16268
+ *
16269
+ * Generates a cryptographically binding commitment to a bid amount.
16270
+ * The commitment can be published publicly without revealing the bid.
16271
+ *
16272
+ * **Important:** Keep the returned `BidReceipt` secret! It contains the bid
16273
+ * amount and salt needed to reveal the bid later. Only publish the commitment.
16274
+ *
16275
+ * @param params - Bid creation parameters
16276
+ * @returns Complete bid receipt (keep secret!) and sealed bid (publish this)
16277
+ * @throws {ValidationError} If auctionId is empty, amount is non-positive, or salt is invalid
16278
+ *
16279
+ * @example
16280
+ * ```typescript
16281
+ * const auction = new SealedBidAuction()
16282
+ *
16283
+ * // Create a bid for 50 ETH
16284
+ * const receipt = auction.createBid({
16285
+ * auctionId: 'auction-xyz',
16286
+ * amount: 50n * 10n**18n,
16287
+ * })
16288
+ *
16289
+ * // Public data (safe to publish)
16290
+ * console.log({
16291
+ * auctionId: receipt.auctionId,
16292
+ * commitment: receipt.commitment,
16293
+ * timestamp: receipt.timestamp,
16294
+ * })
16295
+ *
16296
+ * // Secret data (store securely, needed for reveal)
16297
+ * secureStorage.save({
16298
+ * amount: receipt.amount,
16299
+ * salt: receipt.salt,
16300
+ * })
16301
+ * ```
16302
+ */
16303
+ createBid(params) {
16304
+ if (typeof params.auctionId !== "string" || params.auctionId.length === 0) {
16305
+ throw new ValidationError(
16306
+ "auctionId must be a non-empty string",
16307
+ "auctionId",
16308
+ { received: params.auctionId }
16309
+ );
15514
16310
  }
15515
16311
  if (typeof params.amount !== "bigint") {
15516
16312
  throw new ValidationError(
@@ -15542,7 +16338,7 @@ var SealedBidAuction = class {
15542
16338
  );
15543
16339
  }
15544
16340
  }
15545
- const salt = params.salt ?? (0, import_utils27.randomBytes)(32);
16341
+ const salt = params.salt ?? (0, import_utils28.randomBytes)(32);
15546
16342
  const { commitment, blinding } = commit(params.amount, salt);
15547
16343
  const sealedBid = {
15548
16344
  auctionId: params.auctionId,
@@ -15686,7 +16482,7 @@ var SealedBidAuction = class {
15686
16482
  * ```
15687
16483
  */
15688
16484
  revealBid(bid, amount, salt) {
15689
- const saltHex = `0x${(0, import_utils27.bytesToHex)(salt)}`;
16485
+ const saltHex = `0x${(0, import_utils28.bytesToHex)(salt)}`;
15690
16486
  const isValid = this.verifyBid({
15691
16487
  commitment: bid.commitment,
15692
16488
  amount,
@@ -16171,9 +16967,9 @@ function createSealedBidAuction() {
16171
16967
  }
16172
16968
 
16173
16969
  // src/governance/private-vote.ts
16174
- var import_sha25620 = require("@noble/hashes/sha256");
16970
+ var import_sha25621 = require("@noble/hashes/sha256");
16175
16971
  var import_hkdf3 = require("@noble/hashes/hkdf");
16176
- var import_utils28 = require("@noble/hashes/utils");
16972
+ var import_utils29 = require("@noble/hashes/utils");
16177
16973
  var import_chacha4 = require("@noble/ciphers/chacha.js");
16178
16974
  init_errors();
16179
16975
  init_secure_memory();
@@ -16213,7 +17009,7 @@ var PrivateVoting = class {
16213
17009
  const { proposalId, choice, weight, encryptionKey, voter = "anonymous" } = params;
16214
17010
  const derivedKey = this.deriveEncryptionKey(encryptionKey, proposalId);
16215
17011
  try {
16216
- const nonce = (0, import_utils28.randomBytes)(NONCE_SIZE2);
17012
+ const nonce = (0, import_utils29.randomBytes)(NONCE_SIZE2);
16217
17013
  const voteData = {
16218
17014
  proposalId,
16219
17015
  choice,
@@ -16221,14 +17017,14 @@ var PrivateVoting = class {
16221
17017
  voter,
16222
17018
  timestamp: Date.now()
16223
17019
  };
16224
- const plaintext = (0, import_utils28.utf8ToBytes)(JSON.stringify(voteData));
17020
+ const plaintext = (0, import_utils29.utf8ToBytes)(JSON.stringify(voteData));
16225
17021
  const cipher = (0, import_chacha4.xchacha20poly1305)(derivedKey, nonce);
16226
17022
  const ciphertext = cipher.encrypt(plaintext);
16227
- const keyHash = (0, import_sha25620.sha256)((0, import_utils28.hexToBytes)(encryptionKey.slice(2)));
17023
+ const keyHash = (0, import_sha25621.sha256)((0, import_utils29.hexToBytes)(encryptionKey.slice(2)));
16228
17024
  return {
16229
- ciphertext: `0x${(0, import_utils28.bytesToHex)(ciphertext)}`,
16230
- nonce: `0x${(0, import_utils28.bytesToHex)(nonce)}`,
16231
- encryptionKeyHash: `0x${(0, import_utils28.bytesToHex)(keyHash)}`,
17025
+ ciphertext: `0x${(0, import_utils29.bytesToHex)(ciphertext)}`,
17026
+ nonce: `0x${(0, import_utils29.bytesToHex)(nonce)}`,
17027
+ encryptionKeyHash: `0x${(0, import_utils29.bytesToHex)(keyHash)}`,
16232
17028
  proposalId,
16233
17029
  voter,
16234
17030
  timestamp: voteData.timestamp
@@ -16274,8 +17070,8 @@ var PrivateVoting = class {
16274
17070
  }
16275
17071
  const derivedKey = this.deriveEncryptionKey(decryptionKey, vote.proposalId);
16276
17072
  try {
16277
- const keyHash = (0, import_sha25620.sha256)((0, import_utils28.hexToBytes)(decryptionKey.slice(2)));
16278
- const expectedKeyHash = `0x${(0, import_utils28.bytesToHex)(keyHash)}`;
17073
+ const keyHash = (0, import_sha25621.sha256)((0, import_utils29.hexToBytes)(decryptionKey.slice(2)));
17074
+ const expectedKeyHash = `0x${(0, import_utils29.bytesToHex)(keyHash)}`;
16279
17075
  if (vote.encryptionKeyHash !== expectedKeyHash) {
16280
17076
  throw new CryptoError(
16281
17077
  "Decryption key hash mismatch - this key cannot decrypt this vote",
@@ -16284,9 +17080,9 @@ var PrivateVoting = class {
16284
17080
  );
16285
17081
  }
16286
17082
  const nonceHex = vote.nonce.startsWith("0x") ? vote.nonce.slice(2) : vote.nonce;
16287
- const nonce = (0, import_utils28.hexToBytes)(nonceHex);
17083
+ const nonce = (0, import_utils29.hexToBytes)(nonceHex);
16288
17084
  const ciphertextHex = vote.ciphertext.startsWith("0x") ? vote.ciphertext.slice(2) : vote.ciphertext;
16289
- const ciphertext = (0, import_utils28.hexToBytes)(ciphertextHex);
17085
+ const ciphertext = (0, import_utils29.hexToBytes)(ciphertextHex);
16290
17086
  const cipher = (0, import_chacha4.xchacha20poly1305)(derivedKey, nonce);
16291
17087
  let plaintext;
16292
17088
  try {
@@ -16375,11 +17171,11 @@ var PrivateVoting = class {
16375
17171
  */
16376
17172
  deriveEncryptionKey(key, proposalId) {
16377
17173
  const keyHex = key.startsWith("0x") ? key.slice(2) : key;
16378
- const keyBytes = (0, import_utils28.hexToBytes)(keyHex);
17174
+ const keyBytes = (0, import_utils29.hexToBytes)(keyHex);
16379
17175
  try {
16380
- const salt = (0, import_utils28.utf8ToBytes)(VOTE_ENCRYPTION_DOMAIN);
16381
- const info = (0, import_utils28.utf8ToBytes)(proposalId);
16382
- return (0, import_hkdf3.hkdf)(import_sha25620.sha256, keyBytes, salt, info, 32);
17176
+ const salt = (0, import_utils29.utf8ToBytes)(VOTE_ENCRYPTION_DOMAIN);
17177
+ const info = (0, import_utils29.utf8ToBytes)(proposalId);
17178
+ return (0, import_hkdf3.hkdf)(import_sha25621.sha256, keyBytes, salt, info, 32);
16383
17179
  } finally {
16384
17180
  secureWipe(keyBytes);
16385
17181
  }
@@ -16524,21 +17320,21 @@ var PrivateVoting = class {
16524
17320
  const blindings = {};
16525
17321
  for (const [choice, weights] of Object.entries(votesByChoice)) {
16526
17322
  const totalWeight = weights.reduce((sum, w) => sum + w, 0n);
16527
- const { commitment, blinding } = commit(totalWeight, (0, import_utils28.hexToBytes)(generateBlinding().slice(2)));
17323
+ const { commitment, blinding } = commit(totalWeight, (0, import_utils29.hexToBytes)(generateBlinding().slice(2)));
16528
17324
  tallies[choice] = commitment;
16529
17325
  blindings[choice] = blinding;
16530
17326
  }
16531
17327
  const encryptedBlindings = {};
16532
17328
  for (const [choice, blinding] of Object.entries(blindings)) {
16533
- const nonce = (0, import_utils28.randomBytes)(NONCE_SIZE2);
17329
+ const nonce = (0, import_utils29.randomBytes)(NONCE_SIZE2);
16534
17330
  const derivedKey = this.deriveEncryptionKey(decryptionKey, `${proposalId}-tally-${choice}`);
16535
17331
  try {
16536
17332
  const cipher = (0, import_chacha4.xchacha20poly1305)(derivedKey, nonce);
16537
- const blindingBytes = (0, import_utils28.hexToBytes)(blinding.slice(2));
17333
+ const blindingBytes = (0, import_utils29.hexToBytes)(blinding.slice(2));
16538
17334
  const ciphertext = cipher.encrypt(blindingBytes);
16539
17335
  encryptedBlindings[choice] = {
16540
- ciphertext: `0x${(0, import_utils28.bytesToHex)(ciphertext)}`,
16541
- nonce: `0x${(0, import_utils28.bytesToHex)(nonce)}`
17336
+ ciphertext: `0x${(0, import_utils29.bytesToHex)(ciphertext)}`,
17337
+ nonce: `0x${(0, import_utils29.bytesToHex)(nonce)}`
16542
17338
  };
16543
17339
  } finally {
16544
17340
  secureWipe(derivedKey);
@@ -16631,9 +17427,9 @@ var PrivateVoting = class {
16631
17427
  }
16632
17428
  let reconstructedKey = null;
16633
17429
  try {
16634
- reconstructedKey = (0, import_utils28.hexToBytes)(decryptionShares[0].share.slice(2));
17430
+ reconstructedKey = (0, import_utils29.hexToBytes)(decryptionShares[0].share.slice(2));
16635
17431
  for (let i = 1; i < decryptionShares.length; i++) {
16636
- const shareBytes = (0, import_utils28.hexToBytes)(decryptionShares[i].share.slice(2));
17432
+ const shareBytes = (0, import_utils29.hexToBytes)(decryptionShares[i].share.slice(2));
16637
17433
  if (shareBytes.length !== reconstructedKey.length) {
16638
17434
  throw new ValidationError(
16639
17435
  "all decryption shares must have the same length",
@@ -16646,7 +17442,7 @@ var PrivateVoting = class {
16646
17442
  reconstructedKey[j] ^= shareBytes[j];
16647
17443
  }
16648
17444
  }
16649
- const reconstructedKeyHex = `0x${(0, import_utils28.bytesToHex)(reconstructedKey)}`;
17445
+ const reconstructedKeyHex = `0x${(0, import_utils29.bytesToHex)(reconstructedKey)}`;
16650
17446
  const results = {};
16651
17447
  for (const [choice, commitmentPoint] of Object.entries(tally.tallies)) {
16652
17448
  const encBlinding = tally.encryptedBlindings[choice];
@@ -16663,11 +17459,11 @@ var PrivateVoting = class {
16663
17459
  );
16664
17460
  let blindingFactor;
16665
17461
  try {
16666
- const nonceBytes = (0, import_utils28.hexToBytes)(encBlinding.nonce.slice(2));
16667
- const ciphertextBytes = (0, import_utils28.hexToBytes)(encBlinding.ciphertext.slice(2));
17462
+ const nonceBytes = (0, import_utils29.hexToBytes)(encBlinding.nonce.slice(2));
17463
+ const ciphertextBytes = (0, import_utils29.hexToBytes)(encBlinding.ciphertext.slice(2));
16668
17464
  const cipher = (0, import_chacha4.xchacha20poly1305)(derivedKey, nonceBytes);
16669
17465
  const blindingBytes = cipher.decrypt(ciphertextBytes);
16670
- blindingFactor = `0x${(0, import_utils28.bytesToHex)(blindingBytes)}`;
17466
+ blindingFactor = `0x${(0, import_utils29.bytesToHex)(blindingBytes)}`;
16671
17467
  } catch (e) {
16672
17468
  throw new CryptoError(
16673
17469
  "failed to decrypt blinding factor",
@@ -16687,7 +17483,7 @@ var PrivateVoting = class {
16687
17483
  try {
16688
17484
  const { commitment: testCommit } = commit(
16689
17485
  value,
16690
- (0, import_utils28.hexToBytes)(blindingFactor.slice(2))
17486
+ (0, import_utils29.hexToBytes)(blindingFactor.slice(2))
16691
17487
  );
16692
17488
  if (testCommit === commitmentPoint) {
16693
17489
  results[choice] = value;
@@ -16887,9 +17683,9 @@ function createPrivateVoting() {
16887
17683
  }
16888
17684
 
16889
17685
  // src/nft/private-nft.ts
16890
- var import_sha25621 = require("@noble/hashes/sha256");
17686
+ var import_sha25622 = require("@noble/hashes/sha256");
16891
17687
  var import_secp256k18 = require("@noble/curves/secp256k1");
16892
- var import_utils29 = require("@noble/hashes/utils");
17688
+ var import_utils30 = require("@noble/hashes/utils");
16893
17689
  init_stealth();
16894
17690
  init_errors();
16895
17691
  init_validation();
@@ -16978,23 +17774,23 @@ var PrivateNFT = class {
16978
17774
  const { ownership, challenge, stealthPrivateKey } = params;
16979
17775
  try {
16980
17776
  const message = this.createProofMessage(ownership, challenge);
16981
- const messageHash = (0, import_sha25621.sha256)(new TextEncoder().encode(message));
16982
- const privateKeyBytes = (0, import_utils29.hexToBytes)(stealthPrivateKey.slice(2));
17777
+ const messageHash = (0, import_sha25622.sha256)(new TextEncoder().encode(message));
17778
+ const privateKeyBytes = (0, import_utils30.hexToBytes)(stealthPrivateKey.slice(2));
16983
17779
  const signature = import_secp256k18.secp256k1.sign(messageHash, privateKeyBytes);
16984
17780
  const zkProof = {
16985
17781
  type: "ownership",
16986
- proof: `0x${(0, import_utils29.bytesToHex)(signature.toCompactRawBytes())}`,
17782
+ proof: `0x${(0, import_utils30.bytesToHex)(signature.toCompactRawBytes())}`,
16987
17783
  publicInputs: [
16988
- `0x${(0, import_utils29.bytesToHex)(messageHash)}`
17784
+ `0x${(0, import_utils30.bytesToHex)(messageHash)}`
16989
17785
  ]
16990
17786
  };
16991
- const stealthHashBytes = (0, import_sha25621.sha256)((0, import_utils29.hexToBytes)(ownership.ownerStealth.address.slice(2)));
17787
+ const stealthHashBytes = (0, import_sha25622.sha256)((0, import_utils30.hexToBytes)(ownership.ownerStealth.address.slice(2)));
16992
17788
  return {
16993
17789
  nftContract: ownership.nftContract,
16994
17790
  tokenId: ownership.tokenId,
16995
17791
  challenge,
16996
17792
  proof: zkProof,
16997
- stealthHash: `0x${(0, import_utils29.bytesToHex)(stealthHashBytes)}`,
17793
+ stealthHash: `0x${(0, import_utils30.bytesToHex)(stealthHashBytes)}`,
16998
17794
  timestamp: Date.now()
16999
17795
  };
17000
17796
  } catch (e) {
@@ -17036,9 +17832,9 @@ var PrivateNFT = class {
17036
17832
  verifyOwnership(proof) {
17037
17833
  try {
17038
17834
  this.validateOwnershipProof(proof);
17039
- const signatureBytes = (0, import_utils29.hexToBytes)(proof.proof.proof.slice(2));
17835
+ const signatureBytes = (0, import_utils30.hexToBytes)(proof.proof.proof.slice(2));
17040
17836
  const signature = import_secp256k18.secp256k1.Signature.fromCompact(signatureBytes);
17041
- const messageHash = (0, import_utils29.hexToBytes)(proof.proof.publicInputs[0].slice(2));
17837
+ const messageHash = (0, import_utils30.hexToBytes)(proof.proof.publicInputs[0].slice(2));
17042
17838
  if (signatureBytes.length !== 64) {
17043
17839
  return {
17044
17840
  valid: false,
@@ -17135,12 +17931,12 @@ var PrivateNFT = class {
17135
17931
  chain: nft.chain,
17136
17932
  timestamp: Date.now()
17137
17933
  };
17138
- const previousOwnerHashBytes = (0, import_sha25621.sha256)((0, import_utils29.hexToBytes)(nft.ownerStealth.address.slice(2)));
17934
+ const previousOwnerHashBytes = (0, import_sha25622.sha256)((0, import_utils30.hexToBytes)(nft.ownerStealth.address.slice(2)));
17139
17935
  const transfer = {
17140
17936
  nftContract: nft.nftContract,
17141
17937
  tokenId: nft.tokenId,
17142
17938
  newOwnerStealth,
17143
- previousOwnerHash: `0x${(0, import_utils29.bytesToHex)(previousOwnerHashBytes)}`,
17939
+ previousOwnerHash: `0x${(0, import_utils30.bytesToHex)(previousOwnerHashBytes)}`,
17144
17940
  chain: nft.chain,
17145
17941
  timestamp: Date.now()
17146
17942
  };
@@ -17207,8 +18003,8 @@ var PrivateNFT = class {
17207
18003
  );
17208
18004
  }
17209
18005
  const ownedNFTs = [];
17210
- const scanKeyHex = `0x${(0, import_utils29.bytesToHex)(scanKey)}`;
17211
- const viewingKeyHex = `0x${(0, import_utils29.bytesToHex)(viewingKey)}`;
18006
+ const scanKeyHex = `0x${(0, import_utils30.bytesToHex)(scanKey)}`;
18007
+ const viewingKeyHex = `0x${(0, import_utils30.bytesToHex)(viewingKey)}`;
17212
18008
  for (const transfer of transfers) {
17213
18009
  try {
17214
18010
  if (!transfer || typeof transfer !== "object") {
@@ -17426,10 +18222,10 @@ function verifyOwnership(proof) {
17426
18222
 
17427
18223
  // src/wallet/errors.ts
17428
18224
  init_errors();
17429
- var import_types21 = require("@sip-protocol/types");
18225
+ var import_types22 = require("@sip-protocol/types");
17430
18226
  var WalletError = class extends SIPError {
17431
18227
  walletCode;
17432
- constructor(message, walletCode = import_types21.WalletErrorCode.UNKNOWN, options) {
18228
+ constructor(message, walletCode = import_types22.WalletErrorCode.UNKNOWN, options) {
17433
18229
  super(message, "SIP_7000" /* WALLET_ERROR */, options);
17434
18230
  this.walletCode = walletCode;
17435
18231
  this.name = "WalletError";
@@ -17439,10 +18235,10 @@ var WalletError = class extends SIPError {
17439
18235
  */
17440
18236
  isConnectionError() {
17441
18237
  const codes = [
17442
- import_types21.WalletErrorCode.NOT_INSTALLED,
17443
- import_types21.WalletErrorCode.CONNECTION_REJECTED,
17444
- import_types21.WalletErrorCode.CONNECTION_FAILED,
17445
- import_types21.WalletErrorCode.NOT_CONNECTED
18238
+ import_types22.WalletErrorCode.NOT_INSTALLED,
18239
+ import_types22.WalletErrorCode.CONNECTION_REJECTED,
18240
+ import_types22.WalletErrorCode.CONNECTION_FAILED,
18241
+ import_types22.WalletErrorCode.NOT_CONNECTED
17446
18242
  ];
17447
18243
  return codes.includes(this.walletCode);
17448
18244
  }
@@ -17451,9 +18247,9 @@ var WalletError = class extends SIPError {
17451
18247
  */
17452
18248
  isSigningError() {
17453
18249
  const codes = [
17454
- import_types21.WalletErrorCode.SIGNING_REJECTED,
17455
- import_types21.WalletErrorCode.SIGNING_FAILED,
17456
- import_types21.WalletErrorCode.INVALID_MESSAGE
18250
+ import_types22.WalletErrorCode.SIGNING_REJECTED,
18251
+ import_types22.WalletErrorCode.SIGNING_FAILED,
18252
+ import_types22.WalletErrorCode.INVALID_MESSAGE
17457
18253
  ];
17458
18254
  return codes.includes(this.walletCode);
17459
18255
  }
@@ -17462,10 +18258,10 @@ var WalletError = class extends SIPError {
17462
18258
  */
17463
18259
  isTransactionError() {
17464
18260
  const codes = [
17465
- import_types21.WalletErrorCode.INSUFFICIENT_FUNDS,
17466
- import_types21.WalletErrorCode.TRANSACTION_REJECTED,
17467
- import_types21.WalletErrorCode.TRANSACTION_FAILED,
17468
- import_types21.WalletErrorCode.INVALID_TRANSACTION
18261
+ import_types22.WalletErrorCode.INSUFFICIENT_FUNDS,
18262
+ import_types22.WalletErrorCode.TRANSACTION_REJECTED,
18263
+ import_types22.WalletErrorCode.TRANSACTION_FAILED,
18264
+ import_types22.WalletErrorCode.INVALID_TRANSACTION
17469
18265
  ];
17470
18266
  return codes.includes(this.walletCode);
17471
18267
  }
@@ -17474,9 +18270,9 @@ var WalletError = class extends SIPError {
17474
18270
  */
17475
18271
  isPrivacyError() {
17476
18272
  const codes = [
17477
- import_types21.WalletErrorCode.STEALTH_NOT_SUPPORTED,
17478
- import_types21.WalletErrorCode.VIEWING_KEY_NOT_SUPPORTED,
17479
- import_types21.WalletErrorCode.SHIELDED_NOT_SUPPORTED
18273
+ import_types22.WalletErrorCode.STEALTH_NOT_SUPPORTED,
18274
+ import_types22.WalletErrorCode.VIEWING_KEY_NOT_SUPPORTED,
18275
+ import_types22.WalletErrorCode.SHIELDED_NOT_SUPPORTED
17480
18276
  ];
17481
18277
  return codes.includes(this.walletCode);
17482
18278
  }
@@ -17485,10 +18281,10 @@ var WalletError = class extends SIPError {
17485
18281
  */
17486
18282
  isUserRejection() {
17487
18283
  const codes = [
17488
- import_types21.WalletErrorCode.CONNECTION_REJECTED,
17489
- import_types21.WalletErrorCode.SIGNING_REJECTED,
17490
- import_types21.WalletErrorCode.TRANSACTION_REJECTED,
17491
- import_types21.WalletErrorCode.CHAIN_SWITCH_REJECTED
18284
+ import_types22.WalletErrorCode.CONNECTION_REJECTED,
18285
+ import_types22.WalletErrorCode.SIGNING_REJECTED,
18286
+ import_types22.WalletErrorCode.TRANSACTION_REJECTED,
18287
+ import_types22.WalletErrorCode.CHAIN_SWITCH_REJECTED
17492
18288
  ];
17493
18289
  return codes.includes(this.walletCode);
17494
18290
  }
@@ -17496,15 +18292,15 @@ var WalletError = class extends SIPError {
17496
18292
  function notConnectedError() {
17497
18293
  return new WalletError(
17498
18294
  "Wallet not connected. Call connect() first.",
17499
- import_types21.WalletErrorCode.NOT_CONNECTED
18295
+ import_types22.WalletErrorCode.NOT_CONNECTED
17500
18296
  );
17501
18297
  }
17502
- function featureNotSupportedError(feature, code = import_types21.WalletErrorCode.UNKNOWN) {
18298
+ function featureNotSupportedError(feature, code = import_types22.WalletErrorCode.UNKNOWN) {
17503
18299
  return new WalletError(`${feature} is not supported by this wallet`, code);
17504
18300
  }
17505
18301
 
17506
18302
  // src/wallet/base-adapter.ts
17507
- var import_types22 = require("@sip-protocol/types");
18303
+ var import_types23 = require("@sip-protocol/types");
17508
18304
  var BaseWalletAdapter = class {
17509
18305
  _address = "";
17510
18306
  _publicKey = "";
@@ -17667,12 +18463,12 @@ var MockWalletAdapter = class extends BaseWalletAdapter {
17667
18463
  this._connectionState = "connecting";
17668
18464
  if (this.shouldFailConnect) {
17669
18465
  this.setError(
17670
- import_types22.WalletErrorCode.CONNECTION_FAILED,
18466
+ import_types23.WalletErrorCode.CONNECTION_FAILED,
17671
18467
  "Mock connection failure"
17672
18468
  );
17673
18469
  throw new WalletError(
17674
18470
  "Mock connection failure",
17675
- import_types22.WalletErrorCode.CONNECTION_FAILED
18471
+ import_types23.WalletErrorCode.CONNECTION_FAILED
17676
18472
  );
17677
18473
  }
17678
18474
  await new Promise((resolve) => setTimeout(resolve, 10));
@@ -17684,7 +18480,7 @@ var MockWalletAdapter = class extends BaseWalletAdapter {
17684
18480
  async signMessage(message) {
17685
18481
  this.requireConnected();
17686
18482
  if (this.shouldFailSign) {
17687
- throw new WalletError("Mock signing failure", import_types22.WalletErrorCode.SIGNING_FAILED);
18483
+ throw new WalletError("Mock signing failure", import_types23.WalletErrorCode.SIGNING_FAILED);
17688
18484
  }
17689
18485
  const mockSig = new Uint8Array(64);
17690
18486
  for (let i = 0; i < 64; i++) {
@@ -17699,7 +18495,7 @@ var MockWalletAdapter = class extends BaseWalletAdapter {
17699
18495
  async signTransaction(tx) {
17700
18496
  this.requireConnected();
17701
18497
  if (this.shouldFailSign) {
17702
- throw new WalletError("Mock signing failure", import_types22.WalletErrorCode.SIGNING_FAILED);
18498
+ throw new WalletError("Mock signing failure", import_types23.WalletErrorCode.SIGNING_FAILED);
17703
18499
  }
17704
18500
  const signature = await this.signMessage(
17705
18501
  new TextEncoder().encode(JSON.stringify(tx.data))
@@ -17881,7 +18677,7 @@ function isPrivateWalletAdapter(adapter) {
17881
18677
  }
17882
18678
 
17883
18679
  // src/wallet/solana/adapter.ts
17884
- var import_types23 = require("@sip-protocol/types");
18680
+ var import_types24 = require("@sip-protocol/types");
17885
18681
 
17886
18682
  // src/wallet/solana/types.ts
17887
18683
  function getSolanaProvider(wallet = "phantom") {
@@ -18002,19 +18798,19 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
18002
18798
  }
18003
18799
  if (!this.provider) {
18004
18800
  this.setError(
18005
- import_types23.WalletErrorCode.NOT_INSTALLED,
18801
+ import_types24.WalletErrorCode.NOT_INSTALLED,
18006
18802
  `${this.walletName} wallet is not installed`
18007
18803
  );
18008
18804
  throw new WalletError(
18009
18805
  `${this.walletName} wallet is not installed`,
18010
- import_types23.WalletErrorCode.NOT_INSTALLED
18806
+ import_types24.WalletErrorCode.NOT_INSTALLED
18011
18807
  );
18012
18808
  }
18013
18809
  const { publicKey } = await this.provider.connect();
18014
18810
  if (!publicKey) {
18015
18811
  throw new WalletError(
18016
18812
  "No public key returned from wallet",
18017
- import_types23.WalletErrorCode.CONNECTION_FAILED
18813
+ import_types24.WalletErrorCode.CONNECTION_FAILED
18018
18814
  );
18019
18815
  }
18020
18816
  this.setupEventHandlers();
@@ -18024,11 +18820,11 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
18024
18820
  } catch (error) {
18025
18821
  const message = error instanceof Error ? error.message : "Connection failed";
18026
18822
  if (message.includes("User rejected") || message.includes("rejected")) {
18027
- this.setError(import_types23.WalletErrorCode.CONNECTION_REJECTED, message);
18028
- throw new WalletError(message, import_types23.WalletErrorCode.CONNECTION_REJECTED);
18823
+ this.setError(import_types24.WalletErrorCode.CONNECTION_REJECTED, message);
18824
+ throw new WalletError(message, import_types24.WalletErrorCode.CONNECTION_REJECTED);
18029
18825
  }
18030
- this.setError(import_types23.WalletErrorCode.CONNECTION_FAILED, message);
18031
- throw error instanceof WalletError ? error : new WalletError(message, import_types23.WalletErrorCode.CONNECTION_FAILED, { cause: error });
18826
+ this.setError(import_types24.WalletErrorCode.CONNECTION_FAILED, message);
18827
+ throw error instanceof WalletError ? error : new WalletError(message, import_types24.WalletErrorCode.CONNECTION_FAILED, { cause: error });
18032
18828
  }
18033
18829
  }
18034
18830
  /**
@@ -18051,7 +18847,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
18051
18847
  async signMessage(message) {
18052
18848
  this.requireConnected();
18053
18849
  if (!this.provider) {
18054
- throw new WalletError("Provider not available", import_types23.WalletErrorCode.NOT_CONNECTED);
18850
+ throw new WalletError("Provider not available", import_types24.WalletErrorCode.NOT_CONNECTED);
18055
18851
  }
18056
18852
  try {
18057
18853
  const { signature } = await this.provider.signMessage(message);
@@ -18062,9 +18858,9 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
18062
18858
  } catch (error) {
18063
18859
  const message2 = error instanceof Error ? error.message : "Signing failed";
18064
18860
  if (message2.includes("User rejected") || message2.includes("rejected")) {
18065
- throw new WalletError(message2, import_types23.WalletErrorCode.SIGNING_REJECTED);
18861
+ throw new WalletError(message2, import_types24.WalletErrorCode.SIGNING_REJECTED);
18066
18862
  }
18067
- throw new WalletError(message2, import_types23.WalletErrorCode.SIGNING_FAILED, {
18863
+ throw new WalletError(message2, import_types24.WalletErrorCode.SIGNING_FAILED, {
18068
18864
  cause: error
18069
18865
  });
18070
18866
  }
@@ -18077,7 +18873,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
18077
18873
  async signTransaction(tx) {
18078
18874
  this.requireConnected();
18079
18875
  if (!this.provider) {
18080
- throw new WalletError("Provider not available", import_types23.WalletErrorCode.NOT_CONNECTED);
18876
+ throw new WalletError("Provider not available", import_types24.WalletErrorCode.NOT_CONNECTED);
18081
18877
  }
18082
18878
  try {
18083
18879
  const solTx = tx.data;
@@ -18096,9 +18892,9 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
18096
18892
  } catch (error) {
18097
18893
  const message = error instanceof Error ? error.message : "Signing failed";
18098
18894
  if (message.includes("User rejected") || message.includes("rejected")) {
18099
- throw new WalletError(message, import_types23.WalletErrorCode.SIGNING_REJECTED);
18895
+ throw new WalletError(message, import_types24.WalletErrorCode.SIGNING_REJECTED);
18100
18896
  }
18101
- throw new WalletError(message, import_types23.WalletErrorCode.SIGNING_FAILED, {
18897
+ throw new WalletError(message, import_types24.WalletErrorCode.SIGNING_FAILED, {
18102
18898
  cause: error
18103
18899
  });
18104
18900
  }
@@ -18109,7 +18905,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
18109
18905
  async signAndSendTransaction(tx) {
18110
18906
  this.requireConnected();
18111
18907
  if (!this.provider) {
18112
- throw new WalletError("Provider not available", import_types23.WalletErrorCode.NOT_CONNECTED);
18908
+ throw new WalletError("Provider not available", import_types24.WalletErrorCode.NOT_CONNECTED);
18113
18909
  }
18114
18910
  try {
18115
18911
  const solTx = tx.data;
@@ -18124,12 +18920,12 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
18124
18920
  } catch (error) {
18125
18921
  const message = error instanceof Error ? error.message : "Transaction failed";
18126
18922
  if (message.includes("User rejected") || message.includes("rejected")) {
18127
- throw new WalletError(message, import_types23.WalletErrorCode.TRANSACTION_REJECTED);
18923
+ throw new WalletError(message, import_types24.WalletErrorCode.TRANSACTION_REJECTED);
18128
18924
  }
18129
18925
  if (message.includes("insufficient") || message.includes("Insufficient")) {
18130
- throw new WalletError(message, import_types23.WalletErrorCode.INSUFFICIENT_FUNDS);
18926
+ throw new WalletError(message, import_types24.WalletErrorCode.INSUFFICIENT_FUNDS);
18131
18927
  }
18132
- throw new WalletError(message, import_types23.WalletErrorCode.TRANSACTION_FAILED, {
18928
+ throw new WalletError(message, import_types24.WalletErrorCode.TRANSACTION_FAILED, {
18133
18929
  cause: error
18134
18930
  });
18135
18931
  }
@@ -18142,16 +18938,16 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
18142
18938
  async signAllTransactions(transactions) {
18143
18939
  this.requireConnected();
18144
18940
  if (!this.provider) {
18145
- throw new WalletError("Provider not available", import_types23.WalletErrorCode.NOT_CONNECTED);
18941
+ throw new WalletError("Provider not available", import_types24.WalletErrorCode.NOT_CONNECTED);
18146
18942
  }
18147
18943
  try {
18148
18944
  return await this.provider.signAllTransactions(transactions);
18149
18945
  } catch (error) {
18150
18946
  const message = error instanceof Error ? error.message : "Signing failed";
18151
18947
  if (message.includes("User rejected") || message.includes("rejected")) {
18152
- throw new WalletError(message, import_types23.WalletErrorCode.SIGNING_REJECTED);
18948
+ throw new WalletError(message, import_types24.WalletErrorCode.SIGNING_REJECTED);
18153
18949
  }
18154
- throw new WalletError(message, import_types23.WalletErrorCode.SIGNING_FAILED, {
18950
+ throw new WalletError(message, import_types24.WalletErrorCode.SIGNING_FAILED, {
18155
18951
  cause: error
18156
18952
  });
18157
18953
  }
@@ -18172,7 +18968,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
18172
18968
  } catch (error) {
18173
18969
  throw new WalletError(
18174
18970
  "Failed to get balance",
18175
- import_types23.WalletErrorCode.UNKNOWN,
18971
+ import_types24.WalletErrorCode.UNKNOWN,
18176
18972
  { cause: error }
18177
18973
  );
18178
18974
  }
@@ -18185,7 +18981,7 @@ var SolanaWalletAdapter = class extends BaseWalletAdapter {
18185
18981
  if (asset.chain !== "solana") {
18186
18982
  throw new WalletError(
18187
18983
  `Asset chain ${asset.chain} not supported by Solana adapter`,
18188
- import_types23.WalletErrorCode.UNSUPPORTED_CHAIN
18984
+ import_types24.WalletErrorCode.UNSUPPORTED_CHAIN
18189
18985
  );
18190
18986
  }
18191
18987
  if (!asset.address) {
@@ -18303,7 +19099,7 @@ function createSolanaAdapter(config = {}) {
18303
19099
  }
18304
19100
 
18305
19101
  // src/wallet/solana/mock.ts
18306
- var import_types25 = require("@sip-protocol/types");
19102
+ var import_types26 = require("@sip-protocol/types");
18307
19103
  var MockPublicKey = class {
18308
19104
  base58;
18309
19105
  bytes;
@@ -18369,8 +19165,8 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
18369
19165
  this._connectionState = "connecting";
18370
19166
  await this.simulateLatency();
18371
19167
  if (this.shouldFailConnect) {
18372
- this.setError(import_types25.WalletErrorCode.CONNECTION_FAILED, "Mock connection failure");
18373
- throw new WalletError("Mock connection failure", import_types25.WalletErrorCode.CONNECTION_FAILED);
19168
+ this.setError(import_types26.WalletErrorCode.CONNECTION_FAILED, "Mock connection failure");
19169
+ throw new WalletError("Mock connection failure", import_types26.WalletErrorCode.CONNECTION_FAILED);
18374
19170
  }
18375
19171
  const hexPubKey = "0x" + Buffer.from(this.mockPublicKey.toBytes()).toString("hex");
18376
19172
  this.setConnected(this.mockAddress, hexPubKey);
@@ -18389,7 +19185,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
18389
19185
  this.requireConnected();
18390
19186
  await this.simulateLatency();
18391
19187
  if (this.shouldFailSign) {
18392
- throw new WalletError("Mock signing failure", import_types25.WalletErrorCode.SIGNING_REJECTED);
19188
+ throw new WalletError("Mock signing failure", import_types26.WalletErrorCode.SIGNING_REJECTED);
18393
19189
  }
18394
19190
  const mockSig = new Uint8Array(64);
18395
19191
  for (let i = 0; i < 64; i++) {
@@ -18407,7 +19203,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
18407
19203
  this.requireConnected();
18408
19204
  await this.simulateLatency();
18409
19205
  if (this.shouldFailSign) {
18410
- throw new WalletError("Mock signing failure", import_types25.WalletErrorCode.SIGNING_REJECTED);
19206
+ throw new WalletError("Mock signing failure", import_types26.WalletErrorCode.SIGNING_REJECTED);
18411
19207
  }
18412
19208
  const solTx = tx.data;
18413
19209
  this.signedTransactions.push(solTx);
@@ -18427,10 +19223,10 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
18427
19223
  this.requireConnected();
18428
19224
  await this.simulateLatency();
18429
19225
  if (this.shouldFailSign) {
18430
- throw new WalletError("Mock signing failure", import_types25.WalletErrorCode.SIGNING_REJECTED);
19226
+ throw new WalletError("Mock signing failure", import_types26.WalletErrorCode.SIGNING_REJECTED);
18431
19227
  }
18432
19228
  if (this.shouldFailTransaction) {
18433
- throw new WalletError("Mock transaction failure", import_types25.WalletErrorCode.TRANSACTION_FAILED);
19229
+ throw new WalletError("Mock transaction failure", import_types26.WalletErrorCode.TRANSACTION_FAILED);
18434
19230
  }
18435
19231
  const txSig = `mock_tx_${Date.now()}_${Math.random().toString(36).slice(2)}`;
18436
19232
  this.sentTransactions.push(txSig);
@@ -18450,7 +19246,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
18450
19246
  this.requireConnected();
18451
19247
  await this.simulateLatency();
18452
19248
  if (this.shouldFailSign) {
18453
- throw new WalletError("Mock signing failure", import_types25.WalletErrorCode.SIGNING_REJECTED);
19249
+ throw new WalletError("Mock signing failure", import_types26.WalletErrorCode.SIGNING_REJECTED);
18454
19250
  }
18455
19251
  this.signedTransactions.push(...transactions);
18456
19252
  return transactions.map((tx) => {
@@ -18477,7 +19273,7 @@ var MockSolanaAdapter = class extends BaseWalletAdapter {
18477
19273
  if (asset.chain !== "solana") {
18478
19274
  throw new WalletError(
18479
19275
  `Asset chain ${asset.chain} not supported by Solana adapter`,
18480
- import_types25.WalletErrorCode.UNSUPPORTED_CHAIN
19276
+ import_types26.WalletErrorCode.UNSUPPORTED_CHAIN
18481
19277
  );
18482
19278
  }
18483
19279
  if (!asset.address) {
@@ -18646,7 +19442,7 @@ function createMockSolanaAdapter(config = {}) {
18646
19442
  }
18647
19443
 
18648
19444
  // src/wallet/ethereum/adapter.ts
18649
- var import_types27 = require("@sip-protocol/types");
19445
+ var import_types28 = require("@sip-protocol/types");
18650
19446
 
18651
19447
  // src/wallet/ethereum/types.ts
18652
19448
  var EthereumChainId = {
@@ -18788,7 +19584,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
18788
19584
  this._connectionState = "error";
18789
19585
  throw new WalletError(
18790
19586
  `${this.walletType} wallet not found. Please install the extension.`,
18791
- import_types27.WalletErrorCode.NOT_INSTALLED
19587
+ import_types28.WalletErrorCode.NOT_INSTALLED
18792
19588
  );
18793
19589
  }
18794
19590
  const accounts = await this.provider.request({
@@ -18798,7 +19594,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
18798
19594
  this._connectionState = "error";
18799
19595
  throw new WalletError(
18800
19596
  "No accounts returned from wallet",
18801
- import_types27.WalletErrorCode.CONNECTION_REJECTED
19597
+ import_types28.WalletErrorCode.CONNECTION_REJECTED
18802
19598
  );
18803
19599
  }
18804
19600
  const address = normalizeAddress(accounts[0]);
@@ -18818,12 +19614,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
18818
19614
  if (rpcError.code === 4001) {
18819
19615
  throw new WalletError(
18820
19616
  "User rejected connection request",
18821
- import_types27.WalletErrorCode.CONNECTION_REJECTED
19617
+ import_types28.WalletErrorCode.CONNECTION_REJECTED
18822
19618
  );
18823
19619
  }
18824
19620
  throw new WalletError(
18825
19621
  `Failed to connect: ${rpcError.message || String(error)}`,
18826
- import_types27.WalletErrorCode.CONNECTION_FAILED
19622
+ import_types28.WalletErrorCode.CONNECTION_FAILED
18827
19623
  );
18828
19624
  }
18829
19625
  }
@@ -18843,7 +19639,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
18843
19639
  if (!this.provider) {
18844
19640
  throw new WalletError(
18845
19641
  "Provider not available",
18846
- import_types27.WalletErrorCode.NOT_CONNECTED
19642
+ import_types28.WalletErrorCode.NOT_CONNECTED
18847
19643
  );
18848
19644
  }
18849
19645
  try {
@@ -18861,12 +19657,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
18861
19657
  if (rpcError.code === 4001) {
18862
19658
  throw new WalletError(
18863
19659
  "User rejected signing request",
18864
- import_types27.WalletErrorCode.SIGNING_REJECTED
19660
+ import_types28.WalletErrorCode.SIGNING_REJECTED
18865
19661
  );
18866
19662
  }
18867
19663
  throw new WalletError(
18868
19664
  `Failed to sign message: ${rpcError.message || String(error)}`,
18869
- import_types27.WalletErrorCode.SIGNING_FAILED
19665
+ import_types28.WalletErrorCode.SIGNING_FAILED
18870
19666
  );
18871
19667
  }
18872
19668
  }
@@ -18878,7 +19674,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
18878
19674
  if (!this.provider) {
18879
19675
  throw new WalletError(
18880
19676
  "Provider not available",
18881
- import_types27.WalletErrorCode.NOT_CONNECTED
19677
+ import_types28.WalletErrorCode.NOT_CONNECTED
18882
19678
  );
18883
19679
  }
18884
19680
  try {
@@ -18895,12 +19691,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
18895
19691
  if (rpcError.code === 4001) {
18896
19692
  throw new WalletError(
18897
19693
  "User rejected signing request",
18898
- import_types27.WalletErrorCode.SIGNING_REJECTED
19694
+ import_types28.WalletErrorCode.SIGNING_REJECTED
18899
19695
  );
18900
19696
  }
18901
19697
  throw new WalletError(
18902
19698
  `Failed to sign typed data: ${rpcError.message || String(error)}`,
18903
- import_types27.WalletErrorCode.SIGNING_FAILED
19699
+ import_types28.WalletErrorCode.SIGNING_FAILED
18904
19700
  );
18905
19701
  }
18906
19702
  }
@@ -18912,7 +19708,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
18912
19708
  if (!this.provider) {
18913
19709
  throw new WalletError(
18914
19710
  "Provider not available",
18915
- import_types27.WalletErrorCode.NOT_CONNECTED
19711
+ import_types28.WalletErrorCode.NOT_CONNECTED
18916
19712
  );
18917
19713
  }
18918
19714
  try {
@@ -18940,7 +19736,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
18940
19736
  if (rpcError.code === 4001) {
18941
19737
  throw new WalletError(
18942
19738
  "User rejected transaction signing",
18943
- import_types27.WalletErrorCode.SIGNING_REJECTED
19739
+ import_types28.WalletErrorCode.SIGNING_REJECTED
18944
19740
  );
18945
19741
  }
18946
19742
  if (rpcError.code === -32601 || rpcError.message?.includes("not supported")) {
@@ -18958,7 +19754,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
18958
19754
  }
18959
19755
  throw new WalletError(
18960
19756
  `Failed to sign transaction: ${rpcError.message || String(error)}`,
18961
- import_types27.WalletErrorCode.TRANSACTION_FAILED
19757
+ import_types28.WalletErrorCode.TRANSACTION_FAILED
18962
19758
  );
18963
19759
  }
18964
19760
  }
@@ -18970,7 +19766,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
18970
19766
  if (!this.provider) {
18971
19767
  throw new WalletError(
18972
19768
  "Provider not available",
18973
- import_types27.WalletErrorCode.NOT_CONNECTED
19769
+ import_types28.WalletErrorCode.NOT_CONNECTED
18974
19770
  );
18975
19771
  }
18976
19772
  try {
@@ -18992,12 +19788,12 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
18992
19788
  if (rpcError.code === 4001) {
18993
19789
  throw new WalletError(
18994
19790
  "User rejected transaction",
18995
- import_types27.WalletErrorCode.TRANSACTION_REJECTED
19791
+ import_types28.WalletErrorCode.TRANSACTION_REJECTED
18996
19792
  );
18997
19793
  }
18998
19794
  throw new WalletError(
18999
19795
  `Failed to send transaction: ${rpcError.message || String(error)}`,
19000
- import_types27.WalletErrorCode.TRANSACTION_FAILED
19796
+ import_types28.WalletErrorCode.TRANSACTION_FAILED
19001
19797
  );
19002
19798
  }
19003
19799
  }
@@ -19032,7 +19828,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
19032
19828
  } catch (error) {
19033
19829
  throw new WalletError(
19034
19830
  `Failed to fetch balance: ${String(error)}`,
19035
- import_types27.WalletErrorCode.UNKNOWN
19831
+ import_types28.WalletErrorCode.UNKNOWN
19036
19832
  );
19037
19833
  }
19038
19834
  }
@@ -19044,7 +19840,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
19044
19840
  if (asset.chain !== "ethereum") {
19045
19841
  throw new WalletError(
19046
19842
  `Asset chain ${asset.chain} not supported by Ethereum adapter`,
19047
- import_types27.WalletErrorCode.UNSUPPORTED_CHAIN
19843
+ import_types28.WalletErrorCode.UNSUPPORTED_CHAIN
19048
19844
  );
19049
19845
  }
19050
19846
  if (!asset.address) {
@@ -19069,7 +19865,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
19069
19865
  } catch (error) {
19070
19866
  throw new WalletError(
19071
19867
  `Failed to fetch token balance: ${String(error)}`,
19072
- import_types27.WalletErrorCode.UNKNOWN
19868
+ import_types28.WalletErrorCode.UNKNOWN
19073
19869
  );
19074
19870
  }
19075
19871
  }
@@ -19081,7 +19877,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
19081
19877
  if (!this.provider) {
19082
19878
  throw new WalletError(
19083
19879
  "Provider not available",
19084
- import_types27.WalletErrorCode.NOT_CONNECTED
19880
+ import_types28.WalletErrorCode.NOT_CONNECTED
19085
19881
  );
19086
19882
  }
19087
19883
  try {
@@ -19096,18 +19892,18 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
19096
19892
  if (rpcError.code === 4001) {
19097
19893
  throw new WalletError(
19098
19894
  "User rejected chain switch",
19099
- import_types27.WalletErrorCode.CHAIN_SWITCH_REJECTED
19895
+ import_types28.WalletErrorCode.CHAIN_SWITCH_REJECTED
19100
19896
  );
19101
19897
  }
19102
19898
  if (rpcError.code === 4902) {
19103
19899
  throw new WalletError(
19104
19900
  `Chain ${chainId} not added to wallet`,
19105
- import_types27.WalletErrorCode.UNSUPPORTED_CHAIN
19901
+ import_types28.WalletErrorCode.UNSUPPORTED_CHAIN
19106
19902
  );
19107
19903
  }
19108
19904
  throw new WalletError(
19109
19905
  `Failed to switch chain: ${rpcError.message || String(error)}`,
19110
- import_types27.WalletErrorCode.CHAIN_SWITCH_FAILED
19906
+ import_types28.WalletErrorCode.CHAIN_SWITCH_FAILED
19111
19907
  );
19112
19908
  }
19113
19909
  }
@@ -19143,7 +19939,7 @@ var EthereumWalletAdapter = class extends BaseWalletAdapter {
19143
19939
  }
19144
19940
  throw new WalletError(
19145
19941
  `Transaction ${txHash} not confirmed after ${maxAttempts * 5} seconds`,
19146
- import_types27.WalletErrorCode.TRANSACTION_FAILED
19942
+ import_types28.WalletErrorCode.TRANSACTION_FAILED
19147
19943
  );
19148
19944
  }
19149
19945
  /**
@@ -19217,7 +20013,7 @@ function createEthereumAdapter(config) {
19217
20013
  }
19218
20014
 
19219
20015
  // src/wallet/ethereum/mock.ts
19220
- var import_types29 = require("@sip-protocol/types");
20016
+ var import_types30 = require("@sip-protocol/types");
19221
20017
  var MockEthereumAdapter = class extends BaseWalletAdapter {
19222
20018
  chain = "ethereum";
19223
20019
  name = "mock-ethereum";
@@ -19258,7 +20054,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
19258
20054
  this._connectionState = "error";
19259
20055
  throw new WalletError(
19260
20056
  "Mock connection rejected",
19261
- import_types29.WalletErrorCode.CONNECTION_REJECTED
20057
+ import_types30.WalletErrorCode.CONNECTION_REJECTED
19262
20058
  );
19263
20059
  }
19264
20060
  await new Promise((resolve) => setTimeout(resolve, 10));
@@ -19270,7 +20066,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
19270
20066
  this._connectionState = "error";
19271
20067
  throw new WalletError(
19272
20068
  `Mock connection failed: ${String(error)}`,
19273
- import_types29.WalletErrorCode.CONNECTION_FAILED
20069
+ import_types30.WalletErrorCode.CONNECTION_FAILED
19274
20070
  );
19275
20071
  }
19276
20072
  }
@@ -19288,7 +20084,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
19288
20084
  if (this._shouldFailSign) {
19289
20085
  throw new WalletError(
19290
20086
  "Mock signing rejected",
19291
- import_types29.WalletErrorCode.SIGNING_REJECTED
20087
+ import_types30.WalletErrorCode.SIGNING_REJECTED
19292
20088
  );
19293
20089
  }
19294
20090
  const msgHex = Buffer.from(message).toString("hex");
@@ -19306,7 +20102,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
19306
20102
  if (this._shouldFailSign) {
19307
20103
  throw new WalletError(
19308
20104
  "Mock signing rejected",
19309
- import_types29.WalletErrorCode.SIGNING_REJECTED
20105
+ import_types30.WalletErrorCode.SIGNING_REJECTED
19310
20106
  );
19311
20107
  }
19312
20108
  const mockSig = `0x${"1".repeat(130)}`;
@@ -19323,7 +20119,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
19323
20119
  if (this._shouldFailSign) {
19324
20120
  throw new WalletError(
19325
20121
  "Mock signing rejected",
19326
- import_types29.WalletErrorCode.SIGNING_REJECTED
20122
+ import_types30.WalletErrorCode.SIGNING_REJECTED
19327
20123
  );
19328
20124
  }
19329
20125
  this._signedTransactions.push(tx);
@@ -19348,7 +20144,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
19348
20144
  if (this._shouldFailTransaction) {
19349
20145
  throw new WalletError(
19350
20146
  "Mock transaction failed",
19351
- import_types29.WalletErrorCode.TRANSACTION_FAILED
20147
+ import_types30.WalletErrorCode.TRANSACTION_FAILED
19352
20148
  );
19353
20149
  }
19354
20150
  this._signedTransactions.push(tx);
@@ -19378,7 +20174,7 @@ var MockEthereumAdapter = class extends BaseWalletAdapter {
19378
20174
  if (asset.chain !== "ethereum") {
19379
20175
  throw new WalletError(
19380
20176
  `Asset chain ${asset.chain} not supported by Ethereum adapter`,
19381
- import_types29.WalletErrorCode.UNSUPPORTED_CHAIN
20177
+ import_types30.WalletErrorCode.UNSUPPORTED_CHAIN
19382
20178
  );
19383
20179
  }
19384
20180
  if (!asset.address) {
@@ -19583,28 +20379,28 @@ function createMockEthereumProvider(config = {}) {
19583
20379
  }
19584
20380
 
19585
20381
  // src/wallet/cosmos/adapter.ts
19586
- var import_types32 = require("@sip-protocol/types");
20382
+ var import_types33 = require("@sip-protocol/types");
19587
20383
 
19588
20384
  // src/wallet/cosmos/mock.ts
19589
- var import_types34 = require("@sip-protocol/types");
20385
+ var import_types35 = require("@sip-protocol/types");
19590
20386
 
19591
20387
  // src/wallet/bitcoin/adapter.ts
19592
- var import_types37 = require("@sip-protocol/types");
20388
+ var import_types38 = require("@sip-protocol/types");
19593
20389
 
19594
20390
  // src/wallet/bitcoin/mock.ts
19595
- var import_types39 = require("@sip-protocol/types");
20391
+ var import_types40 = require("@sip-protocol/types");
19596
20392
 
19597
20393
  // src/wallet/aptos/adapter.ts
19598
- var import_types42 = require("@sip-protocol/types");
20394
+ var import_types43 = require("@sip-protocol/types");
19599
20395
 
19600
20396
  // src/wallet/aptos/mock.ts
19601
- var import_types44 = require("@sip-protocol/types");
20397
+ var import_types45 = require("@sip-protocol/types");
19602
20398
 
19603
20399
  // src/wallet/sui/adapter.ts
19604
- var import_types46 = require("@sip-protocol/types");
20400
+ var import_types47 = require("@sip-protocol/types");
19605
20401
 
19606
20402
  // src/wallet/sui/mock.ts
19607
- var import_types48 = require("@sip-protocol/types");
20403
+ var import_types49 = require("@sip-protocol/types");
19608
20404
 
19609
20405
  // src/wallet/hardware/types.ts
19610
20406
  var DerivationPath = {
@@ -19684,7 +20480,7 @@ function getAvailableTransports() {
19684
20480
 
19685
20481
  // src/wallet/hardware/ledger.ts
19686
20482
  var import_rlp = require("@ethereumjs/rlp");
19687
- var import_types50 = require("@sip-protocol/types");
20483
+ var import_types51 = require("@sip-protocol/types");
19688
20484
  var LedgerWalletAdapter = class extends BaseWalletAdapter {
19689
20485
  chain;
19690
20486
  name = "ledger";
@@ -19837,7 +20633,7 @@ var LedgerWalletAdapter = class extends BaseWalletAdapter {
19837
20633
  async getBalance() {
19838
20634
  throw new WalletError(
19839
20635
  "Hardware wallets do not track balances. Use an RPC provider.",
19840
- import_types50.WalletErrorCode.UNSUPPORTED_OPERATION
20636
+ import_types51.WalletErrorCode.UNSUPPORTED_OPERATION
19841
20637
  );
19842
20638
  }
19843
20639
  /**
@@ -19848,7 +20644,7 @@ var LedgerWalletAdapter = class extends BaseWalletAdapter {
19848
20644
  async getTokenBalance(_asset) {
19849
20645
  throw new WalletError(
19850
20646
  "Hardware wallets do not track balances. Use an RPC provider.",
19851
- import_types50.WalletErrorCode.UNSUPPORTED_OPERATION
20647
+ import_types51.WalletErrorCode.UNSUPPORTED_OPERATION
19852
20648
  );
19853
20649
  }
19854
20650
  // ─── Account Management ─────────────────────────────────────────────────────
@@ -20075,7 +20871,7 @@ var LedgerWalletAdapter = class extends BaseWalletAdapter {
20075
20871
  * @see https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/
20076
20872
  */
20077
20873
  buildRawEthereumTx(tx) {
20078
- const hexToBytes24 = (hex) => {
20874
+ const hexToBytes25 = (hex) => {
20079
20875
  if (!hex || hex === "0x" || hex === "0x0" || hex === "0x00") {
20080
20876
  return new Uint8Array(0);
20081
20877
  }
@@ -20092,21 +20888,21 @@ var LedgerWalletAdapter = class extends BaseWalletAdapter {
20092
20888
  const isEIP1559 = tx.maxFeePerGas !== void 0 && tx.maxPriorityFeePerGas !== void 0;
20093
20889
  if (isEIP1559) {
20094
20890
  const txData = [
20095
- hexToBytes24(`0x${tx.chainId.toString(16)}`),
20891
+ hexToBytes25(`0x${tx.chainId.toString(16)}`),
20096
20892
  // chainId
20097
- hexToBytes24(tx.nonce),
20893
+ hexToBytes25(tx.nonce),
20098
20894
  // nonce
20099
- hexToBytes24(tx.maxPriorityFeePerGas),
20895
+ hexToBytes25(tx.maxPriorityFeePerGas),
20100
20896
  // maxPriorityFeePerGas
20101
- hexToBytes24(tx.maxFeePerGas),
20897
+ hexToBytes25(tx.maxFeePerGas),
20102
20898
  // maxFeePerGas
20103
- hexToBytes24(tx.gasLimit),
20899
+ hexToBytes25(tx.gasLimit),
20104
20900
  // gasLimit
20105
- hexToBytes24(tx.to),
20901
+ hexToBytes25(tx.to),
20106
20902
  // to
20107
- hexToBytes24(tx.value),
20903
+ hexToBytes25(tx.value),
20108
20904
  // value
20109
- hexToBytes24(tx.data),
20905
+ hexToBytes25(tx.data),
20110
20906
  // data
20111
20907
  []
20112
20908
  // accessList (empty)
@@ -20125,19 +20921,19 @@ var LedgerWalletAdapter = class extends BaseWalletAdapter {
20125
20921
  );
20126
20922
  }
20127
20923
  const txData = [
20128
- hexToBytes24(tx.nonce),
20924
+ hexToBytes25(tx.nonce),
20129
20925
  // nonce
20130
- hexToBytes24(tx.gasPrice),
20926
+ hexToBytes25(tx.gasPrice),
20131
20927
  // gasPrice
20132
- hexToBytes24(tx.gasLimit),
20928
+ hexToBytes25(tx.gasLimit),
20133
20929
  // gasLimit
20134
- hexToBytes24(tx.to),
20930
+ hexToBytes25(tx.to),
20135
20931
  // to
20136
- hexToBytes24(tx.value),
20932
+ hexToBytes25(tx.value),
20137
20933
  // value
20138
- hexToBytes24(tx.data),
20934
+ hexToBytes25(tx.data),
20139
20935
  // data
20140
- hexToBytes24(`0x${tx.chainId.toString(16)}`),
20936
+ hexToBytes25(`0x${tx.chainId.toString(16)}`),
20141
20937
  // v (chainId for EIP-155)
20142
20938
  new Uint8Array(0),
20143
20939
  // r (empty for unsigned)
@@ -20214,7 +21010,7 @@ function createLedgerAdapter(config) {
20214
21010
  }
20215
21011
 
20216
21012
  // src/wallet/hardware/trezor.ts
20217
- var import_types52 = require("@sip-protocol/types");
21013
+ var import_types53 = require("@sip-protocol/types");
20218
21014
  var TrezorWalletAdapter = class extends BaseWalletAdapter {
20219
21015
  chain;
20220
21016
  name = "trezor";
@@ -20360,7 +21156,7 @@ var TrezorWalletAdapter = class extends BaseWalletAdapter {
20360
21156
  async getBalance() {
20361
21157
  throw new WalletError(
20362
21158
  "Hardware wallets do not track balances. Use an RPC provider.",
20363
- import_types52.WalletErrorCode.UNSUPPORTED_OPERATION
21159
+ import_types53.WalletErrorCode.UNSUPPORTED_OPERATION
20364
21160
  );
20365
21161
  }
20366
21162
  /**
@@ -20371,7 +21167,7 @@ var TrezorWalletAdapter = class extends BaseWalletAdapter {
20371
21167
  async getTokenBalance(_asset) {
20372
21168
  throw new WalletError(
20373
21169
  "Hardware wallets do not track balances. Use an RPC provider.",
20374
- import_types52.WalletErrorCode.UNSUPPORTED_OPERATION
21170
+ import_types53.WalletErrorCode.UNSUPPORTED_OPERATION
20375
21171
  );
20376
21172
  }
20377
21173
  // ─── Account Management ─────────────────────────────────────────────────────
@@ -20652,8 +21448,8 @@ function createTrezorAdapter(config) {
20652
21448
  }
20653
21449
 
20654
21450
  // src/wallet/hardware/mock.ts
20655
- var import_types54 = require("@sip-protocol/types");
20656
- var import_utils30 = require("@noble/hashes/utils");
21451
+ var import_types55 = require("@sip-protocol/types");
21452
+ var import_utils31 = require("@noble/hashes/utils");
20657
21453
  var MockLedgerAdapter = class extends BaseWalletAdapter {
20658
21454
  chain;
20659
21455
  name = "mock-ledger";
@@ -20800,7 +21596,7 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
20800
21596
  async getBalance() {
20801
21597
  throw new WalletError(
20802
21598
  "Hardware wallets do not track balances",
20803
- import_types54.WalletErrorCode.UNSUPPORTED_OPERATION
21599
+ import_types55.WalletErrorCode.UNSUPPORTED_OPERATION
20804
21600
  );
20805
21601
  }
20806
21602
  /**
@@ -20809,7 +21605,7 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
20809
21605
  async getTokenBalance(_asset) {
20810
21606
  throw new WalletError(
20811
21607
  "Hardware wallets do not track balances",
20812
- import_types54.WalletErrorCode.UNSUPPORTED_OPERATION
21608
+ import_types55.WalletErrorCode.UNSUPPORTED_OPERATION
20813
21609
  );
20814
21610
  }
20815
21611
  /**
@@ -20898,15 +21694,15 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
20898
21694
  }
20899
21695
  }
20900
21696
  generateMockAddress(index) {
20901
- const bytes = (0, import_utils30.randomBytes)(20);
21697
+ const bytes = (0, import_utils31.randomBytes)(20);
20902
21698
  bytes[0] = index;
20903
- return `0x${(0, import_utils30.bytesToHex)(bytes)}`;
21699
+ return `0x${(0, import_utils31.bytesToHex)(bytes)}`;
20904
21700
  }
20905
21701
  generateMockPublicKey(index) {
20906
- const bytes = (0, import_utils30.randomBytes)(33);
21702
+ const bytes = (0, import_utils31.randomBytes)(33);
20907
21703
  bytes[0] = 2;
20908
21704
  bytes[1] = index;
20909
- return `0x${(0, import_utils30.bytesToHex)(bytes)}`;
21705
+ return `0x${(0, import_utils31.bytesToHex)(bytes)}`;
20910
21706
  }
20911
21707
  generateMockSignature(data) {
20912
21708
  const sig = new Uint8Array(65);
@@ -20915,7 +21711,7 @@ var MockLedgerAdapter = class extends BaseWalletAdapter {
20915
21711
  sig[32 + i] = (data[i % data.length] ?? 0) ^ i * 11;
20916
21712
  }
20917
21713
  sig[64] = 27;
20918
- return `0x${(0, import_utils30.bytesToHex)(sig)}`;
21714
+ return `0x${(0, import_utils31.bytesToHex)(sig)}`;
20919
21715
  }
20920
21716
  delay(ms) {
20921
21717
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -21039,13 +21835,13 @@ var MockTrezorAdapter = class extends BaseWalletAdapter {
21039
21835
  async getBalance() {
21040
21836
  throw new WalletError(
21041
21837
  "Hardware wallets do not track balances",
21042
- import_types54.WalletErrorCode.UNSUPPORTED_OPERATION
21838
+ import_types55.WalletErrorCode.UNSUPPORTED_OPERATION
21043
21839
  );
21044
21840
  }
21045
21841
  async getTokenBalance(_asset) {
21046
21842
  throw new WalletError(
21047
21843
  "Hardware wallets do not track balances",
21048
- import_types54.WalletErrorCode.UNSUPPORTED_OPERATION
21844
+ import_types55.WalletErrorCode.UNSUPPORTED_OPERATION
21049
21845
  );
21050
21846
  }
21051
21847
  async getAccounts(startIndex = 0, count = 5) {
@@ -21104,15 +21900,15 @@ var MockTrezorAdapter = class extends BaseWalletAdapter {
21104
21900
  }
21105
21901
  }
21106
21902
  generateMockAddress(index) {
21107
- const bytes = (0, import_utils30.randomBytes)(20);
21903
+ const bytes = (0, import_utils31.randomBytes)(20);
21108
21904
  bytes[0] = index + 100;
21109
- return `0x${(0, import_utils30.bytesToHex)(bytes)}`;
21905
+ return `0x${(0, import_utils31.bytesToHex)(bytes)}`;
21110
21906
  }
21111
21907
  generateMockPublicKey(index) {
21112
- const bytes = (0, import_utils30.randomBytes)(33);
21908
+ const bytes = (0, import_utils31.randomBytes)(33);
21113
21909
  bytes[0] = 3;
21114
21910
  bytes[1] = index + 100;
21115
- return `0x${(0, import_utils30.bytesToHex)(bytes)}`;
21911
+ return `0x${(0, import_utils31.bytesToHex)(bytes)}`;
21116
21912
  }
21117
21913
  generateMockSignature(data) {
21118
21914
  const sig = new Uint8Array(65);
@@ -21121,7 +21917,7 @@ var MockTrezorAdapter = class extends BaseWalletAdapter {
21121
21917
  sig[32 + i] = (data[i % data.length] ?? 0) ^ i * 17;
21122
21918
  }
21123
21919
  sig[64] = 28;
21124
- return `0x${(0, import_utils30.bytesToHex)(sig)}`;
21920
+ return `0x${(0, import_utils31.bytesToHex)(sig)}`;
21125
21921
  }
21126
21922
  delay(ms) {
21127
21923
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -21135,7 +21931,7 @@ function createMockTrezorAdapter(config) {
21135
21931
  }
21136
21932
 
21137
21933
  // src/wallet/index.ts
21138
- var import_types57 = require("@sip-protocol/types");
21934
+ var import_types58 = require("@sip-protocol/types");
21139
21935
 
21140
21936
  // src/index.ts
21141
21937
  init_solana();
@@ -21189,6 +21985,1772 @@ function getSupportedSameChainChains() {
21189
21985
  return ["solana"];
21190
21986
  }
21191
21987
 
21988
+ // src/privacy-backends/registry.ts
21989
+ var DEFAULT_PRIORITY = 50;
21990
+ var PrivacyBackendRegistry = class {
21991
+ backends = /* @__PURE__ */ new Map();
21992
+ /**
21993
+ * Register a privacy backend
21994
+ *
21995
+ * @param backend - Backend instance to register
21996
+ * @param options - Registration options
21997
+ * @throws Error if backend with same name exists and override is false
21998
+ *
21999
+ * @example
22000
+ * ```typescript
22001
+ * registry.register(new SIPNativeBackend())
22002
+ * registry.register(new PrivacyCashBackend(), { priority: 100 })
22003
+ * ```
22004
+ */
22005
+ register(backend, options = {}) {
22006
+ const { override = false, priority = DEFAULT_PRIORITY, enabled = true } = options;
22007
+ if (this.backends.has(backend.name) && !override) {
22008
+ throw new Error(
22009
+ `Backend '${backend.name}' is already registered. Use { override: true } to replace it.`
22010
+ );
22011
+ }
22012
+ this.backends.set(backend.name, {
22013
+ backend,
22014
+ priority,
22015
+ enabled,
22016
+ registeredAt: Date.now()
22017
+ });
22018
+ }
22019
+ /**
22020
+ * Unregister a backend by name
22021
+ *
22022
+ * @param name - Backend name to unregister
22023
+ * @returns true if backend was removed, false if not found
22024
+ */
22025
+ unregister(name) {
22026
+ return this.backends.delete(name);
22027
+ }
22028
+ /**
22029
+ * Get a backend by name
22030
+ *
22031
+ * @param name - Backend name
22032
+ * @returns Backend instance or undefined if not found
22033
+ */
22034
+ get(name) {
22035
+ const entry = this.backends.get(name);
22036
+ return entry?.enabled ? entry.backend : void 0;
22037
+ }
22038
+ /**
22039
+ * Check if a backend is registered
22040
+ *
22041
+ * @param name - Backend name
22042
+ * @returns true if registered (regardless of enabled state)
22043
+ */
22044
+ has(name) {
22045
+ return this.backends.has(name);
22046
+ }
22047
+ /**
22048
+ * Get all enabled backends sorted by priority
22049
+ *
22050
+ * @returns Array of backends (highest priority first)
22051
+ */
22052
+ getAll() {
22053
+ return Array.from(this.backends.values()).filter((entry) => entry.enabled).sort((a, b) => b.priority - a.priority).map((entry) => entry.backend);
22054
+ }
22055
+ /**
22056
+ * Get all registered entries (including disabled)
22057
+ *
22058
+ * @returns Array of registered backend entries
22059
+ */
22060
+ getAllEntries() {
22061
+ return Array.from(this.backends.values()).sort((a, b) => b.priority - a.priority);
22062
+ }
22063
+ /**
22064
+ * Get backends supporting a specific chain
22065
+ *
22066
+ * @param chain - Chain type to filter by
22067
+ * @returns Array of backends supporting the chain
22068
+ */
22069
+ getByChain(chain) {
22070
+ return this.getAll().filter(
22071
+ (backend) => backend.chains.includes(chain)
22072
+ );
22073
+ }
22074
+ /**
22075
+ * Get backends of a specific type
22076
+ *
22077
+ * @param type - Backend type to filter by
22078
+ * @returns Array of backends of the specified type
22079
+ */
22080
+ getByType(type) {
22081
+ return this.getAll().filter(
22082
+ (backend) => backend.type === type || backend.type === "both"
22083
+ );
22084
+ }
22085
+ /**
22086
+ * Get backends that support compliance (viewing keys)
22087
+ *
22088
+ * @returns Array of compliance-supporting backends
22089
+ */
22090
+ getCompliant() {
22091
+ return this.getAll().filter(
22092
+ (backend) => backend.getCapabilities().complianceSupport
22093
+ );
22094
+ }
22095
+ /**
22096
+ * Find available backends for a transfer
22097
+ *
22098
+ * @param params - Transfer parameters
22099
+ * @returns Array of available backends with availability info
22100
+ */
22101
+ async findAvailable(params) {
22102
+ const chainBackends = this.getByChain(params.chain);
22103
+ const results = [];
22104
+ for (const backend of chainBackends) {
22105
+ const availability = await backend.checkAvailability(params);
22106
+ if (availability.available) {
22107
+ results.push({ backend, availability });
22108
+ }
22109
+ }
22110
+ return results;
22111
+ }
22112
+ /**
22113
+ * Enable a backend
22114
+ *
22115
+ * @param name - Backend name
22116
+ * @returns true if backend was enabled, false if not found
22117
+ */
22118
+ enable(name) {
22119
+ const entry = this.backends.get(name);
22120
+ if (entry) {
22121
+ entry.enabled = true;
22122
+ return true;
22123
+ }
22124
+ return false;
22125
+ }
22126
+ /**
22127
+ * Disable a backend
22128
+ *
22129
+ * @param name - Backend name
22130
+ * @returns true if backend was disabled, false if not found
22131
+ */
22132
+ disable(name) {
22133
+ const entry = this.backends.get(name);
22134
+ if (entry) {
22135
+ entry.enabled = false;
22136
+ return true;
22137
+ }
22138
+ return false;
22139
+ }
22140
+ /**
22141
+ * Set backend priority
22142
+ *
22143
+ * @param name - Backend name
22144
+ * @param priority - New priority value
22145
+ * @returns true if priority was set, false if not found
22146
+ */
22147
+ setPriority(name, priority) {
22148
+ const entry = this.backends.get(name);
22149
+ if (entry) {
22150
+ entry.priority = priority;
22151
+ return true;
22152
+ }
22153
+ return false;
22154
+ }
22155
+ /**
22156
+ * Get count of registered backends
22157
+ *
22158
+ * @param enabledOnly - If true, only count enabled backends
22159
+ * @returns Number of backends
22160
+ */
22161
+ count(enabledOnly = false) {
22162
+ if (enabledOnly) {
22163
+ return Array.from(this.backends.values()).filter((e) => e.enabled).length;
22164
+ }
22165
+ return this.backends.size;
22166
+ }
22167
+ /**
22168
+ * Clear all registered backends
22169
+ */
22170
+ clear() {
22171
+ this.backends.clear();
22172
+ }
22173
+ /**
22174
+ * Get backend names
22175
+ *
22176
+ * @param enabledOnly - If true, only return enabled backend names
22177
+ * @returns Array of backend names
22178
+ */
22179
+ getNames(enabledOnly = false) {
22180
+ if (enabledOnly) {
22181
+ return Array.from(this.backends.entries()).filter(([, entry]) => entry.enabled).map(([name]) => name);
22182
+ }
22183
+ return Array.from(this.backends.keys());
22184
+ }
22185
+ };
22186
+ var defaultRegistry = new PrivacyBackendRegistry();
22187
+
22188
+ // src/privacy-backends/sip-native.ts
22189
+ var SUPPORTED_CHAINS = [
22190
+ "solana",
22191
+ "ethereum",
22192
+ "near",
22193
+ "polygon",
22194
+ "arbitrum",
22195
+ "optimism",
22196
+ "base",
22197
+ "avalanche",
22198
+ "bsc"
22199
+ ];
22200
+ var SIP_NATIVE_CAPABILITIES = {
22201
+ hiddenAmount: true,
22202
+ hiddenSender: true,
22203
+ hiddenRecipient: true,
22204
+ hiddenCompute: false,
22205
+ complianceSupport: true,
22206
+ anonymitySet: void 0,
22207
+ // Not pool-based
22208
+ setupRequired: false,
22209
+ latencyEstimate: "fast",
22210
+ supportedTokens: "all",
22211
+ minAmount: void 0,
22212
+ maxAmount: void 0
22213
+ };
22214
+ var SIPNativeBackend = class {
22215
+ name = "sip-native";
22216
+ type = "transaction";
22217
+ chains;
22218
+ config;
22219
+ /**
22220
+ * Create a new SIP Native backend
22221
+ *
22222
+ * @param config - Backend configuration
22223
+ */
22224
+ constructor(config = {}) {
22225
+ this.chains = config.chains ?? SUPPORTED_CHAINS;
22226
+ this.config = {
22227
+ chains: this.chains,
22228
+ requireViewingKey: config.requireViewingKey ?? false,
22229
+ minAmount: config.minAmount ?? BigInt(0),
22230
+ maxAmount: config.maxAmount ?? BigInt(Number.MAX_SAFE_INTEGER)
22231
+ };
22232
+ }
22233
+ /**
22234
+ * Check if backend is available for given parameters
22235
+ */
22236
+ async checkAvailability(params) {
22237
+ if (!this.chains.includes(params.chain)) {
22238
+ return {
22239
+ available: false,
22240
+ reason: `Chain '${params.chain}' not supported by SIP Native backend`
22241
+ };
22242
+ }
22243
+ if (this.config.requireViewingKey && !params.viewingKey) {
22244
+ return {
22245
+ available: false,
22246
+ reason: "Viewing key required for SIP Native backend"
22247
+ };
22248
+ }
22249
+ if (params.amount < this.config.minAmount) {
22250
+ return {
22251
+ available: false,
22252
+ reason: `Amount ${params.amount} below minimum ${this.config.minAmount}`
22253
+ };
22254
+ }
22255
+ if (params.amount > this.config.maxAmount) {
22256
+ return {
22257
+ available: false,
22258
+ reason: `Amount ${params.amount} above maximum ${this.config.maxAmount}`
22259
+ };
22260
+ }
22261
+ const estimatedCost = this.getEstimatedCostForChain(params.chain);
22262
+ return {
22263
+ available: true,
22264
+ estimatedCost,
22265
+ estimatedTime: 1e3
22266
+ // ~1 second for stealth address operations
22267
+ };
22268
+ }
22269
+ /**
22270
+ * Get backend capabilities
22271
+ */
22272
+ getCapabilities() {
22273
+ return {
22274
+ ...SIP_NATIVE_CAPABILITIES,
22275
+ minAmount: this.config.minAmount > BigInt(0) ? this.config.minAmount : void 0,
22276
+ maxAmount: this.config.maxAmount < BigInt(Number.MAX_SAFE_INTEGER) ? this.config.maxAmount : void 0
22277
+ };
22278
+ }
22279
+ /**
22280
+ * Execute a privacy-preserving transfer
22281
+ *
22282
+ * This creates a stealth address transfer with:
22283
+ * - Ephemeral keypair generation
22284
+ * - Stealth address derivation
22285
+ * - Pedersen commitment for amount
22286
+ * - Optional viewing key encryption
22287
+ */
22288
+ async execute(params) {
22289
+ const availability = await this.checkAvailability(params);
22290
+ if (!availability.available) {
22291
+ return {
22292
+ success: false,
22293
+ error: availability.reason,
22294
+ backend: this.name
22295
+ };
22296
+ }
22297
+ try {
22298
+ const simulatedSignature = `sim_${Date.now()}_${Math.random().toString(36).slice(2)}`;
22299
+ return {
22300
+ success: true,
22301
+ signature: simulatedSignature,
22302
+ backend: this.name,
22303
+ metadata: {
22304
+ chain: params.chain,
22305
+ amount: params.amount.toString(),
22306
+ hasViewingKey: !!params.viewingKey,
22307
+ timestamp: Date.now()
22308
+ }
22309
+ };
22310
+ } catch (error) {
22311
+ return {
22312
+ success: false,
22313
+ error: error instanceof Error ? error.message : "Unknown error",
22314
+ backend: this.name
22315
+ };
22316
+ }
22317
+ }
22318
+ /**
22319
+ * Estimate cost for a transfer
22320
+ */
22321
+ async estimateCost(params) {
22322
+ return this.getEstimatedCostForChain(params.chain);
22323
+ }
22324
+ /**
22325
+ * Get estimated cost based on chain
22326
+ */
22327
+ getEstimatedCostForChain(chain) {
22328
+ const costMap = {
22329
+ solana: BigInt(5e3),
22330
+ // ~0.000005 SOL
22331
+ ethereum: BigInt("50000000000000"),
22332
+ // ~0.00005 ETH
22333
+ near: BigInt("1000000000000000000000"),
22334
+ // ~0.001 NEAR
22335
+ polygon: BigInt("50000000000000"),
22336
+ // ~0.00005 MATIC
22337
+ arbitrum: BigInt("50000000000000"),
22338
+ optimism: BigInt("50000000000000"),
22339
+ base: BigInt("50000000000000"),
22340
+ avalanche: BigInt("50000000000000"),
22341
+ bsc: BigInt("50000000000000")
22342
+ };
22343
+ return costMap[chain] ?? BigInt(0);
22344
+ }
22345
+ };
22346
+
22347
+ // src/privacy-backends/privacycash-types.ts
22348
+ var SOL_POOL_SIZES = {
22349
+ /** 0.1 SOL pool */
22350
+ SMALL: BigInt(1e8),
22351
+ /** 1 SOL pool */
22352
+ MEDIUM: BigInt(1e9),
22353
+ /** 10 SOL pool */
22354
+ LARGE: BigInt(1e10),
22355
+ /** 100 SOL pool */
22356
+ WHALE: BigInt(1e11)
22357
+ };
22358
+ var USDC_POOL_SIZES = {
22359
+ /** 10 USDC pool */
22360
+ SMALL: BigInt(1e7),
22361
+ /** 100 USDC pool */
22362
+ MEDIUM: BigInt(1e8),
22363
+ /** 1,000 USDC pool */
22364
+ LARGE: BigInt(1e9),
22365
+ /** 10,000 USDC pool */
22366
+ WHALE: BigInt(1e10)
22367
+ };
22368
+ var USDT_POOL_SIZES = {
22369
+ /** 10 USDT pool */
22370
+ SMALL: BigInt(1e7),
22371
+ /** 100 USDT pool */
22372
+ MEDIUM: BigInt(1e8),
22373
+ /** 1,000 USDT pool */
22374
+ LARGE: BigInt(1e9),
22375
+ /** 10,000 USDT pool */
22376
+ WHALE: BigInt(1e10)
22377
+ };
22378
+ var SOL_POOL_AMOUNTS = [
22379
+ SOL_POOL_SIZES.SMALL,
22380
+ SOL_POOL_SIZES.MEDIUM,
22381
+ SOL_POOL_SIZES.LARGE,
22382
+ SOL_POOL_SIZES.WHALE
22383
+ ];
22384
+ var SPL_POOL_AMOUNTS = [
22385
+ USDC_POOL_SIZES.SMALL,
22386
+ USDC_POOL_SIZES.MEDIUM,
22387
+ USDC_POOL_SIZES.LARGE,
22388
+ USDC_POOL_SIZES.WHALE
22389
+ ];
22390
+
22391
+ // src/privacy-backends/privacycash.ts
22392
+ var DEFAULT_ANONYMITY_SET = 50;
22393
+ var BASE_COST_LAMPORTS = BigInt(1e7);
22394
+ var PRIVACYCASH_CAPABILITIES = {
22395
+ hiddenAmount: false,
22396
+ // Fixed pool sizes, amount is known
22397
+ hiddenSender: true,
22398
+ // Pool mixing hides sender
22399
+ hiddenRecipient: true,
22400
+ // Withdrawal to fresh address
22401
+ hiddenCompute: false,
22402
+ // No compute privacy
22403
+ complianceSupport: false,
22404
+ // No viewing keys
22405
+ anonymitySet: DEFAULT_ANONYMITY_SET,
22406
+ setupRequired: false,
22407
+ // No setup needed
22408
+ latencyEstimate: "medium",
22409
+ // Need to wait for pool
22410
+ supportedTokens: "all",
22411
+ // SOL + USDC/USDT
22412
+ minAmount: SOL_POOL_AMOUNTS[0],
22413
+ // Smallest pool
22414
+ maxAmount: SOL_POOL_AMOUNTS[SOL_POOL_AMOUNTS.length - 1]
22415
+ // Largest pool
22416
+ };
22417
+
22418
+ // src/privacy-backends/router.ts
22419
+ var DEFAULT_CONFIG2 = {
22420
+ prioritize: "privacy",
22421
+ requireViewingKeys: false,
22422
+ allowComputePrivacy: true
22423
+ };
22424
+ var PRIORITY_WEIGHTS = {
22425
+ privacy: {
22426
+ hiddenAmount: 25,
22427
+ hiddenSender: 25,
22428
+ hiddenRecipient: 25,
22429
+ hiddenCompute: 10,
22430
+ anonymitySet: 15
22431
+ },
22432
+ speed: {
22433
+ fast: 40,
22434
+ medium: 25,
22435
+ slow: 10,
22436
+ setupRequired: -20
22437
+ },
22438
+ cost: {
22439
+ baseCost: 50,
22440
+ estimatedCost: 50
22441
+ },
22442
+ compliance: {
22443
+ complianceSupport: 60,
22444
+ hiddenAmount: 15,
22445
+ hiddenSender: 15,
22446
+ hiddenRecipient: 10
22447
+ }
22448
+ };
22449
+ var SmartRouter2 = class {
22450
+ registry;
22451
+ /**
22452
+ * Create a new SmartRouter
22453
+ *
22454
+ * @param registry - Backend registry to use for selection
22455
+ */
22456
+ constructor(registry) {
22457
+ this.registry = registry;
22458
+ }
22459
+ /**
22460
+ * Select the best backend for a transfer
22461
+ *
22462
+ * @param params - Transfer parameters
22463
+ * @param config - Router configuration
22464
+ * @returns Selection result with backend and reasoning
22465
+ * @throws Error if no suitable backend is found
22466
+ */
22467
+ async selectBackend(params, config = {}) {
22468
+ const fullConfig = { ...DEFAULT_CONFIG2, ...config };
22469
+ const chainBackends = this.registry.getByChain(params.chain);
22470
+ if (chainBackends.length === 0) {
22471
+ throw new Error(
22472
+ `No backends available for chain '${params.chain}'. Register a backend that supports this chain.`
22473
+ );
22474
+ }
22475
+ const scoredBackends = [];
22476
+ for (const backend of chainBackends) {
22477
+ if (fullConfig.excludeBackends?.includes(backend.name)) {
22478
+ continue;
22479
+ }
22480
+ const availability = await backend.checkAvailability(params);
22481
+ if (!availability.available) {
22482
+ continue;
22483
+ }
22484
+ const capabilities = backend.getCapabilities();
22485
+ if (fullConfig.requireViewingKeys && !capabilities.complianceSupport) {
22486
+ continue;
22487
+ }
22488
+ if (fullConfig.minAnonymitySet && capabilities.anonymitySet !== void 0 && capabilities.anonymitySet < fullConfig.minAnonymitySet) {
22489
+ continue;
22490
+ }
22491
+ if (!fullConfig.allowComputePrivacy && backend.type === "compute") {
22492
+ continue;
22493
+ }
22494
+ if (fullConfig.maxCost && availability.estimatedCost) {
22495
+ if (availability.estimatedCost > fullConfig.maxCost) {
22496
+ continue;
22497
+ }
22498
+ }
22499
+ if (fullConfig.maxLatency && availability.estimatedTime) {
22500
+ if (availability.estimatedTime > fullConfig.maxLatency) {
22501
+ continue;
22502
+ }
22503
+ }
22504
+ const { score, reason } = this.scoreBackend(
22505
+ backend,
22506
+ availability,
22507
+ fullConfig
22508
+ );
22509
+ scoredBackends.push({
22510
+ backend,
22511
+ availability,
22512
+ score,
22513
+ reason
22514
+ });
22515
+ }
22516
+ if (scoredBackends.length === 0) {
22517
+ throw new Error(
22518
+ `No backends meet the requirements for this transfer. Check your router configuration and registered backends.`
22519
+ );
22520
+ }
22521
+ scoredBackends.sort((a, b) => b.score - a.score);
22522
+ if (fullConfig.preferredBackend) {
22523
+ const preferredIndex = scoredBackends.findIndex(
22524
+ (s) => s.backend.name === fullConfig.preferredBackend
22525
+ );
22526
+ if (preferredIndex > 0) {
22527
+ const preferred = scoredBackends[preferredIndex];
22528
+ const leader = scoredBackends[0];
22529
+ if (leader.score - preferred.score <= 10) {
22530
+ scoredBackends.splice(preferredIndex, 1);
22531
+ scoredBackends.unshift(preferred);
22532
+ preferred.reason = `Preferred backend (within 10pts of optimal)`;
22533
+ }
22534
+ }
22535
+ }
22536
+ const selected = scoredBackends[0];
22537
+ const alternatives = scoredBackends.slice(1).map((s) => ({
22538
+ backend: s.backend,
22539
+ score: s.score,
22540
+ reason: s.reason
22541
+ }));
22542
+ return {
22543
+ backend: selected.backend,
22544
+ reason: selected.reason,
22545
+ alternatives,
22546
+ score: selected.score
22547
+ };
22548
+ }
22549
+ /**
22550
+ * Execute a transfer using the best available backend
22551
+ *
22552
+ * @param params - Transfer parameters
22553
+ * @param config - Router configuration
22554
+ * @returns Transaction result
22555
+ */
22556
+ async execute(params, config = {}) {
22557
+ const selection = await this.selectBackend(params, config);
22558
+ return selection.backend.execute(params);
22559
+ }
22560
+ /**
22561
+ * Get available backends for a transfer (without selecting)
22562
+ *
22563
+ * @param params - Transfer parameters
22564
+ * @returns Array of available backends with scores
22565
+ */
22566
+ async getAvailableBackends(params) {
22567
+ return this.registry.findAvailable(params);
22568
+ }
22569
+ /**
22570
+ * Score a backend based on configuration priority
22571
+ */
22572
+ scoreBackend(backend, availability, config) {
22573
+ const capabilities = backend.getCapabilities();
22574
+ let score = 0;
22575
+ const reasons = [];
22576
+ switch (config.prioritize) {
22577
+ case "privacy":
22578
+ if (capabilities.hiddenAmount) {
22579
+ score += PRIORITY_WEIGHTS.privacy.hiddenAmount;
22580
+ reasons.push("hidden amounts");
22581
+ }
22582
+ if (capabilities.hiddenSender) {
22583
+ score += PRIORITY_WEIGHTS.privacy.hiddenSender;
22584
+ reasons.push("hidden sender");
22585
+ }
22586
+ if (capabilities.hiddenRecipient) {
22587
+ score += PRIORITY_WEIGHTS.privacy.hiddenRecipient;
22588
+ reasons.push("hidden recipient");
22589
+ }
22590
+ if (capabilities.hiddenCompute) {
22591
+ score += PRIORITY_WEIGHTS.privacy.hiddenCompute;
22592
+ reasons.push("private compute");
22593
+ }
22594
+ if (capabilities.anonymitySet && capabilities.anonymitySet >= 100) {
22595
+ score += PRIORITY_WEIGHTS.privacy.anonymitySet;
22596
+ reasons.push(`anonymity set: ${capabilities.anonymitySet}`);
22597
+ }
22598
+ break;
22599
+ case "speed":
22600
+ score += PRIORITY_WEIGHTS.speed[capabilities.latencyEstimate];
22601
+ reasons.push(`${capabilities.latencyEstimate} latency`);
22602
+ if (capabilities.setupRequired) {
22603
+ score += PRIORITY_WEIGHTS.speed.setupRequired;
22604
+ reasons.push("setup required");
22605
+ }
22606
+ break;
22607
+ case "cost":
22608
+ if (availability.estimatedCost !== void 0) {
22609
+ const logCost = availability.estimatedCost > BigInt(0) ? Math.log10(Number(availability.estimatedCost)) : 0;
22610
+ const costScore = Math.max(0, 70 - logCost * 5);
22611
+ score += costScore;
22612
+ reasons.push(`low cost`);
22613
+ }
22614
+ break;
22615
+ case "compliance":
22616
+ if (capabilities.complianceSupport) {
22617
+ score += PRIORITY_WEIGHTS.compliance.complianceSupport;
22618
+ reasons.push("viewing key support");
22619
+ }
22620
+ if (capabilities.hiddenAmount) {
22621
+ score += PRIORITY_WEIGHTS.compliance.hiddenAmount;
22622
+ }
22623
+ if (capabilities.hiddenSender) {
22624
+ score += PRIORITY_WEIGHTS.compliance.hiddenSender;
22625
+ }
22626
+ if (capabilities.hiddenRecipient) {
22627
+ score += PRIORITY_WEIGHTS.compliance.hiddenRecipient;
22628
+ }
22629
+ break;
22630
+ }
22631
+ score = Math.min(100, Math.max(0, score));
22632
+ return {
22633
+ score,
22634
+ reason: reasons.length > 0 ? reasons.join(", ") : "default selection"
22635
+ };
22636
+ }
22637
+ };
22638
+
22639
+ // src/surveillance/algorithms/address-reuse.ts
22640
+ var MAX_DEDUCTION = 25;
22641
+ var DEDUCTION_PER_REUSE = 2;
22642
+ var REUSE_THRESHOLD = 1;
22643
+ function analyzeAddressReuse(transactions, walletAddress) {
22644
+ const receiveAddresses = /* @__PURE__ */ new Map();
22645
+ const sendAddresses = /* @__PURE__ */ new Map();
22646
+ for (const tx of transactions) {
22647
+ if (!tx.success) continue;
22648
+ if (tx.recipient === walletAddress) {
22649
+ const count = receiveAddresses.get(walletAddress) ?? 0;
22650
+ receiveAddresses.set(walletAddress, count + 1);
22651
+ }
22652
+ if (tx.sender === walletAddress) {
22653
+ const count = sendAddresses.get(walletAddress) ?? 0;
22654
+ sendAddresses.set(walletAddress, count + 1);
22655
+ }
22656
+ for (const addr of tx.involvedAddresses) {
22657
+ if (addr === walletAddress) continue;
22658
+ if (tx.sender === walletAddress) {
22659
+ const count = sendAddresses.get(addr) ?? 0;
22660
+ sendAddresses.set(addr, count + 1);
22661
+ }
22662
+ if (tx.recipient === walletAddress) {
22663
+ const count = receiveAddresses.get(addr) ?? 0;
22664
+ receiveAddresses.set(addr, count + 1);
22665
+ }
22666
+ }
22667
+ }
22668
+ let receiveReuseCount = 0;
22669
+ let sendReuseCount = 0;
22670
+ const reusedAddresses = [];
22671
+ for (const [address, count] of Array.from(receiveAddresses.entries())) {
22672
+ if (count > REUSE_THRESHOLD) {
22673
+ const reuseCount = count - REUSE_THRESHOLD;
22674
+ receiveReuseCount += reuseCount;
22675
+ const existing = reusedAddresses.find((r) => r.address === address);
22676
+ if (existing) {
22677
+ existing.useCount = Math.max(existing.useCount, count);
22678
+ existing.type = "both";
22679
+ } else {
22680
+ reusedAddresses.push({
22681
+ address,
22682
+ useCount: count,
22683
+ type: "receive"
22684
+ });
22685
+ }
22686
+ }
22687
+ }
22688
+ for (const [address, count] of Array.from(sendAddresses.entries())) {
22689
+ if (count > REUSE_THRESHOLD) {
22690
+ const reuseCount = count - REUSE_THRESHOLD;
22691
+ sendReuseCount += reuseCount;
22692
+ const existing = reusedAddresses.find((r) => r.address === address);
22693
+ if (existing) {
22694
+ existing.useCount = Math.max(existing.useCount, count);
22695
+ existing.type = "both";
22696
+ } else {
22697
+ reusedAddresses.push({
22698
+ address,
22699
+ useCount: count,
22700
+ type: "send"
22701
+ });
22702
+ }
22703
+ }
22704
+ }
22705
+ const totalReuseCount = receiveReuseCount + sendReuseCount;
22706
+ const rawDeduction = totalReuseCount * DEDUCTION_PER_REUSE;
22707
+ const scoreDeduction = Math.min(rawDeduction, MAX_DEDUCTION);
22708
+ reusedAddresses.sort((a, b) => b.useCount - a.useCount);
22709
+ return {
22710
+ receiveReuseCount,
22711
+ sendReuseCount,
22712
+ totalReuseCount,
22713
+ scoreDeduction,
22714
+ reusedAddresses: reusedAddresses.slice(0, 10)
22715
+ // Top 10 most reused
22716
+ };
22717
+ }
22718
+
22719
+ // src/surveillance/algorithms/cluster.ts
22720
+ var MAX_DEDUCTION2 = 25;
22721
+ var DEDUCTION_PER_LINK = 3;
22722
+ var MIN_LINK_THRESHOLD = 2;
22723
+ var UnionFind = class {
22724
+ parent;
22725
+ rank;
22726
+ constructor() {
22727
+ this.parent = /* @__PURE__ */ new Map();
22728
+ this.rank = /* @__PURE__ */ new Map();
22729
+ }
22730
+ find(x) {
22731
+ if (!this.parent.has(x)) {
22732
+ this.parent.set(x, x);
22733
+ this.rank.set(x, 0);
22734
+ }
22735
+ if (this.parent.get(x) !== x) {
22736
+ this.parent.set(x, this.find(this.parent.get(x)));
22737
+ }
22738
+ return this.parent.get(x);
22739
+ }
22740
+ union(x, y) {
22741
+ const rootX = this.find(x);
22742
+ const rootY = this.find(y);
22743
+ if (rootX === rootY) return;
22744
+ const rankX = this.rank.get(rootX) ?? 0;
22745
+ const rankY = this.rank.get(rootY) ?? 0;
22746
+ if (rankX < rankY) {
22747
+ this.parent.set(rootX, rootY);
22748
+ } else if (rankX > rankY) {
22749
+ this.parent.set(rootY, rootX);
22750
+ } else {
22751
+ this.parent.set(rootY, rootX);
22752
+ this.rank.set(rootX, rankX + 1);
22753
+ }
22754
+ }
22755
+ getClusters() {
22756
+ const clusters = /* @__PURE__ */ new Map();
22757
+ for (const addr of Array.from(this.parent.keys())) {
22758
+ const root = this.find(addr);
22759
+ if (!clusters.has(root)) {
22760
+ clusters.set(root, []);
22761
+ }
22762
+ clusters.get(root).push(addr);
22763
+ }
22764
+ return clusters;
22765
+ }
22766
+ };
22767
+ function detectClusters(transactions, walletAddress) {
22768
+ const uf = new UnionFind();
22769
+ const linkCounts = /* @__PURE__ */ new Map();
22770
+ const linkTypes = /* @__PURE__ */ new Map();
22771
+ const txCountPerPair = /* @__PURE__ */ new Map();
22772
+ uf.find(walletAddress);
22773
+ for (const tx of transactions) {
22774
+ if (!tx.success) continue;
22775
+ const involvedWithWallet = tx.involvedAddresses.filter(
22776
+ (addr) => addr !== walletAddress
22777
+ );
22778
+ if (tx.sender === walletAddress && involvedWithWallet.length > 0) {
22779
+ for (const addr of involvedWithWallet) {
22780
+ const pairKey = [walletAddress, addr].sort().join(":");
22781
+ const count = (txCountPerPair.get(pairKey) ?? 0) + 1;
22782
+ txCountPerPair.set(pairKey, count);
22783
+ if (count >= MIN_LINK_THRESHOLD) {
22784
+ uf.union(walletAddress, addr);
22785
+ linkCounts.set(addr, count);
22786
+ linkTypes.set(addr, "common-input");
22787
+ }
22788
+ }
22789
+ }
22790
+ if (tx.sender === walletAddress && tx.recipient !== walletAddress) {
22791
+ const otherRecipients = involvedWithWallet.filter(
22792
+ (addr) => addr !== tx.recipient
22793
+ );
22794
+ for (const addr of otherRecipients) {
22795
+ const pairKey = [walletAddress, addr].sort().join(":");
22796
+ const count = (txCountPerPair.get(pairKey) ?? 0) + 1;
22797
+ txCountPerPair.set(pairKey, count);
22798
+ if (count >= MIN_LINK_THRESHOLD) {
22799
+ uf.union(walletAddress, addr);
22800
+ if (!linkTypes.has(addr)) {
22801
+ linkTypes.set(addr, "change-address");
22802
+ }
22803
+ linkCounts.set(addr, count);
22804
+ }
22805
+ }
22806
+ }
22807
+ if (tx.recipient === walletAddress && involvedWithWallet.length > 1) {
22808
+ for (let i = 0; i < involvedWithWallet.length; i++) {
22809
+ for (let j = i + 1; j < involvedWithWallet.length; j++) {
22810
+ const addr1 = involvedWithWallet[i];
22811
+ const addr2 = involvedWithWallet[j];
22812
+ const pairKey2 = [addr1, addr2].sort().join(":");
22813
+ const count2 = (txCountPerPair.get(pairKey2) ?? 0) + 1;
22814
+ txCountPerPair.set(pairKey2, count2);
22815
+ if (count2 >= MIN_LINK_THRESHOLD) {
22816
+ uf.union(addr1, addr2);
22817
+ linkTypes.set(addr1, "consolidation");
22818
+ linkTypes.set(addr2, "consolidation");
22819
+ }
22820
+ }
22821
+ const pairKey = [walletAddress, involvedWithWallet[i]].sort().join(":");
22822
+ const count = (txCountPerPair.get(pairKey) ?? 0) + 1;
22823
+ txCountPerPair.set(pairKey, count);
22824
+ if (count >= MIN_LINK_THRESHOLD) {
22825
+ uf.union(walletAddress, involvedWithWallet[i]);
22826
+ linkCounts.set(involvedWithWallet[i], count);
22827
+ }
22828
+ }
22829
+ }
22830
+ }
22831
+ const allClusters = uf.getClusters();
22832
+ const walletRoot = uf.find(walletAddress);
22833
+ const walletCluster = allClusters.get(walletRoot) ?? [walletAddress];
22834
+ const linkedAddresses = walletCluster.filter((addr) => addr !== walletAddress);
22835
+ const linkedAddressCount = linkedAddresses.length;
22836
+ const totalLinkTxs = Array.from(linkCounts.values()).reduce((a, b) => a + b, 0);
22837
+ const confidence = Math.min(totalLinkTxs / (linkedAddressCount * 5), 1);
22838
+ const rawDeduction = linkedAddressCount * DEDUCTION_PER_LINK;
22839
+ const scoreDeduction = Math.min(rawDeduction, MAX_DEDUCTION2);
22840
+ const clusters = [];
22841
+ if (linkedAddressCount > 0) {
22842
+ const byType = /* @__PURE__ */ new Map();
22843
+ for (const addr of linkedAddresses) {
22844
+ const type = linkTypes.get(addr) ?? "common-input";
22845
+ if (!byType.has(type)) {
22846
+ byType.set(type, []);
22847
+ }
22848
+ byType.get(type).push(addr);
22849
+ }
22850
+ for (const [type, addresses] of Array.from(byType.entries())) {
22851
+ const txCount = addresses.reduce(
22852
+ (sum, addr) => sum + (linkCounts.get(addr) ?? 0),
22853
+ 0
22854
+ );
22855
+ clusters.push({
22856
+ addresses: [walletAddress, ...addresses],
22857
+ linkType: type,
22858
+ transactionCount: txCount
22859
+ });
22860
+ }
22861
+ }
22862
+ return {
22863
+ linkedAddressCount,
22864
+ confidence,
22865
+ scoreDeduction,
22866
+ clusters
22867
+ };
22868
+ }
22869
+
22870
+ // src/surveillance/algorithms/exchange.ts
22871
+ var MAX_DEDUCTION3 = 20;
22872
+ var DEDUCTION_PER_CEX = 8;
22873
+ var DEDUCTION_PER_DEX = 2;
22874
+ var KNOWN_EXCHANGES = [
22875
+ // Centralized Exchanges (KYC Required)
22876
+ {
22877
+ name: "Binance",
22878
+ addresses: [
22879
+ "5tzFkiKscXHK5ZXCGbXZxdw7gTjjD1mBwuoFbhUvuAi9",
22880
+ "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
22881
+ "AC5RDfQFmDS1deWZos921JfqscXdByf8BKHs5ACWjtW2"
22882
+ ],
22883
+ type: "cex",
22884
+ kycRequired: true
22885
+ },
22886
+ {
22887
+ name: "Coinbase",
22888
+ addresses: [
22889
+ "H8sMJSCQxfKiFTCfDR3DUMLPwcRbM61LGFJ8N4dK3WjS",
22890
+ "2ojv9BAiHUrvsm9gxDe7fJSzbNZSJcxZvf8dqmWGHG8S",
22891
+ "GJRs4FwHtemZ5ZE9x3FNvJ8TMwitKTh21yxdRPqn7npE"
22892
+ ],
22893
+ type: "cex",
22894
+ kycRequired: true
22895
+ },
22896
+ {
22897
+ name: "Kraken",
22898
+ addresses: [
22899
+ "krakenmRKej41L9sX8N8Z2mhjZ8UpVHHBMzkKzfBh54"
22900
+ ],
22901
+ type: "cex",
22902
+ kycRequired: true
22903
+ },
22904
+ {
22905
+ name: "FTX (Defunct)",
22906
+ addresses: [
22907
+ "FTXkd8cjuYGRLzPVdvqxNxNNNYBfFPPjrF3vW2Yq8p7"
22908
+ ],
22909
+ type: "cex",
22910
+ kycRequired: true
22911
+ },
22912
+ {
22913
+ name: "KuCoin",
22914
+ addresses: [
22915
+ "BmFdpraQhkiDQE6SnfG5omcA1VwzqfXrwtNYBwWTymy6"
22916
+ ],
22917
+ type: "cex",
22918
+ kycRequired: true
22919
+ },
22920
+ {
22921
+ name: "OKX",
22922
+ addresses: [
22923
+ "GGztQqQ6pCPaJQnNpXBgELr5cs3WwDakRbh1iEMzjgSJ"
22924
+ ],
22925
+ type: "cex",
22926
+ kycRequired: true
22927
+ },
22928
+ {
22929
+ name: "Bybit",
22930
+ addresses: [
22931
+ "AC5RDfQFmDS1deWZos921JfqscXdByf8BKHs5ACWjtW3"
22932
+ ],
22933
+ type: "cex",
22934
+ kycRequired: true
22935
+ },
22936
+ {
22937
+ name: "Gate.io",
22938
+ addresses: [
22939
+ "u6PJ8DtQuPFnfmwHbGFULQ4u4EgjDiyYKjVEsynXq2w"
22940
+ ],
22941
+ type: "cex",
22942
+ kycRequired: true
22943
+ },
22944
+ // Decentralized Exchanges (No KYC but traceable)
22945
+ {
22946
+ name: "Jupiter",
22947
+ addresses: [
22948
+ "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",
22949
+ "JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB"
22950
+ ],
22951
+ type: "dex",
22952
+ kycRequired: false
22953
+ },
22954
+ {
22955
+ name: "Raydium",
22956
+ addresses: [
22957
+ "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8",
22958
+ "5Q544fKrFoe6tsEbD7S8EmxGTJYAKtTVhAW5Q5pge4j1"
22959
+ ],
22960
+ type: "dex",
22961
+ kycRequired: false
22962
+ },
22963
+ {
22964
+ name: "Orca",
22965
+ addresses: [
22966
+ "9W959DqEETiGZocYWCQPaJ6sBmUzgfxXfqGeTEdp3aQP",
22967
+ "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc"
22968
+ ],
22969
+ type: "dex",
22970
+ kycRequired: false
22971
+ },
22972
+ {
22973
+ name: "Marinade",
22974
+ addresses: [
22975
+ "MarBmsSgKXdrN1egZf5sqe1TMai9K1rChYNDJgjq7aD"
22976
+ ],
22977
+ type: "dex",
22978
+ kycRequired: false
22979
+ },
22980
+ {
22981
+ name: "Phantom Swap",
22982
+ addresses: [
22983
+ "PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY"
22984
+ ],
22985
+ type: "dex",
22986
+ kycRequired: false
22987
+ }
22988
+ ];
22989
+ function buildExchangeLookup(exchanges) {
22990
+ const lookup = /* @__PURE__ */ new Map();
22991
+ for (const exchange of exchanges) {
22992
+ for (const address of exchange.addresses) {
22993
+ lookup.set(address, exchange);
22994
+ }
22995
+ }
22996
+ return lookup;
22997
+ }
22998
+ function detectExchangeExposure(transactions, walletAddress, customExchanges) {
22999
+ const exchanges = customExchanges ? [...KNOWN_EXCHANGES, ...customExchanges] : KNOWN_EXCHANGES;
23000
+ const lookup = buildExchangeLookup(exchanges);
23001
+ const exchangeStats = /* @__PURE__ */ new Map();
23002
+ for (const tx of transactions) {
23003
+ if (!tx.success) continue;
23004
+ for (const addr of tx.involvedAddresses) {
23005
+ const exchange = lookup.get(addr);
23006
+ if (!exchange) continue;
23007
+ if (!exchangeStats.has(exchange.name)) {
23008
+ exchangeStats.set(exchange.name, {
23009
+ exchange,
23010
+ deposits: 0,
23011
+ withdrawals: 0,
23012
+ firstInteraction: tx.timestamp,
23013
+ lastInteraction: tx.timestamp
23014
+ });
23015
+ }
23016
+ const stats = exchangeStats.get(exchange.name);
23017
+ stats.firstInteraction = Math.min(stats.firstInteraction, tx.timestamp);
23018
+ stats.lastInteraction = Math.max(stats.lastInteraction, tx.timestamp);
23019
+ if (tx.sender === walletAddress && tx.recipient === addr) {
23020
+ stats.deposits++;
23021
+ } else if (tx.sender === addr && tx.recipient === walletAddress) {
23022
+ stats.withdrawals++;
23023
+ } else if (tx.sender === walletAddress) {
23024
+ stats.deposits++;
23025
+ }
23026
+ }
23027
+ }
23028
+ let totalDeposits = 0;
23029
+ let totalWithdrawals = 0;
23030
+ let cexCount = 0;
23031
+ let dexCount = 0;
23032
+ const exchangeResults = [];
23033
+ for (const [name, stats] of Array.from(exchangeStats.entries())) {
23034
+ totalDeposits += stats.deposits;
23035
+ totalWithdrawals += stats.withdrawals;
23036
+ if (stats.exchange.type === "cex") {
23037
+ cexCount++;
23038
+ } else {
23039
+ dexCount++;
23040
+ }
23041
+ exchangeResults.push({
23042
+ name,
23043
+ type: stats.exchange.type,
23044
+ kycRequired: stats.exchange.kycRequired,
23045
+ deposits: stats.deposits,
23046
+ withdrawals: stats.withdrawals,
23047
+ firstInteraction: stats.firstInteraction,
23048
+ lastInteraction: stats.lastInteraction
23049
+ });
23050
+ }
23051
+ exchangeResults.sort(
23052
+ (a, b) => b.deposits + b.withdrawals - (a.deposits + a.withdrawals)
23053
+ );
23054
+ const cexDeduction = cexCount * DEDUCTION_PER_CEX;
23055
+ const dexDeduction = dexCount * DEDUCTION_PER_DEX;
23056
+ const rawDeduction = cexDeduction + dexDeduction;
23057
+ const scoreDeduction = Math.min(rawDeduction, MAX_DEDUCTION3);
23058
+ return {
23059
+ exchangeCount: exchangeStats.size,
23060
+ depositCount: totalDeposits,
23061
+ withdrawalCount: totalWithdrawals,
23062
+ scoreDeduction,
23063
+ exchanges: exchangeResults
23064
+ };
23065
+ }
23066
+
23067
+ // src/surveillance/algorithms/temporal.ts
23068
+ var MAX_DEDUCTION4 = 15;
23069
+ var DEDUCTION_PER_PATTERN = 5;
23070
+ var MIN_TRANSACTIONS_FOR_PATTERN = 5;
23071
+ var DAY_REGULARITY_THRESHOLD = 0.3;
23072
+ var HOUR_REGULARITY_THRESHOLD = 0.25;
23073
+ var TIMEZONES = {
23074
+ "UTC-12": -12,
23075
+ "UTC-11": -11,
23076
+ "HST": -10,
23077
+ "AKST": -9,
23078
+ "PST": -8,
23079
+ "MST": -7,
23080
+ "CST": -6,
23081
+ "EST": -5,
23082
+ "AST": -4,
23083
+ "BRT": -3,
23084
+ "UTC-2": -2,
23085
+ "UTC-1": -1,
23086
+ "UTC": 0,
23087
+ "CET": 1,
23088
+ "EET": 2,
23089
+ "MSK": 3,
23090
+ "GST": 4,
23091
+ "PKT": 5,
23092
+ "BST": 6,
23093
+ "ICT": 7,
23094
+ "CST_ASIA": 8,
23095
+ "JST": 9,
23096
+ "AEST": 10,
23097
+ "AEDT": 11,
23098
+ "NZST": 12
23099
+ };
23100
+ function analyzeTemporalPatterns(transactions) {
23101
+ const patterns = [];
23102
+ if (transactions.length < MIN_TRANSACTIONS_FOR_PATTERN) {
23103
+ return {
23104
+ patterns: [],
23105
+ scoreDeduction: 0
23106
+ };
23107
+ }
23108
+ const txTimes = transactions.filter((tx) => tx.success && tx.timestamp > 0).map((tx) => new Date(tx.timestamp * 1e3));
23109
+ if (txTimes.length < MIN_TRANSACTIONS_FOR_PATTERN) {
23110
+ return {
23111
+ patterns: [],
23112
+ scoreDeduction: 0
23113
+ };
23114
+ }
23115
+ const dayOfWeekPattern = analyzeDayOfWeekPattern(txTimes);
23116
+ if (dayOfWeekPattern) {
23117
+ patterns.push(dayOfWeekPattern);
23118
+ }
23119
+ const hourPattern = analyzeHourPattern(txTimes);
23120
+ if (hourPattern) {
23121
+ patterns.push(hourPattern);
23122
+ }
23123
+ const inferredTimezone = inferTimezone(txTimes);
23124
+ const burstPattern = detectActivityBursts(transactions);
23125
+ if (burstPattern) {
23126
+ patterns.push(burstPattern);
23127
+ }
23128
+ const rawDeduction = patterns.length * DEDUCTION_PER_PATTERN;
23129
+ const scoreDeduction = Math.min(rawDeduction, MAX_DEDUCTION4);
23130
+ return {
23131
+ patterns,
23132
+ inferredTimezone,
23133
+ scoreDeduction
23134
+ };
23135
+ }
23136
+ function analyzeDayOfWeekPattern(times) {
23137
+ const dayCount = new Array(7).fill(0);
23138
+ for (const time of times) {
23139
+ dayCount[time.getUTCDay()]++;
23140
+ }
23141
+ const total = times.length;
23142
+ const dominantDays = [];
23143
+ for (let day = 0; day < 7; day++) {
23144
+ const percentage = dayCount[day] / total;
23145
+ if (percentage >= DAY_REGULARITY_THRESHOLD) {
23146
+ dominantDays.push(day);
23147
+ }
23148
+ }
23149
+ if (dominantDays.length === 0 || dominantDays.length > 3) {
23150
+ return null;
23151
+ }
23152
+ const dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
23153
+ const dominantDayNames = dominantDays.map((d) => dayNames[d]).join(", ");
23154
+ return {
23155
+ type: "regular-schedule",
23156
+ description: `Most transactions occur on ${dominantDayNames}`,
23157
+ confidence: Math.max(...dominantDays.map((d) => dayCount[d] / total)),
23158
+ evidence: {
23159
+ dayOfWeek: dominantDays
23160
+ }
23161
+ };
23162
+ }
23163
+ function analyzeHourPattern(times) {
23164
+ const hourCount = new Array(24).fill(0);
23165
+ for (const time of times) {
23166
+ hourCount[time.getUTCHours()]++;
23167
+ }
23168
+ const total = times.length;
23169
+ const activeHours = [];
23170
+ for (let hour = 0; hour < 24; hour++) {
23171
+ const windowCount = hourCount[hour] + hourCount[(hour + 1) % 24] + hourCount[(hour + 2) % 24];
23172
+ const windowPercentage = windowCount / total;
23173
+ if (windowPercentage >= HOUR_REGULARITY_THRESHOLD) {
23174
+ if (!activeHours.includes(hour)) {
23175
+ activeHours.push(hour);
23176
+ }
23177
+ }
23178
+ }
23179
+ if (activeHours.length === 0 || activeHours.length > 8) {
23180
+ return null;
23181
+ }
23182
+ const activeHourRange = Math.max(...activeHours) - Math.min(...activeHours);
23183
+ if (activeHourRange <= 6) {
23184
+ const startHour = Math.min(...activeHours);
23185
+ const endHour = Math.max(...activeHours) + 2;
23186
+ return {
23187
+ type: "timezone-inference",
23188
+ description: `Activity concentrated between ${startHour}:00-${endHour}:00 UTC`,
23189
+ confidence: 0.7,
23190
+ evidence: {
23191
+ hourOfDay: activeHours
23192
+ }
23193
+ };
23194
+ }
23195
+ return null;
23196
+ }
23197
+ function inferTimezone(times) {
23198
+ const hourCount = new Array(24).fill(0);
23199
+ for (const time of times) {
23200
+ hourCount[time.getUTCHours()]++;
23201
+ }
23202
+ let maxActivity = 0;
23203
+ let bestStartHour = 0;
23204
+ for (let start = 0; start < 24; start++) {
23205
+ let windowActivity = 0;
23206
+ for (let i = 0; i < 8; i++) {
23207
+ windowActivity += hourCount[(start + i) % 24];
23208
+ }
23209
+ if (windowActivity > maxActivity) {
23210
+ maxActivity = windowActivity;
23211
+ bestStartHour = start;
23212
+ }
23213
+ }
23214
+ const totalActivity = times.length;
23215
+ if (maxActivity / totalActivity < 0.6) {
23216
+ return void 0;
23217
+ }
23218
+ const assumedLocalNoon = 12;
23219
+ const peakMidpoint = (bestStartHour + 4) % 24;
23220
+ const inferredOffset = (assumedLocalNoon - peakMidpoint + 24) % 24;
23221
+ const normalizedOffset = inferredOffset > 12 ? inferredOffset - 24 : inferredOffset;
23222
+ for (const [name, offset] of Object.entries(TIMEZONES)) {
23223
+ if (Math.abs(offset - normalizedOffset) <= 1) {
23224
+ return name;
23225
+ }
23226
+ }
23227
+ return `UTC${normalizedOffset >= 0 ? "+" : ""}${normalizedOffset}`;
23228
+ }
23229
+ function detectActivityBursts(transactions) {
23230
+ if (transactions.length < 10) {
23231
+ return null;
23232
+ }
23233
+ const sorted = [...transactions].filter((tx) => tx.timestamp > 0).sort((a, b) => a.timestamp - b.timestamp);
23234
+ const gaps = [];
23235
+ for (let i = 1; i < sorted.length; i++) {
23236
+ gaps.push(sorted[i].timestamp - sorted[i - 1].timestamp);
23237
+ }
23238
+ const avgGap = gaps.reduce((a, b) => a + b, 0) / gaps.length;
23239
+ const burstThreshold = avgGap * 0.1;
23240
+ let burstCount = 0;
23241
+ for (const gap of gaps) {
23242
+ if (gap < burstThreshold && gap < 3600) {
23243
+ burstCount++;
23244
+ }
23245
+ }
23246
+ const burstPercentage = burstCount / gaps.length;
23247
+ if (burstPercentage > 0.2) {
23248
+ return {
23249
+ type: "activity-burst",
23250
+ description: `${Math.round(burstPercentage * 100)}% of transactions occur in rapid succession`,
23251
+ confidence: burstPercentage,
23252
+ evidence: {
23253
+ frequency: `${burstCount} bursts detected`
23254
+ }
23255
+ };
23256
+ }
23257
+ return null;
23258
+ }
23259
+
23260
+ // src/surveillance/scoring.ts
23261
+ var MAX_POINTS = {
23262
+ addressReuse: 25,
23263
+ clusterExposure: 25,
23264
+ exchangeExposure: 20,
23265
+ temporalPatterns: 15,
23266
+ socialLinks: 15
23267
+ };
23268
+ var TOTAL_MAX_SCORE = Object.values(MAX_POINTS).reduce((a, b) => a + b, 0);
23269
+ var RISK_THRESHOLDS = {
23270
+ critical: 30,
23271
+ high: 50,
23272
+ medium: 70,
23273
+ low: 100
23274
+ };
23275
+ function calculatePrivacyScore(addressReuse, cluster, exchangeExposure, temporalPatterns, socialLinks, walletAddress) {
23276
+ const breakdown = {
23277
+ addressReuse: MAX_POINTS.addressReuse - addressReuse.scoreDeduction,
23278
+ clusterExposure: MAX_POINTS.clusterExposure - cluster.scoreDeduction,
23279
+ exchangeExposure: MAX_POINTS.exchangeExposure - exchangeExposure.scoreDeduction,
23280
+ temporalPatterns: MAX_POINTS.temporalPatterns - temporalPatterns.scoreDeduction,
23281
+ socialLinks: MAX_POINTS.socialLinks - socialLinks.scoreDeduction
23282
+ };
23283
+ const totalScore = breakdown.addressReuse + breakdown.clusterExposure + breakdown.exchangeExposure + breakdown.temporalPatterns + breakdown.socialLinks;
23284
+ const overall = Math.round(totalScore / TOTAL_MAX_SCORE * 100);
23285
+ let risk = "low";
23286
+ if (overall < RISK_THRESHOLDS.critical) {
23287
+ risk = "critical";
23288
+ } else if (overall < RISK_THRESHOLDS.high) {
23289
+ risk = "high";
23290
+ } else if (overall < RISK_THRESHOLDS.medium) {
23291
+ risk = "medium";
23292
+ }
23293
+ const recommendations = generateRecommendations(
23294
+ addressReuse,
23295
+ cluster,
23296
+ exchangeExposure,
23297
+ temporalPatterns,
23298
+ socialLinks
23299
+ );
23300
+ return {
23301
+ overall,
23302
+ breakdown,
23303
+ risk,
23304
+ recommendations,
23305
+ analyzedAt: Date.now(),
23306
+ walletAddress
23307
+ };
23308
+ }
23309
+ function generateRecommendations(addressReuse, cluster, exchangeExposure, temporalPatterns, socialLinks) {
23310
+ const recommendations = [];
23311
+ if (addressReuse.scoreDeduction > 0) {
23312
+ const severity = getSeverity(addressReuse.scoreDeduction, MAX_POINTS.addressReuse);
23313
+ recommendations.push({
23314
+ id: "address-reuse-001",
23315
+ severity,
23316
+ category: "addressReuse",
23317
+ title: `Address reused ${addressReuse.totalReuseCount} times`,
23318
+ description: "Reusing the same address for multiple transactions creates linkability between your transactions, allowing observers to track your activity.",
23319
+ action: "Use SIP stealth addresses for each transaction. Each payment uses a unique one-time address that cannot be linked to your main address.",
23320
+ potentialGain: addressReuse.scoreDeduction
23321
+ });
23322
+ }
23323
+ if (cluster.scoreDeduction > 0) {
23324
+ const severity = getSeverity(cluster.scoreDeduction, MAX_POINTS.clusterExposure);
23325
+ recommendations.push({
23326
+ id: "cluster-001",
23327
+ severity,
23328
+ category: "clusterExposure",
23329
+ title: `${cluster.linkedAddressCount} addresses linked to your wallet`,
23330
+ description: "Transaction analysis has linked multiple addresses to your wallet through common input ownership patterns. This expands your privacy exposure.",
23331
+ action: "Use SIP for all transactions to prevent cluster analysis. Stealth addresses break the link between your spending and receiving addresses.",
23332
+ potentialGain: cluster.scoreDeduction
23333
+ });
23334
+ }
23335
+ if (exchangeExposure.scoreDeduction > 0) {
23336
+ const cexes = exchangeExposure.exchanges.filter((e) => e.kycRequired);
23337
+ const severity = getSeverity(exchangeExposure.scoreDeduction, MAX_POINTS.exchangeExposure);
23338
+ if (cexes.length > 0) {
23339
+ recommendations.push({
23340
+ id: "exchange-cex-001",
23341
+ severity,
23342
+ category: "exchangeExposure",
23343
+ title: `Interacted with ${cexes.length} KYC exchange(s)`,
23344
+ description: `Deposits to ${cexes.map((e) => e.name).join(", ")} link your on-chain activity to your verified identity. This is one of the biggest privacy risks.`,
23345
+ action: "Use SIP viewing keys for selective disclosure. You can prove compliance to exchanges without exposing your full transaction history.",
23346
+ potentialGain: Math.min(cexes.length * 8, MAX_POINTS.exchangeExposure)
23347
+ });
23348
+ }
23349
+ const dexes = exchangeExposure.exchanges.filter((e) => !e.kycRequired);
23350
+ if (dexes.length > 0) {
23351
+ recommendations.push({
23352
+ id: "exchange-dex-001",
23353
+ severity: "low",
23354
+ category: "exchangeExposure",
23355
+ title: `Used ${dexes.length} DEX(es) without privacy`,
23356
+ description: "DEX swaps are public and can be traced. While no KYC is required, your swap patterns can reveal trading strategies.",
23357
+ action: "Use SIP for private swaps. Amounts and swap details are hidden while still using your preferred DEX.",
23358
+ potentialGain: Math.min(dexes.length * 2, 6)
23359
+ });
23360
+ }
23361
+ }
23362
+ if (temporalPatterns.scoreDeduction > 0) {
23363
+ const severity = getSeverity(temporalPatterns.scoreDeduction, MAX_POINTS.temporalPatterns);
23364
+ for (const pattern of temporalPatterns.patterns) {
23365
+ if (pattern.type === "regular-schedule") {
23366
+ recommendations.push({
23367
+ id: "temporal-schedule-001",
23368
+ severity,
23369
+ category: "temporalPatterns",
23370
+ title: "Regular transaction schedule detected",
23371
+ description: `${pattern.description}. Predictable patterns make your activity easier to track and attribute.`,
23372
+ action: "Vary your transaction timing. Consider using scheduled private transactions through SIP to obscure timing patterns.",
23373
+ potentialGain: 5
23374
+ });
23375
+ }
23376
+ if (pattern.type === "timezone-inference") {
23377
+ recommendations.push({
23378
+ id: "temporal-timezone-001",
23379
+ severity: "medium",
23380
+ category: "temporalPatterns",
23381
+ title: "Timezone can be inferred from activity",
23382
+ description: `${pattern.description}. This narrows down your geographic location based on when you transact.`,
23383
+ action: "Use time-delayed transactions or vary your active hours. SIP can queue transactions for random future execution.",
23384
+ potentialGain: 5
23385
+ });
23386
+ }
23387
+ }
23388
+ }
23389
+ if (socialLinks.scoreDeduction > 0) {
23390
+ const severity = getSeverity(socialLinks.scoreDeduction, MAX_POINTS.socialLinks);
23391
+ if (socialLinks.isDoxxed) {
23392
+ recommendations.push({
23393
+ id: "social-doxxed-001",
23394
+ severity: "critical",
23395
+ category: "socialLinks",
23396
+ title: "Wallet publicly linked to your identity",
23397
+ description: "Your wallet address is publicly associated with your real identity through ENS/SNS names or social profiles. All transactions are attributable to you.",
23398
+ action: "Use a fresh wallet with SIP for private transactions. Your viewing keys let you prove ownership when needed without constant exposure.",
23399
+ potentialGain: 15
23400
+ });
23401
+ } else if (socialLinks.partialExposure) {
23402
+ recommendations.push({
23403
+ id: "social-partial-001",
23404
+ severity,
23405
+ category: "socialLinks",
23406
+ title: "Partial identity exposure detected",
23407
+ description: "Some identifying information is linked to your wallet, such as ENS names or labeled addresses on block explorers.",
23408
+ action: "Consider using a separate wallet for private activities. SIP stealth addresses prevent linking to your main identity.",
23409
+ potentialGain: socialLinks.scoreDeduction
23410
+ });
23411
+ }
23412
+ }
23413
+ recommendations.sort((a, b) => b.potentialGain - a.potentialGain);
23414
+ return recommendations;
23415
+ }
23416
+ function getSeverity(deduction, maxPoints) {
23417
+ const percentage = deduction / maxPoints;
23418
+ if (percentage >= 0.8) return "critical";
23419
+ if (percentage >= 0.5) return "high";
23420
+ if (percentage >= 0.25) return "medium";
23421
+ return "low";
23422
+ }
23423
+ function calculateSIPComparison(currentScore) {
23424
+ const improvements = [];
23425
+ const addressReuseImprovement = MAX_POINTS.addressReuse - currentScore.breakdown.addressReuse;
23426
+ if (addressReuseImprovement > 0) {
23427
+ improvements.push({
23428
+ category: "addressReuse",
23429
+ currentScore: currentScore.breakdown.addressReuse,
23430
+ projectedScore: MAX_POINTS.addressReuse,
23431
+ reason: "Stealth addresses prevent any address reuse"
23432
+ });
23433
+ }
23434
+ const clusterImprovement = MAX_POINTS.clusterExposure - currentScore.breakdown.clusterExposure;
23435
+ if (clusterImprovement > 0) {
23436
+ improvements.push({
23437
+ category: "clusterExposure",
23438
+ currentScore: currentScore.breakdown.clusterExposure,
23439
+ projectedScore: MAX_POINTS.clusterExposure,
23440
+ reason: "Stealth addresses cannot be linked via common input analysis"
23441
+ });
23442
+ }
23443
+ const exchangeImprovement = Math.min(
23444
+ (MAX_POINTS.exchangeExposure - currentScore.breakdown.exchangeExposure) * 0.5,
23445
+ 10
23446
+ );
23447
+ if (exchangeImprovement > 0) {
23448
+ improvements.push({
23449
+ category: "exchangeExposure",
23450
+ currentScore: currentScore.breakdown.exchangeExposure,
23451
+ projectedScore: currentScore.breakdown.exchangeExposure + Math.round(exchangeImprovement),
23452
+ reason: "Viewing keys allow selective disclosure without exposing full history"
23453
+ });
23454
+ }
23455
+ const temporalImprovement = Math.min(
23456
+ (MAX_POINTS.temporalPatterns - currentScore.breakdown.temporalPatterns) * 0.3,
23457
+ 5
23458
+ );
23459
+ if (temporalImprovement > 0) {
23460
+ improvements.push({
23461
+ category: "temporalPatterns",
23462
+ currentScore: currentScore.breakdown.temporalPatterns,
23463
+ projectedScore: currentScore.breakdown.temporalPatterns + Math.round(temporalImprovement),
23464
+ reason: "Private transactions reduce pattern correlation"
23465
+ });
23466
+ }
23467
+ const totalImprovement = improvements.reduce(
23468
+ (sum, imp) => sum + (imp.projectedScore - imp.currentScore),
23469
+ 0
23470
+ );
23471
+ const projectedTotal = currentScore.overall / 100 * TOTAL_MAX_SCORE + totalImprovement;
23472
+ const projectedScore = Math.min(Math.round(projectedTotal / TOTAL_MAX_SCORE * 100), 100);
23473
+ return {
23474
+ currentScore: currentScore.overall,
23475
+ projectedScore,
23476
+ improvement: projectedScore - currentScore.overall,
23477
+ improvements
23478
+ };
23479
+ }
23480
+
23481
+ // src/surveillance/analyzer.ts
23482
+ var SurveillanceAnalyzer = class _SurveillanceAnalyzer {
23483
+ config;
23484
+ heliusUrl;
23485
+ constructor(config) {
23486
+ if (!config.heliusApiKey) {
23487
+ throw new Error(
23488
+ "Helius API key is required. Get one at https://dev.helius.xyz"
23489
+ );
23490
+ }
23491
+ this.config = {
23492
+ heliusApiKey: config.heliusApiKey,
23493
+ cluster: config.cluster ?? "mainnet-beta",
23494
+ maxTransactions: config.maxTransactions ?? 1e3,
23495
+ includeSocialLinks: config.includeSocialLinks ?? false,
23496
+ customExchangeAddresses: config.customExchangeAddresses ?? []
23497
+ };
23498
+ this.heliusUrl = this.config.cluster === "devnet" ? `https://api-devnet.helius.xyz/v0` : `https://api.helius.xyz/v0`;
23499
+ }
23500
+ /**
23501
+ * Perform full privacy analysis on a wallet
23502
+ *
23503
+ * @param walletAddress - Solana wallet address to analyze
23504
+ * @returns Complete analysis result with all details
23505
+ */
23506
+ async analyze(walletAddress) {
23507
+ const startTime = Date.now();
23508
+ const transactions = await this.fetchTransactionHistory(walletAddress);
23509
+ const addressReuse = analyzeAddressReuse(transactions, walletAddress);
23510
+ const cluster = detectClusters(transactions, walletAddress);
23511
+ const exchangeExposure = detectExchangeExposure(
23512
+ transactions,
23513
+ walletAddress,
23514
+ this.config.customExchangeAddresses
23515
+ );
23516
+ const temporalPatterns = analyzeTemporalPatterns(transactions);
23517
+ const socialLinks = await this.analyzeSocialLinks(walletAddress);
23518
+ const privacyScore = calculatePrivacyScore(
23519
+ addressReuse,
23520
+ cluster,
23521
+ exchangeExposure,
23522
+ temporalPatterns,
23523
+ socialLinks,
23524
+ walletAddress
23525
+ );
23526
+ const sipComparison = calculateSIPComparison(privacyScore);
23527
+ const analysisDurationMs = Date.now() - startTime;
23528
+ return {
23529
+ privacyScore,
23530
+ addressReuse,
23531
+ cluster,
23532
+ exchangeExposure,
23533
+ temporalPatterns,
23534
+ socialLinks,
23535
+ sipComparison,
23536
+ transactionCount: transactions.length,
23537
+ analysisDurationMs
23538
+ };
23539
+ }
23540
+ /**
23541
+ * Fetch transaction history using Helius Enhanced Transactions API
23542
+ */
23543
+ async fetchTransactionHistory(walletAddress) {
23544
+ const transactions = [];
23545
+ let beforeSignature;
23546
+ let hasMore = true;
23547
+ while (hasMore && transactions.length < this.config.maxTransactions) {
23548
+ const url = new URL(`${this.heliusUrl}/addresses/${walletAddress}/transactions`);
23549
+ url.searchParams.set("api-key", this.config.heliusApiKey);
23550
+ url.searchParams.set("limit", "100");
23551
+ if (beforeSignature) {
23552
+ url.searchParams.set("before", beforeSignature);
23553
+ }
23554
+ const controller = new AbortController();
23555
+ const timeoutId = setTimeout(() => controller.abort(), 3e4);
23556
+ let response;
23557
+ try {
23558
+ response = await fetch(url.toString(), {
23559
+ signal: controller.signal
23560
+ });
23561
+ } catch (error) {
23562
+ clearTimeout(timeoutId);
23563
+ if (error instanceof Error && error.name === "AbortError") {
23564
+ throw new Error("Helius API request timed out after 30 seconds");
23565
+ }
23566
+ throw error;
23567
+ }
23568
+ clearTimeout(timeoutId);
23569
+ if (!response.ok) {
23570
+ throw new Error(
23571
+ `Helius API error: ${response.status} ${response.statusText}`
23572
+ );
23573
+ }
23574
+ const data = await response.json();
23575
+ if (data.length === 0) {
23576
+ hasMore = false;
23577
+ break;
23578
+ }
23579
+ for (const tx of data) {
23580
+ const analyzable = this.parseTransaction(tx, walletAddress);
23581
+ if (analyzable) {
23582
+ transactions.push(analyzable);
23583
+ }
23584
+ }
23585
+ beforeSignature = data[data.length - 1]?.signature;
23586
+ hasMore = data.length === 100;
23587
+ await new Promise((resolve) => setTimeout(resolve, 100));
23588
+ }
23589
+ return transactions;
23590
+ }
23591
+ /**
23592
+ * Parse Helius transaction into analyzable format
23593
+ */
23594
+ parseTransaction(tx, walletAddress) {
23595
+ const involvedAddresses = /* @__PURE__ */ new Set();
23596
+ if (tx.feePayer) {
23597
+ involvedAddresses.add(tx.feePayer);
23598
+ }
23599
+ let sender = null;
23600
+ let recipient = null;
23601
+ let amount = BigInt(0);
23602
+ if (tx.nativeTransfers && tx.nativeTransfers.length > 0) {
23603
+ for (const transfer of tx.nativeTransfers) {
23604
+ involvedAddresses.add(transfer.fromUserAccount);
23605
+ involvedAddresses.add(transfer.toUserAccount);
23606
+ if (transfer.fromUserAccount === walletAddress) {
23607
+ sender = walletAddress;
23608
+ recipient = transfer.toUserAccount;
23609
+ amount = BigInt(transfer.amount);
23610
+ } else if (transfer.toUserAccount === walletAddress) {
23611
+ sender = transfer.fromUserAccount;
23612
+ recipient = walletAddress;
23613
+ amount = BigInt(transfer.amount);
23614
+ }
23615
+ }
23616
+ }
23617
+ let mint = null;
23618
+ if (tx.tokenTransfers && tx.tokenTransfers.length > 0) {
23619
+ for (const transfer of tx.tokenTransfers) {
23620
+ if (transfer.fromUserAccount) {
23621
+ involvedAddresses.add(transfer.fromUserAccount);
23622
+ }
23623
+ if (transfer.toUserAccount) {
23624
+ involvedAddresses.add(transfer.toUserAccount);
23625
+ }
23626
+ if (transfer.fromUserAccount === walletAddress) {
23627
+ sender = walletAddress;
23628
+ recipient = transfer.toUserAccount;
23629
+ amount = BigInt(Math.floor(transfer.tokenAmount));
23630
+ mint = transfer.mint;
23631
+ } else if (transfer.toUserAccount === walletAddress) {
23632
+ sender = transfer.fromUserAccount;
23633
+ recipient = walletAddress;
23634
+ amount = BigInt(Math.floor(transfer.tokenAmount));
23635
+ mint = transfer.mint;
23636
+ }
23637
+ }
23638
+ }
23639
+ if (tx.accountData) {
23640
+ for (const account of tx.accountData) {
23641
+ involvedAddresses.add(account.account);
23642
+ }
23643
+ }
23644
+ let type = "other";
23645
+ if (tx.type === "SWAP" || tx.events?.swap) {
23646
+ type = "swap";
23647
+ } else if (tx.type === "TRANSFER" || tx.nativeTransfers?.length || tx.tokenTransfers?.length) {
23648
+ type = "transfer";
23649
+ } else if (tx.type?.includes("STAKE")) {
23650
+ type = "stake";
23651
+ }
23652
+ return {
23653
+ signature: tx.signature,
23654
+ slot: tx.slot,
23655
+ timestamp: tx.timestamp,
23656
+ sender,
23657
+ recipient,
23658
+ amount,
23659
+ mint,
23660
+ fee: BigInt(tx.fee || 0),
23661
+ involvedAddresses: Array.from(involvedAddresses),
23662
+ type,
23663
+ success: true
23664
+ // Helius only returns successful transactions
23665
+ };
23666
+ }
23667
+ /**
23668
+ * Analyze social links (placeholder for external API integration)
23669
+ *
23670
+ * In production, this would query:
23671
+ * - SNS (Solana Name Service)
23672
+ * - Arkham Intelligence
23673
+ * - 0xppl API
23674
+ * - Other identity providers
23675
+ */
23676
+ async analyzeSocialLinks(walletAddress) {
23677
+ if (!this.config.includeSocialLinks) {
23678
+ return {
23679
+ isDoxxed: false,
23680
+ partialExposure: false,
23681
+ scoreDeduction: 0,
23682
+ links: []
23683
+ };
23684
+ }
23685
+ try {
23686
+ const snsResult = await this.checkSNS(walletAddress);
23687
+ if (snsResult) {
23688
+ return {
23689
+ isDoxxed: false,
23690
+ partialExposure: true,
23691
+ scoreDeduction: 7,
23692
+ links: [snsResult]
23693
+ };
23694
+ }
23695
+ } catch {
23696
+ }
23697
+ return {
23698
+ isDoxxed: false,
23699
+ partialExposure: false,
23700
+ scoreDeduction: 0,
23701
+ links: []
23702
+ };
23703
+ }
23704
+ /**
23705
+ * Check Solana Name Service for domain names
23706
+ */
23707
+ async checkSNS(walletAddress) {
23708
+ try {
23709
+ const url = `${this.heliusUrl}/addresses/${walletAddress}/names?api-key=${this.config.heliusApiKey}`;
23710
+ const response = await fetch(url);
23711
+ if (!response.ok) {
23712
+ return null;
23713
+ }
23714
+ const data = await response.json();
23715
+ if (Array.isArray(data) && data.length > 0) {
23716
+ return {
23717
+ platform: "sns",
23718
+ identifier: data[0].name || data[0],
23719
+ confidence: 1
23720
+ };
23721
+ }
23722
+ } catch {
23723
+ }
23724
+ return null;
23725
+ }
23726
+ /**
23727
+ * Get quick privacy score without full analysis
23728
+ *
23729
+ * Performs a lighter analysis suitable for real-time display.
23730
+ * Uses only the most recent transactions (100 max).
23731
+ */
23732
+ async quickScore(walletAddress) {
23733
+ const quickAnalyzer = new _SurveillanceAnalyzer({
23734
+ heliusApiKey: this.config.heliusApiKey,
23735
+ cluster: this.config.cluster,
23736
+ maxTransactions: 100,
23737
+ includeSocialLinks: false,
23738
+ // Skip social links for speed
23739
+ customExchangeAddresses: this.config.customExchangeAddresses
23740
+ });
23741
+ const result = await quickAnalyzer.analyze(walletAddress);
23742
+ const topRecommendation = result.privacyScore.recommendations[0];
23743
+ return {
23744
+ score: result.privacyScore.overall,
23745
+ risk: result.privacyScore.risk,
23746
+ topIssue: topRecommendation?.title ?? null
23747
+ };
23748
+ }
23749
+ };
23750
+ function createSurveillanceAnalyzer(config) {
23751
+ return new SurveillanceAnalyzer(config);
23752
+ }
23753
+
21192
23754
  // src/proofs/browser.ts
21193
23755
  init_errors();
21194
23756
  var import_noir_js = require("@noir-lang/noir_js");
@@ -22422,7 +24984,7 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
22422
24984
  message: "Proof generated successfully"
22423
24985
  });
22424
24986
  const commitmentHashBytes = returnValue;
22425
- const commitmentHashHex = bytesToHex12(new Uint8Array(commitmentHashBytes));
24987
+ const commitmentHashHex = bytesToHex11(new Uint8Array(commitmentHashBytes));
22426
24988
  const publicInputs = [
22427
24989
  `0x${params.minimumRequired.toString(16).padStart(64, "0")}`,
22428
24990
  `0x${this.assetIdToField(params.assetId)}`,
@@ -22430,7 +24992,7 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
22430
24992
  ];
22431
24993
  const proof = {
22432
24994
  type: "funding",
22433
- proof: `0x${bytesToHex12(proofData.proof)}`,
24995
+ proof: `0x${bytesToHex11(proofData.proof)}`,
22434
24996
  publicInputs
22435
24997
  };
22436
24998
  return { proof, publicInputs };
@@ -22545,7 +25107,7 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
22545
25107
  ];
22546
25108
  const proof = {
22547
25109
  type: "validity",
22548
- proof: `0x${bytesToHex12(proofData.proof)}`,
25110
+ proof: `0x${bytesToHex11(proofData.proof)}`,
22549
25111
  publicInputs
22550
25112
  };
22551
25113
  return { proof, publicInputs };
@@ -22647,7 +25209,7 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
22647
25209
  ];
22648
25210
  const proof = {
22649
25211
  type: "fulfillment",
22650
- proof: `0x${bytesToHex12(proofData.proof)}`,
25212
+ proof: `0x${bytesToHex11(proofData.proof)}`,
22651
25213
  publicInputs
22652
25214
  };
22653
25215
  return { proof, publicInputs };
@@ -22761,14 +25323,14 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
22761
25323
  }
22762
25324
  async computeCommitmentHash(balance, blindingFactor, assetId) {
22763
25325
  const blindingField = this.bytesToField(blindingFactor);
22764
- const { sha256: sha25622 } = await import("@noble/hashes/sha256");
25326
+ const { sha256: sha25623 } = await import("@noble/hashes/sha256");
22765
25327
  const { bytesToHex: nobleToHex } = await import("@noble/hashes/utils");
22766
25328
  const preimage = new Uint8Array([
22767
25329
  ...this.bigintToBytes(balance, 8),
22768
25330
  ...blindingFactor.slice(0, 32),
22769
25331
  ...hexToBytes10(this.assetIdToField(assetId))
22770
25332
  ]);
22771
- const hash2 = sha25622(preimage);
25333
+ const hash2 = sha25623(preimage);
22772
25334
  const commitmentHash = nobleToHex(hash2);
22773
25335
  return { commitmentHash, blindingField };
22774
25336
  }
@@ -22872,8 +25434,8 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
22872
25434
  const addressBytes = hexToBytes10(senderAddressField.padStart(64, "0"));
22873
25435
  const blindingBytes = hexToBytes10(senderBlindingField.padStart(64, "0"));
22874
25436
  const result = await api.pedersenCommit({ inputs: [addressBytes, blindingBytes], hashIndex: 0 });
22875
- const commitmentX = bytesToHex12(result.point.x).padStart(64, "0");
22876
- const commitmentY = bytesToHex12(result.point.y).padStart(64, "0");
25437
+ const commitmentX = bytesToHex11(result.point.x).padStart(64, "0");
25438
+ const commitmentY = bytesToHex11(result.point.y).padStart(64, "0");
22877
25439
  return { commitmentX, commitmentY };
22878
25440
  } finally {
22879
25441
  await api.destroy();
@@ -22893,7 +25455,7 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
22893
25455
  const intentBytes = hexToBytes10(intentHashField.padStart(64, "0"));
22894
25456
  const nonceBytes = hexToBytes10(nonceField.padStart(64, "0"));
22895
25457
  const result = await api.pedersenHash({ inputs: [secretBytes, intentBytes, nonceBytes], hashIndex: 0 });
22896
- const nullifier = bytesToHex12(result.hash).padStart(64, "0");
25458
+ const nullifier = bytesToHex11(result.hash).padStart(64, "0");
22897
25459
  return nullifier;
22898
25460
  } finally {
22899
25461
  await api.destroy();
@@ -22953,25 +25515,25 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
22953
25515
  return sig;
22954
25516
  }
22955
25517
  async computeOutputCommitment(outputAmount, outputBlinding) {
22956
- const { sha256: sha25622 } = await import("@noble/hashes/sha256");
25518
+ const { sha256: sha25623 } = await import("@noble/hashes/sha256");
22957
25519
  const { bytesToHex: nobleToHex } = await import("@noble/hashes/utils");
22958
25520
  const amountBytes = this.bigintToBytes(outputAmount, 8);
22959
25521
  const blindingBytes = outputBlinding.slice(0, 32);
22960
25522
  const preimage = new Uint8Array([...amountBytes, ...blindingBytes]);
22961
- const hash2 = sha25622(preimage);
25523
+ const hash2 = sha25623(preimage);
22962
25524
  const commitmentX = nobleToHex(hash2.slice(0, 16)).padStart(64, "0");
22963
25525
  const commitmentY = nobleToHex(hash2.slice(16, 32)).padStart(64, "0");
22964
25526
  return { commitmentX, commitmentY };
22965
25527
  }
22966
25528
  async computeSolverId(solverSecretField) {
22967
- const { sha256: sha25622 } = await import("@noble/hashes/sha256");
25529
+ const { sha256: sha25623 } = await import("@noble/hashes/sha256");
22968
25530
  const { bytesToHex: nobleToHex } = await import("@noble/hashes/utils");
22969
25531
  const secretBytes = hexToBytes10(solverSecretField.padStart(64, "0"));
22970
- const hash2 = sha25622(secretBytes);
25532
+ const hash2 = sha25623(secretBytes);
22971
25533
  return this.reduceToField(nobleToHex(hash2));
22972
25534
  }
22973
25535
  async computeOracleMessageHash(recipient, amount, txHash, blockNumber) {
22974
- const { sha256: sha25622 } = await import("@noble/hashes/sha256");
25536
+ const { sha256: sha25623 } = await import("@noble/hashes/sha256");
22975
25537
  const recipientBytes = hexToBytes10(this.hexToField(recipient));
22976
25538
  const amountBytes = this.bigintToBytes(amount, 8);
22977
25539
  const txHashBytes = hexToBytes10(this.hexToField(txHash));
@@ -22982,7 +25544,7 @@ var BrowserNoirProvider = class _BrowserNoirProvider {
22982
25544
  ...txHashBytes,
22983
25545
  ...blockBytes
22984
25546
  ]);
22985
- const hash2 = sha25622(preimage);
25547
+ const hash2 = sha25623(preimage);
22986
25548
  return Array.from(hash2);
22987
25549
  }
22988
25550
  getPublicKeyCoordinates(privateKey) {
@@ -23542,6 +26104,8 @@ var ProofWorker = class _ProofWorker {
23542
26104
  0 && (module.exports = {
23543
26105
  ATTESTATION_VERSION,
23544
26106
  AptosStealthService,
26107
+ AttestationGatedDisclosure,
26108
+ AttestationSchema,
23545
26109
  AuditorKeyDerivation,
23546
26110
  AuditorType,
23547
26111
  BaseWalletAdapter,
@@ -23560,11 +26124,14 @@ var ProofWorker = class _ProofWorker {
23560
26124
  ErrorCode,
23561
26125
  EthereumChainId,
23562
26126
  EthereumWalletAdapter,
26127
+ GenericProvider,
23563
26128
  HardwareErrorCode,
23564
26129
  HardwareWalletError,
26130
+ HeliusProvider,
23565
26131
  IntentBuilder,
23566
26132
  IntentError,
23567
26133
  IntentStatus,
26134
+ KNOWN_EXCHANGES,
23568
26135
  LedgerWalletAdapter,
23569
26136
  MEMO_PROGRAM_ID,
23570
26137
  MockEthereumAdapter,
@@ -23586,7 +26153,9 @@ var ProofWorker = class _ProofWorker {
23586
26153
  OneClickSwapType,
23587
26154
  PaymentBuilder,
23588
26155
  PaymentStatus,
26156
+ PrivacyBackendRegistry,
23589
26157
  PrivacyLevel,
26158
+ PrivacySmartRouter,
23590
26159
  PrivateNFT,
23591
26160
  PrivateVoting,
23592
26161
  ProofError,
@@ -23597,6 +26166,7 @@ var ProofWorker = class _ProofWorker {
23597
26166
  ReportStatus,
23598
26167
  SIP,
23599
26168
  SIPError,
26169
+ SIPNativeBackend,
23600
26170
  SIP_MEMO_PREFIX,
23601
26171
  SIP_VERSION,
23602
26172
  SOLANA_EXPLORER_URLS,
@@ -23613,6 +26183,7 @@ var ProofWorker = class _ProofWorker {
23613
26183
  SolanaSameChainExecutor,
23614
26184
  SolanaWalletAdapter,
23615
26185
  SuiStealthService,
26186
+ SurveillanceAnalyzer,
23616
26187
  SwapStatus,
23617
26188
  ThresholdViewingKey,
23618
26189
  Treasury,
@@ -23629,11 +26200,15 @@ var ProofWorker = class _ProofWorker {
23629
26200
  addBlindings,
23630
26201
  addCommitments,
23631
26202
  addOracle,
26203
+ analyzeAddressReuse,
26204
+ analyzeTemporalPatterns,
23632
26205
  aptosAddressToAuthKey,
23633
26206
  attachProofs,
23634
26207
  base58ToHex,
23635
26208
  browserBytesToHex,
23636
26209
  browserHexToBytes,
26210
+ calculatePrivacyScore,
26211
+ calculateSIPComparison,
23637
26212
  checkAptosStealthAddress,
23638
26213
  checkEd25519StealthAddress,
23639
26214
  checkMobileWASMCompatibility,
@@ -23649,6 +26224,7 @@ var ProofWorker = class _ProofWorker {
23649
26224
  createEthereumAdapter,
23650
26225
  createKeySpendOnlyOutput,
23651
26226
  createLedgerAdapter,
26227
+ createMockAttestation,
23652
26228
  createMockEthereumAdapter,
23653
26229
  createMockEthereumProvider,
23654
26230
  createMockLedgerAdapter,
@@ -23663,6 +26239,7 @@ var ProofWorker = class _ProofWorker {
23663
26239
  createPrivateOwnership,
23664
26240
  createPrivateVoting,
23665
26241
  createProductionSIP,
26242
+ createProvider,
23666
26243
  createSIP,
23667
26244
  createSameChainExecutor,
23668
26245
  createSealedBidAuction,
@@ -23670,9 +26247,11 @@ var ProofWorker = class _ProofWorker {
23670
26247
  createShieldedPayment,
23671
26248
  createSmartRouter,
23672
26249
  createSolanaAdapter,
26250
+ createSurveillanceAnalyzer,
23673
26251
  createTaprootOutput,
23674
26252
  createTrezorAdapter,
23675
26253
  createWalletFactory,
26254
+ createWebhookHandler,
23676
26255
  createWorkerBlobURL,
23677
26256
  createZcashClient,
23678
26257
  createZcashNativeBackend,
@@ -23682,6 +26261,7 @@ var ProofWorker = class _ProofWorker {
23682
26261
  decodeTaprootAddress,
23683
26262
  decryptMemo,
23684
26263
  decryptWithViewing,
26264
+ defaultRegistry,
23685
26265
  deriveAptosStealthPrivateKey,
23686
26266
  deriveEd25519StealthPrivateKey,
23687
26267
  deriveOracleId,
@@ -23691,7 +26271,9 @@ var ProofWorker = class _ProofWorker {
23691
26271
  deserializeAttestationMessage,
23692
26272
  deserializeIntent,
23693
26273
  deserializePayment,
26274
+ detectClusters,
23694
26275
  detectEthereumWallets,
26276
+ detectExchangeExposure,
23695
26277
  detectMobileBrowser,
23696
26278
  detectMobilePlatform,
23697
26279
  detectSolanaWallets,
@@ -23703,6 +26285,7 @@ var ProofWorker = class _ProofWorker {
23703
26285
  encryptForViewing,
23704
26286
  estimatePrivateTransferFee,
23705
26287
  featureNotSupportedError,
26288
+ fetchAttestation,
23706
26289
  formatStablecoinAmount,
23707
26290
  fromHex,
23708
26291
  fromStablecoinUnits,
@@ -23791,6 +26374,7 @@ var ProofWorker = class _ProofWorker {
23791
26374
  normalizeSuiAddress,
23792
26375
  notConnectedError,
23793
26376
  parseAnnouncement,
26377
+ processWebhookTransaction,
23794
26378
  proveOwnership,
23795
26379
  publicKeyToEthAddress,
23796
26380
  registerWallet,
@@ -23834,6 +26418,7 @@ var ProofWorker = class _ProofWorker {
23834
26418
  validateScalar,
23835
26419
  validateViewingKey,
23836
26420
  verifyAttestation,
26421
+ verifyAttestationSignature,
23837
26422
  verifyCommitment,
23838
26423
  verifyOpening,
23839
26424
  verifyOracleSignature,