@exodus/headless 2.0.0-alpha.14 → 2.0.0-alpha.140
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 +979 -0
- package/README.md +16 -4
- package/package.json +61 -31
- package/src/api.js +5 -75
- package/src/application.js +59 -28
- package/src/atoms/base-asset-names-to-monitor.js +40 -0
- package/src/constants.js +18 -8
- package/src/dependencies/atoms.js +2 -108
- package/src/dependencies/index.js +2 -9
- package/src/dependencies/modules.js +4 -43
- package/src/dependencies/utils.js +0 -4
- package/src/index.js +89 -80
- package/src/ioc.js +54 -10
- package/src/migrations/attach.js +62 -0
- package/src/plugins/attach.js +28 -7
- package/src/plugins/index.js +3 -1
- package/src/plugins/log-lifecycle.js +1 -0
- package/src/reporting.js +36 -0
- package/src/unlock-encrypted-storage.js +2 -0
- package/src/utils/fusion.js +17 -0
- package/src/utils/promises.js +7 -0
- package/src/atoms/attach.js +0 -40
- package/src/dependencies/monitors.js +0 -33
- package/src/utils/blockchain-metadata.js +0 -48
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@ The headless Exodus wallet SDK
|
|
|
15
15
|
|
|
16
16
|
```js
|
|
17
17
|
import createExodus from '@exodus/headless'
|
|
18
|
+
import referrals from '@exodus/headless/src/modules/referrals'
|
|
18
19
|
import Emitter from '@exodus/wild-emitter'
|
|
19
20
|
|
|
20
21
|
// 1. Create port. Acts as an event bus between headless wallet and client
|
|
@@ -25,10 +26,10 @@ const adapters = {}
|
|
|
25
26
|
const config = {}
|
|
26
27
|
|
|
27
28
|
// 3. Create Exodus container
|
|
28
|
-
const
|
|
29
|
+
const exodusContainer = createExodus({ port, adapters, config })
|
|
29
30
|
|
|
30
31
|
// 4. Register external modules. Does not support overriding modules at the moment.
|
|
31
|
-
|
|
32
|
+
exodusContainer.register({
|
|
32
33
|
definition: {
|
|
33
34
|
id: 'remoteConfig',
|
|
34
35
|
factory: createRemoteConfig,
|
|
@@ -36,11 +37,22 @@ container.register({
|
|
|
36
37
|
},
|
|
37
38
|
})
|
|
38
39
|
|
|
40
|
+
// see an example feature definition:
|
|
41
|
+
// https://github.com/ExodusMovement/exodus-hydra/blob/2e8d63426421ffcbec84a9b6fbc83eb913b47eba/modules/headless/src/modules/geolocation/index.js
|
|
42
|
+
exodusContainer.use(referrals())
|
|
43
|
+
exodusContainer.use(myCustomFeature({ id: 'myCustomFeature', ... }))
|
|
44
|
+
|
|
39
45
|
// 5. Resolve exodus instance
|
|
40
|
-
const exodus =
|
|
46
|
+
const exodus = exodusContainer.resolve()
|
|
47
|
+
|
|
48
|
+
// 6. Start exodus instance
|
|
49
|
+
await exodus.wallet.start()
|
|
41
50
|
|
|
42
|
-
//
|
|
51
|
+
// 7. Use it!
|
|
43
52
|
await exodus.wallet.create({ passphrase: 'my-super-secure-passphrase' })
|
|
53
|
+
|
|
54
|
+
// 8. Use your custom feature API, if any
|
|
55
|
+
exodus.myCustomFeature.doThatThingYouDo()
|
|
44
56
|
```
|
|
45
57
|
|
|
46
58
|
## Lifecycle
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/headless",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
4
|
-
"description": "The
|
|
5
|
-
"author": "Exodus Movement Inc",
|
|
3
|
+
"version": "2.0.0-alpha.140",
|
|
4
|
+
"description": "The platform-agnostic Exodus wallet SDK",
|
|
5
|
+
"author": "Exodus Movement Inc.",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "git+https://github.com/ExodusMovement/exodus-hydra.git"
|
|
10
10
|
},
|
|
11
|
-
"homepage": "https://github.com/ExodusMovement/exodus-hydra/tree/master/
|
|
11
|
+
"homepage": "https://github.com/ExodusMovement/exodus-hydra/tree/master/sdks/headless",
|
|
12
12
|
"license": "UNLICENSED",
|
|
13
13
|
"bugs": {
|
|
14
14
|
"url": "https://github.com/ExodusMovement/exodus-hydra/issues?q=is%3Aissue+is%3Aopen+label%3Aheadless"
|
|
@@ -17,56 +17,86 @@
|
|
|
17
17
|
"src",
|
|
18
18
|
"README.md",
|
|
19
19
|
"CHANGELOG.md",
|
|
20
|
-
"!**/__tests__",
|
|
20
|
+
"!**/__tests__/**",
|
|
21
21
|
"!**/*.test.js"
|
|
22
22
|
],
|
|
23
23
|
"scripts": {
|
|
24
24
|
"lint": "eslint . --ignore-path ../../.gitignore",
|
|
25
25
|
"lint:fix": "yarn lint --fix",
|
|
26
|
-
"test": "jest"
|
|
26
|
+
"test": "NODE_OPTIONS=--max-old-space-size=4096 jest"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@exodus/
|
|
30
|
-
"@exodus/
|
|
31
|
-
"@exodus/
|
|
29
|
+
"@exodus/address-provider": "^8.0.0",
|
|
30
|
+
"@exodus/assets-feature": "^3.7.0",
|
|
31
|
+
"@exodus/atoms": "^6.0.0",
|
|
32
|
+
"@exodus/auto-enable-assets-plugin": "^4.3.0",
|
|
33
|
+
"@exodus/available-assets": "^7.0.0",
|
|
34
|
+
"@exodus/balances": "^11.1.0",
|
|
32
35
|
"@exodus/basic-utils": "^2.0.0",
|
|
33
|
-
"@exodus/blockchain-metadata": "^
|
|
34
|
-
"@exodus/
|
|
35
|
-
"@exodus/dependency-
|
|
36
|
-
"@exodus/
|
|
37
|
-
"@exodus/
|
|
38
|
-
"@exodus/
|
|
36
|
+
"@exodus/blockchain-metadata": "^14.2.0",
|
|
37
|
+
"@exodus/dependency-injection": "^2.0.1",
|
|
38
|
+
"@exodus/dependency-preprocessors": "^3.1.1",
|
|
39
|
+
"@exodus/enabled-assets": "^9.0.1",
|
|
40
|
+
"@exodus/feature-flags": "^4.2.0",
|
|
41
|
+
"@exodus/fee-data-monitors": "^3.0.0",
|
|
39
42
|
"@exodus/fetch": "^1.2.1",
|
|
40
|
-
"@exodus/
|
|
41
|
-
"@exodus/
|
|
42
|
-
"@exodus/
|
|
43
|
-
"@exodus/
|
|
44
|
-
"@exodus/
|
|
45
|
-
"@exodus/
|
|
46
|
-
"@exodus/
|
|
47
|
-
"@exodus/
|
|
48
|
-
"
|
|
43
|
+
"@exodus/geolocation": "^3.0.0",
|
|
44
|
+
"@exodus/hd-key-slip-10": "^2.0.0",
|
|
45
|
+
"@exodus/key-identifier-provider": "^1.3.1",
|
|
46
|
+
"@exodus/keychain": "^4.3.0",
|
|
47
|
+
"@exodus/locale": "^2.0.2",
|
|
48
|
+
"@exodus/module": "^1.2.0",
|
|
49
|
+
"@exodus/pricing": "^1.1.0",
|
|
50
|
+
"@exodus/rates-monitor": "^4.0.2",
|
|
51
|
+
"@exodus/remote-config": "^2.3.0",
|
|
52
|
+
"@exodus/restore-progress-tracker": "^3.0.0",
|
|
53
|
+
"@exodus/sodium-crypto": "^3.2.0",
|
|
54
|
+
"@exodus/tx-signer": "^1.1.0",
|
|
55
|
+
"@exodus/wallet": "^10.0.2",
|
|
56
|
+
"@exodus/wallet-accounts": "^14.2.0",
|
|
57
|
+
"@exodus/wallet-compatibility-modes": "^3.1.2",
|
|
58
|
+
"bip39": "^2.6.0",
|
|
49
59
|
"events": "^3.3.0",
|
|
50
|
-
"lodash": "
|
|
60
|
+
"lodash": "npm:@exodus/lodash@^4.17.21-exodus.2",
|
|
51
61
|
"minimalistic-assert": "^1.0.1"
|
|
52
62
|
},
|
|
53
63
|
"devDependencies": {
|
|
54
|
-
"@exodus/
|
|
64
|
+
"@exodus/ab-testing": "^7.0.1",
|
|
65
|
+
"@exodus/algorand-lib": "^2.0.1",
|
|
66
|
+
"@exodus/algorand-meta": "^1.1.4",
|
|
67
|
+
"@exodus/apy-rates": "^3.3.1",
|
|
68
|
+
"@exodus/assets-feature": "workspace:^",
|
|
69
|
+
"@exodus/bitcoin-plugin": "^1.0.14",
|
|
70
|
+
"@exodus/connected-origins": "^3.3.0",
|
|
71
|
+
"@exodus/crypto-news-monitor": "^4.1.0",
|
|
55
72
|
"@exodus/currency": "^2.2.0",
|
|
56
|
-
"@exodus/ethereum-lib": "^
|
|
73
|
+
"@exodus/ethereum-lib": "^3.3.34",
|
|
57
74
|
"@exodus/ethereum-meta": "^1.0.23",
|
|
58
|
-
"@exodus/
|
|
75
|
+
"@exodus/exodus-pricing-client": "^1.2.0",
|
|
76
|
+
"@exodus/key-utils": "^3.0.0",
|
|
77
|
+
"@exodus/kyc": "^4.2.0",
|
|
78
|
+
"@exodus/litecoin-meta": "^1.0.0",
|
|
79
|
+
"@exodus/market-history": "^7.1.0",
|
|
80
|
+
"@exodus/models": "^10.1.0",
|
|
81
|
+
"@exodus/nfts": "^6.4.1",
|
|
82
|
+
"@exodus/personal-notes": "^3.6.0",
|
|
83
|
+
"@exodus/referrals": "^8.0.1",
|
|
59
84
|
"@exodus/solana-lib": "^1.3.11",
|
|
60
85
|
"@exodus/solana-meta": "^1.0.2",
|
|
61
86
|
"@exodus/storage-encrypted": "^1.1.2",
|
|
62
|
-
"@exodus/storage-memory": "^1.1
|
|
87
|
+
"@exodus/storage-memory": "^2.1.1",
|
|
88
|
+
"@exodus/top-movers-monitor": "^3.2.0",
|
|
89
|
+
"@exodus/ui-config": "^3.2.0",
|
|
63
90
|
"@exodus/wild-emitter": "^1.0.0",
|
|
64
91
|
"buffer-json": "^2.0.0",
|
|
65
92
|
"deepmerge": "^4.2.2",
|
|
66
|
-
"
|
|
93
|
+
"delay": "^5.0.0",
|
|
94
|
+
"eslint": "^8.44.0",
|
|
95
|
+
"eslint-plugin-simple-import-sort": "^7.0.0",
|
|
67
96
|
"events": "^3.3.0",
|
|
68
97
|
"jest": "^29.1.2",
|
|
98
|
+
"msw": "^1.3.0",
|
|
69
99
|
"p-defer": "^4.0.0"
|
|
70
100
|
},
|
|
71
|
-
"gitHead": "
|
|
101
|
+
"gitHead": "1f654f0ebc89d0666b6342b162d94b960b0302a7"
|
|
72
102
|
}
|
package/src/api.js
CHANGED
|
@@ -1,83 +1,13 @@
|
|
|
1
1
|
import { validateMnemonic as isMnemonicValid } from 'bip39'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
const { passphraseCache } = ioc.getByType('adapter')
|
|
3
|
+
import createReporting from './reporting'
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const { ratesMonitor } = ioc.getByType('monitor')
|
|
10
|
-
const { assetsModule } = ioc.getByType('adapter')
|
|
11
|
-
|
|
12
|
-
const {
|
|
13
|
-
// ...
|
|
14
|
-
currencyAtom,
|
|
15
|
-
enabledWalletAccountsAtom,
|
|
16
|
-
languageAtom,
|
|
17
|
-
} = ioc.getByType('atom')
|
|
5
|
+
const createApi = ({ ioc, port, lockedAtom, config }) => {
|
|
6
|
+
const apis = ioc.getByType('api')
|
|
18
7
|
|
|
19
8
|
return {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
load: application.load,
|
|
23
|
-
unload: application.unload,
|
|
24
|
-
create: application.create,
|
|
25
|
-
lock: application.lock,
|
|
26
|
-
unlock: application.unlock,
|
|
27
|
-
import: application.import,
|
|
28
|
-
delete: application.delete,
|
|
29
|
-
getMnemonic: application.getMnemonic,
|
|
30
|
-
setBackedUp: application.setBackedUp,
|
|
31
|
-
changePassphrase: application.changePassphrase,
|
|
32
|
-
restoreFromCurrentPhrase: async ({ passphrase } = {}) => {
|
|
33
|
-
if (!passphrase) passphrase = await passphraseCache.get()
|
|
34
|
-
const mnemonic = await application.getMnemonic({ passphrase })
|
|
35
|
-
|
|
36
|
-
await application.import({ passphrase, mnemonic })
|
|
37
|
-
},
|
|
38
|
-
changeLockTimer: application.changeLockTimer,
|
|
39
|
-
isLocked: () => wallet.isLocked(),
|
|
40
|
-
},
|
|
41
|
-
walletAccounts: {
|
|
42
|
-
create: walletAccounts.create,
|
|
43
|
-
update: walletAccounts.update,
|
|
44
|
-
disable: walletAccounts.disable,
|
|
45
|
-
enable: walletAccounts.enable,
|
|
46
|
-
getEnabled: enabledWalletAccountsAtom.get,
|
|
47
|
-
},
|
|
48
|
-
blockchainMetadata: {
|
|
49
|
-
getTxLog: blockchainMetadata.getTxLog,
|
|
50
|
-
getLoadedTxLogs: blockchainMetadata.getLoadedTxLogs,
|
|
51
|
-
updateTxs: blockchainMetadata.updateTxs,
|
|
52
|
-
overwriteTxs: blockchainMetadata.overwriteTxs,
|
|
53
|
-
clearTxs: blockchainMetadata.clearTxs,
|
|
54
|
-
removeTxs: blockchainMetadata.removeTxs,
|
|
55
|
-
getAccountState: blockchainMetadata.getAccountState,
|
|
56
|
-
getLoadedAccountStates: blockchainMetadata.getLoadedAccountStates,
|
|
57
|
-
updateAccountState: blockchainMetadata.updateAccountState,
|
|
58
|
-
removeAccountState: blockchainMetadata.removeAccountState,
|
|
59
|
-
batch: blockchainMetadata.batch,
|
|
60
|
-
},
|
|
61
|
-
assets: {
|
|
62
|
-
enable: enabledAssets.enable,
|
|
63
|
-
disable: enabledAssets.disable,
|
|
64
|
-
addAndEnableToken: async (...args) => {
|
|
65
|
-
const asset = await assetsModule.addToken(...args)
|
|
66
|
-
await enabledAssets.enable([asset.name])
|
|
67
|
-
return asset.name
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
remoteConfig: {
|
|
71
|
-
get: remoteConfig.get,
|
|
72
|
-
getAll: remoteConfig.getAll,
|
|
73
|
-
},
|
|
74
|
-
locale: {
|
|
75
|
-
setLanguage: (value) => languageAtom.set(value),
|
|
76
|
-
setCurrency: (value) => currencyAtom.set(value),
|
|
77
|
-
},
|
|
78
|
-
rates: {
|
|
79
|
-
refresh: () => ratesMonitor.update(),
|
|
80
|
-
},
|
|
9
|
+
...Object.assign({}, ...Object.values(apis)),
|
|
10
|
+
...createReporting({ ioc, lockedAtom, config }),
|
|
81
11
|
isMnemonicValid,
|
|
82
12
|
subscribe: port.subscribe.bind(port),
|
|
83
13
|
unsubscribe: port.unsubscribe.bind(port),
|
package/src/application.js
CHANGED
|
@@ -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 {
|
|
@@ -71,12 +56,26 @@ class Application extends ExodusModule {
|
|
|
71
56
|
const walletExists = await this.#wallet.exists()
|
|
72
57
|
|
|
73
58
|
if (isImporting || !walletExists) {
|
|
74
|
-
await this.fire(Hook.Clear)
|
|
59
|
+
await this.fire(Hook.Clear, null, { concurrent: true })
|
|
75
60
|
}
|
|
76
61
|
|
|
77
62
|
if (isImporting) await this.fire(Hook.Import)
|
|
78
63
|
|
|
79
|
-
await
|
|
64
|
+
const [hasPassphraseSet, isLocked, isBackedUp, isRestoring] = await Promise.all([
|
|
65
|
+
this.#wallet.hasPassphraseSet(),
|
|
66
|
+
this.#wallet.isLocked(),
|
|
67
|
+
this.#wallet.isBackedUp(),
|
|
68
|
+
this.isRestoring(),
|
|
69
|
+
])
|
|
70
|
+
|
|
71
|
+
await this.fire(Hook.Start, {
|
|
72
|
+
walletExists,
|
|
73
|
+
hasPassphraseSet,
|
|
74
|
+
isLocked,
|
|
75
|
+
isBackedUp,
|
|
76
|
+
isRestoring,
|
|
77
|
+
})
|
|
78
|
+
|
|
80
79
|
await this.#autoUnlock()
|
|
81
80
|
|
|
82
81
|
const locked = await this.#wallet.isLocked()
|
|
@@ -120,14 +119,28 @@ class Application extends ExodusModule {
|
|
|
120
119
|
this.#hooks[hookName].push(listener)
|
|
121
120
|
}
|
|
122
121
|
|
|
123
|
-
fire = async (hookName, params) => {
|
|
122
|
+
fire = async (hookName, params, { concurrent } = {}) => {
|
|
124
123
|
assert(HOOKS.has(hookName), `no such hook: ${hookName}`)
|
|
125
|
-
|
|
124
|
+
|
|
125
|
+
this._logger.debug(`firing hooks ${concurrent ? 'concurrently' : 'sequentially'}`, hookName)
|
|
126
126
|
|
|
127
127
|
const hooks = this.#hooks[hookName] || []
|
|
128
128
|
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
const hookFns = hooks.map((hook) => async () => {
|
|
130
|
+
try {
|
|
131
|
+
await hook(params)
|
|
132
|
+
} catch (err) {
|
|
133
|
+
this._logger.error(`application lifecycle hook failed: ${hookName}`, hook.name, params, err)
|
|
134
|
+
throw err
|
|
135
|
+
}
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
if (concurrent) {
|
|
139
|
+
await Promise.allSettled(hookFns.map((promise) => promise()))
|
|
140
|
+
} else {
|
|
141
|
+
for (let i = 0; i < hookFns.length; i++) {
|
|
142
|
+
await hookFns[i]()
|
|
143
|
+
}
|
|
131
144
|
}
|
|
132
145
|
|
|
133
146
|
this.emit(hookName, params)
|
|
@@ -139,7 +152,15 @@ class Application extends ExodusModule {
|
|
|
139
152
|
await this.#applicationStarted
|
|
140
153
|
await this.#wallet.create(opts)
|
|
141
154
|
|
|
142
|
-
await this.
|
|
155
|
+
const isLocked = await this.#wallet.isLocked()
|
|
156
|
+
|
|
157
|
+
await this.fire(Hook.Create, {
|
|
158
|
+
hasPassphraseSet: !!opts?.passphrase,
|
|
159
|
+
isBackedUp: false,
|
|
160
|
+
isLocked,
|
|
161
|
+
isRestoring: false,
|
|
162
|
+
walletExists: true,
|
|
163
|
+
})
|
|
143
164
|
}
|
|
144
165
|
|
|
145
166
|
import = async (opts) => {
|
|
@@ -151,14 +172,14 @@ class Application extends ExodusModule {
|
|
|
151
172
|
|
|
152
173
|
const walletExists = await this.#wallet.exists()
|
|
153
174
|
|
|
154
|
-
const { forceRestart, ...wallet } = opts
|
|
175
|
+
const { forceRestart, forgotPassphrase, ...wallet } = opts
|
|
155
176
|
|
|
156
177
|
await this.#wallet.import(wallet)
|
|
157
178
|
|
|
158
179
|
if (forceRestart || walletExists) {
|
|
159
180
|
await this.#storage.set(IMPORT_FLAG, true)
|
|
160
181
|
|
|
161
|
-
this.
|
|
182
|
+
await this.fire(Hook.Restart, { reason: 'import' })
|
|
162
183
|
} else {
|
|
163
184
|
await this.fire(Hook.Import)
|
|
164
185
|
|
|
@@ -207,6 +228,8 @@ class Application extends ExodusModule {
|
|
|
207
228
|
this._logger.log('unlocking with cache')
|
|
208
229
|
|
|
209
230
|
await this.#wallet.unlock({ passphrase })
|
|
231
|
+
|
|
232
|
+
await this.fire(Hook.Migrate)
|
|
210
233
|
await this.fire(Hook.Unlock)
|
|
211
234
|
|
|
212
235
|
this.#restoreIfNeeded()
|
|
@@ -244,15 +267,23 @@ class Application extends ExodusModule {
|
|
|
244
267
|
this._logger.log('passphrase changed')
|
|
245
268
|
}
|
|
246
269
|
|
|
247
|
-
delete = async () => {
|
|
270
|
+
delete = async ({ forgotPassphrase } = {}) => {
|
|
248
271
|
await this.#storage.set(DELETE_FLAG, true)
|
|
249
|
-
this.
|
|
272
|
+
await this.fire(Hook.Restart, { reason: 'delete', forgotPassphrase })
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
stop = async () => {
|
|
276
|
+
await this.fire(Hook.Stop)
|
|
250
277
|
}
|
|
251
278
|
|
|
252
279
|
changeLockTimer = async ({ ttl }) => {
|
|
253
280
|
await this.#passphraseCache.changeTtl(ttl)
|
|
254
281
|
}
|
|
255
282
|
|
|
283
|
+
restartAutoLockTimer = async () => {
|
|
284
|
+
await this.#passphraseCache.scheduleClear()
|
|
285
|
+
}
|
|
286
|
+
|
|
256
287
|
isRestoring = async () => {
|
|
257
288
|
return this.#storage.get(RESTORE_FLAG)
|
|
258
289
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { combine, compute, dedupe } from '@exodus/atoms'
|
|
2
|
+
import { uniq } from 'lodash'
|
|
3
|
+
|
|
4
|
+
const getNetworks = (assetNames, assets) =>
|
|
5
|
+
uniq(
|
|
6
|
+
assetNames
|
|
7
|
+
.map((assetName) => assets[assetName]?.baseAsset.name)
|
|
8
|
+
.filter((assetName) => !!assetName && !assets[assetName].isCombined)
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
const createBaseAssetNamesToMonitorAtom = ({
|
|
12
|
+
assetsModule,
|
|
13
|
+
enabledAssetsAtom,
|
|
14
|
+
restoreAtom,
|
|
15
|
+
availableAssetNamesAtom,
|
|
16
|
+
}) => {
|
|
17
|
+
const selector = ({ isRestore, enabledAssets, availableAssetNames }) => {
|
|
18
|
+
const assetNames = isRestore ? availableAssetNames : Object.keys(enabledAssets)
|
|
19
|
+
return getNetworks(assetNames, assetsModule.getAssets())
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return dedupe(
|
|
23
|
+
compute({
|
|
24
|
+
atom: combine({
|
|
25
|
+
isRestore: restoreAtom,
|
|
26
|
+
enabledAssets: enabledAssetsAtom,
|
|
27
|
+
availableAssetNames: availableAssetNamesAtom,
|
|
28
|
+
}),
|
|
29
|
+
selector,
|
|
30
|
+
})
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// eslint-disable-next-line @exodus/export-default/named
|
|
35
|
+
export default {
|
|
36
|
+
id: 'baseAssetNamesToMonitorAtom',
|
|
37
|
+
type: 'atom',
|
|
38
|
+
factory: createBaseAssetNamesToMonitorAtom,
|
|
39
|
+
dependencies: ['assetsModule', 'availableAssetNamesAtom', 'enabledAssetsAtom', 'restoreAtom'],
|
|
40
|
+
}
|
package/src/constants.js
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
|
-
export const
|
|
2
|
-
'
|
|
3
|
-
'
|
|
4
|
-
'
|
|
5
|
-
'
|
|
6
|
-
'
|
|
7
|
-
'
|
|
8
|
-
|
|
1
|
+
export const LifecycleHook = Object.freeze({
|
|
2
|
+
Lock: 'lock',
|
|
3
|
+
Unlock: 'unlock',
|
|
4
|
+
Clear: 'clear',
|
|
5
|
+
Import: 'import',
|
|
6
|
+
Migrate: 'migrate',
|
|
7
|
+
Start: 'start',
|
|
8
|
+
Stop: 'stop',
|
|
9
|
+
Restart: 'restart',
|
|
10
|
+
Load: 'load',
|
|
11
|
+
Unload: 'unload',
|
|
12
|
+
Create: 'create',
|
|
13
|
+
Backup: 'backup',
|
|
14
|
+
Restore: 'restore',
|
|
15
|
+
RestoreCompleted: 'restore-completed',
|
|
16
|
+
AssetsSynced: 'assets-synced',
|
|
17
|
+
ChangePassphrase: 'change-passphrase',
|
|
18
|
+
})
|
|
@@ -1,111 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
createInMemoryAtom,
|
|
3
|
-
createRemoteConfigAtomFactory,
|
|
4
|
-
createStorageAtomFactory,
|
|
5
|
-
createFusionAtomFactory,
|
|
6
|
-
} from '@exodus/atoms'
|
|
7
|
-
import {
|
|
8
|
-
walletAccountsAtomDefinition,
|
|
9
|
-
enabledWalletAccountsAtomDefinition,
|
|
10
|
-
} from '@exodus/wallet-accounts/atoms'
|
|
1
|
+
import baseAssetNamesToMonitorAtomDefinition from '../atoms/base-asset-names-to-monitor'
|
|
11
2
|
|
|
12
|
-
|
|
13
|
-
enabledAndDisabledAssetsAtomDefinition,
|
|
14
|
-
enabledAssetsAtomDefinition,
|
|
15
|
-
} from '@exodus/enabled-assets/atoms'
|
|
16
|
-
|
|
17
|
-
import { availableAssetNamesAtomDefinition } from '@exodus/available-assets/atoms'
|
|
18
|
-
import { ratesAtomDefinition } from '@exodus/rates-monitor/atoms'
|
|
19
|
-
|
|
20
|
-
import { withType } from './utils'
|
|
21
|
-
import { balancesAtomDefinition } from '@exodus/balances/atoms'
|
|
22
|
-
|
|
23
|
-
const createAtomDependencies = () =>
|
|
24
|
-
[
|
|
25
|
-
{
|
|
26
|
-
definition: {
|
|
27
|
-
id: 'lockedAtom',
|
|
28
|
-
factory: () => createInMemoryAtom({ defaultValue: true }),
|
|
29
|
-
dependencies: [],
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
definition: walletAccountsAtomDefinition,
|
|
34
|
-
storage: { namespace: 'walletAccounts' },
|
|
35
|
-
},
|
|
36
|
-
{ definition: enabledWalletAccountsAtomDefinition },
|
|
37
|
-
{ definition: enabledAndDisabledAssetsAtomDefinition },
|
|
38
|
-
{ definition: enabledAssetsAtomDefinition },
|
|
39
|
-
{ definition: availableAssetNamesAtomDefinition },
|
|
40
|
-
{
|
|
41
|
-
definition: {
|
|
42
|
-
id: 'pricingServerUrlAtom',
|
|
43
|
-
factory: ({ config, remoteConfig }) =>
|
|
44
|
-
createRemoteConfigAtomFactory({ remoteConfig })({
|
|
45
|
-
path: config.pricingServerPath,
|
|
46
|
-
defaultValue: config.defaultPricingServerUrl,
|
|
47
|
-
}),
|
|
48
|
-
dependencies: ['config', 'remoteConfig'],
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
definition: {
|
|
53
|
-
id: 'languageAtom',
|
|
54
|
-
factory: ({ storage, config }) =>
|
|
55
|
-
createStorageAtomFactory({ storage })({
|
|
56
|
-
key: 'language',
|
|
57
|
-
defaultValue: config.defaultValue,
|
|
58
|
-
isSoleWriter: true,
|
|
59
|
-
}),
|
|
60
|
-
dependencies: ['storage', 'config'],
|
|
61
|
-
},
|
|
62
|
-
aliases: [
|
|
63
|
-
{
|
|
64
|
-
implementationId: 'unsafeStorage',
|
|
65
|
-
interfaceId: 'storage',
|
|
66
|
-
},
|
|
67
|
-
],
|
|
68
|
-
storage: { namespace: 'locale' },
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
definition: {
|
|
72
|
-
id: 'currencyAtom',
|
|
73
|
-
factory: ({ fusion, config }) =>
|
|
74
|
-
createFusionAtomFactory({ fusion })({
|
|
75
|
-
path: `private.currency`,
|
|
76
|
-
defaultValue: config.defaultValue,
|
|
77
|
-
}),
|
|
78
|
-
dependencies: ['fusion', 'config'],
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
// TODO: move to @exodus/market-history
|
|
82
|
-
{
|
|
83
|
-
definition: {
|
|
84
|
-
id: 'marketHistoryClearCacheAtom',
|
|
85
|
-
factory: ({ config }) => createInMemoryAtom(config),
|
|
86
|
-
dependencies: ['config'],
|
|
87
|
-
},
|
|
88
|
-
},
|
|
89
|
-
// TODO: move to @exodus/market-history
|
|
90
|
-
{
|
|
91
|
-
definition: {
|
|
92
|
-
id: 'remoteConfigClearMarketHistoryCacheAtom',
|
|
93
|
-
factory: ({ config, remoteConfig }) =>
|
|
94
|
-
createRemoteConfigAtomFactory({ remoteConfig })(config),
|
|
95
|
-
dependencies: ['config', 'remoteConfig'],
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
// TODO: move to @exodus/market-history
|
|
99
|
-
{
|
|
100
|
-
definition: {
|
|
101
|
-
id: 'marketHistoryRefreshIntervalAtom',
|
|
102
|
-
factory: ({ config, remoteConfig }) =>
|
|
103
|
-
createRemoteConfigAtomFactory({ remoteConfig })(config),
|
|
104
|
-
dependencies: ['config', 'remoteConfig'],
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
{ definition: balancesAtomDefinition },
|
|
108
|
-
{ definition: ratesAtomDefinition },
|
|
109
|
-
].map(withType('atom'))
|
|
3
|
+
const createAtomDependencies = () => [{ definition: baseAssetNamesToMonitorAtomDefinition }]
|
|
110
4
|
|
|
111
5
|
export default createAtomDependencies
|
|
@@ -3,22 +3,18 @@
|
|
|
3
3
|
|
|
4
4
|
import assert from 'minimalistic-assert'
|
|
5
5
|
|
|
6
|
-
import createConfigDependencies from './configs'
|
|
7
6
|
import createAdapterDependencies from './adapters'
|
|
8
7
|
import createAtomDependencies from './atoms'
|
|
8
|
+
import createConfigDependencies from './configs'
|
|
9
9
|
import createModuleDependencies from './modules'
|
|
10
|
-
import createMonitorDependencies from './monitors'
|
|
11
|
-
import { wrapConstant } from './utils'
|
|
12
10
|
import createPluginDependencies from './plugins'
|
|
11
|
+
import { wrapConstant } from './utils'
|
|
13
12
|
|
|
14
13
|
const adapterKeys = [
|
|
15
|
-
// ...
|
|
16
|
-
'assetsModule',
|
|
17
14
|
'createLogger',
|
|
18
15
|
'legacyPrivToPub',
|
|
19
16
|
'seedStorage',
|
|
20
17
|
'unsafeStorage',
|
|
21
|
-
'fusion',
|
|
22
18
|
'fetch',
|
|
23
19
|
'freeze',
|
|
24
20
|
]
|
|
@@ -34,8 +30,6 @@ const createDependencies = ({ adapters, config }) => {
|
|
|
34
30
|
|
|
35
31
|
const modules = createModuleDependencies({ adapters, config })
|
|
36
32
|
|
|
37
|
-
const monitors = createMonitorDependencies({ adapters, config })
|
|
38
|
-
|
|
39
33
|
const atoms = createAtomDependencies({ adapters, config })
|
|
40
34
|
|
|
41
35
|
const adaptersTree = createAdapterDependencies({ adapters, config })
|
|
@@ -46,7 +40,6 @@ const createDependencies = ({ adapters, config }) => {
|
|
|
46
40
|
.concat(adaptersTree)
|
|
47
41
|
.concat(configs)
|
|
48
42
|
.concat(modules)
|
|
49
|
-
.concat(monitors)
|
|
50
43
|
.concat(atoms)
|
|
51
44
|
.concat(plugins)
|
|
52
45
|
.concat(wrapConstant({ id: 'logger', type: 'module', value: logger }))
|