Move accountFromAny into new module and create a test

This commit is contained in:
Simon Warta 2021-03-15 17:52:20 +01:00
parent f2191ee211
commit 8804e0ccb2
5 changed files with 125 additions and 87 deletions

View File

@ -0,0 +1,9 @@
import { QueryClient, setupAuthExtension } from "@cosmjs/stargate";
import { Any } from "@cosmjs/stargate/build/codec/google/protobuf/any";
import { Tendermint34Client } from "@cosmjs/tendermint-rpc";
// https://github.com/ovrclk/net/blob/24ddbb427b0c15/mainnet/rpc-nodes.txt
const tmClient = await Tendermint34Client.connect("http://rpc.akash.forbole.com:80");
const client = QueryClient.withExtensions(tmClient, setupAuthExtension);
const account = await client.auth.unverified.account("akash1qy0vur3fl2ucztpzcrfea7mc8jwz8xjmvq7qvy");
console.log(Any.toJSON(account))

View File

@ -0,0 +1,27 @@
import { accountFromAny } from "./accounts";
import { Any } from "./codec/google/protobuf/any";
describe("accounts", () => {
describe("accountFromAny", () => {
it("works for PeriodicVestingAccount", () => {
// Arbitrary entry from https://raw.githubusercontent.com/ovrclk/net/24ddbb427/mainnet/genesis.json
// queried from chain via `packages/cli/examples/get_vesting_account.ts`.
const any = Any.fromJSON({
typeUrl: "/cosmos.vesting.v1beta1.PeriodicVestingAccount",
value:
"CsMBCnoKLGFrYXNoMXF5MHZ1cjNmbDJ1Y3p0cHpjcmZlYTdtYzhqd3o4eGptdnE3cXZ5EkYKHy9jb3Ntb3MuY3J5cHRvLnNlY3AyNTZrMS5QdWJLZXkSIwohA/XsdhwSIKU73TltD9STcaS07FNw0szR4a+oDLr6vikaGDggGxIUCgR1YWt0EgwxNjY2NjY2NzAwMDAaEwoEdWFrdBILMzcxOTAzMzAwMDAiFAoEdWFrdBIMMTY2NjY2NjcwMDAwKOC9wZkGEODvt/sFGhoIgOeEDxITCgR1YWt0Egs4MzMzMzMzNTAwMBoaCIC/ugcSEwoEdWFrdBILNDE2NjY2Njc1MDAaGgiAqMoHEhMKBHVha3QSCzQxNjY2NjY3NTAw",
});
const account = accountFromAny(any);
expect(account).toEqual({
address: "akash1qy0vur3fl2ucztpzcrfea7mc8jwz8xjmvq7qvy",
pubkey: {
type: "tendermint/PubKeySecp256k1",
value: "A/XsdhwSIKU73TltD9STcaS07FNw0szR4a+oDLr6vika",
},
accountNumber: 56,
sequence: 27,
});
});
});
});

View File

@ -0,0 +1,85 @@
import { PubKey } from "@cosmjs/launchpad";
import { Uint64 } from "@cosmjs/math";
import { decodePubkey } from "@cosmjs/proto-signing";
import { assert } from "@cosmjs/utils";
import Long from "long";
import { BaseAccount, ModuleAccount } from "./codec/cosmos/auth/v1beta1/auth";
import {
BaseVestingAccount,
ContinuousVestingAccount,
DelayedVestingAccount,
PeriodicVestingAccount,
} from "./codec/cosmos/vesting/v1beta1/vesting";
import { Any } from "./codec/google/protobuf/any";
export interface Account {
/** Bech32 account address */
readonly address: string;
readonly pubkey: PubKey | null;
readonly accountNumber: number;
readonly sequence: number;
}
function uint64FromProto(input: number | Long): Uint64 {
return Uint64.fromString(input.toString());
}
function accountFromBaseAccount(input: BaseAccount): Account {
const { address, pubKey, accountNumber, sequence } = input;
const pubkey = decodePubkey(pubKey);
return {
address: address,
pubkey: pubkey,
accountNumber: uint64FromProto(accountNumber).toNumber(),
sequence: uint64FromProto(sequence).toNumber(),
};
}
/**
* Takes an `Any` encoded account from the chain and extracts some common
* `Account` information from it. This is supposed to support the most relevant
* common Cosmos SDK account types. If you need support for exotix account types,
* you'll need to write your own account decoder.
*/
export function accountFromAny(input: Any): Account {
const { typeUrl, value } = input;
switch (typeUrl) {
// auth
case "/cosmos.auth.v1beta1.BaseAccount":
return accountFromBaseAccount(BaseAccount.decode(value));
case "/cosmos.auth.v1beta1.ModuleAccount": {
const baseAccount = ModuleAccount.decode(value).baseAccount;
assert(baseAccount);
return accountFromBaseAccount(baseAccount);
}
// vesting
case "/cosmos.vesting.v1beta1.BaseVestingAccount": {
const baseAccount = BaseVestingAccount.decode(value)?.baseAccount;
assert(baseAccount);
return accountFromBaseAccount(baseAccount);
}
case "/cosmos.vesting.v1beta1.ContinuousVestingAccount": {
const baseAccount = ContinuousVestingAccount.decode(value)?.baseVestingAccount?.baseAccount;
assert(baseAccount);
return accountFromBaseAccount(baseAccount);
}
case "/cosmos.vesting.v1beta1.DelayedVestingAccount": {
const baseAccount = DelayedVestingAccount.decode(value)?.baseVestingAccount?.baseAccount;
assert(baseAccount);
return accountFromBaseAccount(baseAccount);
}
case "/cosmos.vesting.v1beta1.PeriodicVestingAccount": {
const baseAccount = PeriodicVestingAccount.decode(value)?.baseVestingAccount?.baseAccount;
assert(baseAccount);
return accountFromBaseAccount(baseAccount);
}
default:
throw new Error(`Unsupported type: '${typeUrl}'`);
}
}

