import {
MsgSend,
ChainRestAuthApi,
ChainRestTendermintApi,
BaseAccount,
getEip712TypedData,
getEthereumAddress,
recoverTypedSignaturePubKey,
hexToBase64,
createTransaction,
SIGN_AMINO,
createWeb3Extension,
createTxRawEIP712,
TxRestApi,
} from "@injectivelabs/sdk-ts";
import {
BigNumberInBase,
DEFAULT_STD_FEE,
DEFAULT_BLOCK_TIMEOUT_HEIGHT,
} from "@injectivelabs/utils";
import { ChainId } from "@injectivelabs/ts-types";
import { Network, getNetworkEndpoints } from "@injectivelabs/networks";
const injectiveAddress = "inj1";
const ethereumAddress = getEthereumAddress(injectiveAddress)
const chainId = "injective-1"; /* ChainId.Mainnet */
const ethereumChainId = 1; /* ChainId.EthereumMainnet */
const restEndpoint = getNetworkEndpoints(Network.MainnetSentry).rest;
const amount = {
amount: new BigNumberInBase(0.01).toWei().toFixed(),
denom: "inj",
};
/** 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 = new BigNumberInBase(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 = getEip712TypedData({
msgs: [msg],
tx: {
accountNumber: accountDetails.accountNumber.toString(),
sequence: accountDetails.sequence.toString(),
timeoutHeight: timeoutHeight.toFixed(),
chainId: chainId,
},
ethereumChainId: ethereumChainId,
});
/** Use your preferred approach to sign EIP712 TypedData, example with Metamask */
const signature = await window.ethereum.request({
method: "eth_signTypedData_v4",
params: [ethereumAddress, JSON.stringify(eip712TypedData)],
});
/** Get Public Key of the signer */
const publicKeyHex = recoverTypedSignaturePubKey(eip712TypedData, signature);
const publicKeyBase64 = hexToBase64(publicKeyHex);
const signatureBuff = Buffer.from(signature.replace('0x', ''), "hex");
const { txRaw } = createTransaction({
message: [msg],
memo: '',
signMode: SIGN_AMINO,
fee: DEFAULT_STD_FEE,
pubKey: publicKeyBase64,
sequence: baseAccount.sequence,
timeoutHeight: timeoutHeight.toNumber(),
accountNumber: baseAccount.accountNumber,
chainId: chainId,
});
const web3Extension = createWeb3Extension({
ethereumChainId,
});
const txRawEip712 = createTxRawEIP712(txRaw, web3Extension);
/** Append Signatures */
txRawEip712.signatures = [signatureBuff];
/** Broadcast the Transaction */
const txRestApi = new TxRestApi(restEndpoint);
const txResponse = await txRestApi.broadcast(txRawEip712);
const response = await txRestApi.fetchTxPoll(txResponse.txHash);