Skip to content

Commit 2bc026d

Browse files
feat(cardano-services): blockfrost chain history provider now caches transactions locally
1 parent 956690e commit 2bc026d

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

packages/cardano-services-client/src/ChainHistoryProvider/BlockfrostChainHistoryProvider.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type BlockfrostTx = Pick<Responses['address_transactions_content'][0], 'block_he
3434
const compareTx = (a: BlockfrostTx, b: BlockfrostTx) => a.block_height - b.block_height || a.tx_index - b.tx_index;
3535

3636
export class BlockfrostChainHistoryProvider extends BlockfrostProvider implements ChainHistoryProvider {
37+
private readonly cache: Map<string, Cardano.HydratedTx> = new Map();
3738
private networkInfoProvider: NetworkInfoProvider;
3839

3940
constructor(client: BlockfrostClient, networkInfoProvider: NetworkInfoProvider, logger: Logger) {
@@ -475,11 +476,31 @@ export class BlockfrostChainHistoryProvider extends BlockfrostProvider implement
475476
}
476477

477478
public async transactionsByHashes({ ids }: TransactionsByIdsArgs): Promise<Cardano.HydratedTx[]> {
478-
try {
479-
return Promise.all(ids.map((id) => this.fetchTransaction(id)));
480-
} catch (error) {
481-
throw this.toProviderError(error);
479+
const cachedTransactions: Cardano.HydratedTx[] = [];
480+
const idsToFetch: Cardano.TransactionId[] = [];
481+
482+
for (const id of ids) {
483+
if (this.cache.has(id)) {
484+
cachedTransactions.push(this.cache.get(id)!);
485+
} else {
486+
idsToFetch.push(id);
487+
}
488+
}
489+
490+
let fetchedTransactions: Cardano.HydratedTx[] = [];
491+
if (idsToFetch.length > 0) {
492+
try {
493+
fetchedTransactions = await Promise.all(idsToFetch.map((id) => this.fetchTransaction(id)));
494+
495+
for (const tx of fetchedTransactions) {
496+
this.cache.set(tx.id, tx);
497+
}
498+
} catch (error) {
499+
throw this.toProviderError(error);
500+
}
482501
}
502+
503+
return [...cachedTransactions, ...fetchedTransactions];
483504
}
484505

485506
// eslint-disable-next-line sonarjs/cognitive-complexity

packages/cardano-services-client/test/ChainHistoryProvider/BlockfrostChainHistoryProvider.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,5 +590,25 @@ describe('blockfrostChainHistoryProvider', () => {
590590
expect(response[0]).toEqual(expectedHydratedTxCBOR);
591591
});
592592
});
593+
594+
test('caches transactions and returns them from the cache on subsequent calls', async () => {
595+
const firstResponse = await provider.transactionsByHashes({
596+
ids: ['1e043f100dce12d107f679685acd2fc0610e10f72a92d412794c9773d11d8477' as Cardano.TransactionId]
597+
});
598+
599+
expect(firstResponse).toHaveLength(1);
600+
expect(firstResponse[0]).toEqual(expectedHydratedTxCBOR);
601+
expect(request).toHaveBeenCalled();
602+
603+
request.mockClear();
604+
605+
const secondResponse = await provider.transactionsByHashes({
606+
ids: ['1e043f100dce12d107f679685acd2fc0610e10f72a92d412794c9773d11d8477' as Cardano.TransactionId]
607+
});
608+
609+
expect(secondResponse).toHaveLength(1);
610+
expect(secondResponse[0]).toEqual(expectedHydratedTxCBOR);
611+
expect(request).not.toHaveBeenCalled();
612+
});
593613
});
594614
});

0 commit comments

Comments
 (0)