Feature/more exposed client api (#591)

* Added public sign and broadcast to net client

* Created a function to send funds multiple times in a single block
This commit is contained in:
Jędrzej Stuczyński
2021-04-28 14:13:41 +01:00
committed by GitHub
parent 18adb1f5bd
commit 7f7c37eeba
5 changed files with 58 additions and 10 deletions
+28 -2
View File
@@ -1,9 +1,9 @@
import NetClient, { INetClient } from "./net-client";
import { Gateway, GatewayBond, MixNode, MixNodeBond } from "./types";
import { Gateway, GatewayBond, MixNode, MixNodeBond, SendRequest } from "./types";
import { Bip39, Random } from "@cosmjs/crypto";
import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";
import MixnodesCache from "./caches/mixnodes";
import { coin, Coin, coins } from "@cosmjs/launchpad";
import { buildFeeTable, coin, Coin, coins, StdFee } from "@cosmjs/launchpad";
import {
ExecuteResult,
InstantiateOptions,
@@ -24,6 +24,8 @@ import {
import GatewaysCache from "./caches/gateways";
import QueryClient, { IQueryClient } from "./query-client";
import { BroadcastTxSuccess, isBroadcastTxFailure } from "@cosmjs/stargate";
import { makeBankMsgSend } from "./utils";
import { nymGasLimits, nymGasPrice } from "./stargate-helper";
export { coins, coin };
export { Coin };
@@ -383,6 +385,30 @@ export default class ValidatorClient {
}
}
/**
* Send funds multiple times from one address to another in a single block.
*/
async sendMultiple(senderAddress: string, data: SendRequest[], memo?: string): Promise<BroadcastTxSuccess> {
if (this.client instanceof NetClient) {
if (data.length === 1) {
return this.send(data[0].senderAddress, data[0].recipientAddress, data[0].transferAmount, memo)
}
const encoded = data.map(req => makeBankMsgSend(req.senderAddress, req.recipientAddress, req.transferAmount));
// the function to calculate fee for a single entry is not exposed...
const table = buildFeeTable(nymGasPrice(this.stakeDenom), {sendMultiple: nymGasLimits.send * data.length}, {sendMultiple: nymGasLimits.send * data.length})
const fee = table.sendMultiple
const result = await this.client.signAndBroadcast(senderAddress, encoded, fee, memo)
if (isBroadcastTxFailure(result)) {
throw new Error(`Error when broadcasting tx ${result.transactionHash} at height ${result.height}. Code: ${result.code}; Raw log: ${result.rawLog}`)
}
return result
} else {
throw new Error("Tried to use sendMultiple with a query client");
}
}
async upload(senderAddress: string, wasmCode: Uint8Array, meta?: UploadMeta, memo?: string): Promise<UploadResult> {
if (this.client instanceof NetClient) {
return this.client.upload(senderAddress, wasmCode, meta, memo).catch((err) => this.handleRequestFailure(err));
+9 -4
View File
@@ -6,10 +6,10 @@ import {
PagedResponse,
StateParams
} from "./index";
import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";
import { Coin, GasPrice } from "@cosmjs/launchpad";
import { DirectSecp256k1HdWallet, EncodeObject } from "@cosmjs/proto-signing";
import { Coin, GasPrice, StdFee } from "@cosmjs/launchpad";
import { BroadcastTxResponse } from "@cosmjs/stargate"
import { nymGasLimits } from "./stargate-helper"
import { nymGasLimits, nymGasPrice } from "./stargate-helper"
import { ExecuteResult, InstantiateOptions, InstantiateResult, MigrateResult, UploadMeta, UploadResult } from "@cosmjs/cosmwasm";
export interface INetClient {
@@ -21,6 +21,7 @@ export interface INetClient {
ownsMixNode(contractAddress: string, address: string): Promise<MixOwnershipResponse>;
ownsGateway(contractAddress: string, address: string): Promise<GatewayOwnershipResponse>;
getStateParams(contractAddress: string): Promise<StateParams>;
signAndBroadcast(signerAddress: string, messages: readonly EncodeObject[], fee: StdFee, memo?: string): Promise<BroadcastTxResponse>;
executeContract(senderAddress: string, contractAddress: string, handleMsg: Record<string, unknown>, memo?: string, transferAmount?: readonly Coin[]): Promise<ExecuteResult>;
instantiate(senderAddress: string, codeId: number, initMsg: Record<string, unknown>, label: string, options?: InstantiateOptions): Promise<InstantiateResult>;
sendTokens(senderAddress: string, recipientAddress: string, transferAmount: readonly Coin[], memo?: string): Promise<BroadcastTxResponse>;
@@ -54,7 +55,7 @@ export default class NetClient implements INetClient {
public static async connect(wallet: DirectSecp256k1HdWallet, url: string, stakeDenom: string): Promise<INetClient> {
const [{ address }] = await wallet.getAccounts();
const signerOptions: SigningCosmWasmClientOptions = {
gasPrice: GasPrice.fromString(`0.025${stakeDenom}`),
gasPrice: nymGasPrice(stakeDenom),
gasLimits: nymGasLimits,
};
const client = await SigningCosmWasmClient.connectWithSigner(url, wallet, signerOptions);
@@ -101,6 +102,10 @@ export default class NetClient implements INetClient {
return this.cosmClient.execute(senderAddress, contractAddress, handleMsg, memo, transferAmount);
}
public signAndBroadcast(signerAddress: string, messages: readonly EncodeObject[], fee: StdFee, memo?: string): Promise<BroadcastTxResponse> {
return this.cosmClient.signAndBroadcast(signerAddress, messages, fee, memo)
}
public sendTokens(senderAddress: string, recipientAddress: string, transferAmount: readonly Coin[], memo?: string): Promise<BroadcastTxResponse> {
return this.cosmClient.sendTokens(senderAddress, recipientAddress, transferAmount, memo);
}
+3 -1
View File
@@ -1,5 +1,5 @@
import axios from "axios";
import { GasLimits } from "@cosmjs/launchpad";
import { GasLimits, GasPrice } from "@cosmjs/launchpad";
import { CosmWasmFeeTable } from "@cosmjs/cosmwasm";
@@ -19,6 +19,8 @@ export const nymGasLimits: GasLimits<CosmWasmFeeTable> = {
changeAdmin: 80_000,
};
export const nymGasPrice: (stakeDenom: string) => GasPrice = (stakeDenom: string) => GasPrice.fromString(`0.025${stakeDenom}`);
export const defaultOptions: Options = {
httpUrl: "http://localhost:26657",
networkId: "nymnet",
+6
View File
@@ -30,3 +30,9 @@ export type Gateway = {
identity_key: string,
version: string
}
export type SendRequest = {
senderAddress: string,
recipientAddress: string,
transferAmount: readonly Coin[]
}
+12 -3
View File
@@ -1,5 +1,14 @@
// eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/explicit-module-boundary-types
export default function log(text: string, thing: any): void {
const msg = JSON.stringify(thing);
console.log(`${text}: ${msg}`);
import { Coin } from "@cosmjs/launchpad/";
import { EncodeObject } from "@cosmjs/proto-signing";
export function makeBankMsgSend(senderAddress: string, recipientAddress: string, transferAmount: readonly Coin[]): EncodeObject {
return {
typeUrl: "/cosmos.bank.v1beta1.MsgSend",
value: {
fromAddress: senderAddress,
toAddress: recipientAddress,
amount: transferAmount,
},
};
}