Skip to content

Commit 4e10d20

Browse files
reubenyapReuben Yap
authored andcommitted
feat: add Firo chain support to rosen-service
- Add `@rosen-bridge/firo-scanner` and `@rosen-bridge/firo-observation-extractor` as dependencies. - Wire up a new `FiroRpcScanner` in `scanner-service`, reading from the configured Firo RPC node using a failover connector manager. - Register `FiroRpcObservationExtractor` for the lock address. - Register the `firo-extractor` event-trigger extractor on the Ergo scanner. - Register a Firo scanner-sync health check (`firoScannerWarnDiff` / `firoScannerCriticalDiff`). - Pass the Firo calculator config (addresses + `explorerUrl`) to `AssetCalculator`. - Add `firo` network section plus health-check thresholds and `calculator.addresses.firo` defaults to `config/default.yaml`. - Add `FIRO_SCANNER_INTERVAL`, `FIRO_SCANNER_LOGGER_NAME`, and `FIRO_BLOCK_TIME` constants. Part of the RCS-003 Bridge Expansion Kit for Firo. Builds on the Firo asset-calculator integration.
1 parent 258d469 commit 4e10d20

13 files changed

Lines changed: 516 additions & 102 deletions

File tree

‎.changeset/firo-rosen-service.md‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
'@rosen-bridge/rosen-service': minor
3+
---
4+
5+
Add Firo chain support to rosen-service
6+
7+
- Add `@rosen-bridge/firo-scanner` and `@rosen-bridge/firo-observation-extractor`
8+
as dependencies.
9+
- Wire up a new `FiroRpcScanner` in `scanner-service`, reading from the
10+
configured Firo RPC node.
11+
- Register `FiroRpcObservationExtractor` for the lock address.
12+
- Register the `firo-extractor` event-trigger extractor on the Ergo scanner.
13+
- Register a Firo scanner-sync health check.
14+
- Pass the Firo calculator config (addresses + `explorerUrl`) to
15+
`AssetCalculator`.
16+
- Add `firo` network section plus health-check thresholds and
17+
`calculator.addresses.firo` defaults to `config/default.yaml`.

‎apps/rosen-service/config/default.yaml‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,21 @@ doge:
7070
# - url:
7171
# username:
7272
# password:
73+
firo:
74+
addresses:
75+
lock:
76+
eventTrigger:
77+
permit:
78+
fraud:
79+
commitment:
80+
tokens:
81+
rwt:
82+
initialHeight:
83+
explorerUrl: https://explorer.firo.org
84+
rpc:
85+
url:
86+
username:
87+
password:
7388
ethereum:
7489
addresses:
7590
lock:
@@ -107,6 +122,7 @@ calculator:
107122
doge: []
108123
ethereum: []
109124
binance: []
125+
firo: []
110126
healthCheck:
111127
ergoScannerWarnDiff: 3
112128
ergoScannerCriticalDiff: 5
@@ -120,6 +136,8 @@ healthCheck:
120136
ethereumScannerCriticalDiff: 5
121137
binanceScannerWarnDiff: 3
122138
binanceScannerCriticalDiff: 5
139+
firoScannerWarnDiff: 3
140+
firoScannerCriticalDiff: 5
123141
interval: 60 # health check update interval (in seconds)
124142
duration: 600 # log duration time check (in seconds)
125143
maxAllowedErrorCount: 1 # maximum allowed error log lines

‎apps/rosen-service/package.json‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
"@rosen-bridge/ergo-scanner": "^1.0.2",
3939
"@rosen-bridge/evm-observation-extractor": "^6.0.3",
4040
"@rosen-bridge/evm-scanner": "^1.0.2",
41+
"@rosen-bridge/firo-observation-extractor": "^0.1.2",
42+
"@rosen-bridge/firo-scanner": "^0.1.1",
4143
"@rosen-bridge/health-check": "^8.0.0",
4244
"@rosen-bridge/log-level-check": "^4.0.0",
4345
"@rosen-bridge/scanner-interfaces": "^0.2.2",

‎apps/rosen-service/src/calculator/calculator-service.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ const start = async () => {
7878
addresses: config.calculator.addresses.doge,
7979
blockcypherUrl: config.doge.blockcypherUrl,
8080
},
81+
{
82+
addresses: config.calculator.addresses.firo,
83+
explorerUrl: config.firo.explorerUrl,
84+
},
8185
dataSource,
8286
logger,
8387
);

