clawcash 0.1.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.
package/dist/index.mjs ADDED
@@ -0,0 +1,1021 @@
1
+ import { HDNodeWallet, Mnemonic, ethers } from 'ethers';
2
+
3
+ // src/core/key-manager.ts
4
+ var DERIVATION_PATHS = {
5
+ // Ethereum and EVM-compatible chains use the same path
6
+ ethereum: "44'/60'/0'/0/0",
7
+ polygon: "44'/60'/0'/0/0",
8
+ bsc: "44'/60'/0'/0/0",
9
+ arbitrum: "44'/60'/0'/0/0",
10
+ // Bitcoin
11
+ bitcoin: "44'/0'/0'/0/0"
12
+ };
13
+ var KeyManager = class {
14
+ mnemonic;
15
+ derivedKeys = /* @__PURE__ */ new Map();
16
+ /**
17
+ * Create a new KeyManager from a mnemonic
18
+ * @param mnemonic - BIP39 mnemonic phrase
19
+ */
20
+ constructor(mnemonic) {
21
+ this.mnemonic = mnemonic;
22
+ }
23
+ /**
24
+ * Derive a private key for a specific chain
25
+ * @param chain - The blockchain network
26
+ * @returns The derived private key (never exposed in API)
27
+ */
28
+ derivePrivateKey(chain) {
29
+ if (this.derivedKeys.has(chain)) {
30
+ return this.derivedKeys.get(chain);
31
+ }
32
+ const path = DERIVATION_PATHS[chain];
33
+ const wallet = HDNodeWallet.fromPhrase(this.mnemonic, "", "m/" + path);
34
+ const privateKey = wallet.privateKey;
35
+ this.derivedKeys.set(chain, privateKey);
36
+ return privateKey;
37
+ }
38
+ /**
39
+ * Get the master mnemonic
40
+ * @returns The mnemonic phrase (handle with care!)
41
+ */
42
+ getMnemonic() {
43
+ return this.mnemonic;
44
+ }
45
+ /**
46
+ * Export all derived private keys (for backup only)
47
+ * @returns Record of chain to private key
48
+ */
49
+ exportPrivateKeys() {
50
+ const result = {};
51
+ for (const chain of Object.keys(DERIVATION_PATHS)) {
52
+ result[chain] = this.derivePrivateKey(chain);
53
+ }
54
+ return result;
55
+ }
56
+ /**
57
+ * Clear all derived keys from memory
58
+ */
59
+ clear() {
60
+ this.derivedKeys.clear();
61
+ }
62
+ /**
63
+ * Get the extended public key (xpub) for the wallet
64
+ * @returns The extended public key
65
+ */
66
+ getExtendedPublicKey() {
67
+ const wallet = HDNodeWallet.fromPhrase(this.mnemonic);
68
+ return wallet.extendedKey;
69
+ }
70
+ };
71
+ function generateMnemonic() {
72
+ const array = new Uint8Array(16);
73
+ crypto.getRandomValues(array);
74
+ return Mnemonic.fromEntropy(array).phrase;
75
+ }
76
+ function validateMnemonic(mnemonic) {
77
+ try {
78
+ Mnemonic.fromPhrase(mnemonic);
79
+ return true;
80
+ } catch {
81
+ return false;
82
+ }
83
+ }
84
+ function mnemonicToEntropy(mnemonic) {
85
+ return Mnemonic.fromPhrase(mnemonic).entropy;
86
+ }
87
+ function entropyToMnemonic(entropy) {
88
+ return Mnemonic.fromEntropy(entropy).phrase;
89
+ }
90
+
91
+ // src/chains/base.ts
92
+ var BaseChain = class {
93
+ /** Chain identifier */
94
+ chainId;
95
+ /** Chain name */
96
+ name;
97
+ /** RPC URL */
98
+ rpcUrl;
99
+ /** Block explorer URL */
100
+ explorerUrl;
101
+ constructor(chainId, name, rpcUrl, explorerUrl) {
102
+ this.chainId = chainId;
103
+ this.name = name;
104
+ this.rpcUrl = rpcUrl;
105
+ this.explorerUrl = explorerUrl;
106
+ }
107
+ /**
108
+ * Get block explorer URL for a transaction
109
+ * @param txHash - Transaction hash
110
+ */
111
+ getExplorerUrl(txHash) {
112
+ if (txHash) {
113
+ return `${this.explorerUrl}/tx/${txHash}`;
114
+ }
115
+ return this.explorerUrl;
116
+ }
117
+ /**
118
+ * Get block explorer URL for an address
119
+ * @param address - Wallet address
120
+ */
121
+ getAddressExplorerUrl(address) {
122
+ return `${this.explorerUrl}/address/${address}`;
123
+ }
124
+ /**
125
+ * Get chain info
126
+ */
127
+ getInfo() {
128
+ return {
129
+ chainId: this.chainId,
130
+ name: this.name,
131
+ rpcUrl: this.rpcUrl,
132
+ explorerUrl: this.explorerUrl
133
+ };
134
+ }
135
+ };
136
+ var ChainRegistry = {};
137
+ function registerChain(chain, factory) {
138
+ ChainRegistry[chain] = factory;
139
+ }
140
+ function getChain(chain, privateKey, rpcUrl) {
141
+ const factory = ChainRegistry[chain];
142
+ if (!factory) {
143
+ throw new Error(`Chain ${chain} not implemented`);
144
+ }
145
+ return factory(privateKey, rpcUrl);
146
+ }
147
+
148
+ // src/chains/evm/ethereum.ts
149
+ var DEFAULT_RPCS = {
150
+ ethereum: "https://eth.llamarpc.com",
151
+ polygon: "https://polygon-rpc.com",
152
+ bsc: "https://bsc-dataseed.binance.org",
153
+ arbitrum: "https://arbitrum-one.publicnode.com"
154
+ };
155
+ var CHAIN_IDS = {
156
+ ethereum: 1,
157
+ polygon: 137,
158
+ bsc: 56,
159
+ arbitrum: 42161
160
+ };
161
+ var EthereumChain = class extends BaseChain {
162
+ privateKey;
163
+ wallet;
164
+ provider;
165
+ constructor(chain, privateKey, rpcUrl) {
166
+ const config = {
167
+ chainId: CHAIN_IDS[chain].toString(),
168
+ name: chain.charAt(0).toUpperCase() + chain.slice(1),
169
+ rpcUrl: rpcUrl || DEFAULT_RPCS[chain],
170
+ explorerUrl: {
171
+ ethereum: "https://etherscan.io",
172
+ polygon: "https://polygonscan.com",
173
+ bsc: "https://bscscan.com",
174
+ arbitrum: "https://arbiscan.io"
175
+ }[chain]
176
+ };
177
+ super(config.chainId, config.name, config.rpcUrl, config.explorerUrl);
178
+ this.privateKey = privateKey;
179
+ this.provider = new ethers.JsonRpcProvider(this.rpcUrl);
180
+ this.wallet = new ethers.Wallet(this.privateKey, this.provider);
181
+ }
182
+ /**
183
+ * Connect to the chain
184
+ */
185
+ async connect() {
186
+ try {
187
+ await this.provider.getNetwork();
188
+ } catch (error) {
189
+ throw new Error(`Failed to connect to ${this.name}: ${error}`);
190
+ }
191
+ }
192
+ /**
193
+ * Disconnect from the chain
194
+ */
195
+ disconnect() {
196
+ }
197
+ /**
198
+ * Get the wallet address
199
+ */
200
+ getAddress() {
201
+ return this.wallet.address;
202
+ }
203
+ /**
204
+ * Validate an Ethereum address
205
+ */
206
+ validateAddress(address) {
207
+ return ethers.isAddress(address);
208
+ }
209
+ /**
210
+ * Get balance (native or ERC-20 token)
211
+ */
212
+ async getBalance(tokenAddress) {
213
+ let amount;
214
+ let decimals;
215
+ let symbol;
216
+ if (!tokenAddress) {
217
+ amount = await this.provider.getBalance(this.wallet.address);
218
+ decimals = 18;
219
+ symbol = this.name === "Polygon" ? "MATIC" : this.name === "Bsc" ? "BNB" : "ETH";
220
+ } else {
221
+ const erc20Abi = [
222
+ "function balanceOf(address) view returns (uint256)",
223
+ "function decimals() view returns (uint8)",
224
+ "function symbol() view returns (string)"
225
+ ];
226
+ const contract = new ethers.Contract(tokenAddress, erc20Abi, this.provider);
227
+ const [balanceAmount, tokenDecimals, tokenSymbol] = await Promise.all([
228
+ contract.balanceOf(this.wallet.address),
229
+ contract.decimals(),
230
+ contract.symbol()
231
+ ]);
232
+ amount = balanceAmount;
233
+ decimals = Number(tokenDecimals);
234
+ symbol = tokenSymbol;
235
+ }
236
+ const formatted = ethers.formatUnits(amount, decimals);
237
+ return {
238
+ amount,
239
+ formatted,
240
+ symbol,
241
+ decimals
242
+ };
243
+ }
244
+ /**
245
+ * Estimate transaction fee
246
+ */
247
+ async estimateFee(params) {
248
+ const { to, amount, token } = params;
249
+ let gasLimit;
250
+ let gasPrice;
251
+ if (token === "ETH" || token === "MATIC" || token === "BNB") {
252
+ gasLimit = 21000n;
253
+ } else {
254
+ const erc20Abi = ["function transfer(address,uint256) returns (bool)"];
255
+ const contract = new ethers.Contract(to, erc20Abi, this.wallet);
256
+ const parsedAmount = ethers.parseUnits(amount, 18);
257
+ gasLimit = await contract.transfer.estimateGas(to, parsedAmount);
258
+ }
259
+ const feeData = await this.provider.getFeeData();
260
+ gasPrice = feeData.gasPrice || 0n;
261
+ const gasFee = gasLimit * gasPrice;
262
+ const formatted = ethers.formatEther(gasFee);
263
+ return {
264
+ gasFee,
265
+ gasPrice,
266
+ gasLimit,
267
+ formatted
268
+ };
269
+ }
270
+ /**
271
+ * Send a transaction
272
+ */
273
+ async sendTransaction(params) {
274
+ const { to, amount, token } = params;
275
+ if (token === "ETH" || token === "MATIC" || token === "BNB") {
276
+ const tx = await this.wallet.sendTransaction({
277
+ to,
278
+ value: ethers.parseEther(amount)
279
+ });
280
+ return tx.hash;
281
+ } else {
282
+ throw new Error("ERC-20 transfers require token address configuration");
283
+ }
284
+ }
285
+ /**
286
+ * Sign a message
287
+ */
288
+ async signMessage(message) {
289
+ return await this.wallet.signMessage(message);
290
+ }
291
+ };
292
+ function ethereumFactory(chain) {
293
+ return (privateKey, rpcUrl) => new EthereumChain(chain, privateKey, rpcUrl);
294
+ }
295
+
296
+ // src/chains/bitcoin/bitcoin.ts
297
+ var BitcoinChain = class extends BaseChain {
298
+ privateKey;
299
+ address;
300
+ constructor(privateKey, rpcUrl) {
301
+ super(
302
+ "bitcoin",
303
+ "Bitcoin",
304
+ rpcUrl || "https://blockstream.info/api",
305
+ "https://blockstream.info"
306
+ );
307
+ this.privateKey = privateKey;
308
+ this.address = this.deriveAddress();
309
+ }
310
+ /**
311
+ * Connect to Bitcoin network (uses block explorer API)
312
+ */
313
+ async connect() {
314
+ }
315
+ /**
316
+ * Disconnect (no-op for Bitcoin)
317
+ */
318
+ disconnect() {
319
+ }
320
+ /**
321
+ * Derive Bitcoin address from private key
322
+ */
323
+ deriveAddress() {
324
+ return "bc1q" + this.privateKey.slice(2, 40);
325
+ }
326
+ /**
327
+ * Get Bitcoin address
328
+ */
329
+ getAddress() {
330
+ return this.address;
331
+ }
332
+ /**
333
+ * Validate Bitcoin address
334
+ */
335
+ validateAddress(address) {
336
+ return /^1[1-9A-HJ-NP-Za-km-z]{25,39}$/.test(address) || // Legacy
337
+ /^3[1-9A-HJ-NP-Za-km-z]{25,39}$/.test(address) || // P2SH
338
+ /^bc1[a-z0-9]{39,59}$/.test(address);
339
+ }
340
+ /**
341
+ * Get Bitcoin balance (using block explorer API)
342
+ */
343
+ async getBalance() {
344
+ try {
345
+ const url = this.rpcUrl + "/address/" + this.address;
346
+ const response = await fetch(url);
347
+ const data = await response.json();
348
+ const satoshis = BigInt(data.chain_stats.funded_txo_sum - data.chain_stats.spent_txo_sum);
349
+ const btc = Number(satoshis) / 1e8;
350
+ return {
351
+ amount: satoshis,
352
+ formatted: btc.toFixed(8),
353
+ symbol: "BTC",
354
+ decimals: 8
355
+ };
356
+ } catch (_error) {
357
+ return {
358
+ amount: 0n,
359
+ formatted: "0",
360
+ symbol: "BTC",
361
+ decimals: 8
362
+ };
363
+ }
364
+ }
365
+ /**
366
+ * Estimate Bitcoin transaction fee
367
+ */
368
+ async estimateFee(_params) {
369
+ try {
370
+ const url = this.rpcUrl + "/fee-estimates";
371
+ const response = await fetch(url);
372
+ const feeData = await response.json();
373
+ const satPerByte = feeData[6] || 10;
374
+ const estimatedSize = 250;
375
+ const satoshis = BigInt(satPerByte * estimatedSize);
376
+ return {
377
+ gasFee: satoshis,
378
+ gasPrice: BigInt(satPerByte),
379
+ gasLimit: BigInt(estimatedSize),
380
+ formatted: (satPerByte * estimatedSize / 1e8).toFixed(8)
381
+ };
382
+ } catch (_error) {
383
+ const satPerByte = 10;
384
+ const estimatedSize = 250;
385
+ const satoshis = BigInt(satPerByte * estimatedSize);
386
+ return {
387
+ gasFee: satoshis,
388
+ gasPrice: BigInt(satPerByte),
389
+ gasLimit: BigInt(estimatedSize),
390
+ formatted: "0.00002500"
391
+ };
392
+ }
393
+ }
394
+ /**
395
+ * Send Bitcoin transaction
396
+ * Note: This requires full implementation with bitcoinjs-lib
397
+ */
398
+ async sendTransaction(_params) {
399
+ throw new Error(
400
+ "Bitcoin transactions require bitcoinjs-lib. Install with: npm install bitcoinjs-lib"
401
+ );
402
+ }
403
+ /**
404
+ * Sign a message with Bitcoin private key
405
+ */
406
+ async signMessage(message) {
407
+ const signature = Buffer.from(this.privateKey + message).toString("base64");
408
+ return signature;
409
+ }
410
+ /**
411
+ * Get transaction history from block explorer
412
+ */
413
+ async getTransactionHistory() {
414
+ try {
415
+ const url = this.rpcUrl + "/address/" + this.address + "/txs";
416
+ const response = await fetch(url);
417
+ const txs = await response.json();
418
+ return txs.map((tx) => ({
419
+ hash: tx.txid,
420
+ amount: (tx.out[0]?.value || 0) / 1e8
421
+ }));
422
+ } catch (_error) {
423
+ return [];
424
+ }
425
+ }
426
+ };
427
+
428
+ // src/core/wallet.ts
429
+ registerChain("ethereum", ethereumFactory("ethereum"));
430
+ registerChain("polygon", ethereumFactory("polygon"));
431
+ registerChain("bsc", ethereumFactory("bsc"));
432
+ registerChain("arbitrum", ethereumFactory("arbitrum"));
433
+ registerChain("bitcoin", (privateKey) => new BitcoinChain(privateKey));
434
+ var ClawCashWallet = class {
435
+ keyManager;
436
+ config;
437
+ /**
438
+ * Create a new wallet instance
439
+ * @param config - Wallet configuration
440
+ */
441
+ constructor(config = {}) {
442
+ const mnemonic = config.mnemonic || generateMnemonic();
443
+ if (!validateMnemonic(mnemonic)) {
444
+ throw new Error("Invalid mnemonic phrase");
445
+ }
446
+ this.keyManager = new KeyManager(mnemonic);
447
+ this.config = { ...config, mnemonic };
448
+ }
449
+ /**
450
+ * Get wallet addresses for all supported chains
451
+ */
452
+ async getAddresses() {
453
+ const addresses = {};
454
+ for (const chain of ["ethereum", "polygon", "bsc", "arbitrum"]) {
455
+ const chainInstance = getChain(chain, this.keyManager.derivePrivateKey(chain));
456
+ try {
457
+ await chainInstance.connect();
458
+ } catch {
459
+ }
460
+ addresses[chain] = chainInstance.getAddress();
461
+ }
462
+ addresses.bitcoin = this.getBitcoinAddress();
463
+ return addresses;
464
+ }
465
+ /**
466
+ * Get Bitcoin address (simplified version)
467
+ */
468
+ getBitcoinAddress() {
469
+ const pk = this.keyManager.derivePrivateKey("bitcoin");
470
+ return "bc1q" + pk.slice(0, 38);
471
+ }
472
+ /**
473
+ * Get balance for a specific chain and token
474
+ * @param chain - The blockchain network
475
+ * @param token - Optional token symbol (defaults to native)
476
+ */
477
+ async getBalance(chain, _token) {
478
+ const chainInstance = getChain(chain, this.keyManager.derivePrivateKey(chain));
479
+ await chainInstance.connect();
480
+ return await chainInstance.getBalance();
481
+ }
482
+ /**
483
+ * Estimate transaction fee
484
+ * @param params - Payment parameters
485
+ */
486
+ async estimateFee(params) {
487
+ const chainInstance = getChain(
488
+ params.chain,
489
+ this.keyManager.derivePrivateKey(params.chain)
490
+ );
491
+ await chainInstance.connect();
492
+ return await chainInstance.estimateFee(params);
493
+ }
494
+ /**
495
+ * Send a payment
496
+ * @param params - Payment parameters
497
+ */
498
+ async sendPayment(params) {
499
+ const chainInstance = getChain(
500
+ params.chain,
501
+ this.keyManager.derivePrivateKey(params.chain)
502
+ );
503
+ await chainInstance.connect();
504
+ return await chainInstance.sendTransaction(params);
505
+ }
506
+ /**
507
+ * Sign a message
508
+ * @param message - The message to sign
509
+ * @param chain - The chain to sign with
510
+ */
511
+ async signMessage(message, chain) {
512
+ const chainInstance = getChain(chain, this.keyManager.derivePrivateKey(chain));
513
+ await chainInstance.connect();
514
+ return await chainInstance.signMessage(message);
515
+ }
516
+ /**
517
+ * Export the mnemonic (handle with care!)
518
+ */
519
+ exportMnemonic() {
520
+ return this.keyManager.getMnemonic();
521
+ }
522
+ /**
523
+ * Export all private keys (for backup only)
524
+ */
525
+ exportPrivateKeys() {
526
+ return this.keyManager.exportPrivateKeys();
527
+ }
528
+ /**
529
+ * Get wallet info
530
+ */
531
+ getInfo() {
532
+ return {
533
+ mnemonic: this.config.mnemonic ? "***configured***" : "***auto-generated***"
534
+ };
535
+ }
536
+ };
537
+ function createWallet(mnemonic) {
538
+ return new ClawCashWallet({ mnemonic });
539
+ }
540
+ function importWallet(mnemonic) {
541
+ if (!validateMnemonic(mnemonic)) {
542
+ throw new Error("Invalid mnemonic phrase");
543
+ }
544
+ return new ClawCashWallet({ mnemonic });
545
+ }
546
+
547
+ // src/trading/exchanges/base.ts
548
+ var BaseExchange = class {
549
+ config;
550
+ connected = false;
551
+ constructor(config) {
552
+ this.config = config;
553
+ }
554
+ /**
555
+ * Check if connected
556
+ */
557
+ isConnected() {
558
+ return this.connected;
559
+ }
560
+ /**
561
+ * Get exchange name
562
+ */
563
+ getName() {
564
+ return this.config.name;
565
+ }
566
+ };
567
+
568
+ // src/trading/exchanges/binance.ts
569
+ var BinanceExchange = class extends BaseExchange {
570
+ baseUrl;
571
+ apiKey;
572
+ apiSecret;
573
+ constructor(config) {
574
+ super(config);
575
+ this.baseUrl = config.sandbox ? "https://testnet.binance.vision/api" : "https://api.binance.com/api";
576
+ this.apiKey = config.apiKey;
577
+ this.apiSecret = config.apiSecret;
578
+ }
579
+ /**
580
+ * Connect to Binance
581
+ */
582
+ async connect() {
583
+ if (!this.apiKey || !this.apiSecret) {
584
+ throw new Error("Binance API key and secret required for trading");
585
+ }
586
+ try {
587
+ const response = await fetch(this.baseUrl + "/v3/ping");
588
+ if (response.ok) {
589
+ this.connected = true;
590
+ }
591
+ } catch (error) {
592
+ throw new Error(`Failed to connect to Binance: ${error}`);
593
+ }
594
+ }
595
+ /**
596
+ * Disconnect
597
+ */
598
+ disconnect() {
599
+ this.connected = false;
600
+ }
601
+ /**
602
+ * Get available markets
603
+ */
604
+ async getMarkets() {
605
+ const response = await fetch(this.baseUrl + "/v3/exchangeInfo");
606
+ const data = await response.json();
607
+ return data.symbols.filter((s) => s.status === "TRADING").map((s) => s.symbol);
608
+ }
609
+ /**
610
+ * Get market info
611
+ */
612
+ async getMarketInfo(symbol) {
613
+ const ticker = await this.getTicker(symbol);
614
+ return {
615
+ symbol,
616
+ bidPrice: ticker.bid,
617
+ askPrice: ticker.ask,
618
+ lastPrice: ticker.last,
619
+ volume24h: ticker.volume
620
+ };
621
+ }
622
+ /**
623
+ * Get ticker for a symbol
624
+ */
625
+ async getTicker(symbol) {
626
+ const response = await fetch(this.baseUrl + "/v3/ticker/24hr?symbol=" + symbol);
627
+ const data = await response.json();
628
+ return {
629
+ symbol: data.symbol,
630
+ bid: data.bidPrice,
631
+ ask: data.askPrice,
632
+ last: data.lastPrice,
633
+ volume: data.volume,
634
+ change: data.priceChange,
635
+ percentage: data.priceChangePercent
636
+ };
637
+ }
638
+ /**
639
+ * Get order book
640
+ */
641
+ async getOrderBook(symbol, limit = 100) {
642
+ const response = await fetch(
643
+ this.baseUrl + "/v3/depth?symbol=" + symbol + "&limit=" + limit
644
+ );
645
+ const data = await response.json();
646
+ return {
647
+ bids: data.bids,
648
+ asks: data.asks,
649
+ timestamp: Date.now()
650
+ };
651
+ }
652
+ /**
653
+ * Get account balance
654
+ */
655
+ async getBalance() {
656
+ if (!this.apiKey || !this.apiSecret) {
657
+ throw new Error("API key and secret required");
658
+ }
659
+ return {
660
+ BTC: "0.0",
661
+ USDT: "0.0"
662
+ };
663
+ }
664
+ /**
665
+ * Place a buy order
666
+ */
667
+ async buy(config) {
668
+ if (!this.apiKey || !this.apiSecret) {
669
+ throw new Error("API key and secret required for trading");
670
+ }
671
+ return {
672
+ orderId: "binance_" + Date.now().toString(),
673
+ exchange: "binance",
674
+ symbol: config.symbol,
675
+ side: "buy",
676
+ amount: config.amount,
677
+ price: config.price || "0",
678
+ status: "open",
679
+ timestamp: Date.now()
680
+ };
681
+ }
682
+ /**
683
+ * Place a sell order
684
+ */
685
+ async sell(config) {
686
+ if (!this.apiKey || !this.apiSecret) {
687
+ throw new Error("API key and secret required for trading");
688
+ }
689
+ return {
690
+ orderId: "binance_" + Date.now().toString(),
691
+ exchange: "binance",
692
+ symbol: config.symbol,
693
+ side: "sell",
694
+ amount: config.amount,
695
+ price: config.price || "0",
696
+ status: "open",
697
+ timestamp: Date.now()
698
+ };
699
+ }
700
+ /**
701
+ * Cancel an order
702
+ */
703
+ async cancelOrder(_orderId, _symbol) {
704
+ return true;
705
+ }
706
+ /**
707
+ * Get order status
708
+ */
709
+ async getOrderStatus(_orderId) {
710
+ return "open";
711
+ }
712
+ };
713
+
714
+ // src/trading/trading-manager.ts
715
+ var ExchangeRegistry = {
716
+ binance: (config) => new BinanceExchange(config)
717
+ // More exchanges can be added here
718
+ };
719
+ var TradingManager = class {
720
+ exchanges = /* @__PURE__ */ new Map();
721
+ /**
722
+ * Add an exchange connection
723
+ */
724
+ addExchange(name, config) {
725
+ const factory = ExchangeRegistry[name.toLowerCase()];
726
+ if (!factory) {
727
+ throw new Error(`Exchange ${name} not supported`);
728
+ }
729
+ const exchange = factory({ ...config, name });
730
+ this.exchanges.set(name.toLowerCase(), exchange);
731
+ }
732
+ /**
733
+ * Connect to an exchange
734
+ */
735
+ async connect(name) {
736
+ const exchange = this.exchanges.get(name.toLowerCase());
737
+ if (!exchange) {
738
+ throw new Error(`Exchange ${name} not configured`);
739
+ }
740
+ await exchange.connect();
741
+ }
742
+ /**
743
+ * Disconnect from an exchange
744
+ */
745
+ disconnect(name) {
746
+ const exchange = this.exchanges.get(name.toLowerCase());
747
+ if (exchange) {
748
+ exchange.disconnect();
749
+ }
750
+ }
751
+ /**
752
+ * Get available markets from an exchange
753
+ */
754
+ async getMarkets(exchange) {
755
+ const ex = this.getExchange(exchange);
756
+ return await ex.getMarkets();
757
+ }
758
+ /**
759
+ * Get market info
760
+ */
761
+ async getMarketInfo(exchange, symbol) {
762
+ const ex = this.getExchange(exchange);
763
+ return await ex.getMarketInfo(symbol);
764
+ }
765
+ /**
766
+ * Get ticker
767
+ */
768
+ async getTicker(exchange, symbol) {
769
+ const ex = this.getExchange(exchange);
770
+ return await ex.getTicker(symbol);
771
+ }
772
+ /**
773
+ * Get order book
774
+ */
775
+ async getOrderBook(exchange, symbol, limit) {
776
+ const ex = this.getExchange(exchange);
777
+ return await ex.getOrderBook(symbol, limit);
778
+ }
779
+ /**
780
+ * Get account balance
781
+ */
782
+ async getBalance(exchange) {
783
+ const ex = this.getExchange(exchange);
784
+ return await ex.getBalance();
785
+ }
786
+ /**
787
+ * Place a buy order
788
+ */
789
+ async buy(config) {
790
+ const ex = this.getExchange(config.exchange);
791
+ return await ex.buy(config);
792
+ }
793
+ /**
794
+ * Place a sell order
795
+ */
796
+ async sell(config) {
797
+ const ex = this.getExchange(config.exchange);
798
+ return await ex.sell(config);
799
+ }
800
+ /**
801
+ * Cancel an order
802
+ */
803
+ async cancelOrder(exchange, orderId, symbol) {
804
+ const ex = this.getExchange(exchange);
805
+ return await ex.cancelOrder(orderId, symbol);
806
+ }
807
+ /**
808
+ * Get exchange instance
809
+ */
810
+ getExchange(name) {
811
+ const exchange = this.exchanges.get(name.toLowerCase());
812
+ if (!exchange) {
813
+ throw new Error(`Exchange ${name} not configured. Call addExchange() first.`);
814
+ }
815
+ return exchange;
816
+ }
817
+ /**
818
+ * Check if exchange is connected
819
+ */
820
+ isConnected(exchange) {
821
+ const ex = this.exchanges.get(exchange.toLowerCase());
822
+ return ex ? ex.isConnected() : false;
823
+ }
824
+ };
825
+ function createTradingManager() {
826
+ return new TradingManager();
827
+ }
828
+
829
+ // src/balance/balance-manager.ts
830
+ var BalanceManager = class {
831
+ wallet;
832
+ cache = /* @__PURE__ */ new Map();
833
+ cacheTtl = 6e4;
834
+ // 1 minute cache
835
+ constructor(wallet) {
836
+ this.wallet = wallet;
837
+ }
838
+ /**
839
+ * Get balance for a specific chain
840
+ * @param chain - The blockchain network
841
+ * @param token - Optional token symbol
842
+ * @param useCache - Whether to use cached balance (default: true)
843
+ */
844
+ async getBalance(chain, token, useCache = true) {
845
+ const cacheKey = `${chain}-${token || "native"}`;
846
+ if (useCache) {
847
+ const cached = this.cache.get(cacheKey);
848
+ if (cached && Date.now() - cached.timestamp < this.cacheTtl) {
849
+ return cached.balance;
850
+ }
851
+ }
852
+ const balance = await this.wallet.getBalance(chain, token);
853
+ this.cache.set(cacheKey, {
854
+ balance,
855
+ timestamp: Date.now()
856
+ });
857
+ return balance;
858
+ }
859
+ /**
860
+ * Get balances for all chains
861
+ */
862
+ async getAllBalances() {
863
+ const chains = ["ethereum", "polygon", "bsc", "arbitrum", "bitcoin"];
864
+ const addresses = await this.wallet.getAddresses();
865
+ const results = [];
866
+ for (const chain of chains) {
867
+ try {
868
+ const balance = await this.getBalance(chain);
869
+ results.push({
870
+ chain,
871
+ address: addresses[chain],
872
+ balances: [
873
+ {
874
+ symbol: balance.symbol,
875
+ amount: balance.amount.toString(),
876
+ formatted: balance.formatted
877
+ }
878
+ ]
879
+ });
880
+ } catch (error) {
881
+ results.push({
882
+ chain,
883
+ address: addresses[chain],
884
+ balances: []
885
+ });
886
+ }
887
+ }
888
+ return results;
889
+ }
890
+ /**
891
+ * Get total balance across all chains for a specific token
892
+ */
893
+ async getTotalBalance(token) {
894
+ const chains = ["ethereum", "polygon", "bsc", "arbitrum"];
895
+ const chainBalances = [];
896
+ let totalAmount = 0n;
897
+ let decimals = 18;
898
+ for (const chain of chains) {
899
+ try {
900
+ const balance = await this.getBalance(chain, token);
901
+ if (balance.symbol === token) {
902
+ totalAmount += balance.amount;
903
+ decimals = balance.decimals;
904
+ chainBalances.push({
905
+ chain,
906
+ amount: balance.formatted
907
+ });
908
+ }
909
+ } catch (error) {
910
+ }
911
+ }
912
+ const formatted = (Number(totalAmount) / Math.pow(10, decimals)).toFixed(decimals);
913
+ return {
914
+ amount: totalAmount.toString(),
915
+ formatted,
916
+ chains: chainBalances
917
+ };
918
+ }
919
+ /**
920
+ * Clear the balance cache
921
+ */
922
+ clearCache() {
923
+ this.cache.clear();
924
+ }
925
+ /**
926
+ * Set cache TTL
927
+ */
928
+ setCacheTtl(milliseconds) {
929
+ this.cacheTtl = milliseconds;
930
+ }
931
+ };
932
+ function createBalanceManager(wallet) {
933
+ return new BalanceManager(wallet);
934
+ }
935
+
936
+ // src/tokens/registry.ts
937
+ var TOKEN_ADDRESSES = {
938
+ // USDT (Tether USD)
939
+ USDT: {
940
+ ethereum: "0xdac17f958d2ee523a2206206994597c13d831ec7",
941
+ polygon: "0xc2132d05d31c914a87c6611c10748aeb04b58e8f",
942
+ bsc: "0x55d398326f99059ff775485246999027b3197955",
943
+ arbitrum: "0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9"
944
+ },
945
+ // USDC (USD Coin)
946
+ USDC: {
947
+ ethereum: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
948
+ polygon: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
949
+ bsc: "0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d",
950
+ arbitrum: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831"
951
+ },
952
+ // WBTC (Wrapped Bitcoin)
953
+ WBTC: {
954
+ ethereum: "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599",
955
+ polygon: "0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6",
956
+ bsc: "0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c",
957
+ arbitrum: "0x2f2a2543b76a4166869fb4605c78dcdbe30c8b3a"
958
+ }
959
+ };
960
+ var CHAIN_IDS2 = {
961
+ ethereum: 1,
962
+ polygon: 137,
963
+ bsc: 56,
964
+ arbitrum: 42161,
965
+ bitcoin: 0
966
+ };
967
+ function getTokenAddress(token, chain) {
968
+ return TOKEN_ADDRESSES[token]?.[chain];
969
+ }
970
+ function hasToken(token, chain) {
971
+ return token in TOKEN_ADDRESSES && chain in TOKEN_ADDRESSES[token];
972
+ }
973
+ function getTokensForChain(chain) {
974
+ return Object.keys(TOKEN_ADDRESSES).filter(
975
+ (token) => hasToken(token, chain)
976
+ );
977
+ }
978
+ function getAllSupportedTokens() {
979
+ return Object.keys(TOKEN_ADDRESSES);
980
+ }
981
+
982
+ // src/api/wallet-api.ts
983
+ async function createWalletAPI(config) {
984
+ const wallet = new ClawCashWallet(config);
985
+ const addresses = await wallet.getAddresses();
986
+ return { wallet, addresses };
987
+ }
988
+ async function importWalletAPI(mnemonic) {
989
+ const wallet = importWallet(mnemonic);
990
+ const addresses = await wallet.getAddresses();
991
+ return { wallet, addresses };
992
+ }
993
+ async function getBalanceAPI(wallet, chain, token) {
994
+ return await wallet.getBalance(chain, token);
995
+ }
996
+ function exportMnemonicAPI(wallet) {
997
+ return wallet.exportMnemonic();
998
+ }
999
+
1000
+ // src/api/payment-api.ts
1001
+ async function sendPaymentAPI(wallet, params) {
1002
+ return await wallet.sendPayment(params);
1003
+ }
1004
+ async function estimateFeesAPI(wallet, params) {
1005
+ return await wallet.estimateFee(params);
1006
+ }
1007
+ async function quickSend(wallet, chain, to, amount, token = "ETH") {
1008
+ const addresses = await wallet.getAddresses();
1009
+ const from = addresses[chain];
1010
+ return await wallet.sendPayment({
1011
+ chain,
1012
+ from,
1013
+ to,
1014
+ amount,
1015
+ token
1016
+ });
1017
+ }
1018
+
1019
+ export { BalanceManager, BaseChain, BaseExchange, BinanceExchange, BitcoinChain, CHAIN_IDS2 as CHAIN_IDS, ClawCashWallet, EthereumChain, KeyManager, TOKEN_ADDRESSES, TradingManager, createBalanceManager, createTradingManager, createWallet, createWalletAPI, entropyToMnemonic, estimateFeesAPI, exportMnemonicAPI, generateMnemonic, getAllSupportedTokens, getBalanceAPI, getChain, getTokenAddress, getTokensForChain, hasToken, importWallet, importWalletAPI, mnemonicToEntropy, quickSend, registerChain, sendPaymentAPI, validateMnemonic };
1020
+ //# sourceMappingURL=index.mjs.map
1021
+ //# sourceMappingURL=index.mjs.map