Fire client (#947)

This commit is contained in:
Dima 2020-09-21 16:42:53 +03:00 committed by GitHub
parent bc46062279
commit 85587c087d
9 changed files with 62 additions and 22 deletions

View File

@ -8,5 +8,4 @@ src
tsconfig.json tsconfig.json
webpack.config.js webpack.config.js
*.js.map
bundle bundle

View File

@ -1,6 +1,6 @@
{ {
"name": "fluence", "name": "fluence",
"version": "0.7.11", "version": "0.7.24",
"description": "the browser js-libp2p client for the Fluence network", "description": "the browser js-libp2p client for the Fluence network",
"main": "./dist/fluence.js", "main": "./dist/fluence.js",
"typings": "./dist/fluence.d.ts", "typings": "./dist/fluence.d.ts",

View File

@ -36,6 +36,10 @@ export enum ProtocolType {
const PROTOCOL = "fluence:"; 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 { export function addressToString(address: Address): string {
let addressStr = PROTOCOL; 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<Address> {
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<Address> { export async function createRelayAddress(relay: string, peerId: PeerId, withSig: boolean, hash?: string): Promise<Address> {
let protocols = [ let protocols = [

View File

@ -24,7 +24,7 @@ log.setLevel('info')
export default class Fluence { export default class Fluence {
setLogLevel(level: LogLevelDesc): void { static setLogLevel(level: LogLevelDesc): void {
log.setLevel(level); log.setLevel(level);
} }

View File

@ -20,7 +20,7 @@ import {
createRelayAddress, createRelayAddress,
createProviderAddress, createProviderAddress,
ProtocolType, ProtocolType,
addressToString addressToString, createRelayAddressWithSig
} from "./address"; } from "./address";
import {callToString, FunctionCall, genUUID, makeFunctionCall,} from "./functionCall"; import {callToString, FunctionCall, genUUID, makeFunctionCall,} from "./functionCall";
import * as PeerId from "peer-id"; import * as PeerId from "peer-id";
@ -55,7 +55,7 @@ export class FluenceClient {
readonly selfPeerIdStr: string; readonly selfPeerIdStr: string;
private nodePeerIdStr: string; private nodePeerIdStr: string;
private connection: FluenceConnection; connection: FluenceConnection;
private services: LocalServices = new LocalServices(); 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 predicate will be applied to each incoming call until it matches
* @param ignoreErrors ignore an errors, wait for success response * @param ignoreErrors ignore an errors, wait for success response
*/ */
waitResponse(predicate: (args: any, target: Address, replyTo: Address) => (boolean | undefined), ignoreErrors: boolean): Promise<any> { waitResponse(predicate: (args: any, target: Address, replyTo: Address, moduleId?: string, fname?: string) => (boolean | undefined), ignoreErrors: boolean): Promise<any> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// subscribe for responses, to handle response // subscribe for responses, to handle response
// TODO if there's no conn, reject // TODO if there's no conn, reject
this.subscribe((args: any, target: Address, replyTo: Address) => { this.subscribe((args: any, target: Address, replyTo: Address, moduleId?: string, fname?: string) => {
if (predicate(args, target, replyTo)) { if (predicate(args, target, replyTo, moduleId, fname)) {
if (args.reason) { if (args.reason) {
if (ignoreErrors) { if (ignoreErrors) {
return false; return false;
@ -134,6 +134,25 @@ export class FluenceClient {
return await this.waitResponse(predicate, true); 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<void> {
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. * 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 // 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` // 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) this.subscriptions.subscribe(predicate)
} }
@ -417,8 +436,9 @@ export class FluenceClient {
} }
let peerId = PeerId.createFromB58String(nodePeerId); let peerId = PeerId.createFromB58String(nodePeerId);
let relayAddress = await createRelayAddress(nodePeerId, this.selfPeerId, true); let sender = await createRelayAddress(nodePeerId, this.selfPeerId, false);
let connection = new FluenceConnection(multiaddr, peerId, this.selfPeerId, relayAddress, this.handleCall()); let replyTo = await createRelayAddress(nodePeerId, this.selfPeerId, true);
let connection = new FluenceConnection(multiaddr, peerId, this.selfPeerId, sender, replyTo, this.handleCall());
await connection.connect(); await connection.connect();

View File

@ -46,24 +46,26 @@ export class FluenceConnection {
private readonly selfPeerId: PeerId; private readonly selfPeerId: PeerId;
readonly sender: Address; readonly sender: Address;
readonly replyTo: Address;
private node: LibP2p; private node: LibP2p;
private readonly address: Multiaddr; private readonly address: Multiaddr;
readonly nodePeerId: PeerId; readonly nodePeerId: PeerId;
private readonly selfPeerIdStr: string; private readonly selfPeerIdStr: string;
private readonly handleCall: (call: FunctionCall) => FunctionCall | undefined; 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.selfPeerId = selfPeerId;
this.handleCall = handleCall; this.handleCall = handleCall;
this.selfPeerIdStr = selfPeerId.toB58String(); this.selfPeerIdStr = selfPeerId.toB58String();
this.address = multiaddr; this.address = multiaddr;
this.nodePeerId = hostPeerId; this.nodePeerId = hostPeerId;
this.sender = sender this.sender = sender
this.replyTo = replyTo
} }
makeReplyTo(reply?: string): Address { makeReplyTo(reply?: string): Address {
if (reply) { if (reply) {
let replyToWithHash = {...this.sender} let replyToWithHash = {...this.replyTo}
if (typeof reply === "string") replyToWithHash.hash = reply; if (typeof reply === "string") replyToWithHash.hash = reply;
return replyToWithHash; return replyToWithHash;
} else { } else {
@ -176,7 +178,7 @@ export class FluenceConnection {
async provideName(name: string) { async provideName(name: string) {
let target = createPeerAddress(this.nodePeerId.toB58String()) 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); await this.sendCall(regMsg);
} }
} }

View File

@ -94,8 +94,8 @@ export function genUUID() {
/** /**
* Message to provide new name. * Message to provide new name.
*/ */
export async function makeProvideMessage(name: string, target: Address, sender: Address): Promise<FunctionCall> { export async function makeProvideMessage(name: string, target: Address, sender: Address, sigAddress: Address): Promise<FunctionCall> {
return makeFunctionCall(genUUID(), target, sender, {name: name, address: addressToString(sender)}, "provide", undefined, sender, "provide service_id"); 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 // TODO uncomment when this will be implemented in Fluence network

View File

@ -18,7 +18,7 @@ import {FunctionCall} from "./functionCall";
import {Address} from "./address"; import {Address} from "./address";
export class Subscriptions { 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() {} constructor() {}
@ -27,7 +27,7 @@ export class Subscriptions {
* If subscription returns true, delete subscription. * If subscription returns true, delete subscription.
* @param f * @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); this.subscriptions.push(f);
} }
@ -36,7 +36,7 @@ export class Subscriptions {
* @param call * @param call
*/ */
applyToSubscriptions(call: FunctionCall) { applyToSubscriptions(call: FunctionCall) {
// if subscription return false - delete it from subscriptions // if subscription return true - delete it from subscriptions
this.subscriptions = this.subscriptions.filter(callback => !callback(call.arguments, call.target, call.reply_to)) this.subscriptions = this.subscriptions.filter(callback => !callback(call.arguments, call.target, call.reply_to, call.module, call.fname))
} }
} }

View File

@ -7,18 +7,20 @@
], ],
"outDir": "./dist/", "outDir": "./dist/",
"sourceMap": true, "sourceMap": true,
"inlineSources": true,
"noImplicitAny": true, "noImplicitAny": true,
"strictFunctionTypes": true, "strictFunctionTypes": true,
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"resolveJsonModule": true, "resolveJsonModule": true,
"pretty": true, "pretty": true,
"target": "esnext", "target": "es2018",
"module": "commonjs", "module": "commonjs",
"moduleResolution": "node", "moduleResolution": "node",
"declaration": true, "declaration": true,
"strict": true, "strict": true,
"strictNullChecks": false, "strictNullChecks": false,
"esModuleInterop": true, "esModuleInterop": true,
"declarationMap": true,
"baseUrl": "." "baseUrl": "."
}, },
"exclude": [ "exclude": [