@xyo-network/chain-mempool 1.16.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/LICENSE +165 -0
- package/README.md +96 -0
- package/dist/node/helpers/index.d.ts +2 -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/index.d.ts +2 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.mjs +618 -0
- package/dist/node/index.mjs.map +1 -0
- package/dist/node/manifest/getLocator.d.ts +14 -0
- package/dist/node/manifest/getLocator.d.ts.map +1 -0
- package/dist/node/manifest/getNode.d.ts +15 -0
- package/dist/node/manifest/getNode.d.ts.map +1 -0
- package/dist/node/manifest/index.d.ts +6 -0
- package/dist/node/manifest/index.d.ts.map +1 -0
- package/dist/node/manifest/nodeManifest.d.ts +6 -0
- package/dist/node/manifest/nodeManifest.d.ts.map +1 -0
- package/dist/node/manifest/private/index.d.ts +5 -0
- package/dist/node/manifest/private/index.d.ts.map +1 -0
- package/dist/node/manifest/public/index.d.ts +14 -0
- package/dist/node/manifest/public/index.d.ts.map +1 -0
- package/dist/node/manifest/public/spec/Node.spec.d.ts +2 -0
- package/dist/node/manifest/public/spec/Node.spec.d.ts.map +1 -0
- package/dist/node/server/app.d.ts +4 -0
- package/dist/node/server/app.d.ts.map +1 -0
- package/dist/node/server/index.d.ts +11 -0
- package/dist/node/server/index.d.ts.map +1 -0
- package/dist/node/server/instrumentation.d.ts +9 -0
- package/dist/node/server/instrumentation.d.ts.map +1 -0
- package/dist/node/server/routes/addRoutes.d.ts +3 -0
- package/dist/node/server/routes/addRoutes.d.ts.map +1 -0
- package/dist/node/server/routes/address/AddressPathParams.d.ts +4 -0
- package/dist/node/server/routes/address/AddressPathParams.d.ts.map +1 -0
- package/dist/node/server/routes/address/addNodeRoutes.d.ts +3 -0
- package/dist/node/server/routes/address/addNodeRoutes.d.ts.map +1 -0
- package/dist/node/server/routes/address/get/get.d.ts +4 -0
- package/dist/node/server/routes/address/get/get.d.ts.map +1 -0
- package/dist/node/server/routes/address/get/index.d.ts +2 -0
- package/dist/node/server/routes/address/get/index.d.ts.map +1 -0
- package/dist/node/server/routes/address/index.d.ts +2 -0
- package/dist/node/server/routes/address/index.d.ts.map +1 -0
- package/dist/node/server/routes/address/post/getQueryConfig.d.ts +6 -0
- package/dist/node/server/routes/address/post/getQueryConfig.d.ts.map +1 -0
- package/dist/node/server/routes/address/post/index.d.ts +2 -0
- package/dist/node/server/routes/address/post/index.d.ts.map +1 -0
- package/dist/node/server/routes/address/post/post.d.ts +8 -0
- package/dist/node/server/routes/address/post/post.d.ts.map +1 -0
- package/dist/node/server/routes/dataLake/addDataLakeRoutes.d.ts +3 -0
- package/dist/node/server/routes/dataLake/addDataLakeRoutes.d.ts.map +1 -0
- package/dist/node/server/routes/dataLake/archivistMiddleware.d.ts +10 -0
- package/dist/node/server/routes/dataLake/archivistMiddleware.d.ts.map +1 -0
- package/dist/node/server/routes/dataLake/index.d.ts +2 -0
- package/dist/node/server/routes/dataLake/index.d.ts.map +1 -0
- package/dist/node/server/routes/healthz/addHealthRoutes.d.ts +3 -0
- package/dist/node/server/routes/healthz/addHealthRoutes.d.ts.map +1 -0
- package/dist/node/server/routes/healthz/index.d.ts +2 -0
- package/dist/node/server/routes/healthz/index.d.ts.map +1 -0
- package/dist/node/server/routes/index.d.ts +4 -0
- package/dist/node/server/routes/index.d.ts.map +1 -0
- package/dist/node/server/server.d.ts +11 -0
- package/dist/node/server/server.d.ts.map +1 -0
- package/package.json +118 -0
- package/src/helpers/index.ts +1 -0
- package/src/helpers/initChainId.ts +20 -0
- package/src/index.ts +1 -0
- package/src/manifest/getLocator.ts +85 -0
- package/src/manifest/getNode.ts +32 -0
- package/src/manifest/index.ts +5 -0
- package/src/manifest/node.json +17 -0
- package/src/manifest/nodeManifest.ts +8 -0
- package/src/manifest/private/index.ts +4 -0
- package/src/manifest/public/Chain.json +101 -0
- package/src/manifest/public/Pending.json +35 -0
- package/src/manifest/public/index.ts +20 -0
- package/src/manifest/public/spec/Node.spec.ts +32 -0
- package/src/server/app.ts +36 -0
- package/src/server/index.ts +13 -0
- package/src/server/instrumentation.ts +15 -0
- package/src/server/routes/addRoutes.ts +11 -0
- package/src/server/routes/address/AddressPathParams.ts +3 -0
- package/src/server/routes/address/addNodeRoutes.ts +21 -0
- package/src/server/routes/address/get/get.ts +31 -0
- package/src/server/routes/address/get/index.ts +1 -0
- package/src/server/routes/address/index.ts +1 -0
- package/src/server/routes/address/post/getQueryConfig.ts +23 -0
- package/src/server/routes/address/post/index.ts +1 -0
- package/src/server/routes/address/post/post.ts +77 -0
- package/src/server/routes/dataLake/addDataLakeRoutes.ts +9 -0
- package/src/server/routes/dataLake/archivistMiddleware.ts +86 -0
- package/src/server/routes/dataLake/index.ts +1 -0
- package/src/server/routes/healthz/addHealthRoutes.ts +14 -0
- package/src/server/routes/healthz/index.ts +1 -0
- package/src/server/routes/index.ts +3 -0
- package/src/server/server.ts +63 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { setRawResponseFormat } from '@xylabs/express'
|
|
2
|
+
import { asHash } from '@xylabs/hex'
|
|
3
|
+
import { isDefined } from '@xylabs/typeof'
|
|
4
|
+
import type {
|
|
5
|
+
ArchivistInstance,
|
|
6
|
+
ArchivistNextOptions, NextOptions,
|
|
7
|
+
} from '@xyo-network/archivist-model'
|
|
8
|
+
import { asArchivistInstance } from '@xyo-network/archivist-model'
|
|
9
|
+
import type { ModuleIdentifier } from '@xyo-network/module-model'
|
|
10
|
+
import type { NodeInstance } from '@xyo-network/node-model'
|
|
11
|
+
import { PayloadBuilder } from '@xyo-network/payload-builder'
|
|
12
|
+
import type { Payload } from '@xyo-network/payload-model'
|
|
13
|
+
import { isAnyPayload, isSequence } from '@xyo-network/payload-model'
|
|
14
|
+
import type { Router } from 'express'
|
|
15
|
+
import express from 'express'
|
|
16
|
+
import type { Request } from 'express-serve-static-core'
|
|
17
|
+
|
|
18
|
+
const resolveArchivist = async (node: NodeInstance, archivistModuleIdentifier: ModuleIdentifier): Promise<ArchivistInstance> => {
|
|
19
|
+
const mod = await node.resolve(archivistModuleIdentifier)
|
|
20
|
+
return asArchivistInstance(mod, { required: true })
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let archivistInstance: ArchivistInstance | undefined
|
|
24
|
+
|
|
25
|
+
const getArchivist = async (node: NodeInstance, archivistModuleIdentifier: ModuleIdentifier): Promise<ArchivistInstance> => {
|
|
26
|
+
if (isDefined(archivistInstance)) return archivistInstance
|
|
27
|
+
archivistInstance = await resolveArchivist(node, archivistModuleIdentifier)
|
|
28
|
+
return archivistInstance
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
type ArchivistMiddlewareOptions = {
|
|
32
|
+
archivistModuleIdentifier: ModuleIdentifier
|
|
33
|
+
node: NodeInstance
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const archivistMiddleware = (options: ArchivistMiddlewareOptions): Router => {
|
|
37
|
+
const { node, archivistModuleIdentifier } = options
|
|
38
|
+
const router = express.Router({ mergeParams: true })
|
|
39
|
+
|
|
40
|
+
router.post('/insert', async (req, res) => {
|
|
41
|
+
setRawResponseFormat(res)
|
|
42
|
+
const body = Array.isArray(req.body) ? req.body : [req.body]
|
|
43
|
+
const payloads = (await PayloadBuilder.hashPairs<Payload>(body)).map(p => p[0])
|
|
44
|
+
const archivist = await getArchivist(node, archivistModuleIdentifier)
|
|
45
|
+
const result = await archivist.insert(payloads)
|
|
46
|
+
res.status(200).json(result)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
router.get('/next', async (req: Request<Partial<NextOptions>>, res) => {
|
|
50
|
+
setRawResponseFormat(res)
|
|
51
|
+
const cursor = isSequence(req.query.cursor) ? req.query.cursor : undefined
|
|
52
|
+
const limit = isDefined(req.query.limit) ? Number(req.query.limit) : undefined
|
|
53
|
+
const open = isDefined(req.query.open) ? Boolean(req.query.open) : undefined
|
|
54
|
+
const order = req.query.order === 'asc' ? 'asc' : 'desc'
|
|
55
|
+
const options: ArchivistNextOptions = {
|
|
56
|
+
limit, open, order, cursor,
|
|
57
|
+
}
|
|
58
|
+
const archivist = await getArchivist(node, archivistModuleIdentifier)
|
|
59
|
+
const result = await archivist.next(options)
|
|
60
|
+
res.status(200).json(result)
|
|
61
|
+
})
|
|
62
|
+
router.post('/next', async (req: Request<{}, {}, ArchivistNextOptions | undefined>, res) => {
|
|
63
|
+
setRawResponseFormat(res)
|
|
64
|
+
const options = req.body
|
|
65
|
+
const archivist = await getArchivist(node, archivistModuleIdentifier)
|
|
66
|
+
const result = await (isDefined(options) ? archivist.next(options) : archivist.next())
|
|
67
|
+
res.status(200).json(result)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
router.get('/get/:hash', async (req, res) => {
|
|
71
|
+
setRawResponseFormat(res)
|
|
72
|
+
const { hash: rawHash } = req.params
|
|
73
|
+
const hash = asHash(rawHash)
|
|
74
|
+
if (isDefined(hash)) {
|
|
75
|
+
const archivist = await getArchivist(node, archivistModuleIdentifier)
|
|
76
|
+
const [payload] = await archivist.get([hash])
|
|
77
|
+
if (isAnyPayload(payload)) {
|
|
78
|
+
res.json(payload)
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
res.status(400).send()
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
return router
|
|
86
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './addDataLakeRoutes.ts'
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Express } from 'express'
|
|
2
|
+
import { StatusCodes } from 'http-status-codes'
|
|
3
|
+
|
|
4
|
+
export const addHealthRoutes = (app: Express) => {
|
|
5
|
+
app.get('/healthz', (_req, res) => {
|
|
6
|
+
res.status(StatusCodes.OK).send()
|
|
7
|
+
})
|
|
8
|
+
app.get('/livez', (_req, res) => {
|
|
9
|
+
res.status(StatusCodes.OK).send()
|
|
10
|
+
})
|
|
11
|
+
app.get('/readyz', (_req, res) => {
|
|
12
|
+
res.status(StatusCodes.OK).send()
|
|
13
|
+
})
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './addHealthRoutes.ts'
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { assertEx } from '@xylabs/assert'
|
|
2
|
+
import type { Logger } from '@xylabs/logger'
|
|
3
|
+
import { isDefined, isString } from '@xylabs/typeof'
|
|
4
|
+
import { boot } from '@xyo-network/bios'
|
|
5
|
+
import type { BiosExternalInterface } from '@xyo-network/bios-model'
|
|
6
|
+
import type { NodeInstance } from '@xyo-network/node-model'
|
|
7
|
+
import { HDWallet } from '@xyo-network/wallet'
|
|
8
|
+
import type { Config } from '@xyo-network/xl1-protocol-sdk'
|
|
9
|
+
|
|
10
|
+
import { getNode } from '../manifest/index.ts'
|
|
11
|
+
import { getApp } from './app.ts'
|
|
12
|
+
|
|
13
|
+
const hostname = '::'
|
|
14
|
+
// const hostname = '0.0.0.0'
|
|
15
|
+
|
|
16
|
+
// TODO: Make nodejs version of bios support round tripping mnemonic between boots
|
|
17
|
+
const getSeedPhrase = async (bios: BiosExternalInterface, config: Config, logger?: Logger): Promise<string> => {
|
|
18
|
+
const storedSeedPhrase = await bios.seedPhraseStore.get('os')
|
|
19
|
+
logger?.debug(`[API] Stored mnemonic: ${storedSeedPhrase}`)
|
|
20
|
+
const { mnemonic } = config.api
|
|
21
|
+
if (isString(storedSeedPhrase) && isString(mnemonic)) {
|
|
22
|
+
logger?.warn('[API] Stored mnemonic does not match supplied. Updating stored mnemonic to supplied.')
|
|
23
|
+
await bios.seedPhraseStore.set('os', mnemonic)
|
|
24
|
+
} else {
|
|
25
|
+
let seedPhrase: string
|
|
26
|
+
if (isString(mnemonic)) {
|
|
27
|
+
seedPhrase = mnemonic
|
|
28
|
+
} else {
|
|
29
|
+
seedPhrase = HDWallet.generateMnemonic()
|
|
30
|
+
logger?.log('[API] No mnemonic provided, using random mnemonic. This is not recommended for production use.')
|
|
31
|
+
logger?.log(`[API] Mnemonic: ${seedPhrase}`)
|
|
32
|
+
}
|
|
33
|
+
await bios.seedPhraseStore.set('os', seedPhrase)
|
|
34
|
+
}
|
|
35
|
+
return assertEx(await bios.seedPhraseStore.get('os'), () => 'Unable to acquire mnemonic from bios')
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface GetServerContext {
|
|
39
|
+
config: Config
|
|
40
|
+
logger?: Logger
|
|
41
|
+
node?: NodeInstance
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const getServer = async (context: GetServerContext) => {
|
|
45
|
+
const {
|
|
46
|
+
config, logger, node,
|
|
47
|
+
} = context
|
|
48
|
+
const { mnemonic, port } = context.config.mempool
|
|
49
|
+
const bios = await boot()
|
|
50
|
+
const seedPhrase = isDefined(mnemonic) ? mnemonic : await getSeedPhrase(bios, config, logger)
|
|
51
|
+
const wallet = await HDWallet.fromPhrase(seedPhrase)
|
|
52
|
+
const nodeContext = {
|
|
53
|
+
wallet, logger, config,
|
|
54
|
+
}
|
|
55
|
+
const resolvedNode: NodeInstance = node ?? await getNode(nodeContext)
|
|
56
|
+
const mods = await resolvedNode.resolve('*')
|
|
57
|
+
const startResults = await Promise.all(mods.map(mod => mod.start?.() ?? true))
|
|
58
|
+
assertEx(startResults.every(r => r === true), () => '[Mempool] Not all modules started successfully')
|
|
59
|
+
const app = getApp(resolvedNode)
|
|
60
|
+
const server = app.listen(port, hostname, () => logger?.log(`[Mempool] Server listening at http://${hostname}:${port}`))
|
|
61
|
+
server.setTimeout(20_000)
|
|
62
|
+
return server
|
|
63
|
+
}
|