diff --git a/services/watcher/config/default.yaml b/services/watcher/config/default.yaml index e0dd9e0b..8c4017a1 100644 --- a/services/watcher/config/default.yaml +++ b/services/watcher/config/default.yaml @@ -4,7 +4,7 @@ observation: confirmation: 60 # number of required block confirmations to create the commitment after observing an event validThreshold: 4320 # observations that have not been triggered won't be processed after this period (in blocks) cardano: - type: '' # options: koios, ogmios + type: '' # options: koios, ogmios, blockfrost initial: slot: -1 # initial block global slot, only used for ogmios hash: '' # initial block hash, only used for ogmios @@ -17,6 +17,11 @@ cardano: host: '' # ogmios node host address port: 1337 # ogmios port useTls: false # connect to ogmios using https or not + blockfrost: + url: '' # url to connect to blockfrost + projectId: '' # blockfrost project Id + timeout: 10 # blockfrost request timeout + interval: 20 # blockfrost check timeout ergo: network: 'Mainnet' # ergo network type. testnet or mainnet type: 'node' # ergo scanner type. options: node, explorer diff --git a/services/watcher/src/config/config.ts b/services/watcher/src/config/config.ts index d272fa43..3a5fdccf 100644 --- a/services/watcher/src/config/config.ts +++ b/services/watcher/src/config/config.ts @@ -277,6 +277,13 @@ class CardanoConfig { interval: number; authToken?: string; }; + blockfrost?: { + url?: string; + timeout: number; + initialHeight: number; + interval: number; + projectId: string; + }; constructor(network: string) { this.type = config.get('cardano.type'); @@ -297,6 +304,15 @@ class CardanoConfig { ? config.get('cardano.koios.authToken') : undefined; this.koios = { url, initialHeight, interval, timeout, authToken }; + } else if (this.type === Constants.BLOCK_FROST_TYPE) { + const url = config.has('cardano.blockfrost.url') + ? getRequiredString('cardano.blockfrost.url') + : undefined; + const interval = getRequiredNumber('cardano.blockfrost.interval'); + const timeout = getRequiredNumber('cardano.blockfrost.timeout'); + const initialHeight = getRequiredNumber('cardano.initial.height'); + const projectId = config.get('cardano.blockfrost.projectId'); + this.blockfrost = { url, timeout, initialHeight, interval, projectId }; } else { throw new Error( `Improperly configured. cardano configuration type is invalid available choices are '${Constants.OGMIOS_TYPE}', '${Constants.KOIOS_TYPE}'` diff --git a/services/watcher/src/config/constants.ts b/services/watcher/src/config/constants.ts index 480b52fd..0bb3cda0 100644 --- a/services/watcher/src/config/constants.ts +++ b/services/watcher/src/config/constants.ts @@ -4,6 +4,7 @@ export const COMMITMENT_EXTRACTOR_NAME = 'watcher-commitment-extractor'; export const TRIGGER_EXTRACTOR_NAME = 'watcher-trigger-extractor'; export const OGMIOS_TYPE = 'ogmios'; export const KOIOS_TYPE = 'koios'; +export const BLOCK_FROST_TYPE = 'blockfrost'; export const NODE_TYPE = 'node'; export const EXPLORER_TYPE = 'explorer'; export const ERGO_CHAIN_NAME = 'ergo'; diff --git a/services/watcher/src/jobs/initScanner.ts b/services/watcher/src/jobs/initScanner.ts index 12df7808..231bdd90 100644 --- a/services/watcher/src/jobs/initScanner.ts +++ b/services/watcher/src/jobs/initScanner.ts @@ -1,4 +1,5 @@ import { + CardanoBlockFrostScanner, CardanoKoiosScanner, CardanoOgmiosScanner, GeneralScanner, @@ -35,6 +36,11 @@ export const scannerInit = () => { cardanoConfig.koios.interval, scanner.observationScanner as CardanoKoiosScanner ).then(() => null); + } else if (cardanoConfig.blockfrost) { + scanningJob( + cardanoConfig.blockfrost.interval, + scanner.observationScanner as CardanoBlockFrostScanner + ).then(() => null); } else { throw new Error( `The observing network [${config.networkWatcher}] is not supported` diff --git a/services/watcher/src/utils/scanner.ts b/services/watcher/src/utils/scanner.ts index 20c31657..bbfb94cd 100644 --- a/services/watcher/src/utils/scanner.ts +++ b/services/watcher/src/utils/scanner.ts @@ -3,11 +3,13 @@ import { CardanoKoiosScanner, CardanoOgmiosScanner, ErgoNetworkType, + CardanoBlockFrostScanner, } from '@rosen-bridge/scanner'; import { ErgoObservationExtractor, CardanoKoiosObservationExtractor, CardanoOgmiosObservationExtractor, + CardanoBlockFrostObservationExtractor, } from '@rosen-bridge/observation-extractor'; import { CommitmentExtractor, @@ -55,7 +57,11 @@ const logger = WinstonLogger.getInstance().getLogger(import.meta.url); class CreateScanner { ergoScanner: ErgoScanner; - observationScanner: ErgoScanner | CardanoKoiosScanner | CardanoOgmiosScanner; + observationScanner: + | ErgoScanner + | CardanoKoiosScanner + | CardanoOgmiosScanner + | CardanoBlockFrostScanner; constructor() { this.createErgoScanner(); @@ -184,6 +190,21 @@ class CreateScanner { loggers.observationExtractorLogger ); this.observationScanner.registerExtractor(observationExtractor); + } else if (cardanoConfig.blockfrost) { + this.observationScanner = new CardanoBlockFrostScanner({ + dataSource, + initialHeight: cardanoConfig.blockfrost.initialHeight, + projectId: cardanoConfig.blockfrost.projectId, + timeout: cardanoConfig.blockfrost.timeout, + blockFrostUrl: cardanoConfig.blockfrost.url, + }); + const observationExtractor = new CardanoBlockFrostObservationExtractor( + dataSource, + tokensConfig.tokens, + rosenConfig.lockAddress, + loggers.observationExtractorLogger + ); + this.observationScanner.registerExtractor(observationExtractor); } } };