@@ -6,16 +6,24 @@ import {
6
6
import {
7
7
Caip25CaveatType ,
8
8
Caip25EndowmentPermissionName ,
9
- getEthAccounts ,
10
- setEthAccounts ,
11
- getPermittedEthChainIds ,
12
- setPermittedEthChainIds ,
13
- } from '@metamask/multichain' ;
9
+ setPermittedChainIds ,
10
+ setPermittedAccounts ,
11
+ } from '@metamask/chain-agnostic-permission' ;
14
12
import { isSnapId } from '@metamask/snaps-utils' ;
13
+ import { parseCaipAccountId , parseCaipChainId } from '@metamask/utils' ;
14
+ import {
15
+ getCaipAccountIdsFromCaip25CaveatValue ,
16
+ isInternalAccountInPermittedAccountIds ,
17
+ } from '../../../../shared/lib/multichain/chain-agnostic-permission-utils/caip-accounts' ;
18
+ import { getAllScopesFromCaip25CaveatValue } from '../../../../shared/lib/multichain/chain-agnostic-permission-utils/caip-chainids' ;
19
+ import { getNetworkConfigurationsByCaipChainId } from '../../../../shared/modules/selectors/networks' ;
15
20
16
21
export function getPermissionBackgroundApiMethods ( {
17
22
permissionController,
18
23
approvalController,
24
+ accountsController,
25
+ networkController,
26
+ multichainNetworkController,
19
27
} ) {
20
28
// Returns the CAIP-25 caveat or undefined if it does not exist
21
29
const getCaip25Caveat = ( origin ) => {
@@ -38,30 +46,98 @@ export function getPermissionBackgroundApiMethods({
38
46
} ;
39
47
40
48
// To add more than one account when already connected to the dapp
41
- const addMoreAccounts = ( origin , accounts ) => {
49
+ const addMoreAccounts = ( origin , addresses ) => {
42
50
const caip25Caveat = getCaip25Caveat ( origin ) ;
43
51
if ( ! caip25Caveat ) {
44
52
throw new Error (
45
53
`Cannot add account permissions for origin "${ origin } ": no permission currently exists for this origin.` ,
46
54
) ;
47
55
}
48
56
49
- const ethAccounts = getEthAccounts ( caip25Caveat . value ) ;
57
+ const internalAccounts = addresses . map ( ( address ) => {
58
+ return accountsController . getAccountByAddress ( address ) ;
59
+ } ) ;
60
+
61
+ // Only the first scope in the scopes array is needed because
62
+ // setPermittedAccounts currently sets accounts on all matching
63
+ // namespaces, not just the exact CaipChainId.
64
+ const caipAccountIds = internalAccounts . map ( ( internalAccount ) => {
65
+ return `${ internalAccount . scopes [ 0 ] } :${ internalAccount . address } ` ;
66
+ } ) ;
50
67
51
- const updatedEthAccounts = Array . from (
52
- new Set ( [ ... ethAccounts , ... accounts ] ) ,
68
+ const existingPermittedAccountIds = getCaipAccountIdsFromCaip25CaveatValue (
69
+ caip25Caveat . value ,
53
70
) ;
54
71
55
- const updatedCaveatValue = setEthAccounts (
72
+ const existingPermittedChainIds = getAllScopesFromCaip25CaveatValue (
56
73
caip25Caveat . value ,
57
- updatedEthAccounts ,
74
+ ) ;
75
+
76
+ const updatedAccountIds = Array . from (
77
+ new Set ( [ ...existingPermittedAccountIds , ...caipAccountIds ] ) ,
78
+ ) ;
79
+
80
+ let updatedPermittedChainIds = [ ...existingPermittedChainIds ] ;
81
+
82
+ const allNetworksList = Object . keys (
83
+ getNetworkConfigurationsByCaipChainId ( {
84
+ networkConfigurationsByChainId :
85
+ networkController . state . networkConfigurationsByChainId ,
86
+ multichainNetworkConfigurationsByChainId :
87
+ multichainNetworkController . state
88
+ . multichainNetworkConfigurationsByChainId ,
89
+ internalAccounts : accountsController . state . internalAccounts ,
90
+ } ) ,
91
+ ) ;
92
+
93
+ updatedAccountIds . forEach ( ( caipAccountAddress ) => {
94
+ const {
95
+ chain : { namespace : accountNamespace } ,
96
+ } = parseCaipAccountId ( caipAccountAddress ) ;
97
+
98
+ const existsSelectedChainForNamespace = updatedPermittedChainIds . some (
99
+ ( caipChainId ) => {
100
+ try {
101
+ const { namespace : chainNamespace } = parseCaipChainId ( caipChainId ) ;
102
+ return accountNamespace === chainNamespace ;
103
+ } catch ( err ) {
104
+ return false ;
105
+ }
106
+ } ,
107
+ ) ;
108
+
109
+ if ( ! existsSelectedChainForNamespace ) {
110
+ const chainIdsForNamespace = allNetworksList . filter ( ( caipChainId ) => {
111
+ try {
112
+ const { namespace : chainNamespace } = parseCaipChainId ( caipChainId ) ;
113
+ return accountNamespace === chainNamespace ;
114
+ } catch ( err ) {
115
+ return false ;
116
+ }
117
+ } ) ;
118
+
119
+ updatedPermittedChainIds = [
120
+ ...updatedPermittedChainIds ,
121
+ ...chainIdsForNamespace ,
122
+ ] ;
123
+ }
124
+ } ) ;
125
+
126
+ const updatedCaveatValueWithChainIds = setPermittedChainIds (
127
+ caip25Caveat . value ,
128
+ updatedPermittedChainIds ,
129
+ ) ;
130
+
131
+ const updatedCaveatValueWithAccountIds = setPermittedAccounts (
132
+ updatedCaveatValueWithChainIds ,
133
+ updatedAccountIds ,
58
134
) ;
59
135
60
136
permissionController . updateCaveat (
61
137
origin ,
62
138
Caip25EndowmentPermissionName ,
63
139
Caip25CaveatType ,
64
- updatedCaveatValue ,
140
+ updatedCaveatValueWithAccountIds ,
65
141
) ;
66
142
} ;
67
143
@@ -73,22 +149,26 @@ export function getPermissionBackgroundApiMethods({
73
149
) ;
74
150
}
75
151
76
- const ethChainIds = getPermittedEthChainIds ( caip25Caveat . value ) ;
152
+ const updatedChainIds = Array . from (
153
+ new Set ( [
154
+ ...getAllScopesFromCaip25CaveatValue ( caip25Caveat . value ) ,
155
+ ...chainIds ,
156
+ ] ) ,
157
+ ) ;
77
158
78
- const updatedEthChainIds = Array . from (
79
- new Set ( [ ...ethChainIds , ...chainIds ] ) ,
159
+ const caveatValueWithChainIds = setPermittedChainIds (
160
+ caip25Caveat . value ,
161
+ updatedChainIds ,
80
162
) ;
81
163
82
- const caveatValueWithChains = setPermittedEthChainIds (
164
+ const permittedAccountIds = getCaipAccountIdsFromCaip25CaveatValue (
83
165
caip25Caveat . value ,
84
- updatedEthChainIds ,
85
166
) ;
86
167
87
- // ensure that the list of permitted eth accounts is set for the newly added eth scopes
88
- const ethAccounts = getEthAccounts ( caveatValueWithChains ) ;
89
- const caveatValueWithAccountsSynced = setEthAccounts (
90
- caveatValueWithChains ,
91
- ethAccounts ,
168
+ // ensure that the list of permitted accounts is set for the newly added scopes
169
+ const caveatValueWithAccountsSynced = setPermittedAccounts (
170
+ caveatValueWithChainIds ,
171
+ permittedAccountIds ,
92
172
) ;
93
173
94
174
permissionController . updateCaveat (
@@ -147,33 +227,41 @@ export function getPermissionBackgroundApiMethods({
147
227
addPermittedAccounts : ( origin , accounts ) =>
148
228
addMoreAccounts ( origin , accounts ) ,
149
229
150
- removePermittedAccount : ( origin , account ) => {
230
+ removePermittedAccount : ( origin , address ) => {
151
231
const caip25Caveat = getCaip25Caveat ( origin ) ;
152
232
if ( ! caip25Caveat ) {
153
233
throw new Error (
154
- `Cannot remove account "${ account } ": No permissions exist for origin "${ origin } ".` ,
234
+ `Cannot remove account "${ address } ": No permissions exist for origin "${ origin } ".` ,
155
235
) ;
156
236
}
157
237
158
- const existingAccounts = getEthAccounts ( caip25Caveat . value ) ;
238
+ const existingAccountIds = getCaipAccountIdsFromCaip25CaveatValue (
239
+ caip25Caveat . value ,
240
+ ) ;
159
241
160
- const remainingAccounts = existingAccounts . filter (
161
- ( existingAccount ) => existingAccount !== account ,
242
+ const internalAccount = accountsController . getAccountByAddress ( address ) ;
243
+
244
+ const remainingAccountIds = existingAccountIds . filter (
245
+ ( existingAccountId ) => {
246
+ return ! isInternalAccountInPermittedAccountIds ( internalAccount , [
247
+ existingAccountId ,
248
+ ] ) ;
249
+ } ,
162
250
) ;
163
251
164
- if ( remainingAccounts . length === existingAccounts . length ) {
252
+ if ( remainingAccountIds . length === existingAccountIds . length ) {
165
253
return ;
166
254
}
167
255
168
- if ( remainingAccounts . length === 0 ) {
256
+ if ( remainingAccountIds . length === 0 ) {
169
257
permissionController . revokePermission (
170
258
origin ,
171
259
Caip25EndowmentPermissionName ,
172
260
) ;
173
261
} else {
174
- const updatedCaveatValue = setEthAccounts (
262
+ const updatedCaveatValue = setPermittedAccounts (
175
263
caip25Caveat . value ,
176
- remainingAccounts ,
264
+ remainingAccountIds ,
177
265
) ;
178
266
permissionController . updateCaveat (
179
267
origin ,
@@ -196,13 +284,15 @@ export function getPermissionBackgroundApiMethods({
196
284
) ;
197
285
}
198
286
199
- const existingEthChainIds = getPermittedEthChainIds ( caip25Caveat . value ) ;
287
+ const existingChainIds = getAllScopesFromCaip25CaveatValue (
288
+ caip25Caveat . value ,
289
+ ) ;
200
290
201
- const remainingChainIds = existingEthChainIds . filter (
291
+ const remainingChainIds = existingChainIds . filter (
202
292
( existingChainId ) => existingChainId !== chainId ,
203
293
) ;
204
294
205
- if ( remainingChainIds . length === existingEthChainIds . length ) {
295
+ if ( remainingChainIds . length === existingChainIds . length ) {
206
296
return ;
207
297
}
208
298
@@ -212,7 +302,7 @@ export function getPermissionBackgroundApiMethods({
212
302
Caip25EndowmentPermissionName ,
213
303
) ;
214
304
} else {
215
- const updatedCaveatValue = setPermittedEthChainIds (
305
+ const updatedCaveatValue = setPermittedChainIds (
216
306
caip25Caveat . value ,
217
307
remainingChainIds ,
218
308
) ;
0 commit comments