@sip-protocol/sdk 0.7.2 → 0.7.4

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 (262) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +267 -0
  3. package/dist/{TransportWebUSB-TQ7WZ4LE.mjs → TransportWebUSB-YQMAGJAJ.mjs} +12 -9
  4. package/dist/browser.d.mts +10 -4
  5. package/dist/browser.d.ts +10 -4
  6. package/dist/browser.js +48874 -18336
  7. package/dist/browser.mjs +674 -48
  8. package/dist/chunk-4GRJ5MAW.mjs +152 -0
  9. package/dist/chunk-5D7A3L3W.mjs +717 -0
  10. package/dist/chunk-64AYA5F5.mjs +7834 -0
  11. package/dist/chunk-GMDGB22A.mjs +379 -0
  12. package/dist/chunk-I534WKN7.mjs +328 -0
  13. package/dist/chunk-IBZVA5Y7.mjs +1003 -0
  14. package/dist/chunk-PRRZAWJE.mjs +223 -0
  15. package/dist/{chunk-UJCSKKID.mjs → chunk-XGB3TDIC.mjs} +13 -1
  16. package/dist/chunk-YWGJ77A2.mjs +33806 -0
  17. package/dist/{chunk-6WGN57S2.mjs → chunk-Z3K7W5S3.mjs} +48 -0
  18. package/dist/constants-LHAAUC2T.mjs +51 -0
  19. package/dist/dist-2OGQ7FED.mjs +3957 -0
  20. package/dist/dist-IFHPYLDX.mjs +254 -0
  21. package/dist/fulfillment_proof-ANHVPKTB.mjs +21 -0
  22. package/dist/funding_proof-ICFZ5LHY.mjs +21 -0
  23. package/dist/index-DXh2IGkz.d.ts +24681 -0
  24. package/dist/index-DeE1ZzA4.d.mts +24681 -0
  25. package/dist/index.d.mts +9 -3
  26. package/dist/index.d.ts +9 -3
  27. package/dist/index.js +48676 -17318
  28. package/dist/index.mjs +583 -19
  29. package/dist/interface-Bf7w1PLW.d.mts +679 -0
  30. package/dist/interface-Bf7w1PLW.d.ts +679 -0
  31. package/dist/{noir-DKfEzWy9.d.mts → noir-kzbLVTei.d.mts} +31 -21
  32. package/dist/{noir-DKfEzWy9.d.ts → noir-kzbLVTei.d.ts} +31 -21
  33. package/dist/proofs/halo2.d.mts +151 -0
  34. package/dist/proofs/halo2.d.ts +151 -0
  35. package/dist/proofs/halo2.js +350 -0
  36. package/dist/proofs/halo2.mjs +11 -0
  37. package/dist/proofs/kimchi.d.mts +160 -0
  38. package/dist/proofs/kimchi.d.ts +160 -0
  39. package/dist/proofs/kimchi.js +431 -0
  40. package/dist/proofs/kimchi.mjs +13 -0
  41. package/dist/proofs/noir.d.mts +1 -1
  42. package/dist/proofs/noir.d.ts +1 -1
  43. package/dist/proofs/noir.js +74 -18
  44. package/dist/proofs/noir.mjs +84 -24
  45. package/dist/solana-U3MEGU7W.mjs +280 -0
  46. package/dist/validity_proof-3POXLPNY.mjs +21 -0
  47. package/package.json +54 -21
  48. package/src/adapters/index.ts +41 -0
  49. package/src/adapters/jupiter.ts +571 -0
  50. package/src/adapters/near-intents.ts +135 -0
  51. package/src/advisor/advisor.ts +653 -0
  52. package/src/advisor/index.ts +54 -0
  53. package/src/advisor/tools.ts +303 -0
  54. package/src/advisor/types.ts +164 -0
  55. package/src/chains/ethereum/announcement.ts +536 -0
  56. package/src/chains/ethereum/bnb-optimizations.ts +474 -0
  57. package/src/chains/ethereum/commitment.ts +522 -0
  58. package/src/chains/ethereum/constants.ts +462 -0
  59. package/src/chains/ethereum/deployment.ts +596 -0
  60. package/src/chains/ethereum/gas-estimation.ts +538 -0
  61. package/src/chains/ethereum/index.ts +268 -0
  62. package/src/chains/ethereum/optimizations.ts +614 -0
  63. package/src/chains/ethereum/privacy-adapter.ts +855 -0
  64. package/src/chains/ethereum/registry.ts +584 -0
  65. package/src/chains/ethereum/rpc.ts +905 -0
  66. package/src/chains/ethereum/stealth.ts +491 -0
  67. package/src/chains/ethereum/token.ts +790 -0
  68. package/src/chains/ethereum/transfer.ts +637 -0
  69. package/src/chains/ethereum/types.ts +456 -0
  70. package/src/chains/ethereum/viewing-key.ts +455 -0
  71. package/src/chains/near/commitment.ts +608 -0
  72. package/src/chains/near/constants.ts +284 -0
  73. package/src/chains/near/function-call.ts +871 -0
  74. package/src/chains/near/history.ts +654 -0
  75. package/src/chains/near/implicit-account.ts +840 -0
  76. package/src/chains/near/index.ts +393 -0
  77. package/src/chains/near/native-transfer.ts +658 -0
  78. package/src/chains/near/nep141.ts +775 -0
  79. package/src/chains/near/privacy-adapter.ts +889 -0
  80. package/src/chains/near/resolver.ts +971 -0
  81. package/src/chains/near/rpc.ts +1016 -0
  82. package/src/chains/near/stealth.ts +419 -0
  83. package/src/chains/near/types.ts +317 -0
  84. package/src/chains/near/viewing-key.ts +876 -0
  85. package/src/chains/solana/anchor-transfer.ts +386 -0
  86. package/src/chains/solana/commitment.ts +577 -0
  87. package/src/chains/solana/constants.ts +126 -12
  88. package/src/chains/solana/ephemeral-keys.ts +543 -0
  89. package/src/chains/solana/index.ts +276 -1
  90. package/src/chains/solana/key-derivation.ts +418 -0
  91. package/src/chains/solana/kit-compat.ts +334 -0
  92. package/src/chains/solana/optimizations.ts +560 -0
  93. package/src/chains/solana/privacy-adapter.ts +605 -0
  94. package/src/chains/solana/providers/generic.ts +201 -0
  95. package/src/chains/solana/providers/helius-enhanced-types.ts +336 -0
  96. package/src/chains/solana/providers/helius-enhanced.ts +623 -0
  97. package/src/chains/solana/providers/helius.ts +402 -0
  98. package/src/chains/solana/providers/index.ts +85 -0
  99. package/src/chains/solana/providers/interface.ts +221 -0
  100. package/src/chains/solana/providers/quicknode.ts +409 -0
  101. package/src/chains/solana/providers/triton.ts +426 -0
  102. package/src/chains/solana/providers/webhook.ts +790 -0
  103. package/src/chains/solana/rpc-client.ts +1150 -0
  104. package/src/chains/solana/scan.ts +170 -73
  105. package/src/chains/solana/sol-transfer.ts +732 -0
  106. package/src/chains/solana/spl-transfer.ts +886 -0
  107. package/src/chains/solana/stealth-scanner.ts +703 -0
  108. package/src/chains/solana/sunspot-verifier.ts +453 -0
  109. package/src/chains/solana/transaction-builder.ts +755 -0
  110. package/src/chains/solana/transfer.ts +74 -5
  111. package/src/chains/solana/types.ts +77 -7
  112. package/src/chains/solana/utils.ts +110 -0
  113. package/src/chains/solana/viewing-key.ts +807 -0
  114. package/src/compliance/fireblocks.ts +921 -0
  115. package/src/compliance/index.ts +37 -0
  116. package/src/compliance/range-sas.ts +956 -0
  117. package/src/config/endpoints.ts +100 -0
  118. package/src/crypto.ts +11 -8
  119. package/src/errors.ts +82 -0
  120. package/src/evm/erc4337-relayer.ts +830 -0
  121. package/src/evm/index.ts +47 -0
  122. package/src/fees/calculator.ts +396 -0
  123. package/src/fees/index.ts +87 -0
  124. package/src/fees/near-contract.ts +429 -0
  125. package/src/fees/types.ts +268 -0
  126. package/src/index.ts +785 -1
  127. package/src/intent.ts +6 -3
  128. package/src/logger.ts +324 -0
  129. package/src/network/index.ts +80 -0
  130. package/src/network/proxy.ts +691 -0
  131. package/src/optimizations/index.ts +541 -0
  132. package/src/oracle/types.ts +1 -0
  133. package/src/privacy-backends/arcium-types.ts +727 -0
  134. package/src/privacy-backends/arcium.ts +719 -0
  135. package/src/privacy-backends/combined-privacy.ts +866 -0
  136. package/src/privacy-backends/cspl-token.ts +595 -0
  137. package/src/privacy-backends/cspl-types.ts +512 -0
  138. package/src/privacy-backends/cspl.ts +907 -0
  139. package/src/privacy-backends/health.ts +488 -0
  140. package/src/privacy-backends/inco-types.ts +323 -0
  141. package/src/privacy-backends/inco.ts +616 -0
  142. package/src/privacy-backends/index.ts +336 -0
  143. package/src/privacy-backends/interface.ts +906 -0
  144. package/src/privacy-backends/lru-cache.ts +343 -0
  145. package/src/privacy-backends/magicblock.ts +458 -0
  146. package/src/privacy-backends/mock.ts +258 -0
  147. package/src/privacy-backends/privacycash-types.ts +278 -0
  148. package/src/privacy-backends/privacycash.ts +456 -0
  149. package/src/privacy-backends/private-swap.ts +570 -0
  150. package/src/privacy-backends/rate-limiter.ts +683 -0
  151. package/src/privacy-backends/registry.ts +690 -0
  152. package/src/privacy-backends/router.ts +626 -0
  153. package/src/privacy-backends/shadowwire.ts +449 -0
  154. package/src/privacy-backends/sip-native.ts +256 -0
  155. package/src/privacy-logger.ts +191 -0
  156. package/src/production-safety.ts +373 -0
  157. package/src/proofs/aggregator.ts +1029 -0
  158. package/src/proofs/browser-composer.ts +1150 -0
  159. package/src/proofs/browser.ts +113 -25
  160. package/src/proofs/cache/index.ts +127 -0
  161. package/src/proofs/cache/interface.ts +545 -0
  162. package/src/proofs/cache/key-generator.ts +188 -0
  163. package/src/proofs/cache/lru-cache.ts +481 -0
  164. package/src/proofs/cache/multi-tier-cache.ts +575 -0
  165. package/src/proofs/cache/persistent-cache.ts +788 -0
  166. package/src/proofs/compliance-proof.ts +872 -0
  167. package/src/proofs/composer/base.ts +923 -0
  168. package/src/proofs/composer/index.ts +25 -0
  169. package/src/proofs/composer/interface.ts +518 -0
  170. package/src/proofs/composer/types.ts +383 -0
  171. package/src/proofs/converters/halo2.ts +452 -0
  172. package/src/proofs/converters/index.ts +208 -0
  173. package/src/proofs/converters/interface.ts +363 -0
  174. package/src/proofs/converters/kimchi.ts +462 -0
  175. package/src/proofs/converters/noir.ts +451 -0
  176. package/src/proofs/fallback.ts +888 -0
  177. package/src/proofs/halo2.ts +42 -0
  178. package/src/proofs/index.ts +471 -0
  179. package/src/proofs/interface.ts +13 -0
  180. package/src/proofs/kimchi.ts +42 -0
  181. package/src/proofs/lazy.ts +1004 -0
  182. package/src/proofs/mock.ts +25 -1
  183. package/src/proofs/noir.ts +111 -30
  184. package/src/proofs/orchestrator.ts +960 -0
  185. package/src/proofs/parallel/concurrency.ts +297 -0
  186. package/src/proofs/parallel/dependency-graph.ts +602 -0
  187. package/src/proofs/parallel/executor.ts +420 -0
  188. package/src/proofs/parallel/index.ts +131 -0
  189. package/src/proofs/parallel/interface.ts +685 -0
  190. package/src/proofs/parallel/worker-pool.ts +644 -0
  191. package/src/proofs/providers/halo2.ts +560 -0
  192. package/src/proofs/providers/index.ts +34 -0
  193. package/src/proofs/providers/kimchi.ts +641 -0
  194. package/src/proofs/validator.ts +881 -0
  195. package/src/proofs/verifier.ts +867 -0
  196. package/src/quantum/index.ts +112 -0
  197. package/src/quantum/winternitz-vault.ts +639 -0
  198. package/src/quantum/wots.ts +611 -0
  199. package/src/settlement/backends/direct-chain.ts +1 -0
  200. package/src/settlement/index.ts +9 -0
  201. package/src/settlement/router.ts +732 -46
  202. package/src/solana/index.ts +72 -0
  203. package/src/solana/jito-relayer.ts +687 -0
  204. package/src/solana/noir-verifier-types.ts +430 -0
  205. package/src/solana/noir-verifier.ts +816 -0
  206. package/src/stealth/address-derivation.ts +193 -0
  207. package/src/stealth/ed25519.ts +431 -0
  208. package/src/stealth/index.ts +233 -0
  209. package/src/stealth/meta-address.ts +221 -0
  210. package/src/stealth/secp256k1.ts +368 -0
  211. package/src/stealth/utils.ts +194 -0
  212. package/src/stealth.ts +50 -1504
  213. package/src/surveillance/algorithms/address-reuse.ts +143 -0
  214. package/src/surveillance/algorithms/cluster.ts +247 -0
  215. package/src/surveillance/algorithms/exchange.ts +295 -0
  216. package/src/surveillance/algorithms/temporal.ts +337 -0
  217. package/src/surveillance/analyzer.ts +442 -0
  218. package/src/surveillance/index.ts +64 -0
  219. package/src/surveillance/scoring.ts +372 -0
  220. package/src/surveillance/types.ts +264 -0
  221. package/src/sync/index.ts +106 -0
  222. package/src/sync/manager.ts +504 -0
  223. package/src/sync/mock-provider.ts +318 -0
  224. package/src/sync/oblivious.ts +625 -0
  225. package/src/tokens/index.ts +15 -0
  226. package/src/tokens/registry.ts +301 -0
  227. package/src/utils/deprecation.ts +94 -0
  228. package/src/utils/index.ts +9 -0
  229. package/src/wallet/ethereum/index.ts +68 -0
  230. package/src/wallet/ethereum/metamask-privacy.ts +420 -0
  231. package/src/wallet/ethereum/multi-wallet.ts +646 -0
  232. package/src/wallet/ethereum/privacy-adapter.ts +700 -0
  233. package/src/wallet/ethereum/types.ts +3 -1
  234. package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
  235. package/src/wallet/hardware/index.ts +10 -0
  236. package/src/wallet/hardware/ledger-privacy.ts +414 -0
  237. package/src/wallet/index.ts +71 -0
  238. package/src/wallet/near/adapter.ts +626 -0
  239. package/src/wallet/near/index.ts +86 -0
  240. package/src/wallet/near/meteor-wallet.ts +1153 -0
  241. package/src/wallet/near/my-near-wallet.ts +790 -0
  242. package/src/wallet/near/wallet-selector.ts +702 -0
  243. package/src/wallet/solana/adapter.ts +6 -4
  244. package/src/wallet/solana/index.ts +13 -0
  245. package/src/wallet/solana/privacy-adapter.ts +567 -0
  246. package/src/wallet/sui/types.ts +6 -4
  247. package/src/zcash/rpc-client.ts +13 -6
  248. package/dist/chunk-3INS3PR5.mjs +0 -884
  249. package/dist/chunk-3OVABDRH.mjs +0 -17096
  250. package/dist/chunk-DLDWZFYC.mjs +0 -1495
  251. package/dist/chunk-E6SZWREQ.mjs +0 -57
  252. package/dist/chunk-G33LB27A.mjs +0 -16166
  253. package/dist/chunk-HGU6HZRC.mjs +0 -231
  254. package/dist/chunk-L2K34JCU.mjs +0 -1496
  255. package/dist/chunk-SN4ZDTVW.mjs +0 -16166
  256. package/dist/constants-VOI7BSLK.mjs +0 -27
  257. package/dist/index-BYZbDjal.d.ts +0 -11390
  258. package/dist/index-CHB3KuOB.d.mts +0 -11859
  259. package/dist/index-CzWPI6Le.d.ts +0 -11859
  260. package/dist/index-xbWjohNq.d.mts +0 -11390
  261. package/dist/solana-5EMCTPTS.mjs +0 -46
  262. package/dist/solana-Q4NAVBTS.mjs +0 -46
@@ -0,0 +1,449 @@
1
+ /**
2
+ * ShadowWire Privacy Backend
3
+ *
4
+ * Integrates ShadowWire by Radr Labs as a privacy backend for SIP Protocol.
5
+ * ShadowWire uses Pedersen Commitments + Bulletproofs for amount hiding.
6
+ *
7
+ * SIP adds viewing keys to ShadowWire for compliance support.
8
+ *
9
+ * @see https://radrlabs.io
10
+ * @see https://github.com/Radrdotfun/ShadowWire
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import { ShadowWireBackend, PrivacyBackendRegistry } from '@sip-protocol/sdk'
15
+ *
16
+ * const backend = new ShadowWireBackend()
17
+ * const registry = new PrivacyBackendRegistry()
18
+ * registry.register(backend)
19
+ *
20
+ * // Execute private transfer
21
+ * const result = await backend.execute({
22
+ * chain: 'solana',
23
+ * sender: 'sender-pubkey',
24
+ * recipient: 'recipient-pubkey',
25
+ * mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC
26
+ * amount: 1000000n, // 1 USDC
27
+ * decimals: 6,
28
+ * })
29
+ * ```
30
+ */
31
+
32
+ import {
33
+ ShadowWireClient,
34
+ type TransferType,
35
+ type TokenSymbol,
36
+ type WalletAdapter,
37
+ InsufficientBalanceError,
38
+ RecipientNotFoundError,
39
+ InvalidAmountError,
40
+ InvalidAddressError,
41
+ } from '@radr/shadowwire'
42
+ import type { ChainType, ViewingKey } from '@sip-protocol/types'
43
+ import type {
44
+ PrivacyBackend,
45
+ BackendType,
46
+ BackendCapabilities,
47
+ TransferParams,
48
+ TransactionResult,
49
+ AvailabilityResult,
50
+ BackendParams,
51
+ } from './interface'
52
+ import { isTransferParams } from './interface'
53
+ import { generateViewingKey, encryptForViewing } from '../privacy'
54
+ import type { HexString } from '@sip-protocol/types'
55
+ import { bytesToHex } from '@noble/hashes/utils'
56
+
57
+ /**
58
+ * ShadowWire supported token mint addresses
59
+ * Note: ShadowWire supports a specific set of tokens. Check SUPPORTED_TOKENS in @radr/shadowwire
60
+ */
61
+ export const SHADOWWIRE_TOKEN_MINTS: Record<TokenSymbol, string> = {
62
+ SOL: 'So11111111111111111111111111111111111111112',
63
+ USDC: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
64
+ RADR: 'RADRi35VqLmMu4t7Gax1KVszxnQnbtqEwJQJVfzpump',
65
+ ORE: 'oreoU2P8bN6jkk3jbaiVxYnG1dCXcYxwhycK7fw73F', // ORE mining token
66
+ BONK: 'DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263',
67
+ JIM: 'JIMa1xG7h7h7h7h7h7h7h7h7h7h7h7h7h7h7h7h7', // Placeholder
68
+ GODL: 'GODL1111111111111111111111111111111111111', // Placeholder
69
+ HUSTLE: 'HUSTLEexampleaddress1111111111111111111', // Placeholder
70
+ ZEC: 'ZECexampleaddress1111111111111111111111111', // Placeholder
71
+ CRT: 'CRTexampleaddress11111111111111111111111111', // Placeholder
72
+ BLACKCOIN: 'BLACKexampleaddress111111111111111111111', // Placeholder
73
+ GIL: 'GILexampleaddress11111111111111111111111111', // Placeholder
74
+ ANON: 'ANONexampleaddress1111111111111111111111111', // Placeholder
75
+ WLFI: 'WLFIexampleaddress1111111111111111111111111', // Placeholder - World Liberty Financial
76
+ USD1: 'USD1exampleaddress1111111111111111111111111', // Placeholder - USD1 stablecoin
77
+ AOL: 'AOLexampleaddress11111111111111111111111111', // Placeholder
78
+ IQLABS: 'IQLABSexampleaddress111111111111111111111', // Placeholder - IQ Labs token
79
+ }
80
+
81
+ /**
82
+ * Reverse lookup: mint address to symbol
83
+ */
84
+ const MINT_TO_SYMBOL: Record<string, TokenSymbol> = Object.fromEntries(
85
+ Object.entries(SHADOWWIRE_TOKEN_MINTS).map(([symbol, mint]) => [mint, symbol as TokenSymbol])
86
+ )
87
+
88
+ /**
89
+ * ShadowWire backend configuration
90
+ */
91
+ export interface ShadowWireBackendConfig {
92
+ /** API base URL (optional, uses default if not provided) */
93
+ apiBaseUrl?: string
94
+ /** Enable debug logging */
95
+ debug?: boolean
96
+ /** Default transfer type */
97
+ defaultTransferType?: TransferType
98
+ /** Wallet adapter for signing */
99
+ wallet?: WalletAdapter
100
+ /** Enable client-side proof generation (WASM) */
101
+ clientSideProofs?: boolean
102
+ }
103
+
104
+ /**
105
+ * ShadowWire backend capabilities
106
+ */
107
+ const SHADOWWIRE_CAPABILITIES: BackendCapabilities = {
108
+ hiddenAmount: true,
109
+ hiddenSender: true,
110
+ hiddenRecipient: true, // Internal transfers only
111
+ hiddenCompute: false,
112
+ complianceSupport: true, // SIP adds viewing keys
113
+ anonymitySet: undefined, // Not pool-based
114
+ setupRequired: false,
115
+ latencyEstimate: 'medium', // ~500ms for proof generation
116
+ supportedTokens: 'spl',
117
+ minAmount: 1n, // Minimum 1 lamport
118
+ maxAmount: undefined,
119
+ }
120
+
121
+ /**
122
+ * ShadowWire Privacy Backend
123
+ *
124
+ * Wraps the ShadowWire SDK to provide a unified PrivacyBackend interface.
125
+ * Adds SIP's viewing key support for compliance.
126
+ */
127
+ export class ShadowWireBackend implements PrivacyBackend {
128
+ readonly name = 'shadowwire'
129
+ readonly type: BackendType = 'transaction'
130
+ readonly chains: ChainType[] = ['solana']
131
+
132
+ private client: ShadowWireClient
133
+ private config: ShadowWireBackendConfig
134
+ private wallet?: WalletAdapter
135
+
136
+ constructor(config: ShadowWireBackendConfig = {}) {
137
+ this.config = {
138
+ defaultTransferType: 'internal',
139
+ clientSideProofs: false,
140
+ ...config,
141
+ }
142
+
143
+ this.client = new ShadowWireClient({
144
+ debug: config.debug,
145
+ apiBaseUrl: config.apiBaseUrl,
146
+ })
147
+
148
+ this.wallet = config.wallet
149
+ }
150
+
151
+ /**
152
+ * Set wallet adapter for signing
153
+ */
154
+ setWallet(wallet: WalletAdapter): void {
155
+ this.wallet = wallet
156
+ }
157
+
158
+ /**
159
+ * Check if backend is available for given parameters
160
+ */
161
+ async checkAvailability(params: BackendParams): Promise<AvailabilityResult> {
162
+ if (!isTransferParams(params)) {
163
+ return {
164
+ available: false,
165
+ reason: 'ShadowWire only supports transfer operations, not compute',
166
+ }
167
+ }
168
+
169
+ // Check chain support
170
+ if (params.chain !== 'solana') {
171
+ return {
172
+ available: false,
173
+ reason: `Chain '${params.chain}' not supported. ShadowWire only works on Solana`,
174
+ }
175
+ }
176
+
177
+ // Check token support
178
+ const tokenSymbol = this.getTokenSymbol(params.mint)
179
+ if (!tokenSymbol) {
180
+ return {
181
+ available: false,
182
+ reason: `Token mint '${params.mint}' not supported by ShadowWire`,
183
+ }
184
+ }
185
+
186
+ // Check amount validity
187
+ if (params.amount <= 0n) {
188
+ return {
189
+ available: false,
190
+ reason: 'Amount must be greater than 0',
191
+ }
192
+ }
193
+
194
+ // Check balance (if wallet is connected)
195
+ if (this.wallet) {
196
+ try {
197
+ const balance = await this.client.getBalance(params.sender, tokenSymbol)
198
+ if (BigInt(balance.available) < params.amount) {
199
+ return {
200
+ available: false,
201
+ reason: `Insufficient ShadowWire balance. Have: ${balance.available}, Need: ${params.amount}`,
202
+ }
203
+ }
204
+ } catch {
205
+ // Balance check failed, but might still be available
206
+ }
207
+ }
208
+
209
+ return {
210
+ available: true,
211
+ estimatedCost: this.estimateTransferCost(params),
212
+ estimatedTime: 2000, // ~2s for proof generation + confirmation
213
+ }
214
+ }
215
+
216
+ /**
217
+ * Get backend capabilities
218
+ */
219
+ getCapabilities(): BackendCapabilities {
220
+ return { ...SHADOWWIRE_CAPABILITIES }
221
+ }
222
+
223
+ /**
224
+ * Execute a privacy-preserving transfer via ShadowWire
225
+ */
226
+ async execute(params: TransferParams): Promise<TransactionResult> {
227
+ // Validate parameters
228
+ const validation = await this.checkAvailability(params)
229
+ if (!validation.available) {
230
+ return {
231
+ success: false,
232
+ error: validation.reason,
233
+ backend: this.name,
234
+ }
235
+ }
236
+
237
+ // Get token symbol
238
+ const tokenSymbol = this.getTokenSymbol(params.mint)
239
+ if (!tokenSymbol) {
240
+ return {
241
+ success: false,
242
+ error: `Unsupported token: ${params.mint}`,
243
+ backend: this.name,
244
+ }
245
+ }
246
+
247
+ // Determine wallet
248
+ const wallet = this.wallet || (params.options?.wallet as WalletAdapter | undefined)
249
+ if (!wallet) {
250
+ return {
251
+ success: false,
252
+ error: 'Wallet adapter required for ShadowWire transfers. Set via setWallet() or options.wallet',
253
+ backend: this.name,
254
+ }
255
+ }
256
+
257
+ try {
258
+ // Determine transfer type
259
+ const transferType: TransferType =
260
+ (params.options?.transferType as TransferType) ||
261
+ this.config.defaultTransferType ||
262
+ 'internal'
263
+
264
+ // Convert amount to decimal (ShadowWire uses decimal amounts)
265
+ const decimalAmount = Number(params.amount) / Math.pow(10, params.decimals)
266
+
267
+ // Execute ShadowWire transfer
268
+ const response = await this.client.transfer({
269
+ sender: params.sender,
270
+ recipient: params.recipient,
271
+ amount: decimalAmount,
272
+ token: tokenSymbol,
273
+ type: transferType,
274
+ wallet,
275
+ })
276
+
277
+ // Generate SIP viewing key for compliance
278
+ let viewingKey: ViewingKey | undefined
279
+ let encryptedData: HexString | undefined
280
+
281
+ if (params.viewingKey || params.options?.generateViewingKey) {
282
+ viewingKey = params.viewingKey || generateViewingKey()
283
+
284
+ // Encrypt transaction details for viewing key holder
285
+ const txDetails = {
286
+ sender: params.sender,
287
+ recipient: params.recipient,
288
+ amount: params.amount.toString(),
289
+ token: tokenSymbol,
290
+ timestamp: Date.now(),
291
+ shadowwireTxId: response.tx_signature,
292
+ }
293
+
294
+ // encryptForViewing returns EncryptedTransaction object
295
+ const encrypted = encryptForViewing(txDetails, viewingKey)
296
+ // Convert to hex string for storage
297
+ const jsonBytes = new TextEncoder().encode(JSON.stringify(encrypted))
298
+ encryptedData = `0x${bytesToHex(jsonBytes)}` as HexString
299
+ }
300
+
301
+ return {
302
+ success: true,
303
+ signature: response.tx_signature,
304
+ backend: this.name,
305
+ encryptedData,
306
+ metadata: {
307
+ transferType,
308
+ token: tokenSymbol,
309
+ viewingKeyGenerated: !!viewingKey,
310
+ },
311
+ }
312
+ } catch (error) {
313
+ return {
314
+ success: false,
315
+ error: this.formatError(error),
316
+ backend: this.name,
317
+ }
318
+ }
319
+ }
320
+
321
+ /**
322
+ * Estimate cost for a transfer
323
+ */
324
+ async estimateCost(params: BackendParams): Promise<bigint> {
325
+ if (!isTransferParams(params)) {
326
+ return 0n
327
+ }
328
+ return this.estimateTransferCost(params)
329
+ }
330
+
331
+ /**
332
+ * Get ShadowWire balance for a token
333
+ */
334
+ async getBalance(walletAddress: string, token: TokenSymbol): Promise<bigint> {
335
+ const balance = await this.client.getBalance(walletAddress, token)
336
+ return BigInt(balance.available)
337
+ }
338
+
339
+ /**
340
+ * Deposit funds into ShadowWire pool
341
+ * Returns an unsigned transaction that must be signed and sent by the caller
342
+ */
343
+ async deposit(
344
+ walletAddress: string,
345
+ amount: number,
346
+ tokenMint?: string
347
+ ): Promise<{ unsignedTx: string; poolAddress: string }> {
348
+ const response = await this.client.deposit({
349
+ wallet: walletAddress,
350
+ amount,
351
+ token_mint: tokenMint,
352
+ })
353
+ return {
354
+ unsignedTx: response.unsigned_tx_base64,
355
+ poolAddress: response.pool_address,
356
+ }
357
+ }
358
+
359
+ /**
360
+ * Withdraw funds from ShadowWire pool
361
+ * Returns an unsigned transaction that must be signed and sent by the caller
362
+ */
363
+ async withdraw(
364
+ walletAddress: string,
365
+ amount: number,
366
+ tokenMint?: string
367
+ ): Promise<{ unsignedTx: string; amountWithdrawn: number; fee: number }> {
368
+ const response = await this.client.withdraw({
369
+ wallet: walletAddress,
370
+ amount,
371
+ token_mint: tokenMint,
372
+ })
373
+ return {
374
+ unsignedTx: response.unsigned_tx_base64,
375
+ amountWithdrawn: response.amount_withdrawn,
376
+ fee: response.fee,
377
+ }
378
+ }
379
+
380
+ /**
381
+ * Get underlying ShadowWire client
382
+ */
383
+ getClient(): ShadowWireClient {
384
+ return this.client
385
+ }
386
+
387
+ // ─── Private Helpers ───────────────────────────────────────────────────────
388
+
389
+ /**
390
+ * Get token symbol from mint address
391
+ */
392
+ private getTokenSymbol(mint: string | null): TokenSymbol | undefined {
393
+ if (!mint) {
394
+ return 'SOL'
395
+ }
396
+ return MINT_TO_SYMBOL[mint]
397
+ }
398
+
399
+ /**
400
+ * Estimate transfer cost in lamports
401
+ */
402
+ private estimateTransferCost(params: TransferParams): bigint {
403
+ // Base transaction fee
404
+ let cost = 5000n // ~0.000005 SOL
405
+
406
+ // Add proof generation cost estimate
407
+ const transferType =
408
+ (params.options?.transferType as TransferType) ||
409
+ this.config.defaultTransferType ||
410
+ 'internal'
411
+
412
+ if (transferType === 'internal') {
413
+ cost += 10000n // Additional cost for ZK proof verification
414
+ }
415
+
416
+ return cost
417
+ }
418
+
419
+ /**
420
+ * Format error for user-friendly message
421
+ */
422
+ private formatError(error: unknown): string {
423
+ if (error instanceof InsufficientBalanceError) {
424
+ return 'Insufficient balance in ShadowWire pool. Deposit funds first.'
425
+ }
426
+ if (error instanceof RecipientNotFoundError) {
427
+ return 'Recipient must be a ShadowWire user for internal transfers. Use external transfer type for non-users.'
428
+ }
429
+ if (error instanceof InvalidAmountError) {
430
+ return 'Invalid transfer amount'
431
+ }
432
+ if (error instanceof InvalidAddressError) {
433
+ return 'Invalid Solana address'
434
+ }
435
+ if (error instanceof Error) {
436
+ return error.message
437
+ }
438
+ return 'Unknown ShadowWire error'
439
+ }
440
+ }
441
+
442
+ /**
443
+ * Create a ShadowWire backend with default configuration
444
+ */
445
+ export function createShadowWireBackend(
446
+ config?: ShadowWireBackendConfig
447
+ ): ShadowWireBackend {
448
+ return new ShadowWireBackend(config)
449
+ }
@@ -0,0 +1,256 @@
1
+ /**
2
+ * SIP Native Privacy Backend
3
+ *
4
+ * Implements the PrivacyBackend interface using SIP's native privacy primitives:
5
+ * - Stealth addresses (EIP-5564 style)
6
+ * - Pedersen commitments (amount hiding)
7
+ * - Viewing keys (compliance support)
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { SIPNativeBackend, PrivacyBackendRegistry } from '@sip-protocol/sdk'
12
+ *
13
+ * const backend = new SIPNativeBackend()
14
+ * const registry = new PrivacyBackendRegistry()
15
+ * registry.register(backend)
16
+ *
17
+ * // Check capabilities
18
+ * const caps = backend.getCapabilities()
19
+ * console.log(caps.complianceSupport) // true
20
+ *
21
+ * // Execute transfer
22
+ * const result = await backend.execute({
23
+ * chain: 'solana',
24
+ * sender: 'sender-address',
25
+ * recipient: 'stealth-address',
26
+ * mint: 'token-mint',
27
+ * amount: BigInt(1000000),
28
+ * decimals: 6,
29
+ * })
30
+ * ```
31
+ */
32
+
33
+ import type { ChainType } from '@sip-protocol/types'
34
+ import type {
35
+ PrivacyBackend,
36
+ BackendType,
37
+ BackendCapabilities,
38
+ TransferParams,
39
+ TransactionResult,
40
+ AvailabilityResult,
41
+ PrivacyBackendVersion,
42
+ } from './interface'
43
+ import { CURRENT_BACKEND_VERSION } from './interface'
44
+
45
+ /**
46
+ * Supported chains for SIP Native backend
47
+ */
48
+ const SUPPORTED_CHAINS: ChainType[] = [
49
+ 'solana',
50
+ 'ethereum',
51
+ 'near',
52
+ 'polygon',
53
+ 'arbitrum',
54
+ 'optimism',
55
+ 'base',
56
+ 'avalanche',
57
+ 'bsc',
58
+ ]
59
+
60
+ /**
61
+ * SIP Native backend capabilities
62
+ */
63
+ const SIP_NATIVE_CAPABILITIES: BackendCapabilities = {
64
+ hiddenAmount: true,
65
+ hiddenSender: true,
66
+ hiddenRecipient: true,
67
+ hiddenCompute: false,
68
+ complianceSupport: true,
69
+ anonymitySet: undefined, // Not pool-based
70
+ setupRequired: false,
71
+ latencyEstimate: 'fast',
72
+ supportedTokens: 'all',
73
+ minAmount: undefined,
74
+ maxAmount: undefined,
75
+ }
76
+
77
+ /**
78
+ * Configuration options for SIP Native backend
79
+ */
80
+ export interface SIPNativeBackendConfig {
81
+ /** Custom supported chains (overrides default) */
82
+ chains?: ChainType[]
83
+ /** Whether to require viewing keys for all transfers */
84
+ requireViewingKey?: boolean
85
+ /** Minimum amount for transfers (optional) */
86
+ minAmount?: bigint
87
+ /** Maximum amount for transfers (optional) */
88
+ maxAmount?: bigint
89
+ }
90
+
91
+ /**
92
+ * SIP Native Privacy Backend
93
+ *
94
+ * Uses stealth addresses and Pedersen commitments for transaction privacy,
95
+ * with viewing key support for regulatory compliance.
96
+ */
97
+ export class SIPNativeBackend implements PrivacyBackend {
98
+ readonly version: PrivacyBackendVersion = CURRENT_BACKEND_VERSION
99
+ readonly name = 'sip-native'
100
+ readonly type: BackendType = 'transaction'
101
+ readonly chains: ChainType[]
102
+
103
+ private config: Required<SIPNativeBackendConfig>
104
+
105
+ /**
106
+ * Create a new SIP Native backend
107
+ *
108
+ * @param config - Backend configuration
109
+ */
110
+ constructor(config: SIPNativeBackendConfig = {}) {
111
+ this.chains = config.chains ?? SUPPORTED_CHAINS
112
+ this.config = {
113
+ chains: this.chains,
114
+ requireViewingKey: config.requireViewingKey ?? false,
115
+ minAmount: config.minAmount ?? BigInt(0),
116
+ maxAmount: config.maxAmount ?? BigInt(Number.MAX_SAFE_INTEGER),
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Check if backend is available for given parameters
122
+ */
123
+ async checkAvailability(params: TransferParams): Promise<AvailabilityResult> {
124
+ // Check chain support
125
+ if (!this.chains.includes(params.chain)) {
126
+ return {
127
+ available: false,
128
+ reason: `Chain '${params.chain}' not supported by SIP Native backend`,
129
+ }
130
+ }
131
+
132
+ // Check viewing key requirement
133
+ if (this.config.requireViewingKey && !params.viewingKey) {
134
+ return {
135
+ available: false,
136
+ reason: 'Viewing key required for SIP Native backend',
137
+ }
138
+ }
139
+
140
+ // Check amount bounds
141
+ if (params.amount < this.config.minAmount) {
142
+ return {
143
+ available: false,
144
+ reason: `Amount ${params.amount} below minimum ${this.config.minAmount}`,
145
+ }
146
+ }
147
+
148
+ if (params.amount > this.config.maxAmount) {
149
+ return {
150
+ available: false,
151
+ reason: `Amount ${params.amount} above maximum ${this.config.maxAmount}`,
152
+ }
153
+ }
154
+
155
+ // Estimate cost based on chain
156
+ const estimatedCost = this.getEstimatedCostForChain(params.chain)
157
+
158
+ return {
159
+ available: true,
160
+ estimatedCost,
161
+ estimatedTime: 1000, // ~1 second for stealth address operations
162
+ }
163
+ }
164
+
165
+ /**
166
+ * Get backend capabilities
167
+ */
168
+ getCapabilities(): BackendCapabilities {
169
+ return {
170
+ ...SIP_NATIVE_CAPABILITIES,
171
+ minAmount: this.config.minAmount > BigInt(0) ? this.config.minAmount : undefined,
172
+ maxAmount: this.config.maxAmount < BigInt(Number.MAX_SAFE_INTEGER)
173
+ ? this.config.maxAmount
174
+ : undefined,
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Execute a privacy-preserving transfer
180
+ *
181
+ * This creates a stealth address transfer with:
182
+ * - Ephemeral keypair generation
183
+ * - Stealth address derivation
184
+ * - Pedersen commitment for amount
185
+ * - Optional viewing key encryption
186
+ */
187
+ async execute(params: TransferParams): Promise<TransactionResult> {
188
+ // Validate availability first
189
+ const availability = await this.checkAvailability(params)
190
+ if (!availability.available) {
191
+ return {
192
+ success: false,
193
+ error: availability.reason,
194
+ backend: this.name,
195
+ }
196
+ }
197
+
198
+ try {
199
+ // In a real implementation, this would:
200
+ // 1. Generate ephemeral keypair
201
+ // 2. Derive stealth address from recipient's meta-address
202
+ // 3. Create Pedersen commitment for amount
203
+ // 4. Build and submit transaction
204
+ // 5. Optionally encrypt data for viewing key
205
+
206
+ // For now, return a simulated successful result
207
+ // Real implementation depends on chain-specific adapters
208
+ const simulatedSignature = `sim_${Date.now()}_${Math.random().toString(36).slice(2)}`
209
+
210
+ return {
211
+ success: true,
212
+ signature: simulatedSignature,
213
+ backend: this.name,
214
+ metadata: {
215
+ chain: params.chain,
216
+ amount: params.amount.toString(),
217
+ hasViewingKey: !!params.viewingKey,
218
+ timestamp: Date.now(),
219
+ },
220
+ }
221
+ } catch (error) {
222
+ return {
223
+ success: false,
224
+ error: error instanceof Error ? error.message : 'Unknown error',
225
+ backend: this.name,
226
+ }
227
+ }
228
+ }
229
+
230
+ /**
231
+ * Estimate cost for a transfer
232
+ */
233
+ async estimateCost(params: TransferParams): Promise<bigint> {
234
+ return this.getEstimatedCostForChain(params.chain)
235
+ }
236
+
237
+ /**
238
+ * Get estimated cost based on chain
239
+ */
240
+ private getEstimatedCostForChain(chain: ChainType): bigint {
241
+ // Estimated costs in smallest chain units
242
+ const costMap: Partial<Record<ChainType, bigint>> = {
243
+ solana: BigInt(5000), // ~0.000005 SOL
244
+ ethereum: BigInt('50000000000000'), // ~0.00005 ETH
245
+ near: BigInt('1000000000000000000000'), // ~0.001 NEAR
246
+ polygon: BigInt('50000000000000'), // ~0.00005 MATIC
247
+ arbitrum: BigInt('50000000000000'),
248
+ optimism: BigInt('50000000000000'),
249
+ base: BigInt('50000000000000'),
250
+ avalanche: BigInt('50000000000000'),
251
+ bsc: BigInt('50000000000000'),
252
+ }
253
+
254
+ return costMap[chain] ?? BigInt(0)
255
+ }
256
+ }