From 8a71d19041d26fd0473da8a17e62231849fd9bf0 Mon Sep 17 00:00:00 2001 From: shivaji43 Date: Fri, 10 Jan 2025 17:36:48 +0530 Subject: [PATCH] feat:added spl token support to priority fee transaction --- src/agent/index.ts | 12 +- src/tools/send_transaction_with_priority.ts | 207 ++++++++++++++------ src/types/index.ts | 5 - 3 files changed, 157 insertions(+), 67 deletions(-) diff --git a/src/agent/index.ts b/src/agent/index.ts index 08bae14e..c17f667a 100644 --- a/src/agent/index.ts +++ b/src/agent/index.ts @@ -81,7 +81,6 @@ import { OrderParams, FlashTradeParams, FlashCloseTradeParams, - PriorityFeeTransaction, HeliusWebhookIdResponse, HeliusWebhookResponse, } from "../types"; @@ -629,8 +628,15 @@ export class SolanaAgentKit { priorityLevel: string, amount: number, to: PublicKey, - ): Promise { - return sendTransactionWithPriorityFee(this, priorityLevel, amount, to); + splmintAddress?: PublicKey, + ): Promise<{ transactionId: string; fee: number }> { + return sendTransactionWithPriorityFee( + this, + priorityLevel, + amount, + to, + splmintAddress, + ); } async createSquadsMultisig(creator: PublicKey): Promise { diff --git a/src/tools/send_transaction_with_priority.ts b/src/tools/send_transaction_with_priority.ts index da13ee13..136f333b 100644 --- a/src/tools/send_transaction_with_priority.ts +++ b/src/tools/send_transaction_with_priority.ts @@ -7,8 +7,14 @@ import { PublicKey, LAMPORTS_PER_SOL, } from "@solana/web3.js"; +import { + getAssociatedTokenAddress, + createTransferInstruction, + getMint, + createAssociatedTokenAccountInstruction, +} from "@solana/spl-token"; import bs58 from "bs58"; -import { PriorityFeeTransaction, PriorityFeeResponse } from "../types"; +import { PriorityFeeResponse } from "../types"; /** * Sends a transaction with an estimated priority fee using the provided SolanaAgentKit. @@ -24,63 +30,146 @@ export async function sendTransactionWithPriorityFee( priorityLevel: string, amount: number, to: PublicKey, -): Promise { - const transaction = new Transaction(); - const { blockhash, lastValidBlockHeight } = - await agent.connection.getLatestBlockhash(); - transaction.recentBlockhash = blockhash; - transaction.lastValidBlockHeight = lastValidBlockHeight; - transaction.feePayer = agent.wallet_address; - - const transferIx = SystemProgram.transfer({ - fromPubkey: agent.wallet_address, - toPubkey: to, - lamports: amount * LAMPORTS_PER_SOL, - }); - - transaction.add(transferIx); - transaction.sign(agent.wallet); - - const response = await fetch( - `https://mainnet.helius-rpc.com/?api-key=${agent.config.HELIUS_API_KEY}`, - { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - jsonrpc: "2.0", - id: "1", - method: "getPriorityFeeEstimate", - params: [ - { - transaction: bs58.encode(transaction.serialize()), - options: { priorityLevel: priorityLevel }, - }, - ], - } as PriorityFeeResponse), - }, - ); - - const data = await response.json(); - if (data.error) { - throw new Error("Error fetching priority fee:"); + splmintAddress?: PublicKey, +): Promise<{ transactionId: string; fee: number }> { + try { + if (!splmintAddress) { + const transaction = new Transaction(); + const { blockhash, lastValidBlockHeight } = + await agent.connection.getLatestBlockhash(); + transaction.recentBlockhash = blockhash; + transaction.lastValidBlockHeight = lastValidBlockHeight; + transaction.feePayer = agent.wallet_address; + + const transferIx = SystemProgram.transfer({ + fromPubkey: agent.wallet_address, + toPubkey: to, + lamports: amount * LAMPORTS_PER_SOL, + }); + + transaction.add(transferIx); + transaction.sign(agent.wallet); + + const response = await fetch( + `https://mainnet.helius-rpc.com/?api-key=${agent.config.HELIUS_API_KEY}`, + { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + jsonrpc: "2.0", + id: "1", + method: "getPriorityFeeEstimate", + params: [ + { + transaction: bs58.encode(transaction.serialize()), + options: { priorityLevel: priorityLevel }, + }, + ], + } as PriorityFeeResponse), + }, + ); + + const data = await response.json(); + if (data.error) { + throw new Error("Error fetching priority fee:"); + } + const feeEstimate: number = data.result.priorityFeeEstimate; + + // Set the priority fee if applicable + const computePriceIx = ComputeBudgetProgram.setComputeUnitPrice({ + microLamports: feeEstimate, + }); + transaction.add(computePriceIx); + + // Send the transaction and confirm + const txSignature = await sendAndConfirmTransaction( + agent.connection, + transaction, + [agent.wallet], + ); + + return { + transactionId: txSignature, + fee: feeEstimate, + }; + } else { + const fromAta = await getAssociatedTokenAddress( + splmintAddress, + agent.wallet_address, + ); + const toAta = await getAssociatedTokenAddress(splmintAddress, to); + + const mintInfo = await getMint(agent.connection, splmintAddress); + const adjustedAmount = amount * Math.pow(10, mintInfo.decimals); + + const transaction = new Transaction(); + const { blockhash, lastValidBlockHeight } = + await agent.connection.getLatestBlockhash(); + transaction.recentBlockhash = blockhash; + transaction.lastValidBlockHeight = lastValidBlockHeight; + transaction.feePayer = agent.wallet_address; + + const response = await fetch( + `https://mainnet.helius-rpc.com/?api-key=${agent.config.HELIUS_API_KEY}`, + { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + jsonrpc: "2.0", + id: "1", + method: "getPriorityFeeEstimate", + params: [ + { + transaction: bs58.encode(transaction.serialize()), + options: { priorityLevel: priorityLevel }, + }, + ], + } as PriorityFeeResponse), + }, + ); + + const data = await response.json(); + if (data.error) { + throw new Error("Error fetching priority fee:"); + } + const feeEstimate: number = data.result.priorityFeeEstimate; + + transaction.add( + ComputeBudgetProgram.setComputeUnitPrice({ + microLamports: feeEstimate, + }), + ); + + transaction.add( + createAssociatedTokenAccountInstruction( + agent.wallet_address, + toAta, + to, + splmintAddress, + ), + ); + + transaction.add( + createTransferInstruction( + fromAta, + toAta, + agent.wallet_address, + adjustedAmount, + ), + ); + + const txSignature = await sendAndConfirmTransaction( + agent.connection, + transaction, + [agent.wallet], + ); + + return { + transactionId: txSignature, + fee: feeEstimate, + }; + } + } catch (error: any) { + throw new Error(`Failed to process transaction: ${error.message}`); } - const feeEstimate: number = data.result.priorityFeeEstimate; - - // Set the priority fee if applicable - const computePriceIx = ComputeBudgetProgram.setComputeUnitPrice({ - microLamports: feeEstimate, - }); - transaction.add(computePriceIx); - - // Send the transaction and confirm - const txSignature = await sendAndConfirmTransaction( - agent.connection, - transaction, - [agent.wallet], - ); - - return { - transactionId: txSignature, - fee: feeEstimate, - }; } diff --git a/src/types/index.ts b/src/types/index.ts index 57757d7b..2c0a54ce 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -239,11 +239,6 @@ export interface FlashCloseTradeParams { side: "long" | "short"; } -export interface PriorityFeeTransaction { - transactionId: string; - fee: number; -} - export interface HeliusWebhookResponse { webhookURL: string; webhookID: string;