Effect.gen(function* (_) {
const block = yield* _(
Effect.retry(
Effect.tryPromise(() => {
return viem.request({
method: 'eth_getBlockByNumber',
params: [toHex(blockNumber), true],
});
}),
Schedule.intersect(Schedule.jittered(Schedule.exponential(1000)), Schedule.recurs(5)),
),
);
if (!block) return yield* _(Effect.fail(new Error(`Block ${blockNumber} not found`)));
const transactions = yield* _(
Effect.forEach(
block.transactions as RpcTransaction[],
tx => {
return Effect.gen(function* (_) {
const receipt = yield* _(
Effect.retry(
Effect.tryPromise(() => {
return viem.request({
params: [tx.hash],
method: 'eth_getTransactionReceipt',
});
}),
Schedule.intersect(Schedule.jittered(Schedule.exponential(1000)), Schedule.recurs(5)),
),
);
if (!receipt) return yield* _(Effect.fail(new Error(`No transaction`)));
return yield* _(Effect.succeed({ ...tx, ...receipt }));
});
},
{ concurrency: 30 },
),
);
return yield* _(Effect.succeed({ ...block, transactions }));
})
Effect.gen(function* (_) {
const block = yield* _(
Effect.retry(
Effect.tryPromise(() => {
return viem.request({
method: 'eth_getBlockByNumber',
params: [toHex(blockNumber), true],
});
}),
Schedule.intersect(Schedule.jittered(Schedule.exponential(1000)), Schedule.recurs(5)),
),
);
if (!block) return yield* _(Effect.fail(new Error(`Block ${blockNumber} not found`)));
const transactions = yield* _(
Effect.forEach(
block.transactions as RpcTransaction[],
tx => {
return Effect.gen(function* (_) {
const receipt = yield* _(
Effect.retry(
Effect.tryPromise(() => {
return viem.request({
params: [tx.hash],
method: 'eth_getTransactionReceipt',
});
}),
Schedule.intersect(Schedule.jittered(Schedule.exponential(1000)), Schedule.recurs(5)),
),
);
if (!receipt) return yield* _(Effect.fail(new Error(`No transaction`)));
return yield* _(Effect.succeed({ ...tx, ...receipt }));
});
},
{ concurrency: 30 },
),
);
return yield* _(Effect.succeed({ ...block, transactions }));
})