@exodus/headless 4.0.1 → 5.0.0-rc.0
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 +18 -0
- package/README.md +2 -2
- package/package.json +9 -7
- package/src/application/module/application.js +32 -24
- package/src/index.js +14 -2
- package/src/plugins/analytics.js +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,24 @@
|
|
|
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.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@4.0.1...@exodus/headless@5.0.0-rc.0) (2024-04-15)
|
|
7
|
+
|
|
8
|
+
### ⚠ BREAKING CHANGES
|
|
9
|
+
|
|
10
|
+
- accept port via adapters (#6362)
|
|
11
|
+
- assets balance fields (#5933)
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
- accept port via adapters ([#6362](https://github.com/ExodusMovement/exodus-hydra/issues/6362)) ([8c5619a](https://github.com/ExodusMovement/exodus-hydra/commit/8c5619a11a63a8eda5a193e1cd5242696a480cd2))
|
|
16
|
+
- assets balance fields ([#5933](https://github.com/ExodusMovement/exodus-hydra/issues/5933)) ([000eb65](https://github.com/ExodusMovement/exodus-hydra/commit/000eb653d9424b2a427f087009a2cc0dd5d0b3ea))
|
|
17
|
+
- pass through restartOptions in application.delete ([#6223](https://github.com/ExodusMovement/exodus-hydra/issues/6223)) ([db700d0](https://github.com/ExodusMovement/exodus-hydra/commit/db700d0f19c9437e2a4612df4f5b11eec2e20751))
|
|
18
|
+
- update default wallet account with mode and seed id ([#6091](https://github.com/ExodusMovement/exodus-hydra/issues/6091)) ([311061f](https://github.com/ExodusMovement/exodus-hydra/commit/311061fea6b6fb5bfea6bb8992ae01fa475f50d1))
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
- kyc test setup ([#6256](https://github.com/ExodusMovement/exodus-hydra/issues/6256)) ([694dd5c](https://github.com/ExodusMovement/exodus-hydra/commit/694dd5cc70f369b56b5b197b405dccfec18baa34))
|
|
23
|
+
|
|
6
24
|
## [4.0.1](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/headless@4.0.0...@exodus/headless@4.0.1) (2024-03-11)
|
|
7
25
|
|
|
8
26
|
**Note:** Version bump only for package @exodus/headless
|
package/README.md
CHANGED
|
@@ -167,13 +167,13 @@ Unsafe (raw text) storage instance. Used internally by modules to persist data i
|
|
|
167
167
|
|
|
168
168
|
In most cases you probably want to use encrypted storage instead (not yet migrated).
|
|
169
169
|
|
|
170
|
-
Check [storage-spec](https://github.com/ExodusMovement/exodus-hydra/tree/master/
|
|
170
|
+
Check [storage-spec](https://github.com/ExodusMovement/exodus-hydra/tree/master/adapters/storage-spec/spec.md) for more details about Storage API
|
|
171
171
|
|
|
172
172
|
### seedStorage
|
|
173
173
|
|
|
174
174
|
Storage instance used unquely by wallet module to store seed and autogenerated passphrase (if present).
|
|
175
175
|
|
|
176
|
-
Check [storage-spec](https://github.com/ExodusMovement/exodus-hydra/tree/master/
|
|
176
|
+
Check [storage-spec](https://github.com/ExodusMovement/exodus-hydra/tree/master/adapters/storage-spec/spec.md) for more details about Storage API
|
|
177
177
|
|
|
178
178
|
> **Note:** Because Browser Extension needs the passphrase to encrypt/decrypt seed, it get's passed as a 3rd parameter to get/set
|
|
179
179
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/headless",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0-rc.0",
|
|
4
4
|
"description": "The platform-agnostic Exodus wallet SDK",
|
|
5
5
|
"author": "Exodus Movement Inc.",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@exodus/assets-feature": "^4.0.1",
|
|
32
32
|
"@exodus/atoms": "^7.0.0",
|
|
33
33
|
"@exodus/available-assets": "^8.0.0",
|
|
34
|
-
"@exodus/balances": "^
|
|
34
|
+
"@exodus/balances": "^13.0.0",
|
|
35
35
|
"@exodus/basic-utils": "^2.0.0",
|
|
36
36
|
"@exodus/blockchain-metadata": "^15.0.0",
|
|
37
37
|
"@exodus/dependency-injection": "^2.1.2",
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
"@exodus/sodium-crypto": "^3.2.0",
|
|
58
58
|
"@exodus/startup-counter": "^1.0.0",
|
|
59
59
|
"@exodus/tx-signer": "^2.0.1",
|
|
60
|
+
"@exodus/typeforce": "^1.18.1",
|
|
60
61
|
"@exodus/wallet": "^14.0.0",
|
|
61
62
|
"@exodus/wallet-accounts": "^16.2.0",
|
|
62
63
|
"bip39": "^2.6.0",
|
|
@@ -80,19 +81,20 @@
|
|
|
80
81
|
"@exodus/ethereum-lib": "^3.3.34",
|
|
81
82
|
"@exodus/ethereum-meta": "^1.0.23",
|
|
82
83
|
"@exodus/exodus-pricing-client": "^1.2.0",
|
|
84
|
+
"@exodus/fetch-factory": "^1.0.0",
|
|
83
85
|
"@exodus/key-utils": "^3.0.0",
|
|
84
|
-
"@exodus/kyc": "^
|
|
86
|
+
"@exodus/kyc": "^5.0.0",
|
|
85
87
|
"@exodus/litecoin-meta": "^1.0.0",
|
|
86
88
|
"@exodus/market-history": "^7.4.0",
|
|
87
89
|
"@exodus/models": "^11.9.0",
|
|
88
|
-
"@exodus/nfts": "^
|
|
90
|
+
"@exodus/nfts": "^9.1.1",
|
|
89
91
|
"@exodus/personal-notes": "^3.6.0",
|
|
90
92
|
"@exodus/referrals": "^8.2.0",
|
|
91
|
-
"@exodus/solana-lib": "^
|
|
93
|
+
"@exodus/solana-lib": "^2.0.0",
|
|
92
94
|
"@exodus/solana-meta": "^1.0.2",
|
|
93
95
|
"@exodus/storage-encrypted": "^1.2.0",
|
|
94
96
|
"@exodus/storage-memory": "^2.1.1",
|
|
95
|
-
"@exodus/top-movers-monitor": "^4.
|
|
97
|
+
"@exodus/top-movers-monitor": "^4.1.0",
|
|
96
98
|
"@exodus/ui-config": "^3.4.0",
|
|
97
99
|
"@exodus/wild-emitter": "^1.0.0",
|
|
98
100
|
"buffer-json": "^2.0.0",
|
|
@@ -103,5 +105,5 @@
|
|
|
103
105
|
"msw": "^2.0.0",
|
|
104
106
|
"p-defer": "^4.0.0"
|
|
105
107
|
},
|
|
106
|
-
"gitHead": "
|
|
108
|
+
"gitHead": "cd2d72202cb71d7fff8e340ab54193543bfc53c4"
|
|
107
109
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable unicorn/no-for-loop */
|
|
2
2
|
|
|
3
|
-
import ExodusModule from '@exodus/module'
|
|
3
|
+
import ExodusModule from '@exodus/module' // eslint-disable-line import/no-deprecated
|
|
4
4
|
import assert from 'minimalistic-assert'
|
|
5
5
|
|
|
6
6
|
import { LifecycleHook as Hook } from '../constants'
|
|
@@ -31,13 +31,14 @@ const passphraseCachePlaceholder = {
|
|
|
31
31
|
|
|
32
32
|
class Application extends ExodusModule {
|
|
33
33
|
#hooks = {}
|
|
34
|
-
#wallet
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
#
|
|
34
|
+
#wallet
|
|
35
|
+
#lockedAtom
|
|
36
|
+
#backedUpAtom
|
|
37
|
+
#passphraseCache
|
|
38
|
+
#applicationStarted
|
|
39
|
+
#resolveStart
|
|
40
|
+
#flagsStorage
|
|
41
|
+
#storage
|
|
41
42
|
|
|
42
43
|
constructor({
|
|
43
44
|
wallet,
|
|
@@ -53,14 +54,15 @@ class Application extends ExodusModule {
|
|
|
53
54
|
this.#lockedAtom = lockedAtom
|
|
54
55
|
this.#backedUpAtom = backedUpAtom
|
|
55
56
|
this.#passphraseCache = passphraseCache
|
|
56
|
-
this.#
|
|
57
|
+
this.#flagsStorage = unsafeStorage.namespace('flags')
|
|
58
|
+
this.#storage = unsafeStorage.namespace('application')
|
|
57
59
|
|
|
58
60
|
this.#applicationStarted = new Promise((resolve) => (this.#resolveStart = resolve))
|
|
59
61
|
this.setMaxListeners(Number.POSITIVE_INFINITY)
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
start = async () => {
|
|
63
|
-
const [deleteFlag, importFlag] = await this.#
|
|
65
|
+
const [deleteFlag, importFlag] = await this.#flagsStorage.batchGet([DELETE_FLAG, IMPORT_FLAG])
|
|
64
66
|
|
|
65
67
|
const isDeleting = !!deleteFlag
|
|
66
68
|
const isImporting = !!importFlag
|
|
@@ -68,7 +70,7 @@ class Application extends ExodusModule {
|
|
|
68
70
|
if (isDeleting) await this.#wallet.clear()
|
|
69
71
|
|
|
70
72
|
if (isDeleting || isImporting) {
|
|
71
|
-
await this.#
|
|
73
|
+
await this.#flagsStorage.batchDelete([DELETE_FLAG, IMPORT_FLAG])
|
|
72
74
|
await this.#passphraseCache.clear()
|
|
73
75
|
}
|
|
74
76
|
|
|
@@ -78,7 +80,10 @@ class Application extends ExodusModule {
|
|
|
78
80
|
await this.fire(Hook.Clear, null, { concurrent: true })
|
|
79
81
|
}
|
|
80
82
|
|
|
81
|
-
if (isImporting)
|
|
83
|
+
if (isImporting) {
|
|
84
|
+
const params = await this.#storage.get('importParams')
|
|
85
|
+
await this.fire(Hook.Import, params)
|
|
86
|
+
}
|
|
82
87
|
|
|
83
88
|
const [hasPassphraseSet, isLocked, isBackedUp, isRestoring] = await Promise.all([
|
|
84
89
|
this.#wallet.hasPassphraseSet(),
|
|
@@ -170,7 +175,7 @@ class Application extends ExodusModule {
|
|
|
170
175
|
this._logger.log('creating wallet')
|
|
171
176
|
|
|
172
177
|
await this.#applicationStarted
|
|
173
|
-
await this.#wallet.create(opts)
|
|
178
|
+
const seedId = await this.#wallet.create(opts)
|
|
174
179
|
|
|
175
180
|
const isLocked = await this.#wallet.isLocked()
|
|
176
181
|
|
|
@@ -180,28 +185,31 @@ class Application extends ExodusModule {
|
|
|
180
185
|
isLocked,
|
|
181
186
|
isRestoring: false,
|
|
182
187
|
walletExists: true,
|
|
188
|
+
seedId,
|
|
183
189
|
})
|
|
184
190
|
}
|
|
185
191
|
|
|
186
192
|
import = async (opts) => {
|
|
187
193
|
this._logger.log('importing wallet')
|
|
188
194
|
|
|
189
|
-
await this.#
|
|
195
|
+
await this.#flagsStorage.set(RESTORE_FLAG, true)
|
|
190
196
|
|
|
191
197
|
await this.#applicationStarted
|
|
192
198
|
|
|
193
199
|
const walletExists = await this.#wallet.exists()
|
|
194
200
|
|
|
195
|
-
const { forceRestart, forgotPassphrase, ...wallet } = opts
|
|
201
|
+
const { forceRestart, forgotPassphrase, compatibilityMode, ...wallet } = opts
|
|
196
202
|
|
|
197
|
-
await this.#wallet.import(wallet)
|
|
203
|
+
const seedId = await this.#wallet.import(wallet)
|
|
204
|
+
const importParams = { seedId, compatibilityMode }
|
|
198
205
|
|
|
199
206
|
if (forceRestart || walletExists) {
|
|
200
|
-
await this.#
|
|
207
|
+
await this.#flagsStorage.set(IMPORT_FLAG, true)
|
|
201
208
|
|
|
209
|
+
await this.#storage.set('importParams', importParams)
|
|
202
210
|
await this.fire(Hook.Restart, { reason: 'import' })
|
|
203
211
|
} else {
|
|
204
|
-
await this.fire(Hook.Import)
|
|
212
|
+
await this.fire(Hook.Import, importParams)
|
|
205
213
|
|
|
206
214
|
this._logger.log('wallet imported')
|
|
207
215
|
}
|
|
@@ -239,7 +247,7 @@ class Application extends ExodusModule {
|
|
|
239
247
|
|
|
240
248
|
if (isRestoring) {
|
|
241
249
|
await this.fire(Hook.Restore)
|
|
242
|
-
await this.#
|
|
250
|
+
await this.#flagsStorage.delete(RESTORE_FLAG)
|
|
243
251
|
await this.fire(Hook.RestoreCompleted)
|
|
244
252
|
}
|
|
245
253
|
|
|
@@ -249,7 +257,7 @@ class Application extends ExodusModule {
|
|
|
249
257
|
}
|
|
250
258
|
|
|
251
259
|
restore = async () => {
|
|
252
|
-
await this.#
|
|
260
|
+
await this.#flagsStorage.set(RESTORE_FLAG, true)
|
|
253
261
|
await this.#restoreIfNeeded()
|
|
254
262
|
}
|
|
255
263
|
|
|
@@ -304,9 +312,9 @@ class Application extends ExodusModule {
|
|
|
304
312
|
this._logger.log('passphrase changed')
|
|
305
313
|
}
|
|
306
314
|
|
|
307
|
-
delete = async ({ forgotPassphrase } = {}) => {
|
|
308
|
-
await this.#
|
|
309
|
-
await this.fire(Hook.Restart, { reason: 'delete', forgotPassphrase })
|
|
315
|
+
delete = async ({ forgotPassphrase, restartOptions } = {}) => {
|
|
316
|
+
await this.#flagsStorage.set(DELETE_FLAG, true)
|
|
317
|
+
await this.fire(Hook.Restart, { ...restartOptions, reason: 'delete', forgotPassphrase })
|
|
310
318
|
}
|
|
311
319
|
|
|
312
320
|
stop = async () => {
|
|
@@ -322,7 +330,7 @@ class Application extends ExodusModule {
|
|
|
322
330
|
}
|
|
323
331
|
|
|
324
332
|
isRestoring = async () => {
|
|
325
|
-
return this.#
|
|
333
|
+
return this.#flagsStorage.get(RESTORE_FLAG)
|
|
326
334
|
}
|
|
327
335
|
|
|
328
336
|
// TODO: stop emitting this on hooks?
|
package/src/index.js
CHANGED
|
@@ -19,6 +19,7 @@ import remoteConfig from '@exodus/remote-config'
|
|
|
19
19
|
import restoreProgressTracker from '@exodus/restore-progress-tracker'
|
|
20
20
|
import startupCounter from '@exodus/startup-counter'
|
|
21
21
|
import transactionSigner from '@exodus/tx-signer'
|
|
22
|
+
import typeforce from '@exodus/typeforce'
|
|
22
23
|
import wallet from '@exodus/wallet'
|
|
23
24
|
import walletAccounts from '@exodus/wallet-accounts'
|
|
24
25
|
|
|
@@ -28,7 +29,18 @@ import createDependencies from './dependencies'
|
|
|
28
29
|
import attachMigrations from './migrations/attach'
|
|
29
30
|
import attachPlugins from './plugins/attach'
|
|
30
31
|
|
|
31
|
-
const createExodus = (
|
|
32
|
+
const createExodus = (opts) => {
|
|
33
|
+
typeforce(
|
|
34
|
+
{
|
|
35
|
+
adapters: 'Object',
|
|
36
|
+
config: 'Object',
|
|
37
|
+
debug: '?Boolean',
|
|
38
|
+
},
|
|
39
|
+
opts,
|
|
40
|
+
true
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
const { adapters, config, debug = false } = opts
|
|
32
44
|
const ioc = createIOC({ adapters, config, debug })
|
|
33
45
|
|
|
34
46
|
ioc.use(application())
|
|
@@ -56,7 +68,6 @@ const createExodus = ({ adapters, config, port, debug = false }) => {
|
|
|
56
68
|
ioc.use(walletAccounts())
|
|
57
69
|
|
|
58
70
|
ioc.registerMultiple(createDependencies({ adapters, config }))
|
|
59
|
-
ioc.register({ definition: { id: 'port', type: 'port', factory: () => port } })
|
|
60
71
|
|
|
61
72
|
const resolve = () => {
|
|
62
73
|
ioc.resolve()
|
|
@@ -67,6 +78,7 @@ const createExodus = ({ adapters, config, port, debug = false }) => {
|
|
|
67
78
|
|
|
68
79
|
const { migrations } = ioc.getAll()
|
|
69
80
|
|
|
81
|
+
const port = ioc.get('port')
|
|
70
82
|
application.on('start', (payload) => port.emit('start', payload))
|
|
71
83
|
|
|
72
84
|
application.hook('load', (args) => port.emit('pre-load', args))
|
package/src/plugins/analytics.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
const setBuildMetadataProperties = async ({ analytics, getBuildMetadata }) => {
|
|
2
|
-
analytics.
|
|
2
|
+
analytics.requireDefaultEventProperties(['appId', 'osName'])
|
|
3
3
|
|
|
4
4
|
const { appId, osName, deviceModel, platformVersion, deviceManufacturer } =
|
|
5
5
|
await getBuildMetadata()
|
|
6
6
|
|
|
7
|
-
analytics.
|
|
7
|
+
analytics.setDefaultEventProperties({
|
|
8
8
|
appId,
|
|
9
9
|
osName,
|
|
10
10
|
deviceModel,
|
|
@@ -17,13 +17,13 @@ const setBuildMetadataProperties = async ({ analytics, getBuildMetadata }) => {
|
|
|
17
17
|
|
|
18
18
|
const setSystemPreferencesProperties = async ({ analytics, systemPreferences }) => {
|
|
19
19
|
if (!systemPreferences) return
|
|
20
|
-
analytics.
|
|
20
|
+
analytics.requireDefaultEventProperties(['locale'])
|
|
21
21
|
const languages = await systemPreferences.getPreferredLanguages()
|
|
22
|
-
analytics.
|
|
22
|
+
analytics.setDefaultEventProperties({ locale: languages })
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
const setEnvProperties = async ({ analytics, env }) => {
|
|
26
|
-
analytics.
|
|
26
|
+
analytics.setDefaultEventProperties({
|
|
27
27
|
appPlatform: env.platform,
|
|
28
28
|
appVersion: env.version,
|
|
29
29
|
appBuild: env.build === 'development' ? 'dev' : 'prod',
|