@xyo-network/chain-api 1.15.1 → 1.15.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/node/driver/mongo/MongoMap.d.ts +9 -3
- package/dist/node/driver/mongo/MongoMap.d.ts.map +1 -1
- package/dist/node/helpers/index.d.ts +5 -0
- package/dist/node/helpers/index.d.ts.map +1 -0
- package/dist/node/helpers/initChainId.d.ts +4 -0
- package/dist/node/helpers/initChainId.d.ts.map +1 -0
- package/dist/node/helpers/initEvmProvider.d.ts +11 -0
- package/dist/node/helpers/initEvmProvider.d.ts.map +1 -0
- package/dist/node/helpers/initInfuraProvider.d.ts +6 -0
- package/dist/node/helpers/initInfuraProvider.d.ts.map +1 -0
- package/dist/node/helpers/initJsonRpcProvider.d.ts +6 -0
- package/dist/node/helpers/initJsonRpcProvider.d.ts.map +1 -0
- package/dist/node/index.mjs +197 -42
- package/dist/node/index.mjs.map +1 -1
- package/dist/node/manifest/getLocator.d.ts.map +1 -1
- package/dist/node/server/app.d.ts +2 -1
- package/dist/node/server/app.d.ts.map +1 -1
- package/dist/node/server/routes/addRoutes.d.ts +2 -1
- package/dist/node/server/routes/addRoutes.d.ts.map +1 -1
- package/dist/node/server/routes/healthz/get.d.ts +2 -1
- package/dist/node/server/routes/healthz/get.d.ts.map +1 -1
- package/dist/node/server/routes/rpc/routes/addRpcRoutes.d.ts +2 -1
- package/dist/node/server/routes/rpc/routes/addRpcRoutes.d.ts.map +1 -1
- package/dist/node/server/server.d.ts.map +1 -1
- package/package.json +56 -51
- package/src/driver/mongo/MongoMap.ts +42 -4
- package/src/helpers/index.ts +4 -0
- package/src/helpers/initChainId.ts +20 -0
- package/src/helpers/initEvmProvider.ts +24 -0
- package/src/helpers/initInfuraProvider.ts +27 -0
- package/src/helpers/initJsonRpcProvider.ts +21 -0
- package/src/manifest/getLocator.ts +22 -9
- package/src/manifest/public/Chain.json +52 -15
- package/src/server/app.ts +3 -2
- package/src/server/routes/addRoutes.ts +3 -2
- package/src/server/routes/healthz/get.ts +1 -1
- package/src/server/routes/rpc/routes/addRpcRoutes.ts +6 -5
- package/src/server/server.ts +23 -2
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { assertEx } from '@xylabs/assert'
|
|
2
|
+
import { hexFrom, isHex } from '@xylabs/hex'
|
|
3
|
+
import { isDefined } from '@xylabs/typeof'
|
|
4
|
+
import type { Config } from '@xyo-network/xl1-protocol-sdk'
|
|
5
|
+
|
|
6
|
+
export const canUseChainId = (config: Config): boolean => {
|
|
7
|
+
return isDefined(config.evm.chainId)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const getChainId = (config: Config) => {
|
|
11
|
+
const chainId = assertEx(config.evm.chainId, () => 'Missing config.evm.chainId')
|
|
12
|
+
if (isHex(chainId, { prefix: true })) {
|
|
13
|
+
const hex = hexFrom(chainId)
|
|
14
|
+
const parsed = Number.parseInt(hex, 16)
|
|
15
|
+
return parsed
|
|
16
|
+
} else {
|
|
17
|
+
const parsed = Number.parseInt(chainId, 10)
|
|
18
|
+
return parsed
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { assertEx } from '@xylabs/assert'
|
|
2
|
+
import type { Logger } from '@xylabs/logger'
|
|
3
|
+
import type { Config } from '@xyo-network/xl1-protocol-sdk'
|
|
4
|
+
import type { Provider } from 'ethers'
|
|
5
|
+
import type { JsonRpcProvider } from 'ethers/providers'
|
|
6
|
+
|
|
7
|
+
import { canUseInfuraProvider, initInfuraProvider } from './initInfuraProvider.ts'
|
|
8
|
+
import { canUseJsonRpcProvider, initJsonRpcProvider } from './initJsonRpcProvider.ts'
|
|
9
|
+
|
|
10
|
+
let provider: Promise<JsonRpcProvider> | undefined
|
|
11
|
+
|
|
12
|
+
export const initEvmProvider = async ({ config }: { config: Config; logger?: Logger }): Promise<Provider> => {
|
|
13
|
+
if (provider) return provider
|
|
14
|
+
if (canUseInfuraProvider(config)) {
|
|
15
|
+
provider = initInfuraProvider(config)
|
|
16
|
+
} else if (canUseJsonRpcProvider(config)) {
|
|
17
|
+
provider = initJsonRpcProvider(config)
|
|
18
|
+
}
|
|
19
|
+
return assertEx(await provider, () => 'Error: No provider available')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const canUseEvmProvider = ({ config }: { config: Config }) => {
|
|
23
|
+
return canUseInfuraProvider(config) || canUseJsonRpcProvider(config)
|
|
24
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { assertEx } from '@xylabs/assert'
|
|
2
|
+
import { isDefined } from '@xylabs/typeof'
|
|
3
|
+
import type { Config } from '@xyo-network/xl1-protocol-sdk'
|
|
4
|
+
import { InfuraProvider } from 'ethers/providers'
|
|
5
|
+
|
|
6
|
+
import { canUseChainId, getChainId } from './initChainId.ts'
|
|
7
|
+
|
|
8
|
+
let instance: Promise<InfuraProvider> | undefined
|
|
9
|
+
|
|
10
|
+
export const initInfuraProvider = (config: Config) => {
|
|
11
|
+
if (instance) return instance
|
|
12
|
+
const providerConfig = getInfuraProviderConfig(config)
|
|
13
|
+
instance = Promise.resolve(new InfuraProvider(...providerConfig))
|
|
14
|
+
return instance
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const canUseInfuraProvider = (config: Config): boolean => {
|
|
18
|
+
return canUseChainId(config)
|
|
19
|
+
&& isDefined(config.evm?.infura?.projectId)
|
|
20
|
+
&& isDefined(config.evm?.infura?.projectSecret)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const getInfuraProviderConfig = (config: Config) => {
|
|
24
|
+
const projectId = assertEx(config.evm?.infura?.projectId, () => 'Missing config.evm.infura.projectId')
|
|
25
|
+
const projectSecret = assertEx(config.evm?.infura?.projectSecret, () => 'Missing config.evm.infura.projectSecret')
|
|
26
|
+
return [getChainId(config), projectId, projectSecret] as const
|
|
27
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { assertEx } from '@xylabs/assert'
|
|
2
|
+
import { isDefined } from '@xylabs/typeof'
|
|
3
|
+
import type { Config } from '@xyo-network/xl1-protocol-sdk'
|
|
4
|
+
import { JsonRpcProvider } from 'ethers/providers'
|
|
5
|
+
|
|
6
|
+
import { canUseChainId, getChainId } from './initChainId.ts'
|
|
7
|
+
|
|
8
|
+
export const initJsonRpcProvider = (config: Config) => {
|
|
9
|
+
const providerConfig = getJsonRpcProviderConfig(config)
|
|
10
|
+
return Promise.resolve(new JsonRpcProvider(...providerConfig))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const canUseJsonRpcProvider = (config: Config) => {
|
|
14
|
+
return canUseChainId(config)
|
|
15
|
+
&& isDefined(config.evm.jsonRpc?.url)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const getJsonRpcProviderConfig = (config: Config) => {
|
|
19
|
+
const jsonRpcUrl = assertEx(config.evm.jsonRpc?.url, () => 'Missing config.evm.jsonRpc.url')
|
|
20
|
+
return [jsonRpcUrl, getChainId(config)] as const
|
|
21
|
+
}
|
|
@@ -8,16 +8,17 @@ import { MemoryArchivist } from '@xyo-network/archivist-memory'
|
|
|
8
8
|
import { MongoDBArchivistV2 } from '@xyo-network/archivist-mongodb'
|
|
9
9
|
import { ViewArchivist } from '@xyo-network/archivist-view'
|
|
10
10
|
import {
|
|
11
|
-
AddressBalanceDivinerV2,
|
|
11
|
+
AddressBalanceDivinerV2, AddressTransferDiviner, ArchivistSyncDiviner, HeadValidationDiviner,
|
|
12
12
|
} from '@xyo-network/chain-modules'
|
|
13
|
-
import type { MapType } from '@xyo-network/chain-protocol'
|
|
14
13
|
import { initTelemetry } from '@xyo-network/chain-telemetry'
|
|
15
14
|
import { AbstractModule, LoggerModuleStatusReporter } from '@xyo-network/module-abstract'
|
|
16
15
|
import { ModuleFactoryLocator } from '@xyo-network/module-factory-locator'
|
|
17
16
|
import type { MongoDBModuleParamsV2 } from '@xyo-network/module-model-mongodb'
|
|
18
17
|
import type { WithStorageMeta } from '@xyo-network/payload-model'
|
|
19
18
|
import { MemorySentinel } from '@xyo-network/sentinel-memory'
|
|
20
|
-
import type {
|
|
19
|
+
import type {
|
|
20
|
+
BalancesStepSummary, Config, MapType, TransfersStepSummary,
|
|
21
|
+
} from '@xyo-network/xl1-protocol-sdk'
|
|
21
22
|
import { hasMongoConfig } from '@xyo-network/xl1-protocol-sdk'
|
|
22
23
|
|
|
23
24
|
import { MongoMap } from '../driver/index.ts'
|
|
@@ -51,8 +52,8 @@ export const getLocator = async (context: GetLocatorContext) => {
|
|
|
51
52
|
const statusReporter = logger ? new LoggerModuleStatusReporter(logger) : undefined
|
|
52
53
|
|
|
53
54
|
const locator = new ModuleFactoryLocator()
|
|
54
|
-
|
|
55
|
-
let
|
|
55
|
+
let balanceSummaryMap: MapType<string, WithStorageMeta<BalancesStepSummary>> | undefined
|
|
56
|
+
let transferSummaryMap: MapType<string, WithStorageMeta<TransfersStepSummary>> | undefined
|
|
56
57
|
// If there's a MongoDB configuration
|
|
57
58
|
const mongoConfig = config.storage?.mongo
|
|
58
59
|
if (hasMongoConfig(mongoConfig)) {
|
|
@@ -70,13 +71,25 @@ export const getLocator = async (context: GetLocatorContext) => {
|
|
|
70
71
|
locator.register(MongoDBArchivistV2.factory(params), undefined, true)
|
|
71
72
|
|
|
72
73
|
// Use a persistent MongoMap for the summary repository if MongoDB is configured
|
|
73
|
-
const
|
|
74
|
-
|
|
74
|
+
const sdkBalanceSummaryMap = new BaseMongoSdk<WithStorageMeta<BalancesStepSummary>>({ ...payloadSdkConfig, collection: 'balance_summary_map' })
|
|
75
|
+
balanceSummaryMap = await MongoMap.create<MongoMap<Hash, WithStorageMeta<BalancesStepSummary>>>({
|
|
76
|
+
sdk: sdkBalanceSummaryMap,
|
|
77
|
+
getCache: { enabled: true, maxEntries: 5000 },
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
const sdkTransferSummaryMap = new BaseMongoSdk<WithStorageMeta<TransfersStepSummary>>({ ...payloadSdkConfig, collection: 'transfer_summary_map' })
|
|
81
|
+
transferSummaryMap = await MongoMap.create<MongoMap<Hash, WithStorageMeta<TransfersStepSummary>>>({
|
|
82
|
+
sdk: sdkTransferSummaryMap,
|
|
83
|
+
getCache: { enabled: true, maxEntries: 5000 },
|
|
84
|
+
})
|
|
75
85
|
}
|
|
76
86
|
|
|
77
|
-
const summaryRepository = balanceSummaryRepositoryFromMap(summaryMap)
|
|
78
87
|
locator.register(AddressBalanceDivinerV2.factory<AddressBalanceDivinerV2>({
|
|
79
|
-
traceProvider, meterProvider, statusReporter,
|
|
88
|
+
traceProvider, meterProvider, statusReporter, summaryMap: balanceSummaryMap,
|
|
89
|
+
}))
|
|
90
|
+
|
|
91
|
+
locator.register(AddressTransferDiviner.factory<AddressTransferDiviner>({
|
|
92
|
+
traceProvider, meterProvider, statusReporter, summaryMap: transferSummaryMap,
|
|
80
93
|
}))
|
|
81
94
|
|
|
82
95
|
const chainId = isDefined(config.chain.id)
|
|
@@ -30,12 +30,12 @@
|
|
|
30
30
|
"eventSubscriptions": [
|
|
31
31
|
{
|
|
32
32
|
"sourceEvent": "inserted",
|
|
33
|
-
"sourceModule": "
|
|
33
|
+
"sourceModule": "Submissions",
|
|
34
34
|
"targetModuleFunction": "divine"
|
|
35
35
|
}
|
|
36
36
|
],
|
|
37
|
-
"inArchivist": "
|
|
38
|
-
"outArchivist": "
|
|
37
|
+
"inArchivist": "Submissions",
|
|
38
|
+
"outArchivist": "Validated",
|
|
39
39
|
"name": "HeadValidationDiviner"
|
|
40
40
|
}
|
|
41
41
|
},
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"accountPath": "1/1'/4'",
|
|
67
67
|
"automations": [
|
|
68
68
|
{
|
|
69
|
-
"frequency":
|
|
69
|
+
"frequency": 10000,
|
|
70
70
|
"frequencyUnits": "millis",
|
|
71
71
|
"schema": "network.xyo.automation.interval",
|
|
72
72
|
"type": "interval"
|
|
@@ -82,6 +82,28 @@
|
|
|
82
82
|
}
|
|
83
83
|
]
|
|
84
84
|
}
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"config": {
|
|
88
|
+
"accountPath": "1/1'/5'",
|
|
89
|
+
"automations": [
|
|
90
|
+
{
|
|
91
|
+
"frequency": 10000,
|
|
92
|
+
"frequencyUnits": "millis",
|
|
93
|
+
"schema": "network.xyo.automation.interval",
|
|
94
|
+
"type": "interval"
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
"name": "AddressTransferPollingSentinel",
|
|
98
|
+
"schema": "network.xyo.sentinel.config",
|
|
99
|
+
"synchronous": true,
|
|
100
|
+
"tasks": [
|
|
101
|
+
{
|
|
102
|
+
"mod": "AddressTransferDiviner",
|
|
103
|
+
"endPoint": "divine"
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
}
|
|
85
107
|
}
|
|
86
108
|
],
|
|
87
109
|
"public": [
|
|
@@ -111,23 +133,38 @@
|
|
|
111
133
|
"enabled": true,
|
|
112
134
|
"maxEntries": 5000
|
|
113
135
|
},
|
|
114
|
-
"originArchivist": "
|
|
136
|
+
"originArchivist": "Validated",
|
|
115
137
|
"schema": "network.xyo.archivist.view.config"
|
|
116
138
|
}
|
|
117
139
|
},
|
|
118
140
|
{
|
|
119
141
|
"config": {
|
|
120
|
-
"accountPath": "1/1/3",
|
|
121
|
-
"schema": "network.xyo.diviner.chain.address.balance.config",
|
|
122
|
-
"archivist": "Chain:Validated",
|
|
142
|
+
"accountPath": "1/1/3'",
|
|
123
143
|
"name": "AddressBalanceDiviner",
|
|
124
|
-
"
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
"
|
|
128
|
-
"
|
|
144
|
+
"schema": "network.xyo.diviner.chain.address.balance.config",
|
|
145
|
+
"map": {
|
|
146
|
+
"lmdb": {
|
|
147
|
+
"dbName": "summaries",
|
|
148
|
+
"storeName": "address_balance",
|
|
149
|
+
"location": ".store"
|
|
129
150
|
}
|
|
130
|
-
|
|
151
|
+
},
|
|
152
|
+
"archivist": "Validated"
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"config": {
|
|
157
|
+
"accountPath": "1/1/4'",
|
|
158
|
+
"name": "AddressTransferDiviner",
|
|
159
|
+
"schema": "network.xyo.diviner.chain.address.transfer.config",
|
|
160
|
+
"map": {
|
|
161
|
+
"lmdb": {
|
|
162
|
+
"dbName": "summaries",
|
|
163
|
+
"storeName": "address_transfer",
|
|
164
|
+
"location": ".store"
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
"archivist": "Validated"
|
|
131
168
|
}
|
|
132
169
|
}
|
|
133
170
|
]
|
|
@@ -135,4 +172,4 @@
|
|
|
135
172
|
}
|
|
136
173
|
],
|
|
137
174
|
"schema": "network.xyo.manifest"
|
|
138
|
-
}
|
|
175
|
+
}
|
package/src/server/app.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
standardResponses,
|
|
10
10
|
} from '@xylabs/express'
|
|
11
11
|
import type { NodeInstance } from '@xyo-network/node-model'
|
|
12
|
+
import type { StakedChainContextRead, StakeEventsRead } from '@xyo-network/xl1-protocol-sdk'
|
|
12
13
|
import compression from 'compression'
|
|
13
14
|
import cors from 'cors'
|
|
14
15
|
import type { Express } from 'express'
|
|
@@ -17,7 +18,7 @@ import express from 'express'
|
|
|
17
18
|
import { addInstrumentation } from './instrumentation.ts'
|
|
18
19
|
import { addRoutes } from './routes/index.ts'
|
|
19
20
|
|
|
20
|
-
export const getApp = (node: NodeInstance): Express => {
|
|
21
|
+
export const getApp = (node: NodeInstance, eventsReader: StakeEventsRead, stakedChainContext: StakedChainContextRead): Express => {
|
|
21
22
|
addInstrumentation()
|
|
22
23
|
const app = express()
|
|
23
24
|
app.set('etag', false)
|
|
@@ -31,7 +32,7 @@ export const getApp = (node: NodeInstance): Express => {
|
|
|
31
32
|
app.use(customPoweredByHeader)
|
|
32
33
|
disableCaseSensitiveRouting(app)
|
|
33
34
|
app.node = node
|
|
34
|
-
addRoutes(app)
|
|
35
|
+
addRoutes(app, eventsReader, stakedChainContext)
|
|
35
36
|
app.use(standardErrors)
|
|
36
37
|
return app
|
|
37
38
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import type { StakedChainContextRead, StakeEventsRead } from '@xyo-network/xl1-protocol-sdk'
|
|
1
2
|
import type { Express } from 'express'
|
|
2
3
|
|
|
3
4
|
import { addNodeRoutes } from './address/index.ts'
|
|
4
5
|
import { addDataLakeRoutes } from './dataLake/index.ts'
|
|
5
6
|
import { addRpcRoutes } from './rpc/index.ts'
|
|
6
7
|
|
|
7
|
-
export const addRoutes = (app: Express) => {
|
|
8
|
-
addRpcRoutes(app)
|
|
8
|
+
export const addRoutes = (app: Express, eventsReader: StakeEventsRead, stakedChainContext: StakedChainContextRead) => {
|
|
9
|
+
addRpcRoutes(app, eventsReader, stakedChainContext)
|
|
9
10
|
addDataLakeRoutes(app)
|
|
10
11
|
addNodeRoutes(app)
|
|
11
12
|
}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { setRawResponseFormat } from '@xylabs/express'
|
|
2
2
|
import { NodeXyoViewer } from '@xyo-network/chain-rpc'
|
|
3
|
+
import type { StakedChainContextRead, StakeEventsRead } from '@xyo-network/xl1-protocol-sdk'
|
|
3
4
|
import {
|
|
4
|
-
NodeXyoRunner,
|
|
5
|
+
NodeXyoRunner, rpcEngineFromConnection,
|
|
5
6
|
XyoBaseConnection,
|
|
6
7
|
} from '@xyo-network/xl1-rpc'
|
|
7
8
|
import type { Express } from 'express'
|
|
8
9
|
|
|
9
|
-
export const addRpcRoutes = (app: Express) => {
|
|
10
|
+
export const addRpcRoutes = (app: Express, eventsReader: StakeEventsRead, stakedChainContext: StakedChainContextRead) => {
|
|
10
11
|
const { node } = app
|
|
11
12
|
const runner = new NodeXyoRunner(node)
|
|
12
|
-
const viewer = new NodeXyoViewer(node)
|
|
13
|
-
const
|
|
14
|
-
const engine =
|
|
13
|
+
const viewer = new NodeXyoViewer(node, eventsReader, stakedChainContext)
|
|
14
|
+
const connection = new XyoBaseConnection({ runner, viewer })
|
|
15
|
+
const engine = rpcEngineFromConnection(connection)
|
|
15
16
|
|
|
16
17
|
app.post('/rpc', (req, res) => {
|
|
17
18
|
setRawResponseFormat(res)
|
package/src/server/server.ts
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { assertEx } from '@xylabs/assert'
|
|
2
|
+
import { toEthAddress, ZERO_HASH } from '@xylabs/hex'
|
|
2
3
|
import type { Logger } from '@xylabs/logger'
|
|
3
4
|
import { isDefined, isString } from '@xylabs/typeof'
|
|
5
|
+
import { asArchivistInstance } from '@xyo-network/archivist-model'
|
|
4
6
|
import { boot } from '@xyo-network/bios'
|
|
5
7
|
import type { BiosExternalInterface } from '@xyo-network/bios-model'
|
|
8
|
+
import { EthereumChainStake, EthereumChainStakeEvents } from '@xyo-network/chain-ethereum'
|
|
6
9
|
import type { NodeInstance } from '@xyo-network/node-model'
|
|
10
|
+
import type { Payload, WithStorageMeta } from '@xyo-network/payload-model'
|
|
11
|
+
import { StakedXyoChainV2__factory } from '@xyo-network/typechain'
|
|
7
12
|
import { HDWallet } from '@xyo-network/wallet'
|
|
8
|
-
import {
|
|
13
|
+
import type { ChainId } from '@xyo-network/xl1-protocol'
|
|
14
|
+
import { type Config, readPayloadMapFromStore } from '@xyo-network/xl1-protocol-sdk'
|
|
9
15
|
|
|
16
|
+
import { initInfuraProvider } from '../helpers/index.ts'
|
|
10
17
|
import { getNode } from '../manifest/index.ts'
|
|
11
18
|
import { getApp } from './app.ts'
|
|
12
19
|
|
|
@@ -49,10 +56,24 @@ export const getServer = async (context: GetServerContext) => {
|
|
|
49
56
|
const bios = await boot()
|
|
50
57
|
const seedPhrase = isDefined(mnemonic) ? mnemonic : await getSeedPhrase(bios, config, logger)
|
|
51
58
|
const wallet = await HDWallet.fromPhrase(seedPhrase)
|
|
59
|
+
const provider = await initInfuraProvider(config)
|
|
60
|
+
const contractAddress = assertEx(config.chain.id, () => 'Missing config.evm.chainId') as ChainId
|
|
61
|
+
const contract = StakedXyoChainV2__factory.connect(toEthAddress(contractAddress), provider)
|
|
52
62
|
const nodeContext = {
|
|
53
63
|
wallet, logger, config,
|
|
54
64
|
}
|
|
55
|
-
const
|
|
65
|
+
const eventsReader = new EthereumChainStakeEvents(contract)
|
|
66
|
+
const stakeChainReader = await EthereumChainStake.create({ contract, eventsReader })
|
|
67
|
+
await stakeChainReader.start()
|
|
68
|
+
const rootNode = await getNode(nodeContext)
|
|
69
|
+
const archivist = assertEx(asArchivistInstance(
|
|
70
|
+
await rootNode.resolve('Chain:Validated'),
|
|
71
|
+
{ required: true },
|
|
72
|
+
), () => 'FinalizedArchivist not found in node')
|
|
73
|
+
const chainMap = readPayloadMapFromStore<WithStorageMeta<Payload>>(archivist)
|
|
74
|
+
const app = getApp(node ?? await getNode(nodeContext), eventsReader, {
|
|
75
|
+
chainId: contractAddress, stake: stakeChainReader, store: { chainMap }, head: () => ZERO_HASH,
|
|
76
|
+
})
|
|
56
77
|
const server = app.listen(port, hostname, () => logger?.log(`[API] Server listening at http://${hostname}:${port}`))
|
|
57
78
|
server.setTimeout(20_000)
|
|
58
79
|
return server
|