Skip to content

Commit

Permalink
added bloXroute tx exeutor in src/Transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
outsmartchad committed Aug 22, 2024
1 parent f514b87 commit 8880f4b
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 46 deletions.
65 changes: 65 additions & 0 deletions src/Transactions/bloXroute_tips_tx_executor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const {
createTraderAPIMemoInstruction,
HttpProvider,
MAINNET_API_UK_HTTP,
} = require("@bloxroute/solana-trader-client-ts");
const { private_key, bloXRoute_auth_header } = require("../helpers/config");
const {
Connection,
LAMPORTS_PER_SOL,
PublicKey,
Keypair,
SystemProgram,
} = require("@solana/web3.js");
const base58 = require("bs58");
const { Transaction } = require("@solana/web3.js");
const TRADER_API_TIP_WALLET = "HWEoBxYs7ssKuudEjzjmpfJVX7Dvi7wescFsVx2L5yoY";
const provider = new HttpProvider(
bloXRoute_auth_header,
private_key,
MAINNET_API_UK_HTTP
);
async function CreateTraderAPITipTransaction(
senderAddress,
tipAmountInLamports
) {
const tipAddress = new PublicKey(TRADER_API_TIP_WALLET);
return new Transaction().add(
SystemProgram.transfer({
fromPubkey: senderAddress,
toPubkey: tipAddress,
lamports: tipAmountInLamports,
})
);
}
async function bloXroute_executeAndConfirm(transaction, signers) {
const memo = createTraderAPIMemoInstruction("");
const wallet = Keypair.fromSecretKey(base58.decode(private_key));
const recentBlockhash = await provider.getRecentBlockHash({});
let tx = new Transaction({
recentBlockhash: recentBlockhash.blockHash,
feePayer: wallet.publicKey,
});
tx.add(transaction);
tx.add(memo);
tx.add(await CreateTraderAPITipTransaction(wallet.publicKey, 0.001 * LAMPORTS_PER_SOL));
tx.sign(wallet);
const serializeTxBytes = tx.serialize();
const buffTx = Buffer.from(serializeTxBytes);
const encodedTx = buffTx.toString("base64");
console.log("Submitting transaction to bloXroute...");
const response = await provider.postSubmit({
transaction: { content: encodedTx, isCleanup: false },
skipPreFlight: false,
});

if (response.signature) {
console.log(
`✅ txn landed successfully\nSignature: https://solscan.io/tx/${response.signature}`
);
} else {
console.log("❌ Transaction failed");
}
}

