From 85587c087df4b0cefaf10a1996470afdc750d112 Mon Sep 17 00:00:00 2001 From: Dima Date: Mon, 21 Sep 2020 16:42:53 +0300 Subject: [PATCH] Fire client (#947) --- .npmignore | 3 +-- package.json | 2 +- src/address.ts | 17 +++++++++++++++++ src/fluence.ts | 2 +- src/fluenceClient.ts | 36 ++++++++++++++++++++++++++++-------- src/fluenceConnection.ts | 8 +++++--- src/functionCall.ts | 4 ++-- src/subscriptions.ts | 8 ++++---- tsconfig.json | 4 +++- 9 files changed, 62 insertions(+), 22 deletions(-) diff --git a/.npmignore b/.npmignore index 4678238e..ef247aae 100644 --- a/.npmignore +++ b/.npmignore @@ -8,5 +8,4 @@ src tsconfig.json webpack.config.js -*.js.map -bundle \ No newline at end of file +bundle diff --git a/package.json b/package.json index 656ac0e8..c54358b7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fluence", - "version": "0.7.11", + "version": "0.7.24", "description": "the browser js-libp2p client for the Fluence network", "main": "./dist/fluence.js", "typings": "./dist/fluence.d.ts", diff --git a/src/address.ts b/src/address.ts index 8221770f..e4d1a2c9 100644 --- a/src/address.ts +++ b/src/address.ts @@ -36,6 +36,10 @@ export enum ProtocolType { const PROTOCOL = "fluence:"; +export function getSignature(address: Address): string | undefined { + return address.protocols.find(p => p.protocol === ProtocolType.Signature)?.value +} + export function addressToString(address: Address): string { let addressStr = PROTOCOL; @@ -83,6 +87,19 @@ export function parseProtocol(protocol: string, protocolIterator: IterableIterat } +export async function createRelayAddressWithSig(relay: string, peerId: PeerId, sig: string, hash?: string): Promise
{ + let protocols = [ + {protocol: ProtocolType.Peer, value: relay}, + {protocol: ProtocolType.Client, value: peerId.toB58String()}, + {protocol: ProtocolType.Signature, value: sig} + ]; + + return { + protocols: protocols, + hash: hash + } +} + export async function createRelayAddress(relay: string, peerId: PeerId, withSig: boolean, hash?: string): Promise
{ let protocols = [ diff --git a/src/fluence.ts b/src/fluence.ts index f6f74805..23802b3f 100644 --- a/src/fluence.ts +++ b/src/fluence.ts @@ -24,7 +24,7 @@ log.setLevel('info') export default class Fluence { - setLogLevel(level: LogLevelDesc): void { + static setLogLevel(level: LogLevelDesc): void { log.setLevel(level); } diff --git a/src/fluenceClient.ts b/src/fluenceClient.ts index cecbb23d..87633a76 100644 --- a/src/fluenceClient.ts +++ b/src/fluenceClient.ts @@ -20,7 +20,7 @@ import { createRelayAddress, createProviderAddress, ProtocolType, - addressToString + addressToString, createRelayAddressWithSig } from "./address"; import {callToString, FunctionCall, genUUID, makeFunctionCall,} from "./functionCall"; import * as PeerId from "peer-id"; @@ -55,7 +55,7 @@ export class FluenceClient { readonly selfPeerIdStr: string; private nodePeerIdStr: string; - private connection: FluenceConnection; + connection: FluenceConnection; private services: LocalServices = new LocalServices(); @@ -79,12 +79,12 @@ export class FluenceClient { * @param predicate will be applied to each incoming call until it matches * @param ignoreErrors ignore an errors, wait for success response */ - waitResponse(predicate: (args: any, target: Address, replyTo: Address) => (boolean | undefined), ignoreErrors: boolean): Promise { + waitResponse(predicate: (args: any, target: Address, replyTo: Address, moduleId?: string, fname?: string) => (boolean | undefined), ignoreErrors: boolean): Promise { return new Promise((resolve, reject) => { // subscribe for responses, to handle response // TODO if there's no conn, reject - this.subscribe((args: any, target: Address, replyTo: Address) => { - if (predicate(args, target, replyTo)) { + this.subscribe((args: any, target: Address, replyTo: Address, moduleId?: string, fname?: string) => { + if (predicate(args, target, replyTo, moduleId, fname)) { if (args.reason) { if (ignoreErrors) { return false; @@ -134,6 +134,25 @@ export class FluenceClient { return await this.waitResponse(predicate, true); } + /** + * Send a message to a client that connected with a relay. + * + * @param relayId + * @param clientId + * @param sig + * @param moduleId + * @param args message to the service + * @param fname function name + * @param name debug info + */ + async callClient(relayId: string, clientId: string, sig: string, moduleId: string, args: any, fname?: string, name?: string): Promise { + let msgId = genUUID(); + let clientPeerId = await PeerId.createFromB58String(clientId); + let address = await createRelayAddressWithSig(relayId, clientPeerId, sig); + + await this.sendCall({target: address, args: args, moduleId: moduleId, fname: fname, msgId: msgId, name: name}) + } + /** * Send a call to the local service and wait a response matches predicate on a peer the client connected with. * @@ -373,7 +392,7 @@ export class FluenceClient { // subscribe new hook for every incoming call, to handle in-service responses and other different cases // the hook will be deleted if it will return `true` - subscribe(predicate: (args: any, target: Address, replyTo: Address) => (boolean | undefined)) { + subscribe(predicate: (args: any, target: Address, replyTo: Address, moduleId?: string, fname?: string) => (boolean | undefined)) { this.subscriptions.subscribe(predicate) } @@ -417,8 +436,9 @@ export class FluenceClient { } let peerId = PeerId.createFromB58String(nodePeerId); - let relayAddress = await createRelayAddress(nodePeerId, this.selfPeerId, true); - let connection = new FluenceConnection(multiaddr, peerId, this.selfPeerId, relayAddress, this.handleCall()); + let sender = await createRelayAddress(nodePeerId, this.selfPeerId, false); + let replyTo = await createRelayAddress(nodePeerId, this.selfPeerId, true); + let connection = new FluenceConnection(multiaddr, peerId, this.selfPeerId, sender, replyTo, this.handleCall()); await connection.connect(); diff --git a/src/fluenceConnection.ts b/src/fluenceConnection.ts index e1cdb68d..f0ce9294 100644 --- a/src/fluenceConnection.ts +++ b/src/fluenceConnection.ts @@ -46,24 +46,26 @@ export class FluenceConnection { private readonly selfPeerId: PeerId; readonly sender: Address; + readonly replyTo: Address; private node: LibP2p; private readonly address: Multiaddr; readonly nodePeerId: PeerId; private readonly selfPeerIdStr: string; private readonly handleCall: (call: FunctionCall) => FunctionCall | undefined; - constructor(multiaddr: Multiaddr, hostPeerId: PeerId, selfPeerId: PeerId, sender: Address, handleCall: (call: FunctionCall) => FunctionCall | undefined) { + constructor(multiaddr: Multiaddr, hostPeerId: PeerId, selfPeerId: PeerId, sender: Address, replyTo: Address, handleCall: (call: FunctionCall) => FunctionCall | undefined) { this.selfPeerId = selfPeerId; this.handleCall = handleCall; this.selfPeerIdStr = selfPeerId.toB58String(); this.address = multiaddr; this.nodePeerId = hostPeerId; this.sender = sender + this.replyTo = replyTo } makeReplyTo(reply?: string): Address { if (reply) { - let replyToWithHash = {...this.sender} + let replyToWithHash = {...this.replyTo} if (typeof reply === "string") replyToWithHash.hash = reply; return replyToWithHash; } else { @@ -176,7 +178,7 @@ export class FluenceConnection { async provideName(name: string) { let target = createPeerAddress(this.nodePeerId.toB58String()) - let regMsg = await makeProvideMessage(name, target, this.sender); + let regMsg = await makeProvideMessage(name, target, this.sender, this.replyTo); await this.sendCall(regMsg); } } diff --git a/src/functionCall.ts b/src/functionCall.ts index ed8f1c76..e8f3d5cf 100644 --- a/src/functionCall.ts +++ b/src/functionCall.ts @@ -94,8 +94,8 @@ export function genUUID() { /** * Message to provide new name. */ -export async function makeProvideMessage(name: string, target: Address, sender: Address): Promise { - return makeFunctionCall(genUUID(), target, sender, {name: name, address: addressToString(sender)}, "provide", undefined, sender, "provide service_id"); +export async function makeProvideMessage(name: string, target: Address, sender: Address, sigAddress: Address): Promise { + return makeFunctionCall(genUUID(), target, sender, {name: name, address: addressToString(sigAddress)}, "provide", undefined, sender, "provide service_id"); } // TODO uncomment when this will be implemented in Fluence network diff --git a/src/subscriptions.ts b/src/subscriptions.ts index b776dc8a..9386303e 100644 --- a/src/subscriptions.ts +++ b/src/subscriptions.ts @@ -18,7 +18,7 @@ import {FunctionCall} from "./functionCall"; import {Address} from "./address"; export class Subscriptions { - private subscriptions: ((args: any, target: Address, replyTo: Address) => (boolean | undefined))[] = []; + private subscriptions: ((args: any, target: Address, replyTo: Address, module?: string, fname?: string) => (boolean | undefined))[] = []; constructor() {} @@ -27,7 +27,7 @@ export class Subscriptions { * If subscription returns true, delete subscription. * @param f */ - subscribe(f: (args: any, target: Address, replyTo: Address) => (boolean | undefined)) { + subscribe(f: (args: any, target: Address, replyTo: Address, moduleId?: string, fname?: string) => (boolean | undefined)) { this.subscriptions.push(f); } @@ -36,7 +36,7 @@ export class Subscriptions { * @param call */ applyToSubscriptions(call: FunctionCall) { - // if subscription return false - delete it from subscriptions - this.subscriptions = this.subscriptions.filter(callback => !callback(call.arguments, call.target, call.reply_to)) + // if subscription return true - delete it from subscriptions + this.subscriptions = this.subscriptions.filter(callback => !callback(call.arguments, call.target, call.reply_to, call.module, call.fname)) } } diff --git a/tsconfig.json b/tsconfig.json index 45fb7ffc..56a537cd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,18 +7,20 @@ ], "outDir": "./dist/", "sourceMap": true, + "inlineSources": true, "noImplicitAny": true, "strictFunctionTypes": true, "allowSyntheticDefaultImports": true, "resolveJsonModule": true, "pretty": true, - "target": "esnext", + "target": "es2018", "module": "commonjs", "moduleResolution": "node", "declaration": true, "strict": true, "strictNullChecks": false, "esModuleInterop": true, + "declarationMap": true, "baseUrl": "." }, "exclude": [