@holochain/client 0.15.1 → 0.16.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/README.md CHANGED
@@ -13,14 +13,11 @@ A JavaScript client for the Holochain Conductor API (works with browsers as well
13
13
 
14
14
  [Complete API reference](./docs/client.md)
15
15
 
16
- ## Compatibility
16
+ ## Installation
17
17
 
18
18
  **JS client v0.12.x** is compatible with **Holochain v0.1.x**.
19
19
 
20
- **JS client v0.14.x** is compatible with **Holochain v0.2.x**.
21
- *As target, ES2020 or higher is required when bundling for production*.
22
-
23
- ## Installation
20
+ **JS client v0.16.x** are compatible with **Holochain v0.2.x**.
24
21
 
25
22
  To install from NPM, run
26
23
  ```bash
@@ -157,13 +154,6 @@ setSigningCredentials(cell_id, signingCredentials);
157
154
  localStorage.setItem(cellIdB64, JSON.stringify(signingCredentials));
158
155
  ```
159
156
 
160
- # Holochain Compatibility
161
-
162
- See [default.nix](./default.nix) for the Holochain version this package is compatible with.
163
-
164
- If updating the Holochain version included in holonix, please use `niv update` as explained in the
165
- [Holochain Installation Guide](https://developer.holochain.org/install-advanced/#upgrading-the-holochain-version).
166
-
167
157
  ## Running tests
168
158
 
169
159
  You need a version (`stable` toolchain) of Rust available.
@@ -134,7 +134,7 @@ export class AdminWebsocket {
134
134
  * @returns The cap secret of the created capability.
135
135
  */
136
136
  grantSigningKey = async (cellId, functions, signingKey) => {
137
- const capSecret = randomCapSecret();
137
+ const capSecret = await randomCapSecret();
138
138
  await this.grantZomeCallCapability({
139
139
  cell_id: cellId,
140
140
  cap_grant: {
@@ -1,6 +1,6 @@
1
1
  import { hashZomeCall } from "@holochain/serialization";
2
2
  import { decode, encode } from "@msgpack/msgpack";
3
- import * as ed25519 from "@noble/ed25519";
3
+ import _sodium from "libsodium-wrappers";
4
4
  import Emittery from "emittery";
5
5
  import { getLauncherEnvironment, isLauncher, signZomeCallTauri, } from "../../environments/launcher.js";
6
6
  import { encodeHashToBase64 } from "../../utils/base64.js";
@@ -23,8 +23,9 @@ export class AppWebsocket extends Emittery {
23
23
  // Please retain until the upstream is fixed https://github.com/sindresorhus/emittery/issues/86.
24
24
  Object.getOwnPropertyNames(Emittery.prototype).forEach((name) => {
25
25
  const to_bind = this[name];
26
- if (typeof to_bind === 'function') {
27
- this[name] = to_bind.bind(this);
26
+ if (typeof to_bind === "function") {
27
+ this[name] =
28
+ to_bind.bind(this);
28
29
  }
29
30
  });
30
31
  this.client = client;
@@ -130,11 +131,15 @@ export const signZomeCall = async (request) => {
130
131
  fn_name: request.fn_name,
131
132
  provenance: signingCredentialsForCell.signingKey,
132
133
  payload: encode(request.payload),
133
- nonce: randomNonce(),
134
+ nonce: await randomNonce(),
134
135
  expires_at: getNonceExpiration(),
135
136
  };
136
137
  const hashedZomeCall = await hashZomeCall(unsignedZomeCallPayload);
137
- const signature = await ed25519.signAsync(hashedZomeCall, signingCredentialsForCell.keyPair.privateKey);
138
+ await _sodium.ready;
139
+ const sodium = _sodium;
140
+ const signature = sodium
141
+ .crypto_sign(hashedZomeCall, signingCredentialsForCell.keyPair.privateKey)
142
+ .subarray(0, sodium.crypto_sign_BYTES);
138
143
  const signedZomeCall = {
139
144
  ...unsignedZomeCallPayload,
140
145
  signature,
@@ -1,16 +1,10 @@
1
- import { CapSecret } from "../hdk/capabilities.js";
2
- import { AgentPubKey, CellId } from "../types.js";
1
+ import { type KeyPair } from "libsodium-wrappers";
2
+ import type { CapSecret } from "../hdk/capabilities.js";
3
+ import type { AgentPubKey, CellId } from "../types.js";
3
4
  /**
4
5
  * @public
5
6
  */
6
7
  export type Nonce256Bit = Uint8Array;
7
- /**
8
- * @public
9
- */
10
- export interface KeyPair {
11
- privateKey: Uint8Array;
12
- publicKey: Uint8Array;
13
- }
14
8
  /**
15
9
  * @public
16
10
  */
@@ -39,26 +33,25 @@ export declare const setSigningCredentials: (cellId: CellId, credentials: Signin
39
33
  /**
40
34
  * Generates a key pair for signing zome calls.
41
35
  *
36
+ * @param agentPubKey - The agent pub key to take 4 last bytes (= DHT location)
37
+ * from (optional).
42
38
  * @returns The signing key pair and an agent pub key based on the public key.
43
39
  *
44
40
  * @public
45
41
  */
46
- export declare const generateSigningKeyPair: () => Promise<[
47
- KeyPair,
48
- AgentPubKey
49
- ]>;
42
+ export declare const generateSigningKeyPair: (agentPubKey?: AgentPubKey) => Promise<[KeyPair, AgentPubKey]>;
50
43
  /**
51
44
  * @public
52
45
  */
53
- export declare const randomCapSecret: () => CapSecret;
46
+ export declare const randomCapSecret: () => Promise<CapSecret>;
54
47
  /**
55
48
  * @public
56
49
  */
57
- export declare const randomNonce: () => Nonce256Bit;
50
+ export declare const randomNonce: () => Promise<Nonce256Bit>;
58
51
  /**
59
52
  * @public
60
53
  */
61
- export declare const randomByteArray: (length: number) => Uint8Array;
54
+ export declare const randomByteArray: (length: number) => Promise<Uint8Array>;
62
55
  /**
63
56
  * @public
64
57
  */
@@ -1,8 +1,5 @@
1
- import * as ed25519 from "@noble/ed25519";
1
+ import _sodium from "libsodium-wrappers";
2
2
  import { encodeHashToBase64 } from "../utils/base64.js";
3
- if (!globalThis.crypto) {
4
- import("node:crypto").then((webcrypto) => (globalThis.crypto = webcrypto));
5
- }
6
3
  const signingCredentials = new Map();
7
4
  /**
8
5
  * Get credentials for signing zome calls.
@@ -30,29 +27,39 @@ export const setSigningCredentials = (cellId, credentials) => {
30
27
  /**
31
28
  * Generates a key pair for signing zome calls.
32
29
  *
30
+ * @param agentPubKey - The agent pub key to take 4 last bytes (= DHT location)
31
+ * from (optional).
33
32
  * @returns The signing key pair and an agent pub key based on the public key.
34
33
  *
35
34
  * @public
36
35
  */
37
- export const generateSigningKeyPair = async () => {
38
- const privateKey = ed25519.utils.randomPrivateKey();
39
- const publicKey = await ed25519.getPublicKeyAsync(privateKey);
40
- const keyPair = { privateKey, publicKey };
41
- const signingKey = new Uint8Array([132, 32, 36].concat(...publicKey).concat(...[0, 0, 0, 0]));
36
+ export const generateSigningKeyPair = async (agentPubKey) => {
37
+ await _sodium.ready;
38
+ const sodium = _sodium;
39
+ const keyPair = sodium.crypto_sign_keypair();
40
+ const locationBytes = agentPubKey ? agentPubKey.subarray(35) : [0, 0, 0, 0];
41
+ const signingKey = new Uint8Array([132, 32, 36].concat(...keyPair.publicKey).concat(...locationBytes));
42
42
  return [keyPair, signingKey];
43
43
  };
44
44
  /**
45
45
  * @public
46
46
  */
47
- export const randomCapSecret = () => randomByteArray(64);
47
+ export const randomCapSecret = async () => randomByteArray(64);
48
48
  /**
49
49
  * @public
50
50
  */
51
- export const randomNonce = () => randomByteArray(32);
51
+ export const randomNonce = async () => randomByteArray(32);
52
52
  /**
53
53
  * @public
54
54
  */
55
- export const randomByteArray = (length) => globalThis.crypto.getRandomValues(new Uint8Array(length));
55
+ export const randomByteArray = async (length) => {
56
+ if (globalThis.crypto && "getRandomValues" in globalThis.crypto) {
57
+ return globalThis.crypto.getRandomValues(new Uint8Array(length));
58
+ }
59
+ await _sodium.ready;
60
+ const sodium = _sodium;
61
+ return sodium.randombytes_buf(length);
62
+ };
56
63
  /**
57
64
  * @public
58
65
  */
@@ -11,7 +11,7 @@ export const signZomeCallTauri = async (request) => {
11
11
  zome_name: request.zome_name,
12
12
  fn_name: request.fn_name,
13
13
  payload: Array.from(encode(request.payload)),
14
- nonce: Array.from(randomNonce()),
14
+ nonce: Array.from(await randomNonce()),
15
15
  expires_at: getNonceExpiration(),
16
16
  };
17
17
  const signedZomeCallTauri = await invoke("sign_zome_call", { zomeCallUnsigned });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holochain/client",
3
- "version": "0.15.1",
3
+ "version": "0.16.0",
4
4
  "description": "A JavaScript client for the Holochain Conductor API",
5
5
  "author": "Holochain Foundation <info@holochain.org> (http://holochain.org)",
6
6
  "license": "CAL-1.0",
@@ -46,6 +46,7 @@
46
46
  "emittery": "^1.0.1",
47
47
  "isomorphic-ws": "^5.0.0",
48
48
  "js-base64": "^3.7.3",
49
+ "libsodium-wrappers": "^0.7.11",
49
50
  "lodash-es": "^4.17.21",
50
51
  "ws": "^8.13.0"
51
52
  },
@@ -53,17 +54,18 @@
53
54
  "@microsoft/api-documenter": "^7.21.7",
54
55
  "@microsoft/api-extractor": "^7.34.4",
55
56
  "@types/js-yaml": "^3.12.7",
57
+ "@types/libsodium-wrappers": "^0.7.10",
56
58
  "@types/lodash-es": "^4.17.6",
57
59
  "@types/tape": "^4.13.2",
58
60
  "@types/ws": "^8.5.3",
59
- "@typescript-eslint/eslint-plugin": "^5.27.0",
60
- "@typescript-eslint/parser": "^5.27.0",
61
- "eslint": "^8.16.0",
62
- "eslint-config-prettier": "^8.5.0",
63
- "eslint-plugin-prettier": "^4.0.0",
64
- "eslint-plugin-tsdoc": "^0.2.16",
61
+ "@typescript-eslint/eslint-plugin": "^5.62.0",
62
+ "@typescript-eslint/parser": "^5.62.0",
63
+ "eslint": "^8.46.0",
64
+ "eslint-config-prettier": "^8.10.0",
65
+ "eslint-plugin-prettier": "^4.2.1",
66
+ "eslint-plugin-tsdoc": "^0.2.17",
65
67
  "js-yaml": "^3.14.1",
66
- "prettier": "^2.6.2",
68
+ "prettier": "^2.8.8",
67
69
  "rimraf": "^3.0.2",
68
70
  "tape": "^5.5.3",
69
71
  "ts-node": "^10.9.1",