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

1wallet app library #73

Open
polymorpher opened this issue Aug 12, 2021 · 9 comments
Open

1wallet app library #73

polymorpher opened this issue Aug 12, 2021 · 9 comments

Comments

@polymorpher
Copy link
Owner

1wallet app library

The library should allow developers to onboard a user who does not yet have a wallet, or connect a user’s existing wallet to their app. The library should allow the app to

  1. create a new wallet
  2. authenticate the user,
  3. retrieve a user’s wallet information, balance, and transaction history,
  4. perform a transfer
  5. authorize a request (by signature) that may have a time-limit on its validity
  6. revoke an existing authorization

Multiple methods of integration should be provided to developers, because apps may have different user interaction flow and onboarding processes. Some methods are more complex than others and may take weeks to develop the first version. Here, we list the proposed methods by how fast we can develop these methods and make them ready for developers.

Redirect

This method is ideal for web apps to work with web-based 1wallet (https://1wallet.crazy.one).

The user is redirected to a /request endpoint of the site hosting the wallet client (e.g. https://1wallet.crazy.one/request). The specific nature of the request would be specified by GET parameters, e.g. callback URL, app name, reason, action to be performed, any specific wallet, and more. The user would be able to choose a wallet (if one is not specified), inspect the request, and click a button to grant or deny the request. In either case, the user would be redirected back to the app itself.

If the request is granted, the callback would attach information necessary for the app to further process the request, e.g. signature and data, in cases of an authorization or authentication, or transaction id, in cases of a transfer, or just a wallet address, in cases of creating a new wallet. The information should be minimally sufficient. The library itself can perform most read operations (e.g. retrieving wallet information) without using Redirect or requesting an authorization.

Wallet Connect

This method is ideal for a mobile 1wallet client to connect with a web-based app. This is discussed in detail in Part IV of #5. In fact, its core mechanism and data flow is similar to Redirect method. Evaluating this method for a second time, I find its additional complexity is only justified in the narrow scope of mobile 1wallet client working with a web-based app, because Redirect method is significantly easier to implement for a web-to-web integration, and Redirect method can be similarly implemented for a scenario connecting mobile 1wallet to mobile based app: the app could use deep link to redirect to the 1wallet mobile app (or simply open a browser link which triggers the activation of the 1wallet mobile app), and the 1wallet mobile app can perform a callback similarly to the original app.

Import

This method is ideal for apps or other web clients that intend to function as a wallet, and to perform all operations such as transfer, authorization, and signing inside the app. In these operations, OTP would still be required from the user.

The process begins by the app asking the user (via a function call to the library) to select a local file previously exported from 1wallet that contains the state of the wallet and the proofs the wallet generated. For a complete export of a standard 1wallet that has a 1-year lifespan, the file should be around 64MB. The export can be a partial export, in which case it only contains proofs needed for a subset of time ranges, and the size of the file would be substantially less. After the user selects a file, the library would process the file and essentially generates a copy of the 1wallet inside the app, and store a copy of the proofs in IndexedDB under the app’s domain. The app can then use functions from the library to perform the desired operations (subject to user’s approval using OTPs). Note that, a large amount of implementation work should be expected by using this approach, since the app would essentially have to implement the UI and user interactions related to all the operations by the app itself. The app would be unable to leverage existing 1wallet UI as in the Redirect method. The library does not provide any UI either. It only provides the core functions.

We will add export functionality to our 1wallet client soon (https://1wallet.crazy.one)

IPFS

This method serves the purpose as in the Import method. The core mechanism of this method is similar to Import, except the proofs needed by the wallet at any given point of time would be dynamically loaded from IPFS. The app still needs to get one piece of information for the library: the hseed from the client. The hseed is necessary to produce the proof needed for every operation on the wallet. The hseed is 18-26 bytes long (e.g. a hexadecimal string of 36-52 characters long), depending on the setting and version of the wallet.

This method requires the IPFS version of the implementation of Scrambled Memory Layout (revised) (#63) to function. It may take some time before we can get to it and make it work reliability.

After the above implementation is complete, we will add a feature for the user to display and copy the hseed from our 1wallet client (https://1wallet.crazy.one).

@givp
Copy link
Collaborator

givp commented Aug 12, 2021

@polymorpher for the redirect option, I recommend borrowing concepts from OAuth2 protocol by making the handshake a multi-step process. Like OAuth, the redirect should obtain a temporary request token and then the client can use that to exchange with an access token to complete the transaction. It is obviously not identical but I see many "man in the middle" security holes if the redirect flow is not implemented correctly.

@polymorpher
Copy link
Owner Author

@polymorpher for the redirect option, I recommend borrowing concepts from OAuth2 protocol by making the handshake a multi-step process. Like OAuth, the redirect should obtain a temporary request token and then the client can use that to exchange with an access token to complete the transaction. It is obviously not identical but I see many "man in the middle" security holes if the redirect flow is not implemented correctly.

I thought about using OAuth2. The problems are the following. It would require the application developer to register the app with a central authority which manages and generates secrets for each application. The app would also be forced to bind with a particular client instead of the wallet, since the confidential OAuth token cannot be stored on the wallet - it has to be stored at the wallet client and has a short-lifespan.

A major difference between OAuth flow and the use cases here is that neither the app nor the wallet would be expected to do anything offline - the user is involved in every step, and no authorization token is issued to allow either the wallet or the app to do anything without the user's involvement. I think Redirect should be secure against attacks for the following reasons:

  1. The first redirect from the app to the wallet is secured by HTTPS. If the app redirects to a malicious URL, the malicious URL would not be able to perform use case (2)(4)(5)(6) because it cannot access the storage and state of the wallet which are associated with 1wallet.crazy.one.
    1. For use case (1), if the malicious URL creates a tampered wallet, the client library can detect the wallet's code hash is incorrect by retrieving and hashing the code using the returned wallet address. We cannot prevent a malicious URL from creating a untampered wallet, but neither can OAuth, and this scenario would be harmless.
  2. At the wallet, the user can inspect the request and verify the requested parameters. This and step 1 ensure the request is not tampered with.
  3. If the request generates a signature, the signature committed, produced, and stored on-chain will be only valid for the request. This applies to use case (2)(5)(6). The signature can also be validated by the app by performing read-only operation on-chain via the library.
  4. If the request performs some action and produces a transaction id (use case (4)) or an address (use case (1)), the transaction id can be validated similarly to step 3.
  5. Use case (3) does not require Redirect.

@givp
Copy link
Collaborator

givp commented Aug 13, 2021

Would be great to create a data flow diagram for the redirect solution.

@stephen-tse
Copy link
Collaborator

let's focus first on just the use case 6 (authorize a request). a tip jar demo as a single-page web app will be useful for our hackathon – even as dao peer bonus like yearn's https://coordinape.com. a helpful feature: no reauthorize for 30 mins for total 100 ONE tokens.

for ux or security flow, google "ethereum login" or "ethereum authentication" or "ethereum iframe". https://github.com/burner-wallet/burner-wallet-2 is a good reference, too.

@polymorpher
Copy link
Owner Author

polymorpher commented Aug 14, 2021

Coordinape restricts access but the article linked on the site is informative: https://medium.com/iearn/decentralized-payroll-management-for-daos-b2252160c543

Yes, we can start with a quick tip jar demo based on (5) request authorization and (4) transfer

@Dewansahil
Copy link

@polymorpher have you checked out Atheneum app connection libraries? https://docs.authereum.com/integration

@hypnagonia
Copy link

hypnagonia commented Aug 31, 2021

when using redirect an application loses all non-persistent state

we can extend redirect approach providing developers conventional library with async methods

const address = await wallet.auth()

using cross tab communication
https://github.com/pubkey/broadcast-channel

library on page A opens wallet's redirect url on new tab B
on B wallet eventually redirects back to callback url
library listens to location change and once it is callback url, emits data to other tabs (A) and self close (B)
on page A library receives the crosstab event and returns the response to the app

so we can implement conventional wallet connect interfaces like
https://github.com/WalletConnect/walletconnect-monorepo

@polymorpher
Copy link
Owner Author

Note: work is underway in various PRs. Also see documentation in https://github.com/polymorpher/one-wallet/wiki/App-Integration

@saugion
Copy link

saugion commented Jan 5, 2022

This is a great project, I'm starting to develop an application based on Harmony and I'd really love to be able to integrate such a feature. Will follow this thread with lot of curiosity. Good luck!

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

No branches or pull requests

6 participants