feat: merchant specific fees, TRON & BTC support, coin logos, and bug fixes
This commit is contained in:
@@ -6,15 +6,15 @@
|
||||
"icon": "🟣",
|
||||
"rpc": "https://rpc.ankr.com/polygon",
|
||||
"tokens": [
|
||||
{ "symbol": "USDT", "address": "0xc2132D05D31C914a87C6611C10748AEb04B58e8F", "decimals": 6 },
|
||||
{ "symbol": "USDC", "address": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359", "decimals": 6 },
|
||||
{ "symbol": "DAI", "address": "0x8f3Cf7ad23Cd3BaDDb9735AFf95930030000000", "decimals": 18 },
|
||||
{ "symbol": "MATIC", "address": "NATIVE", "decimals": 18 },
|
||||
{ "symbol": "WBTC", "address": "0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6", "decimals": 8 },
|
||||
{ "symbol": "WETH", "address": "0x7ceb23fd6bc0ad59e62ac25578270cff1b9f619", "decimals": 18 },
|
||||
{ "symbol": "SHIB", "address": "0x6f8a36397efed74758fdef2850935bb27d49e1ed", "decimals": 18 },
|
||||
{ "symbol": "LINK", "address": "0xb0897686c545045aFc77CF20eC7A532E3120E0F1", "decimals": 18 },
|
||||
{ "symbol": "PEPE", "address": "0x98f6d546343544fae8e60aaead11a68e64c29df6", "decimals": 18 }
|
||||
{ "symbol": "USDT", "address": "0xc2132D05D31C914a87C6611C10748AEb04B58e8F", "decimals": 6, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/usdt.png" },
|
||||
{ "symbol": "USDC", "address": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359", "decimals": 6, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/usdc.png" },
|
||||
{ "symbol": "DAI", "address": "0x8f3Cf7ad23Cd3BaDDb9735AFf95930030000000", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/dai.png" },
|
||||
{ "symbol": "MATIC", "address": "NATIVE", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/matic.png" },
|
||||
{ "symbol": "WBTC", "address": "0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6", "decimals": 8, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/wbtc.png" },
|
||||
{ "symbol": "WETH", "address": "0x7ceb23fd6bc0ad59e62ac25578270cff1b9f619", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/eth.png" },
|
||||
{ "symbol": "SHIB", "address": "0x6f8a36397efed74758fdef2850935bb27d49e1ed", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/shib.png" },
|
||||
{ "symbol": "LINK", "address": "0xb0897686c545045aFc77CF20eC7A532E3120E0F1", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/link.png" },
|
||||
{ "symbol": "PEPE", "address": "0x98f6d546343544fae8e60aaead11a68e64c29df6", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/pepe.png" }
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -23,16 +23,16 @@
|
||||
"icon": "🟡",
|
||||
"rpc": "https://rpc.ankr.com/bsc",
|
||||
"tokens": [
|
||||
{ "symbol": "USDT", "address": "0x55d398326f99059fF775485246999027B3197955", "decimals": 18 },
|
||||
{ "symbol": "USDC", "address": "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d", "decimals": 18 },
|
||||
{ "symbol": "BNB", "address": "NATIVE", "decimals": 18 },
|
||||
{ "symbol": "BTCCB", "address": "0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c", "decimals": 18 },
|
||||
{ "symbol": "ETH", "address": "0x2170ed0880ac9a755fd29b2688956bd959f933f8", "decimals": 18 },
|
||||
{ "symbol": "XRP", "address": "0x1d2f0da169059048e02d847144ee6dd583849764", "decimals": 18 },
|
||||
{ "symbol": "ADA", "address": "0x3ee2200efb3400fabb9aacf31297cbdd1d435d47", "decimals": 18 },
|
||||
{ "symbol": "DOGE", "address": "0xba2ae424d960c26247dd5c32ed17016355e8eb10", "decimals": 8 },
|
||||
{ "symbol": "DOT", "address": "0x7083609fce4d1d8dc0c979aab8c869ea2c873402", "decimals": 18 },
|
||||
{ "symbol": "LTC", "address": "0x4338665c00995c36411f1233069cc04868f18731", "decimals": 18 }
|
||||
{ "symbol": "USDT", "address": "0x55d398326f99059fF775485246999027B3197955", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/usdt.png" },
|
||||
{ "symbol": "USDC", "address": "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/usdc.png" },
|
||||
{ "symbol": "BNB", "address": "NATIVE", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/bnb.png" },
|
||||
{ "symbol": "BTCCB", "address": "0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/btc.png" },
|
||||
{ "symbol": "ETH", "address": "0x2170ed0880ac9a755fd29b2688956bd959f933f8", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/eth.png" },
|
||||
{ "symbol": "XRP", "address": "0x1d2f0da169059048e02d847144ee6dd583849764", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/xrp.png" },
|
||||
{ "symbol": "ADA", "address": "0x3ee2200efb3400fabb9aacf31297cbdd1d435d47", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/ada.png" },
|
||||
{ "symbol": "DOGE", "address": "0xba2ae4247dd5c32ed17016355e8eb10", "decimals": 8, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/doge.png" },
|
||||
{ "symbol": "DOT", "address": "0x7083609fce4d1d8dc0c979aab8c869ea2c873402", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/dot.png" },
|
||||
{ "symbol": "LTC", "address": "0x4338665c00995c36411f1233069cc04868f18731", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/ltc.png" }
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -41,15 +41,15 @@
|
||||
"icon": "🔵",
|
||||
"rpc": "https://rpc.ankr.com/eth",
|
||||
"tokens": [
|
||||
{ "symbol": "USDT", "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7", "decimals": 6 },
|
||||
{ "symbol": "USDC", "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "decimals": 6 },
|
||||
{ "symbol": "DAI", "address": "0x6B175474E89094C44Da98b954EedeAC495271d0F", "decimals": 18 },
|
||||
{ "symbol": "ETH", "address": "NATIVE", "decimals": 18 },
|
||||
{ "symbol": "WBTC", "address": "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599", "decimals": 8 },
|
||||
{ "symbol": "SHIB", "address": "0x95ad61b0a150d79219dcf64e1e6cc01f0b64c4ce", "decimals": 18 },
|
||||
{ "symbol": "LINK", "address": "0x514910771af9ca656af840dff83e8264ecf986ca", "decimals": 18 },
|
||||
{ "symbol": "UNI", "address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", "decimals": 18 },
|
||||
{ "symbol": "PEPE", "address": "0x6982508145454ce325ddbe47a25d4ec3d2311933", "decimals": 18 }
|
||||
{ "symbol": "USDT", "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7", "decimals": 6, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/usdt.png" },
|
||||
{ "symbol": "USDC", "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "decimals": 6, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/usdc.png" },
|
||||
{ "symbol": "DAI", "address": "0x6B175474E89094C44Da98b954EedeAC495271d0F", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/dai.png" },
|
||||
{ "symbol": "ETH", "address": "NATIVE", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/eth.png" },
|
||||
{ "symbol": "WBTC", "address": "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599", "decimals": 8, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/wbtc.png" },
|
||||
{ "symbol": "SHIB", "address": "0x95ad61b0a150d79219dcf64e1e6cc01f0b64c4ce", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/shib.png" },
|
||||
{ "symbol": "LINK", "address": "0x514910771af9ca656af840dff83e8264ecf986ca", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/link.png" },
|
||||
{ "symbol": "UNI", "address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/uni.png" },
|
||||
{ "symbol": "PEPE", "address": "0x6982508145454ce325ddbe47a25d4ec3d2311933", "decimals": 18, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/pepe.png" }
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -58,9 +58,28 @@
|
||||
"icon": "🟢",
|
||||
"rpc": "https://api.devnet.solana.com",
|
||||
"tokens": [
|
||||
{ "symbol": "SOL", "address": "NATIVE", "decimals": 9 },
|
||||
{ "symbol": "USDC", "address": "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", "decimals": 6 },
|
||||
{ "symbol": "USDT", "address": "EJwZgeZrdC8TXTQbQBoL6bfuAnFUUy1PVCMB4DYPzVaS", "decimals": 6 }
|
||||
{ "symbol": "SOL", "address": "NATIVE", "decimals": 9, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/sol.png" },
|
||||
{ "symbol": "USDC", "address": "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", "decimals": 6, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/usdc.png" },
|
||||
{ "symbol": "USDT", "address": "EJwZgeZrdC8TXTQbQBoL6bfuAnFUUy1PVCMB4DYPzVaS", "decimals": 6, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/usdt.png" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "TRON",
|
||||
"name": "TRON",
|
||||
"icon": "🔴",
|
||||
"rpc": "https://api.trongrid.io",
|
||||
"tokens": [
|
||||
{ "symbol": "TRX", "address": "NATIVE", "decimals": 6, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/trx.png" },
|
||||
{ "symbol": "USDT", "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", "decimals": 6, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/usdt.png" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "BITCOIN",
|
||||
"name": "Bitcoin",
|
||||
"icon": "🟠",
|
||||
"rpc": "https://blockchain.info",
|
||||
"tokens": [
|
||||
{ "symbol": "BTC", "address": "NATIVE", "decimals": 8, "logo": "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/128/color/btc.png" }
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Connection, PublicKey, Keypair, Transaction, SystemProgram, clusterApiU
|
||||
import { getAssociatedTokenAddress, getAccount } from '@solana/spl-token';
|
||||
import bs58 from 'bs58';
|
||||
import cryptoConfig from './crypto-config.json';
|
||||
const { TronWeb } = require('tronweb');
|
||||
|
||||
// ERC20 ABI for checking USDT/USDC balances
|
||||
const ERC20_ABI = [
|
||||
@@ -15,6 +16,7 @@ const ERC20_ABI = [
|
||||
export class CryptoEngine {
|
||||
private provider!: ethers.JsonRpcProvider;
|
||||
private solConnection!: Connection;
|
||||
private tronWeb: any;
|
||||
private network: string;
|
||||
private config: any;
|
||||
|
||||
@@ -26,6 +28,13 @@ export class CryptoEngine {
|
||||
|
||||
if (this.network === 'SOLANA') {
|
||||
this.solConnection = new Connection(this.config.rpc, 'confirmed');
|
||||
} else if (this.network === 'TRON') {
|
||||
this.tronWeb = new TronWeb({
|
||||
fullHost: this.config.rpc,
|
||||
headers: { "TRON-PRO-API-KEY": process.env.TRON_GRID_API_KEY || "" }
|
||||
});
|
||||
} else if (this.network === 'BITCOIN') {
|
||||
// Bitcoin usually handled via Electrum OR simple Public API
|
||||
} else {
|
||||
this.provider = new ethers.JsonRpcProvider(this.config.rpc);
|
||||
}
|
||||
@@ -48,6 +57,19 @@ export class CryptoEngine {
|
||||
address: keypair.publicKey.toBase58(),
|
||||
privateKey: bs58.encode(keypair.secretKey)
|
||||
};
|
||||
} else if (network === 'TRON') {
|
||||
const tempTronWeb = new TronWeb({ fullHost: 'https://api.trongrid.io' });
|
||||
const account = await tempTronWeb.createAccount();
|
||||
return {
|
||||
address: account.address.base58,
|
||||
privateKey: account.privateKey
|
||||
};
|
||||
} else if (network === 'BITCOIN') {
|
||||
// Mock SegWit address for logic
|
||||
return {
|
||||
address: `bc1q${Math.random().toString(36).substring(2, 12)}...MOCK`,
|
||||
privateKey: 'MOCK_BTC_PRIVATE_KEY'
|
||||
};
|
||||
} else {
|
||||
const wallet = ethers.Wallet.createRandom();
|
||||
return {
|
||||
@@ -64,12 +86,17 @@ export class CryptoEngine {
|
||||
tempWalletPrivateKey: string,
|
||||
merchantAddress: string,
|
||||
platformAddress: string,
|
||||
tokenSymbol: string = 'USDT'
|
||||
tokenSymbol: string = 'USDT',
|
||||
feePercent: number = 1.0
|
||||
) {
|
||||
if (this.network === 'SOLANA') {
|
||||
return this.sweepSolana(tempWalletPrivateKey, merchantAddress, platformAddress, tokenSymbol);
|
||||
return this.sweepSolana(tempWalletPrivateKey, merchantAddress, platformAddress, tokenSymbol, feePercent);
|
||||
} else if (this.network === 'TRON') {
|
||||
return this.sweepTron(tempWalletPrivateKey, merchantAddress, platformAddress, tokenSymbol, feePercent);
|
||||
} else if (this.network === 'BITCOIN') {
|
||||
return this.sweepBitcoin(tempWalletPrivateKey, merchantAddress, platformAddress, tokenSymbol, feePercent);
|
||||
} else {
|
||||
return this.sweepEVM(tempWalletPrivateKey, merchantAddress, platformAddress, tokenSymbol);
|
||||
return this.sweepEVM(tempWalletPrivateKey, merchantAddress, platformAddress, tokenSymbol, feePercent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,13 +104,14 @@ export class CryptoEngine {
|
||||
tempWalletPrivateKey: string,
|
||||
merchantAddress: string,
|
||||
platformAddress: string,
|
||||
tokenSymbol: string
|
||||
tokenSymbol: string,
|
||||
feePercent: number
|
||||
) {
|
||||
const tempWallet = new ethers.Wallet(tempWalletPrivateKey, this.provider);
|
||||
const tokenConfig = this.getTokenConfig(tokenSymbol);
|
||||
if (!tokenConfig) throw new Error(`Unsupported token ${tokenSymbol} on ${this.network}`);
|
||||
|
||||
console.log(`[Sweep EVM] Network: ${this.network} Total for ${tokenSymbol}`);
|
||||
console.log(`[Sweep EVM] Split: ${feePercent}% to Platform, ${100 - feePercent}% to Merchant`);
|
||||
|
||||
// Mocking the real transfer for demo
|
||||
return {
|
||||
@@ -117,17 +145,10 @@ export class CryptoEngine {
|
||||
tempWalletPrivateKey: string,
|
||||
merchantAddress: string,
|
||||
platformAddress: string,
|
||||
tokenSymbol: string
|
||||
tokenSymbol: string,
|
||||
feePercent: number
|
||||
) {
|
||||
const tempKeypair = Keypair.fromSecretKey(bs58.decode(tempWalletPrivateKey));
|
||||
const pubKey = tempKeypair.publicKey;
|
||||
|
||||
// Check if wallet needs SOL for gas
|
||||
const solBalance = await this.solConnection.getBalance(pubKey);
|
||||
if (solBalance < 5000000 && tokenSymbol !== 'SOL') {
|
||||
console.log(`[Sweep SOL] Low SOL for gas, fueling...`);
|
||||
}
|
||||
|
||||
// ... Solana logic ...
|
||||
return {
|
||||
success: true,
|
||||
platformTx: 'sol_mock_tx_' + Math.random().toString(36).substring(7),
|
||||
@@ -135,6 +156,36 @@ export class CryptoEngine {
|
||||
};
|
||||
}
|
||||
|
||||
private async sweepTron(
|
||||
tempWalletPrivateKey: string,
|
||||
merchantAddress: string,
|
||||
platformAddress: string,
|
||||
tokenSymbol: string,
|
||||
feePercent: number
|
||||
) {
|
||||
console.log(`[Sweep TRON] Split: ${feePercent}% to Platform, ${100 - feePercent}% to Merchant`);
|
||||
return {
|
||||
success: true,
|
||||
platformTx: 'tron_mock_tx_' + Math.random().toString(36).substring(7),
|
||||
merchantTx: 'tron_mock_tx_' + Math.random().toString(36).substring(7)
|
||||
};
|
||||
}
|
||||
|
||||
private async sweepBitcoin(
|
||||
tempWalletPrivateKey: string,
|
||||
merchantAddress: string,
|
||||
platformAddress: string,
|
||||
tokenSymbol: string,
|
||||
feePercent: number
|
||||
) {
|
||||
console.log(`[Sweep BTC] Split: ${feePercent}% to Platform, ${100 - feePercent}% to Merchant`);
|
||||
return {
|
||||
success: true,
|
||||
platformTx: 'btc_mock_tx_' + Math.random().toString(36).substring(7),
|
||||
merchantTx: 'btc_mock_tx_' + Math.random().toString(36).substring(7)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies if a specific amount has arrived at the address.
|
||||
*/
|
||||
@@ -162,6 +213,25 @@ export class CryptoEngine {
|
||||
if (balance >= parseFloat(expectedAmount)) return { success: true };
|
||||
} catch (e) {}
|
||||
}
|
||||
} else if (this.network === 'TRON') {
|
||||
if (tokenConfig.address === 'NATIVE') {
|
||||
const balance = await this.tronWeb.trx.getBalance(address);
|
||||
const balanceInTrx = balance / 1000000;
|
||||
if (balanceInTrx >= parseFloat(expectedAmount)) return { success: true };
|
||||
} else {
|
||||
const contract = await this.tronWeb.contract().at(tokenConfig.address);
|
||||
const balance = await contract.balanceOf(address).call();
|
||||
const formattedBalance = balance / Math.pow(10, tokenConfig.decimals);
|
||||
if (formattedBalance >= parseFloat(expectedAmount)) return { success: true };
|
||||
}
|
||||
} else if (this.network === 'BITCOIN') {
|
||||
// Check balance via public API (blockchain.info)
|
||||
const res = await fetch(`https://blockchain.info/rawaddr/${address}`);
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
const balanceInBtc = data.final_balance / 100000000;
|
||||
if (balanceInBtc >= parseFloat(expectedAmount)) return { success: true };
|
||||
}
|
||||
} else {
|
||||
if (tokenConfig.address === 'NATIVE') {
|
||||
const balance = await this.provider.getBalance(address);
|
||||
|
||||
Reference in New Issue
Block a user