-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.ts
157 lines (130 loc) · 4.3 KB
/
main.ts
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import { FetcherMsI } from './interface.js'
import {
AddAccountEntityRequestArgs,
BlockchainFetcherI,
DelAccountEntityRequestArgs,
GetAccountEntityStateRequestArgs,
AccountEntityHistoryState,
CheckEntityRequestArgs,
EntityState,
DelEntityRequestArgs,
FetcherStateRequestArgs,
FetcherState,
FetchAccountEntitiesByDateRequestArgs,
FetchEntitiesByIdRequestArgs,
} from './src/types.js'
import { FetcherMsClient } from './client.js'
import { InvokeBlockchainMethodRequestArgs } from '../types.js'
import { Blockchain } from '../../types.js'
/**
* The main class of the fetcher service.
*/
export class FetcherMsMain implements FetcherMsI {
protected inited = false
/**
* Initialize the fetcher service.
* @param fetcherClient The fetcher ms client.
* @param blockchains A dictionary of instances that implements BlockchainFetcherI interface
*/
constructor(
protected fetcherClient: FetcherMsClient,
protected blockchains: Record<Blockchain, BlockchainFetcherI>,
) {}
/**
* Initialize the fetcher service.
* First fetches pending transactions and parses them, then loads existing
* requests to the service.
*/
async start(): Promise<void> {
if (this.inited) return
this.inited = true
await Promise.all(
Object.values(this.blockchains).map((fetcher) => fetcher.start()),
)
}
async stop(): Promise<void> {
if (!this.inited) return
this.inited = false
await Promise.all(
Object.values(this.blockchains).map((fetcher) => fetcher.stop()),
)
}
getAllFetchers(): string[] {
return this.fetcherClient.getAllFetchers()
}
// Account transaction
async addAccountEntityFetcher(
args: AddAccountEntityRequestArgs,
): Promise<void> {
const fetcher = this.getBlockchainInstance(args.blockchainId)
await fetcher.addAccountEntityFetcher(args)
}
async delAccountEntityFetcher(
args: DelAccountEntityRequestArgs,
): Promise<void> {
const fetcher = this.getBlockchainInstance(args.blockchainId)
await fetcher.delAccountEntityFetcher(args)
}
async getAccountEntityFetcherState(
args: GetAccountEntityStateRequestArgs,
): Promise<AccountEntityHistoryState<unknown> | undefined> {
const fetcher = this.getBlockchainInstance(args.blockchainId)
return fetcher.getAccountEntityFetcherState(args)
}
fetchAccountEntitiesByDate(
args: FetchAccountEntitiesByDateRequestArgs,
): Promise<void | AsyncIterable<string[]>> {
const fetcher = this.getBlockchainInstance(args.blockchainId)
return fetcher.fetchAccountEntitiesByDate(args)
}
fetchEntitiesById(args: FetchEntitiesByIdRequestArgs): Promise<void> {
const fetcher = this.getBlockchainInstance(args.blockchainId)
return fetcher.fetchEntitiesById(args)
}
// Transaction specific methods
getEntityState(args: CheckEntityRequestArgs): Promise<EntityState[]> {
const fetcher = this.getBlockchainInstance(args.blockchainId)
return fetcher.getEntityState(args)
}
delEntityCache(args: DelEntityRequestArgs): Promise<void> {
const fetcher = this.getBlockchainInstance(args.blockchainId)
return fetcher.delEntityCache(args)
}
// Extended methods
async getFetcherState(
args: FetcherStateRequestArgs,
): Promise<FetcherState[]> {
const { blockchainId } = args
const blockchains =
blockchainId && blockchainId.length > 0
? blockchainId.map((id) => this.getBlockchainInstance(id))
: Object.values(this.blockchains)
return Promise.all(
blockchains.map((fetcher) => fetcher.getFetcherState(args)),
)
}
async invokeBlockchainMethod<R, A>(
args: InvokeBlockchainMethodRequestArgs<A>,
): Promise<R> {
const { blockchainId, method, args: params } = args
const fetcher = this.getBlockchainInstance(blockchainId)
if (!(method in fetcher)) {
throw new Error(
`Method "${method}" not supported in ${blockchainId} blockchain`,
)
}
return (fetcher as any)[method]({ blockchainId, ...params })
}
protected getBlockchainInstance(
blockchainId: Blockchain,
): BlockchainFetcherI {
const instance = this.blockchains[blockchainId]
if (!instance) {
throw new Error(`${blockchainId} blockchain not supported`)
}
return instance
}
protected getFetcherId(): string {
return this.fetcherClient.getNodeId()
}
}