Socket
Socket
Sign inDemoInstall

@holochain/client

Package Overview
Dependencies
16
Maintainers
13
Versions
81
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.17.0-dev.9 to 0.17.0-dev.10

34

lib/api/admin/types.d.ts

@@ -1,5 +0,4 @@

import { Action, DhtOp, Entry, ZomeCallCapGrant } from "../../hdk/index.js";
import { Action, DhtOp, Entry, ZomeCallCapGrant } from "../../hdk";
import { ActionHash, AgentPubKey, CellId, DnaHash, DnaProperties, Duration, HoloHash, HoloHashB64, InstalledAppId, KitsuneAgent, KitsuneSpace, RoleName, Signature, Timestamp, WasmHash } from "../../types.js";
import { Requester } from "../common.js";
import { DisableCloneCellRequest } from "../index.js";
/**

@@ -503,3 +502,12 @@ * @public

*/
export type DeleteCloneCellRequest = DisableCloneCellRequest;
export interface DeleteCloneCellRequest {
/**
* The app id that the clone cell belongs to
*/
app_id: InstalledAppId;
/**
* The clone id or cell id of the clone cell
*/
clone_cell_id: RoleName | CellId;
}
/**

@@ -726,2 +734,21 @@ * @public

*/
export interface IssueAppAuthenticationTokenRequest {
installed_app_id: InstalledAppId;
expiry_seconds?: number;
single_use?: boolean;
}
/**
* @public
*/
export type AppAuthenticationToken = number[];
/**
* @public
*/
export interface IssueAppAuthenticationTokenResponse {
token: AppAuthenticationToken;
expires_at?: Timestamp;
}
/**
* @public
*/
export type DumpNetworkStatsRequest = void;

