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

Channel Integration #2878

Closed
ndzik opened this issue Oct 16, 2023 · 12 comments
Closed

Channel Integration #2878

ndzik opened this issue Oct 16, 2023 · 12 comments
Assignees

Comments

@ndzik
Copy link

ndzik commented Oct 16, 2023

We would like to integrate Perun channels according to its specification into Neuron and propose our idea in this issue.

The things that have to be integrated are the following:

  1. Wallet Callback handler (WCH):
    Essentially a RPC service exposed by the Neuron wallet. To aid the implementation of these endpoints we will provide perun-wallet-wrapper. This repository will contain the interfaces and types as well as their conversions. We will also provide a higher-level interface to make it even easier for integration.
    Question remaining: How would we expose any RPC interface in Neuron and how does it fit into your current architecture?

  2. Channel Service Adapter (CSA):
    A client implementation calling the endpoints of the perun-channel-service. The client implementation will also be contained in perun-wallet-wrapper.
    Additionally, we will create a high-level interface, which the client implements. This eases splitting up the work-packages and lets someone else implement a UI against the interface.

  3. UI tying together CSA & WCH:
    Naively, we think of a tab within Neuron presenting the possibility to use Perun channels to the user.
    Actions a user can take:

    • Opening a channel
    • Updating a channel
    • Closing a channel
    • Bonus features:
      • Listing all open channels
      • History of all channels

    The WCH might receive notifications from the externally running channel-service. E.g.: The channel-service requests a signature on some payload. This would call an endpoint in WCH and it would be nice if the WCH would ultimately propagate this signing request to the user. Might be via a popup or something else.
    Actions triggered externally by the channel-service like this might be a component of their own. It is also possible to use dependency injection and create an interface for a notification service which the implementation of WCH expects and calls when necessary. This is up for discussion.

