diff --git a/package-lock.json b/package-lock.json index c41164d85c..13caa2180c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29090,8 +29090,11 @@ "@babel/runtime-corejs3": "^7.24.7", "@lit-protocol/core": "2.2.5", "@lit-protocol/uint8arrays": "^6.1.0", + "@protobuf-ts/runtime": "^2.8.2", + "@protobuf-ts/runtime-rpc": "^2.8.2", "@streamr/config": "^5.3.13", "@streamr/dht": "101.0.1", + "@streamr/proto-rpc": "101.0.1", "@streamr/trackerless-network": "101.0.1", "@streamr/utils": "101.0.1", "core-js": "^3.36.0", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 202a11a4df..04aeca7766 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -86,8 +86,11 @@ "@babel/runtime-corejs3": "^7.24.7", "@lit-protocol/core": "2.2.5", "@lit-protocol/uint8arrays": "^6.1.0", + "@protobuf-ts/runtime": "^2.8.2", + "@protobuf-ts/runtime-rpc": "^2.8.2", "@streamr/config": "^5.3.13", "@streamr/dht": "101.0.1", + "@streamr/proto-rpc": "101.0.1", "@streamr/trackerless-network": "101.0.1", "@streamr/utils": "101.0.1", "core-js": "^3.36.0", diff --git a/packages/sdk/src/NetworkNodeFacade.ts b/packages/sdk/src/NetworkNodeFacade.ts index a58028a598..286cb632cd 100644 --- a/packages/sdk/src/NetworkNodeFacade.ts +++ b/packages/sdk/src/NetworkNodeFacade.ts @@ -3,6 +3,8 @@ */ import { DhtAddress, PeerDescriptor } from '@streamr/dht' import { + ExternalRpcClient, + ExternalRpcClientClass, NetworkOptions, StreamMessage as NewStreamMessage, ProxyDirection, @@ -20,6 +22,9 @@ import { StreamMessage as OldStreamMessage } from './protocol/StreamMessage' import { StreamMessageTranslator } from './protocol/StreamMessageTranslator' import { pOnce } from './utils/promises' import { peerDescriptorTranslator } from './utils/utils' +import { ProtoRpcClient } from '@streamr/proto-rpc' +import { IMessageType } from '@protobuf-ts/runtime' +import { ServerCallContext } from '@protobuf-ts/runtime-rpc' // TODO should we make getNode() an internal method, and provide these all these services as client methods? /** @deprecated This in an internal interface */ @@ -52,6 +57,19 @@ export interface NetworkNodeStub { ) => Promise isProxiedStreamPart(streamPartId: StreamPartID): boolean setStreamPartEntryPoints: (streamPartId: StreamPartID, peerDescriptors: PeerDescriptor[]) => void + createExternalRpcClient(clientClass: ExternalRpcClientClass ): ProtoRpcClient + registerExternalNetworkRpcMethod< + RequestClass extends IMessageType, + ResponseClass extends IMessageType, + RequestType extends object, + ResponseType extends object + >( + request: RequestClass, + response: ResponseClass, + name: string, + fn: (req: RequestType, context: ServerCallContext) => Promise + ): void + } export interface Events { diff --git a/packages/sdk/test/test-utils/fake/FakeNetworkNode.ts b/packages/sdk/test/test-utils/fake/FakeNetworkNode.ts index 728fc1ef45..4e8cd87fb0 100644 --- a/packages/sdk/test/test-utils/fake/FakeNetworkNode.ts +++ b/packages/sdk/test/test-utils/fake/FakeNetworkNode.ts @@ -1,5 +1,10 @@ import { DhtAddress, PeerDescriptor, getDhtAddressFromRaw } from '@streamr/dht' -import { NetworkOptions, StreamMessage as NewStreamMessage, ProxyDirection } from '@streamr/trackerless-network' +import { + ExternalRpcClient, + NetworkOptions, + StreamMessage as NewStreamMessage, + ProxyDirection +} from '@streamr/trackerless-network' import { EthereumAddress, MetricsContext, StreamPartID } from '@streamr/utils' import crypto from 'crypto' import pull from 'lodash/pull' @@ -7,6 +12,7 @@ import { Lifecycle, scoped } from 'tsyringe' import { NetworkNodeFactory, NetworkNodeStub } from '../../../src/NetworkNodeFacade' import { StreamMessageTranslator } from '../../../src/protocol/StreamMessageTranslator' import { FakeNetwork } from './FakeNetwork' +import { ProtoRpcClient } from '@streamr/proto-rpc' type MessageListener = (msg: NewStreamMessage) => void @@ -127,6 +133,15 @@ export class FakeNetworkNode implements NetworkNodeStub { getDiagnosticInfo(): Record { return {} } + + // eslint-disable-next-line class-methods-use-this + createExternalRpcClient(): ProtoRpcClient { + return {} as any + } + + // eslint-disable-next-line class-methods-use-this + registerExternalNetworkRpcMethod(): void {} + } @scoped(Lifecycle.ContainerScoped) diff --git a/packages/trackerless-network/src/NetworkNode.ts b/packages/trackerless-network/src/NetworkNode.ts index 6880146b35..734c1af4b5 100644 --- a/packages/trackerless-network/src/NetworkNode.ts +++ b/packages/trackerless-network/src/NetworkNode.ts @@ -2,10 +2,10 @@ import { DhtAddress, PeerDescriptor } from '@streamr/dht' import { EthereumAddress, MetricsContext, StreamPartID } from '@streamr/utils' import { NetworkOptions, NetworkStack, NodeInfo } from './NetworkStack' import { ProxyDirection, StreamMessage } from './proto/packages/trackerless-network/protos/NetworkRpc' -import { ExternalNetworkRpc } from './logic/ExternalNetworkRpc' +import { ExternalNetworkRpc, ExternalRpcClient, ExternalRpcClientClass } from './logic/ExternalNetworkRpc' import { IMessageType } from '@protobuf-ts/runtime' -import { ServerCallContext, ServiceInfo } from '@protobuf-ts/runtime-rpc' -import { ClassType, ClientTransport, ProtoRpcClient } from '@streamr/proto-rpc' +import { ServerCallContext } from '@protobuf-ts/runtime-rpc' +import { ProtoRpcClient } from '@streamr/proto-rpc' export const createNetworkNode = (opts: NetworkOptions): NetworkNode => { return new NetworkNode(new NetworkStack(opts)) @@ -132,8 +132,7 @@ export class NetworkNode { this.externalNetworkRpc!.registerRpcMethod(request, response, name, fn) } - // eslint-disable-next-line @typescript-eslint/prefer-function-type - createExternalRpcClient(clientClass: { new (clientTransport: ClientTransport): T }): ProtoRpcClient { + createExternalRpcClient(clientClass: ExternalRpcClientClass ): ProtoRpcClient { return this.externalNetworkRpc!.createRpcClient(clientClass) } diff --git a/packages/trackerless-network/src/exports.ts b/packages/trackerless-network/src/exports.ts index 7c9d700957..eae7abffd6 100644 --- a/packages/trackerless-network/src/exports.ts +++ b/packages/trackerless-network/src/exports.ts @@ -13,4 +13,4 @@ export { SignatureType, StreamMessage } from './proto/packages/trackerless-network/protos/NetworkRpc' - +export { ExternalRpcClient, ExternalRpcClientClass } from './logic/ExternalNetworkRpc' diff --git a/packages/trackerless-network/src/logic/ExternalNetworkRpc.ts b/packages/trackerless-network/src/logic/ExternalNetworkRpc.ts index 5d55a69db7..b030e80e45 100644 --- a/packages/trackerless-network/src/logic/ExternalNetworkRpc.ts +++ b/packages/trackerless-network/src/logic/ExternalNetworkRpc.ts @@ -5,6 +5,11 @@ import { ClassType, ClientTransport, ProtoRpcClient, toProtoRpcClient } from '@s export const SERVICE_ID = 'external-network-service' +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions +export type ExternalRpcClient = ServiceInfo & ClassType +// eslint-disable-next-line @typescript-eslint/prefer-function-type, @typescript-eslint/consistent-type-definitions +export type ExternalRpcClientClass = { new (clientTransport: ClientTransport): T } + export class ExternalNetworkRpc { private readonly rpcCommunicator: ListeningRpcCommunicator @@ -27,8 +32,7 @@ export class ExternalNetworkRpc { this.rpcCommunicator.registerRpcMethod(request, response, name, fn) } - // eslint-disable-next-line @typescript-eslint/prefer-function-type - createRpcClient(clientClass: { new (clientTransport: ClientTransport): T }): ProtoRpcClient { + createRpcClient(clientClass: ExternalRpcClientClass): ProtoRpcClient { return toProtoRpcClient(new clientClass(this.rpcCommunicator.getRpcClientTransport())) }