@xyo-network/chain-bridge 1.15.2
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/driver/index.d.ts +2 -0
- package/dist/node/driver/index.d.ts.map +1 -0
- package/dist/node/driver/indexer/ChainBlockIteration/ChainHashIterationService.d.ts +24 -0
- package/dist/node/driver/indexer/ChainBlockIteration/ChainHashIterationService.d.ts.map +1 -0
- package/dist/node/driver/indexer/ChainBlockIteration/index.d.ts +2 -0
- package/dist/node/driver/indexer/ChainBlockIteration/index.d.ts.map +1 -0
- package/dist/node/driver/indexer/ChainBlocksObservable.d.ts +5 -0
- package/dist/node/driver/indexer/ChainBlocksObservable.d.ts.map +1 -0
- package/dist/node/driver/indexer/ChainHydratedBlocksObservable.d.ts +11 -0
- package/dist/node/driver/indexer/ChainHydratedBlocksObservable.d.ts.map +1 -0
- package/dist/node/driver/indexer/index.d.ts +2 -0
- package/dist/node/driver/indexer/index.d.ts.map +1 -0
- package/dist/node/driver/indexer/spec/ChainBlocksObservable.spec.d.ts +2 -0
- package/dist/node/driver/indexer/spec/ChainBlocksObservable.spec.d.ts.map +1 -0
- package/dist/node/driver/indexer/spec/ChainHydratedBlocksObservable.spec.d.ts +2 -0
- package/dist/node/driver/indexer/spec/ChainHydratedBlocksObservable.spec.d.ts.map +1 -0
- package/dist/node/driver/mongo/MongoMap.d.ts +17 -0
- package/dist/node/driver/mongo/MongoMap.d.ts.map +1 -0
- package/dist/node/driver/mongo/index.d.ts +2 -0
- package/dist/node/driver/mongo/index.d.ts.map +1 -0
- package/dist/node/driver/mongo/spec/MongoMap.spec.d.ts +2 -0
- package/dist/node/driver/mongo/spec/MongoMap.spec.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 +751 -0
- package/dist/node/index.mjs.map +1 -0
- package/dist/node/interface/index.d.ts +5 -0
- package/dist/node/interface/index.d.ts.map +1 -0
- package/dist/node/interface/interface/ChainBridgeRelayInterface.d.ts +9 -0
- package/dist/node/interface/interface/ChainBridgeRelayInterface.d.ts.map +1 -0
- package/dist/node/interface/interface/IntentIndexerInterface.d.ts +6 -0
- package/dist/node/interface/interface/IntentIndexerInterface.d.ts.map +1 -0
- package/dist/node/interface/interface/LockingProcessorInterface.d.ts +9 -0
- package/dist/node/interface/interface/LockingProcessorInterface.d.ts.map +1 -0
- package/dist/node/interface/interface/ObservationIndexerInterface.d.ts +7 -0
- package/dist/node/interface/interface/ObservationIndexerInterface.d.ts.map +1 -0
- package/dist/node/interface/interface/Params.d.ts +26 -0
- package/dist/node/interface/interface/Params.d.ts.map +1 -0
- package/dist/node/interface/interface/RelayInterface.d.ts +8 -0
- package/dist/node/interface/interface/RelayInterface.d.ts.map +1 -0
- package/dist/node/interface/interface/index.d.ts +7 -0
- package/dist/node/interface/interface/index.d.ts.map +1 -0
- package/dist/node/interface/repository/RepositoryInterface.d.ts +22 -0
- package/dist/node/interface/repository/RepositoryInterface.d.ts.map +1 -0
- package/dist/node/interface/repository/index.d.ts +2 -0
- package/dist/node/interface/repository/index.d.ts.map +1 -0
- package/dist/node/interface/service/ChainBridgeRelay/ChainBridgeRelayInterface.d.ts +9 -0
- package/dist/node/interface/service/ChainBridgeRelay/ChainBridgeRelayInterface.d.ts.map +1 -0
- package/dist/node/interface/service/ChainBridgeRelay/ChainBridgeRelayService.d.ts +31 -0
- package/dist/node/interface/service/ChainBridgeRelay/ChainBridgeRelayService.d.ts.map +1 -0
- package/dist/node/interface/service/ChainBridgeRelay/index.d.ts +2 -0
- package/dist/node/interface/service/ChainBridgeRelay/index.d.ts.map +1 -0
- package/dist/node/interface/service/ChainBridgeRelay/spec/ChainBridgeRelayService.spec.d.ts +2 -0
- package/dist/node/interface/service/ChainBridgeRelay/spec/ChainBridgeRelayService.spec.d.ts.map +1 -0
- package/dist/node/interface/service/Observer/Observer.d.ts +15 -0
- package/dist/node/interface/service/Observer/Observer.d.ts.map +1 -0
- package/dist/node/interface/service/Observer/index.d.ts +2 -0
- package/dist/node/interface/service/Observer/index.d.ts.map +1 -0
- package/dist/node/interface/service/index.d.ts +3 -0
- package/dist/node/interface/service/index.d.ts.map +1 -0
- package/dist/node/interface/util/getBridgeIntentIdentifier.d.ts +5 -0
- package/dist/node/interface/util/getBridgeIntentIdentifier.d.ts.map +1 -0
- package/dist/node/interface/util/index.d.ts +2 -0
- package/dist/node/interface/util/index.d.ts.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/get.d.ts +3 -0
- package/dist/node/server/routes/healthz/get.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 +5 -0
- package/dist/node/server/routes/index.d.ts.map +1 -0
- package/dist/node/server/routes/rpc/index.d.ts +2 -0
- package/dist/node/server/routes/rpc/index.d.ts.map +1 -0
- package/dist/node/server/routes/rpc/routes/addRpcRoutes.d.ts +3 -0
- package/dist/node/server/routes/rpc/routes/addRpcRoutes.d.ts.map +1 -0
- package/dist/node/server/routes/rpc/routes/index.d.ts +2 -0
- package/dist/node/server/routes/rpc/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 +125 -0
- package/src/driver/index.ts +1 -0
- package/src/driver/indexer/ChainBlockIteration/ChainHashIterationService.ts +87 -0
- package/src/driver/indexer/ChainBlockIteration/index.ts +1 -0
- package/src/driver/indexer/ChainBlocksObservable.ts +47 -0
- package/src/driver/indexer/ChainHydratedBlocksObservable.ts +23 -0
- package/src/driver/indexer/index.ts +1 -0
- package/src/driver/indexer/spec/ChainBlocksObservable.spec.ts +58 -0
- package/src/driver/indexer/spec/ChainHydratedBlocksObservable.spec.ts +58 -0
- package/src/driver/mongo/MongoMap.ts +62 -0
- package/src/driver/mongo/index.ts +1 -0
- package/src/driver/mongo/spec/MongoMap.spec.ts +67 -0
- package/src/index.ts +1 -0
- package/src/interface/index.ts +4 -0
- package/src/interface/interface/ChainBridgeRelayInterface.ts +9 -0
- package/src/interface/interface/IntentIndexerInterface.ts +7 -0
- package/src/interface/interface/LockingProcessorInterface.ts +10 -0
- package/src/interface/interface/ObservationIndexerInterface.ts +12 -0
- package/src/interface/interface/Params.ts +26 -0
- package/src/interface/interface/RelayInterface.ts +8 -0
- package/src/interface/interface/index.ts +6 -0
- package/src/interface/repository/RepositoryInterface.ts +28 -0
- package/src/interface/repository/index.ts +1 -0
- package/src/interface/service/ChainBridgeRelay/ChainBridgeRelayInterface.ts +11 -0
- package/src/interface/service/ChainBridgeRelay/ChainBridgeRelayService.ts +116 -0
- package/src/interface/service/ChainBridgeRelay/index.ts +1 -0
- package/src/interface/service/ChainBridgeRelay/spec/ChainBridgeRelayService.spec.ts +264 -0
- package/src/interface/service/Observer/Observer.ts +48 -0
- package/src/interface/service/Observer/index.ts +1 -0
- package/src/interface/service/index.ts +2 -0
- package/src/interface/util/getBridgeIntentIdentifier.ts +18 -0
- package/src/interface/util/index.ts +1 -0
- package/src/manifest/getLocator.ts +105 -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 +138 -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 +37 -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 +33 -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/get.ts +20 -0
- package/src/server/routes/healthz/index.ts +1 -0
- package/src/server/routes/index.ts +5 -0
- package/src/server/routes/rpc/index.ts +1 -0
- package/src/server/routes/rpc/routes/addRpcRoutes.ts +22 -0
- package/src/server/routes/rpc/routes/index.ts +1 -0
- package/src/server/server.ts +59 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { assertEx } from '@xylabs/assert'
|
|
2
|
+
import { BaseAccountableService } from '@xyo-network/chain-services'
|
|
3
|
+
|
|
4
|
+
import type {
|
|
5
|
+
BridgeDestinationObservationIndexerInterface, BridgeIntentIndexerInterface, BridgeServiceParams,
|
|
6
|
+
BridgeSourceObservationIndexerInterface,
|
|
7
|
+
ChainBridgeRelayInterface,
|
|
8
|
+
LockingBridgeIntentProcessorInterface, UnlockingBridgeIntentProcessorInterface,
|
|
9
|
+
} from '../../interface/index.ts'
|
|
10
|
+
|
|
11
|
+
export interface BridgeObserverInterface {
|
|
12
|
+
// TODO:
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class BridgeObserverService<TParams extends BridgeServiceParams = BridgeServiceParams>
|
|
16
|
+
extends BaseAccountableService<TParams> implements BridgeObserverInterface {
|
|
17
|
+
protected get account() {
|
|
18
|
+
return assertEx(this.params.account, () => 'account is required')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
protected get destinationObservations(): BridgeDestinationObservationIndexerInterface {
|
|
22
|
+
return assertEx(this.params.destinationObservations, () => 'destinationObservations is required')
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
protected get destinationRelay(): ChainBridgeRelayInterface {
|
|
26
|
+
return assertEx(this.params.destinationRelay, () => 'destinationRelay is required')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
protected get intentProcessed(): LockingBridgeIntentProcessorInterface {
|
|
30
|
+
return assertEx(this.params.intentProcessed, () => 'intentProcessed is required')
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
protected get intentProcessing(): UnlockingBridgeIntentProcessorInterface {
|
|
34
|
+
return assertEx(this.params.intentProcessing, () => 'intentProcessing is required')
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
protected get intentResourceAccess(): BridgeIntentIndexerInterface {
|
|
38
|
+
return assertEx(this.params.intents, () => 'intents is required')
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
protected get sourceObservations(): BridgeSourceObservationIndexerInterface {
|
|
42
|
+
return assertEx(this.params.sourceObservations, () => 'sourceObservations is required')
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async process(): Promise<void> {
|
|
46
|
+
await Promise.resolve()
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Observer.ts'
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Hash } from '@xylabs/hex'
|
|
2
|
+
import { PayloadBuilder } from '@xyo-network/payload-builder'
|
|
3
|
+
import {
|
|
4
|
+
type BridgeDestinationObservation, type BridgeIntent, BridgeIntentSchema, type BridgeSourceObservation,
|
|
5
|
+
} from '@xyo-network/xl1-protocol'
|
|
6
|
+
|
|
7
|
+
export const getBridgeIntentFromObservation = (observation: BridgeSourceObservation | BridgeDestinationObservation, nonce: string): BridgeIntent => {
|
|
8
|
+
const {
|
|
9
|
+
src, srcAddress, srcAmount, srcToken, dest, destAddress, destAmount, destToken,
|
|
10
|
+
} = observation
|
|
11
|
+
return new PayloadBuilder<BridgeIntent>({ schema: BridgeIntentSchema }).fields({
|
|
12
|
+
src, srcAddress, srcAmount, srcToken, dest, destAddress, destAmount, destToken, nonce,
|
|
13
|
+
}).build()
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const getBridgeIntentIdentifier = async (bridgeIntent: BridgeIntent): Promise<Hash> => {
|
|
17
|
+
return await PayloadBuilder.hash(bridgeIntent)
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './getBridgeIntentIdentifier.ts'
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { assertEx } from '@xylabs/assert'
|
|
2
|
+
import type { Hash } from '@xylabs/hex'
|
|
3
|
+
import { asAddress, ZERO_ADDRESS } from '@xylabs/hex'
|
|
4
|
+
import type { Logger } from '@xylabs/logger'
|
|
5
|
+
import { BaseMongoSdk, type BaseMongoSdkPrivateConfig } from '@xylabs/mongo'
|
|
6
|
+
import { isDefined } from '@xylabs/typeof'
|
|
7
|
+
import { MemoryArchivist } from '@xyo-network/archivist-memory'
|
|
8
|
+
import { MongoDBArchivistV2 } from '@xyo-network/archivist-mongodb'
|
|
9
|
+
import { ViewArchivist } from '@xyo-network/archivist-view'
|
|
10
|
+
import {
|
|
11
|
+
AddressBalanceDivinerV2, ArchivistSyncDiviner, balanceSummaryRepositoryFromMap, HeadValidationDiviner,
|
|
12
|
+
} from '@xyo-network/chain-modules'
|
|
13
|
+
import type { MapType } from '@xyo-network/chain-protocol'
|
|
14
|
+
import { initTelemetry } from '@xyo-network/chain-telemetry'
|
|
15
|
+
import { AbstractModule, LoggerModuleStatusReporter } from '@xyo-network/module-abstract'
|
|
16
|
+
import { ModuleFactoryLocator } from '@xyo-network/module-factory-locator'
|
|
17
|
+
import type { MongoDBModuleParamsV2 } from '@xyo-network/module-model-mongodb'
|
|
18
|
+
import type { WithStorageMeta } from '@xyo-network/payload-model'
|
|
19
|
+
import { MemorySentinel } from '@xyo-network/sentinel-memory'
|
|
20
|
+
import type { BalancesStepSummary, Config } from '@xyo-network/xl1-protocol-sdk'
|
|
21
|
+
import { hasMongoConfig } from '@xyo-network/xl1-protocol-sdk'
|
|
22
|
+
|
|
23
|
+
import { MongoMap } from '../driver/index.ts'
|
|
24
|
+
|
|
25
|
+
export interface GetLocatorContext {
|
|
26
|
+
config: Config
|
|
27
|
+
logger?: Logger
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Used for retrieving a locator with the necessary modules registered for testing
|
|
32
|
+
* operation of the node (entirely in memory)
|
|
33
|
+
* @returns A locator with the necessary modules registered
|
|
34
|
+
*/
|
|
35
|
+
export const getLocator = async (context: GetLocatorContext) => {
|
|
36
|
+
const { config, logger } = context
|
|
37
|
+
const { otlpEndpoint } = config.telemetry?.otel ?? {}
|
|
38
|
+
const { traceProvider, meterProvider } = await initTelemetry({
|
|
39
|
+
attributes: {
|
|
40
|
+
serviceName: 'xl1-bridge',
|
|
41
|
+
serviceVersion: '1.0.0',
|
|
42
|
+
},
|
|
43
|
+
otlpEndpoint,
|
|
44
|
+
metricsConfig: {
|
|
45
|
+
endpoint: '/metrics',
|
|
46
|
+
port: 9465,
|
|
47
|
+
},
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
if (isDefined(logger)) AbstractModule.defaultLogger = logger
|
|
51
|
+
const statusReporter = logger ? new LoggerModuleStatusReporter(logger) : undefined
|
|
52
|
+
|
|
53
|
+
const locator = new ModuleFactoryLocator()
|
|
54
|
+
// Initialize with an in-memory map for backing the summary repository
|
|
55
|
+
let summaryMap: MapType<Hash, WithStorageMeta<BalancesStepSummary>> = new Map<Hash, WithStorageMeta<BalancesStepSummary>>()
|
|
56
|
+
// If there's a MongoDB configuration
|
|
57
|
+
const mongoConfig = config.storage?.mongo
|
|
58
|
+
if (hasMongoConfig(mongoConfig)) {
|
|
59
|
+
// Create the MongoDB SDK from the configuration
|
|
60
|
+
const {
|
|
61
|
+
connectionString: dbConnectionString, database: dbName, domain: dbDomain, password: dbPassword, username: dbUserName,
|
|
62
|
+
} = mongoConfig
|
|
63
|
+
const payloadSdkConfig: BaseMongoSdkPrivateConfig = {
|
|
64
|
+
dbConnectionString, dbDomain, dbName, dbPassword, dbUserName,
|
|
65
|
+
}
|
|
66
|
+
const params: Partial<MongoDBModuleParamsV2> = {
|
|
67
|
+
meterProvider, payloadSdkConfig, statusReporter, traceProvider,
|
|
68
|
+
}
|
|
69
|
+
// Register the MongoDB Archivist as the default
|
|
70
|
+
locator.register(MongoDBArchivistV2.factory(params), undefined, true)
|
|
71
|
+
|
|
72
|
+
// Use a persistent MongoMap for the summary repository if MongoDB is configured
|
|
73
|
+
const sdk = new BaseMongoSdk<WithStorageMeta<BalancesStepSummary>>({ ...payloadSdkConfig, collection: 'balance_summary_map' })
|
|
74
|
+
summaryMap = await MongoMap.create<MongoMap<Hash, WithStorageMeta<BalancesStepSummary>>>({ sdk })
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const summaryRepository = balanceSummaryRepositoryFromMap(summaryMap)
|
|
78
|
+
locator.register(AddressBalanceDivinerV2.factory<AddressBalanceDivinerV2>({
|
|
79
|
+
traceProvider, meterProvider, statusReporter, summaryRepository,
|
|
80
|
+
}))
|
|
81
|
+
|
|
82
|
+
const chainId = isDefined(config.chain.id)
|
|
83
|
+
? assertEx(asAddress(config.chain.id), () => 'chain.id must be an Address')
|
|
84
|
+
: ZERO_ADDRESS
|
|
85
|
+
locator.register(HeadValidationDiviner.factory<HeadValidationDiviner>({
|
|
86
|
+
traceProvider,
|
|
87
|
+
meterProvider,
|
|
88
|
+
statusReporter,
|
|
89
|
+
chainId,
|
|
90
|
+
allowedProducers: config.producer.allowlist,
|
|
91
|
+
}))
|
|
92
|
+
locator.register(MemoryArchivist.factory({
|
|
93
|
+
traceProvider, meterProvider, statusReporter,
|
|
94
|
+
}))
|
|
95
|
+
locator.register(MemorySentinel.factory({
|
|
96
|
+
traceProvider, meterProvider, statusReporter,
|
|
97
|
+
}))
|
|
98
|
+
locator.register(ViewArchivist.factory({
|
|
99
|
+
traceProvider, meterProvider, statusReporter,
|
|
100
|
+
}))
|
|
101
|
+
locator.register(ArchivistSyncDiviner.factory({
|
|
102
|
+
traceProvider, meterProvider, statusReporter,
|
|
103
|
+
}))
|
|
104
|
+
return locator
|
|
105
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Logger } from '@xylabs/logger'
|
|
2
|
+
import { ManifestWrapper } from '@xyo-network/manifest-wrapper'
|
|
3
|
+
import type { WalletInstance } from '@xyo-network/wallet-model'
|
|
4
|
+
import type { Config } from '@xyo-network/xl1-protocol-sdk'
|
|
5
|
+
|
|
6
|
+
import { getLocator } from './getLocator.ts'
|
|
7
|
+
import { NodeManifest } from './nodeManifest.ts'
|
|
8
|
+
import { PrivateChildManifests } from './private/index.ts'
|
|
9
|
+
import { PublicChildManifests } from './public/index.ts'
|
|
10
|
+
|
|
11
|
+
export interface GetNodeContext {
|
|
12
|
+
config: Config
|
|
13
|
+
logger?: Logger
|
|
14
|
+
wallet: WalletInstance
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Creates a node with the xyo-chain modules registered
|
|
19
|
+
* @param context The context to use for the node
|
|
20
|
+
* @returns A node with the xyo-chain modules registered
|
|
21
|
+
*/
|
|
22
|
+
export const getNode = async (context: GetNodeContext) => {
|
|
23
|
+
const { wallet } = context
|
|
24
|
+
const locator = await getLocator(context)
|
|
25
|
+
const wrapper = new ManifestWrapper(NodeManifest, wallet, locator, PublicChildManifests, PrivateChildManifests)
|
|
26
|
+
const [node, ...childNodes] = await wrapper.loadNodes()
|
|
27
|
+
if (childNodes?.length > 0) {
|
|
28
|
+
await Promise.all(childNodes.map(childNode => node.register(childNode)))
|
|
29
|
+
await Promise.all(childNodes.map(childNode => node.attach(childNode.address, true)))
|
|
30
|
+
}
|
|
31
|
+
return node
|
|
32
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/XYOracleNetwork/sdk-xyo-client-js/main/packages/manifest/src/schema.json",
|
|
3
|
+
"nodes": [
|
|
4
|
+
{
|
|
5
|
+
"config": {
|
|
6
|
+
"accountPath": "44'/60'/1",
|
|
7
|
+
"name": "XYOChain",
|
|
8
|
+
"schema": "network.xyo.node.config"
|
|
9
|
+
},
|
|
10
|
+
"modules": {
|
|
11
|
+
"private": [],
|
|
12
|
+
"public": []
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"schema": "network.xyo.manifest"
|
|
17
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/XYOracleNetwork/sdk-xyo-client-js/main/packages/manifest/src/schema.json",
|
|
3
|
+
"nodes": [
|
|
4
|
+
{
|
|
5
|
+
"config": {
|
|
6
|
+
"accountPath": "1",
|
|
7
|
+
"name": "Chain",
|
|
8
|
+
"schema": "network.xyo.node.config"
|
|
9
|
+
},
|
|
10
|
+
"modules": {
|
|
11
|
+
"private": [
|
|
12
|
+
{
|
|
13
|
+
"config": {
|
|
14
|
+
"accountPath": "1/1'/1'",
|
|
15
|
+
"name": "Validated",
|
|
16
|
+
"getCache": {
|
|
17
|
+
"enabled": true,
|
|
18
|
+
"maxEntries": 5000
|
|
19
|
+
},
|
|
20
|
+
"payloadSdkConfig": {
|
|
21
|
+
"collection": "chain_validated"
|
|
22
|
+
},
|
|
23
|
+
"schema": "network.xyo.archivist.config"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"config": {
|
|
28
|
+
"accountPath": "1/1'/2'",
|
|
29
|
+
"schema": "network.xyo.diviner.chain.head.validation.config",
|
|
30
|
+
"eventSubscriptions": [
|
|
31
|
+
{
|
|
32
|
+
"sourceEvent": "inserted",
|
|
33
|
+
"sourceModule": "Chain:Submissions",
|
|
34
|
+
"targetModuleFunction": "divine"
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"inArchivist": "Chain:Submissions",
|
|
38
|
+
"outArchivist": "Chain:Validated",
|
|
39
|
+
"name": "HeadValidationDiviner"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"config": {
|
|
44
|
+
"accountPath": "1/1'/3'",
|
|
45
|
+
"automations": [
|
|
46
|
+
{
|
|
47
|
+
"frequency": 1000,
|
|
48
|
+
"frequencyUnits": "millis",
|
|
49
|
+
"schema": "network.xyo.automation.interval",
|
|
50
|
+
"type": "interval"
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"name": "ChainValidationSentinel",
|
|
54
|
+
"schema": "network.xyo.sentinel.config",
|
|
55
|
+
"synchronous": true,
|
|
56
|
+
"tasks": [
|
|
57
|
+
{
|
|
58
|
+
"mod": "HeadValidationDiviner",
|
|
59
|
+
"endPoint": "divine"
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"config": {
|
|
66
|
+
"accountPath": "1/1'/4'",
|
|
67
|
+
"automations": [
|
|
68
|
+
{
|
|
69
|
+
"frequency": 60000,
|
|
70
|
+
"frequencyUnits": "millis",
|
|
71
|
+
"schema": "network.xyo.automation.interval",
|
|
72
|
+
"type": "interval"
|
|
73
|
+
}
|
|
74
|
+
],
|
|
75
|
+
"name": "AddressBalancePollingSentinel",
|
|
76
|
+
"schema": "network.xyo.sentinel.config",
|
|
77
|
+
"synchronous": true,
|
|
78
|
+
"tasks": [
|
|
79
|
+
{
|
|
80
|
+
"mod": "AddressBalanceDiviner",
|
|
81
|
+
"endPoint": "divine"
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
],
|
|
87
|
+
"public": [
|
|
88
|
+
{
|
|
89
|
+
"config": {
|
|
90
|
+
"accountPath": "1/1/1",
|
|
91
|
+
"name": "Submissions",
|
|
92
|
+
"getCache": {
|
|
93
|
+
"enabled": true,
|
|
94
|
+
"maxEntries": 5000
|
|
95
|
+
},
|
|
96
|
+
"payloadSdkConfig": {
|
|
97
|
+
"collection": "chain_submissions"
|
|
98
|
+
},
|
|
99
|
+
"schema": "network.xyo.archivist.config"
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"config": {
|
|
104
|
+
"accountPath": "1/1/2",
|
|
105
|
+
"name": "Finalized",
|
|
106
|
+
"allowedQueries": [
|
|
107
|
+
"network.xyo.query.archivist.get",
|
|
108
|
+
"network.xyo.query.archivist.next"
|
|
109
|
+
],
|
|
110
|
+
"getCache": {
|
|
111
|
+
"enabled": true,
|
|
112
|
+
"maxEntries": 5000
|
|
113
|
+
},
|
|
114
|
+
"originArchivist": "Chain:Validated",
|
|
115
|
+
"schema": "network.xyo.archivist.view.config"
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"config": {
|
|
120
|
+
"accountPath": "1/1/3",
|
|
121
|
+
"schema": "network.xyo.diviner.chain.address.balance.config",
|
|
122
|
+
"archivist": "Chain:Validated",
|
|
123
|
+
"name": "AddressBalanceDiviner",
|
|
124
|
+
"eventSubscriptions": [
|
|
125
|
+
{
|
|
126
|
+
"sourceEvent": "inserted",
|
|
127
|
+
"sourceModule": "Chain:Validated",
|
|
128
|
+
"targetModuleFunction": "divine"
|
|
129
|
+
}
|
|
130
|
+
]
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
],
|
|
137
|
+
"schema": "network.xyo.manifest"
|
|
138
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/XYOracleNetwork/sdk-xyo-client-js/main/packages/manifest/src/schema.json",
|
|
3
|
+
"nodes": [
|
|
4
|
+
{
|
|
5
|
+
"config": {
|
|
6
|
+
"accountPath": "2",
|
|
7
|
+
"name": "Pending",
|
|
8
|
+
"schema": "network.xyo.node.config"
|
|
9
|
+
},
|
|
10
|
+
"modules": {
|
|
11
|
+
"private": [],
|
|
12
|
+
"public": [
|
|
13
|
+
{
|
|
14
|
+
"config": {
|
|
15
|
+
"accountPath": "2/1/2",
|
|
16
|
+
"name": "PendingTransactions",
|
|
17
|
+
"getCache": {
|
|
18
|
+
"enabled": true,
|
|
19
|
+
"maxEntries": 5000
|
|
20
|
+
},
|
|
21
|
+
"labels": {
|
|
22
|
+
"network.xyo.storage.class": "mongodb"
|
|
23
|
+
},
|
|
24
|
+
"payloadSdkConfig": {
|
|
25
|
+
"collection": "pending_bundles"
|
|
26
|
+
},
|
|
27
|
+
"schema": "network.xyo.archivist.config"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"schema": "network.xyo.manifest"
|
|
35
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ModuleManifest, PackageManifestPayload } from '@xyo-network/manifest-model'
|
|
2
|
+
|
|
3
|
+
import Chain from './Chain.json' with { type: 'json' }
|
|
4
|
+
import Pending from './Pending.json' with { type: 'json' }
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Chain Node Manifest
|
|
8
|
+
*/
|
|
9
|
+
export const ChainNodeManifest = Chain as PackageManifestPayload
|
|
10
|
+
/**
|
|
11
|
+
* Pending Node Manifest
|
|
12
|
+
*/
|
|
13
|
+
export const PendingNodeManifest = Pending as PackageManifestPayload
|
|
14
|
+
/**
|
|
15
|
+
* Public Child Manifests
|
|
16
|
+
*/
|
|
17
|
+
export const PublicChildManifests: ModuleManifest[] = [
|
|
18
|
+
...ChainNodeManifest.nodes,
|
|
19
|
+
...PendingNodeManifest.nodes,
|
|
20
|
+
]
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { MemoryNode } from '@xyo-network/node-memory'
|
|
2
|
+
import { HDWallet } from '@xyo-network/wallet'
|
|
3
|
+
import { getDefaultConfig } from '@xyo-network/xl1-protocol-sdk'
|
|
4
|
+
import {
|
|
5
|
+
beforeAll, describe, expect,
|
|
6
|
+
it,
|
|
7
|
+
} from 'vitest'
|
|
8
|
+
|
|
9
|
+
import { getNode, GetNodeContext } from '../../getNode.ts'
|
|
10
|
+
import { SilentLogger } from '@xylabs/logger'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @group manifest
|
|
14
|
+
*/
|
|
15
|
+
describe('Node', () => {
|
|
16
|
+
let node: MemoryNode
|
|
17
|
+
let context: GetNodeContext
|
|
18
|
+
|
|
19
|
+
beforeAll(async () => {
|
|
20
|
+
const config = getDefaultConfig()
|
|
21
|
+
const logger = new SilentLogger()
|
|
22
|
+
const wallet = await HDWallet.random()
|
|
23
|
+
context = {
|
|
24
|
+
config, logger, wallet,
|
|
25
|
+
}
|
|
26
|
+
// Create a node with the default configuration
|
|
27
|
+
node = await getNode(context)
|
|
28
|
+
})
|
|
29
|
+
it('should return node', () => {
|
|
30
|
+
expect(node).toBeDefined()
|
|
31
|
+
})
|
|
32
|
+
})
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
customPoweredByHeader,
|
|
3
|
+
disableCaseSensitiveRouting,
|
|
4
|
+
disableExpressDefaultPoweredByHeader,
|
|
5
|
+
getJsonBodyParser,
|
|
6
|
+
getJsonBodyParserOptions,
|
|
7
|
+
responseProfiler,
|
|
8
|
+
standardErrors,
|
|
9
|
+
standardResponses,
|
|
10
|
+
} from '@xylabs/express'
|
|
11
|
+
import type { NodeInstance } from '@xyo-network/node-model'
|
|
12
|
+
import compression from 'compression'
|
|
13
|
+
import cors from 'cors'
|
|
14
|
+
import type { Express } from 'express'
|
|
15
|
+
import express from 'express'
|
|
16
|
+
|
|
17
|
+
import { addInstrumentation } from './instrumentation.ts'
|
|
18
|
+
import { addRoutes } from './routes/index.ts'
|
|
19
|
+
|
|
20
|
+
export const getApp = (node: NodeInstance): Express => {
|
|
21
|
+
addInstrumentation()
|
|
22
|
+
const app = express()
|
|
23
|
+
app.set('etag', false)
|
|
24
|
+
|
|
25
|
+
app.use(cors())
|
|
26
|
+
app.use(compression())
|
|
27
|
+
app.use(responseProfiler)
|
|
28
|
+
app.use(getJsonBodyParser(getJsonBodyParserOptions({ limit: '1mb' })))
|
|
29
|
+
app.use(standardResponses)
|
|
30
|
+
disableExpressDefaultPoweredByHeader(app)
|
|
31
|
+
app.use(customPoweredByHeader)
|
|
32
|
+
disableCaseSensitiveRouting(app)
|
|
33
|
+
app.node = node
|
|
34
|
+
addRoutes(app)
|
|
35
|
+
app.use(standardErrors)
|
|
36
|
+
return app
|
|
37
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from './app.ts'
|
|
2
|
+
export * from './server.ts'
|
|
3
|
+
|
|
4
|
+
import type { NodeInstance } from '@xyo-network/node-model'
|
|
5
|
+
|
|
6
|
+
declare global {
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
8
|
+
namespace Express {
|
|
9
|
+
interface Application {
|
|
10
|
+
node: NodeInstance
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { registerInstrumentations } from '@opentelemetry/instrumentation'
|
|
2
|
+
import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express'
|
|
3
|
+
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Registers OpenTelemetry instrumentations for HTTP and Express.
|
|
7
|
+
* This function is used to set up the necessary instrumentations for monitoring
|
|
8
|
+
* HTTP requests and Express applications. Since it monkey patches the Express
|
|
9
|
+
* router & middleware system, it should be called before any Express applications
|
|
10
|
+
* are defined.
|
|
11
|
+
*/
|
|
12
|
+
export const addInstrumentation = () => {
|
|
13
|
+
const instrumentations = [new HttpInstrumentation(), new ExpressInstrumentation()]
|
|
14
|
+
registerInstrumentations({ instrumentations })
|
|
15
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Express } from 'express'
|
|
2
|
+
|
|
3
|
+
import { addNodeRoutes } from './address/index.ts'
|
|
4
|
+
import { addDataLakeRoutes } from './dataLake/index.ts'
|
|
5
|
+
import { addRpcRoutes } from './rpc/index.ts'
|
|
6
|
+
|
|
7
|
+
export const addRoutes = (app: Express) => {
|
|
8
|
+
addRpcRoutes(app)
|
|
9
|
+
addDataLakeRoutes(app)
|
|
10
|
+
addNodeRoutes(app)
|
|
11
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Express } from 'express'
|
|
2
|
+
import { StatusCodes } from 'http-status-codes'
|
|
3
|
+
|
|
4
|
+
import { getAddress } from './get/index.ts'
|
|
5
|
+
import { postAddress } from './post/index.ts'
|
|
6
|
+
|
|
7
|
+
export const addNodeRoutes = (app: Express) => {
|
|
8
|
+
const defaultModule = app.node
|
|
9
|
+
const address = defaultModule.address
|
|
10
|
+
const defaultModuleEndpoint = `/${address}`
|
|
11
|
+
app.get('/', (_req, res) => res.redirect(StatusCodes.MOVED_TEMPORARILY, defaultModuleEndpoint))
|
|
12
|
+
app.post('/', (_req, res) => res.redirect(StatusCodes.TEMPORARY_REDIRECT, defaultModuleEndpoint))
|
|
13
|
+
app.get('/:address', getAddress)
|
|
14
|
+
app.post('/:address', postAddress)
|
|
15
|
+
app.get('/:hash', (_req, res) => {
|
|
16
|
+
res.sendStatus(StatusCodes.NOT_FOUND)
|
|
17
|
+
})
|
|
18
|
+
app.post('/:hash', (_req, res) => {
|
|
19
|
+
res.sendStatus(StatusCodes.NOT_FOUND)
|
|
20
|
+
})
|
|
21
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { assertEx } from '@xylabs/assert'
|
|
2
|
+
import { asyncHandler } from '@xylabs/express'
|
|
3
|
+
import { asAddress, toAddress } from '@xylabs/hex'
|
|
4
|
+
import { isModuleIdentifierPart } from '@xyo-network/module-model'
|
|
5
|
+
import type { Payload } from '@xyo-network/payload-model'
|
|
6
|
+
import type { RequestHandler } from 'express'
|
|
7
|
+
import { StatusCodes } from 'http-status-codes'
|
|
8
|
+
|
|
9
|
+
import type { AddressPathParams } from '../AddressPathParams.ts'
|
|
10
|
+
|
|
11
|
+
const handler: RequestHandler<AddressPathParams, Payload[]> = async (req, res, next) => {
|
|
12
|
+
const { address: rawAddress } = req.params
|
|
13
|
+
const { node } = req.app
|
|
14
|
+
const address = asAddress(rawAddress)
|
|
15
|
+
if (address !== undefined) {
|
|
16
|
+
let mod = node.address === address ? node : (await node.resolve(address, { direction: 'down' }))
|
|
17
|
+
if (mod) {
|
|
18
|
+
res.json(await mod.state())
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (isModuleIdentifierPart(rawAddress)) {
|
|
23
|
+
const moduleIdentifier = toAddress(rawAddress)
|
|
24
|
+
const mod = await node.resolve(moduleIdentifier, { direction: 'down' })
|
|
25
|
+
if (mod) {
|
|
26
|
+
const moduleAddress = assertEx(mod?.address, () => 'Error redirecting to module by address')
|
|
27
|
+
res.redirect(StatusCodes.MOVED_TEMPORARILY, `/${moduleAddress}`)
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
next('route')
|
|
32
|
+
}
|
|
33
|
+
export const getAddress = asyncHandler(handler)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './get.ts'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './addNodeRoutes.ts'
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { BoundWitness, QueryBoundWitness } from '@xyo-network/boundwitness-model'
|
|
2
|
+
import { BoundWitnessSchema } from '@xyo-network/boundwitness-model'
|
|
3
|
+
import type { ModuleConfig, ModuleInstance } from '@xyo-network/module-model'
|
|
4
|
+
import { ModuleConfigSchema } from '@xyo-network/module-model'
|
|
5
|
+
import type { Payload } from '@xyo-network/payload-model'
|
|
6
|
+
import type { Request } from 'express'
|
|
7
|
+
|
|
8
|
+
const DEFAULT_DEPTH = 5 as const
|
|
9
|
+
|
|
10
|
+
export const getQueryConfig = (mod: ModuleInstance, req: Request, bw: QueryBoundWitness, payloads?: Payload[]): ModuleConfig | undefined => {
|
|
11
|
+
// TODO: Filter based on query addresses?
|
|
12
|
+
// Recurse through payloads for nested BWs
|
|
13
|
+
const nestedBwAddresses
|
|
14
|
+
= payloads
|
|
15
|
+
?.flat(DEFAULT_DEPTH)
|
|
16
|
+
.filter<BoundWitness>((payload): payload is BoundWitness => payload?.schema === BoundWitnessSchema)
|
|
17
|
+
.map(bw => bw.addresses) || []
|
|
18
|
+
// TODO: Do we want to end up with a list of addresses or a list of address lists?
|
|
19
|
+
const addresses = [bw.addresses, ...nestedBwAddresses].filter(address => address.length > 0)
|
|
20
|
+
const allowed = addresses.length > 0 ? Object.fromEntries(mod.queries.map(schema => [schema, addresses])) : {}
|
|
21
|
+
const security = { allowed }
|
|
22
|
+
return { schema: ModuleConfigSchema, security }
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './post.ts'
|