Add query extension tx for simulation
This commit is contained in:
parent
25556ae4a8
commit
8a944ddf21
@ -78,7 +78,9 @@ export {
|
||||
setupGovExtension,
|
||||
setupIbcExtension,
|
||||
setupStakingExtension,
|
||||
setupTxExtension,
|
||||
StakingExtension,
|
||||
TxExtension,
|
||||
} from "./queries";
|
||||
export {
|
||||
SearchByHeightQuery,
|
||||
|
||||
@ -10,4 +10,5 @@ export { DistributionExtension, setupDistributionExtension } from "./distributio
|
||||
export { setupGovExtension, GovExtension, GovProposalId, GovParamsType } from "./gov";
|
||||
export { IbcExtension, setupIbcExtension } from "./ibc";
|
||||
export { setupStakingExtension, StakingExtension } from "./staking";
|
||||
export { setupTxExtension, TxExtension } from "./tx";
|
||||
export { createPagination, createProtobufRpcClient, ProtobufRpcClient } from "./utils";
|
||||
|
||||
104
packages/stargate/src/queries/tx.spec.ts
Normal file
104
packages/stargate/src/queries/tx.spec.ts
Normal file
@ -0,0 +1,104 @@
|
||||
import { coin, coins, DirectSecp256k1HdWallet, Registry } from "@cosmjs/proto-signing";
|
||||
import { Tendermint34Client } from "@cosmjs/tendermint-rpc";
|
||||
import { assertDefined, sleep } from "@cosmjs/utils";
|
||||
import { MsgDelegate } from "cosmjs-types/cosmos/staking/v1beta1/tx";
|
||||
import Long from "long";
|
||||
|
||||
import { defaultRegistryTypes, SigningStargateClient } from "../signingstargateclient";
|
||||
import { assertIsBroadcastTxSuccess, StargateClient } from "../stargateclient";
|
||||
import {
|
||||
defaultSigningClientOptions,
|
||||
faucet,
|
||||
makeRandomAddress,
|
||||
pendingWithoutSimapp,
|
||||
simapp,
|
||||
simappEnabled,
|
||||
validator,
|
||||
} from "../testutils.spec";
|
||||
import { QueryClient } from "./queryclient";
|
||||
import { setupTxExtension, TxExtension } from "./tx";
|
||||
import { longify } from "./utils";
|
||||
|
||||
async function makeClientWithTx(rpcUrl: string): Promise<[QueryClient & TxExtension, Tendermint34Client]> {
|
||||
const tmClient = await Tendermint34Client.connect(rpcUrl);
|
||||
return [QueryClient.withExtensions(tmClient, setupTxExtension), tmClient];
|
||||
}
|
||||
|
||||
describe("TxExtension", () => {
|
||||
const defaultFee = {
|
||||
amount: coins(25000, "ucosm"),
|
||||
gas: "1500000", // 1.5 million
|
||||
};
|
||||
let txHash: string | undefined;
|
||||
let memo: string | undefined;
|
||||
|
||||
beforeAll(async () => {
|
||||
if (simappEnabled()) {
|
||||
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic);
|
||||
const client = await SigningStargateClient.connectWithSigner(
|
||||
simapp.tendermintUrl,
|
||||
wallet,
|
||||
defaultSigningClientOptions,
|
||||
);
|
||||
|
||||
{
|
||||
const recipient = makeRandomAddress();
|
||||
memo = `Test tx ${Date.now()}`;
|
||||
const result = await client.sendTokens(
|
||||
faucet.address0,
|
||||
recipient,
|
||||
coins(25000, "ucosm"),
|
||||
defaultFee,
|
||||
memo,
|
||||
);
|
||||
assertIsBroadcastTxSuccess(result);
|
||||
txHash = result.transactionHash;
|
||||
}
|
||||
|
||||
await sleep(75); // wait until transactions are indexed
|
||||
}
|
||||
});
|
||||
|
||||
describe("getTx", () => {
|
||||
it("works", async () => {
|
||||
pendingWithoutSimapp();
|
||||
assertDefined(txHash);
|
||||
assertDefined(memo);
|
||||
const [client, tmClient] = await makeClientWithTx(simapp.tendermintUrl);
|
||||
|
||||
const response = await client.tx.getTx(txHash);
|
||||
expect(response.tx?.body?.memo).toEqual(memo);
|
||||
|
||||
tmClient.disconnect();
|
||||
});
|
||||
});
|
||||
|
||||
describe("simulate", () => {
|
||||
it("works", async () => {
|
||||
pendingWithoutSimapp();
|
||||
assertDefined(txHash);
|
||||
assertDefined(memo);
|
||||
const [client, tmClient] = await makeClientWithTx(simapp.tendermintUrl);
|
||||
const sequenceClient = await StargateClient.connect(simapp.tendermintUrl);
|
||||
|
||||
const registry = new Registry(defaultRegistryTypes);
|
||||
const msg: MsgDelegate = {
|
||||
delegatorAddress: faucet.address0,
|
||||
validatorAddress: validator.validatorAddress,
|
||||
amount: coin(25000, "ustake"),
|
||||
};
|
||||
const msgAny = registry.encodeAsAny({
|
||||
typeUrl: "/cosmos.staking.v1beta1.MsgDelegate",
|
||||
value: msg,
|
||||
});
|
||||
|
||||
const { sequence } = await sequenceClient.getSequence(faucet.address0);
|
||||
const response = await client.tx.simulate([msgAny], "foo", faucet.pubkey0, sequence);
|
||||
expect(response.gasInfo?.gasUsed.toNumber()).toBeGreaterThanOrEqual(101_000);
|
||||
expect(response.gasInfo?.gasUsed.toNumber()).toBeLessThanOrEqual(107_000);
|
||||
expect(response.gasInfo?.gasWanted).toEqual(longify(Long.UZERO));
|
||||
|
||||
tmClient.disconnect();
|
||||
});
|
||||
});
|
||||
});
|
||||
81
packages/stargate/src/queries/tx.ts
Normal file
81
packages/stargate/src/queries/tx.ts
Normal file
@ -0,0 +1,81 @@
|
||||
import { Pubkey } from "@cosmjs/amino";
|
||||
import { encodePubkey } from "@cosmjs/proto-signing";
|
||||
import { SignMode } from "cosmjs-types/cosmos/tx/signing/v1beta1/signing";
|
||||
import {
|
||||
GetTxRequest,
|
||||
GetTxResponse,
|
||||
ServiceClientImpl,
|
||||
SimulateRequest,
|
||||
SimulateResponse,
|
||||
} from "cosmjs-types/cosmos/tx/v1beta1/service";
|
||||
import { AuthInfo, Fee, Tx, TxBody } from "cosmjs-types/cosmos/tx/v1beta1/tx";
|
||||
import { Any } from "cosmjs-types/google/protobuf/any";
|
||||
import Long from "long";
|
||||
|
||||
import { QueryClient } from "./queryclient";
|
||||
import { createProtobufRpcClient } from "./utils";
|
||||
|
||||
export interface TxExtension {
|
||||
readonly tx: {
|
||||
getTx: (txId: string) => Promise<GetTxResponse>;
|
||||
simulate: (
|
||||
messages: readonly Any[],
|
||||
memo: string | undefined,
|
||||
signer: Pubkey,
|
||||
sequence: number,
|
||||
) => Promise<SimulateResponse>;
|
||||
// Add here with tests:
|
||||
// - broadcastTx
|
||||
// - getTxsEvent
|
||||
};
|
||||
}
|
||||
|
||||
export function setupTxExtension(base: QueryClient): TxExtension {
|
||||
// Use this service to get easy typed access to query methods
|
||||
// This cannot be used for proof verification
|
||||
const rpc = createProtobufRpcClient(base);
|
||||
const queryService = new ServiceClientImpl(rpc);
|
||||
|
||||
return {
|
||||
tx: {
|
||||
getTx: async (txId: string) => {
|
||||
const request: GetTxRequest = {
|
||||
hash: txId,
|
||||
};
|
||||
const response = await queryService.GetTx(request);
|
||||
return response;
|
||||
},
|
||||
simulate: async (
|
||||
messages: readonly Any[],
|
||||
memo: string | undefined,
|
||||
signer: Pubkey,
|
||||
sequence: number,
|
||||
) => {
|
||||
const request = SimulateRequest.fromPartial({
|
||||
tx: Tx.fromPartial({
|
||||
authInfo: AuthInfo.fromPartial({
|
||||
fee: Fee.fromPartial({}),
|
||||
signerInfos: [
|
||||
{
|
||||
publicKey: encodePubkey(signer),
|
||||
sequence: Long.fromNumber(sequence, true),
|
||||
modeInfo: { single: { mode: SignMode.SIGN_MODE_DIRECT } },
|
||||
},
|
||||
],
|
||||
}),
|
||||
body: TxBody.fromPartial({
|
||||
messages: Array.from(messages),
|
||||
memo: memo,
|
||||
}),
|
||||
signatures: [new Uint8Array()],
|
||||
}),
|
||||
// Sending serialized `txBytes` is the future. But
|
||||
// this is not available in Comsos SDK 0.42.
|
||||
txBytes: undefined,
|
||||
});
|
||||
const response = await queryService.Simulate(request);
|
||||
return response;
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user