@holochain/client 0.18.0-dev.1 → 0.18.0-dev.11

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,64 +30,92 @@ npm install --save-exact @holochain/client
30
30
 
31
31
  ## Sample usage
32
32
 
33
- ### Use AppAgentWebsocket with implicit zome call signing
33
+ ### Use AppWebsocket with implicit zome call signing
34
34
  ```typescript
35
- import { ActionHash, AdminWebsocket, AppAgentWebsocket, CellType } from "@holochain/client";
36
-
37
- const adminWs = await AdminWebsocket.connect({url: "ws://127.0.0.1:65000"});
35
+ import {
36
+ AdminWebsocket,
37
+ AppWebsocket,
38
+ CellType,
39
+ type ActionHash,
40
+ type CallZomeRequest,
41
+ } from "@holochain/client";
42
+
43
+ const adminWs = await AdminWebsocket.connect({
44
+ url: new URL("ws://127.0.0.1:65000"),
45
+ wsClientOptions: { origin: "my-happ" },
46
+ });
38
47
  const agent_key = await adminWs.generateAgentPubKey();
39
- const role_name = "role";
48
+ const role_name = "foo";
40
49
  const installed_app_id = "test-app";
41
50
  const appInfo = await adminWs.installApp({
42
51
  agent_key,
43
- path: "path/to/happ/file",
52
+ path: "./test/e2e/fixture/test.happ",
44
53
  installed_app_id,
45
54
  membrane_proofs: {},
46
55
  });
47
56
  await adminWs.enableApp({ installed_app_id });
48
57
  if (!(CellType.Provisioned in appInfo.cell_info[role_name][0])) {
49
- process.exit();
58
+ throw new Error(`No cell found under role name ${role_name}`);
50
59
  }
51
60
  const { cell_id } = appInfo.cell_info[role_name][0][CellType.Provisioned];
52
61
  await adminWs.authorizeSigningCredentials(cell_id);
53
- await adminWs.attachAppInterface({ port: 65001 });
54
- const appAgentWs = await AppAgentWebsocket.connect(installed_app_id, {url: "ws://127.0.0.1:65001"});
62
+ await adminWs.attachAppInterface({ port: 65001, allowed_origins: "my-happ" });
63
+ const issuedToken = await adminWs.issueAppAuthenticationToken({
64
+ installed_app_id,
65
+ });
66
+ const appWs = await AppWebsocket.connect({
67
+ url: new URL("ws://127.0.0.1:65001"),
68
+ token: issuedToken.token,
69
+ wsClientOptions: { origin: "my-happ" },
70
+ });
55
71
 
56
72
  const zomeCallPayload: CallZomeRequest = {
57
73
  cell_id,
58
- zome_name: "zome_name",
59
- fn_name: "create_entry",
74
+ zome_name: "foo",
75
+ fn_name: "foo",
60
76
  provenance: agent_key,
61
- payload: "some_content",
77
+ payload: null,
62
78
  };
63
79
 
64
- const response: ActionHash = await appAgentWs.callZome(zomeCallPayload, 30000);
80
+ const response: ActionHash = await appWs.callZome(zomeCallPayload, 30000);
81
+ console.log("zome call response is", response);
65
82
 
66
- await appAgentWs.appWebsocket.client.close();
83
+ await appWs.client.close();
67
84
  await adminWs.client.close();
68
85
  ```
69
86
 
