@sidhujag/sysweb3-keyring 1.0.627 → 2.0.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 +42 -0
- package/README.md +66 -0
- package/cjs/hardware-wallet-manager.js +302 -128
- package/cjs/hardware-wallet-manager.js.map +1 -1
- package/cjs/keyring-core.js +2605 -0
- package/cjs/keyring-core.js.map +1 -0
- package/cjs/keyring-manager.js +31 -2439
- package/cjs/keyring-manager.js.map +1 -1
- package/cjs/ledger/bitcoin_client/lib/appClient.js.map +1 -1
- package/cjs/ledger/host-types.js +10 -0
- package/cjs/ledger/host-types.js.map +1 -0
- package/cjs/ledger/index.js +243 -447
- package/cjs/ledger/index.js.map +1 -1
- package/cjs/ledger/prepare-psbt.js +177 -0
- package/cjs/ledger/prepare-psbt.js.map +1 -0
- package/cjs/software-hd-account.js +23 -0
- package/cjs/software-hd-account.js.map +1 -0
- package/cjs/software.js +74 -0
- package/cjs/software.js.map +1 -0
- package/cjs/storage-core.js +227 -0
- package/cjs/storage-core.js.map +1 -0
- package/cjs/storage.js +15 -210
- package/cjs/storage.js.map +1 -1
- package/cjs/transactions/ethereum.js +176 -39
- package/cjs/transactions/ethereum.js.map +1 -1
- package/cjs/transactions/evm-local-signer.js +11 -1
- package/cjs/transactions/evm-local-signer.js.map +1 -1
- package/cjs/transactions/hardware-psbt.js +159 -0
- package/cjs/transactions/hardware-psbt.js.map +1 -0
- package/cjs/transactions/prepared-evm.js +196 -0
- package/cjs/transactions/prepared-evm.js.map +1 -0
- package/cjs/transactions/syscoin-core.js +651 -0
- package/cjs/transactions/syscoin-core.js.map +1 -0
- package/cjs/transactions/syscoin.js +8 -768
- package/cjs/transactions/syscoin.js.map +1 -1
- package/cjs/trezor/connect.js +243 -0
- package/cjs/trezor/connect.js.map +1 -0
- package/cjs/trezor/index.js +96 -58
- package/cjs/trezor/index.js.map +1 -1
- package/cjs/trezor/witness.js +25 -0
- package/cjs/trezor/witness.js.map +1 -0
- package/cjs/types.js.map +1 -1
- package/cjs/utils/psbt-account-scope.js +5 -3
- package/cjs/utils/psbt-account-scope.js.map +1 -1
- package/esm/errorUtils.js +72 -0
- package/esm/errorUtils.js.map +1 -0
- package/esm/ethers-v6.js +207 -0
- package/esm/ethers-v6.js.map +1 -0
- package/esm/hardware-wallet-manager.js +643 -0
- package/esm/hardware-wallet-manager.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/appClient.js +279 -0
- package/esm/ledger/bitcoin_client/lib/appClient.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/bip32.js +49 -0
- package/esm/ledger/bitcoin_client/lib/bip32.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/buffertools.js +119 -0
- package/esm/ledger/bitcoin_client/lib/buffertools.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/clientCommands.js +269 -0
- package/esm/ledger/bitcoin_client/lib/clientCommands.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/merkelizedPsbt.js +50 -0
- package/esm/ledger/bitcoin_client/lib/merkelizedPsbt.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/merkle.js +111 -0
- package/esm/ledger/bitcoin_client/lib/merkle.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/merkleMap.js +42 -0
- package/esm/ledger/bitcoin_client/lib/merkleMap.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/policy.js +68 -0
- package/esm/ledger/bitcoin_client/lib/policy.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/psbtv2.js +645 -0
- package/esm/ledger/bitcoin_client/lib/psbtv2.js.map +1 -0
- package/esm/ledger/bitcoin_client/lib/varint.js +108 -0
- package/esm/ledger/bitcoin_client/lib/varint.js.map +1 -0
- package/esm/ledger/consts.js +4 -0
- package/esm/ledger/consts.js.map +1 -0
- package/esm/ledger/dmk-evm.js +258 -0
- package/esm/ledger/dmk-evm.js.map +1 -0
- package/esm/ledger/dmk-session.js +264 -0
- package/esm/ledger/dmk-session.js.map +1 -0
- package/esm/ledger/dmk-utxo.js +279 -0
- package/esm/ledger/dmk-utxo.js.map +1 -0
- package/esm/ledger/host-types.js +5 -0
- package/esm/ledger/host-types.js.map +1 -0
- package/esm/ledger/index.js +268 -0
- package/esm/ledger/index.js.map +1 -0
- package/esm/ledger/prepare-psbt.js +141 -0
- package/esm/ledger/prepare-psbt.js.map +1 -0
- package/esm/ledger/types.js +2 -0
- package/esm/ledger/types.js.map +1 -0
- package/esm/ledger-host.js +36 -0
- package/esm/ledger-host.js.map +1 -0
- package/esm/private-records.js +153 -0
- package/esm/private-records.js.map +1 -0
- package/esm/providers.js +588 -0
- package/esm/providers.js.map +1 -0
- package/esm/signers.js +28 -0
- package/esm/signers.js.map +1 -0
- package/esm/trezor/connect.js +206 -0
- package/esm/trezor/connect.js.map +1 -0
- package/esm/trezor/index.js +876 -0
- package/esm/trezor/index.js.map +1 -0
- package/esm/trezor/witness.js +21 -0
- package/esm/trezor/witness.js.map +1 -0
- package/esm/types.js +17 -0
- package/esm/types.js.map +1 -0
- package/esm/utils/derivation-paths.js +109 -0
- package/esm/utils/derivation-paths.js.map +1 -0
- package/esm/utils/psbt-account-scope.js +310 -0
- package/esm/utils/psbt-account-scope.js.map +1 -0
- package/package.json +55 -8
- package/types/hardware-wallet-manager.d.ts +12 -19
- package/types/keyring-core.d.ts +263 -0
- package/types/keyring-manager.d.ts +7 -224
- package/types/ledger/bitcoin_client/lib/appClient.d.ts +6 -3
- package/types/ledger/dmk-evm.d.ts +8 -0
- package/types/ledger/dmk-session.d.ts +60 -0
- package/types/ledger/dmk-utxo.d.ts +26 -0
- package/types/ledger/host-types.d.ts +131 -0
- package/types/ledger/index.d.ts +21 -58
- package/types/ledger/prepare-psbt.d.ts +3 -0
- package/types/ledger/types.d.ts +3 -0
- package/types/ledger-host.d.ts +7 -0
- package/types/software-hd-account.d.ts +16 -0
- package/types/software.d.ts +39 -0
- package/types/storage-core.d.ts +22 -0
- package/types/storage.d.ts +1 -4
- package/types/transactions/ethereum.d.ts +17 -7
- package/types/transactions/evm-local-signer.d.ts +3 -1
- package/types/transactions/hardware-psbt.d.ts +7 -0
- package/types/transactions/prepared-evm.d.ts +53 -0
- package/types/transactions/syscoin-core.d.ts +92 -0
- package/types/transactions/syscoin.d.ts +8 -67
- package/types/trezor/connect.d.ts +42 -0
- package/types/trezor/index.d.ts +22 -4
- package/types/trezor/witness.d.ts +3 -0
- package/types/types.d.ts +10 -0
- package/types/utils/psbt-account-scope.d.ts +1 -0
- package/cjs/transactions/__tests__/integration.test.js +0 -237
- package/cjs/transactions/__tests__/integration.test.js.map +0 -1
- package/cjs/transactions/__tests__/syscoin.test.js +0 -361
- package/cjs/transactions/__tests__/syscoin.test.js.map +0 -1
- package/types/transactions/__tests__/integration.test.d.ts +0 -1
- package/types/transactions/__tests__/syscoin.test.d.ts +0 -1
package/cjs/storage.js
CHANGED
|
@@ -1,215 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
3
|
+
exports.VaultAuthenticationError = exports.getDecryptedVault = exports.setEncryptedVault = void 0;
|
|
7
4
|
const sysweb3_core_1 = require("@sidhujag/sysweb3-core");
|
|
8
|
-
const
|
|
5
|
+
const storage_core_1 = require("./storage-core");
|
|
6
|
+
// Preserve the legacy process-wide storage authority. Host-isolated consumers
|
|
7
|
+
// import storage-core directly and supply their own asynchronous storage port.
|
|
9
8
|
const storage = sysweb3_core_1.sysweb3Di.getStateStorageDb();
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
async
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
await oldMutex;
|
|
22
|
-
try {
|
|
23
|
-
return await callback();
|
|
24
|
-
}
|
|
25
|
-
finally {
|
|
26
|
-
release();
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
const vaultMutex = new AsyncMutex();
|
|
31
|
-
const isHex = (s) => /^[0-9a-fA-F]+$/.test(s);
|
|
32
|
-
const hexToBytes = (hex) => {
|
|
33
|
-
const clean = (hex || '').trim();
|
|
34
|
-
if (!isHex(clean) || clean.length % 2 !== 0) {
|
|
35
|
-
throw new Error('Invalid hex string');
|
|
36
|
-
}
|
|
37
|
-
const out = new Uint8Array(clean.length / 2);
|
|
38
|
-
for (let i = 0; i < out.length; i++) {
|
|
39
|
-
out[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);
|
|
40
|
-
}
|
|
41
|
-
return out;
|
|
42
|
-
};
|
|
43
|
-
const bytesToHex = (bytes) => {
|
|
44
|
-
const u8 = new Uint8Array(bytes);
|
|
45
|
-
let hex = '';
|
|
46
|
-
for (let i = 0; i < u8.length; i++) {
|
|
47
|
-
hex += u8[i].toString(16).padStart(2, '0');
|
|
48
|
-
}
|
|
49
|
-
return hex;
|
|
50
|
-
};
|
|
51
|
-
const maybeParseGcmEnvelope = (raw) => {
|
|
52
|
-
if (!raw || typeof raw !== 'string')
|
|
53
|
-
return null;
|
|
54
|
-
if (!raw.trim().startsWith('{'))
|
|
55
|
-
return null;
|
|
56
|
-
try {
|
|
57
|
-
const parsed = JSON.parse(raw);
|
|
58
|
-
if (parsed &&
|
|
59
|
-
parsed.v === 4 &&
|
|
60
|
-
parsed.alg === 'A256GCM' &&
|
|
61
|
-
typeof parsed.iv === 'string' &&
|
|
62
|
-
typeof parsed.ct === 'string') {
|
|
63
|
-
return parsed;
|
|
64
|
-
}
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
|
-
catch {
|
|
68
|
-
return null;
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
const encryptVaultWebCrypto = async (plaintextJson, keyHex) => {
|
|
72
|
-
const subtle = globalThis.crypto.subtle;
|
|
73
|
-
const iv = new Uint8Array(12);
|
|
74
|
-
globalThis.crypto.getRandomValues(iv);
|
|
75
|
-
const keyBytes = hexToBytes(keyHex);
|
|
76
|
-
if (keyBytes.length !== 32) {
|
|
77
|
-
throw new Error('Vault key must be 32 bytes (hex length 64)');
|
|
78
|
-
}
|
|
79
|
-
const key = await subtle.importKey('raw', keyBytes, { name: 'AES-GCM' }, false, ['encrypt']);
|
|
80
|
-
const pt = new TextEncoder().encode(plaintextJson);
|
|
81
|
-
const ct = await subtle.encrypt({ name: 'AES-GCM', iv: iv }, key, pt);
|
|
82
|
-
return {
|
|
83
|
-
v: 4,
|
|
84
|
-
alg: 'A256GCM',
|
|
85
|
-
iv: bytesToHex(iv.buffer),
|
|
86
|
-
ct: bytesToHex(ct),
|
|
87
|
-
};
|
|
88
|
-
};
|
|
89
|
-
class VaultAuthenticationError extends Error {
|
|
90
|
-
constructor() {
|
|
91
|
-
super('Failed to decrypt vault - invalid password or corrupted data');
|
|
92
|
-
this.code = 'INVALID_PASSWORD';
|
|
93
|
-
this.name = 'VaultAuthenticationError';
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
exports.VaultAuthenticationError = VaultAuthenticationError;
|
|
97
|
-
const invalidPasswordError = () => new VaultAuthenticationError();
|
|
98
|
-
const decryptVaultWebCrypto = async (envelope, keyHex) => {
|
|
99
|
-
const subtle = globalThis?.crypto?.subtle;
|
|
100
|
-
if (!subtle) {
|
|
101
|
-
throw new Error('WebCrypto is required to decrypt this vault');
|
|
102
|
-
}
|
|
103
|
-
const keyBytes = hexToBytes(keyHex);
|
|
104
|
-
if (keyBytes.length !== 32) {
|
|
105
|
-
throw new Error('Vault key must be 32 bytes (hex length 64)');
|
|
106
|
-
}
|
|
107
|
-
const key = await subtle.importKey('raw', keyBytes, { name: 'AES-GCM' }, false, ['decrypt']);
|
|
108
|
-
const ivBytes = hexToBytes(envelope.iv);
|
|
109
|
-
const ctBytes = hexToBytes(envelope.ct);
|
|
110
|
-
if (ivBytes.length !== 12 || ctBytes.length < 16) {
|
|
111
|
-
throw new Error('Invalid encrypted vault format');
|
|
112
|
-
}
|
|
113
|
-
let pt;
|
|
114
|
-
try {
|
|
115
|
-
pt = await subtle.decrypt({ name: 'AES-GCM', iv: ivBytes }, key, ctBytes);
|
|
116
|
-
}
|
|
117
|
-
catch (error) {
|
|
118
|
-
// Only a failed authentication tag is a password/ciphertext failure.
|
|
119
|
-
// Key import and other platform exceptions must remain operational.
|
|
120
|
-
if (error?.name === 'OperationError') {
|
|
121
|
-
throw invalidPasswordError();
|
|
122
|
-
}
|
|
123
|
-
throw error;
|
|
124
|
-
}
|
|
125
|
-
return new TextDecoder().decode(pt);
|
|
126
|
-
};
|
|
127
|
-
// Single vault for all networks - stores the mnemonic and can derive accounts for any slip44
|
|
128
|
-
const setEncryptedVault = async (decryptedVault, pwd, freshVaultKeys) => {
|
|
129
|
-
return vaultMutex.runExclusive(async () => {
|
|
130
|
-
const plaintext = JSON.stringify(decryptedVault);
|
|
131
|
-
// Writes never downgrade to unauthenticated passphrase AES. Legacy CBC
|
|
132
|
-
// remains readable below, but missing WebCrypto is an operational failure.
|
|
133
|
-
const canUseWebCrypto = !!globalThis?.crypto?.subtle &&
|
|
134
|
-
!!globalThis?.crypto?.getRandomValues;
|
|
135
|
-
if (!canUseWebCrypto) {
|
|
136
|
-
throw new Error('WebCrypto is required for vault encryption');
|
|
137
|
-
}
|
|
138
|
-
if (typeof pwd !== 'string' || !isHex(pwd) || pwd.length !== 64) {
|
|
139
|
-
throw new Error('Vault key must be 32 bytes (hex length 64)');
|
|
140
|
-
}
|
|
141
|
-
const envelope = await encryptVaultWebCrypto(plaintext, pwd);
|
|
142
|
-
const toStore = JSON.stringify(envelope);
|
|
143
|
-
if (freshVaultKeys) {
|
|
144
|
-
// The backend primitive (or native storage Web Lock) covers both the
|
|
145
|
-
// absence check and batch commit across independently bundled contexts.
|
|
146
|
-
const created = await storage.createManyIfAbsent({
|
|
147
|
-
'vault-keys': freshVaultKeys,
|
|
148
|
-
vault: toStore,
|
|
149
|
-
});
|
|
150
|
-
if (!created)
|
|
151
|
-
throw new Error('Cannot initialize a new vault over existing wallet storage');
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
// Existing vault updates retain their migration-specific write ordering.
|
|
155
|
-
await storage.set('vault', toStore);
|
|
156
|
-
}
|
|
157
|
-
});
|
|
158
|
-
};
|
|
159
|
-
exports.setEncryptedVault = setEncryptedVault;
|
|
160
|
-
const getDecryptedVault = async (pwd, legacyPassword) => {
|
|
161
|
-
return vaultMutex.runExclusive(async () => {
|
|
162
|
-
// Always use single 'vault' key
|
|
163
|
-
const vault = await storage.get('vault');
|
|
164
|
-
if (!vault) {
|
|
165
|
-
throw new Error('Vault not found');
|
|
166
|
-
}
|
|
167
|
-
// Prefer WebCrypto AES-GCM when the stored vault is in v4 envelope format.
|
|
168
|
-
const maybeEnvelope = maybeParseGcmEnvelope(vault);
|
|
169
|
-
if (!maybeEnvelope &&
|
|
170
|
-
typeof vault === 'string' &&
|
|
171
|
-
vault.trim().startsWith('{')) {
|
|
172
|
-
// Legacy CBC vaults are base64. A JSON-shaped record must be a valid
|
|
173
|
-
// GCM envelope rather than being misreported as a password failure.
|
|
174
|
-
throw new Error('Invalid encrypted vault format');
|
|
175
|
-
}
|
|
176
|
-
let decryptedVault;
|
|
177
|
-
if (maybeEnvelope) {
|
|
178
|
-
decryptedVault = await decryptVaultWebCrypto(maybeEnvelope, pwd);
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
// Legacy CryptoJS passphrase-AES vault (v3 and older v4 canary).
|
|
182
|
-
// An interrupted migration can already have written CBC with the
|
|
183
|
-
// derived key while the metadata still selects the legacy password.
|
|
184
|
-
for (const candidateKey of new Set([legacyPassword ?? pwd, pwd])) {
|
|
185
|
-
let plaintext;
|
|
186
|
-
try {
|
|
187
|
-
plaintext = crypto_js_1.default.AES.decrypt(vault, candidateKey).toString(crypto_js_1.default.enc.Utf8);
|
|
188
|
-
}
|
|
189
|
-
catch (error) {
|
|
190
|
-
if (error?.message === 'Malformed UTF-8 data')
|
|
191
|
-
continue;
|
|
192
|
-
throw error;
|
|
193
|
-
}
|
|
194
|
-
if (!plaintext)
|
|
195
|
-
continue;
|
|
196
|
-
try {
|
|
197
|
-
return JSON.parse(plaintext);
|
|
198
|
-
}
|
|
199
|
-
catch (error) {
|
|
200
|
-
// CBC has no authentication tag; invalid plaintext is the only
|
|
201
|
-
// available indication of a bad password/ciphertext.
|
|
202
|
-
if (!(error instanceof SyntaxError))
|
|
203
|
-
throw error;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
throw invalidPasswordError();
|
|
207
|
-
}
|
|
208
|
-
if (!decryptedVault) {
|
|
209
|
-
throw invalidPasswordError();
|
|
210
|
-
}
|
|
211
|
-
return JSON.parse(decryptedVault);
|
|
212
|
-
});
|
|
213
|
-
};
|
|
214
|
-
exports.getDecryptedVault = getDecryptedVault;
|
|
9
|
+
const persistence = (0, storage_core_1.createVaultPersistence)({
|
|
10
|
+
get: async (key) => storage.get(key),
|
|
11
|
+
set: async (key, value) => {
|
|
12
|
+
await storage.set(key, value);
|
|
13
|
+
},
|
|
14
|
+
createManyIfAbsent: async (items) => storage.createManyIfAbsent(items),
|
|
15
|
+
});
|
|
16
|
+
exports.setEncryptedVault = persistence.setEncryptedVault;
|
|
17
|
+
exports.getDecryptedVault = persistence.getDecryptedVault;
|
|
18
|
+
var storage_core_2 = require("./storage-core");
|
|
19
|
+
Object.defineProperty(exports, "VaultAuthenticationError", { enumerable: true, get: function () { return storage_core_2.VaultAuthenticationError; } });
|
|
215
20
|
//# sourceMappingURL=storage.js.map
|
package/cjs/storage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/storage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/storage.ts"],"names":[],"mappings":";;;AAAA,yDAAmD;AAEnD,iDAAwD;AAExD,8EAA8E;AAC9E,+EAA+E;AAC/E,MAAM,OAAO,GAAG,wBAAS,CAAC,iBAAiB,EAAE,CAAC;AAC9C,MAAM,WAAW,GAAG,IAAA,qCAAsB,EAAC;IACzC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;IACpC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;QACxB,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAChC,CAAC;IACD,kBAAkB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC;CACvE,CAAC,CAAC;AAEU,QAAA,iBAAiB,GAAG,WAAW,CAAC,iBAAiB,CAAC;AAClD,QAAA,iBAAiB,GAAG,WAAW,CAAC,iBAAiB,CAAC;AAC/D,+CAA0D;AAAjD,wHAAA,wBAAwB,OAAA"}
|