stargate: Update code for new codec
This commit is contained in:
parent
05bcfa2e90
commit
131974822a
@ -1,12 +1,16 @@
|
||||
import { encodeAminoPubkey } from "@cosmjs/launchpad";
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { fromBase64 } from "@cosmjs/encoding";
|
||||
import { Client as TendermintClient } from "@cosmjs/tendermint-rpc";
|
||||
import { assert } from "@cosmjs/utils";
|
||||
import Long from "long";
|
||||
|
||||
import { cosmos, google } from "../codec";
|
||||
import { nonExistentAddress, pendingWithoutSimapp, simapp, unused, validator } from "../testutils.spec";
|
||||
import { AuthExtension, setupAuthExtension } from "./auth";
|
||||
import { QueryClient } from "./queryclient";
|
||||
import { toAccAddress } from "./utils";
|
||||
|
||||
const { PubKey } = cosmos.crypto.secp256k1;
|
||||
const { Any } = google.protobuf;
|
||||
|
||||
async function makeClientWithAuth(rpcUrl: string): Promise<[QueryClient & AuthExtension, TendermintClient]> {
|
||||
const tmClient = await TendermintClient.connect(rpcUrl);
|
||||
@ -18,12 +22,11 @@ describe("AuthExtension", () => {
|
||||
it("works for unused account", async () => {
|
||||
pendingWithoutSimapp();
|
||||
const [client, tmClient] = await makeClientWithAuth(simapp.tendermintUrl);
|
||||
|
||||
const account = await client.auth.account(unused.address);
|
||||
assert(account);
|
||||
|
||||
expect(account).toEqual({
|
||||
address: toAccAddress(unused.address),
|
||||
address: unused.address,
|
||||
// pubKey not set
|
||||
accountNumber: Long.fromNumber(unused.accountNumber, true),
|
||||
// sequence not set
|
||||
@ -35,12 +38,19 @@ describe("AuthExtension", () => {
|
||||
it("works for account with pubkey and non-zero sequence", async () => {
|
||||
pendingWithoutSimapp();
|
||||
const [client, tmClient] = await makeClientWithAuth(simapp.tendermintUrl);
|
||||
|
||||
const account = await client.auth.account(validator.address);
|
||||
assert(account);
|
||||
|
||||
const pubkey = PubKey.create({
|
||||
key: fromBase64(validator.pubkey.value),
|
||||
});
|
||||
const pubkeyAny = Any.create({
|
||||
type_url: "/cosmos.crypto.secp256k1.PubKey",
|
||||
value: Uint8Array.from(PubKey.encode(pubkey).finish()),
|
||||
});
|
||||
expect(account).toEqual({
|
||||
address: toAccAddress(validator.address),
|
||||
pubKey: encodeAminoPubkey(validator.pubkey),
|
||||
address: validator.address,
|
||||
pubKey: pubkeyAny,
|
||||
// accountNumber not set
|
||||
sequence: Long.fromNumber(validator.sequence, true),
|
||||
});
|
||||
@ -51,8 +61,8 @@ describe("AuthExtension", () => {
|
||||
it("returns null for non-existent address", async () => {
|
||||
pendingWithoutSimapp();
|
||||
const [client, tmClient] = await makeClientWithAuth(simapp.tendermintUrl);
|
||||
|
||||
const account = await client.auth.account(nonExistentAddress);
|
||||
|
||||
expect(account).toBeNull();
|
||||
|
||||
tmClient.disconnect();
|
||||
@ -64,11 +74,11 @@ describe("AuthExtension", () => {
|
||||
it("works for unused account", async () => {
|
||||
pendingWithoutSimapp();
|
||||
const [client, tmClient] = await makeClientWithAuth(simapp.tendermintUrl);
|
||||
|
||||
const account = await client.auth.unverified.account(unused.address);
|
||||
assert(account);
|
||||
|
||||
expect(account).toEqual({
|
||||
address: toAccAddress(unused.address),
|
||||
address: unused.address,
|
||||
// pubKey not set
|
||||
accountNumber: Long.fromNumber(unused.accountNumber, true),
|
||||
// sequence not set
|
||||
@ -80,12 +90,19 @@ describe("AuthExtension", () => {
|
||||
it("works for account with pubkey and non-zero sequence", async () => {
|
||||
pendingWithoutSimapp();
|
||||
const [client, tmClient] = await makeClientWithAuth(simapp.tendermintUrl);
|
||||
|
||||
const account = await client.auth.unverified.account(validator.address);
|
||||
assert(account);
|
||||
|
||||
const pubkey = PubKey.create({
|
||||
key: fromBase64(validator.pubkey.value),
|
||||
});
|
||||
const pubkeyAny = Any.create({
|
||||
type_url: "/cosmos.crypto.secp256k1.PubKey",
|
||||
value: Uint8Array.from(PubKey.encode(pubkey).finish()),
|
||||
});
|
||||
expect(account).toEqual({
|
||||
address: toAccAddress(validator.address),
|
||||
pubKey: encodeAminoPubkey(validator.pubkey),
|
||||
address: validator.address,
|
||||
pubKey: pubkeyAny,
|
||||
// accountNumber not set
|
||||
sequence: Long.fromNumber(validator.sequence, true),
|
||||
});
|
||||
|
||||
@ -1,14 +1,17 @@
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { assert } from "@cosmjs/utils";
|
||||
|
||||
import { cosmos, google } from "../codec";
|
||||
import { QueryClient } from "./queryclient";
|
||||
import { toAccAddress, toObject } from "./utils";
|
||||
|
||||
const { BaseAccount, Query } = cosmos.auth.v1beta1;
|
||||
|
||||
export interface AuthExtension {
|
||||
readonly auth: {
|
||||
readonly account: (address: string) => Promise<cosmos.auth.IBaseAccount | null>;
|
||||
readonly account: (address: string) => Promise<cosmos.auth.v1beta1.IBaseAccount | null>;
|
||||
readonly unverified: {
|
||||
readonly account: (address: string) => Promise<cosmos.auth.IBaseAccount | null>;
|
||||
readonly account: (address: string) => Promise<cosmos.auth.v1beta1.IBaseAccount | null>;
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -16,9 +19,9 @@ export interface AuthExtension {
|
||||
export function setupAuthExtension(base: QueryClient): AuthExtension {
|
||||
// Use this service to get easy typed access to query methods
|
||||
// This cannot be used to for proof verification
|
||||
const queryService = cosmos.auth.Query.create((method: any, requestData, callback) => {
|
||||
const queryService = Query.create((method: any, requestData, callback) => {
|
||||
// Parts of the path are unavailable, so we hardcode them here. See https://github.com/protobufjs/protobuf.js/issues/1229
|
||||
const path = `/cosmos.auth.Query/${method.name}`;
|
||||
const path = `/cosmos.auth.v1beta1.Query/${method.name}`;
|
||||
base
|
||||
.queryUnverified(path, requestData)
|
||||
.then((response) => callback(null, response))
|
||||
@ -34,8 +37,8 @@ export function setupAuthExtension(base: QueryClient): AuthExtension {
|
||||
if (responseData.length === 0) return null;
|
||||
const account = google.protobuf.Any.decode(responseData);
|
||||
switch (account.type_url) {
|
||||
case "/cosmos.auth.BaseAccount": {
|
||||
return toObject(cosmos.auth.BaseAccount.decode(account.value));
|
||||
case "/cosmos.auth.v1beta1.BaseAccount": {
|
||||
return toObject(BaseAccount.decode(account.value));
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unsupported type: '${account.type_url}'`);
|
||||
@ -43,12 +46,12 @@ export function setupAuthExtension(base: QueryClient): AuthExtension {
|
||||
},
|
||||
unverified: {
|
||||
account: async (address: string) => {
|
||||
const { account } = await queryService.account({ address: toAccAddress(address) });
|
||||
const { account } = await queryService.account({ address: address });
|
||||
if (!account) return null;
|
||||
switch (account.type_url) {
|
||||
case "/cosmos.auth.BaseAccount": {
|
||||
case "/cosmos.auth.v1beta1.BaseAccount": {
|
||||
assert(account.value);
|
||||
return toObject(cosmos.auth.BaseAccount.decode(account.value));
|
||||
return toObject(BaseAccount.decode(account.value));
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unsupported type: '${account.type_url}'`);
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { toAscii } from "@cosmjs/encoding";
|
||||
import { assert } from "@cosmjs/utils";
|
||||
|
||||
@ -5,14 +6,17 @@ import { cosmos } from "../codec";
|
||||
import { QueryClient } from "./queryclient";
|
||||
import { toAccAddress, toObject } from "./utils";
|
||||
|
||||
const { Coin } = cosmos.base.v1beta1;
|
||||
const { Query } = cosmos.bank.v1beta1;
|
||||
|
||||
export interface BankExtension {
|
||||
readonly bank: {
|
||||
readonly balance: (address: string, denom: string) => Promise<cosmos.ICoin | null>;
|
||||
readonly balance: (address: string, denom: string) => Promise<cosmos.base.v1beta1.ICoin | null>;
|
||||
readonly unverified: {
|
||||
readonly balance: (address: string, denom: string) => Promise<cosmos.ICoin>;
|
||||
readonly allBalances: (address: string) => Promise<cosmos.ICoin[]>;
|
||||
readonly totalSupply: () => Promise<cosmos.ICoin[]>;
|
||||
readonly supplyOf: (denom: string) => Promise<cosmos.ICoin>;
|
||||
readonly balance: (address: string, denom: string) => Promise<cosmos.base.v1beta1.ICoin>;
|
||||
readonly allBalances: (address: string) => Promise<cosmos.base.v1beta1.ICoin[]>;
|
||||
readonly totalSupply: () => Promise<cosmos.base.v1beta1.ICoin[]>;
|
||||
readonly supplyOf: (denom: string) => Promise<cosmos.base.v1beta1.ICoin>;
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -20,9 +24,9 @@ export interface BankExtension {
|
||||
export function setupBankExtension(base: QueryClient): BankExtension {
|
||||
// Use this service to get easy typed access to query methods
|
||||
// This cannot be used to for proof verification
|
||||
const queryService = cosmos.bank.Query.create((method: any, requestData, callback) => {
|
||||
const queryService = Query.create((method: any, requestData, callback) => {
|
||||
// Parts of the path are unavailable, so we hardcode them here. See https://github.com/protobufjs/protobuf.js/issues/1229
|
||||
const path = `/cosmos.bank.Query/${method.name}`;
|
||||
const path = `/cosmos.bank.v1beta1.Query/${method.name}`;
|
||||
base
|
||||
.queryUnverified(path, requestData)
|
||||
.then((response) => callback(null, response))
|
||||
@ -40,16 +44,16 @@ export function setupBankExtension(base: QueryClient): BankExtension {
|
||||
// https://github.com/cosmos/cosmos-sdk/blob/2879c0702c87dc9dd828a8c42b9224dc054e28ad/store/prefix/store.go#L37-L43
|
||||
const key = Uint8Array.from([...toAscii("balances"), ...toAccAddress(address), ...toAscii(denom)]);
|
||||
const responseData = await base.queryVerified("bank", key);
|
||||
return responseData.length ? toObject(cosmos.Coin.decode(responseData)) : null;
|
||||
return responseData.length ? toObject(Coin.decode(responseData)) : null;
|
||||
},
|
||||
unverified: {
|
||||
balance: async (address: string, denom: string) => {
|
||||
const { balance } = await queryService.balance({ address: toAccAddress(address), denom: denom });
|
||||
const { balance } = await queryService.balance({ address: address, denom: denom });
|
||||
assert(balance);
|
||||
return toObject(balance);
|
||||
},
|
||||
allBalances: async (address: string) => {
|
||||
const { balances } = await queryService.allBalances({ address: toAccAddress(address) });
|
||||
const { balances } = await queryService.allBalances({ address: address });
|
||||
return balances.map(toObject);
|
||||
},
|
||||
totalSupply: async () => {
|
||||
|
||||
@ -88,13 +88,26 @@ describe("IbcExtension", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("unrelayedPackets", () => {
|
||||
describe("unreceivedPackets", () => {
|
||||
it("can be called", async () => {
|
||||
pending("Fails with 'Query failed with (1): internal'. Make it work.");
|
||||
pendingWithoutSimapp();
|
||||
const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl);
|
||||
|
||||
const response = await client.ibc.unverified.unrelayedPackets("foo", "bar", [0, 1], true);
|
||||
const response = await client.ibc.unverified.unreceivedPackets("foo", "bar", [0, 1]);
|
||||
expect(response).toBeTruthy(); // TODO: implement checks
|
||||
|
||||
tmClient.disconnect();
|
||||
});
|
||||
});
|
||||
|
||||
describe("unrelayedAcks", () => {
|
||||
it("can be called", async () => {
|
||||
pending("Fails with 'Query failed with (1): internal'. Make it work.");
|
||||
pendingWithoutSimapp();
|
||||
const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl);
|
||||
|
||||
const response = await client.ibc.unverified.unrelayedAcks("foo", "bar", [0, 1]);
|
||||
expect(response).toBeTruthy(); // TODO: implement checks
|
||||
|
||||
tmClient.disconnect();
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { toAscii } from "@cosmjs/encoding";
|
||||
import { Uint64 } from "@cosmjs/math";
|
||||
import Long from "long";
|
||||
@ -6,9 +7,12 @@ import { ibc } from "../codec";
|
||||
import { QueryClient } from "./queryclient";
|
||||
import { toObject } from "./utils";
|
||||
|
||||
const { Query: ChannelQuery } = ibc.core.channel.v1;
|
||||
const { Query: ConnectionQuery } = ibc.core.connection.v1;
|
||||
|
||||
export interface IbcExtension {
|
||||
readonly ibc: {
|
||||
readonly channel: (portId: string, channelId: string) => Promise<ibc.channel.IChannel | null>;
|
||||
readonly channel: (portId: string, channelId: string) => Promise<ibc.core.channel.v1.IChannel | null>;
|
||||
readonly packetCommitment: (portId: string, channelId: string, sequence: number) => Promise<Uint8Array>;
|
||||
readonly packetAcknowledgement: (
|
||||
portId: string,
|
||||
@ -17,44 +21,51 @@ export interface IbcExtension {
|
||||
) => Promise<Uint8Array>;
|
||||
readonly nextSequenceReceive: (portId: string, channelId: string) => Promise<number | null>;
|
||||
readonly unverified: {
|
||||
// Queries for ibc.channel
|
||||
readonly channel: (portId: string, channelId: string) => Promise<ibc.channel.IQueryChannelResponse>;
|
||||
readonly channels: () => Promise<ibc.channel.IQueryChannelsResponse>;
|
||||
// Queries for ibc.core.channel.v1
|
||||
readonly channel: (
|
||||
portId: string,
|
||||
channelId: string,
|
||||
) => Promise<ibc.core.channel.v1.IQueryChannelResponse>;
|
||||
readonly channels: () => Promise<ibc.core.channel.v1.IQueryChannelsResponse>;
|
||||
readonly connectionChannels: (
|
||||
connection: string,
|
||||
) => Promise<ibc.channel.IQueryConnectionChannelsResponse>;
|
||||
) => Promise<ibc.core.channel.v1.IQueryConnectionChannelsResponse>;
|
||||
readonly packetCommitment: (
|
||||
portId: string,
|
||||
channelId: string,
|
||||
sequence: number,
|
||||
) => Promise<ibc.channel.IQueryPacketCommitmentResponse>;
|
||||
) => Promise<ibc.core.channel.v1.IQueryPacketCommitmentResponse>;
|
||||
readonly packetCommitments: (
|
||||
portId: string,
|
||||
channelId: string,
|
||||
) => Promise<ibc.channel.IQueryPacketCommitmentsResponse>;
|
||||
) => Promise<ibc.core.channel.v1.IQueryPacketCommitmentsResponse>;
|
||||
readonly packetAcknowledgement: (
|
||||
portId: string,
|
||||
channelId: string,
|
||||
sequence: number,
|
||||
) => Promise<ibc.channel.IQueryPacketAcknowledgementResponse>;
|
||||
readonly unrelayedPackets: (
|
||||
) => Promise<ibc.core.channel.v1.IQueryPacketAcknowledgementResponse>;
|
||||
readonly unreceivedPackets: (
|
||||
portId: string,
|
||||
channelId: string,
|
||||
packetCommitmentSequences: readonly number[],
|
||||
acknowledgements: boolean,
|
||||
) => Promise<ibc.channel.IQueryUnrelayedPacketsResponse>;
|
||||
) => Promise<ibc.core.channel.v1.IQueryUnreceivedPacketsResponse>;
|
||||
readonly unrelayedAcks: (
|
||||
portId: string,
|
||||
channelId: string,
|
||||
packetCommitmentSequences: readonly number[],
|
||||
) => Promise<ibc.core.channel.v1.IQueryUnrelayedAcksResponse>;
|
||||
readonly nextSequenceReceive: (
|
||||
portId: string,
|
||||
channelId: string,
|
||||
) => Promise<ibc.channel.IQueryNextSequenceReceiveResponse>;
|
||||
) => Promise<ibc.core.channel.v1.IQueryNextSequenceReceiveResponse>;
|
||||
|
||||
// Queries for ibc.connection
|
||||
// Queries for ibc.core.connection.v1
|
||||
|
||||
readonly connection: (connectionId: string) => Promise<ibc.connection.IQueryConnectionResponse>;
|
||||
readonly connections: () => Promise<ibc.connection.IQueryConnectionsResponse>;
|
||||
readonly connection: (connectionId: string) => Promise<ibc.core.connection.v1.IQueryConnectionResponse>;
|
||||
readonly connections: () => Promise<ibc.core.connection.v1.IQueryConnectionsResponse>;
|
||||
readonly clientConnections: (
|
||||
clientId: string,
|
||||
) => Promise<ibc.connection.IQueryClientConnectionsResponse>;
|
||||
) => Promise<ibc.core.connection.v1.IQueryClientConnectionsResponse>;
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -63,18 +74,18 @@ export function setupIbcExtension(base: QueryClient): IbcExtension {
|
||||
// Use this service to get easy typed access to query methods
|
||||
// This cannot be used to for proof verification
|
||||
|
||||
const channelQuerySerice = ibc.channel.Query.create((method: any, requestData, callback) => {
|
||||
const channelQuerySerice = ChannelQuery.create((method: any, requestData, callback) => {
|
||||
// Parts of the path are unavailable, so we hardcode them here. See https://github.com/protobufjs/protobuf.js/issues/1229
|
||||
const path = `/ibc.channel.Query/${method.name}`;
|
||||
const path = `/ibc.core.channel.v1.Query/${method.name}`;
|
||||
base
|
||||
.queryUnverified(path, requestData)
|
||||
.then((response) => callback(null, response))
|
||||
.catch((error) => callback(error));
|
||||
});
|
||||
|
||||
const connectionQuerySerice = ibc.connection.Query.create((method: any, requestData, callback) => {
|
||||
const connectionQuerySerice = ConnectionQuery.create((method: any, requestData, callback) => {
|
||||
// Parts of the path are unavailable, so we hardcode them here. See https://github.com/protobufjs/protobuf.js/issues/1229
|
||||
const path = `/ibc.connection.Query/${method.name}`;
|
||||
const path = `/ibc.core.connection.v1.Query/${method.name}`;
|
||||
base
|
||||
.queryUnverified(path, requestData)
|
||||
.then((response) => callback(null, response))
|
||||
@ -88,7 +99,7 @@ export function setupIbcExtension(base: QueryClient): IbcExtension {
|
||||
// key: https://github.com/cosmos/cosmos-sdk/blob/ef0a7344af345882729598bc2958a21143930a6b/x/ibc/24-host/keys.go#L117-L120
|
||||
const key = toAscii(`channelEnds/ports/${portId}/channels/${channelId}`);
|
||||
const responseData = await base.queryVerified("ibc", key);
|
||||
return responseData.length ? toObject(ibc.channel.Channel.decode(responseData)) : null;
|
||||
return responseData.length ? toObject(ibc.core.channel.v1.Channel.decode(responseData)) : null;
|
||||
},
|
||||
packetCommitment: async (portId: string, channelId: string, sequence: number) => {
|
||||
// keeper: https://github.com/cosmos/cosmos-sdk/blob/3bafd8255a502e5a9cee07391cf8261538245dfd/x/ibc/04-channel/keeper/keeper.go#L128-L133
|
||||
@ -115,7 +126,7 @@ export function setupIbcExtension(base: QueryClient): IbcExtension {
|
||||
},
|
||||
|
||||
unverified: {
|
||||
// Queries for ibc.channel
|
||||
// Queries for ibc.core.channel.v1
|
||||
channel: async (portId: string, channelId: string) => {
|
||||
const response = await channelQuerySerice.channel({ portId: portId, channelId: channelId });
|
||||
return toObject(response);
|
||||
@ -151,17 +162,27 @@ export function setupIbcExtension(base: QueryClient): IbcExtension {
|
||||
});
|
||||
return toObject(response);
|
||||
},
|
||||
unrelayedPackets: async (
|
||||
unreceivedPackets: async (
|
||||
portId: string,
|
||||
channelId: string,
|
||||
packetCommitmentSequences: readonly number[],
|
||||
acknowledgements: boolean,
|
||||
) => {
|
||||
const response = await channelQuerySerice.unrelayedPackets({
|
||||
const response = await channelQuerySerice.unreceivedPackets({
|
||||
portId: portId,
|
||||
channelId: channelId,
|
||||
packetCommitmentSequences: packetCommitmentSequences.map((s) => Long.fromNumber(s)),
|
||||
});
|
||||
return toObject(response);
|
||||
},
|
||||
unrelayedAcks: async (
|
||||
portId: string,
|
||||
channelId: string,
|
||||
packetCommitmentSequences: readonly number[],
|
||||
) => {
|
||||
const response = await channelQuerySerice.unrelayedAcks({
|
||||
portId: portId,
|
||||
channelId: channelId,
|
||||
packetCommitmentSequences: packetCommitmentSequences.map((s) => Long.fromNumber(s)),
|
||||
acknowledgements: acknowledgements,
|
||||
});
|
||||
return toObject(response);
|
||||
},
|
||||
@ -173,7 +194,7 @@ export function setupIbcExtension(base: QueryClient): IbcExtension {
|
||||
return toObject(response);
|
||||
},
|
||||
|
||||
// Queries for ibc.connection
|
||||
// Queries for ibc.core.connection.v1
|
||||
|
||||
connection: async (connectionId: string) => {
|
||||
const response = await connectionQuerySerice.connection({ connectionId: connectionId });
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { toAscii } from "@cosmjs/encoding";
|
||||
import { Client as TendermintClient } from "@cosmjs/tendermint-rpc";
|
||||
|
||||
@ -6,6 +7,9 @@ import { nonNegativeIntegerMatcher, pendingWithoutSimapp, simapp, unused } from
|
||||
import { QueryClient } from "./queryclient";
|
||||
import { toAccAddress } from "./utils";
|
||||
|
||||
const { Coin } = cosmos.base.v1beta1;
|
||||
const { QueryAllBalancesRequest, QueryAllBalancesResponse } = cosmos.bank.v1beta1;
|
||||
|
||||
async function makeClient(rpcUrl: string): Promise<[QueryClient, TendermintClient]> {
|
||||
const tmClient = await TendermintClient.connect(rpcUrl);
|
||||
return [QueryClient.withExtensions(tmClient), tmClient];
|
||||
@ -23,7 +27,7 @@ describe("QueryClient", () => {
|
||||
...toAscii(simapp.denomFee),
|
||||
]);
|
||||
const data = await client.queryVerified("bank", key);
|
||||
const response = cosmos.Coin.decode(data);
|
||||
const response = Coin.decode(data);
|
||||
expect(response.amount).toMatch(nonNegativeIntegerMatcher);
|
||||
expect(response.denom).toEqual(simapp.denomFee);
|
||||
|
||||
@ -40,7 +44,7 @@ describe("QueryClient", () => {
|
||||
...toAscii(simapp.denomFee),
|
||||
]);
|
||||
const data = await client.queryVerified("bank", key);
|
||||
const response = cosmos.Coin.decode(data);
|
||||
const response = Coin.decode(data);
|
||||
expect(response.amount).toMatch(nonNegativeIntegerMatcher);
|
||||
expect(response.denom).toEqual(simapp.denomFee);
|
||||
|
||||
@ -54,10 +58,10 @@ describe("QueryClient", () => {
|
||||
const [client, tmClient] = await makeClient(simapp.tendermintUrlWs);
|
||||
|
||||
const requestData = Uint8Array.from(
|
||||
cosmos.bank.QueryAllBalancesRequest.encode({ address: toAccAddress(unused.address) }).finish(),
|
||||
QueryAllBalancesRequest.encode({ address: unused.address }).finish(),
|
||||
);
|
||||
const data = await client.queryUnverified(`/cosmos.bank.Query/AllBalances`, requestData);
|
||||
const response = cosmos.bank.QueryAllBalancesResponse.decode(data);
|
||||
const data = await client.queryUnverified(`/cosmos.bank.v1beta1.Query/AllBalances`, requestData);
|
||||
const response = QueryAllBalancesResponse.decode(data);
|
||||
expect(response.balances.length).toEqual(2);
|
||||
|
||||
tmClient.disconnect();
|
||||
@ -68,10 +72,10 @@ describe("QueryClient", () => {
|
||||
const [client, tmClient] = await makeClient(simapp.tendermintUrlHttp);
|
||||
|
||||
const requestData = Uint8Array.from(
|
||||
cosmos.bank.QueryAllBalancesRequest.encode({ address: toAccAddress(unused.address) }).finish(),
|
||||
QueryAllBalancesRequest.encode({ address: unused.address }).finish(),
|
||||
);
|
||||
const data = await client.queryUnverified(`/cosmos.bank.Query/AllBalances`, requestData);
|
||||
const response = cosmos.bank.QueryAllBalancesResponse.decode(data);
|
||||
const data = await client.queryUnverified(`/cosmos.bank.v1beta1.Query/AllBalances`, requestData);
|
||||
const response = QueryAllBalancesResponse.decode(data);
|
||||
expect(response.balances.length).toEqual(2);
|
||||
|
||||
tmClient.disconnect();
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { Bech32, fromBase64 } from "@cosmjs/encoding";
|
||||
import { fromBase64 } from "@cosmjs/encoding";
|
||||
import { Coin, coins } from "@cosmjs/launchpad";
|
||||
import { DirectSecp256k1Wallet, makeAuthInfo, makeSignBytes, Registry } from "@cosmjs/proto-signing";
|
||||
import { assert, sleep } from "@cosmjs/utils";
|
||||
|
||||
import { cosmos } from "./codec";
|
||||
import { cosmos, google } from "./codec";
|
||||
import {
|
||||
BroadcastTxResponse,
|
||||
isBroadcastTxFailure,
|
||||
@ -13,8 +13,9 @@ import {
|
||||
} from "./stargateclient";
|
||||
import { faucet, makeRandomAddress, pendingWithoutSimapp, simapp, simappEnabled } from "./testutils.spec";
|
||||
|
||||
const { AuthInfo, Tx, TxBody } = cosmos.tx;
|
||||
const { PublicKey } = cosmos.crypto;
|
||||
const { TxRaw } = cosmos.tx.v1beta1;
|
||||
const { PubKey } = cosmos.crypto.secp256k1;
|
||||
const { Any } = google.protobuf;
|
||||
|
||||
interface TestTxSend {
|
||||
readonly sender: string;
|
||||
@ -36,16 +37,20 @@ async function sendTokens(
|
||||
readonly tx: Uint8Array;
|
||||
}> {
|
||||
const [{ address: walletAddress, pubkey: pubkeyBytes }] = await wallet.getAccounts();
|
||||
const publicKey = PublicKey.create({ secp256k1: pubkeyBytes });
|
||||
const pubkey = PubKey.create({ key: pubkeyBytes });
|
||||
const pubkeyAny = Any.create({
|
||||
type_url: "/cosmos.crypto.secp256k1.PubKey",
|
||||
value: PubKey.encode(pubkey).finish(),
|
||||
});
|
||||
const txBodyFields = {
|
||||
typeUrl: "/cosmos.tx.TxBody",
|
||||
typeUrl: "/cosmos.tx.v1beta1.TxBody",
|
||||
value: {
|
||||
messages: [
|
||||
{
|
||||
typeUrl: "/cosmos.bank.MsgSend",
|
||||
typeUrl: "/cosmos.bank.v1beta1.MsgSend",
|
||||
value: {
|
||||
fromAddress: Bech32.decode(walletAddress).data,
|
||||
toAddress: Bech32.decode(recipient).data,
|
||||
fromAddress: walletAddress,
|
||||
toAddress: recipient,
|
||||
amount: amount,
|
||||
},
|
||||
},
|
||||
@ -54,20 +59,25 @@ async function sendTokens(
|
||||
},
|
||||
};
|
||||
const txBodyBytes = registry.encode(txBodyFields);
|
||||
const txBody = TxBody.decode(txBodyBytes);
|
||||
const authInfoBytes = makeAuthInfo([publicKey], 200000);
|
||||
|
||||
const { accountNumber, sequence } = (await client.getSequence(walletAddress))!;
|
||||
const feeAmount = [
|
||||
{
|
||||
amount: "2000",
|
||||
denom: "ucosm",
|
||||
},
|
||||
];
|
||||
const gasLimit = 200000;
|
||||
const authInfoBytes = makeAuthInfo([pubkeyAny], feeAmount, gasLimit, sequence);
|
||||
|
||||
const chainId = await client.getChainId();
|
||||
const signDocBytes = makeSignBytes(txBodyBytes, authInfoBytes, chainId, accountNumber, sequence);
|
||||
const signDocBytes = makeSignBytes(txBodyBytes, authInfoBytes, chainId, accountNumber);
|
||||
const signature = await wallet.sign(walletAddress, signDocBytes);
|
||||
// TODO: Why is this not a TxRaw? https://github.com/CosmWasm/cosmjs/issues/383
|
||||
const txRaw = Tx.create({
|
||||
body: txBody,
|
||||
authInfo: AuthInfo.decode(authInfoBytes),
|
||||
const txRaw = TxRaw.create({
|
||||
bodyBytes: txBodyBytes,
|
||||
authInfoBytes: authInfoBytes,
|
||||
signatures: [fromBase64(signature.signature)],
|
||||
});
|
||||
const txRawBytes = Uint8Array.from(Tx.encode(txRaw).finish());
|
||||
const txRawBytes = Uint8Array.from(TxRaw.encode(txRaw).finish());
|
||||
const broadcastResponse = await client.broadcastTx(txRawBytes);
|
||||
return {
|
||||
broadcastResponse: broadcastResponse,
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { Bech32, fromBase64 } from "@cosmjs/encoding";
|
||||
import { fromBase64 } from "@cosmjs/encoding";
|
||||
import { DirectSecp256k1Wallet, makeAuthInfo, makeSignBytes, Registry } from "@cosmjs/proto-signing";
|
||||
import { assert, sleep } from "@cosmjs/utils";
|
||||
import { ReadonlyDate } from "readonly-date";
|
||||
|
||||
import { cosmos } from "./codec";
|
||||
import { cosmos, google } from "./codec";
|
||||
import { assertIsBroadcastTxSuccess, PrivateStargateClient, StargateClient } from "./stargateclient";
|
||||
import {
|
||||
faucet,
|
||||
makeRandomAddressBytes,
|
||||
makeRandomAddress,
|
||||
nonExistentAddress,
|
||||
pendingWithoutSimapp,
|
||||
simapp,
|
||||
@ -17,8 +17,9 @@ import {
|
||||
validator,
|
||||
} from "./testutils.spec";
|
||||
|
||||
const { AuthInfo, Tx, TxBody } = cosmos.tx;
|
||||
const { PublicKey } = cosmos.crypto;
|
||||
const { TxRaw } = cosmos.tx.v1beta1;
|
||||
const { PubKey } = cosmos.crypto.secp256k1;
|
||||
const { Any } = google.protobuf;
|
||||
|
||||
describe("StargateClient", () => {
|
||||
describe("connect", () => {
|
||||
@ -253,17 +254,21 @@ describe("StargateClient", () => {
|
||||
const client = await StargateClient.connect(simapp.tendermintUrl);
|
||||
const wallet = await DirectSecp256k1Wallet.fromMnemonic(faucet.mnemonic);
|
||||
const [{ address, pubkey: pubkeyBytes }] = await wallet.getAccounts();
|
||||
const publicKey = PublicKey.create({ secp256k1: pubkeyBytes });
|
||||
const pubkey = PubKey.create({ key: pubkeyBytes });
|
||||
const pubkeyAny = Any.create({
|
||||
type_url: "/cosmos.crypto.secp256k1.PubKey",
|
||||
value: PubKey.encode(pubkey).finish(),
|
||||
});
|
||||
const registry = new Registry();
|
||||
const txBodyFields = {
|
||||
typeUrl: "/cosmos.tx.TxBody",
|
||||
typeUrl: "/cosmos.tx.v1beta1.TxBody",
|
||||
value: {
|
||||
messages: [
|
||||
{
|
||||
typeUrl: "/cosmos.bank.MsgSend",
|
||||
typeUrl: "/cosmos.bank.v1beta1.MsgSend",
|
||||
value: {
|
||||
fromAddress: Bech32.decode(address).data,
|
||||
toAddress: makeRandomAddressBytes(),
|
||||
fromAddress: address,
|
||||
toAddress: makeRandomAddress(),
|
||||
amount: [
|
||||
{
|
||||
denom: "ucosm",
|
||||
@ -276,20 +281,25 @@ describe("StargateClient", () => {
|
||||
},
|
||||
};
|
||||
const txBodyBytes = registry.encode(txBodyFields);
|
||||
const txBody = TxBody.decode(txBodyBytes);
|
||||
const authInfoBytes = makeAuthInfo([publicKey], 200000);
|
||||
const { accountNumber, sequence } = (await client.getSequence(address))!;
|
||||
const feeAmount = [
|
||||
{
|
||||
amount: "2000",
|
||||
denom: "ucosm",
|
||||
},
|
||||
];
|
||||
const gasLimit = 200000;
|
||||
const authInfoBytes = makeAuthInfo([pubkeyAny], feeAmount, gasLimit, sequence);
|
||||
|
||||
const chainId = await client.getChainId();
|
||||
const { accountNumber, sequence } = (await client.getSequence(address))!;
|
||||
const signDocBytes = makeSignBytes(txBodyBytes, authInfoBytes, chainId, accountNumber, sequence);
|
||||
const signDocBytes = makeSignBytes(txBodyBytes, authInfoBytes, chainId, accountNumber);
|
||||
const signature = await wallet.sign(address, signDocBytes);
|
||||
// TODO: Why is this not a TxRaw? https://github.com/CosmWasm/cosmjs/issues/383
|
||||
const txRaw = Tx.create({
|
||||
body: txBody,
|
||||
authInfo: AuthInfo.decode(authInfoBytes),
|
||||
const txRaw = TxRaw.create({
|
||||
bodyBytes: txBodyBytes,
|
||||
authInfoBytes: authInfoBytes,
|
||||
signatures: [fromBase64(signature.signature)],
|
||||
});
|
||||
const txRawBytes = Uint8Array.from(Tx.encode(txRaw).finish());
|
||||
const txRawBytes = Uint8Array.from(TxRaw.encode(txRaw).finish());
|
||||
const txResult = await client.broadcastTx(txRawBytes);
|
||||
assertIsBroadcastTxSuccess(txResult);
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { Bech32, toHex } from "@cosmjs/encoding";
|
||||
import { toHex } from "@cosmjs/encoding";
|
||||
import {
|
||||
Block,
|
||||
Coin,
|
||||
decodeAminoPubkey,
|
||||
encodeSecp256k1Pubkey,
|
||||
isSearchByHeightQuery,
|
||||
isSearchByIdQuery,
|
||||
PubKey,
|
||||
@ -15,7 +15,7 @@ import { broadcastTxCommitSuccess, Client as TendermintClient, QueryString } fro
|
||||
import { assert, assertDefined } from "@cosmjs/utils";
|
||||
import Long from "long";
|
||||
|
||||
import { cosmos } from "./codec";
|
||||
import { cosmos, google } from "./codec";
|
||||
import { AuthExtension, BankExtension, QueryClient, setupAuthExtension, setupBankExtension } from "./queries";
|
||||
|
||||
/** A transaction that is indexed as part of the transaction history */
|
||||
@ -85,20 +85,34 @@ function uint64FromProto(input: number | Long | null | undefined): Uint64 {
|
||||
return Uint64.fromString(input.toString());
|
||||
}
|
||||
|
||||
function accountFromProto(input: cosmos.auth.IBaseAccount, prefix: string): Account {
|
||||
function decodePubkey(pubkey?: google.protobuf.IAny | null): PubKey | null {
|
||||
if (!pubkey || !pubkey.value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (pubkey.type_url) {
|
||||
case "/cosmos.crypto.secp256k1.PubKey": {
|
||||
const { key } = cosmos.crypto.secp256k1.PubKey.decode(pubkey.value);
|
||||
return encodeSecp256k1Pubkey(key);
|
||||
}
|
||||
default:
|
||||
throw new Error("Unknown pubkey type");
|
||||
}
|
||||
}
|
||||
|
||||
function accountFromProto(input: cosmos.auth.v1beta1.IBaseAccount): Account {
|
||||
const { address, pubKey, accountNumber, sequence } = input;
|
||||
// Pubkey is still Amino-encoded in BaseAccount (https://github.com/cosmos/cosmos-sdk/issues/6886)
|
||||
const pubkey = pubKey && pubKey.length ? decodeAminoPubkey(pubKey) : null;
|
||||
const pubkey = decodePubkey(pubKey);
|
||||
assert(address);
|
||||
return {
|
||||
address: Bech32.encode(prefix, address),
|
||||
address: address,
|
||||
pubkey: pubkey,
|
||||
accountNumber: uint64FromProto(accountNumber).toNumber(),
|
||||
sequence: uint64FromProto(sequence).toNumber(),
|
||||
};
|
||||
}
|
||||
|
||||
function coinFromProto(input: cosmos.ICoin): Coin {
|
||||
function coinFromProto(input: cosmos.base.v1beta1.ICoin): Coin {
|
||||
assertDefined(input.amount);
|
||||
assertDefined(input.denom);
|
||||
assert(input.amount !== null);
|
||||
@ -146,10 +160,8 @@ export class StargateClient {
|
||||
}
|
||||
|
||||
public async getAccount(searchAddress: string): Promise<Account | null> {
|
||||
const { prefix } = Bech32.decode(searchAddress);
|
||||
|
||||
const account = await this.queryClient.auth.account(searchAddress);
|
||||
return account ? accountFromProto(account, prefix) : null;
|
||||
return account ? accountFromProto(account) : null;
|
||||
}
|
||||
|
||||
public async getSequence(address: string): Promise<SequenceResponse | null> {
|
||||
|
||||
4
packages/stargate/types/queries/auth.d.ts
vendored
4
packages/stargate/types/queries/auth.d.ts
vendored
@ -2,9 +2,9 @@ import { cosmos } from "../codec";
|
||||
import { QueryClient } from "./queryclient";
|
||||
export interface AuthExtension {
|
||||
readonly auth: {
|
||||
readonly account: (address: string) => Promise<cosmos.auth.IBaseAccount | null>;
|
||||
readonly account: (address: string) => Promise<cosmos.auth.v1beta1.IBaseAccount | null>;
|
||||
readonly unverified: {
|
||||
readonly account: (address: string) => Promise<cosmos.auth.IBaseAccount | null>;
|
||||
readonly account: (address: string) => Promise<cosmos.auth.v1beta1.IBaseAccount | null>;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
10
packages/stargate/types/queries/bank.d.ts
vendored
10
packages/stargate/types/queries/bank.d.ts
vendored
@ -2,12 +2,12 @@ import { cosmos } from "../codec";
|
||||
import { QueryClient } from "./queryclient";
|
||||
export interface BankExtension {
|
||||
readonly bank: {
|
||||
readonly balance: (address: string, denom: string) => Promise<cosmos.ICoin | null>;
|
||||
readonly balance: (address: string, denom: string) => Promise<cosmos.base.v1beta1.ICoin | null>;
|
||||
readonly unverified: {
|
||||
readonly balance: (address: string, denom: string) => Promise<cosmos.ICoin>;
|
||||
readonly allBalances: (address: string) => Promise<cosmos.ICoin[]>;
|
||||
readonly totalSupply: () => Promise<cosmos.ICoin[]>;
|
||||
readonly supplyOf: (denom: string) => Promise<cosmos.ICoin>;
|
||||
readonly balance: (address: string, denom: string) => Promise<cosmos.base.v1beta1.ICoin>;
|
||||
readonly allBalances: (address: string) => Promise<cosmos.base.v1beta1.ICoin[]>;
|
||||
readonly totalSupply: () => Promise<cosmos.base.v1beta1.ICoin[]>;
|
||||
readonly supplyOf: (denom: string) => Promise<cosmos.base.v1beta1.ICoin>;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
35
packages/stargate/types/queries/ibc.d.ts
vendored
35
packages/stargate/types/queries/ibc.d.ts
vendored
@ -2,7 +2,7 @@ import { ibc } from "../codec";
|
||||
import { QueryClient } from "./queryclient";
|
||||
export interface IbcExtension {
|
||||
readonly ibc: {
|
||||
readonly channel: (portId: string, channelId: string) => Promise<ibc.channel.IChannel | null>;
|
||||
readonly channel: (portId: string, channelId: string) => Promise<ibc.core.channel.v1.IChannel | null>;
|
||||
readonly packetCommitment: (portId: string, channelId: string, sequence: number) => Promise<Uint8Array>;
|
||||
readonly packetAcknowledgement: (
|
||||
portId: string,
|
||||
@ -11,40 +11,47 @@ export interface IbcExtension {
|
||||
) => Promise<Uint8Array>;
|
||||
readonly nextSequenceReceive: (portId: string, channelId: string) => Promise<number | null>;
|
||||
readonly unverified: {
|
||||
readonly channel: (portId: string, channelId: string) => Promise<ibc.channel.IQueryChannelResponse>;
|
||||
readonly channels: () => Promise<ibc.channel.IQueryChannelsResponse>;
|
||||
readonly channel: (
|
||||
portId: string,
|
||||
channelId: string,
|
||||
) => Promise<ibc.core.channel.v1.IQueryChannelResponse>;
|
||||
readonly channels: () => Promise<ibc.core.channel.v1.IQueryChannelsResponse>;
|
||||
readonly connectionChannels: (
|
||||
connection: string,
|
||||
) => Promise<ibc.channel.IQueryConnectionChannelsResponse>;
|
||||
) => Promise<ibc.core.channel.v1.IQueryConnectionChannelsResponse>;
|
||||
readonly packetCommitment: (
|
||||
portId: string,
|
||||
channelId: string,
|
||||
sequence: number,
|
||||
) => Promise<ibc.channel.IQueryPacketCommitmentResponse>;
|
||||
) => Promise<ibc.core.channel.v1.IQueryPacketCommitmentResponse>;
|
||||
readonly packetCommitments: (
|
||||
portId: string,
|
||||
channelId: string,
|
||||
) => Promise<ibc.channel.IQueryPacketCommitmentsResponse>;
|
||||
) => Promise<ibc.core.channel.v1.IQueryPacketCommitmentsResponse>;
|
||||
readonly packetAcknowledgement: (
|
||||
portId: string,
|
||||
channelId: string,
|
||||
sequence: number,
|
||||
) => Promise<ibc.channel.IQueryPacketAcknowledgementResponse>;
|
||||
readonly unrelayedPackets: (
|
||||
) => Promise<ibc.core.channel.v1.IQueryPacketAcknowledgementResponse>;
|
||||
readonly unreceivedPackets: (
|
||||
portId: string,
|
||||
channelId: string,
|
||||
packetCommitmentSequences: readonly number[],
|
||||
acknowledgements: boolean,
|
||||
) => Promise<ibc.channel.IQueryUnrelayedPacketsResponse>;
|
||||
) => Promise<ibc.core.channel.v1.IQueryUnreceivedPacketsResponse>;
|
||||
readonly unrelayedAcks: (
|
||||
portId: string,
|
||||
channelId: string,
|
||||
packetCommitmentSequences: readonly number[],
|
||||
) => Promise<ibc.core.channel.v1.IQueryUnrelayedAcksResponse>;
|
||||
readonly nextSequenceReceive: (
|
||||
portId: string,
|
||||
channelId: string,
|
||||
) => Promise<ibc.channel.IQueryNextSequenceReceiveResponse>;
|
||||
readonly connection: (connectionId: string) => Promise<ibc.connection.IQueryConnectionResponse>;
|
||||
readonly connections: () => Promise<ibc.connection.IQueryConnectionsResponse>;
|
||||
) => Promise<ibc.core.channel.v1.IQueryNextSequenceReceiveResponse>;
|
||||
readonly connection: (connectionId: string) => Promise<ibc.core.connection.v1.IQueryConnectionResponse>;
|
||||
readonly connections: () => Promise<ibc.core.connection.v1.IQueryConnectionsResponse>;
|
||||
readonly clientConnections: (
|
||||
clientId: string,
|
||||
) => Promise<ibc.connection.IQueryClientConnectionsResponse>;
|
||||
) => Promise<ibc.core.connection.v1.IQueryClientConnectionsResponse>;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user