View File

@ -1,3 +1,4 @@
export { Account, accountFromAny } from "./accounts";
export { AminoConverter, AminoTypes } from "./aminotypes";
export { parseRawLog } from "./logs";
export {
@ -17,8 +18,6 @@ export {
StakingExtension,
} from "./queries";
export {
Account,
accountFromAny,
assertIsBroadcastTxSuccess,
BroadcastTxFailure,
BroadcastTxResponse,

View File

@ -5,30 +5,20 @@ import {
isSearchByHeightQuery,
isSearchBySentFromOrToQuery,
isSearchByTagsQuery,
PubKey,
SearchTxFilter,
SearchTxQuery,
} from "@cosmjs/launchpad";
import { Uint53, Uint64 } from "@cosmjs/math";
import { decodePubkey } from "@cosmjs/proto-signing";
import { Uint53 } from "@cosmjs/math";
import {
broadcastTxCommitSuccess,
Tendermint34Client,
toRfc3339WithNanoseconds,
} from "@cosmjs/tendermint-rpc";
import { assert, assertDefinedAndNotNull } from "@cosmjs/utils";
import Long from "long";
import { assertDefinedAndNotNull } from "@cosmjs/utils";
import { BaseAccount, ModuleAccount } from "./codec/cosmos/auth/v1beta1/auth";
import { Account, accountFromAny } from "./accounts";
import { MsgData, TxMsgData } from "./codec/cosmos/base/abci/v1beta1/abci";
import { Coin } from "./codec/cosmos/base/v1beta1/coin";
import {
BaseVestingAccount,
ContinuousVestingAccount,
DelayedVestingAccount,
PeriodicVestingAccount,
} from "./codec/cosmos/vesting/v1beta1/vesting";
import { Any } from "./codec/google/protobuf/any";
import { AuthExtension, BankExtension, QueryClient, setupAuthExtension, setupBankExtension } from "./queries";
/** A transaction that is indexed as part of the transaction history */
@ -42,14 +32,6 @@ export interface IndexedTx {
readonly tx: Uint8Array;
}
export interface Account {
/** Bech32 account address */
readonly address: string;
readonly pubkey: PubKey | null;
readonly accountNumber: number;
readonly sequence: number;
}
export interface SequenceResponse {
readonly accountNumber: number;
readonly sequence: number;
@ -93,70 +75,6 @@ export function assertIsBroadcastTxSuccess(
}
}
function uint64FromProto(input: number | Long | null | undefined): Uint64 {
if (!input) return Uint64.fromNumber(0);
return Uint64.fromString(input.toString());
}
function accountFromBaseAccount(input: BaseAccount): Account {
const { address, pubKey, accountNumber, sequence } = input;
const pubkey = decodePubkey(pubKey);
return {
address: address,
pubkey: pubkey,
accountNumber: uint64FromProto(accountNumber).toNumber(),
sequence: uint64FromProto(sequence).toNumber(),
};
}
/**
* Takes an `Any` encoded account from the chain and extracts some common
* `Account` information from it. This is supposed to support the most relevant
* common Cosmos SDK account types. If you need support for exotix account types,
* you'll need to write your own account decoder.
*/
export function accountFromAny(input: Any): Account {
const { typeUrl, value } = input;
switch (typeUrl) {
// auth
case "/cosmos.auth.v1beta1.BaseAccount":
return accountFromBaseAccount(BaseAccount.decode(value));
case "/cosmos.auth.v1beta1.ModuleAccount": {
const baseAccount = ModuleAccount.decode(value).baseAccount;
assert(baseAccount);
return accountFromBaseAccount(baseAccount);
}
// vesting
case "/cosmos.vesting.v1beta1.BaseVestingAccount": {
const baseAccount = BaseVestingAccount.decode(value)?.baseAccount;
assert(baseAccount);
return accountFromBaseAccount(baseAccount);
}
case "/cosmos.vesting.v1beta1.ContinuousVestingAccount": {
const baseAccount = ContinuousVestingAccount.decode(value)?.baseVestingAccount?.baseAccount;
assert(baseAccount);
return accountFromBaseAccount(baseAccount);
}
case "/cosmos.vesting.v1beta1.DelayedVestingAccount": {
const baseAccount = DelayedVestingAccount.decode(value)?.baseVestingAccount?.baseAccount;
assert(baseAccount);
return accountFromBaseAccount(baseAccount);
}
case "/cosmos.vesting.v1beta1.PeriodicVestingAccount": {
const baseAccount = PeriodicVestingAccount.decode(value)?.baseVestingAccount?.baseAccount;
assert(baseAccount);
return accountFromBaseAccount(baseAccount);
}
default:
throw new Error(`Unsupported type: '${typeUrl}'`);
}
}
export function coinFromProto(input: Coin): Coin {
assertDefinedAndNotNull(input.amount);
assertDefinedAndNotNull(input.denom);