Simplify searchTx
This commit is contained in:
parent
d0071697bb
commit
eb52e93fd4
@ -196,12 +196,12 @@ describe("CosmWasmClient.getTx and .searchTx", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("with SearchByHeightQuery", () => {
|
||||
describe("searchTx", () => {
|
||||
it("can search successful tx by height", async () => {
|
||||
pendingWithoutWasmd();
|
||||
assert(sendSuccessful, "value must be set in beforeAll()");
|
||||
const client = await CosmWasmClient.connect(wasmd.endpoint);
|
||||
const result = await client.searchTx({ height: sendSuccessful.height });
|
||||
const result = await client.searchTx(`tx.height=${sendSuccessful.height}`);
|
||||
expect(result.length).toBeGreaterThanOrEqual(1);
|
||||
expect(result).toContain(
|
||||
jasmine.objectContaining({
|
||||
@ -218,7 +218,7 @@ describe("CosmWasmClient.getTx and .searchTx", () => {
|
||||
pendingWithoutWasmd();
|
||||
assert(sendUnsuccessful, "value must be set in beforeAll()");
|
||||
const client = await CosmWasmClient.connect(wasmd.endpoint);
|
||||
const result = await client.searchTx({ height: sendUnsuccessful.height });
|
||||
const result = await client.searchTx(`tx.height=${sendUnsuccessful.height}`);
|
||||
expect(result.length).toBeGreaterThanOrEqual(1);
|
||||
expect(result).toContain(
|
||||
jasmine.objectContaining({
|
||||
@ -230,14 +230,14 @@ describe("CosmWasmClient.getTx and .searchTx", () => {
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("with SearchBySentFromOrToQuery", () => {
|
||||
it("can search by sender", async () => {
|
||||
pendingWithoutWasmd();
|
||||
assert(sendSuccessful, "value must be set in beforeAll()");
|
||||
const client = await CosmWasmClient.connect(wasmd.endpoint);
|
||||
const results = await client.searchTx({ sentFromOrTo: sendSuccessful.sender });
|
||||
const results = await client.searchTx(
|
||||
`message.module='bank' AND transfer.sender='${sendSuccessful.sender}'`,
|
||||
);
|
||||
expect(results.length).toBeGreaterThanOrEqual(1);
|
||||
|
||||
// Check basic structure of all results
|
||||
@ -266,7 +266,9 @@ describe("CosmWasmClient.getTx and .searchTx", () => {
|
||||
pendingWithoutWasmd();
|
||||
assert(sendSuccessful, "value must be set in beforeAll()");
|
||||
const client = await CosmWasmClient.connect(wasmd.endpoint);
|
||||
const results = await client.searchTx({ sentFromOrTo: sendSuccessful.recipient });
|
||||
const results = await client.searchTx(
|
||||
`message.module='bank' AND transfer.recipient='${sendSuccessful.recipient}'`,
|
||||
);
|
||||
expect(results.length).toBeGreaterThanOrEqual(1);
|
||||
|
||||
// Check basic structure of all results
|
||||
@ -290,69 +292,11 @@ describe("CosmWasmClient.getTx and .searchTx", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("can search by recipient and filter by minHeight", async () => {
|
||||
pendingWithoutWasmd();
|
||||
assert(sendSuccessful);
|
||||
const client = await CosmWasmClient.connect(wasmd.endpoint);
|
||||
const query = { sentFromOrTo: sendSuccessful.recipient };
|
||||
|
||||
{
|
||||
const result = await client.searchTx(query, { minHeight: 0 });
|
||||
expect(result.length).toEqual(1);
|
||||
}
|
||||
|
||||
{
|
||||
const result = await client.searchTx(query, { minHeight: sendSuccessful.height - 1 });
|
||||
expect(result.length).toEqual(1);
|
||||
}
|
||||
|
||||
{
|
||||
const result = await client.searchTx(query, { minHeight: sendSuccessful.height });
|
||||
expect(result.length).toEqual(1);
|
||||
}
|
||||
|
||||
{
|
||||
const result = await client.searchTx(query, { minHeight: sendSuccessful.height + 1 });
|
||||
expect(result.length).toEqual(0);
|
||||
}
|
||||
});
|
||||
|
||||
it("can search by recipient and filter by maxHeight", async () => {
|
||||
pendingWithoutWasmd();
|
||||
assert(sendSuccessful);
|
||||
const client = await CosmWasmClient.connect(wasmd.endpoint);
|
||||
const query = { sentFromOrTo: sendSuccessful.recipient };
|
||||
|
||||
{
|
||||
const result = await client.searchTx(query, { maxHeight: 9999999999999 });
|
||||
expect(result.length).toEqual(1);
|
||||
}
|
||||
|
||||
{
|
||||
const result = await client.searchTx(query, { maxHeight: sendSuccessful.height + 1 });
|
||||
expect(result.length).toEqual(1);
|
||||
}
|
||||
|
||||
{
|
||||
const result = await client.searchTx(query, { maxHeight: sendSuccessful.height });
|
||||
expect(result.length).toEqual(1);
|
||||
}
|
||||
|
||||
{
|
||||
const result = await client.searchTx(query, { maxHeight: sendSuccessful.height - 1 });
|
||||
expect(result.length).toEqual(0);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("with SearchByTagsQuery", () => {
|
||||
it("can search by transfer.recipient", async () => {
|
||||
it("works with tags", async () => {
|
||||
pendingWithoutWasmd();
|
||||
assert(sendSuccessful, "value must be set in beforeAll()");
|
||||
const client = await CosmWasmClient.connect(wasmd.endpoint);
|
||||
const results = await client.searchTx({
|
||||
tags: [{ key: "transfer.recipient", value: sendSuccessful.recipient }],
|
||||
});
|
||||
const results = await client.searchTx([{ key: "transfer.recipient", value: sendSuccessful.recipient }]);
|
||||
expect(results.length).toBeGreaterThanOrEqual(1);
|
||||
|
||||
// Check basic structure of all results
|
||||
|
||||
@ -12,11 +12,7 @@ import {
|
||||
DeliverTxResponse,
|
||||
fromTendermintEvent,
|
||||
IndexedTx,
|
||||
isSearchByHeightQuery,
|
||||
isSearchBySentFromOrToQuery,
|
||||
isSearchByTagsQuery,
|
||||
QueryClient,
|
||||
SearchTxFilter,
|
||||
SearchTxQuery,
|
||||
SequenceResponse,
|
||||
setupAuthExtension,
|
||||
@ -221,42 +217,16 @@ export class CosmWasmClient {
|
||||
return results[0] ?? null;
|
||||
}
|
||||
|
||||
public async searchTx(query: SearchTxQuery, filter: SearchTxFilter = {}): Promise<readonly IndexedTx[]> {
|
||||
const minHeight = filter.minHeight || 0;
|
||||
const maxHeight = filter.maxHeight || Number.MAX_SAFE_INTEGER;
|
||||
|
||||
if (maxHeight < minHeight) return []; // optional optimization
|
||||
|
||||
function withFilters(originalQuery: string): string {
|
||||
return `${originalQuery} AND tx.height>=${minHeight} AND tx.height<=${maxHeight}`;
|
||||
}
|
||||
|
||||
let txs: readonly IndexedTx[];
|
||||
|
||||
if (isSearchByHeightQuery(query)) {
|
||||
txs =
|
||||
query.height >= minHeight && query.height <= maxHeight
|
||||
? await this.txsQuery(`tx.height=${query.height}`)
|
||||
: [];
|
||||
} else if (isSearchBySentFromOrToQuery(query)) {
|
||||
const sentQuery = withFilters(`message.module='bank' AND transfer.sender='${query.sentFromOrTo}'`);
|
||||
const receivedQuery = withFilters(
|
||||
`message.module='bank' AND transfer.recipient='${query.sentFromOrTo}'`,
|
||||
);
|
||||
const [sent, received] = await Promise.all(
|
||||
[sentQuery, receivedQuery].map((rawQuery) => this.txsQuery(rawQuery)),
|
||||
);
|
||||
const sentHashes = sent.map((t) => t.hash);
|
||||
txs = [...sent, ...received.filter((t) => !sentHashes.includes(t.hash))];
|
||||
} else if (isSearchByTagsQuery(query)) {
|
||||
const rawQuery = withFilters(query.tags.map((t) => `${t.key}='${t.value}'`).join(" AND "));
|
||||
txs = await this.txsQuery(rawQuery);
|
||||
public async searchTx(query: SearchTxQuery): Promise<IndexedTx[]> {
|
||||
let rawQuery: string;
|
||||
if (typeof query === "string") {
|
||||
rawQuery = query;
|
||||
} else if (Array.isArray(query)) {
|
||||
rawQuery = query.map((t) => `${t.key}='${t.value}'`).join(" AND ");
|
||||
} else {
|
||||
throw new Error("Unknown query type");
|
||||
throw new Error("Got unsupported query type. See CosmJS 0.31 CHANGELOG for API breaking changes here.");
|
||||
}
|
||||
|
||||
const filtered = txs.filter((tx) => tx.height >= minHeight && tx.height <= maxHeight);
|
||||
return filtered;
|
||||
return this.txsQuery(rawQuery);
|
||||
}
|
||||
|
||||
public disconnect(): void {
|
||||
@ -477,7 +447,7 @@ export class CosmWasmClient {
|
||||
}
|
||||
}
|
||||
|
||||
private async txsQuery(query: string): Promise<readonly IndexedTx[]> {
|
||||
private async txsQuery(query: string): Promise<IndexedTx[]> {
|
||||
const results = await this.forceGetTmClient().txSearchAll({ query: query });
|
||||
return results.txs.map((tx) => {
|
||||
return {
|
||||
|
||||
@ -112,16 +112,7 @@ export {
|
||||
QueryClient,
|
||||
QueryStoreResponse,
|
||||
} from "./queryclient";
|
||||
export {
|
||||
isSearchByHeightQuery,
|
||||
isSearchBySentFromOrToQuery,
|
||||
isSearchByTagsQuery,
|
||||
SearchByHeightQuery,
|
||||
SearchBySentFromOrToQuery,
|
||||
SearchByTagsQuery,
|
||||
SearchTxFilter,
|
||||
SearchTxQuery,
|
||||
} from "./search";
|
||||
export { SearchByHeightQuery, SearchBySentFromOrToQuery, SearchTxQuery } from "./search";
|
||||
export {
|
||||
createDefaultAminoConverters,
|
||||
defaultRegistryTypes,
|
||||
|
||||
@ -7,28 +7,11 @@ export interface SearchBySentFromOrToQuery {
|
||||
}
|
||||
|
||||
/**
|
||||
* This query type allows you to pass arbitrary key/value pairs to the backend. It is
|
||||
* more powerful and slightly lower level than the other search options.
|
||||
* This query type allows you to pass arbitrary key/value pairs to the backend.
|
||||
*/
|
||||
export interface SearchByTagsQuery {
|
||||
readonly tags: ReadonlyArray<{ readonly key: string; readonly value: string }>;
|
||||
}
|
||||
|
||||
export type SearchTxQuery = SearchByHeightQuery | SearchBySentFromOrToQuery | SearchByTagsQuery;
|
||||
|
||||
export function isSearchByHeightQuery(query: SearchTxQuery): query is SearchByHeightQuery {
|
||||
return (query as SearchByHeightQuery).height !== undefined;
|
||||
}
|
||||
|
||||
export function isSearchBySentFromOrToQuery(query: SearchTxQuery): query is SearchBySentFromOrToQuery {
|
||||
return (query as SearchBySentFromOrToQuery).sentFromOrTo !== undefined;
|
||||
}
|
||||
|
||||
export function isSearchByTagsQuery(query: SearchTxQuery): query is SearchByTagsQuery {
|
||||
return (query as SearchByTagsQuery).tags !== undefined;
|
||||
}
|
||||
|
||||
export interface SearchTxFilter {
|
||||
readonly minHeight?: number;
|
||||
readonly maxHeight?: number;
|
||||
}
|
||||
export type SearchTxQuery =
|
||||
| string
|
||||
| ReadonlyArray<{
|
||||
readonly key: string;
|
||||
readonly value: string;
|
||||
}>;
|
||||
|
||||
@ -190,12 +190,12 @@ describe("StargateClient.getTx and .searchTx", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("with SearchByHeightQuery", () => {
|
||||
describe("searchTx", () => {
|
||||
it("can search successful tx by height", async () => {
|
||||
pendingWithoutSimapp();
|
||||
assert(sendSuccessful, "value must be set in beforeAll()");
|
||||
const client = await StargateClient.connect(simapp.tendermintUrl);
|
||||
const result = await client.searchTx({ height: sendSuccessful.height });
|
||||
const result = await client.searchTx(`tx.height=${sendSuccessful.height}`);
|
||||
expect(result.length).toBeGreaterThanOrEqual(1);
|
||||
expect(result).toContain(
|
||||
jasmine.objectContaining({
|
||||
@ -211,7 +211,7 @@ describe("StargateClient.getTx and .searchTx", () => {
|
||||
pendingWithoutSimapp();
|
||||
assert(sendUnsuccessful, "value must be set in beforeAll()");
|
||||
const client = await StargateClient.connect(simapp.tendermintUrl);
|
||||
const result = await client.searchTx({ height: sendUnsuccessful.height });
|
||||
const result = await client.searchTx(`tx.height=${sendUnsuccessful.height}`);
|
||||
expect(result.length).toBeGreaterThanOrEqual(1);
|
||||
expect(result).toContain(
|
||||
jasmine.objectContaining({
|
||||
@ -222,14 +222,14 @@ describe("StargateClient.getTx and .searchTx", () => {
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("with SearchBySentFromOrToQuery", () => {
|
||||
it("can search by sender", async () => {
|
||||
pendingWithoutSimapp();
|
||||
assert(sendSuccessful, "value must be set in beforeAll()");
|
||||
const client = await StargateClient.connect(simapp.tendermintUrl);
|
||||
const results = await client.searchTx({ sentFromOrTo: sendSuccessful.sender });
|
||||
const results = await client.searchTx(
|
||||
`message.module='bank' AND transfer.sender='${sendSuccessful.sender}'`,
|
||||
);
|
||||
expect(results.length).toBeGreaterThanOrEqual(1);
|
||||
|
||||
// Check basic structure of all results
|
||||
@ -257,7 +257,9 @@ describe("StargateClient.getTx and .searchTx", () => {
|
||||
pendingWithoutSimapp();
|
||||
assert(sendSuccessful, "value must be set in beforeAll()");
|
||||
const client = await StargateClient.connect(simapp.tendermintUrl);
|
||||
const results = await client.searchTx({ sentFromOrTo: sendSuccessful.recipient });
|
||||
const results = await client.searchTx(
|
||||
`message.module='bank' AND transfer.recipient='${sendSuccessful.recipient}'`,
|
||||
);
|
||||
expect(results.length).toBeGreaterThanOrEqual(1);
|
||||
|
||||
// Check basic structure of all results
|
||||
@ -281,69 +283,11 @@ describe("StargateClient.getTx and .searchTx", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("can search by recipient and filter by minHeight", async () => {
|
||||
pendingWithoutSimapp();
|
||||
assert(sendSuccessful);
|
||||
const client = await StargateClient.connect(simapp.tendermintUrl);
|
||||
const query = { sentFromOrTo: sendSuccessful.recipient };
|
||||
|
||||
{
|
||||
const result = await client.searchTx(query, { minHeight: 0 });
|
||||
expect(result.length).toEqual(1);
|
||||
}
|
||||
|
||||
{
|
||||
const result = await client.searchTx(query, { minHeight: sendSuccessful.height - 1 });
|
||||
expect(result.length).toEqual(1);
|
||||
}
|
||||
|
||||
{
|
||||
const result = await client.searchTx(query, { minHeight: sendSuccessful.height });
|
||||
expect(result.length).toEqual(1);
|
||||
}
|
||||
|
||||
{
|
||||
const result = await client.searchTx(query, { minHeight: sendSuccessful.height + 1 });
|
||||
expect(result.length).toEqual(0);
|
||||
}
|
||||
});
|
||||
|
||||
it("can search by recipient and filter by maxHeight", async () => {
|
||||
pendingWithoutSimapp();
|
||||
assert(sendSuccessful);
|
||||
const client = await StargateClient.connect(simapp.tendermintUrl);
|
||||
const query = { sentFromOrTo: sendSuccessful.recipient };
|
||||
|
||||
{
|
||||
const result = await client.searchTx(query, { maxHeight: 9999999999999 });
|
||||
expect(result.length).toEqual(1);
|
||||
}
|
||||
|
||||
{
|
||||
const result = await client.searchTx(query, { maxHeight: sendSuccessful.height + 1 });
|
||||
expect(result.length).toEqual(1);
|
||||
}
|
||||
|
||||
{
|
||||
const result = await client.searchTx(query, { maxHeight: sendSuccessful.height });
|
||||
expect(result.length).toEqual(1);
|
||||
}
|
||||
|
||||
{
|
||||
const result = await client.searchTx(query, { maxHeight: sendSuccessful.height - 1 });
|
||||
expect(result.length).toEqual(0);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("with SearchByTagsQuery", () => {
|
||||
it("can search by transfer.recipient", async () => {
|
||||
it("works with tags", async () => {
|
||||
pendingWithoutSimapp();
|
||||
assert(sendSuccessful, "value must be set in beforeAll()");
|
||||
const client = await StargateClient.connect(simapp.tendermintUrl);
|
||||
const results = await client.searchTx({
|
||||
tags: [{ key: "transfer.recipient", value: sendSuccessful.recipient }],
|
||||
});
|
||||
const results = await client.searchTx([{ key: "transfer.recipient", value: sendSuccessful.recipient }]);
|
||||
expect(results.length).toBeGreaterThanOrEqual(1);
|
||||
|
||||
// Check basic structure of all results
|
||||
|
||||
@ -28,13 +28,7 @@ import {
|
||||
TxExtension,
|
||||
} from "./modules";
|
||||
import { QueryClient } from "./queryclient";
|
||||
import {
|
||||
isSearchByHeightQuery,
|
||||
isSearchBySentFromOrToQuery,
|
||||
isSearchByTagsQuery,
|
||||
SearchTxFilter,
|
||||
SearchTxQuery,
|
||||
} from "./search";
|
||||
import { SearchTxQuery } from "./search";
|
||||
|
||||
export class TimeoutError extends Error {
|
||||
public readonly txId: string;
|
||||
@ -394,42 +388,16 @@ export class StargateClient {
|
||||
return results[0] ?? null;
|
||||
}
|
||||
|
||||
public async searchTx(query: SearchTxQuery, filter: SearchTxFilter = {}): Promise<readonly IndexedTx[]> {
|
||||
const minHeight = filter.minHeight || 0;
|
||||
const maxHeight = filter.maxHeight || Number.MAX_SAFE_INTEGER;
|
||||
|
||||
if (maxHeight < minHeight) return []; // optional optimization
|
||||
|
||||
function withFilters(originalQuery: string): string {
|
||||
return `${originalQuery} AND tx.height>=${minHeight} AND tx.height<=${maxHeight}`;
|
||||
}
|
||||
|
||||
let txs: readonly IndexedTx[];
|
||||
|
||||
if (isSearchByHeightQuery(query)) {
|
||||
txs =
|
||||
query.height >= minHeight && query.height <= maxHeight
|
||||
? await this.txsQuery(`tx.height=${query.height}`)
|
||||
: [];
|
||||
} else if (isSearchBySentFromOrToQuery(query)) {
|
||||
const sentQuery = withFilters(`message.module='bank' AND transfer.sender='${query.sentFromOrTo}'`);
|
||||
const receivedQuery = withFilters(
|
||||
`message.module='bank' AND transfer.recipient='${query.sentFromOrTo}'`,
|
||||
);
|
||||
const [sent, received] = await Promise.all(
|
||||
[sentQuery, receivedQuery].map((rawQuery) => this.txsQuery(rawQuery)),
|
||||
);
|
||||
const sentHashes = sent.map((t) => t.hash);
|
||||
txs = [...sent, ...received.filter((t) => !sentHashes.includes(t.hash))];
|
||||
} else if (isSearchByTagsQuery(query)) {
|
||||
const rawQuery = withFilters(query.tags.map((t) => `${t.key}='${t.value}'`).join(" AND "));
|
||||
txs = await this.txsQuery(rawQuery);
|
||||
public async searchTx(query: SearchTxQuery): Promise<IndexedTx[]> {
|
||||
let rawQuery: string;
|
||||
if (typeof query === "string") {
|
||||
rawQuery = query;
|
||||
} else if (Array.isArray(query)) {
|
||||
rawQuery = query.map((t) => `${t.key}='${t.value}'`).join(" AND ");
|
||||
} else {
|
||||
throw new Error("Unknown query type");
|
||||
throw new Error("Got unsupported query type. See CosmJS 0.31 CHANGELOG for API breaking changes here.");
|
||||
}
|
||||
|
||||
const filtered = txs.filter((tx) => tx.height >= minHeight && tx.height <= maxHeight);
|
||||
return filtered;
|
||||
return this.txsQuery(rawQuery);
|
||||
}
|
||||
|
||||
public disconnect(): void {
|
||||
@ -503,7 +471,7 @@ export class StargateClient {
|
||||
);
|
||||
}
|
||||
|
||||
private async txsQuery(query: string): Promise<readonly IndexedTx[]> {
|
||||
private async txsQuery(query: string): Promise<IndexedTx[]> {
|
||||
const results = await this.forceGetTmClient().txSearchAll({ query: query });
|
||||
return results.txs.map((tx) => {
|
||||
return {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user