Skip to content

Commit

Permalink
feat: allow to specify an AccountParser inside StargateClient (#1102)
Browse files Browse the repository at this point in the history
* feat: added the ability to specify an AccountParser inside StargateClient

* use inheritance instead of composition

* make accountParser not optional

* added changelog

* added types to index.ts
  • Loading branch information
RiccardoM authored Mar 30, 2022
1 parent af4215e commit 13ce43c
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 11 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and this project adheres to

## [Unreleased]

### Added

- @cosmjs/stargate: Added the ability to specify a custom account parser for `StargateClient`

### Fixed

- @cosmjs/proto-signing: Add missing runtime dependencies @cosmjs/encoding and
Expand Down
9 changes: 7 additions & 2 deletions packages/stargate/src/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,13 @@ function accountFromBaseAccount(input: BaseAccount): Account {
}

/**
* Takes an `Any` encoded account from the chain and extracts some common
* `Account` information from it. This is supposed to support the most relevant
* Represents a generic function that takes an `Any` encoded account from the chain
* and extracts some common `Account` information from it.
*/
export type AccountParser = (any: Any) => Account;

/**
* Basic implementation of AccountParser. This is supposed to support the most relevant
* common Cosmos SDK account types. If you need support for exotic account types,
* you'll need to write your own account decoder.
*/
Expand Down
3 changes: 2 additions & 1 deletion packages/stargate/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { Account, accountFromAny } from "./accounts";
export { Account, accountFromAny, AccountParser } from "./accounts";
export { AminoConverter, AminoConverters, AminoTypes } from "./aminotypes";
export { calculateFee, GasPrice } from "./fee";
export * as logs from "./logs";
Expand Down Expand Up @@ -117,6 +117,7 @@ export {
isDeliverTxSuccess,
SequenceResponse,
StargateClient,
StargateClientOptions,
TimeoutError,
} from "./stargateclient";
export { StdFee } from "@cosmjs/amino";
Expand Down
6 changes: 3 additions & 3 deletions packages/stargate/src/signingstargateclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import {
createIbcAminoConverters,
createStakingAminoConverters,
} from "./modules";
import { DeliverTxResponse, StargateClient } from "./stargateclient";
import { DeliverTxResponse, StargateClient, StargateClientOptions } from "./stargateclient";

export const defaultRegistryTypes: ReadonlyArray<[string, GeneratedType]> = [
["/cosmos.base.v1beta1.Coin", Coin],
Expand Down Expand Up @@ -81,7 +81,7 @@ export interface PrivateSigningStargateClient {
readonly registry: Registry;
}

export interface SigningStargateClientOptions {
export interface SigningStargateClientOptions extends StargateClientOptions {
readonly registry?: Registry;
readonly aminoTypes?: AminoTypes;
readonly prefix?: string;
Expand Down Expand Up @@ -141,7 +141,7 @@ export class SigningStargateClient extends StargateClient {
signer: OfflineSigner,
options: SigningStargateClientOptions,
) {
super(tmClient);
super(tmClient, options);
// TODO: do we really want to set a default here? Ideally we could get it from the signer such that users only have to set it once.
const prefix = options.prefix ?? "cosmos";
const { registry = createDefaultRegistry(), aminoTypes = new AminoTypes(createDefaultTypes(prefix)) } =
Expand Down
20 changes: 15 additions & 5 deletions packages/stargate/src/stargateclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { sleep } from "@cosmjs/utils";
import { MsgData } from "cosmjs-types/cosmos/base/abci/v1beta1/abci";
import { Coin } from "cosmjs-types/cosmos/base/v1beta1/coin";

import { Account, accountFromAny } from "./accounts";
import { Account, accountFromAny, AccountParser } from "./accounts";
import {
AuthExtension,
BankExtension,
Expand Down Expand Up @@ -136,19 +136,27 @@ export interface PrivateStargateClient {
readonly tmClient: Tendermint34Client | undefined;
}

export interface StargateClientOptions {
readonly accountParser?: AccountParser;
}

export class StargateClient {
private readonly tmClient: Tendermint34Client | undefined;
private readonly queryClient:
| (QueryClient & AuthExtension & BankExtension & StakingExtension & TxExtension)
| undefined;
private chainId: string | undefined;
private readonly accountParser: AccountParser;

public static async connect(endpoint: string): Promise<StargateClient> {
public static async connect(
endpoint: string,
options: StargateClientOptions = {},
): Promise<StargateClient> {
const tmClient = await Tendermint34Client.connect(endpoint);
return new StargateClient(tmClient);
return new StargateClient(tmClient, options);
}

protected constructor(tmClient: Tendermint34Client | undefined) {
protected constructor(tmClient: Tendermint34Client | undefined, options: StargateClientOptions) {
if (tmClient) {
this.tmClient = tmClient;
this.queryClient = QueryClient.withExtensions(
Expand All @@ -159,6 +167,8 @@ export class StargateClient {
setupTxExtension,
);
}
const { accountParser = accountFromAny } = options;
this.accountParser = accountParser;
}

protected getTmClient(): Tendermint34Client | undefined {
Expand Down Expand Up @@ -210,7 +220,7 @@ export class StargateClient {
public async getAccount(searchAddress: string): Promise<Account | null> {
try {
const account = await this.forceGetQueryClient().auth.account(searchAddress);
return account ? accountFromAny(account) : null;
return account ? this.accountParser(account) : null;
} catch (error: any) {
if (/rpc error: code = NotFound/i.test(error.toString())) {
return null;
Expand Down

0 comments on commit 13ce43c

Please sign in to comment.