From 911c9f06494afafe2f44d54131d126b3c53b8f91 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Mon, 2 Mar 2020 14:07:37 +0100 Subject: [PATCH] Create higher level types Block, BlockHeader --- packages/bcp/src/cosmwasmconnection.ts | 15 +++++---- packages/sdk/src/cosmwasmclient.spec.ts | 30 +++++++++--------- packages/sdk/src/cosmwasmclient.ts | 41 ++++++++++++++++++++----- packages/sdk/src/index.ts | 2 ++ packages/sdk/types/cosmwasmclient.d.ts | 21 +++++++++++-- packages/sdk/types/index.d.ts | 2 ++ 6 files changed, 79 insertions(+), 32 deletions(-) diff --git a/packages/bcp/src/cosmwasmconnection.ts b/packages/bcp/src/cosmwasmconnection.ts index 54d039b2..6c5b16c9 100644 --- a/packages/bcp/src/cosmwasmconnection.ts +++ b/packages/bcp/src/cosmwasmconnection.ts @@ -138,8 +138,8 @@ export class CosmWasmConnection implements BlockchainConnection { } public async height(): Promise { - const { block } = await this.cosmWasmClient.getBlock(); - return parseInt(block.header.height, 10); + const { header } = await this.cosmWasmClient.getBlock(); + return header.height; } public async getToken(searchTicker: TokenTicker): Promise { @@ -247,13 +247,12 @@ export class CosmWasmConnection implements BlockchainConnection { } public async getBlockHeader(height: number): Promise { - // eslint-disable-next-line @typescript-eslint/camelcase - const { block_id: blockId, block } = await this.cosmWasmClient.getBlock(height); + const { id, header, txs } = await this.cosmWasmClient.getBlock(height); return { - id: blockId.hash as BlockId, - height: parseInt(block.header.height, 10), - time: new ReadonlyDate(block.header.time), - transactionCount: block.data.txs?.length || 0, + id: id as BlockId, + height: header.height, + time: new ReadonlyDate(header.time), + transactionCount: txs.length, }; } diff --git a/packages/sdk/src/cosmwasmclient.spec.ts b/packages/sdk/src/cosmwasmclient.spec.ts index 1953b3c2..88d65dc8 100644 --- a/packages/sdk/src/cosmwasmclient.spec.ts +++ b/packages/sdk/src/cosmwasmclient.spec.ts @@ -108,39 +108,39 @@ describe("CosmWasmClient", () => { const response = await client.getBlock(); // id - expect(response.block_id.hash).toMatch(tendermintIdMatcher); + expect(response.id).toMatch(tendermintIdMatcher); // header - expect(parseInt(response.block.header.height, 10)).toBeGreaterThanOrEqual(1); - expect(response.block.header.chain_id).toEqual(await client.chainId()); - expect(new ReadonlyDate(response.block.header.time).getTime()).toBeLessThan(ReadonlyDate.now()); - expect(new ReadonlyDate(response.block.header.time).getTime()).toBeGreaterThanOrEqual( + expect(response.header.height).toBeGreaterThanOrEqual(1); + expect(response.header.chainId).toEqual(await client.chainId()); + expect(new ReadonlyDate(response.header.time).getTime()).toBeLessThan(ReadonlyDate.now()); + expect(new ReadonlyDate(response.header.time).getTime()).toBeGreaterThanOrEqual( ReadonlyDate.now() - 5_000, ); - // data - expect(response.block.data.txs === null || Array.isArray(response.block.data.txs)).toEqual(true); + // txs + expect(Array.isArray(response.txs)).toEqual(true); }); it("works for block by height", async () => { pendingWithoutWasmd(); const client = new CosmWasmClient(wasmdEndpoint); - const height = parseInt((await client.getBlock()).block.header.height, 10); + const height = (await client.getBlock()).header.height; const response = await client.getBlock(height - 1); // id - expect(response.block_id.hash).toMatch(tendermintIdMatcher); + expect(response.id).toMatch(tendermintIdMatcher); // header - expect(response.block.header.height).toEqual(`${height - 1}`); - expect(response.block.header.chain_id).toEqual(await client.chainId()); - expect(new ReadonlyDate(response.block.header.time).getTime()).toBeLessThan(ReadonlyDate.now()); - expect(new ReadonlyDate(response.block.header.time).getTime()).toBeGreaterThanOrEqual( + expect(response.header.height).toEqual(height - 1); + expect(response.header.chainId).toEqual(await client.chainId()); + expect(new ReadonlyDate(response.header.time).getTime()).toBeLessThan(ReadonlyDate.now()); + expect(new ReadonlyDate(response.header.time).getTime()).toBeGreaterThanOrEqual( ReadonlyDate.now() - 5_000, ); - // data - expect(response.block.data.txs === null || Array.isArray(response.block.data.txs)).toEqual(true); + // txs + expect(Array.isArray(response.txs)).toEqual(true); }); }); diff --git a/packages/sdk/src/cosmwasmclient.ts b/packages/sdk/src/cosmwasmclient.ts index 0ac9cb4b..26b9e590 100644 --- a/packages/sdk/src/cosmwasmclient.ts +++ b/packages/sdk/src/cosmwasmclient.ts @@ -2,7 +2,7 @@ import { Sha256 } from "@iov/crypto"; import { Encoding } from "@iov/encoding"; import { Log, parseLogs } from "./logs"; -import { BlockResponse, BroadcastMode, RestClient } from "./restclient"; +import { BroadcastMode, RestClient } from "./restclient"; import { CosmosSdkAccount, CosmosSdkTx, StdTx } from "./types"; export interface GetNonceResult { @@ -106,6 +106,25 @@ export interface IndexedTx { readonly timestamp: string; } +export interface BlockHeader { + readonly version: { + readonly block: string; + readonly app: string; + }; + readonly height: number; + readonly chainId: string; + /** An RFC 3339 time string like e.g. '2020-02-15T10:39:10.4696305Z' */ + readonly time: string; +} + +export interface Block { + /** The ID is a hash of the block header (uppercase hex) */ + readonly id: string; + readonly header: BlockHeader; + /** Array of raw transactions */ + readonly txs: ReadonlyArray; +} + export class CosmWasmClient { protected readonly restClient: RestClient; @@ -159,12 +178,20 @@ export class CosmWasmClient { * * @param height The height of the block. If undefined, the latest height is used. */ - public async getBlock(height?: number): Promise { - if (height !== undefined) { - return this.restClient.blocks(height); - } else { - return this.restClient.blocksLatest(); - } + public async getBlock(height?: number): Promise { + const response = + height !== undefined ? await this.restClient.blocks(height) : await this.restClient.blocksLatest(); + + return { + id: response.block_id.hash, + header: { + version: response.block.header.version, + time: response.block.header.time, + height: parseInt(response.block.header.height, 10), + chainId: response.block.header.chain_id, + }, + txs: (response.block.data.txs || []).map(encoded => Encoding.fromBase64(encoded)), + }; } public async searchTx(query: SearchTxQuery, filter: SearchTxFilter = {}): Promise { diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 28400ecf..bf7704fd 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -7,6 +7,8 @@ export { unmarshalTx } from "./decoding"; export { makeSignBytes, marshalTx } from "./encoding"; export { BroadcastMode, RestClient, TxsResponse } from "./restclient"; export { + Block, + BlockHeader, Code, CodeDetails, Contract, diff --git a/packages/sdk/types/cosmwasmclient.d.ts b/packages/sdk/types/cosmwasmclient.d.ts index a35d3839..54fa2749 100644 --- a/packages/sdk/types/cosmwasmclient.d.ts +++ b/packages/sdk/types/cosmwasmclient.d.ts @@ -1,5 +1,5 @@ import { Log } from "./logs"; -import { BlockResponse, BroadcastMode, RestClient } from "./restclient"; +import { BroadcastMode, RestClient } from "./restclient"; import { CosmosSdkAccount, CosmosSdkTx, StdTx } from "./types"; export interface GetNonceResult { readonly accountNumber: number; @@ -76,6 +76,23 @@ export interface IndexedTx { readonly gasUsed?: number; readonly timestamp: string; } +export interface BlockHeader { + readonly version: { + readonly block: string; + readonly app: string; + }; + readonly height: number; + readonly chainId: string; + /** An RFC 3339 time string like e.g. '2020-02-15T10:39:10.4696305Z' */ + readonly time: string; +} +export interface Block { + /** The ID is a hash of the block header (uppercase hex) */ + readonly id: string; + readonly header: BlockHeader; + /** Array of raw transactions */ + readonly txs: ReadonlyArray; +} export declare class CosmWasmClient { protected readonly restClient: RestClient; constructor(url: string, broadcastMode?: BroadcastMode); @@ -98,7 +115,7 @@ export declare class CosmWasmClient { * * @param height The height of the block. If undefined, the latest height is used. */ - getBlock(height?: number): Promise; + getBlock(height?: number): Promise; searchTx(query: SearchTxQuery, filter?: SearchTxFilter): Promise; postTx(tx: StdTx): Promise; getCodes(): Promise; diff --git a/packages/sdk/types/index.d.ts b/packages/sdk/types/index.d.ts index 6c1aecba..54934860 100644 --- a/packages/sdk/types/index.d.ts +++ b/packages/sdk/types/index.d.ts @@ -6,6 +6,8 @@ export { unmarshalTx } from "./decoding"; export { makeSignBytes, marshalTx } from "./encoding"; export { BroadcastMode, RestClient, TxsResponse } from "./restclient"; export { + Block, + BlockHeader, Code, CodeDetails, Contract,