Skip to content

Commit

Permalink
fix(coin:tezos): api iterates over all results
Browse files Browse the repository at this point in the history
  • Loading branch information
jprudent committed Feb 6, 2025
1 parent ff98251 commit 20493ed
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 3 deletions.
38 changes: 38 additions & 0 deletions libs/coin-modules/coin-tezos/src/api/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { createApi } from "./index";

const mockGetTransactions = jest.fn();
jest.mock("../logic/listOperations", () => ({
listOperations: () => mockGetTransactions(),
}));

describe("get operations", () => {
it("operations", async () => {
const api = createApi({
baker: {
url: "https://baker.example.com",
},
explorer: {
url: "foo",
maxTxQuery: 1,
},
node: {
url: "bar",
},
fees: {
minGasLimit: 1,
minRevealGasLimit: 1,
minStorageLimit: 1,
minFees: 1,
minEstimatedFees: 2,
},
});

mockGetTransactions.mockResolvedValue([]);

// When
const operations = await api.listOperations("addr", { limit: 100 });

// Then
expect(operations).toEqual([]);
});
});
52 changes: 49 additions & 3 deletions libs/coin-modules/coin-tezos/src/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
IncorrectTypeError,
Operation,
Pagination,
type Api,
type Transaction as ApiTransaction,
Expand Down Expand Up @@ -65,7 +66,52 @@ async function estimate(addr: string, amount: bigint): Promise<bigint> {
return estimatedFees.estimatedFees;
}

function operations(address: string, _pagination: Pagination) {
//TODO implement properly with https://github.com/LedgerHQ/ledger-live/pull/8875
return listOperations(address, {});
type PaginationState = {
pageSize: number;
heightLimit: number;
continueIterations: boolean;
apiNextCursor?: number;
accumulator: Operation[];
};

async function operationsFromHeight(
address: string,
start: number,
): Promise<[Operation[], number]> {
async function fetchNextPage(state: PaginationState): Promise<PaginationState> {
const [operations, apiNextCursor] = await listOperations(address, {
limit: state.pageSize,
lastId: state.apiNextCursor,
});
const filteredOperations = operations.filter(op => op.block.height >= state.heightLimit);
const isTruncated = operations.length !== filteredOperations.length;
const continueIteration = !(apiNextCursor === -1 || isTruncated);
const accumulated = state.accumulator.concat(filteredOperations);
return {
...state,
continueIterations: continueIteration,
apiNextCursor: apiNextCursor,
accumulator: accumulated,
};
}

const firstState: PaginationState = {
pageSize: 1,
heightLimit: start,
continueIterations: true,
accumulator: [],
};

let state = await fetchNextPage(firstState);
while (state.continueIterations) {
state = await fetchNextPage(state);
}
return [state.accumulator, state.apiNextCursor ?? 0];
}

async function operations(
address: string,
{ limit, start }: Pagination,
): Promise<[Operation[], number]> {
return start ? operationsFromHeight(address, start) : listOperations(address, { limit: limit });
}
9 changes: 9 additions & 0 deletions libs/coin-modules/coin-tezos/src/logic/listOperations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ export type Operation = {

export async function listOperations(
address: string,
{ lastId, limit }: { lastId?: number; limit?: number },
): Promise<[Operation[], number]> {
const operations = await tzkt.getAccountOperations(address, {
lastId: lastId,
sort: 1,
limit: limit,
});
const lastOperation = operations.slice(-1)[0];
const nextLastId = lastOperation?.id ?? -1;
{ token, limit }: { limit?: number; token?: string },
): Promise<[Operation[], string]> {
let options: { lastId?: number; limit?: number } = { limit: limit };
Expand Down

0 comments on commit 20493ed

Please sign in to comment.