@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,420 @@
1
+ /**
2
+ * MetaMask Privacy Signing Utilities
3
+ *
4
+ * Provides MetaMask-specific helpers for privacy operations including
5
+ * EIP-712 signing, viewing key derivation, and transaction building.
6
+ *
7
+ * @module wallet/ethereum/metamask-privacy
8
+ */
9
+
10
+ import type { HexString } from '@sip-protocol/types'
11
+ import type { EIP712TypedData } from './types'
12
+ import { PrivacyEthereumWalletAdapter } from './privacy-adapter'
13
+
14
+ // ─── Types ──────────────────────────────────────────────────────────────────
15
+
16
+ /**
17
+ * MetaMask signing request types
18
+ */
19
+ export type MetaMaskSigningMethod =
20
+ | 'personal_sign'
21
+ | 'eth_signTypedData_v4'
22
+ | 'eth_sign'
23
+
24
+ /**
25
+ * Privacy operation types that require signing
26
+ */
27
+ export type PrivacyOperationType =
28
+ | 'key_derivation'
29
+ | 'stealth_transfer'
30
+ | 'token_approval'
31
+ | 'claim_funds'
32
+ | 'view_key_share'
33
+
34
+ /**
35
+ * Human-readable signing context for privacy operations
36
+ */
37
+ export interface PrivacySigningContext {
38
+ operation: PrivacyOperationType
39
+ description: string
40
+ warnings?: string[]
41
+ data?: Record<string, unknown>
42
+ }
43
+
44
+ /**
45
+ * MetaMask signing request with context
46
+ */
47
+ export interface MetaMaskSigningRequest {
48
+ method: MetaMaskSigningMethod
49
+ params: unknown[]
50
+ context: PrivacySigningContext
51
+ }
52
+
53
+ /**
54
+ * EIP-712 domain configuration for SIP Protocol
55
+ */
56
+ export interface SIPDomainConfig {
57
+ name: string
58
+ version: string
59
+ chainId: number
60
+ verifyingContract?: HexString
61
+ }
62
+
63
+ // ─── Constants ──────────────────────────────────────────────────────────────
64
+
65
+ /**
66
+ * Default SIP Protocol EIP-712 domain
67
+ */
68
+ export const DEFAULT_SIP_DOMAIN: Omit<SIPDomainConfig, 'chainId'> = {
69
+ name: 'SIP Protocol',
70
+ version: '1',
71
+ }
72
+
73
+ /**
74
+ * Privacy operation descriptions for user prompts
75
+ */
76
+ export const PRIVACY_OPERATION_DESCRIPTIONS: Record<PrivacyOperationType, string> = {
77
+ key_derivation: 'Generate privacy keys for stealth address operations',
78
+ stealth_transfer: 'Send funds to a private stealth address',
79
+ token_approval: 'Approve tokens for privacy transfer',
80
+ claim_funds: 'Claim funds from stealth address',
81
+ view_key_share: 'Share viewing key for compliance',
82
+ }
83
+
84
+ // ─── EIP-712 Type Definitions ───────────────────────────────────────────────
85
+
86
+ /**
87
+ * EIP-712 types for key derivation
88
+ */
89
+ export const KEY_DERIVATION_TYPES = {
90
+ EIP712Domain: [
91
+ { name: 'name', type: 'string' },
92
+ { name: 'version', type: 'string' },
93
+ { name: 'chainId', type: 'uint256' },
94
+ ],
95
+ KeyDerivation: [
96
+ { name: 'purpose', type: 'string' },
97
+ { name: 'domain', type: 'string' },
98
+ { name: 'address', type: 'address' },
99
+ { name: 'nonce', type: 'uint256' },
100
+ ],
101
+ } as const
102
+
103
+ /**
104
+ * EIP-712 types for stealth transfer authorization
105
+ */
106
+ export const STEALTH_TRANSFER_TYPES = {
107
+ EIP712Domain: [
108
+ { name: 'name', type: 'string' },
109
+ { name: 'version', type: 'string' },
110
+ { name: 'chainId', type: 'uint256' },
111
+ ],
112
+ StealthTransfer: [
113
+ { name: 'recipient', type: 'address' },
114
+ { name: 'amount', type: 'uint256' },
115
+ { name: 'token', type: 'address' },
116
+ { name: 'nonce', type: 'uint256' },
117
+ { name: 'deadline', type: 'uint256' },
118
+ ],
119
+ } as const
120
+
121
+ /**
122
+ * EIP-712 types for viewing key sharing
123
+ */
124
+ export const VIEW_KEY_SHARE_TYPES = {
125
+ EIP712Domain: [
126
+ { name: 'name', type: 'string' },
127
+ { name: 'version', type: 'string' },
128
+ { name: 'chainId', type: 'uint256' },
129
+ ],
130
+ ViewKeyShare: [
131
+ { name: 'auditor', type: 'address' },
132
+ { name: 'scope', type: 'string' },
133
+ { name: 'validFrom', type: 'uint256' },
134
+ { name: 'validUntil', type: 'uint256' },
135
+ ],
136
+ } as const
137
+
138
+ // ─── Message Building ───────────────────────────────────────────────────────
139
+
140
+ /**
141
+ * Build key derivation signing message
142
+ *
143
+ * This message is signed by the user to deterministically derive
144
+ * stealth keys. The same signature always produces the same keys.
145
+ *
146
+ * @param params - Derivation parameters
147
+ * @returns Human-readable message for signing
148
+ */
149
+ export function buildKeyDerivationMessage(params: {
150
+ domain: string
151
+ address: string
152
+ nonce?: number
153
+ }): string {
154
+ return [
155
+ 'SIP Protocol Key Derivation Request',
156
+ '',
157
+ `Domain: ${params.domain}`,
158
+ `Address: ${params.address}`,
159
+ `Nonce: ${params.nonce ?? 0}`,
160
+ '',
161
+ 'By signing this message, you authorize the generation of',
162
+ 'privacy keys for stealth address operations.',
163
+ '',
164
+ 'These keys will be derived deterministically from this signature.',
165
+ 'Use the same domain and nonce to recover the same keys.',
166
+ ].join('\n')
167
+ }
168
+
169
+ /**
170
+ * Build EIP-712 typed data for key derivation
171
+ *
172
+ * @param params - Derivation parameters
173
+ * @param chainId - Chain ID
174
+ * @returns EIP-712 typed data
175
+ */
176
+ export function buildKeyDerivationTypedData(
177
+ params: {
178
+ domain: string
179
+ address: HexString
180
+ nonce?: number
181
+ },
182
+ chainId: number
183
+ ): EIP712TypedData {
184
+ return {
185
+ domain: {
186
+ ...DEFAULT_SIP_DOMAIN,
187
+ chainId,
188
+ },
189
+ types: {
190
+ KeyDerivation: KEY_DERIVATION_TYPES.KeyDerivation as unknown as Array<{
191
+ name: string
192
+ type: string
193
+ }>,
194
+ },
195
+ primaryType: 'KeyDerivation',
196
+ message: {
197
+ purpose: 'SIP Protocol Stealth Key Derivation',
198
+ domain: params.domain,
199
+ address: params.address,
200
+ nonce: (params.nonce ?? 0).toString(),
201
+ },
202
+ }
203
+ }
204
+
205
+ /**
206
+ * Build viewing key share authorization
207
+ *
208
+ * Creates EIP-712 typed data for authorizing viewing key sharing
209
+ * with auditors or compliance services.
210
+ *
211
+ * @param params - Share parameters
212
+ * @param chainId - Chain ID
213
+ * @returns EIP-712 typed data
214
+ */
215
+ export function buildViewKeyShareTypedData(
216
+ params: {
217
+ auditor: HexString
218
+ scope: string
219
+ validFrom: number
220
+ validUntil: number
221
+ },
222
+ chainId: number
223
+ ): EIP712TypedData {
224
+ return {
225
+ domain: {
226
+ ...DEFAULT_SIP_DOMAIN,
227
+ chainId,
228
+ },
229
+ types: {
230
+ ViewKeyShare: VIEW_KEY_SHARE_TYPES.ViewKeyShare as unknown as Array<{
231
+ name: string
232
+ type: string
233
+ }>,
234
+ },
235
+ primaryType: 'ViewKeyShare',
236
+ message: {
237
+ auditor: params.auditor,
238
+ scope: params.scope,
239
+ validFrom: params.validFrom.toString(),
240
+ validUntil: params.validUntil.toString(),
241
+ },
242
+ }
243
+ }
244
+
245
+ // ─── MetaMask Detection ─────────────────────────────────────────────────────
246
+
247
+ /**
248
+ * Check if MetaMask is installed
249
+ *
250
+ * @returns True if MetaMask is detected
251
+ */
252
+ export function isMetaMaskInstalled(): boolean {
253
+ if (typeof window === 'undefined') return false
254
+ const ethereum = (window as unknown as { ethereum?: { isMetaMask?: boolean } }).ethereum
255
+ return !!ethereum?.isMetaMask
256
+ }
257
+
258
+ /**
259
+ * Check if MetaMask Flask is installed
260
+ *
261
+ * Flask is MetaMask's developer version with experimental features
262
+ * including Snaps support.
263
+ *
264
+ * @returns True if MetaMask Flask is detected
265
+ */
266
+ export function isMetaMaskFlaskInstalled(): boolean {
267
+ if (typeof window === 'undefined') return false
268
+ const ethereum = (window as unknown as {
269
+ ethereum?: { isMetaMask?: boolean; _metamask?: { isUnlocked?: () => Promise<boolean> } }
270
+ }).ethereum
271
+ // Flask has additional internal properties
272
+ return !!ethereum?.isMetaMask && !!ethereum?._metamask
273
+ }
274
+
275
+ /**
276
+ * Get MetaMask version info
277
+ *
278
+ * @returns Version string or undefined if not available
279
+ */
280
+ export async function getMetaMaskVersion(): Promise<string | undefined> {
281
+ if (!isMetaMaskInstalled()) return undefined
282
+
283
+ try {
284
+ const ethereum = (window as unknown as { ethereum: { request: (args: { method: string }) => Promise<string> } }).ethereum
285
+ const result = await ethereum.request({ method: 'web3_clientVersion' })
286
+ return result
287
+ } catch {
288
+ return undefined
289
+ }
290
+ }
291
+
292
+ // ─── Privacy Context Helpers ────────────────────────────────────────────────
293
+
294
+ /**
295
+ * Create signing context for privacy operation
296
+ *
297
+ * Provides user-friendly context for what they're signing.
298
+ *
299
+ * @param operation - Privacy operation type
300
+ * @param data - Additional context data
301
+ * @returns Signing context
302
+ */
303
+ export function createSigningContext(
304
+ operation: PrivacyOperationType,
305
+ data?: Record<string, unknown>
306
+ ): PrivacySigningContext {
307
+ const warnings: string[] = []
308
+
309
+ if (operation === 'key_derivation') {
310
+ warnings.push('Your privacy keys will be derived from this signature')
311
+ warnings.push('Save your derivation domain and nonce to recover keys later')
312
+ } else if (operation === 'view_key_share') {
313
+ warnings.push('The auditor will be able to see your transaction amounts')
314
+ warnings.push('They cannot spend your funds with just the viewing key')
315
+ } else if (operation === 'stealth_transfer') {
316
+ warnings.push('This transaction cannot be easily traced to your address')
317
+ }
318
+
319
+ return {
320
+ operation,
321
+ description: PRIVACY_OPERATION_DESCRIPTIONS[operation],
322
+ warnings,
323
+ data,
324
+ }
325
+ }
326
+
327
+ // ─── Adapter Helpers ────────────────────────────────────────────────────────
328
+
329
+ /**
330
+ * Create a MetaMask-configured privacy adapter
331
+ *
332
+ * @param options - Adapter options
333
+ * @returns Configured privacy adapter
334
+ */
335
+ export function createMetaMaskPrivacyAdapter(options: {
336
+ deriveFromWallet?: boolean
337
+ derivationDomain?: string
338
+ } = {}): PrivacyEthereumWalletAdapter {
339
+ if (!isMetaMaskInstalled()) {
340
+ throw new Error('MetaMask is not installed')
341
+ }
342
+
343
+ const ethereum = (window as unknown as { ethereum: unknown }).ethereum
344
+
345
+ return new PrivacyEthereumWalletAdapter({
346
+ wallet: 'metamask',
347
+ provider: ethereum as unknown as import('./types').EIP1193Provider,
348
+ deriveFromWallet: options.deriveFromWallet ?? true,
349
+ derivationDomain: options.derivationDomain ?? 'app.sip-protocol.org',
350
+ })
351
+ }
352
+
353
+ /**
354
+ * Check if wallet adapter is MetaMask
355
+ *
356
+ * @param adapter - Privacy adapter to check
357
+ * @returns True if adapter is using MetaMask
358
+ */
359
+ export function isMetaMaskAdapter(adapter: PrivacyEthereumWalletAdapter): boolean {
360
+ return adapter.name.includes('metamask')
361
+ }
362
+
363
+ // ─── Signature Verification ─────────────────────────────────────────────────
364
+
365
+ /**
366
+ * Extract V, R, S from signature
367
+ *
368
+ * MetaMask returns signatures in different formats depending on the method.
369
+ * This normalizes them to V, R, S components.
370
+ *
371
+ * @param signature - Raw signature hex string
372
+ * @returns Signature components
373
+ */
374
+ export function parseSignature(signature: HexString): {
375
+ v: number
376
+ r: HexString
377
+ s: HexString
378
+ } {
379
+ // Remove 0x prefix
380
+ const sig = signature.slice(2)
381
+
382
+ // Standard 65-byte signature: r (32 bytes) + s (32 bytes) + v (1 byte)
383
+ if (sig.length !== 130) {
384
+ throw new Error(`Invalid signature length: expected 130 hex chars, got ${sig.length}`)
385
+ }
386
+
387
+ const r = `0x${sig.slice(0, 64)}` as HexString
388
+ const s = `0x${sig.slice(64, 128)}` as HexString
389
+ let v = parseInt(sig.slice(128, 130), 16)
390
+
391
+ // EIP-155: v is 27 or 28 for legacy, or chainId*2 + 35/36 for replay protection
392
+ // MetaMask typically returns 27/28, normalize to 0/1 if needed
393
+ if (v === 0 || v === 1) {
394
+ v += 27
395
+ }
396
+
397
+ return { v, r, s }
398
+ }
399
+
400
+ /**
401
+ * Format signature to EIP-2098 compact format
402
+ *
403
+ * Reduces signature size from 65 to 64 bytes by encoding v in s.
404
+ *
405
+ * @param signature - Raw 65-byte signature
406
+ * @returns Compact 64-byte signature
407
+ */
408
+ export function toCompactSignature(signature: HexString): HexString {
409
+ const { v, r, s } = parseSignature(signature)
410
+
411
+ // In compact format, if v is 28, the highest bit of s is set
412
+ let sVal = BigInt(s)
413
+ if (v === 28) {
414
+ // Set bit 255 of s
415
+ sVal |= BigInt(1) << BigInt(255)
416
+ }
417
+
418
+ const sHex = sVal.toString(16).padStart(64, '0')
419
+ return `${r}${sHex}` as HexString
420
+ }