@sip-protocol/sdk 0.3.2 → 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 (47) hide show
  1. package/dist/browser.d.mts +2 -2
  2. package/dist/browser.d.ts +2 -2
  3. package/dist/browser.js +1019 -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-FKXPHKYD.mjs +12955 -0
  8. package/dist/chunk-OPQ2GQIO.mjs +13013 -0
  9. package/dist/index-BcWNakUD.d.ts +7990 -0
  10. package/dist/index-BsKY3Hr0.d.mts +7990 -0
  11. package/dist/index.d.mts +2 -2
  12. package/dist/index.d.ts +2 -2
  13. package/dist/index.js +990 -117
  14. package/dist/index.mjs +49 -1
  15. package/package.json +2 -1
  16. package/src/adapters/near-intents.ts +8 -0
  17. package/src/bitcoin/index.ts +51 -0
  18. package/src/bitcoin/silent-payments.ts +865 -0
  19. package/src/bitcoin/taproot.ts +590 -0
  20. package/src/cosmos/ibc-stealth.ts +825 -0
  21. package/src/cosmos/index.ts +83 -0
  22. package/src/cosmos/stealth.ts +487 -0
  23. package/src/index.ts +51 -0
  24. package/src/move/aptos.ts +369 -0
  25. package/src/move/index.ts +35 -0
  26. package/src/move/sui.ts +367 -0
  27. package/src/oracle/types.ts +8 -0
  28. package/src/settlement/backends/direct-chain.ts +8 -0
  29. package/src/stealth.ts +3 -3
  30. package/src/validation.ts +42 -1
  31. package/src/wallet/aptos/adapter.ts +422 -0
  32. package/src/wallet/aptos/index.ts +10 -0
  33. package/src/wallet/aptos/mock.ts +410 -0
  34. package/src/wallet/aptos/types.ts +278 -0
  35. package/src/wallet/bitcoin/adapter.ts +470 -0
  36. package/src/wallet/bitcoin/index.ts +38 -0
  37. package/src/wallet/bitcoin/mock.ts +516 -0
  38. package/src/wallet/bitcoin/types.ts +274 -0
  39. package/src/wallet/cosmos/adapter.ts +484 -0
  40. package/src/wallet/cosmos/index.ts +63 -0
  41. package/src/wallet/cosmos/mock.ts +596 -0
  42. package/src/wallet/cosmos/types.ts +462 -0
  43. package/src/wallet/index.ts +127 -0
  44. package/src/wallet/sui/adapter.ts +471 -0
  45. package/src/wallet/sui/index.ts +10 -0
  46. package/src/wallet/sui/mock.ts +439 -0
  47. package/src/wallet/sui/types.ts +245 -0
