@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/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 exodusContainer = createExodus({ port, adapters, config })
28
+ const container = createExodus({ port, adapters, config })
30
29
 
31
30
  // 4. Register external modules. Does not support overriding modules at the moment.
32
- exodusContainer.register({
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 = exodusContainer.resolve()
47
-
48
- // 6. Start exodus instance
49
- await exodus.wallet.start()
40
+ const exodus = container.resolve()
50
41
 
51
- // 7. Use it!
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
- ### wallet
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
- ### isMnemonicValid
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
- ### walletAccounts
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
- ### blockchainMetadata
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
- ### assets
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
- ### locale
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
- ### subscribe
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.149",
4
- "description": "The platform-agnostic Exodus wallet SDK",
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/sdks/headless",
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": "NODE_OPTIONS=--max-old-space-size=4096 jest"
26
+ "test": "jest"
27
27
  },
28
28
  "dependencies": {
29
- "@exodus/address-provider": "^9.0.1",
30
- "@exodus/assets-feature": "^4.0.0",
31
- "@exodus/atoms": "^7.0.0",
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": "^15.0.0",
37
- "@exodus/dependency-injection": "^2.1.0",
38
- "@exodus/dependency-preprocessors": "^4.0.0",
39
- "@exodus/enabled-assets": "^9.0.1",
40
- "@exodus/feature-flags": "^5.1.0",
41
- "@exodus/fee-data-monitors": "^3.0.0",
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": "^3.0.0",
44
- "@exodus/hd-key-slip-10": "^2.0.0",
45
- "@exodus/key-identifier-provider": "^1.4.0",
46
- "@exodus/keychain": "^4.3.0",
47
- "@exodus/locale": "^2.0.2",
48
- "@exodus/module": "^1.2.2",
49
- "@exodus/pricing": "^1.1.0",
50
- "@exodus/public-key-store": "^1.2.0",
51
- "@exodus/rates-monitor": "^4.0.2",
52
- "@exodus/remote-config": "^2.3.0",
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": "npm:@exodus/lodash@^4.17.21-exodus.2",
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/ab-testing": "^7.1.0",
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": "^3.3.34",
57
+ "@exodus/ethereum-lib": "^2.22.2",
76
58
  "@exodus/ethereum-meta": "^1.0.23",
77
- "@exodus/exodus-pricing-client": "^1.2.0",
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": "^2.1.1",
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
- "delay": "^5.0.0",
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": "20d96231a08ff6a8cad77f5c7ef8f9b62627656f"
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
@@ -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 HOOKS = new Set(Object.values(Hook))
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 passphraseCachePlaceholder = {
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 = passphraseCachePlaceholder, logger }) {
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, null, { concurrent: true })
74
+ await this.fire(Hook.Clear)
68
75
  }
69
76
 
70
77
  if (isImporting) await this.fire(Hook.Import)
71
78
 
72
- const [hasPassphraseSet, isLocked, isBackedUp, isRestoring] = await Promise.all([
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, { concurrent } = {}) => {
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
- const hookFns = hooks.map((hook) => async () => {
139
- try {
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
- const isLocked = await this.#wallet.isLocked()
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, forgotPassphrase, ...wallet } = opts
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
- await this.fire(Hook.Restart, { reason: 'import' })
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 ({ forgotPassphrase } = {}) => {
247
+ delete = async () => {
285
248
  await this.#storage.set(DELETE_FLAG, true)
286
- await this.fire(Hook.Restart, { reason: 'delete', forgotPassphrase })
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 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
+ export const atomsToAttach = [
2
+ 'availableAssetNamesAtom',
3
+ 'balancesAtom',
4
+ 'currencyAtom',
5
+ 'enabledWalletAccountsAtom',
6
+ 'geolocationAtom',
7
+ 'languageAtom',
8
+ 'walletAccountsAtom',
9
+ ]