Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ MONGO_REPLICASET=
# Ethereum RPC
ETH_RPC_URL=http://10.1.200.113:8545
ETH_WS_URL=ws://10.1.200.113:8546
# Max time (ms) for a single JSON-RPC request before timing out (slow nodes / large blocks)
ETH_RPC_TIMEOUT_MS=120000

# Chain
CHAIN_ID=1
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@missionsquad/agentindex-api",
"version": "1.5.1",
"version": "1.5.2",
"description": "AgentIndex blockchain scanner API",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand Down
4 changes: 4 additions & 0 deletions src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ export const env = {
// Ethereum RPC
ETH_RPC_URL: process.env.ETH_RPC_URL || '',
ETH_WS_URL: process.env.ETH_WS_URL || '',
// Max time (ms) for a single JSON-RPC request to the Ethereum node before timing
// out. Applied to evmdecoder's HTTP transport (node-fetch request timeout AND the
// keep-alive agent socket timeout). Raise for slow nodes / large blocks.
ETH_RPC_TIMEOUT_MS: parseInt(process.env.ETH_RPC_TIMEOUT_MS || '120000', 10),

// Chain
CHAIN_ID: parseInt(process.env.CHAIN_ID || '1', 10),
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ async function startServer(): Promise<void> {
rpcUrl: chainConfig.rpcUrl,
abiDirectory: env.ABI_DIRECTORY,
txConcurrency: env.SCANNER_TX_CONCURRENCY,
rpcTimeoutMs: env.ETH_RPC_TIMEOUT_MS,
onEventFactsPersisted: (eventFacts) => {
void publishDashboardActivityFromPersistedEventFacts(eventFacts).catch((error) => {
log({ level: 'warn', msg: 'Failed to publish dashboard activity websocket events', error })
Expand Down
8 changes: 8 additions & 0 deletions src/services/scanner.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ interface ScannerOptions {
rpcUrl: string
abiDirectory?: string
txConcurrency?: number
rpcTimeoutMs?: number
onEventFactsPersisted?: (eventFacts: EventFact[]) => void
}

Expand All @@ -49,6 +50,7 @@ export class ScannerService {
private readonly rpcUrl: string
private readonly abiDirectory: string | undefined
private readonly txConcurrency: number
private readonly rpcTimeoutMs: number
private readonly onEventFactsPersisted?: (eventFacts: EventFact[]) => void
private readonly inFlightTx = new Map<string, Promise<void>>()

Expand All @@ -58,13 +60,19 @@ export class ScannerService {
this.rpcUrl = opts.rpcUrl
this.abiDirectory = opts.abiDirectory
this.txConcurrency = Math.max(1, opts.txConcurrency ?? 8)
this.rpcTimeoutMs = Math.max(1000, opts.rpcTimeoutMs ?? 120_000)
this.onEventFactsPersisted = opts.onEventFactsPersisted
}

async initialize(): Promise<void> {
const config: DeepPartial<Config> = {
eth: {
url: this.rpcUrl,
http: {
// Configurable RPC request timeout. evmdecoder >= 0.0.70 propagates this to
// both the node-fetch request timeout and the keep-alive agent socket timeout.
timeout: this.rpcTimeoutMs,
},
},
abi: {
decodeAnonymous: true,
Expand Down
Loading