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/LICENSE +21 -0
- package/README.md +155 -0
- package/dist/index.d.mts +918 -0
- package/dist/index.d.ts +918 -0
- package/dist/index.js +1054 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1021 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +70 -0
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
|