-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
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
[Feature request] Support eth_decrypt - metamask encryption and decryption methods. #1422
Comments
💰 I commit a bounty of USD 250 to anybody that can solve this issue. Terms:
|
Please don’t jump on opening a PR or working on this until I have a chance to evaluate whether this is something that makes sense to add to ethers. I’ve considered adding similar features to ethers before, but the consequences and caveats to making encryption “easy” require people to think carefully what they are doing. The example I usually give of this is that when data is encrypted, the length does not change, so you could imagine encrypting a vote for “yes” vs “no”; even when encrypted, if the encrypted text is 3 bytes long, the input was “yes”. So appropriate padding (or random size) is essential to prevent side-channel attacks. I’ll research this more. Ideally there is an EIP in progress for something like this, and then the ability can be added more genetically to Signer. :) |
(Or if you would like, an ancillary package doesn’t require my blessings on any level, if you want to jump the gun ;)) |
@ricmoo This is more request to copy the functionality of metamask as is. Since we would like compatibility to encrypt with ethers and decrypt via metamask and the other way around. Normally you could use the wallets public key to encrypt and its private key to decrypt but metamask does not allow access to the private key via interface and has completely different way of generating an encryption public key and a metamask only |
Right. My concern is adding methods to Provider that only work on MetaMask. It is important to keep things abstract, and come up with standards so things continue to work in the future and for users not using metamask. I just want a moment to research this and reach out to MM before I get flooded with a bunch of PRs because of a bounty offered on this. I am quite particular with making changes, especially changing/adding nee methods to fundamental classes. If the standard is sound, or on its way to broader adoption (EIP or other wallets following suite), then I can also add it to the Wallet object and other Signers. |
Just to add to this, you can still use await window.ethereum.enable()
const provider = new ethers.providers.Web3Provider(window.ethereum);
const accounts = await provider.listAccounts();
const pubkey = await provider.send('eth_getEncryptionPublicKey', [accounts[0]]);
console.log(pubkey); // zpKOsHVU1YdbTKwZJ4u/YBSsu+q6VxJvTfnU8LLCmCg= The docs are available here. |
Now I’m confused again. How would encrypt and decrypt work if they don’t have MetaMask installed? |
Oh, so this feature request is about encryption and decryption methods like metamask to be implemented for general wallets/signers. If there is a signer e.g. Wallet, that keeps the private key with it, then it would work. But if there is a Signer other than metamask (like a ledger or trezor) which similarly doesn't expose private key, then how can those methods be implemented for them? Pls correct me if I am misunderstanding. |
@zemse Exactly. No it would not work for ledger or trezor. This are not actually blockchain functionalities its just metamasks way to reveal them as So if you have a wallet with privateKey it should be possible to generate the same encryption key as in |
Ok, so it sounds like these methods can only be implemented for Wallet class since it is supposed to be initialized with a private key, while no changes in general Signer. You can still extend the Wallet class and add those methods to it, you can even publish the package.
Do you want to add any idea as to why this should be included in the ethers.js code base (since the code snippet appears to contain some dependencies), this might help @ricmoo to take a positive decision. |
Yeah my point of view is that with NFTs and other kinds of blockchain applications encrypting / decrypting or to better say restricting access to only a specific person / owner will become more and more important. Wallets are literally private/public keys and are very useful for this kinds of applications. Like you can encrypt a file with someones public key only because he has a specific token in his wallet. And he and only he will be able to decrypt it with said wallet. The problem arises with compatibility. There is no coherent way to encrypt / decrypt across different wallets. I believe metamasks approach is ok since this can then also get supported by wallets like ledger and trezor. And having this supported in ethers will further approve the options on the market and allow more secure / better applications. So I only see reason too support rather then not. |
This is one reason I want to open a dialog with MetaMask too. There are actually EIP-191 compatible ways to do this, which would mean Ledger and any weird signer (that manages a key) could perform these operations. In a nutshell, you would add a new By choosing an unused This way won’t be backwards compatible with existing keys, but the sooner we move to the generalized solutions, the better. :) And we can provide some alternate way methods for legacy encryption... |
(this is something I have thought a lot about, but want it down properly, not just stapled in ;)) |
@ricmoo I am all for opening a dialog and standardising a way :) So if there are any discussions open I would love to contribute. I would also like to ship apps with best UX asap 😂 But yeah I understand. |
Just my 5 cents: adding |
I don't know why everything has to be complicated.
|
Can we open a discussion with metamask regarding this so we can find a solution that works on both ends? |
I understand that there is interest in a new standard for encrypting/decrypting files. That effort is identified as requiring:
In my experience, it is infeasible that this can be accomplished in 2021 with the slowest part being MetaMask and firmware upgrades. For reference I can say that it has taken several years for MetaMask to adopt ERC-721 and their support was minimal at that. I am a biased source here but some people consider 721 to be a super-important use case. Please use a new issue to discuss any new possible standards and achieve consensus with other projects. For this issue I hope we can continue to discuss making Ethers.JS compatible with the existing and well-documented (i.e. open source software) process that MetaMask already supports. I can help by bringing resources to this effort. I quadruple my original bounty (now USD 1,000) and extend this commitment to 2021-07-31 (previously 2021-07-02). |
For this issue I hope we can continue to discuss making Ethers.JS compatible with the existing and well-documented (i.e. open source software) process that MetaMask already supports. I can help by bringing resources to this effort. I octuple my original bounty (now USD 2,000) and extend this commitment to 2021-09-07 (previously 2021-07-02). |
Is there an EIP for this yet? |
No. I make EIPs after multiple competing implementations of a thing exist. |
Related: ethereum/EIPs#2844 (current) |
I've been following this but only decided to chime in now. Chasing universal standards and support feels....endless. Maybe for OP it might be best to just require users to have MetaMask and leave it at that. Support for Ledger and Trezor and other hardware wallets feels like it's always "on the edge" of breaking. I'm not sure if wallet connect supports this... EDIT: I agree with @fulldecent below. It would be nice to have this in ethers. |
I have participated in and delivered major standards including ERC-721 and IEEE 802.3 ten gigabit ethernet, and I agree standards should not be embarked on lightly. But this issue is much more modest and limited in scope: it is simply asking one major JavaScript framework, Ethers, to be compatible with another major browser extension, MetaMask. |
hello! Is there an update on this? |
@amirgamil Have there been any progress in terms of a standard and adoption? |
Keep in mind any feature in ethers must a long time, being maintained and kept backwards compatible. It must also be included in every dapp that uses ethers; for this reason, and keeping things lean, an attempt is made to find a balance between features that are used frequently by a large number of users and keeping the library lean. It is fairly trivial to add additional libraries that work against ethers porcelain API; for example, creating an Ethers makes an effort to remain flexible and extensible so that application-specific features are easy to add. I don't believe a core library should add features that are not mature and more widely adopted; this is how we get the This is the job os an extension library, until all the sharp corners are smoothed over. |
And I want to reiterate we must not add new algorithms just for a bunch of new features. Cryptography is hard, having different cryptography everywhere is bad. secp256k1 + aes can do their job. There is no need to bring in Nacl/secretbox. If someone would be implementing a EIP or something, make sure it's not nacl. |
Just checkin as well! |
Moving this to the "Ideas Discussion". This may make more sense as an extension package, as the additional size requirements seem like they may be substantial. |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
Since metamask never exposes the private key of a wallet they added another way of encrypting and decrypting data:
https://docs.metamask.io/guide/rpc-api.html#eth-decrypt
https://docs.metamask.io/guide/rpc-api.html#eth-getencryptionpublickey
https://docs.metamask.io/guide/rpc-api.html#encrypting
Since metamask is "special" in this way it is very hard to support encrypting in multiple wallets. So this is a request to add metamasks methods to ethers.js.
Here is how MetaMask can decrypt messages:
https://github.com/MetaMask/eth-sig-util/blob/3d96bb1e1e5d1a1c548095b18e17fdb2802abe5b/src/index.ts#L503-L537
Source:
https://github.com/MetaMask/eth-sig-util/blob/3d96bb1e1e5d1a1c548095b18e17fdb2802abe5b/src/index.ts#L503-L537
https://github.com/MetaMask/eth-simple-keyring/blob/b23bbaf5cb2ac21a33ebaafc567af6cb1cb57cae/index.js
https://github.com/MetaMask/eth-simple-keyring/blob/b23bbaf5cb2ac21a33ebaafc567af6cb1cb57cae/README.md
https://github.com/MetaMask/eth-simple-keyring/search?q=decryptMessage&type=code
https://github.com/MetaMask/KeyringController/blob/master/package.json#L48
https://github.com/MetaMask/KeyringController/blob/1a0dbbaf45e54e7b80200d4a9c6b21ce74b61b2f/index.js#L424
https://github.com/MetaMask/metamask-extension/blob/38fe75b7d9255b0fb7515ef2f78250a5b9791aa3/app/scripts/lib/encryption-public-key-manager.js#L82
The text was updated successfully, but these errors were encountered: