Deduplicate large parts of the RestClient

This commit is contained in:
Simon Warta 2020-06-03 13:21:53 +02:00
parent 54cff0367e
commit 3ceae61a0d
13 changed files with 70 additions and 590 deletions

View File

@ -1,9 +1,17 @@
import { Coin, CosmosSdkTx, decodeBech32Pubkey, IndexedTx, PubKey, StdTx } from "@cosmwasm/sdk38";
import {
BroadcastMode,
Coin,
CosmosSdkTx,
decodeBech32Pubkey,
IndexedTx,
PubKey,
StdTx,
} from "@cosmwasm/sdk38";
import { Sha256 } from "@iov/crypto";
import { Encoding } from "@iov/encoding";
import { Log, parseLogs } from "./logs";
import { BroadcastMode, RestClient } from "./restclient";
import { RestClient } from "./restclient";
import { JsonObject } from "./types";
export interface GetNonceResult {

View File

@ -1,7 +1,7 @@
import * as logs from "./logs";
export { logs };
export { BroadcastMode, RestClient, TxsResponse } from "./restclient";
export { RestClient, TxsResponse } from "./restclient";
export {
Account,
Block,

View File

@ -7,6 +7,7 @@ import {
Msg,
MsgSend,
Pen,
PostTxsResponse,
rawSecp256k1PubkeyToAddress,
Secp256k1Pen,
StdFee,
@ -26,7 +27,7 @@ import {
MsgInstantiateContract,
MsgStoreCode,
} from "./msgs";
import { PostTxsResponse, RestClient, TxsResponse } from "./restclient";
import { RestClient, TxsResponse } from "./restclient";
import { SigningCosmWasmClient } from "./signingcosmwasmclient";
import cosmoshub from "./testdata/cosmoshub.json";
import {

View File

@ -1,108 +1,10 @@
import { Coin, CosmosSdkTx, StdTx } from "@cosmwasm/sdk38";
import { Encoding, isNonNullObject } from "@iov/encoding";
import axios, { AxiosError, AxiosInstance } from "axios";
import { BroadcastMode, CosmosSdkTx, RestClient as BaseRestClient } from "@cosmwasm/sdk38";
import { Encoding } from "@iov/encoding";
import { JsonObject, Model, parseWasmData, WasmData } from "./types";
const { fromBase64, fromUtf8, toHex, toUtf8 } = Encoding;
export interface CosmosSdkAccount {
/** Bech32 account address */
readonly address: string;
readonly coins: ReadonlyArray<Coin>;
/** Bech32 encoded pubkey */
readonly public_key: string;
readonly account_number: number;
readonly sequence: number;
}
export interface NodeInfo {
readonly protocol_version: {
readonly p2p: string;
readonly block: string;
readonly app: string;
};
readonly id: string;
readonly listen_addr: string;
readonly network: string;
readonly version: string;
readonly channels: string;
readonly moniker: string;
readonly other: {
readonly tx_index: string;
readonly rpc_address: string;
};
}
export interface ApplicationVersion {
readonly name: string;
readonly server_name: string;
readonly client_name: string;
readonly version: string;
readonly commit: string;
readonly build_tags: string;
readonly go: string;
}
export interface NodeInfoResponse {
readonly node_info: NodeInfo;
readonly application_version: ApplicationVersion;
}
export interface BlockId {
readonly hash: string;
// TODO: here we also have this
// parts: {
// total: '1',
// hash: '7AF200C78FBF9236944E1AB270F4045CD60972B7C265E3A9DA42973397572931'
// }
}
export interface BlockHeader {
readonly version: {
readonly block: string;
readonly app: string;
};
readonly height: string;
readonly chain_id: string;
/** An RFC 3339 time string like e.g. '2020-02-15T10:39:10.4696305Z' */
readonly time: string;
readonly last_commit_hash: string;
readonly last_block_id: BlockId;
/** Can be empty */
readonly data_hash: string;
readonly validators_hash: string;
readonly next_validators_hash: string;
readonly consensus_hash: string;
readonly app_hash: string;
/** Can be empty */
readonly last_results_hash: string;
/** Can be empty */
readonly evidence_hash: string;
readonly proposer_address: string;
}
export interface Block {
readonly header: BlockHeader;
readonly data: {
/** Array of base64 encoded transactions */
readonly txs: ReadonlyArray<string> | null;
};
}
export interface BlockResponse {
readonly block_id: BlockId;
readonly block: Block;
}
interface AuthAccountsResponse {
readonly height: string;
readonly result: {
readonly type: "cosmos-sdk/Account";
readonly value: CosmosSdkAccount;
};
}
// Currently all wasm query responses return json-encoded strings...
// later deprecate this and use the specific types for result
// (assuming it is inlined, no second parse needed)
@ -134,33 +36,6 @@ export interface TxsResponse {
readonly timestamp: string;
}
interface SearchTxsResponse {
readonly total_count: string;
readonly count: string;
readonly page_number: string;
readonly page_total: string;
readonly limit: string;
readonly txs: readonly TxsResponse[];
}
export interface PostTxsResponse {
readonly height: string;
readonly txhash: string;
readonly code?: number;
readonly raw_log?: string;
/** The same as `raw_log` but deserialized? */
readonly logs?: object;
/** The gas limit as set by the user */
readonly gas_wanted?: string;
/** The gas used by the execution */
readonly gas_used?: string;
}
interface EncodeTxResponse {
// base64-encoded amino-binary encoded representation
readonly tx: string;
}
export interface CodeInfo {
readonly id: number;
/** Bech32 account address */
@ -196,20 +71,6 @@ interface SmartQueryResponse {
readonly smart: string;
}
type RestClientResponse =
| NodeInfoResponse
| BlockResponse
| AuthAccountsResponse
| TxsResponse
| SearchTxsResponse
| PostTxsResponse
| EncodeTxResponse
| WasmResponse<string>
| WasmResponse<CodeInfo[]>
| WasmResponse<CodeDetails>
| WasmResponse<ContractInfo[] | null>
| WasmResponse<ContractDetails | null>;
/** Unfortunately, Cosmos SDK encodes empty arrays as null */
type CosmosSdkArray<T> = ReadonlyArray<T> | null;
@ -217,20 +78,6 @@ function normalizeArray<T>(backend: CosmosSdkArray<T>): ReadonlyArray<T> {
return backend || [];
}
/**
* The mode used to send transaction
*
* @see https://cosmos.network/rpc/#/Transactions/post_txs
*/
export enum BroadcastMode {
/** Return after tx commit */
Block = "block",
/** Return afer CheckTx */
Sync = "sync",
/** Return right away */
Async = "async",
}
function isWasmError<T>(resp: WasmResponse<T>): resp is WasmError {
return (resp as WasmError).error !== undefined;
}
@ -242,32 +89,7 @@ function unwrapWasmResponse<T>(response: WasmResponse<T>): T {
return response.result;
}
// We want to get message data from 500 errors
// https://stackoverflow.com/questions/56577124/how-to-handle-500-error-message-with-axios
// this should be chained to catch one error and throw a more informative one
function parseAxiosError(err: AxiosError): never {
// use the error message sent from server, not default 500 msg
if (err.response?.data) {
let errorText: string;
const data = err.response.data;
// expect { error: string }, but otherwise dump
if (data.error && typeof data.error === "string") {
errorText = data.error;
} else if (typeof data === "string") {
errorText = data;
} else {
errorText = JSON.stringify(data);
}
throw new Error(`${errorText} (HTTP ${err.response.status})`);
} else {
throw err;
}
}
export class RestClient {
private readonly client: AxiosInstance;
private readonly broadcastMode: BroadcastMode;
export class RestClient extends BaseRestClient {
/**
* Creates a new client to interact with a Cosmos SDK light client daemon.
* This class tries to be a direct mapping onto the API. Some basic decoding and normalizatin is done
@ -280,116 +102,7 @@ export class RestClient {
* @param broadcastMode Defines at which point of the transaction processing the postTx method (i.e. transaction broadcasting) returns
*/
public constructor(apiUrl: string, broadcastMode = BroadcastMode.Block) {
const headers = {
post: { "Content-Type": "application/json" },
};
this.client = axios.create({
baseURL: apiUrl,
headers: headers,
});
this.broadcastMode = broadcastMode;
}
public async get(path: string): Promise<RestClientResponse> {
const { data } = await this.client.get(path).catch(parseAxiosError);
if (data === null) {
throw new Error("Received null response from server");
}
return data;
}
public async post(path: string, params: any): Promise<RestClientResponse> {
if (!isNonNullObject(params)) throw new Error("Got unexpected type of params. Expected object.");
const { data } = await this.client.post(path, params).catch(parseAxiosError);
if (data === null) {
throw new Error("Received null response from server");
}
return data;
}
// The /auth endpoints
public async authAccounts(address: string): Promise<AuthAccountsResponse> {
const path = `/auth/accounts/${address}`;
const responseData = await this.get(path);
if ((responseData as any).result.type !== "cosmos-sdk/Account") {
throw new Error("Unexpected response data format");
}
return responseData as AuthAccountsResponse;
}
// The /blocks endpoints
public async blocksLatest(): Promise<BlockResponse> {
const responseData = await this.get("/blocks/latest");
if (!(responseData as any).block) {
throw new Error("Unexpected response data format");
}
return responseData as BlockResponse;
}
public async blocks(height: number): Promise<BlockResponse> {
const responseData = await this.get(`/blocks/${height}`);
if (!(responseData as any).block) {
throw new Error("Unexpected response data format");
}
return responseData as BlockResponse;
}
// The /node_info endpoint
public async nodeInfo(): Promise<NodeInfoResponse> {
const responseData = await this.get("/node_info");
if (!(responseData as any).node_info) {
throw new Error("Unexpected response data format");
}
return responseData as NodeInfoResponse;
}
// The /txs endpoints
public async txById(id: string): Promise<TxsResponse> {
const responseData = await this.get(`/txs/${id}`);
if (!(responseData as any).tx) {
throw new Error("Unexpected response data format");
}
return responseData as TxsResponse;
}
public async txsQuery(query: string): Promise<SearchTxsResponse> {
const responseData = await this.get(`/txs?${query}`);
if (!(responseData as any).txs) {
throw new Error("Unexpected response data format");
}
return responseData as SearchTxsResponse;
}
/** returns the amino-encoding of the transaction performed by the server */
public async encodeTx(tx: CosmosSdkTx): Promise<Uint8Array> {
const responseData = await this.post("/txs/encode", tx);
if (!(responseData as any).tx) {
throw new Error("Unexpected response data format");
}
return Encoding.fromBase64((responseData as EncodeTxResponse).tx);
}
/**
* Broadcasts a signed transaction to into the transaction pool.
* Depending on the RestClient's broadcast mode, this might or might
* wait for checkTx or deliverTx to be executed before returning.
*
* @param tx a signed transaction as StdTx (i.e. not wrapped in type/value container)
*/
public async postTx(tx: StdTx): Promise<PostTxsResponse> {
const params = {
tx: tx,
mode: this.broadcastMode,
};
const responseData = await this.post("/txs", params);
if (!(responseData as any).txhash) {
throw new Error("Unexpected response data format");
}
return responseData as PostTxsResponse;
super(apiUrl, broadcastMode);
}
// The /wasm endpoints

View File

@ -1,4 +1,4 @@
import { Coin, coins, makeSignBytes, MsgSend, StdFee, StdSignature } from "@cosmwasm/sdk38";
import { BroadcastMode, Coin, coins, makeSignBytes, MsgSend, StdFee, StdSignature } from "@cosmwasm/sdk38";
import { Sha256 } from "@iov/crypto";
import { Encoding } from "@iov/encoding";
import pako from "pako";
@ -7,7 +7,6 @@ import { isValidBuilder } from "./builder";
import { Account, CosmWasmClient, GetNonceResult, PostTxResult } from "./cosmwasmclient";
import { findAttribute, Log } from "./logs";
import { MsgExecuteContract, MsgInstantiateContract, MsgStoreCode } from "./msgs";
import { BroadcastMode } from "./restclient";
export interface SigningCallback {
(signBytes: Uint8Array): Promise<StdSignature>;

View File

@ -1,6 +1,6 @@
import { Coin, CosmosSdkTx, IndexedTx, PubKey, StdTx } from "@cosmwasm/sdk38";
import { BroadcastMode, Coin, CosmosSdkTx, IndexedTx, PubKey, StdTx } from "@cosmwasm/sdk38";
import { Log } from "./logs";
import { BroadcastMode, RestClient } from "./restclient";
import { RestClient } from "./restclient";
import { JsonObject } from "./types";
export interface GetNonceResult {
readonly accountNumber: number;

View File

@ -1,6 +1,6 @@
import * as logs from "./logs";
export { logs };
export { BroadcastMode, RestClient, TxsResponse } from "./restclient";
export { RestClient, TxsResponse } from "./restclient";
export {
Account,
Block,

View File

@ -1,96 +1,5 @@
import { Coin, CosmosSdkTx, StdTx } from "@cosmwasm/sdk38";
import { BroadcastMode, CosmosSdkTx, RestClient as BaseRestClient } from "@cosmwasm/sdk38";
import { JsonObject, Model } from "./types";
export interface CosmosSdkAccount {
/** Bech32 account address */
readonly address: string;
readonly coins: ReadonlyArray<Coin>;
/** Bech32 encoded pubkey */
readonly public_key: string;
readonly account_number: number;
readonly sequence: number;
}
export interface NodeInfo {
readonly protocol_version: {
readonly p2p: string;
readonly block: string;
readonly app: string;
};
readonly id: string;
readonly listen_addr: string;
readonly network: string;
readonly version: string;
readonly channels: string;
readonly moniker: string;
readonly other: {
readonly tx_index: string;
readonly rpc_address: string;
};
}
export interface ApplicationVersion {
readonly name: string;
readonly server_name: string;
readonly client_name: string;
readonly version: string;
readonly commit: string;
readonly build_tags: string;
readonly go: string;
}
export interface NodeInfoResponse {
readonly node_info: NodeInfo;
readonly application_version: ApplicationVersion;
}
export interface BlockId {
readonly hash: string;
}
export interface BlockHeader {
readonly version: {
readonly block: string;
readonly app: string;
};
readonly height: string;
readonly chain_id: string;
/** An RFC 3339 time string like e.g. '2020-02-15T10:39:10.4696305Z' */
readonly time: string;
readonly last_commit_hash: string;
readonly last_block_id: BlockId;
/** Can be empty */
readonly data_hash: string;
readonly validators_hash: string;
readonly next_validators_hash: string;
readonly consensus_hash: string;
readonly app_hash: string;
/** Can be empty */
readonly last_results_hash: string;
/** Can be empty */
readonly evidence_hash: string;
readonly proposer_address: string;
}
export interface Block {
readonly header: BlockHeader;
readonly data: {
/** Array of base64 encoded transactions */
readonly txs: ReadonlyArray<string> | null;
};
}
export interface BlockResponse {
readonly block_id: BlockId;
readonly block: Block;
}
interface AuthAccountsResponse {
readonly height: string;
readonly result: {
readonly type: "cosmos-sdk/Account";
readonly value: CosmosSdkAccount;
};
}
declare type WasmResponse<T = string> = WasmSuccess<T> | WasmError;
interface WasmSuccess<T = string> {
readonly height: string;
readonly result: T;
}
interface WasmError {
readonly error: string;
}
export interface TxsResponse {
readonly height: string;
readonly txhash: string;
@ -107,29 +16,6 @@ export interface TxsResponse {
readonly gas_used?: string;
readonly timestamp: string;
}
interface SearchTxsResponse {
readonly total_count: string;
readonly count: string;
readonly page_number: string;
readonly page_total: string;
readonly limit: string;
readonly txs: readonly TxsResponse[];
}
export interface PostTxsResponse {
readonly height: string;
readonly txhash: string;
readonly code?: number;
readonly raw_log?: string;
/** The same as `raw_log` but deserialized? */
readonly logs?: object;
/** The gas limit as set by the user */
readonly gas_wanted?: string;
/** The gas used by the execution */
readonly gas_used?: string;
}
interface EncodeTxResponse {
readonly tx: string;
}
export interface CodeInfo {
readonly id: number;
/** Bech32 account address */
@ -154,35 +40,7 @@ export interface ContractDetails extends ContractInfo {
/** Argument passed on initialization of the contract */
readonly init_msg: object;
}
declare type RestClientResponse =
| NodeInfoResponse
| BlockResponse
| AuthAccountsResponse
| TxsResponse
| SearchTxsResponse
| PostTxsResponse
| EncodeTxResponse
| WasmResponse<string>
| WasmResponse<CodeInfo[]>
| WasmResponse<CodeDetails>
| WasmResponse<ContractInfo[] | null>
| WasmResponse<ContractDetails | null>;
/**
* The mode used to send transaction
*
* @see https://cosmos.network/rpc/#/Transactions/post_txs
*/
export declare enum BroadcastMode {
/** Return after tx commit */
Block = "block",
/** Return afer CheckTx */
Sync = "sync",
/** Return right away */
Async = "async",
}
export declare class RestClient {
private readonly client;
private readonly broadcastMode;
export declare class RestClient extends BaseRestClient {
/**
* Creates a new client to interact with a Cosmos SDK light client daemon.
* This class tries to be a direct mapping onto the API. Some basic decoding and normalizatin is done
@ -195,24 +53,6 @@ export declare class RestClient {
* @param broadcastMode Defines at which point of the transaction processing the postTx method (i.e. transaction broadcasting) returns
*/
constructor(apiUrl: string, broadcastMode?: BroadcastMode);
get(path: string): Promise<RestClientResponse>;
post(path: string, params: any): Promise<RestClientResponse>;
authAccounts(address: string): Promise<AuthAccountsResponse>;
blocksLatest(): Promise<BlockResponse>;
blocks(height: number): Promise<BlockResponse>;
nodeInfo(): Promise<NodeInfoResponse>;
txById(id: string): Promise<TxsResponse>;
txsQuery(query: string): Promise<SearchTxsResponse>;
/** returns the amino-encoding of the transaction performed by the server */
encodeTx(tx: CosmosSdkTx): Promise<Uint8Array>;
/**
* Broadcasts a signed transaction to into the transaction pool.
* Depending on the RestClient's broadcast mode, this might or might
* wait for checkTx or deliverTx to be executed before returning.
*
* @param tx a signed transaction as StdTx (i.e. not wrapped in type/value container)
*/
postTx(tx: StdTx): Promise<PostTxsResponse>;
listCodeInfo(): Promise<readonly CodeInfo[]>;
getCode(id: number): Promise<CodeDetails>;
listContractsByCodeId(id: number): Promise<readonly ContractInfo[]>;
@ -228,4 +68,3 @@ export declare class RestClient {
*/
queryContractSmart(address: string, query: object): Promise<JsonObject>;
}
export {};

View File

@ -1,7 +1,6 @@
import { Coin, StdFee, StdSignature } from "@cosmwasm/sdk38";
import { BroadcastMode, Coin, StdFee, StdSignature } from "@cosmwasm/sdk38";
import { Account, CosmWasmClient, GetNonceResult, PostTxResult } from "./cosmwasmclient";
import { Log } from "./logs";
import { BroadcastMode } from "./restclient";
export interface SigningCallback {
(signBytes: Uint8Array): Promise<StdSignature>;
}

View File

@ -21,7 +21,16 @@ export {
} from "./cosmosclient";
export { unmarshalTx } from "./decoding";
export { makeSignBytes, marshalTx } from "./encoding";
export { BroadcastMode, RestClient, TxsResponse } from "./restclient";
export {
AuthAccountsResponse,
BlockResponse,
BroadcastMode,
PostTxsResponse,
NodeInfoResponse,
RestClient,
SearchTxsResponse,
TxsResponse,
} from "./restclient";
export { Pen, Secp256k1Pen, makeCosmoshubPath } from "./pen";
export { decodeBech32Pubkey, encodeBech32Pubkey, encodeSecp256k1Pubkey } from "./pubkey";
export { findSequenceForSignedTx } from "./sequence";

View File

@ -14,7 +14,7 @@ export interface CosmosSdkAccount {
readonly sequence: number;
}
export interface NodeInfo {
interface NodeInfo {
readonly protocol_version: {
readonly p2p: string;
readonly block: string;
@ -32,7 +32,7 @@ export interface NodeInfo {
};
}
export interface ApplicationVersion {
interface ApplicationVersion {
readonly name: string;
readonly server_name: string;
readonly client_name: string;
@ -47,7 +47,7 @@ export interface NodeInfoResponse {
readonly application_version: ApplicationVersion;
}
export interface BlockId {
interface BlockId {
readonly hash: string;
// TODO: here we also have this
// parts: {
@ -56,7 +56,7 @@ export interface BlockId {
// }
}
export interface BlockHeader {
interface BlockHeader {
readonly version: {
readonly block: string;
readonly app: string;
@ -80,7 +80,7 @@ export interface BlockHeader {
readonly proposer_address: string;
}
export interface Block {
interface Block {
readonly header: BlockHeader;
readonly data: {
/** Array of base64 encoded transactions */
@ -93,7 +93,7 @@ export interface BlockResponse {
readonly block: Block;
}
interface AuthAccountsResponse {
export interface AuthAccountsResponse {
readonly height: string;
readonly result: {
readonly type: "cosmos-sdk/Account";
@ -132,7 +132,7 @@ export interface TxsResponse {
readonly timestamp: string;
}
interface SearchTxsResponse {
export interface SearchTxsResponse {
readonly total_count: string;
readonly count: string;
readonly page_number: string;
@ -159,55 +159,6 @@ interface EncodeTxResponse {
readonly tx: string;
}
export interface CodeInfo {
readonly id: number;
/** Bech32 account address */
readonly creator: string;
/** Hex-encoded sha256 hash of the code stored here */
readonly data_hash: string;
// TODO: these are not supported in current wasmd
readonly source?: string;
readonly builder?: string;
}
export interface CodeDetails extends CodeInfo {
/** Base64 encoded raw wasm data */
readonly data: string;
}
// This is list view, without contract info
export interface ContractInfo {
readonly address: string;
readonly code_id: number;
/** Bech32 account address */
readonly creator: string;
readonly label: string;
}
export interface ContractDetails extends ContractInfo {
/** Argument passed on initialization of the contract */
readonly init_msg: object;
}
interface SmartQueryResponse {
// base64 encoded response
readonly smart: string;
}
type RestClientResponse =
| NodeInfoResponse
| BlockResponse
| AuthAccountsResponse
| TxsResponse
| SearchTxsResponse
| PostTxsResponse
| EncodeTxResponse
| WasmResponse<string>
| WasmResponse<CodeInfo[]>
| WasmResponse<CodeDetails>
| WasmResponse<ContractInfo[] | null>
| WasmResponse<ContractDetails | null>;
/**
* The mode used to send transaction
*
@ -270,7 +221,7 @@ export class RestClient {
this.broadcastMode = broadcastMode;
}
public async get(path: string): Promise<RestClientResponse> {
public async get(path: string): Promise<any> {
const { data } = await this.client.get(path).catch(parseAxiosError);
if (data === null) {
throw new Error("Received null response from server");
@ -278,7 +229,7 @@ export class RestClient {
return data;
}
public async post(path: string, params: any): Promise<RestClientResponse> {
public async post(path: string, params: any): Promise<any> {
if (!isNonNullObject(params)) throw new Error("Got unexpected type of params. Expected object.");
const { data } = await this.client.post(path, params).catch(parseAxiosError);
if (data === null) {
@ -292,7 +243,7 @@ export class RestClient {
public async authAccounts(address: string): Promise<AuthAccountsResponse> {
const path = `/auth/accounts/${address}`;
const responseData = await this.get(path);
if ((responseData as any).result.type !== "cosmos-sdk/Account") {
if (responseData.result.type !== "cosmos-sdk/Account") {
throw new Error("Unexpected response data format");
}
return responseData as AuthAccountsResponse;
@ -302,7 +253,7 @@ export class RestClient {
public async blocksLatest(): Promise<BlockResponse> {
const responseData = await this.get("/blocks/latest");
if (!(responseData as any).block) {
if (!responseData.block) {
throw new Error("Unexpected response data format");
}
return responseData as BlockResponse;
@ -310,7 +261,7 @@ export class RestClient {
public async blocks(height: number): Promise<BlockResponse> {
const responseData = await this.get(`/blocks/${height}`);
if (!(responseData as any).block) {
if (!responseData.block) {
throw new Error("Unexpected response data format");
}
return responseData as BlockResponse;
@ -320,7 +271,7 @@ export class RestClient {
public async nodeInfo(): Promise<NodeInfoResponse> {
const responseData = await this.get("/node_info");
if (!(responseData as any).node_info) {
if (!responseData.node_info) {
throw new Error("Unexpected response data format");
}
return responseData as NodeInfoResponse;
@ -330,7 +281,7 @@ export class RestClient {
public async txById(id: string): Promise<TxsResponse> {
const responseData = await this.get(`/txs/${id}`);
if (!(responseData as any).tx) {
if (!responseData.tx) {
throw new Error("Unexpected response data format");
}
return responseData as TxsResponse;
@ -338,7 +289,7 @@ export class RestClient {
public async txsQuery(query: string): Promise<SearchTxsResponse> {
const responseData = await this.get(`/txs?${query}`);
if (!(responseData as any).txs) {
if (!responseData.txs) {
throw new Error("Unexpected response data format");
}
return responseData as SearchTxsResponse;
@ -347,7 +298,7 @@ export class RestClient {
/** returns the amino-encoding of the transaction performed by the server */
public async encodeTx(tx: CosmosSdkTx): Promise<Uint8Array> {
const responseData = await this.post("/txs/encode", tx);
if (!(responseData as any).tx) {
if (!responseData.tx) {
throw new Error("Unexpected response data format");
}
return Encoding.fromBase64((responseData as EncodeTxResponse).tx);
@ -366,7 +317,7 @@ export class RestClient {
mode: this.broadcastMode,
};
const responseData = await this.post("/txs", params);
if (!(responseData as any).txhash) {
if (!responseData.txhash) {
throw new Error("Unexpected response data format");
}
return responseData as PostTxsResponse;

View File

@ -19,7 +19,16 @@ export {
} from "./cosmosclient";
export { unmarshalTx } from "./decoding";
export { makeSignBytes, marshalTx } from "./encoding";
export { BroadcastMode, RestClient, TxsResponse } from "./restclient";
export {
AuthAccountsResponse,
BlockResponse,
BroadcastMode,
PostTxsResponse,
NodeInfoResponse,
RestClient,
SearchTxsResponse,
TxsResponse,
} from "./restclient";
export { Pen, Secp256k1Pen, makeCosmoshubPath } from "./pen";
export { decodeBech32Pubkey, encodeBech32Pubkey, encodeSecp256k1Pubkey } from "./pubkey";
export { findSequenceForSignedTx } from "./sequence";

View File

@ -9,7 +9,7 @@ export interface CosmosSdkAccount {
readonly account_number: number;
readonly sequence: number;
}
export interface NodeInfo {
interface NodeInfo {
readonly protocol_version: {
readonly p2p: string;
readonly block: string;
@ -26,7 +26,7 @@ export interface NodeInfo {
readonly rpc_address: string;
};
}
export interface ApplicationVersion {
interface ApplicationVersion {
readonly name: string;
readonly server_name: string;
readonly client_name: string;
@ -39,10 +39,10 @@ export interface NodeInfoResponse {
readonly node_info: NodeInfo;
readonly application_version: ApplicationVersion;
}
export interface BlockId {
interface BlockId {
readonly hash: string;
}
export interface BlockHeader {
interface BlockHeader {
readonly version: {
readonly block: string;
readonly app: string;
@ -65,7 +65,7 @@ export interface BlockHeader {
readonly evidence_hash: string;
readonly proposer_address: string;
}
export interface Block {
interface Block {
readonly header: BlockHeader;
readonly data: {
/** Array of base64 encoded transactions */
@ -76,21 +76,13 @@ export interface BlockResponse {
readonly block_id: BlockId;
readonly block: Block;
}
interface AuthAccountsResponse {
export interface AuthAccountsResponse {
readonly height: string;
readonly result: {
readonly type: "cosmos-sdk/Account";
readonly value: CosmosSdkAccount;
};
}
declare type WasmResponse<T = string> = WasmSuccess<T> | WasmError;
interface WasmSuccess<T = string> {
readonly height: string;
readonly result: T;
}
interface WasmError {
readonly error: string;
}
export interface TxsResponse {
readonly height: string;
readonly txhash: string;
@ -107,7 +99,7 @@ export interface TxsResponse {
readonly gas_used?: string;
readonly timestamp: string;
}
interface SearchTxsResponse {
export interface SearchTxsResponse {
readonly total_count: string;
readonly count: string;
readonly page_number: string;
@ -127,46 +119,6 @@ export interface PostTxsResponse {
/** The gas used by the execution */
readonly gas_used?: string;
}
interface EncodeTxResponse {
readonly tx: string;
}
export interface CodeInfo {
readonly id: number;
/** Bech32 account address */
readonly creator: string;
/** Hex-encoded sha256 hash of the code stored here */
readonly data_hash: string;
readonly source?: string;
readonly builder?: string;
}
export interface CodeDetails extends CodeInfo {
/** Base64 encoded raw wasm data */
readonly data: string;
}
export interface ContractInfo {
readonly address: string;
readonly code_id: number;
/** Bech32 account address */
readonly creator: string;
readonly label: string;
}
export interface ContractDetails extends ContractInfo {
/** Argument passed on initialization of the contract */
readonly init_msg: object;
}
declare type RestClientResponse =
| NodeInfoResponse
| BlockResponse
| AuthAccountsResponse
| TxsResponse
| SearchTxsResponse
| PostTxsResponse
| EncodeTxResponse
| WasmResponse<string>
| WasmResponse<CodeInfo[]>
| WasmResponse<CodeDetails>
| WasmResponse<ContractInfo[] | null>
| WasmResponse<ContractDetails | null>;
/**
* The mode used to send transaction
*
@ -195,8 +147,8 @@ export declare class RestClient {
* @param broadcastMode Defines at which point of the transaction processing the postTx method (i.e. transaction broadcasting) returns
*/
constructor(apiUrl: string, broadcastMode?: BroadcastMode);
get(path: string): Promise<RestClientResponse>;
post(path: string, params: any): Promise<RestClientResponse>;
get(path: string): Promise<any>;
post(path: string, params: any): Promise<any>;
authAccounts(address: string): Promise<AuthAccountsResponse>;
blocksLatest(): Promise<BlockResponse>;
blocks(height: number): Promise<BlockResponse>;