Skip to content

Getting Started With the Transaction Manager

The transaction manager is a package that allows you to easily send transactions to the blockchain without having to handle all the potential errors that may occur until the transaction is included in a block and successfully executed.

Install

npm
npm install @happy.tech/txm

Setup

After installing, the first thing you will need to do is import the TransactionManager class and then create an instance of it.

app.ts
import { TransactionManager } from '@happy.tech/txm'
import { abis } from "./abis"
 
const txm = new TransactionManager({
    privateKey: "0x...",
    chainId: 31337,
    abis: abis,
    rpc: {
        url: 'http://localhost:8545',
    },
    gas: {}
})

After creating the transaction manager, you will need to start it.

txm.start()

Usage

Creating Transactions

We use our custom Transaction class to represent transactions. Along with the standard parameters such as source, destination, and gas fees, this class incorporates custom fields specifically tailored for the transaction manager.

You can see all the fields that our Transaction class has here.

To create a transaction, you will have to use its constructor. You can see all the fields that you can provide to the constructor here.

import { Transaction } from '@happy.tech/txm'
import { TransactionManager } from '@happy.tech/txm'
import { abis } from "./abis"
 
const txm = new TransactionManager({
    privateKey: "0x...",
    chainId: 31337,
    abis: abis,
    rpc: {
        url: 'http://localhost:8545',
    },
    gas: {}
})
 
const tx = new Transaction({
    address: "0x...",
    functionName: "transfer",
    contractName: "erc20",
    args: ["0x...", "1000000000000000000"],
    deadline: Math.floor(Date.now() / 1000) + 60,
    from: '0x...',
    chainId: 216,
}, txm.abiManager)

A very important field to understand is the intentId. This is a unique identifier for your transaction within the transaction manager.

The intentId is a field automatically generated by the transaction manager, so you don't need to provide it when creating a transaction.

It is not the same as the transaction hash, because a transaction can be resent multiple times with different nonces, gas prices, and gas limits, which alter the hash.

It is important to note that if you want to monitor the status of the transaction, you will need to use the intentId.

Sending Transactions

To send a transaction, you will need to add a TransactionOriginator

A TransactionOriginator is a function that will be called every time the transaction manager detects a new block. It will receive the latest block as an argument and will need to return an array of Transactions to be sent.

import { LatestBlock } from '@happy.tech/txm'
 
const transactions: Transaction[] = []
 
const demoOriginator = async (block: LatestBlock) => {
    return transactions
}
 
txm.addTransactionOriginator(demoOriginator)

After adding the transaction originator, the transaction manager will automatically send the transactions returned by the originator and will handle all the errors that may occur during the inclusion of the transactions in a block for you.

Monitoring Transactions

There are two ways to monitor the status of a transaction that you have sent through the transaction manager.

Active monitoring

You can call the method getTransaction of the transaction manager. This method will return the transaction with the latest changes.

Example

import { TransactionStatus } from "@happy.tech/txm"
 
const tx = await txm.getTransaction(intentId)
 
if (tx.status === TransactionStatus.Success) {
    console.log("Transaction executed successfully")
} else if (tx.status === TransactionStatus.Failed) {
    console.log("Transaction failed")
}

You can check all the possible statuses of a transaction here.

Passive monitoring

Use hooks to be notified when the status of a transaction changes. To subscribe to a hook you will have to use the addHook method.

Example

import { TxmHookType, TxmHookHandler } from "@happy.tech/txm"
 
const hookHandler: TxmHookHandler = (tx: Transaction) => {
    console.log("Transaction status changed to", tx.status)
}
 
txm.addHook(TxmHookType.OnStatusChange, hookHandler)