@talismn/keyring 0.1.2 → 0.1.4

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.
@@ -1,5 +1,5 @@
1
1
  import type { KeypairCurve } from "@talismn/crypto";
2
- export type AccountPlatform = "ethereum" | "polkadot" | "solana";
2
+ export type AccountPlatform = "ethereum" | "polkadot" | "solana" | "bitcoin";
3
3
  export type AccountBase = {
4
4
  address: string;
5
5
  name: string;
@@ -8,6 +8,7 @@ declare const ACCOUNT_TYPES_OWNED: readonly ["keypair", "ledger-ethereum", "ledg
8
8
  declare const ACCOUNT_TYPES_EXTERNAL: readonly ["contact", "watch-only", "ledger-ethereum", "ledger-polkadot", "polkadot-vault", "signet"];
9
9
  declare const ACCOUNT_TYPES_ETHEREUM: readonly ["contact", "watch-only", "keypair", "ledger-ethereum"];
10
10
  declare const ACCOUNT_TYPES_POLKADOT: readonly ["contact", "watch-only", "keypair", "ledger-polkadot", "polkadot-vault", "signet"];
11
+ declare const ACCOUNT_TYPES_BITCOIN: readonly ["contact", "watch-only"];
11
12
  export declare const isAccountExternal: (account: Account | null | undefined) => account is AccountOfType<(typeof ACCOUNT_TYPES_EXTERNAL)[number]>;
12
13
  export declare const isAccountOwned: (account: Account | null | undefined) => account is AccountOfType<(typeof ACCOUNT_TYPES_OWNED)[number]>;
13
14
  export declare const isAccountPortfolio: (account: Account | null | undefined) => account is Account;
@@ -30,6 +31,10 @@ export declare const isAccountLedgerPolkadotGeneric: (account: Account | null |
30
31
  export declare const isAccountLedgerPolkadotLegacy: (account: Account | null | undefined) => account is AccountLedgerPolkadot & {
31
32
  genesisHash: `0x${string}`;
32
33
  };
34
+ type AccountBitcoin = Extract<Account, {
35
+ type: (typeof ACCOUNT_TYPES_BITCOIN)[number];
36
+ }>;
37
+ export declare const isAccountBitcoin: (account: Account | null | undefined) => account is AccountBitcoin;
33
38
  export declare const getAccountGenesisHash: (account: Account | null | undefined) => `0x${string}` | undefined;
34
39
  export declare const getAccountSignetUrl: (account: Account | null | undefined) => string | undefined;
35
40
  export declare const getAccountPlatform: (account: Account | null | undefined) => import("@talismn/crypto").Platform | undefined;
@@ -32,6 +32,9 @@ const isAccountLedgerPolkadotGeneric = account => {
32
32
  const isAccountLedgerPolkadotLegacy = account => {
33
33
  return isAccountOfType(account, "ledger-polkadot") && !!account.genesisHash;
34
34
  };
35
+ const isAccountBitcoin = account => {
36
+ return !!account && crypto$1.isBitcoinAddress(account.address);
37
+ };
35
38
  const getAccountGenesisHash = account => {
36
39
  if (!account) return undefined;
37
40
  return "genesisHash" in account ? account.genesisHash || undefined : undefined;
@@ -45,19 +48,15 @@ const getAccountPlatform = account => {
45
48
  };
46
49
 
47
50
  // Derive a key generated with PBKDF2 that will be used for AES-GCM encryption
48
- const deriveKey = async (password, salt) => {
49
- // Deriving 32-byte key using PBKDF2 with 100000 iterations and SHA-256
50
- const keyMaterial = await crypto.subtle.importKey("raw", new TextEncoder().encode(password), "PBKDF2", false, ["deriveKey"]);
51
- return crypto.subtle.deriveKey({
52
- name: "PBKDF2",
53
- salt,
54
- iterations: 100000,
55
- hash: "SHA-256"
56
- }, keyMaterial, {
57
- name: "AES-GCM",
58
- length: 256
59
- }, false, ["encrypt", "decrypt"]);
60
- };
51
+ const deriveKey = async (password, salt) =>
52
+ // Deriving 32-byte key using PBKDF2 with 100,000 iterations and SHA-256
53
+ await crypto.subtle.importKey("raw", await crypto$1.pbkdf2("SHA-256", new TextEncoder().encode(password), salt, 100_000,
54
+ // 100,000 iterations
55
+ 32 // 32 bytes (32 * 8 == 256 bits)
56
+ ), {
57
+ name: "AES-GCM",
58
+ length: 256
59
+ }, false, ["encrypt", "decrypt"]);
61
60
  const encryptData = async (data, password) => {
62
61
  try {
63
62
  const salt = crypto.getRandomValues(new Uint8Array(16)); // 16 bytes of salt
@@ -337,7 +336,7 @@ class Keyring {
337
336
  const mnemonic = this.#data.mnemonics.find(s => s.id === mnemonicId);
338
337
  if (!mnemonic) throw new Error("Mnemonic not found");
339
338
  const entropy = await decryptData(mnemonic.entropy, password);
340
- const seed = crypto$1.entropyToSeed(entropy, curve);
339
+ const seed = await crypto$1.entropyToSeed(entropy, curve);
341
340
  const pair = crypto$1.deriveKeypair(seed, derivationPath, curve);
342
341
  if (this.getAccount(pair.address)) throw new Error("Account already exists");
343
342
  const account = {
@@ -388,7 +387,7 @@ class Keyring {
388
387
  const mnemonic = this.#data.mnemonics.find(s => s.id === mnemonicId);
389
388
  if (!mnemonic) throw new Error("Mnemonic not found");
390
389
  const entropy = await decryptData(mnemonic.entropy, password);
391
- const seed = crypto$1.entropyToSeed(entropy, curve);
390
+ const seed = await crypto$1.entropyToSeed(entropy, curve);
392
391
  const pair = crypto$1.deriveKeypair(seed, derivationPath, curve);
393
392
  return pair.address;
394
393
  }
@@ -415,6 +414,7 @@ exports.Keyring = Keyring;
415
414
  exports.getAccountGenesisHash = getAccountGenesisHash;
416
415
  exports.getAccountPlatform = getAccountPlatform;
417
416
  exports.getAccountSignetUrl = getAccountSignetUrl;
417
+ exports.isAccountBitcoin = isAccountBitcoin;
418
418
  exports.isAccountEthereum = isAccountEthereum;
419
419
  exports.isAccountExternal = isAccountExternal;
420
420
  exports.isAccountInTypes = isAccountInTypes;
@@ -32,6 +32,9 @@ const isAccountLedgerPolkadotGeneric = account => {
32
32
  const isAccountLedgerPolkadotLegacy = account => {
33
33
  return isAccountOfType(account, "ledger-polkadot") && !!account.genesisHash;
34
34
  };
35
+ const isAccountBitcoin = account => {
36
+ return !!account && crypto$1.isBitcoinAddress(account.address);
37
+ };
35
38
  const getAccountGenesisHash = account => {
36
39
  if (!account) return undefined;
37
40
  return "genesisHash" in account ? account.genesisHash || undefined : undefined;
@@ -45,19 +48,15 @@ const getAccountPlatform = account => {
45
48
  };
46
49
 
47
50
  // Derive a key generated with PBKDF2 that will be used for AES-GCM encryption
48
- const deriveKey = async (password, salt) => {
49
- // Deriving 32-byte key using PBKDF2 with 100000 iterations and SHA-256
50
- const keyMaterial = await crypto.subtle.importKey("raw", new TextEncoder().encode(password), "PBKDF2", false, ["deriveKey"]);
51
- return crypto.subtle.deriveKey({
52
- name: "PBKDF2",
53
- salt,
54
- iterations: 100000,
55
- hash: "SHA-256"
56
- }, keyMaterial, {
57
- name: "AES-GCM",
58
- length: 256
59
- }, false, ["encrypt", "decrypt"]);
60
- };
51
+ const deriveKey = async (password, salt) =>
52
+ // Deriving 32-byte key using PBKDF2 with 100,000 iterations and SHA-256
53
+ await crypto.subtle.importKey("raw", await crypto$1.pbkdf2("SHA-256", new TextEncoder().encode(password), salt, 100_000,
54
+ // 100,000 iterations
55
+ 32 // 32 bytes (32 * 8 == 256 bits)
56
+ ), {
57
+ name: "AES-GCM",
58
+ length: 256
59
+ }, false, ["encrypt", "decrypt"]);
61
60
  const encryptData = async (data, password) => {
62
61
  try {
63
62
  const salt = crypto.getRandomValues(new Uint8Array(16)); // 16 bytes of salt
@@ -337,7 +336,7 @@ class Keyring {
337
336
  const mnemonic = this.#data.mnemonics.find(s => s.id === mnemonicId);
338
337
  if (!mnemonic) throw new Error("Mnemonic not found");
339
338
  const entropy = await decryptData(mnemonic.entropy, password);
340
- const seed = crypto$1.entropyToSeed(entropy, curve);
339
+ const seed = await crypto$1.entropyToSeed(entropy, curve);
341
340
  const pair = crypto$1.deriveKeypair(seed, derivationPath, curve);
342
341
  if (this.getAccount(pair.address)) throw new Error("Account already exists");
343
342
  const account = {
@@ -388,7 +387,7 @@ class Keyring {
388
387
  const mnemonic = this.#data.mnemonics.find(s => s.id === mnemonicId);
389
388
  if (!mnemonic) throw new Error("Mnemonic not found");
390
389
  const entropy = await decryptData(mnemonic.entropy, password);
391
- const seed = crypto$1.entropyToSeed(entropy, curve);
390
+ const seed = await crypto$1.entropyToSeed(entropy, curve);
392
391
  const pair = crypto$1.deriveKeypair(seed, derivationPath, curve);
393
392
  return pair.address;
394
393
  }
@@ -415,6 +414,7 @@ exports.Keyring = Keyring;
415
414
  exports.getAccountGenesisHash = getAccountGenesisHash;
416
415
  exports.getAccountPlatform = getAccountPlatform;
417
416
  exports.getAccountSignetUrl = getAccountSignetUrl;
417
+ exports.isAccountBitcoin = isAccountBitcoin;
418
418
  exports.isAccountEthereum = isAccountEthereum;
419
419
  exports.isAccountExternal = isAccountExternal;
420
420
  exports.isAccountInTypes = isAccountInTypes;
@@ -1,4 +1,4 @@
1
- import { isEthereumAddress, detectAddressEncoding, platformFromCurve, platformFromAddress, stringToBytes, bytesToString, isValidMnemonic, mnemonicToEntropy, entropyToMnemonic, isAddressEqual, normalizeAddress, entropyToSeed, deriveKeypair, getPublicKeyFromSecret, addressEncodingFromCurve, addressFromPublicKey, blake3 } from '@talismn/crypto';
1
+ import { isEthereumAddress, detectAddressEncoding, isBitcoinAddress, platformFromCurve, platformFromAddress, pbkdf2, stringToBytes, bytesToString, isValidMnemonic, mnemonicToEntropy, entropyToMnemonic, isAddressEqual, normalizeAddress, entropyToSeed, deriveKeypair, getPublicKeyFromSecret, addressEncodingFromCurve, addressFromPublicKey, blake3 } from '@talismn/crypto';
2
2
 
3
3
  const isAccountOfType = (account, type) => {
4
4
  return account?.type === type;
@@ -30,6 +30,9 @@ const isAccountLedgerPolkadotGeneric = account => {
30
30
  const isAccountLedgerPolkadotLegacy = account => {
31
31
  return isAccountOfType(account, "ledger-polkadot") && !!account.genesisHash;
32
32
  };
33
+ const isAccountBitcoin = account => {
34
+ return !!account && isBitcoinAddress(account.address);
35
+ };
33
36
  const getAccountGenesisHash = account => {
34
37
  if (!account) return undefined;
35
38
  return "genesisHash" in account ? account.genesisHash || undefined : undefined;
@@ -43,19 +46,15 @@ const getAccountPlatform = account => {
43
46
  };
44
47
 
45
48
  // Derive a key generated with PBKDF2 that will be used for AES-GCM encryption
46
- const deriveKey = async (password, salt) => {
47
- // Deriving 32-byte key using PBKDF2 with 100000 iterations and SHA-256
48
- const keyMaterial = await crypto.subtle.importKey("raw", new TextEncoder().encode(password), "PBKDF2", false, ["deriveKey"]);
49
- return crypto.subtle.deriveKey({
50
- name: "PBKDF2",
51
- salt,
52
- iterations: 100000,
53
- hash: "SHA-256"
54
- }, keyMaterial, {
55
- name: "AES-GCM",
56
- length: 256
57
- }, false, ["encrypt", "decrypt"]);
58
- };
49
+ const deriveKey = async (password, salt) =>
50
+ // Deriving 32-byte key using PBKDF2 with 100,000 iterations and SHA-256
51
+ await crypto.subtle.importKey("raw", await pbkdf2("SHA-256", new TextEncoder().encode(password), salt, 100_000,
52
+ // 100,000 iterations
53
+ 32 // 32 bytes (32 * 8 == 256 bits)
54
+ ), {
55
+ name: "AES-GCM",
56
+ length: 256
57
+ }, false, ["encrypt", "decrypt"]);
59
58
  const encryptData = async (data, password) => {
60
59
  try {
61
60
  const salt = crypto.getRandomValues(new Uint8Array(16)); // 16 bytes of salt
@@ -335,7 +334,7 @@ class Keyring {
335
334
  const mnemonic = this.#data.mnemonics.find(s => s.id === mnemonicId);
336
335
  if (!mnemonic) throw new Error("Mnemonic not found");
337
336
  const entropy = await decryptData(mnemonic.entropy, password);
338
- const seed = entropyToSeed(entropy, curve);
337
+ const seed = await entropyToSeed(entropy, curve);
339
338
  const pair = deriveKeypair(seed, derivationPath, curve);
340
339
  if (this.getAccount(pair.address)) throw new Error("Account already exists");
341
340
  const account = {
@@ -386,7 +385,7 @@ class Keyring {
386
385
  const mnemonic = this.#data.mnemonics.find(s => s.id === mnemonicId);
387
386
  if (!mnemonic) throw new Error("Mnemonic not found");
388
387
  const entropy = await decryptData(mnemonic.entropy, password);
389
- const seed = entropyToSeed(entropy, curve);
388
+ const seed = await entropyToSeed(entropy, curve);
390
389
  const pair = deriveKeypair(seed, derivationPath, curve);
391
390
  return pair.address;
392
391
  }
@@ -409,4 +408,4 @@ const accountFromStorage = data => {
409
408
  return Object.freeze(copy);
410
409
  };
411
410
 
412
- export { Keyring, getAccountGenesisHash, getAccountPlatform, getAccountSignetUrl, isAccountEthereum, isAccountExternal, isAccountInTypes, isAccountLedgerPolkadotGeneric, isAccountLedgerPolkadotLegacy, isAccountNotContact, isAccountOfType, isAccountOwned, isAccountPolkadot, isAccountPortfolio };
411
+ export { Keyring, getAccountGenesisHash, getAccountPlatform, getAccountSignetUrl, isAccountBitcoin, isAccountEthereum, isAccountExternal, isAccountInTypes, isAccountLedgerPolkadotGeneric, isAccountLedgerPolkadotLegacy, isAccountNotContact, isAccountOfType, isAccountOwned, isAccountPolkadot, isAccountPortfolio };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@talismn/keyring",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "author": "Talisman",
5
5
  "homepage": "https://talisman.xyz",
6
6
  "license": "GPL-3.0-or-later",
@@ -22,7 +22,7 @@
22
22
  "node": ">=18"
23
23
  },
24
24
  "dependencies": {
25
- "@talismn/crypto": "0.1.1"
25
+ "@talismn/crypto": "0.1.3"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/jest": "^29.5.14",
@@ -31,8 +31,8 @@
31
31
  "jest-fixed-jsdom": "^0.0.9",
32
32
  "ts-jest": "^29.2.5",
33
33
  "typescript": "^5.6.3",
34
- "@talismn/eslint-config": "0.0.3",
35
- "@talismn/tsconfig": "0.0.2"
34
+ "@talismn/tsconfig": "0.0.2",
35
+ "@talismn/eslint-config": "0.0.3"
36
36
  },
37
37
  "preconstruct": {
38
38
  "entrypoints": [