Transactions flow

This page explains how to leverage the Brian API/SDK to prepare and execute blockchain transactions. The Brian API provides a flexible and agnostic approach to transaction handling, enabling developers to design workflows that best fit their application's architecture.

The transaction flow consists of two main steps:

  1. Transaction Request: Your application backend interacts with the Brian API/SDK to generate one or more transaction objects. These objects include all necessary details, such as recipient addresses, values, calldata, and additional metadata for frontend purpose.

  2. Transaction Execution: Transactions can be executed in several ways, depending on your use case. The API is agnostic about execution, enabling flexibility:

    • Backend Execution: Your server signs and broadcasts the transaction using a wallet private key.

    • Frontend Execution: The transaction is sent to your frontend for user signing and execution through a wallet.

    • Smart Contract Execution: The transaction is forwarded to a smart contract call that handles execution.


Example of Transaction Execution

Backend Execution (using Viem)

  const walletClient = createWalletClient({
      chain: base,
      transport: http(),
  });

  const account = privateKeyToAccount(process.env.PRIVATE_KEY! as `0x${string}`);
  
  const brian = new BrianSDK(options);

  const request = await brian.transact({
    prompt: "swap 1 ETH for USDC on base",
    address: "vitalik.eth",
  });
  console.log("transaction result:", request);

  //Execute all the transactions in the steps array for each request returned
  for (const req of request) {
    for (const step of req.data.steps!) {
      const tx = await walletClient.sendTransaction({
        account: account,
        to: step.to,
        value: BigInt(step.value),
        data: step.data,
      });

      console.log(`Transaction for step ${step.chainId} sent:`, tx);
      await publicClient.waitForTransactionReceipt({ hash: tx }); // Wait for the transaction to be mined
      console.log(`Transaction for step ${step.chainId} confirmed.`);
    }
  }
}

Frontend Execution (using Wagmi)

// YOUR BACKEND


  ...
  const brianAPIUrl = "https://api.brianknows.org/api/v0/agent/transaction"
  const options = {
    method: 'POST',
    headers: {'Content-Type': 'application/json', 'X-Brian-Api-Key': 'your-api-key'},
    body: JSON.stringify({ // Convert the body object to a JSON string
    prompt: "I want to swap 10 MATIC to USDC on Polygon",
    address: "vitalik.eth"
    })
  };
  
  try {
    const response = await fetch(brianAPIUrl, options);
    const request = await response.json();
    console.log(request);
    // Respond with the transaction details
    res.status(200).json(request)
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "Failed to create transaction" });
  }

  
// YOUR FRONTEND  

// FRONTEND REACT TS

import { useWalletClient } from "wagmi";
import { useState } from "react";

export default function ExecuteTransaction() {
  const { data: walletClient } = useWalletClient();
  const [transactionResults, setTransactionResults] = useState<any[]>([]); // Store the array of transaction results
  const [loading, setLoading] = useState(false);

  // Function to fetch transaction details from the backend API
  const fetchTransactionDetails = async () => {
    setLoading(true);
    try {
      const response = await fetch("/api/create-transaction", { //your API
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          prompt: "swap 1 ETH for USDC on base",
          address: "vitalik.eth",
        }),
      });

      if (!response.ok) {
        throw new Error("Failed to fetch transaction details");
      }

      const data = await response.json();
      setTransactionResults(data); // Store the array of transaction results
      console.log("Fetched transaction details:", data);
    } catch (error) {
      console.error("Error fetching transaction details:", error);
    } finally {
      setLoading(false);
    }
  };

  // Function to execute all the transactions using Wagmi
  const handleTransaction = async () => {
    try {
      if (!walletClient) {
        console.error("Wallet client not found");
        return;
      }

      if (transactionResults.length === 0) {
        console.error("No transaction details available");
        return;
      }

      for (const result of transactionResults) {
        for (const step of result.data.steps) {
          const tx = await walletClient.sendTransaction({
            ...step, // Pass all required properties directly from the step
          });
          if (tx) {
            await publicClient?.waitForTransactionReceipt({
              hash: tx,
          })
          console.log(`Transaction for step ${step.chainId} confirmed.`);
        }
      }

      console.log("All transactions executed successfully.");
    } catch (error) {
      console.error("Error executing transactions:", error);
    }
  };

  return (
    <div>
      <button onClick={fetchTransactionDetails} disabled={loading}>
        {loading ? "Fetching..." : "Fetch Transaction Details"}
      </button>
      <button onClick={handleTransaction} disabled={transactionResults.length === 0}>
        Execute Transactions
      </button>
    </div>
  );
}



Smart Contract Execution

Coming soon.

Last updated