@sip-protocol/sdk 0.5.1 → 0.6.1

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 (76) hide show
  1. package/README.md +58 -0
  2. package/dist/TransportWebUSB-TQ7WZ4LE.mjs +3098 -0
  3. package/dist/browser.d.mts +4 -4
  4. package/dist/browser.d.ts +4 -4
  5. package/dist/browser.js +10133 -4664
  6. package/dist/browser.mjs +32 -1
  7. package/dist/chunk-7QZPORY5.mjs +15604 -0
  8. package/dist/chunk-C2NPCUAJ.mjs +17010 -0
  9. package/dist/chunk-FCVLFUIC.mjs +16699 -0
  10. package/dist/chunk-G5UHXECN.mjs +16340 -0
  11. package/dist/chunk-GEDEIZHJ.mjs +16798 -0
  12. package/dist/chunk-KBS3OMSZ.mjs +14737 -0
  13. package/dist/chunk-MTNYSNR7.mjs +16269 -0
  14. package/dist/chunk-O5PIB2EA.mjs +16698 -0
  15. package/dist/chunk-PCFM7FQO.mjs +17010 -0
  16. package/dist/chunk-QK464ARC.mjs +16946 -0
  17. package/dist/chunk-TK3FWQNC.mjs +14737 -0
  18. package/dist/chunk-UJCSKKID.mjs +30 -0
  19. package/dist/chunk-VNBMNGC3.mjs +16698 -0
  20. package/dist/chunk-W5TUELDQ.mjs +16947 -0
  21. package/dist/index-05W_S8A7.d.mts +9237 -0
  22. package/dist/index-C5ehlFhR.d.mts +9443 -0
  23. package/dist/index-CD_zShu-.d.ts +10870 -0
  24. package/dist/index-CNzhx-WH.d.mts +9316 -0
  25. package/dist/index-CQBYdLYy.d.mts +10976 -0
  26. package/dist/index-Cg9TYEPv.d.mts +11321 -0
  27. package/dist/index-CqSppS4i.d.ts +9237 -0
  28. package/dist/index-CqZJOO8C.d.mts +11323 -0
  29. package/dist/index-CywN9Bnp.d.ts +11321 -0
  30. package/dist/index-DBa_jiZF.d.mts +9606 -0
  31. package/dist/index-DHy5ZjCD.d.ts +10976 -0
  32. package/dist/index-DLNdSQFQ.d.ts +9316 -0
  33. package/dist/index-DfsVsmxu.d.ts +11323 -0
  34. package/dist/index-Ink8HnKW.d.ts +9606 -0
  35. package/dist/index-ObjwyVDX.d.mts +10870 -0
  36. package/dist/index-h7B23m5b.d.ts +9443 -0
  37. package/dist/index-m0xbSfmT.d.mts +11318 -0
  38. package/dist/index-rWLEgvhN.d.ts +11318 -0
  39. package/dist/index.d.mts +3 -3
  40. package/dist/index.d.ts +3 -3
  41. package/dist/index.js +10112 -4637
  42. package/dist/index.mjs +32 -1
  43. package/dist/noir-DKfEzWy9.d.mts +482 -0
  44. package/dist/noir-DKfEzWy9.d.ts +482 -0
  45. package/dist/proofs/noir.d.mts +1 -1
  46. package/dist/proofs/noir.d.ts +1 -1
  47. package/dist/proofs/noir.js +12 -3
  48. package/dist/proofs/noir.mjs +13 -3
  49. package/package.json +5 -3
  50. package/src/adapters/near-intents.ts +13 -3
  51. package/src/auction/index.ts +20 -0
  52. package/src/auction/sealed-bid.ts +1037 -0
  53. package/src/compliance/derivation.ts +13 -3
  54. package/src/compliance/reports.ts +5 -4
  55. package/src/cosmos/ibc-stealth.ts +2 -2
  56. package/src/cosmos/stealth.ts +2 -2
  57. package/src/crypto.ts +79 -9
  58. package/src/governance/index.ts +19 -0
  59. package/src/governance/private-vote.ts +1116 -0
  60. package/src/index.ts +50 -2
  61. package/src/intent.ts +227 -12
  62. package/src/nft/index.ts +27 -0
  63. package/src/nft/private-nft.ts +811 -0
  64. package/src/privacy.ts +88 -2
  65. package/src/proofs/browser-utils.ts +1 -7
  66. package/src/proofs/noir.ts +34 -7
  67. package/src/settlement/backends/direct-chain.ts +14 -3
  68. package/src/sip.ts +324 -25
  69. package/src/stealth.ts +120 -9
  70. package/src/types/browser.d.ts +67 -0
  71. package/src/validation.ts +4 -2
  72. package/src/wallet/bitcoin/adapter.ts +159 -15
  73. package/src/wallet/bitcoin/types.ts +340 -15
  74. package/src/wallet/cosmos/mock.ts +16 -12
  75. package/src/wallet/hardware/ledger.ts +83 -14
  76. package/src/wallet/hardware/types.ts +2 -0
