IC WebSocket: Stable Release

Hello IC community,

IC WebSocket is ready to be used in your canisters!
Compared to the beta release, the new IC WebSocket protocol is much simpler and lightweight.

We published the following SDKs as packages in the respective registries:

As always, we are hosting a fully managed version of the IC WebSocket Gateway which you can use for your canisters as explained at the end of the getting started tutorial that @ilbert wrote. This tutorial has been updated and still remains the easiest way for you to get started using IC WebSocket.

You can find some examples in the following repositories:

  • Ping pong (Rust backend + JS frontend):
  • Ping pong (Motoko backend + JS frontend)
  • Chat (Motoko backend + JS frontend)

Thanks a lot @iamenochchirima for the Motoko examples!

If you have any feedback, feature request, bug report or simply want to reach out to us, join our Discord.

Looking forward to what you will build!

43 Likes

Congratz guys, nice work. Perfect timing too, il want to be using this for a feature soon.

5 Likes

Awesome! Really nice work @massimoalbarello and @ilbert!

3 Likes

Can you explain the plans with the hosted gateway? Will it become a part of the boundary nodes? When?

6 Likes

Awesome! Congrats! Starting to work implementing changes to our IC4J WebSocket Client. Should be out soon.

6 Likes

In the short term the WS Gateway cannot be integrated into the API Boundary Node because this decision would have to be proposed and adopted by the community, as API Boundary Nodes will soon be controlled by the NNS.
This implies that only the API Boundary Node image can run on the server which the NNS will elect as a Boundary Node.
Therefore, the only way to put the WS Gateway into a Boundary Node would be to integrate it into the API Boundary Node image but this is not something we can do right now.

However, this does NOT mean that developers must run their own WS Gateway, in the same way as they do NOT have to run their own HTTP Gateway.
Once the the API Boundary Node is integrated into the NNS, both the HTTP Gateway and the WS Gateway will be hosted on separate servers “outside” of the IC.
Dfinity will certainly host an HTTP Gateway - and hopefully also a WS Gateway - but many others will be able to do so. This way developers do NOT have to host their Gateway and do NOT have to rely on Dfinity (or on us) as the only providers of Gateways.
Designing a mechanism for rewarding the providers of WS Gateways (and maybe even HTTP Gateways) is something that we are considering and would be great to hear other people’s opinion on this.

Regarding the guarantees, as of right now, we provide a way for the client and canister to detect whether the WS Gateway acted maliciously (tampered, reordered or blocked the messages) and in the future we could integrate a way to switch from one WS Gateway to another in case malicious behaviour is detected. Also, once VetKeys are implemented the SDK and CDK, the WS Gateway will not be able to read the messages it relays and therefore developers can consider it as a fully trustless intermediary.

Let me know if there is something I missed.

14 Likes

Awesome! Big round of applause to @massimoalbarello & @ilbert , and also to Dfinity (@Kobi and the team).

4 Likes

WebSockets tech has a lot of vulnerabilities, is prone to many attack vectors. What could be the best ways to protect our new jewel in IC?

1 Like

Which attacks are you referring to?

I googled “websocket vulnerability OR attack” to check how things are circa 2023, plenty to be cautious about, imho.

1 Like

Hi @massimoalbarello i was busy doing some tests and everything works pretty smooth except for the fact that initializing the websocket on the frontend required a SignIdentity / Secp256k1KeyIdentity

const ws = new IcWebSocket(gatewayUrl, undefined, {
    canisterId: backendCanisterId,
    identity: generateRandomIdentity(),
    networkUrl: icUrl
});

Is there any specific reason to not accept the same options as creating an HttpAgent for an Actor (a regular Identity or Ed25519KeyIdentity)?

The dapp i want to integrate this in has multiple options to login from an getting a SignIdentity or Secp256k1KeyIdentity isn’t possible in all cases afaik.

Hi @rem.codes, SignIdentity is just an Identity that can sign blobs as stated in the agent-js code:

and both Ed25519KeyIdentity and ECDSAKeyIdentity implement it (see here and here), so it should be possible for you to pass them to the IcWebSocket constructor. Isn’t it working for you?

We can’t just have an Identity in the parameters because that can also be an AnonymousIdentity, but the IC WebSocket protocol doesn’t allow anonymous clients. We created the generateRandomIdentity function so that you can pass a temporary identity (newly generated every time you call that function) to the constructor without having the need to have a user identity.

By the way, we’re working with @iamenochchirima to provide an example that uses the Internet Identity of a user to open an IC WebSocket connection.

1 Like

to be honest i have no clue, why its not working, mainly because no errors are thrown that something is going wrong, the only confirmation i have is the console.log in the ws.onopen.

This is the code that i have, the identity here is the same as the one we pass into a agent so i would assume it should work.

if i change the identity on the initialize ws params to generateRandomIdentity() it connects and goes into the ws.onopen.

We are using all dfinity packages on 0.19.3, so thats shouldnt be an issue

const identity = await getIdentity(); // returns `Ed25519KeyIdentity | DelegationIdentity` (both extends `SignIdentity`)

console.log(!!identity); // returns true;
if (identity) {
	const ws = new IcWebSocket(gatewayUrl, undefined, {
		canisterId: backendCanisterId,
		identity: identity,
		networkUrl: icUrl
	});

	ws.onopen = () => {
		console.log('WebSocket state:', ws?.readyState, 'is open:', ws?.readyState === ws?.OPEN);
	};
}
1 Like

Let me try to reproduce it and I’ll get back to you asap. @RMCS which IC WebSocket SDK version are you using?

2 Likes

Thanks, these are the versions im using

frontend

"ic-websocket-js": "^0.1.2",

backend

ic-websocket-cdk = "0.1.2"
2 Likes

Hi @ilbert,

Is this version really stable?

Running the ping-pong example works like a charm but i’ve been trying to send messages to different principals / identities that are generated from a seedphrase and the behaviour is pretty unexpected where sometimes it connects, sometimes it don’t, sometimes i receive messages, sometimes i don’t (without doing any code changes).

Is there maybe a chance to get you on a call and see if i’m doing anything wrong?

Sure let’s have a call, feel free to book a session on my calendar: IC WebSocket | Luca Bertelli | Cal.com.

1 Like

I’m having the same issue.

I did the Ping Pong with the random identity function and works just fine.

Then i added my logic to front and backend and also works fine with the random identity but in the moment i added the identity from II, the ws just closes in the moment is open with no error or any log.

If i force and send identity._inner the websocket works again, but as it is another principal signing the calls it doesn’t work for my use case.

As a note, i’m using motoko for the backend.

@rem.codes @pk34 we managed to find the what was causing the issue and published the updates!
New versions:

If you’re using a self-hosted gateway or running it locally, please update it to v1.0.4.

We fixed the issue with Internet Identities: now you can pass an identity from authClient.getIdentity() to the IcWebSocket constructor.

These updates also introduce a new feature for serialization and deserialization of the messages: in the JS SDK, you must now create the ws config using the createWsConfig() function and pass the generated actor from the declarations in the canisterActor parameter. This way, you can:

  • receive your application message in the onmessage callback without the need to explicitly deserialize it
  • pass your application message directly to the ws.send method, without the need to serialize it

Head over to the updated tutorial and/or the example for more details.

6 Likes

Fantastic work, excited to see what you’ll create)!!!

2 Likes