Ethereum Transaction
Every transaction on Injective follows the same flow. The flow consists of three steps: preparing, signing and broadcasting the transaction. Let's dive into each step separately and explain the process in-depth (including examples) so we can understand the whole transaction flow.
Preparing a transaction
First of, we need to prepare the transaction for signing. To use Ethereum native wallets, we have to convert the transaction to EIP712 typed data and use the wallet to sign this typed data.
Using our custom abstraction for the Messages which allows the developer to get EIP712 TypedData straight from the proto file of the particular message.
import {
MsgSend,
BaseAccount,
ChainRestAuthApi,
getEip712TypedDataV2,
ChainRestTendermintApi,
} from "@injectivelabs/sdk-ts";
import {
toBigNumber,
toChainFormat,
DEFAULT_BLOCK_TIMEOUT_HEIGHT,
} from "@injectivelabs/utils";
import { ChainId, EvmChainId } from "@injectivelabs/ts-types";
import { Network, getNetworkEndpoints } from "@injectivelabs/networks";
const injectiveAddress = "inj1";
const chainId = ChainId.Mainnet;
const evmChainId = EvmChainId.Mainnet;
const restEndpoint =
"https://lcd.injective.network"; /* getNetworkEndpoints(Network.Mainnet).rest */
const amount = {
denom: "inj",
amount: toChainFormat(0.01).toFixed(),
};
/** Account Details **/
const chainRestAuthApi = new ChainRestAuthApi(restEndpoint);
const accountDetailsResponse = await chainRestAuthApi.fetchAccount(
injectiveAddress
);
const baseAccount = BaseAccount.fromRestApi(accountDetailsResponse);
const accountDetails = baseAccount.toAccountDetails();
/** Block Details */
const chainRestTendermintApi = new ChainRestTendermintApi(restEndpoint);
const latestBlock = await chainRestTendermintApi.fetchLatestBlock();
const latestHeight = latestBlock.header.height;
const timeoutHeight = toBigNumber(latestHeight).plus(
DEFAULT_BLOCK_TIMEOUT_HEIGHT
);
/** Preparing the transaction */
const msg = MsgSend.fromJSON({
amount,
srcInjectiveAddress: injectiveAddress,
dstInjectiveAddress: injectiveAddress,
});
/** EIP712 for signing on Ethereum wallets */
const eip712TypedData = getEip712TypedDataV2({
msgs: [msg],
tx: {
accountNumber: accountDetails.accountNumber.toString(),
sequence: accountDetails.sequence.toString(),
timeoutHeight: timeoutHeight.toFixed(),
chainId: chainId,
},
evmChainId,
});Signing a transaction
Once we have prepared the EIP712 typed data, we proceed to signing.
You can also use our @injectivelabs/wallet-strategy package to get out-of-the-box wallet provides that will give you abstracted methods which you can use to sign transaction. Refer to the documentation of the package, its really simple to setup and use. This is the recommended way as you have access to more than one wallet to use in your dApp. The WalletStrategy provides more than just signing transaction abstractions.
Broadcasting a transaction
Once we have the signature ready, we need to broadcast the transaction to the Injective chain itself. After getting the signature from the second step, we need to include that signature in the signed transaction and broadcast it to the chain.
Example without WalletStrategy (Prepare + Sign + Broadcast)
Let's have a look at the whole flow (using Metamask as a signing wallet)
Example with WalletStrategy (Prepare + Sign + Broadcast)
Example can be found here.
Last updated
