Skip to content

Commit

Permalink
feat:added spl token support to priority fee transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
shivaji43 committed Jan 12, 2025
1 parent 2cc46dc commit 8a71d19
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 67 deletions.
12 changes: 9 additions & 3 deletions src/agent/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ import {
OrderParams,
FlashTradeParams,
FlashCloseTradeParams,
PriorityFeeTransaction,
HeliusWebhookIdResponse,
HeliusWebhookResponse,
} from "../types";
Expand Down Expand Up @@ -629,8 +628,15 @@ export class SolanaAgentKit {
priorityLevel: string,
amount: number,
to: PublicKey,
): Promise<PriorityFeeTransaction> {
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<string> {
Expand Down
207 changes: 148 additions & 59 deletions src/tools/send_transaction_with_priority.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -24,63 +30,146 @@ export async function sendTransactionWithPriorityFee(
priorityLevel: string,
amount: number,
to: PublicKey,
): Promise<PriorityFeeTransaction> {
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,
};
}
5 changes: 0 additions & 5 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,11 +239,6 @@ export interface FlashCloseTradeParams {
side: "long" | "short";
}

export interface PriorityFeeTransaction {
transactionId: string;
fee: number;
}

export interface HeliusWebhookResponse {
webhookURL: string;
webhookID: string;
Expand Down

0 comments on commit 8a71d19

Please sign in to comment.