@@ -9,22 +9,24 @@ import {
9
9
} from '@metamask/controller-utils' ;
10
10
import HttpProvider from '@metamask/ethjs-provider-http' ;
11
11
import type {
12
- NetworkClientId ,
13
- NetworkControllerMessenger ,
14
12
Provider ,
13
+ NetworkClientId ,
14
+ NetworkControllerEvents ,
15
+ NetworkControllerActions ,
15
16
} from '@metamask/network-controller' ;
16
17
import {
17
18
NetworkController ,
18
19
NetworkClientType ,
19
20
} from '@metamask/network-controller' ;
20
- import {
21
- getDefaultPreferencesState ,
22
- type PreferencesState ,
23
- } from '@metamask/preferences-controller' ;
21
+ import { getDefaultPreferencesState } from '@metamask/preferences-controller' ;
24
22
import assert from 'assert' ;
25
23
26
24
import { mockNetwork } from '../../../tests/mock-network' ;
27
25
import { buildInfuraNetworkClientConfiguration } from '../../network-controller/tests/helpers' ;
26
+ import type {
27
+ AllowedActions as AssetsContractAllowedActions ,
28
+ AllowedEvents as AssetsContractAllowedEvents
29
+ } from './AssetsContractController' ;
28
30
import {
29
31
AssetsContractController ,
30
32
MISSING_PROVIDER_ERROR ,
@@ -65,70 +67,71 @@ async function setupAssetContractControllers({
65
67
} = { } ) {
66
68
const networkClientConfiguration = {
67
69
type : NetworkClientType . Infura ,
68
- network : ' mainnet' ,
70
+ network : NetworkType . mainnet ,
69
71
infuraProjectId,
70
72
chainId : BUILT_IN_NETWORKS . mainnet . chainId ,
71
73
ticker : BUILT_IN_NETWORKS . mainnet . ticker ,
72
74
} as const ;
73
75
let provider : Provider ;
74
76
75
- const messenger : NetworkControllerMessenger =
76
- new ControllerMessenger ( ) . getRestricted ( {
77
- name : 'NetworkController' ,
78
- allowedActions : [ ] ,
79
- allowedEvents : [ ] ,
80
- } ) ;
77
+ const controllerMessenger = new ControllerMessenger <
78
+ NetworkControllerActions | AssetsContractAllowedActions ,
79
+ NetworkControllerEvents | AssetsContractAllowedEvents
80
+ > ( ) ;
81
+ const networkMessenger = controllerMessenger . getRestricted ( {
82
+ name : 'NetworkController' ,
83
+ allowedActions : [ ] ,
84
+ allowedEvents : [ ] ,
85
+ } ) ;
81
86
const networkController = new NetworkController ( {
82
87
infuraProjectId,
83
- messenger,
88
+ messenger : networkMessenger ,
84
89
trackMetaMetricsEvent : jest . fn ( ) ,
85
90
} ) ;
86
91
if ( useNetworkControllerProvider ) {
87
92
await networkController . initializeProvider ( ) ;
88
93
const selectedNetworkClient = networkController . getSelectedNetworkClient ( ) ;
89
94
assert ( selectedNetworkClient , 'No network is selected' ) ;
90
95
provider = selectedNetworkClient . provider ;
96
+
97
+ controllerMessenger . unregisterActionHandler ( 'NetworkController:getNetworkClientById' ) ;
98
+ controllerMessenger . registerActionHandler (
99
+ 'NetworkController:getNetworkClientById' ,
100
+ // @ts -expect-error TODO: remove this annotation once the `Eip1193Provider` class is released
101
+ ( networkClientId : NetworkClientId ) => {
102
+ return {
103
+ ...networkController . getNetworkClientById ( networkClientId ) ,
104
+ provider,
105
+ }
106
+ }
107
+ ) ;
91
108
} else {
92
109
provider = new HttpProvider (
93
110
`https://mainnet.infura.io/v3/${ infuraProjectId } ` ,
94
111
) ;
95
112
}
96
113
97
- const getNetworkClientById = useNetworkControllerProvider
98
- ? networkController . getNetworkClientById . bind ( networkController )
99
- : ( networkClientId : NetworkClientId ) =>
100
- ( {
101
- ...networkController . getNetworkClientById ( networkClientId ) ,
102
- provider,
103
- // TODO: Replace `any` with type
104
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
- } as any ) ;
106
-
107
- const preferencesStateChangeListeners : ( ( state : PreferencesState ) => void ) [ ] =
108
- [ ] ;
114
+ const assetsContractMessenger = controllerMessenger . getRestricted ( {
115
+ name : 'AssetsContractController' ,
116
+ allowedActions : [ 'NetworkController:getNetworkClientById' ] ,
117
+ allowedEvents : [
118
+ 'PreferencesController:stateChange' ,
119
+ 'NetworkController:networkDidChange' ,
120
+ ] ,
121
+ } ) ;
109
122
const assetsContract = new AssetsContractController ( {
110
123
chainId : ChainId . mainnet ,
111
- onPreferencesStateChange : ( listener ) => {
112
- preferencesStateChangeListeners . push ( listener ) ;
113
- } ,
114
- onNetworkDidChange : ( listener ) =>
115
- messenger . subscribe ( 'NetworkController:networkDidChange' , listener ) ,
116
- getNetworkClientById,
124
+ messenger : assetsContractMessenger ,
117
125
...options ,
118
126
} ) ;
119
127
120
128
return {
121
- messenger,
129
+ messenger : controllerMessenger ,
122
130
network : networkController ,
123
131
assetsContract,
124
132
provider,
125
133
networkClientConfiguration,
126
134
infuraProjectId,
127
- triggerPreferencesStateChange : ( state : PreferencesState ) => {
128
- for ( const listener of preferencesStateChangeListeners ) {
129
- listener ( state ) ;
130
- }
131
- } ,
132
135
} ;
133
136
}
134
137
@@ -170,32 +173,41 @@ export { setupAssetContractControllers, mockNetworkWithDefaultChainId };
170
173
describe ( 'AssetsContractController' , ( ) => {
171
174
it ( 'should set default config' , async ( ) => {
172
175
const { assetsContract, messenger } = await setupAssetContractControllers ( ) ;
173
- expect ( assetsContract . config ) . toStrictEqual ( {
176
+ expect ( {
177
+ chainId : assetsContract . chainId ,
178
+ ipfsGateway : assetsContract . ipfsGateway ,
179
+ } ) . toStrictEqual ( {
174
180
chainId : SupportedTokenDetectionNetworks . mainnet ,
175
181
ipfsGateway : IPFS_DEFAULT_GATEWAY_URL ,
176
- provider : undefined ,
177
182
} ) ;
178
183
messenger . clearEventSubscriptions ( 'NetworkController:networkDidChange' ) ;
179
184
} ) ;
180
185
181
186
it ( 'should update the ipfsGateWay config value when this value is changed in the preferences controller' , async ( ) => {
182
- const { assetsContract, messenger, triggerPreferencesStateChange } =
183
- await setupAssetContractControllers ( ) ;
184
- expect ( assetsContract . config ) . toStrictEqual ( {
187
+ const { assetsContract, messenger } = await setupAssetContractControllers ( ) ;
188
+ expect ( {
189
+ chainId : assetsContract . chainId ,
190
+ ipfsGateway : assetsContract . ipfsGateway ,
191
+ } ) . toStrictEqual ( {
185
192
chainId : SupportedTokenDetectionNetworks . mainnet ,
186
193
ipfsGateway : IPFS_DEFAULT_GATEWAY_URL ,
187
- provider : undefined ,
188
194
} ) ;
189
195
190
- triggerPreferencesStateChange ( {
191
- ...getDefaultPreferencesState ( ) ,
192
- ipfsGateway : 'newIPFSGateWay' ,
193
- } ) ;
196
+ messenger . publish (
197
+ 'PreferencesController:stateChange' ,
198
+ {
199
+ ...getDefaultPreferencesState ( ) ,
200
+ ipfsGateway : 'newIPFSGateWay' ,
201
+ } ,
202
+ [ ] ,
203
+ ) ;
194
204
195
- expect ( assetsContract . config ) . toStrictEqual ( {
205
+ expect ( {
206
+ chainId : assetsContract . chainId ,
207
+ ipfsGateway : assetsContract . ipfsGateway ,
208
+ } ) . toStrictEqual ( {
196
209
ipfsGateway : 'newIPFSGateWay' ,
197
210
chainId : SupportedTokenDetectionNetworks . mainnet ,
198
- provider : undefined ,
199
211
} ) ;
200
212
201
213
messenger . clearEventSubscriptions ( 'NetworkController:networkDidChange' ) ;
@@ -211,7 +223,7 @@ describe('AssetsContractController', () => {
211
223
212
224
it ( 'should throw missing provider error when getting ERC-20 token balance when missing provider' , async ( ) => {
213
225
const { assetsContract, messenger } = await setupAssetContractControllers ( ) ;
214
- assetsContract . configure ( { provider : undefined } ) ;
226
+ assetsContract . provider = undefined ;
215
227
await expect (
216
228
assetsContract . getERC20BalanceOf (
217
229
ERC20_UNI_ADDRESS ,
@@ -223,7 +235,7 @@ describe('AssetsContractController', () => {
223
235
224
236
it ( 'should throw missing provider error when getting ERC-20 token decimal when missing provider' , async ( ) => {
225
237
const { assetsContract, messenger } = await setupAssetContractControllers ( ) ;
226
- assetsContract . configure ( { provider : undefined } ) ;
238
+ assetsContract . provider = undefined ;
227
239
await expect (
228
240
assetsContract . getERC20TokenDecimals ( ERC20_UNI_ADDRESS ) ,
229
241
) . rejects . toThrow ( MISSING_PROVIDER_ERROR ) ;
@@ -233,7 +245,7 @@ describe('AssetsContractController', () => {
233
245
it ( 'should get balance of ERC-20 token contract correctly' , async ( ) => {
234
246
const { assetsContract, messenger, provider, networkClientConfiguration } =
235
247
await setupAssetContractControllers ( ) ;
236
- assetsContract . configure ( { provider } ) ;
248
+ assetsContract . provider = provider ;
237
249
mockNetworkWithDefaultChainId ( {
238
250
networkClientConfiguration,
239
251
mocks : [
@@ -287,7 +299,7 @@ describe('AssetsContractController', () => {
287
299
it ( 'should get ERC-721 NFT tokenId correctly' , async ( ) => {
288
300
const { assetsContract, messenger, provider, networkClientConfiguration } =
289
301
await setupAssetContractControllers ( ) ;
290
- assetsContract . configure ( { provider } ) ;
302
+ assetsContract . provider = provider ;
291
303
mockNetworkWithDefaultChainId ( {
292
304
networkClientConfiguration,
293
305
mocks : [
@@ -320,7 +332,7 @@ describe('AssetsContractController', () => {
320
332
321
333
it ( 'should throw missing provider error when getting ERC-721 token standard and details when missing provider' , async ( ) => {
322
334
const { assetsContract, messenger } = await setupAssetContractControllers ( ) ;
323
- assetsContract . configure ( { provider : undefined } ) ;
335
+ assetsContract . provider = undefined ;
324
336
await expect (
325
337
assetsContract . getTokenStandardAndDetails (
326
338
ERC20_UNI_ADDRESS ,
@@ -333,7 +345,7 @@ describe('AssetsContractController', () => {
333
345
it ( 'should throw contract standard error when getting ERC-20 token standard and details when provided with invalid ERC-20 address' , async ( ) => {
334
346
const { assetsContract, messenger, provider } =
335
347
await setupAssetContractControllers ( ) ;
336
- assetsContract . configure ( { provider } ) ;
348
+ assetsContract . provider = provider ;
337
349
const error = 'Unable to determine contract standard' ;
338
350
await expect (
339
351
assetsContract . getTokenStandardAndDetails (
@@ -347,7 +359,7 @@ describe('AssetsContractController', () => {
347
359
it ( 'should get ERC-721 token standard and details' , async ( ) => {
348
360
const { assetsContract, messenger, provider, networkClientConfiguration } =
349
361
await setupAssetContractControllers ( ) ;
350
- assetsContract . configure ( { provider } ) ;
362
+ assetsContract . provider = provider ;
351
363
mockNetworkWithDefaultChainId ( {
352
364
networkClientConfiguration,
353
365
mocks : [
@@ -412,7 +424,7 @@ describe('AssetsContractController', () => {
412
424
it ( 'should get ERC-1155 token standard and details' , async ( ) => {
413
425
const { assetsContract, messenger, provider, networkClientConfiguration } =
414
426
await setupAssetContractControllers ( ) ;
415
- assetsContract . configure ( { provider } ) ;
427
+ assetsContract . provider = provider ;
416
428
mockNetworkWithDefaultChainId ( {
417
429
networkClientConfiguration,
418
430
mocks : [
@@ -497,7 +509,7 @@ describe('AssetsContractController', () => {
497
509
it ( 'should get ERC-20 token standard and details' , async ( ) => {
498
510
const { assetsContract, messenger, provider, networkClientConfiguration } =
499
511
await setupAssetContractControllers ( ) ;
500
- assetsContract . configure ( { provider } ) ;
512
+ assetsContract . provider = provider ;
501
513
mockNetworkWithDefaultChainId ( {
502
514
networkClientConfiguration,
503
515
mocks : [
@@ -594,7 +606,7 @@ describe('AssetsContractController', () => {
594
606
it ( 'should get ERC-721 NFT tokenURI correctly' , async ( ) => {
595
607
const { assetsContract, messenger, provider, networkClientConfiguration } =
596
608
await setupAssetContractControllers ( ) ;
597
- assetsContract . configure ( { provider } ) ;
609
+ assetsContract . provider = provider ;
598
610
mockNetworkWithDefaultChainId ( {
599
611
networkClientConfiguration,
600
612
mocks : [
@@ -643,7 +655,7 @@ describe('AssetsContractController', () => {
643
655
it ( 'should not throw an error when address given does not support NFT Metadata interface' , async ( ) => {
644
656
const { assetsContract, messenger, provider, networkClientConfiguration } =
645
657
await setupAssetContractControllers ( ) ;
646
- assetsContract . configure ( { provider } ) ;
658
+ assetsContract . provider = provider ;
647
659
const errorLogSpy = jest
648
660
. spyOn ( console , 'error' )
649
661
. mockImplementationOnce ( ( ) => {
@@ -701,7 +713,7 @@ describe('AssetsContractController', () => {
701
713
it ( 'should get ERC-721 NFT name' , async ( ) => {
702
714
const { assetsContract, messenger, provider, networkClientConfiguration } =
703
715
await setupAssetContractControllers ( ) ;
704
- assetsContract . configure ( { provider } ) ;
716
+ assetsContract . provider = provider ;
705
717
mockNetworkWithDefaultChainId ( {
706
718
networkClientConfiguration,
707
719
mocks : [
@@ -731,7 +743,7 @@ describe('AssetsContractController', () => {
731
743
it ( 'should get ERC-721 NFT symbol' , async ( ) => {
732
744
const { assetsContract, messenger, provider, networkClientConfiguration } =
733
745
await setupAssetContractControllers ( ) ;
734
- assetsContract . configure ( { provider } ) ;
746
+ assetsContract . provider = provider ;
735
747
mockNetworkWithDefaultChainId ( {
736
748
networkClientConfiguration,
737
749
mocks : [
@@ -771,7 +783,7 @@ describe('AssetsContractController', () => {
771
783
it ( 'should get ERC-20 token decimals' , async ( ) => {
772
784
const { assetsContract, messenger, provider, networkClientConfiguration } =
773
785
await setupAssetContractControllers ( ) ;
774
- assetsContract . configure ( { provider } ) ;
786
+ assetsContract . provider = provider ;
775
787
mockNetworkWithDefaultChainId ( {
776
788
networkClientConfiguration,
777
789
mocks : [
@@ -803,7 +815,7 @@ describe('AssetsContractController', () => {
803
815
it ( 'should get ERC-20 token name' , async ( ) => {
804
816
const { assetsContract, messenger, provider, networkClientConfiguration } =
805
817
await setupAssetContractControllers ( ) ;
806
- assetsContract . configure ( { provider } ) ;
818
+ assetsContract . provider = provider ;
807
819
mockNetworkWithDefaultChainId ( {
808
820
networkClientConfiguration,
809
821
mocks : [
@@ -835,7 +847,7 @@ describe('AssetsContractController', () => {
835
847
it ( 'should get ERC-721 NFT ownership' , async ( ) => {
836
848
const { assetsContract, messenger, provider, networkClientConfiguration } =
837
849
await setupAssetContractControllers ( ) ;
838
- assetsContract . configure ( { provider } ) ;
850
+ assetsContract . provider = provider ;
839
851
mockNetworkWithDefaultChainId ( {
840
852
networkClientConfiguration,
841
853
mocks : [
@@ -876,7 +888,7 @@ describe('AssetsContractController', () => {
876
888
it ( 'should get balance of ERC-20 token in a single call on network with token detection support' , async ( ) => {
877
889
const { assetsContract, messenger, provider, networkClientConfiguration } =
878
890
await setupAssetContractControllers ( ) ;
879
- assetsContract . configure ( { provider } ) ;
891
+ assetsContract . provider = provider ;
880
892
mockNetworkWithDefaultChainId ( {
881
893
networkClientConfiguration,
882
894
mocks : [
@@ -982,7 +994,7 @@ describe('AssetsContractController', () => {
982
994
useNetworkControllerProvider : true ,
983
995
infuraProjectId,
984
996
} ) ;
985
- assetsContract . configure ( { provider } ) ;
997
+ assetsContract . provider = provider ;
986
998
987
999
const balancesOnMainnet = await assetsContract . getBalancesInSingleCall (
988
1000
ERC20_SAI_ADDRESS ,
@@ -1011,7 +1023,7 @@ describe('AssetsContractController', () => {
1011
1023
provider,
1012
1024
networkClientConfiguration,
1013
1025
} = await setupAssetContractControllers ( ) ;
1014
- assetsContract . configure ( { provider } ) ;
1026
+ assetsContract . provider = provider ;
1015
1027
mockNetworkWithDefaultChainId ( {
1016
1028
networkClientConfiguration,
1017
1029
mocks : [
@@ -1082,7 +1094,7 @@ describe('AssetsContractController', () => {
1082
1094
1083
1095
it ( 'should throw missing provider error when transferring single ERC-1155 when missing provider' , async ( ) => {
1084
1096
const { assetsContract, messenger } = await setupAssetContractControllers ( ) ;
1085
- assetsContract . configure ( { provider : undefined } ) ;
1097
+ assetsContract . provider = undefined ;
1086
1098
await expect (
1087
1099
assetsContract . transferSingleERC1155 (
1088
1100
ERC1155_ADDRESS ,
@@ -1098,7 +1110,7 @@ describe('AssetsContractController', () => {
1098
1110
it ( 'should throw when ERC1155 function transferSingle is not defined' , async ( ) => {
1099
1111
const { assetsContract, messenger, provider, networkClientConfiguration } =
1100
1112
await setupAssetContractControllers ( ) ;
1101
- assetsContract . configure ( { provider } ) ;
1113
+ assetsContract . provider = provider ;
1102
1114
mockNetworkWithDefaultChainId ( {
1103
1115
networkClientConfiguration,
1104
1116
mocks : [
@@ -1135,7 +1147,7 @@ describe('AssetsContractController', () => {
1135
1147
it ( 'should get the balance of a ERC-1155 NFT for a given address' , async ( ) => {
1136
1148
const { assetsContract, messenger, provider, networkClientConfiguration } =
1137
1149
await setupAssetContractControllers ( ) ;
1138
- assetsContract . configure ( { provider } ) ;
1150
+ assetsContract . provider = provider ;
1139
1151
mockNetworkWithDefaultChainId ( {
1140
1152
networkClientConfiguration,
1141
1153
mocks : [
@@ -1181,7 +1193,7 @@ describe('AssetsContractController', () => {
1181
1193
it ( 'should get the URI of a ERC-1155 NFT' , async ( ) => {
1182
1194
const { assetsContract, messenger, provider, networkClientConfiguration } =
1183
1195
await setupAssetContractControllers ( ) ;
1184
- assetsContract . configure ( { provider } ) ;
1196
+ assetsContract . provider = provider ;
1185
1197
mockNetworkWithDefaultChainId ( {
1186
1198
networkClientConfiguration,
1187
1199
mocks : [
0 commit comments