module.exports = { bloXroute_executeAndConfirm };
4 changes: 3 additions & 1 deletion src/helpers/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ function loadKeypairFromFile(filename) {
const jito_fee = process.env.JITO_FEE; // 0.00009 SOL
const shyft_api_key = process.env.SHYFT_API_KEY; // your shyft api key
const wallet = Keypair.fromSecretKey(bs58.decode(process.env.PRIVATE_KEY)); // your wallet
const private_key = process.env.PRIVATE_KEY; // your private key
const dev_endpoint = process.env.DEVNET_ENDPOINT; // devnet endpoint, if you use devnet
const main_endpoint = process.env.MAINNET_ENDPOINT; // mainnet endpoint
const bloXRoute_auth_header = process.env.BLOXROUTE_AUTH_HEADER;
Expand Down Expand Up @@ -89,5 +90,6 @@ module.exports = {
shyft_api_key,
jito_fee,
smart_money_wallet,
bloXRoute_auth_header
bloXRoute_auth_header,
private_key
};
140 changes: 95 additions & 45 deletions src/raydium/Pool/swap.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ const {
TransactionMessage,
ComputeBudgetProgram,
VersionedTransaction,
LAMPORTS_PER_SOL
LAMPORTS_PER_SOL,
Transaction,
} = require("@solana/web3.js");
const { Decimal } = require("decimal.js");
const { BN } = require("@project-serum/anchor");
Expand All @@ -24,15 +25,15 @@ const {
RAYDIUM_MAINNET_API,
_ENDPOINT,
wallet,
jito_fee
jito_fee,
} = require("../../helpers/config.js");
const {
getDecimals,
getTokenMetadata,
checkTx,
} = require("../../helpers/util.js");
//const { getPoolId, getPoolIdByPair } = require("./query_pool.js");
const {fetchAMMPoolId} = require("./fetch_pool.js")
const { fetchAMMPoolId } = require("./fetch_pool.js");
const {
getAssociatedTokenAddress,
getAssociatedTokenAddressSync,
Expand All @@ -47,11 +48,8 @@ const {
const {
jito_executeAndConfirm,
} = require("../../Transactions/jito_tips_tx_executor.js");

let tokenToPoolIdMap = {

};

const {bloXroute_executeAndConfirm} = require("../../Transactions/bloXroute_tips_tx_executor.js")
let tokenToPoolIdMap = {};

/**
* Performs a swap transaction using an Automated Market Maker (AMM) pool.
Expand Down Expand Up @@ -105,13 +103,12 @@ async function swapOnlyAmm(input) {
payerKey: wallet.publicKey,
recentBlockhash: latestBlockhash.blockhash,
instructions: [

...[
ComputeBudgetProgram.setComputeUnitPrice({
microLamports: 3052900,
microLamports: 305290,
}),
ComputeBudgetProgram.setComputeUnitLimit({
units: 3127500,
units: 312750,
}),
],
...(input.side === "buy"
Expand All @@ -134,32 +131,90 @@ async function swapOnlyAmm(input) {
const maxAttempts = 3;

while (attempts < maxAttempts) {
attempts++;
try {
const res = await jito_executeAndConfirm(transaction, wallet, latestBlockhash, jito_fee);
const signature = res.signature;
const confirmed = res.confirmed;
attempts++;
try {
const res = await jito_executeAndConfirm(
transaction,
wallet,
latestBlockhash,
jito_fee
);
const signature = res.signature;
const confirmed = res.confirmed;

if (signature) {
return { txid: signature };
} else {
console.log("jito fee transaction failed");
console.log(`Retry attempt ${attempts}`);
}
} catch (e) {
console.log(e);
if (e.signature) {
return { txid: e.signature };
}
if (signature) {
return { txid: signature };
} else {
console.log("jito fee transaction failed");
console.log(`Retry attempt ${attempts}`);
}
} catch (e) {
console.log(e);
if (e.signature) {
return { txid: e.signature };
}
latestBlockhash = await connection.getLatestBlockhash();
}
latestBlockhash = await connection.getLatestBlockhash();
}

console.log("Transaction failed after maximum retry attempts");
return { txid: null };
}


async function swapOnlyAmmUsingBloXRoute(input) {
const poolKeys = await formatAmmKeysById_swap(
new PublicKey(input.targetPool)
);
assert(poolKeys, "cannot find the target pool");
const poolInfo = await Liquidity.fetchInfo({
connection: connection,
poolKeys: poolKeys,
});
// -------- step 1: coumpute amount out --------
const { amountOut, minAmountOut } = Liquidity.computeAmountOut({
poolKeys: poolKeys,
poolInfo: poolInfo,
amountIn: input.inputTokenAmount,
currencyOut: input.outputToken,
slippage: input.slippage,
});
// -------- step 2: create instructions by SDK function --------
const { innerTransaction } = await Liquidity.makeSwapFixedInInstruction(
{
poolKeys: poolKeys,
userKeys: {
tokenAccountIn: input.ataIn,
tokenAccountOut: input.ataOut,
owner: wallet.publicKey,
},
amountIn: input.inputTokenAmount.raw,
minAmountOut: minAmountOut.raw,
},
poolKeys.version
);
if (input.usage == "volume") return innerTransaction;
const latestBlockhash = await connection.getLatestBlockhash();
let tx = new Transaction();
tx.add(
ComputeBudgetProgram.setComputeUnitPrice({
microLamports: 305290,
}),
ComputeBudgetProgram.setComputeUnitLimit({
units: 312750,
}),
...(input.side === "buy"
? [
createAssociatedTokenAccountIdempotentInstruction(
wallet.publicKey,
input.ataOut,
wallet.publicKey,
input.outputToken.mint
),
]
: []),
...innerTransaction.instructions,
)
await bloXroute_executeAndConfirm(tx, [wallet]);
}
/**
* Swaps tokens for a specified volume.
* @param {string} tokenAddr - The address of the token to swap.
Expand Down Expand Up @@ -210,11 +265,7 @@ async function swapForVolume(tokenAddr, sol_per_order) {
let signature = null,
confirmed = null;
try {
const res = simple_executeAndConfirm(
transaction,
wallet,
latestBlockhash
);
const res = simple_executeAndConfirm(transaction, wallet, latestBlockhash);
signature = res.signature;
confirmed = res.confirmed;
} catch (e) {
Expand All @@ -224,8 +275,6 @@ async function swapForVolume(tokenAddr, sol_per_order) {
return { confirmed: confirmed, txid: signature };
}



/**
* Helper function for swapping tokens using the AMM protocol.
* @param {Object} input - The input object containing the necessary parameters for the swap.
Expand All @@ -248,7 +297,6 @@ async function swapOnlyAmmHelper(input) {
console.log(`https://solscan.io/tx/${txid}?cluster=mainnet`);
} else {
console.log("Transaction failed");

}
}
/**
Expand Down Expand Up @@ -290,10 +338,10 @@ async function swap(
);
const inputToken = DEFAULT_TOKEN.WSOL; // SOL
let targetPool = null;
if(!(tokenAddress in tokenToPoolIdMap)){
if (!(tokenAddress in tokenToPoolIdMap)) {
targetPool = await fetchAMMPoolId(tokenAddress);
tokenToPoolIdMap[tokenAddress] = targetPool;
}else targetPool = tokenToPoolIdMap[tokenAddress];
} else targetPool = tokenToPoolIdMap[tokenAddress];

if (targetPool === null) {
console.log(
Expand All @@ -320,7 +368,8 @@ async function swap(
if (usage == "volume") {
return await swapOnlyAmm(input);
}
swapOnlyAmmHelper(input);
//swapOnlyAmmHelper(input); // using jito
swapOnlyAmmUsingBloXRoute(input); // using bloXroute
} else {
// sell
const { tokenName, tokenSymbol } = await getTokenMetadata(tokenAddress);
Expand All @@ -333,10 +382,10 @@ async function swap(
);
const outputToken = DEFAULT_TOKEN.WSOL; // SOL
let targetPool = null;
if(!(tokenAddress in tokenToPoolIdMap)){
if (!(tokenAddress in tokenToPoolIdMap)) {
targetPool = await fetchAMMPoolId(tokenAddress);
tokenToPoolIdMap[tokenAddress] = targetPool;
}else targetPool = tokenToPoolIdMap[tokenAddress];
} else targetPool = tokenToPoolIdMap[tokenAddress];

if (targetPool === null) {
console.log(
Expand Down Expand Up @@ -368,12 +417,13 @@ async function swap(
ataOut: quoteAta,
side,
usage,
tokenAddress: tokenAddress
tokenAddress: tokenAddress,
};
if (usage == "volume") {
return await swapOnlyAmm(input);
}
swapOnlyAmmHelper(input);
//swapOnlyAmmHelper(input); // using Jito
swapOnlyAmmUsingBloXRoute(input); // using bloXroute
}
}

Expand Down

0 comments on commit 8880f4b

Please sign in to comment.