-
Notifications
You must be signed in to change notification settings - Fork 456
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
Add ERC: App Keys for Fully Embedded Accounts #615
base: master
Are you sure you want to change the base?
Changes from all commits
2cb5cbc
1d2de27
06b23e9
adf0292
13b1db4
3bb1270
8d91055
d8c1972
85cd73a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,132 @@ | ||||||||||
--- | ||||||||||
eip: 7763 | ||||||||||
title: App Keys for Fully Embedded Accounts | ||||||||||
description: Generate and manage exposed application-specific key pairs | ||||||||||
author: Dan Finlay (@danfinlay) | ||||||||||
discussions-to: https://ethereum-magicians.org/t/wallet-getexposedappkey/20958 | ||||||||||
status: Draft | ||||||||||
type: Standards Track | ||||||||||
category: ERC | ||||||||||
created: 2024-09-04 | ||||||||||
requires: 1193 | ||||||||||
--- | ||||||||||
|
||||||||||
Check failure on line 13 in ERCS/erc-7763.md GitHub Actions / EIP Walidatorbody is missing section(s): `Copyright`
|
||||||||||
## Abstract | ||||||||||
|
||||||||||
This ERC proposes a standard for wallets to generate and manage exposed application-specific key pairs, building upon the concepts introduced in [ERC-1775](./eip-1775.md) and complementing [ERC-7716](./eip-7716.md). It defines exposed keys that allow free signing by the current site. This approach enhances flexibility in managing permissions for decentralized applications (dApps) while maintaining a balance with security considerations. | ||||||||||
|
||||||||||
## Motivation | ||||||||||
|
||||||||||
As the ecosystem of dApps grows, there's an increasing need for more granular and flexible key management. This ERC simplifies the ideas presented in [ERC-1775](./eip-1775.md) and [ERC-7715](./eip-7715.md) by providing a standard for exposed app keys that a wallet can use to manage permissions for a dApp: | ||||||||||
|
||||||||||
Exposed Keys (Freely Signable): Allow dApps to sign transactions without repeated user intervention, enabling smoother user experiences for certain operations. | ||||||||||
|
||||||||||
This approach allows for improved user convenience in scenarios where frequent signing is required, giving users and dApps more control over how permissions and identities are handled across different applications. | ||||||||||
|
||||||||||
## Specification | ||||||||||
|
||||||||||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. | ||||||||||
|
||||||||||
### Wallet Interface | ||||||||||
|
||||||||||
Wallets MUST implement the following method: | ||||||||||
|
||||||||||
### `wallet_getExposedAppKey` | ||||||||||
|
||||||||||
This method generates or retrieves an exposed app-specific key for the current dApp. | ||||||||||
|
||||||||||
#### Parameters | ||||||||||
- `options`: An optional object that can include: | ||||||||||
- `type`: The type of key to generate. Currently supports `'ethereum-secp256k1'`. Additional types may be supported in future extensions of this standard. | ||||||||||
- `nonce`: An optional number that allows the site to generate multiple distinct keys. If not provided, it defaults to 0. | ||||||||||
|
||||||||||
#### Returns | ||||||||||
- A Promise that resolves to an object containing: | ||||||||||
- `address`: The Ethereum address derived from the exposed app key. | ||||||||||
- `publicKey`: The public key of the exposed app key. | ||||||||||
- `privateKey`: The private key of the exposed app key. | ||||||||||
- `type`: The type of key that was generated. | ||||||||||
- `nonce`: The nonce used to generate this key. | ||||||||||
|
||||||||||
### Exposed App Key Generation Algorithm | ||||||||||
|
||||||||||
The exposed app key generation algorithm is based on a simplified version of BIP-44, without ENS complications. This algorithm ensures that each application receives a unique, deterministic key pair that can be easily regenerated by any compliant wallet. | ||||||||||
|
||||||||||
1. Derive the app-specific path: | ||||||||||
- Use the BIP-44 purpose field `44'` | ||||||||||
- Use coin type `60'` for Ethereum | ||||||||||
- Use `0'` for account index | ||||||||||
- Use the first 4 bytes of keccak256 hash of the app's origin (domain) for change level | ||||||||||
- Use the provided `nonce` (or 0 if not provided) for address index | ||||||||||
|
||||||||||
2. Generate the private key: | ||||||||||
- Derive the private key using the app-specific path from the wallet's master seed | ||||||||||
|
||||||||||
3. Compute the public key and address: | ||||||||||
- Derive the public key from the private key | ||||||||||
- Compute the Ethereum address from the public key | ||||||||||
|
||||||||||
Here's a JavaScript representation of the algorithm using the scure-bip39 library: | ||||||||||
```javascript | ||||||||||
import * as bip39 from '@metamask/scure-bip39'; | ||||||||||
import { wordlist } from '@metamask/scure-bip39/wordlists/english'; | ||||||||||
import { HDKey } from '@scure/bip32'; | ||||||||||
import { keccak256 } from 'ethereum-cryptography/keccak'; | ||||||||||
import { publicToAddress, privateToPublic } from 'ethereum-cryptography/secp256k1'; | ||||||||||
|
||||||||||
async function getExposedAppKey(origin, nonce = 0) { | ||||||||||
// Generate or retrieve the wallet's master seed | ||||||||||
const mnemonic = bip39.generateMnemonic(wordlist); | ||||||||||
const seed = await bip39.mnemonicToSeed(mnemonic); | ||||||||||
|
||||||||||
// Derive the app-specific path | ||||||||||
const purpose = 44; | ||||||||||
const coinType = 60; // Ethereum | ||||||||||
const account = 0; | ||||||||||
const change = parseInt(keccak256(Buffer.from(origin)).slice(0, 4).toString('hex'), 16); | ||||||||||
const addressIndex = nonce; | ||||||||||
|
||||||||||
const path = `m/${purpose}'/${coinType}'/${account}'/${change}/${addressIndex}`; | ||||||||||
|
||||||||||
// Generate the private key | ||||||||||
const hdkey = HDKey.fromMasterSeed(seed); | ||||||||||
const derivedKey = hdkey.derive(path); | ||||||||||
const privateKey = derivedKey.privateKey; | ||||||||||
|
||||||||||
// Compute the public key and address | ||||||||||
const publicKey = privateToPublic(privateKey); | ||||||||||
const address = '0x' + publicToAddress(publicKey).toString('hex'); | ||||||||||
|
||||||||||
return { | ||||||||||
address, | ||||||||||
publicKey: publicKey.toString('hex'), | ||||||||||
privateKey: privateKey.toString('hex'), | ||||||||||
type: 'ethereum-secp256k1', | ||||||||||
nonce | ||||||||||
}; | ||||||||||
} | ||||||||||
|
||||||||||
// Example usage | ||||||||||
getExposedAppKey('example.com', 0).then(console.log); | ||||||||||
``` | ||||||||||
|
||||||||||
## Rationale | ||||||||||
|
||||||||||
<!-- TODO --> | ||||||||||
Check warning on line 115 in ERCS/erc-7763.md GitHub Actions / EIP WalidatorHTML comments are only allowed while `status` is one of: `Draft`, `Withdrawn`
|
||||||||||
|
||||||||||
## Security Considerations | ||||||||||
|
||||||||||
This ERC passes the entire private key to the dApp, which can be used to sign transactions. This is a departure from the current best practice of using a signing method that does not reveal the private key to the dApp. | ||||||||||
|
||||||||||
An alternative and slightly more secure approach is to use a signing method that does not reveal the private key to the dApp. This would improve revokability, but would increase friction especially for mobile apps that don't have a continuous connection to the user's wallet. I am partly drafting this ERC to establish an initial minimal standard which we can iterate on. | ||||||||||
|
||||||||||
## Conclusion | ||||||||||
Check failure on line 123 in ERCS/erc-7763.md GitHub Actions / EIP Walidatorbody has extra section(s)
|
||||||||||
|
||||||||||
This ERC proposes a standardized method for wallets to generate and manage app-specific keys, providing a secure and consistent approach to permission management in decentralized applications. By implementing this standard, wallets can offer enhanced privacy and security for users while enabling more seamless interactions between dApps and user accounts. | ||||||||||
|
||||||||||
The proposed `wallet_getAppKey` method allows for the creation of unique, deterministic keys for each application, reducing the risk of cross-app tracking and improving overall user privacy. This approach also facilitates easier permission management and potential future upgrades to more advanced account structures. | ||||||||||
|
||||||||||
As the Ethereum ecosystem continues to evolve, standardized approaches to key management and permissions become increasingly important. This ERC aims to contribute to the ongoing development of user-friendly and secure wallet interfaces, fostering innovation in decentralized applications while maintaining strong security practices. | ||||||||||
|
||||||||||
By adopting this standard, wallets and dApps can work together more effectively, providing users with a more streamlined and secure experience in the Web3 environment. As the community continues to refine and expand upon these concepts, we anticipate further improvements in user experience, security, and interoperability across the Ethereum ecosystem. | ||||||||||
|
||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
The copyright section is not optional. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of this content probably belongs in the Motivation section, since it's trying to convince the reader to pick this particular standard.