@exodus/headless 2.0.0-alpha.149 → 2.0.0-alpha.15
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 +0 -1019
- package/README.md +11 -34
- package/package.json +32 -63
- package/src/api.js +86 -0
- package/src/application.js +30 -75
- package/src/atoms/attach.js +40 -0
- package/src/constants.js +9 -18
- package/src/dependencies/atoms.js +117 -2
- package/src/dependencies/index.js +9 -2
- package/src/dependencies/modules.js +45 -5
- package/src/dependencies/monitors.js +33 -0
- package/src/dependencies/utils.js +4 -0
- package/src/index.js +80 -91
- package/src/ioc.js +11 -49
- package/src/plugins/attach.js +7 -28
- package/src/plugins/index.js +1 -3
- package/src/plugins/log-lifecycle.js +0 -1
- package/src/unlock-encrypted-storage.js +0 -2
- package/src/utils/blockchain-metadata.js +48 -0
- package/src/api/debug.js +0 -13
- package/src/api/index.js +0 -19
- package/src/api/reporting.js +0 -39
- package/src/atoms/base-asset-names-to-monitor.js +0 -40
- package/src/migrations/attach.js +0 -62
- package/src/utils/fusion.js +0 -17
- package/src/utils/promises.js +0 -7
package/README.md
CHANGED
|
@@ -15,7 +15,6 @@ 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'
|
|
19
18
|
import Emitter from '@exodus/wild-emitter'
|
|
20
19
|
|
|
21
20
|
// 1. Create port. Acts as an event bus between headless wallet and client
|
|
@@ -26,10 +25,10 @@ const adapters = {}
|
|
|
26
25
|
const config = {}
|
|
27
26
|
|
|
28
27
|
// 3. Create Exodus container
|
|
29
|
-
const
|
|
28
|
+
const container = createExodus({ port, adapters, config })
|
|
30
29
|
|
|
31
30
|
// 4. Register external modules. Does not support overriding modules at the moment.
|
|
32
|
-
|
|
31
|
+
container.register({
|
|
33
32
|
definition: {
|
|
34
33
|
id: 'remoteConfig',
|
|
35
34
|
factory: createRemoteConfig,
|
|
@@ -37,22 +36,11 @@ exodusContainer.register({
|
|
|
37
36
|
},
|
|
38
37
|
})
|
|
39
38
|
|
|
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
|
-
|
|
45
39
|
// 5. Resolve exodus instance
|
|
46
|
-
const exodus =
|
|
47
|
-
|
|
48
|
-
// 6. Start exodus instance
|
|
49
|
-
await exodus.wallet.start()
|
|
40
|
+
const exodus = container.resolve()
|
|
50
41
|
|
|
51
|
-
//
|
|
42
|
+
// 6. Use it!
|
|
52
43
|
await exodus.wallet.create({ passphrase: 'my-super-secure-passphrase' })
|
|
53
|
-
|
|
54
|
-
// 8. Use your custom feature API, if any
|
|
55
|
-
exodus.myCustomFeature.doThatThingYouDo()
|
|
56
44
|
```
|
|
57
45
|
|
|
58
46
|
## Lifecycle
|
|
@@ -197,7 +185,7 @@ Currently not used.
|
|
|
197
185
|
|
|
198
186
|
## Headless API
|
|
199
187
|
|
|
200
|
-
|
|
188
|
+
## wallet
|
|
201
189
|
|
|
202
190
|
> Type: object
|
|
203
191
|
|
|
@@ -217,7 +205,7 @@ Currently not used.
|
|
|
217
205
|
| unload | `async () => void` | Unloads UI by rehydratating data through port (`BE Only`) |
|
|
218
206
|
| changeLockTimer | `async ({ ttl: number }) => void` | Change auto unlock ttl (`BE Only`) |
|
|
219
207
|
|
|
220
|
-
|
|
208
|
+
## isMnemonicValid
|
|
221
209
|
|
|
222
210
|
> Type: function
|
|
223
211
|
|
|
@@ -228,7 +216,7 @@ Currently not used.
|
|
|
228
216
|
|
|
229
217
|
**Returns**: `boolean`
|
|
230
218
|
|
|
231
|
-
|
|
219
|
+
## walletAccounts
|
|
232
220
|
|
|
233
221
|
> Type: object
|
|
234
222
|
|
|
@@ -240,7 +228,7 @@ Currently not used.
|
|
|
240
228
|
| disable | `async (name) => void` | Disables an existing WalletAccount. |
|
|
241
229
|
| getEnabled | `async () => object` | Returns enabled walletAccounts as `{ [name]: WalletAccount }`. |
|
|
242
230
|
|
|
243
|
-
|
|
231
|
+
## blockchainMetadata
|
|
244
232
|
|
|
245
233
|
> Type: object
|
|
246
234
|
|
|
@@ -258,7 +246,7 @@ Currently not used.
|
|
|
258
246
|
| removeAccountState | `async ({ assetName: string, walletAccount: string }) => void` | Remove accountState for AssetSource. |
|
|
259
247
|
| batch | `() => Batch` | Create a batch of updates. See [blockchainMetadata](../blockchain-metadata) README for batching details. |
|
|
260
248
|
|
|
261
|
-
|
|
249
|
+
## assets
|
|
262
250
|
|
|
263
251
|
> Type: object
|
|
264
252
|
|
|
@@ -268,7 +256,7 @@ Currently not used.
|
|
|
268
256
|
| disable | `async (assetNames: string[]) => void` | Disables assets. |
|
|
269
257
|
| addAndEnableToken | `async (assetId: string, baseAssetName: string) => string` | Adds and enables a custom token. Returns the created `asset`'s `.name` |
|
|
270
258
|
|
|
271
|
-
|
|
259
|
+
## locale
|
|
272
260
|
|
|
273
261
|
> Type: object
|
|
274
262
|
|
|
@@ -277,7 +265,7 @@ Currently not used.
|
|
|
277
265
|
| setCurrency | `async (currency: string) => void` | Changes current currency. |
|
|
278
266
|
| setLanguage | `async (language: string) => void` | Changes current language. |
|
|
279
267
|
|
|
280
|
-
|
|
268
|
+
## subscribe
|
|
281
269
|
|
|
282
270
|
> Type: function
|
|
283
271
|
|
|
@@ -285,14 +273,3 @@ Currently not used.
|
|
|
285
273
|
| ----------- | ------------------------------------------ | ------------------------------------------ |
|
|
286
274
|
| subscribe | `({ type: string, payload: any }) => void` | Subscribe to receive events. |
|
|
287
275
|
| unsubscribe | `({ type: string, payload: any }) => void` | Unsubscribe handler from receiving events. |
|
|
288
|
-
|
|
289
|
-
### featureFlags
|
|
290
|
-
|
|
291
|
-
> Type: object
|
|
292
|
-
|
|
293
|
-
| Method | Type | Description |
|
|
294
|
-
| ------- | ------------------------------------- | -------------------------------------- |
|
|
295
|
-
| enable | `async (featureName: string) => void` | Enables a feature-flag gated feature. |
|
|
296
|
-
| disable | `async (featureName: string) => void` | Disables a feature-flag gated feature. |
|
|
297
|
-
|
|
298
|
-
See [more details](../../features/feature-flags/).
|
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.15",
|
|
4
|
+
"description": "The headless 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/modules/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,88 +17,57 @@
|
|
|
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": "
|
|
26
|
+
"test": "jest"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@exodus/
|
|
30
|
-
"@exodus/assets
|
|
31
|
-
"@exodus/
|
|
32
|
-
"@exodus/auto-enable-assets-plugin": "^4.4.0",
|
|
33
|
-
"@exodus/available-assets": "^8.0.0",
|
|
34
|
-
"@exodus/balances": "^12.0.1",
|
|
29
|
+
"@exodus/atoms": "^2.9.0",
|
|
30
|
+
"@exodus/available-assets": "^2.0.0",
|
|
31
|
+
"@exodus/balances": "^6.0.0",
|
|
35
32
|
"@exodus/basic-utils": "^2.0.0",
|
|
36
|
-
"@exodus/blockchain-metadata": "^
|
|
37
|
-
"@exodus/
|
|
38
|
-
"@exodus/dependency-
|
|
39
|
-
"@exodus/
|
|
40
|
-
"@exodus/
|
|
41
|
-
"@exodus/
|
|
33
|
+
"@exodus/blockchain-metadata": "^8.0.1",
|
|
34
|
+
"@exodus/config": "7.0.0",
|
|
35
|
+
"@exodus/dependency-injection": "^1.2.0",
|
|
36
|
+
"@exodus/dependency-preprocessors": "^2.3.0",
|
|
37
|
+
"@exodus/enabled-assets": "^6.0.0",
|
|
38
|
+
"@exodus/exodus-pricing-client": "^1.1.0",
|
|
42
39
|
"@exodus/fetch": "^1.2.1",
|
|
43
|
-
"@exodus/geolocation": "
|
|
44
|
-
"@exodus/
|
|
45
|
-
"@exodus/
|
|
46
|
-
"@exodus/
|
|
47
|
-
"@exodus/
|
|
48
|
-
"@exodus/
|
|
49
|
-
"@exodus/
|
|
50
|
-
"@exodus/
|
|
51
|
-
"@exodus/
|
|
52
|
-
"
|
|
53
|
-
"@exodus/restore-progress-tracker": "^3.0.0",
|
|
54
|
-
"@exodus/sodium-crypto": "^3.2.0",
|
|
55
|
-
"@exodus/startup-counter": "^1.0.0",
|
|
56
|
-
"@exodus/tx-signer": "^1.1.0",
|
|
57
|
-
"@exodus/wallet": "^10.3.0",
|
|
58
|
-
"@exodus/wallet-accounts": "^15.0.0",
|
|
59
|
-
"@exodus/wallet-compatibility-modes": "^3.2.0",
|
|
60
|
-
"bip39": "^2.6.0",
|
|
40
|
+
"@exodus/geolocation": "1.1.0",
|
|
41
|
+
"@exodus/key-identifier-provider": "^1.1.3",
|
|
42
|
+
"@exodus/keychain": "^4.0.0",
|
|
43
|
+
"@exodus/market-history": "^3.1.0",
|
|
44
|
+
"@exodus/module": "^1.0.0",
|
|
45
|
+
"@exodus/rates-monitor": "^2.0.0",
|
|
46
|
+
"@exodus/wallet": "^6.0.1",
|
|
47
|
+
"@exodus/wallet-accounts": "^8.0.1",
|
|
48
|
+
"@exodus/wallet-compatibility-modes": "^2.0.0",
|
|
49
|
+
"bip39": "2.6.0",
|
|
61
50
|
"events": "^3.3.0",
|
|
62
|
-
"lodash": "
|
|
51
|
+
"lodash": "https://registry.yarnpkg.com/@exodus/lodash/-/lodash-4.17.21-exodus.2.tgz",
|
|
63
52
|
"minimalistic-assert": "^1.0.1"
|
|
64
53
|
},
|
|
65
54
|
"devDependencies": {
|
|
66
|
-
"@exodus/
|
|
67
|
-
"@exodus/algorand-lib": "^2.0.1",
|
|
68
|
-
"@exodus/algorand-meta": "^1.1.4",
|
|
69
|
-
"@exodus/apy-rates": "^3.3.1",
|
|
70
|
-
"@exodus/assets-feature": "workspace:^",
|
|
71
|
-
"@exodus/bitcoin-plugin": "^1.0.14",
|
|
72
|
-
"@exodus/connected-origins": "^3.3.0",
|
|
73
|
-
"@exodus/crypto-news-monitor": "^4.1.0",
|
|
55
|
+
"@exodus/bitcoin-meta": "^1.0.0",
|
|
74
56
|
"@exodus/currency": "^2.2.0",
|
|
75
|
-
"@exodus/ethereum-lib": "^
|
|
57
|
+
"@exodus/ethereum-lib": "^2.22.2",
|
|
76
58
|
"@exodus/ethereum-meta": "^1.0.23",
|
|
77
|
-
"@exodus/
|
|
78
|
-
"@exodus/key-utils": "^3.0.0",
|
|
79
|
-
"@exodus/kyc": "^4.2.0",
|
|
80
|
-
"@exodus/litecoin-meta": "^1.0.0",
|
|
81
|
-
"@exodus/market-history": "^7.2.0",
|
|
82
|
-
"@exodus/models": "^10.1.0",
|
|
83
|
-
"@exodus/nfts": "^7.1.2",
|
|
84
|
-
"@exodus/personal-notes": "^3.6.0",
|
|
85
|
-
"@exodus/referrals": "^8.0.1",
|
|
59
|
+
"@exodus/models": "^8.11.1",
|
|
86
60
|
"@exodus/solana-lib": "^1.3.11",
|
|
87
61
|
"@exodus/solana-meta": "^1.0.2",
|
|
88
62
|
"@exodus/storage-encrypted": "^1.1.2",
|
|
89
|
-
"@exodus/storage-memory": "^
|
|
90
|
-
"@exodus/top-movers-monitor": "^3.2.0",
|
|
91
|
-
"@exodus/ui-config": "^3.3.0",
|
|
63
|
+
"@exodus/storage-memory": "^1.1.0",
|
|
92
64
|
"@exodus/wild-emitter": "^1.0.0",
|
|
93
65
|
"buffer-json": "^2.0.0",
|
|
94
66
|
"deepmerge": "^4.2.2",
|
|
95
|
-
"
|
|
96
|
-
"eslint": "^8.44.0",
|
|
97
|
-
"eslint-plugin-simple-import-sort": "^7.0.0",
|
|
67
|
+
"eslint": "^8.33.0",
|
|
98
68
|
"events": "^3.3.0",
|
|
99
69
|
"jest": "^29.1.2",
|
|
100
|
-
"msw": "^2.0.0",
|
|
101
70
|
"p-defer": "^4.0.0"
|
|
102
71
|
},
|
|
103
|
-
"gitHead": "
|
|
72
|
+
"gitHead": "5aae21f6315492fe857aa8bd79995134886d2fcd"
|
|
104
73
|
}
|
package/src/api.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { validateMnemonic as isMnemonicValid } from 'bip39'
|
|
2
|
+
|
|
3
|
+
const createApi = ({ ioc, port }) => {
|
|
4
|
+
const { assetsModule, passphraseCache } = ioc.getByType('adapter')
|
|
5
|
+
|
|
6
|
+
const { application, blockchainMetadata, enabledAssets, remoteConfig, wallet, walletAccounts } =
|
|
7
|
+
ioc.getByType('module')
|
|
8
|
+
|
|
9
|
+
const { ratesMonitor } = ioc.getByType('monitor')
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
// ...
|
|
13
|
+
currencyAtom,
|
|
14
|
+
enabledWalletAccountsAtom,
|
|
15
|
+
languageAtom,
|
|
16
|
+
} = ioc.getByType('atom')
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
wallet: {
|
|
20
|
+
exists: () => wallet.exists(),
|
|
21
|
+
load: application.load,
|
|
22
|
+
unload: application.unload,
|
|
23
|
+
create: application.create,
|
|
24
|
+
lock: application.lock,
|
|
25
|
+
unlock: application.unlock,
|
|
26
|
+
import: application.import,
|
|
27
|
+
delete: application.delete,
|
|
28
|
+
getMnemonic: application.getMnemonic,
|
|
29
|
+
setBackedUp: application.setBackedUp,
|
|
30
|
+
changePassphrase: application.changePassphrase,
|
|
31
|
+
restoreFromCurrentPhrase: async ({ passphrase } = {}) => {
|
|
32
|
+
if (!passphrase) passphrase = await passphraseCache.get()
|
|
33
|
+
const mnemonic = await application.getMnemonic({ passphrase })
|
|
34
|
+
|
|
35
|
+
await application.import({ passphrase, mnemonic })
|
|
36
|
+
},
|
|
37
|
+
changeLockTimer: application.changeLockTimer,
|
|
38
|
+
isLocked: () => wallet.isLocked(),
|
|
39
|
+
},
|
|
40
|
+
walletAccounts: {
|
|
41
|
+
create: walletAccounts.create,
|
|
42
|
+
update: walletAccounts.update,
|
|
43
|
+
disable: walletAccounts.disable,
|
|
44
|
+
enable: walletAccounts.enable,
|
|
45
|
+
getEnabled: enabledWalletAccountsAtom.get,
|
|
46
|
+
},
|
|
47
|
+
blockchainMetadata: {
|
|
48
|
+
getTxLog: blockchainMetadata.getTxLog,
|
|
49
|
+
getLoadedTxLogs: blockchainMetadata.getLoadedTxLogs,
|
|
50
|
+
updateTxs: blockchainMetadata.updateTxs,
|
|
51
|
+
overwriteTxs: blockchainMetadata.overwriteTxs,
|
|
52
|
+
clearTxs: blockchainMetadata.clearTxs,
|
|
53
|
+
removeTxs: blockchainMetadata.removeTxs,
|
|
54
|
+
getAccountState: blockchainMetadata.getAccountState,
|
|
55
|
+
getLoadedAccountStates: blockchainMetadata.getLoadedAccountStates,
|
|
56
|
+
updateAccountState: blockchainMetadata.updateAccountState,
|
|
57
|
+
removeAccountState: blockchainMetadata.removeAccountState,
|
|
58
|
+
batch: blockchainMetadata.batch,
|
|
59
|
+
},
|
|
60
|
+
assets: {
|
|
61
|
+
enable: enabledAssets.enable,
|
|
62
|
+
disable: enabledAssets.disable,
|
|
63
|
+
addAndEnableToken: async (...args) => {
|
|
64
|
+
const asset = await assetsModule.addToken(...args)
|
|
65
|
+
await enabledAssets.enable([asset.name])
|
|
66
|
+
return asset.name
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
remoteConfig: {
|
|
70
|
+
get: remoteConfig.get,
|
|
71
|
+
getAll: remoteConfig.getAll,
|
|
72
|
+
},
|
|
73
|
+
locale: {
|
|
74
|
+
setLanguage: (value) => languageAtom.set(value),
|
|
75
|
+
setCurrency: (value) => currencyAtom.set(value),
|
|
76
|
+
},
|
|
77
|
+
rates: {
|
|
78
|
+
refresh: () => ratesMonitor.update(),
|
|
79
|
+
},
|
|
80
|
+
isMnemonicValid,
|
|
81
|
+
subscribe: port.subscribe.bind(port),
|
|
82
|
+
unsubscribe: port.unsubscribe.bind(port),
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export default createApi
|
package/src/application.js
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
import ExodusModule from '@exodus/module'
|
|
4
4
|
import assert from 'minimalistic-assert'
|
|
5
5
|
|
|
6
|
-
import { LifecycleHook as Hook } from './constants'
|
|
7
|
-
|
|
8
6
|
// Because we are forced to restart wallet after deleting/importing, we need to store certain flags to persist state between executions
|
|
9
7
|
|
|
10
8
|
// Triggers deletetion logic when wallet starts.
|
|
@@ -19,15 +17,24 @@ const IMPORT_FLAG = 'importFlag'
|
|
|
19
17
|
// Set as true on import method is called, and set to false after restore is completed
|
|
20
18
|
const RESTORE_FLAG = 'restoreFlag'
|
|
21
19
|
|
|
22
|
-
const
|
|
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
|
+
})
|
|
23
36
|
|
|
24
|
-
const
|
|
25
|
-
get: () => {},
|
|
26
|
-
set: () => {},
|
|
27
|
-
changeTtl: () => {},
|
|
28
|
-
clear: () => {},
|
|
29
|
-
scheduleClear: () => {},
|
|
30
|
-
}
|
|
37
|
+
const HOOKS = new Set(Object.values(Hook))
|
|
31
38
|
|
|
32
39
|
class Application extends ExodusModule {
|
|
33
40
|
#hooks = {}
|
|
@@ -37,7 +44,7 @@ class Application extends ExodusModule {
|
|
|
37
44
|
#applicationStarted = null
|
|
38
45
|
#resolveStart = null
|
|
39
46
|
|
|
40
|
-
constructor({ wallet, unsafeStorage, passphraseCache
|
|
47
|
+
constructor({ wallet, unsafeStorage, passphraseCache, logger }) {
|
|
41
48
|
super({ name: 'Application', logger })
|
|
42
49
|
|
|
43
50
|
this.#wallet = wallet
|
|
@@ -64,26 +71,12 @@ class Application extends ExodusModule {
|
|
|
64
71
|
const walletExists = await this.#wallet.exists()
|
|
65
72
|
|
|
66
73
|
if (isImporting || !walletExists) {
|
|
67
|
-
await this.fire(Hook.Clear
|
|
74
|
+
await this.fire(Hook.Clear)
|
|
68
75
|
}
|
|
69
76
|
|
|
70
77
|
if (isImporting) await this.fire(Hook.Import)
|
|
71
78
|
|
|
72
|
-
|
|
73
|
-
this.#wallet.hasPassphraseSet(),
|
|
74
|
-
this.#wallet.isLocked(),
|
|
75
|
-
this.#wallet.isBackedUp(),
|
|
76
|
-
this.isRestoring(),
|
|
77
|
-
])
|
|
78
|
-
|
|
79
|
-
await this.fire(Hook.Start, {
|
|
80
|
-
walletExists,
|
|
81
|
-
hasPassphraseSet,
|
|
82
|
-
isLocked,
|
|
83
|
-
isBackedUp,
|
|
84
|
-
isRestoring,
|
|
85
|
-
})
|
|
86
|
-
|
|
79
|
+
await this.fire(Hook.Start)
|
|
87
80
|
await this.#autoUnlock()
|
|
88
81
|
|
|
89
82
|
const locked = await this.#wallet.isLocked()
|
|
@@ -111,7 +104,6 @@ class Application extends ExodusModule {
|
|
|
111
104
|
isRestoring,
|
|
112
105
|
})
|
|
113
106
|
}
|
|
114
|
-
|
|
115
107
|
unload = async () => {
|
|
116
108
|
await this.#applicationStarted
|
|
117
109
|
await this.#passphraseCache.scheduleClear()
|
|
@@ -128,28 +120,14 @@ class Application extends ExodusModule {
|
|
|
128
120
|
this.#hooks[hookName].push(listener)
|
|
129
121
|
}
|
|
130
122
|
|
|
131
|
-
fire = async (hookName, params
|
|
123
|
+
fire = async (hookName, params) => {
|
|
132
124
|
assert(HOOKS.has(hookName), `no such hook: ${hookName}`)
|
|
133
|
-
|
|
134
|
-
this._logger.debug(`firing hooks ${concurrent ? 'concurrently' : 'sequentially'}`, hookName)
|
|
125
|
+
this._logger.debug('firing hooks', hookName)
|
|
135
126
|
|
|
136
127
|
const hooks = this.#hooks[hookName] || []
|
|
137
128
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
await hook(params)
|
|
141
|
-
} catch (err) {
|
|
142
|
-
this._logger.error(`application lifecycle hook failed: ${hookName}`, hook.name, params, err)
|
|
143
|
-
throw err
|
|
144
|
-
}
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
if (concurrent) {
|
|
148
|
-
await Promise.allSettled(hookFns.map((promise) => promise()))
|
|
149
|
-
} else {
|
|
150
|
-
for (let i = 0; i < hookFns.length; i++) {
|
|
151
|
-
await hookFns[i]()
|
|
152
|
-
}
|
|
129
|
+
for (let i = 0; i < hooks.length; i++) {
|
|
130
|
+
await hooks[i](params)
|
|
153
131
|
}
|
|
154
132
|
|
|
155
133
|
this.emit(hookName, params)
|
|
@@ -161,15 +139,7 @@ class Application extends ExodusModule {
|
|
|
161
139
|
await this.#applicationStarted
|
|
162
140
|
await this.#wallet.create(opts)
|
|
163
141
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
await this.fire(Hook.Create, {
|
|
167
|
-
hasPassphraseSet: !!opts?.passphrase,
|
|
168
|
-
isBackedUp: false,
|
|
169
|
-
isLocked,
|
|
170
|
-
isRestoring: false,
|
|
171
|
-
walletExists: true,
|
|
172
|
-
})
|
|
142
|
+
await this.fire(Hook.Create, { hasPassphraseSet: !!opts?.passphrase })
|
|
173
143
|
}
|
|
174
144
|
|
|
175
145
|
import = async (opts) => {
|
|
@@ -181,15 +151,14 @@ class Application extends ExodusModule {
|
|
|
181
151
|
|
|
182
152
|
const walletExists = await this.#wallet.exists()
|
|
183
153
|
|
|
184
|
-
const { forceRestart,
|
|
154
|
+
const { forceRestart, ...wallet } = opts
|
|
185
155
|
|
|
186
156
|
await this.#wallet.import(wallet)
|
|
187
|
-
await this.fire(Hook.Backup)
|
|
188
157
|
|
|
189
158
|
if (forceRestart || walletExists) {
|
|
190
159
|
await this.#storage.set(IMPORT_FLAG, true)
|
|
191
160
|
|
|
192
|
-
|
|
161
|
+
this.emit('restart', { reason: 'import' })
|
|
193
162
|
} else {
|
|
194
163
|
await this.fire(Hook.Import)
|
|
195
164
|
|
|
@@ -221,17 +190,13 @@ class Application extends ExodusModule {
|
|
|
221
190
|
if (isRestoring) {
|
|
222
191
|
await this.fire(Hook.Restore)
|
|
223
192
|
await this.#storage.delete(RESTORE_FLAG)
|
|
193
|
+
await this.setBackedUp()
|
|
224
194
|
await this.fire(Hook.RestoreCompleted)
|
|
225
195
|
}
|
|
226
196
|
|
|
227
197
|
this.fire(Hook.AssetsSynced)
|
|
228
198
|
}
|
|
229
199
|
|
|
230
|
-
restore = async () => {
|
|
231
|
-
await this.#storage.set(RESTORE_FLAG, true)
|
|
232
|
-
await this.restoreIfNeeded()
|
|
233
|
-
}
|
|
234
|
-
|
|
235
200
|
#autoUnlock = async () => {
|
|
236
201
|
const walletLocked = await this.#wallet.isLocked()
|
|
237
202
|
const passphrase = await this.#passphraseCache.get()
|
|
@@ -242,8 +207,6 @@ class Application extends ExodusModule {
|
|
|
242
207
|
this._logger.log('unlocking with cache')
|
|
243
208
|
|
|
244
209
|
await this.#wallet.unlock({ passphrase })
|
|
245
|
-
|
|
246
|
-
await this.fire(Hook.Migrate)
|
|
247
210
|
await this.fire(Hook.Unlock)
|
|
248
211
|
|
|
249
212
|
this.#restoreIfNeeded()
|
|
@@ -281,23 +244,15 @@ class Application extends ExodusModule {
|
|
|
281
244
|
this._logger.log('passphrase changed')
|
|
282
245
|
}
|
|
283
246
|
|
|
284
|
-
delete = async (
|
|
247
|
+
delete = async () => {
|
|
285
248
|
await this.#storage.set(DELETE_FLAG, true)
|
|
286
|
-
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
stop = async () => {
|
|
290
|
-
await this.fire(Hook.Stop)
|
|
249
|
+
this.emit('restart', { reason: 'delete' })
|
|
291
250
|
}
|
|
292
251
|
|
|
293
252
|
changeLockTimer = async ({ ttl }) => {
|
|
294
253
|
await this.#passphraseCache.changeTtl(ttl)
|
|
295
254
|
}
|
|
296
255
|
|
|
297
|
-
restartAutoLockTimer = async () => {
|
|
298
|
-
await this.#passphraseCache.scheduleClear()
|
|
299
|
-
}
|
|
300
|
-
|
|
301
256
|
isRestoring = async () => {
|
|
302
257
|
return this.#storage.get(RESTORE_FLAG)
|
|
303
258
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const emitAtomValue = async (opts) => {
|
|
2
|
+
const { port, atomId, atom } = opts
|
|
3
|
+
const value = 'value' in opts ? opts.value : await atom.get()
|
|
4
|
+
port.emit(atomId, value)
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const emitFromAtoms = ({ atoms, port }) =>
|
|
8
|
+
Object.entries(atoms).forEach(async ([atomId, atom]) => emitAtomValue({ port, atomId, atom }))
|
|
9
|
+
|
|
10
|
+
const attachAtom = ({ port, application, logger, atom, atomId, lifecycleEvents }) => {
|
|
11
|
+
let loaded = false
|
|
12
|
+
|
|
13
|
+
lifecycleEvents.forEach((event) =>
|
|
14
|
+
application.on(event, async () => {
|
|
15
|
+
loaded = true
|
|
16
|
+
await emitAtomValue({ port, atomId, atom })
|
|
17
|
+
})
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
application.on('clear', async () => {
|
|
21
|
+
try {
|
|
22
|
+
await atom?.set(undefined)
|
|
23
|
+
} catch (error) {
|
|
24
|
+
logger.debug('failed to clear atom', error)
|
|
25
|
+
// noop. atom might not support set
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
atom.observe((value) => {
|
|
30
|
+
if (loaded) emitAtomValue({ port, atomId, atom, value })
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const attachAtoms = ({ port, application, logger, atoms, lifecycleEvents = ['start'] }) => {
|
|
35
|
+
for (const [atomId, atom] of Object.entries(atoms)) {
|
|
36
|
+
attachAtom({ port, application, logger, atom, atomId, lifecycleEvents })
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default attachAtoms
|
package/src/constants.js
CHANGED
|
@@ -1,18 +1,9 @@
|
|
|
1
|
-
export const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
+
export const atomsToAttach = [
|
|
2
|
+
'availableAssetNamesAtom',
|
|
3
|
+
'balancesAtom',
|
|
4
|
+
'currencyAtom',
|
|
5
|
+
'enabledWalletAccountsAtom',
|
|
6
|
+
'geolocationAtom',
|
|
7
|
+
'languageAtom',
|
|
8
|
+
'walletAccountsAtom',
|
|
9
|
+
]
|