70
- ### Use AppWebsocket with implicit zome call signing
87
+ ### Subscribe to signals
71
88
  ```typescript
72
89
  import { AdminWebsocket, AppWebsocket, CellType } from "@holochain/client";
73
90
 
74
- const adminWs = await AdminWebsocket.connect({url: "ws://127.0.0.1:65000"});
91
+ const adminWs = await AdminWebsocket.connect({
92
+ url: new URL("ws://127.0.0.1:65000"),
93
+ wsClientOptions: { origin: "my-happ" },
94
+ });
75
95
  const agent_key = await adminWs.generateAgentPubKey();
96
+ const role_name = "foo";
76
97
  const installed_app_id = "test-app";
77
98
  const appInfo = await adminWs.installApp({
78
99
  agent_key,
79
- path: "path/to/happ/file",
100
+ path: "./test/e2e/fixture/test.happ",
80
101
  installed_app_id,
81
102
  membrane_proofs: {},
82
103
  });
83
104
  await adminWs.enableApp({ installed_app_id });
84
- if (!(CellType.Provisioned in appInfo.cell_info["role"][0])) {
85
- process.exit();
105
+ if (!(CellType.Provisioned in appInfo.cell_info[role_name][0])) {
106
+ throw new Error(`No cell found under role name ${role_name}`);
86
107
  }
87
- const { cell_id } = appInfo.cell_info["role"][0][CellType.Provisioned];
108
+ const { cell_id } = appInfo.cell_info[role_name][0][CellType.Provisioned];
88
109
  await adminWs.authorizeSigningCredentials(cell_id);
89
- await adminWs.attachAppInterface({ port: 65001 });
90
- const appWs = await AppWebsocket.connect({url: "ws://127.0.0.1:65001"});
110
+ await adminWs.attachAppInterface({ port: 65001, allowed_origins: "my-happ" });
111
+ const issuedToken = await adminWs.issueAppAuthenticationToken({
112
+ installed_app_id,
113
+ });
114
+ const appWs = await AppWebsocket.connect({
115
+ url: new URL("ws://127.0.0.1:65001"),
116
+ token: issuedToken.token,
117
+ wsClientOptions: { origin: "my-happ" },
118
+ });
91
119
 
92
120
  let signalCb;
93
121
  const signalReceived = new Promise<void>((resolve) => {
@@ -103,7 +131,7 @@ appWs.on("signal", signalCb);
103
131
  // trigger an emit_signal
104
132
  await appWs.callZome({
105
133
  cell_id,
106
- zome_name: "zome",
134
+ zome_name: "foo",
107
135
  fn_name: "emitter",
108
136
  provenance: agent_key,
109
137
  payload: null,
@@ -165,7 +193,7 @@ Holochain is an open source project. We welcome all sorts of participation and
165
193
 
166
194
  [![License: CAL 1.0](https://img.shields.io/badge/License-CAL%201.0-blue.svg)](https://github.com/holochain/cryptographic-autonomy-license)
167
195
 
168
- Copyright (C) 2020-2023, Holochain Foundation
196
+ Copyright (C) 2020-2024, Holochain Foundation
169
197
 
170
198
  This program is free software: you can redistribute it and/or modify it under the terms of the license
171
199
  provided in the LICENSE file (CAL-1.0). This program is distributed in the hope that it will be useful,
@@ -1,5 +1,5 @@
1
1
  import { Action, DhtOp, Entry, ZomeCallCapGrant } from "../../hdk/index.js";
2
- import { ActionHash, AgentPubKey, CellId, DnaHash, DnaProperties, Duration, HoloHash, HoloHashB64, InstalledAppId, KitsuneAgent, KitsuneSpace, RoleName, Signature, Timestamp, WasmHash } from "../../types.js";
2
+ import { ActionHash, AgentPubKey, CellId, DnaHash, DnaHashB64, DnaProperties, Duration, HoloHash, HoloHashB64, InstalledAppId, KitsuneAgent, KitsuneSpace, RoleName, Signature, Timestamp, WasmHash } from "../../types.js";
3
3
  import { Requester } from "../common.js";
4
4
  /**
5
5
  * @public
@@ -52,7 +52,7 @@ export type PausedAppReason = {
52
52
  /**
53
53
  * @public
54
54
  */
55
- export type DisabledAppReason = "never_started" | "user" | {
55
+ export type DisabledAppReason = "never_started" | "user" | "not_started_after_providing_memproofs" | {
56
56
  error: string;
57
57
  };
58
58
  /**
@@ -66,7 +66,7 @@ export type InstalledAppInfoStatus = {
66
66
  disabled: {
67
67
  reason: DisabledAppReason;
68
68
  };
69
- } | "running";
69
+ } | "awaiting_memproofs" | "running";
70
70
  /**
71
71
  * @public
72
72
  */
@@ -125,6 +125,12 @@ export type AppInfo = {
125
125
  * @public
126
126
  */
127
127
  export type MembraneProof = Uint8Array;
128
+ /**
129
+ * @public
130
+ */
131
+ export type MemproofMap = {
132
+ [key: string]: MembraneProof;
133
+ };
128
134
  /**
129
135
  * @public
130
136
  */
@@ -228,6 +234,7 @@ export type CoordinatorZome = ZomeDefinition;
228
234
  export type DnaDefinition = {
229
235
  name: string;
230
236
  modifiers: DnaModifiers;
237
+ lineage: DnaHashB64[];
231
238
  integrity_zomes: IntegrityZome[];
232
239
  coordinator_zomes: CoordinatorZome[];
233
240
  };
@@ -239,6 +246,14 @@ export type GetDnaDefinitionRequest = DnaHash;
239
246
  * @public
240
247
  */
241
248
  export type GetDnaDefinitionResponse = DnaDefinition;
249
+ /**
250
+ * @public
251
+ */
252
+ export type GetCompatibleCellsRequest = DnaHashB64;
253
+ /**
254
+ * @public
255
+ */
256
+ export type GetCompatibleCellsResponse = Set<[InstalledAppId, Set<CellId>]>;
242
257
  /**
243
258
  * @public
244
259
  */
@@ -356,6 +371,7 @@ export type AppManifest = {
356
371
  name: string;
357
372
  description?: string;
358
373
  roles: Array<AppRoleManifest>;
374
+ membrane_proofs_deferred: boolean;
359
375
  };
360
376
  /**
361
377
  * @public
@@ -382,8 +398,11 @@ export type NetworkSeed = string;
382
398
  export type InstallAppRequest = {
383
399
  /**
384
400
  * The agent to use when creating Cells for this App.
401
+ * If not specified, a new agent will be generated by Holochain.
402
+ * If DPKI is enabled (default), and the agent key is not specified here,
403
+ * a new agent key will be derived from the DPKI device seed and registered with DPKI.
385
404
  */
386
- agent_key: AgentPubKey;
405
+ agent_key?: AgentPubKey;
387
406
  /**
388
407
  * The unique identifier for an installed app in this conductor.
389
408
  * If not specified, it will be derived from the app name in the bundle manifest.
@@ -393,9 +412,7 @@ export type InstallAppRequest = {
393
412
  * Include proof-of-membrane-membership data for cells that require it,
394
413
  * keyed by the CellNick specified in the app bundle manifest.
395
414
  */
396
- membrane_proofs: {
397
- [key: string]: MembraneProof;
398
- };
415
+ membrane_proofs: MemproofMap;
399
416
  /**
400
417
  * Optional global network seed override. If set will override the network seed value for all
401
418
  * DNAs in the bundle.
@@ -509,7 +526,7 @@ export interface DeleteCloneCellRequest {
509
526
  /**
510
527
  * The clone id or cell id of the clone cell
511
528
  */
512
- clone_cell_id: RoleName | CellId;
529
+ clone_cell_id: RoleName | DnaHash;
513
530
  }
514
531
  /**
515
532
  * @public
@@ -605,6 +622,26 @@ export type DnaManifest = {
605
622
  * The order is significant: it determines initialization order.
606
623
  */
607
624
  zomes: Array<ZomeManifest>;
625
+ /**
626
+ * A list of past "ancestors" of this DNA.
627
+ *
628
+ * Whenever a DNA is created which is intended to be used as a migration from
629
+ * a previous DNA, the lineage should be updated to include the hash of the
630
+ * DNA being migrated from. DNA hashes may also be removed from this list if
631
+ * it is desired to remove them from the lineage.
632
+ *
633
+ * The meaning of the "ancestor" relationship is as follows:
634
+ * - For any DNA, there is a migration path from any of its ancestors to itself.
635
+ * - When an app depends on a DnaHash via UseExisting, it means that any installed
636
+ * DNA in the lineage which contains that DnaHash can be used.
637
+ * - The app's Coordinator interface is expected to be compatible across the lineage.
638
+ * (Though this cannot be enforced, since Coordinators can be swapped out at
639
+ * will by the user, the intention is still there.)
640
+ *
641
+ * Holochain does nothing to ensure the correctness of the lineage, it is up to
642
+ * the app developer to make the necessary guarantees.
643
+ */
644
+ lineage: DnaHashB64[];
608
645
  };
609
646
  /**
610
647
  * @public
@@ -2,7 +2,7 @@ import { CapSecret, GrantedFunctions } from "../../hdk/index.js";
2
2
  import type { AgentPubKey, CellId } from "../../types.js";
3
3
  import { WsClient } from "../client.js";
4
4
  import { Requester, Transformer, WebsocketConnectionOptions } from "../common.js";
5
- import { AddAgentInfoRequest, AddAgentInfoResponse, AdminApi, AgentInfoRequest, AgentInfoResponse, AttachAppInterfaceRequest, AttachAppInterfaceResponse, DeleteCloneCellRequest, DeleteCloneCellResponse, DisableAppRequest, DisableAppResponse, DumpFullStateRequest, DumpFullStateResponse, DumpNetworkStatsRequest, DumpNetworkStatsResponse, DumpStateRequest, DumpStateResponse, EnableAppRequest, EnableAppResponse, GenerateAgentPubKeyRequest, GenerateAgentPubKeyResponse, GetDnaDefinitionRequest, GetDnaDefinitionResponse, GrantZomeCallCapabilityRequest, GrantZomeCallCapabilityResponse, InstallAppRequest, InstallAppResponse, IssueAppAuthenticationTokenRequest, IssueAppAuthenticationTokenResponse, ListAppInterfacesRequest, ListAppInterfacesResponse, ListAppsRequest, ListAppsResponse, ListCellIdsRequest, ListCellIdsResponse, ListDnasRequest, ListDnasResponse, RegisterDnaRequest, RegisterDnaResponse, StorageInfoRequest, StorageInfoResponse, UninstallAppRequest, UninstallAppResponse, UpdateCoordinatorsRequest, UpdateCoordinatorsResponse } from "./types.js";
5
+ import { AddAgentInfoRequest, AddAgentInfoResponse, AdminApi, AgentInfoRequest, AgentInfoResponse, AttachAppInterfaceRequest, AttachAppInterfaceResponse, DeleteCloneCellRequest, DeleteCloneCellResponse, DisableAppRequest, DisableAppResponse, DumpFullStateRequest, DumpFullStateResponse, DumpNetworkStatsRequest, DumpNetworkStatsResponse, DumpStateRequest, DumpStateResponse, EnableAppRequest, EnableAppResponse, GenerateAgentPubKeyRequest, GenerateAgentPubKeyResponse, GetCompatibleCellsRequest, GetCompatibleCellsResponse, GetDnaDefinitionRequest, GetDnaDefinitionResponse, GrantZomeCallCapabilityRequest, GrantZomeCallCapabilityResponse, InstallAppRequest, InstallAppResponse, IssueAppAuthenticationTokenRequest, IssueAppAuthenticationTokenResponse, ListAppInterfacesRequest, ListAppInterfacesResponse, ListAppsRequest, ListAppsResponse, ListCellIdsRequest, ListCellIdsResponse, ListDnasRequest, ListDnasResponse, RegisterDnaRequest, RegisterDnaResponse, StorageInfoRequest, StorageInfoResponse, UninstallAppRequest, UninstallAppResponse, UpdateCoordinatorsRequest, UpdateCoordinatorsResponse } from "./types.js";
6
6
  /**
7
7
  * A class for interacting with a conductor's Admin API.
8
8
  *
@@ -61,6 +61,7 @@ export declare class AdminWebsocket implements AdminApi {
61
61
  * Get the DNA definition for the specified DNA hash.
62
62
  */
63
63
  getDnaDefinition: Requester<GetDnaDefinitionRequest, GetDnaDefinitionResponse>;
64
+ getCompatibleCells: Requester<GetCompatibleCellsRequest, GetCompatibleCellsResponse>;
64
65
  /**
65
66
  * Uninstall the specified app from Holochain.
66
67
  */
@@ -78,6 +78,9 @@ export class AdminWebsocket {
78
78
  * Get the DNA definition for the specified DNA hash.
79
79
  */
80
80
  getDnaDefinition = this._requester("get_dna_definition");
81
+ /// Find installed cells which use a DNA that's forward-compatible with the given DNA hash.
82
+ /// Namely, this finds cells with DNAs whose manifest lists the given DNA hash in its `lineage` field.
83
+ getCompatibleCells = this._requester("get_compatible_cells");
81
84
  /**
82
85
  * Uninstall the specified app from Holochain.
83
86
  */
@@ -1,5 +1,5 @@
1
1
  import { UnsubscribeFunction } from "emittery";
2
- import { AgentPubKey, AppAuthenticationToken, AppInfo, CapSecret, CellId, ClonedCell, DnaHash, DnaProperties, FunctionName, InstalledAppId, MembraneProof, NetworkInfo, NetworkSeed, Nonce256Bit, RoleName, Timestamp, Transformer, WebsocketConnectionOptions, ZomeName } from "../../index.js";
2
+ import { AgentPubKey, AppAuthenticationToken, AppInfo, CapSecret, CellId, ClonedCell, DnaHash, DnaProperties, EntryHash, FunctionName, InstalledAppId, MembraneProof, MemproofMap, NetworkInfo, NetworkSeed, Nonce256Bit, RoleName, Timestamp, Transformer, WebsocketConnectionOptions, ZomeName } from "../../index.js";
3
3
  /**
4
4
  * @public
5
5
  */
@@ -40,7 +40,7 @@ export type AppNetworkInfoRequest = Omit<NetworkInfoRequest, "agent_pub_key">;
40
40
  * @public
41
41
  */
42
42
  export interface AppEvents {
43
- signal: AppSignal;
43
+ signal: Signal;
44
44
  }
45
45
  /**
46
46
  * @public
@@ -82,6 +82,22 @@ export type CallZomeResponse = CallZomeResponseGeneric<any>;
82
82
  * @public
83
83
  */
84
84
  export type AppInfoResponse = AppInfo | null;
85
+ /**
86
+ * @public
87
+ */
88
+ export type ProvideMemproofsRequest = MemproofMap;
89
+ /**
90
+ * @public
91
+ */
92
+ export type ProvideMemproofsResponse = void;
93
+ /**
94
+ * @public
95
+ */
96
+ export type EnableRequest = void;
97
+ /**
98
+ * @public
99
+ */
100
+ export type EnableResponse = void;
85
101
  /**
86
102
  * @public
87
103
  */
@@ -136,7 +152,7 @@ export interface DisableCloneCellRequest {
136
152
  /**
137
153
  * The clone id or cell id of the clone cell
138
154
  */
139
- clone_cell_id: RoleName | CellId;
155
+ clone_cell_id: RoleName | DnaHash;
140
156
  }
141
157
  /**
142
158
  * @public
@@ -177,10 +193,18 @@ export declare const SignalType: {
177
193
  /**
178
194
  * @public
179
195
  */
180
- export type Signal = {
196
+ export type RawSignal = {
181
197
  [SignalType.App]: EncodedAppSignal;
182
198
  } | {
183
- [SignalType.System]: unknown;
199
+ [SignalType.System]: SystemSignal;
200
+ };
201
+ /**
202
+ * @public
203
+ */
204
+ export type Signal = {
205
+ [SignalType.App]: AppSignal;
206
+ } | {
207
+ [SignalType.System]: SystemSignal;
184
208
  };
185
209
  /**
186
210
  * @public
@@ -201,7 +225,13 @@ export type AppSignal = {
201
225
  /**
202
226
  * @public
203
227
  */
204
- export type AppSignalCb = (signal: AppSignal) => void;
228
+ export type SystemSignal = {
229
+ SuccessfulCountersigning: EntryHash;
230
+ };
231
+ /**
232
+ * @public
233
+ */
234
+ export type SignalCb = (signal: Signal) => void;
205
235
  /**
206
236
  * @public
207
237
  */
@@ -211,7 +241,7 @@ export type NetworkInfoResponse = NetworkInfo[];
211
241
  */
212
242
  export interface AppClient {
213
243
  callZome(args: AppCallZomeRequest, timeout?: number): Promise<any>;
214
- on<Name extends keyof AppEvents>(eventName: Name | readonly Name[], listener: AppSignalCb): UnsubscribeFunction;
244
+ on<Name extends keyof AppEvents>(eventName: Name | readonly Name[], listener: SignalCb): UnsubscribeFunction;
215
245
  appInfo(): Promise<AppInfoResponse>;
216
246
  myPubKey: AgentPubKey;
217
247
  installedAppId: InstalledAppId;
@@ -227,4 +257,7 @@ export interface AppWebsocketConnectionOptions extends WebsocketConnectionOption
227
257
  token?: AppAuthenticationToken;
228
258
  callZomeTransform?: CallZomeTransform;
229
259
  }
260
+ /**
261
+ * @public
262
+ */
230
263
  export type CallZomeTransform = Transformer<CallZomeRequest | CallZomeRequestSigned, Promise<CallZomeRequestSigned>, CallZomeResponseGeneric<Uint8Array>, CallZomeResponse>;
@@ -1,7 +1,7 @@
1
1
  import { UnsubscribeFunction } from "emittery";
2
2
  import { AgentPubKey, CellId, InstalledAppId, RoleName } from "../../types.js";
3
- import { AppInfo } from "../admin/index.js";
4
- import { AppCallZomeRequest, AppClient, AppEvents, AppNetworkInfoRequest, AppCreateCloneCellRequest, AppDisableCloneCellRequest, AppEnableCloneCellRequest, AppSignalCb, CallZomeRequest, CallZomeRequestSigned, CallZomeResponse, CreateCloneCellResponse, DisableCloneCellResponse, EnableCloneCellResponse, NetworkInfoResponse, AppWebsocketConnectionOptions } from "./types.js";
3
+ import { AppInfo, MemproofMap } from "../admin/index.js";
4
+ import { AppCallZomeRequest, AppClient, AppEvents, AppNetworkInfoRequest, AppCreateCloneCellRequest, AppDisableCloneCellRequest, AppEnableCloneCellRequest, SignalCb, CallZomeRequest, CallZomeRequestSigned, CallZomeResponse, CreateCloneCellResponse, DisableCloneCellResponse, EnableCloneCellResponse, NetworkInfoResponse, AppWebsocketConnectionOptions } from "./types.js";
5
5
  import { WsClient } from "../client.js";
6
6
  /**
7
7
  * A class to establish a websocket connection to an App interface, for a
@@ -19,6 +19,8 @@ export declare class AppWebsocket implements AppClient {
19
19
  cachedAppInfo?: AppInfo | null;
20
20
  private readonly appInfoRequester;
21
21
  private readonly callZomeRequester;
22
+ private readonly provideMemproofRequester;
23
+ private readonly enableAppRequester;
22
24
  private readonly createCloneCellRequester;
23
25
  private readonly enableCloneCellRequester;
24
26
  private readonly disableCloneCellRequester;
@@ -39,6 +41,17 @@ export declare class AppWebsocket implements AppClient {
39
41
  * @returns The app's {@link AppInfo}.
40
42
  */
41
43
  appInfo(timeout?: number): Promise<AppInfo>;
44
+ /**
45
+ * Provide membrane proofs for the app.
46
+ *
47
+ * @param memproofs - A map of {@link MembraneProof}s.
48
+ */
49
+ provideMemproofs(memproofs: MemproofMap): Promise<void>;
50
+ /**
51
+ * Enablie an app only if the app is in the `AppStatus::Disabled(DisabledAppReason::NotStartedAfterProvidingMemproofs)`
52
+ * state. Attempting to enable the app from other states (other than Running) will fail.
53
+ */
54
+ enableApp(): Promise<void>;
42
55
  /**
43
56
  * Get a cell id by its role name or clone id.
44
57
  *
@@ -88,7 +101,7 @@ export declare class AppWebsocket implements AppClient {
88
101
  * @param listener - The function to call when event is triggered.
89
102
  * @returns A function to unsubscribe the event listener.
90
103
  */
91
- on<Name extends keyof AppEvents>(eventName: Name | readonly Name[], listener: AppSignalCb): UnsubscribeFunction;
104
+ on<Name extends keyof AppEvents>(eventName: Name | readonly Name[], listener: SignalCb): UnsubscribeFunction;
92
105
  private static requester;
93
106
  private containsCell;
94
107
  }
@@ -25,6 +25,8 @@ export class AppWebsocket {
25
25
  cachedAppInfo;
26
26
  appInfoRequester;
27
27
  callZomeRequester;
28
+ provideMemproofRequester;
29
+ enableAppRequester;
28
30
  createCloneCellRequester;
29
31
  enableCloneCellRequester;
30
32
  disableCloneCellRequester;
@@ -39,6 +41,8 @@ export class AppWebsocket {
39
41
  this.cachedAppInfo = appInfo;
40
42
  this.appInfoRequester = AppWebsocket.requester(this.client, "app_info", this.defaultTimeout);
41
43
  this.callZomeRequester = AppWebsocket.requester(this.client, "call_zome", this.defaultTimeout, this.callZomeTransform);
44
+ this.provideMemproofRequester = AppWebsocket.requester(this.client, "provide_memproofs", this.defaultTimeout);
45
+ this.enableAppRequester = AppWebsocket.requester(this.client, "enable_app", this.defaultTimeout);
42
46
  this.createCloneCellRequester = AppWebsocket.requester(this.client, "create_clone_cell", this.defaultTimeout);
43
47
  this.enableCloneCellRequester = AppWebsocket.requester(this.client, "enable_clone_cell", this.defaultTimeout);
44
48
  this.disableCloneCellRequester = AppWebsocket.requester(this.client, "disable_clone_cell", this.defaultTimeout);
@@ -53,9 +57,7 @@ export class AppWebsocket {
53
57
  }
54
58
  });
55
59
  this.client.on("signal", (signal) => {
56
- if (this.containsCell(signal.cell_id)) {
57
- this.emitter.emit("signal", signal).catch(console.error);
58
- }
60
+ this.emitter.emit("signal", signal).catch(console.error);
59
61
  });
60
62
  }
61
63
  /**
@@ -85,7 +87,7 @@ export class AppWebsocket {
85
87
  }
86
88
  await client.authenticate({ token: options.token });
87
89
  }
88
- const appInfo = await this.requester(client, "app_info", DEFAULT_TIMEOUT)(null);
90
+ const appInfo = await AppWebsocket.requester(client, "app_info", DEFAULT_TIMEOUT)(null);
89
91
  if (!appInfo) {
90
92
  throw new HolochainError("AppNotFound", `The app your connection token was issued for was not found. The app needs to be installed and enabled.`);
91
93
  }
@@ -105,6 +107,21 @@ export class AppWebsocket {
105
107
  this.cachedAppInfo = appInfo;
106
108
  return appInfo;
107
109
  }
110
+ /**
111
+ * Provide membrane proofs for the app.
112
+ *
113
+ * @param memproofs - A map of {@link MembraneProof}s.
114
+ */
115
+ async provideMemproofs(memproofs) {
116
+ await this.provideMemproofRequester(memproofs);
117
+ }
118
+ /**
119
+ * Enablie an app only if the app is in the `AppStatus::Disabled(DisabledAppReason::NotStartedAfterProvidingMemproofs)`
120
+ * state. Attempting to enable the app from other states (other than Running) will fail.
121
+ */
122
+ async enableApp() {
123
+ await this.enableAppRequester();
124
+ }
108
125
  /**
109
126
  * Get a cell id by its role name or clone id.
110
127
  *
package/lib/api/client.js CHANGED
@@ -52,18 +52,21 @@ export class WsClient extends Emittery {
52
52
  const deserializedSignal = decode(message.data);
53
53
  assertHolochainSignal(deserializedSignal);
54
54
  if (SignalType.System in deserializedSignal) {
55
- // We have received a system signal, do nothing
56
- return;
55
+ this.emit("signal", {
56
+ System: deserializedSignal[SignalType.System],
57
+ });
58
+ }
59
+ else {
60
+ const encodedAppSignal = deserializedSignal[SignalType.App];
61
+ // In order to return readable content to the UI, the signal payload must also be deserialized.
62
+ const payload = decode(encodedAppSignal.signal);
63
+ const signal = {
64
+ cell_id: encodedAppSignal.cell_id,
65
+ zome_name: encodedAppSignal.zome_name,
66
+ payload,
67
+ };
68
+ this.emit("signal", { App: signal });
57
69
  }
58
- const encodedAppSignal = deserializedSignal[SignalType.App];
59
- // In order to return readable content to the UI, the signal payload must also be deserialized.
60
- const payload = decode(encodedAppSignal.signal);
61
- const signal = {
62
- cell_id: encodedAppSignal.cell_id,
63
- zome_name: encodedAppSignal.zome_name,
64
- payload,
65
- };
66
- this.emit("signal", signal);
67
70
  }
68
71
  else if (message.type === "response") {
69
72
  this.handleResponse(message);
@@ -18,6 +18,23 @@ export interface PreflightRequest {
18
18
  action_base: ActionBase;
19
19
  preflight_bytes: PreflightBytes;
20
20
  }
21
+ /**
22
+ * @public
23
+ */
24
+ export interface PreflightResponse {
25
+ /**
26
+ * The request associated with this response.
27
+ */
28
+ request: PreflightRequest;
29
+ /**
30
+ * The chain state declaration for the agent that produced this response.
31
+ */
32
+ agent_state: CountersigningAgentState;
33
+ /**
34
+ * The signature of this response, by the agent that created it.
35
+ */
36
+ signature: Signature;
37
+ }
21
38
  /**
22
39
  * @public
23
40
  */
@@ -1,4 +1,4 @@
1
- import { Signature } from "../types.js";
1
+ import { ActionHash, AgentPubKey, Signature, Timestamp } from "../types.js";
2
2
  import { Entry } from "./entry.js";
3
3
  import { CreateLink, Delete, DeleteLink, Action, NewEntryAction, Update } from "./action.js";
4
4
  /**
@@ -19,6 +19,27 @@ export declare enum DhtOpType {
19
19
  * @public
20
20
  */
21
21
  export type DhtOp = {
22
+ ChainOp: ChainOp;
23
+ } | {
24
+ WarrantOp: WarrantOp;
25
+ };
26
+ /**
27
+ * @public
28
+ */
29
+ export interface WarrantOp {
30
+ /** The warrant which was issued */
31
+ warrant: Warrant;
32
+ /** author of the warrant */
33
+ author: AgentPubKey;
34
+ /** signature of (Warrant, Timestamp) by the author */
35
+ signature: Signature;
36
+ /** time when the warrant was issued */
37
+ timestamp: Timestamp;
38
+ }
39
+ /**
40
+ * @public
41
+ */
42
+ export type ChainOp = {
22
43
  [DhtOpType.StoreRecord]: [Signature, Action, Entry | undefined];
23
44
  } | {
24
45
  [DhtOpType.StoreEntry]: [Signature, NewEntryAction, Entry];
@@ -41,6 +62,55 @@ export type DhtOp = {
41
62
  } | {
42
63
  [DhtOpType.RegisterRemoveLink]: [Signature, DeleteLink];
43
64
  };
65
+ /**
66
+ * @public
67
+ */
68
+ export interface Warrant {
69
+ /**
70
+ * Signifies evidence of a breach of chain integrity
71
+ */
72
+ ChainIntegrity: ChainIntegrityWarrant;
73
+ }
74
+ /**
75
+ * @public
76
+ */
77
+ export type ChainIntegrityWarrant = {
78
+ /**
79
+ * Something invalid was authored on a chain.
80
+ * When we receive this warrant, we fetch the Action and validate it
81
+ * under every applicable DhtOpType.
82
+ */
83
+ InvalidChainOp: {
84
+ /** The author of the action */
85
+ action_author: AgentPubKey;
86
+ /** The hash of the action to fetch by */
87
+ action: ActionHashAndSig;
88
+ /** Whether to run app or sys validation */
89
+ validation_type: ValidationType;
90
+ } | {
91
+ /** Proof of chain fork. */
92
+ ChainFork: {
93
+ /** Author of the chain which is forked */
94
+ chain_author: AgentPubKey;
95
+ /** Two actions of the same seq number which prove the fork */
96
+ action_pair: [ActionHashAndSig, ActionHashAndSig];
97
+ };
98
+ };
99
+ };
100
+ /**
101
+ * @public
102
+ */
103
+ export type ValidationType = {
104
+ /** Sys validation */
105
+ Sys: null;
106
+ /** App validation */
107
+ App: null;
108
+ };
109
+ /**
110
+ * Action hash with the signature of the action at that hash
111
+ * @public
112
+ */
113
+ export type ActionHashAndSig = [ActionHash, Signature];
44
114
  /**
45
115
  * @public
46
116
  */
package/lib/hdk/link.d.ts CHANGED
@@ -39,6 +39,7 @@ export type RateUnits = number;
39
39
  */
40
40
  export interface Link {
41
41
  author: AgentPubKey;
42
+ base: AnyLinkableHash;
42
43
  target: AnyLinkableHash;
43
44
  timestamp: Timestamp;
44
45
  zome_index: ZomeIndex;
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.43.1"
8
+ "packageVersion": "7.47.0"
9
9
  }
10
10
  ]
11
11
  }
@@ -0,0 +1,11 @@
1
+ import { CellId } from "../types.js";
2
+ /**
3
+ * Check if two cell ids are identical.
4
+ *
5
+ * @param cellId1 - Cell id 1 to compare.
6
+ * @param cellId2 - Cell id 1 to compare.
7
+ * @returns True if the cell ids are identical.
8
+ *
9
+ * @public
10
+ */
11
+ export declare const isSameCell: (cellId1: CellId, cellId2: CellId) => boolean;
@@ -0,0 +1,17 @@
1
+ import { encodeHashToBase64 } from "./base64.js";
2
+ /**
3
+ * Check if two cell ids are identical.
4
+ *
5
+ * @param cellId1 - Cell id 1 to compare.
6
+ * @param cellId2 - Cell id 1 to compare.
7
+ * @returns True if the cell ids are identical.
8
+ *
9
+ * @public
10
+ */
11
+ export const isSameCell = (cellId1, cellId2) => {
12
+ const dnaHashB64_1 = encodeHashToBase64(cellId1[0]);
13
+ const agentPubKeyB64_1 = encodeHashToBase64(cellId1[1]);
14
+ const dnaHashB64_2 = encodeHashToBase64(cellId2[0]);
15
+ const agentPubKeyB64_2 = encodeHashToBase64(cellId2[1]);
16
+ return dnaHashB64_1 === dnaHashB64_2 && agentPubKeyB64_1 === agentPubKeyB64_2;
17
+ };
@@ -1,6 +1,6 @@
1
1
  import { ActionHash, AgentPubKey, EntryHash } from "../types.js";
2
2
  /**
3
- * Hash type labels and their 3 byte values (forming the first 3 bytes of hash)
3
+ * Hash type labels and their 3 byte values (forming the first 3 bytes of hash).
4
4
  *
5
5
  * From https://github.com/holochain/holochain/blob/develop/crates/holo_hash/src/hash_type/primitive.rs
6
6
  *
@@ -14,18 +14,18 @@ export declare const HASH_TYPE_PREFIX: {
14
14
  External: Uint8Array;
15
15
  };
16
16
  /**
17
- * Get dht location (last 4 bytes) from a hash
17
+ * Get hash type (initial 3 bytes) from a hash.
18
18
  *
19
19
  * From https://github.com/holochain/holochain/blob/develop/crates/holo_hash/src/hash_type/primitive.rs
20
20
  *
21
21
  * @param hash - The full 39 byte hash.
22
- * @returns The last 4 bytes of the hash.
22
+ * @returns The initial 3 bytes of the hash.
23
23
  *
24
24
  * @public
25
25
  */
26
- export declare function sliceDhtLocation(hash: AgentPubKey | EntryHash | ActionHash): Uint8Array;
26
+ export declare function sliceHashType(hash: AgentPubKey | EntryHash | ActionHash): Uint8Array;
27
27
  /**
28
- * Get core (center 32 bytes) from a hash
28
+ * Get core hash from a Holochain hash (32 bytes).
29
29
  *
30
30
  * From https://github.com/holochain/holochain/blob/develop/crates/holo_hash/src/hash_type/primitive.rs
31
31
  *
@@ -36,18 +36,18 @@ export declare function sliceDhtLocation(hash: AgentPubKey | EntryHash | ActionH
36
36
  */
37
37
  export declare function sliceCore32(hash: AgentPubKey | EntryHash | ActionHash): Uint8Array;
38
38
  /**
39
- * Get hash type (initial 3 bytes) from a hash
39
+ * Get DHT location (last 4 bytes) from a hash.
40
40
  *
41
41
  * From https://github.com/holochain/holochain/blob/develop/crates/holo_hash/src/hash_type/primitive.rs
42
42
  *
43
43
  * @param hash - The full 39 byte hash.
44
- * @returns The initial 3 bytes of the hash.
44
+ * @returns The last 4 bytes of the hash.
45
45
  *
46
46
  * @public
47
47
  */
48
- export declare function sliceHashType(hash: AgentPubKey | EntryHash | ActionHash): Uint8Array;
48
+ export declare function sliceDhtLocation(hash: AgentPubKey | EntryHash | ActionHash): Uint8Array;
49
49
  /**
50
- * Generate dht location (last 4 bytes) from a core hash (middle 32 bytes)
50
+ * Generate DHT location (last 4 bytes) from a core hash (middle 32 bytes).
51
51
  *
52
52
  * From https://github.com/holochain/holochain/blob/develop/crates/holo_hash/src/hash_type/primitive.rs
53
53
  *
@@ -58,7 +58,7 @@ export declare function sliceHashType(hash: AgentPubKey | EntryHash | ActionHash
58
58
  */
59
59
  export declare function dhtLocationFrom32(hashCore: Uint8Array): Uint8Array;
60
60
  /**
61
- * Generate full hash from a core hash (middle 32 bytes) and hash type label
61
+ * Generate full hash from a core hash (middle 32 bytes) and hash type label.
62
62
  *
63
63
  * From https://github.com/holochain/holochain/blob/develop/crates/holo_hash/src/hash_type/primitive.rs
64
64
  *
@@ -1,6 +1,10 @@
1
1
  import blake2b from "@bitgo/blake2b";
2
+ const HASH_TYPE_START = 0;
3
+ const HASH_TYPE_BYTE_LENGTH = 3;
4
+ const CORE_HASH_BYTE_LENGTH = 32;
5
+ const DHT_LOCATION_BYTE_LENGTH = 4;
2
6
  /**
3
- * Hash type labels and their 3 byte values (forming the first 3 bytes of hash)
7
+ * Hash type labels and their 3 byte values (forming the first 3 bytes of hash).
4
8
  *
5
9
  * From https://github.com/holochain/holochain/blob/develop/crates/holo_hash/src/hash_type/primitive.rs
6
10
  *
@@ -14,20 +18,20 @@ export const HASH_TYPE_PREFIX = {
14
18
  External: Uint8Array.from([132, 47, 36]),
15
19
  };
16
20
  /**
17
- * Get dht location (last 4 bytes) from a hash
21
+ * Get hash type (initial 3 bytes) from a hash.
18
22
  *
19
23
  * From https://github.com/holochain/holochain/blob/develop/crates/holo_hash/src/hash_type/primitive.rs
20
24
  *
21
25
  * @param hash - The full 39 byte hash.
22
- * @returns The last 4 bytes of the hash.
26
+ * @returns The initial 3 bytes of the hash.
23
27
  *
24
28
  * @public
25
29
  */
26
- export function sliceDhtLocation(hash) {
27
- return Uint8Array.from(hash.slice(36, 40));
30
+ export function sliceHashType(hash) {
31
+ return Uint8Array.from(hash.slice(0, 3));
28
32
  }
29
33
  /**
30
- * Get core (center 32 bytes) from a hash
34
+ * Get core hash from a Holochain hash (32 bytes).
31
35
  *
32
36
  * From https://github.com/holochain/holochain/blob/develop/crates/holo_hash/src/hash_type/primitive.rs
33
37
  *
@@ -37,23 +41,27 @@ export function sliceDhtLocation(hash) {
37
41
  * @public
38
42
  */
39
43
  export function sliceCore32(hash) {
40
- return Uint8Array.from(hash.slice(3, 36));
44
+ const start = HASH_TYPE_START + HASH_TYPE_BYTE_LENGTH;
45
+ const end = start + CORE_HASH_BYTE_LENGTH;
46
+ return Uint8Array.from(hash.slice(start, end));
41
47
  }
42
48
  /**
43
- * Get hash type (initial 3 bytes) from a hash
49
+ * Get DHT location (last 4 bytes) from a hash.
44
50
  *
45
51
  * From https://github.com/holochain/holochain/blob/develop/crates/holo_hash/src/hash_type/primitive.rs
46
52
  *
47
53
  * @param hash - The full 39 byte hash.
48
- * @returns The initial 3 bytes of the hash.
54
+ * @returns The last 4 bytes of the hash.
49
55
  *
50
56
  * @public
51
57
  */
52
- export function sliceHashType(hash) {
53
- return Uint8Array.from(hash.slice(0, 3));
58
+ export function sliceDhtLocation(hash) {
59
+ const start = HASH_TYPE_START + HASH_TYPE_BYTE_LENGTH + CORE_HASH_BYTE_LENGTH;
60
+ const end = start + DHT_LOCATION_BYTE_LENGTH;
61
+ return Uint8Array.from(hash.slice(start, end));
54
62
  }
55
63
  /**
56
- * Generate dht location (last 4 bytes) from a core hash (middle 32 bytes)
64
+ * Generate DHT location (last 4 bytes) from a core hash (middle 32 bytes).
57
65
  *
58
66
  * From https://github.com/holochain/holochain/blob/develop/crates/holo_hash/src/hash_type/primitive.rs
59
67
  *
@@ -75,7 +83,7 @@ export function dhtLocationFrom32(hashCore) {
75
83
  return out;
76
84
  }
77
85
  /**
78
- * Generate full hash from a core hash (middle 32 bytes) and hash type label
86
+ * Generate full hash from a core hash (middle 32 bytes) and hash type label.
79
87
  *
80
88
  * From https://github.com/holochain/holochain/blob/develop/crates/holo_hash/src/hash_type/primitive.rs
81
89
  *
@@ -1,3 +1,4 @@
1
1
  export * from "./base64.js";
2
2
  export * from "./fake-hash.js";
3
3
  export * from "./hash-parts.js";
4
+ export * from "./cell.js";
@@ -1,3 +1,4 @@
1
1
  export * from "./base64.js";
2
2
  export * from "./fake-hash.js";
3
3
  export * from "./hash-parts.js";
4
+ export * from "./cell.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holochain/client",
3
- "version": "0.18.0-dev.1",
3
+ "version": "0.18.0-dev.11",
4
4
  "description": "A JavaScript client for the Holochain Conductor API",
5
5
  "author": "Holochain Foundation <info@holochain.org> (https://holochain.org)",
6
6
  "license": "CAL-1.0",