From cd7c5c2efa3e686b413cb9cffae264a5fd821d92 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 12 Aug 2020 12:28:04 +0200 Subject: [PATCH] stargate: Add getBlock method to client --- packages/stargate/src/stargateclient.spec.ts | 49 ++++++++++++++++++++ packages/stargate/src/stargateclient.ts | 21 ++++++++- packages/stargate/src/testutils.spec.ts | 2 + packages/stargate/types/stargateclient.d.ts | 3 +- 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/packages/stargate/src/stargateclient.spec.ts b/packages/stargate/src/stargateclient.spec.ts index c3f37ba6..8bb302d5 100644 --- a/packages/stargate/src/stargateclient.spec.ts +++ b/packages/stargate/src/stargateclient.spec.ts @@ -3,6 +3,7 @@ import { Bech32, fromBase64 } from "@cosmjs/encoding"; import { Secp256k1Wallet } from "@cosmjs/launchpad"; import { makeSignBytes, omitDefaults, Registry } from "@cosmjs/proto-signing"; import { assert, sleep } from "@cosmjs/utils"; +import { ReadonlyDate } from "readonly-date"; import { cosmos } from "./generated/codecimpl"; import { assertIsBroadcastTxSuccess, PrivateStargateClient, StargateClient } from "./stargateclient"; @@ -12,6 +13,7 @@ import { nonExistentAddress, pendingWithoutSimapp, simapp, + tendermintIdMatcher, unused, validator, } from "./testutils.spec"; @@ -133,6 +135,53 @@ describe("StargateClient", () => { }); }); + describe("getBlock", () => { + it("works for latest block", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + const response = await client.getBlock(); + + expect(response).toEqual( + jasmine.objectContaining({ + id: jasmine.stringMatching(tendermintIdMatcher), + header: jasmine.objectContaining({ + chainId: await client.getChainId(), + }), + txs: [], + }), + ); + + expect(response.header.height).toBeGreaterThanOrEqual(1); + expect(new ReadonlyDate(response.header.time).getTime()).toBeLessThan(ReadonlyDate.now()); + expect(new ReadonlyDate(response.header.time).getTime()).toBeGreaterThanOrEqual( + ReadonlyDate.now() - 5_000, + ); + }); + + it("works for block by height", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + const height = (await client.getBlock()).header.height; + const response = await client.getBlock(height - 1); + + expect(response).toEqual( + jasmine.objectContaining({ + id: jasmine.stringMatching(tendermintIdMatcher), + header: jasmine.objectContaining({ + height: height - 1, + chainId: await client.getChainId(), + }), + txs: [], + }), + ); + + expect(new ReadonlyDate(response.header.time).getTime()).toBeLessThan(ReadonlyDate.now()); + expect(new ReadonlyDate(response.header.time).getTime()).toBeGreaterThanOrEqual( + ReadonlyDate.now() - 5_000, + ); + }); + }); + describe("getBalance", () => { it("works for different existing balances", async () => { pendingWithoutSimapp(); diff --git a/packages/stargate/src/stargateclient.ts b/packages/stargate/src/stargateclient.ts index 14647007..cda62e28 100644 --- a/packages/stargate/src/stargateclient.ts +++ b/packages/stargate/src/stargateclient.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ import { Bech32, toAscii, toHex } from "@cosmjs/encoding"; -import { Coin, decodeAminoPubkey, PubKey } from "@cosmjs/launchpad"; -import { Uint64 } from "@cosmjs/math"; +import { Block, Coin, decodeAminoPubkey, PubKey } from "@cosmjs/launchpad"; +import { Uint53, Uint64 } from "@cosmjs/math"; import { decodeAny } from "@cosmjs/proto-signing"; import { broadcastTxCommitSuccess, Client as TendermintClient } from "@cosmjs/tendermint-rpc"; import { arrayContentEquals, assert, assertDefined } from "@cosmjs/utils"; @@ -151,6 +151,23 @@ export class StargateClient { } } + public async getBlock(height?: number): Promise { + const response = await this.tmClient.block(height); + return { + id: toHex(response.blockId.hash).toUpperCase(), + header: { + version: { + block: new Uint53(response.block.header.version.block).toString(), + app: new Uint53(response.block.header.version.app).toString(), + }, + height: response.block.header.height, + chainId: response.block.header.chainId, + time: response.block.header.time.toISOString(), + }, + txs: response.block.txs, + }; + } + public async getBalance(address: string, searchDenom: string): Promise { // balance key is a bit tricker, using some prefix stores // https://github.com/cosmwasm/cosmos-sdk/blob/80f7ff62f79777a487d0c7a53c64b0f7e43c47b9/x/bank/keeper/view.go#L74-L77 diff --git a/packages/stargate/src/testutils.spec.ts b/packages/stargate/src/testutils.spec.ts index ea501b86..efb85a5e 100644 --- a/packages/stargate/src/testutils.spec.ts +++ b/packages/stargate/src/testutils.spec.ts @@ -54,3 +54,5 @@ export const validator = { }; export const nonExistentAddress = "cosmos1p79apjaufyphcmsn4g07cynqf0wyjuezqu84hd"; + +export const tendermintIdMatcher = /^[0-9A-F]{64}$/; diff --git a/packages/stargate/types/stargateclient.d.ts b/packages/stargate/types/stargateclient.d.ts index 69123a7b..e3c01a43 100644 --- a/packages/stargate/types/stargateclient.d.ts +++ b/packages/stargate/types/stargateclient.d.ts @@ -1,4 +1,4 @@ -import { Coin, PubKey } from "@cosmjs/launchpad"; +import { Block, Coin, PubKey } from "@cosmjs/launchpad"; import { Client as TendermintClient } from "@cosmjs/tendermint-rpc"; export interface Account { /** Bech32 account address */ @@ -46,6 +46,7 @@ export declare class StargateClient { getHeight(): Promise; getAccount(searchAddress: string): Promise; getSequence(address: string): Promise; + getBlock(height?: number): Promise; getBalance(address: string, searchDenom: string): Promise; /** * Queries all balances for all denoms that belong to this address.