@tdxvolt/volt-client-grpc 0.18.10 → 0.19.1
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.
- package/lib/index.cjs +1568 -1504
- package/package.json +3 -3
- package/src/constants.js +11 -2
- package/src/index.js +5 -4
- package/src/volt-client-internal.js +131 -48
- package/src/volt-client.js +24 -59
- package/src/volt-proto-literals.js +1 -0
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.19.1",
|
|
7
7
|
"description": "tdx Volt library for nodejs clients",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"exports": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"author": "toby.ealden@gmail.com",
|
|
38
38
|
"license": "ISC",
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@tdxvolt/volt-client-web": "^0.
|
|
40
|
+
"@tdxvolt/volt-client-web": "^0.19.1",
|
|
41
41
|
"builtin-modules": "^3.3.0",
|
|
42
42
|
"debug": "^4.1.1",
|
|
43
43
|
"ip": "^1.1.5",
|
|
@@ -47,4 +47,4 @@
|
|
|
47
47
|
"protobufjs": "^7.4.0",
|
|
48
48
|
"uuid": "^8.1.0"
|
|
49
49
|
}
|
|
50
|
-
}
|
|
50
|
+
}
|
package/src/constants.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
const _constants = {
|
|
2
2
|
authTokenName: "volt-token",
|
|
3
3
|
defaultDIDHostName: "coreid.com",
|
|
4
4
|
didServiceType: {
|
|
@@ -19,5 +19,14 @@ export const constants = {
|
|
|
19
19
|
terminalAPI: "tdx.volt_api.volt.v1.TerminalAPI",
|
|
20
20
|
voltAPI: "tdx.volt_api.volt.v1.VoltAPI",
|
|
21
21
|
wireAPI: "tdx.volt_api.volt.v1.WireAPI"
|
|
22
|
-
}
|
|
22
|
+
},
|
|
23
|
+
voltDIDPrefix: "did:volt:"
|
|
23
24
|
};
|
|
25
|
+
|
|
26
|
+
_constants.defaultRegistryList = [
|
|
27
|
+
_constants.defaultDIDHostName,
|
|
28
|
+
"https://tdxvolt.com",
|
|
29
|
+
"https://tdxid.com"
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
export const constants = _constants;
|
package/src/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { SyncProvider } from "@tdxvolt/volt-client-web";
|
|
2
|
+
export { v4 as generateId } from "uuid";
|
|
3
|
+
export { constants } from "./constants.js";
|
|
2
4
|
export * as grpcUtils from "./grpc-utils.js";
|
|
5
|
+
export * as protoUtils from "./proto-utils.js";
|
|
3
6
|
export * as utils from "./utils.js";
|
|
4
|
-
export {VoltClient} from "./volt-client.js";
|
|
7
|
+
export { VoltClient } from "./volt-client.js";
|
|
5
8
|
export * from "./volt-credential.js";
|
|
6
|
-
export * as protoUtils from "./proto-utils.js";
|
|
7
|
-
export {v4 as generateId} from "uuid";
|
|
@@ -105,30 +105,6 @@ export async function authenticateInternal(
|
|
|
105
105
|
ownDID = false
|
|
106
106
|
) {
|
|
107
107
|
try {
|
|
108
|
-
// Check if we need to resolve a Relay volt.
|
|
109
|
-
if (
|
|
110
|
-
typeof this._voltConfig?.relay === "string" ||
|
|
111
|
-
this._voltConfig?.relay?.http_address
|
|
112
|
-
) {
|
|
113
|
-
const relayURL =
|
|
114
|
-
this._voltConfig.relay?.http_address || this._voltConfig.relay;
|
|
115
|
-
log("attempting to retrieve Relay information from %s", relayURL);
|
|
116
|
-
this._voltConfig.relay = await fetchVoltConfig.call(
|
|
117
|
-
this,
|
|
118
|
-
`${relayURL}/discover`
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
if (this._voltConfig.relay.ca_pem) {
|
|
122
|
-
log(
|
|
123
|
-
"Auto-fetched Relay CA %s, remote address %s",
|
|
124
|
-
this._voltConfig.relay.ca_pem,
|
|
125
|
-
this._voltConfig.relay.address
|
|
126
|
-
);
|
|
127
|
-
} else {
|
|
128
|
-
throw new Error("Unable to fetch Relay CA - cannot securely connect.");
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
108
|
if (!this._credential.cache.ca) {
|
|
133
109
|
this._credential.cache.ca = this._voltConfig.ca_pem;
|
|
134
110
|
}
|
|
@@ -458,18 +434,18 @@ export function streamingCallInternal(methodType, method, request, service) {
|
|
|
458
434
|
|
|
459
435
|
export async function fetchVoltConfig(discovery_url) {
|
|
460
436
|
try {
|
|
461
|
-
const response = await fetch(discovery_url
|
|
462
|
-
headers: { Accept: "application/json" }
|
|
463
|
-
});
|
|
437
|
+
const response = await fetch(discovery_url);
|
|
464
438
|
|
|
465
439
|
if (!response.ok) {
|
|
466
|
-
|
|
440
|
+
log("fetchVoltConfig - error [%s]", response.status);
|
|
441
|
+
return null;
|
|
467
442
|
}
|
|
468
443
|
|
|
469
444
|
const fullVoltConfig = await response.json();
|
|
470
445
|
|
|
471
446
|
if (!fullVoltConfig || typeof fullVoltConfig !== "object") {
|
|
472
|
-
|
|
447
|
+
log("fetchVoltConfig - invalid config resolved from: %s", discovery_url);
|
|
448
|
+
return null;
|
|
473
449
|
}
|
|
474
450
|
|
|
475
451
|
const voltConfig = pick(
|
|
@@ -484,11 +460,12 @@ export async function fetchVoltConfig(discovery_url) {
|
|
|
484
460
|
"relay"
|
|
485
461
|
);
|
|
486
462
|
|
|
463
|
+
log("fetchVoltConfig from %s", discovery_url);
|
|
464
|
+
|
|
487
465
|
return voltConfig;
|
|
488
466
|
} catch (err) {
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
);
|
|
467
|
+
log("fetchVoltConfig - %s error [%s]", discovery_url, err.message);
|
|
468
|
+
return null;
|
|
492
469
|
}
|
|
493
470
|
}
|
|
494
471
|
|
|
@@ -499,12 +476,10 @@ async function fetchVoltConfigFromDIDInternal(volt_did, registryUrl) {
|
|
|
499
476
|
throw new Error(`Invalid Volt DID: ${volt_did}`);
|
|
500
477
|
}
|
|
501
478
|
|
|
502
|
-
const response = await fetch(didResolution
|
|
503
|
-
headers: { Accept: "application/json" }
|
|
504
|
-
});
|
|
479
|
+
const response = await fetch(didResolution);
|
|
505
480
|
|
|
506
481
|
if (!response.ok) {
|
|
507
|
-
throw new Error(`HTTP error
|
|
482
|
+
throw new Error(`HTTP error, status: ${response.status}`);
|
|
508
483
|
}
|
|
509
484
|
|
|
510
485
|
const didDocument = await response.json();
|
|
@@ -523,7 +498,12 @@ async function fetchVoltConfigFromDIDInternal(volt_did, registryUrl) {
|
|
|
523
498
|
log("resolved DID from %s", didResolution);
|
|
524
499
|
|
|
525
500
|
const serviceEndpoint = voltConfigServices[0].serviceEndpoint;
|
|
526
|
-
|
|
501
|
+
const voltConfig = await fetchVoltConfig.call(this, serviceEndpoint);
|
|
502
|
+
if (!voltConfig) {
|
|
503
|
+
throw new Error(`failed to resolve Volt config from ${serviceEndpoint}`);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
return voltConfig;
|
|
527
507
|
} catch (err) {
|
|
528
508
|
throw new Error(
|
|
529
509
|
`Failure fetching Volt config from DID document ${volt_did}: ${err.message}`
|
|
@@ -531,25 +511,128 @@ async function fetchVoltConfigFromDIDInternal(volt_did, registryUrl) {
|
|
|
531
511
|
}
|
|
532
512
|
}
|
|
533
513
|
|
|
534
|
-
export async function fetchVoltConfigFromDID(
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
514
|
+
export async function fetchVoltConfigFromDID(volt_did, registryListIn) {
|
|
515
|
+
let registryList;
|
|
516
|
+
if (!registryListIn) {
|
|
517
|
+
// If no registry list is provided, use the default registry list.
|
|
518
|
+
registryList = constants.defaultRegistryList;
|
|
519
|
+
} else {
|
|
520
|
+
// If a registry list is provided, merge it with the default registry list.
|
|
521
|
+
registryList = Array.from(
|
|
522
|
+
new Set(registryListIn.concat(constants.defaultRegistryList))
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
let voltConfig;
|
|
538
527
|
for (let registryUrl of registryList) {
|
|
539
528
|
try {
|
|
540
|
-
|
|
529
|
+
voltConfig = await fetchVoltConfigFromDIDInternal.call(
|
|
541
530
|
this,
|
|
542
531
|
volt_did,
|
|
543
532
|
registryUrl
|
|
544
533
|
);
|
|
534
|
+
|
|
535
|
+
// If we've found a config, break out of the loop.
|
|
536
|
+
break;
|
|
537
|
+
} catch (err) {
|
|
538
|
+
log("unable to fetch Volt config from %s: %s", registryUrl, err.message);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
if (!voltConfig) {
|
|
543
|
+
log("failed to fetch Volt config for %s from any registry", volt_did);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
return voltConfig;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
export async function resolveVoltConfig(cfg, didRegistryList) {
|
|
550
|
+
// Start by resolving the relay if one is specified.
|
|
551
|
+
let relay = cfg?.relay?.http_address || cfg?.relay;
|
|
552
|
+
if (relay) {
|
|
553
|
+
relay = await resolveVoltConfig.call(this, relay, didRegistryList);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
let voltDID = "";
|
|
557
|
+
let voltHttpAddress = "";
|
|
558
|
+
|
|
559
|
+
if (typeof cfg === "string") {
|
|
560
|
+
// If the configuration is a string, determine if it is a DID or HTTP address.
|
|
561
|
+
if (cfg.indexOf("did:") === 0) {
|
|
562
|
+
voltDID = cfg;
|
|
563
|
+
} else {
|
|
564
|
+
voltHttpAddress = cfg;
|
|
565
|
+
}
|
|
566
|
+
cfg = {};
|
|
567
|
+
} else if (typeof cfg === "object") {
|
|
568
|
+
voltDID = cfg.id;
|
|
569
|
+
voltHttpAddress = cfg.http_address;
|
|
570
|
+
} else {
|
|
571
|
+
throw new Error("configuration is missing the 'volt' object");
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
let resolvedConfig;
|
|
575
|
+
|
|
576
|
+
if (relay) {
|
|
577
|
+
if (!voltDID) {
|
|
578
|
+
throw new Error("relay specified but no Volt DID provided");
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
// Build the sub-domain URL for the Volt discovery service by inserting the volt DID into the relay URL.
|
|
582
|
+
const relayURL = relay.http_address;
|
|
583
|
+
const relayParts = relayURL.split("://");
|
|
584
|
+
const subdomain = voltDID.substring(constants.voltDIDPrefix.length);
|
|
585
|
+
voltHttpAddress = `${relayParts[0]}://${subdomain}.${relayParts[1]}`;
|
|
586
|
+
} else if (voltDID) {
|
|
587
|
+
resolvedConfig = await fetchVoltConfigFromDID.call(
|
|
588
|
+
this,
|
|
589
|
+
voltDID,
|
|
590
|
+
didRegistryList
|
|
591
|
+
);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
if (!resolvedConfig && voltHttpAddress) {
|
|
595
|
+
try {
|
|
596
|
+
resolvedConfig = await fetchVoltConfig.call(
|
|
597
|
+
this,
|
|
598
|
+
`${voltHttpAddress}/discover`
|
|
599
|
+
);
|
|
600
|
+
|
|
601
|
+
// Update the http address in the resolved config to the one we used to
|
|
602
|
+
// fetch it, since we may have used the relay rather than local address.
|
|
603
|
+
resolvedConfig.http_address = voltHttpAddress;
|
|
545
604
|
} catch (err) {
|
|
546
|
-
log(
|
|
605
|
+
log(
|
|
606
|
+
"failed to resolve Volt configuration %s [%s]",
|
|
607
|
+
voltHttpAddress,
|
|
608
|
+
err.message
|
|
609
|
+
);
|
|
547
610
|
}
|
|
548
611
|
}
|
|
549
612
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
613
|
+
if (!resolvedConfig) {
|
|
614
|
+
if (cfg.address && cfg.ca_pem) {
|
|
615
|
+
log(
|
|
616
|
+
"unable to resolve %s / %s, using existing configuration",
|
|
617
|
+
voltDID,
|
|
618
|
+
voltHttpAddress
|
|
619
|
+
);
|
|
620
|
+
} else {
|
|
621
|
+
throw new Error(
|
|
622
|
+
`failed to resolve Volt ${voltDID} / ${voltHttpAddress} and no existing configuration`
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
} else {
|
|
626
|
+
log("resolved config from: %s", voltDID || voltHttpAddress);
|
|
627
|
+
log(JSON.stringify(resolvedConfig, null, 2));
|
|
628
|
+
|
|
629
|
+
cfg = {
|
|
630
|
+
...cfg,
|
|
631
|
+
...resolvedConfig
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
cfg.relay = relay;
|
|
636
|
+
|
|
637
|
+
return cfg;
|
|
555
638
|
}
|
package/src/volt-client.js
CHANGED
|
@@ -6,9 +6,8 @@ import GRPCCall from "./grpc-call.js";
|
|
|
6
6
|
import {
|
|
7
7
|
authenticateInternal,
|
|
8
8
|
connectInternal,
|
|
9
|
-
fetchVoltConfig,
|
|
10
|
-
fetchVoltConfigFromDID,
|
|
11
9
|
getVoltAPIClientInternal,
|
|
10
|
+
resolveVoltConfig,
|
|
12
11
|
streamingCallInternal,
|
|
13
12
|
unaryCallInternal
|
|
14
13
|
} from "./volt-client-internal.js";
|
|
@@ -74,19 +73,22 @@ export class VoltClient extends EventEmitter {
|
|
|
74
73
|
|
|
75
74
|
/**
|
|
76
75
|
* Initialises a binding and connection to the volt.
|
|
77
|
-
* @param {string} [config] - the location of the Volt configuration
|
|
78
|
-
*
|
|
76
|
+
* @param {string | object} [config] - the location of the Volt configuration
|
|
77
|
+
* file, or a configuration object
|
|
78
|
+
* @param {object} [options] - initialisation options
|
|
79
|
+
* @param {string[]} [options.didRegistryList] - list of DID registry URLs to use for
|
|
80
|
+
* resolving DIDs
|
|
81
|
+
* @param {object} [options.extraConfig] - additional configuration to be merged with the
|
|
82
|
+
* configuration from the config file.
|
|
83
|
+
* @param {boolean} [options.ownDID] - whether the Volt should manage the DID - set to
|
|
84
|
+
* true if you want to manage the DID yourself
|
|
79
85
|
*/
|
|
80
|
-
async initialise(
|
|
81
|
-
|
|
82
|
-
extras = {},
|
|
83
|
-
ownDID = false,
|
|
84
|
-
didRegistryList = undefined
|
|
85
|
-
) {
|
|
86
|
+
async initialise(config, options = {}) {
|
|
87
|
+
const { ownDID, didRegistryList, extraConfig } = options;
|
|
86
88
|
try {
|
|
87
89
|
if (!config) {
|
|
88
90
|
throw new Error(
|
|
89
|
-
"
|
|
91
|
+
"config argument is required to be a non-empty string or JSON object"
|
|
90
92
|
);
|
|
91
93
|
}
|
|
92
94
|
|
|
@@ -119,7 +121,8 @@ export class VoltClient extends EventEmitter {
|
|
|
119
121
|
throw new Error("config argument is required to be an object");
|
|
120
122
|
}
|
|
121
123
|
|
|
122
|
-
|
|
124
|
+
// Merge any extra configuration supplied, preferring that loaded from file.
|
|
125
|
+
this._config = { ...extraConfig, ...configJSON };
|
|
123
126
|
|
|
124
127
|
if (
|
|
125
128
|
!this._config.client_name ||
|
|
@@ -128,52 +131,13 @@ export class VoltClient extends EventEmitter {
|
|
|
128
131
|
throw new Error("client_name property required in config");
|
|
129
132
|
}
|
|
130
133
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
} else {
|
|
137
|
-
voltHttpAddress = this._config.volt;
|
|
138
|
-
}
|
|
139
|
-
delete this._config.volt;
|
|
140
|
-
} else if (typeof this._config.volt !== "object") {
|
|
141
|
-
throw new Error("configuration is missing the 'volt' object");
|
|
142
|
-
} else {
|
|
143
|
-
voltDID = this._config.volt.did;
|
|
144
|
-
voltHttpAddress = this._config.volt.http_address;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (voltDID) {
|
|
148
|
-
const didConfig = await fetchVoltConfigFromDID.call(
|
|
149
|
-
this,
|
|
150
|
-
voltDID,
|
|
151
|
-
didRegistryList
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
// Remove the relay list from the DID config, as it would overwrite the relay in the supplied config.
|
|
155
|
-
delete didConfig.relay;
|
|
156
|
-
|
|
157
|
-
this._config = { ...this._config, volt: didConfig };
|
|
158
|
-
log("resolved config from DID: %s", JSON.stringify(didConfig, null, 2));
|
|
159
|
-
} else if (voltHttpAddress && !this._config?.volt?.id) {
|
|
160
|
-
const discoConfig = await fetchVoltConfig.call(
|
|
161
|
-
this,
|
|
162
|
-
`${voltHttpAddress}/discover`
|
|
163
|
-
);
|
|
164
|
-
this._config = {
|
|
165
|
-
...this._config,
|
|
166
|
-
volt: { ...this._config.volt, ...discoConfig }
|
|
167
|
-
};
|
|
168
|
-
}
|
|
134
|
+
this._config.volt = await resolveVoltConfig.call(
|
|
135
|
+
this,
|
|
136
|
+
this._config.volt,
|
|
137
|
+
didRegistryList
|
|
138
|
+
);
|
|
169
139
|
|
|
170
140
|
this._voltConfig = this._config.volt;
|
|
171
|
-
if (voltDID) {
|
|
172
|
-
this._voltConfig.did = voltDID;
|
|
173
|
-
}
|
|
174
|
-
if (voltHttpAddress) {
|
|
175
|
-
this._voltConfig.http_address = voltHttpAddress;
|
|
176
|
-
}
|
|
177
141
|
|
|
178
142
|
if (!this._voltConfig.id || typeof this._voltConfig.id !== "string") {
|
|
179
143
|
throw new Error("'id' property is missing in Volt configuration");
|
|
@@ -228,13 +192,14 @@ export class VoltClient extends EventEmitter {
|
|
|
228
192
|
|
|
229
193
|
return Promise.resolve(this._config);
|
|
230
194
|
} catch (err) {
|
|
231
|
-
log("
|
|
195
|
+
log("failure starting Volt client [%s]", err.message);
|
|
232
196
|
throw err;
|
|
233
197
|
}
|
|
234
198
|
}
|
|
235
199
|
|
|
236
|
-
initialiseAndConnect(configPath,
|
|
237
|
-
|
|
200
|
+
initialiseAndConnect(configPath, options) {
|
|
201
|
+
const helloPayload = options?.helloPayload;
|
|
202
|
+
return this.initialise(configPath, options)
|
|
238
203
|
.then(() => {
|
|
239
204
|
return connectInternal.call(this, helloPayload);
|
|
240
205
|
})
|
|
@@ -2747,6 +2747,7 @@ message InvokeResponse {
|
|
|
2747
2747
|
// The invocation id to match the originating request.
|
|
2748
2748
|
uint64 invoke_id = 1;
|
|
2749
2749
|
|
|
2750
|
+
// Key exchange details for the response payload encryption. Only necessary for the first response.
|
|
2750
2751
|
InvokeRequestKeyExchange key_exchange = 2;
|
|
2751
2752
|
|
|
2752
2753
|
// The initialisation vector for the response payload encryption. This will be a random 16 byte value, that is different for each response.
|