Merge pull request #733 from cosmos/687-common-staking-messages

Add common staking methods to SigningStargateClient
This commit is contained in:
Will Clark 2021-03-25 13:06:53 +00:00 committed by GitHub
commit cb45cdf2cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 260 additions and 7 deletions

View File

@ -46,6 +46,10 @@ and this project adheres to
not connect to Tendermint. This allows offline signing.
- @cosmjs/stargate: Add `makeMultisignedTx` which allows you to assemble a
transaction signed by a multisig account.
- @cosmjs/stargate: Add `delegateTokens`, `undelegateTokens` and
`withdrawRewards` methods to `SigningStargateClient`.
- @cosmjs/stargate: Export `defaultGasLimits` and `defaultGasPrice`.
- @cosmjs/cosmwasm-stargate: Export `defaultGasLimits`.
### Changed

View File

@ -1,3 +1,7 @@
export { cosmWasmTypes } from "./aminotypes";
export { CosmWasmClient } from "./cosmwasmclient";
export { SigningCosmWasmClient, SigningCosmWasmClientOptions } from "./signingcosmwasmclient";
export {
defaultGasLimits,
SigningCosmWasmClient,
SigningCosmWasmClientOptions,
} from "./signingcosmwasmclient";

View File

@ -91,6 +91,18 @@ describe("SigningCosmWasmClient", () => {
amount: coins(251200, "utest"),
gas: "80000",
},
delegate: {
amount: coins(502400, "utest"),
gas: "160000",
},
undelegate: {
amount: coins(502400, "utest"),
gas: "160000",
},
withdraw: {
amount: coins(502400, "utest"),
gas: "160000",
},
});
});
@ -130,6 +142,18 @@ describe("SigningCosmWasmClient", () => {
amount: coins(2000, "ucosm"),
gas: "80000",
},
delegate: {
amount: coins(4000, "ucosm"),
gas: "160000",
},
undelegate: {
amount: coins(4000, "ucosm"),
gas: "160000",
},
withdraw: {
amount: coins(4000, "ucosm"),
gas: "160000",
},
});
});
@ -170,6 +194,18 @@ describe("SigningCosmWasmClient", () => {
amount: coins(251200, "utest"),
gas: "80000",
},
delegate: {
amount: coins(502400, "utest"),
gas: "160000",
},
undelegate: {
amount: coins(502400, "utest"),
gas: "160000",
},
withdraw: {
amount: coins(502400, "utest"),
gas: "160000",
},
});
});
});

View File

