diff --git a/src/Memecoin_dev/volume/boost_volume.js b/src/Memecoin_dev/volume/boost_volume.js index 37c5817f..751df3a4 100644 --- a/src/Memecoin_dev/volume/boost_volume.js +++ b/src/Memecoin_dev/volume/boost_volume.js @@ -6,7 +6,10 @@ const { jito_executeAndConfirm, } = require("../../Transactions/jito_tips_tx_executor.js"); const { program } = require("commander"); -const { loadOrCreateKeypair_wallet, checkTx } = require("../../helpers/util.js"); +const { + loadOrCreateKeypair_wallet, + checkTx, +} = require("../../helpers/util.js"); const { ComputeBudgetProgram, TransactionMessage, diff --git a/src/Trading_dev/memecoin_trading_strategies/copy_trading/copy-buy.js b/src/Trading_dev/memecoin_trading_strategies/copy_trading/copy-buy.js index 6087f922..5c356f23 100644 --- a/src/Trading_dev/memecoin_trading_strategies/copy_trading/copy-buy.js +++ b/src/Trading_dev/memecoin_trading_strategies/copy_trading/copy-buy.js @@ -1,182 +1,212 @@ +const { PublicKey } = require("@solana/web3.js"); +const { TOKEN_PROGRAM_ID, AccountLayout } = require("@solana/spl-token"); const { - PublicKey, -} = require("@solana/web3.js"); -const { - TOKEN_PROGRAM_ID, - AccountLayout, -} = require("@solana/spl-token"); -const { connection, wallet, smart_money_wallet } = require("../../../helpers/config"); + connection, + wallet, + smart_money_wallet, +} = require("../../../helpers/config"); //const { buy } = require("../../dex/jupiter/swap/buy-helper"); //const { sell } = require("../../dex/jupiter/swap/sell-helper"); -const path = require('path'); +const path = require("path"); const { swap } = require("../../../jupiter/swap/swap-helper"); -const {buy} = require("../../../raydium/buy_helper") -const {sell} = require("../../../raydium/sell_helper") -const fs = require('fs'); -const boughtTokensPath = path.join(__dirname, 'bought-tokens.json'); -//const {swap} = require("../../../Pool/swap") +const { buy } = require("../../../raydium/buy_helper"); +const { sell } = require("../../../raydium/sell_helper"); +const fs = require("fs"); +const boughtTokensPath = path.join(__dirname, "bought-tokens.json"); +//const {swap} = require("../../../Pool/swap") let walletsToListen = []; var previous_trader_wallet_state = {}; var previous_our_wallet_state = {}; // [usdc, sol, usdt, wsol] -const wsol = "So11111111111111111111111111111111111111112" +const wsol = "So11111111111111111111111111111111111111112"; const quoteToken = [ "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "SOL", "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", wsol, ]; -let boughtTokens = JSON.parse(fs.readFileSync(boughtTokensPath, 'utf8')); +let boughtTokens = JSON.parse(fs.readFileSync(boughtTokensPath, "utf8")); async function saveToJson(token) { boughtTokens.push(token); fs.writeFileSync(boughtTokensPath, JSON.stringify(boughtTokens, null, 2)); } - /** * Listens to changes in multiple wallets and performs trading actions based on the changes. * @returns {Promise} A promise that resolves once the wallet listening is set up. */ async function listenToWallets(address) { - try{ - - - connection.onProgramAccountChange( - TOKEN_PROGRAM_ID, - async (data) => { - const changedMint = AccountLayout.decode(data.accountInfo.data).mint.toBase58(); - console.log("changed mint: ", changedMint); - // realize in smart money wallet there is a token's balance changed - // then we look at trader's portfolio - console.log("Wallet state changed"); - const current_trader_wallet_state = await retriveWalletState( - address.toBase58() - ); - const current_our_wallet_state = await retriveWalletState( - wallet.publicKey.toBase58() - ); - if((changedMint in current_trader_wallet_state || current_trader_wallet_state[changedMint] > 0) && current_trader_wallet_state["SOL"] < previous_trader_wallet_state["SOL"]){ - console.log(`buying ${changedMint}...`) - if (!current_our_wallet_state[wsol]) { - console.log("We don't have enough SOL to swap"); - throw new Error("We don't have enough SOL to swap"); - } - const buy_percentage = Math.abs((current_trader_wallet_state["SOL"] - previous_trader_wallet_state["SOL"]) / previous_trader_wallet_state["SOL"]); - const amountOut = current_our_wallet_state[wsol] * buy_percentage; - console.log("amountOut: ", amountOut); - buy("buy", changedMint, amountOut, wallet) - saveToJson(changedMint); - previous_our_wallet_state = await retriveWalletState(wallet.publicKey.toBase58()); - previous_trader_wallet_state = await retriveWalletState(address.toBase58()); - return; - } - else if((!(changedMint in current_trader_wallet_state) || current_trader_wallet_state[changedMint] <= previous_trader_wallet_state[changedMint] ) && current_trader_wallet_state["SOL"] > previous_trader_wallet_state["SOL"]){ - console.log(`selling ${changedMint}...`) - if (!current_our_wallet_state[wsol]) { - console.log("We don't have enough SOL to swap"); - throw new Error("We don't have enough SOL to swap"); - } - if(!changedMint in current_trader_wallet_state){ - current_trader_wallet_state[changedMint] = 0; - } - const sell_percentage = Math.abs((current_trader_wallet_state[changedMint] - previous_trader_wallet_state[changedMint]) / previous_trader_wallet_state[changedMint]); - const amountOut = current_our_wallet_state[changedMint] * sell_percentage; - console.log("amountOut: ", amountOut); - sell("sell", changedMint, amountOut*100, wallet); - previous_our_wallet_state = await retriveWalletState(wallet.publicKey.toBase58()); - previous_trader_wallet_state = await retriveWalletState(address.toBase58()); - return; - } - // changed mint might dissapear in the current trader state if they sold all of it before - // so we need to add it to the state with 0 balance - // Compare the current wallet state with the previous state - // to determine if the trader is buying or selling - // trader's wallet state - const prevState = previous_trader_wallet_state; - const currentState = current_trader_wallet_state; - let res_case = 0; - // Check if there is one token that decreased and one token that increased - let increasedToken = null, decreasedToken = null, increasedTokenPercentage = 0, decreasedTokenPercentage = 0; - for (const mint in currentState) { - if (increasedToken && decreasedToken) { - break; - } - const prevBalance = prevState[mint] || 0; - const currentBalance = currentState[mint]; - - if (currentBalance > prevBalance) { - increasedToken = mint; - increasedTokenPercentage = - (currentBalance - prevBalance) / prevBalance; - } else if (currentBalance < prevBalance) { - decreasedToken = mint; - decreasedTokenPercentage = - (currentBalance - prevBalance) / prevBalance; - } - } - // the Trader is trading - if (increasedToken && decreasedToken) { + try { + connection.onProgramAccountChange( + TOKEN_PROGRAM_ID, + async (data) => { + const changedMint = AccountLayout.decode( + data.accountInfo.data + ).mint.toBase58(); + console.log("changed mint: ", changedMint); + // realize in smart money wallet there is a token's balance changed + // then we look at trader's portfolio + console.log("Wallet state changed"); + const current_trader_wallet_state = await retriveWalletState( + address.toBase58() + ); + const current_our_wallet_state = await retriveWalletState( + wallet.publicKey.toBase58() + ); if ( - !quoteToken.includes(increasedToken) && - !quoteToken.includes(decreasedToken) + (changedMint in current_trader_wallet_state || + current_trader_wallet_state[changedMint] > 0) && + current_trader_wallet_state["SOL"] < + previous_trader_wallet_state["SOL"] ) { - console.log( - `case1: The trader is swapping ${decreasedToken} to ${increasedToken}` + console.log(`buying ${changedMint}...`); + if (!current_our_wallet_state[wsol]) { + console.log("We don't have enough SOL to swap"); + throw new Error("We don't have enough SOL to swap"); + } + const buy_percentage = Math.abs( + (current_trader_wallet_state["SOL"] - + previous_trader_wallet_state["SOL"]) / + previous_trader_wallet_state["SOL"] ); - + const amountOut = current_our_wallet_state[wsol] * buy_percentage; + console.log("amountOut: ", amountOut); + buy("buy", changedMint, amountOut, wallet); + saveToJson(changedMint); + previous_our_wallet_state = await retriveWalletState( + wallet.publicKey.toBase58() + ); + previous_trader_wallet_state = await retriveWalletState( + address.toBase58() + ); + return; + } else if ( + (!(changedMint in current_trader_wallet_state) || + current_trader_wallet_state[changedMint] <= + previous_trader_wallet_state[changedMint]) && + current_trader_wallet_state["SOL"] > + previous_trader_wallet_state["SOL"] + ) { + console.log(`selling ${changedMint}...`); if (!current_our_wallet_state[wsol]) { console.log("We don't have enough SOL to swap"); throw new Error("We don't have enough SOL to swap"); } - res_case = 1; - // swap directly it if we have decreased token and balance > 0 + if ((!changedMint) in current_trader_wallet_state) { + current_trader_wallet_state[changedMint] = 0; + } + const sell_percentage = Math.abs( + (current_trader_wallet_state[changedMint] - + previous_trader_wallet_state[changedMint]) / + previous_trader_wallet_state[changedMint] + ); + const amountOut = + current_our_wallet_state[changedMint] * sell_percentage; + console.log("amountOut: ", amountOut); + sell("sell", changedMint, amountOut * 100, wallet); + previous_our_wallet_state = await retriveWalletState( + wallet.publicKey.toBase58() + ); + previous_trader_wallet_state = await retriveWalletState( + address.toBase58() + ); + return; + } + // changed mint might dissapear in the current trader state if they sold all of it before + // so we need to add it to the state with 0 balance + // Compare the current wallet state with the previous state + // to determine if the trader is buying or selling + // trader's wallet state + const prevState = previous_trader_wallet_state; + const currentState = current_trader_wallet_state; + let res_case = 0; + // Check if there is one token that decreased and one token that increased + let increasedToken = null, + decreasedToken = null, + increasedTokenPercentage = 0, + decreasedTokenPercentage = 0; + for (const mint in currentState) { + if (increasedToken && decreasedToken) { + break; + } + const prevBalance = prevState[mint] || 0; + const currentBalance = currentState[mint]; + + if (currentBalance > prevBalance) { + increasedToken = mint; + increasedTokenPercentage = + (currentBalance - prevBalance) / prevBalance; + } else if (currentBalance < prevBalance) { + decreasedToken = mint; + decreasedTokenPercentage = + (currentBalance - prevBalance) / prevBalance; + } + } + // the Trader is trading + if (increasedToken && decreasedToken) { if ( - decreasedToken in current_our_wallet_state && - current_our_wallet_state[decreasedToken] + !quoteToken.includes(increasedToken) && + !quoteToken.includes(decreasedToken) ) { - const buy_percentage = Math.abs(decreasedTokenPercentage); - const amountOut = - current_our_wallet_state[decreasedToken] * buy_percentage; + console.log( + `case1: The trader is swapping ${decreasedToken} to ${increasedToken}` + ); - swap(decreasedToken, increasedToken, amountOut, 5); + if (!current_our_wallet_state[wsol]) { + console.log("We don't have enough SOL to swap"); + throw new Error("We don't have enough SOL to swap"); + } + res_case = 1; + // swap directly it if we have decreased token and balance > 0 + if ( + decreasedToken in current_our_wallet_state && + current_our_wallet_state[decreasedToken] + ) { + const buy_percentage = Math.abs(decreasedTokenPercentage); + const amountOut = + current_our_wallet_state[decreasedToken] * buy_percentage; - } else if (current_our_wallet_state[wsol]) { - // use sol to buy it if we don't have decreased token - const buy_percentage = Math.abs(decreasedTokenPercentage); - const amountOut = current_our_wallet_state[wsol] * buy_percentage; + swap(decreasedToken, increasedToken, amountOut, 5); + } else if (current_our_wallet_state[wsol]) { + // use sol to buy it if we don't have decreased token + const buy_percentage = Math.abs(decreasedTokenPercentage); + const amountOut = current_our_wallet_state[wsol] * buy_percentage; - buy("buy", increasedToken, amountOut, wallet) - saveToJson(increasedToken); + buy("buy", increasedToken, amountOut, wallet); + saveToJson(increasedToken); + } + } else { + // when the trader is swapping usdt to usdc, ignore it } - } else { - // when the trader is swapping usdt to usdc, ignore it + } else { + // someone send token to the wallet + // wallet send token to someone + // wallet send some token to limit order program or DCA program + // ignore it for now, we only focus on trading for now } - } else { - - // someone send token to the wallet - // wallet send token to someone - // wallet send some token to limit order program or DCA program - // ignore it for now, we only focus on trading for now - } - previous_our_wallet_state = await retriveWalletState(wallet.publicKey.toBase58()); - previous_trader_wallet_state = await retriveWalletState(address.toBase58()); - }, - "confirmed", - [ - { - dataSize: 165, + previous_our_wallet_state = await retriveWalletState( + wallet.publicKey.toBase58() + ); + previous_trader_wallet_state = await retriveWalletState( + address.toBase58() + ); }, - { - memcmp: { - offset: 32, - bytes: address.toBase58(), + "confirmed", + [ + { + dataSize: 165, }, - }, - ] - );} - catch(e){ - console.log(e) + { + memcmp: { + offset: 32, + bytes: address.toBase58(), + }, + }, + ] + ); + } catch (e) { + console.log(e); } } @@ -186,38 +216,40 @@ async function listenToWallets(address) { * @returns {Object} - An object containing the token balances of the wallet and the SOL balance. */ async function retriveWalletState(wallet_address) { - try{ - const filters = [ - { - dataSize: 165, //size of account (bytes) - }, - { - memcmp: { - offset: 32, //location of our query in the account (bytes) - bytes: wallet_address, //our search criteria, a base58 encoded string + try { + const filters = [ + { + dataSize: 165, //size of account (bytes) }, - }, - ]; - const accounts = await connection.getParsedProgramAccounts( - TOKEN_PROGRAM_ID, //new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA") - { filters: filters } - ); - let results = {}; - const solBalance = await connection.getBalance(new PublicKey(wallet_address)); - accounts.forEach((account, i) => { - //Parse the account data - const parsedAccountInfo = account.account.data; - const mintAddress = parsedAccountInfo["parsed"]["info"]["mint"]; - const tokenBalance = - parsedAccountInfo["parsed"]["info"]["tokenAmount"]["uiAmount"]; + { + memcmp: { + offset: 32, //location of our query in the account (bytes) + bytes: wallet_address, //our search criteria, a base58 encoded string + }, + }, + ]; + const accounts = await connection.getParsedProgramAccounts( + TOKEN_PROGRAM_ID, //new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA") + { filters: filters } + ); + let results = {}; + const solBalance = await connection.getBalance( + new PublicKey(wallet_address) + ); + accounts.forEach((account, i) => { + //Parse the account data + const parsedAccountInfo = account.account.data; + const mintAddress = parsedAccountInfo["parsed"]["info"]["mint"]; + const tokenBalance = + parsedAccountInfo["parsed"]["info"]["tokenAmount"]["uiAmount"]; - results[mintAddress] = tokenBalance; - results["SOL"] = solBalance / 10 ** 9; - }); - return results; -}catch(e){ - console.log(e) -} + results[mintAddress] = tokenBalance; + results["SOL"] = solBalance / 10 ** 9; + }); + return results; + } catch (e) { + console.log(e); + } } /** diff --git a/src/Trading_dev/memecoin_trading_strategies/copy_trading/copy-sell.js b/src/Trading_dev/memecoin_trading_strategies/copy_trading/copy-sell.js index 3a2b0902..70012d8e 100644 --- a/src/Trading_dev/memecoin_trading_strategies/copy_trading/copy-sell.js +++ b/src/Trading_dev/memecoin_trading_strategies/copy_trading/copy-sell.js @@ -1,113 +1,113 @@ const { - PublicKey, - } = require("@solana/web3.js"); - const { - TOKEN_PROGRAM_ID, - AccountLayout, - } = require("@solana/spl-token"); - const fs = require('fs'); - const path = require('path'); - const { wallet, second_connection, smart_money_wallet } = require("../../../helpers/config"); - //const { buy } = require("../../dex/jupiter/swap/buy-helper"); - //const { sell } = require("../../dex/jupiter/swap/sell-helper"); - const {sell} = require("../../../raydium/sell_helper") + PublicKey, +} = require("@solana/web3.js"); +const { + TOKEN_PROGRAM_ID, + AccountLayout, +} = require("@solana/spl-token"); +const fs = require('fs'); +const path = require('path'); +const { wallet, second_connection, smart_money_wallet } = require("../../../helpers/config"); +//const { buy } = require("../../dex/jupiter/swap/buy-helper"); +//const { sell } = require("../../dex/jupiter/swap/sell-helper"); +const {sell} = require("../../dex/raydium/sell_helper") - //const {swap} = require("../../../Pool/swap") - var current_trader_wallet_state = {}; - var current_our_wallet_state = {}; - // [usdc, sol, usdt, wsol] - const wsol = "So11111111111111111111111111111111111111112" - const quoteToken = [ - "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", - "SOL", - "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", - wsol, - ]; - const boughtTokensPath = path.join(__dirname, 'bought-tokens.json'); - let boughtTokens = JSON.parse(fs.readFileSync(boughtTokensPath, 'utf8')); +//const {swap} = require("../../../Pool/swap") +var current_trader_wallet_state = {}; +var current_our_wallet_state = {}; +// [usdc, sol, usdt, wsol] +const wsol = "So11111111111111111111111111111111111111112" +const quoteToken = [ + "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + "SOL", + "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", + wsol, +]; +const boughtTokensPath = path.join(__dirname, 'bought-tokens.json'); +let boughtTokens = JSON.parse(fs.readFileSync(boughtTokensPath, 'utf8')); console.log(boughtTokens); function saveToJson() { - fs.writeFileSync(boughtTokensPath, JSON.stringify(boughtTokens, null, 2)); - } + fs.writeFileSync(boughtTokensPath, JSON.stringify(boughtTokens, null, 2)); +} /** - * Retrieves the state of a wallet by querying the Solana blockchain. - * @param {string} wallet_address - The address of the wallet to retrieve the state for. - * @returns {Object} - An object containing the token balances of the wallet and the SOL balance. - */ +* Retrieves the state of a wallet by querying the Solana blockchain. +* @param {string} wallet_address - The address of the wallet to retrieve the state for. +* @returns {Object} - An object containing the token balances of the wallet and the SOL balance. +*/ async function retriveWalletState(wallet_address) { - const filters = [ - { - dataSize: 165, //size of account (bytes) - }, - { - memcmp: { - offset: 32, //location of our query in the account (bytes) - bytes: wallet_address, //our search criteria, a base58 encoded string - }, + const filters = [ + { + dataSize: 165, //size of account (bytes) + }, + { + memcmp: { + offset: 32, //location of our query in the account (bytes) + bytes: wallet_address, //our search criteria, a base58 encoded string }, - ]; - const accounts = await second_connection.getParsedProgramAccounts( - TOKEN_PROGRAM_ID, //new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA") - { filters: filters } - ); - let results = {}; - const solBalance = await second_connection.getBalance(new PublicKey(wallet_address)); - accounts.forEach((account, i) => { - //Parse the account data - const parsedAccountInfo = account.account.data; - const mintAddress = parsedAccountInfo["parsed"]["info"]["mint"]; - const tokenBalance = - parsedAccountInfo["parsed"]["info"]["tokenAmount"]["uiAmount"]; - - results[mintAddress] = tokenBalance; - results["SOL"] = solBalance / 10 ** 9; - }); - return results; - } + }, + ]; + const accounts = await second_connection.getParsedProgramAccounts( + TOKEN_PROGRAM_ID, //new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA") + { filters: filters } + ); + let results = {}; + const solBalance = await second_connection.getBalance(new PublicKey(wallet_address)); + accounts.forEach((account, i) => { + //Parse the account data + const parsedAccountInfo = account.account.data; + const mintAddress = parsedAccountInfo["parsed"]["info"]["mint"]; + const tokenBalance = + parsedAccountInfo["parsed"]["info"]["tokenAmount"]["uiAmount"]; + + results[mintAddress] = tokenBalance; + results["SOL"] = solBalance / 10 ** 9; + }); + return results; +} async function copy_sell(address){ - // 400 ms to check the wallet state - // if token we have but trader doesn't have, sell it - // that's it - let soldTokens = []; - let flag = false; - let possible_cant_sell_token = null - try{ - if(boughtTokens.length > 0){ - for(let i=0; i 0){ + for(let i=0; i !soldTokens.includes(token)); - // Save the updated list back to the JSON file - saveToJson(); - - } - -} -async function main(){ - while(true){ - boughtTokens = JSON.parse(fs.readFileSync(boughtTokensPath, 'utf8')); - console.log(boughtTokens); - await copy_sell(smart_money_wallet); + } + if(flag){ + // Update the list with the remaining unsold tokens + boughtTokens = boughtTokens.filter((token) => !soldTokens.includes(token)); + // Save the updated list back to the JSON file + saveToJson(); - await new Promise((resolve) => setTimeout(resolve, 2500)); } + +} +async function main(){ +while(true){ + boughtTokens = JSON.parse(fs.readFileSync(boughtTokensPath, 'utf8')); + console.log(boughtTokens); + await copy_sell(smart_money_wallet); + + await new Promise((resolve) => setTimeout(resolve, 2500)); +} } main(); -module.exports = {copy_sell} +module.exports = {copy_sell} \ No newline at end of file diff --git a/src/raydium/Pool/fetch_pool.js b/src/raydium/Pool/fetch_pool.js index 2b337b43..36018ad8 100644 --- a/src/raydium/Pool/fetch_pool.js +++ b/src/raydium/Pool/fetch_pool.js @@ -1,4 +1,4 @@ -const { initSdk } = require("../raydium_config"); +const { initSdk } = require("../raydium_config.js"); const { wsol } = require("../constants.js"); let sdkCache = { sdk: null, expiry: 0 }; async function fetchAMMPoolId(tokenAddress) { @@ -48,22 +48,28 @@ async function fetchAMMPoolIdByMintPair(mint1, mint2) { console.log("No AMM pool ID found for the given mint pair"); return ""; // return empty string if no AMM pool ID is found } -async function fetchLPToken(tokenAddress){ - try{ - const poolId = await fetchAMMPoolId(tokenAddress); - let response = await( await fetch(`https://api-v3.raydium.io/pools/info/ids?ids=${poolId}`)).json(); - let lpToken = ""; - response.success = false; - console.log(response.data); - while(!response.success){ - console.log("The response was not successful when getting LP token, trying again") - response = await( await fetch(`https://api-v3.raydium.io/pools/info/ids?ids=${poolId}`)).json(); - if(response.success) lpToken = response.data[0].lpMint.address - } - return lpToken; - }catch(e){ - console.log("Error getting LP token: ", e) +async function fetchLPToken(tokenAddress) { + try { + const poolId = await fetchAMMPoolId(tokenAddress); + let response = await ( + await fetch(`https://api-v3.raydium.io/pools/info/ids?ids=${poolId}`) + ).json(); + let lpToken = ""; + response.success = false; + console.log(response.data); + while (!response.success) { + console.log( + "The response was not successful when getting LP token, trying again" + ); + response = await ( + await fetch(`https://api-v3.raydium.io/pools/info/ids?ids=${poolId}`) + ).json(); + if (response.success) lpToken = response.data[0].lpMint.address; } + return lpToken; + } catch (e) { + console.log("Error getting LP token: ", e); + } } //fetchLPToken("3XTp12PmKMHxB6YkejaGPUjMGBLKRGgzHWgJuVTsBCoP");