@sip-protocol/sdk 0.7.3 → 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 (264) 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 +47556 -19603
  7. package/dist/browser.mjs +628 -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-3M3HNQCW.mjs → chunk-YWGJ77A2.mjs} +28656 -13103
  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-DIBZHOOQ.d.ts → index-DXh2IGkz.d.ts} +21239 -10304
  24. package/dist/{index-8MQz13eJ.d.mts → index-DeE1ZzA4.d.mts} +21239 -10304
  25. package/dist/index.d.mts +9 -3
  26. package/dist/index.d.ts +9 -3
  27. package/dist/index.js +48396 -19623
  28. package/dist/index.mjs +537 -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 +252 -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 +47 -6
  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 +186 -33
  98. package/src/chains/solana/providers/index.ts +31 -0
  99. package/src/chains/solana/providers/interface.ts +61 -18
  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 +338 -67
  103. package/src/chains/solana/rpc-client.ts +1150 -0
  104. package/src/chains/solana/scan.ts +83 -66
  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 +57 -6
  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 +23 -0
  116. package/src/compliance/range-sas.ts +398 -33
  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 +686 -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 +254 -4
  143. package/src/privacy-backends/interface.ts +649 -6
  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.ts +13 -17
  148. package/src/privacy-backends/private-swap.ts +570 -0
  149. package/src/privacy-backends/rate-limiter.ts +683 -0
  150. package/src/privacy-backends/registry.ts +414 -2
  151. package/src/privacy-backends/router.ts +283 -3
  152. package/src/privacy-backends/shadowwire.ts +449 -0
  153. package/src/privacy-backends/sip-native.ts +3 -0
  154. package/src/privacy-logger.ts +191 -0
  155. package/src/production-safety.ts +373 -0
  156. package/src/proofs/aggregator.ts +1029 -0
  157. package/src/proofs/browser-composer.ts +1150 -0
  158. package/src/proofs/browser.ts +113 -25
  159. package/src/proofs/cache/index.ts +127 -0
  160. package/src/proofs/cache/interface.ts +545 -0
  161. package/src/proofs/cache/key-generator.ts +188 -0
  162. package/src/proofs/cache/lru-cache.ts +481 -0
  163. package/src/proofs/cache/multi-tier-cache.ts +575 -0
  164. package/src/proofs/cache/persistent-cache.ts +788 -0
  165. package/src/proofs/compliance-proof.ts +872 -0
  166. package/src/proofs/composer/base.ts +923 -0
  167. package/src/proofs/composer/index.ts +25 -0
  168. package/src/proofs/composer/interface.ts +518 -0
  169. package/src/proofs/composer/types.ts +383 -0
  170. package/src/proofs/converters/halo2.ts +452 -0
  171. package/src/proofs/converters/index.ts +208 -0
  172. package/src/proofs/converters/interface.ts +363 -0
  173. package/src/proofs/converters/kimchi.ts +462 -0
  174. package/src/proofs/converters/noir.ts +451 -0
  175. package/src/proofs/fallback.ts +888 -0
  176. package/src/proofs/halo2.ts +42 -0
  177. package/src/proofs/index.ts +471 -0
  178. package/src/proofs/interface.ts +13 -0
  179. package/src/proofs/kimchi.ts +42 -0
  180. package/src/proofs/lazy.ts +1004 -0
  181. package/src/proofs/mock.ts +25 -1
  182. package/src/proofs/noir.ts +110 -29
  183. package/src/proofs/orchestrator.ts +960 -0
  184. package/src/proofs/parallel/concurrency.ts +297 -0
  185. package/src/proofs/parallel/dependency-graph.ts +602 -0
  186. package/src/proofs/parallel/executor.ts +420 -0
  187. package/src/proofs/parallel/index.ts +131 -0
  188. package/src/proofs/parallel/interface.ts +685 -0
  189. package/src/proofs/parallel/worker-pool.ts +644 -0
  190. package/src/proofs/providers/halo2.ts +560 -0
  191. package/src/proofs/providers/index.ts +34 -0
  192. package/src/proofs/providers/kimchi.ts +641 -0
  193. package/src/proofs/validator.ts +881 -0
  194. package/src/proofs/verifier.ts +867 -0
  195. package/src/quantum/index.ts +112 -0
  196. package/src/quantum/winternitz-vault.ts +639 -0
  197. package/src/quantum/wots.ts +611 -0
  198. package/src/settlement/backends/direct-chain.ts +1 -0
  199. package/src/settlement/index.ts +9 -0
  200. package/src/settlement/router.ts +732 -46
  201. package/src/solana/index.ts +72 -0
  202. package/src/solana/jito-relayer.ts +687 -0
  203. package/src/solana/noir-verifier-types.ts +430 -0
  204. package/src/solana/noir-verifier.ts +816 -0
  205. package/src/stealth/address-derivation.ts +193 -0
  206. package/src/stealth/ed25519.ts +431 -0
  207. package/src/stealth/index.ts +233 -0
  208. package/src/stealth/meta-address.ts +221 -0
  209. package/src/stealth/secp256k1.ts +368 -0
  210. package/src/stealth/utils.ts +194 -0
  211. package/src/stealth.ts +50 -1504
  212. package/src/sync/index.ts +106 -0
  213. package/src/sync/manager.ts +504 -0
  214. package/src/sync/mock-provider.ts +318 -0
  215. package/src/sync/oblivious.ts +625 -0
  216. package/src/tokens/index.ts +15 -0
  217. package/src/tokens/registry.ts +301 -0
  218. package/src/utils/deprecation.ts +94 -0
  219. package/src/utils/index.ts +9 -0
  220. package/src/wallet/ethereum/index.ts +68 -0
  221. package/src/wallet/ethereum/metamask-privacy.ts +420 -0
  222. package/src/wallet/ethereum/multi-wallet.ts +646 -0
  223. package/src/wallet/ethereum/privacy-adapter.ts +700 -0
  224. package/src/wallet/ethereum/types.ts +3 -1
  225. package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
  226. package/src/wallet/hardware/index.ts +10 -0
  227. package/src/wallet/hardware/ledger-privacy.ts +414 -0
  228. package/src/wallet/index.ts +71 -0
  229. package/src/wallet/near/adapter.ts +626 -0
  230. package/src/wallet/near/index.ts +86 -0
  231. package/src/wallet/near/meteor-wallet.ts +1153 -0
  232. package/src/wallet/near/my-near-wallet.ts +790 -0
  233. package/src/wallet/near/wallet-selector.ts +702 -0
  234. package/src/wallet/solana/adapter.ts +6 -4
  235. package/src/wallet/solana/index.ts +13 -0
  236. package/src/wallet/solana/privacy-adapter.ts +567 -0
  237. package/src/wallet/sui/types.ts +6 -4
  238. package/src/zcash/rpc-client.ts +13 -6
  239. package/dist/chunk-2XIVXWHA.mjs +0 -1930
  240. package/dist/chunk-3INS3PR5.mjs +0 -884
  241. package/dist/chunk-3OVABDRH.mjs +0 -17096
  242. package/dist/chunk-7RFRWDCW.mjs +0 -1504
  243. package/dist/chunk-DLDWZFYC.mjs +0 -1495
  244. package/dist/chunk-E6SZWREQ.mjs +0 -57
  245. package/dist/chunk-F6F73W35.mjs +0 -16166
  246. package/dist/chunk-G33LB27A.mjs +0 -16166
  247. package/dist/chunk-HGU6HZRC.mjs +0 -231
  248. package/dist/chunk-L2K34JCU.mjs +0 -1496
  249. package/dist/chunk-OFDBEIEK.mjs +0 -16166
  250. package/dist/chunk-SF7YSLF5.mjs +0 -1515
  251. package/dist/chunk-SN4ZDTVW.mjs +0 -16166
  252. package/dist/chunk-WWUSGOXE.mjs +0 -17129
  253. package/dist/constants-VOI7BSLK.mjs +0 -27
  254. package/dist/index-B71aXVzk.d.ts +0 -13264
  255. package/dist/index-BYZbDjal.d.ts +0 -11390
  256. package/dist/index-CHB3KuOB.d.mts +0 -11859
  257. package/dist/index-CzWPI6Le.d.ts +0 -11859
  258. package/dist/index-pOIIuwfV.d.mts +0 -13264
  259. package/dist/index-xbWjohNq.d.mts +0 -11390
  260. package/dist/solana-4O4K45VU.mjs +0 -46
  261. package/dist/solana-5EMCTPTS.mjs +0 -46
  262. package/dist/solana-NDABAZ6P.mjs +0 -56
  263. package/dist/solana-Q4NAVBTS.mjs +0 -46
  264. package/dist/solana-ZYO63LY5.mjs +0 -46
@@ -0,0 +1,653 @@
1
+ /**
2
+ * Privacy Advisor Agent
3
+ *
4
+ * LangChain-powered AI agent that analyzes wallet privacy and provides
5
+ * intelligent, contextual recommendations in plain English.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+
10
+ import { ChatOpenAI } from '@langchain/openai'
11
+ import { HumanMessage, SystemMessage, AIMessage } from '@langchain/core/messages'
12
+ import { StringOutputParser } from '@langchain/core/output_parsers'
13
+ import { z } from 'zod'
14
+
15
+ import type {
16
+ PrivacyAdvisorConfig,
17
+ AdvisoryContext,
18
+ AdvisorResponse,
19
+ PrivacyAdvisoryReport,
20
+ AdvisorRecommendation,
21
+ AdvisorMessage,
22
+ StreamCallback,
23
+ } from './types'
24
+ import type { FullAnalysisResult, RiskLevel } from '../surveillance/types'
25
+
26
+ /**
27
+ * System prompt for the Privacy Advisor Agent
28
+ */
29
+ const SYSTEM_PROMPT = `You are a Privacy Advisor for SIP Protocol, the privacy standard for Web3. Your role is to help users understand their wallet's privacy exposure and provide actionable recommendations.
30
+
31
+ ## Your Principles:
32
+ 1. **Clarity**: Explain complex privacy concepts in plain English
33
+ 2. **Actionability**: Every recommendation should have clear, step-by-step actions
34
+ 3. **Prioritization**: Focus on highest-impact improvements first
35
+ 4. **Education**: Help users understand WHY something matters, not just WHAT to do
36
+ 5. **Honesty**: Be direct about risks without causing unnecessary alarm
37
+
38
+ ## Privacy Score Categories (100 points total):
39
+ - Address Reuse (0-25 points): Reusing addresses links your transactions
40
+ - Cluster Exposure (0-25 points): Common-input heuristic can link your wallets
41
+ - Exchange Exposure (0-20 points): CEX interactions create KYC-linked records
42
+ - Temporal Patterns (0-15 points): Regular timing reveals timezone/habits
43
+ - Social Links (0-15 points): ENS/SNS domains link identity to wallet
44
+
45
+ ## Risk Levels:
46
+ - Critical (0-25): Severe privacy exposure, immediate action needed
47
+ - High (26-50): Significant risks, prioritize improvements
48
+ - Medium (51-75): Moderate exposure, room for improvement
49
+ - Low (76-100): Good privacy hygiene, maintain practices
50
+
51
+ ## SIP Protocol Benefits:
52
+ - Stealth Addresses: One-time addresses prevent transaction linking
53
+ - Pedersen Commitments: Hide transaction amounts cryptographically
54
+ - Viewing Keys: Selective disclosure for compliance without sacrificing privacy
55
+
56
+ ## Response Guidelines:
57
+ - Use bullet points and numbered lists for clarity
58
+ - Include specific, actionable steps
59
+ - Estimate time/difficulty for each recommendation
60
+ - Highlight what SIP Protocol can automate
61
+ - Suggest 2-3 follow-up questions to explore further`
62
+
63
+ /**
64
+ * Schema for structured report generation
65
+ */
66
+ const ReportSchema = z.object({
67
+ summary: z.string().describe('2-3 sentence executive summary'),
68
+ recommendations: z.array(z.object({
69
+ id: z.string(),
70
+ priority: z.number().min(1).max(10),
71
+ title: z.string(),
72
+ explanation: z.string(),
73
+ actions: z.array(z.string()),
74
+ expectedImprovement: z.number(),
75
+ difficulty: z.enum(['easy', 'medium', 'hard']),
76
+ estimatedTime: z.string(),
77
+ canAutomate: z.boolean(),
78
+ })),
79
+ keyRisks: z.array(z.object({
80
+ category: z.string(),
81
+ description: z.string(),
82
+ severity: z.enum(['critical', 'high', 'medium', 'low']),
83
+ })),
84
+ })
85
+
86
+ /**
87
+ * PrivacyAdvisorAgent - AI-powered privacy recommendations
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * import { PrivacyAdvisorAgent, createSurveillanceAnalyzer } from '@sip-protocol/sdk'
92
+ *
93
+ * const analyzer = createSurveillanceAnalyzer({
94
+ * heliusApiKey: process.env.HELIUS_API_KEY!,
95
+ * })
96
+ *
97
+ * const advisor = new PrivacyAdvisorAgent({
98
+ * openaiApiKey: process.env.OPENAI_API_KEY!,
99
+ * })
100
+ *
101
+ * const analysis = await analyzer.analyze('7xK9...')
102
+ * const response = await advisor.analyze({
103
+ * analysisResult: analysis,
104
+ * userQuery: 'What should I do first to improve my privacy?',
105
+ * })
106
+ *
107
+ * console.log(response.message)
108
+ * console.log(response.report?.recommendations)
109
+ * ```
110
+ */
111
+ export class PrivacyAdvisorAgent {
112
+ private model: ChatOpenAI
113
+ private config: Required<PrivacyAdvisorConfig>
114
+ private conversationHistory: AdvisorMessage[] = []
115
+
116
+ constructor(config: PrivacyAdvisorConfig) {
117
+ if (!config.openaiApiKey) {
118
+ throw new Error(
119
+ 'OpenAI API key is required. Get one at https://platform.openai.com'
120
+ )
121
+ }
122
+
123
+ this.config = {
124
+ openaiApiKey: config.openaiApiKey,
125
+ model: config.model ?? 'gpt-4o-mini',
126
+ temperature: config.temperature ?? 0.3,
127
+ maxTokens: config.maxTokens ?? 1024,
128
+ verbose: config.verbose ?? false,
129
+ }
130
+
131
+ this.model = new ChatOpenAI({
132
+ openAIApiKey: this.config.openaiApiKey,
133
+ modelName: this.config.model,
134
+ temperature: this.config.temperature,
135
+ maxTokens: this.config.maxTokens,
136
+ })
137
+ }
138
+
139
+ /**
140
+ * Analyze wallet privacy and generate recommendations
141
+ *
142
+ * @param context - Analysis context including surveillance results
143
+ * @returns Advisor response with message and optional report
144
+ */
145
+ async analyze(context: AdvisoryContext): Promise<AdvisorResponse> {
146
+ const { analysisResult, userQuery, preferences } = context
147
+
148
+ // Build the analysis prompt
149
+ const analysisPrompt = this.buildAnalysisPrompt(analysisResult, preferences)
150
+
151
+ // Prepare messages
152
+ const messages = [
153
+ new SystemMessage(SYSTEM_PROMPT),
154
+ new HumanMessage(analysisPrompt),
155
+ ]
156
+
157
+ // Add conversation history if present
158
+ if (context.conversationHistory) {
159
+ for (const msg of context.conversationHistory) {
160
+ if (msg.role === 'user') {
161
+ messages.push(new HumanMessage(msg.content))
162
+ } else if (msg.role === 'assistant') {
163
+ messages.push(new AIMessage(msg.content))
164
+ }
165
+ }
166
+ }
167
+
168
+ // Add user query if present
169
+ if (userQuery) {
170
+ messages.push(new HumanMessage(userQuery))
171
+ } else {
172
+ messages.push(new HumanMessage(
173
+ 'Please analyze this wallet and provide a comprehensive privacy report with prioritized recommendations.'
174
+ ))
175
+ }
176
+
177
+ // Generate response
178
+ const response = await this.model.invoke(messages)
179
+ const parser = new StringOutputParser()
180
+ const content = await parser.invoke(response)
181
+
182
+ // Track usage
183
+ const usage = response.usage_metadata ? {
184
+ promptTokens: response.usage_metadata.input_tokens,
185
+ completionTokens: response.usage_metadata.output_tokens,
186
+ totalTokens: response.usage_metadata.total_tokens,
187
+ estimatedCost: this.estimateCost(
188
+ response.usage_metadata.input_tokens,
189
+ response.usage_metadata.output_tokens
190
+ ),
191
+ } : undefined
192
+
193
+ // Generate structured report
194
+ const report = this.generateReport(analysisResult, content)
195
+
196
+ // Generate suggested follow-up questions
197
+ const suggestedQuestions = this.generateSuggestedQuestions(analysisResult)
198
+
199
+ // Update conversation history
200
+ this.conversationHistory.push(
201
+ { role: 'user', content: userQuery || 'Analyze my wallet privacy', timestamp: Date.now() },
202
+ { role: 'assistant', content, timestamp: Date.now() }
203
+ )
204
+
205
+ return {
206
+ message: content,
207
+ report,
208
+ suggestedQuestions,
209
+ usage,
210
+ }
211
+ }
212
+
213
+ /**
214
+ * Chat with the advisor about privacy (follow-up questions)
215
+ *
216
+ * @param message - User message
217
+ * @param context - Optional analysis context for new analysis
218
+ * @returns Advisor response
219
+ */
220
+ async chat(message: string, context?: AdvisoryContext): Promise<AdvisorResponse> {
221
+ const messages = [new SystemMessage(SYSTEM_PROMPT)]
222
+
223
+ // Add analysis context if provided
224
+ if (context?.analysisResult) {
225
+ const analysisPrompt = this.buildAnalysisPrompt(
226
+ context.analysisResult,
227
+ context.preferences
228
+ )
229
+ messages.push(new HumanMessage(analysisPrompt))
230
+ messages.push(new AIMessage('I\'ve analyzed the wallet data. What would you like to know?'))
231
+ }
232
+
233
+ // Add conversation history
234
+ for (const msg of this.conversationHistory) {
235
+ if (msg.role === 'user') {
236
+ messages.push(new HumanMessage(msg.content))
237
+ } else if (msg.role === 'assistant') {
238
+ messages.push(new AIMessage(msg.content))
239
+ }
240
+ }
241
+
242
+ // Add current message
243
+ messages.push(new HumanMessage(message))
244
+
245
+ // Generate response
246
+ const response = await this.model.invoke(messages)
247
+ const parser = new StringOutputParser()
248
+ const content = await parser.invoke(response)
249
+
250
+ // Track usage
251
+ const usage = response.usage_metadata ? {
252
+ promptTokens: response.usage_metadata.input_tokens,
253
+ completionTokens: response.usage_metadata.output_tokens,
254
+ totalTokens: response.usage_metadata.total_tokens,
255
+ estimatedCost: this.estimateCost(
256
+ response.usage_metadata.input_tokens,
257
+ response.usage_metadata.output_tokens
258
+ ),
259
+ } : undefined
260
+
261
+ // Update conversation history
262
+ this.conversationHistory.push(
263
+ { role: 'user', content: message, timestamp: Date.now() },
264
+ { role: 'assistant', content, timestamp: Date.now() }
265
+ )
266
+
267
+ return {
268
+ message: content,
269
+ usage,
270
+ }
271
+ }
272
+
273
+ /**
274
+ * Stream a response for real-time UI updates
275
+ *
276
+ * @param context - Analysis context
277
+ * @param onChunk - Callback for each streamed chunk
278
+ * @returns Final advisor response
279
+ */
280
+ async stream(
281
+ context: AdvisoryContext,
282
+ onChunk: StreamCallback
283
+ ): Promise<AdvisorResponse> {
284
+ const { analysisResult, userQuery, preferences } = context
285
+
286
+ // Build the analysis prompt
287
+ const analysisPrompt = this.buildAnalysisPrompt(analysisResult, preferences)
288
+
289
+ // Prepare messages
290
+ const messages = [
291
+ new SystemMessage(SYSTEM_PROMPT),
292
+ new HumanMessage(analysisPrompt),
293
+ ]
294
+
295
+ if (userQuery) {
296
+ messages.push(new HumanMessage(userQuery))
297
+ } else {
298
+ messages.push(new HumanMessage(
299
+ 'Please analyze this wallet and provide a comprehensive privacy report with prioritized recommendations.'
300
+ ))
301
+ }
302
+
303
+ // Stream response
304
+ let fullContent = ''
305
+ const stream = await this.model.stream(messages)
306
+
307
+ for await (const chunk of stream) {
308
+ const text = typeof chunk.content === 'string' ? chunk.content : ''
309
+ fullContent += text
310
+ onChunk(text)
311
+ }
312
+
313
+ // Generate report from full content
314
+ const report = this.generateReport(analysisResult, fullContent)
315
+ const suggestedQuestions = this.generateSuggestedQuestions(analysisResult)
316
+
317
+ // Update conversation history
318
+ this.conversationHistory.push(
319
+ { role: 'user', content: userQuery || 'Analyze my wallet privacy', timestamp: Date.now() },
320
+ { role: 'assistant', content: fullContent, timestamp: Date.now() }
321
+ )
322
+
323
+ return {
324
+ message: fullContent,
325
+ report,
326
+ suggestedQuestions,
327
+ }
328
+ }
329
+
330
+ /**
331
+ * Clear conversation history
332
+ */
333
+ clearHistory(): void {
334
+ this.conversationHistory = []
335
+ }
336
+
337
+ /**
338
+ * Get conversation history
339
+ */
340
+ getHistory(): AdvisorMessage[] {
341
+ return [...this.conversationHistory]
342
+ }
343
+
344
+ /**
345
+ * Build analysis prompt from surveillance data
346
+ */
347
+ private buildAnalysisPrompt(
348
+ result: FullAnalysisResult,
349
+ preferences?: AdvisoryContext['preferences']
350
+ ): string {
351
+ const { privacyScore, addressReuse, cluster, exchangeExposure, temporalPatterns, socialLinks, sipComparison } = result
352
+
353
+ let prompt = `## Wallet Privacy Analysis Data
354
+
355
+ **Wallet**: ${privacyScore.walletAddress}
356
+ **Overall Score**: ${privacyScore.overall}/100
357
+ **Risk Level**: ${privacyScore.risk.toUpperCase()}
358
+ **Transactions Analyzed**: ${result.transactionCount}
359
+
360
+ ### Score Breakdown:
361
+ - Address Reuse: ${privacyScore.breakdown.addressReuse}/25 points
362
+ - Cluster Exposure: ${privacyScore.breakdown.clusterExposure}/25 points
363
+ - Exchange Exposure: ${privacyScore.breakdown.exchangeExposure}/20 points
364
+ - Temporal Patterns: ${privacyScore.breakdown.temporalPatterns}/15 points
365
+ - Social Links: ${privacyScore.breakdown.socialLinks}/15 points
366
+
367
+ ### Detailed Findings:
368
+
369
+ **Address Reuse**:
370
+ - Receive reuse count: ${addressReuse.receiveReuseCount}
371
+ - Send reuse count: ${addressReuse.sendReuseCount}
372
+ - Total reuse: ${addressReuse.totalReuseCount}
373
+ - Score deduction: -${addressReuse.scoreDeduction} points
374
+
375
+ **Cluster Detection (CIOH)**:
376
+ - Linked addresses found: ${cluster.linkedAddressCount}
377
+ - Confidence: ${(cluster.confidence * 100).toFixed(0)}%
378
+ - Clusters detected: ${cluster.clusters.length}
379
+ - Score deduction: -${cluster.scoreDeduction} points
380
+
381
+ **Exchange Exposure**:
382
+ - Exchanges interacted: ${exchangeExposure.exchangeCount}
383
+ - Total deposits: ${exchangeExposure.depositCount}
384
+ - Total withdrawals: ${exchangeExposure.withdrawalCount}
385
+ - Score deduction: -${exchangeExposure.scoreDeduction} points
386
+ ${exchangeExposure.exchanges.length > 0 ? `- Exchanges: ${exchangeExposure.exchanges.map(e => `${e.name} (${e.type}, KYC: ${e.kycRequired})`).join(', ')}` : ''}
387
+
388
+ **Temporal Patterns**:
389
+ - Patterns detected: ${temporalPatterns.patterns.length}
390
+ ${temporalPatterns.inferredTimezone ? `- Inferred timezone: ${temporalPatterns.inferredTimezone}` : ''}
391
+ - Score deduction: -${temporalPatterns.scoreDeduction} points
392
+
393
+ **Social Links**:
394
+ - Is doxxed: ${socialLinks.isDoxxed ? 'YES' : 'No'}
395
+ - Partial exposure: ${socialLinks.partialExposure ? 'Yes' : 'No'}
396
+ - Links found: ${socialLinks.links.length}
397
+ - Score deduction: -${socialLinks.scoreDeduction} points
398
+
399
+ ### SIP Protocol Projection:
400
+ - Current score: ${sipComparison.currentScore}/100
401
+ - Projected with SIP: ${sipComparison.projectedScore}/100
402
+ - Potential improvement: +${sipComparison.improvement} points`
403
+
404
+ // Add user preferences if specified
405
+ if (preferences) {
406
+ prompt += '\n\n### User Preferences:'
407
+ if (preferences.preferAutomation) {
408
+ prompt += '\n- Prefers automated solutions over manual steps'
409
+ }
410
+ if (preferences.technicalLevel) {
411
+ prompt += `\n- Technical level: ${preferences.technicalLevel}`
412
+ }
413
+ if (preferences.focusAreas?.length) {
414
+ prompt += `\n- Focus areas: ${preferences.focusAreas.join(', ')}`
415
+ }
416
+ }
417
+
418
+ return prompt
419
+ }
420
+
421
+ /**
422
+ * Generate structured report from analysis and LLM response
423
+ */
424
+ private generateReport(
425
+ result: FullAnalysisResult,
426
+ llmResponse: string
427
+ ): PrivacyAdvisoryReport {
428
+ const { privacyScore, sipComparison } = result
429
+
430
+ // Extract recommendations from existing privacy score
431
+ const recommendations: AdvisorRecommendation[] = privacyScore.recommendations
432
+ .slice(0, 5)
433
+ .map((rec, index) => ({
434
+ id: rec.id,
435
+ priority: index + 1,
436
+ title: rec.title,
437
+ explanation: rec.description,
438
+ actions: [rec.action],
439
+ expectedImprovement: rec.potentialGain,
440
+ difficulty: this.mapSeverityToDifficulty(rec.severity),
441
+ estimatedTime: this.estimateTime(rec.category),
442
+ canAutomate: this.canAutomate(rec.category),
443
+ }))
444
+
445
+ // Extract key risks
446
+ const keyRisks = this.extractKeyRisks(result)
447
+
448
+ // Generate summary from LLM response (first 2-3 sentences)
449
+ const summaryMatch = llmResponse.match(/^(.+?\..*?\..*?\.)/s)
450
+ const summary = summaryMatch
451
+ ? summaryMatch[1].replace(/\n/g, ' ').trim()
452
+ : `Your wallet has a privacy score of ${privacyScore.overall}/100 (${privacyScore.risk} risk). ${
453
+ privacyScore.recommendations[0]
454
+ ? `Top priority: ${privacyScore.recommendations[0].title}.`
455
+ : 'Review the recommendations below to improve your privacy.'
456
+ }`
457
+
458
+ return {
459
+ walletAddress: privacyScore.walletAddress,
460
+ currentScore: privacyScore.overall,
461
+ riskLevel: privacyScore.risk,
462
+ summary,
463
+ recommendations,
464
+ keyRisks,
465
+ sipBenefits: {
466
+ projectedScore: sipComparison.projectedScore,
467
+ improvement: sipComparison.improvement,
468
+ features: [
469
+ 'Stealth addresses for unlinkable transactions',
470
+ 'Pedersen commitments for hidden amounts',
471
+ 'Viewing keys for selective compliance disclosure',
472
+ ],
473
+ },
474
+ generatedAt: Date.now(),
475
+ }
476
+ }
477
+
478
+ /**
479
+ * Extract key risks from analysis
480
+ */
481
+ private extractKeyRisks(result: FullAnalysisResult): PrivacyAdvisoryReport['keyRisks'] {
482
+ const risks: PrivacyAdvisoryReport['keyRisks'] = []
483
+
484
+ if (result.addressReuse.scoreDeduction > 10) {
485
+ risks.push({
486
+ category: 'Address Reuse',
487
+ description: `Found ${result.addressReuse.totalReuseCount} instances of address reuse, allowing observers to link your transactions together.`,
488
+ severity: result.addressReuse.scoreDeduction > 20 ? 'critical' : 'high',
489
+ })
490
+ }
491
+
492
+ if (result.cluster.linkedAddressCount > 0) {
493
+ risks.push({
494
+ category: 'Wallet Clustering',
495
+ description: `${result.cluster.linkedAddressCount} addresses are linked to your wallet through common-input heuristics.`,
496
+ severity: result.cluster.scoreDeduction > 15 ? 'high' : 'medium',
497
+ })
498
+ }
499
+
500
+ if (result.exchangeExposure.exchangeCount > 0) {
501
+ const kycExchanges = result.exchangeExposure.exchanges.filter(e => e.kycRequired)
502
+ if (kycExchanges.length > 0) {
503
+ risks.push({
504
+ category: 'Exchange Exposure',
505
+ description: `Interacted with ${kycExchanges.length} KYC-required exchange(s), creating a link between your identity and on-chain activity.`,
506
+ severity: kycExchanges.length > 2 ? 'high' : 'medium',
507
+ })
508
+ }
509
+ }
510
+
511
+ if (result.socialLinks.isDoxxed) {
512
+ risks.push({
513
+ category: 'Identity Exposure',
514
+ description: 'Your wallet is publicly linked to your identity through social profiles or naming services.',
515
+ severity: 'critical',
516
+ })
517
+ }
518
+
519
+ if (result.temporalPatterns.patterns.length > 0) {
520
+ risks.push({
521
+ category: 'Behavioral Patterns',
522
+ description: `Detected ${result.temporalPatterns.patterns.length} timing pattern(s) that could reveal your timezone or habits.`,
523
+ severity: 'low',
524
+ })
525
+ }
526
+
527
+ return risks
528
+ }
529
+
530
+ /**
531
+ * Generate suggested follow-up questions
532
+ */
533
+ private generateSuggestedQuestions(result: FullAnalysisResult): string[] {
534
+ const questions: string[] = []
535
+
536
+ if (result.privacyScore.overall < 50) {
537
+ questions.push('What\'s the single most impactful thing I can do right now?')
538
+ }
539
+
540
+ if (result.exchangeExposure.exchangeCount > 0) {
541
+ questions.push('How can I reduce my exchange exposure going forward?')
542
+ }
543
+
544
+ if (result.addressReuse.totalReuseCount > 5) {
545
+ questions.push('How do stealth addresses prevent address reuse?')
546
+ }
547
+
548
+ questions.push('How would using SIP Protocol improve my privacy?')
549
+ questions.push('What privacy practices should I adopt for the future?')
550
+
551
+ return questions.slice(0, 3)
552
+ }
553
+
554
+ /**
555
+ * Map severity to difficulty
556
+ */
557
+ private mapSeverityToDifficulty(severity: RiskLevel): 'easy' | 'medium' | 'hard' {
558
+ switch (severity) {
559
+ case 'critical':
560
+ case 'high':
561
+ return 'medium'
562
+ case 'medium':
563
+ return 'easy'
564
+ case 'low':
565
+ return 'easy'
566
+ default:
567
+ return 'medium'
568
+ }
569
+ }
570
+
571
+ /**
572
+ * Estimate time to implement recommendation
573
+ */
574
+ private estimateTime(category: string): string {
575
+ switch (category) {
576
+ case 'addressReuse':
577
+ return '5-10 minutes'
578
+ case 'clusterExposure':
579
+ return '15-30 minutes'
580
+ case 'exchangeExposure':
581
+ return '1-2 hours'
582
+ case 'temporalPatterns':
583
+ return 'Ongoing practice'
584
+ case 'socialLinks':
585
+ return '30-60 minutes'
586
+ default:
587
+ return '10-20 minutes'
588
+ }
589
+ }
590
+
591
+ /**
592
+ * Check if SIP can automate this recommendation
593
+ */
594
+ private canAutomate(category: string): boolean {
595
+ switch (category) {
596
+ case 'addressReuse':
597
+ return true // Stealth addresses
598
+ case 'clusterExposure':
599
+ return true // Stealth addresses prevent clustering
600
+ case 'exchangeExposure':
601
+ return false // User behavior
602
+ case 'temporalPatterns':
603
+ return false // User behavior
604
+ case 'socialLinks':
605
+ return false // User decision
606
+ default:
607
+ return false
608
+ }
609
+ }
610
+
611
+ /**
612
+ * Estimate cost based on model and token usage
613
+ */
614
+ private estimateCost(inputTokens: number, outputTokens: number): number {
615
+ // Pricing as of 2024 (in USD per 1K tokens)
616
+ const pricing: Record<string, { input: number; output: number }> = {
617
+ 'gpt-4o-mini': { input: 0.00015, output: 0.0006 },
618
+ 'gpt-4o': { input: 0.005, output: 0.015 },
619
+ 'gpt-4-turbo': { input: 0.01, output: 0.03 },
620
+ }
621
+
622
+ const modelPricing = pricing[this.config.model] ?? pricing['gpt-4o-mini']
623
+
624
+ return (
625
+ (inputTokens / 1000) * modelPricing.input +
626
+ (outputTokens / 1000) * modelPricing.output
627
+ )
628
+ }
629
+ }
630
+
631
+ /**
632
+ * Create a new PrivacyAdvisorAgent instance
633
+ *
634
+ * @param config - Agent configuration
635
+ * @returns PrivacyAdvisorAgent instance
636
+ *
637
+ * @example
638
+ * ```typescript
639
+ * const advisor = createPrivacyAdvisor({
640
+ * openaiApiKey: 'your-api-key',
641
+ * model: 'gpt-4o-mini', // Cost-efficient default
642
+ * })
643
+ *
644
+ * const response = await advisor.analyze({
645
+ * analysisResult: await analyzer.analyze('wallet-address'),
646
+ * })
647
+ * ```
648
+ */
649
+ export function createPrivacyAdvisor(
650
+ config: PrivacyAdvisorConfig
651
+ ): PrivacyAdvisorAgent {
652
+ return new PrivacyAdvisorAgent(config)
653
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Privacy Advisor Module
3
+ *
4
+ * LangChain-powered AI agent for intelligent privacy recommendations.
5
+ *
6
+ * @packageDocumentation
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { PrivacyAdvisorAgent, createPrivacyAdvisorTools } from '@sip-protocol/sdk'
11
+ *
12
+ * // Create advisor (simple chat mode)
13
+ * const advisor = new PrivacyAdvisorAgent({
14
+ * openaiApiKey: process.env.OPENAI_API_KEY!,
15
+ * })
16
+ *
17
+ * // Or use tools for a full agent
18
+ * const tools = createPrivacyAdvisorTools({
19
+ * heliusApiKey: process.env.HELIUS_API_KEY!,
20
+ * })
21
+ * ```
22
+ */
23
+
24
+ // Main agent
25
+ export { PrivacyAdvisorAgent, createPrivacyAdvisor } from './advisor'
26
+
27
+ // LangChain tools (for building custom agents)
28
+ export {
29
+ createPrivacyAdvisorTools,
30
+ createAnalyzeWalletTool,
31
+ createQuickScoreTool,
32
+ createSIPComparisonTool,
33
+ createExplainTool,
34
+ } from './tools'
35
+
36
+ export type { ToolsConfig } from './tools'
37
+
38
+ // Types
39
+ export type {
40
+ // Core types
41
+ AdvisorRole,
42
+ AdvisorMessage,
43
+ AdvisorStatus,
44
+ // Configuration
45
+ PrivacyAdvisorConfig,
46
+ AdvisoryContext,
47
+ // Response types
48
+ AdvisorResponse,
49
+ PrivacyAdvisoryReport,
50
+ AdvisorRecommendation,
51
+ // Utilities
52
+ ToolResult,
53
+ StreamCallback,
54
+ } from './types'