@ -2,7 +2,6 @@
import { encodeSecp256k1Pubkey, makeSignDoc as makeSignDocAmino } from "@cosmjs/amino";
import {
ChangeAdminResult,
CosmWasmFeeTable,
ExecuteResult,
InstantiateOptions,
InstantiateResult,
@ -30,6 +29,8 @@ import {
buildFeeTable,
Coin,
CosmosFeeTable,
defaultGasLimits as defaultStargateGasLimits,
defaultGasPrice,
defaultRegistryTypes,
GasLimits,
GasPrice,
@ -37,6 +38,8 @@ import {
logs,
StdFee,
} from "@cosmjs/stargate";
import { MsgWithdrawDelegatorReward } from "@cosmjs/stargate/build/codec/cosmos/distribution/v1beta1/tx";
import { MsgDelegate, MsgUndelegate } from "@cosmjs/stargate/build/codec/cosmos/staking/v1beta1/tx";
import { SignMode } from "@cosmjs/stargate/build/codec/cosmos/tx/signing/v1beta1/signing";
import { TxRaw } from "@cosmjs/stargate/build/codec/cosmos/tx/v1beta1/tx";
import { Tendermint34Client } from "@cosmjs/tendermint-rpc";
@ -54,6 +57,18 @@ import {
} from "./codec/x/wasm/internal/types/tx";
import { CosmWasmClient } from "./cosmwasmclient";
/**
* These fees are used by the higher level methods of SigningCosmWasmClient
*/
export interface CosmWasmFeeTable extends CosmosFeeTable {
readonly upload: StdFee;
readonly init: StdFee;
readonly exec: StdFee;
readonly migrate: StdFee;
/** Paid when setting the contract admin to a new address or unsetting it */
readonly changeAdmin: StdFee;
}
function prepareBuilder(builder: string | undefined): string {
if (builder === undefined) {
return ""; // normalization needed by backend
@ -63,13 +78,12 @@ function prepareBuilder(builder: string | undefined): string {
}
}
const defaultGasPrice = GasPrice.fromString("0.025ucosm");
const defaultGasLimits: GasLimits<CosmWasmFeeTable> = {
export const defaultGasLimits: GasLimits<CosmWasmFeeTable> = {
...defaultStargateGasLimits,
upload: 1_500_000,
init: 500_000,
migrate: 200_000,
exec: 200_000,
send: 80_000,
changeAdmin: 80_000,
};
@ -320,6 +334,44 @@ export class SigningCosmWasmClient extends CosmWasmClient {
return this.signAndBroadcast(senderAddress, [sendMsg], this.fees.send, memo);
}
public async delegateTokens(
delegatorAddress: string,
validatorAddress: string,
amount: Coin,
memo = "",
): Promise<BroadcastTxResponse> {
const delegateMsg = {
typeUrl: "/cosmos.staking.v1beta1.MsgDelegate",
value: MsgDelegate.fromPartial({ delegatorAddress: delegatorAddress, validatorAddress, amount }),
};
return this.signAndBroadcast(delegatorAddress, [delegateMsg], this.fees.delegate, memo);
}
public async undelegateTokens(
delegatorAddress: string,
validatorAddress: string,
amount: Coin,
memo = "",
): Promise<BroadcastTxResponse> {
const undelegateMsg = {
typeUrl: "/cosmos.staking.v1beta1.MsgUndelegate",
value: MsgUndelegate.fromPartial({ delegatorAddress: delegatorAddress, validatorAddress, amount }),
};
return this.signAndBroadcast(delegatorAddress, [undelegateMsg], this.fees.undelegate, memo);
}
public async withdrawRewards(
delegatorAddress: string,
validatorAddress: string,
memo = "",
): Promise<BroadcastTxResponse> {
const withdrawMsg = {
typeUrl: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward",
value: MsgWithdrawDelegatorReward.fromPartial({ delegatorAddress: delegatorAddress, validatorAddress }),
};
return this.signAndBroadcast(delegatorAddress, [withdrawMsg], this.fees.withdraw, memo);
}
/**
* Creates a transaction with the given messages, fee and memo. Then signs and broadcasts the transaction.
*

View File

@ -84,6 +84,8 @@ export {
} from "./stargateclient";
export {
CosmosFeeTable,
defaultGasLimits,
defaultGasPrice,
defaultRegistryTypes,
SignerData,
SigningStargateClient,

View File

@ -40,6 +40,33 @@ describe("SigningStargateClient", () => {
],
gas: "80000",
},
delegate: {
amount: [
{
amount: "4000",
denom: "ucosm",
},
],
gas: "160000",
},
undelegate: {
amount: [
{
amount: "4000",
denom: "ucosm",
},
],
gas: "160000",
},
withdraw: {
amount: [
{
amount: "4000",
denom: "ucosm",
},
],
gas: "160000",
},
});
});
@ -71,6 +98,33 @@ describe("SigningStargateClient", () => {
],
gas: "80000",
},
delegate: {
amount: [
{
amount: "502400", // 3.14 * 160_000
denom: "utest",
},
],
gas: "160000",
},
undelegate: {
amount: [
{
amount: "502400",
denom: "utest",
},
],
gas: "160000",
},
withdraw: {
amount: [
{
amount: "502400",
denom: "utest",
},
],
gas: "160000",
},
});
});
@ -79,6 +133,7 @@ describe("SigningStargateClient", () => {
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic);
const gasLimits = {
send: 160000,
delegate: 120000,
};
const options = { gasLimits: gasLimits };
const client = await SigningStargateClient.connectWithSigner(simapp.tendermintUrl, wallet, options);
@ -93,6 +148,33 @@ describe("SigningStargateClient", () => {
],
gas: "160000",
},
delegate: {
amount: [
{
amount: "3000", // 0.025 * 120_000
denom: "ucosm",
},
],
gas: "120000",
},
undelegate: {
amount: [
{
amount: "4000",
denom: "ucosm",
},
],
gas: "160000",
},
withdraw: {
amount: [
{
amount: "4000",
denom: "ucosm",
},
],
gas: "160000",
},
});
});
@ -116,6 +198,33 @@ describe("SigningStargateClient", () => {
],
gas: "160000",
},
delegate: {
amount: [
{
amount: "502400", // 3.14 * 160_000
denom: "utest",
},
],
gas: "160000",
},
undelegate: {
amount: [
{
amount: "502400",
denom: "utest",
},
],
gas: "160000",
},
withdraw: {
amount: [
{
amount: "502400",
denom: "utest",
},
],
gas: "160000",
},
});
});
});

View File

@ -66,10 +66,18 @@ import { BroadcastTxResponse, StargateClient } from "./stargateclient";
*/
export interface CosmosFeeTable extends FeeTable {
readonly send: StdFee;
readonly delegate: StdFee;
readonly undelegate: StdFee;
readonly withdraw: StdFee;
}
const defaultGasPrice = GasPrice.fromString("0.025ucosm");
const defaultGasLimits: GasLimits<CosmosFeeTable> = { send: 80000 };
export const defaultGasPrice = GasPrice.fromString("0.025ucosm");
export const defaultGasLimits: GasLimits<CosmosFeeTable> = {
send: 80_000,
delegate: 160_000,
undelegate: 160_000,
withdraw: 160_000,
};
export const defaultRegistryTypes: ReadonlyArray<[string, GeneratedType]> = [
["/cosmos.bank.v1beta1.MsgMultiSend", MsgMultiSend],
@ -198,6 +206,44 @@ export class SigningStargateClient extends StargateClient {
return this.signAndBroadcast(senderAddress, [sendMsg], this.fees.send, memo);
}
public async delegateTokens(
delegatorAddress: string,
validatorAddress: string,
amount: Coin,
memo = "",
): Promise<BroadcastTxResponse> {
const delegateMsg = {
typeUrl: "/cosmos.staking.v1beta1.MsgDelegate",
value: MsgDelegate.fromPartial({ delegatorAddress: delegatorAddress, validatorAddress, amount }),
};
return this.signAndBroadcast(delegatorAddress, [delegateMsg], this.fees.delegate, memo);
}
public async undelegateTokens(
delegatorAddress: string,
validatorAddress: string,
amount: Coin,
memo = "",
): Promise<BroadcastTxResponse> {
const undelegateMsg = {
typeUrl: "/cosmos.staking.v1beta1.MsgUndelegate",
value: MsgUndelegate.fromPartial({ delegatorAddress: delegatorAddress, validatorAddress, amount }),
};
return this.signAndBroadcast(delegatorAddress, [undelegateMsg], this.fees.undelegate, memo);
}
public async withdrawRewards(
delegatorAddress: string,
validatorAddress: string,
memo = "",
): Promise<BroadcastTxResponse> {
const withdrawMsg = {
typeUrl: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward",
value: MsgWithdrawDelegatorReward.fromPartial({ delegatorAddress: delegatorAddress, validatorAddress }),
};
return this.signAndBroadcast(delegatorAddress, [withdrawMsg], this.fees.withdraw, memo);
}
public async signAndBroadcast(
signerAddress: string,
messages: readonly EncodeObject[],