@@ -0,0 +1,596 @@
1
+ /**
2
+ * Mock Cosmos Wallet Adapter
3
+ *
4
+ * Testing implementation of Cosmos 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
+ Keplr,
21
+ Key,
22
+ StdSignDoc,
23
+ DirectSignDoc,
24
+ AminoSignResponse,
25
+ DirectSignResponse,
26
+ CosmosAccountData,
27
+ CosmosUnsignedTransaction,
28
+ CosmosAlgo,
29
+ StdSignature,
30
+ PubKey,
31
+ } from './types'
32
+ import {
33
+ cosmosPublicKeyToHex,
34
+ getDefaultRpcEndpoint,
35
+ getDefaultRestEndpoint,
36
+ CosmosChainId,
37
+ } from './types'
38
+
39
+ /**
40
+ * Configuration for mock Cosmos adapter
41
+ */
42
+ export interface MockCosmosAdapterConfig {
43
+ /** Mock address (bech32) */
44
+ address?: string
45
+ /** Mock balance in base units */
46
+ balance?: bigint
47
+ /** Token balances by denomination */
48
+ tokenBalances?: Record<string, bigint>
49
+ /** Whether to simulate connection failure */
50
+ shouldFailConnect?: boolean
51
+ /** Whether to simulate signing failure */
52
+ shouldFailSign?: boolean
53
+ /** Whether to simulate transaction failure */
54
+ shouldFailTransaction?: boolean
55
+ /** Simulated chain ID */
56
+ chainId?: string
57
+ /** Simulated latency in ms */
58
+ latency?: number
59
+ /** Algorithm to use */
60
+ algo?: CosmosAlgo
61
+ /** Bech32 prefix */
62
+ bech32Prefix?: string
63
+ }
64
+
65
+ /**
66
+ * Mock Cosmos wallet adapter for testing
67
+ *
68
+ * Provides full Cosmos wallet functionality with mock data.
69
+ * No browser environment or actual wallet required.
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * const wallet = new MockCosmosAdapter({
74
+ * address: 'cosmos1testaddress123',
75
+ * balance: 1_000_000n, // 1 ATOM
76
+ * })
77
+ *
78
+ * await wallet.connect()
79
+ * const balance = await wallet.getBalance() // 1_000_000n
80
+ *
81
+ * // Simulate failures
82
+ * const failingWallet = new MockCosmosAdapter({
83
+ * shouldFailSign: true,
84
+ * })
85
+ * ```
86
+ */
87
+ export class MockCosmosAdapter extends BaseWalletAdapter {
88
+ readonly chain = 'cosmos' as const
89
+ readonly name = 'mock-cosmos'
90
+
91
+ private mockAddress: string
92
+ private mockPubKey: Uint8Array
93
+ private mockBalance: bigint
94
+ private mockTokenBalances: Map<string, bigint>
95
+ private shouldFailConnect: boolean
96
+ private shouldFailSign: boolean
97
+ private shouldFailTransaction: boolean
98
+ private _chainId: string
99
+ private latency: number
100
+ private algo: CosmosAlgo
101
+ private bech32Prefix: string
102
+
103
+ // Track signed transactions for verification
104
+ private signedAmino: StdSignDoc[] = []
105
+ private signedDirect: DirectSignDoc[] = []
106
+ private sentTransactions: string[] = []
107
+
108
+ constructor(config: MockCosmosAdapterConfig = {}) {
109
+ super()
110
+ this.mockAddress = config.address ?? 'cosmos1mockaddress1234567890abcdef'
111
+ this.mockBalance = config.balance ?? 1_000_000n // 1 ATOM default
112
+ this.mockTokenBalances = new Map(Object.entries(config.tokenBalances ?? {}))
113
+ this.shouldFailConnect = config.shouldFailConnect ?? false
114
+ this.shouldFailSign = config.shouldFailSign ?? false
115
+ this.shouldFailTransaction = config.shouldFailTransaction ?? false
116
+ this._chainId = config.chainId ?? CosmosChainId.COSMOSHUB
117
+ this.latency = config.latency ?? 10
118
+ this.algo = config.algo ?? 'secp256k1'
119
+ this.bech32Prefix = config.bech32Prefix ?? 'cosmos'
120
+
121
+ // Create deterministic mock public key
122
+ this.mockPubKey = new Uint8Array(33)
123
+ for (let i = 0; i < 33; i++) {
124
+ this.mockPubKey[i] = this.mockAddress.charCodeAt(i % this.mockAddress.length) ^ i
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Get the current Cosmos chain ID
130
+ */
131
+ getChainId(): string {
132
+ return this._chainId
133
+ }
134
+
135
+ /**
136
+ * Get RPC endpoint
137
+ */
138
+ getRpcEndpoint(): string {
139
+ return getDefaultRpcEndpoint(this._chainId)
140
+ }
141
+
142
+ /**
143
+ * Get REST endpoint
144
+ */
145
+ getRestEndpoint(): string {
146
+ return getDefaultRestEndpoint(this._chainId)
147
+ }
148
+
149
+ /**
150
+ * Get Bech32 prefix
151
+ */
152
+ getBech32Prefix(): string {
153
+ return this.bech32Prefix
154
+ }
155
+
156
+ /**
157
+ * Connect to the mock wallet
158
+ */
159
+ async connect(): Promise<void> {
160
+ this._connectionState = 'connecting'
161
+
162
+ // Simulate network latency
163
+ await this.simulateLatency()
164
+
165
+ if (this.shouldFailConnect) {
166
+ this.setError(WalletErrorCode.CONNECTION_FAILED, 'Mock connection failure')
167
+ throw new WalletError('Mock connection failure', WalletErrorCode.CONNECTION_FAILED)
168
+ }
169
+
170
+ const hexPubKey = cosmosPublicKeyToHex(this.mockPubKey)
171
+ this.setConnected(this.mockAddress, hexPubKey)
172
+ }
173
+
174
+ /**
175
+ * Disconnect from the mock wallet
176
+ */
177
+ async disconnect(): Promise<void> {
178
+ await this.simulateLatency()
179
+ this.setDisconnected('User disconnected')
180
+ }
181
+
182
+ /**
183
+ * Sign a message
184
+ */
185
+ async signMessage(message: Uint8Array): Promise<Signature> {
186
+ this.requireConnected()
187
+ await this.simulateLatency()
188
+
189
+ if (this.shouldFailSign) {
190
+ throw new WalletError('Mock signing failure', WalletErrorCode.SIGNING_REJECTED)
191
+ }
192
+
193
+ // Create deterministic mock signature
194
+ const mockSig = new Uint8Array(64)
195
+ for (let i = 0; i < 64; i++) {
196
+ mockSig[i] = (message[i % message.length] ?? 0) ^ (i * 7) ^ this.mockAddress.charCodeAt(i % this.mockAddress.length)
197
+ }
198
+
199
+ return {
200
+ signature: ('0x' + Buffer.from(mockSig).toString('hex')) as HexString,
201
+ publicKey: this._publicKey as HexString,
202
+ }
203
+ }
204
+
205
+ /**
206
+ * Sign a transaction
207
+ */
208
+ async signTransaction(tx: UnsignedTransaction): Promise<SignedTransaction> {
209
+ this.requireConnected()
210
+ await this.simulateLatency()
211
+
212
+ if (this.shouldFailSign) {
213
+ throw new WalletError('Mock signing failure', WalletErrorCode.SIGNING_REJECTED)
214
+ }
215
+
216
+ const cosmosTx = tx.data as CosmosUnsignedTransaction
217
+
218
+ if (cosmosTx.aminoSignDoc) {
219
+ this.signedAmino.push(cosmosTx.aminoSignDoc)
220
+ } else if (cosmosTx.directSignDoc) {
221
+ this.signedDirect.push(cosmosTx.directSignDoc)
222
+ }
223
+
224
+ // Serialize transaction data, handling BigInt
225
+ const txDataStr = JSON.stringify(tx.data, (_, value) =>
226
+ typeof value === 'bigint' ? value.toString() : value
227
+ )
228
+ const signature = await this.signMessage(
229
+ new TextEncoder().encode(txDataStr)
230
+ )
231
+
232
+ // Serialize transaction data, handling BigInt
233
+ const serializedData = JSON.stringify(tx.data, (_, value) =>
234
+ typeof value === 'bigint' ? value.toString() : value
235
+ )
236
+
237
+ return {
238
+ unsigned: tx,
239
+ signatures: [signature],
240
+ serialized: ('0x' + Buffer.from(serializedData).toString('hex')) as HexString,
241
+ }
242
+ }
243
+
244
+ /**
245
+ * Sign and send a transaction
246
+ */
247
+ async signAndSendTransaction(tx: UnsignedTransaction): Promise<TransactionReceipt> {
248
+ this.requireConnected()
249
+ await this.simulateLatency()
250
+
251
+ if (this.shouldFailSign) {
252
+ throw new WalletError('Mock signing failure', WalletErrorCode.SIGNING_REJECTED)
253
+ }
254
+
255
+ if (this.shouldFailTransaction) {
256
+ throw new WalletError('Mock transaction failure', WalletErrorCode.TRANSACTION_FAILED)
257
+ }
258
+
259
+ // Generate mock transaction hash
260
+ const txHash = `cosmos_tx_${Date.now()}_${Math.random().toString(36).slice(2)}`
261
+ this.sentTransactions.push(txHash)
262
+
263
+ return {
264
+ txHash: ('0x' + Buffer.from(txHash).toString('hex')) as HexString,
265
+ status: 'confirmed',
266
+ blockNumber: BigInt(Math.floor(Math.random() * 1000000)),
267
+ timestamp: Date.now(),
268
+ }
269
+ }
270
+
271
+ /**
272
+ * Get native balance
273
+ */
274
+ async getBalance(): Promise<bigint> {
275
+ this.requireConnected()
276
+ await this.simulateLatency()
277
+ return this.mockBalance
278
+ }
279
+
280
+ /**
281
+ * Get token balance
282
+ */
283
+ async getTokenBalance(asset: Asset): Promise<bigint> {
284
+ this.requireConnected()
285
+ await this.simulateLatency()
286
+
287
+ if (asset.chain !== 'cosmos') {
288
+ throw new WalletError(
289
+ `Asset chain ${asset.chain} not supported by Cosmos adapter`,
290
+ WalletErrorCode.UNSUPPORTED_CHAIN
291
+ )
292
+ }
293
+
294
+ const denom = asset.address ?? asset.symbol.toLowerCase()
295
+ return this.mockTokenBalances.get(denom) ?? 0n
296
+ }
297
+
298
+ /**
299
+ * Sign using Amino
300
+ */
301
+ async signAmino(
302
+ signerAddress: string,
303
+ signDoc: StdSignDoc
304
+ ): Promise<AminoSignResponse> {
305
+ this.requireConnected()
306
+ await this.simulateLatency()
307
+
308
+ if (this.shouldFailSign) {
309
+ throw new WalletError('Mock signing failure', WalletErrorCode.SIGNING_REJECTED)
310
+ }
311
+
312
+ this.signedAmino.push(signDoc)
313
+
314
+ const signature = await this.signMessage(
315
+ new TextEncoder().encode(JSON.stringify(signDoc))
316
+ )
317
+
318
+ const stdSig: StdSignature = {
319
+ pub_key: {
320
+ type: 'tendermint/PubKeySecp256k1',
321
+ value: Buffer.from(this.mockPubKey).toString('base64'),
322
+ },
323
+ signature: Buffer.from(signature.signature.slice(2), 'hex').toString('base64'),
324
+ }
325
+
326
+ return {
327
+ signed: signDoc,
328
+ signature: stdSig,
329
+ }
330
+ }
331
+
332
+ /**
333
+ * Sign using Direct
334
+ */
335
+ async signDirect(
336
+ signerAddress: string,
337
+ signDoc: DirectSignDoc
338
+ ): Promise<DirectSignResponse> {
339
+ this.requireConnected()
340
+ await this.simulateLatency()
341
+
342
+ if (this.shouldFailSign) {
343
+ throw new WalletError('Mock signing failure', WalletErrorCode.SIGNING_REJECTED)
344
+ }
345
+
346
+ this.signedDirect.push(signDoc)
347
+
348
+ const signature = await this.signMessage(
349
+ new Uint8Array([...signDoc.bodyBytes, ...signDoc.authInfoBytes])
350
+ )
351
+
352
+ const stdSig: StdSignature = {
353
+ pub_key: {
354
+ type: 'tendermint/PubKeySecp256k1',
355
+ value: Buffer.from(this.mockPubKey).toString('base64'),
356
+ },
357
+ signature: Buffer.from(signature.signature.slice(2), 'hex').toString('base64'),
358
+ }
359
+
360
+ return {
361
+ signed: signDoc,
362
+ signature: stdSig,
363
+ }
364
+ }
365
+
366
+ /**
367
+ * Get key info
368
+ */
369
+ getKeyInfo(): Key {
370
+ return {
371
+ name: 'Mock Cosmos Account',
372
+ algo: this.algo,
373
+ pubKey: this.mockPubKey,
374
+ address: this.mockAddress,
375
+ bech32Address: this.mockAddress,
376
+ }
377
+ }
378
+
379
+ // ── Mock Control Methods ──────────────────────────────────────────────────
380
+
381
+ /**
382
+ * Set mock balance
383
+ */
384
+ setMockBalance(balance: bigint): void {
385
+ this.mockBalance = balance
386
+ }
387
+
388
+ /**
389
+ * Set mock token balance
390
+ */
391
+ setMockTokenBalance(denom: string, balance: bigint): void {
392
+ this.mockTokenBalances.set(denom, balance)
393
+ }
394
+
395
+ /**
396
+ * Get all signed Amino transactions (for verification)
397
+ */
398
+ getSignedAminoTransactions(): StdSignDoc[] {
399
+ return [...this.signedAmino]
400
+ }
401
+
402
+ /**
403
+ * Get all signed Direct transactions (for verification)
404
+ */
405
+ getSignedDirectTransactions(): DirectSignDoc[] {
406
+ return [...this.signedDirect]
407
+ }
408
+
409
+ /**
410
+ * Get all sent transaction hashes (for verification)
411
+ */
412
+ getSentTransactions(): string[] {
413
+ return [...this.sentTransactions]
414
+ }
415
+
416
+ /**
417
+ * Clear transaction history
418
+ */
419
+ clearTransactionHistory(): void {
420
+ this.signedAmino = []
421
+ this.signedDirect = []
422
+ this.sentTransactions = []
423
+ }
424
+
425
+ /**
426
+ * Simulate an account change event
427
+ */
428
+ simulateAccountChange(newAddress: string): void {
429
+ const previousAddress = this._address
430
+ this.mockAddress = newAddress
431
+ this._address = newAddress
432
+
433
+ // Update public key
434
+ this.mockPubKey = new Uint8Array(33)
435
+ for (let i = 0; i < 33; i++) {
436
+ this.mockPubKey[i] = newAddress.charCodeAt(i % newAddress.length) ^ i
437
+ }
438
+ this._publicKey = cosmosPublicKeyToHex(this.mockPubKey)
439
+
440
+ this.emitAccountChanged(previousAddress, newAddress)
441
+ }
442
+
443
+ /**
444
+ * Simulate a disconnect event
445
+ */
446
+ simulateDisconnect(): void {
447
+ this.setDisconnected('Simulated disconnect')
448
+ }
449
+
450
+ private async simulateLatency(): Promise<void> {
451
+ if (this.latency > 0) {
452
+ await new Promise((resolve) => setTimeout(resolve, this.latency))
453
+ }
454
+ }
455
+ }
456
+
457
+ /**
458
+ * Create a mock Cosmos wallet provider for testing real adapter
459
+ */
460
+ export function createMockCosmosProvider(
461
+ config: MockCosmosAdapterConfig = {}
462
+ ): Keplr {
463
+ const address = config.address ?? 'cosmos1mockaddress1234567890abcdef'
464
+ const chainId = config.chainId ?? CosmosChainId.COSMOSHUB
465
+ const algo = config.algo ?? 'secp256k1'
466
+
467
+ const mockPubKey = new Uint8Array(33)
468
+ for (let i = 0; i < 33; i++) {
469
+ mockPubKey[i] = address.charCodeAt(i % address.length) ^ i
470
+ }
471
+
472
+ const key: Key = {
473
+ name: 'Mock Cosmos Account',
474
+ algo,
475
+ pubKey: mockPubKey,
476
+ address,
477
+ bech32Address: address,
478
+ }
479
+
480
+ return {
481
+ async enable() {
482
+ if (config.shouldFailConnect) {
483
+ throw new Error('Request rejected by user')
484
+ }
485
+ },
486
+
487
+ async getKey() {
488
+ return key
489
+ },
490
+
491
+ async signAmino(chainId: string, signer: string, signDoc: StdSignDoc): Promise<AminoSignResponse> {
492
+ if (config.shouldFailSign) {
493
+ throw new Error('Request rejected by user')
494
+ }
495
+
496
+ const mockSig: StdSignature = {
497
+ pub_key: {
498
+ type: 'tendermint/PubKeySecp256k1',
499
+ value: Buffer.from(mockPubKey).toString('base64'),
500
+ },
501
+ signature: Buffer.from(new Uint8Array(64).fill(1)).toString('base64'),
502
+ }
503
+
504
+ return {
505
+ signed: signDoc,
506
+ signature: mockSig,
507
+ }
508
+ },
509
+
510
+ async signDirect(chainId: string, signer: string, signDoc: {
511
+ bodyBytes?: Uint8Array | null
512
+ authInfoBytes?: Uint8Array | null
513
+ chainId?: string | null
514
+ accountNumber?: bigint | null
515
+ }): Promise<DirectSignResponse> {
516
+ if (config.shouldFailSign) {
517
+ throw new Error('Request rejected by user')
518
+ }
519
+
520
+ const mockSig: StdSignature = {
521
+ pub_key: {
522
+ type: 'tendermint/PubKeySecp256k1',
523
+ value: Buffer.from(mockPubKey).toString('base64'),
524
+ },
525
+ signature: Buffer.from(new Uint8Array(64).fill(1)).toString('base64'),
526
+ }
527
+
528
+ return {
529
+ signed: {
530
+ bodyBytes: signDoc.bodyBytes ?? new Uint8Array(),
531
+ authInfoBytes: signDoc.authInfoBytes ?? new Uint8Array(),
532
+ chainId: signDoc.chainId ?? chainId,
533
+ accountNumber: signDoc.accountNumber ?? 0n,
534
+ },
535
+ signature: mockSig,
536
+ }
537
+ },
538
+
539
+ async signArbitrary(_chainId: string, _signer: string, data: string | Uint8Array): Promise<StdSignature> {
540
+ if (config.shouldFailSign) {
541
+ throw new Error('Request rejected by user')
542
+ }
543
+
544
+ return {
545
+ pub_key: {
546
+ type: 'tendermint/PubKeySecp256k1',
547
+ value: Buffer.from(mockPubKey).toString('base64'),
548
+ },
549
+ signature: Buffer.from(new Uint8Array(64).fill(1)).toString('base64'),
550
+ }
551
+ },
552
+
553
+ async verifyArbitrary(): Promise<boolean> {
554
+ return true
555
+ },
556
+
557
+ async getOfflineSignerAuto(_chainId: string) {
558
+ return {
559
+ async getAccounts(): Promise<readonly CosmosAccountData[]> {
560
+ return [{ address, algo, pubkey: mockPubKey }]
561
+ },
562
+ async signDirect(signerAddress: string, signDoc: DirectSignDoc): Promise<DirectSignResponse> {
563
+ return this.signDirect(chainId, signerAddress, signDoc)
564
+ },
565
+ } as any
566
+ },
567
+
568
+ async getOfflineSignerOnlyAmino(_chainId: string) {
569
+ return {
570
+ async getAccounts(): Promise<readonly CosmosAccountData[]> {
571
+ return [{ address, algo, pubkey: mockPubKey }]
572
+ },
573
+ async signAmino(signerAddress: string, signDoc: StdSignDoc): Promise<AminoSignResponse> {
574
+ return this.signAmino(chainId, signerAddress, signDoc)
575
+ },
576
+ } as any
577
+ },
578
+
579
+ async getOfflineSigner(chainId: string) {
580
+ return this.getOfflineSignerAuto(chainId)
581
+ },
582
+
583
+ async experimentalSuggestChain() {
584
+ // No-op for mock
585
+ },
586
+ } as Keplr
587
+ }
588
+
589
+ /**
590
+ * Create a mock Cosmos adapter
591
+ */
592
+ export function createMockCosmosAdapter(
593
+ config: MockCosmosAdapterConfig = {}
594
+ ): MockCosmosAdapter {
595
+ return new MockCosmosAdapter(config)
596
+ }