Eager to see your replies (:

@yanguoyu
Copy link
Collaborator

@Keith-CY @homura @yanguoyu

@homura
Copy link
Collaborator

homura commented Oct 16, 2023

Question remaining: How would we expose any RPC interface in Neuron and how does it fit into your current architecture?

The architecture of Neuron is not complicated. Neuron is based on Electron, so we can simply treat it as a web application but with the ability to interact with the OS, and its server is able to push messages to the UI. From a bird's view, it looks like this

The arrows mean the directions of responsive messages

So I imagine that, to integrate with Perun, Neuron needs

  • run a perun-channel-service in the background when Neuron is launched
  • implement a ChannelServiceAdapter in Neuron's Services layer to help users to request to perun-channel-service, such as open, update, or close channels
  • implement a PerunServiceCallbackHandler(a bit like the Sync in the above illustration) module and register it to the ApiController to handle requests from other users (or technically, from perun-channel-service), to ask users if they accept to open, to close, or to update channels

This is a very high-level design, and I think that we may need to discuss the details, but the https://github.com/perun-network/perun-wallet-wrapper and https://github.com/perun-network/channel-service are not accessible, could you change their visibility to public?

@yanguoyu
Copy link
Collaborator

I have one question about the WCH:
Is the RPC service opened by Neuron a local service? If it's a local service, it can not be called by perun channel service. I guess creating a web socket to listen to Perun service's event is better. @ndzik

@ndzik
Copy link
Author

ndzik commented Oct 19, 2023

Thank you for your response and the illusttration. The WCH serves a RPC Interface which can easily be done via a websocket connection.

It is correct that Neuron would in the best case start the channel service similar to the way it allows starting a default node IIRC.

I will take a deeper look at your architecture and get back to you later today 🙏

@ndzik
Copy link
Author

ndzik commented Oct 23, 2023

The ChannelServiceAdapter you mentioned would need to open a connection (could be websocket) on some port to the PerunChannelService running in the background. The implementation can utilize our SimpleChannelServiceClient interface.

All methods there are supposed to be invoked by the user of the Neuron wallet. This interface should be all that is required to implement the actionable front-end part.
An implementation for the SimpleChannelServiceClient will be added to the perun-wallet-wrapper repository.

Regarding the PerunServiceCallbackHandler. It would be easiest if we could construct the WalletServiceServer by using the mkWalletServiceServer constructor. Upon receiving a request on a specific port for Neuron it should be possible to tie that connection to an instance running the gRPC server. If you could confirm/deny, that would be nice.

It can be seen that the WalletServiceServer requires two interfaces which inject Neuron dependencies into this wrapper:

  • WalletBackend: It's type is parameterized by the MessageType it expects to sign. This is important for the signMessageRequest callback. In a real-world scenario the MessageType would be either an interface, or even more instructive, a sum-type identifying all possible allowed messages. This ensures the Wallet is always able to display and decode the to be signed message to the user.
    • The WalletBackend should also be responsible for emitting some kind of notification to the user/pop-up or similar when it's functions are called. Since all methods are requests which ask for permission from the user.
  • MessageValidator: Since we do pre-processing in the wrapper for Perun logic and to make the types used in the WalletBackend easier to use, we inject the MessageValidator. This is the function that narrows down the MessageType and is allowed to throw if it is not able to decode the byte-blob.

Open to any questions and happy to hear from you.

@yanguoyu
Copy link
Collaborator

Thank you for your response. Here is my understanding:SimpleChannelServiceClient is a service used to send requests to the perunService, and the WalletServiceServer responds the perunService and then notifies users. And I have no further questions.

@Keith-CY
Copy link
Collaborator

Hi @ndzik I'm slightly confused by the following statement

Upon receiving a request on a specific port for Neuron it should be possible to tie that connection to an instance running the gRPC server. If you could confirm/deny, that would be nice.

I just had an inspection at https://github.com/perun-network/perun-wallet-wrapper/blob/main/src/services.ts#L161 and it returns a grpc server that connected to the channel service. Which detail should we check for it?

@ndzik
Copy link
Author

ndzik commented Oct 31, 2023

Hi @ndzik I'm slightly confused by the following statement

Upon receiving a request on a specific port for Neuron it should be possible to tie that connection to an instance running the gRPC server. If you could confirm/deny, that would be nice.

I just had an inspection at https://github.com/perun-network/perun-wallet-wrapper/blob/main/src/services.ts#L161 and it returns a grpc server that connected to the channel service. Which detail should we check for it?

Hi @Keith-CY, as you can see in the referenced constructor it receives a WalletBackend<MessageType>. The question we have is how we could display notifications or prompts to the user of Neuron, i.e. do you already have some internal framework for displaying signing requests to the user or do we just come up with something of our own?

Furthermore, where would be the best place to create that grpc server in your applications data-flow. E.g. you might have some initializer module or similar which handles all of that.

Thanks for your help 💪

@Keith-CY
Copy link
Collaborator

Keith-CY commented Nov 1, 2023

Hi @ndzik I'm slightly confused by the following statement

Upon receiving a request on a specific port for Neuron it should be possible to tie that connection to an instance running the gRPC server. If you could confirm/deny, that would be nice.

I just had an inspection at perun-network/perun-wallet-wrapper@main/src/services.ts#L161 and it returns a grpc server that connected to the channel service. Which detail should we check for it?

Hi @Keith-CY, as you can see in the referenced constructor it receives a WalletBackend<MessageType>. The question we have is how we could display notifications or prompts to the user of Neuron, i.e. do you already have some internal framework for displaying signing requests to the user or do we just come up with something of our own?

Got it, currently there isn't a unified API to inform users about a coming transaction request.
Neuron has similar functions for reference:

  1. import a transaction to sign: https://github.com/nervosnetwork/neuron/blob/develop/packages/neuron-wallet/src/controllers/api.ts#L743-L745
    handle('sign-transaction-only', async (_, params) => {
      return this.#offlineSignController.signTransaction(params)
    })

It can be accessed by Menu => Tools => Offline sign

  1. get sign request from dapp via wallet connect(on a feature branch): https://github.com/nervosnetwork/neuron/pull/2880/files#diff-6d296ae0608e078c2b37ecc6f77f4e596ca59022c02d09e635a161c66f39ad63R838-R840
    handle('wc-approve-request', async (_, params) => {
      return this.#walletConnectController.approveRequest(params)
    })

It's demonstrated in the first video in PR(#2880) message

Furthermore, where would be the best place to create that grpc server in your applications data-flow. E.g. you might have some initializer module or similar which handles all of that.

Any suggestion about the architecture @yanguoyu @homura

@ndzik
Copy link
Author

ndzik commented Nov 2, 2023

Thank you for your input @Keith-CY !

Copy link
Contributor

github-actions bot commented Jan 2, 2024

Mark this issue stale because no activity for 60 days

@github-actions github-actions bot added the stale label Jan 2, 2024
Copy link
Contributor

github-actions bot commented Jan 9, 2024

Close this issue because it's inactive since marked stale

@github-actions github-actions bot closed this as completed Jan 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants