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:
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.
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)
constwalletClient=createWalletClient({ chain: base, transport:http(), });constaccount=privateKeyToAccount(process.env.PRIVATE_KEY!as`0x${string}`);constbrian=newBrianSDK(options);constrequest=awaitbrian.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 returnedfor (constreqof request) {for (conststepofreq.data.steps!) {consttx=awaitwalletClient.sendTransaction({ account: account, to:step.to, value:BigInt(step.value), data:step.data, });console.log(`Transaction for step ${step.chainId} sent:`, tx);awaitpublicClient.waitForTransactionReceipt({ hash: tx }); // Wait for the transaction to be minedconsole.log(`Transaction for step ${step.chainId} confirmed.`); } }}
Frontend Execution (using Wagmi)
// YOUR BACKEND...constbrianAPIUrl="https://api.brianknows.org/api/v0/agent/transaction"constoptions= { 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 {constresponse=awaitfetch(brianAPIUrl, options);constrequest=awaitresponse.json();console.log(request);// Respond with the transaction detailsres.status(200).json(request) } catch (error) {console.error(error);res.status(500).json({ error:"Failed to create transaction" }); }
// YOUR FRONTEND // FRONTEND REACT TSimport { useWalletClient } from"wagmi";import { useState } from"react";exportdefaultfunctionExecuteTransaction() {const { data: walletClient } =useWalletClient();const [transactionResults,setTransactionResults] =useState<any[]>([]); // Store the array of transaction resultsconst [loading,setLoading] =useState(false);// Function to fetch transaction details from the backend APIconstfetchTransactionDetails=async () => {setLoading(true);try {constresponse=awaitfetch("/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) {thrownewError("Failed to fetch transaction details"); }constdata=awaitresponse.json();setTransactionResults(data); // Store the array of transaction resultsconsole.log("Fetched transaction details:", data); } catch (error) {console.error("Error fetching transaction details:", error); } finally {setLoading(false); } };// Function to execute all the transactions using WagmiconsthandleTransaction=async () => {try {if (!walletClient) {console.error("Wallet client not found");return; }if (transactionResults.length===0) {console.error("No transaction details available");return; }for (constresultof transactionResults) {for (conststepofresult.data.steps) {consttx=awaitwalletClient.sendTransaction({...step,// Pass all required properties directly from the step });if (tx) {awaitpublicClient?.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> );}