-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathabi-store.ts
More file actions
69 lines (57 loc) · 2.13 KB
/
abi-store.ts
File metadata and controls
69 lines (57 loc) · 2.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { Context, Effect, RateLimiter, Function, Layer } from 'effect'
import { ContractABI, ContractAbiResolverStrategy, GetContractABIStrategyParams } from './abi-strategy/request-model.js'
export interface AbiParams {
chainID: number
address: string
event?: string | undefined
signature?: string | undefined
}
export interface ContractAbiSuccess {
status: 'success'
result: ContractABI
}
export interface ContractAbiNotFound {
status: 'not-found'
result: null
}
export interface ContractAbiEmpty {
status: 'empty'
result: null
}
export type ContractAbiResult = ContractAbiSuccess | ContractAbiNotFound | ContractAbiEmpty
type ChainOrDefault = number | 'default'
export interface AbiStore {
readonly strategies: Record<ChainOrDefault, readonly ContractAbiResolverStrategy[]>
readonly set: (key: AbiParams, value: ContractAbiResult) => Effect.Effect<void, never>
readonly get: (arg: AbiParams) => Effect.Effect<ContractAbiResult, never>
readonly getMany?: (arg: Array<AbiParams>) => Effect.Effect<Array<ContractAbiResult>, never>
}
export const AbiStore = Context.GenericTag<AbiStore>('@3loop-decoder/AbiStore')
export const make = ({ strategies: strategiesWithoutRateLimit, ...rest }: AbiStore) =>
Effect.gen(function* () {
const strategies = yield* Effect.reduce(
Object.entries(strategiesWithoutRateLimit),
{} as Record<ChainOrDefault, ContractAbiResolverStrategy[]>,
(acc, [chainID, specific]) =>
Effect.gen(function* () {
const all = yield* Effect.forEach(specific, (strategy) =>
Effect.gen(function* () {
const rateLimit = strategy.rateLimit ? yield* RateLimiter.make(strategy.rateLimit) : Function.identity
return yield* Effect.succeed({
...strategy,
resolver: (params: GetContractABIStrategyParams) => strategy.resolver(params).pipe(rateLimit),
})
}),
)
return {
...acc,
[chainID]: all,
}
}),
)
return {
strategies,
...rest,
}
})
export const layer = (args: AbiStore) => Layer.scoped(AbiStore, make(args))