separate wallet ETH USDT USDC
This commit is contained in:
@@ -29,6 +29,7 @@ export default class AdminWalletsHandler {
|
||||
],
|
||||
[
|
||||
{ text: 'Tether (USDT)', callback_data: 'wallet_type_USDT' },
|
||||
{ text: 'USD Coin (USDC)', callback_data: 'wallet_type_USDC' },
|
||||
{ text: 'Ethereum (ETH)', callback_data: 'wallet_type_ETH' }
|
||||
]
|
||||
]
|
||||
@@ -76,9 +77,9 @@ export default class AdminWalletsHandler {
|
||||
let walletList = '';
|
||||
for (const wallet of walletsPage) {
|
||||
const walletUtilsInstance = new WalletUtils(
|
||||
wallet.wallet_type.startsWith('BTC') ? wallet.address : null,
|
||||
wallet.wallet_type.startsWith('LTC') ? wallet.address : null,
|
||||
wallet.wallet_type.startsWith('ETH') ? wallet.address : null,
|
||||
wallet.wallet_type === 'BTC' ? wallet.address : null,
|
||||
wallet.wallet_type === 'LTC' ? wallet.address : null,
|
||||
wallet.wallet_type === 'ETH' || wallet.wallet_type === 'USDT' || wallet.wallet_type === 'USDC' ? wallet.address : null,
|
||||
null, // userId не нужен для админки
|
||||
Date.now() - 30 * 24 * 60 * 60 * 1000
|
||||
);
|
||||
@@ -87,7 +88,7 @@ export default class AdminWalletsHandler {
|
||||
const balance = balances[wallet.wallet_type] || { amount: 0, usdValue: 0 };
|
||||
|
||||
walletList += `💰 *${wallet.wallet_type}*\n`;
|
||||
walletList += `├ Balance: ${balance.amount.toFixed(8)} ${wallet.wallet_type.split(' ')[0]}\n`;
|
||||
walletList += `├ Balance: ${balance.amount.toFixed(8)} ${wallet.wallet_type}\n`;
|
||||
walletList += `├ Value: $${balance.usdValue.toFixed(2)}\n`;
|
||||
walletList += `└ Address: \`${wallet.address}\`\n\n`;
|
||||
}
|
||||
@@ -132,9 +133,9 @@ export default class AdminWalletsHandler {
|
||||
|
||||
for (const wallet of wallets) {
|
||||
const walletUtilsInstance = new WalletUtils(
|
||||
wallet.wallet_type.startsWith('BTC') ? wallet.address : null,
|
||||
wallet.wallet_type.startsWith('LTC') ? wallet.address : null,
|
||||
wallet.wallet_type.startsWith('ETH') ? wallet.address : null,
|
||||
wallet.wallet_type === 'BTC' ? wallet.address : null,
|
||||
wallet.wallet_type === 'LTC' ? wallet.address : null,
|
||||
wallet.wallet_type === 'ETH' || wallet.wallet_type === 'USDT' || wallet.wallet_type === 'USDC' ? wallet.address : null,
|
||||
null, // userId не нужен для админки
|
||||
Date.now() - 30 * 24 * 60 * 60 * 1000
|
||||
);
|
||||
@@ -205,9 +206,9 @@ export default class AdminWalletsHandler {
|
||||
}
|
||||
|
||||
const walletUtilsInstance = new WalletUtils(
|
||||
wallet.wallet_type.startsWith('BTC') ? wallet.address : null,
|
||||
wallet.wallet_type.startsWith('LTC') ? wallet.address : null,
|
||||
wallet.wallet_type.startsWith('ETH') ? wallet.address : null,
|
||||
wallet.wallet_type === 'BTC' ? wallet.address : null,
|
||||
wallet.wallet_type === 'LTC' ? wallet.address : null,
|
||||
wallet.wallet_type === 'ETH' || wallet.wallet_type === 'USDT' || wallet.wallet_type === 'USDC' ? wallet.address : null,
|
||||
null, // userId не нужен для админки
|
||||
Date.now() - 30 * 24 * 60 * 60 * 1000
|
||||
);
|
||||
@@ -248,7 +249,6 @@ export default class AdminWalletsHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// Метод для возврата к списку типов кошельков
|
||||
static async handleBackToWalletTypes(callbackQuery) {
|
||||
const chatId = callbackQuery.message.chat.id;
|
||||
|
||||
@@ -265,6 +265,7 @@ export default class AdminWalletsHandler {
|
||||
],
|
||||
[
|
||||
{ text: 'Tether (USDT)', callback_data: 'wallet_type_USDT' },
|
||||
{ text: 'USD Coin (USDC)', callback_data: 'wallet_type_USDC' },
|
||||
{ text: 'Ethereum (ETH)', callback_data: 'wallet_type_ETH' }
|
||||
]
|
||||
]
|
||||
|
||||
@@ -6,6 +6,7 @@ import WalletService from "../../services/walletService.js";
|
||||
import bot from "../../context/bot.js";
|
||||
|
||||
export default class UserWalletsHandler {
|
||||
|
||||
static async showBalance(msg) {
|
||||
const chatId = msg.chat.id;
|
||||
const telegramId = msg.from.id;
|
||||
@@ -30,9 +31,11 @@ export default class UserWalletsHandler {
|
||||
|
||||
if (cryptoWallets.length > 0) {
|
||||
const walletUtilsInstance = new WalletUtils(
|
||||
cryptoWallets.find(w => w.wallet_type === 'BTC')?.address,
|
||||
cryptoWallets.find(w => w.wallet_type === 'LTC')?.address,
|
||||
cryptoWallets.find(w => w.wallet_type === 'ETH')?.address,
|
||||
cryptoWallets.find(w => w.wallet_type === 'BTC')?.address, // BTC address
|
||||
cryptoWallets.find(w => w.wallet_type === 'LTC')?.address, // LTC address
|
||||
cryptoWallets.find(w => w.wallet_type === 'ETH')?.address, // ETH address
|
||||
cryptoWallets.find(w => w.wallet_type === 'USDT')?.address, // USDT address
|
||||
cryptoWallets.find(w => w.wallet_type === 'USDC')?.address, // USDC address
|
||||
user.id,
|
||||
Date.now() - 30 * 24 * 60 * 60 * 1000
|
||||
);
|
||||
@@ -42,11 +45,7 @@ export default class UserWalletsHandler {
|
||||
|
||||
// Show active wallets
|
||||
for (const [type, balance] of Object.entries(balances)) {
|
||||
const baseType = this.getBaseWalletType(type);
|
||||
const wallet = cryptoWallets.find(w =>
|
||||
w.wallet_type === baseType ||
|
||||
(type.includes('ERC-20') && w.wallet_type === 'ETH')
|
||||
);
|
||||
const wallet = cryptoWallets.find(w => w.wallet_type === type.split(' ')[0]);
|
||||
|
||||
if (wallet) {
|
||||
message += `🔐 *${type}*\n`;
|
||||
@@ -229,7 +228,7 @@ export default class UserWalletsHandler {
|
||||
|
||||
const cryptoOptions = [
|
||||
['BTC', 'ETH', 'LTC'],
|
||||
['USDT ERC-20', 'USDC ERC-20']
|
||||
['USDT', 'USDC']
|
||||
];
|
||||
|
||||
const keyboard = {
|
||||
@@ -273,40 +272,50 @@ export default class UserWalletsHandler {
|
||||
const mnemonic = await WalletGenerator.generateMnemonic();
|
||||
const wallets = await WalletGenerator.generateWallets(mnemonic);
|
||||
|
||||
// Get the base wallet type (ETH for ERC-20)
|
||||
const baseType = this.getBaseWalletType(walletType);
|
||||
// Определяем базовый тип кошелька и путь деривации
|
||||
let baseType, derivationPath;
|
||||
if (walletType === 'USDT') {
|
||||
baseType = 'ETH';
|
||||
derivationPath = "m/44'/60'/0'/0/1"; // Путь для USDT
|
||||
} else if (walletType === 'USDC') {
|
||||
baseType = 'ETH';
|
||||
derivationPath = "m/44'/60'/0'/0/2"; // Путь для USDC
|
||||
} else {
|
||||
baseType = walletType;
|
||||
derivationPath = wallets[walletType].path; // Путь для других кошельков
|
||||
}
|
||||
|
||||
// Get existing wallet of this type
|
||||
// Получаем существующий кошелек этого типа
|
||||
const existingWallet = await db.getAsync(
|
||||
'SELECT id, address FROM crypto_wallets WHERE user_id = ? AND wallet_type = ?',
|
||||
[user.id, baseType]
|
||||
[user.id, walletType]
|
||||
);
|
||||
|
||||
if (existingWallet) {
|
||||
// Archive the old wallet by adding a suffix to its type
|
||||
// Архивируем старый кошелек, добавляя суффикс с таймштампом
|
||||
const timestamp = Date.now();
|
||||
await db.runAsync(
|
||||
'UPDATE crypto_wallets SET wallet_type = ? WHERE id = ?',
|
||||
[`${baseType}_${timestamp}`, existingWallet.id]
|
||||
[`${walletType}_${timestamp}`, existingWallet.id]
|
||||
);
|
||||
}
|
||||
|
||||
// Store the new wallet
|
||||
// Сохраняем новый кошелек
|
||||
await db.runAsync(
|
||||
`INSERT INTO crypto_wallets (
|
||||
user_id, wallet_type, address, derivation_path, mnemonic
|
||||
) VALUES (?, ?, ?, ?, ?)`,
|
||||
[
|
||||
user.id,
|
||||
baseType,
|
||||
wallets[baseType].address,
|
||||
wallets[baseType].path,
|
||||
walletType, // Используем выбранный тип (USDT, USDC, ETH и т.д.)
|
||||
wallets[baseType].address, // Адрес берется из базового типа
|
||||
derivationPath, // Используем корректный путь деривации
|
||||
mnemonic
|
||||
]
|
||||
);
|
||||
|
||||
// Get the appropriate address for the requested wallet type
|
||||
const displayAddress = this.getWalletAddress(wallets, walletType);
|
||||
// Получаем адрес для отображения
|
||||
const displayAddress = wallets[baseType].address;
|
||||
const network = this.getNetworkName(walletType);
|
||||
|
||||
let message = `✅ New wallet generated successfully!\n\n`;
|
||||
@@ -541,7 +550,7 @@ export default class UserWalletsHandler {
|
||||
const walletUtilsInstance = new WalletUtils(
|
||||
groupedWallets['BTC']?.[0]?.address,
|
||||
groupedWallets['LTC']?.[0]?.address,
|
||||
groupedWallets['ETH']?.[0]?.address,
|
||||
groupedWallets['ETH']?.[0]?.address || groupedWallets['USDT']?.[0]?.address || groupedWallets['USDC']?.[0]?.address,
|
||||
user.id,
|
||||
Date.now() - 30 * 24 * 60 * 60 * 1000
|
||||
);
|
||||
@@ -577,8 +586,10 @@ export default class UserWalletsHandler {
|
||||
usdValue = balances.LTC.usdValue;
|
||||
break;
|
||||
case 'ETH':
|
||||
balance = balances.ETH.amount;
|
||||
usdValue = balances.ETH.usdValue;
|
||||
case 'USDT':
|
||||
case 'USDC':
|
||||
balance = balances[baseType]?.amount || 0;
|
||||
usdValue = balances[baseType]?.usdValue || 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -677,10 +688,16 @@ export default class UserWalletsHandler {
|
||||
}
|
||||
|
||||
static getNetworkName(walletType) {
|
||||
if (walletType.includes('ERC-20')) return 'Ethereum Network (ERC-20)';
|
||||
if (walletType.includes('USDT')) return 'Ethereum Network (ERC-20)';
|
||||
if (walletType.includes('USDC')) return 'Ethereum Network (ERC-20)';
|
||||
if (walletType === 'BTC') return 'Bitcoin Network';
|
||||
if (walletType === 'LTC') return 'Litecoin Network';
|
||||
if (walletType === 'ETH') return 'Ethereum Network';
|
||||
return 'Unknown Network';
|
||||
}
|
||||
|
||||
static getBaseWalletType(walletType) {
|
||||
// Убираем суффиксы, такие как ERC-20, TRC-20 и т.д.
|
||||
return walletType.replace(/ (ERC-20|TRC-20)$/, '');
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,14 @@ export default class WalletGenerator {
|
||||
const ethNode = hdkey.derive("m/44'/60'/0'/0/0");
|
||||
const ethAddress = '0x' + publicToAddress(ethNode.publicKey, true).toString('hex');
|
||||
|
||||
// Generate USDT wallet (BIP44, same as ETH but different index)
|
||||
const usdtNode = hdkey.derive("m/44'/60'/0'/0/1");
|
||||
const usdtAddress = '0x' + publicToAddress(usdtNode.publicKey, true).toString('hex');
|
||||
|
||||
// Generate USDC wallet (BIP44, same as ETH but different index)
|
||||
const usdcNode = hdkey.derive("m/44'/60'/0'/0/2");
|
||||
const usdcAddress = '0x' + publicToAddress(usdcNode.publicKey, true).toString('hex');
|
||||
|
||||
// Generate LTC wallet (BIP84 - Native SegWit)
|
||||
const ltcNode = hdkey.derive("m/84'/2'/0'/0/0");
|
||||
const ltcKeyPair = ECPair.fromPrivateKey(ltcNode.privateKey);
|
||||
@@ -60,6 +68,14 @@ export default class WalletGenerator {
|
||||
address: ethAddress,
|
||||
path: "m/44'/60'/0'/0/0",
|
||||
},
|
||||
USDT: {
|
||||
address: usdtAddress,
|
||||
path: "m/44'/60'/0'/0/1",
|
||||
},
|
||||
USDC: {
|
||||
address: usdcAddress,
|
||||
path: "m/44'/60'/0'/0/2",
|
||||
},
|
||||
LTC: {
|
||||
address: ltcAddress,
|
||||
path: "m/84'/2'/0'/0/0",
|
||||
|
||||
@@ -1,31 +1,30 @@
|
||||
import axios from 'axios';
|
||||
|
||||
export default class WalletUtils{
|
||||
constructor(btcAddress, ltcAddress, trxAddress, ethAddress, userId, minTimestamp) {
|
||||
export default class WalletUtils {
|
||||
constructor(btcAddress, ltcAddress, ethAddress, usdtAddress, usdcAddress, userId, minTimestamp) {
|
||||
this.btcAddress = btcAddress;
|
||||
this.ltcAddress = ltcAddress;
|
||||
this.trxAddress = trxAddress;
|
||||
this.ethAddress = ethAddress;
|
||||
this.usdtAddress = usdtAddress;
|
||||
this.usdcAddress = usdcAddress;
|
||||
this.userId = userId;
|
||||
this.minTimestamp = minTimestamp;
|
||||
}
|
||||
|
||||
static async getCryptoPrices() {
|
||||
try {
|
||||
const response = await axios.get('https://api.coingecko.com/api/v3/simple/price?ids=bitcoin,litecoin,tether,usd-coin,tron,ethereum&vs_currencies=usd');
|
||||
const response = await axios.get('https://api.coingecko.com/api/v3/simple/price?ids=bitcoin,litecoin,ethereum&vs_currencies=usd');
|
||||
return {
|
||||
btc: response.data.bitcoin?.usd || 0,
|
||||
ltc: response.data.litecoin?.usd || 0,
|
||||
eth: response.data.ethereum?.usd || 0,
|
||||
usdt: 1, // Stablecoin
|
||||
usdc: 1, // Stablecoin
|
||||
trx: response.data.tron?.usd || 0,
|
||||
usdd: 1 // Stablecoin
|
||||
usdt: 1, // USDT — это стейблкоин, его цена всегда 1 USD
|
||||
usdc: 1 // USDC — это стейблкоин, его цена всегда 1 USD
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error fetching crypto prices:', error);
|
||||
return {
|
||||
btc: 0, ltc: 0, eth: 0, usdt: 1, usdc: 1, trx: 0, usdd: 1
|
||||
btc: 0, ltc: 0, eth: 0, usdt: 1, usdc: 1
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -77,9 +76,9 @@ export default class WalletUtils{
|
||||
}
|
||||
|
||||
async getUsdtErc20Balance() {
|
||||
if (!this.ethAddress) return 0;
|
||||
if (!this.usdtAddress) return 0;
|
||||
try {
|
||||
const url = `https://api.etherscan.io/api?module=account&action=tokenbalance&contractaddress=0xdac17f958d2ee523a2206206994597c13d831ec7&address=${this.ethAddress}&tag=latest`;
|
||||
const url = `https://api.etherscan.io/api?module=account&action=tokenbalance&contractaddress=0xdac17f958d2ee523a2206206994597c13d831ec7&address=${this.usdtAddress}&tag=latest`;
|
||||
const data = await this.fetchApiRequest(url);
|
||||
return data?.result ? parseFloat(data.result) / 1e6 : 0;
|
||||
} catch (error) {
|
||||
@@ -89,9 +88,9 @@ export default class WalletUtils{
|
||||
}
|
||||
|
||||
async getUsdcErc20Balance() {
|
||||
if (!this.ethAddress) return 0;
|
||||
if (!this.usdcAddress) return 0;
|
||||
try {
|
||||
const url = `https://api.etherscan.io/api?module=account&action=tokenbalance&contractaddress=0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48&address=${this.ethAddress}&tag=latest`;
|
||||
const url = `https://api.etherscan.io/api?module=account&action=tokenbalance&contractaddress=0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48&address=${this.usdcAddress}&tag=latest`;
|
||||
const data = await this.fetchApiRequest(url);
|
||||
return data?.result ? parseFloat(data.result) / 1e6 : 0;
|
||||
} catch (error) {
|
||||
@@ -100,36 +99,6 @@ export default class WalletUtils{
|
||||
}
|
||||
}
|
||||
|
||||
async getUsdtTrc20Balance() {
|
||||
if (!this.trxAddress) return 0;
|
||||
try {
|
||||
const url = `https://apilist.tronscan.org/api/account?address=${this.trxAddress}`;
|
||||
const data = await this.fetchApiRequest(url);
|
||||
const usdtToken = data?.trc20token_balances?.find(token =>
|
||||
token.tokenId === 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t'
|
||||
);
|
||||
return usdtToken ? parseFloat(usdtToken.balance) / 1e6 : 0;
|
||||
} catch (error) {
|
||||
console.error('Error getting USDT TRC20 balance:', error);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
async getUsddTrc20Balance() {
|
||||
if (!this.trxAddress) return 0;
|
||||
try {
|
||||
const url = `https://apilist.tronscan.org/api/account?address=${this.trxAddress}`;
|
||||
const data = await this.fetchApiRequest(url);
|
||||
const usddToken = data?.trc20token_balances?.find(token =>
|
||||
token.tokenId === 'TPYmHEhy5n8TCEfYGqW2rPxsghSfzghPDn'
|
||||
);
|
||||
return usddToken ? parseFloat(usddToken.balance) / 1e18 : 0;
|
||||
} catch (error) {
|
||||
console.error('Error getting USDD TRC20 balance:', error);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
async getAllBalances() {
|
||||
const [
|
||||
btcBalance,
|
||||
@@ -137,8 +106,6 @@ export default class WalletUtils{
|
||||
ethBalance,
|
||||
usdtErc20Balance,
|
||||
usdcErc20Balance,
|
||||
usdtTrc20Balance,
|
||||
usddTrc20Balance,
|
||||
prices
|
||||
] = await Promise.all([
|
||||
this.getBtcBalance(),
|
||||
@@ -146,8 +113,6 @@ export default class WalletUtils{
|
||||
this.getEthBalance(),
|
||||
this.getUsdtErc20Balance(),
|
||||
this.getUsdcErc20Balance(),
|
||||
this.getUsdtTrc20Balance(),
|
||||
this.getUsddTrc20Balance(),
|
||||
WalletUtils.getCryptoPrices()
|
||||
]);
|
||||
|
||||
@@ -156,9 +121,7 @@ export default class WalletUtils{
|
||||
LTC: { amount: ltcBalance, usdValue: ltcBalance * prices.ltc },
|
||||
ETH: { amount: ethBalance, usdValue: ethBalance * prices.eth },
|
||||
'USDT ERC-20': { amount: usdtErc20Balance, usdValue: usdtErc20Balance },
|
||||
'USDC ERC-20': { amount: usdcErc20Balance, usdValue: usdcErc20Balance },
|
||||
'USDT TRC-20': { amount: usdtTrc20Balance, usdValue: usdtTrc20Balance },
|
||||
'USDD TRC-20': { amount: usddTrc20Balance, usdValue: usddTrc20Balance }
|
||||
'USDC ERC-20': { amount: usdcErc20Balance, usdValue: usdcErc20Balance }
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user