package/src/privacy.ts CHANGED
@@ -48,7 +48,41 @@ export interface PrivacyConfig {
48
48
  }
49
49
 
50
50
  /**
51
- * Get privacy configuration for a privacy level
51
+ * Get privacy configuration for a given privacy level
52
+ *
53
+ * Returns a configuration object that determines which privacy features
54
+ * to enable for an intent. Used internally by the SDK to configure
55
+ * privacy behavior.
56
+ *
57
+ * **Privacy Levels:**
58
+ * - `'transparent'`: No privacy, fully public on-chain
59
+ * - `'shielded'`: Full privacy, hidden sender/amount/recipient
60
+ * - `'compliant'`: Privacy with viewing key for regulatory compliance
61
+ *
62
+ * @param level - Privacy level to configure
63
+ * @param viewingKey - Required for compliant mode, optional otherwise
64
+ * @returns Configuration object specifying privacy features
65
+ *
66
+ * @throws {ValidationError} If compliant mode specified without viewing key
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * // Transparent (no privacy)
71
+ * const config = getPrivacyConfig('transparent')
72
+ * // { level: 'transparent', useStealth: false, encryptData: false }
73
+ *
74
+ * // Shielded (full privacy)
75
+ * const config = getPrivacyConfig('shielded')
76
+ * // { level: 'shielded', useStealth: true, encryptData: true }
77
+ *
78
+ * // Compliant (privacy + audit)
79
+ * const viewingKey = generateViewingKey()
80
+ * const config = getPrivacyConfig('compliant', viewingKey)
81
+ * // { level: 'compliant', viewingKey, useStealth: true, encryptData: true }
82
+ * ```
83
+ *
84
+ * @see {@link PrivacyLevel} for available privacy levels
85
+ * @see {@link generateViewingKey} to create viewing keys
52
86
  */
