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