@sip-protocol/sdk 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/browser.d.mts +2 -2
  2. package/dist/browser.d.ts +2 -2
  3. package/dist/browser.js +1028 -146
  4. package/dist/browser.mjs +49 -1
  5. package/dist/chunk-AOZIY3GU.mjs +12995 -0
  6. package/dist/chunk-BCLIX5T2.mjs +12940 -0
  7. package/dist/chunk-EU4UEWWG.mjs +12164 -0
  8. package/dist/chunk-FKXPHKYD.mjs +12955 -0
  9. package/dist/chunk-OPQ2GQIO.mjs +13013 -0
  10. package/dist/index-BcWNakUD.d.ts +7990 -0
  11. package/dist/index-BsKY3Hr0.d.mts +7990 -0
  12. package/dist/index.d.mts +2 -2
  13. package/dist/index.d.ts +2 -2
  14. package/dist/index.js +999 -117
  15. package/dist/index.mjs +49 -1
  16. package/package.json +2 -1
  17. package/src/adapters/near-intents.ts +8 -0
  18. package/src/bitcoin/index.ts +51 -0
  19. package/src/bitcoin/silent-payments.ts +865 -0
  20. package/src/bitcoin/taproot.ts +590 -0
  21. package/src/cosmos/ibc-stealth.ts +825 -0
  22. package/src/cosmos/index.ts +83 -0
  23. package/src/cosmos/stealth.ts +487 -0
  24. package/src/index.ts +51 -0
  25. package/src/move/aptos.ts +369 -0
  26. package/src/move/index.ts +35 -0
  27. package/src/move/sui.ts +367 -0
  28. package/src/oracle/types.ts +8 -0
  29. package/src/settlement/backends/direct-chain.ts +8 -0
  30. package/src/settlement/backends/near-intents.ts +11 -0
  31. package/src/stealth.ts +3 -3
  32. package/src/validation.ts +42 -1
  33. package/src/wallet/aptos/adapter.ts +422 -0
  34. package/src/wallet/aptos/index.ts +10 -0
  35. package/src/wallet/aptos/mock.ts +410 -0
  36. package/src/wallet/aptos/types.ts +278 -0
  37. package/src/wallet/bitcoin/adapter.ts +470 -0
  38. package/src/wallet/bitcoin/index.ts +38 -0
  39. package/src/wallet/bitcoin/mock.ts +516 -0
  40. package/src/wallet/bitcoin/types.ts +274 -0
  41. package/src/wallet/cosmos/adapter.ts +484 -0
  42. package/src/wallet/cosmos/index.ts +63 -0
  43. package/src/wallet/cosmos/mock.ts +596 -0
  44. package/src/wallet/cosmos/types.ts +462 -0
  45. package/src/wallet/index.ts +127 -0
  46. package/src/wallet/sui/adapter.ts +471 -0
  47. package/src/wallet/sui/index.ts +10 -0
  48. package/src/wallet/sui/mock.ts +439 -0
  49. package/src/wallet/sui/types.ts +245 -0