@@ -755,3 +782,4 @@ /**

storageInfo: Requester<StorageInfoRequest, StorageInfoResponse>;
issueAppAuthenticationToken: Requester<IssueAppAuthenticationTokenRequest, IssueAppAuthenticationTokenResponse>;
dumpNetworkStats: Requester<DumpNetworkStatsRequest, DumpNetworkStatsResponse>;
}

3

lib/api/admin/websocket.d.ts

@@ -5,3 +5,3 @@ import { CapSecret, GrantedFunctions } from "../../hdk/capabilities.js";

import { WebsocketConnectionOptions, Requester, Transformer } from "../common.js";
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, ListAppInterfacesRequest, ListAppInterfacesResponse, ListAppsRequest, ListAppsResponse, ListCellIdsRequest, ListCellIdsResponse, ListDnasRequest, ListDnasResponse, RegisterDnaRequest, RegisterDnaResponse, StorageInfoRequest, StorageInfoResponse, UninstallAppRequest, UninstallAppResponse, UpdateCoordinatorsRequest, UpdateCoordinatorsResponse } from "./types.js";
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";
/**

@@ -111,2 +111,3 @@ * A class for interacting with a conductor's Admin API.

storageInfo: Requester<StorageInfoRequest, StorageInfoResponse>;
issueAppAuthenticationToken: Requester<IssueAppAuthenticationTokenRequest, IssueAppAuthenticationTokenResponse>;
dumpNetworkStats: Requester<DumpNetworkStatsRequest, DumpNetworkStatsResponse>;

@@ -113,0 +114,0 @@ /**

@@ -128,2 +128,3 @@ import { getLauncherEnvironment } from "../../environments/launcher.js";

storageInfo = this._requester("storage_info");
issueAppAuthenticationToken = this._requester("issue_app_authentication_token");
dumpNetworkStats = this._requester("dump_network_stats");

@@ -130,0 +131,0 @@ // zome call signing related methods

@@ -1,7 +0,62 @@

import { AgentPubKey, CellId, DnaHash, DnaProperties, InstalledAppId, NetworkInfo, RoleName, Timestamp } from "../../types.js";
import { AppInfo, ClonedCell, FunctionName, MembraneProof, NetworkSeed, ZomeName } from "../admin/types.js";
import { Requester } from "../common.js";
import { UnsubscribeFunction } from "emittery";
import { AgentPubKey, AppInfo, CapSecret, CellId, ClonedCell, DnaHash, DnaProperties, FunctionName, MembraneProof, NetworkInfo, NetworkSeed, Nonce256Bit, RoleName, Timestamp, ZomeName } from "../../index.js";
/**
* @public
*/
export type NonProvenanceCallZomeRequest = Omit<CallZomeRequest, "provenance">;
/**
* @public
*/
export type RoleNameCallZomeRequest = Omit<NonProvenanceCallZomeRequest, "cell_id"> & {
role_name: RoleName;
};
/**
* @public
*/
export type RoleNameCallZomeRequestSigned = Omit<CallZomeRequestSigned, "cell_id"> & {
role_name: RoleName;
};
/**
* @public
*/
export type AppCallZomeRequest = NonProvenanceCallZomeRequest | RoleNameCallZomeRequest | CallZomeRequestSigned | RoleNameCallZomeRequestSigned;
/**
* @public
*/
export type AppCreateCloneCellRequest = Omit<CreateCloneCellRequest, "app_id">;
/**
* @public
*/
export type AppEnableCloneCellRequest = Omit<EnableCloneCellRequest, "app_id">;
/**
* @public
*/
export type AppDisableCloneCellRequest = Omit<DisableCloneCellRequest, "app_id">;
/**
* @public
*/
export type AppNetworkInfoRequest = Omit<NetworkInfoRequest, "agent_pub_key">;
/**
* @public
*/
export interface AppEvents {
signal: AppSignal;
}
/**
* @public
*/
export interface CallZomeRequestUnsigned extends CallZomeRequest {
cap_secret: CapSecret | null;
nonce: Nonce256Bit;
expires_at: number;
}
/**
* @public
*/
export interface CallZomeRequestSigned extends CallZomeRequestUnsigned {
signature: Uint8Array;
}
/**
* @public
*/
export type CallZomeRequestGeneric<Payload> = {

@@ -29,8 +84,2 @@ cell_id: CellId;

*/
export type AppInfoRequest = {
installed_app_id: InstalledAppId;
};
/**
* @public
*/
export type AppInfoResponse = AppInfo | null;

@@ -42,6 +91,2 @@ /**

/**
* The app id that the DNA to clone belongs to
*/
app_id: InstalledAppId;
/**
* The DNA's role id to clone.

@@ -94,6 +139,2 @@ */

/**
* The app id that the clone cell belongs to
*/
app_id: InstalledAppId;
/**
* The clone id or cell id of the clone cell

@@ -174,7 +215,11 @@ */

*/
export interface AppApi {
appInfo: Requester<AppInfoRequest, AppInfoResponse>;
callZome: Requester<CallZomeRequest, CallZomeResponse>;
enableCloneCell: Requester<EnableCloneCellRequest, EnableCloneCellResponse>;
disableCloneCell: Requester<DisableCloneCellRequest, DisableCloneCellResponse>;
export interface AppClient {
callZome(args: AppCallZomeRequest, timeout?: number): Promise<any>;
on<Name extends keyof AppEvents>(eventName: Name | readonly Name[], listener: AppSignalCb): UnsubscribeFunction;
appInfo(): Promise<AppInfoResponse>;
myPubKey: AgentPubKey;
createCloneCell(args: AppCreateCloneCellRequest): Promise<CreateCloneCellResponse>;
enableCloneCell(args: AppEnableCloneCellRequest): Promise<EnableCloneCellResponse>;
disableCloneCell(args: AppDisableCloneCellRequest): Promise<DisableCloneCellResponse>;
networkInfo(args: AppNetworkInfoRequest): Promise<NetworkInfoResponse>;
}

@@ -1,34 +0,50 @@

import Emittery from "emittery";
import { CapSecret } from "../../hdk/capabilities.js";
import { InstalledAppId } from "../../types.js";
import { WsClient } from "../client.js";
import { WebsocketConnectionOptions, Requester, Transformer } from "../common.js";
import { Nonce256Bit } from "../zome-call-signing.js";
import { AppApi, AppInfoRequest, AppInfoResponse, CallZomeRequest, CallZomeResponse, CreateCloneCellRequest, CreateCloneCellResponse, DisableCloneCellRequest, DisableCloneCellResponse, EnableCloneCellRequest, EnableCloneCellResponse, NetworkInfoRequest, NetworkInfoResponse } from "./types.js";
import { UnsubscribeFunction } from "emittery";
import { AgentPubKey, CellId, RoleName } from "../../types.js";
import { AppAuthenticationToken, AppInfo } from "../admin";
import { WebsocketConnectionOptions } from "../common.js";
import { AppCallZomeRequest, AppClient, AppEvents, AppNetworkInfoRequest, AppCreateCloneCellRequest, AppDisableCloneCellRequest, AppEnableCloneCellRequest, AppSignalCb, CallZomeRequest, CallZomeRequestSigned, CallZomeResponse, CreateCloneCellResponse, DisableCloneCellResponse, EnableCloneCellResponse, NetworkInfoResponse } from "./types.js";
import { WsClient } from "../client";
/**
* A class to establish a websocket connection to an App interface of a
* Holochain conductor.
* A class to establish a websocket connection to an App interface, for a
* specific agent and app.
*
* @public
*/
export declare class AppWebsocket extends Emittery implements AppApi {
export declare class AppWebsocket implements AppClient {
readonly client: WsClient;
defaultTimeout: number;
overrideInstalledAppId?: InstalledAppId;
readonly myPubKey: AgentPubKey;
private readonly defaultTimeout;
private readonly emitter;
cachedAppInfo?: AppInfo | null;
private readonly appInfoRequester;
private readonly callZomeRequester;
private readonly createCloneCellRequester;
private readonly enableCloneCellRequester;
private readonly disableCloneCellRequester;
private readonly networkInfoRequester;
private constructor();
/**
* Instance factory for creating AppWebsockets.
* Instance factory for creating an {@link AppWebsocket}.
*
* @param token - A token to authenticate the websocket connection. Get a token using AdminWebsocket#issueAppAuthenticationToken.
* @param options - {@link (WebsocketConnectionOptions:interface)}
* @returns A new instance of an AppWebsocket.
*/
static connect(options?: WebsocketConnectionOptions): Promise<AppWebsocket>;
_requester<ReqI, ReqO, ResI, ResO>(tag: string, transformer?: Transformer<ReqI, ReqO, ResI, ResO>): (req: ReqI, timeout?: number | undefined) => Promise<ResO>;
static connect(token: AppAuthenticationToken, options?: WebsocketConnectionOptions): Promise<AppWebsocket>;
/**
* Request the app's info, including all cell infos.
*
* @param timeout - A timeout to override the default.
* @returns The app's {@link AppInfo}.
*/
appInfo: Requester<AppInfoRequest, AppInfoResponse>;
appInfo(timeout?: number): Promise<AppInfo>;
/**
* Get a cell id by its role name or clone id.
*
* @param roleName - The role name or clone id of the cell.
* @param appInfo - The app info containing all cell infos.
* @returns The cell id or throws an error if not found.
*/
getCellIdFromRoleName(roleName: RoleName, appInfo: AppInfo): CellId;
/**
* Call a zome.

@@ -40,3 +56,3 @@ *

*/
callZome: Requester<CallZomeRequest | CallZomeRequestSigned, CallZomeResponse>;
callZome(request: AppCallZomeRequest, timeout?: number): Promise<CallZomeResponse>;
/**

@@ -48,3 +64,3 @@ * Clone an existing provisioned cell.

*/
createCloneCell: Requester<CreateCloneCellRequest, CreateCloneCellResponse>;
createCloneCell(args: AppCreateCloneCellRequest): Promise<CreateCloneCellResponse>;
/**

@@ -56,3 +72,3 @@ * Enable a disabled clone cell.

*/
enableCloneCell: Requester<EnableCloneCellRequest, EnableCloneCellResponse>;
enableCloneCell(args: AppEnableCloneCellRequest): Promise<EnableCloneCellResponse>;
/**

@@ -63,7 +79,19 @@ * Disable an enabled clone cell.

*/
disableCloneCell: Requester<DisableCloneCellRequest, DisableCloneCellResponse>;
disableCloneCell(args: AppDisableCloneCellRequest): Promise<DisableCloneCellResponse>;
/**
* Request network info about gossip status.
* @param args - Specify the DNAs for which you want network info
* @returns Network info for the specified DNAs
*/
networkInfo: Requester<NetworkInfoRequest, NetworkInfoResponse>;
networkInfo(args: AppNetworkInfoRequest): Promise<NetworkInfoResponse>;
/**
* Register an event listener for signals.
*
* @param eventName - Event name to listen to (currently only "signal").
* @param listener - The function to call when event is triggered.
* @returns A function to unsubscribe the event listener.
*/
on<Name extends keyof AppEvents>(eventName: Name | readonly Name[], listener: AppSignalCb): UnsubscribeFunction;
private static requester;
private containsCell;
}

@@ -73,16 +101,2 @@ /**

*/
export interface CallZomeRequestUnsigned extends CallZomeRequest {
cap_secret: CapSecret | null;
nonce: Nonce256Bit;
expires_at: number;
}
/**
* @public
*/
export interface CallZomeRequestSigned extends CallZomeRequestUnsigned {
signature: Uint8Array;
}
/**
* @public
*/
export declare const signZomeCall: (request: CallZomeRequest) => Promise<CallZomeRequestSigned>;

@@ -0,43 +1,65 @@

import Emittery from "emittery";
import { omit } from "lodash-es";
import { CellType } from "../admin";
import { catchError, DEFAULT_TIMEOUT, getBaseRoleNameFromCloneId, HolochainError, isCloneId, promiseTimeout, requesterTransformer, } from "../common.js";
import { getHostZomeCallSigner, getLauncherEnvironment, signZomeCallElectron, signZomeCallTauri, } from "../../environments/launcher";
import { decode, encode } from "@msgpack/msgpack";
import { getNonceExpiration, getSigningCredentials, randomNonce, } from "../zome-call-signing";
import { encodeHashToBase64 } from "../../utils";
import { hashZomeCall } from "@holochain/serialization";
import { decode, encode } from "@msgpack/msgpack";
import _sodium from "libsodium-wrappers";
import Emittery from "emittery";
import { getLauncherEnvironment, signZomeCallTauri, signZomeCallElectron, getHostZomeCallSigner, } from "../../environments/launcher.js";
import { encodeHashToBase64 } from "../../utils/base64.js";
import { WsClient } from "../client.js";
import { DEFAULT_TIMEOUT, catchError, promiseTimeout, requesterTransformer, HolochainError, } from "../common.js";
import { getNonceExpiration, getSigningCredentials, randomNonce, } from "../zome-call-signing.js";
import { WsClient } from "../client";
/**
* A class to establish a websocket connection to an App interface of a
* Holochain conductor.
* A class to establish a websocket connection to an App interface, for a
* specific agent and app.
*
* @public
*/
export class AppWebsocket extends Emittery {
export class AppWebsocket {
client;
myPubKey;
defaultTimeout;
overrideInstalledAppId;
constructor(client, defaultTimeout, overrideInstalledAppId) {
super();
emitter;
cachedAppInfo;
appInfoRequester;
callZomeRequester;
createCloneCellRequester;
enableCloneCellRequester;
disableCloneCellRequester;
networkInfoRequester;
constructor(client, appInfo, defaultTimeout) {
this.client = client;
this.myPubKey = appInfo.agent_pub_key;
this.defaultTimeout = defaultTimeout ?? DEFAULT_TIMEOUT;
this.emitter = new Emittery();
this.cachedAppInfo = appInfo;
this.appInfoRequester = AppWebsocket.requester(this.client, "app_info", this.defaultTimeout);
this.callZomeRequester = AppWebsocket.requester(this.client, "call_zome", this.defaultTimeout, callZomeTransform);
this.createCloneCellRequester = AppWebsocket.requester(this.client, "create_clone_cell", this.defaultTimeout);
this.enableCloneCellRequester = AppWebsocket.requester(this.client, "enable_clone_cell", this.defaultTimeout);
this.disableCloneCellRequester = AppWebsocket.requester(this.client, "disable_clone_cell", this.defaultTimeout);
this.networkInfoRequester = AppWebsocket.requester(this.client, "network_info", this.defaultTimeout);
// Ensure all super methods are bound to this instance because Emittery relies on `this` being the instance.
// Please retain until the upstream is fixed https://github.com/sindresorhus/emittery/issues/86.
Object.getOwnPropertyNames(Emittery.prototype).forEach((name) => {
const to_bind = this[name];
const to_bind = this.emitter[name];
if (typeof to_bind === "function") {
this[name] =
to_bind.bind(this);
this.emitter[name] =
to_bind.bind(this.emitter);
}
});
this.client = client;
this.defaultTimeout =
defaultTimeout === undefined ? DEFAULT_TIMEOUT : defaultTimeout;
this.overrideInstalledAppId = overrideInstalledAppId;
this.client.on("signal", (signal) => {
if (this.containsCell(signal.cell_id)) {
this.emitter.emit("signal", signal).catch(console.error);
}
});
}
/**
* Instance factory for creating AppWebsockets.
* Instance factory for creating an {@link AppWebsocket}.
*
* @param token - A token to authenticate the websocket connection. Get a token using AdminWebsocket#issueAppAuthenticationToken.
* @param options - {@link (WebsocketConnectionOptions:interface)}
* @returns A new instance of an AppWebsocket.
*/
static async connect(options = {}) {
static async connect(token, options = {}) {
// Check if we are in the launcher's environment, and if so, redirect the url to connect to

@@ -51,17 +73,53 @@ const env = getLauncherEnvironment();

}
const wsClient = await WsClient.connect(options.url, options.wsClientOptions);
const appWebsocket = new AppWebsocket(wsClient, options.defaultTimeout, env?.INSTALLED_APP_ID);
wsClient.on("signal", (signal) => appWebsocket.emit("signal", signal));
return appWebsocket;
const client = await WsClient.connect(options.url, options.wsClientOptions);
await client.authenticate({ token });
const appInfo = await this.requester(client, "app_info", DEFAULT_TIMEOUT)(null);
if (!appInfo) {
throw new HolochainError("AppNotFound", `The app your connection token was issued for was not found. The app needs to be installed and enabled.`);
}
return new AppWebsocket(client, appInfo, options.defaultTimeout);
}
_requester(tag, transformer) {
return requesterTransformer((req, timeout) => promiseTimeout(this.client.request(req), tag, timeout || this.defaultTimeout).then(catchError), tag, transformer);
}
/**
* Request the app's info, including all cell infos.
*
* @param timeout - A timeout to override the default.
* @returns The app's {@link AppInfo}.
*/
appInfo = this._requester("app_info", appInfoTransform(this));
async appInfo(timeout) {
const appInfo = await this.appInfoRequester(null, timeout);
if (!appInfo) {
throw new HolochainError("AppNotFound", `App info not found. App needs to be installed and enabled.`);
}
this.cachedAppInfo = appInfo;
return appInfo;
}
/**
* Get a cell id by its role name or clone id.
*
* @param roleName - The role name or clone id of the cell.
* @param appInfo - The app info containing all cell infos.
* @returns The cell id or throws an error if not found.
*/
getCellIdFromRoleName(roleName, appInfo) {
if (isCloneId(roleName)) {
const baseRoleName = getBaseRoleNameFromCloneId(roleName);
if (!(baseRoleName in appInfo.cell_info)) {
throw new HolochainError("NoCellForRoleName", `no cell found with role_name ${roleName}`);
}
const cloneCell = appInfo.cell_info[baseRoleName].find((c) => CellType.Cloned in c && c[CellType.Cloned].clone_id === roleName);
if (!cloneCell || !(CellType.Cloned in cloneCell)) {
throw new HolochainError("NoCellForCloneId", `no clone cell found with clone id ${roleName}`);
}
return cloneCell[CellType.Cloned].cell_id;
}
if (!(roleName in appInfo.cell_info)) {
throw new HolochainError("NoCellForRoleName", `no cell found with role_name ${roleName}`);
}
const cell = appInfo.cell_info[roleName].find((c) => CellType.Provisioned in c);
if (!cell || !(CellType.Provisioned in cell)) {
throw new HolochainError("NoProvisionedCellForRoleName", `no provisioned cell found with role_name ${roleName}`);
}
return cell[CellType.Provisioned].cell_id;
}
/**
* Call a zome.

@@ -73,3 +131,24 @@ *

*/
callZome = this._requester("call_zome", callZomeTransform);
async callZome(request, timeout) {
if (!("provenance" in request)) {
request = {
...request,
provenance: this.myPubKey,
};
}
if ("role_name" in request && request.role_name) {
const appInfo = this.cachedAppInfo || (await this.appInfo());
const cell_id = this.getCellIdFromRoleName(request.role_name, appInfo);
const zomeCallPayload = {
...omit(request, "role_name"),
provenance: this.myPubKey,
cell_id: [cell_id[0], cell_id[1]],
};
return this.callZomeRequester(zomeCallPayload, timeout);
}
else if ("cell_id" in request && request.cell_id) {
return this.callZomeRequester(request, timeout);
}
throw new HolochainError("MissingRoleNameOrCellId", "callZome requires a role_name or cell_id argument");
}
/**

@@ -81,3 +160,9 @@ * Clone an existing provisioned cell.

*/
createCloneCell = this._requester("create_clone_cell");
async createCloneCell(args) {
const clonedCell = this.createCloneCellRequester({
...args,
});
this.cachedAppInfo = undefined;
return clonedCell;
}
/**

@@ -89,3 +174,7 @@ * Enable a disabled clone cell.

*/
enableCloneCell = this._requester("enable_clone_cell");
async enableCloneCell(args) {
return this.enableCloneCellRequester({
...args,
});
}
/**

@@ -96,7 +185,50 @@ * Disable an enabled clone cell.

*/
disableCloneCell = this._requester("disable_clone_cell");
async disableCloneCell(args) {
return this.disableCloneCellRequester({
...args,
});
}
/**
* Request network info about gossip status.
* @param args - Specify the DNAs for which you want network info
* @returns Network info for the specified DNAs
*/
networkInfo = this._requester("network_info");
async networkInfo(args) {
return this.networkInfoRequester({
...args,
agent_pub_key: this.myPubKey,
});
}
/**
* Register an event listener for signals.
*
* @param eventName - Event name to listen to (currently only "signal").
* @param listener - The function to call when event is triggered.
* @returns A function to unsubscribe the event listener.
*/
on(eventName, listener) {
return this.emitter.on(eventName, listener);
}
static requester(client, tag, defaultTimeout, transformer) {
return requesterTransformer((req, timeout) => promiseTimeout(client.request(req), tag, timeout || defaultTimeout).then(catchError), tag, transformer);
}
containsCell(cellId) {
const appInfo = this.cachedAppInfo;
if (!appInfo) {
return false;
}
for (const roleName of Object.keys(appInfo.cell_info)) {
for (const cellInfo of appInfo.cell_info[roleName]) {
const currentCellId = CellType.Provisioned in cellInfo
? cellInfo[CellType.Provisioned].cell_id
: CellType.Cloned in cellInfo
? cellInfo[CellType.Cloned].cell_id
: undefined;
if (currentCellId && isSameCell(currentCellId, cellId)) {
return true;
}
}
}
return false;
}
}

@@ -125,13 +257,4 @@ const callZomeTransform = {

};
const appInfoTransform = (appWs) => ({
input: (request) => {
if (appWs.overrideInstalledAppId) {
return {
installed_app_id: appWs.overrideInstalledAppId,
};
}
return request;
},
output: (response) => response,
});
const isSameCell = (cellId1, cellId2) => cellId1[0].every((byte, index) => byte === cellId2[0][index]) &&
cellId1[1].every((byte, index) => byte === cellId2[1][index]);
/**

@@ -138,0 +261,0 @@ * @public

@@ -5,3 +5,10 @@ /// <reference types="ws" />

import { WsClientOptions } from "./common.js";
import { AppAuthenticationToken } from "./admin";
/**
* @public
*/
export interface AppAuthenticationRequest {
token: AppAuthenticationToken;
}
/**
* A WebSocket client which can make requests and receive responses,

@@ -26,2 +33,3 @@ * as well as send and receive signals.

* @param url - The WebSocket URL to connect to.
* @param options - Options for the WsClient.
* @returns An new instance of the WsClient.

@@ -37,2 +45,10 @@ */

/**
* Authenticate the client with the conductor.
*
* This is only relevant for app websockets.
*
* @param request - The authentication request, containing an app authentication token.
*/
authenticate(request: AppAuthenticationRequest): Promise<void>;
/**
* Send requests to the connected websocket.

@@ -44,2 +60,3 @@ *

request<Response>(request: unknown): Promise<Response>;
private exchange;
private sendMessage;

@@ -46,0 +63,0 @@ private handleResponse;

import { decode, encode } from "@msgpack/msgpack";
import Emittery from "emittery";
import IsoWebSocket from "isomorphic-ws";
import { SignalType } from "./app/types.js";
import { HolochainError } from "./common.js";
import { SignalType } from "./app";
/**

@@ -90,2 +90,3 @@ * A WebSocket client which can make requests and receive responses,

* @param url - The WebSocket URL to connect to.
* @param options - Options for the WsClient.
* @returns An new instance of the WsClient.

@@ -118,2 +119,20 @@ */

/**
* Authenticate the client with the conductor.
*
* This is only relevant for app websockets.
*
* @param request - The authentication request, containing an app authentication token.
*/
async authenticate(request) {
return this.exchange(request, (request, resolve) => {
const encodedMsg = encode({
type: "authenticate",
data: encode(request),
});
this.socket.send(encodedMsg);
// Message just needs to be sent first, no need to wait for a response or even require a flush
resolve(null);
});
}
/**
* Send requests to the connected websocket.

@@ -125,23 +144,11 @@ *

async request(request) {
return this.exchange(request, this.sendMessage.bind(this));
}
exchange(request, sendHandler) {
if (this.socket.readyState === this.socket.OPEN) {
const promise = new Promise((resolve, reject) => {
this.sendMessage(request, resolve, reject);
sendHandler(request, resolve, reject);
});
return promise;
}
else if (this.url) {
const response = new Promise((resolve, reject) => {
// typescript forgets in this promise scope that this.url is not undefined
const socket = new IsoWebSocket(this.url, this.options);
this.socket = socket;
socket.onerror = (errorEvent) => {
reject(new HolochainError("ConnectionError", `could not connect to Holochain Conductor API at ${this.url} - ${errorEvent.error}`));
};
socket.onopen = () => {
this.sendMessage(request, resolve, reject);
};
this.setupSocket();
});
return response;
}
else {

@@ -148,0 +155,0 @@ return Promise.reject(new Error("Socket is not open"));

@@ -19,3 +19,3 @@ /// <reference types="ws" />

*/
export type RequesterUnit<Res> = () => Promise<Res>;
export type RequesterNoArg<Res> = (timeout?: number) => Promise<Res>;
/**

@@ -22,0 +22,0 @@ * @public

@@ -14,4 +14,3 @@ const ERROR_TYPE = "error";

const response = await requester(input, timeout);
const output = transform.output(response.data);
return output;
return transform.output(response.data);
};

@@ -18,0 +17,0 @@ const identity = (x) => x;

export { hashZomeCall } from "@holochain/serialization";
export * from "./admin/index.js";
export * from "./app-agent/index.js";
export * from "./app/index.js";
export { IsoWebSocket, WsClient } from "./client.js";
export { IsoWebSocket, WsClient, AppAuthenticationRequest } from "./client.js";
export { CloneId, HolochainError, getBaseRoleNameFromCloneId, isCloneId, type Requester, type Transformer, type WebsocketConnectionOptions, type WsClientOptions, } from "./common.js";
export * from "./zome-call-signing.js";
export { hashZomeCall } from "@holochain/serialization";
export * from "./admin/index.js";
export * from "./app-agent/index.js";
export * from "./app/index.js";

@@ -5,0 +4,0 @@ export { IsoWebSocket, WsClient } from "./client.js";

@@ -1,3 +0,3 @@

import { CallZomeRequest } from "../api/app/types.js";
import { CallZomeRequestSigned, CallZomeRequestUnsigned } from "../api/app/websocket.js";
import { CallZomeRequest } from "../api";
import { CallZomeRequestSigned, CallZomeRequestUnsigned } from "../api";
import { InstalledAppId } from "../types.js";

@@ -4,0 +4,0 @@ export interface LauncherEnvironment {

import { encode } from "@msgpack/msgpack";
import { invoke } from "@tauri-apps/api/tauri";
import { getNonceExpiration, randomNonce } from "../api/zome-call-signing.js";
import { getNonceExpiration, randomNonce } from "../api";
const __HC_LAUNCHER_ENV__ = "__HC_LAUNCHER_ENV__";

@@ -5,0 +5,0 @@ const __HC_ZOME_CALL_SIGNER__ = "__HC_ZOME_CALL_SIGNER__";

{
"name": "@holochain/client",
"version": "0.17.0-dev.9",
"version": "0.17.0-dev.10",
"description": "A JavaScript client for the Holochain Conductor API",
"author": "Holochain Foundation <info@holochain.org> (http://holochain.org)",
"author": "Holochain Foundation <info@holochain.org> (https://holochain.org)",
"license": "CAL-1.0",

@@ -35,3 +35,4 @@ "repository": {

"lint": "eslint --fix --ext .ts src test .eslintrc.cjs",
"test:app-agent": "RUST_LOG=error RUST_BACKTRACE=1 tsx test/e2e/app-agent-websocket.ts",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"test:app-agent": "RUST_LOG=error RUST_BACKTRACE=1 tsx test/e2e/app-websocket.ts",
"test:utils": "RUST_LOG=error RUST_BACKTRACE=1 tsx test/e2e/utils.ts",

@@ -38,0 +39,0 @@ "test": "RUST_LOG=error RUST_BACKTRACE=1 tsx test/index.ts",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc