Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: transaction fetching #147

Merged
merged 13 commits into from
Jan 15, 2025
2 changes: 1 addition & 1 deletion packages/profiles/source/transaction-index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ export class TransactionIndex implements ITransactionIndex {
query: Services.ClientTransactionsInput = {},
): Promise<ExtendedConfirmedTransactionDataCollection> {
return this.#fetch({
...query,
identifiers: [
{
method: this.#wallet.data().get(WalletData.ImportMethod),
type: "address",
value: this.#wallet.address(),
},
],
...query,
});
}

Expand Down
1 change: 1 addition & 0 deletions packages/profiles/source/transaction.aggregate.contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ExtendedConfirmedTransactionDataCollection } from "./transaction.collec

export type AggregateQuery = {
identifiers?: Services.WalletIdentifier[];
types?: string[];
} & Services.ClientPagination;

/**
Expand Down
78 changes: 41 additions & 37 deletions packages/profiles/source/transaction.aggregate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,57 +50,61 @@ export class TransactionAggregate implements ITransactionAggregate {
}

async #aggregate(method: string, query: AggregateQuery): Promise<ExtendedConfirmedTransactionDataCollection> {
if (!this.#history[method]) {
this.#history[method] = {};
const syncedWallets: IReadWriteWallet[] = this.#getWallets(query.identifiers);

if (syncedWallets.length === 0) {
return new ExtendedConfirmedTransactionDataCollection([], {
last: undefined,
next: 0,
prev: undefined,
self: undefined,
});
}

const syncedWallets: IReadWriteWallet[] = this.#getWallets(query.identifiers);
const requests: Record<string, Promise<Collections.ConfirmedTransactionDataCollection>> = {};
const historyRecords = this.#history[method] ?? {};

delete query.identifiers;
const historyKeys: string[] = [];

for (const syncedWallet of syncedWallets) {
requests[syncedWallet.id()] = new Promise((resolve, reject) => {
const lastResponse: HistoryWallet = this.#history[method][syncedWallet.id()];

if (lastResponse && !lastResponse.hasMorePages()) {
return reject(
`Fetched all transactions for ${syncedWallet.id()}. Call [#flush] if you want to reset the history.`,
);
}

if (lastResponse && lastResponse.hasMorePages()) {
return resolve(
syncedWallet.transactionIndex()[method]({ cursor: lastResponse.nextPage(), ...query }),
);
}

return resolve(syncedWallet.transactionIndex()[method](query));
});
historyKeys.push(syncedWallet.address());
}

const responses = await promiseAllSettledByKey<ExtendedConfirmedTransactionDataCollection>(requests);
const result: ExtendedConfirmedTransactionData[] = [];
// to sort wallet addresses
historyKeys.sort((a, b) => a.localeCompare(b));

for (const [id, request] of Object.entries(responses || {})) {
if (request.status === "rejected" || request.value instanceof Error) {
continue;
}
query.orderBy && historyKeys.push(query.orderBy);
query.limit && historyKeys.push(query.limit.toString());

if (request.value.isEmpty()) {
continue;
}
if (query.types && query.types.length > 0) {
historyKeys.push(query.types.join(":"));
}

for (const transaction of request.value.items()) {
result.push(transaction);
}
const historyKey = historyKeys.join("-");

this.#history[method][id] = request.value;
if (historyRecords[historyKey]) {
query = { ...query, cursor: historyRecords[historyKey].nextPage() };
}

return new ExtendedConfirmedTransactionDataCollection(result, {
let response: ExtendedConfirmedTransactionDataCollection;

try {
response = (await syncedWallets[0]
.transactionIndex()
[method](query)) as ExtendedConfirmedTransactionDataCollection;
} catch {
return new ExtendedConfirmedTransactionDataCollection([], {
last: undefined,
next: 0,
prev: undefined,
self: undefined,
});
}

historyRecords[historyKey] = response;

return new ExtendedConfirmedTransactionDataCollection(response.items(), {
last: undefined,
next: Number(this.hasMore(method)),
next: Number(response.nextPage()),
prev: undefined,
self: undefined,
});
Expand Down
Loading