Skip to content

Instantly share code, notes, and snippets.

@timfong888
Created May 30, 2023 18:33
Show Gist options
  • Save timfong888/62d037da405512c62a7b226f0272f664 to your computer and use it in GitHub Desktop.
Save timfong888/62d037da405512c62a7b226f0272f664 to your computer and use it in GitHub Desktop.
Trying to figure out why mnemonic isn't working as an ENV variable
1 "use strict";
2 var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4 return new (P || (P = Promise))(function (resolve, reject) {
5 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8 step((generator = generator.apply(thisArg, _arguments || [])).next());
9 });
10 };
11 var __importDefault = (this && this.__importDefault) || function (mod) {
12 return (mod && mod.__esModule) ? mod : { "default": mod };
13 };
14 Object.defineProperty(exports, "__esModule", { value: true });
15 const fs_1 = __importDefault(require("fs"));
16 const path_1 = __importDefault(require("path"));
17 const yaml_1 = require("yaml");
18 const umzug_1 = require("umzug");
19 const common_ts_1 = require("@graphprotocol/common-ts");
20 const indexer_common_1 = require("@graphprotocol/indexer-common");
21 const agent_1 = require("../agent");
22 const indexer_1 = require("../indexer");
23 const ethers_1 = require("ethers");
24 const cost_1 = require("../cost");
25 const syncing_server_1 = require("../syncing-server");
26 const utils_1 = require("../utils");
27 exports.default = {
28 command: 'start',
29 describe: 'Start the agent',
30 builder: (yargs) => {
31 return yargs
32 .option('ethereum', {
33 description: 'Ethereum node or provider URL',
34 type: 'string',
35 required: true,
36 group: 'Ethereum',
37 })
38 .option('ethereum-polling-interval', {
39 description: 'Polling interval for the Ethereum provider (ms)',
40 type: 'number',
41 default: 4000,
42 group: 'Ethereum',
43 })
44 .option('gas-increase-timeout', {
45 description: 'Time (in seconds) after which transactions will be resubmitted with a higher gas price',
46 type: 'number',
47 default: 240,
48 group: 'Ethereum',
49 coerce: arg => arg * 1000,
50 })
51 .option('gas-increase-factor', {
52 description: 'Factor by which gas prices are increased when resubmitting transactions',
53 type: 'number',
54 default: 1.2,
55 group: 'Ethereum',
56 })
57 .option('gas-price-max', {
58 description: 'The maximum gas price (gwei) to use for transactions',
59 type: 'number',
60 default: 100,
61 deprecated: true,
62 group: 'Ethereum',
63 coerce: arg => arg * Math.pow(10, 9),
64 })
65 .option('base-fee-per-gas-max', {
66 description: 'The maximum base fee per gas (gwei) to use for transactions, for legacy transactions this will be treated as the max gas price',
67 type: 'number',
68 required: false,
69 group: 'Ethereum',
70 coerce: arg => arg * Math.pow(10, 9),
71 })
72 .option('transaction-attempts', {
73 description: 'The maximum number of transaction attempts (Use 0 for unlimited)',
74 type: 'number',
75 default: 0,
76 group: 'Ethereum',
77 })
78 .option('mnemonic', {
79 description: 'Mnemonic for the operator wallet',
80 type: 'string',
81 required: true,
82 group: 'Ethereum',
83 })
84 .option('indexer-address', {
85 description: 'Ethereum address of the indexer',
86 type: 'string',
87 required: true,
88 group: 'Ethereum',
89 })
90 .option('graph-node-query-endpoint', {
91 description: 'Graph Node endpoint for querying subgraphs',
92 type: 'string',
93 required: true,
94 group: 'Indexer Infrastructure',
95 })
96 .option('graph-node-status-endpoint', {
97 description: 'Graph Node endpoint for indexing statuses etc.',
98 type: 'string',
99 required: true,
100 group: 'Indexer Infrastructure',
101 })
102 .option('graph-node-admin-endpoint', {
103 description: 'Graph Node endpoint for applying and updating subgraph deployments',
104 type: 'string',
105 required: true,
106 group: 'Indexer Infrastructure',
107 })
108 .option('public-indexer-url', {
109 description: 'Indexer endpoint for receiving requests from the network',
110 type: 'string',
111 required: true,
112 group: 'Indexer Infrastructure',
113 })
114 .options('indexer-geo-coordinates', {
115 description: `Coordinates describing the Indexer's location using latitude and longitude`,
116 type: 'string',
117 array: true,
118 default: ['31.780715', '-41.179504'],
119 group: 'Indexer Infrastructure',
120 coerce: arg => arg.reduce((acc, value) => [...acc, ...value.split(' ')], []),
121 })
122 .option('network-subgraph-deployment', {
123 description: 'Network subgraph deployment',
124 type: 'string',
125 group: 'Network Subgraph',
126 })
127 .option('network-subgraph-endpoint', {
128 description: 'Endpoint to query the network subgraph from',
129 type: 'string',
130 group: 'Network Subgraph',
131 })
132 .option('allocate-on-network-subgraph', {
133 description: 'Whether to allocate to the network subgraph',
134 type: 'boolean',
135 default: false,
136 group: 'Network Subgraph',
137 })
138 .option('epoch-subgraph-endpoint', {
139 description: 'Endpoint to query the epoch block oracle subgraph from',
140 type: 'string',
141 required: true,
142 group: 'Protocol',
143 })
144 .option('index-node-ids', {
145 description: 'Node IDs of Graph nodes to use for indexing (separated by commas)',
146 type: 'string',
147 array: true,
148 required: true,
149 coerce: arg => arg.reduce((acc, value) => [...acc, ...value.split(',')], []),
150 group: 'Indexer Infrastructure',
151 })
152 .option('default-allocation-amount', {
153 description: 'Default amount of GRT to allocate to a subgraph deployment',
154 type: 'string',
155 default: '0.01',
156 required: false,
157 group: 'Protocol',
158 coerce: arg => (0, common_ts_1.parseGRT)(arg),
159 })
160 .option('indexer-management-port', {
161 description: 'Port to serve the indexer management API at',
162 type: 'number',
163 default: 8000,
164 required: false,
165 group: 'Indexer Infrastructure',
166 })
167 .option('metrics-port', {
168 description: 'Port to serve Prometheus metrics at',
169 type: 'number',
170 defaut: 7300,
171 required: false,
172 group: 'Indexer Infrastructure',
173 })
174 .option('syncing-port', {
175 description: 'Port to serve the network subgraph and other syncing data for indexer service at',
176 type: 'number',
177 default: 8002,
178 required: false,
179 group: 'Indexer Infrastructure',
180 })
181 .option('restake-rewards', {
182 description: `Restake claimed indexer rewards, if set to 'false' rewards will be returned to the wallet`,
183 type: 'boolean',
184 default: true,
185 group: 'Indexer Infrastructure',
186 })
187 .option('rebate-claim-threshold', {
188 description: `Minimum value of rebate for a single allocation (in GRT) in order for it to be included in a batch rebate claim on-chain`,
189 type: 'string',
190 default: '200',
191 group: 'Query Fees',
192 coerce: arg => (0, common_ts_1.parseGRT)(arg),
193 })
194 .option('rebate-claim-batch-threshold', {
195 description: `Minimum total value of all rebates in an batch (in GRT) before the batch is claimed on-chain`,
196 type: 'string',
197 default: '2000',
198 group: 'Query Fees',
199 coerce: arg => (0, common_ts_1.parseGRT)(arg),
200 })
201 .option('rebate-claim-max-batch-size', {
202 description: `Maximum number of rebates inside a batch. Upper bound is constrained by available system memory, and by the block gas limit`,
203 type: 'number',
204 default: 100,
205 group: 'Query Fees',
206 })
207 .option('voucher-redemption-threshold', {
208 description: `Minimum value of rebate for a single allocation (in GRT) in order for it to be included in a batch rebate claim on-chain`,
209 type: 'string',
210 default: '200',
211 group: 'Query Fees',
212 coerce: arg => (0, common_ts_1.parseGRT)(arg),
213 })
214 .option('voucher-redemption-batch-threshold', {
215 description: `Minimum total value of all rebates in an batch (in GRT) before the batch is claimed on-chain`,
216 type: 'string',
217 default: '2000',
218 group: 'Query Fees',
219 coerce: arg => (0, common_ts_1.parseGRT)(arg),
220 })
221 .option('voucher-redemption-max-batch-size', {
222 description: `Maximum number of rebates inside a batch. Upper bound is constrained by available system memory, and by the block gas limit`,
223 type: 'number',
224 default: 100,
225 group: 'Query Fees',
226 })
227 .option('inject-dai', {
228 description: 'Inject the GRT to DAI/USDC conversion rate into cost model variables',
229 type: 'boolean',
230 default: true,
231 group: 'Cost Models',
232 })
233 .option('dai-contract', {
234 description: 'Address of the DAI or USDC contract to use for the --inject-dai conversion rate',
235 type: 'string',
236 // Default to USDC
237 default: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
238 })
239 .option('postgres-host', {
240 description: 'Postgres host',
241 type: 'string',
242 required: true,
243 group: 'Postgres',
244 })
245 .option('postgres-port', {
246 description: 'Postgres port',
247 type: 'number',
248 default: 5432,
249 group: 'Postgres',
250 })
251 .option('postgres-username', {
252 description: 'Postgres username',
253 type: 'string',
254 required: false,
255 default: 'postgres',
256 group: 'Postgres',
257 })
258 .option('postgres-password', {
259 description: 'Postgres password',
260 type: 'string',
261 default: '',
262 required: false,
263 group: 'Postgres',
264 })
265 .option('postgres-database', {
266 description: 'Postgres database name',
267 type: 'string',
268 required: true,
269 group: 'Postgres',
270 })
271 .option('log-level', {
272 description: 'Log level',
273 type: 'string',
274 default: 'debug',
275 group: 'Indexer Infrastructure',
276 })
277 .option('register', {
278 description: 'Whether to register the indexer on chain',
279 type: 'boolean',
280 default: true,
281 group: 'Protocol',
282 })
283 .option('offchain-subgraphs', {
284 description: 'Subgraphs to index that are not on chain (comma-separated)',
285 type: 'string',
286 array: true,
287 default: [],
288 coerce: arg => arg
289 .reduce((acc, value) => [...acc, ...value.split(',')], [])
290 .map((id) => id.trim())
291 .filter((id) => id.length > 0),
292 })
293 .option('poi-disputable-epochs', {
294 description: 'The number of epochs in the past to look for potential POI disputes',
295 type: 'number',
296 default: 1,
297 group: 'Disputes',
298 })
299 .option('poi-dispute-monitoring', {
300 description: 'Monitor the network for potential POI disputes',
301 type: 'boolean',
302 default: false,
303 group: 'Disputes',
304 })
305 .check(argv => {
306 if (!argv['network-subgraph-endpoint'] &&
307 !argv['network-subgraph-deployment']) {
308 return `At least one of --network-subgraph-endpoint and --network-subgraph-deployment must be provided`;
309 }
310 if (argv['indexer-geo-coordinates']) {
311 const [geo1, geo2] = argv['indexer-geo-coordinates'];
312 if (!+geo1 || !+geo2) {
313 return 'Invalid --indexer-geo-coordinates provided. Must be of format e.g.: 31.780715 -41.179504';
314 }
315 }
316 if (argv['gas-increase-timeout']) {
317 if (argv['gas-increase-timeout'] < 30000) {
318 return 'Invalid --gas-increase-timeout provided. Must be at least 30 seconds';
319 }
320 }
321 if (argv['gas-increase-factor'] <= 1.0) {
322 return 'Invalid --gas-increase-factor provided. Must be > 1.0';
323 }
324 if (!Number.isInteger(argv['rebate-claim-max-batch-size']) ||
325 argv['rebate-claim-max-batch-size'] <= 0) {
326 return 'Invalid --rebate-claim-max-batch-size provided. Must be > 0 and an integer.';
327 }
328 return true;
329 })
330 .option('collect-receipts-endpoint', {
331 description: 'Client endpoint for collecting receipts',
332 type: 'string',
333 required: false,
334 group: 'Query Fees',
335 })
336 .option('allocation-management', {
337 description: 'Indexer agent allocation management automation mode (auto|manual) ',
338 type: 'string',
339 required: false,
340 default: 'auto',
341 group: 'Indexer Infrastructure',
342 })
343 .option('auto-allocation-min-batch-size', {
344 description: `Minimum number of allocation transactions inside a batch for auto allocation management. No obvious upperbound, with default of 1`,
345 type: 'number',
346 default: 1,
347 group: 'Indexer Infrastructure',
348 })
349 .config({
350 key: 'config-file',
351 description: 'Indexer agent configuration file (YAML format)',
352 parseFn: function (cfgFilePath) {
353 return (0, yaml_1.parse)(fs_1.default.readFileSync(cfgFilePath, 'utf-8'));
354 },
355 });
356 },
357 handler: (
358 // eslint-disable-next-line @typescript-eslint/no-explicit-any
359 argv) => __awaiter(void 0, void 0, void 0, function* () {
360 const logger = (0, common_ts_1.createLogger)({
361 name: 'IndexerAgent',
362 async: false,
363 level: argv.logLevel,
364 });
365 if (argv.gasIncreaseTimeout < 90000) {
366 logger.warn('Gas increase timeout is set to less than 90 seconds (~ 6 blocks). This may lead to high gas usage', { gasIncreaseTimeout: argv.gasIncreaseTimeout / 1000.0 });
367 }
368 if (argv.gasIncreaseFactor > 1.5) {
369 logger.warn(`Gas increase factor is set to > 1.5. This may lead to high gas usage`, { gasIncreaseFactor: argv.gasIncreaseFactor });
370 }
371 if (argv.rebateClaimThreshold.lt(argv.voucherRedemptionThreshold)) {
372 logger.warn(`Rebate single minimum claim value is less than voucher minimum redemption value, but claims depend on redemptions`, {
373 voucherRedemptionThreshold: (0, common_ts_1.formatGRT)(argv.voucherRedemptionThreshold),
374 rebateClaimThreshold: (0, common_ts_1.formatGRT)(argv.rebateClaimThreshold),
375 });
376 }
377 if (argv.rebateClaimThreshold.eq(0)) {
378 logger.warn(`Minimum query fee rebate value is 0 GRT, which may lead to claiming unprofitable rebates`);
379 }
380 if (argv.rebateClaimMaxBatchSize > 200) {
381 logger.warn(`Setting the max batch size for rebate claims to more than 200 may result in batches that are too large to fit into a block`, { rebateClaimMaxBatchSize: argv.rebateClaimMaxBatchSize });
382 }
383 if (argv.voucherRedemptionThreshold.eq(0)) {
384 logger.warn(`Minimum voucher redemption value is 0 GRT, which may lead to redeeming unprofitable vouchers`);
385 }
386 if (argv.voucherRedemptionMaxBatchSize > 200) {
387 logger.warn(`Setting the max batch size for voucher redemptions to more than 200 may result in batches that are too large to fit into a block`, { voucherRedemptionMaxBatchSize: argv.voucherRedemptionMaxBatchSize });
388 }
389 process.on('unhandledRejection', err => {
390 logger.warn(`Unhandled promise rejection`, {
391 err: (0, indexer_common_1.indexerError)(indexer_common_1.IndexerErrorCode.IE035, err),
392 });
393 });
394 process.on('uncaughtException', err => {
395 logger.warn(`Uncaught exception`, {
396 err: (0, indexer_common_1.indexerError)(indexer_common_1.IndexerErrorCode.IE036, err),
397 });
398 });
399 // Spin up a metrics server
400 const metrics = (0, common_ts_1.createMetrics)();
401 (0, common_ts_1.createMetricsServer)({
402 logger: logger.child({ component: 'MetricsServer' }),
403 registry: metrics.registry,
404 port: argv.metricsPort,
405 });
406 // Register indexer error metrics so we can track any errors that happen
407 // inside the agent
408 (0, indexer_common_1.registerIndexerErrorMetrics)(metrics);
409 const indexingStatusResolver = new indexer_common_1.IndexingStatusResolver({
410 logger: logger,
411 statusEndpoint: argv.graphNodeStatusEndpoint,
412 });
413 // Parse the Network Subgraph optional argument
414 const networkSubgraphDeploymentId = argv.networkSubgraphDeployment
415 ? new common_ts_1.SubgraphDeploymentID(argv.networkSubgraphDeployment)
416 : undefined;
417 const networkSubgraph = yield indexer_common_1.NetworkSubgraph.create({
418 logger,
419 endpoint: argv.networkSubgraphEndpoint,
420 deployment: networkSubgraphDeploymentId !== undefined
421 ? {
422 indexingStatusResolver: indexingStatusResolver,
423 deployment: networkSubgraphDeploymentId,
424 graphNodeQueryEndpoint: argv.graphNodeQueryEndpoint,
425 }
426 : undefined,
427 });
428 const networkProvider = yield indexer_common_1.Network.provider(logger, metrics, argv.ethereum, argv.ethereumPollingInterval);
429 const networkMeta = yield networkProvider.getNetwork();
430 logger.info(`Connect to contracts`, {
431 network: networkMeta.name,
432 chainId: networkMeta.chainId,
433 providerNetworkChainID: networkProvider.network.chainId,
434 });
435 logger.info(`Connect wallet`, {
436 network: networkMeta.name,
437 chainId: networkMeta.chainId,
438 });
439 let wallet = ethers_1.Wallet.fromMnemonic(argv.mnemonic);
440 wallet = wallet.connect(networkProvider);
441 logger.info(`Connected wallet`);
442 let contracts = undefined;
443 try {
444 contracts = yield (0, common_ts_1.connectContracts)(wallet, networkMeta.chainId);
445 }
446 catch (err) {
447 logger.error(`Failed to connect to contracts, please ensure you are using the intended Ethereum network`, {
448 err,
449 });
450 process.exit(1);
451 }
452 logger.info(`Successfully connected to contracts`, {
453 curation: contracts.curation.address,
454 disputeManager: contracts.disputeManager.address,
455 epochManager: contracts.epochManager.address,
456 gns: contracts.gns.address,
457 rewardsManager: contracts.rewardsManager.address,
458 serviceRegistry: contracts.serviceRegistry.address,
459 staking: contracts.staking.address,
460 token: contracts.token.address,
461 });
462 const indexerAddress = (0, common_ts_1.toAddress)(argv.indexerAddress);
463 const epochSubgraph = yield indexer_common_1.EpochSubgraph.create(argv.epochSubgraphEndpoint);
464 const networkMonitor = new indexer_common_1.NetworkMonitor((0, indexer_common_1.resolveChainId)(networkMeta.chainId), contracts, (0, common_ts_1.toAddress)(indexerAddress), logger.child({ component: 'NetworkMonitor' }), indexingStatusResolver, networkSubgraph, networkProvider, epochSubgraph);
465 logger.info('Connect to database', {
466 host: argv.postgresHost,
467 port: argv.postgresPort,
468 database: argv.postgresDatabase,
469 });
470 const sequelize = yield (0, common_ts_1.connectDatabase)({
471 logging: undefined,
472 host: argv.postgresHost,
473 port: argv.postgresPort,
474 username: argv.postgresUsername,
475 password: argv.postgresPassword,
476 database: argv.postgresDatabase,
477 });
478 logger.info('Successfully connected to database');
479 // Automatic database migrations
480 logger.info(`Run database migrations`);
481 // If the application is being executed using ts-node __dirname may be in /src rather than /dist
482 const migrations_path = __dirname.includes('dist')
483 ? path_1.default.join(__dirname, '..', 'db', 'migrations', '*.js')
484 : path_1.default.join(__dirname, '..', '..', 'dist', 'db', 'migrations', '*.js');
485 try {
486 const umzug = new umzug_1.Umzug({
487 migrations: {
488 glob: migrations_path,
489 },
490 context: {
491 queryInterface: sequelize.getQueryInterface(),
492 logger,
493 indexingStatusResolver,
494 graphNodeAdminEndpoint: argv.graphNodeAdminEndpoint,
495 networkMonitor,
496 },
497 storage: new umzug_1.SequelizeStorage({ sequelize }),
498 logger: console,
499 });
500 const pending = yield umzug.pending();
501 const executed = yield umzug.executed();
502 logger.debug(`Migrations status`, { pending, executed });
503 yield umzug.up();
504 }
505 catch (err) {
506 logger.fatal(`Failed to run database migrations`, {
507 err: (0, indexer_common_1.indexerError)(indexer_common_1.IndexerErrorCode.IE001, err),
508 });
509 process.exit(1);
510 }
511 logger.info(`Successfully ran database migrations`);
512 logger.info(`Sync database models`);
513 const managementModels = (0, indexer_common_1.defineIndexerManagementModels)(sequelize);
514 const queryFeeModels = (0, indexer_common_1.defineQueryFeeModels)(sequelize);
515 yield sequelize.sync();
516 logger.info(`Successfully synced database models`);
517 logger.info('Connect to network');
518 const maxGasFee = argv.baseFeeGasMax || argv.gasPriceMax;
519 const network = yield indexer_common_1.Network.create(logger, networkProvider, contracts, wallet, indexerAddress, argv.publicIndexerUrl, argv.indexerGeoCoordinates, networkSubgraph, argv.restakeRewards, argv.rebateClaimThreshold, argv.rebateClaimBatchThreshold, argv.rebateClaimMaxBatchSize, argv.poiDisputeMonitoring, argv.poiDisputableEpochs, argv.gasIncreaseTimeout, argv.gasIncreaseFactor, maxGasFee, argv.transactionAttempts);
520 logger.info('Successfully connected to network', {
521 restakeRewards: argv.restakeRewards,
522 });
523 const receiptCollector = new indexer_common_1.AllocationReceiptCollector({
524 logger,
525 metrics,
526 transactionManager: network.transactionManager,
527 models: queryFeeModels,
528 allocationExchange: network.contracts.allocationExchange,
529 collectEndpoint: argv.collectReceiptsEndpoint,
530 voucherRedemptionThreshold: argv.voucherRedemptionThreshold,
531 voucherRedemptionBatchThreshold: argv.voucherRedemptionBatchThreshold,
532 voucherRedemptionMaxBatchSize: argv.voucherRedemptionMaxBatchSize,
533 });
534 yield receiptCollector.queuePendingReceiptsFromDatabase();
535 logger.info('Launch indexer management API server');
536 const allocationManagementMode = indexer_common_1.AllocationManagementMode[argv.allocationManagement.toUpperCase()];
537 const indexerManagementClient = yield (0, indexer_common_1.createIndexerManagementClient)({
538 models: managementModels,
539 address: indexerAddress,
540 contracts,
541 indexingStatusResolver,
542 indexNodeIDs: argv.indexNodeIds,
543 deploymentManagementEndpoint: argv.graphNodeAdminEndpoint,
544 networkSubgraph,
545 logger,
546 defaults: {
547 globalIndexingRule: {
548 allocationAmount: argv.defaultAllocationAmount,
549 parallelAllocations: 1,
550 },
551 },
552 features: {
553 injectDai: argv.injectDai,
554 },
555 transactionManager: network.transactionManager,
556 receiptCollector,
557 networkMonitor,
558 allocationManagementMode,
559 autoAllocationMinBatchSize: argv.autoAllocationMinBatchSize,
560 });
561 yield (0, indexer_common_1.createIndexerManagementServer)({
562 logger,
563 client: indexerManagementClient,
564 port: argv.indexerManagementPort,
565 });
566 logger.info(`Successfully launched indexer management API server`);
567 const indexer = new indexer_1.Indexer(logger, argv.graphNodeAdminEndpoint, indexingStatusResolver, indexerManagementClient, argv.indexNodeIds, argv.defaultAllocationAmount, indexerAddress, allocationManagementMode);
568 if (networkSubgraphDeploymentId !== undefined) {
569 // Make sure the network subgraph is being indexed
570 yield indexer.ensure(`indexer-agent/${networkSubgraphDeploymentId.ipfsHash.slice(-10)}`, networkSubgraphDeploymentId);
571 // Validate if the Network Subgraph belongs to the current provider's network.
572 // This check must be performed after we ensure the Network Subgraph is being indexed.
573 try {
574 yield validateNetworkId(networkMeta, argv.networkSubgraphDeployment, indexingStatusResolver, logger);
575 }
576 catch (e) {
577 logger.critical('Failed to validate Network Subgraph. Exiting.', e);
578 process.exit(1);
579 }
580 }
581 // Monitor ETH balance of the operator and write the latest value to a metric
582 yield (0, utils_1.monitorEthBalance)(logger, wallet, metrics);
583 logger.info(`Launch syncing server`);
584 yield (0, syncing_server_1.createSyncingServer)({
585 logger,
586 networkSubgraph,
587 port: argv.syncingPort,
588 });
589 logger.info(`Successfully launched syncing server`);
590 (0, cost_1.startCostModelAutomation)({
591 logger,
592 ethereum: networkProvider,
593 contracts: network.contracts,
594 indexerManagement: indexerManagementClient,
595 injectDai: argv.injectDai,
596 daiContractAddress: (0, common_ts_1.toAddress)(argv.daiContract),
597 metrics,
598 });
599 yield (0, agent_1.startAgent)({
600 logger,
601 metrics,
602 indexer,
603 network,
604 networkMonitor,
605 networkSubgraph,
606 allocateOnNetworkSubgraph: argv.allocateOnNetworkSubgraph,
607 registerIndexer: argv.register,
608 offchainSubgraphs: argv.offchainSubgraphs.map((s) => new common_ts_1.SubgraphDeploymentID(s)),
609 receiptCollector,
610 });
611 }),
612 };
613 // Compares the CAIP-2 chain ID between the Ethereum provider and the Network Subgraph and requires
614 // they are equal.
615 function validateNetworkId(providerNetwork, networkSubgraphDeploymentIpfsHash, indexingStatusResolver, logger) {
616 return __awaiter(this, void 0, void 0, function* () {
617 const subgraphNetworkId = new common_ts_1.SubgraphDeploymentID(networkSubgraphDeploymentIpfsHash);
618 const { network: subgraphNetworkChainName } = yield indexingStatusResolver.subgraphFeatures(subgraphNetworkId);
619 if (!subgraphNetworkChainName) {
620 // This is unlikely to happen because we expect that the Network Subgraph manifest is valid.
621 const errorMsg = 'Failed to fetch the networkId for the Network Subgraph';
622 logger.error(errorMsg, { networkSubgraphDeploymentIpfsHash });
623 throw new Error(errorMsg);
624 }
625 const providerChainId = (0, indexer_common_1.resolveChainId)(providerNetwork.chainId);
626 const networkSubgraphChainId = (0, indexer_common_1.resolveChainId)(subgraphNetworkChainName);
627 if (providerChainId !== networkSubgraphChainId) {
628 const errorMsg = 'The configured provider and the Network Subgraph have different CAIP-2 chain IDs. ' +
629 'Please ensure that both Network Subgraph and the Ethereum provider are correctly configured.';
630 logger.error(errorMsg, {
631 networkSubgraphDeploymentIpfsHash,
632 networkSubgraphChainId,
633 providerChainId,
634 });
635 throw new Error(errorMsg);
636 }
637 });
638 }
639 //# sourceMappingURL=start.js.map
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment