@exodus/headless 2.0.0-alpha.41 → 2.0.0-alpha.42

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 CHANGED
@@ -3,6 +3,20 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [2.0.0-alpha.42](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@2.0.0-alpha.41...@exodus/headless@2.0.0-alpha.42) (2023-06-15)
7
+
8
+ ### Features
9
+
10
+ - .use poc using with kyc and referrals ([#1778](https://github.com/ExodusMovement/exodus-hydra/issues/1778)) ([7f66163](https://github.com/ExodusMovement/exodus-hydra/commit/7f66163364517fe555de220ad3cafd86c7c68516))
11
+ - **headless:** use(nfts) ([#1963](https://github.com/ExodusMovement/exodus-hydra/issues/1963)) ([47ed141](https://github.com/ExodusMovement/exodus-hydra/commit/47ed141b93291938d8790a8697b55c9c9af230bd))
12
+ - use() more modules ([#1953](https://github.com/ExodusMovement/exodus-hydra/issues/1953)) ([4f0d987](https://github.com/ExodusMovement/exodus-hydra/commit/4f0d987e2b3c01829e11b430988168754ebce8f6))
13
+
14
+ ### Bug Fixes
15
+
16
+ - new use modules api export ([#1958](https://github.com/ExodusMovement/exodus-hydra/issues/1958)) ([c7e87eb](https://github.com/ExodusMovement/exodus-hydra/commit/c7e87eb01f5fb79fcc3454a11485dadf638f88ef))
17
+ - remove duplicated kyc api ([#1955](https://github.com/ExodusMovement/exodus-hydra/issues/1955)) ([3357590](https://github.com/ExodusMovement/exodus-hydra/commit/33575908517230b5a187f0ac3b6e32e75982abdb))
18
+ - require plugin methods to be declared correctly ([#1945](https://github.com/ExodusMovement/exodus-hydra/issues/1945)) ([e7feae6](https://github.com/ExodusMovement/exodus-hydra/commit/e7feae6cfaa3cd0e9f9d074f4b5306a264d16b74))
19
+
6
20
  ## [2.0.0-alpha.41](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@2.0.0-alpha.40...@exodus/headless@2.0.0-alpha.41) (2023-06-15)
7
21
 
8
22
  ### Features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/headless",
3
- "version": "2.0.0-alpha.41",
3
+ "version": "2.0.0-alpha.42",
4
4
  "description": "The headless Exodus wallet SDK",
5
5
  "author": "Exodus Movement Inc",
6
6
  "main": "src/index.js",
@@ -87,5 +87,5 @@
87
87
  "nock": "^13.3.1",
88
88
  "p-defer": "^4.0.0"
89
89
  },
90
- "gitHead": "c548938b8c6dee498023373e2122cb95da1005f5"
90
+ "gitHead": "bd71b5cf5b53868f90e6741bff3425022df792e9"
91
91
  }
package/src/api.js CHANGED
@@ -1,45 +1,34 @@
1
1
  import { validateMnemonic as isMnemonicValid } from 'bip39'
2
2
 
3
3
  const createApi = ({ ioc, port }) => {
4
+ const apis = ioc.getByType('api')
5
+
4
6
  const { assetsModule } = ioc.getByType('adapter')
5
7
 
6
8
  const {
7
9
  addressProvider,
8
10
  application,
9
11
  blockchainMetadata,
10
- connectedOrigins,
11
12
  enabledAssets,
12
- kyc,
13
- nfts,
14
13
  personalNotes,
15
- referrals,
16
14
  remoteConfig,
17
15
  wallet,
18
- walletAccounts,
19
16
  } = ioc.getByType('module')
20
17
 
21
18
  const { feeMonitors, ratesMonitor, nftsMonitor } = ioc.getByType('monitor')
19
+
22
20
  // TODO: decide where this belongs
23
21
  const { passphraseCache } = ioc.getAll()
24
22
 
25
- const {
26
- // ...
27
- currencyAtom,
28
- enabledWalletAccountsAtom,
29
- languageAtom,
30
- connectedOriginsAtom,
31
- } = ioc.getByType('atom')
32
-
33
23
  // TODO: do this on 'unload'
34
24
  const stop = () => {
35
- kyc.stop()
36
- referrals.stop()
37
25
  remoteConfig.stop()
38
26
  feeMonitors.stop()
39
- nftsMonitor.stop()
27
+ nftsMonitor?.stop()
40
28
  }
41
29
 
42
30
  return {
31
+ ...Object.assign({}, ...Object.values(apis)),
43
32
  wallet: {
44
33
  exists: () => wallet.exists(),
45
34
  start: application.start,
@@ -62,13 +51,6 @@ const createApi = ({ ioc, port }) => {
62
51
  changeLockTimer: application.changeLockTimer,
63
52
  isLocked: () => wallet.isLocked(),
64
53
  },
65
- walletAccounts: {
66
- create: walletAccounts.create,
67
- update: walletAccounts.update,
68
- disable: walletAccounts.disable,
69
- enable: walletAccounts.enable,
70
- getEnabled: enabledWalletAccountsAtom.get,
71
- },
72
54
  blockchainMetadata: {
73
55
  getTxLog: blockchainMetadata.getTxLog,
74
56
  getLoadedTxLogs: blockchainMetadata.getLoadedTxLogs,
@@ -95,10 +77,6 @@ const createApi = ({ ioc, port }) => {
95
77
  get: remoteConfig.get,
96
78
  getAll: remoteConfig.getAll,
97
79
  },
98
- locale: {
99
- setLanguage: (value) => languageAtom.set(value),
100
- setCurrency: (value) => currencyAtom.set(value),
101
- },
102
80
  rates: {
103
81
  refresh: () => ratesMonitor.update(),
104
82
  },
@@ -107,36 +85,9 @@ const createApi = ({ ioc, port }) => {
107
85
  getSupportedPurposes: addressProvider.getSupportedPurposes.bind(addressProvider),
108
86
  getReceiveAddress: addressProvider.getReceiveAddress.bind(addressProvider),
109
87
  },
110
- kyc: {
111
- start: kyc.start,
112
- sync: kyc.sync,
113
- requestKycToken: kyc.requestKycToken,
114
- },
115
- referrals: {
116
- setReferredBy: referrals.setReferredBy,
117
- referralCodeExists: referrals.referralCodeExists,
118
- },
119
88
  personalNotes: {
120
89
  upsert: personalNotes.upsert,
121
90
  },
122
- nfts: {
123
- upsertConfig: nfts.upsertConfig,
124
- setMonitorInterval: nftsMonitor.setInterval,
125
- },
126
- connectedOrigins: {
127
- get: connectedOriginsAtom.get,
128
- add: connectedOrigins.add,
129
- clear: connectedOrigins.clear,
130
- untrust: connectedOrigins.untrust,
131
- isTrusted: connectedOrigins.isTrusted,
132
- isAutoApprove: connectedOrigins.isAutoApprove,
133
- setFavorite: connectedOrigins.setFavorite,
134
- setAutoApprove: connectedOrigins.setAutoApprove,
135
- connect: connectedOrigins.connect,
136
- disconnect: connectedOrigins.disconnect,
137
- updateConnection: connectedOrigins.updateConnection,
138
- clearConnections: connectedOrigins.clearConnections,
139
- },
140
91
  isMnemonicValid,
141
92
  subscribe: port.subscribe.bind(port),
142
93
  unsubscribe: port.unsubscribe.bind(port),
@@ -3,6 +3,8 @@
3
3
  import ExodusModule from '@exodus/module'
4
4
  import assert from 'minimalistic-assert'
5
5
 
6
+ import { LifecycleHook as Hook } from './constants'
7
+
6
8
  // Because we are forced to restart wallet after deleting/importing, we need to store certain flags to persist state between executions
7
9
 
8
10
  // Triggers deletetion logic when wallet starts.
@@ -17,23 +19,6 @@ const IMPORT_FLAG = 'importFlag'
17
19
  // Set as true on import method is called, and set to false after restore is completed
18
20
  const RESTORE_FLAG = 'restoreFlag'
19
21
 
20
- const Hook = Object.freeze({
21
- Lock: 'lock',
22
- Unlock: 'unlock',
23
- Clear: 'clear',
24
- Import: 'import',
25
- Migrate: 'migrate',
26
- Start: 'start',
27
- Load: 'load',
28
- Unload: 'unload',
29
- Create: 'create',
30
- Backup: 'backup',
31
- Restore: 'restore',
32
- RestoreCompleted: 'restore-completed',
33
- AssetsSynced: 'assets-synced',
34
- ChangePassphrase: 'change-passphrase',
35
- })
36
-
37
22
  const HOOKS = new Set(Object.values(Hook))
38
23
 
39
24
  class Application extends ExodusModule {
package/src/constants.js CHANGED
@@ -16,3 +16,20 @@ export const atomsToAttach = [
16
16
  'topMoversAtom',
17
17
  'walletAccountsAtom',
18
18
  ]
19
+
20
+ export const LifecycleHook = Object.freeze({
21
+ Lock: 'lock',
22
+ Unlock: 'unlock',
23
+ Clear: 'clear',
24
+ Import: 'import',
25
+ Migrate: 'migrate',
26
+ Start: 'start',
27
+ Load: 'load',
28
+ Unload: 'unload',
29
+ Create: 'create',
30
+ Backup: 'backup',
31
+ Restore: 'restore',
32
+ RestoreCompleted: 'restore-completed',
33
+ AssetsSynced: 'assets-synced',
34
+ ChangePassphrase: 'change-passphrase',
35
+ })
@@ -1,13 +1,11 @@
1
1
  import { apyRatesAtomDefinition } from '@exodus/apy-rates/atoms'
2
2
  import {
3
- createFusionAtomFactory,
4
3
  createInMemoryAtom,
5
4
  createRemoteConfigAtomFactory,
6
5
  createStorageAtomFactory,
7
6
  } from '@exodus/atoms'
8
7
  import { availableAssetNamesAtomDefinition } from '@exodus/available-assets/atoms'
9
8
  import { balancesAtomDefinition } from '@exodus/balances/atoms'
10
- import { connectedOriginsAtomDefinition } from '@exodus/connected-origins/atoms'
11
9
  import { cryptoNewsAtomDefinition } from '@exodus/crypto-news-monitor/atoms'
12
10
  import {
13
11
  enabledAndDisabledAssetsAtomDefinition,
@@ -15,16 +13,9 @@ import {
15
13
  } from '@exodus/enabled-assets/atoms'
16
14
  import { featureFlagsAtomDefinition } from '@exodus/feature-flags/atoms'
17
15
  import { geolocationAtomDefinition } from '@exodus/geolocation/atoms'
18
- import { kycAtomDefinition } from '@exodus/kyc/atoms'
19
- import { nftsCacheAtomDefinition, nftsConfigsAtomDefinition } from '@exodus/nfts/atoms'
20
16
  import { personalNotesAtomDefinition } from '@exodus/personal-notes/atoms'
21
17
  import { ratesAtomDefinition } from '@exodus/rates-monitor/atoms'
22
- import { referralsAtomDefinition } from '@exodus/referrals/atoms'
23
18
  import { topMoversAtomDefinition } from '@exodus/top-movers-monitor/atoms'
24
- import {
25
- enabledWalletAccountsAtomDefinition,
26
- walletAccountsAtomDefinition,
27
- } from '@exodus/wallet-accounts/atoms'
28
19
 
29
20
  import baseAssetNamesToMonitorAtomDefinition from '../atoms/base-asset-names-to-monitor'
30
21
  import nonDustBalanceAssetNamesAtomDefinition from '../atoms/non-dust-balance-asset-names-atom'
@@ -40,11 +31,6 @@ const createAtomDependencies = () =>
40
31
  dependencies: [],
41
32
  },
42
33
  },
43
- {
44
- definition: walletAccountsAtomDefinition,
45
- storage: { namespace: 'walletAccounts' },
46
- },
47
- { definition: enabledWalletAccountsAtomDefinition },
48
34
  {
49
35
  definition: enabledAndDisabledAssetsAtomDefinition,
50
36
  storage: { namespace: 'enabledAssets' },
@@ -65,36 +51,6 @@ const createAtomDependencies = () =>
65
51
  dependencies: ['config', 'remoteConfig'],
66
52
  },
67
53
  },
68
- {
69
- definition: {
70
- id: 'languageAtom',
71
- factory: ({ storage, config }) =>
72
- createStorageAtomFactory({ storage })({
73
- key: 'language',
74
- defaultValue: config.defaultValue,
75
- isSoleWriter: true,
76
- }),
77
- dependencies: ['storage', 'config'],
78
- },
79
- aliases: [
80
- {
81
- implementationId: 'unsafeStorage',
82
- interfaceId: 'storage',
83
- },
84
- ],
85
- storage: { namespace: 'locale' },
86
- },
87
- {
88
- definition: {
89
- id: 'currencyAtom',
90
- factory: ({ fusion, config }) =>
91
- createFusionAtomFactory({ fusion })({
92
- path: `private.currency`,
93
- defaultValue: config.defaultValue,
94
- }),
95
- dependencies: ['fusion', 'config'],
96
- },
97
- },
98
54
  // TODO: move to @exodus/market-history
99
55
  {
100
56
  definition: {
@@ -144,8 +100,6 @@ const createAtomDependencies = () =>
144
100
  { definition: ratesAtomDefinition },
145
101
  { definition: geolocationAtomDefinition },
146
102
  { definition: featureFlagsAtomDefinition },
147
- { definition: kycAtomDefinition },
148
- { definition: referralsAtomDefinition },
149
103
  {
150
104
  definition: personalNotesAtomDefinition,
151
105
  aliases: [
@@ -155,30 +109,11 @@ const createAtomDependencies = () =>
155
109
  },
156
110
  ],
157
111
  },
158
- {
159
- definition: connectedOriginsAtomDefinition,
160
- storage: { namespace: 'connectedOrigins' },
161
- aliases: [
162
- {
163
- implementationId: 'unsafeStorage',
164
- interfaceId: 'storage',
165
- },
166
- ],
167
- },
168
112
  { definition: baseAssetNamesToMonitorAtomDefinition },
169
113
  { definition: topMoversAtomDefinition },
170
114
  { definition: cryptoNewsAtomDefinition },
171
115
  { definition: restoreAtomDefinition },
172
116
  { definition: apyRatesAtomDefinition },
173
- {
174
- definition: nftsCacheAtomDefinition,
175
- storage: { namespace: 'nftsCache' },
176
- },
177
- {
178
- definition: nftsConfigsAtomDefinition,
179
- aliases: [{ implementationId: 'unsafeStorage', interfaceId: 'storage' }],
180
- storage: { namespace: 'nfts-config' },
181
- },
182
117
  ].map(withType('atom'))
183
118
 
184
119
  export default createAtomDependencies
@@ -3,18 +3,13 @@ import availableAssetsModuleDefinition from '@exodus/available-assets/module'
3
3
  import balancesDefinition from '@exodus/balances/module'
4
4
  import blockchainMetadataDefinition from '@exodus/blockchain-metadata/module'
5
5
  import createRemoteConfig from '@exodus/config/remote'
6
- import connectedOriginsDefinition from '@exodus/connected-origins/module'
7
6
  import enabledAssetsModuleDefinition from '@exodus/enabled-assets/module'
8
7
  import createExodusPricingClient from '@exodus/exodus-pricing-client'
9
8
  import featureFlagsDefinition from '@exodus/feature-flags/module'
10
9
  import createKeyIdentifierProvider from '@exodus/key-identifier-provider'
11
10
  import keychainDefinition from '@exodus/keychain/module'
12
- import kycDefinition from '@exodus/kyc/module'
13
- import nftsModuleDefinition from '@exodus/nfts/module'
14
11
  import personalNotesDefinition from '@exodus/personal-notes/module'
15
- import referralsDefinition from '@exodus/referrals/module'
16
12
  import walletDefinition from '@exodus/wallet/module'
17
- import walletAccountsDefinition from '@exodus/wallet-accounts/module'
18
13
  import walletCompatibilityModesDefinition from '@exodus/wallet-compatibility-modes/module'
19
14
  import EventEmitter from 'events/'
20
15
 
@@ -49,7 +44,6 @@ const createModuleDependencies = ({ config }) =>
49
44
  definition: walletCompatibilityModesDefinition,
50
45
  },
51
46
  { definition: unlockEncryptedStorageDefinition },
52
- { definition: walletAccountsDefinition, writesAtoms: ['walletAccountsAtom'] },
53
47
  {
54
48
  definition: blockchainMetadataDefinition,
55
49
  storage: { namespace: ['blockchain', 'v1'] },
@@ -79,31 +73,9 @@ const createModuleDependencies = ({ config }) =>
79
73
  writesAtoms: ['featureFlagAtoms'],
80
74
  },
81
75
  ...createAddressProviderDependencies(config.addressProvider),
82
- {
83
- definition: kycDefinition,
84
- writesAtoms: ['kycAtom'],
85
- },
86
- {
87
- definition: referralsDefinition,
88
- storage: { namespace: 'referrals' },
89
- writesAtoms: ['referralsAtom'],
90
- aliases: [
91
- {
92
- implementationId: 'unsafeStorage',
93
- interfaceId: 'storage',
94
- },
95
- ],
96
- },
97
76
  {
98
77
  definition: personalNotesDefinition,
99
78
  },
100
- {
101
- definition: connectedOriginsDefinition,
102
- writesAtoms: ['connectedOriginsAtom'],
103
- },
104
- {
105
- definition: nftsModuleDefinition,
106
- },
107
79
  ].map(withType('module'))
108
80
 
109
81
  export default createModuleDependencies
@@ -3,7 +3,6 @@ import cryptoNewsMonitorDefinition from '@exodus/crypto-news-monitor/monitor'
3
3
  import feeMonitorsDefinition from '@exodus/fee-monitors/monitor'
4
4
  import geolocationMonitorDefinition from '@exodus/geolocation/monitor'
5
5
  import marketHistoryMonitorDefinition from '@exodus/market-history/module'
6
- import nftsMonitorDefinition from '@exodus/nfts/monitor'
7
6
  import ratesMonitorDefinition from '@exodus/rates-monitor/module'
8
7
  import localTopMoversMonitorDefinition from '@exodus/top-movers-monitor/monitor/local'
9
8
  import remoteTopMoversMonitorDefinition from '@exodus/top-movers-monitor/monitor/remote'
@@ -57,10 +56,6 @@ const createMonitorDependencies = ({ config }) =>
57
56
  definition: apyRatesMonitorDefinition,
58
57
  writesAtoms: ['apyRatesAtom'],
59
58
  },
60
- {
61
- definition: nftsMonitorDefinition,
62
- writesAtoms: ['nftsCacheAtom'],
63
- },
64
59
  ].map(withType('monitor'))
65
60
 
66
61
  export default createMonitorDependencies
package/src/index.js CHANGED
@@ -4,6 +4,12 @@ import createApi from './api'
4
4
  import attachAtoms from './atoms/attach'
5
5
  import { atomsToAttach } from './constants'
6
6
  import createIOC from './ioc'
7
+ import connectedOrigins from './modules/connected-origins'
8
+ import kyc from './modules/kyc'
9
+ import locale from './modules/locale'
10
+ import nfts from './modules/nfts'
11
+ import referrals from './modules/referrals'
12
+ import walletAccounts from './modules/wallet-accounts'
7
13
  import attachPlugins from './plugins/attach'
8
14
  import { createLoadWalletAccountsHandler } from './utils/blockchain-metadata'
9
15
 
@@ -11,26 +17,28 @@ const createExodus = ({ adapters, config, port }) => {
11
17
  const ioc = createIOC({ adapters, config })
12
18
  const { headless: headlessConfig } = config
13
19
 
20
+ ioc.use(walletAccounts())
21
+ ioc.use(locale())
22
+ ioc.use(nfts())
23
+ ioc.use(kyc())
24
+ ioc.use(referrals())
25
+ ioc.use(connectedOrigins())
26
+
27
+ ioc.register({ definition: { id: 'port', type: 'port', factory: () => port } })
28
+
14
29
  const resolve = () => {
15
30
  ioc.resolve()
16
31
 
17
32
  const { assetsModule, storage } = ioc.getByType('adapter')
18
33
 
19
- const { languageAtom } = ioc.getByType('atom')
20
-
21
34
  const {
22
35
  application,
23
36
  blockchainMetadata,
24
- connectedOrigins,
25
37
  enabledAssets,
26
38
  featureFlags,
27
- kyc,
28
- nfts,
29
39
  personalNotes,
30
- referrals,
31
40
  remoteConfig,
32
41
  unlockEncryptedStorage,
33
- walletAccounts,
34
42
  } = ioc.getByType('module')
35
43
 
36
44
  const {
@@ -39,7 +47,6 @@ const createExodus = ({ adapters, config, port }) => {
39
47
  feeMonitors,
40
48
  geolocationMonitor,
41
49
  marketHistory,
42
- nftsMonitor,
43
50
  ratesMonitor,
44
51
  topMoversMonitor,
45
52
  } = ioc.getByType('monitor')
@@ -71,9 +78,6 @@ const createExodus = ({ adapters, config, port }) => {
71
78
  // TODO: migrate to ratesAtom. Will be easier once it's on headless
72
79
  ratesMonitor.on('rates', (payload) => port.emit('rates', payload))
73
80
 
74
- nftsMonitor.on('nfts', (data) => port.emit('nfts', data))
75
- nftsMonitor.on('nfts-txs', (data) => port.emit('nfts-txs', data))
76
-
77
81
  application.hook('start', (payload) => {
78
82
  remoteConfig.load()
79
83
  featureFlags.load()
@@ -90,23 +94,14 @@ const createExodus = ({ adapters, config, port }) => {
90
94
  ratesMonitor.start()
91
95
  feeMonitors.start()
92
96
  apyRatesMonitor.start()
93
- nftsMonitor.start()
94
97
 
95
98
  await assetsModule.load()
96
- await connectedOrigins.load()
97
- await walletAccounts.load()
98
99
  await Promise.all([
99
100
  //
100
101
  blockchainMetadata.load(),
101
102
  enabledAssets.load(),
102
103
  ])
103
104
 
104
- featureFlagAtoms.referrals?.get().then(({ isOn }) => {
105
- if (!isOn) return
106
- kyc.load()
107
- referrals.load()
108
- })
109
-
110
105
  featureFlagAtoms.topMovers?.get().then(({ isOn }) => {
111
106
  if (!isOn) return
112
107
  topMoversMonitor.start()
@@ -126,18 +121,16 @@ const createExodus = ({ adapters, config, port }) => {
126
121
  await Promise.all([
127
122
  //
128
123
  assetsModule.clear(),
129
- walletAccounts.clear(),
130
124
  blockchainMetadata.clear(),
131
125
  enabledAssets.clear(),
132
- connectedOrigins.clear(),
133
126
  featureFlags.clear(),
134
- languageAtom.set(undefined),
135
127
  ])
136
128
 
137
129
  // TEMP: dont wait to clear as encrypted storage is not yet unlocked
138
130
  personalNotes.clear()
139
- nfts.clear()
131
+ })
140
132
 
133
+ application.on('clear', () => {
141
134
  port.emit('clear')
142
135
  })
143
136
 
@@ -153,7 +146,11 @@ const createExodus = ({ adapters, config, port }) => {
153
146
  lifecycleEvents: headlessConfig?.attachAtomsLifecycleEvents,
154
147
  })
155
148
 
156
- attachPlugins({ application, plugins: ioc.getByType('plugin') })
149
+ attachPlugins({
150
+ application,
151
+ plugins: ioc.getByType('plugin'),
152
+ logger: ioc.get('createLogger')('attachPlugins'),
153
+ })
157
154
 
158
155
  return createApi({ ioc, port })
159
156
  }
package/src/ioc.js CHANGED
@@ -15,7 +15,6 @@ const createIOC = ({ adapters, config }) => {
15
15
  const { readOnlyAtoms: readOnlyAtomsConfig, devModeAtoms: devModeAtomsConfig } = config.ioc ?? {}
16
16
 
17
17
  const ioc = createIocContainer({ logger: createLogger('exodus:ioc') })
18
- const dependencies = createDependencies({ adapters, config })
19
18
 
20
19
  const preprocessors = [
21
20
  logify({ createLogger }),
@@ -40,9 +39,13 @@ const createIOC = ({ adapters, config }) => {
40
39
  registerMultiple([dependency])
41
40
  }
42
41
 
43
- registerMultiple(dependencies)
42
+ const use = (module) => {
43
+ registerMultiple(module.definitions)
44
+ }
45
+
46
+ registerMultiple(createDependencies({ adapters, config }))
44
47
 
45
- return { ...ioc, register, registerMultiple }
48
+ return { ...ioc, register, registerMultiple, use }
46
49
  }
47
50
 
48
51
  export default createIOC
@@ -0,0 +1,23 @@
1
+ const connectedOriginsApi = ({ connectedOrigins, connectedOriginsAtom }) => ({
2
+ connectedOrigins: {
3
+ get: connectedOriginsAtom.get,
4
+ add: connectedOrigins.add,
5
+ clear: connectedOrigins.clear,
6
+ untrust: connectedOrigins.untrust,
7
+ isTrusted: connectedOrigins.isTrusted,
8
+ isAutoApprove: connectedOrigins.isAutoApprove,
9
+ setFavorite: connectedOrigins.setFavorite,
10
+ setAutoApprove: connectedOrigins.setAutoApprove,
11
+ connect: connectedOrigins.connect,
12
+ disconnect: connectedOrigins.disconnect,
13
+ updateConnection: connectedOrigins.updateConnection,
14
+ clearConnections: connectedOrigins.clearConnections,
15
+ },
16
+ })
17
+
18
+ export default {
19
+ id: 'connectedOriginsApi',
20
+ type: 'api',
21
+ factory: connectedOriginsApi,
22
+ dependencies: ['connectedOrigins', 'connectedOriginsAtom'],
23
+ }
@@ -0,0 +1,31 @@
1
+ import { connectedOriginsAtomDefinition } from '@exodus/connected-origins/atoms'
2
+ import connectedOriginsDefinition from '@exodus/connected-origins/module'
3
+
4
+ import connectedOriginsApiDefinition from './api'
5
+ import connectedOriginsPluginDefinition from './plugin'
6
+
7
+ const connectedOrigins = () => {
8
+ return {
9
+ id: 'connectedOrigins',
10
+ definitions: [
11
+ {
12
+ definition: connectedOriginsAtomDefinition,
13
+ storage: { namespace: 'connectedOrigins' },
14
+ aliases: [
15
+ {
16
+ implementationId: 'unsafeStorage',
17
+ interfaceId: 'storage',
18
+ },
19
+ ],
20
+ },
21
+ {
22
+ definition: connectedOriginsDefinition,
23
+ writesAtoms: ['connectedOriginsAtom'],
24
+ },
25
+ { definition: connectedOriginsPluginDefinition },
26
+ { definition: connectedOriginsApiDefinition },
27
+ ],
28
+ }
29
+ }
30
+
31
+ export default connectedOrigins
@@ -0,0 +1,18 @@
1
+ const connectedOriginsPlugin = ({ connectedOrigins }) => {
2
+ const onUnlock = async () => {
3
+ await connectedOrigins.load()
4
+ }
5
+
6
+ const onClear = async () => {
7
+ await connectedOrigins.clear()
8
+ }
9
+
10
+ return { onUnlock, onClear }
11
+ }
12
+
13
+ export default {
14
+ id: 'connectedOriginsLifecyclePlugin',
15
+ type: 'plugin',
16
+ factory: connectedOriginsPlugin,
17
+ dependencies: ['connectedOrigins'],
18
+ }
@@ -0,0 +1,14 @@
1
+ const kycApi = ({ kyc }) => ({
2
+ kyc: {
3
+ start: kyc.start,
4
+ sync: kyc.sync,
5
+ requestKycToken: kyc.requestKycToken,
6
+ },
7
+ })
8
+
9
+ export default {
10
+ id: 'kycApi',
11
+ type: 'api',
12
+ factory: kycApi,
13
+ dependencies: ['kyc'],
14
+ }
@@ -0,0 +1,19 @@
1
+ import { kycAtomDefinition } from '@exodus/kyc/atoms'
2
+ import kycDefinition from '@exodus/kyc/module'
3
+
4
+ import kycApi from './api'
5
+ import kycPlugin from './plugin'
6
+
7
+ const kyc = () => {
8
+ return {
9
+ id: 'kyc',
10
+ definitions: [
11
+ { definition: kycAtomDefinition },
12
+ { definition: kycDefinition, writesAtoms: ['kycAtom'] },
13
+ { definition: kycPlugin },
14
+ { definition: kycApi },
15
+ ],
16
+ }
17
+ }
18
+
19
+ export default kyc
@@ -0,0 +1,21 @@
1
+ const kycPlugin = ({ kyc, featureFlagAtoms }) => {
2
+ const onUnlock = () => {
3
+ featureFlagAtoms.referrals?.get().then(({ isOn }) => {
4
+ if (!isOn) return
5
+ kyc.load()
6
+ })
7
+ }
8
+
9
+ const onUnload = () => {
10
+ kyc.stop()
11
+ }
12
+
13
+ return { onUnlock, onUnload }
14
+ }
15
+
16
+ export default {
17
+ id: 'kycLifecyclePlugin',
18
+ type: 'plugin',
19
+ factory: kycPlugin,
20
+ dependencies: ['kyc', 'featureFlagAtoms'],
21
+ }
@@ -0,0 +1,13 @@
1
+ const localeApi = ({ languageAtom, currencyAtom }) => ({
2
+ locale: {
3
+ setLanguage: (value) => languageAtom.set(value),
4
+ setCurrency: (value) => currencyAtom.set(value),
5
+ },
6
+ })
7
+
8
+ export default {
9
+ id: 'localeApi',
10
+ type: 'api',
11
+ factory: localeApi,
12
+ dependencies: ['languageAtom', 'currencyAtom'],
13
+ }
@@ -0,0 +1,48 @@
1
+ import { createFusionAtomFactory, createStorageAtomFactory } from '@exodus/atoms'
2
+
3
+ import localeApiDefinition from './api'
4
+ import localePluginDefinition from './plugin'
5
+
6
+ const locale = () => {
7
+ return {
8
+ id: 'locale',
9
+ definitions: [
10
+ {
11
+ definition: {
12
+ id: 'currencyAtom',
13
+ type: 'atom',
14
+ factory: ({ fusion, config }) =>
15
+ createFusionAtomFactory({ fusion })({
16
+ path: `private.currency`,
17
+ defaultValue: config.defaultValue,
18
+ }),
19
+ dependencies: ['fusion', 'config'],
20
+ },
21
+ },
22
+ {
23
+ definition: {
24
+ id: 'languageAtom',
25
+ type: 'atom',
26
+ factory: ({ storage, config }) =>
27
+ createStorageAtomFactory({ storage })({
28
+ key: 'language',
29
+ defaultValue: config.defaultValue,
30
+ isSoleWriter: true,
31
+ }),
32
+ dependencies: ['storage', 'config'],
33
+ },
34
+ aliases: [
35
+ {
36
+ implementationId: 'unsafeStorage',
37
+ interfaceId: 'storage',
38
+ },
39
+ ],
40
+ storage: { namespace: 'locale' },
41
+ },
42
+ { definition: localePluginDefinition },
43
+ { definition: localeApiDefinition },
44
+ ],
45
+ }
46
+ }
47
+
48
+ export default locale
@@ -0,0 +1,14 @@
1
+ const localePlugin = ({ languageAtom }) => {
2
+ const onClear = async () => {
3
+ await languageAtom.set(undefined)
4
+ }
5
+
6
+ return { onClear }
7
+ }
8
+
9
+ export default {
10
+ id: 'localeLifecyclePlugin',
11
+ type: 'plugin',
12
+ factory: localePlugin,
13
+ dependencies: ['languageAtom'],
14
+ }
@@ -0,0 +1,13 @@
1
+ const createNftsApi = ({ nfts, nftsMonitor }) => ({
2
+ nfts: {
3
+ upsertConfig: nfts.upsertConfig,
4
+ setMonitorInterval: nftsMonitor.setInterval,
5
+ },
6
+ })
7
+
8
+ export default {
9
+ id: 'createNftsApi',
10
+ type: 'api',
11
+ factory: createNftsApi,
12
+ dependencies: ['nfts', 'nftsMonitor'],
13
+ }
@@ -0,0 +1,33 @@
1
+ import { nftsCacheAtomDefinition, nftsConfigsAtomDefinition } from '@exodus/nfts/atoms'
2
+ import nftsModuleDefinition from '@exodus/nfts/module'
3
+ import nftsMonitorDefinition from '@exodus/nfts/monitor'
4
+
5
+ import nftsApiDefinition from './api'
6
+ import nftsPluginDefinition from './plugin'
7
+
8
+ // TODO: Add type to module definitions
9
+ const nfts = () => {
10
+ return {
11
+ id: 'nfts',
12
+ definitions: [
13
+ {
14
+ definition: { type: 'atom', ...nftsCacheAtomDefinition },
15
+ storage: { namespace: 'nftsCache' },
16
+ },
17
+ {
18
+ definition: { type: 'atom', ...nftsConfigsAtomDefinition },
19
+ aliases: [{ implementationId: 'unsafeStorage', interfaceId: 'storage' }],
20
+ storage: { namespace: 'nfts-config' },
21
+ },
22
+ {
23
+ definition: { type: 'monitor', ...nftsMonitorDefinition },
24
+ writesAtoms: ['nftsCacheAtom'],
25
+ },
26
+ { definition: nftsModuleDefinition },
27
+ { definition: nftsPluginDefinition },
28
+ { definition: nftsApiDefinition },
29
+ ],
30
+ }
31
+ }
32
+
33
+ export default nfts
@@ -0,0 +1,23 @@
1
+ const nftsLifecyclePlugin = ({ nfts, nftsMonitor, port }) => {
2
+ // TODO: Move to onStart, but needs testing first
3
+ nftsMonitor.on('nfts', (data) => port.emit('nfts', data))
4
+ nftsMonitor.on('nfts-txs', (data) => port.emit('nfts-txs', data))
5
+
6
+ const onUnlock = () => {
7
+ nfts.load()
8
+ nftsMonitor.start()
9
+ }
10
+
11
+ const onClear = () => {
12
+ nfts.clear()
13
+ }
14
+
15
+ return { onUnlock, onClear }
16
+ }
17
+
18
+ export default {
19
+ id: 'nftsLifecyclePlugin',
20
+ type: 'plugin',
21
+ factory: nftsLifecyclePlugin,
22
+ dependencies: ['nfts', 'nftsMonitor', 'port'],
23
+ }
@@ -0,0 +1,13 @@
1
+ const referralsApi = ({ referrals }) => ({
2
+ referrals: {
3
+ setReferredBy: referrals.setReferredBy,
4
+ referralCodeExists: referrals.referralCodeExists,
5
+ },
6
+ })
7
+
8
+ export default {
9
+ id: 'referralsApi',
10
+ type: 'api',
11
+ factory: referralsApi,
12
+ dependencies: ['referrals'],
13
+ }
@@ -0,0 +1,28 @@
1
+ import { referralsAtomDefinition } from '@exodus/referrals/atoms'
2
+ import referralsDefinition from '@exodus/referrals/module'
3
+
4
+ import referralsApi from './api'
5
+ import referralsPlugin from './plugin'
6
+
7
+ const unsafeStorageAlias = { implementationId: 'unsafeStorage', interfaceId: 'storage' }
8
+
9
+ const referrals = ({ namespace = 'referrals', useUnsafeStorage = true } = {}) => {
10
+ const aliases = useUnsafeStorage ? [unsafeStorageAlias] : []
11
+
12
+ return {
13
+ id: 'referrals',
14
+ definitions: [
15
+ { definition: referralsAtomDefinition },
16
+ {
17
+ definition: referralsDefinition,
18
+ storage: { namespace },
19
+ writesAtoms: ['referralsAtom'],
20
+ aliases,
21
+ },
22
+ { definition: referralsPlugin },
23
+ { definition: referralsApi },
24
+ ],
25
+ }
26
+ }
27
+
28
+ export default referrals
@@ -0,0 +1,21 @@
1
+ const referralsPlugin = ({ referrals, featureFlagAtoms }) => {
2
+ const onUnlock = () => {
3
+ featureFlagAtoms.referrals?.get().then(({ isOn }) => {
4
+ if (!isOn) return
5
+ referrals.load()
6
+ })
7
+ }
8
+
9
+ const onUnload = () => {
10
+ referrals.stop()
11
+ }
12
+
13
+ return { onUnlock, onUnload }
14
+ }
15
+
16
+ export default {
17
+ id: 'referralsLifecyclePlugin',
18
+ type: 'plugin',
19
+ factory: referralsPlugin,
20
+ dependencies: ['referrals', 'featureFlagAtoms'],
21
+ }
@@ -0,0 +1,16 @@
1
+ const walletAccountsApi = ({ walletAccounts, enabledWalletAccountsAtom }) => ({
2
+ walletAccounts: {
3
+ create: walletAccounts.create,
4
+ update: walletAccounts.update,
5
+ disable: walletAccounts.disable,
6
+ enable: walletAccounts.enable,
7
+ getEnabled: enabledWalletAccountsAtom.get,
8
+ },
9
+ })
10
+
11
+ export default {
12
+ id: 'walletAccountsApi',
13
+ type: 'api',
14
+ factory: walletAccountsApi,
15
+ dependencies: ['walletAccounts', 'enabledWalletAccountsAtom'],
16
+ }
@@ -0,0 +1,29 @@
1
+ import {
2
+ enabledWalletAccountsAtomDefinition,
3
+ walletAccountsAtomDefinition,
4
+ } from '@exodus/wallet-accounts/atoms'
5
+ import walletAccountsDefinition from '@exodus/wallet-accounts/module'
6
+
7
+ import walletAccountsApiDefinition from './api'
8
+ import walletAccountsPluginDefinition from './plugin'
9
+
10
+ const walletAccounts = () => {
11
+ return {
12
+ id: 'walletAccounts',
13
+ definitions: [
14
+ {
15
+ definition: walletAccountsDefinition,
16
+ writesAtoms: ['walletAccountsAtom'],
17
+ },
18
+ {
19
+ definition: walletAccountsAtomDefinition,
20
+ storage: { namespace: 'walletAccounts' },
21
+ },
22
+ { definition: enabledWalletAccountsAtomDefinition },
23
+ { definition: walletAccountsApiDefinition },
24
+ { definition: walletAccountsPluginDefinition },
25
+ ],
26
+ }
27
+ }
28
+
29
+ export default walletAccounts
@@ -0,0 +1,18 @@
1
+ const walletAccountsPlugin = ({ walletAccounts }) => {
2
+ const onUnlock = async () => {
3
+ await walletAccounts.load()
4
+ }
5
+
6
+ const onClear = async () => {
7
+ await walletAccounts.clear()
8
+ }
9
+
10
+ return { onUnlock, onClear }
11
+ }
12
+
13
+ export default {
14
+ id: 'walletAccountsLifecyclePlugin',
15
+ type: 'plugin',
16
+ factory: walletAccountsPlugin,
17
+ dependencies: ['walletAccounts'],
18
+ }
@@ -1,17 +1,23 @@
1
- import { kebabCase, memoize } from 'lodash'
1
+ import { LifecycleHook } from '../constants'
2
2
 
3
- // e.g. onUnlock -> unlock -> onUnlock, onChangePassphrase -> change-passphrase
4
- const getApplicationHookName = memoize((lifecycleMethod) =>
5
- kebabCase(lifecycleMethod.replace(/^on/, ''))
3
+ const LIFECYCLE_METHOD_TO_HOOK_NAME = Object.fromEntries(
4
+ Object.entries(LifecycleHook).map(([pascalCaseName, hookName]) => [
5
+ `on${pascalCaseName}`,
6
+ hookName,
7
+ ])
6
8
  )
7
9
 
8
- const attachPlugins = ({ plugins, application }) => {
10
+ const attachPlugins = ({ plugins, application, logger }) => {
9
11
  Object.entries(plugins).forEach(([name, lifecycleMethods]) => {
10
12
  const entries = Object.entries(lifecycleMethods || {})
11
13
 
12
14
  for (const [lifecycleMethod, fn] of entries) {
13
- const hookName = getApplicationHookName(lifecycleMethod)
14
- application.hook(hookName, fn)
15
+ const hookName = LIFECYCLE_METHOD_TO_HOOK_NAME[lifecycleMethod]
16
+ if (hookName) {
17
+ application.hook(hookName, fn)
18
+ } else {
19
+ logger.error(`plugin "${name}" declares unsupported lifecycle method "${lifecycleMethod}"`)
20
+ }
15
21
  }
16
22
  })
17
23
  }