@@ -0,0 +1,516 @@
1
+ /**
2
+ * Mock Bitcoin Wallet Adapter
3
+ *
4
+ * Testing implementation of Bitcoin wallet adapter.
5
+ * Provides full mock functionality without requiring browser environment.
6
+ */
7
+
8
+ import type {
9
+ HexString,
10
+ Asset,
11
+ Signature,
12
+ UnsignedTransaction,
13
+ SignedTransaction,
14
+ TransactionReceipt,
15
+ } from '@sip-protocol/types'
16
+ import { WalletErrorCode } from '@sip-protocol/types'
17
+ import { BaseWalletAdapter } from '../base-adapter'
18
+ import { WalletError } from '../errors'
19
+ import type {
20
+ UnisatAPI,
21
+ BitcoinNetwork,
22
+ BitcoinAddress,
23
+ BitcoinBalance,
24
+ SignPsbtOptions,
25
+ } from './types'
26
+ import { bitcoinPublicKeyToHex } from './types'
27
+
28
+ /**
29
+ * Configuration for mock Bitcoin adapter
30
+ */
31
+ export interface MockBitcoinAdapterConfig {
32
+ /** Mock address (Taproot address) */
33
+ address?: string
34
+ /** Mock public key (32-byte x-only hex) */
35
+ publicKey?: string
36
+ /** Mock balance in satoshis */
37
+ balance?: bigint
38
+ /** Token balances by inscription ID */
39
+ tokenBalances?: Record<string, bigint>
40
+ /** Whether to simulate connection failure */
41
+ shouldFailConnect?: boolean
42
+ /** Whether to simulate signing failure */
43
+ shouldFailSign?: boolean
44
+ /** Whether to simulate transaction failure */
45
+ shouldFailTransaction?: boolean
46
+ /** Simulated network */
47
+ network?: BitcoinNetwork
48
+ /** Simulated latency in ms */
49
+ latency?: number
50
+ }
51
+
52
+ /**
53
+ * Mock Bitcoin wallet adapter for testing
54
+ *
55
+ * Provides full Bitcoin wallet functionality with mock data.
56
+ * No browser environment or actual wallet required.
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * const wallet = new MockBitcoinAdapter({
61
+ * address: 'bc1p...',
62
+ * balance: 100_000_000n, // 1 BTC
63
+ * })
64
+ *
65
+ * await wallet.connect()
66
+ * const balance = await wallet.getBalance() // 100_000_000n
67
+ *
68
+ * // Simulate failures
69
+ * const failingWallet = new MockBitcoinAdapter({
70
+ * shouldFailSign: true,
71
+ * })
72
+ * ```
73
+ */
74
+ export class MockBitcoinAdapter extends BaseWalletAdapter {
75
+ readonly chain = 'bitcoin' as const
76
+ readonly name = 'mock-bitcoin'
77
+
78
+ private mockAddress: string
79
+ private mockPubKey: string
80
+ private mockBalance: bigint
81
+ private mockTokenBalances: Map<string, bigint>
82
+ private shouldFailConnect: boolean
83
+ private shouldFailSign: boolean
84
+ private shouldFailTransaction: boolean
85
+ private network: BitcoinNetwork
86
+ private latency: number
87
+
88
+ // Track signed transactions for verification
89
+ private signedPsbts: string[] = []
90
+ private signedMessages: string[] = []
91
+ private broadcastTxs: string[] = []
92
+
93
+ constructor(config: MockBitcoinAdapterConfig = {}) {
94
+ super()
95
+ // Use realistic Taproot address format
96
+ this.mockAddress = config.address ?? 'bc1p5d7rjq7g6rdk2yhzks9smlaqtedr4dekq08ge8ztwac72sfr9rusxg3297'
97
+ // X-only public key (32 bytes for Taproot)
98
+ this.mockPubKey = config.publicKey ?? 'a3c89044f0057b4e6f0abf99a35b4df9c2e8dbfe0c9db9e5d1f8d08e8e09a9c1'
99
+ this.mockBalance = config.balance ?? 100_000_000n // 1 BTC default
100
+ this.mockTokenBalances = new Map(Object.entries(config.tokenBalances ?? {}))
101
+ this.shouldFailConnect = config.shouldFailConnect ?? false
102
+ this.shouldFailSign = config.shouldFailSign ?? false
103
+ this.shouldFailTransaction = config.shouldFailTransaction ?? false
104
+ this.network = config.network ?? 'livenet'
105
+ this.latency = config.latency ?? 10
106
+ }
107
+
108
+ /**
109
+ * Get the current Bitcoin network
110
+ */
111
+ getNetwork(): BitcoinNetwork {
112
+ return this.network
113
+ }
114
+
115
+ /**
116
+ * Set the Bitcoin network
117
+ */
118
+ async setNetwork(network: BitcoinNetwork): Promise<void> {
119
+ await this.simulateLatency()
120
+ this.network = network
121
+ }
122
+
123
+ /**
124
+ * Connect to the mock wallet
125
+ */
126
+ async connect(): Promise<void> {
127
+ this._connectionState = 'connecting'
128
+
129
+ // Simulate network latency
130
+ await this.simulateLatency()
131
+
132
+ if (this.shouldFailConnect) {
133
+ this.setError(WalletErrorCode.CONNECTION_FAILED, 'Mock connection failure')
134
+ throw new WalletError('Mock connection failure', WalletErrorCode.CONNECTION_FAILED)
135
+ }
136
+
137
+ const hexPubKey = bitcoinPublicKeyToHex(this.mockPubKey)
138
+ this.setConnected(this.mockAddress, hexPubKey)
139
+ }
140
+
141
+ /**
142
+ * Disconnect from the mock wallet
143
+ */
144
+ async disconnect(): Promise<void> {
145
+ await this.simulateLatency()
146
+ this.setDisconnected('User disconnected')
147
+ }
148
+
149
+ /**
150
+ * Sign a message
151
+ */
152
+ async signMessage(message: Uint8Array): Promise<Signature> {
153
+ this.requireConnected()
154
+ await this.simulateLatency()
155
+
156
+ if (this.shouldFailSign) {
157
+ throw new WalletError('Mock signing failure', WalletErrorCode.SIGNING_REJECTED)
158
+ }
159
+
160
+ // Track signed message
161
+ const messageStr = new TextDecoder().decode(message)
162
+ this.signedMessages.push(messageStr)
163
+
164
+ // Create deterministic mock signature (64 bytes for Schnorr)
165
+ const mockSig = new Uint8Array(64)
166
+ for (let i = 0; i < 64; i++) {
167
+ mockSig[i] = (message[i % message.length] ?? 0) ^ (i * 7) ^ this.mockAddress.charCodeAt(i % this.mockAddress.length)
168
+ }
169
+
170
+ return {
171
+ signature: ('0x' + Buffer.from(mockSig).toString('hex')) as HexString,
172
+ publicKey: this._publicKey as HexString,
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Sign a PSBT
178
+ */
179
+ async signTransaction(tx: UnsignedTransaction): Promise<SignedTransaction> {
180
+ this.requireConnected()
181
+ await this.simulateLatency()
182
+
183
+ if (this.shouldFailSign) {
184
+ throw new WalletError('Mock signing failure', WalletErrorCode.SIGNING_REJECTED)
185
+ }
186
+
187
+ // Extract PSBT from transaction data
188
+ const psbtHex = tx.data as string
189
+ this.signedPsbts.push(psbtHex)
190
+
191
+ // Create mock signed PSBT (just add some mock signatures)
192
+ const mockSignedPsbt = psbtHex + '0'.repeat(128) // Add mock signature data
193
+
194
+ return {
195
+ unsigned: tx,
196
+ signatures: [
197
+ {
198
+ signature: ('0x' + mockSignedPsbt) as HexString,
199
+ publicKey: this._publicKey as HexString,
200
+ },
201
+ ],
202
+ serialized: ('0x' + mockSignedPsbt) as HexString,
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Sign and send a PSBT
208
+ */
209
+ async signAndSendTransaction(tx: UnsignedTransaction): Promise<TransactionReceipt> {
210
+ this.requireConnected()
211
+ await this.simulateLatency()
212
+
213
+ if (this.shouldFailSign) {
214
+ throw new WalletError('Mock signing failure', WalletErrorCode.SIGNING_REJECTED)
215
+ }
216
+
217
+ if (this.shouldFailTransaction) {
218
+ throw new WalletError('Mock transaction failure', WalletErrorCode.TRANSACTION_FAILED)
219
+ }
220
+
221
+ // Generate mock transaction ID
222
+ const txid = Array.from({ length: 64 }, () =>
223
+ Math.floor(Math.random() * 16).toString(16)
224
+ ).join('')
225
+
226
+ this.broadcastTxs.push(txid)
227
+
228
+ return {
229
+ txHash: ('0x' + txid) as HexString,
230
+ status: 'pending',
231
+ timestamp: Date.now(),
232
+ }
233
+ }
234
+
235
+ /**
236
+ * Get native BTC balance
237
+ */
238
+ async getBalance(): Promise<bigint> {
239
+ this.requireConnected()
240
+ await this.simulateLatency()
241
+ return this.mockBalance
242
+ }
243
+
244
+ /**
245
+ * Get token balance (BRC-20, etc.)
246
+ */
247
+ async getTokenBalance(asset: Asset): Promise<bigint> {
248
+ this.requireConnected()
249
+ await this.simulateLatency()
250
+
251
+ if (asset.chain !== 'bitcoin') {
252
+ throw new WalletError(
253
+ `Asset chain ${asset.chain} not supported by Bitcoin adapter`,
254
+ WalletErrorCode.UNSUPPORTED_CHAIN
255
+ )
256
+ }
257
+
258
+ const key = asset.address ?? asset.symbol
259
+ return this.mockTokenBalances.get(key) ?? 0n
260
+ }
261
+
262
+ /**
263
+ * Get Bitcoin addresses
264
+ */
265
+ async getAddresses(): Promise<BitcoinAddress[]> {
266
+ this.requireConnected()
267
+ await this.simulateLatency()
268
+
269
+ return [
270
+ {
271
+ address: this.mockAddress,
272
+ publicKey: this.mockPubKey,
273
+ type: 'p2tr',
274
+ },
275
+ ]
276
+ }
277
+
278
+ /**
279
+ * Get detailed balance information
280
+ */
281
+ async getBalanceDetails(): Promise<BitcoinBalance> {
282
+ this.requireConnected()
283
+ await this.simulateLatency()
284
+
285
+ // Split balance into confirmed/unconfirmed for realism
286
+ const confirmed = (this.mockBalance * 9n) / 10n
287
+ const unconfirmed = this.mockBalance - confirmed
288
+
289
+ return {
290
+ confirmed,
291
+ unconfirmed,
292
+ total: this.mockBalance,
293
+ }
294
+ }
295
+
296
+ /**
297
+ * Sign a PSBT directly
298
+ */
299
+ async signPsbt(psbtHex: string, options?: SignPsbtOptions): Promise<string> {
300
+ this.requireConnected()
301
+ await this.simulateLatency()
302
+
303
+ if (this.shouldFailSign) {
304
+ throw new WalletError('Mock signing failure', WalletErrorCode.SIGNING_REJECTED)
305
+ }
306
+
307
+ this.signedPsbts.push(psbtHex)
308
+
309
+ // Create mock signed PSBT
310
+ const mockSignedPsbt = psbtHex + '0'.repeat(128)
311
+ return mockSignedPsbt
312
+ }
313
+
314
+ /**
315
+ * Push a raw transaction to the network
316
+ */
317
+ async pushTx(rawTx: string): Promise<string> {
318
+ this.requireConnected()
319
+ await this.simulateLatency()
320
+
321
+ if (this.shouldFailTransaction) {
322
+ throw new WalletError('Mock transaction failure', WalletErrorCode.TRANSACTION_FAILED)
323
+ }
324
+
325
+ // Generate mock transaction ID
326
+ const txid = Array.from({ length: 64 }, () =>
327
+ Math.floor(Math.random() * 16).toString(16)
328
+ ).join('')
329
+
330
+ this.broadcastTxs.push(txid)
331
+ return txid
332
+ }
333
+
334
+ // ── Mock Control Methods ──────────────────────────────────────────────────
335
+
336
+ /**
337
+ * Set mock balance
338
+ */
339
+ setMockBalance(balance: bigint): void {
340
+ this.mockBalance = balance
341
+ }
342
+
343
+ /**
344
+ * Set mock token balance
345
+ */
346
+ setMockTokenBalance(inscriptionId: string, balance: bigint): void {
347
+ this.mockTokenBalances.set(inscriptionId, balance)
348
+ }
349
+
350
+ /**
351
+ * Get all signed PSBTs (for verification)
352
+ */
353
+ getSignedPsbts(): string[] {
354
+ return [...this.signedPsbts]
355
+ }
356
+
357
+ /**
358
+ * Get all signed messages (for verification)
359
+ */
360
+ getSignedMessages(): string[] {
361
+ return [...this.signedMessages]
362
+ }
363
+
364
+ /**
365
+ * Get all broadcast transactions (for verification)
366
+ */
367
+ getBroadcastTransactions(): string[] {
368
+ return [...this.broadcastTxs]
369
+ }
370
+
371
+ /**
372
+ * Clear transaction history
373
+ */
374
+ clearTransactionHistory(): void {
375
+ this.signedPsbts = []
376
+ this.signedMessages = []
377
+ this.broadcastTxs = []
378
+ }
379
+
380
+ /**
381
+ * Simulate an account change event
382
+ */
383
+ simulateAccountChange(newAddress: string, newPubKey?: string): void {
384
+ const previousAddress = this._address
385
+ this.mockAddress = newAddress
386
+ this._address = newAddress
387
+
388
+ // Update public key
389
+ if (newPubKey) {
390
+ this.mockPubKey = newPubKey
391
+ this._publicKey = bitcoinPublicKeyToHex(newPubKey)
392
+ }
393
+
394
+ this.emitAccountChanged(previousAddress, newAddress)
395
+ }
396
+
397
+ /**
398
+ * Simulate a disconnect event
399
+ */
400
+ simulateDisconnect(): void {
401
+ this.setDisconnected('Simulated disconnect')
402
+ }
403
+
404
+ /**
405
+ * Simulate network change
406
+ */
407
+ simulateNetworkChange(newNetwork: BitcoinNetwork): void {
408
+ this.network = newNetwork
409
+ // Bitcoin wallets typically disconnect on network change
410
+ this.simulateDisconnect()
411
+ }
412
+
413
+ private async simulateLatency(): Promise<void> {
414
+ if (this.latency > 0) {
415
+ await new Promise((resolve) => setTimeout(resolve, this.latency))
416
+ }
417
+ }
418
+ }
419
+
420
+ /**
421
+ * Create a mock Bitcoin wallet provider for testing real adapter
422
+ */
423
+ export function createMockBitcoinProvider(
424
+ config: MockBitcoinAdapterConfig = {}
425
+ ): UnisatAPI {
426
+ const address = config.address ?? 'bc1p5d7rjq7g6rdk2yhzks9smlaqtedr4dekq08ge8ztwac72sfr9rusxg3297'
427
+ const publicKey = config.publicKey ?? 'a3c89044f0057b4e6f0abf99a35b4df9c2e8dbfe0c9db9e5d1f8d08e8e09a9c1'
428
+ const balance = config.balance ?? 100_000_000n
429
+ const network = config.network ?? 'livenet'
430
+
431
+ return {
432
+ async requestAccounts(): Promise<string[]> {
433
+ if (config.shouldFailConnect) {
434
+ throw new Error('User cancelled the request')
435
+ }
436
+ return [address]
437
+ },
438
+
439
+ async getAccounts(): Promise<string[]> {
440
+ return [address]
441
+ },
442
+
443
+ async getPublicKey(): Promise<string> {
444
+ return publicKey
445
+ },
446
+
447
+ async getBalance(): Promise<{ confirmed: number; unconfirmed: number; total: number }> {
448
+ const total = Number(balance)
449
+ const confirmed = Math.floor(total * 0.9)
450
+ const unconfirmed = total - confirmed
451
+
452
+ return {
453
+ confirmed,
454
+ unconfirmed,
455
+ total,
456
+ }
457
+ },
458
+
459
+ async signPsbt(psbtHex: string, options?: SignPsbtOptions): Promise<string> {
460
+ if (config.shouldFailSign) {
461
+ throw new Error('User rejected the request')
462
+ }
463
+
464
+ // Return mock signed PSBT
465
+ return psbtHex + '0'.repeat(128)
466
+ },
467
+
468
+ async signMessage(message: string, type: 'ecdsa' | 'bip322-simple' = 'ecdsa'): Promise<string> {
469
+ if (config.shouldFailSign) {
470
+ throw new Error('User rejected the request')
471
+ }
472
+
473
+ // Return mock base64 signature
474
+ const mockSig = new Uint8Array(64)
475
+ for (let i = 0; i < 64; i++) {
476
+ mockSig[i] = message.charCodeAt(i % message.length) ^ i
477
+ }
478
+ return Buffer.from(mockSig).toString('base64')
479
+ },
480
+
481
+ async pushTx(rawTx: string): Promise<string> {
482
+ if (config.shouldFailTransaction) {
483
+ throw new Error('Transaction failed: insufficient funds')
484
+ }
485
+
486
+ // Return mock transaction ID
487
+ return Array.from({ length: 64 }, () =>
488
+ Math.floor(Math.random() * 16).toString(16)
489
+ ).join('')
490
+ },
491
+
492
+ async getNetwork(): Promise<BitcoinNetwork> {
493
+ return network
494
+ },
495
+
496
+ async switchNetwork(newNetwork: BitcoinNetwork): Promise<void> {
497
+ // Mock network switch
498
+ },
499
+
500
+ async getChain(): Promise<{ enum: string; name: string }> {
501
+ return {
502
+ enum: network === 'livenet' ? 'BITCOIN_MAINNET' : 'BITCOIN_TESTNET',
503
+ name: network === 'livenet' ? 'Bitcoin Mainnet' : 'Bitcoin Testnet',
504
+ }
505
+ },
506
+ }
507
+ }
508
+
509
+ /**
510
+ * Create a mock Bitcoin adapter
511
+ */
512
+ export function createMockBitcoinAdapter(
513
+ config: MockBitcoinAdapterConfig = {}
514
+ ): MockBitcoinAdapter {
515
+ return new MockBitcoinAdapter(config)
516
+ }