‎apps/rosen-service/src/configs.ts‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,23 @@ const getConfig = () => {
144144
}>
145145
>('doge.rpcConnections'),
146146
},
147+
firo: {
148+
addresses: {
149+
lock: nodeConfig.get<string>('firo.addresses.lock'),
150+
eventTrigger: nodeConfig.get<string>('firo.addresses.eventTrigger'),
151+
permit: nodeConfig.get<string>('firo.addresses.permit'),
152+
fraud: nodeConfig.get<string>('firo.addresses.fraud'),
153+
commitment: nodeConfig.get<string>('firo.addresses.commitment'),
154+
},
155+
initialHeight: nodeConfig.get<number>('firo.initialHeight'),
156+
tokens: {
157+
rwt: nodeConfig.get<string>('firo.tokens.rwt'),
158+
},
159+
explorerUrl: nodeConfig.get<string>('firo.explorerUrl'),
160+
rpcUrl: nodeConfig.get<string>('firo.rpc.url'),
161+
rpcUsername: getOptionalString('firo.rpc.username'),
162+
rpcPassword: getOptionalString('firo.rpc.password'),
163+
},
147164
postgres: {
148165
url: nodeConfig.get<string>('postgres.url'),
149166
logging: nodeConfig.get<boolean>('postgres.logging'),
@@ -160,6 +177,7 @@ const getConfig = () => {
160177
ethereum: nodeConfig.get<string[]>('calculator.addresses.ethereum'),
161178
binance: nodeConfig.get<string[]>('calculator.addresses.binance'),
162179
doge: nodeConfig.get<string[]>('calculator.addresses.doge'),
180+
firo: nodeConfig.get<string[]>('calculator.addresses.firo'),
163181
},
164182
interval: nodeConfig.get<number>('calculator.interval'),
165183
},
@@ -200,6 +218,12 @@ const getConfig = () => {
200218
binanceScannerCriticalDiff: nodeConfig.get<number>(
201219
'healthCheck.binanceScannerCriticalDiff',
202220
),
221+
firoScannerWarnDiff: nodeConfig.get<number>(
222+
'healthCheck.firoScannerWarnDiff',
223+
),
224+
firoScannerCriticalDiff: nodeConfig.get<number>(
225+
'healthCheck.firoScannerCriticalDiff',
226+
),
203227
updateInterval: nodeConfig.get<number>('healthCheck.interval'),
204228
logDuration: nodeConfig.get<number>('healthCheck.duration'),
205229
errorLogAllowedCount: nodeConfig.get<number>(

‎apps/rosen-service/src/constants.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,21 @@ export const BITCOIN_SCANNER_INTERVAL = 10 * 60 * 1000;
66
export const DOGE_SCANNER_INTERVAL = 60 * 1000;
77
export const ETHEREUM_SCANNER_INTERVAL = 60 * 1000;
88
export const BINANCE_SCANNER_INTERVAL = 10 * 1000;
9+
export const FIRO_SCANNER_INTERVAL = 2 * 60 * 1000;
910

1011
export const ERGO_SCANNER_LOGGER_NAME = 'ergoScanner';
1112
export const CARDANO_SCANNER_LOGGER_NAME = 'cardanoScanner';
1213
export const BITCOIN_SCANNER_LOGGER_NAME = 'bitcoinScanner';
1314
export const DOGE_SCANNER_LOGGER_NAME = 'dogeScanner';
1415
export const ETHEREUM_SCANNER_LOGGER_NAME = 'ethereumScanner';
1516
export const BINANCE_SCANNER_LOGGER_NAME = 'binanceScanner';
17+
export const FIRO_SCANNER_LOGGER_NAME = 'firoScanner';
1618
export const ERGO_BLOCK_TIME = 120;
1719
export const CARDANO_BLOCK_TIME = 20;
1820
export const BITCOIN_BLOCK_TIME = 600;
1921
export const ETHEREUM_BLOCK_TIME = 12;
2022
export const BINANCE_BLOCK_TIME = 3;
2123
export const DOGE_BLOCK_TIME = 60;
24+
export const FIRO_BLOCK_TIME = 150;
2225

2326
export const BITCOIN_RUNES_CONFIG_KEY = 'bitcoinRunes';

‎apps/rosen-service/src/event-trigger/event-trigger-service.ts‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ const binanceEventTriggerExtractorLogger = logger.child(
2929
const dogeEventTriggerExtractorLogger = logger.child(
3030
'dogeEventTriggerExtractor',
3131
);
32+
const firoEventTriggerExtractorLogger = logger.child(
33+
'firoEventTriggerExtractor',
34+
);
3235

3336
/**
3437
* register event trigger extractors for all chains
@@ -113,13 +116,25 @@ export const registerExtractors = async (scanner: ErgoScanner) => {
113116
configs.binance.addresses.fraud,
114117
binanceEventTriggerExtractorLogger,
115118
);
119+
const firoEventTriggerExtractor = new EventTriggerExtractor(
120+
'firo-extractor',
121+
dataSource,
122+
ErgoNetworkType.Explorer,
123+
configs.ergo.explorerUrl,
124+
configs.firo.addresses.eventTrigger,
125+
configs.firo.tokens.rwt,
126+
configs.firo.addresses.permit,
127+
configs.firo.addresses.fraud,
128+
firoEventTriggerExtractorLogger,
129+
);
116130
await scanner.registerExtractor(ergoEventTriggerExtractor);
117131
await scanner.registerExtractor(cardanoEventTriggerExtractor);
118132
await scanner.registerExtractor(bitcoinEventTriggerExtractor);
119133
await scanner.registerExtractor(bitcoinRunesEventTriggerExtractor);
120134
await scanner.registerExtractor(dogeEventTriggerExtractor);
121135
await scanner.registerExtractor(ethereumEventTriggerExtractor);
122136
await scanner.registerExtractor(binanceEventTriggerExtractor);
137+
await scanner.registerExtractor(firoEventTriggerExtractor);
123138

124139
logger.debug('event trigger extractors registered', {
125140
scannerName: scanner.name(),
@@ -131,6 +146,7 @@ export const registerExtractors = async (scanner: ErgoScanner) => {
131146
dogeEventTriggerExtractor.getId(),
132147
ethereumEventTriggerExtractor.getId(),
133148
binanceEventTriggerExtractor.getId(),
149+
firoEventTriggerExtractor.getId(),
134150
],
135151
});
136152
} catch (error) {

‎apps/rosen-service/src/health-check/health-check-service.ts‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import {
2121
ERGO_SCANNER_INTERVAL,
2222
ETHEREUM_BLOCK_TIME,
2323
ETHEREUM_SCANNER_INTERVAL,
24+
FIRO_BLOCK_TIME,
25+
FIRO_SCANNER_INTERVAL,
2426
} from '../constants';
2527
import scannerService from '../scanner/scanner-service';
2628
import { getLastSavedBlock } from './health-check-utils';
@@ -131,6 +133,17 @@ const registerAllHealthChecks = (healthCheck: HealthCheck) => {
131133
),
132134
label: 'binance',
133135
},
136+
{
137+
instance: new ScannerSyncHealthCheckParam(
138+
scannerService.getFiroScanner().name(),
139+
async () => getLastSavedBlock(scannerService.getFiroScanner().name()),
140+
config.healthCheck.firoScannerWarnDiff,
141+
config.healthCheck.firoScannerCriticalDiff,
142+
FIRO_BLOCK_TIME,
143+
FIRO_SCANNER_INTERVAL,
144+
),
145+
label: 'firo',
146+
},
134147
];
135148

136149
for (const { instance, label } of checks) {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { DefaultLogger } from '@rosen-bridge/abstract-logger';
2+
import { FiroRpcObservationExtractor } from '@rosen-bridge/firo-observation-extractor';
3+
import { FiroRpcScanner } from '@rosen-bridge/firo-scanner';
4+
5+
import config from '../../configs';
6+
import dataSource from '../../data-source';
7+
import AppError from '../../errors/AppError';
8+
import { getTokenMap } from '../../utils';
9+
10+
const logger = DefaultLogger.getInstance().child(import.meta.url);
11+
12+
/**
13+
* register an observation extractor for the provided scanner
14+
* @param scanner
15+
*/
16+
export const registerFiroExtractor = async (scanner: FiroRpcScanner) => {
17+
try {
18+
const observationExtractor = new FiroRpcObservationExtractor(
19+
config.firo.addresses.lock,
20+
dataSource,
21+
await getTokenMap(),
22+
logger.child('firoRpcObservationExtractor'),
23+
);
24+
25+
await scanner.registerExtractor(observationExtractor);
26+
27+
logger.debug('firo observation extractor registered', {
28+
scannerName: scanner.name(),
29+
});
30+
} catch (error) {
31+
throw new AppError(
32+
`cannot create or register firo observation extractor due to error: ${error}`,
33+
false,
34+
'error',
35+
error instanceof Error ? error.stack : undefined,
36+
{
37+
scannerName: scanner.name(),
38+
},
39+
);
40+
}
41+
};

‎apps/rosen-service/src/observation/observation-service.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { registerCardanoExtractor } from './chains/cardano';
55
import { registerDogeExtractor } from './chains/doge';
66
import { registerErgoExtractor } from './chains/ergo';
77
import { registerEthereumExtractor } from './chains/ethereum';
8+
import { registerFiroExtractor } from './chains/firo';
89

910
const observationService = {
1011
registerBitcoinExtractor,
@@ -14,6 +15,7 @@ const observationService = {
1415
registerErgoExtractor,
1516
registerEthereumExtractor,
1617
registerBinanceExtractor,
18+
registerFiroExtractor,
1719
};
1820

1921
export default observationService;

0 commit comments

Comments
 (0)