Skip to content

Commit

Permalink
refactor(app-ws)!: simplify zome call parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
jost-s committed Nov 21, 2024
1 parent de866af commit 0a31ea4
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 73 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added
### Fixed
### Changed
- Simplify zome call parameters. `cap_secret`, `provenance` and `payload` are optional parameters of a `CallZomeRequest`. If implicit zome call signing is used, which happens when calling a zome with a `CallZomeRequest`, `provenance` and `cap_secret` are automatically set with the authorized signing credentials. It is still possible to call a cell by its role name instead of its cell id. Alternatively to passing in a `CallZomeRequest`, `callZome` can be invoked with a signed request `CallZomeRequestSigned`, where the zome call parameters have already been serialized and signed.
### Removed

## 2024-11-21: v0.19.0-dev.4
Expand Down
72 changes: 22 additions & 50 deletions src/api/app/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,38 +26,6 @@ import {
SignedActionHashed,
} 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
| CallZomeRequest
| CallZomeRequestAllParams;

/**
* @public
*/
Expand Down Expand Up @@ -91,34 +59,35 @@ export interface AppEvents {
/**
* @public
*/
export interface CallZomeRequestAllParams extends CallZomeRequest {
cap_secret: CapSecret | null;
nonce: Nonce256Bit;
expires_at: number;
}

export type CallZomeRequestGeneric<Payload> = {
cell_id: CellId;
zome_name: ZomeName;
fn_name: FunctionName;
provenance?: AgentPubKey;
payload?: Payload;
cap_secret?: CapSecret;
nonce?: Nonce256Bit;
expires_at?: number;
};
/**
* @public
*/
export interface CallZomeRequestSigned {
bytes: Uint8Array;
signature: Uint8Array;
}
export type CallZomeRequest = CallZomeRequestGeneric<any>;

/**
* @public
*/
export type CallZomeRequestGeneric<Payload> = {
cell_id: CellId;
zome_name: ZomeName;
fn_name: FunctionName;
payload: Payload;
provenance: AgentPubKey;
export type RoleNameCallZomeRequest = Omit<CallZomeRequest, "cell_id"> & {
role_name: RoleName;
};

/**
* @public
*/
export type CallZomeRequest = CallZomeRequestGeneric<any>;
export interface CallZomeRequestSigned {
bytes: Uint8Array;
signature: Uint8Array;
}

/**
* @public
Expand Down Expand Up @@ -526,7 +495,10 @@ export type NetworkInfoResponse = NetworkInfo[];
* @public
*/
export interface AppClient {
callZome(args: AppCallZomeRequest, timeout?: number): Promise<any>;
callZome(
args: CallZomeRequest | RoleNameCallZomeRequest,
timeout?: number
): Promise<any>;

on<Name extends keyof AppEvents>(
eventName: Name | readonly Name[],
Expand Down
27 changes: 12 additions & 15 deletions src/api/app/websocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {
Transformer,
} from "../common.js";
import {
AppCallZomeRequest,
AppClient,
AppEvents,
AppNetworkInfoRequest,
Expand All @@ -30,7 +29,6 @@ import {
SignalCb,
CallZomeRequest,
CallZomeRequestSigned,
CallZomeRequestAllParams,
CallZomeResponse,
CallZomeResponseGeneric,
CreateCloneCellRequest,
Expand All @@ -54,6 +52,7 @@ import {
AbandonCountersigningSessionStateResponse,
PublishCountersigningSessionStateRequest,
PublishCountersigningSessionStateResponse,
RoleNameCallZomeRequest,
} from "./types.js";
import {
getHostZomeCallSigner,
Expand Down Expand Up @@ -363,7 +362,7 @@ export class AppWebsocket implements AppClient {
* @returns The zome call's response.
*/
async callZome<ReturnType>(
request: AppCallZomeRequest,
request: CallZomeRequest | RoleNameCallZomeRequest,
timeout?: number
): Promise<ReturnType> {
if (!("provenance" in request)) {
Expand All @@ -375,19 +374,17 @@ export class AppWebsocket implements AppClient {
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: CallZomeRequest = {
request = {
...omit(request, "role_name"),
provenance: this.myPubKey,
cell_id: [cell_id[0], cell_id[1]],
cell_id,
};
return this.callZomeRequester(zomeCallPayload, timeout);
} else if ("cell_id" in request && request.cell_id) {
return this.callZomeRequester(request as CallZomeRequest, timeout);
} else if (!("cell_id" in request)) {
throw new HolochainError(
"MissingRoleNameOrCellId",
"callZome requires a role_name or cell_id argument"
);
}
throw new HolochainError(
"MissingRoleNameOrCellId",
"callZome requires a role_name or cell_id argument"
);
return this.callZomeRequester(request, timeout);
}

/**
Expand Down Expand Up @@ -603,7 +600,7 @@ export const signZomeCall = async (request: CallZomeRequest) => {
)}, ${encodeHashToBase64(request.cell_id[1])}]`
);
}
const unsignedZomeCallPayload: CallZomeRequestAllParams = {
const zome_call_params: CallZomeRequest = {
cap_secret: signingCredentialsForCell.capSecret,
cell_id: request.cell_id,
zome_name: request.zome_name,
Expand All @@ -613,7 +610,7 @@ export const signZomeCall = async (request: CallZomeRequest) => {
nonce: await randomNonce(),
expires_at: getNonceExpiration(),
};
const bytes = encode(unsignedZomeCallPayload);
const bytes = encode(zome_call_params);
const bytesHash = new Uint8Array(sha512.array(bytes));
await _sodium.ready;
const sodium = _sodium;
Expand Down
12 changes: 4 additions & 8 deletions test/e2e/app-websocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import assert from "node:assert";
import test from "tape";
import {
AdminWebsocket,
AppCallZomeRequest,
AppCreateCloneCellRequest,
AppEntryDef,
AppWebsocket,
CallZomeRequest,
CellType,
CloneId,
fakeAgentPubKey,
NonProvenanceCallZomeRequest,
RoleName,
RoleNameCallZomeRequest,
SignalCb,
SignalType,
} from "../../src";
Expand Down Expand Up @@ -116,7 +116,6 @@ test(
zome_name: TEST_ZOME_NAME,
fn_name: "emitter",
provenance: await fakeAgentPubKey(),
payload: null,
});
await signalReceivedPromise;
})
Expand Down Expand Up @@ -196,7 +195,6 @@ test(
zome_name: TEST_ZOME_NAME,
fn_name: "emitter",
provenance: await fakeAgentPubKey(),
payload: null,
});

// signals are received before the timeout step in the JS event loop is completed
Expand Down Expand Up @@ -230,11 +228,10 @@ test(
"clone cell agent key matches base cell agent key"
);

const params: AppCallZomeRequest = {
const params: RoleNameCallZomeRequest = {
role_name: cloneCell.clone_id,
zome_name: TEST_ZOME_NAME,
fn_name: "foo",
payload: null,
};
const response = await appWs.callZome(params);
t.equal(
Expand Down Expand Up @@ -269,11 +266,10 @@ test(
2,
"disabled clone cell is part of app info"
);
const params: NonProvenanceCallZomeRequest = {
const params: CallZomeRequest = {
cell_id: cloneCell.cell_id,
zome_name: TEST_ZOME_NAME,
fn_name: "foo",
payload: null,
};
try {
await appWs.callZome(params);
Expand Down

0 comments on commit 0a31ea4

Please sign in to comment.