@sip-protocol/sdk 0.7.3 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. package/README.md +267 -0
  2. package/dist/{TransportWebUSB-TQ7WZ4LE.mjs → TransportWebUSB-YQMAGJAJ.mjs} +12 -9
  3. package/dist/browser.d.mts +10 -4
  4. package/dist/browser.d.ts +10 -4
  5. package/dist/browser.js +47556 -19603
  6. package/dist/browser.mjs +628 -48
  7. package/dist/chunk-4GRJ5MAW.mjs +152 -0
  8. package/dist/chunk-5D7A3L3W.mjs +717 -0
  9. package/dist/chunk-64AYA5F5.mjs +7834 -0
  10. package/dist/chunk-GMDGB22A.mjs +379 -0
  11. package/dist/chunk-I534WKN7.mjs +328 -0
  12. package/dist/chunk-IBZVA5Y7.mjs +1003 -0
  13. package/dist/chunk-PRRZAWJE.mjs +223 -0
  14. package/dist/{chunk-UJCSKKID.mjs → chunk-XGB3TDIC.mjs} +13 -1
  15. package/dist/{chunk-3M3HNQCW.mjs → chunk-YWGJ77A2.mjs} +28656 -13103
  16. package/dist/{chunk-6WGN57S2.mjs → chunk-Z3K7W5S3.mjs} +48 -0
  17. package/dist/constants-LHAAUC2T.mjs +51 -0
  18. package/dist/dist-2OGQ7FED.mjs +3957 -0
  19. package/dist/dist-IFHPYLDX.mjs +254 -0
  20. package/dist/fulfillment_proof-ANHVPKTB.mjs +21 -0
  21. package/dist/funding_proof-ICFZ5LHY.mjs +21 -0
  22. package/dist/{index-DIBZHOOQ.d.ts → index-DXh2IGkz.d.ts} +21239 -10304
  23. package/dist/{index-8MQz13eJ.d.mts → index-DeE1ZzA4.d.mts} +21239 -10304
  24. package/dist/index.d.mts +9 -3
  25. package/dist/index.d.ts +9 -3
  26. package/dist/index.js +48396 -19623
  27. package/dist/index.mjs +537 -19
  28. package/dist/interface-Bf7w1PLW.d.mts +679 -0
  29. package/dist/interface-Bf7w1PLW.d.ts +679 -0
  30. package/dist/{noir-DKfEzWy9.d.mts → noir-kzbLVTei.d.mts} +31 -21
  31. package/dist/{noir-DKfEzWy9.d.ts → noir-kzbLVTei.d.ts} +31 -21
  32. package/dist/proofs/halo2.d.mts +151 -0
  33. package/dist/proofs/halo2.d.ts +151 -0
  34. package/dist/proofs/halo2.js +350 -0
  35. package/dist/proofs/halo2.mjs +11 -0
  36. package/dist/proofs/kimchi.d.mts +160 -0
  37. package/dist/proofs/kimchi.d.ts +160 -0
  38. package/dist/proofs/kimchi.js +431 -0
  39. package/dist/proofs/kimchi.mjs +13 -0
  40. package/dist/proofs/noir.d.mts +1 -1
  41. package/dist/proofs/noir.d.ts +1 -1
  42. package/dist/proofs/noir.js +74 -18
  43. package/dist/proofs/noir.mjs +84 -24
  44. package/dist/solana-U3MEGU7W.mjs +280 -0
  45. package/dist/validity_proof-3POXLPNY.mjs +21 -0
  46. package/package.json +44 -11
  47. package/src/adapters/index.ts +41 -0
  48. package/src/adapters/jupiter.ts +571 -0
  49. package/src/adapters/near-intents.ts +135 -0
  50. package/src/advisor/advisor.ts +653 -0
  51. package/src/advisor/index.ts +54 -0
  52. package/src/advisor/tools.ts +303 -0
  53. package/src/advisor/types.ts +164 -0
  54. package/src/chains/ethereum/announcement.ts +536 -0
  55. package/src/chains/ethereum/bnb-optimizations.ts +474 -0
  56. package/src/chains/ethereum/commitment.ts +522 -0
  57. package/src/chains/ethereum/constants.ts +462 -0
  58. package/src/chains/ethereum/deployment.ts +596 -0
  59. package/src/chains/ethereum/gas-estimation.ts +538 -0
  60. package/src/chains/ethereum/index.ts +268 -0
  61. package/src/chains/ethereum/optimizations.ts +614 -0
  62. package/src/chains/ethereum/privacy-adapter.ts +855 -0
  63. package/src/chains/ethereum/registry.ts +584 -0
  64. package/src/chains/ethereum/rpc.ts +905 -0
  65. package/src/chains/ethereum/stealth.ts +491 -0
  66. package/src/chains/ethereum/token.ts +790 -0
  67. package/src/chains/ethereum/transfer.ts +637 -0
  68. package/src/chains/ethereum/types.ts +456 -0
  69. package/src/chains/ethereum/viewing-key.ts +455 -0
  70. package/src/chains/near/commitment.ts +608 -0
  71. package/src/chains/near/constants.ts +284 -0
  72. package/src/chains/near/function-call.ts +871 -0
  73. package/src/chains/near/history.ts +654 -0
  74. package/src/chains/near/implicit-account.ts +840 -0
  75. package/src/chains/near/index.ts +393 -0
  76. package/src/chains/near/native-transfer.ts +658 -0
  77. package/src/chains/near/nep141.ts +775 -0
  78. package/src/chains/near/privacy-adapter.ts +889 -0
  79. package/src/chains/near/resolver.ts +971 -0
  80. package/src/chains/near/rpc.ts +1016 -0
  81. package/src/chains/near/stealth.ts +419 -0
  82. package/src/chains/near/types.ts +317 -0
  83. package/src/chains/near/viewing-key.ts +876 -0
  84. package/src/chains/solana/anchor-transfer.ts +386 -0
  85. package/src/chains/solana/commitment.ts +577 -0
  86. package/src/chains/solana/constants.ts +126 -12
  87. package/src/chains/solana/ephemeral-keys.ts +543 -0
  88. package/src/chains/solana/index.ts +252 -1
  89. package/src/chains/solana/key-derivation.ts +418 -0
  90. package/src/chains/solana/kit-compat.ts +334 -0
  91. package/src/chains/solana/optimizations.ts +560 -0
  92. package/src/chains/solana/privacy-adapter.ts +605 -0
  93. package/src/chains/solana/providers/generic.ts +47 -6
  94. package/src/chains/solana/providers/helius-enhanced-types.ts +336 -0
  95. package/src/chains/solana/providers/helius-enhanced.ts +623 -0
  96. package/src/chains/solana/providers/helius.ts +186 -33
  97. package/src/chains/solana/providers/index.ts +31 -0
  98. package/src/chains/solana/providers/interface.ts +61 -18
  99. package/src/chains/solana/providers/quicknode.ts +409 -0
  100. package/src/chains/solana/providers/triton.ts +426 -0
  101. package/src/chains/solana/providers/webhook.ts +338 -67
  102. package/src/chains/solana/rpc-client.ts +1150 -0
  103. package/src/chains/solana/scan.ts +83 -66
  104. package/src/chains/solana/sol-transfer.ts +732 -0
  105. package/src/chains/solana/spl-transfer.ts +886 -0
  106. package/src/chains/solana/stealth-scanner.ts +703 -0
  107. package/src/chains/solana/sunspot-verifier.ts +453 -0
  108. package/src/chains/solana/transaction-builder.ts +755 -0
  109. package/src/chains/solana/transfer.ts +74 -5
  110. package/src/chains/solana/types.ts +57 -6
  111. package/src/chains/solana/utils.ts +110 -0
  112. package/src/chains/solana/viewing-key.ts +807 -0
  113. package/src/compliance/fireblocks.ts +921 -0
  114. package/src/compliance/index.ts +23 -0
  115. package/src/compliance/range-sas.ts +398 -33
  116. package/src/config/endpoints.ts +100 -0
  117. package/src/crypto.ts +11 -8
  118. package/src/errors.ts +82 -0
  119. package/src/evm/erc4337-relayer.ts +830 -0
  120. package/src/evm/index.ts +47 -0
  121. package/src/fees/calculator.ts +396 -0
  122. package/src/fees/index.ts +87 -0
  123. package/src/fees/near-contract.ts +429 -0
  124. package/src/fees/types.ts +268 -0
  125. package/src/index.ts +686 -1
  126. package/src/intent.ts +6 -3
  127. package/src/logger.ts +324 -0
  128. package/src/network/index.ts +80 -0
  129. package/src/network/proxy.ts +691 -0
  130. package/src/optimizations/index.ts +541 -0
  131. package/src/oracle/types.ts +1 -0
  132. package/src/privacy-backends/arcium-types.ts +727 -0
  133. package/src/privacy-backends/arcium.ts +719 -0
  134. package/src/privacy-backends/combined-privacy.ts +866 -0
  135. package/src/privacy-backends/cspl-token.ts +595 -0
  136. package/src/privacy-backends/cspl-types.ts +512 -0
  137. package/src/privacy-backends/cspl.ts +907 -0
  138. package/src/privacy-backends/health.ts +488 -0
  139. package/src/privacy-backends/inco-types.ts +323 -0
  140. package/src/privacy-backends/inco.ts +616 -0
  141. package/src/privacy-backends/index.ts +254 -4
  142. package/src/privacy-backends/interface.ts +649 -6
  143. package/src/privacy-backends/lru-cache.ts +343 -0
  144. package/src/privacy-backends/magicblock.ts +458 -0
  145. package/src/privacy-backends/mock.ts +258 -0
  146. package/src/privacy-backends/privacycash.ts +13 -17
  147. package/src/privacy-backends/private-swap.ts +570 -0
  148. package/src/privacy-backends/rate-limiter.ts +683 -0
  149. package/src/privacy-backends/registry.ts +414 -2
  150. package/src/privacy-backends/router.ts +283 -3
  151. package/src/privacy-backends/shadowwire.ts +449 -0
  152. package/src/privacy-backends/sip-native.ts +3 -0
  153. package/src/privacy-logger.ts +191 -0
  154. package/src/production-safety.ts +373 -0
  155. package/src/proofs/aggregator.ts +1029 -0
  156. package/src/proofs/browser-composer.ts +1150 -0
  157. package/src/proofs/browser.ts +113 -25
  158. package/src/proofs/cache/index.ts +127 -0
  159. package/src/proofs/cache/interface.ts +545 -0
  160. package/src/proofs/cache/key-generator.ts +188 -0
  161. package/src/proofs/cache/lru-cache.ts +481 -0
  162. package/src/proofs/cache/multi-tier-cache.ts +575 -0
  163. package/src/proofs/cache/persistent-cache.ts +788 -0
  164. package/src/proofs/compliance-proof.ts +872 -0
  165. package/src/proofs/composer/base.ts +923 -0
  166. package/src/proofs/composer/index.ts +25 -0
  167. package/src/proofs/composer/interface.ts +518 -0
  168. package/src/proofs/composer/types.ts +383 -0
  169. package/src/proofs/converters/halo2.ts +452 -0
  170. package/src/proofs/converters/index.ts +208 -0
  171. package/src/proofs/converters/interface.ts +363 -0
  172. package/src/proofs/converters/kimchi.ts +462 -0
  173. package/src/proofs/converters/noir.ts +451 -0
  174. package/src/proofs/fallback.ts +888 -0
  175. package/src/proofs/halo2.ts +42 -0
  176. package/src/proofs/index.ts +471 -0
  177. package/src/proofs/interface.ts +13 -0
  178. package/src/proofs/kimchi.ts +42 -0
  179. package/src/proofs/lazy.ts +1004 -0
  180. package/src/proofs/mock.ts +25 -1
  181. package/src/proofs/noir.ts +110 -29
  182. package/src/proofs/orchestrator.ts +960 -0
  183. package/src/proofs/parallel/concurrency.ts +297 -0
  184. package/src/proofs/parallel/dependency-graph.ts +602 -0
  185. package/src/proofs/parallel/executor.ts +420 -0
  186. package/src/proofs/parallel/index.ts +131 -0
  187. package/src/proofs/parallel/interface.ts +685 -0
  188. package/src/proofs/parallel/worker-pool.ts +644 -0
  189. package/src/proofs/providers/halo2.ts +560 -0
  190. package/src/proofs/providers/index.ts +34 -0
  191. package/src/proofs/providers/kimchi.ts +641 -0
  192. package/src/proofs/validator.ts +881 -0
  193. package/src/proofs/verifier.ts +867 -0
  194. package/src/quantum/index.ts +112 -0
  195. package/src/quantum/winternitz-vault.ts +639 -0
  196. package/src/quantum/wots.ts +611 -0
  197. package/src/settlement/backends/direct-chain.ts +1 -0
  198. package/src/settlement/index.ts +9 -0
  199. package/src/settlement/router.ts +732 -46
  200. package/src/solana/index.ts +72 -0
  201. package/src/solana/jito-relayer.ts +687 -0
  202. package/src/solana/noir-verifier-types.ts +430 -0
  203. package/src/solana/noir-verifier.ts +816 -0
  204. package/src/stealth/address-derivation.ts +193 -0
  205. package/src/stealth/ed25519.ts +431 -0
  206. package/src/stealth/index.ts +233 -0
  207. package/src/stealth/meta-address.ts +221 -0
  208. package/src/stealth/secp256k1.ts +368 -0
  209. package/src/stealth/utils.ts +194 -0
  210. package/src/stealth.ts +50 -1504
  211. package/src/sync/index.ts +106 -0
  212. package/src/sync/manager.ts +504 -0
  213. package/src/sync/mock-provider.ts +318 -0
  214. package/src/sync/oblivious.ts +625 -0
  215. package/src/tokens/index.ts +15 -0
  216. package/src/tokens/registry.ts +301 -0
  217. package/src/utils/deprecation.ts +94 -0
  218. package/src/utils/index.ts +9 -0
  219. package/src/wallet/ethereum/index.ts +68 -0
  220. package/src/wallet/ethereum/metamask-privacy.ts +420 -0
  221. package/src/wallet/ethereum/multi-wallet.ts +646 -0
  222. package/src/wallet/ethereum/privacy-adapter.ts +700 -0
  223. package/src/wallet/ethereum/types.ts +3 -1
  224. package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
  225. package/src/wallet/hardware/index.ts +10 -0
  226. package/src/wallet/hardware/ledger-privacy.ts +414 -0
  227. package/src/wallet/index.ts +71 -0
  228. package/src/wallet/near/adapter.ts +626 -0
  229. package/src/wallet/near/index.ts +86 -0
  230. package/src/wallet/near/meteor-wallet.ts +1153 -0
  231. package/src/wallet/near/my-near-wallet.ts +790 -0
  232. package/src/wallet/near/wallet-selector.ts +702 -0
  233. package/src/wallet/solana/adapter.ts +6 -4
  234. package/src/wallet/solana/index.ts +13 -0
  235. package/src/wallet/solana/privacy-adapter.ts +567 -0
  236. package/src/wallet/sui/types.ts +6 -4
  237. package/src/zcash/rpc-client.ts +13 -6
  238. package/dist/chunk-2XIVXWHA.mjs +0 -1930
  239. package/dist/chunk-3INS3PR5.mjs +0 -884
  240. package/dist/chunk-3OVABDRH.mjs +0 -17096
  241. package/dist/chunk-7RFRWDCW.mjs +0 -1504
  242. package/dist/chunk-DLDWZFYC.mjs +0 -1495
  243. package/dist/chunk-E6SZWREQ.mjs +0 -57
  244. package/dist/chunk-F6F73W35.mjs +0 -16166
  245. package/dist/chunk-G33LB27A.mjs +0 -16166
  246. package/dist/chunk-HGU6HZRC.mjs +0 -231
  247. package/dist/chunk-L2K34JCU.mjs +0 -1496
  248. package/dist/chunk-OFDBEIEK.mjs +0 -16166
  249. package/dist/chunk-SF7YSLF5.mjs +0 -1515
  250. package/dist/chunk-SN4ZDTVW.mjs +0 -16166
  251. package/dist/chunk-WWUSGOXE.mjs +0 -17129
  252. package/dist/constants-VOI7BSLK.mjs +0 -27
  253. package/dist/index-B71aXVzk.d.ts +0 -13264
  254. package/dist/index-BYZbDjal.d.ts +0 -11390
  255. package/dist/index-CHB3KuOB.d.mts +0 -11859
  256. package/dist/index-CzWPI6Le.d.ts +0 -11859
  257. package/dist/index-pOIIuwfV.d.mts +0 -13264
  258. package/dist/index-xbWjohNq.d.mts +0 -11390
  259. package/dist/solana-4O4K45VU.mjs +0 -46
  260. package/dist/solana-5EMCTPTS.mjs +0 -46
  261. package/dist/solana-NDABAZ6P.mjs +0 -56
  262. package/dist/solana-Q4NAVBTS.mjs +0 -46
  263. package/dist/solana-ZYO63LY5.mjs +0 -46
