-
Notifications
You must be signed in to change notification settings - Fork 989
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
Provide wallet 'plugin' architecture #1983
Conversation
I wonder if we could go a different way and provide our wallet as an embeddable lib (like sqlite or lmdb) |
Perhaps I'm missing something but regarding 2, should the wallet API really be responsible to listening? I would expect more of a receive type method and leave the listening logic to the API consumer. |
we should support the flexible wallet shown on grincon0 for ios, where transport and tx creation were fully decoupled. Then, for 'grin wallet' and grin localhost wallet, they could share a 'grin wallet listen' process similar to what we have now, for performance/batched sends. A clean api between UI and wallet security critical code makes audit smoother and we can fuzz the critical api surface more intensively. |
@ignopeverell no, the api isn't and shouldn't be responsible for listening. In the current implementation there's a wrapper around the API that either starts it up in listener mode (with an http/json listener around it), or allows functions to be called directly (as when the command line wallet is invoked). In the current wallet invocation, you start the listener, which invokes the listener API with a wallet instance. There's also an http client, that can talk to this instance (I've isolated them into a single file in this PR so far). Now I'm thinking now of a scenario where there are several choices listener/client pairs that you can specify in the config file (so like, a 'plugin', if not exactly). The current functionality can be thought of as an http 'plugin' which handles the listening and the corresponding client calls. A keybase 'plugin' would replace the client with keybase chat calls, while the keybase 'listener' would similarly be invoked with a wallet instance, and would watch for keybase messages and invoke the wallet api directly. So the concept of a 'listener' can vary widely depending on what the implementation is (watching chat, polling for files etc).. it would seem we need a place where this listener can be defined with an active wallet instance and call API functions directly. (As I've started in |
So first step anyhow that seems to makes sense is to completely decouple the tx building from send/receive logic. At the moment you have a function like 'send_tx_slate' that builds the transaction, exchanges it via http and completes it. Unfortunately, this means you need a separate function to send to self, and a separate function to output to a file, etc. So I've broken this up into discrete steps in the api, and left the send/receive part up to the caller to complete. I'm trying to introduce the concept of a wallet 'adaptor', which should handle the send/receive logic. The call out to another http node becomes encapsulated in an adaptor trait, and I should be able to rework the output-to-file logic to be another instance of an adapter instead of having to call separate, special functions. Still not sure how to handle listeners and receiving, but this is moving in the right direction now, I think. |
Still experimental, and still not entirely sure how to structure this.
Basically, we're looking at trying to provide easily-swappable implementations of an interface that provides 2 separate things:
1 is fairly straightforward, as it's just a simple call to something that either expects a response or doesn't, that's called by the wallet transaction logic similar to how it's being done now. We may want to break up the wallet api somewhat to ensure that transaction building functions don't send anything to anyone, but just return the result of the current step to pass on / respond as required (that will probably make the workflow a bit more flexible).
Still trying to think this through. I've consolidated the relevant areas of logic into
wallet/src/clients/http.rs
as a start, though I'm thinking as per 1 above the WalletToWalletClient trait can probably go and be replaced with simple function pointer rather than needing to be a trait on the wallet, especially if the transaction logic is broken up a bit.Any comments or ideas on how this should be structured are very welcome.