diff --git a/packages/stargate/src/queries/ibc.spec.ts b/packages/stargate/src/queries/ibc.spec.ts new file mode 100644 index 00000000..8f397b13 --- /dev/null +++ b/packages/stargate/src/queries/ibc.spec.ts @@ -0,0 +1,117 @@ +import { Client as TendermintClient } from "@cosmjs/tendermint-rpc"; + +import { pendingWithoutSimapp, simapp } from "../testutils.spec"; +import { IbcExtension, setupIbcExtension } from "./ibc"; +import { QueryClient } from "./queryclient"; + +async function makeClientWithIbc(rpcUrl: string): Promise<[QueryClient & IbcExtension, TendermintClient]> { + const tmClient = await TendermintClient.connect(rpcUrl); + return [QueryClient.withExtensions(tmClient, setupIbcExtension), tmClient]; +} + +describe("IbcExtension", () => { + describe("unverified", () => { + describe("channel", () => { + 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.channel("foo", "bar"); + expect(response).toBeTruthy(); // TODO: implement checks + + tmClient.disconnect(); + }); + }); + + describe("channels", () => { + it("can be called", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.unverified.channels(); + expect(response).toBeTruthy(); // TODO: implement checks + + tmClient.disconnect(); + }); + }); + + describe("connectionChannels", () => { + 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.connectionChannels(); + expect(response).toBeTruthy(); // TODO: implement checks + + tmClient.disconnect(); + }); + }); + + describe("packetCommitment", () => { + 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.packetCommitment(); + expect(response).toBeTruthy(); // TODO: implement checks + + tmClient.disconnect(); + }); + }); + + describe("packetCommitments", () => { + 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.packetCommitments(); + expect(response).toBeTruthy(); // TODO: implement checks + + tmClient.disconnect(); + }); + }); + + describe("packetAcknowledgement", () => { + 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.packetAcknowledgement(); + expect(response).toBeTruthy(); // TODO: implement checks + + tmClient.disconnect(); + }); + }); + + describe("unrelayedPackets", () => { + 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(); + expect(response).toBeTruthy(); // TODO: implement checks + + tmClient.disconnect(); + }); + }); + + describe("nextSequenceReceive", () => { + 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.nextSequenceReceive(); + expect(response).toBeTruthy(); // TODO: implement checks + + tmClient.disconnect(); + }); + }); + }); +}); diff --git a/packages/stargate/src/queries/ibc.ts b/packages/stargate/src/queries/ibc.ts new file mode 100644 index 00000000..98378b94 --- /dev/null +++ b/packages/stargate/src/queries/ibc.ts @@ -0,0 +1,71 @@ +import { ibc } from "../codec"; +import { QueryClient } from "./queryclient"; +import { toObject } from "./utils"; + +export interface IbcExtension { + readonly ibc: { + readonly unverified: { + readonly channel: (portId: string, channelId: string) => Promise; + readonly channels: () => Promise; + readonly connectionChannels: () => Promise; + readonly packetCommitment: () => Promise; + readonly packetCommitments: () => Promise; + readonly packetAcknowledgement: () => Promise; + readonly unrelayedPackets: () => Promise; + readonly nextSequenceReceive: () => Promise; + }; + }; +} + +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) => { + // 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}`; + base + .queryUnverified(path, requestData) + .then((response) => callback(null, response)) + .catch((error) => callback(error)); + }); + + return { + ibc: { + unverified: { + channel: async (portId: string, channelId: string) => { + const response = await channelQuerySerice.channel({ portId: portId, channelId: channelId }); + return toObject(response); + }, + channels: async () => { + const response = await channelQuerySerice.channels({}); + return toObject(response); + }, + connectionChannels: async () => { + const response = await channelQuerySerice.connectionChannels({}); + return toObject(response); + }, + packetCommitment: async () => { + const response = await channelQuerySerice.packetCommitment({}); + return toObject(response); + }, + packetCommitments: async () => { + const response = await channelQuerySerice.packetCommitments({}); + return toObject(response); + }, + packetAcknowledgement: async () => { + const response = await channelQuerySerice.packetAcknowledgement({}); + return toObject(response); + }, + unrelayedPackets: async () => { + const response = await channelQuerySerice.unrelayedPackets({}); + return toObject(response); + }, + nextSequenceReceive: async () => { + const response = await channelQuerySerice.nextSequenceReceive({}); + return toObject(response); + }, + }, + }, + }; +} diff --git a/packages/stargate/src/queries/index.ts b/packages/stargate/src/queries/index.ts index afcfb022..40ab4c10 100644 --- a/packages/stargate/src/queries/index.ts +++ b/packages/stargate/src/queries/index.ts @@ -6,3 +6,4 @@ export { QueryClient } from "./queryclient"; export { AuthExtension, setupAuthExtension } from "./auth"; export { BankExtension, setupBankExtension } from "./bank"; +export { IbcExtension, setupIbcExtension } from "./ibc"; diff --git a/packages/stargate/types/queries/ibc.d.ts b/packages/stargate/types/queries/ibc.d.ts new file mode 100644 index 00000000..59d1c666 --- /dev/null +++ b/packages/stargate/types/queries/ibc.d.ts @@ -0,0 +1,17 @@ +import { ibc } from "../codec"; +import { QueryClient } from "./queryclient"; +export interface IbcExtension { + readonly ibc: { + readonly unverified: { + readonly channel: (portId: string, channelId: string) => Promise; + readonly channels: () => Promise; + readonly connectionChannels: () => Promise; + readonly packetCommitment: () => Promise; + readonly packetCommitments: () => Promise; + readonly packetAcknowledgement: () => Promise; + readonly unrelayedPackets: () => Promise; + readonly nextSequenceReceive: () => Promise; + }; + }; +} +export declare function setupIbcExtension(base: QueryClient): IbcExtension; diff --git a/packages/stargate/types/queries/index.d.ts b/packages/stargate/types/queries/index.d.ts index 3aacc3e3..2cc0699b 100644 --- a/packages/stargate/types/queries/index.d.ts +++ b/packages/stargate/types/queries/index.d.ts @@ -1,3 +1,4 @@ export { QueryClient } from "./queryclient"; export { AuthExtension, setupAuthExtension } from "./auth"; export { BankExtension, setupBankExtension } from "./bank"; +export { IbcExtension, setupIbcExtension } from "./ibc";