11// eslint-disable-next-line jsdoc/check-param-names
22import * as Crypto from '@cardano-sdk/crypto' ;
3- import { BlockfrostProvider } from '../../util/BlockfrostProvider/BlockfrostProvider' ;
3+ import { BlockfrostProvider , BlockfrostProviderDependencies } from '../../util/BlockfrostProvider/BlockfrostProvider' ;
44import {
55 BlockfrostToCore ,
66 BlockfrostTransactionContent ,
@@ -13,12 +13,14 @@ import {
1313 BlocksByIdsArgs ,
1414 Cardano ,
1515 ChainHistoryProvider ,
16+ NetworkInfoProvider ,
1617 Paginated ,
1718 ProviderError ,
1819 ProviderFailure ,
1920 Serialization ,
2021 TransactionsByAddressesArgs ,
21- TransactionsByIdsArgs
22+ TransactionsByIdsArgs ,
23+ createSlotEpochCalc
2224} from '@cardano-sdk/core' ;
2325import { DB_MAX_SAFE_INTEGER } from '../DbSyncChainHistory/queries' ;
2426import { Responses } from '@blockfrost/blockfrost-js' ;
@@ -27,7 +29,17 @@ import omit from 'lodash/omit.js';
2729
2830type WithCertIndex < T > = T & { cert_index : number } ;
2931
32+ export interface BlockfrostChainHistoryProviderDependencies extends BlockfrostProviderDependencies {
33+ networkInfoProvider : NetworkInfoProvider ;
34+ }
35+
3036export class BlockfrostChainHistoryProvider extends BlockfrostProvider implements ChainHistoryProvider {
37+ private networkInfoProvider : NetworkInfoProvider ;
38+ constructor ( { logger, blockfrost, networkInfoProvider } : BlockfrostChainHistoryProviderDependencies ) {
39+ super ( { blockfrost, logger } ) ;
40+ this . networkInfoProvider = networkInfoProvider ;
41+ }
42+
3143 protected async fetchRedeemers ( {
3244 hash,
3345 redeemer_count
@@ -231,6 +243,53 @@ export class BlockfrostChainHistoryProvider extends BlockfrostProvider implement
231243 // eslint-disable-next-line unicorn/consistent-function-scoping
232244 protected parseValidityInterval = ( num : string | null ) => Cardano . Slot ( Number . parseInt ( num || '' ) ) || undefined ;
233245
246+ protected async fetchEpochNo ( slotNo : Cardano . Slot ) {
247+ const calc = await this . networkInfoProvider . eraSummaries ( ) . then ( createSlotEpochCalc ) ;
248+ return calc ( slotNo ) ;
249+ }
250+
251+ protected async fetchEpochParameters ( epochNo : Cardano . EpochNo ) : Promise < Schemas [ 'epoch_param_content' ] > {
252+ return await this . blockfrost . epochsParameters ( epochNo ) ;
253+ }
254+
255+ protected async processCertificates (
256+ txContent : Schemas [ 'tx_content' ] ,
257+ certificates ?: Cardano . Certificate [ ]
258+ ) : Promise < Cardano . Certificate [ ] | undefined > {
259+ const epochNo = await this . fetchEpochNo ( Cardano . Slot ( txContent . slot ) ) ;
260+ const epochParams : Schemas [ 'epoch_param_content' ] = await this . fetchEpochParameters ( epochNo ) ;
261+
262+ return certificates ?. map ( ( c ) => {
263+ const cert = omit ( c , 'cert_index' ) as Cardano . Certificate ;
264+ switch ( cert . __typename ) {
265+ case Cardano . CertificateType . PoolRegistration : {
266+ cert . poolParameters . owners = [ ] ;
267+ cert . poolParameters . relays = [ ] ;
268+ const deposit =
269+ txContent . deposit === undefined || txContent . deposit === '' || txContent . deposit === '0'
270+ ? 0n
271+ : BigInt ( epochParams . pool_deposit ) ;
272+
273+ delete cert . poolParameters . metadataJson ;
274+
275+ return { ...cert , deposit } ;
276+ }
277+ case Cardano . CertificateType . StakeRegistration : {
278+ const deposit = BigInt ( epochParams . key_deposit ) ;
279+
280+ return { ...cert , __typename : Cardano . CertificateType . Registration , deposit } ;
281+ }
282+ case Cardano . CertificateType . StakeDeregistration : {
283+ const deposit = BigInt ( epochParams . key_deposit ) ;
284+
285+ return { ...cert , __typename : Cardano . CertificateType . Unregistration , deposit } ;
286+ }
287+ default :
288+ return cert ;
289+ }
290+ } ) ;
291+ }
292+
234293 protected async fetchTransaction ( txId : Cardano . TransactionId ) : Promise < Cardano . HydratedTx > {
235294 try {
236295 const txContent = await this . blockfrost . txs ( txId . toString ( ) ) ;
@@ -244,17 +303,10 @@ export class BlockfrostChainHistoryProvider extends BlockfrostProvider implement
244303 txFromCBOR ? txFromCBOR . auxiliaryData : this . fetchJsonMetadataAsAuxiliaryData ( txId )
245304 ] ) ;
246305
247- const certificates = certificatesFull ?. map ( ( c ) => {
248- const cert = omit ( c , 'cert_index' ) as Cardano . Certificate ;
249- if ( cert . __typename === Cardano . CertificateType . PoolRegistration ) {
250- cert . poolParameters . owners = [ ] ;
251- cert . poolParameters . relays = [ ] ;
252- }
253- return cert ;
254- } ) ;
306+ const certificates = await this . processCertificates ( txContent , certificatesFull ) ;
255307
256308 // We can't use txFromCBOR.body.inputs since it misses HydratedTxIn.address
257- const { inputs, outputPromises, collaterals } = this . transactionUtxos ( utxos , txId , txFromCBOR ?? undefined ) ;
309+ const { inputs, outputPromises, collaterals } = this . transactionUtxos ( utxos , txFromCBOR ?? undefined ) ;
258310 /*
259311 const inputs = BlockfrostToCore.inputsUtxos(utxos.inputs);
260312 const collaterals = BlockfrostToCore.colleteralsUtxos(utxos.inputs);
@@ -309,7 +361,7 @@ export class BlockfrostChainHistoryProvider extends BlockfrostProvider implement
309361 const proposalProcedures = txFromCBOR ? txFromCBOR . body . proposalProcedures : undefined ;
310362 const votingProcedures = txFromCBOR ? txFromCBOR . body . votingProcedures : undefined ;
311363
312- const body : HydratedTxBody = {
364+ const body : Cardano . HydratedTxBody = {
313365 ...( inputSource === Cardano . InputSource . collaterals
314366 ? {
315367 collateralReturn : outputs . length > 0 ? outputs [ 0 ] : undefined ,
@@ -349,18 +401,14 @@ export class BlockfrostChainHistoryProvider extends BlockfrostProvider implement
349401 }
350402 }
351403
352- private transactionUtxos (
353- utxoResponse : Responses [ 'tx_content_utxo' ] ,
354- _txId : Cardano . TransactionId ,
355- txContent ?: Cardano . Tx
356- ) {
404+ private transactionUtxos ( utxoResponse : Responses [ 'tx_content_utxo' ] , txContent ?: Cardano . Tx ) {
357405 const collaterals = utxoResponse . inputs . filter ( ( input ) => input . collateral ) . map ( BlockfrostToCore . hydratedTxIn ) ;
358406 const inputs = utxoResponse . inputs
359407 . filter ( ( input ) => ! input . collateral && ! input . reference )
360408 . map ( BlockfrostToCore . hydratedTxIn ) ;
361- const outputPromises : Promise < Cardano . TxOut > [ ] = utxoResponse . outputs
409+ const outputPromises : Cardano . TxOut [ ] = utxoResponse . outputs
362410 . filter ( ( output ) => ! output . collateral )
363- . map ( async ( output ) => {
411+ . map ( ( output ) => {
364412 const foundScript = txContent ?. body . outputs . find ( ( o ) => o . address === output . address ) ;
365413
366414 return BlockfrostToCore . txOut ( output , foundScript ) ;
0 commit comments