@exodus/headless 5.0.0-rc.2 → 5.0.0-rc.20

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,144 @@
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
+ ## [5.0.0-rc.20](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@5.0.0-rc.19...@exodus/headless@5.0.0-rc.20) (2024-07-12)
7
+
8
+ ### Features
9
+
10
+ - bump @exodus/error-tracking in headless ([#7824](https://github.com/ExodusMovement/exodus-hydra/issues/7824)) ([8e247f7](https://github.com/ExodusMovement/exodus-hydra/commit/8e247f7111bf847f6b06c0305be1f60f0061a9a2))
11
+
12
+ ## [5.0.0-rc.19](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@5.0.0-rc.18...@exodus/headless@5.0.0-rc.19) (2024-07-12)
13
+
14
+ ### Features
15
+
16
+ - add errorTracking feature to sdk ([#7670](https://github.com/ExodusMovement/exodus-hydra/issues/7670)) ([34dbc5c](https://github.com/ExodusMovement/exodus-hydra/commit/34dbc5c1f0b94ef4213dfaec788790c475eb962c)), closes [#7708](https://github.com/ExodusMovement/exodus-hydra/issues/7708)
17
+
18
+ ## [5.0.0-rc.18](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@5.0.0-rc.17...@exodus/headless@5.0.0-rc.18) (2024-07-12)
19
+
20
+ ### Features
21
+
22
+ - bump @exodus/assets in headless pkg ([#7802](https://github.com/ExodusMovement/exodus-hydra/issues/7802)) ([5a67601](https://github.com/ExodusMovement/exodus-hydra/commit/5a67601cfd72a6b76aec2abc3cf0d8212d80edca))
23
+
24
+ ### Bug Fixes
25
+
26
+ - update referrals config key ([#7666](https://github.com/ExodusMovement/exodus-hydra/issues/7666)) ([17fd92a](https://github.com/ExodusMovement/exodus-hydra/commit/17fd92ab4c95757c4fbbd26b8bb7a4cf6fed87d8))
27
+
28
+ ## [5.0.0-rc.17](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@5.0.0-rc.16...@exodus/headless@5.0.0-rc.17) (2024-07-03)
29
+
30
+ ### Features
31
+
32
+ - allow subscribing to when a new seed is done restoring ([#7565](https://github.com/ExodusMovement/exodus-hydra/issues/7565)) ([1c9464e](https://github.com/ExodusMovement/exodus-hydra/commit/1c9464e8a9e1aafb6a9ebb5e9567ab33de6f2e33))
33
+ - log reporting duration per node ([#7574](https://github.com/ExodusMovement/exodus-hydra/issues/7574)) ([26ba1cb](https://github.com/ExodusMovement/exodus-hydra/commit/26ba1cbb8281072289e99b9ebdd26a940f23d605))
34
+
35
+ ### Bug Fixes
36
+
37
+ - headless test ([#7476](https://github.com/ExodusMovement/exodus-hydra/issues/7476)) ([a901f32](https://github.com/ExodusMovement/exodus-hydra/commit/a901f32c0e9b5f23b04a322f4904a03b1d18f694))
38
+
39
+ ## [5.0.0-rc.16](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@5.0.0-rc.15...@exodus/headless@5.0.0-rc.16) (2024-06-25)
40
+
41
+ **Note:** Version bump only for package @exodus/headless
42
+
43
+ ## [5.0.0-rc.15](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@5.0.0-rc.14...@exodus/headless@5.0.0-rc.15) (2024-06-24)
44
+
45
+ **Note:** Version bump only for package @exodus/headless
46
+
47
+ ### Features
48
+
49
+ - add header handling per domain ([#7439](https://github.com/ExodusMovement/exodus-hydra/issues/7439)) ([7c45192](https://github.com/ExodusMovement/exodus-hydra/commit/7c451924901bd118765bea8bc7e1bb6f8bf1b5f5))
50
+
51
+ ## [5.0.0-rc.14](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@5.0.0-rc.13...@exodus/headless@5.0.0-rc.14) (2024-06-19)
52
+
53
+ ### Bug Fixes
54
+
55
+ - get kyc api-version && url from remote-config ([#7320](https://github.com/ExodusMovement/exodus-hydra/issues/7320)) ([5d22b13](https://github.com/ExodusMovement/exodus-hydra/commit/5d22b13e1c8d5e265f1f93498de7d83be25924ee))
56
+ - revert to use legacy kyc ([#7294](https://github.com/ExodusMovement/exodus-hydra/issues/7294)) ([6b52bcc](https://github.com/ExodusMovement/exodus-hydra/commit/6b52bcc1aa1ed1f1553403d64bb1e3f209be72a6))
57
+ - chore: bump wallet-accounts in headless ([#7431](https://github.com/ExodusMovement/exodus-hydra/issues/7431)) ([d39d9cf](https://github.com/ExodusMovement/exodus-hydra/commit/ad94a2948ffe03aee9c86d3acc6a15e57d39d9cf))
58
+
59
+ ## [5.0.0-rc.13](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@5.0.0-rc.12...@exodus/headless@5.0.0-rc.13) (2024-06-04)
60
+
61
+ ### Bug Fixes
62
+
63
+ - use updated api to persist referral info ([#7224](https://github.com/ExodusMovement/exodus-hydra/issues/7224)) ([4a9906a](https://github.com/ExodusMovement/exodus-hydra/commit/4a9906a8a1746a76fb6dbfd574c4c48865c463c1)), closes [#7225](https://github.com/ExodusMovement/exodus-hydra/issues/7225)
64
+
65
+ ## [5.0.0-rc.12](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@5.0.0-rc.11...@exodus/headless@5.0.0-rc.12) (2024-05-29)
66
+
67
+ ### Features
68
+
69
+ - export `ApplicationWalletApi` type ([#7189](https://github.com/ExodusMovement/exodus-hydra/issues/7189)) ([3aced97](https://github.com/ExodusMovement/exodus-hydra/commit/3aced9749447cca0ebdc1824770eb8a0711f7d65))
70
+
71
+ ### Bug Fixes
72
+
73
+ - await clearing personal notes storage ([#7055](https://github.com/ExodusMovement/exodus-hydra/issues/7055)) ([5522284](https://github.com/ExodusMovement/exodus-hydra/commit/5522284ccc3db4bf837a3ff752234396d10d8bce))
74
+
75
+ ## [5.0.0-rc.11](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@5.0.0-rc.10...@exodus/headless@5.0.0-rc.11) (2024-05-28)
76
+
77
+ ### Bug Fixes
78
+
79
+ - set walletAccount defaultLabel in migration ([#7134](https://github.com/ExodusMovement/exodus-hydra/issues/7134)) ([3a24900](https://github.com/ExodusMovement/exodus-hydra/commit/3a24900e000af929e34f094fd4406e39b48c58dc))
80
+
81
+ ## [5.0.0-rc.10](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@5.0.0-rc.9...@exodus/headless@5.0.0-rc.10) (2024-05-22)
82
+
83
+ ### ⚠ BREAKING CHANGES
84
+
85
+ - update kyc server url and endpoints (#6906)
86
+
87
+ ### Features
88
+
89
+ - addressProvider.getDefaultPurpose ([#6910](https://github.com/ExodusMovement/exodus-hydra/issues/6910)) ([533a105](https://github.com/ExodusMovement/exodus-hydra/commit/533a105af69fabb690e2c0c5fd4b3a21a2500526))
90
+ - include assetSources feature in headless by default ([#7029](https://github.com/ExodusMovement/exodus-hydra/issues/7029)) ([7a9321e](https://github.com/ExodusMovement/exodus-hydra/commit/7a9321ef8503ecaf4bd126f5620720a520a5eda8))
91
+ - update analytics in headless to kill keychain-atoms ([#7052](https://github.com/ExodusMovement/exodus-hydra/issues/7052)) ([c77e7fb](https://github.com/ExodusMovement/exodus-hydra/commit/c77e7fbabcd71ff70c69ce4057312b58b3cf2f77))
92
+
93
+ ### Bug Fixes
94
+
95
+ - atoms should not hit storage after first read or write ([#6834](https://github.com/ExodusMovement/exodus-hydra/issues/6834)) ([63e23f1](https://github.com/ExodusMovement/exodus-hydra/commit/63e23f1f0bf33732f67b70feb9e95e854a8fd90e))
96
+ - improve perf of onAssetsSynced ([#6893](https://github.com/ExodusMovement/exodus-hydra/issues/6893)) ([3a7ce3a](https://github.com/ExodusMovement/exodus-hydra/commit/3a7ce3a28e3a2890118f7f1702120136c2f6fff8))
97
+ - remove `compatibilityMode` from flagsStorage ([#7039](https://github.com/ExodusMovement/exodus-hydra/issues/7039)) ([50f5a7d](https://github.com/ExodusMovement/exodus-hydra/commit/50f5a7d48e039c1629cba6b64d0c952b86cdda3c))
98
+ - update kyc server url and endpoints ([#6906](https://github.com/ExodusMovement/exodus-hydra/issues/6906)) ([485cf5b](https://github.com/ExodusMovement/exodus-hydra/commit/485cf5bc3abc0cfa65b106c0f8af1ddb21f026f6))
99
+
100
+ ## [5.0.0-rc.9](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@5.0.0-rc.8...@exodus/headless@5.0.0-rc.9) (2024-05-08)
101
+
102
+ ### Features
103
+
104
+ - **announcements:** add shownForcedAnnouncement ([#6797](https://github.com/ExodusMovement/exodus-hydra/issues/6797)) ([3af46d1](https://github.com/ExodusMovement/exodus-hydra/commit/3af46d196abdb03885091c03c9e8c86ced500193))
105
+
106
+ ## [5.0.0-rc.8](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@5.0.0-rc.7...@exodus/headless@5.0.0-rc.8) (2024-05-06)
107
+
108
+ ### Features
109
+
110
+ - always pass config to features ([#6820](https://github.com/ExodusMovement/exodus-hydra/issues/6820)) ([656501d](https://github.com/ExodusMovement/exodus-hydra/commit/656501dc47948bf055decfed3a404bc92170532b))
111
+
112
+ ### Bug Fixes
113
+
114
+ - `createExodus` return type ([#6739](https://github.com/ExodusMovement/exodus-hydra/issues/6739)) ([efa2d18](https://github.com/ExodusMovement/exodus-hydra/commit/efa2d18b60a60f625223515f38b065d0cb6b3827))
115
+
116
+ ## [5.0.0-rc.7](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@5.0.0-rc.6...@exodus/headless@5.0.0-rc.7) (2024-04-29)
117
+
118
+ ### Features
119
+
120
+ - add key-viewer to export encoded private keys ([#6713](https://github.com/ExodusMovement/exodus-hydra/issues/6713)) ([272a0cb](https://github.com/ExodusMovement/exodus-hydra/commit/272a0cb23cd5d76df801d661d16b0238b301e88c))
121
+
122
+ ## [5.0.0-rc.6](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@5.0.0-rc.5...@exodus/headless@5.0.0-rc.6) (2024-04-26)
123
+
124
+ **Note:** Version bump only for package @exodus/headless
125
+
126
+ ## [5.0.0-rc.5](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@5.0.0-rc.3...@exodus/headless@5.0.0-rc.5) (2024-04-26)
127
+
128
+ ### Features
129
+
130
+ - add keychain api types ([#6679](https://github.com/ExodusMovement/exodus-hydra/issues/6679)) ([57d1bfc](https://github.com/ExodusMovement/exodus-hydra/commit/57d1bfcd6d98c5ec13a5801a2172e558fb4c3e1e))
131
+
132
+ ## [5.0.0-rc.4](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@5.0.0-rc.3...@exodus/headless@5.0.0-rc.4) (2024-04-25)
133
+
134
+ ### Features
135
+
136
+ - add keychain api types ([#6679](https://github.com/ExodusMovement/exodus-hydra/issues/6679)) ([57d1bfc](https://github.com/ExodusMovement/exodus-hydra/commit/57d1bfcd6d98c5ec13a5801a2172e558fb4c3e1e))
137
+
138
+ ## [5.0.0-rc.3](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@5.0.0-rc.2...@exodus/headless@5.0.0-rc.3) (2024-04-24)
139
+
140
+ ### Features
141
+
142
+ - **referrals:** adds new referral selectors ([#6525](https://github.com/ExodusMovement/exodus-hydra/issues/6525)) ([3eae2f7](https://github.com/ExodusMovement/exodus-hydra/commit/3eae2f7a4c468b5d8d5c0fa3608d3dc2ff7746fc))
143
+
6
144
  ## [5.0.0-rc.2](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@5.0.0-rc.1...@exodus/headless@5.0.0-rc.2) (2024-04-23)
7
145
 
8
146
  ### Features
package/README.md CHANGED
@@ -256,19 +256,19 @@ exodusContainer.debug.geolocation.merge({ countryCode: 'US' })
256
256
 
257
257
  > Type: object
258
258
 
259
- | Method | Type | Description |
260
- | ---------------------- | ---------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
261
- | getTxLog | `async ({ assetName, walletAccount }) => TxSet` | Get the TxSet for the provided `assetName`/`walletAccount` combination (AssetSource) |
262
- | getLoadedTxLogs | `async () => object` | Get the all loaded `TxSet`s as a `{ [walletAccount]: { [assetName]: TxSet } } object` |
263
- | updateTxs | `async ({ assetName: string, walletAccount: string, txs: object[] }) => void` | Add or update txs with updates provided in `txs` |
264
- | overwriteTxs | `async ({ assetName: string, walletAccount: string, txs: object[], notifyReceivedTxs: ?boolean }) => void` | Overwrite specified txs. |
265
- | clearTxs | `async ({ assetName: string, walletAccount: string }) => void` | Remove txs for AssetSource. |
266
- | removeTxs | `async ({ assetName: string, walletAccount: string, txs: object[] }) => void` | Remove provided txs. |
267
- | getAccountState | `async ({ assetName, walletAccount }) => AccountState` | Get the AccountState for the provided AssetSource |
268
- | getLoadedAccountStates | `async () => object` | Get the all loaded `AccountState`s as a `{ [walletAccount]: { [assetName]: AccountState } } object` |
269
- | updateAccountState | `async ({ assetName: string, walletAccount: string, newData: object }) => void` | Update accountState for AssetSource. |
270
- | removeAccountState | `async ({ assetName: string, walletAccount: string }) => void` | Remove accountState for AssetSource. |
271
- | batch | `() => Batch` | Create a batch of updates. See [blockchainMetadata](../blockchain-metadata) README for batching details. |
259
+ | Method | Type | Description |
260
+ | ---------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
261
+ | getTxLog | `async ({ assetName, walletAccount }) => TxSet` | Get the TxSet for the provided `assetName`/`walletAccount` combination (AssetSource) |
262
+ | getLoadedTxLogs | `async () => object` | Get the all loaded `TxSet`s as a `{ [walletAccount]: { [assetName]: TxSet } } object` |
263
+ | updateTxs | `async ({ assetName: string, walletAccount: string, txs: object[] }) => void` | Add or update txs with updates provided in `txs` |
264
+ | overwriteTxs | `async ({ assetName: string, walletAccount: string, txs: object[], notifyReceivedTxs: ?boolean }) => void` | Overwrite specified txs. |
265
+ | clearTxs | `async ({ assetName: string, walletAccount: string }) => void` | Remove txs for AssetSource. |
266
+ | removeTxs | `async ({ assetName: string, walletAccount: string, txs: object[] }) => void` | Remove provided txs. |
267
+ | getAccountState | `async ({ assetName, walletAccount }) => AccountState` | Get the AccountState for the provided AssetSource |
268
+ | getLoadedAccountStates | `async () => object` | Get the all loaded `AccountState`s as a `{ [walletAccount]: { [assetName]: AccountState } } object` |
269
+ | updateAccountState | `async ({ assetName: string, walletAccount: string, newData: object }) => void` | Update accountState for AssetSource. |
270
+ | removeAccountState | `async ({ assetName: string, walletAccount: string }) => void` | Remove accountState for AssetSource. |
271
+ | batch | `() => Batch` | Create a batch of updates. See [blockchainMetadata](../../features/blockchain-metadata/README.md) README for batching details. |
272
272
 
273
273
  ### assets
274
274
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/headless",
3
- "version": "5.0.0-rc.2",
3
+ "version": "5.0.0-rc.20",
4
4
  "description": "The platform-agnostic Exodus wallet SDK",
5
5
  "author": "Exodus Movement, Inc.",
6
6
  "main": "src/index.js",
@@ -26,77 +26,82 @@
26
26
  "test": "NODE_OPTIONS=--max-old-space-size=4096 run -T jest"
27
27
  },
28
28
  "dependencies": {
29
- "@exodus/address-provider": "^10.0.1",
30
- "@exodus/argo": "^1.0.0",
31
- "@exodus/assets-feature": "^4.0.1",
29
+ "@exodus/address-provider": "^11.0.0",
30
+ "@exodus/application": "^1.2.0",
31
+ "@exodus/argo": "^1.3.0",
32
+ "@exodus/asset-sources": "^1.1.1",
33
+ "@exodus/assets-feature": "^5.7.0",
32
34
  "@exodus/atoms": "^7.0.0",
33
- "@exodus/available-assets": "^8.1.0",
35
+ "@exodus/available-assets": "^8.2.1",
34
36
  "@exodus/balances": "^13.0.0",
35
37
  "@exodus/basic-utils": "^2.0.0",
36
38
  "@exodus/blockchain-metadata": "^15.3.0",
37
39
  "@exodus/dependency-injection": "^2.1.2",
38
- "@exodus/dependency-preprocessors": "^5.1.0",
40
+ "@exodus/dependency-preprocessors": "^5.4.0",
39
41
  "@exodus/enabled-assets": "^10.2.0",
42
+ "@exodus/error-tracking": "^1.1.1",
40
43
  "@exodus/feature-flags": "^6.0.0",
41
- "@exodus/fee-data-monitors": "^3.0.0",
44
+ "@exodus/fee-data-monitors": "^4.2.0",
42
45
  "@exodus/fetch": "^1.2.1",
43
46
  "@exodus/filesystem": "^1.1.0",
44
47
  "@exodus/fusion-atoms": "^1.1.2",
45
48
  "@exodus/geolocation": "^4.1.0",
46
49
  "@exodus/hd-key-slip-10": "^2.0.0",
47
50
  "@exodus/key-ids": "^1.0.0",
48
- "@exodus/keychain": "^6.1.0",
51
+ "@exodus/key-viewer": "^1.0.0",
52
+ "@exodus/keychain": "^6.4.0",
49
53
  "@exodus/locale": "^2.2.0",
50
- "@exodus/message-signer": "^1.1.1",
54
+ "@exodus/message-signer": "^1.2.0",
51
55
  "@exodus/module": "^1.2.2",
52
56
  "@exodus/pricing": "^1.2.0",
53
57
  "@exodus/public-key-provider": "^2.0.0",
54
- "@exodus/public-key-store": "^1.2.0",
58
+ "@exodus/public-key-store": "^1.2.1",
55
59
  "@exodus/rates-monitor": "^4.2.0",
56
60
  "@exodus/remote-config": "^2.4.0",
57
- "@exodus/restore-progress-tracker": "^3.0.0",
61
+ "@exodus/restore-progress-tracker": "^3.3.0",
58
62
  "@exodus/sodium-crypto": "^3.2.0",
59
63
  "@exodus/startup-counter": "^1.0.0",
60
- "@exodus/tx-signer": "^2.0.1",
64
+ "@exodus/tx-signer": "^2.2.0",
61
65
  "@exodus/typeforce": "^1.18.1",
62
66
  "@exodus/wallet": "^14.1.0",
63
- "@exodus/wallet-accounts": "^16.2.0",
67
+ "@exodus/wallet-accounts": "^16.6.0",
64
68
  "bip39": "^2.6.0",
65
69
  "events": "^3.3.0",
66
70
  "lodash": "npm:@exodus/lodash@^4.17.21-exodus.2",
67
71
  "minimalistic-assert": "^1.0.1"
68
72
  },
69
73
  "devDependencies": {
70
- "@exodus/ab-testing": "^7.3.0",
74
+ "@exodus/ab-testing": "^7.4.1",
71
75
  "@exodus/algorand-lib": "^2.0.1",
72
76
  "@exodus/algorand-meta": "^1.1.4",
73
- "@exodus/analytics": "^12.0.0",
74
- "@exodus/announcements": "^2.7.0",
75
- "@exodus/apy-rates": "^3.3.1",
77
+ "@exodus/analytics": "^13.1.1",
78
+ "@exodus/announcements": "^2.11.0",
79
+ "@exodus/apy-rates": "^3.4.0",
76
80
  "@exodus/assets-feature": "workspace:^",
77
81
  "@exodus/bip32": "^2.1.1",
78
82
  "@exodus/bitcoin-plugin": "^1.0.14",
79
- "@exodus/connected-origins": "^3.3.0",
83
+ "@exodus/connected-origins": "^3.3.1",
80
84
  "@exodus/crypto-news-monitor": "^5.0.0",
81
85
  "@exodus/currency": "^2.2.0",
86
+ "@exodus/deferring-storage": "^1.0.1",
82
87
  "@exodus/ethereum-lib": "^4.5.0",
83
88
  "@exodus/ethereum-meta": "^1.1.0",
84
89
  "@exodus/exodus-pricing-client": "^1.2.0",
85
- "@exodus/fetch-factory": "^1.0.0",
90
+ "@exodus/fetch-factory": "^2.2.0",
86
91
  "@exodus/key-utils": "^3.0.0",
87
- "@exodus/kyc": "^5.0.0",
92
+ "@exodus/kyc": "^6.1.2",
88
93
  "@exodus/litecoin-meta": "^1.0.0",
89
- "@exodus/market-history": "^7.4.0",
94
+ "@exodus/market-history": "^9.0.1",
90
95
  "@exodus/models": "^11.9.0",
91
- "@exodus/nfts": "^9.1.5",
96
+ "@exodus/nfts": "^9.3.1",
92
97
  "@exodus/personal-notes": "^3.6.0",
93
- "@exodus/referrals": "^8.2.0",
98
+ "@exodus/referrals": "^8.6.0",
94
99
  "@exodus/solana-lib": "^2.0.0",
95
100
  "@exodus/solana-meta": "^1.0.2",
96
- "@exodus/storage-encrypted": "^1.3.0",
101
+ "@exodus/storage-encrypted": "^1.4.1",
97
102
  "@exodus/storage-memory": "^2.1.1",
98
- "@exodus/top-movers-monitor": "^4.1.0",
99
- "@exodus/ui-config": "^3.6.1",
103
+ "@exodus/top-movers-monitor": "^4.2.1",
104
+ "@exodus/ui-config": "^3.7.0",
100
105
  "@exodus/wild-emitter": "^1.0.0",
101
106
  "buffer-json": "^2.0.0",
102
107
  "deepmerge": "^4.2.2",
@@ -106,5 +111,5 @@
106
111
  "msw": "^2.0.0",
107
112
  "p-defer": "^4.0.0"
108
113
  },
109
- "gitHead": "34f1dab70f6c2fc0062d946f5c74ae84e5379539"
114
+ "gitHead": "0708b3bfdf16a3cf2989988b30d68d8a2b949358"
110
115
  }
package/src/api/index.js CHANGED
@@ -4,10 +4,9 @@ import assert from 'minimalistic-assert'
4
4
  import createDebug from './debug'
5
5
  import createReporting from './reporting'
6
6
 
7
- const createApi = ({ ioc, port, config, debug }) => {
7
+ const createApi = ({ ioc, port, config, debug, logger }) => {
8
8
  const apis = ioc.getByType('api')
9
-
10
- const { application, passphraseCache } = ioc.getByType('module')
9
+ const { application } = ioc.get('applicationApi')
11
10
 
12
11
  const featureApis = Object.create(null)
13
12
  for (const api of Object.values(apis)) {
@@ -28,35 +27,36 @@ const createApi = ({ ioc, port, config, debug }) => {
28
27
  }
29
28
  }
30
29
 
31
- const restoreFromCurrentPhrase = async ({ passphrase } = {}) => {
32
- if (!passphrase && passphraseCache) passphrase = await passphraseCache.get()
33
- const mnemonic = await application.getMnemonic({ passphrase })
34
- await application.import({ passphrase, mnemonic })
30
+ const deprecated = (fn) => {
31
+ return (...args) => {
32
+ logger.warn(
33
+ `"wallet.${fn.name}" is deprecated and will be removed soon, please use "application.${fn.name}"`
34
+ )
35
+ return fn(...args)
36
+ }
35
37
  }
36
38
 
37
- // TODO: Improve api here. exodus.wallet.create makes sense, but it's confusing it calls application
38
39
  featureApis.wallet = {
39
40
  ...featureApis.wallet,
40
41
  addSeed: application.addSeed,
41
- start: application.start,
42
- stop: application.stop,
43
- load: application.load,
44
- unload: application.unload,
45
- create: application.create,
46
- lock: application.lock,
47
- unlock: application.unlock,
48
- import: application.import,
49
- delete: application.delete,
50
- getMnemonic: application.getMnemonic,
51
- setBackedUp: application.setBackedUp,
52
- changePassphrase: application.changePassphrase,
53
- changeLockTimer: application.changeLockTimer,
54
- restartAutoLockTimer: application.restartAutoLockTimer,
55
- restoreFromCurrentPhrase,
42
+ start: deprecated(application.start),
43
+ stop: deprecated(application.stop),
44
+ load: deprecated(application.load),
45
+ unload: deprecated(application.unload),
46
+ create: deprecated(application.create),
47
+ lock: deprecated(application.lock),
48
+ unlock: deprecated(application.unlock),
49
+ import: deprecated(application.import),
50
+ delete: deprecated(application.delete),
51
+ getMnemonic: deprecated(application.getMnemonic),
52
+ setBackedUp: deprecated(application.setBackedUp),
53
+ changePassphrase: deprecated(application.changePassphrase),
54
+ changeLockTimer: deprecated(application.changeLockTimer),
55
+ restartAutoLockTimer: deprecated(application.restartAutoLockTimer),
56
+ restoreFromCurrentPhrase: deprecated(application.restoreFromCurrentPhrase),
56
57
  }
57
58
 
58
59
  const debugApi = createDebug({ ioc, port, debug })
59
-
60
60
  const reportingApi = createReporting({ ioc, config })
61
61
 
62
62
  const api = {
@@ -3,6 +3,7 @@ import { zipObject } from 'lodash'
3
3
  import { rejectAfter } from '../utils/promises'
4
4
 
5
5
  const createReporting = ({ ioc, config: { exportTimeout = 2000 } }) => {
6
+ const logger = ioc.get('createLogger')('reporting')
6
7
  const nodes = ioc.getByType('report')
7
8
 
8
9
  const { lockedAtom } = ioc.getByType('atom')
@@ -17,8 +18,16 @@ const createReporting = ({ ioc, config: { exportTimeout = 2000 } }) => {
17
18
  `Export took longer than the maximum export timeout of ${Math.ceil(exportTimeout / 1000)}s`
18
19
  )
19
20
 
21
+ const exportReport = async (report) => {
22
+ const start = performance.now()
23
+ const result = await report.export()
24
+ const duration = performance.now() - start
25
+ logger.debug(`Exported report for ${report.namespace} in ${duration}ms`)
26
+ return result
27
+ }
28
+
20
29
  const resolvedReports = await Promise.allSettled(
21
- reports.map((report) => Promise.race([report.export(), timeoutPromise]))
30
+ reports.map((report) => Promise.race([exportReport(report), timeoutPromise]))
22
31
  )
23
32
 
24
33
  const namespaces = reports.map((report) => report.namespace)
package/src/index.d.ts CHANGED
@@ -1,11 +1,14 @@
1
1
  import addressProvider from '@exodus/address-provider'
2
2
  import { Argo, Definition, Feature, InstanceById } from '@exodus/argo'
3
+ import assetSources from '@exodus/asset-sources'
3
4
  import assets from '@exodus/assets-feature'
4
5
  import availableAssets from '@exodus/available-assets'
5
6
  import blockchainMetadata from '@exodus/blockchain-metadata'
6
7
  import enabledAssets from '@exodus/enabled-assets'
7
8
  import featureFlags from '@exodus/feature-flags'
8
- import fees from '@exodus/fee-data-monitors' // eslint-disable-line @typescript-eslint/no-unused-vars
9
+ import fees from '@exodus/fee-data-monitors'
10
+ import keyViewer from '@exodus/key-viewer'
11
+ import keychain from '@exodus/keychain'
9
12
  import locale from '@exodus/locale'
10
13
  import messageSigner from '@exodus/message-signer'
11
14
  import pricing from '@exodus/pricing'
@@ -16,18 +19,18 @@ import txSigner from '@exodus/tx-signer'
16
19
  import wallet from '@exodus/wallet'
17
20
  import walletAccounts from '@exodus/wallet-accounts'
18
21
 
19
- type ApiDefinitions<F extends Feature<any>> = Extract<
22
+ type ApiDefinitions<F extends Feature> = Extract<
20
23
  F['definitions'][number]['definition'],
21
24
  { type: 'api' }
22
25
  >
23
26
 
24
27
  type Values<D extends object> = D[keyof D]
25
28
 
26
- type FeatureFactory<F extends Feature<any>> = (...args: any[]) => F
29
+ type FeatureFactory = (...args: any[]) => Feature
27
30
 
28
- type FeatureApi<F extends FeatureFactory<any>> = Values<InstanceById<ApiDefinitions<ReturnType<F>>>>
31
+ type FeatureApi<F extends FeatureFactory> = Values<InstanceById<ApiDefinitions<ReturnType<F>>>>
29
32
 
30
- interface ApplicationWalletApi {
33
+ export interface ApplicationWalletApi {
31
34
  addSeed(params: { mnemonic: string; compatibilityMode: string }): Promise<void>
32
35
  start(): Promise<void>
33
36
  stop(): Promise<void>
@@ -71,7 +74,11 @@ export type ExodusApi = FeatureApi<typeof publicKeyProvider> &
71
74
  FeatureApi<typeof pricing> &
72
75
  FeatureApi<typeof rates> &
73
76
  FeatureApi<typeof featureFlags> &
74
- WalletApi // & FeatureApi<typeof fees> TODO: uncomment after updating to fee-data-monitors
77
+ FeatureApi<typeof fees> &
78
+ FeatureApi<typeof keychain> &
79
+ FeatureApi<typeof keyViewer> &
80
+ FeatureApi<typeof assetSources> &
81
+ WalletApi
75
82
 
76
83
  type Params = {
77
84
  adapters: Record<string, any>
@@ -79,6 +86,6 @@ type Params = {
79
86
  debug?: boolean
80
87
  }
81
88
 
82
- export default function createExodus<D extends Definition<any, any>>(
89
+ export default function createExodus<D extends Definition>(
83
90
  params: Params
84
- ): Argo<D> & { resolve: () => ExodusApi }
91
+ ): Omit<Argo<D>, 'resolve'> & { resolve: () => ExodusApi }
package/src/index.js CHANGED
@@ -1,14 +1,18 @@
1
1
  import addressProvider from '@exodus/address-provider'
2
+ import application from '@exodus/application'
2
3
  import createIOC from '@exodus/argo'
4
+ import assetSources from '@exodus/asset-sources'
3
5
  import assetsFeature from '@exodus/assets-feature'
4
6
  import availableAssets from '@exodus/available-assets'
5
7
  import balances from '@exodus/balances'
6
8
  import blockchainMetadata from '@exodus/blockchain-metadata'
7
9
  import enabledAssets from '@exodus/enabled-assets'
10
+ import errorTracking from '@exodus/error-tracking'
8
11
  import featureFlags from '@exodus/feature-flags'
9
12
  import fees from '@exodus/fee-data-monitors'
10
13
  import filesystem from '@exodus/filesystem'
11
14
  import geolocation from '@exodus/geolocation'
15
+ import keyViewer from '@exodus/key-viewer'
12
16
  import keychain from '@exodus/keychain'
13
17
  import locale from '@exodus/locale'
14
18
  import messageSigner from '@exodus/message-signer'
@@ -25,7 +29,6 @@ import wallet from '@exodus/wallet'
25
29
  import walletAccounts from '@exodus/wallet-accounts'
26
30
 
27
31
  import createApi from './api'
28
- import application from './application'
29
32
  import createDependencies from './dependencies'
30
33
  import attachMigrations from './migrations/attach'
31
34
  import attachPlugins from './plugins/attach'
@@ -45,29 +48,32 @@ const createExodus = (opts) => {
45
48
  const ioc = createIOC({ adapters, config, debug })
46
49
 
47
50
  ioc.use(application())
51
+ ioc.use(errorTracking())
48
52
  ioc.use(addressProvider({ config: config.addressProvider, debug }))
49
- ioc.use(assetsFeature())
50
- ioc.use(availableAssets())
53
+ ioc.use(assetsFeature(config.assets))
54
+ ioc.use(availableAssets(config.availableAssets))
55
+ ioc.use(assetSources(config.assetSources))
51
56
  ioc.use(balances(config.balances))
52
- ioc.use(blockchainMetadata())
53
- ioc.use(enabledAssets())
57
+ ioc.use(blockchainMetadata(config.blockchainMetadata))
58
+ ioc.use(enabledAssets(config.enabledAssets))
54
59
  ioc.use(featureFlags(config.featureFlags))
55
- ioc.use(fees())
56
- ioc.use(filesystem())
57
- ioc.use(geolocation())
60
+ ioc.use(fees(config.fees))
61
+ ioc.use(filesystem(config.filesystem))
62
+ ioc.use(geolocation(config.geolocation))
58
63
  ioc.use(keychain(config.keychain))
59
- ioc.use(locale())
60
- ioc.use(messageSigner())
61
- ioc.use(pricing())
62
- ioc.use(publicKeyProvider())
63
- ioc.use(publicKeyStore())
64
- ioc.use(rates())
65
- ioc.use(remoteConfig())
66
- ioc.use(restoreProgressTracker())
67
- ioc.use(startupCounter())
68
- ioc.use(transactionSigner())
69
- ioc.use(wallet())
70
- ioc.use(walletAccounts())
64
+ ioc.use(keyViewer(config.keyViewer))
65
+ ioc.use(locale(config.locale))
66
+ ioc.use(messageSigner(config.messageSigner))
67
+ ioc.use(pricing(config.pricing))
68
+ ioc.use(publicKeyProvider(config.publicKeyProvider))
69
+ ioc.use(publicKeyStore(config.publicKeyStore))
70
+ ioc.use(rates(config.rates))
71
+ ioc.use(remoteConfig(config.remoteConfig))
72
+ ioc.use(restoreProgressTracker(config.restoreProgressTracker))
73
+ ioc.use(startupCounter(config.startupCounter))
74
+ ioc.use(transactionSigner(config.transactionSigner))
75
+ ioc.use(wallet(config.wallet))
76
+ ioc.use(walletAccounts(config.walletAccounts))
71
77
 
72
78
  ioc.registerMultiple(createDependencies({ adapters, config }))
73
79
 
@@ -115,6 +121,13 @@ const createExodus = (opts) => {
115
121
 
116
122
  application.on('add-seed', () => port.emit('add-seed'))
117
123
 
124
+ application.on(
125
+ 'restore-seed',
126
+ () =>
127
+ ({ seedId, compatibilityMode } = Object.create(null)) =>
128
+ port.emit('restore-seed', { seedId, compatibilityMode })
129
+ )
130
+
118
131
  application.hook('unlock', async () => {
119
132
  if (typeof storage.unlock === 'function') unlockEncryptedStorage(storage)
120
133
 
@@ -133,6 +146,7 @@ const createExodus = (opts) => {
133
146
  application,
134
147
  atoms: ioc.getByType('atom'),
135
148
  modules: ioc.getByType('module'),
149
+ config,
136
150
  })
137
151
 
138
152
  attachPlugins({
@@ -141,7 +155,7 @@ const createExodus = (opts) => {
141
155
  logger: ioc.get('createLogger')('attachPlugins'),
142
156
  })
143
157
 
144
- return createApi({ ioc, port, config, debug })
158
+ return createApi({ ioc, port, config, debug, logger: ioc.get('createLogger')('createApi') })
145
159
  }
146
160
 
147
161
  return { ...ioc, resolve }
@@ -1,6 +1,6 @@
1
1
  import { deriveSyncKeys } from '../utils/fusion'
2
2
 
3
- const attachMigrations = ({ migrations = [], application, modules, adapters, ...deps }) => {
3
+ const attachMigrations = ({ migrations = [], application, modules, adapters, config, ...deps }) => {
4
4
  const { unsafeStorage, migrateableStorage } = adapters
5
5
  const { analytics, unlockEncryptedStorage, wallet, fusionKeysDeferred, migrateableFusion } =
6
6
  modules
@@ -21,7 +21,13 @@ const attachMigrations = ({ migrations = [], application, modules, adapters, ...
21
21
  try {
22
22
  const start = performance.now()
23
23
 
24
- await factory({ ...deps, adapters: migrationAdapters, modules: migrationModules, logger })
24
+ await factory({
25
+ ...deps,
26
+ config,
27
+ adapters: migrationAdapters,
28
+ modules: migrationModules,
29
+ logger,
30
+ })
25
31
 
26
32
  const time = performance.now() - start
27
33
 
@@ -1,4 +1,4 @@
1
- import { LifecycleHook } from '../application/constants'
1
+ import { LifecycleHook } from '@exodus/application'
2
2
 
3
3
  const LIFECYCLE_METHOD_TO_HOOK_NAME = Object.fromEntries(
4
4
  Object.entries(LifecycleHook).map(([pascalCaseName, hookName]) => [
@@ -1,9 +0,0 @@
1
- import { createStorageAtomFactory } from '@exodus/atoms'
2
-
3
- const createBackedUpAtom = ({ storage }) => {
4
- const atomFactory = createStorageAtomFactory({ storage })
5
-
6
- return atomFactory({ key: 'backedUp', defaultValue: false, isSoleWriter: true })
7
- }
8
-
9
- export default createBackedUpAtom
@@ -1,4 +0,0 @@
1
- import { createFusionAtom } from '@exodus/fusion-atoms'
2
-
3
- export const createWalletCreatedAtAtom = ({ fusion, logger }) =>
4
- createFusionAtom({ fusion, logger, path: 'createdAt', defaultValue: new Date().toISOString() })
@@ -1,40 +0,0 @@
1
- import createBackedUpAtom from './backed-up'
2
- import { createWalletCreatedAtAtom } from './created-at'
3
- import createLockHistoryAtom from './lock-history'
4
- import createdLockedAtom from './locked'
5
- import createRestoreAtom from './restore'
6
-
7
- export const lockedAtomDefinition = {
8
- id: 'lockedAtom',
9
- type: 'atom',
10
- factory: createdLockedAtom,
11
- dependencies: [],
12
- }
13
-
14
- export const lockHistoryAtomDefinition = {
15
- id: 'lockHistoryAtom',
16
- type: 'atom',
17
- factory: createLockHistoryAtom,
18
- dependencies: ['lockedAtom', 'config?'],
19
- }
20
-
21
- export const restoreAtomDefinition = {
22
- id: 'restoreAtom',
23
- type: 'atom',
24
- factory: createRestoreAtom,
25
- dependencies: [],
26
- }
27
-
28
- export const backedUpAtomDefinition = {
29
- id: 'backedUpAtom',
30
- type: 'atom',
31
- factory: createBackedUpAtom,
32
- dependencies: ['storage'],
33
- }
34
-
35
- export const walletCreatedAtAtomDefinition = {
36
- id: 'walletCreatedAtAtom',
37
- type: 'atom',
38
- factory: createWalletCreatedAtAtom,
39
- dependencies: ['fusion', 'logger'],
40
- }
@@ -1,15 +0,0 @@
1
- import { createInMemoryAtom, difference } from '@exodus/atoms'
2
-
3
- const createLockHistoryAtom = ({ lockedAtom, config: { maxEntries = 10 } = {} }) => {
4
- const lockHistory = createInMemoryAtom({ defaultValue: [] })
5
-
6
- difference(lockedAtom).observe(async ({ current: locked, previous: previouslyLocked }) => {
7
- await lockHistory.set((current) =>
8
- [{ locked, timestamp: new Date() }, ...current].slice(0, maxEntries)
9
- )
10
- })
11
-
12
- return lockHistory
13
- }
14
-
15
- export default createLockHistoryAtom
@@ -1,5 +0,0 @@
1
- import { createInMemoryAtom } from '@exodus/atoms'
2
-
3
- const createLockedAtom = () => createInMemoryAtom({ defaultValue: true })
4
-
5
- export default createLockedAtom
@@ -1,5 +0,0 @@
1
- import { createInMemoryAtom } from '@exodus/atoms'
2
-
3
- const createRestoreAtom = () => createInMemoryAtom() // eslint-disable-line @exodus/hydra/in-memory-atom-default-value
4
-
5
- export default createRestoreAtom
@@ -1,18 +0,0 @@
1
- export const LifecycleHook = Object.freeze({
2
- Lock: 'lock',
3
- Unlock: 'unlock',
4
- Clear: 'clear',
5
- Import: 'import',
6
- AddSeed: 'add-seed',
7
- Migrate: 'migrate',
8
- Start: 'start',
9
- Stop: 'stop',
10
- Restart: 'restart',
11
- Load: 'load',
12
- Unload: 'unload',
13
- Create: 'create',
14
- Restore: 'restore',
15
- RestoreCompleted: 'restore-completed',
16
- AssetsSynced: 'assets-synced',
17
- ChangePassphrase: 'change-passphrase',
18
- })
@@ -1,30 +0,0 @@
1
- import {
2
- backedUpAtomDefinition,
3
- lockedAtomDefinition,
4
- lockHistoryAtomDefinition,
5
- restoreAtomDefinition,
6
- walletCreatedAtAtomDefinition,
7
- } from './atoms'
8
- import applicationDefinition from './module'
9
- import applicationLifecyclePluginDefinition from './plugins/lifecycle'
10
-
11
- const application = () => {
12
- return {
13
- id: 'application',
14
- definitions: [
15
- { definition: applicationDefinition },
16
- { definition: lockedAtomDefinition },
17
- { definition: restoreAtomDefinition },
18
- { definition: lockHistoryAtomDefinition },
19
- { definition: walletCreatedAtAtomDefinition },
20
- { definition: applicationLifecyclePluginDefinition },
21
- {
22
- definition: backedUpAtomDefinition,
23
- storage: { namespace: 'wallet' },
24
- aliases: [{ interfaceId: 'storage', implementationId: 'unsafeStorage' }],
25
- },
26
- ],
27
- }
28
- }
29
-
30
- export default application
@@ -1,344 +0,0 @@
1
- /* eslint-disable unicorn/no-for-loop */
2
-
3
- import ExodusModule from '@exodus/module' // eslint-disable-line import/no-deprecated
4
- import assert from 'minimalistic-assert'
5
-
6
- import { LifecycleHook as Hook } from '../constants'
7
-
8
- // Because we are forced to restart wallet after deleting/importing, we need to store certain flags to persist state between executions
9
-
10
- // Triggers deletetion logic when wallet starts.
11
- // Set as true on delete method is called, and set to false when wallet is restarted
12
- const DELETE_FLAG = 'deleteFlag'
13
-
14
- // Triggers import logic when wallet starts. Used when overwriting existing wallet (not importing one from scratch)
15
- // Set as true on import method is called, and set to false when wallet is restarted
16
- const IMPORT_FLAG = 'importFlag'
17
-
18
- // Triggers restore logic. We need to do it after any import, no matter if there was a previous wallet or not
19
- // Set as true on import method is called, and set to false after restore is completed
20
- const RESTORE_FLAG = 'restoreFlag'
21
-
22
- const HOOKS = new Set(Object.values(Hook))
23
-
24
- const passphraseCachePlaceholder = {
25
- get: () => {},
26
- set: () => {},
27
- changeTtl: () => {},
28
- clear: () => {},
29
- scheduleClear: () => {},
30
- }
31
-
32
- class Application extends ExodusModule {
33
- #hooks = {}
34
- #wallet
35
- #lockedAtom
36
- #backedUpAtom
37
- #passphraseCache
38
- #applicationStarted
39
- #resolveStart
40
- #flagsStorage
41
- #storage
42
-
43
- constructor({
44
- wallet,
45
- unsafeStorage,
46
- lockedAtom,
47
- backedUpAtom,
48
- passphraseCache = passphraseCachePlaceholder,
49
- logger,
50
- }) {
51
- super({ name: 'Application', logger })
52
-
53
- this.#wallet = wallet
54
- this.#lockedAtom = lockedAtom
55
- this.#backedUpAtom = backedUpAtom
56
- this.#passphraseCache = passphraseCache
57
- this.#flagsStorage = unsafeStorage.namespace('flags')
58
- this.#storage = unsafeStorage.namespace('application')
59
-
60
- this.#applicationStarted = new Promise((resolve) => (this.#resolveStart = resolve))
61
- this.setMaxListeners(Number.POSITIVE_INFINITY)
62
- }
63
-
64
- start = async () => {
65
- const [deleteFlag, importFlag] = await this.#flagsStorage.batchGet([DELETE_FLAG, IMPORT_FLAG])
66
-
67
- const isDeleting = !!deleteFlag
68
- const isImporting = !!importFlag
69
-
70
- if (isDeleting) await this.#wallet.clear()
71
-
72
- if (isDeleting || isImporting) {
73
- await this.#flagsStorage.batchDelete([DELETE_FLAG, IMPORT_FLAG])
74
- await this.#passphraseCache.clear()
75
- }
76
-
77
- const walletExists = await this.#wallet.exists()
78
-
79
- if (isImporting || !walletExists) {
80
- await this.fire(Hook.Clear, null, { concurrent: true })
81
- }
82
-
83
- if (isImporting) {
84
- const params = await this.#storage.get('importParams')
85
- await this.fire(Hook.Import, params)
86
- }
87
-
88
- const [hasPassphraseSet, isLocked, isBackedUp, isRestoring] = await Promise.all([
89
- this.#wallet.hasPassphraseSet(),
90
- this.#wallet.isLocked(),
91
- this.isBackedUp(),
92
- this.isRestoring(),
93
- ])
94
-
95
- await this.fire(Hook.Start, {
96
- walletExists,
97
- hasPassphraseSet,
98
- isLocked,
99
- isBackedUp,
100
- isRestoring,
101
- })
102
-
103
- await this.#autoUnlock()
104
-
105
- const locked = await this.#wallet.isLocked()
106
- this._logger.log('wallet is locked', locked)
107
-
108
- this.#resolveStart()
109
- }
110
-
111
- load = async () => {
112
- await this.#applicationStarted
113
-
114
- const [walletExists, hasPassphraseSet, isLocked, isBackedUp, isRestoring] = await Promise.all([
115
- this.#wallet.exists(),
116
- this.#wallet.hasPassphraseSet(),
117
- this.#wallet.isLocked(),
118
- this.isBackedUp(),
119
- this.isRestoring(),
120
- ])
121
-
122
- await this.fire(Hook.Load, {
123
- walletExists,
124
- hasPassphraseSet,
125
- isLocked,
126
- isBackedUp,
127
- isRestoring,
128
- })
129
- }
130
-
131
- unload = async () => {
132
- await this.#applicationStarted
133
- await this.#passphraseCache.scheduleClear()
134
- await this.fire(Hook.Unload)
135
- }
136
-
137
- hook = (hookName, listener) => {
138
- assert(HOOKS.has(hookName), `no such hook: ${hookName}`)
139
-
140
- if (!this.#hooks[hookName]) {
141
- this.#hooks[hookName] = []
142
- }
143
-
144
- this.#hooks[hookName].push(listener)
145
- }
146
-
147
- fire = async (hookName, params, { concurrent } = {}) => {
148
- assert(HOOKS.has(hookName), `no such hook: ${hookName}`)
149
-
150
- this._logger.debug(`firing hooks ${concurrent ? 'concurrently' : 'sequentially'}`, hookName)
151
-
152
- const hooks = this.#hooks[hookName] || []
153
-
154
- const hookFns = hooks.map((hook) => async () => {
155
- try {
156
- await hook(params)
157
- } catch (err) {
158
- this._logger.error(`application lifecycle hook failed: ${hookName}`, hook.name, params, err)
159
- throw err
160
- }
161
- })
162
-
163
- if (concurrent) {
164
- await Promise.allSettled(hookFns.map((promise) => promise()))
165
- } else {
166
- for (let i = 0; i < hookFns.length; i++) {
167
- await hookFns[i]()
168
- }
169
- }
170
-
171
- this.emit(hookName, params)
172
- }
173
-
174
- create = async (opts) => {
175
- this._logger.log('creating wallet')
176
-
177
- await this.#applicationStarted
178
- const seedId = await this.#wallet.create(opts)
179
-
180
- const isLocked = await this.#wallet.isLocked()
181
-
182
- await this.fire(Hook.Create, {
183
- hasPassphraseSet: !!opts?.passphrase,
184
- isBackedUp: false,
185
- isLocked,
186
- isRestoring: false,
187
- walletExists: true,
188
- seedId,
189
- })
190
- }
191
-
192
- import = async (opts) => {
193
- this._logger.log('importing wallet')
194
-
195
- await this.#flagsStorage.set(RESTORE_FLAG, true)
196
-
197
- await this.#applicationStarted
198
-
199
- const walletExists = await this.#wallet.exists()
200
-
201
- const { forceRestart, forgotPassphrase, compatibilityMode, ...wallet } = opts
202
-
203
- const seedId = await this.#wallet.import(wallet)
204
- const importParams = { seedId, compatibilityMode }
205
-
206
- if (forceRestart || walletExists) {
207
- await this.#flagsStorage.set(IMPORT_FLAG, true)
208
-
209
- await this.#storage.set('importParams', importParams)
210
- await this.fire(Hook.Restart, { reason: 'import' })
211
- } else {
212
- await this.fire(Hook.Import, importParams)
213
-
214
- this._logger.log('wallet imported')
215
- }
216
- }
217
-
218
- addSeed = async ({ mnemonic, compatibilityMode }) => {
219
- this._logger.log('adding seed to wallet')
220
-
221
- await this.#applicationStarted
222
-
223
- const seedId = await this.#wallet.addSeed({ mnemonic })
224
- await this.fire(Hook.AddSeed, { seedId, compatibilityMode })
225
- }
226
-
227
- getMnemonic = async (opts) => this.#wallet.getMnemonic(opts)
228
-
229
- setBackedUp = async () => {
230
- await this.#backedUpAtom.set(true)
231
- }
232
-
233
- lock = async (opts) => {
234
- this._logger.log('locking')
235
-
236
- await this.#applicationStarted
237
- await this.#wallet.lock(opts)
238
- await this.#lockedAtom.set(true)
239
- await this.#passphraseCache.clear()
240
- await this.fire(Hook.Lock)
241
-
242
- this._logger.log('locked')
243
- }
244
-
245
- #restoreIfNeeded = async () => {
246
- const isRestoring = await this.isRestoring()
247
-
248
- if (isRestoring) {
249
- await this.fire(Hook.Restore)
250
- await this.#flagsStorage.delete(RESTORE_FLAG)
251
- await this.fire(Hook.RestoreCompleted)
252
- }
253
-
254
- this.fire(Hook.AssetsSynced).catch((e) => {
255
- console.warn('failed to execute onAssetsSynced hooks', e)
256
- })
257
- }
258
-
259
- restore = async () => {
260
- await this.#flagsStorage.set(RESTORE_FLAG, true)
261
- await this.#restoreIfNeeded()
262
- }
263
-
264
- #autoUnlock = async () => {
265
- const walletLocked = await this.#wallet.isLocked()
266
- const passphrase = await this.#passphraseCache.get()
267
-
268
- if (!walletLocked || !passphrase) return
269
-
270
- try {
271
- this._logger.log('unlocking with cache')
272
-
273
- await this.#wallet.unlock({ passphrase })
274
- await this.#lockedAtom.set(false)
275
-
276
- await this.fire(Hook.Migrate)
277
- await this.fire(Hook.Unlock)
278
-
279
- this.#restoreIfNeeded()
280
-
281
- this._logger.log('unlocked with cache')
282
- } catch (err) {
283
- this._logger.error('failed to unlock, outdated cached passphrase?', err)
284
- }
285
- }
286
-
287
- unlock = async ({ passphrase } = {}) => {
288
- this._logger.log('unlocking')
289
-
290
- await this.#applicationStarted
291
- await this.#wallet.unlock({ passphrase })
292
- await this.#lockedAtom.set(false)
293
-
294
- await this.fire(Hook.Migrate)
295
- await this.fire(Hook.Unlock)
296
-
297
- this.#restoreIfNeeded()
298
-
299
- if (passphrase) this.#passphraseCache.set(passphrase)
300
-
301
- this._logger.log('unlocked')
302
- }
303
-
304
- changePassphrase = async ({ currentPassphrase, newPassphrase }) => {
305
- this._logger.log('changing passphrase')
306
-
307
- await this.#applicationStarted
308
- await this.#wallet.changePassphrase({ currentPassphrase, newPassphrase })
309
- await this.#passphraseCache.set(newPassphrase)
310
- await this.fire(Hook.ChangePassphrase)
311
-
312
- this._logger.log('passphrase changed')
313
- }
314
-
315
- delete = async ({ forgotPassphrase, restartOptions } = {}) => {
316
- await this.#flagsStorage.set(DELETE_FLAG, true)
317
- await this.fire(Hook.Restart, { ...restartOptions, reason: 'delete', forgotPassphrase })
318
- }
319
-
320
- stop = async () => {
321
- await this.fire(Hook.Stop)
322
- }
323
-
324
- changeLockTimer = async ({ ttl }) => {
325
- await this.#passphraseCache.changeTtl(ttl)
326
- }
327
-
328
- restartAutoLockTimer = async () => {
329
- await this.#passphraseCache.scheduleClear()
330
- }
331
-
332
- isRestoring = async () => {
333
- return this.#flagsStorage.get(RESTORE_FLAG)
334
- }
335
-
336
- // TODO: stop emitting this on hooks?
337
- isBackedUp = async () => {
338
- return this.#backedUpAtom.get()
339
- }
340
- }
341
-
342
- const createApplication = (args = {}) => new Application({ ...args })
343
-
344
- export default createApplication
@@ -1,17 +0,0 @@
1
- import createApplication from './application'
2
-
3
- const applicationDefinition = {
4
- id: 'application',
5
- type: 'module',
6
- factory: createApplication,
7
- dependencies: [
8
- 'unsafeStorage',
9
- 'backedUpAtom',
10
- 'lockedAtom',
11
- 'passphraseCache?',
12
- 'wallet',
13
- 'logger',
14
- ],
15
- }
16
-
17
- export default applicationDefinition
@@ -1 +0,0 @@
1
- export { default as lifecyclePluginDefinition } from './lifecycle'
@@ -1,52 +0,0 @@
1
- import { createAtomObserver } from '@exodus/atoms'
2
-
3
- const applicationLifecyclePlugin = ({
4
- port,
5
- lockedAtom,
6
- lockHistoryAtom,
7
- restoreAtom,
8
- backedUpAtom,
9
- }) => {
10
- const observers = [
11
- createAtomObserver({ port, atom: lockedAtom, event: 'locked' }),
12
- createAtomObserver({ port, atom: lockHistoryAtom, event: 'lockHistory' }),
13
- createAtomObserver({ port, atom: restoreAtom, event: 'restore' }),
14
- createAtomObserver({ port, atom: backedUpAtom, event: 'backedUp' }),
15
- ]
16
-
17
- const onStart = ({ isRestoring }) => {
18
- restoreAtom.set(isRestoring)
19
- }
20
-
21
- const onLoad = async () => {
22
- observers.forEach((observer) => observer.start())
23
- }
24
-
25
- const onImport = () => {
26
- backedUpAtom.set(true)
27
- restoreAtom.set(true)
28
- }
29
-
30
- const onAssetsSynced = async () => {
31
- await restoreAtom.set(false)
32
- }
33
-
34
- const onStop = () => {
35
- observers.forEach((observer) => observer.unregister())
36
- }
37
-
38
- const onClear = async () => {
39
- await backedUpAtom.set(undefined)
40
- }
41
-
42
- return { onStart, onLoad, onImport, onAssetsSynced, onStop, onClear }
43
- }
44
-
45
- const applicationLifecyclePluginDefinition = {
46
- id: 'applicationLifecyclePlugin',
47
- type: 'plugin',
48
- factory: applicationLifecyclePlugin,
49
- dependencies: ['port', 'lockedAtom', 'lockHistoryAtom', 'restoreAtom', 'backedUpAtom'],
50
- }
51
-
52
- export default applicationLifecyclePluginDefinition