Skip to content

Commit

Permalink
integrated JUP
Browse files Browse the repository at this point in the history
  • Loading branch information
outsmartchad committed Jun 13, 2024
1 parent 6463a9f commit a4b274b
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 8 deletions.
Empty file removed src/Trading/dex/jupiter/swap.js
Empty file.
43 changes: 43 additions & 0 deletions src/Trading/dex/jupiter/swap/buy-helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const swap_helper = require("./swap-helper");
const { wallet } = require("../../../../helpers/config");
const { getDecimals } = require("../../../../helpers/util");
const wsol = "So11111111111111111111111111111111111111112";
/**
* Buys a token by performing a swap transaction.
*
* @param {string} tokenIn - The token to be swapped.
* @param {number} amountTokenOut - The amount of token to be swapped.
* @param {number} slippage - The slippage tolerance for the swap.
* @returns {Promise<void>} - A promise that resolves when the swap transaction is completed.
* @throws {Error} - If an error occurs during the swap transaction.
*/
async function buy(tokenIn, amountTokenOut, slippage) {
try {
const decimals = await getDecimals(wsol);
const convertedAmountOfTokenOut = swap_helper.convertToInteger(
amountTokenOut,
decimals
);
const quoteResponse = await swap_helper.getQuote(
wsol,
tokenIn,
convertedAmountOfTokenOut,
slippage
);
const wallet_PubKey = wallet.publicKey.toBase58();
const swapTransaction = await swap_helper.getSwapTransaction(
quoteResponse,
wallet_PubKey
);
const { confirmed, signature } = await swap_helper.finalizeTransaction(
swapTransaction
);
if (confirmed) {
console.log("http://solscan.io/tx/" + signature);
}
} catch (error) {
console.error(error);
}
}

module.exports = { buy };
35 changes: 35 additions & 0 deletions src/Trading/dex/jupiter/swap/sell-helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const swap_helper = require("./swap-helper");
const { wallet } = require("../../../../helpers/config");
const { getDecimals } = require("../../../../helpers/util");
const wsol = "So11111111111111111111111111111111111111112";

async function sell(addressOfTokenOut, amountOfTokenToSell, slippage) {
try {
const decimals = await getDecimals(addressOfTokenOut);
const convertedAmountOfTokenOut = swap_helper.convertToInteger(
amountOfTokenToSell,
decimals
);
const quoteResponse = await swap_helper.getQuote(
addressOfTokenOut,
wsol,
convertedAmountOfTokenOut,
slippage
);
const wallet_PubKey = wallet.publicKey.toBase58();
const swapTransaction = await swap_helper.getSwapTransaction(
quoteResponse,
wallet_PubKey
);
const { confirmed, signature } = await swap_helper.finalizeTransaction(
swapTransaction
);
if (confirmed) {
console.log("http://solscan.io/tx/" + signature);
}
} catch (error) {
console.error(error);
}
}

module.exports = { sell };
104 changes: 104 additions & 0 deletions src/Trading/dex/jupiter/swap/swap-helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
const { VersionedTransaction } = require("@solana/web3.js");
const fetch = require("cross-fetch");
const { connection, wallet, jito_fee } = require("../../../../helpers/config");
const {
jito_executeAndConfirm,
} = require("../../../../Transactions/jito_tips_tx_executor");
/**
* Get quote for the swap
* @param {string} addressOfTokenOut The token that we are selling
* @param {string} addressOfTokenIn The token that we are buying
* @param {number} convertedAmountOfTokenOut The amount of tokens that we are selling
* @param {number} slippage The slippage percentage
* @returns Promise<QuoteResponse>
*/
async function getQuote(
tokenOut,
tokenIn,
convertedAmountOfTokenOut,
slippage
) {
const url = `https://quote-api.jup.ag/v6/quote?inputMint=${tokenIn}\&outputMint=${tokenOut}\&amount=${convertedAmountOfTokenOut}\&slippageBps=${slippage}`;
const response = await fetch(url);
const quote = await response.json();
return quote;
}

