From 3e9b716d226ede9b1742a91431082f863c9349e4 Mon Sep 17 00:00:00 2001 From: Thunnini Date: Mon, 12 Dec 2022 15:53:41 +0900 Subject: [PATCH] Add initial `simulateMsgs` function --- wallets/cosmos.ts | 77 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/wallets/cosmos.ts b/wallets/cosmos.ts index fe5ebbd..9ad5ee0 100644 --- a/wallets/cosmos.ts +++ b/wallets/cosmos.ts @@ -7,6 +7,7 @@ import { Buffer } from "buffer/"; import { AuthInfo, Fee, + SignerInfo, TxBody, TxRaw, } from "@keplr-wallet/proto-types/cosmos/tx/v1beta1/tx"; @@ -19,7 +20,6 @@ export async function sendMsgs( wallet: Wallet, chainInfo: { readonly chainId: string; - readonly rpc: string; readonly rest: string; }, sender: string, @@ -108,6 +108,81 @@ export async function sendMsgs( return wallet.broadcastTxSync(chainInfo.chainId, signedTx); } +export async function simulateMsgs( + chainInfo: { + readonly chainId: string; + readonly rest: string; + }, + sender: string, + msgs: { + proto: Any[]; + }, + fee: { + readonly amount: readonly { + readonly amount: string; + readonly denom: string; + }[]; + }, + memo: string = "", +): Promise<{ + gasUsed: number; +}> { + const lcdInstance = Axios.create({ + baseURL: chainInfo.rest, + }); + + const account = await BaseAccount.fetchFromRest(lcdInstance, sender, true); + + const unsignedTx = TxRaw.encode({ + bodyBytes: TxBody.encode( + TxBody.fromPartial({ + // XXX: I don't know why typing error occurs. + // TODO: Solve typing problem. + messages: msgs.proto as any, + memo: memo, + }), + ).finish(), + authInfoBytes: AuthInfo.encode({ + signerInfos: [ + SignerInfo.fromPartial({ + modeInfo: { + single: { + mode: SignMode.SIGN_MODE_LEGACY_AMINO_JSON, + }, + multi: undefined, + }, + sequence: account.getSequence().toString(), + }), + ], + fee: Fee.fromPartial({ + // XXX: I don't know why typing error occurs. + // TODO: Solve typing problem. + // amount: fee.amount as { + // amount: string; + // denom: string; + // }[], + amount: fee.amount as any, + }), + }).finish(), + // Because of the validation of tx itself, the signature must exist. + // However, since they do not actually verify the signature, it is okay to use any value. + signatures: [new Uint8Array(64)], + }).finish(); + + const result = await lcdInstance.post("/cosmos/tx/v1beta1/simulate", { + tx_bytes: Buffer.from(unsignedTx).toString("base64"), + }); + + const gasUsed = parseInt(result.data.gas_info.gas_used); + if (Number.isNaN(gasUsed)) { + throw new Error(`Invalid integer gas: ${result.data.gas_info.gas_used}`); + } + + return { + gasUsed, + }; +} + export function makeCosmwasmExecMsg( sender: string, contractAddress: string,