@holochain/hc-spin 0.500.0-rc.1 → 0.500.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.
- package/dist/main/index.js +1282 -1274
- package/package.json +4 -4
package/dist/main/index.js
CHANGED
|
@@ -4537,399 +4537,29 @@ const getBaseRoleNameFromCloneId = (roleName) => {
|
|
|
4537
4537
|
}
|
|
4538
4538
|
return roleName.split(CLONE_ID_DELIMITER)[0];
|
|
4539
4539
|
};
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
u32 = c0 << 16 | c1 << 8 | c2;
|
|
4564
|
-
asc += b64chs[u32 >> 18 & 63] + b64chs[u32 >> 12 & 63] + b64chs[u32 >> 6 & 63] + b64chs[u32 & 63];
|
|
4565
|
-
}
|
|
4566
|
-
return pad ? asc.slice(0, pad - 3) + "===".substring(pad) : asc;
|
|
4567
|
-
};
|
|
4568
|
-
const _btoa = typeof btoa === "function" ? (bin) => btoa(bin) : _hasBuffer ? (bin) => Buffer.from(bin, "binary").toString("base64") : btoaPolyfill;
|
|
4569
|
-
const _fromUint8Array = _hasBuffer ? (u8a) => Buffer.from(u8a).toString("base64") : (u8a) => {
|
|
4570
|
-
const maxargs = 4096;
|
|
4571
|
-
let strs = [];
|
|
4572
|
-
for (let i = 0, l = u8a.length; i < l; i += maxargs) {
|
|
4573
|
-
strs.push(_fromCC.apply(null, u8a.subarray(i, i + maxargs)));
|
|
4574
|
-
}
|
|
4575
|
-
return _btoa(strs.join(""));
|
|
4576
|
-
};
|
|
4577
|
-
const fromUint8Array = (u8a, urlsafe = false) => urlsafe ? _mkUriSafe(_fromUint8Array(u8a)) : _fromUint8Array(u8a);
|
|
4578
|
-
const cb_utob = (c) => {
|
|
4579
|
-
if (c.length < 2) {
|
|
4580
|
-
var cc = c.charCodeAt(0);
|
|
4581
|
-
return cc < 128 ? c : cc < 2048 ? _fromCC(192 | cc >>> 6) + _fromCC(128 | cc & 63) : _fromCC(224 | cc >>> 12 & 15) + _fromCC(128 | cc >>> 6 & 63) + _fromCC(128 | cc & 63);
|
|
4582
|
-
} else {
|
|
4583
|
-
var cc = 65536 + (c.charCodeAt(0) - 55296) * 1024 + (c.charCodeAt(1) - 56320);
|
|
4584
|
-
return _fromCC(240 | cc >>> 18 & 7) + _fromCC(128 | cc >>> 12 & 63) + _fromCC(128 | cc >>> 6 & 63) + _fromCC(128 | cc & 63);
|
|
4585
|
-
}
|
|
4586
|
-
};
|
|
4587
|
-
const re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;
|
|
4588
|
-
const utob = (u) => u.replace(re_utob, cb_utob);
|
|
4589
|
-
const _encode = _hasBuffer ? (s) => Buffer.from(s, "utf8").toString("base64") : _TE ? (s) => _fromUint8Array(_TE.encode(s)) : (s) => _btoa(utob(s));
|
|
4590
|
-
const encode = (src, urlsafe = false) => urlsafe ? _mkUriSafe(_encode(src)) : _encode(src);
|
|
4591
|
-
const encodeURI = (src) => encode(src, true);
|
|
4592
|
-
const re_btou = /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g;
|
|
4593
|
-
const cb_btou = (cccc) => {
|
|
4594
|
-
switch (cccc.length) {
|
|
4595
|
-
case 4:
|
|
4596
|
-
var cp = (7 & cccc.charCodeAt(0)) << 18 | (63 & cccc.charCodeAt(1)) << 12 | (63 & cccc.charCodeAt(2)) << 6 | 63 & cccc.charCodeAt(3), offset = cp - 65536;
|
|
4597
|
-
return _fromCC((offset >>> 10) + 55296) + _fromCC((offset & 1023) + 56320);
|
|
4598
|
-
case 3:
|
|
4599
|
-
return _fromCC((15 & cccc.charCodeAt(0)) << 12 | (63 & cccc.charCodeAt(1)) << 6 | 63 & cccc.charCodeAt(2));
|
|
4600
|
-
default:
|
|
4601
|
-
return _fromCC((31 & cccc.charCodeAt(0)) << 6 | 63 & cccc.charCodeAt(1));
|
|
4602
|
-
}
|
|
4603
|
-
};
|
|
4604
|
-
const btou = (b) => b.replace(re_btou, cb_btou);
|
|
4605
|
-
const atobPolyfill = (asc) => {
|
|
4606
|
-
asc = asc.replace(/\s+/g, "");
|
|
4607
|
-
if (!b64re.test(asc))
|
|
4608
|
-
throw new TypeError("malformed base64.");
|
|
4609
|
-
asc += "==".slice(2 - (asc.length & 3));
|
|
4610
|
-
let u24, bin = "", r1, r2;
|
|
4611
|
-
for (let i = 0; i < asc.length; ) {
|
|
4612
|
-
u24 = b64tab[asc.charAt(i++)] << 18 | b64tab[asc.charAt(i++)] << 12 | (r1 = b64tab[asc.charAt(i++)]) << 6 | (r2 = b64tab[asc.charAt(i++)]);
|
|
4613
|
-
bin += r1 === 64 ? _fromCC(u24 >> 16 & 255) : r2 === 64 ? _fromCC(u24 >> 16 & 255, u24 >> 8 & 255) : _fromCC(u24 >> 16 & 255, u24 >> 8 & 255, u24 & 255);
|
|
4614
|
-
}
|
|
4615
|
-
return bin;
|
|
4616
|
-
};
|
|
4617
|
-
const _atob = typeof atob === "function" ? (asc) => atob(_tidyB64(asc)) : _hasBuffer ? (asc) => Buffer.from(asc, "base64").toString("binary") : atobPolyfill;
|
|
4618
|
-
const _toUint8Array = _hasBuffer ? (a) => _U8Afrom(Buffer.from(a, "base64")) : (a) => _U8Afrom(_atob(a).split("").map((c) => c.charCodeAt(0)));
|
|
4619
|
-
const toUint8Array$1 = (a) => _toUint8Array(_unURI(a));
|
|
4620
|
-
const _decode = _hasBuffer ? (a) => Buffer.from(a, "base64").toString("utf8") : _TD ? (a) => _TD.decode(_toUint8Array(a)) : (a) => btou(_atob(a));
|
|
4621
|
-
const _unURI = (a) => _tidyB64(a.replace(/[-_]/g, (m0) => m0 == "-" ? "+" : "/"));
|
|
4622
|
-
const decode = (src) => _decode(_unURI(src));
|
|
4623
|
-
const isValid = (src) => {
|
|
4624
|
-
if (typeof src !== "string")
|
|
4625
|
-
return false;
|
|
4626
|
-
const s = src.replace(/\s+/g, "").replace(/={0,2}$/, "");
|
|
4627
|
-
return !/[^\s0-9a-zA-Z\+/]/.test(s) || !/[^\s0-9a-zA-Z\-_]/.test(s);
|
|
4628
|
-
};
|
|
4629
|
-
const _noEnum = (v2) => {
|
|
4630
|
-
return {
|
|
4631
|
-
value: v2,
|
|
4632
|
-
enumerable: false,
|
|
4633
|
-
writable: true,
|
|
4634
|
-
configurable: true
|
|
4635
|
-
};
|
|
4636
|
-
};
|
|
4637
|
-
const extendString = function() {
|
|
4638
|
-
const _add = (name, body) => Object.defineProperty(String.prototype, name, _noEnum(body));
|
|
4639
|
-
_add("fromBase64", function() {
|
|
4640
|
-
return decode(this);
|
|
4641
|
-
});
|
|
4642
|
-
_add("toBase64", function(urlsafe) {
|
|
4643
|
-
return encode(this, urlsafe);
|
|
4644
|
-
});
|
|
4645
|
-
_add("toBase64URI", function() {
|
|
4646
|
-
return encode(this, true);
|
|
4647
|
-
});
|
|
4648
|
-
_add("toBase64URL", function() {
|
|
4649
|
-
return encode(this, true);
|
|
4650
|
-
});
|
|
4651
|
-
_add("toUint8Array", function() {
|
|
4652
|
-
return toUint8Array$1(this);
|
|
4653
|
-
});
|
|
4654
|
-
};
|
|
4655
|
-
const extendUint8Array = function() {
|
|
4656
|
-
const _add = (name, body) => Object.defineProperty(Uint8Array.prototype, name, _noEnum(body));
|
|
4657
|
-
_add("toBase64", function(urlsafe) {
|
|
4658
|
-
return fromUint8Array(this, urlsafe);
|
|
4659
|
-
});
|
|
4660
|
-
_add("toBase64URI", function() {
|
|
4661
|
-
return fromUint8Array(this, true);
|
|
4662
|
-
});
|
|
4663
|
-
_add("toBase64URL", function() {
|
|
4664
|
-
return fromUint8Array(this, true);
|
|
4665
|
-
});
|
|
4666
|
-
};
|
|
4667
|
-
const extendBuiltins = () => {
|
|
4668
|
-
extendString();
|
|
4669
|
-
extendUint8Array();
|
|
4670
|
-
};
|
|
4671
|
-
const gBase64 = {
|
|
4672
|
-
version,
|
|
4673
|
-
VERSION,
|
|
4674
|
-
atob: _atob,
|
|
4675
|
-
atobPolyfill,
|
|
4676
|
-
btoa: _btoa,
|
|
4677
|
-
btoaPolyfill,
|
|
4678
|
-
fromBase64: decode,
|
|
4679
|
-
toBase64: encode,
|
|
4680
|
-
encode,
|
|
4681
|
-
encodeURI,
|
|
4682
|
-
encodeURL: encodeURI,
|
|
4683
|
-
utob,
|
|
4684
|
-
btou,
|
|
4685
|
-
decode,
|
|
4686
|
-
isValid,
|
|
4687
|
-
fromUint8Array,
|
|
4688
|
-
toUint8Array: toUint8Array$1,
|
|
4689
|
-
extendString,
|
|
4690
|
-
extendUint8Array,
|
|
4691
|
-
extendBuiltins
|
|
4692
|
-
};
|
|
4693
|
-
function encodeHashToBase64(hash) {
|
|
4694
|
-
return `u${gBase64.fromUint8Array(hash, true)}`;
|
|
4695
|
-
}
|
|
4696
|
-
class WsClient extends Emittery {
|
|
4697
|
-
socket;
|
|
4698
|
-
url;
|
|
4699
|
-
options;
|
|
4700
|
-
pendingRequests;
|
|
4701
|
-
index;
|
|
4702
|
-
authenticationToken;
|
|
4703
|
-
constructor(socket, url2, options) {
|
|
4704
|
-
super();
|
|
4705
|
-
this.registerMessageListener(socket);
|
|
4706
|
-
this.registerCloseListener(socket);
|
|
4707
|
-
this.socket = socket;
|
|
4708
|
-
this.url = url2;
|
|
4709
|
-
this.options = options || {};
|
|
4710
|
-
this.pendingRequests = {};
|
|
4711
|
-
this.index = 0;
|
|
4712
|
-
}
|
|
4713
|
-
/**
|
|
4714
|
-
* Instance factory for creating WsClients.
|
|
4715
|
-
*
|
|
4716
|
-
* @param url - The WebSocket URL to connect to.
|
|
4717
|
-
* @param options - Options for the WsClient.
|
|
4718
|
-
* @returns An new instance of the WsClient.
|
|
4719
|
-
*/
|
|
4720
|
-
static connect(url2, options) {
|
|
4721
|
-
return new Promise((resolve, reject) => {
|
|
4722
|
-
const socket = new IsoWebSocket(url2, options);
|
|
4723
|
-
socket.addEventListener("error", (errorEvent) => {
|
|
4724
|
-
reject(new HolochainError("ConnectionError", `could not connect to Holochain Conductor API at ${url2} - ${errorEvent.error}`));
|
|
4725
|
-
});
|
|
4726
|
-
socket.addEventListener("open", (_) => {
|
|
4727
|
-
const client = new WsClient(socket, url2, options);
|
|
4728
|
-
resolve(client);
|
|
4729
|
-
}, { once: true });
|
|
4730
|
-
});
|
|
4731
|
-
}
|
|
4732
|
-
/**
|
|
4733
|
-
* Sends data as a signal.
|
|
4734
|
-
*
|
|
4735
|
-
* @param data - Data to send.
|
|
4736
|
-
*/
|
|
4737
|
-
emitSignal(data) {
|
|
4738
|
-
const encodedMsg = msgpack.encode({
|
|
4739
|
-
type: "signal",
|
|
4740
|
-
data: msgpack.encode(data)
|
|
4741
|
-
});
|
|
4742
|
-
this.socket.send(encodedMsg);
|
|
4743
|
-
}
|
|
4744
|
-
/**
|
|
4745
|
-
* Authenticate the client with the conductor.
|
|
4746
|
-
*
|
|
4747
|
-
* This is only relevant for app websockets.
|
|
4748
|
-
*
|
|
4749
|
-
* @param request - The authentication request, containing an app authentication token.
|
|
4750
|
-
*/
|
|
4751
|
-
async authenticate(request) {
|
|
4752
|
-
this.authenticationToken = request.token;
|
|
4753
|
-
return this.exchange(request, (request2, resolve, reject) => {
|
|
4754
|
-
const invalidTokenCloseListener = (closeEvent) => {
|
|
4755
|
-
this.authenticationToken = void 0;
|
|
4756
|
-
reject(new HolochainError("InvalidTokenError", `could not connect to ${this.url} due to an invalid app authentication token - close code ${closeEvent.code}`));
|
|
4757
|
-
};
|
|
4758
|
-
this.socket.addEventListener("close", invalidTokenCloseListener, {
|
|
4759
|
-
once: true
|
|
4760
|
-
});
|
|
4761
|
-
const encodedMsg = msgpack.encode({
|
|
4762
|
-
type: "authenticate",
|
|
4763
|
-
data: msgpack.encode(request2)
|
|
4764
|
-
});
|
|
4765
|
-
this.socket.send(encodedMsg);
|
|
4766
|
-
setTimeout(() => {
|
|
4767
|
-
this.socket.removeEventListener("close", invalidTokenCloseListener);
|
|
4768
|
-
resolve(null);
|
|
4769
|
-
}, 10);
|
|
4770
|
-
});
|
|
4771
|
-
}
|
|
4772
|
-
/**
|
|
4773
|
-
* Close the websocket connection.
|
|
4774
|
-
*/
|
|
4775
|
-
close(code = 1e3) {
|
|
4776
|
-
const closedPromise = new Promise((resolve) => this.socket.addEventListener("close", (closeEvent) => resolve(closeEvent), { once: true }));
|
|
4777
|
-
this.socket.close(code);
|
|
4778
|
-
return closedPromise;
|
|
4779
|
-
}
|
|
4780
|
-
/**
|
|
4781
|
-
* Send requests to the connected websocket.
|
|
4782
|
-
*
|
|
4783
|
-
* @param request - The request to send over the websocket.
|
|
4784
|
-
* @returns
|
|
4785
|
-
*/
|
|
4786
|
-
async request(request) {
|
|
4787
|
-
return this.exchange(request, this.sendMessage.bind(this));
|
|
4788
|
-
}
|
|
4789
|
-
async exchange(request, sendHandler) {
|
|
4790
|
-
if (this.socket.readyState === this.socket.OPEN) {
|
|
4791
|
-
const promise = new Promise((resolve, reject) => {
|
|
4792
|
-
sendHandler(request, resolve, reject);
|
|
4793
|
-
});
|
|
4794
|
-
return promise;
|
|
4795
|
-
} else if (this.url && this.authenticationToken) {
|
|
4796
|
-
await this.reconnectWebsocket(this.url, this.authenticationToken);
|
|
4797
|
-
this.registerMessageListener(this.socket);
|
|
4798
|
-
this.registerCloseListener(this.socket);
|
|
4799
|
-
const promise = new Promise((resolve, reject) => sendHandler(request, resolve, reject));
|
|
4800
|
-
return promise;
|
|
4801
|
-
} else {
|
|
4802
|
-
return Promise.reject(new HolochainError("WebsocketClosedError", "Websocket is not open"));
|
|
4803
|
-
}
|
|
4804
|
-
}
|
|
4805
|
-
sendMessage(request, resolve, reject) {
|
|
4806
|
-
const id = this.index;
|
|
4807
|
-
const encodedMsg = msgpack.encode({
|
|
4808
|
-
id,
|
|
4809
|
-
type: "request",
|
|
4810
|
-
data: msgpack.encode(request)
|
|
4811
|
-
});
|
|
4812
|
-
this.socket.send(encodedMsg);
|
|
4813
|
-
this.pendingRequests[id] = { resolve, reject };
|
|
4814
|
-
this.index += 1;
|
|
4815
|
-
}
|
|
4816
|
-
registerMessageListener(socket) {
|
|
4817
|
-
socket.onmessage = async (serializedMessage) => {
|
|
4818
|
-
let deserializedData;
|
|
4819
|
-
if (globalThis.window && serializedMessage.data instanceof globalThis.window.Blob) {
|
|
4820
|
-
deserializedData = await serializedMessage.data.arrayBuffer();
|
|
4821
|
-
} else {
|
|
4822
|
-
if (typeof Buffer !== "undefined" && Buffer.isBuffer(serializedMessage.data)) {
|
|
4823
|
-
deserializedData = serializedMessage.data;
|
|
4824
|
-
} else {
|
|
4825
|
-
throw new HolochainError("UnknownMessageFormat", `incoming message has unknown message format - ${deserializedData}`);
|
|
4826
|
-
}
|
|
4827
|
-
}
|
|
4828
|
-
const message = msgpack.decode(deserializedData);
|
|
4829
|
-
assertHolochainMessage(message);
|
|
4830
|
-
if (message.type === "signal") {
|
|
4831
|
-
if (message.data === null) {
|
|
4832
|
-
throw new HolochainError("UnknownSignalFormat", "incoming signal has no data");
|
|
4833
|
-
}
|
|
4834
|
-
const deserializedSignal = msgpack.decode(message.data);
|
|
4835
|
-
assertHolochainSignal(deserializedSignal);
|
|
4836
|
-
if (deserializedSignal.type === "system") {
|
|
4837
|
-
this.emit("signal", {
|
|
4838
|
-
type: "system",
|
|
4839
|
-
value: deserializedSignal.value
|
|
4840
|
-
});
|
|
4841
|
-
} else {
|
|
4842
|
-
const encodedAppSignal = deserializedSignal.value;
|
|
4843
|
-
const payload = msgpack.decode(encodedAppSignal.signal);
|
|
4844
|
-
const signal = {
|
|
4845
|
-
cell_id: encodedAppSignal.cell_id,
|
|
4846
|
-
zome_name: encodedAppSignal.zome_name,
|
|
4847
|
-
payload
|
|
4848
|
-
};
|
|
4849
|
-
this.emit("signal", { type: "app", value: signal });
|
|
4850
|
-
}
|
|
4851
|
-
} else if (message.type === "response") {
|
|
4852
|
-
this.handleResponse(message);
|
|
4853
|
-
} else {
|
|
4854
|
-
throw new HolochainError("UnknownMessageType", `incoming message has unknown type - ${message.type}`);
|
|
4855
|
-
}
|
|
4856
|
-
};
|
|
4857
|
-
}
|
|
4858
|
-
registerCloseListener(socket) {
|
|
4859
|
-
socket.addEventListener("close", (closeEvent) => {
|
|
4860
|
-
const pendingRequestIds = Object.keys(this.pendingRequests).map((id) => parseInt(id));
|
|
4861
|
-
if (pendingRequestIds.length) {
|
|
4862
|
-
pendingRequestIds.forEach((id) => {
|
|
4863
|
-
const error = new HolochainError("ClientClosedWithPendingRequests", `client closed with pending requests - close event code: ${closeEvent.code}, request id: ${id}`);
|
|
4864
|
-
this.pendingRequests[id].reject(error);
|
|
4865
|
-
delete this.pendingRequests[id];
|
|
4866
|
-
});
|
|
4867
|
-
}
|
|
4868
|
-
}, { once: true });
|
|
4869
|
-
}
|
|
4870
|
-
async reconnectWebsocket(url2, token) {
|
|
4871
|
-
return new Promise((resolve, reject) => {
|
|
4872
|
-
this.socket = new IsoWebSocket(url2, this.options);
|
|
4873
|
-
this.socket.addEventListener("error", (errorEvent) => {
|
|
4874
|
-
this.authenticationToken = void 0;
|
|
4875
|
-
reject(new HolochainError("ConnectionError", `could not connect to Holochain Conductor API at ${url2} - ${errorEvent.message}`));
|
|
4876
|
-
}, { once: true });
|
|
4877
|
-
const invalidTokenCloseListener = (closeEvent) => {
|
|
4878
|
-
this.authenticationToken = void 0;
|
|
4879
|
-
reject(new HolochainError("InvalidTokenError", `could not connect to ${this.url} due to an invalid app authentication token - close code ${closeEvent.code}`));
|
|
4880
|
-
};
|
|
4881
|
-
this.socket.addEventListener("close", invalidTokenCloseListener, {
|
|
4882
|
-
once: true
|
|
4883
|
-
});
|
|
4884
|
-
this.socket.addEventListener("open", async (_) => {
|
|
4885
|
-
const encodedMsg = msgpack.encode({
|
|
4886
|
-
type: "authenticate",
|
|
4887
|
-
data: msgpack.encode({ token })
|
|
4888
|
-
});
|
|
4889
|
-
this.socket.send(encodedMsg);
|
|
4890
|
-
setTimeout(() => {
|
|
4891
|
-
this.socket.removeEventListener("close", invalidTokenCloseListener);
|
|
4892
|
-
resolve();
|
|
4893
|
-
}, 10);
|
|
4894
|
-
}, { once: true });
|
|
4895
|
-
});
|
|
4896
|
-
}
|
|
4897
|
-
handleResponse(msg) {
|
|
4898
|
-
const id = msg.id;
|
|
4899
|
-
if (this.pendingRequests[id]) {
|
|
4900
|
-
if (msg.data === null || msg.data === void 0) {
|
|
4901
|
-
this.pendingRequests[id].reject(new Error("Response canceled by responder"));
|
|
4902
|
-
} else {
|
|
4903
|
-
this.pendingRequests[id].resolve(msgpack.decode(msg.data, {
|
|
4904
|
-
mapKeyConverter: (key) => {
|
|
4905
|
-
if (typeof key === "string" || typeof key === "number") {
|
|
4906
|
-
return key;
|
|
4907
|
-
}
|
|
4908
|
-
if (key && typeof key === "object" && key instanceof Uint8Array) {
|
|
4909
|
-
return encodeHashToBase64(key);
|
|
4910
|
-
}
|
|
4911
|
-
throw new HolochainError("DeserializationError", "Encountered map with key of type 'object', but not HoloHash " + key);
|
|
4912
|
-
}
|
|
4913
|
-
}));
|
|
4914
|
-
}
|
|
4915
|
-
delete this.pendingRequests[id];
|
|
4916
|
-
} else {
|
|
4917
|
-
console.error(`got response with no matching request. id = ${id} msg = ${msg}`);
|
|
4918
|
-
}
|
|
4919
|
-
}
|
|
4920
|
-
}
|
|
4921
|
-
function assertHolochainMessage(message) {
|
|
4922
|
-
if (typeof message === "object" && message !== null && "type" in message && "data" in message) {
|
|
4923
|
-
return;
|
|
4924
|
-
}
|
|
4925
|
-
throw new HolochainError("UnknownMessageFormat", `incoming message has unknown message format ${JSON.stringify(message, null, 4)}`);
|
|
4926
|
-
}
|
|
4927
|
-
function assertHolochainSignal(signal) {
|
|
4928
|
-
if (typeof signal === "object" && signal !== null && "type" in signal && "value" in signal && ["app", "signal"].some((type) => signal.type === type)) {
|
|
4929
|
-
return;
|
|
4930
|
-
}
|
|
4931
|
-
throw new HolochainError("UnknownSignalFormat", `incoming signal has unknown signal format ${JSON.stringify(signal, null, 4)}`);
|
|
4932
|
-
}
|
|
4540
|
+
var CountersigningSessionStateType;
|
|
4541
|
+
(function(CountersigningSessionStateType2) {
|
|
4542
|
+
CountersigningSessionStateType2["Accepted"] = "Accepted";
|
|
4543
|
+
CountersigningSessionStateType2["SignaturesCollected"] = "SignaturesCollected";
|
|
4544
|
+
CountersigningSessionStateType2["Unknown"] = "Unknown";
|
|
4545
|
+
})(CountersigningSessionStateType || (CountersigningSessionStateType = {}));
|
|
4546
|
+
var ResolutionRequiredReason;
|
|
4547
|
+
(function(ResolutionRequiredReason2) {
|
|
4548
|
+
ResolutionRequiredReason2["Timeout"] = "Timeout";
|
|
4549
|
+
ResolutionRequiredReason2["Unknown"] = "Unknown";
|
|
4550
|
+
})(ResolutionRequiredReason || (ResolutionRequiredReason = {}));
|
|
4551
|
+
var SessionCompletionDecisionType;
|
|
4552
|
+
(function(SessionCompletionDecisionType2) {
|
|
4553
|
+
SessionCompletionDecisionType2["Complete"] = "Complete";
|
|
4554
|
+
SessionCompletionDecisionType2["Abandoned"] = "Abandoned";
|
|
4555
|
+
SessionCompletionDecisionType2["Indeterminate"] = "Indeterminate";
|
|
4556
|
+
SessionCompletionDecisionType2["Failed"] = "Failed";
|
|
4557
|
+
})(SessionCompletionDecisionType || (SessionCompletionDecisionType = {}));
|
|
4558
|
+
var SignalType;
|
|
4559
|
+
(function(SignalType2) {
|
|
4560
|
+
SignalType2["App"] = "app";
|
|
4561
|
+
SignalType2["System"] = "system";
|
|
4562
|
+
})(SignalType || (SignalType = {}));
|
|
4933
4563
|
var libsodiumWrappers = {};
|
|
4934
4564
|
var libsodium = { exports: {} };
|
|
4935
4565
|
var hasRequiredLibsodium;
|
|
@@ -9986,372 +9616,158 @@ function requireLibsodium() {
|
|
|
9986
9616
|
b(s2, "invalid usage");
|
|
9987
9617
|
}
|
|
9988
9618
|
function Ur(e3) {
|
|
9989
|
-
var a3 = [];
|
|
9990
|
-
l(e3);
|
|
9991
|
-
var t2 = new u(0 | r2._crypto_stream_keybytes()), _2 = t2.address;
|
|
9992
|
-
a3.push(_2), r2._crypto_stream_keygen(_2);
|
|
9993
|
-
var n2 = y(t2, e3);
|
|
9994
|
-
return g(a3), n2;
|
|
9995
|
-
}
|
|
9996
|
-
function Cr(e3) {
|
|
9997
|
-
var a3 = [];
|
|
9998
|
-
l(e3);
|
|
9999
|
-
var t2 = new u(0 | r2._crypto_stream_xchacha20_keybytes()), _2 = t2.address;
|
|
10000
|
-
a3.push(_2), r2._crypto_stream_xchacha20_keygen(_2);
|
|
10001
|
-
var n2 = y(t2, e3);
|
|
10002
|
-
return g(a3), n2;
|
|
10003
|
-
}
|
|
10004
|
-
function Pr(e3, a3, t2, _2) {
|
|
10005
|
-
var n2 = [];
|
|
10006
|
-
l(_2);
|
|
10007
|
-
var s2 = d(e3 = E(n2, e3, "input_message")), c2 = e3.length;
|
|
10008
|
-
n2.push(s2), a3 = E(n2, a3, "nonce");
|
|
10009
|
-
var h2, o2 = 0 | r2._crypto_stream_xchacha20_noncebytes();
|
|
10010
|
-
a3.length !== o2 && f(n2, "invalid nonce length"), h2 = d(a3), n2.push(h2), t2 = E(n2, t2, "key");
|
|
10011
|
-
var p2, i2 = 0 | r2._crypto_stream_xchacha20_keybytes();
|
|
10012
|
-
t2.length !== i2 && f(n2, "invalid key length"), p2 = d(t2), n2.push(p2);
|
|
10013
|
-
var v3 = new u(0 | c2), m3 = v3.address;
|
|
10014
|
-
if (n2.push(m3), 0 === r2._crypto_stream_xchacha20_xor(m3, s2, c2, 0, h2, p2)) {
|
|
10015
|
-
var x2 = y(v3, _2);
|
|
10016
|
-
return g(n2), x2;
|
|
10017
|
-
}
|
|
10018
|
-
b(n2, "invalid usage");
|
|
10019
|
-
}
|
|
10020
|
-
function Rr(e3, a3, t2, _2, n2) {
|
|
10021
|
-
var s2 = [];
|
|
10022
|
-
l(n2);
|
|
10023
|
-
var c2 = d(e3 = E(s2, e3, "input_message")), h2 = e3.length;
|
|
10024
|
-
s2.push(c2), a3 = E(s2, a3, "nonce");
|
|
10025
|
-
var o2, p2 = 0 | r2._crypto_stream_xchacha20_noncebytes();
|
|
10026
|
-
a3.length !== p2 && f(s2, "invalid nonce length"), o2 = d(a3), s2.push(o2), m2(s2, t2, "nonce_increment"), ("number" != typeof t2 || (0 | t2) !== t2 || t2 < 0) && f(s2, "nonce_increment must be an unsigned integer"), _2 = E(s2, _2, "key");
|
|
10027
|
-
var i2, v3 = 0 | r2._crypto_stream_xchacha20_keybytes();
|
|
10028
|
-
_2.length !== v3 && f(s2, "invalid key length"), i2 = d(_2), s2.push(i2);
|
|
10029
|
-
var x2 = new u(0 | h2), k2 = x2.address;
|
|
10030
|
-
if (s2.push(k2), 0 === r2._crypto_stream_xchacha20_xor_ic(k2, c2, h2, 0, o2, t2, 0, i2)) {
|
|
10031
|
-
var S2 = y(x2, n2);
|
|
10032
|
-
return g(s2), S2;
|
|
10033
|
-
}
|
|
10034
|
-
b(s2, "invalid usage");
|
|
10035
|
-
}
|
|
10036
|
-
function Xr(e3, a3) {
|
|
10037
|
-
var t2 = [];
|
|
10038
|
-
l(a3), m2(t2, e3, "length"), ("number" != typeof e3 || (0 | e3) !== e3 || e3 < 0) && f(t2, "length must be an unsigned integer");
|
|
10039
|
-
var _2 = new u(0 | e3), n2 = _2.address;
|
|
10040
|
-
t2.push(n2), r2._randombytes_buf(n2, e3);
|
|
10041
|
-
var s2 = y(_2, a3);
|
|
10042
|
-
return g(t2), s2;
|
|
10043
|
-
}
|
|
10044
|
-
function Gr(e3, a3, t2) {
|
|
10045
|
-
var _2 = [];
|
|
10046
|
-
l(t2), m2(_2, e3, "length"), ("number" != typeof e3 || (0 | e3) !== e3 || e3 < 0) && f(_2, "length must be an unsigned integer"), a3 = E(_2, a3, "seed");
|
|
10047
|
-
var n2, s2 = 0 | r2._randombytes_seedbytes();
|
|
10048
|
-
a3.length !== s2 && f(_2, "invalid seed length"), n2 = d(a3), _2.push(n2);
|
|
10049
|
-
var c2 = new u(0 | e3), h2 = c2.address;
|
|
10050
|
-
_2.push(h2), r2._randombytes_buf_deterministic(h2, e3, n2);
|
|
10051
|
-
var o2 = y(c2, t2);
|
|
10052
|
-
return g(_2), o2;
|
|
10053
|
-
}
|
|
10054
|
-
function Dr(e3) {
|
|
10055
|
-
l(e3), r2._randombytes_close();
|
|
10056
|
-
}
|
|
10057
|
-
function Fr(e3) {
|
|
10058
|
-
l(e3);
|
|
10059
|
-
var a3 = r2._randombytes_random() >>> 0;
|
|
10060
|
-
return g([]), a3;
|
|
10061
|
-
}
|
|
10062
|
-
function Vr(e3, a3) {
|
|
10063
|
-
var t2 = [];
|
|
10064
|
-
l(a3);
|
|
10065
|
-
for (var _2 = r2._malloc(24), n2 = 0; n2 < 6; n2++) r2.setValue(_2 + 4 * n2, r2.Runtime.addFunction(e3[["implementation_name", "random", "stir", "uniform", "buf", "close"][n2]]), "i32");
|
|
10066
|
-
0 | r2._randombytes_set_implementation(_2) && b(t2, "unsupported implementation"), g(t2);
|
|
10067
|
-
}
|
|
10068
|
-
function Hr(e3) {
|
|
10069
|
-
l(e3), r2._randombytes_stir();
|
|
10070
|
-
}
|
|
10071
|
-
function Wr(e3, a3) {
|
|
10072
|
-
var t2 = [];
|
|
10073
|
-
l(a3), m2(t2, e3, "upper_bound"), ("number" != typeof e3 || (0 | e3) !== e3 || e3 < 0) && f(t2, "upper_bound must be an unsigned integer");
|
|
10074
|
-
var _2 = r2._randombytes_uniform(e3) >>> 0;
|
|
10075
|
-
return g(t2), _2;
|
|
9619
|
+
var a3 = [];
|
|
9620
|
+
l(e3);
|
|
9621
|
+
var t2 = new u(0 | r2._crypto_stream_keybytes()), _2 = t2.address;
|
|
9622
|
+
a3.push(_2), r2._crypto_stream_keygen(_2);
|
|
9623
|
+
var n2 = y(t2, e3);
|
|
9624
|
+
return g(a3), n2;
|
|
10076
9625
|
}
|
|
10077
|
-
function
|
|
10078
|
-
var
|
|
10079
|
-
|
|
9626
|
+
function Cr(e3) {
|
|
9627
|
+
var a3 = [];
|
|
9628
|
+
l(e3);
|
|
9629
|
+
var t2 = new u(0 | r2._crypto_stream_xchacha20_keybytes()), _2 = t2.address;
|
|
9630
|
+
a3.push(_2), r2._crypto_stream_xchacha20_keygen(_2);
|
|
9631
|
+
var n2 = y(t2, e3);
|
|
9632
|
+
return g(a3), n2;
|
|
10080
9633
|
}
|
|
10081
|
-
|
|
10082
|
-
var
|
|
10083
|
-
|
|
10084
|
-
|
|
10085
|
-
|
|
10086
|
-
var
|
|
10087
|
-
|
|
10088
|
-
|
|
10089
|
-
|
|
10090
|
-
|
|
10091
|
-
if (
|
|
10092
|
-
|
|
10093
|
-
|
|
10094
|
-
|
|
10095
|
-
|
|
10096
|
-
|
|
10097
|
-
|
|
10098
|
-
|
|
10099
|
-
|
|
10100
|
-
|
|
10101
|
-
|
|
10102
|
-
|
|
10103
|
-
|
|
10104
|
-
|
|
10105
|
-
|
|
10106
|
-
|
|
10107
|
-
|
|
10108
|
-
|
|
10109
|
-
|
|
10110
|
-
if (e3.length !== a3.length) throw new TypeError("Only instances of identical length can be compared");
|
|
10111
|
-
for (var r3 = 0, t2 = 0, _2 = e3.length; t2 < _2; t2++) r3 |= e3[t2] ^ a3[t2];
|
|
10112
|
-
return 0 === r3;
|
|
10113
|
-
}, e2.memzero = function(e3) {
|
|
10114
|
-
if (!(e3 instanceof Uint8Array)) throw new TypeError("Only Uint8Array instances can be wiped");
|
|
10115
|
-
for (var a3 = 0, r3 = e3.length; a3 < r3; a3++) e3[a3] = 0;
|
|
10116
|
-
}, e2.output_formats = function() {
|
|
10117
|
-
return ["uint8array", "text", "hex", "base64"];
|
|
10118
|
-
}, e2.pad = function(e3, a3) {
|
|
10119
|
-
if (!(e3 instanceof Uint8Array)) throw new TypeError("buffer must be a Uint8Array");
|
|
10120
|
-
if ((a3 |= 0) <= 0) throw new Error("block size must be > 0");
|
|
10121
|
-
var t2, _2 = [], n2 = v2(4), s2 = 1, c2 = 0, h2 = 0 | e3.length, o2 = new u(h2 + a3);
|
|
10122
|
-
_2.push(n2), _2.push(o2.address);
|
|
10123
|
-
for (var p2 = o2.address, y2 = o2.address + h2 + a3; p2 < y2; p2++) r2.HEAPU8[p2] = e3[c2], c2 += s2 = 1 & ~((65535 & ((h2 -= s2) >>> 48 | h2 >>> 32 | h2 >>> 16 | h2)) - 1 >> 16);
|
|
10124
|
-
return 0 !== r2._sodium_pad(n2, o2.address, e3.length, a3, o2.length) && b(_2, "internal error"), o2.length = r2.getValue(n2, "i32"), t2 = o2.to_Uint8Array(), g(_2), t2;
|
|
10125
|
-
}, e2.unpad = function(e3, a3) {
|
|
10126
|
-
if (!(e3 instanceof Uint8Array)) throw new TypeError("buffer must be a Uint8Array");
|
|
10127
|
-
if ((a3 |= 0) <= 0) throw new Error("block size must be > 0");
|
|
10128
|
-
var t2 = [], _2 = d(e3), n2 = v2(4);
|
|
10129
|
-
return t2.push(_2), t2.push(n2), 0 !== r2._sodium_unpad(n2, _2, e3.length, a3) && b(t2, "unsupported/invalid padding"), e3 = (e3 = new Uint8Array(e3)).subarray(0, r2.getValue(n2, "i32")), g(t2), e3;
|
|
10130
|
-
}, e2.ready = _, e2.symbols = function() {
|
|
10131
|
-
return Object.keys(e2).sort();
|
|
10132
|
-
}, e2.to_base64 = p, e2.to_hex = c, e2.to_string = s, e2;
|
|
10133
|
-
}
|
|
10134
|
-
var r = "object" == typeof e.sodium && "function" == typeof e.sodium.onload ? e.sodium.onload : null;
|
|
10135
|
-
"string" != typeof exports2.nodeName ? a(exports2, requireLibsodium()) : e.sodium = a(e.commonJsStrict = {}, e.libsodium), r && e.sodium.ready.then(function() {
|
|
10136
|
-
r(e.sodium);
|
|
10137
|
-
});
|
|
10138
|
-
}(commonjsGlobal);
|
|
10139
|
-
})(libsodiumWrappers);
|
|
10140
|
-
const _sodium = /* @__PURE__ */ getDefaultExportFromCjs(libsodiumWrappers);
|
|
10141
|
-
const signingCredentials = /* @__PURE__ */ new Map();
|
|
10142
|
-
const getSigningCredentials = (cellId) => {
|
|
10143
|
-
const cellIdB64 = encodeHashToBase64(cellId[0]).concat(encodeHashToBase64(cellId[1]));
|
|
10144
|
-
return signingCredentials.get(cellIdB64);
|
|
10145
|
-
};
|
|
10146
|
-
const setSigningCredentials = (cellId, credentials) => {
|
|
10147
|
-
const cellIdB64 = encodeHashToBase64(cellId[0]).concat(encodeHashToBase64(cellId[1]));
|
|
10148
|
-
signingCredentials.set(cellIdB64, credentials);
|
|
10149
|
-
};
|
|
10150
|
-
const generateSigningKeyPair = async (agentPubKey) => {
|
|
10151
|
-
await _sodium.ready;
|
|
10152
|
-
const sodium = _sodium;
|
|
10153
|
-
const keyPair = sodium.crypto_sign_keypair();
|
|
10154
|
-
const locationBytes = [0, 0, 0, 0];
|
|
10155
|
-
const signingKey = new Uint8Array([132, 32, 36].concat(...keyPair.publicKey).concat(...locationBytes));
|
|
10156
|
-
return [keyPair, signingKey];
|
|
10157
|
-
};
|
|
10158
|
-
const randomCapSecret = async () => randomByteArray(64);
|
|
10159
|
-
const randomNonce = async () => randomByteArray(32);
|
|
10160
|
-
const randomByteArray = async (length) => {
|
|
10161
|
-
if (globalThis.crypto && "getRandomValues" in globalThis.crypto) {
|
|
10162
|
-
return globalThis.crypto.getRandomValues(new Uint8Array(length));
|
|
10163
|
-
}
|
|
10164
|
-
await _sodium.ready;
|
|
10165
|
-
const sodium = _sodium;
|
|
10166
|
-
return sodium.randombytes_buf(length);
|
|
10167
|
-
};
|
|
10168
|
-
const getNonceExpiration = () => (Date.now() + 5 * 60 * 1e3) * 1e3;
|
|
10169
|
-
class AdminWebsocket {
|
|
10170
|
-
/**
|
|
10171
|
-
* The websocket client used for transporting requests and responses.
|
|
10172
|
-
*/
|
|
10173
|
-
client;
|
|
10174
|
-
/**
|
|
10175
|
-
* Default timeout for any request made over the websocket.
|
|
10176
|
-
*/
|
|
10177
|
-
defaultTimeout;
|
|
10178
|
-
constructor(client, defaultTimeout) {
|
|
10179
|
-
this.client = client;
|
|
10180
|
-
this.defaultTimeout = defaultTimeout === void 0 ? DEFAULT_TIMEOUT : defaultTimeout;
|
|
10181
|
-
}
|
|
10182
|
-
/**
|
|
10183
|
-
* Factory mehtod to create a new instance connected to the given URL.
|
|
10184
|
-
*
|
|
10185
|
-
* @param options - {@link (WebsocketConnectionOptions:interface)}
|
|
10186
|
-
* @returns A promise for a new connected instance.
|
|
10187
|
-
*/
|
|
10188
|
-
static async connect(options = {}) {
|
|
10189
|
-
const env = getLauncherEnvironment();
|
|
10190
|
-
if (env?.ADMIN_INTERFACE_PORT) {
|
|
10191
|
-
options.url = new URL(`ws://localhost:${env.ADMIN_INTERFACE_PORT}`);
|
|
10192
|
-
}
|
|
10193
|
-
if (!options.url) {
|
|
10194
|
-
throw new HolochainError("ConnectionUrlMissing", `unable to connect to Conductor API - no url provided and not in a launcher environment.`);
|
|
10195
|
-
}
|
|
10196
|
-
const wsClient = await WsClient.connect(options.url, options.wsClientOptions);
|
|
10197
|
-
return new AdminWebsocket(wsClient, options.defaultTimeout);
|
|
10198
|
-
}
|
|
10199
|
-
_requester(tag, transformer) {
|
|
10200
|
-
return requesterTransformer((req, timeout2) => promiseTimeout(this.client.request(req), tag, timeout2 || this.defaultTimeout).then(catchError), tag, transformer);
|
|
10201
|
-
}
|
|
10202
|
-
/**
|
|
10203
|
-
* Send a request to open the given port for {@link AppWebsocket} connections.
|
|
10204
|
-
*/
|
|
10205
|
-
attachAppInterface = this._requester("attach_app_interface");
|
|
10206
|
-
/**
|
|
10207
|
-
* Enable a stopped app.
|
|
10208
|
-
*/
|
|
10209
|
-
enableApp = this._requester("enable_app");
|
|
10210
|
-
/**
|
|
10211
|
-
* Disable a running app.
|
|
10212
|
-
*/
|
|
10213
|
-
disableApp = this._requester("disable_app");
|
|
10214
|
-
/**
|
|
10215
|
-
* Dump the state of the specified cell, including its source chain, as JSON.
|
|
10216
|
-
*/
|
|
10217
|
-
dumpState = this._requester("dump_state", dumpStateTransform);
|
|
10218
|
-
/**
|
|
10219
|
-
* Dump the full state of the specified cell, including its chain and DHT
|
|
10220
|
-
* shard, as JSON.
|
|
10221
|
-
*/
|
|
10222
|
-
dumpFullState = this._requester("dump_full_state");
|
|
10223
|
-
/**
|
|
10224
|
-
* Generate a new agent pub key.
|
|
10225
|
-
*/
|
|
10226
|
-
generateAgentPubKey = this._requester("generate_agent_pub_key");
|
|
10227
|
-
/**
|
|
10228
|
-
* Generate a new agent pub key.
|
|
10229
|
-
*/
|
|
10230
|
-
revokeAgentKey = this._requester("revoke_agent_key");
|
|
10231
|
-
/**
|
|
10232
|
-
* Register a DNA for later app installation.
|
|
10233
|
-
*
|
|
10234
|
-
* Stores the given DNA into the Holochain DNA database and returns the hash of it.
|
|
10235
|
-
*/
|
|
10236
|
-
registerDna = this._requester("register_dna");
|
|
10237
|
-
/**
|
|
10238
|
-
* Get the DNA definition for the specified DNA hash.
|
|
10239
|
-
*/
|
|
10240
|
-
getDnaDefinition = this._requester("get_dna_definition");
|
|
10241
|
-
/**
|
|
10242
|
-
* Uninstall the specified app from Holochain.
|
|
10243
|
-
*/
|
|
10244
|
-
uninstallApp = this._requester("uninstall_app");
|
|
10245
|
-
/**
|
|
10246
|
-
* Install the specified app into Holochain.
|
|
10247
|
-
*/
|
|
10248
|
-
installApp = this._requester("install_app");
|
|
10249
|
-
/**
|
|
10250
|
-
* Update coordinators for an installed app.
|
|
10251
|
-
*/
|
|
10252
|
-
updateCoordinators = this._requester("update_coordinators");
|
|
10253
|
-
/**
|
|
10254
|
-
* List all registered DNAs.
|
|
10255
|
-
*/
|
|
10256
|
-
listDnas = this._requester("list_dnas");
|
|
10257
|
-
/**
|
|
10258
|
-
* List all installed cell ids.
|
|
10259
|
-
*/
|
|
10260
|
-
listCellIds = this._requester("list_cell_ids");
|
|
10261
|
-
/**
|
|
10262
|
-
* List all installed apps.
|
|
10263
|
-
*/
|
|
10264
|
-
listApps = this._requester("list_apps");
|
|
10265
|
-
/**
|
|
10266
|
-
* List all attached app interfaces.
|
|
10267
|
-
*/
|
|
10268
|
-
listAppInterfaces = this._requester("list_app_interfaces");
|
|
10269
|
-
/**
|
|
10270
|
-
* Request all available info about an agent.
|
|
10271
|
-
*/
|
|
10272
|
-
agentInfo = this._requester("agent_info");
|
|
10273
|
-
/**
|
|
10274
|
-
* Add an existing agent to Holochain.
|
|
10275
|
-
*/
|
|
10276
|
-
addAgentInfo = this._requester("add_agent_info");
|
|
10277
|
-
/**
|
|
10278
|
-
* Delete a disabled clone cell.
|
|
10279
|
-
*/
|
|
10280
|
-
deleteCloneCell = this._requester("delete_clone_cell");
|
|
10281
|
-
/**
|
|
10282
|
-
* Grant a zome call capability for an agent, to be used for signing zome
|
|
10283
|
-
* calls.
|
|
10284
|
-
*/
|
|
10285
|
-
grantZomeCallCapability = this._requester("grant_zome_call_capability");
|
|
10286
|
-
storageInfo = this._requester("storage_info");
|
|
10287
|
-
issueAppAuthenticationToken = this._requester("issue_app_authentication_token");
|
|
10288
|
-
dumpNetworkStats = this._requester("dump_network_stats");
|
|
10289
|
-
dumpNetworkMetrics = this._requester("dump_network_metrics");
|
|
10290
|
-
// zome call signing related methods
|
|
10291
|
-
/**
|
|
10292
|
-
* Grant a capability for signing zome calls.
|
|
10293
|
-
*
|
|
10294
|
-
* @param cellId - The cell to grant the capability for.
|
|
10295
|
-
* @param functions - The zome functions to grant the capability for.
|
|
10296
|
-
* @param signingKey - The assignee of the capability.
|
|
10297
|
-
* @returns The cap secret of the created capability.
|
|
10298
|
-
*/
|
|
10299
|
-
grantSigningKey = async (cellId, functions, signingKey) => {
|
|
10300
|
-
const capSecret = await randomCapSecret();
|
|
10301
|
-
await this.grantZomeCallCapability({
|
|
10302
|
-
cell_id: cellId,
|
|
10303
|
-
cap_grant: {
|
|
10304
|
-
tag: "zome-call-signing-key",
|
|
10305
|
-
functions,
|
|
10306
|
-
access: {
|
|
10307
|
-
type: "assigned",
|
|
10308
|
-
value: {
|
|
10309
|
-
secret: capSecret,
|
|
10310
|
-
assignees: [signingKey]
|
|
10311
|
-
}
|
|
9634
|
+
function Pr(e3, a3, t2, _2) {
|
|
9635
|
+
var n2 = [];
|
|
9636
|
+
l(_2);
|
|
9637
|
+
var s2 = d(e3 = E(n2, e3, "input_message")), c2 = e3.length;
|
|
9638
|
+
n2.push(s2), a3 = E(n2, a3, "nonce");
|
|
9639
|
+
var h2, o2 = 0 | r2._crypto_stream_xchacha20_noncebytes();
|
|
9640
|
+
a3.length !== o2 && f(n2, "invalid nonce length"), h2 = d(a3), n2.push(h2), t2 = E(n2, t2, "key");
|
|
9641
|
+
var p2, i2 = 0 | r2._crypto_stream_xchacha20_keybytes();
|
|
9642
|
+
t2.length !== i2 && f(n2, "invalid key length"), p2 = d(t2), n2.push(p2);
|
|
9643
|
+
var v3 = new u(0 | c2), m3 = v3.address;
|
|
9644
|
+
if (n2.push(m3), 0 === r2._crypto_stream_xchacha20_xor(m3, s2, c2, 0, h2, p2)) {
|
|
9645
|
+
var x2 = y(v3, _2);
|
|
9646
|
+
return g(n2), x2;
|
|
9647
|
+
}
|
|
9648
|
+
b(n2, "invalid usage");
|
|
9649
|
+
}
|
|
9650
|
+
function Rr(e3, a3, t2, _2, n2) {
|
|
9651
|
+
var s2 = [];
|
|
9652
|
+
l(n2);
|
|
9653
|
+
var c2 = d(e3 = E(s2, e3, "input_message")), h2 = e3.length;
|
|
9654
|
+
s2.push(c2), a3 = E(s2, a3, "nonce");
|
|
9655
|
+
var o2, p2 = 0 | r2._crypto_stream_xchacha20_noncebytes();
|
|
9656
|
+
a3.length !== p2 && f(s2, "invalid nonce length"), o2 = d(a3), s2.push(o2), m2(s2, t2, "nonce_increment"), ("number" != typeof t2 || (0 | t2) !== t2 || t2 < 0) && f(s2, "nonce_increment must be an unsigned integer"), _2 = E(s2, _2, "key");
|
|
9657
|
+
var i2, v3 = 0 | r2._crypto_stream_xchacha20_keybytes();
|
|
9658
|
+
_2.length !== v3 && f(s2, "invalid key length"), i2 = d(_2), s2.push(i2);
|
|
9659
|
+
var x2 = new u(0 | h2), k2 = x2.address;
|
|
9660
|
+
if (s2.push(k2), 0 === r2._crypto_stream_xchacha20_xor_ic(k2, c2, h2, 0, o2, t2, 0, i2)) {
|
|
9661
|
+
var S2 = y(x2, n2);
|
|
9662
|
+
return g(s2), S2;
|
|
10312
9663
|
}
|
|
9664
|
+
b(s2, "invalid usage");
|
|
9665
|
+
}
|
|
9666
|
+
function Xr(e3, a3) {
|
|
9667
|
+
var t2 = [];
|
|
9668
|
+
l(a3), m2(t2, e3, "length"), ("number" != typeof e3 || (0 | e3) !== e3 || e3 < 0) && f(t2, "length must be an unsigned integer");
|
|
9669
|
+
var _2 = new u(0 | e3), n2 = _2.address;
|
|
9670
|
+
t2.push(n2), r2._randombytes_buf(n2, e3);
|
|
9671
|
+
var s2 = y(_2, a3);
|
|
9672
|
+
return g(t2), s2;
|
|
9673
|
+
}
|
|
9674
|
+
function Gr(e3, a3, t2) {
|
|
9675
|
+
var _2 = [];
|
|
9676
|
+
l(t2), m2(_2, e3, "length"), ("number" != typeof e3 || (0 | e3) !== e3 || e3 < 0) && f(_2, "length must be an unsigned integer"), a3 = E(_2, a3, "seed");
|
|
9677
|
+
var n2, s2 = 0 | r2._randombytes_seedbytes();
|
|
9678
|
+
a3.length !== s2 && f(_2, "invalid seed length"), n2 = d(a3), _2.push(n2);
|
|
9679
|
+
var c2 = new u(0 | e3), h2 = c2.address;
|
|
9680
|
+
_2.push(h2), r2._randombytes_buf_deterministic(h2, e3, n2);
|
|
9681
|
+
var o2 = y(c2, t2);
|
|
9682
|
+
return g(_2), o2;
|
|
9683
|
+
}
|
|
9684
|
+
function Dr(e3) {
|
|
9685
|
+
l(e3), r2._randombytes_close();
|
|
9686
|
+
}
|
|
9687
|
+
function Fr(e3) {
|
|
9688
|
+
l(e3);
|
|
9689
|
+
var a3 = r2._randombytes_random() >>> 0;
|
|
9690
|
+
return g([]), a3;
|
|
9691
|
+
}
|
|
9692
|
+
function Vr(e3, a3) {
|
|
9693
|
+
var t2 = [];
|
|
9694
|
+
l(a3);
|
|
9695
|
+
for (var _2 = r2._malloc(24), n2 = 0; n2 < 6; n2++) r2.setValue(_2 + 4 * n2, r2.Runtime.addFunction(e3[["implementation_name", "random", "stir", "uniform", "buf", "close"][n2]]), "i32");
|
|
9696
|
+
0 | r2._randombytes_set_implementation(_2) && b(t2, "unsupported implementation"), g(t2);
|
|
9697
|
+
}
|
|
9698
|
+
function Hr(e3) {
|
|
9699
|
+
l(e3), r2._randombytes_stir();
|
|
9700
|
+
}
|
|
9701
|
+
function Wr(e3, a3) {
|
|
9702
|
+
var t2 = [];
|
|
9703
|
+
l(a3), m2(t2, e3, "upper_bound"), ("number" != typeof e3 || (0 | e3) !== e3 || e3 < 0) && f(t2, "upper_bound must be an unsigned integer");
|
|
9704
|
+
var _2 = r2._randombytes_uniform(e3) >>> 0;
|
|
9705
|
+
return g(t2), _2;
|
|
9706
|
+
}
|
|
9707
|
+
function qr() {
|
|
9708
|
+
var e3 = r2._sodium_version_string(), a3 = r2.UTF8ToString(e3);
|
|
9709
|
+
return g([]), a3;
|
|
10313
9710
|
}
|
|
9711
|
+
return u.prototype.to_Uint8Array = function() {
|
|
9712
|
+
var e3 = new Uint8Array(this.length);
|
|
9713
|
+
return e3.set(r2.HEAPU8.subarray(this.address, this.address + this.length)), e3;
|
|
9714
|
+
}, e2.add = function(e3, a3) {
|
|
9715
|
+
if (!(e3 instanceof Uint8Array && a3 instanceof Uint8Array)) throw new TypeError("Only Uint8Array instances can added");
|
|
9716
|
+
var r3 = e3.length, t2 = 0, _2 = 0;
|
|
9717
|
+
if (a3.length != e3.length) throw new TypeError("Arguments must have the same length");
|
|
9718
|
+
for (_2 = 0; _2 < r3; _2++) t2 >>= 8, t2 += e3[_2] + a3[_2], e3[_2] = 255 & t2;
|
|
9719
|
+
}, e2.base64_variants = h, e2.compare = function(e3, a3) {
|
|
9720
|
+
if (!(e3 instanceof Uint8Array && a3 instanceof Uint8Array)) throw new TypeError("Only Uint8Array instances can be compared");
|
|
9721
|
+
if (e3.length !== a3.length) throw new TypeError("Only instances of identical length can be compared");
|
|
9722
|
+
for (var r3 = 0, t2 = 1, _2 = e3.length; _2-- > 0; ) r3 |= a3[_2] - e3[_2] >> 8 & t2, t2 &= (a3[_2] ^ e3[_2]) - 1 >> 8;
|
|
9723
|
+
return r3 + r3 + t2 - 1;
|
|
9724
|
+
}, e2.from_base64 = function(e3, a3) {
|
|
9725
|
+
a3 = o(a3);
|
|
9726
|
+
var t2, _2 = [], n2 = new u(3 * (e3 = E(_2, e3, "input")).length / 4), s2 = d(e3), c2 = v2(4), h2 = v2(4);
|
|
9727
|
+
return _2.push(s2), _2.push(n2.address), _2.push(n2.result_bin_len_p), _2.push(n2.b64_end_p), 0 !== r2._sodium_base642bin(n2.address, n2.length, s2, e3.length, 0, c2, h2, a3) && b(_2, "invalid input"), r2.getValue(h2, "i32") - s2 !== e3.length && b(_2, "incomplete input"), n2.length = r2.getValue(c2, "i32"), t2 = n2.to_Uint8Array(), g(_2), t2;
|
|
9728
|
+
}, e2.from_hex = function(e3) {
|
|
9729
|
+
var a3, t2 = [], _2 = new u((e3 = E(t2, e3, "input")).length / 2), n2 = d(e3), s2 = v2(4);
|
|
9730
|
+
return t2.push(n2), t2.push(_2.address), t2.push(_2.hex_end_p), 0 !== r2._sodium_hex2bin(_2.address, _2.length, n2, e3.length, 0, 0, s2) && b(t2, "invalid input"), r2.getValue(s2, "i32") - n2 !== e3.length && b(t2, "incomplete input"), a3 = _2.to_Uint8Array(), g(t2), a3;
|
|
9731
|
+
}, e2.from_string = n, e2.increment = function(e3) {
|
|
9732
|
+
if (!(e3 instanceof Uint8Array)) throw new TypeError("Only Uint8Array instances can be incremented");
|
|
9733
|
+
for (var a3 = 256, r3 = 0, t2 = e3.length; r3 < t2; r3++) a3 >>= 8, a3 += e3[r3], e3[r3] = 255 & a3;
|
|
9734
|
+
}, e2.is_zero = function(e3) {
|
|
9735
|
+
if (!(e3 instanceof Uint8Array)) throw new TypeError("Only Uint8Array instances can be checked");
|
|
9736
|
+
for (var a3 = 0, r3 = 0, t2 = e3.length; r3 < t2; r3++) a3 |= e3[r3];
|
|
9737
|
+
return 0 === a3;
|
|
9738
|
+
}, e2.libsodium = a2, e2.memcmp = function(e3, a3) {
|
|
9739
|
+
if (!(e3 instanceof Uint8Array && a3 instanceof Uint8Array)) throw new TypeError("Only Uint8Array instances can be compared");
|
|
9740
|
+
if (e3.length !== a3.length) throw new TypeError("Only instances of identical length can be compared");
|
|
9741
|
+
for (var r3 = 0, t2 = 0, _2 = e3.length; t2 < _2; t2++) r3 |= e3[t2] ^ a3[t2];
|
|
9742
|
+
return 0 === r3;
|
|
9743
|
+
}, e2.memzero = function(e3) {
|
|
9744
|
+
if (!(e3 instanceof Uint8Array)) throw new TypeError("Only Uint8Array instances can be wiped");
|
|
9745
|
+
for (var a3 = 0, r3 = e3.length; a3 < r3; a3++) e3[a3] = 0;
|
|
9746
|
+
}, e2.output_formats = function() {
|
|
9747
|
+
return ["uint8array", "text", "hex", "base64"];
|
|
9748
|
+
}, e2.pad = function(e3, a3) {
|
|
9749
|
+
if (!(e3 instanceof Uint8Array)) throw new TypeError("buffer must be a Uint8Array");
|
|
9750
|
+
if ((a3 |= 0) <= 0) throw new Error("block size must be > 0");
|
|
9751
|
+
var t2, _2 = [], n2 = v2(4), s2 = 1, c2 = 0, h2 = 0 | e3.length, o2 = new u(h2 + a3);
|
|
9752
|
+
_2.push(n2), _2.push(o2.address);
|
|
9753
|
+
for (var p2 = o2.address, y2 = o2.address + h2 + a3; p2 < y2; p2++) r2.HEAPU8[p2] = e3[c2], c2 += s2 = 1 & ~((65535 & ((h2 -= s2) >>> 48 | h2 >>> 32 | h2 >>> 16 | h2)) - 1 >> 16);
|
|
9754
|
+
return 0 !== r2._sodium_pad(n2, o2.address, e3.length, a3, o2.length) && b(_2, "internal error"), o2.length = r2.getValue(n2, "i32"), t2 = o2.to_Uint8Array(), g(_2), t2;
|
|
9755
|
+
}, e2.unpad = function(e3, a3) {
|
|
9756
|
+
if (!(e3 instanceof Uint8Array)) throw new TypeError("buffer must be a Uint8Array");
|
|
9757
|
+
if ((a3 |= 0) <= 0) throw new Error("block size must be > 0");
|
|
9758
|
+
var t2 = [], _2 = d(e3), n2 = v2(4);
|
|
9759
|
+
return t2.push(_2), t2.push(n2), 0 !== r2._sodium_unpad(n2, _2, e3.length, a3) && b(t2, "unsupported/invalid padding"), e3 = (e3 = new Uint8Array(e3)).subarray(0, r2.getValue(n2, "i32")), g(t2), e3;
|
|
9760
|
+
}, e2.ready = _, e2.symbols = function() {
|
|
9761
|
+
return Object.keys(e2).sort();
|
|
9762
|
+
}, e2.to_base64 = p, e2.to_hex = c, e2.to_string = s, e2;
|
|
9763
|
+
}
|
|
9764
|
+
var r = "object" == typeof e.sodium && "function" == typeof e.sodium.onload ? e.sodium.onload : null;
|
|
9765
|
+
"string" != typeof exports2.nodeName ? a(exports2, requireLibsodium()) : e.sodium = a(e.commonJsStrict = {}, e.libsodium), r && e.sodium.ready.then(function() {
|
|
9766
|
+
r(e.sodium);
|
|
10314
9767
|
});
|
|
10315
|
-
|
|
10316
|
-
|
|
10317
|
-
|
|
10318
|
-
* Generate and authorize a new key pair for signing zome calls.
|
|
10319
|
-
*
|
|
10320
|
-
* @param cellId - The cell id to create the capability grant for.
|
|
10321
|
-
* @param functions - Zomes and functions to authorize the signing key for
|
|
10322
|
-
* (optional). When no functions are specified, the capability will be
|
|
10323
|
-
* granted for all zomes and functions.
|
|
10324
|
-
*/
|
|
10325
|
-
authorizeSigningCredentials = async (cellId, functions) => {
|
|
10326
|
-
const [keyPair, signingKey] = await generateSigningKeyPair();
|
|
10327
|
-
const capSecret = await this.grantSigningKey(cellId, functions || { type: "all" }, signingKey);
|
|
10328
|
-
setSigningCredentials(cellId, { capSecret, keyPair, signingKey });
|
|
10329
|
-
};
|
|
10330
|
-
}
|
|
10331
|
-
const dumpStateTransform = {
|
|
10332
|
-
input: (req) => req,
|
|
10333
|
-
output: (res) => {
|
|
10334
|
-
return JSON.parse(res);
|
|
10335
|
-
}
|
|
10336
|
-
};
|
|
10337
|
-
var CountersigningSessionStateType;
|
|
10338
|
-
(function(CountersigningSessionStateType2) {
|
|
10339
|
-
CountersigningSessionStateType2["Accepted"] = "Accepted";
|
|
10340
|
-
CountersigningSessionStateType2["SignaturesCollected"] = "SignaturesCollected";
|
|
10341
|
-
CountersigningSessionStateType2["Unknown"] = "Unknown";
|
|
10342
|
-
})(CountersigningSessionStateType || (CountersigningSessionStateType = {}));
|
|
10343
|
-
var ResolutionRequiredReason;
|
|
10344
|
-
(function(ResolutionRequiredReason2) {
|
|
10345
|
-
ResolutionRequiredReason2["Timeout"] = "Timeout";
|
|
10346
|
-
ResolutionRequiredReason2["Unknown"] = "Unknown";
|
|
10347
|
-
})(ResolutionRequiredReason || (ResolutionRequiredReason = {}));
|
|
10348
|
-
var SessionCompletionDecisionType;
|
|
10349
|
-
(function(SessionCompletionDecisionType2) {
|
|
10350
|
-
SessionCompletionDecisionType2["Complete"] = "Complete";
|
|
10351
|
-
SessionCompletionDecisionType2["Abandoned"] = "Abandoned";
|
|
10352
|
-
SessionCompletionDecisionType2["Indeterminate"] = "Indeterminate";
|
|
10353
|
-
SessionCompletionDecisionType2["Failed"] = "Failed";
|
|
10354
|
-
})(SessionCompletionDecisionType || (SessionCompletionDecisionType = {}));
|
|
9768
|
+
}(commonjsGlobal);
|
|
9769
|
+
})(libsodiumWrappers);
|
|
9770
|
+
const _sodium = /* @__PURE__ */ getDefaultExportFromCjs(libsodiumWrappers);
|
|
10355
9771
|
var freeGlobal = typeof global == "object" && global && global.Object === Object && global;
|
|
10356
9772
|
var freeSelf = typeof self == "object" && self && self.Object === Object && self;
|
|
10357
9773
|
var root = freeGlobal || freeSelf || Function("return this")();
|
|
@@ -11295,22 +10711,206 @@ var omit = flatRest(function(object, paths) {
|
|
|
11295
10711
|
if (object == null) {
|
|
11296
10712
|
return result;
|
|
11297
10713
|
}
|
|
11298
|
-
var isDeep = false;
|
|
11299
|
-
paths = arrayMap(paths, function(path2) {
|
|
11300
|
-
path2 = castPath(path2, object);
|
|
11301
|
-
isDeep || (isDeep = path2.length > 1);
|
|
11302
|
-
return path2;
|
|
10714
|
+
var isDeep = false;
|
|
10715
|
+
paths = arrayMap(paths, function(path2) {
|
|
10716
|
+
path2 = castPath(path2, object);
|
|
10717
|
+
isDeep || (isDeep = path2.length > 1);
|
|
10718
|
+
return path2;
|
|
10719
|
+
});
|
|
10720
|
+
copyObject(object, getAllKeysIn(object), result);
|
|
10721
|
+
if (isDeep) {
|
|
10722
|
+
result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
|
|
10723
|
+
}
|
|
10724
|
+
var length = paths.length;
|
|
10725
|
+
while (length--) {
|
|
10726
|
+
baseUnset(result, paths[length]);
|
|
10727
|
+
}
|
|
10728
|
+
return result;
|
|
10729
|
+
});
|
|
10730
|
+
const version = "3.7.7";
|
|
10731
|
+
const VERSION = version;
|
|
10732
|
+
const _hasBuffer = typeof Buffer === "function";
|
|
10733
|
+
const _TD = typeof TextDecoder === "function" ? new TextDecoder() : void 0;
|
|
10734
|
+
const _TE = typeof TextEncoder === "function" ? new TextEncoder() : void 0;
|
|
10735
|
+
const b64ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
|
10736
|
+
const b64chs = Array.prototype.slice.call(b64ch);
|
|
10737
|
+
const b64tab = ((a) => {
|
|
10738
|
+
let tab = {};
|
|
10739
|
+
a.forEach((c, i) => tab[c] = i);
|
|
10740
|
+
return tab;
|
|
10741
|
+
})(b64chs);
|
|
10742
|
+
const b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
|
|
10743
|
+
const _fromCC = String.fromCharCode.bind(String);
|
|
10744
|
+
const _U8Afrom = typeof Uint8Array.from === "function" ? Uint8Array.from.bind(Uint8Array) : (it) => new Uint8Array(Array.prototype.slice.call(it, 0));
|
|
10745
|
+
const _mkUriSafe = (src) => src.replace(/=/g, "").replace(/[+\/]/g, (m0) => m0 == "+" ? "-" : "_");
|
|
10746
|
+
const _tidyB64 = (s) => s.replace(/[^A-Za-z0-9\+\/]/g, "");
|
|
10747
|
+
const btoaPolyfill = (bin) => {
|
|
10748
|
+
let u32, c0, c1, c2, asc = "";
|
|
10749
|
+
const pad = bin.length % 3;
|
|
10750
|
+
for (let i = 0; i < bin.length; ) {
|
|
10751
|
+
if ((c0 = bin.charCodeAt(i++)) > 255 || (c1 = bin.charCodeAt(i++)) > 255 || (c2 = bin.charCodeAt(i++)) > 255)
|
|
10752
|
+
throw new TypeError("invalid character found");
|
|
10753
|
+
u32 = c0 << 16 | c1 << 8 | c2;
|
|
10754
|
+
asc += b64chs[u32 >> 18 & 63] + b64chs[u32 >> 12 & 63] + b64chs[u32 >> 6 & 63] + b64chs[u32 & 63];
|
|
10755
|
+
}
|
|
10756
|
+
return pad ? asc.slice(0, pad - 3) + "===".substring(pad) : asc;
|
|
10757
|
+
};
|
|
10758
|
+
const _btoa = typeof btoa === "function" ? (bin) => btoa(bin) : _hasBuffer ? (bin) => Buffer.from(bin, "binary").toString("base64") : btoaPolyfill;
|
|
10759
|
+
const _fromUint8Array = _hasBuffer ? (u8a) => Buffer.from(u8a).toString("base64") : (u8a) => {
|
|
10760
|
+
const maxargs = 4096;
|
|
10761
|
+
let strs = [];
|
|
10762
|
+
for (let i = 0, l = u8a.length; i < l; i += maxargs) {
|
|
10763
|
+
strs.push(_fromCC.apply(null, u8a.subarray(i, i + maxargs)));
|
|
10764
|
+
}
|
|
10765
|
+
return _btoa(strs.join(""));
|
|
10766
|
+
};
|
|
10767
|
+
const fromUint8Array = (u8a, urlsafe = false) => urlsafe ? _mkUriSafe(_fromUint8Array(u8a)) : _fromUint8Array(u8a);
|
|
10768
|
+
const cb_utob = (c) => {
|
|
10769
|
+
if (c.length < 2) {
|
|
10770
|
+
var cc = c.charCodeAt(0);
|
|
10771
|
+
return cc < 128 ? c : cc < 2048 ? _fromCC(192 | cc >>> 6) + _fromCC(128 | cc & 63) : _fromCC(224 | cc >>> 12 & 15) + _fromCC(128 | cc >>> 6 & 63) + _fromCC(128 | cc & 63);
|
|
10772
|
+
} else {
|
|
10773
|
+
var cc = 65536 + (c.charCodeAt(0) - 55296) * 1024 + (c.charCodeAt(1) - 56320);
|
|
10774
|
+
return _fromCC(240 | cc >>> 18 & 7) + _fromCC(128 | cc >>> 12 & 63) + _fromCC(128 | cc >>> 6 & 63) + _fromCC(128 | cc & 63);
|
|
10775
|
+
}
|
|
10776
|
+
};
|
|
10777
|
+
const re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;
|
|
10778
|
+
const utob = (u) => u.replace(re_utob, cb_utob);
|
|
10779
|
+
const _encode = _hasBuffer ? (s) => Buffer.from(s, "utf8").toString("base64") : _TE ? (s) => _fromUint8Array(_TE.encode(s)) : (s) => _btoa(utob(s));
|
|
10780
|
+
const encode = (src, urlsafe = false) => urlsafe ? _mkUriSafe(_encode(src)) : _encode(src);
|
|
10781
|
+
const encodeURI = (src) => encode(src, true);
|
|
10782
|
+
const re_btou = /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g;
|
|
10783
|
+
const cb_btou = (cccc) => {
|
|
10784
|
+
switch (cccc.length) {
|
|
10785
|
+
case 4:
|
|
10786
|
+
var cp = (7 & cccc.charCodeAt(0)) << 18 | (63 & cccc.charCodeAt(1)) << 12 | (63 & cccc.charCodeAt(2)) << 6 | 63 & cccc.charCodeAt(3), offset = cp - 65536;
|
|
10787
|
+
return _fromCC((offset >>> 10) + 55296) + _fromCC((offset & 1023) + 56320);
|
|
10788
|
+
case 3:
|
|
10789
|
+
return _fromCC((15 & cccc.charCodeAt(0)) << 12 | (63 & cccc.charCodeAt(1)) << 6 | 63 & cccc.charCodeAt(2));
|
|
10790
|
+
default:
|
|
10791
|
+
return _fromCC((31 & cccc.charCodeAt(0)) << 6 | 63 & cccc.charCodeAt(1));
|
|
10792
|
+
}
|
|
10793
|
+
};
|
|
10794
|
+
const btou = (b) => b.replace(re_btou, cb_btou);
|
|
10795
|
+
const atobPolyfill = (asc) => {
|
|
10796
|
+
asc = asc.replace(/\s+/g, "");
|
|
10797
|
+
if (!b64re.test(asc))
|
|
10798
|
+
throw new TypeError("malformed base64.");
|
|
10799
|
+
asc += "==".slice(2 - (asc.length & 3));
|
|
10800
|
+
let u24, bin = "", r1, r2;
|
|
10801
|
+
for (let i = 0; i < asc.length; ) {
|
|
10802
|
+
u24 = b64tab[asc.charAt(i++)] << 18 | b64tab[asc.charAt(i++)] << 12 | (r1 = b64tab[asc.charAt(i++)]) << 6 | (r2 = b64tab[asc.charAt(i++)]);
|
|
10803
|
+
bin += r1 === 64 ? _fromCC(u24 >> 16 & 255) : r2 === 64 ? _fromCC(u24 >> 16 & 255, u24 >> 8 & 255) : _fromCC(u24 >> 16 & 255, u24 >> 8 & 255, u24 & 255);
|
|
10804
|
+
}
|
|
10805
|
+
return bin;
|
|
10806
|
+
};
|
|
10807
|
+
const _atob = typeof atob === "function" ? (asc) => atob(_tidyB64(asc)) : _hasBuffer ? (asc) => Buffer.from(asc, "base64").toString("binary") : atobPolyfill;
|
|
10808
|
+
const _toUint8Array = _hasBuffer ? (a) => _U8Afrom(Buffer.from(a, "base64")) : (a) => _U8Afrom(_atob(a).split("").map((c) => c.charCodeAt(0)));
|
|
10809
|
+
const toUint8Array$1 = (a) => _toUint8Array(_unURI(a));
|
|
10810
|
+
const _decode = _hasBuffer ? (a) => Buffer.from(a, "base64").toString("utf8") : _TD ? (a) => _TD.decode(_toUint8Array(a)) : (a) => btou(_atob(a));
|
|
10811
|
+
const _unURI = (a) => _tidyB64(a.replace(/[-_]/g, (m0) => m0 == "-" ? "+" : "/"));
|
|
10812
|
+
const decode = (src) => _decode(_unURI(src));
|
|
10813
|
+
const isValid = (src) => {
|
|
10814
|
+
if (typeof src !== "string")
|
|
10815
|
+
return false;
|
|
10816
|
+
const s = src.replace(/\s+/g, "").replace(/={0,2}$/, "");
|
|
10817
|
+
return !/[^\s0-9a-zA-Z\+/]/.test(s) || !/[^\s0-9a-zA-Z\-_]/.test(s);
|
|
10818
|
+
};
|
|
10819
|
+
const _noEnum = (v2) => {
|
|
10820
|
+
return {
|
|
10821
|
+
value: v2,
|
|
10822
|
+
enumerable: false,
|
|
10823
|
+
writable: true,
|
|
10824
|
+
configurable: true
|
|
10825
|
+
};
|
|
10826
|
+
};
|
|
10827
|
+
const extendString = function() {
|
|
10828
|
+
const _add = (name, body) => Object.defineProperty(String.prototype, name, _noEnum(body));
|
|
10829
|
+
_add("fromBase64", function() {
|
|
10830
|
+
return decode(this);
|
|
11303
10831
|
});
|
|
11304
|
-
|
|
11305
|
-
|
|
11306
|
-
|
|
11307
|
-
|
|
11308
|
-
|
|
11309
|
-
|
|
11310
|
-
|
|
10832
|
+
_add("toBase64", function(urlsafe) {
|
|
10833
|
+
return encode(this, urlsafe);
|
|
10834
|
+
});
|
|
10835
|
+
_add("toBase64URI", function() {
|
|
10836
|
+
return encode(this, true);
|
|
10837
|
+
});
|
|
10838
|
+
_add("toBase64URL", function() {
|
|
10839
|
+
return encode(this, true);
|
|
10840
|
+
});
|
|
10841
|
+
_add("toUint8Array", function() {
|
|
10842
|
+
return toUint8Array$1(this);
|
|
10843
|
+
});
|
|
10844
|
+
};
|
|
10845
|
+
const extendUint8Array = function() {
|
|
10846
|
+
const _add = (name, body) => Object.defineProperty(Uint8Array.prototype, name, _noEnum(body));
|
|
10847
|
+
_add("toBase64", function(urlsafe) {
|
|
10848
|
+
return fromUint8Array(this, urlsafe);
|
|
10849
|
+
});
|
|
10850
|
+
_add("toBase64URI", function() {
|
|
10851
|
+
return fromUint8Array(this, true);
|
|
10852
|
+
});
|
|
10853
|
+
_add("toBase64URL", function() {
|
|
10854
|
+
return fromUint8Array(this, true);
|
|
10855
|
+
});
|
|
10856
|
+
};
|
|
10857
|
+
const extendBuiltins = () => {
|
|
10858
|
+
extendString();
|
|
10859
|
+
extendUint8Array();
|
|
10860
|
+
};
|
|
10861
|
+
const gBase64 = {
|
|
10862
|
+
version,
|
|
10863
|
+
VERSION,
|
|
10864
|
+
atob: _atob,
|
|
10865
|
+
atobPolyfill,
|
|
10866
|
+
btoa: _btoa,
|
|
10867
|
+
btoaPolyfill,
|
|
10868
|
+
fromBase64: decode,
|
|
10869
|
+
toBase64: encode,
|
|
10870
|
+
encode,
|
|
10871
|
+
encodeURI,
|
|
10872
|
+
encodeURL: encodeURI,
|
|
10873
|
+
utob,
|
|
10874
|
+
btou,
|
|
10875
|
+
decode,
|
|
10876
|
+
isValid,
|
|
10877
|
+
fromUint8Array,
|
|
10878
|
+
toUint8Array: toUint8Array$1,
|
|
10879
|
+
extendString,
|
|
10880
|
+
extendUint8Array,
|
|
10881
|
+
extendBuiltins
|
|
10882
|
+
};
|
|
10883
|
+
function encodeHashToBase64(hash) {
|
|
10884
|
+
return `u${gBase64.fromUint8Array(hash, true)}`;
|
|
10885
|
+
}
|
|
10886
|
+
const signingCredentials = /* @__PURE__ */ new Map();
|
|
10887
|
+
const getSigningCredentials = (cellId) => {
|
|
10888
|
+
const cellIdB64 = encodeHashToBase64(cellId[0]).concat(encodeHashToBase64(cellId[1]));
|
|
10889
|
+
return signingCredentials.get(cellIdB64);
|
|
10890
|
+
};
|
|
10891
|
+
const setSigningCredentials = (cellId, credentials) => {
|
|
10892
|
+
const cellIdB64 = encodeHashToBase64(cellId[0]).concat(encodeHashToBase64(cellId[1]));
|
|
10893
|
+
signingCredentials.set(cellIdB64, credentials);
|
|
10894
|
+
};
|
|
10895
|
+
const generateSigningKeyPair = async (agentPubKey) => {
|
|
10896
|
+
await _sodium.ready;
|
|
10897
|
+
const sodium = _sodium;
|
|
10898
|
+
const keyPair = sodium.crypto_sign_keypair();
|
|
10899
|
+
const locationBytes = [0, 0, 0, 0];
|
|
10900
|
+
const signingKey = new Uint8Array([132, 32, 36].concat(...keyPair.publicKey).concat(...locationBytes));
|
|
10901
|
+
return [keyPair, signingKey];
|
|
10902
|
+
};
|
|
10903
|
+
const randomCapSecret = async () => randomByteArray(64);
|
|
10904
|
+
const randomNonce = async () => randomByteArray(32);
|
|
10905
|
+
const randomByteArray = async (length) => {
|
|
10906
|
+
if (globalThis.crypto && "getRandomValues" in globalThis.crypto) {
|
|
10907
|
+
return globalThis.crypto.getRandomValues(new Uint8Array(length));
|
|
11311
10908
|
}
|
|
11312
|
-
|
|
11313
|
-
|
|
10909
|
+
await _sodium.ready;
|
|
10910
|
+
const sodium = _sodium;
|
|
10911
|
+
return sodium.randombytes_buf(length);
|
|
10912
|
+
};
|
|
10913
|
+
const getNonceExpiration = () => (Date.now() + 5 * 60 * 1e3) * 1e3;
|
|
11314
10914
|
var blake2b$1 = { exports: {} };
|
|
11315
10915
|
var nanoassert$1 = assert$3;
|
|
11316
10916
|
class AssertionError extends Error {
|
|
@@ -11789,572 +11389,980 @@ function blake2bCompress(ctx, last2) {
|
|
|
11789
11389
|
v[i] = ctx.h[i];
|
|
11790
11390
|
v[i + 16] = BLAKE2B_IV32[i];
|
|
11791
11391
|
}
|
|
11792
|
-
v[24] = v[24] ^ ctx.t;
|
|
11793
|
-
v[25] = v[25] ^ ctx.t / 4294967296;
|
|
11794
|
-
if (last2) {
|
|
11795
|
-
v[28] = ~v[28];
|
|
11796
|
-
v[29] = ~v[29];
|
|
11392
|
+
v[24] = v[24] ^ ctx.t;
|
|
11393
|
+
v[25] = v[25] ^ ctx.t / 4294967296;
|
|
11394
|
+
if (last2) {
|
|
11395
|
+
v[28] = ~v[28];
|
|
11396
|
+
v[29] = ~v[29];
|
|
11397
|
+
}
|
|
11398
|
+
for (i = 0; i < 32; i++) {
|
|
11399
|
+
m[i] = B2B_GET32(ctx.b, 4 * i);
|
|
11400
|
+
}
|
|
11401
|
+
for (i = 0; i < 12; i++) {
|
|
11402
|
+
B2B_G(0, 8, 16, 24, SIGMA82[i * 16 + 0], SIGMA82[i * 16 + 1]);
|
|
11403
|
+
B2B_G(2, 10, 18, 26, SIGMA82[i * 16 + 2], SIGMA82[i * 16 + 3]);
|
|
11404
|
+
B2B_G(4, 12, 20, 28, SIGMA82[i * 16 + 4], SIGMA82[i * 16 + 5]);
|
|
11405
|
+
B2B_G(6, 14, 22, 30, SIGMA82[i * 16 + 6], SIGMA82[i * 16 + 7]);
|
|
11406
|
+
B2B_G(0, 10, 20, 30, SIGMA82[i * 16 + 8], SIGMA82[i * 16 + 9]);
|
|
11407
|
+
B2B_G(2, 12, 22, 24, SIGMA82[i * 16 + 10], SIGMA82[i * 16 + 11]);
|
|
11408
|
+
B2B_G(4, 14, 16, 26, SIGMA82[i * 16 + 12], SIGMA82[i * 16 + 13]);
|
|
11409
|
+
B2B_G(6, 8, 18, 28, SIGMA82[i * 16 + 14], SIGMA82[i * 16 + 15]);
|
|
11410
|
+
}
|
|
11411
|
+
for (i = 0; i < 16; i++) {
|
|
11412
|
+
ctx.h[i] = ctx.h[i] ^ v[i] ^ v[i + 16];
|
|
11413
|
+
}
|
|
11414
|
+
}
|
|
11415
|
+
const parameter_block = new Uint8Array([
|
|
11416
|
+
0,
|
|
11417
|
+
0,
|
|
11418
|
+
0,
|
|
11419
|
+
0,
|
|
11420
|
+
// 0: outlen, keylen, fanout, depth
|
|
11421
|
+
0,
|
|
11422
|
+
0,
|
|
11423
|
+
0,
|
|
11424
|
+
0,
|
|
11425
|
+
// 4: leaf length, sequential mode
|
|
11426
|
+
0,
|
|
11427
|
+
0,
|
|
11428
|
+
0,
|
|
11429
|
+
0,
|
|
11430
|
+
// 8: node offset
|
|
11431
|
+
0,
|
|
11432
|
+
0,
|
|
11433
|
+
0,
|
|
11434
|
+
0,
|
|
11435
|
+
// 12: node offset
|
|
11436
|
+
0,
|
|
11437
|
+
0,
|
|
11438
|
+
0,
|
|
11439
|
+
0,
|
|
11440
|
+
// 16: node depth, inner length, rfu
|
|
11441
|
+
0,
|
|
11442
|
+
0,
|
|
11443
|
+
0,
|
|
11444
|
+
0,
|
|
11445
|
+
// 20: rfu
|
|
11446
|
+
0,
|
|
11447
|
+
0,
|
|
11448
|
+
0,
|
|
11449
|
+
0,
|
|
11450
|
+
// 24: rfu
|
|
11451
|
+
0,
|
|
11452
|
+
0,
|
|
11453
|
+
0,
|
|
11454
|
+
0,
|
|
11455
|
+
// 28: rfu
|
|
11456
|
+
0,
|
|
11457
|
+
0,
|
|
11458
|
+
0,
|
|
11459
|
+
0,
|
|
11460
|
+
// 32: salt
|
|
11461
|
+
0,
|
|
11462
|
+
0,
|
|
11463
|
+
0,
|
|
11464
|
+
0,
|
|
11465
|
+
// 36: salt
|
|
11466
|
+
0,
|
|
11467
|
+
0,
|
|
11468
|
+
0,
|
|
11469
|
+
0,
|
|
11470
|
+
// 40: salt
|
|
11471
|
+
0,
|
|
11472
|
+
0,
|
|
11473
|
+
0,
|
|
11474
|
+
0,
|
|
11475
|
+
// 44: salt
|
|
11476
|
+
0,
|
|
11477
|
+
0,
|
|
11478
|
+
0,
|
|
11479
|
+
0,
|
|
11480
|
+
// 48: personal
|
|
11481
|
+
0,
|
|
11482
|
+
0,
|
|
11483
|
+
0,
|
|
11484
|
+
0,
|
|
11485
|
+
// 52: personal
|
|
11486
|
+
0,
|
|
11487
|
+
0,
|
|
11488
|
+
0,
|
|
11489
|
+
0,
|
|
11490
|
+
// 56: personal
|
|
11491
|
+
0,
|
|
11492
|
+
0,
|
|
11493
|
+
0,
|
|
11494
|
+
0
|
|
11495
|
+
// 60: personal
|
|
11496
|
+
]);
|
|
11497
|
+
function Blake2b(outlen, key, salt, personal) {
|
|
11498
|
+
parameter_block.fill(0);
|
|
11499
|
+
this.b = new Uint8Array(128);
|
|
11500
|
+
this.h = new Uint32Array(16);
|
|
11501
|
+
this.t = 0;
|
|
11502
|
+
this.c = 0;
|
|
11503
|
+
this.outlen = outlen;
|
|
11504
|
+
parameter_block[0] = outlen;
|
|
11505
|
+
if (key) parameter_block[1] = key.length;
|
|
11506
|
+
parameter_block[2] = 1;
|
|
11507
|
+
parameter_block[3] = 1;
|
|
11508
|
+
if (salt) parameter_block.set(salt, 32);
|
|
11509
|
+
if (personal) parameter_block.set(personal, 48);
|
|
11510
|
+
for (let i = 0; i < 16; i++) {
|
|
11511
|
+
this.h[i] = BLAKE2B_IV32[i] ^ B2B_GET32(parameter_block, i * 4);
|
|
11512
|
+
}
|
|
11513
|
+
if (key) {
|
|
11514
|
+
blake2bUpdate(this, key);
|
|
11515
|
+
this.c = 128;
|
|
11516
|
+
}
|
|
11517
|
+
}
|
|
11518
|
+
Blake2b.prototype.update = function(input) {
|
|
11519
|
+
assert(input instanceof Uint8Array, "input must be Uint8Array or Buffer");
|
|
11520
|
+
blake2bUpdate(this, input);
|
|
11521
|
+
return this;
|
|
11522
|
+
};
|
|
11523
|
+
Blake2b.prototype.digest = function(out) {
|
|
11524
|
+
const buf = !out || out === "binary" || out === "hex" ? new Uint8Array(this.outlen) : out;
|
|
11525
|
+
assert(buf instanceof Uint8Array, 'out must be "binary", "hex", Uint8Array, or Buffer');
|
|
11526
|
+
assert(buf.length >= this.outlen, "out must have at least outlen bytes of space");
|
|
11527
|
+
blake2bFinal(this, buf);
|
|
11528
|
+
if (out === "hex") return hexSlice(buf);
|
|
11529
|
+
return buf;
|
|
11530
|
+
};
|
|
11531
|
+
Blake2b.prototype.final = Blake2b.prototype.digest;
|
|
11532
|
+
Blake2b.ready = function(cb) {
|
|
11533
|
+
b2wasm.ready(function() {
|
|
11534
|
+
cb();
|
|
11535
|
+
});
|
|
11536
|
+
};
|
|
11537
|
+
function blake2bUpdate(ctx, input) {
|
|
11538
|
+
for (let i = 0; i < input.length; i++) {
|
|
11539
|
+
if (ctx.c === 128) {
|
|
11540
|
+
ctx.t += ctx.c;
|
|
11541
|
+
blake2bCompress(ctx, false);
|
|
11542
|
+
ctx.c = 0;
|
|
11543
|
+
}
|
|
11544
|
+
ctx.b[ctx.c++] = input[i];
|
|
11545
|
+
}
|
|
11546
|
+
}
|
|
11547
|
+
function blake2bFinal(ctx, out) {
|
|
11548
|
+
ctx.t += ctx.c;
|
|
11549
|
+
while (ctx.c < 128) {
|
|
11550
|
+
ctx.b[ctx.c++] = 0;
|
|
11551
|
+
}
|
|
11552
|
+
blake2bCompress(ctx, true);
|
|
11553
|
+
for (let i = 0; i < ctx.outlen; i++) {
|
|
11554
|
+
out[i] = ctx.h[i >> 2] >> 8 * (i & 3);
|
|
11555
|
+
}
|
|
11556
|
+
return out;
|
|
11557
|
+
}
|
|
11558
|
+
function hexSlice(buf) {
|
|
11559
|
+
let str = "";
|
|
11560
|
+
for (let i = 0; i < buf.length; i++) str += toHex(buf[i]);
|
|
11561
|
+
return str;
|
|
11562
|
+
}
|
|
11563
|
+
function toHex(n) {
|
|
11564
|
+
if (n < 16) return "0" + n.toString(16);
|
|
11565
|
+
return n.toString(16);
|
|
11566
|
+
}
|
|
11567
|
+
const Proto = Blake2b;
|
|
11568
|
+
blake2b$1.exports = function createHash2(outlen, key, salt, personal, noAssert) {
|
|
11569
|
+
if (noAssert !== true) {
|
|
11570
|
+
assert(outlen >= BYTES_MIN, "outlen must be at least " + BYTES_MIN + ", was given " + outlen);
|
|
11571
|
+
assert(outlen <= BYTES_MAX, "outlen must be at most " + BYTES_MAX + ", was given " + outlen);
|
|
11572
|
+
if (key != null) {
|
|
11573
|
+
assert(key instanceof Uint8Array, "key must be Uint8Array or Buffer");
|
|
11574
|
+
assert(key.length >= KEYBYTES_MIN, "key must be at least " + KEYBYTES_MIN + ", was given " + key.length);
|
|
11575
|
+
assert(key.length <= KEYBYTES_MAX, "key must be at most " + KEYBYTES_MAX + ", was given " + key.length);
|
|
11576
|
+
}
|
|
11577
|
+
if (salt != null) {
|
|
11578
|
+
assert(salt instanceof Uint8Array, "salt must be Uint8Array or Buffer");
|
|
11579
|
+
assert(salt.length === SALTBYTES, "salt must be exactly " + SALTBYTES + ", was given " + salt.length);
|
|
11580
|
+
}
|
|
11581
|
+
if (personal != null) {
|
|
11582
|
+
assert(personal instanceof Uint8Array, "personal must be Uint8Array or Buffer");
|
|
11583
|
+
assert(
|
|
11584
|
+
personal.length === PERSONALBYTES,
|
|
11585
|
+
"personal must be exactly " + PERSONALBYTES + ", was given " + personal.length
|
|
11586
|
+
);
|
|
11587
|
+
}
|
|
11588
|
+
}
|
|
11589
|
+
return new Proto(outlen, key, salt, personal);
|
|
11590
|
+
};
|
|
11591
|
+
blake2b$1.exports.ready = function(cb) {
|
|
11592
|
+
b2wasm.ready(function() {
|
|
11593
|
+
cb();
|
|
11594
|
+
});
|
|
11595
|
+
};
|
|
11596
|
+
blake2b$1.exports.WASM_SUPPORTED = b2wasm.SUPPORTED;
|
|
11597
|
+
blake2b$1.exports.WASM_LOADED = false;
|
|
11598
|
+
b2wasm.ready(function(err) {
|
|
11599
|
+
if (!err) {
|
|
11600
|
+
blake2b$1.exports.WASM_LOADED = true;
|
|
11601
|
+
blake2b$1.exports = b2wasm;
|
|
11602
|
+
}
|
|
11603
|
+
});
|
|
11604
|
+
({
|
|
11605
|
+
Agent: Uint8Array.from([132, 32, 36]),
|
|
11606
|
+
Entry: Uint8Array.from([132, 33, 36]),
|
|
11607
|
+
Dna: Uint8Array.from([132, 45, 36]),
|
|
11608
|
+
Action: Uint8Array.from([132, 41, 36]),
|
|
11609
|
+
External: Uint8Array.from([132, 47, 36])
|
|
11610
|
+
});
|
|
11611
|
+
class AppWebsocket {
|
|
11612
|
+
client;
|
|
11613
|
+
myPubKey;
|
|
11614
|
+
installedAppId;
|
|
11615
|
+
defaultTimeout;
|
|
11616
|
+
emitter;
|
|
11617
|
+
callZomeTransform;
|
|
11618
|
+
cachedAppInfo;
|
|
11619
|
+
appInfoRequester;
|
|
11620
|
+
callZomeRequester;
|
|
11621
|
+
provideMemproofRequester;
|
|
11622
|
+
enableAppRequester;
|
|
11623
|
+
createCloneCellRequester;
|
|
11624
|
+
enableCloneCellRequester;
|
|
11625
|
+
disableCloneCellRequester;
|
|
11626
|
+
dumpNetworkStatsRequester;
|
|
11627
|
+
dumpNetworkMetricsRequester;
|
|
11628
|
+
getCountersigningSessionStateRequester;
|
|
11629
|
+
abandonCountersigningSessionRequester;
|
|
11630
|
+
publishCountersigningSessionRequester;
|
|
11631
|
+
constructor(client, appInfo, callZomeTransform, defaultTimeout) {
|
|
11632
|
+
this.client = client;
|
|
11633
|
+
this.myPubKey = appInfo.agent_pub_key;
|
|
11634
|
+
this.installedAppId = appInfo.installed_app_id;
|
|
11635
|
+
this.defaultTimeout = defaultTimeout ?? DEFAULT_TIMEOUT;
|
|
11636
|
+
this.callZomeTransform = callZomeTransform ?? defaultCallZomeTransform;
|
|
11637
|
+
this.emitter = new Emittery();
|
|
11638
|
+
this.cachedAppInfo = appInfo;
|
|
11639
|
+
this.appInfoRequester = AppWebsocket.requester(this.client, "app_info", this.defaultTimeout);
|
|
11640
|
+
this.callZomeRequester = AppWebsocket.requester(this.client, "call_zome", this.defaultTimeout, this.callZomeTransform);
|
|
11641
|
+
this.provideMemproofRequester = AppWebsocket.requester(this.client, "provide_memproofs", this.defaultTimeout);
|
|
11642
|
+
this.enableAppRequester = AppWebsocket.requester(this.client, "enable_app", this.defaultTimeout);
|
|
11643
|
+
this.createCloneCellRequester = AppWebsocket.requester(this.client, "create_clone_cell", this.defaultTimeout);
|
|
11644
|
+
this.enableCloneCellRequester = AppWebsocket.requester(this.client, "enable_clone_cell", this.defaultTimeout);
|
|
11645
|
+
this.disableCloneCellRequester = AppWebsocket.requester(this.client, "disable_clone_cell", this.defaultTimeout);
|
|
11646
|
+
this.dumpNetworkStatsRequester = AppWebsocket.requester(this.client, "dump_network_stats", this.defaultTimeout);
|
|
11647
|
+
this.dumpNetworkMetricsRequester = AppWebsocket.requester(this.client, "dump_network_metrics", this.defaultTimeout);
|
|
11648
|
+
this.getCountersigningSessionStateRequester = AppWebsocket.requester(this.client, "get_countersigning_session_state", this.defaultTimeout);
|
|
11649
|
+
this.abandonCountersigningSessionRequester = AppWebsocket.requester(this.client, "abandon_countersigning_session", this.defaultTimeout);
|
|
11650
|
+
this.publishCountersigningSessionRequester = AppWebsocket.requester(this.client, "publish_countersigning_session", this.defaultTimeout);
|
|
11651
|
+
Object.getOwnPropertyNames(Emittery.prototype).forEach((name) => {
|
|
11652
|
+
const to_bind = this.emitter[name];
|
|
11653
|
+
if (typeof to_bind === "function") {
|
|
11654
|
+
this.emitter[name] = to_bind.bind(this.emitter);
|
|
11655
|
+
}
|
|
11656
|
+
});
|
|
11657
|
+
this.client.on("signal", (signal) => {
|
|
11658
|
+
this.emitter.emit("signal", signal).catch(console.error);
|
|
11659
|
+
});
|
|
11660
|
+
}
|
|
11661
|
+
/**
|
|
11662
|
+
* Instance factory for creating an {@link AppWebsocket}.
|
|
11663
|
+
*
|
|
11664
|
+
* @param token - A token to authenticate the websocket connection. Get a token using AdminWebsocket#issueAppAuthenticationToken.
|
|
11665
|
+
* @param options - {@link (WebsocketConnectionOptions:interface)}
|
|
11666
|
+
* @returns A new instance of an AppWebsocket.
|
|
11667
|
+
*/
|
|
11668
|
+
static async connect(options = {}) {
|
|
11669
|
+
const env = getLauncherEnvironment();
|
|
11670
|
+
if (env?.APP_INTERFACE_PORT) {
|
|
11671
|
+
options.url = new URL(`ws://localhost:${env.APP_INTERFACE_PORT}`);
|
|
11672
|
+
}
|
|
11673
|
+
if (!options.url) {
|
|
11674
|
+
throw new HolochainError("ConnectionUrlMissing", `unable to connect to Conductor API - no url provided and not in a launcher environment.`);
|
|
11675
|
+
}
|
|
11676
|
+
const client = await WsClient.connect(options.url, options.wsClientOptions);
|
|
11677
|
+
const token = options.token ?? env?.APP_INTERFACE_TOKEN;
|
|
11678
|
+
if (!token)
|
|
11679
|
+
throw new HolochainError("AppAuthenticationTokenMissing", `unable to connect to Conductor API - no app authentication token provided.`);
|
|
11680
|
+
await client.authenticate({ token });
|
|
11681
|
+
const appInfo = await AppWebsocket.requester(client, "app_info", DEFAULT_TIMEOUT)(null);
|
|
11682
|
+
if (!appInfo) {
|
|
11683
|
+
throw new HolochainError("AppNotFound", `The app your connection token was issued for was not found. The app needs to be installed and enabled.`);
|
|
11684
|
+
}
|
|
11685
|
+
return new AppWebsocket(client, appInfo, options.callZomeTransform, options.defaultTimeout);
|
|
11686
|
+
}
|
|
11687
|
+
/**
|
|
11688
|
+
* Request the app's info, including all cell infos.
|
|
11689
|
+
*
|
|
11690
|
+
* @param timeout - A timeout to override the default.
|
|
11691
|
+
* @returns The app's {@link AppInfo}.
|
|
11692
|
+
*/
|
|
11693
|
+
async appInfo(timeout2) {
|
|
11694
|
+
const appInfo = await this.appInfoRequester(null, timeout2);
|
|
11695
|
+
if (!appInfo) {
|
|
11696
|
+
throw new HolochainError("AppNotFound", `App info not found. App needs to be installed and enabled.`);
|
|
11697
|
+
}
|
|
11698
|
+
this.cachedAppInfo = appInfo;
|
|
11699
|
+
return appInfo;
|
|
11700
|
+
}
|
|
11701
|
+
/**
|
|
11702
|
+
* Request network stats.
|
|
11703
|
+
*
|
|
11704
|
+
* @returns The conductor's {@link TransportStats}.
|
|
11705
|
+
*/
|
|
11706
|
+
async dumpNetworkStats(timeout2) {
|
|
11707
|
+
return await this.dumpNetworkStatsRequester(void 0, timeout2);
|
|
11708
|
+
}
|
|
11709
|
+
/**
|
|
11710
|
+
* Request network metrics.
|
|
11711
|
+
*
|
|
11712
|
+
* @returns The {@link NetworkMetrics}.
|
|
11713
|
+
*/
|
|
11714
|
+
async dumpNetworkMetrics(req, timeout2) {
|
|
11715
|
+
return await this.dumpNetworkMetricsRequester(req, timeout2);
|
|
11716
|
+
}
|
|
11717
|
+
/**
|
|
11718
|
+
* Provide membrane proofs for the app.
|
|
11719
|
+
*
|
|
11720
|
+
* @param memproofs - A map of {@link MembraneProof}s.
|
|
11721
|
+
*/
|
|
11722
|
+
async provideMemproofs(memproofs) {
|
|
11723
|
+
await this.provideMemproofRequester(memproofs);
|
|
11724
|
+
}
|
|
11725
|
+
/**
|
|
11726
|
+
* Enable an app only if the app is in the `AppStatus::Disabled(DisabledAppReason::NotStartedAfterProvidingMemproofs)`
|
|
11727
|
+
* state. Attempting to enable the app from other states (other than Running) will fail.
|
|
11728
|
+
*/
|
|
11729
|
+
async enableApp() {
|
|
11730
|
+
await this.enableAppRequester();
|
|
11731
|
+
}
|
|
11732
|
+
/**
|
|
11733
|
+
* Get a cell id by its role name or clone id.
|
|
11734
|
+
*
|
|
11735
|
+
* @param roleName - The role name or clone id of the cell.
|
|
11736
|
+
* @param appInfo - The app info containing all cell infos.
|
|
11737
|
+
* @returns The cell id or throws an error if not found.
|
|
11738
|
+
*/
|
|
11739
|
+
getCellIdFromRoleName(roleName, appInfo) {
|
|
11740
|
+
if (isCloneId(roleName)) {
|
|
11741
|
+
const baseRoleName = getBaseRoleNameFromCloneId(roleName);
|
|
11742
|
+
if (!(baseRoleName in appInfo.cell_info)) {
|
|
11743
|
+
throw new HolochainError("NoCellForRoleName", `no cell found with role_name ${roleName}`);
|
|
11744
|
+
}
|
|
11745
|
+
const cloneCell = appInfo.cell_info[baseRoleName].find((c) => c.type === CellType.Cloned && c.value.clone_id === roleName);
|
|
11746
|
+
if (!cloneCell || cloneCell.type !== CellType.Cloned) {
|
|
11747
|
+
throw new HolochainError("NoCellForCloneId", `no clone cell found with clone id ${roleName}`);
|
|
11748
|
+
}
|
|
11749
|
+
return cloneCell.value.cell_id;
|
|
11750
|
+
}
|
|
11751
|
+
if (!(roleName in appInfo.cell_info)) {
|
|
11752
|
+
throw new HolochainError("NoCellForRoleName", `no cell found with role_name ${roleName}`);
|
|
11753
|
+
}
|
|
11754
|
+
const cell = appInfo.cell_info[roleName].find((c) => c.type === CellType.Provisioned);
|
|
11755
|
+
if (!cell || cell.type !== CellType.Provisioned) {
|
|
11756
|
+
throw new HolochainError("NoProvisionedCellForRoleName", `no provisioned cell found with role_name ${roleName}`);
|
|
11757
|
+
}
|
|
11758
|
+
return cell.value.cell_id;
|
|
11759
|
+
}
|
|
11760
|
+
/**
|
|
11761
|
+
* Call a zome.
|
|
11762
|
+
*
|
|
11763
|
+
* @param request - The zome call arguments.
|
|
11764
|
+
* @param timeout - A timeout to override the default.
|
|
11765
|
+
* @returns The zome call's response.
|
|
11766
|
+
*/
|
|
11767
|
+
async callZome(request, timeout2) {
|
|
11768
|
+
if (!("provenance" in request)) {
|
|
11769
|
+
request = {
|
|
11770
|
+
...request,
|
|
11771
|
+
provenance: this.myPubKey
|
|
11772
|
+
};
|
|
11773
|
+
}
|
|
11774
|
+
if ("role_name" in request && request.role_name) {
|
|
11775
|
+
const appInfo = this.cachedAppInfo || await this.appInfo();
|
|
11776
|
+
const cell_id = this.getCellIdFromRoleName(request.role_name, appInfo);
|
|
11777
|
+
request = {
|
|
11778
|
+
...omit(request, "role_name"),
|
|
11779
|
+
// Some problem here with the launcher with just the `cell_id`.
|
|
11780
|
+
cell_id: [cell_id[0], cell_id[1]]
|
|
11781
|
+
};
|
|
11782
|
+
} else if (!("cell_id" in request)) {
|
|
11783
|
+
throw new HolochainError("MissingRoleNameOrCellId", "callZome requires a role_name or cell_id argument");
|
|
11784
|
+
}
|
|
11785
|
+
return this.callZomeRequester(request, timeout2);
|
|
11786
|
+
}
|
|
11787
|
+
/**
|
|
11788
|
+
* Clone an existing provisioned cell.
|
|
11789
|
+
*
|
|
11790
|
+
* @param args - Specify the cell to clone.
|
|
11791
|
+
* @returns The created clone cell.
|
|
11792
|
+
*/
|
|
11793
|
+
async createCloneCell(args) {
|
|
11794
|
+
const clonedCell = this.createCloneCellRequester({
|
|
11795
|
+
...args
|
|
11796
|
+
});
|
|
11797
|
+
this.cachedAppInfo = void 0;
|
|
11798
|
+
return clonedCell;
|
|
11799
|
+
}
|
|
11800
|
+
/**
|
|
11801
|
+
* Enable a disabled clone cell.
|
|
11802
|
+
*
|
|
11803
|
+
* @param args - Specify the clone cell to enable.
|
|
11804
|
+
* @returns The enabled clone cell.
|
|
11805
|
+
*/
|
|
11806
|
+
async enableCloneCell(args) {
|
|
11807
|
+
return this.enableCloneCellRequester({
|
|
11808
|
+
...args
|
|
11809
|
+
});
|
|
11810
|
+
}
|
|
11811
|
+
/**
|
|
11812
|
+
* Disable an enabled clone cell.
|
|
11813
|
+
*
|
|
11814
|
+
* @param args - Specify the clone cell to disable.
|
|
11815
|
+
*/
|
|
11816
|
+
async disableCloneCell(args) {
|
|
11817
|
+
return this.disableCloneCellRequester({
|
|
11818
|
+
...args
|
|
11819
|
+
});
|
|
11820
|
+
}
|
|
11821
|
+
/**
|
|
11822
|
+
* Get the state of a countersigning session.
|
|
11823
|
+
*/
|
|
11824
|
+
async getCountersigningSessionState(args) {
|
|
11825
|
+
return this.getCountersigningSessionStateRequester(args);
|
|
11826
|
+
}
|
|
11827
|
+
/**
|
|
11828
|
+
* Abandon an unresolved countersigning session.
|
|
11829
|
+
*
|
|
11830
|
+
* If the current session has not been resolved automatically, it can be forcefully abandoned.
|
|
11831
|
+
* A condition for this call to succeed is that at least one attempt has been made to resolve
|
|
11832
|
+
* it automatically.
|
|
11833
|
+
*
|
|
11834
|
+
* # Returns
|
|
11835
|
+
*
|
|
11836
|
+
* [`AppResponse::CountersigningSessionAbandoned`]
|
|
11837
|
+
*
|
|
11838
|
+
* The session is marked for abandoning and the countersigning workflow was triggered. The session
|
|
11839
|
+
* has not been abandoned yet.
|
|
11840
|
+
*
|
|
11841
|
+
* Upon successful abandoning the system signal [`SystemSignal::AbandonedCountersigning`] will
|
|
11842
|
+
* be emitted and the session removed from state, so that [`AppRequest::GetCountersigningSessionState`]
|
|
11843
|
+
* would return `None`.
|
|
11844
|
+
*
|
|
11845
|
+
* In the countersigning workflow it will first be attempted to resolve the session with incoming
|
|
11846
|
+
* signatures of the countersigned entries, before force-abandoning the session. In a very rare event
|
|
11847
|
+
* it could happen that in just the moment where the [`AppRequest::AbandonCountersigningSession`]
|
|
11848
|
+
* is made, signatures for this session come in. If they are valid, the session will be resolved and
|
|
11849
|
+
* published as usual. Should they be invalid, however, the flag to abandon the session is erased.
|
|
11850
|
+
* In such cases this request can be retried until the session has been abandoned successfully.
|
|
11851
|
+
*
|
|
11852
|
+
* # Errors
|
|
11853
|
+
*
|
|
11854
|
+
* [`CountersigningError::WorkspaceDoesNotExist`] likely indicates that an invalid cell id was
|
|
11855
|
+
* passed in to the call.
|
|
11856
|
+
*
|
|
11857
|
+
* [`CountersigningError::SessionNotFound`] when no ongoing session could be found for the provided
|
|
11858
|
+
* cell id.
|
|
11859
|
+
*
|
|
11860
|
+
* [`CountersigningError::SessionNotUnresolved`] when an attempt to resolve the session
|
|
11861
|
+
* automatically has not been made.
|
|
11862
|
+
*/
|
|
11863
|
+
async abandonCountersigningSession(args) {
|
|
11864
|
+
return this.abandonCountersigningSessionRequester(args);
|
|
11865
|
+
}
|
|
11866
|
+
/**
|
|
11867
|
+
* Publish an unresolved countersigning session.
|
|
11868
|
+
*
|
|
11869
|
+
* If the current session has not been resolved automatically, it can be forcefully published.
|
|
11870
|
+
* A condition for this call to succeed is that at least one attempt has been made to resolve
|
|
11871
|
+
* it automatically.
|
|
11872
|
+
*
|
|
11873
|
+
* # Returns
|
|
11874
|
+
*
|
|
11875
|
+
* [`AppResponse::PublishCountersigningSessionTriggered`]
|
|
11876
|
+
*
|
|
11877
|
+
* The session is marked for publishing and the countersigning workflow was triggered. The session
|
|
11878
|
+
* has not been published yet.
|
|
11879
|
+
*
|
|
11880
|
+
* Upon successful publishing the system signal [`SystemSignal::SuccessfulCountersigning`] will
|
|
11881
|
+
* be emitted and the session removed from state, so that [`AppRequest::GetCountersigningSessionState`]
|
|
11882
|
+
* would return `None`.
|
|
11883
|
+
*
|
|
11884
|
+
* In the countersigning workflow it will first be attempted to resolve the session with incoming
|
|
11885
|
+
* signatures of the countersigned entries, before force-publishing the session. In a very rare event
|
|
11886
|
+
* it could happen that in just the moment where the [`AppRequest::PublishCountersigningSession`]
|
|
11887
|
+
* is made, signatures for this session come in. If they are valid, the session will be resolved and
|
|
11888
|
+
* published as usual. Should they be invalid, however, the flag to publish the session is erased.
|
|
11889
|
+
* In such cases this request can be retried until the session has been published successfully.
|
|
11890
|
+
*
|
|
11891
|
+
* # Errors
|
|
11892
|
+
*
|
|
11893
|
+
* [`CountersigningError::WorkspaceDoesNotExist`] likely indicates that an invalid cell id was
|
|
11894
|
+
* passed in to the call.
|
|
11895
|
+
*
|
|
11896
|
+
* [`CountersigningError::SessionNotFound`] when no ongoing session could be found for the provided
|
|
11897
|
+
* cell id.
|
|
11898
|
+
*
|
|
11899
|
+
* [`CountersigningError::SessionNotUnresolved`] when an attempt to resolve the session
|
|
11900
|
+
* automatically has not been made.
|
|
11901
|
+
*/
|
|
11902
|
+
async publishCountersigningSession(args) {
|
|
11903
|
+
return this.publishCountersigningSessionRequester(args);
|
|
11904
|
+
}
|
|
11905
|
+
/**
|
|
11906
|
+
* Register an event listener for signals.
|
|
11907
|
+
*
|
|
11908
|
+
* @param eventName - Event name to listen to (currently only "signal").
|
|
11909
|
+
* @param listener - The function to call when event is triggered.
|
|
11910
|
+
* @returns A function to unsubscribe the event listener.
|
|
11911
|
+
*/
|
|
11912
|
+
on(eventName, listener) {
|
|
11913
|
+
return this.emitter.on(eventName, listener);
|
|
11914
|
+
}
|
|
11915
|
+
static requester(client, tag, defaultTimeout, transformer) {
|
|
11916
|
+
return requesterTransformer((req, timeout2) => promiseTimeout(client.request(req), tag, timeout2 || defaultTimeout).then(catchError), tag, transformer);
|
|
11917
|
+
}
|
|
11918
|
+
}
|
|
11919
|
+
const defaultCallZomeTransform = {
|
|
11920
|
+
input: async (request) => {
|
|
11921
|
+
if ("signature" in request) {
|
|
11922
|
+
return request;
|
|
11923
|
+
}
|
|
11924
|
+
const hostSigner = getHostZomeCallSigner();
|
|
11925
|
+
if (hostSigner) {
|
|
11926
|
+
return hostSigner.signZomeCall(request);
|
|
11927
|
+
} else {
|
|
11928
|
+
return signZomeCall(request);
|
|
11929
|
+
}
|
|
11930
|
+
},
|
|
11931
|
+
output: (response) => msgpack.decode(response)
|
|
11932
|
+
};
|
|
11933
|
+
const signZomeCall = async (request) => {
|
|
11934
|
+
const signingCredentialsForCell = getSigningCredentials(request.cell_id);
|
|
11935
|
+
if (!signingCredentialsForCell) {
|
|
11936
|
+
throw new HolochainError("NoSigningCredentialsForCell", `no signing credentials have been authorized for cell [${encodeHashToBase64(request.cell_id[0])}, ${encodeHashToBase64(request.cell_id[1])}]`);
|
|
11937
|
+
}
|
|
11938
|
+
const zome_call_params = {
|
|
11939
|
+
cap_secret: signingCredentialsForCell.capSecret,
|
|
11940
|
+
cell_id: request.cell_id,
|
|
11941
|
+
zome_name: request.zome_name,
|
|
11942
|
+
fn_name: request.fn_name,
|
|
11943
|
+
provenance: signingCredentialsForCell.signingKey,
|
|
11944
|
+
payload: msgpack.encode(request.payload),
|
|
11945
|
+
nonce: await randomNonce(),
|
|
11946
|
+
expires_at: getNonceExpiration()
|
|
11947
|
+
};
|
|
11948
|
+
const bytes = msgpack.encode(zome_call_params);
|
|
11949
|
+
const bytesHash = new Uint8Array(jsSha512.sha512.array(bytes));
|
|
11950
|
+
await _sodium.ready;
|
|
11951
|
+
const sodium = _sodium;
|
|
11952
|
+
const signature = sodium.crypto_sign(bytesHash, signingCredentialsForCell.keyPair.privateKey).subarray(0, sodium.crypto_sign_BYTES);
|
|
11953
|
+
const signedZomeCall = {
|
|
11954
|
+
bytes,
|
|
11955
|
+
signature
|
|
11956
|
+
};
|
|
11957
|
+
return signedZomeCall;
|
|
11958
|
+
};
|
|
11959
|
+
class WsClient extends Emittery {
|
|
11960
|
+
socket;
|
|
11961
|
+
url;
|
|
11962
|
+
options;
|
|
11963
|
+
pendingRequests;
|
|
11964
|
+
index;
|
|
11965
|
+
authenticationToken;
|
|
11966
|
+
constructor(socket, url2, options) {
|
|
11967
|
+
super();
|
|
11968
|
+
this.registerMessageListener(socket);
|
|
11969
|
+
this.registerCloseListener(socket);
|
|
11970
|
+
this.socket = socket;
|
|
11971
|
+
this.url = url2;
|
|
11972
|
+
this.options = options || {};
|
|
11973
|
+
this.pendingRequests = {};
|
|
11974
|
+
this.index = 0;
|
|
11975
|
+
}
|
|
11976
|
+
/**
|
|
11977
|
+
* Instance factory for creating WsClients.
|
|
11978
|
+
*
|
|
11979
|
+
* @param url - The WebSocket URL to connect to.
|
|
11980
|
+
* @param options - Options for the WsClient.
|
|
11981
|
+
* @returns An new instance of the WsClient.
|
|
11982
|
+
*/
|
|
11983
|
+
static connect(url2, options) {
|
|
11984
|
+
return new Promise((resolve, reject) => {
|
|
11985
|
+
const socket = new IsoWebSocket(url2, options);
|
|
11986
|
+
socket.addEventListener("error", (errorEvent) => {
|
|
11987
|
+
reject(new HolochainError("ConnectionError", `could not connect to Holochain Conductor API at ${url2} - ${errorEvent.error}`));
|
|
11988
|
+
});
|
|
11989
|
+
socket.addEventListener("open", (_) => {
|
|
11990
|
+
const client = new WsClient(socket, url2, options);
|
|
11991
|
+
resolve(client);
|
|
11992
|
+
}, { once: true });
|
|
11993
|
+
});
|
|
11994
|
+
}
|
|
11995
|
+
/**
|
|
11996
|
+
* Sends data as a signal.
|
|
11997
|
+
*
|
|
11998
|
+
* @param data - Data to send.
|
|
11999
|
+
*/
|
|
12000
|
+
emitSignal(data) {
|
|
12001
|
+
const encodedMsg = msgpack.encode({
|
|
12002
|
+
type: "signal",
|
|
12003
|
+
data: msgpack.encode(data)
|
|
12004
|
+
});
|
|
12005
|
+
this.socket.send(encodedMsg);
|
|
12006
|
+
}
|
|
12007
|
+
/**
|
|
12008
|
+
* Authenticate the client with the conductor.
|
|
12009
|
+
*
|
|
12010
|
+
* This is only relevant for app websockets.
|
|
12011
|
+
*
|
|
12012
|
+
* @param request - The authentication request, containing an app authentication token.
|
|
12013
|
+
*/
|
|
12014
|
+
async authenticate(request) {
|
|
12015
|
+
this.authenticationToken = request.token;
|
|
12016
|
+
return this.exchange(request, (request2, resolve, reject) => {
|
|
12017
|
+
const invalidTokenCloseListener = (closeEvent) => {
|
|
12018
|
+
this.authenticationToken = void 0;
|
|
12019
|
+
reject(new HolochainError("InvalidTokenError", `could not connect to ${this.url} due to an invalid app authentication token - close code ${closeEvent.code}`));
|
|
12020
|
+
};
|
|
12021
|
+
this.socket.addEventListener("close", invalidTokenCloseListener, {
|
|
12022
|
+
once: true
|
|
12023
|
+
});
|
|
12024
|
+
const encodedMsg = msgpack.encode({
|
|
12025
|
+
type: "authenticate",
|
|
12026
|
+
data: msgpack.encode(request2)
|
|
12027
|
+
});
|
|
12028
|
+
this.socket.send(encodedMsg);
|
|
12029
|
+
setTimeout(() => {
|
|
12030
|
+
this.socket.removeEventListener("close", invalidTokenCloseListener);
|
|
12031
|
+
resolve(null);
|
|
12032
|
+
}, 10);
|
|
12033
|
+
});
|
|
11797
12034
|
}
|
|
11798
|
-
|
|
11799
|
-
|
|
12035
|
+
/**
|
|
12036
|
+
* Close the websocket connection.
|
|
12037
|
+
*/
|
|
12038
|
+
close(code = 1e3) {
|
|
12039
|
+
const closedPromise = new Promise((resolve) => this.socket.addEventListener("close", (closeEvent) => resolve(closeEvent), { once: true }));
|
|
12040
|
+
this.socket.close(code);
|
|
12041
|
+
return closedPromise;
|
|
11800
12042
|
}
|
|
11801
|
-
|
|
11802
|
-
|
|
11803
|
-
|
|
11804
|
-
|
|
11805
|
-
|
|
11806
|
-
|
|
11807
|
-
|
|
11808
|
-
|
|
11809
|
-
B2B_G(6, 8, 18, 28, SIGMA82[i * 16 + 14], SIGMA82[i * 16 + 15]);
|
|
12043
|
+
/**
|
|
12044
|
+
* Send requests to the connected websocket.
|
|
12045
|
+
*
|
|
12046
|
+
* @param request - The request to send over the websocket.
|
|
12047
|
+
* @returns
|
|
12048
|
+
*/
|
|
12049
|
+
async request(request) {
|
|
12050
|
+
return this.exchange(request, this.sendMessage.bind(this));
|
|
11810
12051
|
}
|
|
11811
|
-
|
|
11812
|
-
|
|
12052
|
+
async exchange(request, sendHandler) {
|
|
12053
|
+
if (this.socket.readyState === this.socket.OPEN) {
|
|
12054
|
+
const promise = new Promise((resolve, reject) => {
|
|
12055
|
+
sendHandler(request, resolve, reject);
|
|
12056
|
+
});
|
|
12057
|
+
return promise;
|
|
12058
|
+
} else if (this.url && this.authenticationToken) {
|
|
12059
|
+
await this.reconnectWebsocket(this.url, this.authenticationToken);
|
|
12060
|
+
this.registerMessageListener(this.socket);
|
|
12061
|
+
this.registerCloseListener(this.socket);
|
|
12062
|
+
const promise = new Promise((resolve, reject) => sendHandler(request, resolve, reject));
|
|
12063
|
+
return promise;
|
|
12064
|
+
} else {
|
|
12065
|
+
return Promise.reject(new HolochainError("WebsocketClosedError", "Websocket is not open"));
|
|
12066
|
+
}
|
|
11813
12067
|
}
|
|
11814
|
-
|
|
11815
|
-
const
|
|
11816
|
-
|
|
11817
|
-
|
|
11818
|
-
|
|
11819
|
-
|
|
11820
|
-
|
|
11821
|
-
|
|
11822
|
-
|
|
11823
|
-
|
|
11824
|
-
0,
|
|
11825
|
-
// 4: leaf length, sequential mode
|
|
11826
|
-
0,
|
|
11827
|
-
0,
|
|
11828
|
-
0,
|
|
11829
|
-
0,
|
|
11830
|
-
// 8: node offset
|
|
11831
|
-
0,
|
|
11832
|
-
0,
|
|
11833
|
-
0,
|
|
11834
|
-
0,
|
|
11835
|
-
// 12: node offset
|
|
11836
|
-
0,
|
|
11837
|
-
0,
|
|
11838
|
-
0,
|
|
11839
|
-
0,
|
|
11840
|
-
// 16: node depth, inner length, rfu
|
|
11841
|
-
0,
|
|
11842
|
-
0,
|
|
11843
|
-
0,
|
|
11844
|
-
0,
|
|
11845
|
-
// 20: rfu
|
|
11846
|
-
0,
|
|
11847
|
-
0,
|
|
11848
|
-
0,
|
|
11849
|
-
0,
|
|
11850
|
-
// 24: rfu
|
|
11851
|
-
0,
|
|
11852
|
-
0,
|
|
11853
|
-
0,
|
|
11854
|
-
0,
|
|
11855
|
-
// 28: rfu
|
|
11856
|
-
0,
|
|
11857
|
-
0,
|
|
11858
|
-
0,
|
|
11859
|
-
0,
|
|
11860
|
-
// 32: salt
|
|
11861
|
-
0,
|
|
11862
|
-
0,
|
|
11863
|
-
0,
|
|
11864
|
-
0,
|
|
11865
|
-
// 36: salt
|
|
11866
|
-
0,
|
|
11867
|
-
0,
|
|
11868
|
-
0,
|
|
11869
|
-
0,
|
|
11870
|
-
// 40: salt
|
|
11871
|
-
0,
|
|
11872
|
-
0,
|
|
11873
|
-
0,
|
|
11874
|
-
0,
|
|
11875
|
-
// 44: salt
|
|
11876
|
-
0,
|
|
11877
|
-
0,
|
|
11878
|
-
0,
|
|
11879
|
-
0,
|
|
11880
|
-
// 48: personal
|
|
11881
|
-
0,
|
|
11882
|
-
0,
|
|
11883
|
-
0,
|
|
11884
|
-
0,
|
|
11885
|
-
// 52: personal
|
|
11886
|
-
0,
|
|
11887
|
-
0,
|
|
11888
|
-
0,
|
|
11889
|
-
0,
|
|
11890
|
-
// 56: personal
|
|
11891
|
-
0,
|
|
11892
|
-
0,
|
|
11893
|
-
0,
|
|
11894
|
-
0
|
|
11895
|
-
// 60: personal
|
|
11896
|
-
]);
|
|
11897
|
-
function Blake2b(outlen, key, salt, personal) {
|
|
11898
|
-
parameter_block.fill(0);
|
|
11899
|
-
this.b = new Uint8Array(128);
|
|
11900
|
-
this.h = new Uint32Array(16);
|
|
11901
|
-
this.t = 0;
|
|
11902
|
-
this.c = 0;
|
|
11903
|
-
this.outlen = outlen;
|
|
11904
|
-
parameter_block[0] = outlen;
|
|
11905
|
-
if (key) parameter_block[1] = key.length;
|
|
11906
|
-
parameter_block[2] = 1;
|
|
11907
|
-
parameter_block[3] = 1;
|
|
11908
|
-
if (salt) parameter_block.set(salt, 32);
|
|
11909
|
-
if (personal) parameter_block.set(personal, 48);
|
|
11910
|
-
for (let i = 0; i < 16; i++) {
|
|
11911
|
-
this.h[i] = BLAKE2B_IV32[i] ^ B2B_GET32(parameter_block, i * 4);
|
|
12068
|
+
sendMessage(request, resolve, reject) {
|
|
12069
|
+
const id = this.index;
|
|
12070
|
+
const encodedMsg = msgpack.encode({
|
|
12071
|
+
id,
|
|
12072
|
+
type: "request",
|
|
12073
|
+
data: msgpack.encode(request)
|
|
12074
|
+
});
|
|
12075
|
+
this.socket.send(encodedMsg);
|
|
12076
|
+
this.pendingRequests[id] = { resolve, reject };
|
|
12077
|
+
this.index += 1;
|
|
11912
12078
|
}
|
|
11913
|
-
|
|
11914
|
-
|
|
11915
|
-
|
|
12079
|
+
registerMessageListener(socket) {
|
|
12080
|
+
socket.onmessage = async (serializedMessage) => {
|
|
12081
|
+
let deserializedData;
|
|
12082
|
+
if (globalThis.window && serializedMessage.data instanceof globalThis.window.Blob) {
|
|
12083
|
+
deserializedData = await serializedMessage.data.arrayBuffer();
|
|
12084
|
+
} else {
|
|
12085
|
+
if (typeof Buffer !== "undefined" && Buffer.isBuffer(serializedMessage.data)) {
|
|
12086
|
+
deserializedData = serializedMessage.data;
|
|
12087
|
+
} else {
|
|
12088
|
+
throw new HolochainError("UnknownMessageFormat", `incoming message has unknown message format - ${deserializedData}`);
|
|
12089
|
+
}
|
|
12090
|
+
}
|
|
12091
|
+
const message = msgpack.decode(deserializedData);
|
|
12092
|
+
assertHolochainMessage(message);
|
|
12093
|
+
if (message.type === "signal") {
|
|
12094
|
+
if (message.data === null) {
|
|
12095
|
+
throw new HolochainError("UnknownSignalFormat", "incoming signal has no data");
|
|
12096
|
+
}
|
|
12097
|
+
const deserializedSignal = msgpack.decode(message.data);
|
|
12098
|
+
assertHolochainSignal(deserializedSignal);
|
|
12099
|
+
if (deserializedSignal.type === SignalType.System) {
|
|
12100
|
+
this.emit("signal", {
|
|
12101
|
+
type: SignalType.System,
|
|
12102
|
+
value: deserializedSignal.value
|
|
12103
|
+
});
|
|
12104
|
+
} else {
|
|
12105
|
+
const encodedAppSignal = deserializedSignal.value;
|
|
12106
|
+
const payload = msgpack.decode(encodedAppSignal.signal);
|
|
12107
|
+
const signal = {
|
|
12108
|
+
cell_id: encodedAppSignal.cell_id,
|
|
12109
|
+
zome_name: encodedAppSignal.zome_name,
|
|
12110
|
+
payload
|
|
12111
|
+
};
|
|
12112
|
+
this.emit("signal", {
|
|
12113
|
+
type: SignalType.App,
|
|
12114
|
+
value: signal
|
|
12115
|
+
});
|
|
12116
|
+
}
|
|
12117
|
+
} else if (message.type === "response") {
|
|
12118
|
+
this.handleResponse(message);
|
|
12119
|
+
} else {
|
|
12120
|
+
throw new HolochainError("UnknownMessageType", `incoming message has unknown type - ${message.type}`);
|
|
12121
|
+
}
|
|
12122
|
+
};
|
|
11916
12123
|
}
|
|
11917
|
-
|
|
11918
|
-
|
|
11919
|
-
|
|
11920
|
-
|
|
11921
|
-
|
|
11922
|
-
};
|
|
11923
|
-
|
|
11924
|
-
|
|
11925
|
-
|
|
11926
|
-
|
|
11927
|
-
|
|
11928
|
-
|
|
11929
|
-
|
|
11930
|
-
|
|
11931
|
-
|
|
11932
|
-
|
|
11933
|
-
|
|
11934
|
-
|
|
11935
|
-
|
|
11936
|
-
|
|
11937
|
-
|
|
11938
|
-
|
|
11939
|
-
|
|
11940
|
-
|
|
11941
|
-
|
|
11942
|
-
|
|
12124
|
+
registerCloseListener(socket) {
|
|
12125
|
+
socket.addEventListener("close", (closeEvent) => {
|
|
12126
|
+
const pendingRequestIds = Object.keys(this.pendingRequests).map((id) => parseInt(id));
|
|
12127
|
+
if (pendingRequestIds.length) {
|
|
12128
|
+
pendingRequestIds.forEach((id) => {
|
|
12129
|
+
const error = new HolochainError("ClientClosedWithPendingRequests", `client closed with pending requests - close event code: ${closeEvent.code}, request id: ${id}`);
|
|
12130
|
+
this.pendingRequests[id].reject(error);
|
|
12131
|
+
delete this.pendingRequests[id];
|
|
12132
|
+
});
|
|
12133
|
+
}
|
|
12134
|
+
}, { once: true });
|
|
12135
|
+
}
|
|
12136
|
+
async reconnectWebsocket(url2, token) {
|
|
12137
|
+
return new Promise((resolve, reject) => {
|
|
12138
|
+
this.socket = new IsoWebSocket(url2, this.options);
|
|
12139
|
+
this.socket.addEventListener("error", (errorEvent) => {
|
|
12140
|
+
this.authenticationToken = void 0;
|
|
12141
|
+
reject(new HolochainError("ConnectionError", `could not connect to Holochain Conductor API at ${url2} - ${errorEvent.message}`));
|
|
12142
|
+
}, { once: true });
|
|
12143
|
+
const invalidTokenCloseListener = (closeEvent) => {
|
|
12144
|
+
this.authenticationToken = void 0;
|
|
12145
|
+
reject(new HolochainError("InvalidTokenError", `could not connect to ${this.url} due to an invalid app authentication token - close code ${closeEvent.code}`));
|
|
12146
|
+
};
|
|
12147
|
+
this.socket.addEventListener("close", invalidTokenCloseListener, {
|
|
12148
|
+
once: true
|
|
12149
|
+
});
|
|
12150
|
+
this.socket.addEventListener("open", async (_) => {
|
|
12151
|
+
const encodedMsg = msgpack.encode({
|
|
12152
|
+
type: "authenticate",
|
|
12153
|
+
data: msgpack.encode({ token })
|
|
12154
|
+
});
|
|
12155
|
+
this.socket.send(encodedMsg);
|
|
12156
|
+
setTimeout(() => {
|
|
12157
|
+
this.socket.removeEventListener("close", invalidTokenCloseListener);
|
|
12158
|
+
resolve();
|
|
12159
|
+
}, 10);
|
|
12160
|
+
}, { once: true });
|
|
12161
|
+
});
|
|
12162
|
+
}
|
|
12163
|
+
handleResponse(msg) {
|
|
12164
|
+
const id = msg.id;
|
|
12165
|
+
if (this.pendingRequests[id]) {
|
|
12166
|
+
if (msg.data === null || msg.data === void 0) {
|
|
12167
|
+
this.pendingRequests[id].reject(new Error("Response canceled by responder"));
|
|
12168
|
+
} else {
|
|
12169
|
+
this.pendingRequests[id].resolve(msgpack.decode(msg.data, {
|
|
12170
|
+
mapKeyConverter: (key) => {
|
|
12171
|
+
if (typeof key === "string" || typeof key === "number") {
|
|
12172
|
+
return key;
|
|
12173
|
+
}
|
|
12174
|
+
if (key && typeof key === "object" && key instanceof Uint8Array) {
|
|
12175
|
+
return encodeHashToBase64(key);
|
|
12176
|
+
}
|
|
12177
|
+
throw new HolochainError("DeserializationError", "Encountered map with key of type 'object', but not HoloHash " + key);
|
|
12178
|
+
}
|
|
12179
|
+
}));
|
|
12180
|
+
}
|
|
12181
|
+
delete this.pendingRequests[id];
|
|
12182
|
+
} else {
|
|
12183
|
+
console.error(`got response with no matching request. id = ${id} msg = ${msg}`);
|
|
11943
12184
|
}
|
|
11944
|
-
ctx.b[ctx.c++] = input[i];
|
|
11945
12185
|
}
|
|
11946
12186
|
}
|
|
11947
|
-
function
|
|
11948
|
-
|
|
11949
|
-
|
|
11950
|
-
ctx.b[ctx.c++] = 0;
|
|
11951
|
-
}
|
|
11952
|
-
blake2bCompress(ctx, true);
|
|
11953
|
-
for (let i = 0; i < ctx.outlen; i++) {
|
|
11954
|
-
out[i] = ctx.h[i >> 2] >> 8 * (i & 3);
|
|
12187
|
+
function assertHolochainMessage(message) {
|
|
12188
|
+
if (typeof message === "object" && message !== null && "type" in message && "data" in message) {
|
|
12189
|
+
return;
|
|
11955
12190
|
}
|
|
11956
|
-
|
|
11957
|
-
}
|
|
11958
|
-
function hexSlice(buf) {
|
|
11959
|
-
let str = "";
|
|
11960
|
-
for (let i = 0; i < buf.length; i++) str += toHex(buf[i]);
|
|
11961
|
-
return str;
|
|
11962
|
-
}
|
|
11963
|
-
function toHex(n) {
|
|
11964
|
-
if (n < 16) return "0" + n.toString(16);
|
|
11965
|
-
return n.toString(16);
|
|
12191
|
+
throw new HolochainError("UnknownMessageFormat", `incoming message has unknown message format ${JSON.stringify(message, null, 4)}`);
|
|
11966
12192
|
}
|
|
11967
|
-
|
|
11968
|
-
|
|
11969
|
-
|
|
11970
|
-
assert(outlen >= BYTES_MIN, "outlen must be at least " + BYTES_MIN + ", was given " + outlen);
|
|
11971
|
-
assert(outlen <= BYTES_MAX, "outlen must be at most " + BYTES_MAX + ", was given " + outlen);
|
|
11972
|
-
if (key != null) {
|
|
11973
|
-
assert(key instanceof Uint8Array, "key must be Uint8Array or Buffer");
|
|
11974
|
-
assert(key.length >= KEYBYTES_MIN, "key must be at least " + KEYBYTES_MIN + ", was given " + key.length);
|
|
11975
|
-
assert(key.length <= KEYBYTES_MAX, "key must be at most " + KEYBYTES_MAX + ", was given " + key.length);
|
|
11976
|
-
}
|
|
11977
|
-
if (salt != null) {
|
|
11978
|
-
assert(salt instanceof Uint8Array, "salt must be Uint8Array or Buffer");
|
|
11979
|
-
assert(salt.length === SALTBYTES, "salt must be exactly " + SALTBYTES + ", was given " + salt.length);
|
|
11980
|
-
}
|
|
11981
|
-
if (personal != null) {
|
|
11982
|
-
assert(personal instanceof Uint8Array, "personal must be Uint8Array or Buffer");
|
|
11983
|
-
assert(
|
|
11984
|
-
personal.length === PERSONALBYTES,
|
|
11985
|
-
"personal must be exactly " + PERSONALBYTES + ", was given " + personal.length
|
|
11986
|
-
);
|
|
11987
|
-
}
|
|
11988
|
-
}
|
|
11989
|
-
return new Proto(outlen, key, salt, personal);
|
|
11990
|
-
};
|
|
11991
|
-
blake2b$1.exports.ready = function(cb) {
|
|
11992
|
-
b2wasm.ready(function() {
|
|
11993
|
-
cb();
|
|
11994
|
-
});
|
|
11995
|
-
};
|
|
11996
|
-
blake2b$1.exports.WASM_SUPPORTED = b2wasm.SUPPORTED;
|
|
11997
|
-
blake2b$1.exports.WASM_LOADED = false;
|
|
11998
|
-
b2wasm.ready(function(err) {
|
|
11999
|
-
if (!err) {
|
|
12000
|
-
blake2b$1.exports.WASM_LOADED = true;
|
|
12001
|
-
blake2b$1.exports = b2wasm;
|
|
12193
|
+
function assertHolochainSignal(signal) {
|
|
12194
|
+
if (typeof signal === "object" && signal !== null && "type" in signal && "value" in signal && [SignalType.App, SignalType.System].some((type) => signal.type === type)) {
|
|
12195
|
+
return;
|
|
12002
12196
|
}
|
|
12003
|
-
});
|
|
12004
|
-
|
|
12005
|
-
|
|
12006
|
-
|
|
12007
|
-
|
|
12008
|
-
|
|
12009
|
-
External: Uint8Array.from([132, 47, 36])
|
|
12010
|
-
});
|
|
12011
|
-
class AppWebsocket {
|
|
12197
|
+
throw new HolochainError("UnknownSignalFormat", `incoming signal has unknown signal format ${JSON.stringify(signal, null, 4)}`);
|
|
12198
|
+
}
|
|
12199
|
+
class AdminWebsocket {
|
|
12200
|
+
/**
|
|
12201
|
+
* The websocket client used for transporting requests and responses.
|
|
12202
|
+
*/
|
|
12012
12203
|
client;
|
|
12013
|
-
|
|
12014
|
-
|
|
12204
|
+
/**
|
|
12205
|
+
* Default timeout for any request made over the websocket.
|
|
12206
|
+
*/
|
|
12015
12207
|
defaultTimeout;
|
|
12016
|
-
|
|
12017
|
-
callZomeTransform;
|
|
12018
|
-
cachedAppInfo;
|
|
12019
|
-
appInfoRequester;
|
|
12020
|
-
callZomeRequester;
|
|
12021
|
-
provideMemproofRequester;
|
|
12022
|
-
enableAppRequester;
|
|
12023
|
-
createCloneCellRequester;
|
|
12024
|
-
enableCloneCellRequester;
|
|
12025
|
-
disableCloneCellRequester;
|
|
12026
|
-
dumpNetworkStatsRequester;
|
|
12027
|
-
dumpNetworkMetricsRequester;
|
|
12028
|
-
getCountersigningSessionStateRequester;
|
|
12029
|
-
abandonCountersigningSessionRequester;
|
|
12030
|
-
publishCountersigningSessionRequester;
|
|
12031
|
-
constructor(client, appInfo, callZomeTransform, defaultTimeout) {
|
|
12208
|
+
constructor(client, defaultTimeout) {
|
|
12032
12209
|
this.client = client;
|
|
12033
|
-
this.
|
|
12034
|
-
this.installedAppId = appInfo.installed_app_id;
|
|
12035
|
-
this.defaultTimeout = defaultTimeout ?? DEFAULT_TIMEOUT;
|
|
12036
|
-
this.callZomeTransform = callZomeTransform ?? defaultCallZomeTransform;
|
|
12037
|
-
this.emitter = new Emittery();
|
|
12038
|
-
this.cachedAppInfo = appInfo;
|
|
12039
|
-
this.appInfoRequester = AppWebsocket.requester(this.client, "app_info", this.defaultTimeout);
|
|
12040
|
-
this.callZomeRequester = AppWebsocket.requester(this.client, "call_zome", this.defaultTimeout, this.callZomeTransform);
|
|
12041
|
-
this.provideMemproofRequester = AppWebsocket.requester(this.client, "provide_memproofs", this.defaultTimeout);
|
|
12042
|
-
this.enableAppRequester = AppWebsocket.requester(this.client, "enable_app", this.defaultTimeout);
|
|
12043
|
-
this.createCloneCellRequester = AppWebsocket.requester(this.client, "create_clone_cell", this.defaultTimeout);
|
|
12044
|
-
this.enableCloneCellRequester = AppWebsocket.requester(this.client, "enable_clone_cell", this.defaultTimeout);
|
|
12045
|
-
this.disableCloneCellRequester = AppWebsocket.requester(this.client, "disable_clone_cell", this.defaultTimeout);
|
|
12046
|
-
this.dumpNetworkStatsRequester = AppWebsocket.requester(this.client, "dump_network_stats", this.defaultTimeout);
|
|
12047
|
-
this.dumpNetworkMetricsRequester = AppWebsocket.requester(this.client, "dump_network_metrics", this.defaultTimeout);
|
|
12048
|
-
this.getCountersigningSessionStateRequester = AppWebsocket.requester(this.client, "get_countersigning_session_state", this.defaultTimeout);
|
|
12049
|
-
this.abandonCountersigningSessionRequester = AppWebsocket.requester(this.client, "abandon_countersigning_session", this.defaultTimeout);
|
|
12050
|
-
this.publishCountersigningSessionRequester = AppWebsocket.requester(this.client, "publish_countersigning_session", this.defaultTimeout);
|
|
12051
|
-
Object.getOwnPropertyNames(Emittery.prototype).forEach((name) => {
|
|
12052
|
-
const to_bind = this.emitter[name];
|
|
12053
|
-
if (typeof to_bind === "function") {
|
|
12054
|
-
this.emitter[name] = to_bind.bind(this.emitter);
|
|
12055
|
-
}
|
|
12056
|
-
});
|
|
12057
|
-
this.client.on("signal", (signal) => {
|
|
12058
|
-
this.emitter.emit("signal", signal).catch(console.error);
|
|
12059
|
-
});
|
|
12210
|
+
this.defaultTimeout = defaultTimeout === void 0 ? DEFAULT_TIMEOUT : defaultTimeout;
|
|
12060
12211
|
}
|
|
12061
12212
|
/**
|
|
12062
|
-
*
|
|
12213
|
+
* Factory mehtod to create a new instance connected to the given URL.
|
|
12063
12214
|
*
|
|
12064
|
-
* @param token - A token to authenticate the websocket connection. Get a token using AdminWebsocket#issueAppAuthenticationToken.
|
|
12065
12215
|
* @param options - {@link (WebsocketConnectionOptions:interface)}
|
|
12066
|
-
* @returns A
|
|
12216
|
+
* @returns A promise for a new connected instance.
|
|
12067
12217
|
*/
|
|
12068
12218
|
static async connect(options = {}) {
|
|
12069
12219
|
const env = getLauncherEnvironment();
|
|
12070
|
-
if (env?.
|
|
12071
|
-
options.url = new URL(`ws://localhost:${env.
|
|
12220
|
+
if (env?.ADMIN_INTERFACE_PORT) {
|
|
12221
|
+
options.url = new URL(`ws://localhost:${env.ADMIN_INTERFACE_PORT}`);
|
|
12072
12222
|
}
|
|
12073
12223
|
if (!options.url) {
|
|
12074
12224
|
throw new HolochainError("ConnectionUrlMissing", `unable to connect to Conductor API - no url provided and not in a launcher environment.`);
|
|
12075
12225
|
}
|
|
12076
|
-
const
|
|
12077
|
-
|
|
12078
|
-
|
|
12079
|
-
|
|
12080
|
-
|
|
12081
|
-
const appInfo = await AppWebsocket.requester(client, "app_info", DEFAULT_TIMEOUT)(null);
|
|
12082
|
-
if (!appInfo) {
|
|
12083
|
-
throw new HolochainError("AppNotFound", `The app your connection token was issued for was not found. The app needs to be installed and enabled.`);
|
|
12084
|
-
}
|
|
12085
|
-
return new AppWebsocket(client, appInfo, options.callZomeTransform, options.defaultTimeout);
|
|
12226
|
+
const wsClient = await WsClient.connect(options.url, options.wsClientOptions);
|
|
12227
|
+
return new AdminWebsocket(wsClient, options.defaultTimeout);
|
|
12228
|
+
}
|
|
12229
|
+
_requester(tag, transformer) {
|
|
12230
|
+
return requesterTransformer((req, timeout2) => promiseTimeout(this.client.request(req), tag, timeout2 || this.defaultTimeout).then(catchError), tag, transformer);
|
|
12086
12231
|
}
|
|
12087
12232
|
/**
|
|
12088
|
-
*
|
|
12089
|
-
*
|
|
12090
|
-
* @param timeout - A timeout to override the default.
|
|
12091
|
-
* @returns The app's {@link AppInfo}.
|
|
12233
|
+
* Send a request to open the given port for {@link AppWebsocket} connections.
|
|
12092
12234
|
*/
|
|
12093
|
-
|
|
12094
|
-
const appInfo = await this.appInfoRequester(null, timeout2);
|
|
12095
|
-
if (!appInfo) {
|
|
12096
|
-
throw new HolochainError("AppNotFound", `App info not found. App needs to be installed and enabled.`);
|
|
12097
|
-
}
|
|
12098
|
-
this.cachedAppInfo = appInfo;
|
|
12099
|
-
return appInfo;
|
|
12100
|
-
}
|
|
12235
|
+
attachAppInterface = this._requester("attach_app_interface");
|
|
12101
12236
|
/**
|
|
12102
|
-
*
|
|
12103
|
-
*
|
|
12104
|
-
* @returns The conductor's {@link TransportStats}.
|
|
12237
|
+
* Enable a stopped app.
|
|
12105
12238
|
*/
|
|
12106
|
-
|
|
12107
|
-
return await this.dumpNetworkStatsRequester(void 0, timeout2);
|
|
12108
|
-
}
|
|
12239
|
+
enableApp = this._requester("enable_app");
|
|
12109
12240
|
/**
|
|
12110
|
-
*
|
|
12111
|
-
*
|
|
12112
|
-
* @returns The {@link NetworkMetrics}.
|
|
12241
|
+
* Disable a running app.
|
|
12113
12242
|
*/
|
|
12114
|
-
|
|
12115
|
-
return await this.dumpNetworkMetricsRequester(req, timeout2);
|
|
12116
|
-
}
|
|
12243
|
+
disableApp = this._requester("disable_app");
|
|
12117
12244
|
/**
|
|
12118
|
-
*
|
|
12119
|
-
*
|
|
12120
|
-
* @param memproofs - A map of {@link MembraneProof}s.
|
|
12245
|
+
* Dump the state of the specified cell, including its source chain, as JSON.
|
|
12121
12246
|
*/
|
|
12122
|
-
|
|
12123
|
-
await this.provideMemproofRequester(memproofs);
|
|
12124
|
-
}
|
|
12247
|
+
dumpState = this._requester("dump_state", dumpStateTransform);
|
|
12125
12248
|
/**
|
|
12126
|
-
*
|
|
12127
|
-
*
|
|
12249
|
+
* Dump the full state of the specified cell, including its chain and DHT
|
|
12250
|
+
* shard, as JSON.
|
|
12128
12251
|
*/
|
|
12129
|
-
|
|
12130
|
-
await this.enableAppRequester();
|
|
12131
|
-
}
|
|
12252
|
+
dumpFullState = this._requester("dump_full_state");
|
|
12132
12253
|
/**
|
|
12133
|
-
*
|
|
12254
|
+
* Generate a new agent pub key.
|
|
12255
|
+
*/
|
|
12256
|
+
generateAgentPubKey = this._requester("generate_agent_pub_key");
|
|
12257
|
+
/**
|
|
12258
|
+
* Generate a new agent pub key.
|
|
12259
|
+
*/
|
|
12260
|
+
revokeAgentKey = this._requester("revoke_agent_key");
|
|
12261
|
+
/**
|
|
12262
|
+
* Register a DNA for later app installation.
|
|
12134
12263
|
*
|
|
12135
|
-
*
|
|
12136
|
-
|
|
12137
|
-
|
|
12264
|
+
* Stores the given DNA into the Holochain DNA database and returns the hash of it.
|
|
12265
|
+
*/
|
|
12266
|
+
registerDna = this._requester("register_dna");
|
|
12267
|
+
/**
|
|
12268
|
+
* Get the DNA definition for the specified DNA hash.
|
|
12269
|
+
*/
|
|
12270
|
+
getDnaDefinition = this._requester("get_dna_definition");
|
|
12271
|
+
/**
|
|
12272
|
+
* Uninstall the specified app from Holochain.
|
|
12273
|
+
*/
|
|
12274
|
+
uninstallApp = this._requester("uninstall_app");
|
|
12275
|
+
/**
|
|
12276
|
+
* Install the specified app into Holochain.
|
|
12277
|
+
*/
|
|
12278
|
+
installApp = this._requester("install_app");
|
|
12279
|
+
/**
|
|
12280
|
+
* Update coordinators for an installed app.
|
|
12281
|
+
*/
|
|
12282
|
+
updateCoordinators = this._requester("update_coordinators");
|
|
12283
|
+
/**
|
|
12284
|
+
* List all registered DNAs.
|
|
12285
|
+
*/
|
|
12286
|
+
listDnas = this._requester("list_dnas");
|
|
12287
|
+
/**
|
|
12288
|
+
* List all installed cell ids.
|
|
12138
12289
|
*/
|
|
12139
|
-
|
|
12140
|
-
if (isCloneId(roleName)) {
|
|
12141
|
-
const baseRoleName = getBaseRoleNameFromCloneId(roleName);
|
|
12142
|
-
if (!(baseRoleName in appInfo.cell_info)) {
|
|
12143
|
-
throw new HolochainError("NoCellForRoleName", `no cell found with role_name ${roleName}`);
|
|
12144
|
-
}
|
|
12145
|
-
const cloneCell = appInfo.cell_info[baseRoleName].find((c) => c.type === CellType.Cloned && c.value.clone_id === roleName);
|
|
12146
|
-
if (!cloneCell || cloneCell.type !== CellType.Cloned) {
|
|
12147
|
-
throw new HolochainError("NoCellForCloneId", `no clone cell found with clone id ${roleName}`);
|
|
12148
|
-
}
|
|
12149
|
-
return cloneCell.value.cell_id;
|
|
12150
|
-
}
|
|
12151
|
-
if (!(roleName in appInfo.cell_info)) {
|
|
12152
|
-
throw new HolochainError("NoCellForRoleName", `no cell found with role_name ${roleName}`);
|
|
12153
|
-
}
|
|
12154
|
-
const cell = appInfo.cell_info[roleName].find((c) => c.type === CellType.Provisioned);
|
|
12155
|
-
if (!cell || cell.type !== CellType.Provisioned) {
|
|
12156
|
-
throw new HolochainError("NoProvisionedCellForRoleName", `no provisioned cell found with role_name ${roleName}`);
|
|
12157
|
-
}
|
|
12158
|
-
return cell.value.cell_id;
|
|
12159
|
-
}
|
|
12290
|
+
listCellIds = this._requester("list_cell_ids");
|
|
12160
12291
|
/**
|
|
12161
|
-
*
|
|
12162
|
-
*
|
|
12163
|
-
* @param request - The zome call arguments.
|
|
12164
|
-
* @param timeout - A timeout to override the default.
|
|
12165
|
-
* @returns The zome call's response.
|
|
12292
|
+
* List all installed apps.
|
|
12166
12293
|
*/
|
|
12167
|
-
|
|
12168
|
-
if (!("provenance" in request)) {
|
|
12169
|
-
request = {
|
|
12170
|
-
...request,
|
|
12171
|
-
provenance: this.myPubKey
|
|
12172
|
-
};
|
|
12173
|
-
}
|
|
12174
|
-
if ("role_name" in request && request.role_name) {
|
|
12175
|
-
const appInfo = this.cachedAppInfo || await this.appInfo();
|
|
12176
|
-
const cell_id = this.getCellIdFromRoleName(request.role_name, appInfo);
|
|
12177
|
-
request = {
|
|
12178
|
-
...omit(request, "role_name"),
|
|
12179
|
-
// Some problem here with the launcher with just the `cell_id`.
|
|
12180
|
-
cell_id: [cell_id[0], cell_id[1]]
|
|
12181
|
-
};
|
|
12182
|
-
} else if (!("cell_id" in request)) {
|
|
12183
|
-
throw new HolochainError("MissingRoleNameOrCellId", "callZome requires a role_name or cell_id argument");
|
|
12184
|
-
}
|
|
12185
|
-
return this.callZomeRequester(request, timeout2);
|
|
12186
|
-
}
|
|
12294
|
+
listApps = this._requester("list_apps");
|
|
12187
12295
|
/**
|
|
12188
|
-
*
|
|
12189
|
-
*
|
|
12190
|
-
* @param args - Specify the cell to clone.
|
|
12191
|
-
* @returns The created clone cell.
|
|
12296
|
+
* List all attached app interfaces.
|
|
12192
12297
|
*/
|
|
12193
|
-
|
|
12194
|
-
const clonedCell = this.createCloneCellRequester({
|
|
12195
|
-
...args
|
|
12196
|
-
});
|
|
12197
|
-
this.cachedAppInfo = void 0;
|
|
12198
|
-
return clonedCell;
|
|
12199
|
-
}
|
|
12298
|
+
listAppInterfaces = this._requester("list_app_interfaces");
|
|
12200
12299
|
/**
|
|
12201
|
-
*
|
|
12202
|
-
*
|
|
12203
|
-
* @param args - Specify the clone cell to enable.
|
|
12204
|
-
* @returns The enabled clone cell.
|
|
12300
|
+
* Request all available info about an agent.
|
|
12205
12301
|
*/
|
|
12206
|
-
|
|
12207
|
-
return this.enableCloneCellRequester({
|
|
12208
|
-
...args
|
|
12209
|
-
});
|
|
12210
|
-
}
|
|
12302
|
+
agentInfo = this._requester("agent_info");
|
|
12211
12303
|
/**
|
|
12212
|
-
*
|
|
12213
|
-
*
|
|
12214
|
-
* @param args - Specify the clone cell to disable.
|
|
12304
|
+
* Add an existing agent to Holochain.
|
|
12215
12305
|
*/
|
|
12216
|
-
|
|
12217
|
-
return this.disableCloneCellRequester({
|
|
12218
|
-
...args
|
|
12219
|
-
});
|
|
12220
|
-
}
|
|
12306
|
+
addAgentInfo = this._requester("add_agent_info");
|
|
12221
12307
|
/**
|
|
12222
|
-
*
|
|
12308
|
+
* Delete a disabled clone cell.
|
|
12223
12309
|
*/
|
|
12224
|
-
|
|
12225
|
-
return this.getCountersigningSessionStateRequester(args);
|
|
12226
|
-
}
|
|
12310
|
+
deleteCloneCell = this._requester("delete_clone_cell");
|
|
12227
12311
|
/**
|
|
12228
|
-
*
|
|
12229
|
-
*
|
|
12230
|
-
* If the current session has not been resolved automatically, it can be forcefully abandoned.
|
|
12231
|
-
* A condition for this call to succeed is that at least one attempt has been made to resolve
|
|
12232
|
-
* it automatically.
|
|
12233
|
-
*
|
|
12234
|
-
* # Returns
|
|
12235
|
-
*
|
|
12236
|
-
* [`AppResponse::CountersigningSessionAbandoned`]
|
|
12237
|
-
*
|
|
12238
|
-
* The session is marked for abandoning and the countersigning workflow was triggered. The session
|
|
12239
|
-
* has not been abandoned yet.
|
|
12240
|
-
*
|
|
12241
|
-
* Upon successful abandoning the system signal [`SystemSignal::AbandonedCountersigning`] will
|
|
12242
|
-
* be emitted and the session removed from state, so that [`AppRequest::GetCountersigningSessionState`]
|
|
12243
|
-
* would return `None`.
|
|
12244
|
-
*
|
|
12245
|
-
* In the countersigning workflow it will first be attempted to resolve the session with incoming
|
|
12246
|
-
* signatures of the countersigned entries, before force-abandoning the session. In a very rare event
|
|
12247
|
-
* it could happen that in just the moment where the [`AppRequest::AbandonCountersigningSession`]
|
|
12248
|
-
* is made, signatures for this session come in. If they are valid, the session will be resolved and
|
|
12249
|
-
* published as usual. Should they be invalid, however, the flag to abandon the session is erased.
|
|
12250
|
-
* In such cases this request can be retried until the session has been abandoned successfully.
|
|
12251
|
-
*
|
|
12252
|
-
* # Errors
|
|
12253
|
-
*
|
|
12254
|
-
* [`CountersigningError::WorkspaceDoesNotExist`] likely indicates that an invalid cell id was
|
|
12255
|
-
* passed in to the call.
|
|
12256
|
-
*
|
|
12257
|
-
* [`CountersigningError::SessionNotFound`] when no ongoing session could be found for the provided
|
|
12258
|
-
* cell id.
|
|
12259
|
-
*
|
|
12260
|
-
* [`CountersigningError::SessionNotUnresolved`] when an attempt to resolve the session
|
|
12261
|
-
* automatically has not been made.
|
|
12312
|
+
* Grant a zome call capability for an agent, to be used for signing zome
|
|
12313
|
+
* calls.
|
|
12262
12314
|
*/
|
|
12263
|
-
|
|
12264
|
-
|
|
12265
|
-
|
|
12315
|
+
grantZomeCallCapability = this._requester("grant_zome_call_capability");
|
|
12316
|
+
storageInfo = this._requester("storage_info");
|
|
12317
|
+
issueAppAuthenticationToken = this._requester("issue_app_authentication_token");
|
|
12318
|
+
dumpNetworkStats = this._requester("dump_network_stats");
|
|
12319
|
+
dumpNetworkMetrics = this._requester("dump_network_metrics");
|
|
12320
|
+
// zome call signing related methods
|
|
12266
12321
|
/**
|
|
12267
|
-
*
|
|
12268
|
-
*
|
|
12269
|
-
* If the current session has not been resolved automatically, it can be forcefully published.
|
|
12270
|
-
* A condition for this call to succeed is that at least one attempt has been made to resolve
|
|
12271
|
-
* it automatically.
|
|
12272
|
-
*
|
|
12273
|
-
* # Returns
|
|
12274
|
-
*
|
|
12275
|
-
* [`AppResponse::PublishCountersigningSessionTriggered`]
|
|
12276
|
-
*
|
|
12277
|
-
* The session is marked for publishing and the countersigning workflow was triggered. The session
|
|
12278
|
-
* has not been published yet.
|
|
12279
|
-
*
|
|
12280
|
-
* Upon successful publishing the system signal [`SystemSignal::SuccessfulCountersigning`] will
|
|
12281
|
-
* be emitted and the session removed from state, so that [`AppRequest::GetCountersigningSessionState`]
|
|
12282
|
-
* would return `None`.
|
|
12283
|
-
*
|
|
12284
|
-
* In the countersigning workflow it will first be attempted to resolve the session with incoming
|
|
12285
|
-
* signatures of the countersigned entries, before force-publishing the session. In a very rare event
|
|
12286
|
-
* it could happen that in just the moment where the [`AppRequest::PublishCountersigningSession`]
|
|
12287
|
-
* is made, signatures for this session come in. If they are valid, the session will be resolved and
|
|
12288
|
-
* published as usual. Should they be invalid, however, the flag to publish the session is erased.
|
|
12289
|
-
* In such cases this request can be retried until the session has been published successfully.
|
|
12290
|
-
*
|
|
12291
|
-
* # Errors
|
|
12292
|
-
*
|
|
12293
|
-
* [`CountersigningError::WorkspaceDoesNotExist`] likely indicates that an invalid cell id was
|
|
12294
|
-
* passed in to the call.
|
|
12295
|
-
*
|
|
12296
|
-
* [`CountersigningError::SessionNotFound`] when no ongoing session could be found for the provided
|
|
12297
|
-
* cell id.
|
|
12322
|
+
* Grant a capability for signing zome calls.
|
|
12298
12323
|
*
|
|
12299
|
-
*
|
|
12300
|
-
*
|
|
12324
|
+
* @param cellId - The cell to grant the capability for.
|
|
12325
|
+
* @param functions - The zome functions to grant the capability for.
|
|
12326
|
+
* @param signingKey - The assignee of the capability.
|
|
12327
|
+
* @returns The cap secret of the created capability.
|
|
12301
12328
|
*/
|
|
12302
|
-
async
|
|
12303
|
-
|
|
12304
|
-
|
|
12329
|
+
grantSigningKey = async (cellId, functions, signingKey) => {
|
|
12330
|
+
const capSecret = await randomCapSecret();
|
|
12331
|
+
await this.grantZomeCallCapability({
|
|
12332
|
+
cell_id: cellId,
|
|
12333
|
+
cap_grant: {
|
|
12334
|
+
tag: "zome-call-signing-key",
|
|
12335
|
+
functions,
|
|
12336
|
+
access: {
|
|
12337
|
+
type: "assigned",
|
|
12338
|
+
value: {
|
|
12339
|
+
secret: capSecret,
|
|
12340
|
+
assignees: [signingKey]
|
|
12341
|
+
}
|
|
12342
|
+
}
|
|
12343
|
+
}
|
|
12344
|
+
});
|
|
12345
|
+
return capSecret;
|
|
12346
|
+
};
|
|
12305
12347
|
/**
|
|
12306
|
-
*
|
|
12348
|
+
* Generate and authorize a new key pair for signing zome calls.
|
|
12307
12349
|
*
|
|
12308
|
-
* @param
|
|
12309
|
-
* @param
|
|
12310
|
-
*
|
|
12350
|
+
* @param cellId - The cell id to create the capability grant for.
|
|
12351
|
+
* @param functions - Zomes and functions to authorize the signing key for
|
|
12352
|
+
* (optional). When no functions are specified, the capability will be
|
|
12353
|
+
* granted for all zomes and functions.
|
|
12311
12354
|
*/
|
|
12312
|
-
|
|
12313
|
-
|
|
12314
|
-
|
|
12315
|
-
|
|
12316
|
-
|
|
12317
|
-
}
|
|
12355
|
+
authorizeSigningCredentials = async (cellId, functions) => {
|
|
12356
|
+
const [keyPair, signingKey] = await generateSigningKeyPair();
|
|
12357
|
+
const capSecret = await this.grantSigningKey(cellId, functions || { type: "all" }, signingKey);
|
|
12358
|
+
setSigningCredentials(cellId, { capSecret, keyPair, signingKey });
|
|
12359
|
+
};
|
|
12318
12360
|
}
|
|
12319
|
-
const
|
|
12320
|
-
input:
|
|
12321
|
-
|
|
12322
|
-
|
|
12323
|
-
}
|
|
12324
|
-
const hostSigner = getHostZomeCallSigner();
|
|
12325
|
-
if (hostSigner) {
|
|
12326
|
-
return hostSigner.signZomeCall(request);
|
|
12327
|
-
} else {
|
|
12328
|
-
return signZomeCall(request);
|
|
12329
|
-
}
|
|
12330
|
-
},
|
|
12331
|
-
output: (response) => msgpack.decode(response)
|
|
12332
|
-
};
|
|
12333
|
-
const signZomeCall = async (request) => {
|
|
12334
|
-
const signingCredentialsForCell = getSigningCredentials(request.cell_id);
|
|
12335
|
-
if (!signingCredentialsForCell) {
|
|
12336
|
-
throw new HolochainError("NoSigningCredentialsForCell", `no signing credentials have been authorized for cell [${encodeHashToBase64(request.cell_id[0])}, ${encodeHashToBase64(request.cell_id[1])}]`);
|
|
12361
|
+
const dumpStateTransform = {
|
|
12362
|
+
input: (req) => req,
|
|
12363
|
+
output: (res) => {
|
|
12364
|
+
return JSON.parse(res);
|
|
12337
12365
|
}
|
|
12338
|
-
const zome_call_params = {
|
|
12339
|
-
cap_secret: signingCredentialsForCell.capSecret,
|
|
12340
|
-
cell_id: request.cell_id,
|
|
12341
|
-
zome_name: request.zome_name,
|
|
12342
|
-
fn_name: request.fn_name,
|
|
12343
|
-
provenance: signingCredentialsForCell.signingKey,
|
|
12344
|
-
payload: msgpack.encode(request.payload),
|
|
12345
|
-
nonce: await randomNonce(),
|
|
12346
|
-
expires_at: getNonceExpiration()
|
|
12347
|
-
};
|
|
12348
|
-
const bytes = msgpack.encode(zome_call_params);
|
|
12349
|
-
const bytesHash = new Uint8Array(jsSha512.sha512.array(bytes));
|
|
12350
|
-
await _sodium.ready;
|
|
12351
|
-
const sodium = _sodium;
|
|
12352
|
-
const signature = sodium.crypto_sign(bytesHash, signingCredentialsForCell.keyPair.privateKey).subarray(0, sodium.crypto_sign_BYTES);
|
|
12353
|
-
const signedZomeCall = {
|
|
12354
|
-
bytes,
|
|
12355
|
-
signature
|
|
12356
|
-
};
|
|
12357
|
-
return signedZomeCall;
|
|
12358
12366
|
};
|
|
12359
12367
|
var ActionType;
|
|
12360
12368
|
(function(ActionType2) {
|