mirror of
https://github.com/cosmos/cosmjs.git
synced 2025-03-10 21:49:15 +00:00
Use Any for account encoding
This commit is contained in:
parent
6491f8f485
commit
659b9193c0
@ -10,6 +10,10 @@ and this project adheres to
|
|||||||
|
|
||||||
- @cosmjs/cosmwasm-stargate: Codec adapted to support wasmd 0.16. Older versions
|
- @cosmjs/cosmwasm-stargate: Codec adapted to support wasmd 0.16. Older versions
|
||||||
of wasmd are not supported anymore.
|
of wasmd are not supported anymore.
|
||||||
|
- @cosmjs/stargate: Let `AuthExtension.account` and
|
||||||
|
`AuthExtension.unverified.account` return an account of type `Any`. This makes
|
||||||
|
the caller responsible for decoding the type.
|
||||||
|
- @cosmjs/stargate: Remove `accountFromProto` in favour of `accountFromAny`.
|
||||||
- @cosmjs/tendermint-rpc: The fields `CommitSignature.validatorAddress`,
|
- @cosmjs/tendermint-rpc: The fields `CommitSignature.validatorAddress`,
|
||||||
`.timestamp` and `.signature` are now optional. They are unset when
|
`.timestamp` and `.signature` are now optional. They are unset when
|
||||||
`blockIdFlag` is `BlockIdFlag.Absent`. The decoding into `CommitSignature` is
|
`blockIdFlag` is `BlockIdFlag.Absent`. The decoding into `CommitSignature` is
|
||||||
|
@ -19,7 +19,7 @@ import {
|
|||||||
import { Uint53 } from "@cosmjs/math";
|
import { Uint53 } from "@cosmjs/math";
|
||||||
import {
|
import {
|
||||||
Account,
|
Account,
|
||||||
accountFromProto,
|
accountFromAny,
|
||||||
AuthExtension,
|
AuthExtension,
|
||||||
BankExtension,
|
BankExtension,
|
||||||
BroadcastTxResponse,
|
BroadcastTxResponse,
|
||||||
@ -87,7 +87,7 @@ export class CosmWasmClient {
|
|||||||
|
|
||||||
public async getAccount(searchAddress: string): Promise<Account | null> {
|
public async getAccount(searchAddress: string): Promise<Account | null> {
|
||||||
const account = await this.queryClient.auth.account(searchAddress);
|
const account = await this.queryClient.auth.account(searchAddress);
|
||||||
return account ? accountFromProto(account) : null;
|
return account ? accountFromAny(account) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getSequence(address: string): Promise<SequenceResponse | null> {
|
public async getSequence(address: string): Promise<SequenceResponse | null> {
|
||||||
|
@ -18,7 +18,7 @@ export {
|
|||||||
} from "./queries";
|
} from "./queries";
|
||||||
export {
|
export {
|
||||||
Account,
|
Account,
|
||||||
accountFromProto,
|
accountFromAny,
|
||||||
assertIsBroadcastTxSuccess,
|
assertIsBroadcastTxSuccess,
|
||||||
BroadcastTxFailure,
|
BroadcastTxFailure,
|
||||||
BroadcastTxResponse,
|
BroadcastTxResponse,
|
||||||
|
@ -4,6 +4,7 @@ import { Tendermint34Client } from "@cosmjs/tendermint-rpc";
|
|||||||
import { assert } from "@cosmjs/utils";
|
import { assert } from "@cosmjs/utils";
|
||||||
import Long from "long";
|
import Long from "long";
|
||||||
|
|
||||||
|
import { BaseAccount } from "../codec/cosmos/auth/v1beta1/auth";
|
||||||
import { Any } from "../codec/google/protobuf/any";
|
import { Any } from "../codec/google/protobuf/any";
|
||||||
import { nonExistentAddress, pendingWithoutSimapp, simapp, unused, validator } from "../testutils.spec";
|
import { nonExistentAddress, pendingWithoutSimapp, simapp, unused, validator } from "../testutils.spec";
|
||||||
import { AuthExtension, setupAuthExtension } from "./auth";
|
import { AuthExtension, setupAuthExtension } from "./auth";
|
||||||
@ -24,7 +25,8 @@ describe("AuthExtension", () => {
|
|||||||
const account = await client.auth.account(unused.address);
|
const account = await client.auth.account(unused.address);
|
||||||
assert(account);
|
assert(account);
|
||||||
|
|
||||||
expect(account).toEqual({
|
expect(account.typeUrl).toEqual("/cosmos.auth.v1beta1.BaseAccount");
|
||||||
|
expect(BaseAccount.decode(account.value)).toEqual({
|
||||||
address: unused.address,
|
address: unused.address,
|
||||||
// pubKey not set
|
// pubKey not set
|
||||||
accountNumber: Long.fromNumber(unused.accountNumber, true),
|
accountNumber: Long.fromNumber(unused.accountNumber, true),
|
||||||
@ -40,10 +42,10 @@ describe("AuthExtension", () => {
|
|||||||
const account = await client.auth.account(validator.delegatorAddress);
|
const account = await client.auth.account(validator.delegatorAddress);
|
||||||
assert(account);
|
assert(account);
|
||||||
|
|
||||||
const pubkey = encodePubkey(validator.pubkey);
|
expect(account.typeUrl).toEqual("/cosmos.auth.v1beta1.BaseAccount");
|
||||||
expect(account).toEqual({
|
expect(BaseAccount.decode(account.value)).toEqual({
|
||||||
address: validator.delegatorAddress,
|
address: validator.delegatorAddress,
|
||||||
pubKey: Any.fromPartial(pubkey),
|
pubKey: Any.fromPartial(encodePubkey(validator.pubkey)),
|
||||||
accountNumber: Long.fromNumber(0, true),
|
accountNumber: Long.fromNumber(0, true),
|
||||||
sequence: Long.fromNumber(validator.sequence, true),
|
sequence: Long.fromNumber(validator.sequence, true),
|
||||||
});
|
});
|
||||||
@ -70,7 +72,8 @@ describe("AuthExtension", () => {
|
|||||||
const account = await client.auth.unverified.account(unused.address);
|
const account = await client.auth.unverified.account(unused.address);
|
||||||
assert(account);
|
assert(account);
|
||||||
|
|
||||||
expect(account).toEqual({
|
expect(account.typeUrl).toEqual("/cosmos.auth.v1beta1.BaseAccount");
|
||||||
|
expect(BaseAccount.decode(account.value)).toEqual({
|
||||||
address: unused.address,
|
address: unused.address,
|
||||||
// pubKey not set
|
// pubKey not set
|
||||||
accountNumber: Long.fromNumber(unused.accountNumber, true),
|
accountNumber: Long.fromNumber(unused.accountNumber, true),
|
||||||
@ -86,10 +89,10 @@ describe("AuthExtension", () => {
|
|||||||
const account = await client.auth.unverified.account(validator.delegatorAddress);
|
const account = await client.auth.unverified.account(validator.delegatorAddress);
|
||||||
assert(account);
|
assert(account);
|
||||||
|
|
||||||
const pubkey = encodePubkey(validator.pubkey);
|
expect(account.typeUrl).toEqual("/cosmos.auth.v1beta1.BaseAccount");
|
||||||
expect(account).toEqual({
|
expect(BaseAccount.decode(account.value)).toEqual({
|
||||||
address: validator.delegatorAddress,
|
address: validator.delegatorAddress,
|
||||||
pubKey: Any.fromPartial(pubkey),
|
pubKey: Any.fromPartial(encodePubkey(validator.pubkey)),
|
||||||
accountNumber: Long.fromNumber(0, true),
|
accountNumber: Long.fromNumber(0, true),
|
||||||
sequence: Long.fromNumber(validator.sequence, true),
|
sequence: Long.fromNumber(validator.sequence, true),
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
/* eslint-disable @typescript-eslint/naming-convention */
|
|
||||||
import { assert } from "@cosmjs/utils";
|
|
||||||
|
|
||||||
import { BaseAccount } from "../codec/cosmos/auth/v1beta1/auth";
|
|
||||||
import { QueryClientImpl } from "../codec/cosmos/auth/v1beta1/query";
|
import { QueryClientImpl } from "../codec/cosmos/auth/v1beta1/query";
|
||||||
import { Any } from "../codec/google/protobuf/any";
|
import { Any } from "../codec/google/protobuf/any";
|
||||||
import { QueryClient } from "./queryclient";
|
import { QueryClient } from "./queryclient";
|
||||||
@ -9,9 +5,23 @@ import { createRpc, toAccAddress } from "./utils";
|
|||||||
|
|
||||||
export interface AuthExtension {
|
export interface AuthExtension {
|
||||||
readonly auth: {
|
readonly auth: {
|
||||||
readonly account: (address: string) => Promise<BaseAccount | null>;
|
/**
|
||||||
|
* Returns an account if it exists and `null` otherwise.
|
||||||
|
*
|
||||||
|
* The account is a protobuf Any in order to be able to support many different
|
||||||
|
* account types in one API. The caller needs to switch over the expeced and supported
|
||||||
|
* `typeUrl` and decode the `value` using its own type decoder.
|
||||||
|
*/
|
||||||
|
readonly account: (address: string) => Promise<Any | null>;
|
||||||
readonly unverified: {
|
readonly unverified: {
|
||||||
readonly account: (address: string) => Promise<BaseAccount | null>;
|
/**
|
||||||
|
* Returns an account if it exists and `null` otherwise.
|
||||||
|
*
|
||||||
|
* The account is a protobuf Any in order to be able to support many different
|
||||||
|
* account types in one API. The caller needs to switch over the expeced and supported
|
||||||
|
* `typeUrl` and decode the `value` using its own type decoder.
|
||||||
|
*/
|
||||||
|
readonly account: (address: string) => Promise<Any | null>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -29,27 +39,13 @@ export function setupAuthExtension(base: QueryClient): AuthExtension {
|
|||||||
const key = Uint8Array.from([0x01, ...toAccAddress(address)]);
|
const key = Uint8Array.from([0x01, ...toAccAddress(address)]);
|
||||||
const responseData = await base.queryVerified("acc", key);
|
const responseData = await base.queryVerified("acc", key);
|
||||||
if (responseData.length === 0) return null;
|
if (responseData.length === 0) return null;
|
||||||
const account = Any.decode(responseData);
|
return Any.decode(responseData);
|
||||||
switch (account.typeUrl) {
|
|
||||||
case "/cosmos.auth.v1beta1.BaseAccount": {
|
|
||||||
return BaseAccount.decode(account.value);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw new Error(`Unsupported type: '${account.typeUrl}'`);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
unverified: {
|
unverified: {
|
||||||
account: async (address: string) => {
|
account: async (address: string) => {
|
||||||
const { account } = await queryService.Account({ address: address });
|
const { account } = await queryService.Account({ address: address });
|
||||||
if (!account) return null;
|
if (!account) return null;
|
||||||
switch (account.typeUrl) {
|
return account;
|
||||||
case "/cosmos.auth.v1beta1.BaseAccount": {
|
|
||||||
assert(account.value);
|
|
||||||
return BaseAccount.decode(account.value);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw new Error(`Unsupported type: '${account.typeUrl}'`);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -16,12 +16,13 @@ import {
|
|||||||
Tendermint34Client,
|
Tendermint34Client,
|
||||||
toRfc3339WithNanoseconds,
|
toRfc3339WithNanoseconds,
|
||||||
} from "@cosmjs/tendermint-rpc";
|
} from "@cosmjs/tendermint-rpc";
|
||||||
import { assert, assertDefinedAndNotNull } from "@cosmjs/utils";
|
import { assertDefinedAndNotNull } from "@cosmjs/utils";
|
||||||
import Long from "long";
|
import Long from "long";
|
||||||
|
|
||||||
import { BaseAccount } from "./codec/cosmos/auth/v1beta1/auth";
|
import { BaseAccount } from "./codec/cosmos/auth/v1beta1/auth";
|
||||||
import { MsgData, TxMsgData } from "./codec/cosmos/base/abci/v1beta1/abci";
|
import { MsgData, TxMsgData } from "./codec/cosmos/base/abci/v1beta1/abci";
|
||||||
import { Coin } from "./codec/cosmos/base/v1beta1/coin";
|
import { Coin } from "./codec/cosmos/base/v1beta1/coin";
|
||||||
|
import { Any } from "./codec/google/protobuf/any";
|
||||||
import { AuthExtension, BankExtension, QueryClient, setupAuthExtension, setupBankExtension } from "./queries";
|
import { AuthExtension, BankExtension, QueryClient, setupAuthExtension, setupBankExtension } from "./queries";
|
||||||
|
|
||||||
/** A transaction that is indexed as part of the transaction history */
|
/** A transaction that is indexed as part of the transaction history */
|
||||||
@ -91,10 +92,9 @@ function uint64FromProto(input: number | Long | null | undefined): Uint64 {
|
|||||||
return Uint64.fromString(input.toString());
|
return Uint64.fromString(input.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function accountFromProto(input: BaseAccount): Account {
|
function accountFromBaseAccount(input: BaseAccount): Account {
|
||||||
const { address, pubKey, accountNumber, sequence } = input;
|
const { address, pubKey, accountNumber, sequence } = input;
|
||||||
const pubkey = decodePubkey(pubKey);
|
const pubkey = decodePubkey(pubKey);
|
||||||
assert(address);
|
|
||||||
return {
|
return {
|
||||||
address: address,
|
address: address,
|
||||||
pubkey: pubkey,
|
pubkey: pubkey,
|
||||||
@ -103,6 +103,24 @@ export function accountFromProto(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
|
||||||
|
* 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) {
|
||||||
|
case "/cosmos.auth.v1beta1.BaseAccount": {
|
||||||
|
return accountFromBaseAccount(BaseAccount.decode(value));
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new Error(`Unsupported type: '${typeUrl}'`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function coinFromProto(input: Coin): Coin {
|
export function coinFromProto(input: Coin): Coin {
|
||||||
assertDefinedAndNotNull(input.amount);
|
assertDefinedAndNotNull(input.amount);
|
||||||
assertDefinedAndNotNull(input.denom);
|
assertDefinedAndNotNull(input.denom);
|
||||||
@ -151,14 +169,14 @@ export class StargateClient {
|
|||||||
// this is nice to display data to the user, but is slower
|
// this is nice to display data to the user, but is slower
|
||||||
public async getAccount(searchAddress: string): Promise<Account | null> {
|
public async getAccount(searchAddress: string): Promise<Account | null> {
|
||||||
const account = await this.queryClient.auth.account(searchAddress);
|
const account = await this.queryClient.auth.account(searchAddress);
|
||||||
return account ? accountFromProto(account) : null;
|
return account ? accountFromAny(account) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we just need to get the sequence for signing a transaction, let's make this faster
|
// if we just need to get the sequence for signing a transaction, let's make this faster
|
||||||
// (no need to wait a block before submitting)
|
// (no need to wait a block before submitting)
|
||||||
public async getAccountUnverified(searchAddress: string): Promise<Account | null> {
|
public async getAccountUnverified(searchAddress: string): Promise<Account | null> {
|
||||||
const account = await this.queryClient.auth.unverified.account(searchAddress);
|
const account = await this.queryClient.auth.unverified.account(searchAddress);
|
||||||
return account ? accountFromProto(account) : null;
|
return account ? accountFromAny(account) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getSequence(address: string): Promise<SequenceResponse | null> {
|
public async getSequence(address: string): Promise<SequenceResponse | null> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user