@@ -0,0 +1,637 @@
1
+ /**
2
+ * Ethereum Stealth Transfer Builder
3
+ *
4
+ * High-level transfer orchestration that combines stealth address generation,
5
+ * announcement building, gas estimation, and transaction preparation.
6
+ *
7
+ * @module chains/ethereum/transfer
8
+ */
9
+
10
+ import type { HexString, StealthMetaAddress } from '@sip-protocol/types'
11
+ import { EthereumPrivacyAdapter } from './privacy-adapter'
12
+ import { EthereumRpcClient } from './rpc'
13
+ import {
14
+ estimateEthTransferGas,
15
+ estimateTokenTransferGas,
16
+ type DetailedGasEstimate,
17
+ } from './gas-estimation'
18
+ import type { EthereumNetwork } from './constants'
19
+
20
+ // ─── Types ────────────────────────────────────────────────────────────────────
21
+
22
+ /**
23
+ * Prepared transaction ready for signing
24
+ */
25
+ export interface PreparedTransaction {
26
+ /**
27
+ * Target address
28
+ */
29
+ to: HexString
30
+
31
+ /**
32
+ * Value in wei
33
+ */
34
+ value: bigint
35
+
36
+ /**
37
+ * Call data (if contract call)
38
+ */
39
+ data?: HexString
40
+
41
+ /**
42
+ * Nonce
43
+ */
44
+ nonce: number
45
+
46
+ /**
47
+ * Gas limit
48
+ */
49
+ gasLimit: bigint
50
+
51
+ /**
52
+ * Chain ID
53
+ */
54
+ chainId: number
55
+
56
+ /**
57
+ * EIP-1559: Max priority fee per gas
58
+ */
59
+ maxPriorityFeePerGas: bigint
60
+
61
+ /**
62
+ * EIP-1559: Max fee per gas
63
+ */
64
+ maxFeePerGas: bigint
65
+
66
+ /**
67
+ * Transaction type (2 = EIP-1559)
68
+ */
69
+ type: 2
70
+ }
71
+
72
+ /**
73
+ * Prepared stealth transfer bundle
74
+ */
75
+ export interface PreparedStealthTransfer {
76
+ /**
77
+ * ETH/token transfer transaction
78
+ */
79
+ transferTx: PreparedTransaction
80
+
81
+ /**
82
+ * Announcement transaction
83
+ */
84
+ announcementTx: PreparedTransaction
85
+
86
+ /**
87
+ * Stealth address receiving funds
88
+ */
89
+ stealthAddress: HexString
90
+
91
+ /**
92
+ * Ephemeral public key for recipient
93
+ */
94
+ ephemeralPublicKey: HexString
95
+
96
+ /**
97
+ * View tag for efficient scanning
98
+ */
99
+ viewTag: number
100
+
101
+ /**
102
+ * Amount commitment (if hiding amounts)
103
+ */
104
+ amountCommitment?: HexString
105
+
106
+ /**
107
+ * Blinding factor (if hiding amounts)
108
+ */
109
+ blindingFactor?: HexString
110
+
111
+ /**
112
+ * Gas estimate breakdown
113
+ */
114
+ gasEstimate: DetailedGasEstimate
115
+
116
+ /**
117
+ * Total cost estimate (gas + value)
118
+ */
119
+ totalCostWei: bigint
120
+ }
121
+
122
+ /**
123
+ * Transfer execution result
124
+ */
125
+ export interface TransferResult {
126
+ /**
127
+ * Transfer transaction hash
128
+ */
129
+ transferTxHash: HexString
130
+
131
+ /**
132
+ * Announcement transaction hash
133
+ */
134
+ announcementTxHash: HexString
135
+
136
+ /**
137
+ * Stealth address funds were sent to
138
+ */
139
+ stealthAddress: HexString
140
+
141
+ /**
142
+ * Amount transferred
143
+ */
144
+ amount: bigint
145
+
146
+ /**
147
+ * Token address (if ERC-20)
148
+ */
149
+ tokenAddress?: HexString
150
+
151
+ /**
152
+ * Ephemeral public key
153
+ */
154
+ ephemeralPublicKey: HexString
155
+
156
+ /**
157
+ * View tag
158
+ */
159
+ viewTag: number
160
+ }
161
+
162
+ /**
163
+ * Claim build result
164
+ */
165
+ export interface PreparedClaim {
166
+ /**
167
+ * Claim transaction
168
+ */
169
+ claimTx: PreparedTransaction
170
+
171
+ /**
172
+ * Stealth address to claim from
173
+ */
174
+ stealthAddress: HexString
175
+
176
+ /**
177
+ * Derived private key for stealth address
178
+ */
179
+ stealthPrivateKey: HexString
180
+
181
+ /**
182
+ * Destination address
183
+ */
184
+ destinationAddress: HexString
185
+
186
+ /**
187
+ * Amount being claimed
188
+ */
189
+ amount: bigint
190
+
191
+ /**
192
+ * Token address (if ERC-20)
193
+ */
194
+ tokenAddress?: HexString
195
+ }
196
+
197
+ // ─── Transfer Builder Class ──────────────────────────────────────────────────
198
+
199
+ /**
200
+ * Ethereum Stealth Transfer Builder
201
+ *
202
+ * Orchestrates the complete flow for privacy transfers:
203
+ * 1. Generate stealth address from recipient's meta-address
204
+ * 2. Build transfer and announcement transactions
205
+ * 3. Estimate gas and prepare for signing
206
+ * 4. Track submissions and confirmations
207
+ *
208
+ * @example Complete flow
209
+ * ```typescript
210
+ * const builder = new StealthTransferBuilder('mainnet', {
211
+ * rpcUrl: 'https://eth.llamarpc.com',
212
+ * })
213
+ *
214
+ * // Prepare transfer
215
+ * const prepared = await builder.prepareEthTransfer({
216
+ * from: senderAddress,
217
+ * recipient: recipientMetaAddress,
218
+ * amount: toWei(1), // 1 ETH
219
+ * })
220
+ *
221
+ * // Sign transactions (with your wallet)
222
+ * const signedTransfer = await wallet.signTransaction(prepared.transferTx)
223
+ * const signedAnnouncement = await wallet.signTransaction(prepared.announcementTx)
224
+ *
225
+ * // Submit
226
+ * const result = await builder.submitTransfer({
227
+ * signedTransferTx: signedTransfer,
228
+ * signedAnnouncementTx: signedAnnouncement,
229
+ * })
230
+ * ```
231
+ */
232
+ export class StealthTransferBuilder {
233
+ private adapter: EthereumPrivacyAdapter
234
+ private rpc: EthereumRpcClient
235
+ private network: EthereumNetwork
236
+ private chainId: number
237
+
238
+ constructor(
239
+ network: EthereumNetwork = 'mainnet',
240
+ options?: {
241
+ rpcUrl?: string
242
+ announcerAddress?: HexString
243
+ }
244
+ ) {
245
+ this.network = network
246
+ this.adapter = new EthereumPrivacyAdapter({
247
+ network,
248
+ announcerAddress: options?.announcerAddress,
249
+ })
250
+ this.rpc = new EthereumRpcClient(network, { rpcUrl: options?.rpcUrl })
251
+ this.chainId = this.rpc.getChainId()
252
+ }
253
+
254
+ // ─── ETH Transfer Methods ────────────────────────────────────────────────────
255
+
256
+ /**
257
+ * Prepare an ETH stealth transfer
258
+ *
259
+ * Generates stealth address, builds transactions, estimates gas.
260
+ *
261
+ * @param params - Transfer parameters
262
+ * @returns Prepared transactions ready for signing
263
+ */
264
+ async prepareEthTransfer(params: {
265
+ from: HexString
266
+ recipient: StealthMetaAddress | string
267
+ amount: bigint
268
+ memo?: string
269
+ }): Promise<PreparedStealthTransfer> {
270
+ // Build shielded transfer
271
+ const build = this.adapter.buildShieldedTransfer({
272
+ recipient: params.recipient,
273
+ amount: params.amount,
274
+ memo: params.memo,
275
+ })
276
+
277
+ // Get fee data and nonces
278
+ const [feeData, nonce] = await Promise.all([
279
+ this.rpc.getFeeData(),
280
+ this.rpc.getNextNonce(params.from),
281
+ ])
282
+
283
+ // Reserve nonces for both transactions
284
+ const transferNonce = nonce
285
+ const announcementNonce = nonce + 1
286
+
287
+ // Get gas estimate
288
+ const gasEstimate = estimateEthTransferGas(this.network)
289
+
290
+ // Prepare transfer transaction
291
+ const transferTx: PreparedTransaction = {
292
+ to: build.stealthEthAddress,
293
+ value: params.amount,
294
+ nonce: transferNonce,
295
+ gasLimit: gasEstimate.breakdown.transferGas,
296
+ chainId: this.chainId,
297
+ maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
298
+ maxFeePerGas: feeData.maxFeePerGas,
299
+ type: 2,
300
+ }
301
+
302
+ // Prepare announcement transaction
303
+ const announcementTx: PreparedTransaction = {
304
+ to: build.announcementTx.to,
305
+ value: 0n,
306
+ data: build.announcementTx.data,
307
+ nonce: announcementNonce,
308
+ gasLimit: gasEstimate.breakdown.announcementGas,
309
+ chainId: this.chainId,
310
+ maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
311
+ maxFeePerGas: feeData.maxFeePerGas,
312
+ type: 2,
313
+ }
314
+
315
+ // Calculate total cost
316
+ const totalGasCost = gasEstimate.estimatedCostWei
317
+ const totalCostWei = params.amount + totalGasCost
318
+
319
+ return {
320
+ transferTx,
321
+ announcementTx,
322
+ stealthAddress: build.stealthEthAddress,
323
+ ephemeralPublicKey: build.ephemeralPublicKey,
324
+ viewTag: build.viewTag,
325
+ amountCommitment: build.amountCommitment,
326
+ blindingFactor: build.blindingFactor,
327
+ gasEstimate,
328
+ totalCostWei,
329
+ }
330
+ }
331
+
332
+ // ─── Token Transfer Methods ──────────────────────────────────────────────────
333
+
334
+ /**
335
+ * Prepare an ERC-20 token stealth transfer
336
+ *
337
+ * @param params - Transfer parameters
338
+ * @returns Prepared transactions ready for signing
339
+ */
340
+ async prepareTokenTransfer(params: {
341
+ from: HexString
342
+ recipient: StealthMetaAddress | string
343
+ amount: bigint
344
+ tokenContract: HexString
345
+ decimals?: number
346
+ memo?: string
347
+ }): Promise<PreparedStealthTransfer & { tokenTransferData: HexString }> {
348
+ // Build shielded token transfer
349
+ const build = this.adapter.buildShieldedTokenTransfer({
350
+ recipient: params.recipient,
351
+ amount: params.amount,
352
+ tokenContract: params.tokenContract,
353
+ decimals: params.decimals,
354
+ memo: params.memo,
355
+ })
356
+
357
+ // Get fee data and nonces
358
+ const [feeData, nonce] = await Promise.all([
359
+ this.rpc.getFeeData(),
360
+ this.rpc.getNextNonce(params.from),
361
+ ])
362
+
363
+ // Reserve nonces
364
+ const transferNonce = nonce
365
+ const announcementNonce = nonce + 1
366
+
367
+ // Get gas estimate (without approval - caller handles that)
368
+ const gasEstimate = estimateTokenTransferGas(this.network, false)
369
+
370
+ // Prepare transfer transaction
371
+ const transferTx: PreparedTransaction = {
372
+ to: params.tokenContract,
373
+ value: 0n,
374
+ data: build.tokenTransferData,
375
+ nonce: transferNonce,
376
+ gasLimit: gasEstimate.breakdown.transferGas,
377
+ chainId: this.chainId,
378
+ maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
379
+ maxFeePerGas: feeData.maxFeePerGas,
380
+ type: 2,
381
+ }
382
+
383
+ // Prepare announcement transaction
384
+ const announcementTx: PreparedTransaction = {
385
+ to: build.announcementTx.to,
386
+ value: 0n,
387
+ data: build.announcementTx.data,
388
+ nonce: announcementNonce,
389
+ gasLimit: gasEstimate.breakdown.announcementGas,
390
+ chainId: this.chainId,
391
+ maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
392
+ maxFeePerGas: feeData.maxFeePerGas,
393
+ type: 2,
394
+ }
395
+
396
+ return {
397
+ transferTx,
398
+ announcementTx,
399
+ stealthAddress: build.stealthEthAddress,
400
+ ephemeralPublicKey: build.ephemeralPublicKey,
401
+ viewTag: build.viewTag,
402
+ amountCommitment: build.amountCommitment,
403
+ blindingFactor: build.blindingFactor,
404
+ gasEstimate,
405
+ totalCostWei: gasEstimate.estimatedCostWei,
406
+ tokenTransferData: build.tokenTransferData,
407
+ }
408
+ }
409
+
410
+ // ─── Submit Methods ──────────────────────────────────────────────────────────
411
+
412
+ /**
413
+ * Submit signed transfer transactions
414
+ *
415
+ * Submits both transfer and announcement, waits for confirmations.
416
+ *
417
+ * @param params - Signed transaction data
418
+ * @returns Submission result
419
+ */
420
+ async submitTransfer(params: {
421
+ signedTransferTx: HexString
422
+ signedAnnouncementTx: HexString
423
+ stealthAddress: HexString
424
+ ephemeralPublicKey: HexString
425
+ viewTag: number
426
+ amount: bigint
427
+ tokenAddress?: HexString
428
+ waitForConfirmation?: boolean
429
+ }): Promise<TransferResult> {
430
+ // Submit transfer first
431
+ const transferTxHash = await this.rpc.sendRawTransaction(params.signedTransferTx)
432
+
433
+ // Submit announcement
434
+ const announcementTxHash = await this.rpc.sendRawTransaction(params.signedAnnouncementTx)
435
+
436
+ // Optionally wait for confirmations
437
+ if (params.waitForConfirmation !== false) {
438
+ await Promise.all([
439
+ this.rpc.waitForTransaction(transferTxHash, 1),
440
+ this.rpc.waitForTransaction(announcementTxHash, 1),
441
+ ])
442
+ }
443
+
444
+ return {
445
+ transferTxHash,
446
+ announcementTxHash,
447
+ stealthAddress: params.stealthAddress,
448
+ amount: params.amount,
449
+ tokenAddress: params.tokenAddress,
450
+ ephemeralPublicKey: params.ephemeralPublicKey,
451
+ viewTag: params.viewTag,
452
+ }
453
+ }
454
+
455
+ // ─── Claim Methods ───────────────────────────────────────────────────────────
456
+
457
+ /**
458
+ * Prepare a claim transaction
459
+ *
460
+ * @param params - Claim parameters
461
+ * @returns Prepared claim transaction
462
+ */
463
+ async prepareClaim(params: {
464
+ stealthAddress: {
465
+ address: HexString
466
+ ephemeralPublicKey: HexString
467
+ viewTag: number
468
+ }
469
+ viewingPrivateKey: HexString
470
+ spendingPrivateKey: HexString
471
+ destinationAddress: HexString
472
+ amount: bigint
473
+ tokenContract?: HexString
474
+ }): Promise<PreparedClaim> {
475
+ // Build claim transaction
476
+ const build = this.adapter.buildClaimTransaction({
477
+ stealthAddress: params.stealthAddress,
478
+ ephemeralPublicKey: params.stealthAddress.ephemeralPublicKey,
479
+ viewingPrivateKey: params.viewingPrivateKey,
480
+ spendingPrivateKey: params.spendingPrivateKey,
481
+ destinationAddress: params.destinationAddress,
482
+ amount: params.amount,
483
+ tokenContract: params.tokenContract,
484
+ })
485
+
486
+ // Get fee data - note: we use the stealth address as "from"
487
+ const feeData = await this.rpc.getFeeData()
488
+
489
+ // For claims, nonce needs to be fetched for the stealth address
490
+ // But we can't know it without the RPC having the address funded
491
+ // We'll set nonce to 0 as stealth addresses typically have no prior txs
492
+ const nonce = 0
493
+
494
+ // Prepare claim transaction
495
+ const claimTx: PreparedTransaction = {
496
+ to: build.tx.to,
497
+ value: build.tx.value,
498
+ data: build.tx.data,
499
+ nonce,
500
+ gasLimit: build.estimatedGas,
501
+ chainId: this.chainId,
502
+ maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
503
+ maxFeePerGas: feeData.maxFeePerGas,
504
+ type: 2,
505
+ }
506
+
507
+ return {
508
+ claimTx,
509
+ stealthAddress: build.stealthEthAddress,
510
+ stealthPrivateKey: build.stealthPrivateKey,
511
+ destinationAddress: params.destinationAddress,
512
+ amount: params.amount,
513
+ tokenAddress: params.tokenContract,
514
+ }
515
+ }
516
+
517
+ /**
518
+ * Submit a signed claim transaction
519
+ *
520
+ * @param signedTx - Signed claim transaction
521
+ * @param waitForConfirmation - Whether to wait for confirmation
522
+ * @returns Transaction hash
523
+ */
524
+ async submitClaim(
525
+ signedTx: HexString,
526
+ waitForConfirmation: boolean = true
527
+ ): Promise<HexString> {
528
+ const txHash = await this.rpc.sendRawTransaction(signedTx)
529
+
530
+ if (waitForConfirmation) {
531
+ await this.rpc.waitForTransaction(txHash, 1)
532
+ }
533
+
534
+ return txHash
535
+ }
536
+
537
+ // ─── Balance Methods ─────────────────────────────────────────────────────────
538
+
539
+ /**
540
+ * Get ETH balance of an address
541
+ *
542
+ * @param address - Address to check
543
+ * @returns Balance in wei
544
+ */
545
+ async getBalance(address: HexString): Promise<bigint> {
546
+ return this.rpc.getBalance(address)
547
+ }
548
+
549
+ /**
550
+ * Check if sender has sufficient balance for transfer
551
+ *
552
+ * @param sender - Sender address
553
+ * @param amount - Amount to transfer
554
+ * @param isToken - Whether this is a token transfer
555
+ * @returns True if sufficient balance
556
+ */
557
+ async hasSufficientBalance(
558
+ sender: HexString,
559
+ amount: bigint,
560
+ isToken: boolean = false
561
+ ): Promise<{ sufficient: boolean; balance: bigint; required: bigint }> {
562
+ const balance = await this.rpc.getBalance(sender)
563
+
564
+ // For token transfers, only need gas
565
+ const gasEstimate = isToken
566
+ ? estimateTokenTransferGas(this.network)
567
+ : estimateEthTransferGas(this.network)
568
+
569
+ const required = isToken ? gasEstimate.estimatedCostWei : amount + gasEstimate.estimatedCostWei
570
+
571
+ return {
572
+ sufficient: balance >= required,
573
+ balance,
574
+ required,
575
+ }
576
+ }
577
+
578
+ // ─── Utility Methods ─────────────────────────────────────────────────────────
579
+
580
+ /**
581
+ * Get the privacy adapter
582
+ */
583
+ getAdapter(): EthereumPrivacyAdapter {
584
+ return this.adapter
585
+ }
586
+
587
+ /**
588
+ * Get the RPC client
589
+ */
590
+ getRpcClient(): EthereumRpcClient {
591
+ return this.rpc
592
+ }
593
+
594
+ /**
595
+ * Get network
596
+ */
597
+ getNetwork(): EthereumNetwork {
598
+ return this.network
599
+ }
600
+
601
+ /**
602
+ * Get chain ID
603
+ */
604
+ getChainId(): number {
605
+ return this.chainId
606
+ }
607
+ }
608
+
609
+ // ─── Factory Functions ────────────────────────────────────────────────────────
610
+
611
+ /**
612
+ * Create a stealth transfer builder
613
+ *
614
+ * @param network - Target network
615
+ * @param rpcUrl - Optional custom RPC URL
616
+ * @returns Transfer builder
617
+ */
618
+ export function createStealthTransferBuilder(
619
+ network: EthereumNetwork = 'mainnet',
620
+ rpcUrl?: string
621
+ ): StealthTransferBuilder {
622
+ return new StealthTransferBuilder(network, { rpcUrl })
623
+ }
624
+
625
+ /**
626
+ * Create a mainnet transfer builder
627
+ */
628
+ export function createMainnetTransferBuilder(rpcUrl?: string): StealthTransferBuilder {
629
+ return new StealthTransferBuilder('mainnet', { rpcUrl })
630
+ }
631
+
632
+ /**
633
+ * Create a Sepolia testnet transfer builder
634
+ */
635
+ export function createSepoliaTransferBuilder(rpcUrl?: string): StealthTransferBuilder {
636
+ return new StealthTransferBuilder('sepolia', { rpcUrl })
637
+ }