Skip to main content

Create a transaction

Overview

This guide describes how to create and send transactions to the blockchain using MPC (multi-party computation).

To create a transaction, make a call to the MPC SDK with the necessary parameters. The SDK then sends the transaction to the blockchain. The SDK supports the following types of transactions:

  • Transfer tokens: the default type, used for transferring assets like the native token RON and various ERC20 tokens from one source to one destination.
  • Contract call: Directly call any function of a smart contract.
  • Sign messages: Sign messages with the standard Ethereum prefix.
  • Approve tokens: Approve ERC20 tokens to be spent on another address.

When sending a transaction, you can choose how you want to manage gas fees: let the SDK estimate the fees automatically, or estimate them manually before sending the transaction. For more information, see Estimate gas.

All operations with transactions return a transaction hash. After obtaining it, you need to confirm that the transaction is successful before any further handling.

Prerequisites

Complete the steps in Create an MPC wallet.

Interact with wallets

Lockbox is EIP-1193 compliant, which means it can be used with any provider that supports this standard. The following examples show how to use Lockbox with popular libraries like ethers.js, Web3.js, and viem.

Usage with ethers.js (v5):

import * as ethers from "ethers";

const walletProvider = new ethers.providers.Web3Provider(lockbox.getProvider());

Transfer RON

Transfer the RON token from one address to another.

const tx = await walletProvider
.getSigner()
.sendTransaction({ to: toAddress, value: rawAmount, type: type });

You can choose to manually construct a txJSON object based on the EVM (Ethereum Virtual Machine) standard, or let the SDK fill in the transaction parameters automatically.

This example shows how to transfer 10 RON to another address:

const amount: BigNumber = BigNumber.from(10)
const toAddress = ${RECEIVER_ADDRESS};

const tx = await walletProvider
.getSigner()
.sendTransaction({ to: toAddress, value: amount})

console.log(tx.hash); // Transaction hash

Transfer ERC20 token

Transfer an ERC20 token, such as AXS, to a specified address.

const txData = await contract.transfer(toAddress, rawAmount);

This example shows how to transfer 1 AXS to another address:

// Create a contract instance using Ethers.js
import { Contract } from "ethers";

const contractAddress = `0x3c4e17b9056272ce1b49f6900d8cfd6171a1869d`; // AXS Contract
const contract = new Contract(contractAddress, ABI, walletProvider.getSigner());

const toAddress = `${RECEIVER_ADDRESS}`;
const amount = ethers.utils.parseUnits("1", 18); // 1 AXS

// Transfer - function of smart contract
const txData = await contract.transfer(toAddress, amount);

Approve ERC20 token

Allow a smart contract to spend a specified amount of an ERC20 token, such as AXS.

Invoke the approve ERC20 function through walletProvider:

// Create a contract using Ethers.js
import { Contract } from "ethers";
...
const contract = new Contract(contractAddress, ABI, walletProvider.getSigner());

// Approve - function of smart contract
const approveTX = await contract.approve(spender, amount);

This example shows how to approve a smart contract to spend 1 AXS:

const contractAddress = "0x3c4e17b9056272ce1b49f6900d8cfd6171a1869d"; // AXS contract
const ABI = `${AXS_ABI}`;
const spender = `${SPENDER_ADDRESS}`;
const approveAmount = ethers.utils.parseUnits("1", 18); // 1 AXS

// Create a contract instance
const contract = new Contract(contractAddress, ABI, walletProvider.getSigner());

// Use approve() in contract
const approveTxHash = await contract.approve(spender, approveAmount);
//...

Call contract function

Call any function of a smart contract.

Before invoking a contract call using walletProvider, you need to compute the input field, including the function selector and parameters.

const contract = new Contract(contractAddress, ABI, walletProvider.getSigner());
caution

Do not use the transfer() and approve() ERC20 functions directly within contract calls.

This example shows how to call the function submit_numbers(uint8[],uint256[]) from a contract with specific parameters submit_numbers([12],[1]):

const contractAddress = "0xaeD7F0FaEc15981835aaAeEd9c8D21327385743e"; // AXS
const ABI = {
...
{
inputs: [
{
internalType: "uint8[]",
name: "numbers",
type: "uint8[]"
},
{
internalType: "uint256[]",
name: "points",
type: "uint256[]"
},
],
name: "submit_numbers",
outputs: [],
stateMutability: "payable",
type: "function"
},
...
};
const contract = new Contract(contractAddress, ABI , walletProvider.getSigner());
const tx = await contract.submit_numbers([12], [1]);

Sign message

Sign a string message with the standard \x19Ethereum Signed Message prefix.

info

Before signing a message, ensure it's encoded to the Base64 format.

To sign a message using walletProvider, call the signMessage function:

const txHash = await walletProvider.getSigner().signMessage(message);

Example:

const encodedMessage =
"Sign this message to breed Axie #223495 with Axie #123232";
const txHash = await walletProvider.getSigner().signMessage(encodedMessage);
//...

Next steps

Recover a wallet from backup