@holochain/client 0.16.0 → 0.16.2

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
@@ -30,7 +30,7 @@ npm install --save-exact @holochain/client
30
30
 
31
31
  ### Use AppAgentWebsocket with implicit zome call signing
32
32
  ```typescript
33
- import { AdminWebsocket, AppAgentWebsocket, CellType } from "@holochain/client";
33
+ import { ActionHash, AdminWebsocket, AppAgentWebsocket, CellType } from "@holochain/client";
34
34
 
35
35
  const adminWs = await AdminWebsocket.connect("ws://127.0.0.1:65000");
36
36
  const agent_key = await adminWs.generateAgentPubKey();
@@ -54,25 +54,15 @@ const appAgentWs = await AppAgentWebsocket.connect(
54
54
  installed_app_id
55
55
  );
56
56
 
57
- let signalCb;
58
- const signalReceived = new Promise<void>((resolve) => {
59
- signalCb = (signal) => {
60
- console.log("signal received", signal);
61
- // act on signal
62
- resolve();
63
- };
64
- });
65
-
66
- appAgentWs.on("signal", signalCb);
57
+ const zomeCallPayload: CallZomeRequest = {
58
+ cell_id,
59
+ zome_name: "zome_name",
60
+ fn_name: "create_entry",
61
+ provenance: agent_key,
62
+ payload: "some_content",
63
+ };
67
64
 
68
- // trigger an emit_signal
69
- await appAgentWs.callZome({
70
- role_name,
71
- zome_name: "zome",
72
- fn_name: "emitter",
73
- payload: null,
74
- });
75
- await signalReceived;
65
+ const response: ActionHash = await appAgentWs.callZome(zomeCallPayload, 30000);
76
66
 
77
67
  await appAgentWs.appWebsocket.client.close();
78
68
  await adminWs.client.close();
@@ -194,7 +194,7 @@ export type RegisterDnaResponse = HoloHash;
194
194
  */
195
195
  export type DnaModifiers = {
196
196
  network_seed: NetworkSeed;
197
- properties: DnaProperties;
197
+ properties: Uint8Array;
198
198
  origin_time: Timestamp;
199
199
  quantum_time: Duration;
200
200
  };
@@ -382,12 +382,33 @@ export type NetworkSeed = string;
382
382
  * @public
383
383
  */
384
384
  export type InstallAppRequest = {
385
+ /**
386
+ * The agent to use when creating Cells for this App.
387
+ */
385
388
  agent_key: AgentPubKey;
389
+ /**
390
+ * The unique identifier for an installed app in this conductor.
391
+ * If not specified, it will be derived from the app name in the bundle manifest.
392
+ */
386
393
  installed_app_id?: InstalledAppId;
394
+ /**
395
+ * Include proof-of-membrane-membership data for cells that require it,
396
+ * keyed by the CellNick specified in the app bundle manifest.
397
+ */
387
398
  membrane_proofs: {
388
399
  [key: string]: MembraneProof;
389
400
  };
401
+ /**
402
+ * Optional global network seed override. If set will override the network seed value for all
403
+ * DNAs in the bundle.
404
+ */
390
405
  network_seed?: NetworkSeed;
406
+ /**
407
+ * Optional: If app installation fails due to genesis failure, normally the app will be immediately uninstalled.
408
+ * When this flag is set, the app is left installed with empty cells intact. This can be useful for
409
+ * using graft_records_onto_source_chain, or for diagnostics.
410
+ */
411
+ ignore_genesis_failure?: boolean;
391
412
  } & AppBundleSource;
392
413
  /**
393
414
  * @public
@@ -2,7 +2,7 @@ import { hashZomeCall } from "@holochain/serialization";
2
2
  import { decode, encode } from "@msgpack/msgpack";
3
3
  import _sodium from "libsodium-wrappers";
4
4
  import Emittery from "emittery";
5
- import { getLauncherEnvironment, isLauncher, signZomeCallTauri, } from "../../environments/launcher.js";
5
+ import { getLauncherEnvironment, signZomeCallTauri, signZomeCallElectron, } from "../../environments/launcher.js";
6
6
  import { encodeHashToBase64 } from "../../utils/base64.js";
7
7
  import { WsClient } from "../client.js";
8
8
  import { DEFAULT_TIMEOUT, catchError, promiseTimeout, requesterTransformer, } from "../common.js";
@@ -98,10 +98,14 @@ const callZomeTransform = {
98
98
  if ("signature" in request) {
99
99
  return request;
100
100
  }
101
- const signedZomeCall = isLauncher
102
- ? await signZomeCallTauri(request)
103
- : await signZomeCall(request);
104
- return signedZomeCall;
101
+ const env = getLauncherEnvironment();
102
+ if (!env) {
103
+ return signZomeCall(request);
104
+ }
105
+ else if (env.FRAMEWORK === "electron") {
106
+ return signZomeCallElectron(request);
107
+ }
108
+ return signZomeCallTauri(request);
105
109
  },
106
110
  output: (response) => decode(response),
107
111
  };
@@ -1,6 +1,6 @@
1
1
  import { UnsubscribeFunction } from "emittery";
2
2
  import { AgentPubKey, RoleName } from "../../index.js";
3
- import { AppInfoResponse, AppSignal, AppSignalCb, CallZomeRequest, CallZomeRequestSigned, DisableCloneCellRequest, EnableCloneCellRequest, EnableCloneCellResponse } from "../app/index.js";
3
+ import { AppInfoResponse, AppSignal, AppSignalCb, CallZomeRequest, CallZomeRequestSigned, DisableCloneCellRequest, EnableCloneCellRequest, EnableCloneCellResponse, NetworkInfoRequest, NetworkInfoResponse } from "../app/index.js";
4
4
  import { CreateCloneCellRequest, CreateCloneCellResponse, DisableCloneCellResponse } from "../index.js";
5
5
  /**
6
6
  * @public
@@ -34,6 +34,10 @@ export type AppEnableCloneCellRequest = Omit<EnableCloneCellRequest, "app_id">;
34
34
  * @public
35
35
  */
36
36
  export type AppDisableCloneCellRequest = Omit<DisableCloneCellRequest, "app_id">;
37
+ /**
38
+ * @public
39
+ */
40
+ export type AppAgentNetworkInfoRequest = Omit<NetworkInfoRequest, "agent_pub_key">;
37
41
  /**
38
42
  * @public
39
43
  */
@@ -51,4 +55,5 @@ export interface AppAgentClient {
51
55
  createCloneCell(args: AppCreateCloneCellRequest): Promise<CreateCloneCellResponse>;
52
56
  enableCloneCell(args: AppEnableCloneCellRequest): Promise<EnableCloneCellResponse>;
53
57
  disableCloneCell(args: AppDisableCloneCellRequest): Promise<DisableCloneCellResponse>;
58
+ networkInfo(args: AppAgentNetworkInfoRequest): Promise<NetworkInfoResponse>;
54
59
  }
@@ -1,9 +1,9 @@
1
1
  import Emittery, { UnsubscribeFunction } from "emittery";
2
2
  import { AgentPubKey, CellId, InstalledAppId, RoleName } from "../../types.js";
3
3
  import { AppInfo } from "../admin/types.js";
4
- import { AppSignalCb, CallZomeResponse, CreateCloneCellResponse, DisableCloneCellResponse, EnableCloneCellResponse } from "../app/types.js";
4
+ import { AppSignalCb, CallZomeResponse, CreateCloneCellResponse, DisableCloneCellResponse, EnableCloneCellResponse, NetworkInfoResponse } from "../app/types.js";
5
5
  import { AppWebsocket } from "../app/websocket.js";
6
- import { AppAgentCallZomeRequest, AppAgentClient, AppAgentEvents, AppCreateCloneCellRequest, AppDisableCloneCellRequest, AppEnableCloneCellRequest } from "./types.js";
6
+ import { AppAgentCallZomeRequest, AppAgentClient, AppAgentEvents, AppAgentNetworkInfoRequest, AppCreateCloneCellRequest, AppDisableCloneCellRequest, AppEnableCloneCellRequest } from "./types.js";
7
7
  /**
8
8
  * A class to establish a websocket connection to an App interface, for a
9
9
  * specific agent and app.
@@ -68,6 +68,12 @@ export declare class AppAgentWebsocket implements AppAgentClient {
68
68
  * @param args - Specify the clone cell to disable.
69
69
  */
70
70
  disableCloneCell(args: AppDisableCloneCellRequest): Promise<DisableCloneCellResponse>;
71
+ /**
72
+ * Request network info about gossip status.
73
+ * @param args - Specify the DNAs for which you want network info
74
+ * @returns Network info for the specified DNAs
75
+ */
76
+ networkInfo(args: AppAgentNetworkInfoRequest): Promise<NetworkInfoResponse>;
71
77
  /**
72
78
  * Register an event listener for signals.
73
79
  *
@@ -23,8 +23,9 @@ export class AppAgentWebsocket {
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.emitter[name];
26
- if (typeof to_bind === 'function') {
27
- this.emitter[name] = to_bind.bind(this.emitter);
26
+ if (typeof to_bind === "function") {
27
+ this.emitter[name] =
28
+ to_bind.bind(this.emitter);
28
29
  }
29
30
  });
30
31
  const env = getLauncherEnvironment();
@@ -159,6 +160,17 @@ export class AppAgentWebsocket {
159
160
  ...args,
160
161
  });
161
162
  }
163
+ /**
164
+ * Request network info about gossip status.
165
+ * @param args - Specify the DNAs for which you want network info
166
+ * @returns Network info for the specified DNAs
167
+ */
168
+ async networkInfo(args) {
169
+ return this.appWebsocket.networkInfo({
170
+ ...args,
171
+ agent_pub_key: this.myPubKey,
172
+ });
173
+ }
162
174
  /**
163
175
  * Register an event listener for signals.
164
176
  *
@@ -1,18 +1,39 @@
1
1
  import { CallZomeRequest } from "../api/app/types.js";
2
- import { CallZomeRequestSigned } from "../api/app/websocket.js";
2
+ import { CallZomeRequestSigned, CallZomeRequestUnsigned } from "../api/app/websocket.js";
3
3
  import { InstalledAppId } from "../types.js";
4
4
  export interface LauncherEnvironment {
5
5
  APP_INTERFACE_PORT?: number;
6
6
  ADMIN_INTERFACE_PORT?: number;
7
7
  INSTALLED_APP_ID?: InstalledAppId;
8
+ FRAMEWORK?: "tauri" | "electron";
8
9
  }
9
10
  declare const __HC_LAUNCHER_ENV__ = "__HC_LAUNCHER_ENV__";
10
- export declare const isLauncher: boolean;
11
+ export declare const isLauncher: () => boolean;
11
12
  export declare const getLauncherEnvironment: () => LauncherEnvironment | undefined;
12
13
  declare global {
13
14
  interface Window {
14
- [__HC_LAUNCHER_ENV__]: LauncherEnvironment | undefined;
15
+ [__HC_LAUNCHER_ENV__]?: LauncherEnvironment;
16
+ electronAPI?: {
17
+ signZomeCall: (data: CallZomeRequestUnsignedElectron) => CallZomeRequestSignedElectron;
18
+ };
15
19
  }
16
20
  }
21
+ interface CallZomeRequestSignedElectron extends Omit<CallZomeRequestSigned, "cap_secret" | "cell_id" | "provenance" | "nonce" | "zome_name" | "fn_name" | "expires_at"> {
22
+ cellId: [Array<number>, Array<number>];
23
+ provenance: Array<number>;
24
+ zomeName: string;
25
+ fnName: string;
26
+ nonce: Array<number>;
27
+ expiresAt: number;
28
+ }
29
+ interface CallZomeRequestUnsignedElectron extends Omit<CallZomeRequestUnsigned, "cap_secret" | "cell_id" | "provenance" | "nonce" | "zome_name" | "fn_name" | "expires_at"> {
30
+ cellId: [Array<number>, Array<number>];
31
+ provenance: Array<number>;
32
+ zomeName: string;
33
+ fnName: string;
34
+ nonce: Array<number>;
35
+ expiresAt: number;
36
+ }
17
37
  export declare const signZomeCallTauri: (request: CallZomeRequest) => Promise<CallZomeRequestSigned>;
38
+ export declare const signZomeCallElectron: (request: CallZomeRequest) => Promise<CallZomeRequestSigned>;
18
39
  export {};
@@ -2,8 +2,8 @@ import { encode } from "@msgpack/msgpack";
2
2
  import { invoke } from "@tauri-apps/api/tauri";
3
3
  import { getNonceExpiration, randomNonce } from "../api/zome-call-signing.js";
4
4
  const __HC_LAUNCHER_ENV__ = "__HC_LAUNCHER_ENV__";
5
- export const isLauncher = globalThis.window && __HC_LAUNCHER_ENV__ in globalThis.window;
6
- export const getLauncherEnvironment = () => isLauncher ? globalThis.window[__HC_LAUNCHER_ENV__] : undefined;
5
+ export const isLauncher = () => globalThis.window && __HC_LAUNCHER_ENV__ in globalThis.window;
6
+ export const getLauncherEnvironment = () => isLauncher() ? globalThis.window[__HC_LAUNCHER_ENV__] : undefined;
7
7
  export const signZomeCallTauri = async (request) => {
8
8
  const zomeCallUnsigned = {
9
9
  provenance: Array.from(request.provenance),
@@ -31,3 +31,33 @@ export const signZomeCallTauri = async (request) => {
31
31
  };
32
32
  return signedZomeCall;
33
33
  };
34
+ export const signZomeCallElectron = async (request) => {
35
+ if (!window.electronAPI) {
36
+ throw Error("Unable to signZomeCallElectron. window.electronAPI not defined");
37
+ }
38
+ const zomeCallUnsignedElectron = {
39
+ provenance: Array.from(request.provenance),
40
+ cellId: [Array.from(request.cell_id[0]), Array.from(request.cell_id[1])],
41
+ zomeName: request.zome_name,
42
+ fnName: request.fn_name,
43
+ payload: Array.from(encode(request.payload)),
44
+ nonce: Array.from(await randomNonce()),
45
+ expiresAt: getNonceExpiration(),
46
+ };
47
+ const zomeCallSignedElectron = await window.electronAPI.signZomeCall(zomeCallUnsignedElectron);
48
+ const zomeCallSigned = {
49
+ provenance: Uint8Array.from(zomeCallSignedElectron.provenance),
50
+ cap_secret: null,
51
+ cell_id: [
52
+ Uint8Array.from(zomeCallSignedElectron.cellId[0]),
53
+ Uint8Array.from(zomeCallSignedElectron.cellId[1]),
54
+ ],
55
+ zome_name: zomeCallSignedElectron.zomeName,
56
+ fn_name: zomeCallSignedElectron.fnName,
57
+ payload: Uint8Array.from(zomeCallSignedElectron.payload),
58
+ signature: Uint8Array.from(zomeCallSignedElectron.signature),
59
+ expires_at: zomeCallSignedElectron.expiresAt,
60
+ nonce: Uint8Array.from(zomeCallSignedElectron.nonce),
61
+ };
62
+ return zomeCallSigned;
63
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holochain/client",
3
- "version": "0.16.0",
3
+ "version": "0.16.2",
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",
@@ -40,34 +40,32 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@holochain/serialization": "^0.1.0-beta-rc.3",
43
- "@msgpack/msgpack": "^2.7.2",
44
- "@noble/ed25519": "^2.0.0",
45
- "@tauri-apps/api": "^1.2.0",
43
+ "@msgpack/msgpack": "^2.8.0",
44
+ "@tauri-apps/api": "^1.4.0",
46
45
  "emittery": "^1.0.1",
47
46
  "isomorphic-ws": "^5.0.0",
48
- "js-base64": "^3.7.3",
49
- "libsodium-wrappers": "^0.7.11",
47
+ "js-base64": "^3.7.5",
48
+ "libsodium-wrappers": "^0.7.13",
50
49
  "lodash-es": "^4.17.21",
51
- "ws": "^8.13.0"
50
+ "ws": "^8.14.2"
52
51
  },
53
52
  "devDependencies": {
54
53
  "@microsoft/api-documenter": "^7.21.7",
55
54
  "@microsoft/api-extractor": "^7.34.4",
56
- "@types/js-yaml": "^3.12.7",
57
- "@types/libsodium-wrappers": "^0.7.10",
55
+ "@types/libsodium-wrappers": "^0.7.11",
58
56
  "@types/lodash-es": "^4.17.6",
59
57
  "@types/tape": "^4.13.2",
60
- "@types/ws": "^8.5.3",
58
+ "@types/ws": "^8.5.5",
61
59
  "@typescript-eslint/eslint-plugin": "^5.62.0",
62
60
  "@typescript-eslint/parser": "^5.62.0",
63
- "eslint": "^8.46.0",
61
+ "eslint": "^8.49.0",
64
62
  "eslint-config-prettier": "^8.10.0",
65
63
  "eslint-plugin-prettier": "^4.2.1",
66
64
  "eslint-plugin-tsdoc": "^0.2.17",
67
65
  "js-yaml": "^3.14.1",
68
66
  "prettier": "^2.8.8",
69
67
  "rimraf": "^3.0.2",
70
- "tape": "^5.5.3",
68
+ "tape": "^5.6.6",
71
69
  "ts-node": "^10.9.1",
72
70
  "typescript": "^4.9.5"
73
71
  }