Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow to specify an AccountParser inside StargateClient #1102

Merged
merged 5 commits into from
Mar 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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`
webmaster128 marked this conversation as resolved.
Show resolved Hide resolved

### 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;
webmaster128 marked this conversation as resolved.
Show resolved Hide resolved

/**
* 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 {
webmaster128 marked this conversation as resolved.
Show resolved Hide resolved
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