@tdxvolt/volt-client-grpc 0.1.2 → 0.11.0

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.
@@ -82,19 +82,21 @@ export async function bindInternal() {
82
82
  try {
83
83
  // Check if we need to resolve a Relay volt.
84
84
  if (
85
- this._config?.relay?.discovery_url ||
86
- typeof this._config?.relay === "string"
85
+ typeof this._voltConfig?.relay === "string" ||
86
+ this._voltConfig?.relay?.http_address
87
87
  ) {
88
- const relayURL = this._config.relay?.discovery_url || this._config.relay;
88
+ const relayURL =
89
+ this._voltConfig.relay?.http_address || this._voltConfig.relay;
89
90
  log("attempting to retrieve Relay information from %s", relayURL);
90
- const voltConfig = await fetchVoltConfig.call(this, relayURL);
91
- this._config.relay = voltConfig.volt;
92
- this._config.relay.discovery_url = relayURL;
93
- if (this._config.relay.ca_pem) {
91
+ this._voltConfig.relay = await fetchVoltConfig.call(
92
+ this,
93
+ `${relayURL}/discovery`,
94
+ );
95
+ if (this._voltConfig.relay.ca_pem) {
94
96
  log(
95
97
  "Auto-fetched Relay CA %s, remote address %s",
96
- this._config.relay.ca_pem,
97
- this._config.relay.address,
98
+ this._voltConfig.relay.ca_pem,
99
+ this._voltConfig.relay.address,
98
100
  );
99
101
  } else {
100
102
  throw new Error("Unable to fetch Relay CA - cannot securely connect.");
@@ -256,8 +258,8 @@ export function getVoltAPIClientInternal() {
256
258
  serviceAddress,
257
259
  this._credential,
258
260
  this.isRemote && !this.isVoltRelay,
259
- this._config?.relay?.cloud_relay ? this._voltConfig.id : "",
260
- this._config?.relay?.cloud_relay ? this._voltConfig.id : "",
261
+ this._config?.relay?.cloud ? this._voltConfig.id : "",
262
+ this._config?.relay?.cloud ? this._voltConfig.id : "",
261
263
  );
262
264
  }
263
265
 
@@ -265,53 +267,93 @@ export function getVoltAPIClientInternal() {
265
267
  }
266
268
 
267
269
  export function unaryCall(method, request) {
268
- const grpcClient = this.getVoltAPIClient();
270
+ return new Promise((resolve, reject) => {
271
+ const grpcClient = this.getVoltAPIClient();
272
+
273
+ const call = new GRPCCall(this, method, "METHOD_TYPE_UNARY");
274
+
275
+ let response = null;
276
+
277
+ call.on("data", (payload) => {
278
+ // Cache the response and wait for `end`.
279
+ response = payload;
280
+ });
281
+
282
+ call.on("error", reject);
283
+
284
+ call.on("end", () => {
285
+ if (!response) {
286
+ return reject(new Error("no response received"));
287
+ }
288
+
289
+ // Convert non-OK status to a JS error.
290
+ if (response.status?.message) {
291
+ reject(new Error(response.status.message));
292
+ } else {
293
+ resolve(response);
294
+ }
295
+ });
269
296
 
270
- const call = new GRPCCall(this, method, "METHOD_TYPE_UNARY");
271
- call.start(grpcClient, request);
272
- return call.wait();
297
+ call.start(grpcClient, request);
298
+ });
273
299
  }
274
300
 
275
- export async function fetchVoltConfig(disovery_url) {
276
- const getJSON = bent("json");
277
- const resolvedConfig = await getJSON(disovery_url);
278
-
279
- const voltConfig = pick(
280
- resolvedConfig,
281
- "id",
282
- "display_name",
283
- "public_key",
284
- "fingerprint",
285
- "address",
286
- "ca_pem",
287
- "challenge_code",
288
- "cloud_relay",
289
- );
290
-
291
- const relayConfig = pick(resolvedConfig, "relay");
292
-
293
- return { volt: voltConfig, ...relayConfig };
301
+ export async function fetchVoltConfig(discovery_url) {
302
+ try {
303
+ const getJSON = bent("json");
304
+ const fullVoltConfig = await getJSON(discovery_url);
305
+
306
+ if (!fullVoltConfig || typeof fullVoltConfig !== "object") {
307
+ throw new Error(`invalid config resolved from: ${discovery_url}`);
308
+ }
309
+
310
+ const voltConfig = pick(
311
+ fullVoltConfig,
312
+ "id",
313
+ "display_name",
314
+ "public_key",
315
+ "fingerprint",
316
+ "address",
317
+ "ca_pem",
318
+ "challenge_code",
319
+ "cloud",
320
+ "relay",
321
+ );
322
+
323
+ return voltConfig;
324
+ } catch (err) {
325
+ throw new Error(
326
+ `Failure loading config from ${discovery_url}: ${err.message}`,
327
+ );
328
+ }
294
329
  }
295
330
 
296
331
  export async function fetchVoltConfigFromDID(volt_did) {
297
- const didResolution = voltUtils.getDIDResolutionURL(volt_did);
298
- if (!didResolution) {
299
- throw new Error(`Invalid Volt DID: ${volt_did}`);
300
- }
332
+ try {
333
+ const didResolution = voltUtils.getDIDResolutionURL(volt_did);
334
+ if (!didResolution) {
335
+ throw new Error(`Invalid Volt DID: ${volt_did}`);
336
+ }
337
+
338
+ const getJSON = bent("json");
339
+ const didDocument = await getJSON(didResolution);
340
+ const voltConfigServices = findDIDDocumentService(
341
+ didDocument,
342
+ constants.didServiceType.voltConfig,
343
+ );
344
+ if (voltConfigServices.length !== 1) {
345
+ log(
346
+ "Unexpected number of Volt configuration endpoints found in DID document for %s, services found: %d",
347
+ volt_did,
348
+ voltConfigServices.length,
349
+ );
350
+ }
301
351
 
302
- const getJSON = bent("json");
303
- const didDocument = await getJSON(didResolution);
304
- const voltConfigServices = findDIDDocumentService(
305
- didDocument,
306
- constants.didServiceType.voltConfig,
307
- );
308
- if (voltConfigServices.length !== 1) {
309
- log(
310
- "Unexpected number of Volt configuration endpoints found in DID document for %s, services found: %d",
311
- volt_did,
312
- voltConfigServices.length,
352
+ const serviceEndpoint = voltConfigServices[0].serviceEndpoint;
353
+ return await fetchVoltConfig.call(this, serviceEndpoint);
354
+ } catch (err) {
355
+ throw new Error(
356
+ `Failure fetching Volt config from DID document ${volt_did}: ${err.message}`,
313
357
  );
314
358
  }
315
- const serviceEndpoint = voltConfigServices[0].serviceEndpoint;
316
- return await fetchVoltConfig.call(this, serviceEndpoint);
317
359
  }
@@ -101,32 +101,38 @@ export class VoltClient extends EventEmitter {
101
101
  this._config = { ...configJSON, ...extras };
102
102
 
103
103
  let voltDID = "";
104
- let voltDiscovery = "";
104
+ let voltHttpAddress = "";
105
105
  if (typeof this._config.volt === "string") {
106
106
  if (this._config.volt.indexOf("did:") === 0) {
107
107
  voltDID = this._config.volt;
108
108
  } else {
109
- voltDiscovery = this._config.volt;
109
+ voltHttpAddress = this._config.volt;
110
110
  }
111
111
  } else if (typeof this._config.volt !== "object") {
112
112
  throw new Error("configuration is missing the 'volt' object");
113
113
  } else {
114
114
  voltDID = this._config.volt.did;
115
- voltDiscovery = this._config.volt.discovery_url;
115
+ voltHttpAddress = this._config.volt.http_address;
116
116
  }
117
117
 
118
118
  if (voltDID) {
119
119
  const didConfig = await fetchVoltConfigFromDID.call(this, voltDID);
120
- this._config = { ...this._config, ...didConfig };
120
+ this._config = { ...this._config, volt: didConfig };
121
121
  log("resolved config from DID: %s", JSON.stringify(didConfig, null, 2));
122
- } else if (voltDiscovery) {
123
- const discoConfig = await fetchVoltConfig.call(this, voltDiscovery);
124
- this._config = { ...this._config, ...discoConfig };
122
+ } else if (voltHttpAddress) {
123
+ const discoConfig = await fetchVoltConfig.call(
124
+ this,
125
+ `${voltHttpAddress}/discovery`,
126
+ );
127
+ this._config = {
128
+ ...this._config,
129
+ volt: { ...this._config.volt, ...discoConfig },
130
+ };
125
131
  }
126
132
 
127
133
  this._voltConfig = this._config.volt;
128
134
  this._voltConfig.did = voltDID;
129
- this._voltConfig.discovery_url = voltDiscovery;
135
+ this._voltConfig.http_address = voltHttpAddress;
130
136
 
131
137
  if (!this._voltConfig.id || typeof this._voltConfig.id !== "string") {
132
138
  throw new Error("'id' property is missing in Volt configuration");
@@ -256,7 +262,7 @@ export class VoltClient extends EventEmitter {
256
262
  }
257
263
 
258
264
  get isVoltRelay() {
259
- return this.isRemote && !this._config?.relay.cloud_relay;
265
+ return this.isRemote && !this._config?.relay.cloud;
260
266
  }
261
267
 
262
268
  connect() {
@@ -277,7 +283,7 @@ export class VoltClient extends EventEmitter {
277
283
  /**
278
284
  * Request resource access.
279
285
  * @param {*} targetResourceId
280
- * @param {*} accessType - see vault.proto for enum values.
286
+ * @param {*} accessType - see volt.proto for values.
281
287
  */
282
288
  async RequestAccessBlocking(
283
289
  targetResourceId,
@@ -452,24 +458,19 @@ export class VoltClient extends EventEmitter {
452
458
  DownloadFile(request) {
453
459
  const grpcClient = this.getVoltAPIClient();
454
460
 
455
- return new Promise((resolve, reject) => {
456
- const meta = this._credential.getIdentityMetadata(
457
- this._grpc,
458
- this._voltConfig.id,
459
- this.isRemote,
460
- );
461
- resolve(grpcClient.DownloadFile(request, meta.metadata));
462
- }).catch((err) => {
463
- log("error during %s [%s]", method, err.message);
464
- return Promise.reject(err);
465
- });
461
+ const downloadCall = new GRPCCall(
462
+ this,
463
+ "DownloadFile",
464
+ "METHOD_TYPE_SERVER_STREAM",
465
+ );
466
+ return downloadCall.start(grpcClient, request);
466
467
  }
467
468
 
468
- UploadFile(request, callback) {
469
+ UploadFile(request) {
469
470
  const grpcClient = this.getVoltAPIClient();
470
471
 
471
472
  const uploadCall = new GRPCCall(this, "UploadFile", "METHOD_TYPE_BIDI");
472
- return uploadCall.start(grpcClient, request, callback);
473
+ return uploadCall.start(grpcClient, request);
473
474
  }
474
475
 
475
476
  /**
@@ -478,72 +479,72 @@ export class VoltClient extends EventEmitter {
478
479
  * @returns file buffer, base64 encoded
479
480
  */
480
481
  DownloadFileSync(request) {
481
- const grpcClient = this.getVoltAPIClient();
482
+ return new Promise((resolve, reject) => {
483
+ const grpcClient = this.getVoltAPIClient();
482
484
 
483
- const blocks = [];
485
+ const blocks = [];
484
486
 
485
- const call = new GRPCCall(
486
- this,
487
- "DownloadFile",
488
- "METHOD_TYPE_SERVER_STREAM",
489
- );
490
- call.start(grpcClient, request, (err, response) => {
491
- if (err) {
492
- return call.reject(err);
493
- }
487
+ const call = new GRPCCall(
488
+ this,
489
+ "DownloadFile",
490
+ "METHOD_TYPE_SERVER_STREAM",
491
+ );
494
492
 
495
- switch (response.payload) {
496
- case "block": {
497
- blocks.push(response.block);
498
- break;
499
- }
500
- case "status": {
501
- if (response.status.message) {
502
- return call.reject(new Error(response.status.message));
503
- } else {
504
- // Non-error response status => do nothing and wait for the stream to end.
493
+ call.on("data", (response) => {
494
+ switch (response.payload) {
495
+ case "block": {
496
+ blocks.push(response.block);
497
+ break;
505
498
  }
506
- break;
499
+ case "status": {
500
+ if (response.status.message) {
501
+ return call.reject(new Error(response.status.message));
502
+ } else {
503
+ // Non-error response status => do nothing and wait for the stream to end.
504
+ }
505
+ break;
506
+ }
507
+ default:
508
+ log("unrecognised response payload %s", response.payload);
509
+ break;
507
510
  }
508
- default:
509
- log("unrecognised response payload %s", response.payload);
510
- break;
511
- }
512
- });
511
+ });
513
512
 
514
- return call
515
- .wait()
516
- .then(() => {
517
- log("Download finished");
518
- return { buffer: Buffer.concat(blocks).toString("base64") };
519
- })
520
- .catch((err) => {
513
+ call.on("error", (err) => {
521
514
  log("error during DownloadFile [%s]", err.message);
522
- return Promise.reject(err);
515
+ reject(err);
516
+ });
517
+
518
+ call.on("end", () => {
519
+ log("Download finished");
520
+ resolve({ buffer: Buffer.concat(blocks).toString("base64") });
523
521
  });
522
+
523
+ call.start(grpcClient, request);
524
+ });
524
525
  }
525
526
 
526
527
  /**
527
528
  * SqliteDatabaseAPI
528
529
  */
529
- SqlExecute(request, callback) {
530
+ SqlExecute(request) {
530
531
  const grpcClient = this.getVoltAPIClient();
531
532
 
532
533
  const subscribeCall = new GRPCCall(this, "Execute", "METHOD_TYPE_BIDI");
533
- return subscribeCall.start(grpcClient, request, callback);
534
+ return subscribeCall.start(grpcClient, request);
534
535
  }
535
536
 
536
537
  /**
537
538
  * WireAPI
538
539
  */
539
- PublishWire(request, callback) {
540
+ PublishWire(request) {
540
541
  const grpcClient = this.getVoltAPIClient();
541
542
 
542
543
  const publishCall = new GRPCCall(this, "PublishWire", "METHOD_TYPE_BIDI");
543
- return publishCall.start(grpcClient, request, callback);
544
+ return publishCall.start(grpcClient, request);
544
545
  }
545
546
 
546
- SubscribeWire(request, callback) {
547
+ SubscribeWire(request) {
547
548
  const grpcClient = this.getVoltAPIClient();
548
549
 
549
550
  const subscribeCall = new GRPCCall(
@@ -551,6 +552,6 @@ export class VoltClient extends EventEmitter {
551
552
  "SubscribeWire",
552
553
  "METHOD_TYPE_BIDI",
553
554
  );
554
- return subscribeCall.start(grpcClient, request, callback);
555
+ return subscribeCall.start(grpcClient, request);
555
556
  }
556
557
  }