Transactions

In this guide, we will look at how to work with transaction responses from the blnk.fun API.

Buy Token Transaction

When you make a POST request to buy or sell a token, the API will return a base64-encoded transaction that can be signed and sent to Solana.

In this example, we are buying 1 SOL worth of infiniteBLINK. We take the base64-encoded transaction and deserialize it into a VersionedTransaction object.

import axios from 'axios'
import { VersionedTransaction } from '@solana/web3.js'

const response = await axios.post(
  `/api/tokens/infiVXrCfi3VCmiJnXRzKNoMZJqKwMpRfit3wWrVuB1/buy`,
  { account: 'B1NKiifexipFc3gpxAN5WACY7aRupgJT7XeFJak7aosw', amount: 1 },
)

const transaction = VersionedTransaction.deserialize(
  Buffer.from(response.data.transaction, 'base64'),
)

Signing Transactions

Transactions returned by the API need to be signed by the account passed into the API request.

Backend

When handling transactions in a backend environment, you can sign the transaction using the secret key of the account.

import { Keypair } from '@solana/web3.js'

const signer = Keypair.fromSecretKey(
  Uint8Array.from([
    // your secret key here
  ]),
)

transaction.sign([signer])

Frontend

To sign transactions in a frontend environment, you'll need to have @solana/wallet-adapter-react set up. We'll use the wallet object returned from the useWallet hook.

import { useWallet } from "@solana/wallet-adapter-react";

export function Component() {
  const wallet = useWallet()

  // ...

  const sendAndConfirmTransaction = async (transaction: VersionedTransaction) => {
    if (wallet.publicKey && wallet.signAllTransactions) {
      const transactions = await wallet.signAllTransactions([
        // include any additional transactions to sign
        transaction
      ])

      // ...
    }
  }

  // ...
}

Sending Transactions

We recommend sending frontend transactions to the Solana network using Jito's sendBundle method. This method allows you to send multiple transactions in a single request that are atomically executed in order.

Transactions sent via Jito have an increased likelihood of landing, creating a better user experience by reducing the time for transactions to confirm.

import axios from 'axios';
import base58 from 'bs58';
import { useConnection, useWallet } from "@solana/wallet-adapter-react";
import {
  LAMPORTS_PER_SOL,
  PublicKey,
  SystemProgram,
  TransactionMessage,
  VersionedTransaction,
} from "@solana/web3.js";

export function Component() {
  const wallet = useWallet()
  const { connection } = useConnection();

  // ...

  const sendAndConfirmTransaction = async (transaction: VersionedTransaction) => {
    if (wallet.publicKey && wallet.signAllTransactions) {
      const latestBlockhash = await connection.getLatestBlockhash();

      const jitoTipTransaction = new VersionedTransaction(
        new TransactionMessage({
          payerKey: wallet.publicKey,
          recentBlockhash: latestBlockhash.blockhash,
          instructions: [
            SystemProgram.transfer({
              fromPubkey: wallet.publicKey,
              toPubkey: new PublicKey(
                "3AVi9Tg9Uo68tJfuvoKvqKNWKkC5wPdSSdeBnizKZ6jT"
              ),
              lamports: 0.0025 * LAMPORTS_PER_SOL,
            }),
          ],
        }).compileToV0Message()
      );

      const transactions = await wallet.signAllTransactions([
        jitoTipTransaction,
        transaction
      ]);

      const serializedTransactions = transactions.map((transaction) =>
        base58.encode(transaction.serialize())
      );

      const response = await axios.post("https://mainnet.block-engine.jito.wtf/api/v1/bundles", {
        jsonrpc: '2.0',
        id: 1,
        method: 'sendBundle',
        params: [serializedTransactions],
      });
    }
  }

  // ...
}