Skip to Content

🚧 These packages are still in development and may change rapidly as they are developed.

ReactSimulating Transactions

Simulating Transactions Guide

The following guide demonstrates how to simulate transactions using @aptos-labs/react and calculating the balance changes for an account. This basic example will simulate a transfer of APT between two accounts.

Getting Started

Setup @aptos-labs/react

Follow the Quick Start guide to set up @aptos-labs/react.

Create the SimulateTransaction Component

Create a new component called SimulateTransaction. This component will act as the form for the users to simulate a transaction.

SimulateTransaction.tsx
export default function SimulateTransaction() { return ( <form> <input name="recipientAddress" type="text" placeholder="0x1…" required /> <input name="amount" type="text" placeholder="0.5" required /> <button type="submit">Simulate</button> </form> ); }

Once the form has been set up, we can add the useSimulateTransaction hook to the component to handle the transaction simulation. We will use the useState hook to store the payload for a simple transfer transaction.

SimulateTransaction.tsx
import { InputGenerateTransactionPayloadData } from "@aptos-labs/ts-sdk"; import { useSimulateTransaction, parseApt } from "@aptos-labs/react"; import { useState } from "react"; export default function SimulateTransaction() { const [payload, setPayload] = useState<InputGenerateTransactionPayloadData>(); const { data: simulation, error: simulationError } = useSimulateTransaction({ data: payload, }); async function handleSubmit(e: React.FormEvent<HTMLFormElement>) { e.preventDefault(); // Get the form data from the event target const formData = new FormData(e.target as HTMLFormElement); const recipientAddress = formData.get("recipientAddress") as string; const amount = formData.get("amount") as string; // Use the form data to save the transaction payload of a simple transfer setPayload({ function: "0x1::account::transfer", functionArguments: [ recipientAddress, parseApt(amount), // `parseApt` parses APT amounts into octas ], }); } return ( <form onSubmit={handleSubmit}> <input name="recipientAddress" type="text" placeholder="0x1…" required /> <input name="amount" type="text" placeholder="0.5" required /> <button type="submit">Simulate</button> {simulation && <div>Simulation: {simulation}</div>} {simulationError && <div>Error: {simulationError}</div>} </form> ); }

Note that whenever the data is undefined, the useSimulateTransaction hook will not run until the data is provided. This is to prevent unnecessary simulations from being made.

Calculating Balance Changes

The @aptos-labs/js-pro package provides a TransactionParser class that can be used to parse the simulation result. This parsed result can be used to calculate the balance changes for an account.

SimulateTransaction.tsx
import { InputGenerateTransactionPayloadData } from "@aptos-labs/ts-sdk"; import { useSimulateTransaction, parseApt } from "@aptos-labs/react"; import { TransactionParser } from "@aptos-labs/js-pro"; import { useState, useMemo } from "react"; export default function SimulateTransaction() { const [payload, setPayload] = useState<InputGenerateTransactionPayloadData>(); const { data: simulation, error: simulationError } = useSimulateTransaction({ data: payload, }); async function handleSubmit(e: React.FormEvent<HTMLFormElement>) { e.preventDefault(); // Get the form data from the event target const formData = new FormData(e.target as HTMLFormElement); const recipientAddress = formData.get("recipientAddress") as string; const amount = formData.get("amount") as string; // Use the form data to sign and submit a transaction payload setPayload({ function: "0x1::account::transfer", functionArguments: [ recipientAddress, parseApt(amount), // `parseApt` parses APT amounts into octas ], }); } const balanceChanges = useMemo(() => { if (!simulation) return null; const parser = TransactionParser.create(); // Parse the simulation result into a context object. A context object breaks downs // the events and writesets into a usable format for calculating balance changes. const context = parser.parseTransaction(simulation); // Calculate the balance changes for the account. This utility function from the // `TransactionParser` class will return a map of account addresses to their balance changes. return TransactionParser.getBalanceChanges(context); }, [simulation]); return ( <form onSubmit={handleSubmit}> <input name="recipientAddress" type="text" placeholder="0x1…" required /> <input name="amount" type="text" placeholder="0.5" required /> <button type="submit">Simulate</button> {simulation && <div>Simulation: {simulation}</div>} {simulationError && <div>Error: {simulationError}</div>} {balanceChanges && <div>Balance Changes: {balanceChanges}</div>} </form> ); }

That’s it!

This simple component demonstrates the usage of useSimulateTransaction and TransactionParser to calculate the balance changes for an account. This is useful when you want to display simulations of transactions to the user. It’s important to understand that simulations may not always be accurate, especially when randomness is introduced to the transaction.

Last updated on