@talismn/keyring 0.0.0-pr2277-20251211071316 → 0.0.0-pr2295-20260110044132

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/dist/index.js ADDED
@@ -0,0 +1,467 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Keyring: () => Keyring,
24
+ getAccountGenesisHash: () => getAccountGenesisHash,
25
+ getAccountPlatform: () => getAccountPlatform,
26
+ getAccountSignetUrl: () => getAccountSignetUrl,
27
+ isAccountAddressEthereum: () => isAccountAddressEthereum,
28
+ isAccountAddressSs58: () => isAccountAddressSs58,
29
+ isAccountBitcoin: () => isAccountBitcoin,
30
+ isAccountExternal: () => isAccountExternal,
31
+ isAccountInTypes: () => isAccountInTypes,
32
+ isAccountLedgerPolkadot: () => isAccountLedgerPolkadot,
33
+ isAccountLedgerPolkadotGeneric: () => isAccountLedgerPolkadotGeneric,
34
+ isAccountLedgerPolkadotLegacy: () => isAccountLedgerPolkadotLegacy,
35
+ isAccountNotContact: () => isAccountNotContact,
36
+ isAccountOfType: () => isAccountOfType,
37
+ isAccountOwned: () => isAccountOwned,
38
+ isAccountPlatformEthereum: () => isAccountPlatformEthereum,
39
+ isAccountPlatformPolkadot: () => isAccountPlatformPolkadot,
40
+ isAccountPlatformSolana: () => isAccountPlatformSolana,
41
+ isAccountPortfolio: () => isAccountPortfolio
42
+ });
43
+ module.exports = __toCommonJS(index_exports);
44
+
45
+ // src/types/utils.ts
46
+ var import_crypto = require("@talismn/crypto");
47
+ var isAccountOfType = (account, type) => {
48
+ return account?.type === type;
49
+ };
50
+ var isAccountInTypes = (account, types) => {
51
+ return !!account && types.includes(account.type);
52
+ };
53
+ var ACCOUNT_TYPES_OWNED = [
54
+ "keypair",
55
+ "ledger-ethereum",
56
+ "ledger-polkadot",
57
+ "ledger-solana",
58
+ "polkadot-vault"
59
+ ];
60
+ var ACCOUNT_TYPES_EXTERNAL = [
61
+ "contact",
62
+ "watch-only",
63
+ "ledger-ethereum",
64
+ "ledger-polkadot",
65
+ "ledger-solana",
66
+ "polkadot-vault",
67
+ "signet"
68
+ ];
69
+ var isAccountExternal = (account) => {
70
+ return isAccountInTypes(account, ACCOUNT_TYPES_EXTERNAL);
71
+ };
72
+ var isAccountOwned = (account) => {
73
+ return isAccountInTypes(account, ACCOUNT_TYPES_OWNED);
74
+ };
75
+ var isAccountPortfolio = (account) => {
76
+ return isAccountOwned(account) || isAccountOfType(account, "watch-only") && account.isPortfolio;
77
+ };
78
+ var isAccountNotContact = (acc) => acc.type !== "contact";
79
+ var isAccountAddressEthereum = (account) => {
80
+ return !!account && (0, import_crypto.isEthereumAddress)(account.address);
81
+ };
82
+ var isAccountPlatformEthereum = (account) => {
83
+ return !!account && account.type !== "ledger-polkadot" && (0, import_crypto.isEthereumAddress)(account.address);
84
+ };
85
+ var isAccountPlatformSolana = (account) => {
86
+ return !!account && (0, import_crypto.isSolanaAddress)(account.address);
87
+ };
88
+ var isAccountPlatformPolkadot = (account) => {
89
+ return !!account && account.type !== "ledger-ethereum" && (isAccountAddressEthereum(account) || isAccountAddressSs58(account));
90
+ };
91
+ var isAccountAddressSs58 = (account) => {
92
+ return !!account && (0, import_crypto.detectAddressEncoding)(account.address) === "ss58";
93
+ };
94
+ var isAccountLedgerPolkadot = (account) => {
95
+ return isAccountOfType(account, "ledger-polkadot");
96
+ };
97
+ var isAccountLedgerPolkadotGeneric = (account) => {
98
+ return isAccountOfType(account, "ledger-polkadot") && !account.genesisHash;
99
+ };
100
+ var isAccountLedgerPolkadotLegacy = (account) => {
101
+ return isAccountOfType(account, "ledger-polkadot") && !!account.genesisHash;
102
+ };
103
+ var isAccountBitcoin = (account) => {
104
+ return !!account && (0, import_crypto.isBitcoinAddress)(account.address);
105
+ };
106
+ var getAccountGenesisHash = (account) => {
107
+ if (!account) return void 0;
108
+ return "genesisHash" in account ? account.genesisHash || void 0 : void 0;
109
+ };
110
+ var getAccountSignetUrl = (account) => {
111
+ return isAccountOfType(account, "signet") ? account.url : void 0;
112
+ };
113
+ var getAccountPlatform = (account) => {
114
+ if (!account) return void 0;
115
+ return "curve" in account ? (0, import_crypto.getAccountPlatformFromCurve)(account.curve) : (0, import_crypto.getAccountPlatformFromAddress)(account.address);
116
+ };
117
+
118
+ // src/keyring/Keyring.ts
119
+ var import_crypto3 = require("@talismn/crypto");
120
+
121
+ // src/keyring/encryption.ts
122
+ var import_crypto2 = require("@talismn/crypto");
123
+ var deriveKey = async (password, salt) => (
124
+ // Deriving 32-byte key using PBKDF2 with 100,000 iterations and SHA-256
125
+ await crypto.subtle.importKey(
126
+ "raw",
127
+ await (0, import_crypto2.pbkdf2)(
128
+ "SHA-256",
129
+ new TextEncoder().encode(password),
130
+ salt,
131
+ 1e5,
132
+ // 100,000 iterations
133
+ 32
134
+ // 32 bytes (32 * 8 == 256 bits)
135
+ ),
136
+ { name: "AES-GCM", length: 256 },
137
+ false,
138
+ ["encrypt", "decrypt"]
139
+ )
140
+ );
141
+ var encryptData = async (data, password) => {
142
+ try {
143
+ const salt = crypto.getRandomValues(new Uint8Array(16));
144
+ const iv = crypto.getRandomValues(new Uint8Array(12));
145
+ const key = await deriveKey(password, salt);
146
+ const encryptedSeed = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, data);
147
+ const combined = new Uint8Array(salt.length + iv.length + encryptedSeed.byteLength);
148
+ combined.set(salt, 0);
149
+ combined.set(iv, salt.length);
150
+ combined.set(new Uint8Array(encryptedSeed), salt.length + iv.length);
151
+ return btoa(String.fromCharCode(...combined));
152
+ } catch (cause) {
153
+ throw new Error("Failed to encrypt data", { cause });
154
+ }
155
+ };
156
+ var decryptData = async (encryptedData, password) => {
157
+ try {
158
+ const combined = Uint8Array.from(atob(encryptedData), (c) => c.charCodeAt(0));
159
+ const salt = combined.slice(0, 16);
160
+ const iv = combined.slice(16, 28);
161
+ const encryptedSeed = combined.slice(28);
162
+ const key = await deriveKey(password, salt);
163
+ const decryptedSeed = await crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, encryptedSeed);
164
+ return new Uint8Array(decryptedSeed);
165
+ } catch (cause) {
166
+ throw new Error("Failed to decrypt data", { cause });
167
+ }
168
+ };
169
+ var changeEncryptedDataPassword = async (encryptedData, oldPassword, newPassword) => {
170
+ try {
171
+ const decrypted = await decryptData(encryptedData, oldPassword);
172
+ return await encryptData(decrypted, newPassword);
173
+ } catch (cause) {
174
+ throw new Error("Failed to change password on encrypted data", { cause });
175
+ }
176
+ };
177
+
178
+ // src/keyring/utils.ts
179
+ var REGEX_HEX_STRING = /^0x[0-9a-fA-F]*$/;
180
+ var isHexString = (value) => {
181
+ return typeof value === "string" && REGEX_HEX_STRING.test(value);
182
+ };
183
+
184
+ // src/keyring/Keyring.ts
185
+ var Keyring = class _Keyring {
186
+ #data;
187
+ constructor(data) {
188
+ this.#data = structuredClone(data);
189
+ }
190
+ static create() {
191
+ return new _Keyring({
192
+ passwordCheck: null,
193
+ // well-known data encrypted using the password, used to ensure all secrets of the keyring are encrypted with the same password
194
+ mnemonics: [],
195
+ accounts: []
196
+ });
197
+ }
198
+ static load(data) {
199
+ if (!data.accounts || !data.mnemonics) throw new Error("Invalid data");
200
+ for (const account of data.accounts) {
201
+ if (account.type === "ledger-polkadot" && !account.curve) account.curve = "ed25519";
202
+ }
203
+ return new _Keyring(data);
204
+ }
205
+ async checkPassword(password, reset = false) {
206
+ if (typeof password !== "string" || !password) throw new Error("password is required");
207
+ const passwordHash = oneWayHash(password);
208
+ const PASSWORD_CHECK_PHRASE = "PASSWORD_CHECK_PHRASE";
209
+ if (!this.#data.passwordCheck || reset) {
210
+ const bytes = import_crypto3.utf8.decode(PASSWORD_CHECK_PHRASE);
211
+ this.#data.passwordCheck = await encryptData(bytes, passwordHash);
212
+ } else {
213
+ try {
214
+ const bytes = await decryptData(this.#data.passwordCheck, passwordHash);
215
+ const text = import_crypto3.utf8.encode(bytes);
216
+ if (text !== PASSWORD_CHECK_PHRASE) throw new Error("Invalid password");
217
+ } catch {
218
+ throw new Error("Invalid password");
219
+ }
220
+ }
221
+ }
222
+ toJson() {
223
+ return structuredClone(this.#data);
224
+ }
225
+ async export(password, jsonPassword) {
226
+ const keyring = new _Keyring(structuredClone(this.#data));
227
+ for (const mnemonic of keyring.#data.mnemonics)
228
+ mnemonic.entropy = await changeEncryptedDataPassword(mnemonic.entropy, password, jsonPassword);
229
+ for (const account of keyring.#data.accounts)
230
+ if (account.type === "keypair")
231
+ account.secretKey = await changeEncryptedDataPassword(
232
+ account.secretKey,
233
+ password,
234
+ jsonPassword
235
+ );
236
+ await keyring.checkPassword(jsonPassword, true);
237
+ return keyring.toJson();
238
+ }
239
+ getMnemonics() {
240
+ return this.#data.mnemonics.map(mnemonicFromStorage);
241
+ }
242
+ async addMnemonic({ name, mnemonic, confirmed }, password) {
243
+ if (typeof name !== "string" || !name) throw new Error("name is required");
244
+ if (typeof mnemonic !== "string") throw new Error("mnemonic is required");
245
+ if (typeof confirmed !== "boolean") throw new Error("confirmed is required");
246
+ if (!(0, import_crypto3.isValidMnemonic)(mnemonic)) throw new Error("Invalid mnemonic");
247
+ await this.checkPassword(password);
248
+ const entropy = (0, import_crypto3.mnemonicToEntropy)(mnemonic);
249
+ const id = oneWayHash(entropy);
250
+ if (this.#data.mnemonics.find((s) => s.id === id)) throw new Error("Mnemonic already exists");
251
+ const storage = {
252
+ id,
253
+ name,
254
+ entropy: await encryptData(entropy, password),
255
+ confirmed,
256
+ createdAt: Date.now()
257
+ };
258
+ this.#data.mnemonics.push(storage);
259
+ return mnemonicFromStorage(storage);
260
+ }
261
+ getMnemonic(id) {
262
+ const mnemonic = this.#data.mnemonics.find((s) => s.id === id);
263
+ return mnemonic ? mnemonicFromStorage(mnemonic) : null;
264
+ }
265
+ updateMnemonic(id, { name, confirmed }) {
266
+ const mnemonic = this.#data.mnemonics.find((s) => s.id === id);
267
+ if (!mnemonic) throw new Error("Mnemonic not found");
268
+ if (name !== void 0) {
269
+ if (typeof name !== "string" || !name) throw new Error("name must be a string");
270
+ mnemonic.name = name;
271
+ }
272
+ if (confirmed !== void 0) {
273
+ if (typeof confirmed !== "boolean") throw new Error("confirmed must be a boolean");
274
+ mnemonic.confirmed = confirmed;
275
+ }
276
+ return mnemonicFromStorage(mnemonic);
277
+ }
278
+ removeMnemonic(id) {
279
+ const index = this.#data.mnemonics.findIndex((mnemonic) => mnemonic.id == id);
280
+ if (index === -1) throw new Error("Mnemonic not found");
281
+ this.#data.mnemonics.splice(index, 1);
282
+ }
283
+ async getMnemonicText(id, password) {
284
+ const mnemonic = this.#data.mnemonics.find((s) => s.id === id);
285
+ if (!mnemonic) throw new Error("Mnemonic not found");
286
+ const entropy = await decryptData(mnemonic.entropy, password);
287
+ return (0, import_crypto3.entropyToMnemonic)(entropy);
288
+ }
289
+ getExistingMnemonicId(mnemonic) {
290
+ const entropy = (0, import_crypto3.mnemonicToEntropy)(mnemonic);
291
+ const mnemonicId = oneWayHash(entropy);
292
+ return this.#data.mnemonics.some((s) => s.id === mnemonicId) ? mnemonicId : null;
293
+ }
294
+ getAccounts() {
295
+ return this.#data.accounts.map(accountFromStorage);
296
+ }
297
+ getAccount(address) {
298
+ const account = this.#data.accounts.find((s) => (0, import_crypto3.isAddressEqual)(s.address, address));
299
+ return account ? accountFromStorage(account) : null;
300
+ }
301
+ updateAccount(address, { name, isPortfolio, genesisHash }) {
302
+ const account = this.#data.accounts.find((s) => s.address === address);
303
+ if (!account) throw new Error("Account not found");
304
+ if (name) {
305
+ if (typeof name !== "string" || !name) throw new Error("name is required");
306
+ account.name = name;
307
+ }
308
+ if (account.type === "watch-only" && isPortfolio !== void 0) {
309
+ if (typeof isPortfolio !== "boolean") throw new Error("isPortfolio must be a boolean");
310
+ account.isPortfolio = isPortfolio;
311
+ }
312
+ if (account.type === "contact") {
313
+ if (genesisHash) {
314
+ if (!isHexString(genesisHash)) throw new Error("genesisHash must be a hex string");
315
+ account.genesisHash = genesisHash;
316
+ } else delete account.genesisHash;
317
+ }
318
+ return accountFromStorage(account);
319
+ }
320
+ removeAccount(address) {
321
+ const index = this.#data.accounts.findIndex((s) => (0, import_crypto3.isAddressEqual)(s.address, address));
322
+ if (index === -1) throw new Error("Account not found");
323
+ this.#data.accounts.splice(index, 1);
324
+ }
325
+ addAccountExternal(options) {
326
+ const address = (0, import_crypto3.normalizeAddress)(options.address);
327
+ if (this.getAccount(address)) throw new Error("Account already exists");
328
+ const account = {
329
+ ...options,
330
+ address,
331
+ createdAt: Date.now()
332
+ };
333
+ if (!isAccountExternal(account)) throw new Error("Invalid account type");
334
+ this.#data.accounts.push(account);
335
+ return accountFromStorage(account);
336
+ }
337
+ /**
338
+ * Needs to be called before deriving an account from a mnemonic.
339
+ *
340
+ * This will ensure that it is present (or add it if possible) in the keyring before actually creating the account.
341
+ *
342
+ * @param options
343
+ * @param password
344
+ * @returns the id of the mnemonic
345
+ */
346
+ async ensureMnemonic(options, password) {
347
+ await this.checkPassword(password);
348
+ switch (options.type) {
349
+ case "new-mnemonic": {
350
+ const { mnemonic, mnemonicName: name, confirmed } = options;
351
+ if (typeof name !== "string" || !name) throw new Error("mnemonicName is required");
352
+ if (typeof confirmed !== "boolean") throw new Error("confirmed is required");
353
+ const mnemonicId = this.getExistingMnemonicId(mnemonic);
354
+ if (mnemonicId) return mnemonicId;
355
+ const { id } = await this.addMnemonic(
356
+ {
357
+ name,
358
+ mnemonic,
359
+ confirmed
360
+ },
361
+ password
362
+ );
363
+ return id;
364
+ }
365
+ case "existing-mnemonic": {
366
+ if (typeof options.mnemonicId !== "string" || !options.mnemonicId)
367
+ throw new Error("mnemonicId must be a string");
368
+ return options.mnemonicId;
369
+ }
370
+ }
371
+ }
372
+ async addAccountDerive(options, password) {
373
+ await this.checkPassword(password);
374
+ const { curve, derivationPath, name } = options;
375
+ const mnemonicId = await this.ensureMnemonic(options, password);
376
+ const mnemonic = this.#data.mnemonics.find((s) => s.id === mnemonicId);
377
+ if (!mnemonic) throw new Error("Mnemonic not found");
378
+ const entropy = await decryptData(mnemonic.entropy, password);
379
+ const seed = await (0, import_crypto3.entropyToSeed)(entropy, curve);
380
+ const pair = (0, import_crypto3.deriveKeypair)(seed, derivationPath, curve);
381
+ if (this.getAccount(pair.address)) throw new Error("Account already exists");
382
+ const account = {
383
+ type: "keypair",
384
+ curve,
385
+ name,
386
+ address: (0, import_crypto3.normalizeAddress)(pair.address),
387
+ secretKey: await encryptData(pair.secretKey, password),
388
+ mnemonicId,
389
+ derivationPath,
390
+ createdAt: Date.now()
391
+ };
392
+ this.#data.accounts.push(account);
393
+ return accountFromStorage(account);
394
+ }
395
+ async addAccountKeypair({ curve, name, secretKey }, password) {
396
+ await this.checkPassword(password);
397
+ const publicKey = (0, import_crypto3.getPublicKeyFromSecret)(secretKey, curve);
398
+ const encoding = (0, import_crypto3.addressEncodingFromCurve)(curve);
399
+ const address = (0, import_crypto3.addressFromPublicKey)(publicKey, encoding);
400
+ if (this.getAccount(address)) throw new Error("Account already exists");
401
+ const account = {
402
+ type: "keypair",
403
+ curve,
404
+ name,
405
+ address: (0, import_crypto3.normalizeAddress)(address),
406
+ secretKey: await encryptData(secretKey, password),
407
+ createdAt: Date.now()
408
+ };
409
+ this.#data.accounts.push(account);
410
+ return accountFromStorage(account);
411
+ }
412
+ getAccountSecretKey(address, password) {
413
+ if (typeof address !== "string" || !address) throw new Error("address is required");
414
+ if (typeof password !== "string" || !password) throw new Error("password is required");
415
+ const account = this.#data.accounts.find((a) => a.address === (0, import_crypto3.normalizeAddress)(address));
416
+ if (!account) throw new Error("Account not found");
417
+ if (account.type !== "keypair") throw new Error("Secret key unavailable");
418
+ return decryptData(account.secretKey, password);
419
+ }
420
+ async getDerivedAddress(mnemonicId, derivationPath, curve, password) {
421
+ if (typeof mnemonicId !== "string" || !mnemonicId) throw new Error("mnemonicId is required");
422
+ if (typeof password !== "string" || !password) throw new Error("password is required");
423
+ const mnemonic = this.#data.mnemonics.find((s) => s.id === mnemonicId);
424
+ if (!mnemonic) throw new Error("Mnemonic not found");
425
+ const entropy = await decryptData(mnemonic.entropy, password);
426
+ const seed = await (0, import_crypto3.entropyToSeed)(entropy, curve);
427
+ const pair = (0, import_crypto3.deriveKeypair)(seed, derivationPath, curve);
428
+ return pair.address;
429
+ }
430
+ };
431
+ var oneWayHash = (bytes) => {
432
+ if (typeof bytes === "string") bytes = import_crypto3.utf8.decode(bytes);
433
+ return import_crypto3.base58.encode((0, import_crypto3.blake3)(bytes));
434
+ };
435
+ var mnemonicFromStorage = (data) => {
436
+ const copy = structuredClone(data);
437
+ if ("entropy" in copy) delete copy.entropy;
438
+ return Object.freeze(copy);
439
+ };
440
+ var accountFromStorage = (data) => {
441
+ const copy = structuredClone(data);
442
+ if ("secretKey" in copy) delete copy.secretKey;
443
+ return Object.freeze(copy);
444
+ };
445
+ // Annotate the CommonJS export names for ESM import in node:
446
+ 0 && (module.exports = {
447
+ Keyring,
448
+ getAccountGenesisHash,
449
+ getAccountPlatform,
450
+ getAccountSignetUrl,
451
+ isAccountAddressEthereum,
452
+ isAccountAddressSs58,
453
+ isAccountBitcoin,
454
+ isAccountExternal,
455
+ isAccountInTypes,
456
+ isAccountLedgerPolkadot,
457
+ isAccountLedgerPolkadotGeneric,
458
+ isAccountLedgerPolkadotLegacy,
459
+ isAccountNotContact,
460
+ isAccountOfType,
461
+ isAccountOwned,
462
+ isAccountPlatformEthereum,
463
+ isAccountPlatformPolkadot,
464
+ isAccountPlatformSolana,
465
+ isAccountPortfolio
466
+ });
467
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/types/utils.ts","../src/keyring/Keyring.ts","../src/keyring/encryption.ts","../src/keyring/utils.ts"],"sourcesContent":["export * from \"./types\"\nexport * from \"./keyring\"\n","import {\n detectAddressEncoding,\n getAccountPlatformFromAddress,\n getAccountPlatformFromCurve,\n isBitcoinAddress,\n isEthereumAddress,\n isSolanaAddress,\n} from \"@talismn/crypto\"\n\nimport type { Account, AccountLedgerPolkadot, AccountType } from \"./account\"\n\nexport type AccountOfType<Type extends AccountType> = Extract<Account, { type: Type }>\n\nexport const isAccountOfType = <Type extends AccountType>(\n account: Account | null | undefined,\n type: Type,\n): account is AccountOfType<Type> => {\n return account?.type === type\n}\n\nexport const isAccountInTypes = <Types extends AccountType[]>(\n account: Account | null | undefined,\n types: Types,\n): account is AccountOfType<Types[number]> => {\n return !!account && types.includes(account.type)\n}\n\nconst ACCOUNT_TYPES_OWNED = [\n \"keypair\",\n \"ledger-ethereum\",\n \"ledger-polkadot\",\n \"ledger-solana\",\n \"polkadot-vault\",\n] as const\n\nconst ACCOUNT_TYPES_EXTERNAL = [\n \"contact\",\n \"watch-only\",\n \"ledger-ethereum\",\n \"ledger-polkadot\",\n \"ledger-solana\",\n \"polkadot-vault\",\n \"signet\",\n] as const\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst ACCOUNT_TYPES_ADDRESS_ETHEREUM = [\n \"contact\",\n \"watch-only\",\n \"keypair\",\n \"ledger-ethereum\",\n \"ledger-polkadot\",\n] as const\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst ACCOUNT_TYPES_PLATFORM_ETHEREUM = [\n \"contact\",\n \"watch-only\",\n \"keypair\",\n \"ledger-ethereum\",\n] as const\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst ACCOUNT_TYPES_PLATFORM_POLKADOT = [\n \"contact\",\n \"watch-only\",\n \"keypair\",\n \"ledger-polkadot\",\n \"polkadot-vault\",\n \"signet\",\n] as const\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst ACCOUNT_TYPES_ADDRESS_SS58 = [\n \"contact\",\n \"watch-only\",\n \"keypair\",\n \"ledger-polkadot\",\n \"polkadot-vault\",\n \"signet\",\n] as const\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst ACCOUNT_TYPES_PLATFORM_SOLANA = [\"contact\", \"watch-only\", \"keypair\", \"ledger-solana\"] as const\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst ACCOUNT_TYPES_BITCOIN = [\"contact\", \"watch-only\"] as const\n\nexport const isAccountExternal = (\n account: Account | null | undefined,\n): account is AccountOfType<(typeof ACCOUNT_TYPES_EXTERNAL)[number]> => {\n return isAccountInTypes(account, ACCOUNT_TYPES_EXTERNAL as unknown as AccountType[])\n}\n\nexport const isAccountOwned = (\n account: Account | null | undefined,\n): account is AccountOfType<(typeof ACCOUNT_TYPES_OWNED)[number]> => {\n return isAccountInTypes(account, ACCOUNT_TYPES_OWNED as unknown as AccountType[])\n}\n\nexport const isAccountPortfolio = (account: Account | null | undefined): account is Account => {\n return isAccountOwned(account) || (isAccountOfType(account, \"watch-only\") && account.isPortfolio)\n}\n\nexport const isAccountNotContact = (acc: Account) => acc.type !== \"contact\"\n\ntype AccountAddressEthereum = Extract<\n Account,\n { type: (typeof ACCOUNT_TYPES_ADDRESS_ETHEREUM)[number] }\n> & {\n address: `0x${string}`\n}\nexport const isAccountAddressEthereum = (\n account: Account | null | undefined,\n): account is AccountAddressEthereum => {\n return !!account && isEthereumAddress(account.address)\n}\n\ntype AccountPlatformEthereum = Extract<\n Account,\n { type: (typeof ACCOUNT_TYPES_PLATFORM_ETHEREUM)[number] }\n> & {\n address: `0x${string}`\n}\nexport const isAccountPlatformEthereum = (\n account: Account | null | undefined,\n): account is AccountPlatformEthereum => {\n return !!account && account.type !== \"ledger-polkadot\" && isEthereumAddress(account.address)\n}\n\ntype AccountPlatformSolana = Extract<\n Account,\n { type: (typeof ACCOUNT_TYPES_PLATFORM_SOLANA)[number] }\n>\n\nexport const isAccountPlatformSolana = (\n account: Account | null | undefined,\n): account is AccountPlatformSolana => {\n return !!account && isSolanaAddress(account.address)\n}\n\ntype AccountPlatformPolkadot = Extract<\n Account,\n { type: (typeof ACCOUNT_TYPES_PLATFORM_POLKADOT)[number] }\n>\nexport const isAccountPlatformPolkadot = (\n account: Account | null | undefined,\n): account is AccountPlatformPolkadot => {\n return (\n !!account &&\n account.type !== \"ledger-ethereum\" &&\n (isAccountAddressEthereum(account) || isAccountAddressSs58(account))\n )\n}\n\ntype AccountAddressSs58 = Extract<\n Account,\n { type: (typeof ACCOUNT_TYPES_ADDRESS_SS58)[number] }\n> & {\n genesisHash?: `0x${string}`\n}\nexport const isAccountAddressSs58 = (\n account: Account | null | undefined,\n): account is AccountAddressSs58 => {\n return !!account && detectAddressEncoding(account.address) === \"ss58\"\n}\n\nexport const isAccountLedgerPolkadot = (\n account: Account | null | undefined,\n): account is AccountLedgerPolkadot => {\n return isAccountOfType(account, \"ledger-polkadot\")\n}\n\nexport const isAccountLedgerPolkadotGeneric = (\n account: Account | null | undefined,\n): account is AccountLedgerPolkadot & { genesisHash: undefined } => {\n return isAccountOfType(account, \"ledger-polkadot\") && !account.genesisHash\n}\n\nexport const isAccountLedgerPolkadotLegacy = (\n account: Account | null | undefined,\n): account is AccountLedgerPolkadot & { genesisHash: `0x${string}` } => {\n return isAccountOfType(account, \"ledger-polkadot\") && !!account.genesisHash\n}\n\ntype AccountBitcoin = Extract<Account, { type: (typeof ACCOUNT_TYPES_BITCOIN)[number] }>\nexport const isAccountBitcoin = (\n account: Account | null | undefined,\n): account is AccountBitcoin => {\n return !!account && isBitcoinAddress(account.address)\n}\n\nexport const getAccountGenesisHash = (account: Account | null | undefined) => {\n if (!account) return undefined\n return \"genesisHash\" in account ? account.genesisHash || undefined : undefined\n}\n\nexport const getAccountSignetUrl = (account: Account | null | undefined) => {\n return isAccountOfType(account, \"signet\") ? account.url : undefined\n}\n\nexport const getAccountPlatform = (account: Account | null | undefined) => {\n if (!account) return undefined\n return \"curve\" in account\n ? getAccountPlatformFromCurve(account.curve)\n : getAccountPlatformFromAddress(account.address)\n}\n","import {\n addressEncodingFromCurve,\n addressFromPublicKey,\n base58,\n blake3,\n deriveKeypair,\n entropyToMnemonic,\n entropyToSeed,\n getPublicKeyFromSecret,\n isAddressEqual,\n isValidMnemonic,\n KeypairCurve,\n mnemonicToEntropy,\n normalizeAddress,\n utf8,\n} from \"@talismn/crypto\"\n\nimport type { Account, Mnemonic } from \"../types\"\nimport type {\n AddAccountDeriveOptions,\n AddAccountExternalOptions,\n AddAccountKeypairOptions,\n AddMnemonicOptions,\n UpdateAccountOptions,\n UpdateMnemonicOptions,\n} from \"../types/keyring\"\nimport type { AccountStorage, MnemonicStorage } from \"./types\"\nimport { isAccountExternal } from \"../types\"\nimport { changeEncryptedDataPassword, decryptData, encryptData } from \"./encryption\"\nimport { isHexString } from \"./utils\"\n\nexport type KeyringStorage = {\n passwordCheck: string | null // well-known data encrypted using the password, used to ensure all secrets of the keyring are encrypted with the same password\n mnemonics: MnemonicStorage[]\n accounts: AccountStorage[]\n}\n\nexport class Keyring {\n #data: KeyringStorage\n\n protected constructor(data: KeyringStorage) {\n this.#data = structuredClone(data)\n }\n\n public static create(): Keyring {\n return new Keyring({\n passwordCheck: null, // well-known data encrypted using the password, used to ensure all secrets of the keyring are encrypted with the same password\n mnemonics: [],\n accounts: [],\n })\n }\n\n public static load(data: KeyringStorage): Keyring {\n if (!data.accounts || !data.mnemonics) throw new Error(\"Invalid data\")\n\n // automatic upgrade : set default values for newly introduced properties\n for (const account of data.accounts) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n if (account.type === \"ledger-polkadot\" && !account.curve) account.curve = \"ed25519\"\n }\n\n return new Keyring(data)\n }\n\n private async checkPassword(password: string, reset = false) {\n if (typeof password !== \"string\" || !password) throw new Error(\"password is required\")\n\n const passwordHash = oneWayHash(password)\n const PASSWORD_CHECK_PHRASE = \"PASSWORD_CHECK_PHRASE\"\n\n // run through same complexity as for other secrets, to make it so it s not easier to brute force passwordCheck than other secrets\n if (!this.#data.passwordCheck || reset) {\n const bytes = utf8.decode(PASSWORD_CHECK_PHRASE)\n this.#data.passwordCheck = await encryptData(bytes, passwordHash)\n } else {\n try {\n const bytes = await decryptData(this.#data.passwordCheck, passwordHash)\n const text = utf8.encode(bytes)\n if (text !== PASSWORD_CHECK_PHRASE) throw new Error(\"Invalid password\")\n } catch {\n throw new Error(\"Invalid password\")\n }\n }\n }\n\n public toJson() {\n return structuredClone(this.#data)\n }\n\n public async export(password: string, jsonPassword: string): Promise<KeyringStorage> {\n const keyring = new Keyring(structuredClone(this.#data))\n\n for (const mnemonic of keyring.#data.mnemonics)\n mnemonic.entropy = await changeEncryptedDataPassword(mnemonic.entropy, password, jsonPassword)\n\n for (const account of keyring.#data.accounts)\n if (account.type === \"keypair\")\n account.secretKey = await changeEncryptedDataPassword(\n account.secretKey,\n password,\n jsonPassword,\n )\n\n // reset password check\n await keyring.checkPassword(jsonPassword, true)\n\n return keyring.toJson()\n }\n\n public getMnemonics(): Mnemonic[] {\n return this.#data.mnemonics.map(mnemonicFromStorage)\n }\n\n public async addMnemonic(\n { name, mnemonic, confirmed }: AddMnemonicOptions,\n password: string,\n ): Promise<Mnemonic> {\n if (typeof name !== \"string\" || !name) throw new Error(\"name is required\")\n if (typeof mnemonic !== \"string\") throw new Error(\"mnemonic is required\")\n if (typeof confirmed !== \"boolean\") throw new Error(\"confirmed is required\")\n if (!isValidMnemonic(mnemonic)) throw new Error(\"Invalid mnemonic\")\n\n await this.checkPassword(password)\n\n const entropy = mnemonicToEntropy(mnemonic)\n\n // id is a hash of the entropy, helps us prevent having duplicates and allows automatic remapping of accounts/mnemonics if mnemonics are deleted then re-added\n const id = oneWayHash(entropy)\n\n if (this.#data.mnemonics.find((s) => s.id === id)) throw new Error(\"Mnemonic already exists\")\n\n const storage: MnemonicStorage = {\n id,\n name,\n entropy: await encryptData(entropy, password),\n confirmed,\n createdAt: Date.now(),\n }\n\n this.#data.mnemonics.push(storage)\n\n return mnemonicFromStorage(storage)\n }\n\n public getMnemonic(id: string): Mnemonic | null {\n const mnemonic = this.#data.mnemonics.find((s) => s.id === id)\n return mnemonic ? mnemonicFromStorage(mnemonic) : null\n }\n\n public updateMnemonic(id: string, { name, confirmed }: UpdateMnemonicOptions) {\n const mnemonic = this.#data.mnemonics.find((s) => s.id === id)\n if (!mnemonic) throw new Error(\"Mnemonic not found\")\n if (name !== undefined) {\n if (typeof name !== \"string\" || !name) throw new Error(\"name must be a string\")\n mnemonic.name = name\n }\n if (confirmed !== undefined) {\n if (typeof confirmed !== \"boolean\") throw new Error(\"confirmed must be a boolean\")\n mnemonic.confirmed = confirmed\n }\n return mnemonicFromStorage(mnemonic)\n }\n\n public removeMnemonic(id: string) {\n const index = this.#data.mnemonics.findIndex((mnemonic) => mnemonic.id == id)\n if (index === -1) throw new Error(\"Mnemonic not found\")\n this.#data.mnemonics.splice(index, 1)\n }\n\n async getMnemonicText(id: string, password: string): Promise<string> {\n const mnemonic = this.#data.mnemonics.find((s) => s.id === id)\n if (!mnemonic) throw new Error(\"Mnemonic not found\")\n\n const entropy = await decryptData(mnemonic.entropy, password)\n\n return entropyToMnemonic(entropy)\n }\n\n public getExistingMnemonicId(mnemonic: string): string | null {\n const entropy = mnemonicToEntropy(mnemonic)\n const mnemonicId = oneWayHash(entropy)\n return this.#data.mnemonics.some((s) => s.id === mnemonicId) ? mnemonicId : null\n }\n\n public getAccounts(): Account[] {\n return this.#data.accounts.map(accountFromStorage)\n }\n\n public getAccount(address: string): Account | null {\n const account = this.#data.accounts.find((s) => isAddressEqual(s.address, address))\n return account ? accountFromStorage(account) : null\n }\n\n public updateAccount(address: string, { name, isPortfolio, genesisHash }: UpdateAccountOptions) {\n const account = this.#data.accounts.find((s) => s.address === address)\n if (!account) throw new Error(\"Account not found\")\n\n if (name) {\n if (typeof name !== \"string\" || !name) throw new Error(\"name is required\")\n account.name = name\n }\n if (account.type === \"watch-only\" && isPortfolio !== undefined) {\n if (typeof isPortfolio !== \"boolean\") throw new Error(\"isPortfolio must be a boolean\")\n account.isPortfolio = isPortfolio\n }\n // allow updating genesisHash only for contacts\n if (account.type === \"contact\") {\n if (genesisHash) {\n if (!isHexString(genesisHash)) throw new Error(\"genesisHash must be a hex string\")\n account.genesisHash = genesisHash\n } else delete account.genesisHash\n }\n\n return accountFromStorage(account)\n }\n\n public removeAccount(address: string) {\n const index = this.#data.accounts.findIndex((s) => isAddressEqual(s.address, address))\n if (index === -1) throw new Error(\"Account not found\")\n this.#data.accounts.splice(index, 1)\n }\n\n public addAccountExternal(options: AddAccountExternalOptions): Account {\n const address = normalizeAddress(options.address) // breaks if invalid address\n\n if (this.getAccount(address)) throw new Error(\"Account already exists\")\n\n const account: AccountStorage = {\n ...options,\n address,\n createdAt: Date.now(),\n }\n\n if (!isAccountExternal(account)) throw new Error(\"Invalid account type\")\n\n this.#data.accounts.push(account)\n\n return accountFromStorage(account)\n }\n\n /**\n * Needs to be called before deriving an account from a mnemonic.\n *\n * This will ensure that it is present (or add it if possible) in the keyring before actually creating the account.\n *\n * @param options\n * @param password\n * @returns the id of the mnemonic\n */\n private async ensureMnemonic(options: AddAccountDeriveOptions, password: string) {\n await this.checkPassword(password)\n\n switch (options.type) {\n case \"new-mnemonic\": {\n const { mnemonic, mnemonicName: name, confirmed } = options\n\n if (typeof name !== \"string\" || !name) throw new Error(\"mnemonicName is required\")\n if (typeof confirmed !== \"boolean\") throw new Error(\"confirmed is required\")\n\n const mnemonicId = this.getExistingMnemonicId(mnemonic)\n if (mnemonicId) return mnemonicId\n\n const { id } = await this.addMnemonic(\n {\n name,\n mnemonic,\n confirmed,\n },\n password,\n )\n\n return id\n }\n case \"existing-mnemonic\": {\n if (typeof options.mnemonicId !== \"string\" || !options.mnemonicId)\n throw new Error(\"mnemonicId must be a string\")\n\n return options.mnemonicId\n }\n }\n }\n\n public async addAccountDerive(\n options: AddAccountDeriveOptions,\n password: string,\n ): Promise<Account> {\n await this.checkPassword(password)\n\n const { curve, derivationPath, name } = options\n\n const mnemonicId = await this.ensureMnemonic(options, password)\n\n const mnemonic = this.#data.mnemonics.find((s) => s.id === mnemonicId)\n if (!mnemonic) throw new Error(\"Mnemonic not found\")\n\n const entropy = await decryptData(mnemonic.entropy, password)\n const seed = await entropyToSeed(entropy, curve)\n const pair = deriveKeypair(seed, derivationPath, curve)\n\n if (this.getAccount(pair.address)) throw new Error(\"Account already exists\")\n\n const account: AccountStorage = {\n type: \"keypair\",\n curve,\n name,\n address: normalizeAddress(pair.address),\n secretKey: await encryptData(pair.secretKey, password),\n mnemonicId,\n derivationPath,\n createdAt: Date.now(),\n }\n\n this.#data.accounts.push(account)\n\n return accountFromStorage(account)\n }\n\n public async addAccountKeypair(\n { curve, name, secretKey }: AddAccountKeypairOptions,\n password: string,\n ): Promise<Account> {\n await this.checkPassword(password)\n\n const publicKey = getPublicKeyFromSecret(secretKey, curve)\n const encoding = addressEncodingFromCurve(curve)\n const address = addressFromPublicKey(publicKey, encoding)\n\n if (this.getAccount(address)) throw new Error(\"Account already exists\")\n\n const account: AccountStorage = {\n type: \"keypair\",\n curve,\n name,\n address: normalizeAddress(address),\n secretKey: await encryptData(secretKey, password),\n createdAt: Date.now(),\n }\n\n this.#data.accounts.push(account)\n\n return accountFromStorage(account)\n }\n\n public getAccountSecretKey(address: string, password: string): Promise<Uint8Array> {\n if (typeof address !== \"string\" || !address) throw new Error(\"address is required\")\n if (typeof password !== \"string\" || !password) throw new Error(\"password is required\")\n\n const account = this.#data.accounts.find((a) => a.address === normalizeAddress(address))\n if (!account) throw new Error(\"Account not found\")\n if (account.type !== \"keypair\") throw new Error(\"Secret key unavailable\")\n\n return decryptData(account.secretKey, password)\n }\n\n public async getDerivedAddress(\n mnemonicId: string,\n derivationPath: string,\n curve: KeypairCurve,\n password: string,\n ): Promise<string> {\n if (typeof mnemonicId !== \"string\" || !mnemonicId) throw new Error(\"mnemonicId is required\")\n if (typeof password !== \"string\" || !password) throw new Error(\"password is required\")\n\n const mnemonic = this.#data.mnemonics.find((s) => s.id === mnemonicId)\n if (!mnemonic) throw new Error(\"Mnemonic not found\")\n\n const entropy = await decryptData(mnemonic.entropy, password)\n const seed = await entropyToSeed(entropy, curve)\n const pair = deriveKeypair(seed, derivationPath, curve)\n\n return pair.address\n }\n}\n\nconst oneWayHash = (bytes: Uint8Array | string) => {\n if (typeof bytes === \"string\") bytes = utf8.decode(bytes)\n\n // cryptographically secure one way hash\n // outputs 44 characters without special characters\n return base58.encode(blake3(bytes))\n}\n\nconst mnemonicFromStorage = (data: MnemonicStorage): Mnemonic => {\n const copy = structuredClone(data) as Mnemonic\n if (\"entropy\" in copy) delete copy.entropy\n return Object.freeze(copy)\n}\n\nconst accountFromStorage = (data: AccountStorage): Account => {\n const copy = structuredClone(data) as Account\n if (\"secretKey\" in copy) delete copy.secretKey\n return Object.freeze(copy)\n}\n","import { pbkdf2 } from \"@talismn/crypto\"\n\n// Derive a key generated with PBKDF2 that will be used for AES-GCM encryption\nconst deriveKey = async (password: string, salt: Uint8Array): Promise<CryptoKey> =>\n // Deriving 32-byte key using PBKDF2 with 100,000 iterations and SHA-256\n await crypto.subtle.importKey(\n \"raw\",\n await pbkdf2(\n \"SHA-256\",\n new TextEncoder().encode(password),\n salt,\n 100_000, // 100,000 iterations\n 32, // 32 bytes (32 * 8 == 256 bits)\n ),\n { name: \"AES-GCM\", length: 256 },\n false,\n [\"encrypt\", \"decrypt\"],\n )\n\nexport const encryptData = async (data: Uint8Array, password: string): Promise<string> => {\n try {\n const salt = crypto.getRandomValues(new Uint8Array(16)) // 16 bytes of salt\n const iv = crypto.getRandomValues(new Uint8Array(12)) // 12-byte IV for AES-GCM\n const key = await deriveKey(password, salt)\n\n // encrypt\n const encryptedSeed = await crypto.subtle.encrypt({ name: \"AES-GCM\", iv }, key, data)\n\n // Combine salt, IV, and encrypted seed\n const combined = new Uint8Array(salt.length + iv.length + encryptedSeed.byteLength)\n combined.set(salt, 0)\n combined.set(iv, salt.length)\n combined.set(new Uint8Array(encryptedSeed), salt.length + iv.length)\n\n // Base64 encode the combined data\n return btoa(String.fromCharCode(...combined))\n } catch (cause) {\n throw new Error(\"Failed to encrypt data\", { cause })\n }\n}\n\nexport const decryptData = async (encryptedData: string, password: string): Promise<Uint8Array> => {\n try {\n // Decode Base64 and parse the combined data\n const combined = Uint8Array.from(atob(encryptedData), (c) => c.charCodeAt(0))\n\n // Extract salt, IV, and encrypted seed\n const salt = combined.slice(0, 16) // First 16 bytes\n const iv = combined.slice(16, 28) // Next 12 bytes\n const encryptedSeed = combined.slice(28) // Remaining bytes\n\n const key = await deriveKey(password, salt)\n\n // Decrypt the seed\n const decryptedSeed = await crypto.subtle.decrypt({ name: \"AES-GCM\", iv }, key, encryptedSeed)\n\n return new Uint8Array(decryptedSeed)\n } catch (cause) {\n throw new Error(\"Failed to decrypt data\", { cause })\n }\n}\n\nexport const changeEncryptedDataPassword = async (\n encryptedData: string,\n oldPassword: string,\n newPassword: string,\n) => {\n try {\n const decrypted = await decryptData(encryptedData, oldPassword)\n return await encryptData(decrypted, newPassword)\n } catch (cause) {\n throw new Error(\"Failed to change password on encrypted data\", { cause })\n }\n}\n","// we dont want to reference @talismn/util in the keyring, so we copy this here\ntype HexString = `0x${string}`\n\nexport const REGEX_HEX_STRING = /^0x[0-9a-fA-F]*$/\n\nexport const isHexString = (value: unknown): value is HexString => {\n return typeof value === \"string\" && REGEX_HEX_STRING.test(value)\n}\n"],"mappings":"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","names":["import_crypto","import_crypto"]}