Skip to content
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

Replace controller context #2416

Merged
merged 7 commits into from
Apr 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 129 additions & 72 deletions app/core/Engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,76 +65,138 @@ class Engine {
currentCurrency: 'usd'
};

this.datamodel = new ComposableController(
[
new KeyringController({ encryptor }, initialState.KeyringController),
new AccountTrackerController(),
new AddressBookController(),
new AssetsContractController(),
new AssetsController(),
new AssetsDetectionController(),
new CurrencyRateController({
nativeCurrency,
currentCurrency
}),
new PersonalMessageManager(),
new MessageManager(),
new NetworkController({
infuraProjectId: process.env.MM_INFURA_PROJECT_ID || NON_EMPTY,
providerConfig: {
static: {
eth_sendTransaction: async (payload, next, end) => {
const { TransactionController } = this.datamodel.context;
try {
const hash = await (await TransactionController.addTransaction(
payload.params[0],
payload.origin,
WalletDevice.MM_MOBILE
)).result;
end(undefined, hash);
} catch (error) {
end(error);
}
}
},
getAccounts: (end, payload) => {
const { approvedHosts, privacyMode } = store.getState();
const isEnabled = !privacyMode || approvedHosts[payload.hostname];
const { KeyringController } = this.datamodel.context;
const isUnlocked = KeyringController.isUnlocked();
const selectedAddress = this.datamodel.context.PreferencesController.state
.selectedAddress;
end(null, isUnlocked && isEnabled && selectedAddress ? [selectedAddress] : []);
const preferencesController = new PreferencesController(
{},
{
ipfsGateway: AppConstants.IPFS_DEFAULT_GATEWAY_URL
}
);
const networkController = new NetworkController({
infuraProjectId: process.env.MM_INFURA_PROJECT_ID || NON_EMPTY,
providerConfig: {
static: {
eth_sendTransaction: async (payload, next, end) => {
const { TransactionController } = this.context;
try {
const hash = await (await TransactionController.addTransaction(
payload.params[0],
payload.origin,
WalletDevice.MM_MOBILE
)).result;
end(undefined, hash);
} catch (error) {
end(error);
}
}
}),
new PhishingController(),
new PreferencesController(
{},
{
ipfsGateway: AppConstants.IPFS_DEFAULT_GATEWAY_URL
}
},
getAccounts: (end, payload) => {
const { approvedHosts, privacyMode } = store.getState();
const isEnabled = !privacyMode || approvedHosts[payload.hostname];
const { KeyringController } = this.context;
const isUnlocked = KeyringController.isUnlocked();
const selectedAddress = this.context.PreferencesController.state.selectedAddress;
end(null, isUnlocked && isEnabled && selectedAddress ? [selectedAddress] : []);
}
}
});
const assetsContractController = new AssetsContractController();
const assetsController = new AssetsController({
onPreferencesStateChange: listener => preferencesController.subscribe(listener),
onNetworkStateChange: listener => networkController.subscribe(listener),
getAssetName: assetsContractController.getAssetName.bind(assetsContractController),
getAssetSymbol: assetsContractController.getAssetSymbol.bind(assetsContractController),
getCollectibleTokenURI: assetsContractController.getCollectibleTokenURI.bind(assetsContractController)
});
const currencyRateController = new CurrencyRateController({
nativeCurrency,
currentCurrency
});

const controllers = [
new KeyringController(
{
removeIdentity: preferencesController.removeIdentity.bind(preferencesController),
syncIdentities: preferencesController.syncIdentities.bind(preferencesController),
updateIdentities: preferencesController.updateIdentities.bind(preferencesController),
setSelectedAddress: preferencesController.setSelectedAddress.bind(preferencesController)
},
{ encryptor },
initialState.KeyringController
),
new AccountTrackerController({
onPreferencesStateChange: listener => preferencesController.subscribe(listener),
getIdentities: () => preferencesController.state.identities
}),
new AddressBookController(),
assetsContractController,
assetsController,
new AssetsDetectionController({
onAssetsStateChange: listener => assetsController.subscribe(listener),
onPreferencesStateChange: listener => preferencesController.subscribe(listener),
onNetworkStateChange: listener => networkController.subscribe(listener),
getOpenSeaApiKey: () => assetsController.openSeaApiKey,
getBalancesInSingleCall: assetsContractController.getBalancesInSingleCall.bind(
assetsContractController
),
new TokenBalancesController({ interval: 10000 }),
new TokenRatesController(),
new TransactionController(),
new TypedMessageManager(),
new SwapsController({
clientId: AppConstants.SWAPS.CLIENT_ID,
fetchAggregatorMetadataThreshold: AppConstants.SWAPS.CACHE_AGGREGATOR_METADATA_THRESHOLD,
fetchTokensThreshold: AppConstants.SWAPS.CACHE_TOKENS_THRESHOLD,
fetchTopAssetsThreshold: AppConstants.SWAPS.CACHE_TOP_ASSETS_THRESHOLD
})
],
initialState
);
addTokens: assetsController.addTokens.bind(assetsController),
addCollectible: assetsController.addCollectible.bind(assetsController),
removeCollectible: assetsController.removeCollectible.bind(assetsController),
getAssetsState: () => assetsController.state
}),
currencyRateController,
new PersonalMessageManager(),
new MessageManager(),
networkController,
new PhishingController(),
preferencesController,
new TokenBalancesController(
{
onAssetsStateChange: listener => assetsController.subscribe(listener),
getSelectedAddress: () => preferencesController.state.selectedAddress,
getBalanceOf: assetsContractController.getBalanceOf.bind(assetsContractController)
},
{ interval: 10000 }
),
new TokenRatesController({
onAssetsStateChange: listener => assetsController.subscribe(listener),
onCurrencyRateStateChange: listener => currencyRateController.subscribe(listener)
}),
new TransactionController({
getNetworkState: () => networkController.state,
onNetworkStateChange: listener => networkController.subscribe(listener),
getProvider: () => networkController.provider
}),
new TypedMessageManager(),
new SwapsController({
clientId: AppConstants.SWAPS.CLIENT_ID,
fetchAggregatorMetadataThreshold: AppConstants.SWAPS.CACHE_AGGREGATOR_METADATA_THRESHOLD,
fetchTokensThreshold: AppConstants.SWAPS.CACHE_TOKENS_THRESHOLD,
fetchTopAssetsThreshold: AppConstants.SWAPS.CACHE_TOP_ASSETS_THRESHOLD
})
];

// set initial state
// TODO: Pass initial state into each controller constructor instead
// This is being set post-construction for now to ensure it's functionally equivalent with
// how the `ComponsedController` used to set initial state.
for (const controller of controllers) {
if (initialState[controller.name]) {
controller.update(initialState[controller.name]);
}
}

this.datamodel = new ComposableController(controllers, initialState);
this.context = controllers.reduce((context, controller) => {
context[controller.name] = controller;
return context;
}, {});

const {
AssetsController: assets,
KeyringController: keyring,
NetworkController: network,
TransactionController: transaction
} = this.datamodel.context;
} = this.context;

assets.setApiKey(process.env.MM_OPENSEA_KEY);
network.refreshNetwork();
Expand Down Expand Up @@ -162,7 +224,7 @@ class Engine {
NetworkController: { provider, state: NetworkControllerState },
TransactionController,
SwapsController
} = this.datamodel.context;
} = this.context;

provider.sendAsync = provider.sendAsync.bind(provider);
AccountTrackerController.configure({ provider });
Expand All @@ -181,7 +243,7 @@ class Engine {
}

refreshTransactionHistory = async forceCheck => {
const { TransactionController, PreferencesController, NetworkController } = this.datamodel.context;
const { TransactionController, PreferencesController, NetworkController } = this.context;
const { selectedAddress } = PreferencesController.state;
const { type: networkType } = NetworkController.state.provider;
const { networkId } = Networks[networkType];
Expand Down Expand Up @@ -242,7 +304,7 @@ class Engine {
AssetsController,
TokenBalancesController,
TokenRatesController
} = this.datamodel.context;
} = this.context;
const { selectedAddress } = PreferencesController.state;
const { conversionRate, currentCurrency } = CurrencyRateController.state;
const { accounts } = AccountTrackerController.state;
Expand Down Expand Up @@ -308,12 +370,7 @@ class Engine {
// Whenever we are gonna start a new wallet
// either imported or created, we need to
// get rid of the old data from state
const {
TransactionController,
AssetsController,
TokenBalancesController,
TokenRatesController
} = this.datamodel.context;
const { TransactionController, AssetsController, TokenBalancesController, TokenRatesController } = this.context;

//Clear assets info
AssetsController.update({
Expand Down Expand Up @@ -346,7 +403,7 @@ class Engine {
NetworkController,
TransactionController,
AssetsController
} = this.datamodel.context;
} = this.context;

// Select same network ?
await NetworkController.setProviderType(network.provider.type);
Expand Down Expand Up @@ -434,7 +491,7 @@ let instance;

export default {
get context() {
return instance && instance.datamodel && instance.datamodel.context;
return instance && instance.context;
},
get state() {
const {
Expand Down
28 changes: 14 additions & 14 deletions app/core/Engine.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ import Engine from './Engine';
describe('Engine', () => {
it('should expose an API', () => {
const engine = Engine.init({});
expect(engine.datamodel.context).toHaveProperty('AccountTrackerController');
expect(engine.datamodel.context).toHaveProperty('AddressBookController');
expect(engine.datamodel.context).toHaveProperty('AssetsContractController');
expect(engine.datamodel.context).toHaveProperty('AssetsController');
expect(engine.datamodel.context).toHaveProperty('AssetsDetectionController');
expect(engine.datamodel.context).toHaveProperty('CurrencyRateController');
expect(engine.datamodel.context).toHaveProperty('KeyringController');
expect(engine.datamodel.context).toHaveProperty('NetworkController');
expect(engine.datamodel.context).toHaveProperty('PersonalMessageManager');
expect(engine.datamodel.context).toHaveProperty('PhishingController');
expect(engine.datamodel.context).toHaveProperty('PreferencesController');
expect(engine.datamodel.context).toHaveProperty('TokenBalancesController');
expect(engine.datamodel.context).toHaveProperty('TokenRatesController');
expect(engine.datamodel.context).toHaveProperty('TypedMessageManager');
expect(engine.context).toHaveProperty('AccountTrackerController');
expect(engine.context).toHaveProperty('AddressBookController');
expect(engine.context).toHaveProperty('AssetsContractController');
expect(engine.context).toHaveProperty('AssetsController');
expect(engine.context).toHaveProperty('AssetsDetectionController');
expect(engine.context).toHaveProperty('CurrencyRateController');
expect(engine.context).toHaveProperty('KeyringController');
expect(engine.context).toHaveProperty('NetworkController');
expect(engine.context).toHaveProperty('PersonalMessageManager');
expect(engine.context).toHaveProperty('PhishingController');
expect(engine.context).toHaveProperty('PreferencesController');
expect(engine.context).toHaveProperty('TokenBalancesController');
expect(engine.context).toHaveProperty('TokenRatesController');
expect(engine.context).toHaveProperty('TypedMessageManager');
});
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
"dependencies": {
"@exodus/react-native-payments": "https://github.com/wachunei/react-native-payments.git#package-json-hack",
"@metamask/contract-metadata": "^1.23.0",
"@metamask/controllers": "^7.0.0",
"@metamask/controllers": "^8.0.0",
"@metamask/etherscan-link": "^2.0.0",
"@metamask/swaps-controller": "^2.0.1",
"@react-native-community/async-storage": "1.12.1",
Expand Down
15 changes: 10 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1539,12 +1539,17 @@
resolved "https://registry.yarnpkg.com/@metamask/contract-metadata/-/contract-metadata-1.23.0.tgz#c70be7f3eaeeb791651ce793b7cdc230e9780b18"
integrity sha512-oTUqL9dtXtbng60DZMRsBmZ5HiOUUfEsZjuswOJ0yHO24YsW0ktCcgCJVYPv1HcOsF0SVrRtG4rtrvOl4nY+HA==

"@metamask/controllers@^7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@metamask/controllers/-/controllers-7.0.0.tgz#8daecd284faa897ca1f112a3f6f28d6936dac674"
integrity sha512-vb2/wgGfJFMUa4Ej67FMkV94s0vp765t2vwOt8EOxhWfmEP2v9myc2B95L5jJJZZgvCk2ojaV11CrFF4ookLng==
"@metamask/contract-metadata@^1.24.0":
version "1.25.0"
resolved "https://registry.yarnpkg.com/@metamask/contract-metadata/-/contract-metadata-1.25.0.tgz#442ace91fb40165310764b68d8096d0017bb0492"
integrity sha512-yhmYB9CQPv0dckNcPoWDcgtrdUp0OgK0uvkRE5QIBv4b3qENI1/03BztvK2ijbTuMlORUpjPq7/1MQDUPoRPVw==

"@metamask/controllers@^8.0.0":
version "8.0.0"
resolved "https://registry.yarnpkg.com/@metamask/controllers/-/controllers-8.0.0.tgz#42ac5aaef67a03d3fe599a67a36597e01902ca8d"
integrity sha512-TrteMifsCxV1g3WHcSD1X98fF4hKep3sXZNGfrvkPqa8mrF03hJke21WBSTRtvJ3vkNLRWgi+5I6lVXFTzbYuQ==
dependencies:
"@metamask/contract-metadata" "^1.23.0"
"@metamask/contract-metadata" "^1.24.0"
"@types/uuid" "^8.3.0"
async-mutex "^0.2.6"
babel-runtime "^6.26.0"
Expand Down