Add "auto" option to fee
This commit is contained in:
parent
e3b18c3859
commit
86467822f9
@ -22,9 +22,19 @@ const rpcEndpoint = "ws://localhost:26658";
|
||||
const gasPrice = GasPrice.fromString("0.025ucosm");
|
||||
|
||||
// Setup client
|
||||
const client = await SigningStargateClient.connectWithSigner(rpcEndpoint, wallet);
|
||||
const client = await SigningStargateClient.connectWithSigner(rpcEndpoint, wallet, { gasPrice: gasPrice });
|
||||
|
||||
// Send transaction (using sendTokens)
|
||||
// Send transaction (using sendTokens with auto gas)
|
||||
{
|
||||
const recipient = "cosmos1xv9tklw7d82sezh9haa573wufgy59vmwe6xxe5";
|
||||
const amount = coins(1234567, "ucosm");
|
||||
const memo = "With simulate";
|
||||
const result = await client.sendTokens(account.address, recipient, amount, "auto", memo);
|
||||
assertIsBroadcastTxSuccess(result);
|
||||
console.log("Successfully broadcasted:", result);
|
||||
}
|
||||
|
||||
// Send transaction (using sendTokens with manual gas)
|
||||
{
|
||||
const recipient = "cosmos1xv9tklw7d82sezh9haa573wufgy59vmwe6xxe5";
|
||||
const amount = coins(1234567, "ucosm");
|
||||
@ -38,13 +48,31 @@ const client = await SigningStargateClient.connectWithSigner(rpcEndpoint, wallet
|
||||
};
|
||||
const memo = "With simulate";
|
||||
const gasEstimation = await client.simulate(account.address, [sendMsg], memo);
|
||||
const fee = calculateFee(Math.floor(gasEstimation * 1.3), gasPrice);
|
||||
const fee = calculateFee(Math.round(gasEstimation * 1.3), gasPrice);
|
||||
const result = await client.sendTokens(account.address, recipient, amount, fee, memo);
|
||||
assertIsBroadcastTxSuccess(result);
|
||||
console.log("Successfully broadcasted:", result);
|
||||
}
|
||||
|
||||
// Send transaction (using signAndBroadcast)
|
||||
// Send transaction (using signAndBroadcast with auto gas)
|
||||
{
|
||||
const recipient = "cosmos1xv9tklw7d82sezh9haa573wufgy59vmwe6xxe5";
|
||||
const amount = coins(1234567, "ucosm");
|
||||
const sendMsg: MsgSendEncodeObject = {
|
||||
typeUrl: "/cosmos.bank.v1beta1.MsgSend",
|
||||
value: {
|
||||
fromAddress: account.address,
|
||||
toAddress: recipient,
|
||||
amount: amount,
|
||||
},
|
||||
};
|
||||
const memo = "With simulate";
|
||||
const result = await client.signAndBroadcast(account.address, [sendMsg], "auto", memo);
|
||||
assertIsBroadcastTxSuccess(result);
|
||||
console.log("Successfully broadcasted:", result);
|
||||
}
|
||||
|
||||
// Send transaction (using signAndBroadcast with manual gas)
|
||||
{
|
||||
const recipient = "cosmos1xv9tklw7d82sezh9haa573wufgy59vmwe6xxe5";
|
||||
const amount = coins(1234567, "ucosm");
|
||||
@ -58,7 +86,7 @@ const client = await SigningStargateClient.connectWithSigner(rpcEndpoint, wallet
|
||||
};
|
||||
const memo = "With simulate";
|
||||
const gasEstimation = await client.simulate(account.address, [sendMsg], memo);
|
||||
const fee = calculateFee(Math.floor(gasEstimation * 1.3), gasPrice);
|
||||
const fee = calculateFee(Math.round(gasEstimation * 1.3), gasPrice);
|
||||
const result = await client.signAndBroadcast(account.address, [sendMsg], fee, memo);
|
||||
assertIsBroadcastTxSuccess(result);
|
||||
console.log("Successfully broadcasted:", result);
|
||||
|
||||
@ -28,6 +28,7 @@ import {
|
||||
alice,
|
||||
defaultClearAdminFee,
|
||||
defaultExecuteFee,
|
||||
defaultGasPrice,
|
||||
defaultInstantiateFee,
|
||||
defaultMigrateFee,
|
||||
defaultSendFee,
|
||||
@ -600,6 +601,32 @@ describe("SigningCosmWasmClient", () => {
|
||||
client.disconnect();
|
||||
});
|
||||
|
||||
it("works with auto gas", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(alice.mnemonic, { prefix: wasmd.prefix });
|
||||
const client = await SigningCosmWasmClient.connectWithSigner(wasmd.endpoint, wallet, {
|
||||
...defaultSigningClientOptions,
|
||||
prefix: wasmd.prefix,
|
||||
gasPrice: defaultGasPrice,
|
||||
});
|
||||
const msgDelegateTypeUrl = "/cosmos.staking.v1beta1.MsgDelegate";
|
||||
|
||||
const msg = MsgDelegate.fromPartial({
|
||||
delegatorAddress: alice.address0,
|
||||
validatorAddress: validator.validatorAddress,
|
||||
amount: coin(1234, "ustake"),
|
||||
});
|
||||
const msgAny: MsgDelegateEncodeObject = {
|
||||
typeUrl: msgDelegateTypeUrl,
|
||||
value: msg,
|
||||
};
|
||||
const memo = "Use your power wisely";
|
||||
const result = await client.signAndBroadcast(alice.address0, [msgAny], "auto", memo);
|
||||
assertIsBroadcastTxSuccess(result);
|
||||
|
||||
client.disconnect();
|
||||
});
|
||||
|
||||
it("works with a modifying signer", async () => {
|
||||
pendingWithoutWasmd();
|
||||
const wallet = await ModifyingDirectSecp256k1HdWallet.fromMnemonic(alice.mnemonic, {
|
||||
|
||||
@ -17,8 +17,10 @@ import {
|
||||
AminoTypes,
|
||||
BroadcastTxFailure,
|
||||
BroadcastTxResponse,
|
||||
calculateFee,
|
||||
Coin,
|
||||
defaultRegistryTypes,
|
||||
GasPrice,
|
||||
isBroadcastTxFailure,
|
||||
logs,
|
||||
MsgDelegateEncodeObject,
|
||||
@ -144,6 +146,7 @@ export interface SigningCosmWasmClientOptions {
|
||||
readonly prefix?: string;
|
||||
readonly broadcastTimeoutMs?: number;
|
||||
readonly broadcastPollIntervalMs?: number;
|
||||
readonly gasPrice?: GasPrice;
|
||||
}
|
||||
|
||||
export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
@ -153,6 +156,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
|
||||
private readonly signer: OfflineSigner;
|
||||
private readonly aminoTypes: AminoTypes;
|
||||
private readonly gasPrice: GasPrice | undefined;
|
||||
|
||||
public static async connectWithSigner(
|
||||
endpoint: string,
|
||||
@ -194,6 +198,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
this.signer = signer;
|
||||
this.broadcastTimeoutMs = options.broadcastTimeoutMs;
|
||||
this.broadcastPollIntervalMs = options.broadcastPollIntervalMs;
|
||||
this.gasPrice = options.gasPrice;
|
||||
}
|
||||
|
||||
public async simulate(
|
||||
@ -219,7 +224,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
public async upload(
|
||||
senderAddress: string,
|
||||
wasmCode: Uint8Array,
|
||||
fee: StdFee,
|
||||
fee: StdFee | "auto",
|
||||
memo = "",
|
||||
): Promise<UploadResult> {
|
||||
const compressed = pako.gzip(wasmCode, { level: 9 });
|
||||
@ -253,7 +258,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
codeId: number,
|
||||
msg: Record<string, unknown>,
|
||||
label: string,
|
||||
fee: StdFee,
|
||||
fee: StdFee | "auto",
|
||||
options: InstantiateOptions = {},
|
||||
): Promise<InstantiateResult> {
|
||||
const instantiateContractMsg: MsgInstantiateContractEncodeObject = {
|
||||
@ -284,7 +289,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
senderAddress: string,
|
||||
contractAddress: string,
|
||||
newAdmin: string,
|
||||
fee: StdFee,
|
||||
fee: StdFee | "auto",
|
||||
memo = "",
|
||||
): Promise<ChangeAdminResult> {
|
||||
const updateAdminMsg: MsgUpdateAdminEncodeObject = {
|
||||
@ -308,7 +313,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
public async clearAdmin(
|
||||
senderAddress: string,
|
||||
contractAddress: string,
|
||||
fee: StdFee,
|
||||
fee: StdFee | "auto",
|
||||
memo = "",
|
||||
): Promise<ChangeAdminResult> {
|
||||
const clearAdminMsg: MsgClearAdminEncodeObject = {
|
||||
@ -333,7 +338,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
contractAddress: string,
|
||||
codeId: number,
|
||||
migrateMsg: Record<string, unknown>,
|
||||
fee: StdFee,
|
||||
fee: StdFee | "auto",
|
||||
memo = "",
|
||||
): Promise<MigrateResult> {
|
||||
const migrateContractMsg: MsgMigrateContractEncodeObject = {
|
||||
@ -359,7 +364,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
senderAddress: string,
|
||||
contractAddress: string,
|
||||
msg: Record<string, unknown>,
|
||||
fee: StdFee,
|
||||
fee: StdFee | "auto",
|
||||
memo = "",
|
||||
funds?: readonly Coin[],
|
||||
): Promise<ExecuteResult> {
|
||||
@ -386,7 +391,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
senderAddress: string,
|
||||
recipientAddress: string,
|
||||
amount: readonly Coin[],
|
||||
fee: StdFee,
|
||||
fee: StdFee | "auto",
|
||||
memo = "",
|
||||
): Promise<BroadcastTxResponse> {
|
||||
const sendMsg: MsgSendEncodeObject = {
|
||||
@ -404,7 +409,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
delegatorAddress: string,
|
||||
validatorAddress: string,
|
||||
amount: Coin,
|
||||
fee: StdFee,
|
||||
fee: StdFee | "auto",
|
||||
memo = "",
|
||||
): Promise<BroadcastTxResponse> {
|
||||
const delegateMsg: MsgDelegateEncodeObject = {
|
||||
@ -418,7 +423,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
delegatorAddress: string,
|
||||
validatorAddress: string,
|
||||
amount: Coin,
|
||||
fee: StdFee,
|
||||
fee: StdFee | "auto",
|
||||
memo = "",
|
||||
): Promise<BroadcastTxResponse> {
|
||||
const undelegateMsg: MsgUndelegateEncodeObject = {
|
||||
@ -431,7 +436,7 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
public async withdrawRewards(
|
||||
delegatorAddress: string,
|
||||
validatorAddress: string,
|
||||
fee: StdFee,
|
||||
fee: StdFee | "auto",
|
||||
memo = "",
|
||||
): Promise<BroadcastTxResponse> {
|
||||
const withdrawDelegatorRewardMsg: MsgWithdrawDelegatorRewardEncodeObject = {
|
||||
@ -452,10 +457,18 @@ export class SigningCosmWasmClient extends CosmWasmClient {
|
||||
public async signAndBroadcast(
|
||||
signerAddress: string,
|
||||
messages: readonly EncodeObject[],
|
||||
fee: StdFee,
|
||||
fee: StdFee | "auto",
|
||||
memo = "",
|
||||
): Promise<BroadcastTxResponse> {
|
||||
const txRaw = await this.sign(signerAddress, messages, fee, memo);
|
||||
let usedFee: StdFee;
|
||||
if (fee == "auto") {
|
||||
assertDefined(this.gasPrice, "Gas price must be set in the client options when auto gas is used.");
|
||||
const gasEstimation = await this.simulate(signerAddress, messages, memo);
|
||||
usedFee = calculateFee(Math.round(gasEstimation * 1.3), this.gasPrice);
|
||||
} else {
|
||||
usedFee = fee;
|
||||
}
|
||||
const txRaw = await this.sign(signerAddress, messages, usedFee, memo);
|
||||
const txBytes = TxRaw.encode(txRaw).finish();
|
||||
return this.broadcastTx(txBytes, this.broadcastTimeoutMs, this.broadcastPollIntervalMs);
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@ import { MsgDelegateEncodeObject, MsgSendEncodeObject } from "./encodeobjects";
|
||||
import { PrivateSigningStargateClient, SigningStargateClient } from "./signingstargateclient";
|
||||
import { assertIsBroadcastTxSuccess, isBroadcastTxFailure } from "./stargateclient";
|
||||
import {
|
||||
defaultGasPrice,
|
||||
defaultSendFee,
|
||||
defaultSigningClientOptions,
|
||||
faucet,
|
||||
@ -273,6 +274,27 @@ describe("SigningStargateClient", () => {
|
||||
assertIsBroadcastTxSuccess(result);
|
||||
});
|
||||
|
||||
it("works with auto gas", async () => {
|
||||
pendingWithoutSimapp();
|
||||
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic);
|
||||
const client = await SigningStargateClient.connectWithSigner(simapp.tendermintUrl, wallet, {
|
||||
...defaultSigningClientOptions,
|
||||
gasPrice: defaultGasPrice,
|
||||
});
|
||||
|
||||
const msg = MsgDelegate.fromPartial({
|
||||
delegatorAddress: faucet.address0,
|
||||
validatorAddress: validator.validatorAddress,
|
||||
amount: coin(1234, "ustake"),
|
||||
});
|
||||
const msgAny: MsgDelegateEncodeObject = {
|
||||
typeUrl: "/cosmos.staking.v1beta1.MsgDelegate",
|
||||
value: msg,
|
||||
};
|
||||
const result = await client.signAndBroadcast(faucet.address0, [msgAny], "auto");
|
||||
assertIsBroadcastTxSuccess(result);
|
||||
});
|
||||
|
||||
it("works with a modifying signer", async () => {
|
||||
pendingWithoutSimapp();
|
||||
const wallet = await ModifyingDirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic);
|
||||
|
||||
@ -68,6 +68,7 @@ import {
|
||||
MsgUndelegateEncodeObject,
|
||||
MsgWithdrawDelegatorRewardEncodeObject,
|
||||
} from "./encodeobjects";
|
||||
import { calculateFee, GasPrice } from "./fee";
|
||||
import { BroadcastTxResponse, StargateClient } from "./stargateclient";
|
||||
|
||||
export const defaultRegistryTypes: ReadonlyArray<[string, GeneratedType]> = [
|
||||
@ -131,6 +132,7 @@ export interface SigningStargateClientOptions {
|
||||
readonly prefix?: string;
|
||||
readonly broadcastTimeoutMs?: number;
|
||||
readonly broadcastPollIntervalMs?: number;
|
||||
readonly gasPrice?: GasPrice;
|
||||
}
|
||||
|
||||
export class SigningStargateClient extends StargateClient {
|
||||
@ -140,6 +142,7 @@ export class SigningStargateClient extends StargateClient {
|
||||
|
||||
private readonly signer: OfflineSigner;
|
||||
private readonly aminoTypes: AminoTypes;
|
||||
private readonly gasPrice: GasPrice | undefined;
|
||||
|
||||
public static async connectWithSigner(
|
||||
endpoint: string,
|
||||
@ -179,6 +182,7 @@ export class SigningStargateClient extends StargateClient {
|
||||
this.signer = signer;
|
||||
this.broadcastTimeoutMs = options.broadcastTimeoutMs;
|
||||
this.broadcastPollIntervalMs = options.broadcastPollIntervalMs;
|
||||
this.gasPrice = options.gasPrice;
|
||||
}
|
||||
|
||||
public async simulate(
|
||||
@ -204,7 +208,7 @@ export class SigningStargateClient extends StargateClient {
|
||||
senderAddress: string,
|
||||
recipientAddress: string,
|
||||
amount: readonly Coin[],
|
||||
fee: StdFee,
|
||||
fee: StdFee | "auto",
|
||||
memo = "",
|
||||
): Promise<BroadcastTxResponse> {
|
||||
const sendMsg: MsgSendEncodeObject = {
|
||||
@ -222,7 +226,7 @@ export class SigningStargateClient extends StargateClient {
|
||||
delegatorAddress: string,
|
||||
validatorAddress: string,
|
||||
amount: Coin,
|
||||
fee: StdFee,
|
||||
fee: StdFee | "auto",
|
||||
memo = "",
|
||||
): Promise<BroadcastTxResponse> {
|
||||
const delegateMsg: MsgDelegateEncodeObject = {
|
||||
@ -240,7 +244,7 @@ export class SigningStargateClient extends StargateClient {
|
||||
delegatorAddress: string,
|
||||
validatorAddress: string,
|
||||
amount: Coin,
|
||||
fee: StdFee,
|
||||
fee: StdFee | "auto",
|
||||
memo = "",
|
||||
): Promise<BroadcastTxResponse> {
|
||||
const undelegateMsg: MsgUndelegateEncodeObject = {
|
||||
@ -257,7 +261,7 @@ export class SigningStargateClient extends StargateClient {
|
||||
public async withdrawRewards(
|
||||
delegatorAddress: string,
|
||||
validatorAddress: string,
|
||||
fee: StdFee,
|
||||
fee: StdFee | "auto",
|
||||
memo = "",
|
||||
): Promise<BroadcastTxResponse> {
|
||||
const withdrawMsg: MsgWithdrawDelegatorRewardEncodeObject = {
|
||||
@ -279,7 +283,7 @@ export class SigningStargateClient extends StargateClient {
|
||||
timeoutHeight: Height | undefined,
|
||||
/** timeout in seconds */
|
||||
timeoutTimestamp: number | undefined,
|
||||
fee: StdFee,
|
||||
fee: StdFee | "auto",
|
||||
memo = "",
|
||||
): Promise<BroadcastTxResponse> {
|
||||
const timeoutTimestampNanoseconds = timeoutTimestamp
|
||||
@ -303,10 +307,18 @@ export class SigningStargateClient extends StargateClient {
|
||||
public async signAndBroadcast(
|
||||
signerAddress: string,
|
||||
messages: readonly EncodeObject[],
|
||||
fee: StdFee,
|
||||
fee: StdFee | "auto",
|
||||
memo = "",
|
||||
): Promise<BroadcastTxResponse> {
|
||||
const txRaw = await this.sign(signerAddress, messages, fee, memo);
|
||||
let usedFee: StdFee;
|
||||
if (fee == "auto") {
|
||||
assertDefined(this.gasPrice, "Gas price must be set in the client options when auto gas is used.");
|
||||
const gasEstimation = await this.simulate(signerAddress, messages, memo);
|
||||
usedFee = calculateFee(Math.round(gasEstimation * 1.3), this.gasPrice);
|
||||
} else {
|
||||
usedFee = fee;
|
||||
}
|
||||
const txRaw = await this.sign(signerAddress, messages, usedFee, memo);
|
||||
const txBytes = TxRaw.encode(txRaw).finish();
|
||||
return this.broadcastTx(txBytes, this.broadcastTimeoutMs, this.broadcastPollIntervalMs);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user