/**
* Get serialized transactions for the swap
* @returns {Promise<string>} swapTransaction
*/
async function getSwapTransaction(quoteResponse, wallet_pubKey) {
try {
let body = null;
body = {
quoteResponse,
userPublicKey: wallet_pubKey,
wrapAndUnwrapSol: true,
restrictIntermediateTokens: false,
prioritizationFeeLamports: "auto",
autoMultiplier: 2,
};
const resp = await fetch("https://quote-api.jup.ag/v6/swap", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
const swapResponse = await resp.json();
return swapResponse.swapTransaction;
} catch (error) {
throw new Error(error);
}
}
async function convertToInteger(amount, decimals) {
return Math.floor(amount * 10 ** decimals);
}

/**
* @param {*} swapTransaction
* @returns Promise<string> txid
*/
async function finalizeTransaction(swapTransaction) {
try {
// deserialize the transaction
const swapTransactionBuf = Buffer.from(swapTransaction, "base64");
let transaction = VersionedTransaction.deserialize(swapTransactionBuf);

// sign the transaction
transaction.sign([wallet]);

const rawTransaction = transaction.serialize();
const latestBlockhash = await connection.getLatestBlockhash();
let { confirmed, signature } = await jito_executeAndConfirm(
rawTransaction,
wallet,
latestBlockhash,
jito_fee
);
while (!confirmed) {
console.log("Transaction failed");
console.log("resubmitting transaction...");
confirmed,
(signature = await jito_executeAndConfirm(
rawTransaction,
wallet,
latestBlockhash,
jito_fee
));
}
console.log(`Jito Transaction sent and confirmed with txid: ${signature}`);
return { confirmed, signature };
} catch (error) {
throw new Error(error);
}
return { confirmed: false, signature: null };
}

module.exports = {
getQuote,
getSwapTransaction,
finalizeTransaction,
convertToInteger,
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ const { currencyEquals } = require("@raydium-io/raydium-sdk");
const { sol } = require("@metaplex-foundation/js");

let walletsToListen = [];
var previous_wallet_state = {};
var previous_trader_wallet_state = {};
var previous_our_wallet_state = {};
// [usdc, sol, usdt, wsol]
const quoteToken = [
"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
Expand Down Expand Up @@ -74,7 +75,7 @@ async function listenToWallets() {

// Compare the current wallet state with the previous state
// to determine if the trader is buying or selling
const prevState = previous_wallet_state || {};
const prevState = previous_trader_wallet_state || {};
const currentState = current_wallet_state;

// Check if there is one token that decreased and one token that increased
Expand Down Expand Up @@ -148,7 +149,7 @@ async function listenToWallets() {
}

// Update the previous wallet state
previous_wallet_state = currentState;
previous_trader_wallet_state = currentState;
},
"confirmed",
[
Expand Down Expand Up @@ -197,8 +198,10 @@ async function retriveWalletState(wallet_address) {

results[mintAddress] = tokenBalance;
results["SOL"] = solBalance / 10 ** 9;

//Log results
});
console.log(results);
return results;
}

Expand All @@ -211,13 +214,18 @@ async function copy_trade() {
// wallet object
let payer_wallet = wallet;
// 0.1 SOL, fixed order size
let solperorder = 0.1;
let buyPercentage = 0;
// depends the account's token balance changes
// 20 A -> 10 A, (10 - 20) / 20 = -50% == sell 50%
// (current token balance - previous token balance / previous token balance) * 100
let sellPercentage = 100;
let smart_money_address = "smart_money_wallet_address";
previous_wallet_state = await retriveWalletState(smart_money_address);
let sellPercentage = 0;
// smart money wallet address
let smart_money_address = "your_smart_money_wallet_address_here";
// our wallet address
let our_wallet_address = wallet.publicKey.toBase58();
previous_trader_wallet_state = await retriveWalletState(smart_money_address);
previous_our_wallet_state = await retriveWalletState(our_wallet_address);
// subscribe to the smart money wallet
walletsToListen.push(new PublicKey(smart_money_address));
await listenToWallets();
}
Expand Down
3 changes: 2 additions & 1 deletion src/Transactions/simple_tx_executor.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ async function simple_executeAndConfirm(transaction, payer, lastestBlockhash) {

async function simple_execute(transaction) {
return connection.sendRawTransaction(transaction.serialize(), {
preflightCommitment: connection.commitment,
skipPreflight: true,
maxRetries: 0,
});
}

Expand Down

0 comments on commit a4b274b

Please sign in to comment.