Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update proposal for SIP-20 to enable two-way communication between Snap and WebSockets #149

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

david0xd
Copy link
Contributor

@david0xd david0xd commented Oct 1, 2024

This PR is proposal to update SIP-20 in order to support two-way communication between Snap and WebSockets.

Fixes: MetaMask/snaps#2728

@david0xd david0xd self-assigned this Oct 1, 2024
@david0xd david0xd requested review from Montoya, ziad-saab and a team as code owners October 1, 2024 12:42
@@ -1,22 +1,23 @@
---
sip: 20
title: External data entry point
title: Advanced external communication and events
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like the name is not reflecting what this SIP really is anymore? Looking for advice to change it if possible. Updated with one of the ideas I had.

status: Draft
author: David Drazic (@david0xd)
created: 2023-12-15
---

## Abstract

This SIP proposes a new permission that enables Snaps to receive data from external sources.
This SIP proposes a new permission that enables Snaps to receive data from external sources and send data back to them.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not all external sources necessarily support two-way communication.

Comment on lines +15 to +16
The Snap can then do whatever it wants with the data.
The Snap can use RPC method to send data back to the external connection (e.g. websocket connection).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The Snap can then do whatever it wants with the data.
The Snap can use RPC method to send data back to the external connection (e.g. websocket connection).
The Snap can then do whatever it wants with the data, and can send data back to the external source if supported (e.g., a WebSocket connection).


## Motivation

Snaps are currently limited in their ability to receive data from external sources; they have to rely on user actions or cron jobs to fetch data, so they can't react to events in real time. Snaps also cannot use WebSocket connections to receive data from external sources, and are limited to HTTP requests.
Snaps are currently limited in their ability to both receive and send data from and to external sources; they have to rely on user actions or cron jobs to fetch data, so they can't react to events in real time. Snaps also cannot use WebSocket connections for bidirectional communication, and are limited to HTTP requests.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Snaps are currently limited in their ability to both receive and send data from and to external sources; they have to rely on user actions or cron jobs to fetch data, so they can't react to events in real time. Snaps also cannot use WebSocket connections for bidirectional communication, and are limited to HTTP requests.
Snaps are currently limited in their ability to communicate with external sources; they have to rely on user actions or cron jobs to fetch data, so they can't react to events in real time. Snaps also cannot use WebSocket connections for bidirectional communication, and are limited to HTTP requests.

@@ -111,6 +112,35 @@ The caveats MUST NOT have duplicate objects with the same `url` properties.

The `url` MUST start with `wss://` which is a protocol indicator for secure WebSocket connection.

### RPC Methods

This SIP introduces new RPC method for sending data to the external connections.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This SIP introduces new RPC method for sending data to the external connections.
This SIP introduces a new RPC method for sending data to the external connections (if supported).


Snap can use `snap_sendData` RPC method to send data specified within request params.
The proposed RPC method `snap_sendData` SHOULD be a restricted RPC method requiring user consent before usage via the permission system. The RPC method SHOULD only be available to Snaps.
Snap MUST specify destination which is URL identifier of an external connection (e.g. websocket). Destination MUST be exact match of some of the URLs defined in manifest's permission caveats within `endowment:external-data`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In theory the same URL can be used twice, in which case it would be ambiguous which one to use.

Snap MUST specify destination which is URL identifier of an external connection (e.g. websocket). Destination MUST be exact match of some of the URLs defined in manifest's permission caveats within `endowment:external-data`.

The `snap_sendData` JSON-RPC method takes an object as parameters, which has the following properties:
- `data` (required, `string` or `binary`): A data, which MUST NOT be empty.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary when this is already specified by the endowment:external-data dataType?

#### snap_sendData

Snap can use `snap_sendData` RPC method to send data specified within request params.
The proposed RPC method `snap_sendData` SHOULD be a restricted RPC method requiring user consent before usage via the permission system. The RPC method SHOULD only be available to Snaps.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should just use endowment:external-data for this RPC method as well.

}
```

The method returns a `boolean`, `true` in case of successful delivery of a message to the WebSocket, `false` if delivery was unsuccessful.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it throw an error instead if delivery failed?

Comment on lines +177 to +201
/**
* A text message sent to a WebSocket.
*
* @property type - The type of the message.
* @property message - The message as a string.
* @property destination - The destination web socket URL as a string.
*/
type WebSocketOutgoingTextMessage = {
type: 'text';
message: string;
destination: string;
};

/**
* A binary message sent to a WebSocket.
*
* @property type - The type of the message.
* @property message - The message as an ArrayBuffer.
* @property destination - The destination web socket URL as a string.
*/
type WebSocketOutgoingBinaryMessage = {
type: 'binary';
message: ArrayBuffer;
destination: string;
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be simplified:

type WebSocketIncomingMessage = WebSocketIncomingTextMessage | WebSocketIncomingBinaryMessage;
type WebSocketOutgoingMessage = WebSocketIncomingMessage & {
  destination: string;
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Update SIP-20 for Accounts requirements
2 participants