@metamask/keyring-api 1.0.0-rc.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -1
- package/README.md +196 -40
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
7
|
|
8
8
|
## [Unreleased]
|
9
9
|
|
10
|
+
## [1.0.0]
|
11
|
+
|
12
|
+
### Added
|
13
|
+
|
14
|
+
- Add migration steps to 1.0.0 ([#149](https://github.com/MetaMask/keyring-api/pull/149)).
|
15
|
+
- Add Account Snaps security guidelines ([#143](https://github.com/MetaMask/keyring-api/pull/143)).
|
16
|
+
|
17
|
+
### Changed
|
18
|
+
|
19
|
+
- Bump @metamask/rpc-errors from 6.0.0 to 6.1.0 ([#151](https://github.com/MetaMask/keyring-api/pull/151)).
|
20
|
+
- Bump postcss from 8.4.24 to 8.4.31 ([#150](https://github.com/MetaMask/keyring-api/pull/150)).
|
21
|
+
|
10
22
|
## [1.0.0-rc.1]
|
11
23
|
|
12
24
|
### Added
|
@@ -136,7 +148,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
136
148
|
- SnapController keyring client. It is intended to be used by MetaMask to talk to the snap.
|
137
149
|
- Helper functions to create keyring handler in the snap.
|
138
150
|
|
139
|
-
[Unreleased]: https://github.com/MetaMask/keyring-api/compare/v1.0.0
|
151
|
+
[Unreleased]: https://github.com/MetaMask/keyring-api/compare/v1.0.0...HEAD
|
152
|
+
[1.0.0]: https://github.com/MetaMask/keyring-api/compare/v1.0.0-rc.1...v1.0.0
|
140
153
|
[1.0.0-rc.1]: https://github.com/MetaMask/keyring-api/compare/v0.2.7...v1.0.0-rc.1
|
141
154
|
[0.2.7]: https://github.com/MetaMask/keyring-api/compare/v0.2.6...v0.2.7
|
142
155
|
[0.2.6]: https://github.com/MetaMask/keyring-api/compare/v0.2.5...v0.2.6
|
package/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
> This TypeScript module is maintained in the style of the MetaMask team.
|
4
4
|
|
5
|
-
This TypeScript module simplifies the integration of
|
5
|
+
This TypeScript module simplifies the integration of Snaps with MetaMask using
|
6
6
|
the Keyring API.
|
7
7
|
|
8
8
|
Features:
|
@@ -12,17 +12,17 @@ Features:
|
|
12
12
|
MetaMask and leverage its functionality.
|
13
13
|
|
14
14
|
- **Dapp Client**: The module includes a client that enables dapps to
|
15
|
-
communicate with the Keyring
|
16
|
-
to the
|
15
|
+
communicate with the Keyring Snap. This client allows dapps to send requests
|
16
|
+
to the Snap, such as retrieving account information or submitting requests.
|
17
17
|
|
18
18
|
- **MetaMask Client**: The module provides a client specifically designed for
|
19
19
|
MetaMask integration. This client enables MetaMask to send requests directly
|
20
|
-
to the Keyring
|
20
|
+
to the Keyring Snap, facilitating smooth interoperability between the two
|
21
21
|
applications.
|
22
22
|
|
23
23
|
- **Request Handler Helper Functions**: The module offers a set of helper
|
24
24
|
functions to simplify the implementation of the request handler in the
|
25
|
-
Keyring
|
25
|
+
Keyring Snap. These functions assist in processing incoming requests,
|
26
26
|
validating data, and handling various request types from dapps and MetaMask.
|
27
27
|
|
28
28
|
## Installation
|
@@ -33,54 +33,196 @@ or
|
|
33
33
|
|
34
34
|
`npm install @metamask/keyring-api`
|
35
35
|
|
36
|
-
##
|
36
|
+
## Keyring Snaps
|
37
37
|
|
38
|
-
|
38
|
+
Starting with MetaMask 11.5, Snaps can implement the Keyring API. This allows
|
39
|
+
users to manage their accounts in a more flexible way, and enables developers
|
40
|
+
to build new types of accounts.
|
39
41
|
|
40
|
-
|
42
|
+
> [!IMPORTANT]
|
43
|
+
> Before implementing your Snap, please make sure to read the [security
|
44
|
+
> recommendations](./docs/security.md) and the [architecture
|
45
|
+
> document](./docs/architecture.md).
|
41
46
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
}
|
46
|
-
```
|
47
|
+
Follow these steps to implement the Keyring API in your Snap. Please note that
|
48
|
+
these instruction assume that you are already familiar with the process of
|
49
|
+
[developing a Snap](https://docs.metamask.io/).
|
47
50
|
|
48
|
-
|
51
|
+
1. **Implement the Keyring API:**
|
49
52
|
|
50
|
-
|
51
|
-
import { keyringRpcDispatcher } from '@metamask/keyring-api';
|
53
|
+
Inside your Snap, implement the `Keyring` API:
|
52
54
|
|
53
|
-
|
54
|
-
|
55
|
-
// ...
|
55
|
+
```typescript
|
56
|
+
class MySnapKeyring implements Keyring {
|
57
|
+
// Implement the required methods here...
|
58
|
+
}
|
59
|
+
```
|
56
60
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
return await keyringRpcDispatcher(keyring, request);
|
62
|
-
};
|
63
|
-
```
|
61
|
+
> [!WARNING]
|
62
|
+
> Ensure that your keyring implements the [methods called by
|
63
|
+
> MetaMask](./docs/security.md#limit-the-methods-exposed-to-dapps),
|
64
|
+
> otherwise some features may not work.
|
64
65
|
|
65
|
-
|
66
|
+
2. **Handle requests submitted by MetaMask:**
|
66
67
|
|
67
|
-
|
68
|
-
|
69
|
-
|
68
|
+
MetaMask will submit requests through the `submitRequest` method of your the
|
69
|
+
Keyring API (check the supported [EVM methods](./docs/evm_methods.md)). Here
|
70
|
+
is an example of request:
|
70
71
|
|
71
|
-
|
72
|
+
```json
|
73
|
+
{
|
74
|
+
"id": "d6e23af6-4bea-48dd-aeb0-7d3c30ea67f9",
|
75
|
+
"scope": "",
|
76
|
+
"account": "69438371-bef3-4957-9f91-c3f22c1d75f3",
|
77
|
+
"request": {
|
78
|
+
"method": "personal_sign",
|
79
|
+
"params": [
|
80
|
+
"0x4578616d706c652060706572736f6e616c5f7369676e60206d657373616765",
|
81
|
+
"0x5874174dcf1ab6F7Efd8496f4f09404CD1c5bA84"
|
82
|
+
]
|
83
|
+
}
|
84
|
+
}
|
85
|
+
```
|
72
86
|
|
73
|
-
|
74
|
-
import { chainHandlers } from '@metamask/keyring-api';
|
87
|
+
Where:
|
75
88
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
89
|
+
- `id` is unique identifier for the request.
|
90
|
+
|
91
|
+
- `scope` is the CAIP-2 chain ID of the selected chain. Currently, this
|
92
|
+
property is always an empty string. Your Snap should use the chain ID
|
93
|
+
present in the request object instead.
|
94
|
+
|
95
|
+
- `account` is the ID of the account that should handle the request.
|
82
96
|
|
83
|
-
|
97
|
+
- `request` is the request object.
|
98
|
+
|
99
|
+
Your Snap must respond with either a synchronous result:
|
100
|
+
|
101
|
+
```typescript
|
102
|
+
return { pending: false, result };
|
103
|
+
```
|
104
|
+
|
105
|
+
Or an asynchronous result:
|
106
|
+
|
107
|
+
```typescript
|
108
|
+
return { pending: true, redirect: { message, url } };
|
109
|
+
```
|
110
|
+
|
111
|
+
The redirect message and URL will be displayed to the user to inform them
|
112
|
+
about how to continue the transaction flow.
|
113
|
+
|
114
|
+
3. **Notify MetaMask about events:**
|
115
|
+
|
116
|
+
The following actions must be notified to MetaMask:
|
117
|
+
|
118
|
+
1. When an account is created:
|
119
|
+
|
120
|
+
```typescript
|
121
|
+
try {
|
122
|
+
emitSnapKeyringEvent(snap, KeyringEvent.AccountCreated, { account });
|
123
|
+
// Update your snap's state...
|
124
|
+
} catch (error) {
|
125
|
+
// Handle the error...
|
126
|
+
}
|
127
|
+
```
|
128
|
+
|
129
|
+
MetaMask will return an error if the account already exists or if the
|
130
|
+
account object is invalid.
|
131
|
+
|
132
|
+
2. When an account is updated:
|
133
|
+
|
134
|
+
```typescript
|
135
|
+
try {
|
136
|
+
emitSnapKeyringEvent(snap, KeyringEvent.AccountUpdated, { account });
|
137
|
+
// Update your snap's state...
|
138
|
+
} catch (error) {
|
139
|
+
// Handle the error...
|
140
|
+
}
|
141
|
+
```
|
142
|
+
|
143
|
+
MetaMask will return an error if the account does not exist, if the
|
144
|
+
account object is invalid, or if the account address changed.
|
145
|
+
|
146
|
+
3. When an account is deleted:
|
147
|
+
|
148
|
+
```typescript
|
149
|
+
try {
|
150
|
+
emitSnapKeyringEvent(snap, KeyringEvent.AccountDeleted, {
|
151
|
+
id: account.id,
|
152
|
+
});
|
153
|
+
// Update your snap's state...
|
154
|
+
} catch (error) {
|
155
|
+
// Handle the error...
|
156
|
+
}
|
157
|
+
```
|
158
|
+
|
159
|
+
The delete event is idempotent, so it is safe to emit it even if the
|
160
|
+
account does not exist.
|
161
|
+
|
162
|
+
4. When a request is approved:
|
163
|
+
|
164
|
+
```typescript
|
165
|
+
try {
|
166
|
+
emitSnapKeyringEvent(snap, KeyringEvent.RequestApproved, {
|
167
|
+
id: request.id,
|
168
|
+
result,
|
169
|
+
});
|
170
|
+
// Update your snap's state...
|
171
|
+
} catch (error) {
|
172
|
+
// Handle the error...
|
173
|
+
}
|
174
|
+
```
|
175
|
+
|
176
|
+
MetaMask will return an error if the request does not exist.
|
177
|
+
|
178
|
+
> [!NOTE]
|
179
|
+
> This only applies to Snaps that implement the [async
|
180
|
+
> flow](./docs/architecture.md#transaction-flow).
|
181
|
+
|
182
|
+
5. When a request is rejected:
|
183
|
+
|
184
|
+
```typescript
|
185
|
+
try {
|
186
|
+
emitSnapKeyringEvent(snap, KeyringEvent.RequestRejected, {
|
187
|
+
id: request.id,
|
188
|
+
});
|
189
|
+
// Update your snap's state...
|
190
|
+
} catch (error) {
|
191
|
+
// Handle the error...
|
192
|
+
}
|
193
|
+
```
|
194
|
+
|
195
|
+
MetaMask will return an error if the request does not exist.
|
196
|
+
|
197
|
+
> [!NOTE]
|
198
|
+
> This only applies to Snaps that implement the [async
|
199
|
+
> flow](./docs/architecture.md#transaction-flow).
|
200
|
+
|
201
|
+
4. **Expose the Keyring API:**
|
202
|
+
|
203
|
+
Then create a handler to expose the keyring methods to MetaMask and your dapp:
|
204
|
+
|
205
|
+
```typescript
|
206
|
+
export const onKeyringRequest: OnKeyringRequestHandler = async ({
|
207
|
+
origin,
|
208
|
+
request,
|
209
|
+
}) => {
|
210
|
+
// Your custom logic here...
|
211
|
+
return handleKeyringRequest(keyring, request);
|
212
|
+
};
|
213
|
+
```
|
214
|
+
|
215
|
+
5. **Call the keyring methods from your dapp:**
|
216
|
+
|
217
|
+
Now you should be able to call your Keyring Snap from your dapp, for
|
218
|
+
example:
|
219
|
+
|
220
|
+
```typescript
|
221
|
+
const client = new KeyringSnapRpcClient(snapId, window.ethereum);
|
222
|
+
const accounts = await client.listAccounts();
|
223
|
+
```
|
224
|
+
|
225
|
+
## Migrating from 0.1.x to 0.2.x
|
84
226
|
|
85
227
|
The following changes were made to the API, which may require changes to your
|
86
228
|
implementation:
|
@@ -180,6 +322,20 @@ implementation:
|
|
180
322
|
};
|
181
323
|
```
|
182
324
|
|
325
|
+
## Migrating from 0.2.x to 1.x.x
|
326
|
+
|
327
|
+
The following changes were made to the API, which may require changes to your
|
328
|
+
implementation:
|
329
|
+
|
330
|
+
- Your Snap must expose the Keyring methods through the `onKeyringRequest`
|
331
|
+
export instead of the `onRpcRequest` export.
|
332
|
+
|
333
|
+
- Your Snap must request the new `endowment:keyring` endowment, and list any
|
334
|
+
dapp that should be allowed to call the Keyring methods.
|
335
|
+
|
336
|
+
For more details about the changes, please refer to the [security
|
337
|
+
guidelines](./docs/security.md).
|
338
|
+
|
183
339
|
## API
|
184
340
|
|
185
341
|
See our documentation:
|