From 3d7bdaf921dfddab547822577497e8691e9ab9f7 Mon Sep 17 00:00:00 2001 From: Shane T Date: Tue, 17 Dec 2024 15:13:10 +0000 Subject: [PATCH 1/3] feat(SIP-30): Add SIP-30 --- SIPS/sip-30.md | 198 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 SIPS/sip-30.md diff --git a/SIPS/sip-30.md b/SIPS/sip-30.md new file mode 100644 index 0000000..40d179d --- /dev/null +++ b/SIPS/sip-30.md @@ -0,0 +1,198 @@ +--- +sip: 30 +title: Entropy Source Identifiers +status: Draft +author: Shane T Odlum (@shane-t) +created: 2024-12-17 +--- + +## Abstract + +This SIP proposes additions to entropy retrieval APIs that allows snaps to request entropy from a specific source. + +## Motivation + +Interoperability snaps and account management snaps use the methods `snap_getEntropy`, `snap_getBip44Entropy`, `snap_getBip32Entropy`, and `snap_getBip32PublicKey` to generate addresses and other key material. + +These methods assume the client contains a single entropy source (the user's primary keyring mnemonic). The proposed API will allow snaps to request entropy from a specific source such as a secondary mnemonic. + +## Specification + +> Formal specifications are written in TypeScript. + +### Language + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", +"NOT RECOMMENDED", "MAY", and "OPTIONAL" written in uppercase in this document are to be interpreted as described in +[RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) + + +### Common Types +```typescript +type Slip10Node = { + depth: number; + parentFingerprint: number; + index: number; + privateKey: string; + publicKey: string; + chainCode: string; + curve: "ed25519" | "secp256k1"; +}; +``` + +```typescript +export type BIP44Node = { + coin_type: number; + depth: number; + privateKey: string; + publicKey: string; + chainCode: string; + path: string[]; +}; +``` + +### Scope + +This SIP applies to snaps that implement the [Keyring API][keyring-api] and any others which use the `snap_getEntropy`, `snap_getBip44Entropy`, `snap_getBip32Entropy`, and `snap_getBip32PublicKey` methods. + +### Snap Manifest + +No changes are required to the snap manifest. + +### Client wallet implementation + +A client wallet MAY invoke the `keyring.createAccount` method with an `entropySource` parameter in the `options` object. + +The `entropySource` parameter MUST be a string which uniquely identifies the entropy source to use. It is not guaranteed to be the same string visible to any other snap, but should always refer to the same source in the context of interactions between the snap and the client wallet. + +#### Snap implementation + +If a snap is asked to create an account via `keyring.createAccount`, and the `entropySource` parameter is provided, and the snap requires entropy to create an account,the snap SHOULD request the entropy from the specified source. + +### RPC Methods + +#### `snap_getEntropy` + +##### Parameters +An object containing: + +- `version` - The number 2. Version `2` is the first version that allows specifying a source ID. +- `salt` (optional) - An arbitrary string to be used as a salt for the entropy. This can be used to generate different entropy for different purposes. +- `source` (optional) - The ID of the entropy source to use. If not specified, the default entropy source will be used. + +#### Returns +The entropy as a hexadecimal string. + +#### Example + +```typescript +const entropy = await snap.request({ + method: "snap_getEntropy", + params: { + version: 2, + salt: "my-salt", + source: "1234-5678-9012-3456-7890", + }, +}); +// '0x1234567890abcdef' +``` + +#### `snap_getBip32Entropy` + +##### Parameters + +- `path`: An array starting with `m` containing the BIP-32 derivation path of the key to retrieve. +- `source`: The ID of the entropy source to use. +- `curve`: The curve to use - `secp256k1` or `ed25519`. + +##### Returns + +A `Slip10Node` object representing the BIP-32 HD tree node and containing its corresponding key material. + +##### Example + +```typescript +const node = await snap.request({ + method: "snap_getBip32Entropy", + params: { + path: ["m", "44", "0", "0", "0"], + source: "1234-5678-9012-3456-7890", + curve: "secp256k1", + }, +}); +// { +// depth: 5, +// parentFingerprint: 1234567890, +// index: 0, +// privateKey: '0x1234567890abcdef', +// publicKey: '0x1234567890abcdef', +// chainCode: '0x1234567890abcdef', +// curve: 'secp256k1', +// } +``` + +#### `snap_getBip32PublicKeyFromSource` + +##### Parameters + +- `path`: An array starting with `m` containing the BIP-32 derivation path of the key to retrieve. +- `source`: The ID of the entropy source to use. +- `curve`: The curve to use - `secp256k1` or `ed25519`. +- `compressed`: Whether to return the public key in compressed format. (defaults to `false`) + +##### Returns + +The public key as a hexadecimal string. + +##### Example + +```typescript +const publicKey = await snap.request({ + method: "snap_getBip32PublicKeyFromSource", + params: { + path: ["m", "44", "0", "0", "0"], + source: "1234-5678-9012-3456-7890", + curve: "secp256k1", + compressed: true, + }, +}); +// '0x1234567890abcdef' +``` + +#### `snap_getBip44Entropy` + +##### Parameters +An object containing: + +- `coin_type`: The BIP-44 coin type value of the node. +- `source` (optional) - The ID of the entropy source to use. If not specified, the default entropy source will be used. + +##### Returns +A `BIP44Node` object representing the BIP-44 `coin_type` HD tree node and containing its corresponding key material. + +##### Example + +```typescript +const node = await snap.request({ + method: "snap_getBip44Entropy", + params: { + coin_type: 1, + source: "1234-5678-9012-3456-7890", + }, +}); +// { +// coin_type: 1, +// depth: 5, +// privateKey: '0x1234567890abcdef', +// publicKey: '0x1234567890abcdef', +// chainCode: '0x1234567890abcdef', +// path: ['m', '44', '0', '0', '0'], +// } +``` + + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE). + +[keyring-api]: https://github.com/MetaMask/accounts/tree/main/packages/keyring-api From 43d32b7d8340a1337c42cf4c1ffbc5c0363c6838 Mon Sep 17 00:00:00 2001 From: Shane T Date: Fri, 20 Dec 2024 11:39:52 +0000 Subject: [PATCH 2/3] Include a section describing the default behaviour --- SIPS/sip-30.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SIPS/sip-30.md b/SIPS/sip-30.md index 40d179d..97238e8 100644 --- a/SIPS/sip-30.md +++ b/SIPS/sip-30.md @@ -61,6 +61,10 @@ No changes are required to the snap manifest. ### Client wallet implementation +If a snap requests entropy and includes the `source` parameter, the wallet MUST return entropy corresponding to that source, if it exists. +If it does not exist, the wallet MUST respond with an error. +If the request does not include the `source` parameter, the wallet MUST return entropy from the default source. + A client wallet MAY invoke the `keyring.createAccount` method with an `entropySource` parameter in the `options` object. The `entropySource` parameter MUST be a string which uniquely identifies the entropy source to use. It is not guaranteed to be the same string visible to any other snap, but should always refer to the same source in the context of interactions between the snap and the client wallet. From b4d37c6c3ff467a1e81f1e303531a7ef5d2522a7 Mon Sep 17 00:00:00 2001 From: Shane Terence Odlum Date: Fri, 20 Dec 2024 14:52:04 +0000 Subject: [PATCH 3/3] chore: add new method to list available entropy sources --- SIPS/sip-30.md | 48 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/SIPS/sip-30.md b/SIPS/sip-30.md index 97238e8..169ea1e 100644 --- a/SIPS/sip-30.md +++ b/SIPS/sip-30.md @@ -14,7 +14,7 @@ This SIP proposes additions to entropy retrieval APIs that allows snaps to reque Interoperability snaps and account management snaps use the methods `snap_getEntropy`, `snap_getBip44Entropy`, `snap_getBip32Entropy`, and `snap_getBip32PublicKey` to generate addresses and other key material. -These methods assume the client contains a single entropy source (the user's primary keyring mnemonic). The proposed API will allow snaps to request entropy from a specific source such as a secondary mnemonic. +These methods assume the client contains a single entropy source (the user's primary keyring mnemonic). The proposed API changes will allow snaps to request entropy from a specific source such as a secondary mnemonic. A new method `snap_listAvailableEntropySources` will be added to allow snaps to request a list of available entropy sources. ## Specification @@ -26,6 +26,18 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S "NOT RECOMMENDED", "MAY", and "OPTIONAL" written in uppercase in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) +### Snap Manifest + +A new set permission is added to the snap manifest: + +```json +{ + "initialPermissions": { + "snap_listAvailableEntropySources": {} + } +} +``` + ### Common Types ```typescript @@ -38,9 +50,7 @@ type Slip10Node = { chainCode: string; curve: "ed25519" | "secp256k1"; }; -``` -```typescript export type BIP44Node = { coin_type: number; depth: number; @@ -49,6 +59,12 @@ export type BIP44Node = { chainCode: string; path: string[]; }; + +interface EntropySource { + name: string; + id: string; + type: "mnemonic"; +} ``` ### Scope @@ -61,8 +77,12 @@ No changes are required to the snap manifest. ### Client wallet implementation -If a snap requests entropy and includes the `source` parameter, the wallet MUST return entropy corresponding to that source, if it exists. -If it does not exist, the wallet MUST respond with an error. +If a snap requests a list of available entropy sources, and it has the permission to do so, the wallet MUST return a list of `EntropySource` objects. + +If a snap requests entropy and includes the `source` parameter for an entropy source of type `mnemonic`, the wallet MUST return entropy corresponding to that source, if it exists. + +If the source does not exist, the wallet MUST respond with an error. + If the request does not include the `source` parameter, the wallet MUST return entropy from the default source. A client wallet MAY invoke the `keyring.createAccount` method with an `entropySource` parameter in the `options` object. @@ -73,7 +93,23 @@ The `entropySource` parameter MUST be a string which uniquely identifies the ent If a snap is asked to create an account via `keyring.createAccount`, and the `entropySource` parameter is provided, and the snap requires entropy to create an account,the snap SHOULD request the entropy from the specified source. -### RPC Methods +### New RPC Methods + +#### `snap_listAvailableEntropySources` + +The method returns an array of `EntropySource` objects, each representing an available entropy source. It is intended that the snap will display this list to the user. + +```typescript +const entropySources = await snap.request({ + method: "snap_listAvailableEntropySources", +}); +// [ +// { name: "Phrase 1", id: "phrase-1" }, +// { name: "Phrase 2", id: "phrase-2" }, +// ] +``` + +### Existing RPC Methods #### `snap_getEntropy`