53
87
  export function getPrivacyConfig(
54
88
  level: PrivacyLevel,
@@ -96,7 +130,59 @@ export function getPrivacyConfig(
96
130
  }
97
131
 
98
132
  /**
99
- * Generate a new viewing key
133
+ * Generate a new viewing key for compliant privacy mode
134
+ *
135
+ * Creates a cryptographically random viewing key that enables selective
136
+ * disclosure of transaction details to auditors or regulators while
137
+ * maintaining on-chain privacy.
138
+ *
139
+ * **Use Cases:**
140
+ * - Regulatory compliance (AML/KYC audits)
141
+ * - Internal accounting and reconciliation
142
+ * - Voluntary disclosure to trusted parties
143
+ * - Hierarchical key management (via derivation paths)
144
+ *
145
+ * **Security:**
146
+ * - Keep viewing keys secret - they decrypt all transaction details
147
+ * - Use hierarchical derivation for key management (BIP32-style paths)
148
+ * - Rotate keys periodically for forward secrecy
149
+ *
150
+ * @param path - Hierarchical derivation path (BIP32-style, e.g., "m/0", "m/44'/0'/0'")
151
+ * @returns Viewing key object with key, path, and hash
152
+ *
153
+ * @example Generate master viewing key
154
+ * ```typescript
155
+ * const masterKey = generateViewingKey('m/0')
156
+ * console.log(masterKey.key) // "0xabc123..."
157
+ * console.log(masterKey.path) // "m/0"
158
+ * console.log(masterKey.hash) // "0xdef456..." (for identification)
159
+ * ```
160
+ *
161
+ * @example Generate organization-specific keys
162
+ * ```typescript
163
+ * const auditKey = generateViewingKey('m/0/audit')
164
+ * const accountingKey = generateViewingKey('m/0/accounting')
165
+ *
166
+ * // Share different keys with different departments
167
+ * shareWithAuditor(auditKey)
168
+ * shareWithAccounting(accountingKey)
169
+ * ```
170
+ *
171
+ * @example Use in compliant intent
172
+ * ```typescript
173
+ * const viewingKey = generateViewingKey()
174
+ *
175
+ * const intent = await sip.createIntent({
176
+ * input: { asset: { chain: 'near', symbol: 'NEAR', address: null, decimals: 24 }, amount: 100n },
177
+ * output: { asset: { chain: 'zcash', symbol: 'ZEC', address: null, decimals: 8 }, minAmount: 0n, maxSlippage: 0.01 },
178
+ * privacy: PrivacyLevel.COMPLIANT,
179
+ * viewingKey: viewingKey.key,
180
+ * })
181
+ * ```
182
+ *
183
+ * @see {@link deriveViewingKey} to derive child keys hierarchically
184
+ * @see {@link encryptForViewing} to encrypt data with viewing key
185
+ * @see {@link decryptWithViewing} to decrypt data with viewing key
100
186
  */
101
187
  export function generateViewingKey(path: string = 'm/0'): ViewingKey {
102
188
  const keyBytes = randomBytes(32)
@@ -241,10 +241,8 @@ export function getMobileDeviceInfo(): MobileDeviceInfo {
241
241
  isTablet: isTablet(),
242
242
  supportsTouch: supportsTouch(),
243
243
  deviceMemoryGB:
244
- // @ts-expect-error - deviceMemory is non-standard
245
244
  typeof navigator !== 'undefined' && navigator.deviceMemory
246
- ? // @ts-expect-error - deviceMemory is non-standard
247
- navigator.deviceMemory
245
+ ? navigator.deviceMemory
248
246
  : null,
249
247
  hardwareConcurrency:
250
248
  typeof navigator !== 'undefined' && navigator.hardwareConcurrency
@@ -487,10 +485,8 @@ export async function estimateAvailableMemory(): Promise<number | null> {
487
485
  if (!isBrowser()) return null
488
486
 
489
487
  // Use Performance API if available (Chrome)
490
- // @ts-expect-error - Performance.measureUserAgentSpecificMemory is Chrome-specific
491
488
  if (typeof performance !== 'undefined' && performance.measureUserAgentSpecificMemory) {
492
489
  try {
493
- // @ts-expect-error - Chrome-specific API
494
490
  const result = await performance.measureUserAgentSpecificMemory()
495
491
  return result.bytes
496
492
  } catch {
@@ -499,10 +495,8 @@ export async function estimateAvailableMemory(): Promise<number | null> {
499
495
  }
500
496
 
501
497
  // Use navigator.deviceMemory if available (Chrome, Opera)
502
- // @ts-expect-error - deviceMemory is non-standard
503
498
  if (typeof navigator !== 'undefined' && navigator.deviceMemory) {
504
499
  // Returns approximate device memory in GB
505
- // @ts-expect-error - deviceMemory is non-standard
506
500
  return navigator.deviceMemory * 1024 * 1024 * 1024
507
501
  }
508
502
 
@@ -71,9 +71,25 @@ export interface NoirProviderConfig {
71
71
 
72
72
  /**
73
73
  * Oracle public key for verifying attestations in fulfillment proofs
74
- * Required for production use. If not provided, proofs will use placeholder keys.
74
+ * Required for production use. If not provided and strictMode is true,
75
+ * fulfillment proof generation will throw an error.
75
76
  */
76
77
  oraclePublicKey?: PublicKeyCoordinates
78
+
79
+ /**
80
+ * Enable strict mode for production use
81
+ *
82
+ * When true:
83
+ * - Fulfillment proofs require configured oraclePublicKey
84
+ * - Missing configuration throws errors instead of warnings
85
+ *
86
+ * When false (default):
87
+ * - Placeholder keys are used when oraclePublicKey not configured
88
+ * - Warnings are logged for missing configuration
89
+ *
90
+ * @default false
91
+ */
92
+ strictMode?: boolean
77
93
  }
78
94
 
79
95
  /**
@@ -114,6 +130,7 @@ export class NoirProofProvider implements ProofProvider {
114
130
  this.config = {
115
131
  backend: 'barretenberg',
116
132
  verbose: false,
133
+ strictMode: false,
117
134
  ...config,
118
135
  }
119
136
  }
@@ -588,15 +605,25 @@ export class NoirProofProvider implements ProofProvider {
588
605
  attestation.blockNumber
589
606
  )
590
607
 
591
- // Use configured oracle public key, or placeholder if not configured
592
- // In production, the oracle public key should always be configured
608
+ // Validate oracle public key configuration
609
+ if (!this.config.oraclePublicKey) {
610
+ if (this.config.strictMode) {
611
+ throw new ProofGenerationError(
612
+ 'fulfillment',
613
+ 'Oracle public key is required in strict mode. Configure oraclePublicKey in NoirProviderConfig for production use.'
614
+ )
615
+ }
616
+ // Always warn when using placeholder keys, not just in verbose mode
617
+ console.warn(
618
+ '[NoirProofProvider] WARNING: No oracle public key configured. Using placeholder keys. ' +
619
+ 'Proofs will NOT be valid for production. Set strictMode: true to enforce configuration.'
620
+ )
621
+ }
622
+
623
+ // Use configured oracle public key, or placeholder if not in strict mode
593
624
  const oraclePubKeyX = this.config.oraclePublicKey?.x ?? new Array(32).fill(0)
594
625
  const oraclePubKeyY = this.config.oraclePublicKey?.y ?? new Array(32).fill(0)
595
626
 
596
- if (!this.config.oraclePublicKey && this.config.verbose) {
597
- console.warn('[NoirProofProvider] Warning: No oracle public key configured. Using placeholder keys.')
598
- }
599
-
600
627
  // Prepare witness inputs for the circuit
601
628
  const witnessInputs = {
602
629
  // Public inputs
@@ -39,6 +39,8 @@ import {
39
39
  ed25519PublicKeyToNearAddress,
40
40
  isEd25519Chain,
41
41
  } from '../../stealth'
42
+ import { ed25519PublicKeyToAptosAddress } from '../../move/aptos'
43
+ import { ed25519PublicKeyToSuiAddress } from '../../move/sui'
42
44
  import { ValidationError } from '../../errors'
43
45
  import { randomBytes, bytesToHex } from '@noble/hashes/utils'
44
46
 
@@ -161,6 +163,8 @@ export class DirectChainBackend implements SettlementBackend {
161
163
  'optimism',
162
164
  'base',
163
165
  'bitcoin',
166
+ 'aptos',
167
+ 'sui',
164
168
  ],
165
169
  supportedDestinationChains: [
166
170
  'ethereum',
@@ -172,6 +176,8 @@ export class DirectChainBackend implements SettlementBackend {
172
176
  'optimism',
173
177
  'base',
174
178
  'bitcoin',
179
+ 'aptos',
180
+ 'sui',
175
181
  ],
176
182
  supportedPrivacyLevels: [
177
183
  PrivacyLevel.TRANSPARENT,
@@ -280,7 +286,7 @@ export class DirectChainBackend implements SettlementBackend {
280
286
  : params.recipientMetaAddress
281
287
 
282
288
  if (isEd25519Chain(chain)) {
283
- // Ed25519 chains (Solana, NEAR)
289
+ // Ed25519 chains (Solana, NEAR, Aptos, Sui)
284
290
  const { stealthAddress } = generateEd25519StealthAddress(metaAddr)
285
291
  stealthData = stealthAddress
286
292
 
@@ -288,11 +294,16 @@ export class DirectChainBackend implements SettlementBackend {
288
294
  recipientAddress = ed25519PublicKeyToSolanaAddress(stealthAddress.address)
289
295
  } else if (chain === 'near') {
290
296
  recipientAddress = ed25519PublicKeyToNearAddress(stealthAddress.address)
297
+ } else if (chain === 'aptos') {
298
+ recipientAddress = ed25519PublicKeyToAptosAddress(stealthAddress.address)
299
+ } else if (chain === 'sui') {
300
+ recipientAddress = ed25519PublicKeyToSuiAddress(stealthAddress.address)
291
301
  } else {
302
+ // This should not happen if ED25519_CHAINS is kept in sync
292
303
  throw new ValidationError(
293
- `Ed25519 address derivation not implemented for ${chain}`,
304
+ `Ed25519 address derivation not implemented for ${chain}. Please add support in direct-chain.ts.`,
294
305
  'toChain',
295
- { chain }
306
+ { chain, hint: 'Add address derivation function for this chain' }
296
307
  )
297
308
  }
298
309
  } else {
package/src/sip.ts CHANGED
@@ -32,50 +32,145 @@ import { isValidChainId } from './validation'
32
32
  import { NEARIntentsAdapter, type NEARIntentsAdapterConfig, type SwapRequest } from './adapters'
33
33
 
34
34
  /**
35
- * SIP SDK configuration
35
+ * Configuration options for the SIP SDK client
36
+ *
37
+ * Controls network selection, privacy defaults, proof generation, and settlement backend.
38
+ *
39
+ * @example Basic configuration
40
+ * ```typescript
41
+ * const sip = new SIP({
42
+ * network: 'testnet',
43
+ * defaultPrivacy: PrivacyLevel.SHIELDED
44
+ * })
45
+ * ```
46
+ *
47
+ * @example Production configuration with NEAR Intents
48
+ * ```typescript
49
+ * const sip = new SIP({
50
+ * network: 'mainnet',
51
+ * mode: 'production',
52
+ * proofProvider: new MockProofProvider(),
53
+ * intentsAdapter: {
54
+ * jwtToken: process.env.NEAR_INTENTS_JWT
55
+ * }
56
+ * })
57
+ * ```
36
58
  */
37
59
  export interface SIPConfig {
38
- /** Network: mainnet or testnet */
60
+ /**
61
+ * Network to operate on
62
+ *
63
+ * - `'mainnet'`: Production network with real assets
64
+ * - `'testnet'`: Test network for development
65
+ */
39
66
  network: 'mainnet' | 'testnet'
67
+
40
68
  /**
41
- * Mode: 'demo' for mock data, 'production' for real NEAR Intents
69
+ * Operating mode for quote fetching and execution
70
+ *
71
+ * - `'demo'`: Returns mock quotes for testing (default)
72
+ * - `'production'`: Uses real NEAR Intents 1Click API
73
+ *
42
74
  * @default 'demo'
43
75
  */
44
76
  mode?: 'demo' | 'production'
45
- /** Default privacy level */
77
+
78
+ /**
79
+ * Default privacy level for new intents
80
+ *
81
+ * Can be overridden per intent. See {@link PrivacyLevel} for options.
82
+ *
83
+ * @default PrivacyLevel.SHIELDED
84
+ */
46
85
  defaultPrivacy?: PrivacyLevel
47
- /** RPC endpoints for chains */
48
- rpcEndpoints?: Partial<Record<ChainId, string>>
86
+
49
87
  /**
50
- * Proof provider for ZK proof generation
88
+ * Custom RPC endpoints for blockchain connections
51
89
  *
52
- * If not provided, proof generation will not be available.
53
- * Use MockProofProvider for testing, NoirProofProvider for production.
90
+ * Maps chain IDs to RPC URLs. Used for direct blockchain interactions
91
+ * when not using settlement adapters.
54
92
  *
55
93
  * @example
56
94
  * ```typescript
95
+ * {
96
+ * rpcEndpoints: {
97
+ * ethereum: 'https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY',
98
+ * solana: 'https://api.mainnet-beta.solana.com'
99
+ * }
100
+ * }
101
+ * ```
102
+ */
103
+ rpcEndpoints?: Partial<Record<ChainId, string>>
104
+
105
+ /**
106
+ * Proof provider for zero-knowledge proof generation
107
+ *
108
+ * Required for SHIELDED and COMPLIANT privacy modes. If not provided,
109
+ * intents will be created without proofs (must be attached later).
110
+ *
111
+ * **Available providers:**
112
+ * - {@link MockProofProvider}: For testing and development
113
+ * - `NoirProofProvider`: For production (import from '@sip-protocol/sdk/proofs/noir')
114
+ * - `BrowserNoirProvider`: For browser environments (import from '@sip-protocol/sdk/browser')
115
+ *
116
+ * @example Testing with mock proofs
117
+ * ```typescript
57
118
  * import { MockProofProvider } from '@sip-protocol/sdk'
58
119
  *
59
120
  * const sip = new SIP({
60
121
  * network: 'testnet',
61
- * proofProvider: new MockProofProvider(),
122
+ * proofProvider: new MockProofProvider()
123
+ * })
124
+ * ```
125
+ *
126
+ * @example Production with Noir proofs (Node.js)
127
+ * ```typescript
128
+ * import { NoirProofProvider } from '@sip-protocol/sdk/proofs/noir'
129
+ *
130
+ * const provider = new NoirProofProvider()
131
+ * await provider.initialize()
132
+ *
133
+ * const sip = new SIP({
134
+ * network: 'mainnet',
135
+ * proofProvider: provider
62
136
  * })
63
137
  * ```
64
138
  */
65
139
  proofProvider?: ProofProvider
140
+
66
141
  /**
67
- * NEAR Intents adapter configuration
142
+ * NEAR Intents adapter for production mode
68
143
  *
69
- * Required for production mode. Provides connection to 1Click API.
144
+ * Required when `mode: 'production'`. Provides connection to the 1Click API
145
+ * for real cross-chain swaps via NEAR Intents.
70
146
  *
71
- * @example
147
+ * Can be either:
148
+ * - Configuration object ({@link NEARIntentsAdapterConfig})
149
+ * - Pre-configured adapter instance ({@link NEARIntentsAdapter})
150
+ *
151
+ * @example With JWT token
72
152
  * ```typescript
73
153
  * const sip = new SIP({
74
154
  * network: 'mainnet',
75
155
  * mode: 'production',
76
156
  * intentsAdapter: {
77
- * jwtToken: process.env.NEAR_INTENTS_JWT,
78
- * },
157
+ * jwtToken: process.env.NEAR_INTENTS_JWT
158
+ * }
159
+ * })
160
+ * ```
161
+ *
162
+ * @example With pre-configured adapter
163
+ * ```typescript
164
+ * import { createNEARIntentsAdapter } from '@sip-protocol/sdk'
165
+ *
166
+ * const adapter = createNEARIntentsAdapter({
167
+ * jwtToken: process.env.NEAR_INTENTS_JWT
168
+ * })
169
+ *
170
+ * const sip = new SIP({
171
+ * network: 'mainnet',
172
+ * mode: 'production',
173
+ * intentsAdapter: adapter
79
174
  * })
80
175
  * ```
81
176
  */
@@ -83,33 +178,212 @@ export interface SIPConfig {
83
178
  }
84
179
 
85
180
  /**
86
- * Wallet adapter interface
181
+ * Wallet adapter interface for blockchain interactions
182
+ *
183
+ * Provides a unified interface for signing messages and transactions
184
+ * across different blockchain wallets (Ethereum, Solana, etc.).
185
+ *
186
+ * @example Implementing a wallet adapter
187
+ * ```typescript
188
+ * class MyWalletAdapter implements WalletAdapter {
189
+ * chain = 'ethereum' as const
190
+ * address = '0x...'
191
+ *
192
+ * async signMessage(message: string): Promise<string> {
193
+ * return await wallet.signMessage(message)
194
+ * }
195
+ *
196
+ * async signTransaction(tx: unknown): Promise<unknown> {
197
+ * return await wallet.signTransaction(tx)
198
+ * }
199
+ * }
200
+ * ```
87
201
  */
88
202
  export interface WalletAdapter {
89
- /** Connected chain */
203
+ /**
204
+ * Blockchain network this wallet is connected to
205
+ *
206
+ * Must match one of the supported {@link ChainId} values.
207
+ */
90
208
  chain: ChainId
91
- /** Wallet address */
209
+
210
+ /**
211
+ * Wallet address on the connected chain
212
+ *
213
+ * Format depends on the chain:
214
+ * - Ethereum: `0x...` (checksummed)
215
+ * - Solana: Base58-encoded public key
216
+ * - NEAR: Account ID or implicit address
217
+ */
92
218
  address: string
93
- /** Sign a message */
219
+
220
+ /**
221
+ * Sign a message with the wallet's private key
222
+ *
223
+ * @param message - UTF-8 string to sign
224
+ * @returns Signature as hex string or base58 (chain-dependent)
225
+ *
226
+ * @example
227
+ * ```typescript
228
+ * const signature = await wallet.signMessage('Hello SIP!')
229
+ * ```
230
+ */
94
231
  signMessage(message: string): Promise<string>
95
- /** Sign a transaction */
232
+
233
+ /**
234
+ * Sign a transaction without broadcasting
235
+ *
236
+ * @param tx - Chain-specific transaction object
237
+ * @returns Signed transaction ready for broadcast
238
+ *
239
+ * @example
240
+ * ```typescript
241
+ * const signedTx = await wallet.signTransaction(tx)
242
+ * ```
243
+ */
96
244
  signTransaction(tx: unknown): Promise<unknown>
97
- /** Send a transaction (optional) */
245
+
246
+ /**
247
+ * Sign and broadcast a transaction (optional)
248
+ *
249
+ * If implemented, allows the wallet to handle both signing and sending.
250
+ * If not implemented, caller must broadcast the signed transaction separately.
251
+ *
252
+ * @param tx - Chain-specific transaction object
253
+ * @returns Transaction hash after broadcast
254
+ *
255
+ * @example
256
+ * ```typescript
257
+ * if (wallet.sendTransaction) {
258
+ * const txHash = await wallet.sendTransaction(tx)
259
+ * }
260
+ * ```
261
+ */
98
262
  sendTransaction?(tx: unknown): Promise<string>
99
263
  }
100
264
 
101
265
  /**
102
- * Extended quote with deposit info for production mode
266
+ * Extended quote with production-specific metadata
267
+ *
268
+ * In production mode, quotes include deposit addresses and raw API responses
269
+ * from the NEAR 1Click API for advanced use cases.
103
270
  */
104
271
  export interface ProductionQuote extends Quote {
105
- /** Deposit address for input tokens (production mode only) */
272
+ /**
273
+ * Deposit address for input tokens
274
+ *
275
+ * When using NEAR Intents in production mode, users deposit funds to this
276
+ * address to initiate the swap.
277
+ *
278
+ * Only present in production mode quotes.
279
+ */
106
280
  depositAddress?: string
107
- /** Raw 1Click quote response (production mode only) */
281
+
282
+ /**
283
+ * Raw response from NEAR 1Click API
284
+ *
285
+ * Contains the complete quote data from the settlement backend.
286
+ * Useful for debugging or accessing provider-specific metadata.
287
+ *
288
+ * Only present in production mode quotes.
289
+ */
108
290
  rawQuote?: OneClickQuoteResponse
109
291
  }
110
292
 
111
293
  /**
112
- * Main SIP SDK class
294
+ * Main SIP SDK client for privacy-preserving cross-chain transactions
295
+ *
296
+ * The SIP class is the primary interface for interacting with the Shielded Intents Protocol.
297
+ * It provides methods for:
298
+ *
299
+ * - Creating shielded intents with privacy guarantees
300
+ * - Fetching quotes from solvers/market makers
301
+ * - Executing cross-chain swaps via settlement backends
302
+ * - Managing stealth addresses and viewing keys
303
+ * - Generating zero-knowledge proofs
304
+ *
305
+ * **Key Concepts:**
306
+ *
307
+ * - **Intent**: A declaration of desired output (e.g., "I want 95+ ZEC on Zcash")
308
+ * - **Privacy Levels**: transparent (public), shielded (private), compliant (private + auditable)
309
+ * - **Stealth Address**: One-time recipient address for unlinkable transactions
310
+ * - **Commitment**: Cryptographic hiding of amounts using Pedersen commitments
311
+ * - **Viewing Key**: Selective disclosure key for compliance/auditing
312
+ *
313
+ * @example Basic usage (demo mode)
314
+ * ```typescript
315
+ * import { SIP, PrivacyLevel } from '@sip-protocol/sdk'
316
+ *
317
+ * // Initialize client
318
+ * const sip = new SIP({ network: 'testnet' })
319
+ *
320
+ * // Create a shielded intent
321
+ * const intent = await sip.createIntent({
322
+ * input: {
323
+ * asset: { chain: 'solana', symbol: 'SOL', address: null, decimals: 9 },
324
+ * amount: 10n * 10n**9n, // 10 SOL
325
+ * },
326
+ * output: {
327
+ * asset: { chain: 'ethereum', symbol: 'ETH', address: null, decimals: 18 },
328
+ * minAmount: 0n, // Accept any amount
329
+ * maxSlippage: 0.01, // 1%
330
+ * },
331
+ * privacy: PrivacyLevel.SHIELDED,
332
+ * })
333
+ *
334
+ * // Get quotes from solvers
335
+ * const quotes = await sip.getQuotes(intent)
336
+ *
337
+ * // Execute with best quote
338
+ * const result = await sip.execute(intent, quotes[0])
339
+ * console.log('Swap completed:', result.txHash)
340
+ * ```
341
+ *
342
+ * @example Production mode with NEAR Intents
343
+ * ```typescript
344
+ * import { SIP, PrivacyLevel, MockProofProvider } from '@sip-protocol/sdk'
345
+ *
346
+ * // Initialize with production backend
347
+ * const sip = new SIP({
348
+ * network: 'mainnet',
349
+ * mode: 'production',
350
+ * proofProvider: new MockProofProvider(), // Use NoirProofProvider in prod
351
+ * intentsAdapter: {
352
+ * jwtToken: process.env.NEAR_INTENTS_JWT,
353
+ * },
354
+ * })
355
+ *
356
+ * // Connect wallet
357
+ * sip.connect(myWalletAdapter)
358
+ *
359
+ * // Generate stealth keys for receiving
360
+ * const stealthMetaAddress = sip.generateStealthKeys('ethereum', 'My Privacy Wallet')
361
+ *
362
+ * // Create intent with stealth recipient
363
+ * const intent = await sip.createIntent({
364
+ * input: { asset: { chain: 'near', symbol: 'NEAR', address: null, decimals: 24 }, amount: 100n },
365
+ * output: { asset: { chain: 'zcash', symbol: 'ZEC', address: null, decimals: 8 }, minAmount: 0n, maxSlippage: 0.01 },
366
+ * privacy: PrivacyLevel.SHIELDED,
367
+ * recipientMetaAddress: sip.getStealthAddress(),
368
+ * })
369
+ *
370
+ * // Get real quotes
371
+ * const quotes = await sip.getQuotes(intent)
372
+ *
373
+ * // Execute with deposit callback
374
+ * const result = await sip.execute(intent, quotes[0], {
375
+ * onDepositRequired: async (depositAddr, amount) => {
376
+ * console.log(`Deposit ${amount} to ${depositAddr}`)
377
+ * const tx = await wallet.transfer(depositAddr, amount)
378
+ * return tx.hash
379
+ * },
380
+ * onStatusUpdate: (status) => console.log('Status:', status),
381
+ * })
382
+ * ```
383
+ *
384
+ * @see {@link SIPConfig} for configuration options
385
+ * @see {@link createShieldedIntent} for intent creation
386
+ * @see {@link PrivacyLevel} for privacy modes
113
387
  */
114
388
  export class SIP {
115
389
  private config: SIPConfig & { mode: 'demo' | 'production' }
@@ -124,6 +398,31 @@ export class SIP {
124
398
  /** Cache of pending swaps by intent ID */
125
399
  private pendingSwaps: Map<string, { depositAddress: string; quote: OneClickQuoteResponse }> = new Map()
126
400
 
401
+ /**
402
+ * Create a new SIP SDK client
403
+ *
404
+ * @param config - Configuration options for the client
405
+ * @throws {ValidationError} If configuration is invalid
406
+ *
407
+ * @example Minimal configuration
408
+ * ```typescript
409
+ * const sip = new SIP({ network: 'testnet' })
410
+ * ```
411
+ *
412
+ * @example Full configuration
413
+ * ```typescript
414
+ * const sip = new SIP({
415
+ * network: 'mainnet',
416
+ * mode: 'production',
417
+ * defaultPrivacy: PrivacyLevel.COMPLIANT,
418
+ * proofProvider: await NoirProofProvider.create(),
419
+ * intentsAdapter: { jwtToken: process.env.JWT },
420
+ * rpcEndpoints: {
421
+ * ethereum: 'https://eth-mainnet.g.alchemy.com/v2/KEY',
422
+ * },
423
+ * })
424
+ * ```
425
+ */
127
426
  constructor(config: SIPConfig) {
128
427
  // Validate config
129
428
  if (!config || typeof config !== 'object') {