@sidhujag/sysweb3-keyring 2.1.3 → 2.1.5
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 +12 -0
- package/README.md +47 -47
- package/cjs/hardware-transaction-authority.js +36 -0
- package/cjs/hardware-transaction-authority.js.map +1 -0
- package/cjs/index.js +5 -5
- package/cjs/index.js.map +1 -1
- package/cjs/keyring-core.js +171 -220
- package/cjs/keyring-core.js.map +1 -1
- package/cjs/keyring-host.js +113 -0
- package/cjs/keyring-host.js.map +1 -0
- package/cjs/keyring-manager.js +15 -151
- package/cjs/keyring-manager.js.map +1 -1
- package/cjs/ledger/host-types.js.map +1 -1
- package/cjs/ledger/index.js +44 -19
- package/cjs/ledger/index.js.map +1 -1
- package/cjs/providers.js +3 -1
- package/cjs/providers.js.map +1 -1
- package/cjs/software.js +10 -56
- package/cjs/software.js.map +1 -1
- package/cjs/transactions/ethereum.js +306 -229
- package/cjs/transactions/ethereum.js.map +1 -1
- package/cjs/transactions/evm-local-signer.js +15 -0
- package/cjs/transactions/evm-local-signer.js.map +1 -1
- package/cjs/transactions/evm-submission.js +61 -65
- package/cjs/transactions/evm-submission.js.map +1 -1
- package/cjs/transactions/hardware-psbt.js +11 -8
- package/cjs/transactions/hardware-psbt.js.map +1 -1
- package/cjs/transactions/index.js +10 -2
- package/cjs/transactions/index.js.map +1 -1
- package/cjs/transactions/prepared-evm.js +10 -7
- package/cjs/transactions/prepared-evm.js.map +1 -1
- package/cjs/transactions/syscoin-core.js +308 -205
- package/cjs/transactions/syscoin-core.js.map +1 -1
- package/cjs/trezor/connect.js +19 -2
- package/cjs/trezor/connect.js.map +1 -1
- package/cjs/trezor/index.js +38 -16
- package/cjs/trezor/index.js.map +1 -1
- package/cjs/types.js.map +1 -1
- package/cjs/utils/excluded-utxos.js +6 -2
- package/cjs/utils/excluded-utxos.js.map +1 -1
- package/cjs/utils/owned-blockbook-account.js +45 -0
- package/cjs/utils/owned-blockbook-account.js.map +1 -0
- package/esm/current-vault-refusal.js +3 -0
- package/esm/current-vault-refusal.js.map +1 -0
- package/esm/evm-fees.js +242 -0
- package/esm/evm-fees.js.map +1 -0
- package/esm/hardware-transaction-authority.js +33 -0
- package/esm/hardware-transaction-authority.js.map +1 -0
- package/esm/initial-state.js +102 -0
- package/esm/initial-state.js.map +1 -0
- package/esm/keyring-core.js +2781 -0
- package/esm/keyring-core.js.map +1 -0
- package/esm/keyring-host.js +108 -0
- package/esm/keyring-host.js.map +1 -0
- package/esm/ledger/dmk-session.js +1 -0
- package/esm/ledger/dmk-session.js.map +1 -1
- package/esm/ledger/dmk-utxo.js +9 -3
- package/esm/ledger/dmk-utxo.js.map +1 -1
- package/esm/ledger/host-types.js.map +1 -1
- package/esm/ledger/index.js +44 -19
- package/esm/ledger/index.js.map +1 -1
- package/esm/network-utils.js +70 -0
- package/esm/network-utils.js.map +1 -0
- package/esm/providers.js +3 -1
- package/esm/providers.js.map +1 -1
- package/esm/software-hd-account.js +20 -0
- package/esm/software-hd-account.js.map +1 -0
- package/esm/storage-core.js +258 -0
- package/esm/storage-core.js.map +1 -0
- package/esm/transactions/ethereum.js +2753 -0
- package/esm/transactions/ethereum.js.map +1 -0
- package/esm/transactions/evm-cancellation.js +40 -0
- package/esm/transactions/evm-cancellation.js.map +1 -0
- package/esm/transactions/evm-local-signer.js +202 -0
- package/esm/transactions/evm-local-signer.js.map +1 -0
- package/esm/transactions/evm-submission.js +187 -0
- package/esm/transactions/evm-submission.js.map +1 -0
- package/esm/transactions/prepared-evm.js +194 -0
- package/esm/transactions/prepared-evm.js.map +1 -0
- package/esm/transactions/syscoin-core.js +714 -0
- package/esm/transactions/syscoin-core.js.map +1 -0
- package/esm/trezor/connect.js +19 -2
- package/esm/trezor/connect.js.map +1 -1
- package/esm/trezor/index.js +38 -16
- package/esm/trezor/index.js.map +1 -1
- package/esm/types.js.map +1 -1
- package/esm/utils/excluded-utxos.js +57 -0
- package/esm/utils/excluded-utxos.js.map +1 -0
- package/esm/utils/owned-blockbook-account.js +9 -0
- package/esm/utils/owned-blockbook-account.js.map +1 -0
- package/esm/utils/psbt.js +32 -0
- package/esm/utils/psbt.js.map +1 -0
- package/esm/utils/watch-descriptor.js +138 -0
- package/esm/utils/watch-descriptor.js.map +1 -0
- package/package.json +5 -11
- package/types/hardware-transaction-authority.d.ts +5 -0
- package/types/index.d.ts +3 -3
- package/types/keyring-core.d.ts +22 -51
- package/types/keyring-host.d.ts +46 -0
- package/types/keyring-manager.d.ts +13 -18
- package/types/ledger/host-types.d.ts +4 -1
- package/types/ledger/index.d.ts +1 -1
- package/types/ledger/types.d.ts +3 -2
- package/types/providers.d.ts +1 -1
- package/types/software.d.ts +6 -19
- package/types/transactions/ethereum.d.ts +14 -11
- package/types/transactions/evm-local-signer.d.ts +2 -2
- package/types/transactions/evm-submission.d.ts +11 -4
- package/types/transactions/hardware-psbt.d.ts +1 -1
- package/types/transactions/index.d.ts +3 -2
- package/types/transactions/prepared-evm.d.ts +4 -1
- package/types/transactions/syscoin-core.d.ts +48 -21
- package/types/trezor/connect.d.ts +6 -3
- package/types/trezor/index.d.ts +4 -3
- package/types/types.d.ts +95 -63
- package/types/utils/excluded-utxos.d.ts +1 -1
- package/types/utils/owned-blockbook-account.d.ts +3 -0
- package/cjs/hardware-wallet-manager-singleton.js +0 -34
- package/cjs/hardware-wallet-manager-singleton.js.map +0 -1
- package/cjs/storage.js +0 -20
- package/cjs/storage.js.map +0 -1
- package/cjs/transactions/syscoin.js +0 -16
- package/cjs/transactions/syscoin.js.map +0 -1
- package/cjs/utils/blockbook-cache.js +0 -76
- package/cjs/utils/blockbook-cache.js.map +0 -1
- package/types/hardware-wallet-manager-singleton.d.ts +0 -19
- package/types/storage.d.ts +0 -5
- package/types/transactions/syscoin.d.ts +0 -9
- package/types/utils/blockbook-cache.d.ts +0 -6
package/cjs/keyring-core.js
CHANGED
|
@@ -71,6 +71,7 @@ const SLH_DSA_PARAMETER_SET = 'SLH-DSA-SHA2-128-24';
|
|
|
71
71
|
const current_vault_refusal_1 = require("./current-vault-refusal");
|
|
72
72
|
const ethers_v6_1 = require("./ethers-v6");
|
|
73
73
|
const initial_state_1 = require("./initial-state");
|
|
74
|
+
const keyring_host_1 = require("./keyring-host");
|
|
74
75
|
const private_records_1 = require("./private-records");
|
|
75
76
|
const signers_1 = require("./signers");
|
|
76
77
|
const software_hd_account_1 = require("./software-hd-account");
|
|
@@ -80,8 +81,8 @@ const evm_local_signer_1 = require("./transactions/evm-local-signer");
|
|
|
80
81
|
const prepared_evm_1 = require("./transactions/prepared-evm");
|
|
81
82
|
const syscoin_core_1 = require("./transactions/syscoin-core");
|
|
82
83
|
const types_1 = require("./types");
|
|
83
|
-
const blockbook_cache_1 = require("./utils/blockbook-cache");
|
|
84
84
|
const derivation_paths_1 = require("./utils/derivation-paths");
|
|
85
|
+
const owned_blockbook_account_1 = require("./utils/owned-blockbook-account");
|
|
85
86
|
const psbt_account_scope_1 = require("./utils/psbt-account-scope");
|
|
86
87
|
const watch_descriptor_1 = require("./utils/watch-descriptor");
|
|
87
88
|
const currentVaultSalt = (keys) => {
|
|
@@ -146,7 +147,7 @@ class SecureBuffer {
|
|
|
146
147
|
}
|
|
147
148
|
}
|
|
148
149
|
class KeyringCore {
|
|
149
|
-
constructor(
|
|
150
|
+
constructor(binding, hardware) {
|
|
150
151
|
_KeyringCore_instances.add(this);
|
|
151
152
|
// Store getter function for accessing Redux state
|
|
152
153
|
this.getVaultState = null;
|
|
@@ -194,7 +195,7 @@ class KeyringCore {
|
|
|
194
195
|
this.privateRecordSessionRevision = 0;
|
|
195
196
|
_KeyringCore_deviceUnlockRetired.set(this, false);
|
|
196
197
|
_KeyringCore_sessionOwnership.set(this, void 0);
|
|
197
|
-
this.createSyscoinTransactions = () => new syscoin_core_1.SyscoinTransactionsCore(this.getSigner, this.getReadOnlySigner, this.getAccountsState, this.
|
|
198
|
+
this.createSyscoinTransactions = () => new syscoin_core_1.SyscoinTransactionsCore(this.getSigner, this.getReadOnlySigner, this.getAccountsState, this.syscoinHardwareSigners, this.capturePsbtSigningContext);
|
|
198
199
|
this.requireLedgerSigner = () => {
|
|
199
200
|
if (!this.ledgerSigner)
|
|
200
201
|
throw (0, syscoin_core_1.createHardwareSignerUnavailableError)('Ledger');
|
|
@@ -206,12 +207,6 @@ class KeyringCore {
|
|
|
206
207
|
return this.trezorSigner;
|
|
207
208
|
};
|
|
208
209
|
// ===================================== PUBLIC METHODS - KEYRING MANAGER FOR HD - SYS ALL ===================================== //
|
|
209
|
-
this.setStorage = (client) => {
|
|
210
|
-
if (!this.storage.setClient) {
|
|
211
|
-
throw new Error('Storage replacement is unavailable in this host');
|
|
212
|
-
}
|
|
213
|
-
this.storage.setClient(client);
|
|
214
|
-
};
|
|
215
210
|
this.validateAccountType = (account) => {
|
|
216
211
|
return account.isImported === true
|
|
217
212
|
? types_1.KeyringAccountType.Imported
|
|
@@ -230,7 +225,7 @@ class KeyringCore {
|
|
|
230
225
|
this.sessionMnemonic = null;
|
|
231
226
|
}
|
|
232
227
|
const ownership = __classPrivateFieldGet(this, _KeyringCore_sessionOwnership, "f");
|
|
233
|
-
if (ownership
|
|
228
|
+
if (ownership.tracker.current === ownership.token) {
|
|
234
229
|
ownership.tracker.current = undefined;
|
|
235
230
|
ownership.tracker.epoch++;
|
|
236
231
|
}
|
|
@@ -284,8 +279,6 @@ class KeyringCore {
|
|
|
284
279
|
this.sessionPassword = null;
|
|
285
280
|
this.sessionMnemonic = null;
|
|
286
281
|
};
|
|
287
|
-
// Legacy trusted-host API. SoftwareKeyring disables direct buffer injection.
|
|
288
|
-
this.receiveSessionOwnership = (sessionPassword, sessionMnemonic) => __classPrivateFieldGet(this, _KeyringCore_instances, "m", _KeyringCore_replaceSessionBuffers).call(this, sessionPassword, sessionMnemonic);
|
|
289
282
|
this.addNewAccount = async (label) => {
|
|
290
283
|
// Check if wallet is unlocked
|
|
291
284
|
if (!this.isUnlocked()) {
|
|
@@ -332,91 +325,41 @@ class KeyringCore {
|
|
|
332
325
|
xpub: derived.address,
|
|
333
326
|
};
|
|
334
327
|
};
|
|
335
|
-
this.
|
|
336
|
-
const
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
const {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
const {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
!this.isXpubLike(xpub))
|
|
364
|
-
return address;
|
|
365
|
-
return await this.getAddress(xpub, true);
|
|
366
|
-
};
|
|
367
|
-
this.getPubkey = async (id, isChangeAddress) => {
|
|
368
|
-
const vault = this.getVault();
|
|
369
|
-
const { accounts, activeAccount } = vault;
|
|
370
|
-
const account = accounts[activeAccount.type]?.[id];
|
|
371
|
-
if (!account) {
|
|
372
|
-
throw new Error(`Account with id ${id} not found`);
|
|
373
|
-
}
|
|
374
|
-
const { xpub, isImported, address } = account;
|
|
375
|
-
// Guard: single-address imported are watch-only
|
|
376
|
-
if (isImported && xpub === address) {
|
|
377
|
-
throw new Error('Public key not available for single-address imported accounts');
|
|
378
|
-
}
|
|
379
|
-
// Guard: descriptor/xpub watch-only (no xprv and not hardware)
|
|
380
|
-
if (this.isWatchOnlyAccount(account)) {
|
|
381
|
-
throw new Error('Public key not available for watch-only accounts');
|
|
382
|
-
}
|
|
383
|
-
return await this.getCurrentAddressPubkey(xpub, isChangeAddress);
|
|
384
|
-
};
|
|
385
|
-
this.getBip32Path = async (id, isChangeAddress) => {
|
|
386
|
-
const vault = this.getVault();
|
|
387
|
-
const { accounts, activeAccount } = vault;
|
|
388
|
-
const account = accounts[activeAccount.type]?.[id];
|
|
389
|
-
if (!account) {
|
|
390
|
-
throw new Error(`Account with id ${id} not found`);
|
|
391
|
-
}
|
|
392
|
-
const { xpub, isImported, address } = account;
|
|
393
|
-
// Guard: single-address imported are watch-only
|
|
394
|
-
if (isImported && xpub === address) {
|
|
395
|
-
throw new Error('BIP32 path not available for single-address imported accounts');
|
|
396
|
-
}
|
|
397
|
-
// Guard: descriptor/xpub watch-only (no xprv and not hardware)
|
|
398
|
-
if (this.isWatchOnlyAccount(account)) {
|
|
399
|
-
throw new Error('BIP32 path not available for watch-only accounts');
|
|
400
|
-
}
|
|
401
|
-
return await this.getCurrentAddressBip32Path(xpub, isChangeAddress);
|
|
402
|
-
};
|
|
403
|
-
this.updateReceivingAddress = async () => {
|
|
404
|
-
const vault = this.getVault();
|
|
405
|
-
const { accounts, activeAccount } = vault;
|
|
406
|
-
const account = accounts[activeAccount.type]?.[activeAccount.id];
|
|
407
|
-
if (!account) {
|
|
408
|
-
throw new Error('Active account not found');
|
|
409
|
-
}
|
|
328
|
+
this.getActiveUtxoAddressAccount = (id, ownedRead) => {
|
|
329
|
+
const captured = (0, syscoin_core_1.captureOwnedSyscoinRead)(ownedRead, this.getAccountsState, this.capturePsbtSigningContext);
|
|
330
|
+
if (id !== captured.accountId)
|
|
331
|
+
throw new Error('UTXO account is not active');
|
|
332
|
+
const account = this.getVault().accounts[captured.accountType]?.[id];
|
|
333
|
+
captured.read.assertCurrent();
|
|
334
|
+
return { account, read: captured.read };
|
|
335
|
+
};
|
|
336
|
+
this.getNewChangeAddress = (ownedRead) => this.getChangeAddress(this.getVault().activeAccount.id, ownedRead);
|
|
337
|
+
this.getChangeAddress = async (id, ownedRead) => {
|
|
338
|
+
const { account, read } = this.getActiveUtxoAddressAccount(id, ownedRead);
|
|
339
|
+
return this.getAddressForUtxoAccount(account, true, read);
|
|
340
|
+
};
|
|
341
|
+
this.getPubkey = async (id, isChangeAddress, ownedRead) => {
|
|
342
|
+
const { account, read } = this.getActiveUtxoAddressAccount(id, ownedRead);
|
|
343
|
+
this.assertUtxoDerivationAvailable(account, 'Public key');
|
|
344
|
+
return this.getAddressPubkey(isChangeAddress, read);
|
|
345
|
+
};
|
|
346
|
+
this.getBip32Path = async (id, isChangeAddress, ownedRead) => {
|
|
347
|
+
const { account, read } = this.getActiveUtxoAddressAccount(id, ownedRead);
|
|
348
|
+
this.assertUtxoDerivationAvailable(account, 'BIP32 path');
|
|
349
|
+
return this.getAddressBip32Path(id, isChangeAddress, read);
|
|
350
|
+
};
|
|
351
|
+
this.updateReceivingAddress = async (ownedRead) => {
|
|
352
|
+
const { account, read } = this.getActiveUtxoAddressAccount(this.getVault().activeAccount.id, ownedRead);
|
|
353
|
+
return this.getAddressForUtxoAccount(account, false, read);
|
|
354
|
+
};
|
|
355
|
+
this.getAddressForUtxoAccount = (account, change, read) => {
|
|
410
356
|
const { xpub, isImported, address } = account;
|
|
411
357
|
if (isImported &&
|
|
412
358
|
xpub === address &&
|
|
413
359
|
!this.isDescriptor(xpub) &&
|
|
414
360
|
!this.isXpubLike(xpub))
|
|
415
|
-
return address;
|
|
416
|
-
|
|
417
|
-
// NOTE: Address updates should be dispatched to Redux store, not updated here
|
|
418
|
-
// The calling code should handle the Redux dispatch
|
|
419
|
-
return nextAddress;
|
|
361
|
+
return Promise.resolve(address);
|
|
362
|
+
return this.discoverUtxoAddress(change, read);
|
|
420
363
|
};
|
|
421
364
|
this.getAccountById = (id, accountType) => {
|
|
422
365
|
const vault = this.getVault();
|
|
@@ -694,62 +637,56 @@ class KeyringCore {
|
|
|
694
637
|
};
|
|
695
638
|
this.getNetwork = () => this.getVault().activeNetwork;
|
|
696
639
|
this.createEthAccount = (privateKey) => (0, evm_local_signer_1.privateKeyToAccount)(privateKey);
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
const
|
|
700
|
-
|
|
701
|
-
// Use read-only signer for backend calls - works for all account types including hardware wallets
|
|
702
|
-
const { main } = this.getReadOnlySigner();
|
|
703
|
-
const options = 'tokens=used&details=tokens';
|
|
704
|
-
// In-flight deduplicated: concurrent callers within a send flow
|
|
705
|
-
// (fee estimation, PSBT creation, signing) share a single request
|
|
706
|
-
const { tokens } = await (0, blockbook_cache_1.fetchBackendAccountCached)(main.blockbookURL, xpub, options);
|
|
640
|
+
this.fetchCurrentAccountData = async (isChangeAddress, read) => {
|
|
641
|
+
read.assertCurrent();
|
|
642
|
+
const { tokens } = await (0, owned_blockbook_account_1.fetchOwnedBlockbookAccount)(read.network.url, read.xpub, read.transport);
|
|
643
|
+
read.assertCurrent();
|
|
707
644
|
const { receivingIndex, changeIndex } = this.setLatestIndexesFromXPubTokens(tokens);
|
|
708
|
-
// Get network configuration for BIP84 using network-provided pub type macros
|
|
709
|
-
const networkConfig = (0, sysweb3_network_1.getNetworkConfig)(activeNetwork.slip44, activeNetwork.currency);
|
|
710
|
-
const pubTypes = networkConfig?.types?.zPubType;
|
|
711
|
-
if (!pubTypes) {
|
|
712
|
-
throw new Error('Missing zPubType in network configuration');
|
|
713
|
-
}
|
|
714
|
-
const networks = networkConfig.networks;
|
|
715
|
-
const currentAccount = new BIP84.fromZPub(xpub, pubTypes, networks);
|
|
716
|
-
const addressIndex = isChangeAddress ? changeIndex : receivingIndex;
|
|
717
645
|
return {
|
|
718
|
-
currentAccount,
|
|
719
|
-
addressIndex,
|
|
720
|
-
main,
|
|
646
|
+
currentAccount: this.loadBip84AddressAccount(read.xpub, read.network),
|
|
647
|
+
addressIndex: isChangeAddress ? changeIndex : receivingIndex,
|
|
721
648
|
};
|
|
722
649
|
};
|
|
723
|
-
this.
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
const { currentAccount, addressIndex } = await this.fetchCurrentAccountData(xpub, isChangeAddress);
|
|
742
|
-
// BIP84 returns the public key as a hex string directly
|
|
650
|
+
this.discoverUtxoAddress = async (isChangeAddress, read) => {
|
|
651
|
+
read.assertCurrent();
|
|
652
|
+
if (this.isDescriptor(read.xpub))
|
|
653
|
+
throw new Error('Address rotation is not supported for watch-only descriptors');
|
|
654
|
+
const { currentAccount, addressIndex } = await this.fetchCurrentAccountData(isChangeAddress, read);
|
|
655
|
+
read.assertCurrent();
|
|
656
|
+
return currentAccount.getAddress(addressIndex, isChangeAddress, 84);
|
|
657
|
+
};
|
|
658
|
+
this.getAddress = async (xpub, isChangeAddress, ownedRead) => {
|
|
659
|
+
const id = this.getVault().activeAccount.id;
|
|
660
|
+
const { account, read } = this.getActiveUtxoAddressAccount(id, ownedRead);
|
|
661
|
+
if (xpub !== read.xpub)
|
|
662
|
+
throw new Error('UTXO account is not active');
|
|
663
|
+
return this.getAddressForUtxoAccount(account, isChangeAddress, read);
|
|
664
|
+
};
|
|
665
|
+
this.getAddressPubkey = async (isChangeAddress, read) => {
|
|
666
|
+
const { currentAccount, addressIndex } = await this.fetchCurrentAccountData(isChangeAddress, read);
|
|
667
|
+
read.assertCurrent();
|
|
743
668
|
return currentAccount.getPublicKey(addressIndex, isChangeAddress);
|
|
744
669
|
};
|
|
745
|
-
this.
|
|
746
|
-
const
|
|
747
|
-
const {
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
670
|
+
this.getCurrentAddressPubkey = async (xpub, isChangeAddress, ownedRead) => {
|
|
671
|
+
const id = this.getVault().activeAccount.id;
|
|
672
|
+
const { account, read } = this.getActiveUtxoAddressAccount(id, ownedRead);
|
|
673
|
+
if (xpub !== read.xpub)
|
|
674
|
+
throw new Error('UTXO account is not active');
|
|
675
|
+
this.assertUtxoDerivationAvailable(account, 'Public key');
|
|
676
|
+
return this.getAddressPubkey(isChangeAddress, read);
|
|
677
|
+
};
|
|
678
|
+
this.getAddressBip32Path = async (id, isChangeAddress, read) => {
|
|
679
|
+
const { addressIndex } = await this.fetchCurrentAccountData(isChangeAddress, read);
|
|
680
|
+
read.assertCurrent();
|
|
681
|
+
return (0, derivation_paths_1.getAddressDerivationPath)(read.network.currency.toLowerCase(), read.network.slip44, id, isChangeAddress, addressIndex);
|
|
682
|
+
};
|
|
683
|
+
this.getCurrentAddressBip32Path = async (xpub, isChangeAddress, ownedRead) => {
|
|
684
|
+
const id = this.getVault().activeAccount.id;
|
|
685
|
+
const { account, read } = this.getActiveUtxoAddressAccount(id, ownedRead);
|
|
686
|
+
if (xpub !== read.xpub)
|
|
687
|
+
throw new Error('UTXO account is not active');
|
|
688
|
+
this.assertUtxoDerivationAvailable(account, 'BIP32 path');
|
|
689
|
+
return this.getAddressBip32Path(id, isChangeAddress, read);
|
|
753
690
|
};
|
|
754
691
|
this.logout = () => {
|
|
755
692
|
this.lockWallet();
|
|
@@ -835,8 +772,9 @@ class KeyringCore {
|
|
|
835
772
|
throw error;
|
|
836
773
|
}
|
|
837
774
|
};
|
|
838
|
-
this.capturePsbtSigningContext = () => {
|
|
775
|
+
this.capturePsbtSigningContext = (bindSessionRevision = true) => {
|
|
839
776
|
const session = this.sessionPassword;
|
|
777
|
+
const revision = this.privateRecordSessionRevision;
|
|
840
778
|
const vault = this.getVault();
|
|
841
779
|
const selected = { ...vault.activeAccount };
|
|
842
780
|
const account = vault.accounts[selected.type]?.[selected.id];
|
|
@@ -848,6 +786,8 @@ class KeyringCore {
|
|
|
848
786
|
if (!session ||
|
|
849
787
|
session.isCleared() ||
|
|
850
788
|
this.sessionPassword !== session ||
|
|
789
|
+
(bindSessionRevision &&
|
|
790
|
+
this.privateRecordSessionRevision !== revision) ||
|
|
851
791
|
current.activeAccount.id !== selected.id ||
|
|
852
792
|
current.activeAccount.type !== selected.type ||
|
|
853
793
|
currentAccount?.address !== identity.address ||
|
|
@@ -950,22 +890,32 @@ class KeyringCore {
|
|
|
950
890
|
};
|
|
951
891
|
};
|
|
952
892
|
// Read-only version that works when wallet is locked
|
|
953
|
-
this.getReadOnlySigner = () => {
|
|
954
|
-
|
|
893
|
+
this.getReadOnlySigner = (ownedRead) => {
|
|
894
|
+
ownedRead?.assertCurrent();
|
|
895
|
+
if ((ownedRead ? ownedRead.network.kind : this.getActiveChain()) !==
|
|
896
|
+
sysweb3_network_1.INetworkType.Syscoin) {
|
|
955
897
|
throw new Error('Switch to UTXO chain');
|
|
956
898
|
}
|
|
957
899
|
// Create syscoinjs instance without HD signer for read-only operations
|
|
958
|
-
const
|
|
959
|
-
const network = vault.activeNetwork;
|
|
900
|
+
const network = ownedRead?.network ?? this.getVault().activeNetwork;
|
|
960
901
|
const networkConfig = (0, sysweb3_network_1.getNetworkConfig)(network.slip44, network.currency);
|
|
961
902
|
const isTestnet = network.slip44 === 1;
|
|
962
903
|
const bitcoinjsNetwork = isTestnet
|
|
963
904
|
? networkConfig?.networks?.testnet
|
|
964
905
|
: networkConfig?.networks?.mainnet;
|
|
906
|
+
if (ownedRead && !bitcoinjsNetwork)
|
|
907
|
+
throw new Error('Missing owned UTXO network configuration');
|
|
965
908
|
const syscoinMainSigner = new syscoinjs.SyscoinJSLib(null, // No HD signer needed for read-only operations
|
|
966
|
-
network.url, bitcoinjsNetwork);
|
|
909
|
+
network.url, bitcoinjsNetwork, ...(ownedRead ? [ownedRead.transport] : []));
|
|
910
|
+
if (!ownedRead)
|
|
911
|
+
return { main: syscoinMainSigner };
|
|
967
912
|
return {
|
|
968
913
|
main: syscoinMainSigner,
|
|
914
|
+
getOwnedAddress: (xpub, isChangeAddress) => {
|
|
915
|
+
if (xpub !== ownedRead.xpub)
|
|
916
|
+
throw new Error('UTXO account is not active');
|
|
917
|
+
return this.discoverUtxoAddress(isChangeAddress, ownedRead);
|
|
918
|
+
},
|
|
969
919
|
};
|
|
970
920
|
};
|
|
971
921
|
this.getAccountsState = () => {
|
|
@@ -1157,10 +1107,13 @@ class KeyringCore {
|
|
|
1157
1107
|
if (!BIP84.validateMnemonic(seedPhrase)) {
|
|
1158
1108
|
throw new Error('Invalid Seed');
|
|
1159
1109
|
}
|
|
1110
|
+
const assertCurrent = __classPrivateFieldGet(this, _KeyringCore_instances, "m", _KeyringCore_captureSessionGuard).call(this);
|
|
1111
|
+
assertCurrent();
|
|
1160
1112
|
const [vault, vaultKeys] = await Promise.all([
|
|
1161
1113
|
this.storage.get('vault'),
|
|
1162
1114
|
this.storage.get('vault-keys'),
|
|
1163
1115
|
]);
|
|
1116
|
+
assertCurrent();
|
|
1164
1117
|
const hasVault = vault !== undefined && vault !== null;
|
|
1165
1118
|
const hasVaultKeys = vaultKeys !== undefined && vaultKeys !== null;
|
|
1166
1119
|
const livePassword = this.sessionPassword;
|
|
@@ -1175,6 +1128,7 @@ class KeyringCore {
|
|
|
1175
1128
|
throw new Error('Cannot initialize a new vault over existing wallet storage');
|
|
1176
1129
|
}
|
|
1177
1130
|
const sessionPasswordSaltedHash = await this.deriveStoredSessionKey(password, vaultKeys);
|
|
1131
|
+
assertCurrent();
|
|
1178
1132
|
if (livePassword === this.sessionPassword &&
|
|
1179
1133
|
liveMnemonic === this.sessionMnemonic &&
|
|
1180
1134
|
sessionPasswordSaltedHash === this.getSessionPasswordString()) {
|
|
@@ -1190,6 +1144,7 @@ class KeyringCore {
|
|
|
1190
1144
|
}
|
|
1191
1145
|
if (currentMnemonic === seedPhrase) {
|
|
1192
1146
|
const storedVault = await this.vaultPersistence.getDecryptedVault(sessionPasswordSaltedHash);
|
|
1147
|
+
assertCurrent();
|
|
1193
1148
|
if (livePassword === this.sessionPassword &&
|
|
1194
1149
|
liveMnemonic === this.sessionMnemonic &&
|
|
1195
1150
|
!livePassword.isCleared() &&
|
|
@@ -1215,8 +1170,10 @@ class KeyringCore {
|
|
|
1215
1170
|
mnemonic: seedPhrase, // Store plain mnemonic - setEncryptedVault will encrypt the entire vault
|
|
1216
1171
|
},
|
|
1217
1172
|
// v4 vault is encrypted with the derived session password key (PBKDF2 output)
|
|
1218
|
-
sessionPasswordSaltedHash, { salt });
|
|
1219
|
-
|
|
1173
|
+
sessionPasswordSaltedHash, { salt }, assertCurrent);
|
|
1174
|
+
assertCurrent();
|
|
1175
|
+
const assertInstalled = await __classPrivateFieldGet(this, _KeyringCore_instances, "m", _KeyringCore_recreateSessionFromVault).call(this, sessionPasswordSaltedHash, assertCurrent);
|
|
1176
|
+
assertInstalled();
|
|
1220
1177
|
};
|
|
1221
1178
|
// NEW: Create first account without signer setup
|
|
1222
1179
|
this.createFirstAccount = async (label) => {
|
|
@@ -1255,27 +1212,17 @@ class KeyringCore {
|
|
|
1255
1212
|
await this.initializeSession(seedPhrase, password);
|
|
1256
1213
|
return await this.createFirstAccount();
|
|
1257
1214
|
};
|
|
1258
|
-
|
|
1259
|
-
typeof dependencies.authority !== 'object' ||
|
|
1260
|
-
dependencies.authority === null) {
|
|
1261
|
-
throw new TypeError('Keyring core requires an explicit wallet authority');
|
|
1262
|
-
}
|
|
1263
|
-
if (typeof dependencies.vaultPersistence?.getDecryptedVault !== 'function' ||
|
|
1264
|
-
typeof dependencies.vaultPersistence?.setEncryptedVault !== 'function') {
|
|
1265
|
-
throw new TypeError('Keyring core requires bound vault persistence');
|
|
1266
|
-
}
|
|
1215
|
+
const dependencies = (0, keyring_host_1.takeKeyringHostBinding)(binding);
|
|
1267
1216
|
this.authority = dependencies.authority;
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
}, "f");
|
|
1273
|
-
}
|
|
1217
|
+
__classPrivateFieldSet(this, _KeyringCore_sessionOwnership, {
|
|
1218
|
+
tracker: dependencies.sessionOwner,
|
|
1219
|
+
token: Symbol(),
|
|
1220
|
+
}, "f");
|
|
1274
1221
|
this.storage = dependencies.storage;
|
|
1275
1222
|
this.vaultPersistence = dependencies.vaultPersistence;
|
|
1276
|
-
this.ledgerSigner =
|
|
1277
|
-
this.trezorSigner =
|
|
1278
|
-
this.syscoinHardwareSigners = { ...
|
|
1223
|
+
this.ledgerSigner = hardware.ledgerSigner;
|
|
1224
|
+
this.trezorSigner = hardware.trezorSigner;
|
|
1225
|
+
this.syscoinHardwareSigners = { ...hardware.syscoinHardwareSigners };
|
|
1279
1226
|
this.writeUtf8Diagnostic(false);
|
|
1280
1227
|
this.utf8Error = false;
|
|
1281
1228
|
this.initialTrezorAccountState = initial_state_1.initialActiveTrezorAccountState;
|
|
@@ -1283,8 +1230,6 @@ class KeyringCore {
|
|
|
1283
1230
|
this.syscoinTransaction = this.createSyscoinTransactions();
|
|
1284
1231
|
this.ethereumTransaction = new ethereum_1.EthereumTransactions(this.getNetwork, this.getDecryptedPrivateKey, this.getAccountsState, this.ledgerSigner, this.trezorSigner, this.capturePsbtSigningContext, dependencies.captureEvmSubmission);
|
|
1285
1232
|
if (dependencies.deviceUnlock) {
|
|
1286
|
-
if (!__classPrivateFieldGet(this, _KeyringCore_sessionOwnership, "f"))
|
|
1287
|
-
throw new TypeError('Device unlock requires a session owner');
|
|
1288
1233
|
const { port, receive } = dependencies.deviceUnlock;
|
|
1289
1234
|
const readVaultPair = this.storage.readDeviceUnlockVaultPair;
|
|
1290
1235
|
if (typeof readVaultPair !== 'function')
|
|
@@ -1313,25 +1258,28 @@ class KeyringCore {
|
|
|
1313
1258
|
let assertCurrent = __classPrivateFieldGet(this, _KeyringCore_instances, "m", _KeyringCore_captureSessionGuard).call(this);
|
|
1314
1259
|
let authenticated = false;
|
|
1315
1260
|
try {
|
|
1316
|
-
assertCurrent
|
|
1261
|
+
assertCurrent();
|
|
1317
1262
|
const vaultKeys = await this.storage.get('vault-keys');
|
|
1318
|
-
assertCurrent?.();
|
|
1319
1263
|
if (!vaultKeys) {
|
|
1264
|
+
assertCurrent();
|
|
1320
1265
|
throw new Error('Vault keys not found. Reload the wallet and try again.');
|
|
1321
1266
|
}
|
|
1322
1267
|
// v4: Validate password by deriving the session key once and decrypting the vault with it.
|
|
1323
1268
|
// This avoids an extra KDF pass just for a stored verifier.
|
|
1324
1269
|
const { salt } = vaultKeys;
|
|
1325
|
-
const readVaultPair =
|
|
1326
|
-
? this.storage.readDeviceUnlockVaultPair
|
|
1327
|
-
: undefined;
|
|
1270
|
+
const readVaultPair = this.storage.readDeviceUnlockVaultPair;
|
|
1328
1271
|
const accountingSalt = readVaultPair
|
|
1329
1272
|
? currentVaultSalt(vaultKeys)
|
|
1330
1273
|
: undefined;
|
|
1274
|
+
// Permit only an authenticated negative verdict for the same atomic
|
|
1275
|
+
// pair after cancellation. Legacy migration and positive results stay guarded.
|
|
1276
|
+
if (accountingSalt === undefined)
|
|
1277
|
+
assertCurrent();
|
|
1331
1278
|
// Derive session encryption key (in-memory only) used to encrypt/decrypt xprv fields
|
|
1332
1279
|
// IMPORTANT: This MUST NOT be the same value as the stored verifier above.
|
|
1333
1280
|
let sessionPasswordKey = await this.deriveStoredSessionKey(password, accountingSalt === undefined ? vaultKeys : { salt: accountingSalt });
|
|
1334
|
-
|
|
1281
|
+
if (accountingSalt === undefined)
|
|
1282
|
+
assertCurrent();
|
|
1335
1283
|
// Handle migration from old vault format with currentSessionSalt
|
|
1336
1284
|
if (vaultKeys.currentSessionSalt) {
|
|
1337
1285
|
console.log('[KeyringManager] Detected old vault format, handling session migration...');
|
|
@@ -1342,7 +1290,7 @@ class KeyringCore {
|
|
|
1342
1290
|
// derived key. Selecting by stored format also permits a safe retry
|
|
1343
1291
|
// if the vault write succeeded but the metadata write was interrupted.
|
|
1344
1292
|
const { mnemonic } = await this.vaultPersistence.getDecryptedVault(sessionPasswordKey, password);
|
|
1345
|
-
assertCurrent
|
|
1293
|
+
assertCurrent();
|
|
1346
1294
|
authenticated = true;
|
|
1347
1295
|
const isValidSecret = (value) => {
|
|
1348
1296
|
if (typeof value !== 'string' || !value)
|
|
@@ -1383,15 +1331,15 @@ class KeyringCore {
|
|
|
1383
1331
|
}
|
|
1384
1332
|
// Do not change either stored record until a valid secret is recovered.
|
|
1385
1333
|
await this.vaultPersistence.setEncryptedVault({ mnemonic: decryptedMnemonic }, sessionPasswordKey, undefined, assertCurrent);
|
|
1386
|
-
assertCurrent
|
|
1334
|
+
assertCurrent();
|
|
1387
1335
|
console.log('[KeyringManager] Vault mnemonic format normalized');
|
|
1388
1336
|
// Remove currentSessionSalt from vault-keys (v4 keeps only the salt on disk)
|
|
1389
1337
|
const migratedVaultKeys = {
|
|
1390
1338
|
salt: vaultKeys.salt,
|
|
1391
1339
|
};
|
|
1392
|
-
assertCurrent
|
|
1340
|
+
assertCurrent();
|
|
1393
1341
|
await this.storage.set('vault-keys', migratedVaultKeys);
|
|
1394
|
-
assertCurrent
|
|
1342
|
+
assertCurrent();
|
|
1395
1343
|
console.log('[KeyringManager] Old vault format migration completed');
|
|
1396
1344
|
}
|
|
1397
1345
|
// v4 vault is encrypted with the derived session password key (PBKDF2 output).
|
|
@@ -1420,7 +1368,7 @@ class KeyringCore {
|
|
|
1420
1368
|
// available for the host counter even if its owner just retired.
|
|
1421
1369
|
return { canLogin: false };
|
|
1422
1370
|
}
|
|
1423
|
-
assertCurrent
|
|
1371
|
+
assertCurrent();
|
|
1424
1372
|
// Only the historical CBC fallback used the 20k key without metadata.
|
|
1425
1373
|
// Never try it for GCM, malformed records, or platform/storage failures.
|
|
1426
1374
|
const rawVault = error instanceof storage_core_1.VaultAuthenticationError &&
|
|
@@ -1428,14 +1376,14 @@ class KeyringCore {
|
|
|
1428
1376
|
!vaultKeys.currentSessionSalt
|
|
1429
1377
|
? await this.storage.get('vault')
|
|
1430
1378
|
: undefined;
|
|
1431
|
-
assertCurrent
|
|
1379
|
+
assertCurrent();
|
|
1432
1380
|
if (typeof rawVault !== 'string' || rawVault.trim().startsWith('{')) {
|
|
1433
1381
|
throw error;
|
|
1434
1382
|
}
|
|
1435
1383
|
const legacyKey = await this.deriveLegacySessionKey(password, salt);
|
|
1436
|
-
assertCurrent
|
|
1384
|
+
assertCurrent();
|
|
1437
1385
|
decryptedVault = await this.vaultPersistence.getDecryptedVault(legacyKey);
|
|
1438
|
-
assertCurrent
|
|
1386
|
+
assertCurrent();
|
|
1439
1387
|
authenticated = true;
|
|
1440
1388
|
sessionPasswordKey = legacyKey;
|
|
1441
1389
|
// Keep the historical account wrapping key. Persist its profile before
|
|
@@ -1444,40 +1392,38 @@ class KeyringCore {
|
|
|
1444
1392
|
...vaultKeys,
|
|
1445
1393
|
keyDerivation: LEGACY_ENCRYPTION_KDF,
|
|
1446
1394
|
};
|
|
1447
|
-
assertCurrent
|
|
1395
|
+
assertCurrent();
|
|
1448
1396
|
await this.storage.set('vault-keys', migratedVaultKeys);
|
|
1449
|
-
assertCurrent
|
|
1397
|
+
assertCurrent();
|
|
1450
1398
|
legacyProfile = true;
|
|
1451
1399
|
}
|
|
1452
|
-
assertCurrent
|
|
1400
|
+
assertCurrent();
|
|
1453
1401
|
authenticated = true;
|
|
1454
1402
|
if (legacyProfile && this.hasWebCrypto()) {
|
|
1455
1403
|
const storedVault = await this.storage.get('vault');
|
|
1456
|
-
assertCurrent
|
|
1404
|
+
assertCurrent();
|
|
1457
1405
|
if (typeof storedVault === 'string' &&
|
|
1458
1406
|
!storedVault.trim().startsWith('{')) {
|
|
1459
1407
|
// A failed earlier rewrap can leave the authenticated profile plus
|
|
1460
1408
|
// CBC. Retry that write without changing the account wrapping key.
|
|
1461
1409
|
await this.vaultPersistence.setEncryptedVault(decryptedVault, sessionPasswordKey, undefined, assertCurrent);
|
|
1462
|
-
assertCurrent
|
|
1410
|
+
assertCurrent();
|
|
1463
1411
|
}
|
|
1464
1412
|
}
|
|
1465
1413
|
// If session data missing or corrupted, recreate from vault
|
|
1466
1414
|
if (!this.sessionMnemonic) {
|
|
1467
1415
|
assertCurrent = await __classPrivateFieldGet(this, _KeyringCore_instances, "m", _KeyringCore_recreateSessionFromVault).call(this, sessionPasswordKey, assertCurrent);
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
console.log('[KeyringManager] Session data recreated from vault');
|
|
1471
|
-
}
|
|
1416
|
+
assertCurrent();
|
|
1417
|
+
console.log('[KeyringManager] Session data recreated from vault');
|
|
1472
1418
|
}
|
|
1473
|
-
assertCurrent
|
|
1419
|
+
assertCurrent();
|
|
1474
1420
|
const result = __classPrivateFieldGet(this, _KeyringCore_instances, "m", _KeyringCore_finishUnlock).call(this);
|
|
1475
|
-
assertCurrent
|
|
1421
|
+
assertCurrent();
|
|
1476
1422
|
return result;
|
|
1477
1423
|
}
|
|
1478
1424
|
catch (error) {
|
|
1479
1425
|
// A superseded attempt must not report authentication or clear its winner.
|
|
1480
|
-
assertCurrent
|
|
1426
|
+
assertCurrent();
|
|
1481
1427
|
if (!authenticated && error instanceof storage_core_1.VaultAuthenticationError) {
|
|
1482
1428
|
return { canLogin: false };
|
|
1483
1429
|
}
|
|
@@ -1489,6 +1435,12 @@ class KeyringCore {
|
|
|
1489
1435
|
throw error;
|
|
1490
1436
|
}
|
|
1491
1437
|
}
|
|
1438
|
+
assertUtxoDerivationAvailable(account, field) {
|
|
1439
|
+
if (account.isImported && account.xpub === account.address)
|
|
1440
|
+
throw new Error(`${field} not available for single-address imported accounts`);
|
|
1441
|
+
if (this.isWatchOnlyAccount(account))
|
|
1442
|
+
throw new Error(`${field} not available for watch-only accounts`);
|
|
1443
|
+
}
|
|
1492
1444
|
isWatchOnlyAccount(a) {
|
|
1493
1445
|
if (a.isLedgerWallet || a.isTrezorWallet)
|
|
1494
1446
|
return false;
|
|
@@ -1599,6 +1551,17 @@ class KeyringCore {
|
|
|
1599
1551
|
throw error;
|
|
1600
1552
|
}
|
|
1601
1553
|
}
|
|
1554
|
+
loadBip84AddressAccount(xpub, network) {
|
|
1555
|
+
const { types, networks } = (0, sysweb3_network_1.getNetworkConfig)(network.slip44, network.currency);
|
|
1556
|
+
if (!types?.zPubType)
|
|
1557
|
+
throw new Error('Missing zPubType in network configuration');
|
|
1558
|
+
return new BIP84.fromZPub(xpub, types.zPubType, networks);
|
|
1559
|
+
}
|
|
1560
|
+
deriveFirstUtxoAddress(xpub, network) {
|
|
1561
|
+
if (this.isDescriptor(xpub))
|
|
1562
|
+
return (0, watch_descriptor_1.deriveDescriptorAddress)(xpub, network);
|
|
1563
|
+
return this.loadBip84AddressAccount(xpub, network).getAddress(0, false, 84);
|
|
1564
|
+
}
|
|
1602
1565
|
async importAccount(privKey, label, options) {
|
|
1603
1566
|
// Check if wallet is unlocked
|
|
1604
1567
|
if (!this.isUnlocked()) {
|
|
@@ -1636,9 +1599,7 @@ class KeyringCore {
|
|
|
1636
1599
|
? types.zPubType.testnet.vpub
|
|
1637
1600
|
: types.zPubType.mainnet.zpub;
|
|
1638
1601
|
const bip84Key = (0, derivation_paths_1.convertExtendedKeyVersion)(identifier, target);
|
|
1639
|
-
addressToStore =
|
|
1640
|
-
forceIndex0: true,
|
|
1641
|
-
});
|
|
1602
|
+
addressToStore = this.deriveFirstUtxoAddress(bip84Key, activeNetwork);
|
|
1642
1603
|
}
|
|
1643
1604
|
// Validate duplicates across all account buckets, including passkey smart accounts.
|
|
1644
1605
|
if (this.accountAddressExists(accounts, addressToStore) ||
|
|
@@ -1939,7 +1900,7 @@ class KeyringCore {
|
|
|
1939
1900
|
if ((0, ethers_v6_1.getAddress)(key.address) !== request.account.expectedAddress)
|
|
1940
1901
|
throw new Error('Prepared EVM signer address mismatch');
|
|
1941
1902
|
assertCurrent();
|
|
1942
|
-
const signed = (0, prepared_evm_1.signPreparedEvmEnvelope)(request.transaction, key.decryptedPrivateKey);
|
|
1903
|
+
const { signed } = (0, prepared_evm_1.signPreparedEvmEnvelope)(request.transaction, key.decryptedPrivateKey);
|
|
1943
1904
|
hostGuard();
|
|
1944
1905
|
assertCurrent();
|
|
1945
1906
|
return signed;
|
|
@@ -2043,7 +2004,7 @@ class KeyringCore {
|
|
|
2043
2004
|
else {
|
|
2044
2005
|
// For UTXO, use the xpub to derive the address
|
|
2045
2006
|
// Always use first receive address (index 0) for imported account display
|
|
2046
|
-
address =
|
|
2007
|
+
address = this.deriveFirstUtxoAddress(xpub, vault.activeNetwork);
|
|
2047
2008
|
}
|
|
2048
2009
|
if (this.accountAddressExists(accounts, address, isEVM))
|
|
2049
2010
|
throw new Error('Account already exists on your Wallet.');
|
|
@@ -2112,7 +2073,7 @@ class KeyringCore {
|
|
|
2112
2073
|
: types.zPubType.mainnet.zpub;
|
|
2113
2074
|
xpub = (0, derivation_paths_1.convertExtendedKeyVersion)(ledgerXpub, bip84Target);
|
|
2114
2075
|
// Always use first receive address (index 0) for imported account display
|
|
2115
|
-
address =
|
|
2076
|
+
address = this.deriveFirstUtxoAddress(xpub, vault.activeNetwork);
|
|
2116
2077
|
}
|
|
2117
2078
|
if (this.accountAddressExists(accounts, address, (0, derivation_paths_1.isEvmCoin)(coin, slip44)))
|
|
2118
2079
|
throw new Error('Account already exists on your Wallet.');
|
|
@@ -2631,8 +2592,7 @@ class KeyringCore {
|
|
|
2631
2592
|
*/
|
|
2632
2593
|
async destroy() {
|
|
2633
2594
|
__classPrivateFieldSet(this, _KeyringCore_deviceUnlockRetired, true, "f");
|
|
2634
|
-
|
|
2635
|
-
__classPrivateFieldGet(this, _KeyringCore_sessionOwnership, "f").destroyed = true;
|
|
2595
|
+
__classPrivateFieldGet(this, _KeyringCore_sessionOwnership, "f").destroyed = true;
|
|
2636
2596
|
await this.lockWallet();
|
|
2637
2597
|
// Clear any remaining references
|
|
2638
2598
|
this.ethereumTransaction = {};
|
|
@@ -2662,7 +2622,7 @@ _KeyringCore_deviceUnlockRetired = new WeakMap(), _KeyringCore_sessionOwnership
|
|
|
2662
2622
|
(!issuing && (this.sessionPassword || this.sessionMnemonic))) {
|
|
2663
2623
|
throw new Error('Device unlock session changed');
|
|
2664
2624
|
}
|
|
2665
|
-
assertOwnership
|
|
2625
|
+
assertOwnership();
|
|
2666
2626
|
};
|
|
2667
2627
|
let key;
|
|
2668
2628
|
try {
|
|
@@ -2753,17 +2713,15 @@ _KeyringCore_deviceUnlockRetired = new WeakMap(), _KeyringCore_sessionOwnership
|
|
|
2753
2713
|
if (source.authority !== this.authority ||
|
|
2754
2714
|
source.storage !== this.storage ||
|
|
2755
2715
|
source.vaultPersistence !== this.vaultPersistence ||
|
|
2756
|
-
__classPrivateFieldGet(source, _KeyringCore_sessionOwnership, "f")
|
|
2716
|
+
__classPrivateFieldGet(source, _KeyringCore_sessionOwnership, "f").tracker !== __classPrivateFieldGet(this, _KeyringCore_sessionOwnership, "f").tracker) {
|
|
2757
2717
|
throw new Error('Cannot transfer session between different wallet authorities');
|
|
2758
2718
|
}
|
|
2759
2719
|
if (!source.sessionPassword || !source.sessionMnemonic) {
|
|
2760
2720
|
throw new Error('Session data is missing during transfer');
|
|
2761
2721
|
}
|
|
2762
|
-
__classPrivateFieldGet(this, _KeyringCore_instances, "m", _KeyringCore_replaceSessionBuffers).call(this, source.sessionPassword, source.sessionMnemonic, __classPrivateFieldGet(source, _KeyringCore_sessionOwnership, "f")
|
|
2722
|
+
__classPrivateFieldGet(this, _KeyringCore_instances, "m", _KeyringCore_replaceSessionBuffers).call(this, source.sessionPassword, source.sessionMnemonic, __classPrivateFieldGet(source, _KeyringCore_sessionOwnership, "f").token);
|
|
2763
2723
|
}, _KeyringCore_assertSessionOwner = function _KeyringCore_assertSessionOwner(sourceToken) {
|
|
2764
2724
|
const ownership = __classPrivateFieldGet(this, _KeyringCore_sessionOwnership, "f");
|
|
2765
|
-
if (!ownership)
|
|
2766
|
-
return;
|
|
2767
2725
|
if (ownership.destroyed)
|
|
2768
2726
|
throw new Error('Wallet keyring was destroyed');
|
|
2769
2727
|
const owner = ownership.tracker.current;
|
|
@@ -2774,8 +2732,6 @@ _KeyringCore_deviceUnlockRetired = new WeakMap(), _KeyringCore_sessionOwnership
|
|
|
2774
2732
|
}
|
|
2775
2733
|
}, _KeyringCore_captureSessionGuard = function _KeyringCore_captureSessionGuard(message = 'Wallet unlock session changed') {
|
|
2776
2734
|
const ownership = __classPrivateFieldGet(this, _KeyringCore_sessionOwnership, "f");
|
|
2777
|
-
if (!ownership)
|
|
2778
|
-
return undefined;
|
|
2779
2735
|
const revision = this.privateRecordSessionRevision;
|
|
2780
2736
|
const epoch = ownership.tracker.epoch;
|
|
2781
2737
|
return () => {
|
|
@@ -2800,10 +2756,8 @@ _KeyringCore_deviceUnlockRetired = new WeakMap(), _KeyringCore_sessionOwnership
|
|
|
2800
2756
|
this.sessionPassword = sessionPassword;
|
|
2801
2757
|
this.sessionMnemonic = sessionMnemonic;
|
|
2802
2758
|
const ownership = __classPrivateFieldGet(this, _KeyringCore_sessionOwnership, "f");
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
ownership.tracker.epoch++;
|
|
2806
|
-
}
|
|
2759
|
+
ownership.tracker.current = ownership.token;
|
|
2760
|
+
ownership.tracker.epoch++;
|
|
2807
2761
|
}, _KeyringCore_finishUnlock = function _KeyringCore_finishUnlock() {
|
|
2808
2762
|
// Re-initialize syscoin transaction handler if it was cleared on lock.
|
|
2809
2763
|
// `lockWallet()` intentionally replaces it with a plain object to drop signer references,
|
|
@@ -2851,16 +2805,13 @@ _KeyringCore_deviceUnlockRetired = new WeakMap(), _KeyringCore_sessionOwnership
|
|
|
2851
2805
|
// v4 vault is encrypted with the derived session password key (PBKDF2 output)
|
|
2852
2806
|
// `saltedHashPassword` is the derived session password key passed by caller.
|
|
2853
2807
|
const { mnemonic } = await this.vaultPersistence.getDecryptedVault(saltedHashPassword);
|
|
2854
|
-
assertCurrent
|
|
2808
|
+
assertCurrent();
|
|
2855
2809
|
if (!mnemonic) {
|
|
2856
2810
|
throw new Error('Mnemonic not found in vault');
|
|
2857
2811
|
}
|
|
2858
2812
|
__classPrivateFieldGet(this, _KeyringCore_instances, "m", _KeyringCore_installVaultSession).call(this, mnemonic, saltedHashPassword, assertCurrent);
|
|
2859
2813
|
// Capture the installed revision before returning to the async caller.
|
|
2860
|
-
|
|
2861
|
-
return __classPrivateFieldGet(this, _KeyringCore_instances, "m", _KeyringCore_captureSessionGuard).call(this);
|
|
2862
|
-
console.log('[KeyringManager] Session data recreated from vault');
|
|
2863
|
-
return undefined;
|
|
2814
|
+
return __classPrivateFieldGet(this, _KeyringCore_instances, "m", _KeyringCore_captureSessionGuard).call(this);
|
|
2864
2815
|
}
|
|
2865
2816
|
catch (error) {
|
|
2866
2817
|
console.error('ERROR recreateSessionFromVault', { error });
|