mirror of
https://github.com/fluencelabs/fluence-js.git
synced 2025-04-25 17:52:13 +00:00
Client certs (#895)
This commit is contained in:
parent
5fbb08bc96
commit
4d306dab63
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "fluence",
|
"name": "fluence",
|
||||||
"version": "0.4.9",
|
"version": "0.5.0",
|
||||||
"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",
|
||||||
|
@ -24,7 +24,7 @@ import * as PeerInfo from "peer-info";
|
|||||||
import {FluenceConnection} from "./fluence_connection";
|
import {FluenceConnection} from "./fluence_connection";
|
||||||
|
|
||||||
export class FluenceClient {
|
export class FluenceClient {
|
||||||
private readonly selfPeerInfo: PeerInfo;
|
readonly selfPeerInfo: PeerInfo;
|
||||||
readonly selfPeerIdStr: string;
|
readonly selfPeerIdStr: string;
|
||||||
|
|
||||||
private connection: FluenceConnection;
|
private connection: FluenceConnection;
|
||||||
@ -51,7 +51,7 @@ 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
|
||||||
*/
|
*/
|
||||||
waitResponse(predicate: (args: any, target: Address, replyTo: Address) => (boolean | undefined)): Promise<any> {
|
waitResponse(predicate: (args: any, target: Address, replyTo: Address) => (boolean | undefined)): Promise<any> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, _) => {
|
||||||
// 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) => {
|
||||||
@ -162,7 +162,10 @@ export class FluenceClient {
|
|||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// if service throw an error, return it to the sender
|
// if service throw an error, return it to the sender
|
||||||
return FluenceClient.responseCall(call.reply_to, {reason: `error on execution: ${e}`, msg: call});
|
return FluenceClient.responseCall(call.reply_to, {
|
||||||
|
reason: `error on execution: ${e}`,
|
||||||
|
msg: call
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
@ -171,7 +174,10 @@ export class FluenceClient {
|
|||||||
console.log(`relay call: ${call}`);
|
console.log(`relay call: ${call}`);
|
||||||
} else {
|
} else {
|
||||||
console.warn(`this relay call is not for me: ${callToString(call)}`);
|
console.warn(`this relay call is not for me: ${callToString(call)}`);
|
||||||
return FluenceClient.responseCall(call.reply_to, {reason: `this relay call is not for me`, msg: call});
|
return FluenceClient.responseCall(call.reply_to, {
|
||||||
|
reason: `this relay call is not for me`,
|
||||||
|
msg: call
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
case ProtocolType.Peer:
|
case ProtocolType.Peer:
|
||||||
@ -179,7 +185,10 @@ export class FluenceClient {
|
|||||||
console.log(`peer call: ${call}`);
|
console.log(`peer call: ${call}`);
|
||||||
} else {
|
} else {
|
||||||
console.warn(`this peer call is not for me: ${callToString(call)}`);
|
console.warn(`this peer call is not for me: ${callToString(call)}`);
|
||||||
return FluenceClient.responseCall(call.reply_to, {reason: `this relay call is not for me`, msg: call});
|
return FluenceClient.responseCall(call.reply_to, {
|
||||||
|
reason: `this relay call is not for me`,
|
||||||
|
msg: call
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@ -203,7 +212,6 @@ export class FluenceClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a call to unregister the service_id.
|
* Sends a call to unregister the service_id.
|
||||||
*/
|
*/
|
||||||
|
@ -162,7 +162,7 @@ export class FluenceConnection {
|
|||||||
|
|
||||||
private async sendCall(call: FunctionCall) {
|
private async sendCall(call: FunctionCall) {
|
||||||
let callStr = callToString(call);
|
let callStr = callToString(call);
|
||||||
console.log("send function call: " + callStr);
|
console.log("send function call: " + JSON.stringify(JSON.parse(callStr), undefined, 2));
|
||||||
console.log(call);
|
console.log(call);
|
||||||
|
|
||||||
// create outgoing substream
|
// create outgoing substream
|
||||||
|
@ -11,6 +11,9 @@ import 'mocha';
|
|||||||
import * as PeerId from "peer-id";
|
import * as PeerId from "peer-id";
|
||||||
import {callToString, genUUID, makeFunctionCall, parseFunctionCall} from "../function_call";
|
import {callToString, genUUID, makeFunctionCall, parseFunctionCall} from "../function_call";
|
||||||
import Fluence from "../fluence";
|
import Fluence from "../fluence";
|
||||||
|
import {certificateFromString, certificateToString, issue} from "../trust/certificate";
|
||||||
|
import {TrustGraph} from "../trust/trust_graph";
|
||||||
|
import {nodeRootCert} from "../trust/misc";
|
||||||
|
|
||||||
describe("Typescript usage suite", () => {
|
describe("Typescript usage suite", () => {
|
||||||
|
|
||||||
@ -89,14 +92,67 @@ describe("Typescript usage suite", () => {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should serialize and deserialize certificate correctly", async function () {
|
||||||
|
let cert = `11
|
||||||
|
1111
|
||||||
|
5566Dn4ZXXbBK5LJdUsE7L3pG9qdAzdPY47adjzkhEx9
|
||||||
|
3HNXpW2cLdqXzf4jz5EhsGEBFkWzuVdBCyxzJUZu2WPVU7kpzPjatcqvdJMjTtcycVAdaV5qh2fCGphSmw8UMBkr
|
||||||
|
158981172690500
|
||||||
|
1589974723504
|
||||||
|
2EvoZAZaGjKWFVdr36F1jphQ5cW7eK3yM16mqEHwQyr7
|
||||||
|
4UAJQWzB3nTchBtwARHAhsn7wjdYtqUHojps9xV6JkuLENV8KRiWM3BhQByx5KijumkaNjr7MhHjouLawmiN1A4d
|
||||||
|
1590061123504
|
||||||
|
1589974723504`
|
||||||
|
|
||||||
|
let deser = await certificateFromString(cert);
|
||||||
|
let ser = certificateToString(deser);
|
||||||
|
|
||||||
|
expect(ser).to.be.equal(cert);
|
||||||
|
});
|
||||||
|
|
||||||
|
// delete `.skip` and run `npm run test` to check service's and certificate's api with Fluence nodes
|
||||||
it("integration test", async function () {
|
it("integration test", async function () {
|
||||||
this.timeout(5000);
|
this.timeout(15000);
|
||||||
await testCalculator();
|
await testCerts();
|
||||||
|
// await testCalculator();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const delay = (ms: number) => new Promise(res => setTimeout(res, ms));
|
const delay = (ms: number) => new Promise(res => setTimeout(res, ms));
|
||||||
|
|
||||||
|
export async function testCerts() {
|
||||||
|
let key1 = await Fluence.generatePeerId();
|
||||||
|
let key2 = await Fluence.generatePeerId();
|
||||||
|
|
||||||
|
// connect to two different nodes
|
||||||
|
let cl1 = await Fluence.connect("/dns4/104.248.25.59/tcp/9003/ws/p2p/12D3KooWBUJifCTgaxAUrcM9JysqCcS4CS8tiYH5hExbdWCAoNwb", key1);
|
||||||
|
let cl2 = await Fluence.connect("/ip4/104.248.25.59/tcp/9002/ws/p2p/12D3KooWHk9BjDQBUqnavciRPhAYFvqKBe4ZiPPvde7vDaqgn5er", key2);
|
||||||
|
|
||||||
|
let trustGraph1 = new TrustGraph(cl1);
|
||||||
|
let trustGraph2 = new TrustGraph(cl2);
|
||||||
|
|
||||||
|
let issuedAt = new Date();
|
||||||
|
let expiresAt = new Date();
|
||||||
|
// certificate expires after one day
|
||||||
|
expiresAt.setDate(new Date().getDate() + 1);
|
||||||
|
|
||||||
|
// create root certificate for key1 and extend it with key2
|
||||||
|
let rootCert = await nodeRootCert(key1);
|
||||||
|
let extended = await issue(key1, key2, rootCert, expiresAt.getTime(), issuedAt.getTime());
|
||||||
|
|
||||||
|
// publish certificates to Fluence network
|
||||||
|
await trustGraph1.publishCertificates(key2.toB58String(), [extended]);
|
||||||
|
|
||||||
|
// get certificates from network
|
||||||
|
let certs = await trustGraph2.getCertificates(key2.toB58String());
|
||||||
|
|
||||||
|
// root certificate could be different because nodes save trusts with bigger `expiresAt` date and less `issuedAt` date
|
||||||
|
expect(certs[0].chain[1].issuedFor.toB58String()).to.be.equal(extended.chain[1].issuedFor.toB58String())
|
||||||
|
expect(certs[0].chain[1].signature).to.be.equal(extended.chain[1].signature)
|
||||||
|
expect(certs[0].chain[1].expiresAt).to.be.equal(extended.chain[1].expiresAt)
|
||||||
|
expect(certs[0].chain[1].issuedAt).to.be.equal(extended.chain[1].issuedAt)
|
||||||
|
}
|
||||||
|
|
||||||
// Shows how to register and call new service in Fluence network
|
// Shows how to register and call new service in Fluence network
|
||||||
export async function testCalculator() {
|
export async function testCalculator() {
|
||||||
|
|
||||||
|
105
src/trust/certificate.ts
Normal file
105
src/trust/certificate.ts
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 Fluence Labs Limited
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {createTrust, Trust, trustFromString, trustToString} from "./trust";
|
||||||
|
import * as PeerId from "peer-id";
|
||||||
|
|
||||||
|
const FORMAT = "11";
|
||||||
|
const VERSION = "1111";
|
||||||
|
|
||||||
|
// TODO verify certificate
|
||||||
|
// Chain of trusts started from self-signed root trust.
|
||||||
|
export interface Certificate {
|
||||||
|
chain: Trust[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function certificateToString(cert: Certificate): string {
|
||||||
|
let certStr = cert.chain.map(t => trustToString(t)).join("\n");
|
||||||
|
return `${FORMAT}\n${VERSION}\n${certStr}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function certificateFromString(str: string): Promise<Certificate> {
|
||||||
|
let lines = str.split("\n");
|
||||||
|
// last line could be empty
|
||||||
|
if (!lines[lines.length - 1]) {
|
||||||
|
lines.pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO do match different formats and versions
|
||||||
|
let _format = lines[0];
|
||||||
|
let _version = lines[1];
|
||||||
|
console.log("LENGTH: " + lines.length)
|
||||||
|
|
||||||
|
// every trust is 4 lines, certificate lines number without format and version should be divided by 4
|
||||||
|
if ((lines.length - 2) % 4 !== 0) {
|
||||||
|
throw Error("Incorrect format of the certificate:\n" + str);
|
||||||
|
}
|
||||||
|
|
||||||
|
let chain: Trust[] = [];
|
||||||
|
|
||||||
|
let i;
|
||||||
|
for(i = 2; i < lines.length; i = i + 4) {
|
||||||
|
chain.push(await trustFromString(lines[i], lines[i+1], lines[i+2], lines[i+3]))
|
||||||
|
}
|
||||||
|
|
||||||
|
return {chain};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates new certificate with root trust (self-signed public key) from a key pair.
|
||||||
|
export async function issueRoot(issuedBy: PeerId,
|
||||||
|
forPk: PeerId,
|
||||||
|
expiresAt: number,
|
||||||
|
issuedAt: number,
|
||||||
|
): Promise<Certificate> {
|
||||||
|
if (expiresAt < issuedAt) {
|
||||||
|
throw Error("Expiration time should be greater then issued time.")
|
||||||
|
}
|
||||||
|
|
||||||
|
let maxDate = new Date(158981172690500).getTime();
|
||||||
|
|
||||||
|
let rootTrust = await createTrust(issuedBy, issuedBy, maxDate, issuedAt);
|
||||||
|
let trust = await createTrust(forPk, issuedBy, expiresAt, issuedAt);
|
||||||
|
let chain = [rootTrust, trust];
|
||||||
|
|
||||||
|
return {
|
||||||
|
chain: chain
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds a new trust into chain of trust in certificate.
|
||||||
|
export async function issue(issuedBy: PeerId,
|
||||||
|
forPk: PeerId,
|
||||||
|
extendCert: Certificate,
|
||||||
|
expiresAt: number,
|
||||||
|
issuedAt: number): Promise<Certificate> {
|
||||||
|
if (expiresAt < issuedAt) {
|
||||||
|
throw Error("Expiration time should be greater then issued time.")
|
||||||
|
}
|
||||||
|
|
||||||
|
let lastTrust = extendCert.chain[extendCert.chain.length - 1];
|
||||||
|
|
||||||
|
if (lastTrust.issuedFor !== issuedBy) {
|
||||||
|
throw Error("`issuedFor` should be equal to `issuedBy` in the last trust of the chain.")
|
||||||
|
}
|
||||||
|
|
||||||
|
let trust = await createTrust(forPk, issuedBy, expiresAt, issuedAt);
|
||||||
|
let chain = [...extendCert.chain];
|
||||||
|
chain.push(trust);
|
||||||
|
|
||||||
|
return {
|
||||||
|
chain: chain
|
||||||
|
}
|
||||||
|
}
|
35
src/trust/misc.ts
Normal file
35
src/trust/misc.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 Fluence Labs Limited
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as PeerId from "peer-id";
|
||||||
|
import {keys} from "libp2p-crypto";
|
||||||
|
import {Certificate, issueRoot} from "./certificate";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate root certificate with one of the Fluence trusted key for one day.
|
||||||
|
*/
|
||||||
|
export async function nodeRootCert(issuedFor: PeerId): Promise<Certificate> {
|
||||||
|
let seed = [46, 188, 245, 171, 145, 73, 40, 24, 52, 233, 215, 163, 54, 26, 31, 221, 159, 179, 126, 106, 27, 199, 189, 194, 80, 133, 235, 42, 42, 247, 80, 201];
|
||||||
|
|
||||||
|
let privateK = await keys.generateKeyPairFromSeed("Ed25519", Uint8Array.from(seed), 256);
|
||||||
|
let peerId = await PeerId.createFromPrivKey(privateK.bytes);
|
||||||
|
|
||||||
|
let issuedAt = new Date();
|
||||||
|
let expiresAt = new Date();
|
||||||
|
expiresAt.setDate(new Date().getDate() + 1);
|
||||||
|
|
||||||
|
return await issueRoot(peerId, issuedFor, expiresAt.getTime(), issuedAt.getTime());
|
||||||
|
}
|
80
src/trust/trust.ts
Normal file
80
src/trust/trust.ts
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 Fluence Labs Limited
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as PeerId from "peer-id";
|
||||||
|
import {decode, encode} from "bs58"
|
||||||
|
import crypto from 'libp2p-crypto';
|
||||||
|
const ed25519 = crypto.keys.supportedKeys.ed25519;
|
||||||
|
|
||||||
|
// One element in chain of trust in a certificate.
|
||||||
|
export interface Trust {
|
||||||
|
issuedFor: PeerId,
|
||||||
|
expiresAt: number,
|
||||||
|
signature: string,
|
||||||
|
issuedAt: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export function trustToString(trust: Trust): string {
|
||||||
|
return `${encode(trust.issuedFor.pubKey.marshal())}\n${trust.signature}\n${trust.expiresAt}\n${trust.issuedAt}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function trustFromString(issuedFor: string, signature: string, expiresAt: string, issuedAt: string): Promise<Trust> {
|
||||||
|
let pubKey = ed25519.unmarshalEd25519PublicKey(decode(issuedFor));
|
||||||
|
let peerId = await PeerId.createFromPubKey(pubKey.bytes);
|
||||||
|
|
||||||
|
return {
|
||||||
|
issuedFor: peerId,
|
||||||
|
signature: signature,
|
||||||
|
expiresAt: parseInt(expiresAt),
|
||||||
|
issuedAt: parseInt(issuedAt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createTrust(forPk: PeerId, issuedBy: PeerId, expiresAt: number, issuedAt: number): Promise<Trust> {
|
||||||
|
let bytes = toSignMessage(forPk, expiresAt, issuedAt);
|
||||||
|
let signature = await issuedBy.privKey.sign(Buffer.from(bytes));
|
||||||
|
let signatureStr = encode(signature);
|
||||||
|
|
||||||
|
return {
|
||||||
|
issuedFor: forPk,
|
||||||
|
expiresAt: expiresAt,
|
||||||
|
signature: signatureStr,
|
||||||
|
issuedAt: issuedAt
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function toSignMessage(pk: PeerId, expiresAt: number, issuedAt: number): Uint8Array {
|
||||||
|
let bytes = new Uint8Array(48);
|
||||||
|
let pkEncoded = pk.pubKey.marshal();
|
||||||
|
|
||||||
|
bytes.set(pkEncoded, 0);
|
||||||
|
bytes.set(numToArray(expiresAt), 32);
|
||||||
|
bytes.set(numToArray(issuedAt), 40);
|
||||||
|
|
||||||
|
return bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
function numToArray(n: number): number[] {
|
||||||
|
let byteArray = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
|
|
||||||
|
for (let index = 0; index < byteArray.length; index++) {
|
||||||
|
let byte = n & 0xff;
|
||||||
|
byteArray [index] = byte;
|
||||||
|
n = (n - byte) / 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
return byteArray;
|
||||||
|
}
|
86
src/trust/trust_graph.ts
Normal file
86
src/trust/trust_graph.ts
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 Fluence Labs Limited
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {FluenceClient} from "../fluence_client";
|
||||||
|
import {Certificate, certificateFromString, certificateToString} from "./certificate";
|
||||||
|
import {genUUID} from "../function_call";
|
||||||
|
|
||||||
|
// The client to interact with the Fluence trust graph API
|
||||||
|
export class TrustGraph {
|
||||||
|
|
||||||
|
client: FluenceClient;
|
||||||
|
|
||||||
|
constructor(client: FluenceClient) {
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Publish certificate to Fluence network. It will be published in Kademlia neighbourhood by `peerId` key.
|
||||||
|
async publishCertificates(peerId: string, certs: Certificate[]) {
|
||||||
|
let certsStr = [];
|
||||||
|
for (let cert of certs) {
|
||||||
|
certsStr.push(await certificateToString(cert));
|
||||||
|
}
|
||||||
|
|
||||||
|
let msgId = genUUID()
|
||||||
|
|
||||||
|
let response = await this.client.sendServiceCallWaitResponse("add_certificates", {
|
||||||
|
certificates: certsStr,
|
||||||
|
msg_id: msgId,
|
||||||
|
peer_id: peerId
|
||||||
|
}, (args) => {
|
||||||
|
// check if it is a successful response
|
||||||
|
let isSuccessResponse = args.msg_id && args.msg_id === msgId
|
||||||
|
if (isSuccessResponse) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
// check if it is an error for this msgId
|
||||||
|
return args.call && args.call.arguments && args.call.arguments.msg_id === msgId
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.reason) {
|
||||||
|
throw Error(response.reason)
|
||||||
|
} else if (response.status) {
|
||||||
|
return response.status
|
||||||
|
} else {
|
||||||
|
throw Error(`Unexpected response: ${response}. Should be 'status' field for a success response or 'reason' field for an error.`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get certificates that stores in Kademlia neighbourhood by `peerId` key.
|
||||||
|
async getCertificates(peerId: string): Promise<Certificate[]> {
|
||||||
|
let msgId = genUUID();
|
||||||
|
let resp = await this.client.sendServiceCallWaitResponse("certificates", {
|
||||||
|
msg_id: msgId,
|
||||||
|
peer_id: peerId
|
||||||
|
}, (args) => args.msg_id && args.msg_id === msgId)
|
||||||
|
|
||||||
|
let certificatesRaw = resp.certificates
|
||||||
|
|
||||||
|
if (!(certificatesRaw && Array.isArray(certificatesRaw))) {
|
||||||
|
console.log(Array.isArray(certificatesRaw))
|
||||||
|
throw Error("Unexpected. Certificates should be presented in the response as an array.")
|
||||||
|
}
|
||||||
|
|
||||||
|
let certs = [];
|
||||||
|
for (let cert of certificatesRaw) {
|
||||||
|
certs.push(await certificateFromString(cert))
|
||||||
|
}
|
||||||
|
|
||||||
|
return certs;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user