From 07d129ba89a478198ac1c91b5b6d45308bc626b7 Mon Sep 17 00:00:00 2001 From: ThetaSinner Date: Thu, 22 Aug 2024 16:01:59 +0100 Subject: [PATCH 1/3] Support system signals --- CHANGELOG.md | 1 + docs/client.appclient.on.md | 4 +- docs/client.appevents.md | 2 +- docs/client.appevents.signal.md | 2 +- docs/client.appsignalcb.md | 14 --- docs/client.appwebsocket.on.md | 4 +- docs/client.md | 50 ++++++++--- docs/client.preflightresponse.agent_state.md | 13 +++ docs/client.preflightresponse.md | 94 ++++++++++++++++++++ docs/client.preflightresponse.request.md | 13 +++ docs/client.preflightresponse.signature.md | 13 +++ docs/client.rawsignal.md | 18 ++++ docs/client.signal.md | 6 +- docs/client.signalcb.md | 14 +++ docs/client.systemsignal.md | 16 ++++ flake.lock | 40 ++++----- src/api/app/types.ts | 31 +++++-- src/api/app/websocket.ts | 12 ++- src/api/client.ts | 30 ++++--- src/hdk/countersigning.ts | 18 ++++ 20 files changed, 316 insertions(+), 79 deletions(-) delete mode 100644 docs/client.appsignalcb.md create mode 100644 docs/client.preflightresponse.agent_state.md create mode 100644 docs/client.preflightresponse.md create mode 100644 docs/client.preflightresponse.request.md create mode 100644 docs/client.preflightresponse.signature.md create mode 100644 docs/client.rawsignal.md create mode 100644 docs/client.signalcb.md create mode 100644 docs/client.systemsignal.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 4318b304..1372b212 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added ### Changed +- Signal listeners changed from only returning an `AppSignal` to a `Signal` which can be either an app or system signal. ### Fixed ### Removed diff --git a/docs/client.appclient.on.md b/docs/client.appclient.on.md index ffab24a8..2ba774a1 100644 --- a/docs/client.appclient.on.md +++ b/docs/client.appclient.on.md @@ -7,7 +7,7 @@ **Signature:** ```typescript -on(eventName: Name | readonly Name[], listener: AppSignalCb): UnsubscribeFunction; +on(eventName: Name | readonly Name[], listener: SignalCb): UnsubscribeFunction; ``` ## Parameters @@ -49,7 +49,7 @@ listener -[AppSignalCb](./client.appsignalcb.md) +[SignalCb](./client.signalcb.md) diff --git a/docs/client.appevents.md b/docs/client.appevents.md index bc8f1ce9..7cc496f7 100644 --- a/docs/client.appevents.md +++ b/docs/client.appevents.md @@ -44,7 +44,7 @@ Description -[AppSignal](./client.appsignal.md) +[Signal](./client.signal.md) diff --git a/docs/client.appevents.signal.md b/docs/client.appevents.signal.md index 8549ae85..7ebf7a8c 100644 --- a/docs/client.appevents.signal.md +++ b/docs/client.appevents.signal.md @@ -7,5 +7,5 @@ **Signature:** ```typescript -signal: AppSignal; +signal: Signal; ``` diff --git a/docs/client.appsignalcb.md b/docs/client.appsignalcb.md deleted file mode 100644 index 7ad3881d..00000000 --- a/docs/client.appsignalcb.md +++ /dev/null @@ -1,14 +0,0 @@ - - -[Home](./index.md) > [@holochain/client](./client.md) > [AppSignalCb](./client.appsignalcb.md) - -## AppSignalCb type - - -**Signature:** - -```typescript -export type AppSignalCb = (signal: AppSignal) => void; -``` -**References:** [AppSignal](./client.appsignal.md) - diff --git a/docs/client.appwebsocket.on.md b/docs/client.appwebsocket.on.md index 110172e3..b46f6c88 100644 --- a/docs/client.appwebsocket.on.md +++ b/docs/client.appwebsocket.on.md @@ -9,7 +9,7 @@ Register an event listener for signals. **Signature:** ```typescript -on(eventName: Name | readonly Name[], listener: AppSignalCb): UnsubscribeFunction; +on(eventName: Name | readonly Name[], listener: SignalCb): UnsubscribeFunction; ``` ## Parameters @@ -53,7 +53,7 @@ listener -[AppSignalCb](./client.appsignalcb.md) +[SignalCb](./client.signalcb.md) diff --git a/docs/client.md b/docs/client.md index 6d87eb08..b4cce9cd 100644 --- a/docs/client.md +++ b/docs/client.md @@ -928,6 +928,16 @@ Description + + + +[PreflightResponse](./client.preflightresponse.md) + + + + + + @@ -1454,16 +1464,6 @@ This type is meant to be opaque - - - -[AppSignalCb](./client.appsignalcb.md) - - - - - - @@ -2465,6 +2465,16 @@ An internal link type index within the DNA, from 0 to 255. + + + +[RawSignal](./client.rawsignal.md) + + + + + + @@ -2585,6 +2595,16 @@ An internal link type index within the DNA, from 0 to 255. + + + +[SignalCb](./client.signalcb.md) + + + + + + @@ -2635,6 +2655,16 @@ An internal link type index within the DNA, from 0 to 255. + + + +[SystemSignal](./client.systemsignal.md) + + + + + + diff --git a/docs/client.preflightresponse.agent_state.md b/docs/client.preflightresponse.agent_state.md new file mode 100644 index 00000000..e785aa49 --- /dev/null +++ b/docs/client.preflightresponse.agent_state.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [@holochain/client](./client.md) > [PreflightResponse](./client.preflightresponse.md) > [agent\_state](./client.preflightresponse.agent_state.md) + +## PreflightResponse.agent\_state property + +The chain state declaration for the agent that produced this response. + +**Signature:** + +```typescript +agent_state: CountersigningAgentState; +``` diff --git a/docs/client.preflightresponse.md b/docs/client.preflightresponse.md new file mode 100644 index 00000000..05db536e --- /dev/null +++ b/docs/client.preflightresponse.md @@ -0,0 +1,94 @@ + + +[Home](./index.md) > [@holochain/client](./client.md) > [PreflightResponse](./client.preflightresponse.md) + +## PreflightResponse interface + + +**Signature:** + +```typescript +export interface PreflightResponse +``` + +## Properties + + + + + +
+ +Property + + + + +Modifiers + + + + +Type + + + + +Description + + +
+ +[agent\_state](./client.preflightresponse.agent_state.md) + + + + + + + +[CountersigningAgentState](./client.countersigningagentstate.md) + + + + +The chain state declaration for the agent that produced this response. + + +
+ +[request](./client.preflightresponse.request.md) + + + + + + + +[PreflightRequest](./client.preflightrequest.md) + + + + +The request associated with this response. + + +
+ +[signature](./client.preflightresponse.signature.md) + + + + + + + +[Signature](./client.signature.md) + + + + +The signature of this response, by the agent that created it. + + +
diff --git a/docs/client.preflightresponse.request.md b/docs/client.preflightresponse.request.md new file mode 100644 index 00000000..cb5c4fec --- /dev/null +++ b/docs/client.preflightresponse.request.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [@holochain/client](./client.md) > [PreflightResponse](./client.preflightresponse.md) > [request](./client.preflightresponse.request.md) + +## PreflightResponse.request property + +The request associated with this response. + +**Signature:** + +```typescript +request: PreflightRequest; +``` diff --git a/docs/client.preflightresponse.signature.md b/docs/client.preflightresponse.signature.md new file mode 100644 index 00000000..61f1dc1d --- /dev/null +++ b/docs/client.preflightresponse.signature.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [@holochain/client](./client.md) > [PreflightResponse](./client.preflightresponse.md) > [signature](./client.preflightresponse.signature.md) + +## PreflightResponse.signature property + +The signature of this response, by the agent that created it. + +**Signature:** + +```typescript +signature: Signature; +``` diff --git a/docs/client.rawsignal.md b/docs/client.rawsignal.md new file mode 100644 index 00000000..319b7475 --- /dev/null +++ b/docs/client.rawsignal.md @@ -0,0 +1,18 @@ + + +[Home](./index.md) > [@holochain/client](./client.md) > [RawSignal](./client.rawsignal.md) + +## RawSignal type + + +**Signature:** + +```typescript +export type RawSignal = { + [SignalType.App]: EncodedAppSignal; +} | { + [SignalType.System]: SystemSignal; +}; +``` +**References:** [EncodedAppSignal](./client.encodedappsignal.md), [SystemSignal](./client.systemsignal.md) + diff --git a/docs/client.signal.md b/docs/client.signal.md index f87b06d7..7bd6875b 100644 --- a/docs/client.signal.md +++ b/docs/client.signal.md @@ -9,10 +9,10 @@ ```typescript export type Signal = { - [SignalType.App]: EncodedAppSignal; + [SignalType.App]: AppSignal; } | { - [SignalType.System]: unknown; + [SignalType.System]: SystemSignal; }; ``` -**References:** [EncodedAppSignal](./client.encodedappsignal.md) +**References:** [AppSignal](./client.appsignal.md), [SystemSignal](./client.systemsignal.md) diff --git a/docs/client.signalcb.md b/docs/client.signalcb.md new file mode 100644 index 00000000..6ebf88a8 --- /dev/null +++ b/docs/client.signalcb.md @@ -0,0 +1,14 @@ + + +[Home](./index.md) > [@holochain/client](./client.md) > [SignalCb](./client.signalcb.md) + +## SignalCb type + + +**Signature:** + +```typescript +export type SignalCb = (signal: Signal) => void; +``` +**References:** [Signal](./client.signal.md) + diff --git a/docs/client.systemsignal.md b/docs/client.systemsignal.md new file mode 100644 index 00000000..9a8cde0f --- /dev/null +++ b/docs/client.systemsignal.md @@ -0,0 +1,16 @@ + + +[Home](./index.md) > [@holochain/client](./client.md) > [SystemSignal](./client.systemsignal.md) + +## SystemSignal type + + +**Signature:** + +```typescript +export type SystemSignal = { + SuccessfulCountersigning: EntryHash; +}; +``` +**References:** [EntryHash](./client.entryhash.md) + diff --git a/flake.lock b/flake.lock index 0a678fb8..9bf39199 100644 --- a/flake.lock +++ b/flake.lock @@ -8,11 +8,11 @@ ] }, "locked": { - "lastModified": 1720546058, - "narHash": "sha256-iU2yVaPIZm5vMGdlT0+57vdB/aPq/V5oZFBRwYw+HBM=", + "lastModified": 1721058578, + "narHash": "sha256-fs/PVa3H5dS1//4BjecWi3nitXm5fRObx0JxXIAo+JA=", "owner": "ipetkov", "repo": "crane", - "rev": "2d83156f23c43598cf44e152c33a59d3892f8b29", + "rev": "17e5109bb1d9fb393d70fba80988f7d70d1ded1a", "type": "github" }, "original": { @@ -59,11 +59,11 @@ "hc-scaffold": { "flake": false, "locked": { - "lastModified": 1720709716, - "narHash": "sha256-JrUNDbAiSPl11L8JxtgNfKXV13bWgCD+Xd0hNy8nK9A=", + "lastModified": 1723558677, + "narHash": "sha256-s5WjtXlu8d7U/zY2Kv4daaH0TlSiVc+D+UqR6B7+qj4=", "owner": "holochain", "repo": "scaffolding", - "rev": "3241aaaf52589ced9e29bf616407b867f6927c44", + "rev": "80edba8c2f5512ba0babcc8d84b78c1d79f0d1d8", "type": "github" }, "original": { @@ -76,16 +76,16 @@ "holochain": { "flake": false, "locked": { - "lastModified": 1720573775, - "narHash": "sha256-ElKLtMDQpK+4NJixEz0SerENGgle88vp3GPePoOkCPQ=", + "lastModified": 1723718736, + "narHash": "sha256-f8Hi7HvANahU5lJjtWk+XpnCcIjfMiV0yFxGqzqEXqU=", "owner": "holochain", "repo": "holochain", - "rev": "e7c08520293e17501637f3d36841b1e5c7802603", + "rev": "a3384305850735b1b71fa0ab6f36f2318ec56d28", "type": "github" }, "original": { "owner": "holochain", - "ref": "holochain-0.4.0-dev.12", + "ref": "holochain-0.4.0-dev.18", "repo": "holochain", "type": "github" } @@ -102,11 +102,11 @@ "rust-overlay": "rust-overlay" }, "locked": { - "lastModified": 1721073993, - "narHash": "sha256-rfACEBBvgXnaJLJED2Jaor79TASTxiBtkuOt7K81cXs=", + "lastModified": 1723737493, + "narHash": "sha256-zP22A91tT/i+chslSATQvjKrZTXelwTcDqeNTLLTcyc=", "owner": "holochain", "repo": "holonix", - "rev": "e62126e5cb2fa68a993e1b94b62466b1fbe5b8a9", + "rev": "6438098657b9441e65db1543f0200f22453238de", "type": "github" }, "original": { @@ -135,16 +135,16 @@ }, "nixpkgs": { "locked": { - "lastModified": 1720542800, - "narHash": "sha256-ZgnNHuKV6h2+fQ5LuqnUaqZey1Lqqt5dTUAiAnqH0QQ=", + "lastModified": 1717179513, + "narHash": "sha256-vboIEwIQojofItm2xGCdZCzW96U85l9nDW3ifMuAIdM=", "owner": "nixos", "repo": "nixpkgs", - "rev": "feb2849fdeb70028c70d73b848214b00d324a497", + "rev": "63dacb46bf939521bdc93981b4cbb7ecb58427a0", "type": "github" }, "original": { "owner": "nixos", - "ref": "nixos-unstable", + "ref": "24.05", "repo": "nixpkgs", "type": "github" } @@ -178,11 +178,11 @@ ] }, "locked": { - "lastModified": 1720664424, - "narHash": "sha256-+odiMNHRYdvzL1ewl41UVFxsjmdoXfH+maQ8xvUoR4g=", + "lastModified": 1721269159, + "narHash": "sha256-eHrGuKZKQb762qdCkrfoyyxXLKumYhiXJca1ig0RftE=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "fec97e65fcbaab0decccba740ac8688f61dadd70", + "rev": "c3e217122ac55680606d69bc693bdf262f14f602", "type": "github" }, "original": { diff --git a/src/api/app/types.ts b/src/api/app/types.ts index 1bde5454..be719ebb 100644 --- a/src/api/app/types.ts +++ b/src/api/app/types.ts @@ -8,6 +8,7 @@ import { ClonedCell, DnaHash, DnaProperties, + EntryHash, FunctionName, InstalledAppId, MembraneProof, @@ -81,7 +82,7 @@ export type AppNetworkInfoRequest = Omit; * @public */ export interface AppEvents { - signal: AppSignal; + signal: Signal; } /** @@ -242,16 +243,29 @@ export const SignalType = { App: "App", System: "System", } as const; + /** * @public */ -export type Signal = +export type RawSignal = | { [SignalType.App]: EncodedAppSignal; } | { - [SignalType.System]: unknown; + [SignalType.System]: SystemSignal; + }; + +/** + * @public + */ +export type Signal = + | { + [SignalType.App]: AppSignal; + } + | { + [SignalType.System]: SystemSignal; }; + /** * @public */ @@ -260,6 +274,7 @@ export type EncodedAppSignal = { zome_name: string; signal: Uint8Array; }; + /** * @public */ @@ -268,10 +283,16 @@ export type AppSignal = { zome_name: string; payload: unknown; }; + +/** + * @public + */ +export type SystemSignal = { SuccessfulCountersigning: EntryHash }; + /** * @public */ -export type AppSignalCb = (signal: AppSignal) => void; +export type SignalCb = (signal: Signal) => void; /** * @public @@ -286,7 +307,7 @@ export interface AppClient { on( eventName: Name | readonly Name[], - listener: AppSignalCb + listener: SignalCb ): UnsubscribeFunction; appInfo(): Promise; diff --git a/src/api/app/websocket.ts b/src/api/app/websocket.ts index 8a356603..14fe737a 100644 --- a/src/api/app/websocket.ts +++ b/src/api/app/websocket.ts @@ -22,8 +22,7 @@ import { AppDisableCloneCellRequest, AppEnableCloneCellRequest, AppInfoResponse, - AppSignal, - AppSignalCb, + SignalCb, CallZomeRequest, CallZomeRequestSigned, CallZomeRequestUnsigned, @@ -43,6 +42,7 @@ import { ProvideMemproofsResponse, EnableRequest, EnableResponse, + Signal, } from "./types.js"; import { getHostZomeCallSigner, @@ -175,10 +175,8 @@ export class AppWebsocket implements AppClient { } }); - this.client.on("signal", (signal: AppSignal) => { - if (this.containsCell(signal.cell_id)) { - this.emitter.emit("signal", signal).catch(console.error); - } + this.client.on("signal", (signal: Signal) => { + this.emitter.emit("signal", signal).catch(console.error); }); } @@ -423,7 +421,7 @@ export class AppWebsocket implements AppClient { */ on( eventName: Name | readonly Name[], - listener: AppSignalCb + listener: SignalCb ): UnsubscribeFunction { return this.emitter.on(eventName, listener); } diff --git a/src/api/client.ts b/src/api/client.ts index 1200b670..5ce90f00 100644 --- a/src/api/client.ts +++ b/src/api/client.ts @@ -3,7 +3,7 @@ import Emittery from "emittery"; import IsoWebSocket from "isomorphic-ws"; import { HolochainError, WsClientOptions } from "./common.js"; import { AppAuthenticationToken } from "./admin/index.js"; -import { AppSignal, Signal, SignalType } from "./app/index.js"; +import { AppSignal, RawSignal, Signal, SignalType } from "./app/index.js"; interface HolochainMessage { id: number; @@ -89,20 +89,22 @@ export class WsClient extends Emittery { assertHolochainSignal(deserializedSignal); if (SignalType.System in deserializedSignal) { - // We have received a system signal, do nothing - return; - } - const encodedAppSignal = deserializedSignal[SignalType.App]; + this.emit("signal", { + System: deserializedSignal[SignalType.System], + } as Signal); + } else { + const encodedAppSignal = deserializedSignal[SignalType.App]; - // In order to return readable content to the UI, the signal payload must also be deserialized. - const payload = decode(encodedAppSignal.signal); + // In order to return readable content to the UI, the signal payload must also be deserialized. + const payload = decode(encodedAppSignal.signal); - const signal: AppSignal = { - cell_id: encodedAppSignal.cell_id, - zome_name: encodedAppSignal.zome_name, - payload, - }; - this.emit("signal", signal); + const signal: AppSignal = { + cell_id: encodedAppSignal.cell_id, + zome_name: encodedAppSignal.zome_name, + payload, + }; + this.emit("signal", { App: signal } as Signal); + } } else if (message.type === "response") { this.handleResponse(message); } else { @@ -291,7 +293,7 @@ function assertHolochainMessage( ); } -function assertHolochainSignal(signal: unknown): asserts signal is Signal { +function assertHolochainSignal(signal: unknown): asserts signal is RawSignal { if ( typeof signal === "object" && signal !== null && diff --git a/src/hdk/countersigning.ts b/src/hdk/countersigning.ts index 0990a7e7..a0cc5f80 100644 --- a/src/hdk/countersigning.ts +++ b/src/hdk/countersigning.ts @@ -37,6 +37,24 @@ export interface PreflightRequest { preflight_bytes: PreflightBytes; } +/** + * @public + */ +export interface PreflightResponse { + /** + * The request associated with this response. + */ + request: PreflightRequest; + /** + * The chain state declaration for the agent that produced this response. + */ + agent_state: CountersigningAgentState; + /** + * The signature of this response, by the agent that created it. + */ + signature: Signature; +} + /** * @public */ From e24920fa53a5ea948b915e606ec8f6ce4fe257bd Mon Sep 17 00:00:00 2001 From: ThetaSinner Date: Thu, 22 Aug 2024 16:03:57 +0100 Subject: [PATCH 2/3] Fix signal test --- test/e2e/index.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/e2e/index.ts b/test/e2e/index.ts index b5a5015c..a6a057de 100644 --- a/test/e2e/index.ts +++ b/test/e2e/index.ts @@ -8,7 +8,6 @@ import { ActionType, AdminWebsocket, AppEntryDef, - AppSignal, AppStatusFilter, AppWebsocket, CallZomeRequest, @@ -27,6 +26,8 @@ import { RoleName, encodeHashToBase64, generateSigningKeyPair, + SignalType, + Signal, } from "../../src"; import { FIXTURE_PATH, @@ -811,8 +812,9 @@ test( const signalReceivedPromise = new Promise( (resolve) => (resolveSignalPromise = resolve) ); - const signalCb = (signal: AppSignal) => { - t.deepEqual(signal, { + const signalCb = (signal: Signal) => { + assert(SignalType.App in signal); + t.deepEqual(signal[SignalType.App], { cell_id, zome_name: TEST_ZOME_NAME, payload: "i am a signal", From 384479c1b23c59c777a8c8bd1d83c7ae35b34753 Mon Sep 17 00:00:00 2001 From: ThetaSinner Date: Thu, 22 Aug 2024 18:29:18 +0100 Subject: [PATCH 3/3] Fix other tests --- test/e2e/app-websocket.ts | 7 +++++-- test/e2e/index.ts | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/test/e2e/app-websocket.ts b/test/e2e/app-websocket.ts index 2998fd3b..8dd0fddf 100644 --- a/test/e2e/app-websocket.ts +++ b/test/e2e/app-websocket.ts @@ -12,6 +12,8 @@ import { fakeAgentPubKey, NonProvenanceCallZomeRequest, RoleName, + SignalCb, + SignalType, } from "../../src"; import { createAppWsAndInstallApp, @@ -89,8 +91,9 @@ test( const signalReceivedPromise = new Promise( (resolve) => (resolveSignalPromise = resolve) ); - const signalCb: AppSignalCb = (signal) => { - t.deepEqual(signal, { + const signalCb: SignalCb = (signal) => { + assert(SignalType.App in signal); + t.deepEqual(signal[SignalType.App], { cell_id, zome_name: TEST_ZOME_NAME, payload: "i am a signal", diff --git a/test/e2e/index.ts b/test/e2e/index.ts index a6a057de..72952ff6 100644 --- a/test/e2e/index.ts +++ b/test/e2e/index.ts @@ -547,9 +547,9 @@ test( }); let appInfo = await client.appInfo(); - t.equal( + t.deepEqual( appInfo.status, - "awaiting_memproofs", + { disabled: { reason: "never_started" } }, "app is in status awaiting_memproofs" );