@talismn/crypto 0.1.5 → 0.2.1

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.
@@ -0,0 +1,5 @@
1
+ type EncodeAddressOptions = {
2
+ ss58Format?: number | undefined;
3
+ };
4
+ export declare const encodeAnyAddress: (address: string, options?: EncodeAddressOptions) => string;
5
+ export {};
@@ -1,5 +1,5 @@
1
1
  export * from "./addressEncodingFromCurve";
2
- export * from "./base58";
2
+ export * from "./solana";
3
3
  export * from "./bitcoin";
4
4
  export * from "./detectAddressEncoding";
5
5
  export * from "./ethereum";
@@ -0,0 +1,2 @@
1
+ export declare const encodeAddressSolana: (publicKey: Uint8Array) => string;
2
+ export declare function isSolanaAddress(address: string): boolean;
@@ -2,3 +2,5 @@ export * from "./encoding";
2
2
  export * from "./addressFromPublicKey";
3
3
  export * from "./normalizeAddress";
4
4
  export * from "./isAddressEqual";
5
+ export * from "./encodeAnyAddress";
6
+ export * from "./isAddressValid";
@@ -0,0 +1 @@
1
+ export declare const isAddressValid: (address: string) => boolean;
@@ -1,16 +1,7 @@
1
- import { KeypairCurve } from "../types";
1
+ import { AccountPlatform, KeypairCurve } from "../types";
2
2
  export declare const deriveKeypair: (seed: Uint8Array, derivationPath: string, curve: KeypairCurve) => import("../types").Keypair;
3
3
  export declare const getPublicKeyFromSecret: (secretKey: Uint8Array, curve: KeypairCurve) => Uint8Array;
4
- export declare const addressFromSuri: (suri: string, type: KeypairCurve) => Promise<string>;
5
- /**
6
- * @dev we only expect suri to contain a mnemonic and derivation path.
7
- * for other cases see https://polkadot.js.org/docs/keyring/start/suri/
8
- */
9
- export declare const parseSuri: (suri: string) => {
10
- mnemonic: string;
11
- derivationPath: string;
12
- password: string | undefined;
13
- };
4
+ export declare const addressFromMnemonic: (mnemonic: string, derivationPath: string, curve: KeypairCurve) => Promise<string>;
14
5
  export declare const removeHexPrefix: (secretKey: string) => string;
15
- export declare const parseSecretKey: (secretKey: string, curve: KeypairCurve) => Uint8Array<ArrayBufferLike>;
6
+ export declare const parseSecretKey: (secretKey: string, platform: AccountPlatform) => Uint8Array<ArrayBufferLike>;
16
7
  export declare const isValidDerivationPath: (derivationPath: string, curve: KeypairCurve) => Promise<boolean>;
@@ -1,4 +1,4 @@
1
- import { AddressEncoding, KeypairCurve, Platform } from "../types";
2
- export declare const platformFromCurve: (curve: KeypairCurve) => Platform;
3
- export declare const platformFromEncoding: (encoding: AddressEncoding) => Platform;
4
- export declare const platformFromAddress: (address: string) => Platform;
1
+ import { AccountPlatform, AddressEncoding, KeypairCurve } from "../types";
2
+ export declare const getAccountPlatformFromCurve: (curve: KeypairCurve) => AccountPlatform;
3
+ export declare const getAccountPlatformFromEncoding: (encoding: AddressEncoding) => AccountPlatform;
4
+ export declare const getAccountPlatformFromAddress: (address: string) => AccountPlatform;
@@ -1,9 +1,9 @@
1
1
  export type KeypairCurve = "ecdsa" | "ed25519" | "sr25519" | "ethereum" | "bitcoin-ed25519" | "bitcoin-ecdsa" | "solana";
2
- export type AddressEncoding = "ss58" | "ethereum" | "bech32m" | "bech32" | "base58check" | "base58";
2
+ export type AddressEncoding = "ss58" | "ethereum" | "bech32m" | "bech32" | "base58check" | "base58solana";
3
3
  export type Keypair = {
4
4
  type: KeypairCurve;
5
5
  secretKey: Uint8Array;
6
6
  publicKey: Uint8Array;
7
7
  address: string;
8
8
  };
9
- export type Platform = "ethereum" | "polkadot" | "bitcoin" | "solana";
9
+ export type AccountPlatform = "ethereum" | "polkadot" | "bitcoin" | "solana";
@@ -1 +1,2 @@
1
- export { bytesToString, stringToBytes } from "@scure/base";
1
+ export { base58, base64, hex, utf8 } from "@scure/base";
2
+ export { ed25519 } from "@noble/curves/ed25519";
@@ -3,15 +3,15 @@
3
3
  var bip39 = require('@scure/bip39');
4
4
  var english = require('@scure/bip39/wordlists/english');
5
5
  var base = require('@scure/base');
6
+ var ed25519 = require('@noble/curves/ed25519');
7
+ var secp256k1 = require('@noble/curves/secp256k1');
6
8
  var bech32 = require('bech32');
7
9
  var bs58check = require('bs58check');
8
10
  var sha3 = require('@noble/hashes/sha3');
9
11
  var utils = require('@noble/hashes/utils');
10
12
  var blake2b = require('@noble/hashes/blake2b');
11
13
  var blake3$1 = require('@noble/hashes/blake3');
12
- var secp256k1 = require('@noble/curves/secp256k1');
13
14
  var scaleTs = require('scale-ts');
14
- var ed25519 = require('@noble/curves/ed25519');
15
15
  var bip32 = require('@scure/bip32');
16
16
  var hmac = require('@noble/hashes/hmac');
17
17
  var sha512 = require('@noble/hashes/sha512');
@@ -140,18 +140,18 @@ const addressEncodingFromCurve = curve => {
140
140
  case "ethereum":
141
141
  return "ethereum";
142
142
  case "solana":
143
- return "base58";
143
+ return "base58solana";
144
144
  }
145
145
  };
146
146
 
147
- const encodeAddressBase58 = publicKey => {
147
+ const encodeAddressSolana = publicKey => {
148
+ if (publicKey.length !== 32) throw new Error("Public key must be 32 bytes long for Solana base58 encoding");
148
149
  return base.base58.encode(publicKey);
149
150
  };
150
- /** Detect if address is base58 encoded (NOTE: also returns true for ss58 addresses) */
151
- function isBase58Address(address) {
151
+ function isSolanaAddress(address) {
152
152
  try {
153
- base.base58.decode(address);
154
- return true;
153
+ const bytes = base.base58.decode(address);
154
+ return bytes.length === 32;
155
155
  } catch (error) {
156
156
  return false;
157
157
  }
@@ -287,7 +287,7 @@ const blake2b512 = msg => blake2b.blake2b(msg, {
287
287
  const getSafeHash = bytes => {
288
288
  // cryptographically secure one way hash
289
289
  // outputs 44 characters without special characters
290
- return base.bytesToString("base58", blake3$1.blake3(bytes));
290
+ return base.base58.encode(blake3$1.blake3(bytes));
291
291
  };
292
292
 
293
293
  // Inspired from MIT licensed @polkadot-labs/hdkd-helpers
@@ -336,10 +336,10 @@ const CACHE$1 = new Map();
336
336
  const detectAddressEncodingInner = address => {
337
337
  if (isEthereumAddress(address)) return "ethereum";
338
338
  if (isSs58Address(address)) return "ss58";
339
+ if (isSolanaAddress(address)) return "base58solana";
339
340
  if (isBech32mAddress(address)) return "bech32m";
340
341
  if (isBech32Address(address)) return "bech32";
341
342
  if (isBase58CheckAddress(address)) return "base58check";
342
- if (isBase58Address(address)) return "base58";
343
343
  throw new Error(`Unknown address encoding`);
344
344
  };
345
345
  const detectAddressEncoding = address => {
@@ -353,12 +353,12 @@ const addressFromPublicKey = (publicKey, encoding, options) => {
353
353
  return encodeAddressSs58(publicKey, options?.ss58Prefix);
354
354
  case "ethereum":
355
355
  return encodeAddressEthereum(publicKey);
356
+ case "base58solana":
357
+ return encodeAddressSolana(publicKey);
356
358
  case "bech32m":
357
359
  case "bech32":
358
360
  case "base58check":
359
361
  throw new Error("addressFromPublicKey is not implemented for Bitcoin");
360
- case "base58":
361
- return encodeAddressBase58(publicKey);
362
362
  }
363
363
  };
364
364
 
@@ -382,7 +382,7 @@ const normalizeAnyAddress = address => {
382
382
  case "bech32m":
383
383
  case "bech32":
384
384
  case "base58check":
385
- case "base58":
385
+ case "base58solana":
386
386
  return address;
387
387
  case "ss58":
388
388
  {
@@ -401,6 +401,29 @@ const isAddressEqual = (address1, address2) => {
401
401
  }
402
402
  };
403
403
 
404
+ const encodeAnyAddress = (address, options) => {
405
+ // this leverages cache
406
+ const encoding = detectAddressEncoding(address);
407
+
408
+ // this does NOT leverage cache
409
+ if (encoding === "ss58" && options?.ss58Format !== undefined) {
410
+ const [publicKey] = decodeSs58Address(address);
411
+ return encodeAddressSs58(publicKey, options?.ss58Format ?? 42);
412
+ }
413
+
414
+ // this leverages cache
415
+ return normalizeAddress(address);
416
+ };
417
+
418
+ const isAddressValid = address => {
419
+ try {
420
+ detectAddressEncoding(address);
421
+ return true;
422
+ } catch {
423
+ return false;
424
+ }
425
+ };
426
+
404
427
  // Inspired from MIT licensed @polkadot-labs/hdkd helpers
405
428
  // https://github.com/polkadot-labs/hdkd/blob/3ef6e02827212d934b59a4e566d8aa61d3ba7b27/packages/hdkd-helpers/src/parseDerivations.ts#L1
406
429
 
@@ -535,7 +558,7 @@ const deriveSolana = (seed, derivationPath) => {
535
558
  type: "solana",
536
559
  secretKey,
537
560
  publicKey,
538
- address: addressFromPublicKey(publicKey, "base58")
561
+ address: addressFromPublicKey(publicKey, "base58solana")
539
562
  };
540
563
  };
541
564
  const getPublicKeySolana = secretKey => {
@@ -593,60 +616,42 @@ const getPublicKeyFromSecret = (secretKey, curve) => {
593
616
  return getPublicKeySolana(secretKey);
594
617
  }
595
618
  };
596
- const addressFromSuri = async (suri, type) => {
597
- const {
598
- mnemonic,
599
- derivationPath,
600
- password
601
- } = parseSuri(suri);
619
+ const addressFromMnemonic = async (mnemonic, derivationPath, curve) => {
602
620
  const entropy = mnemonicToEntropy(mnemonic);
603
- const seed = await entropyToSeed(entropy, type, password); // ~80ms
621
+ const seed = await entropyToSeed(entropy, curve);
604
622
  const {
605
- secretKey
606
- } = deriveKeypair(seed, derivationPath, type);
607
- const publicKey = getPublicKeyFromSecret(secretKey, type);
608
- const encoding = addressEncodingFromCurve(type);
609
- return addressFromPublicKey(publicKey, encoding);
610
- };
611
-
612
- /**
613
- * @dev we only expect suri to contain a mnemonic and derivation path.
614
- * for other cases see https://polkadot.js.org/docs/keyring/start/suri/
615
- */
616
- const parseSuri = suri => {
617
- // extract password if any
618
- const indexOfPassword = suri.indexOf("///");
619
- const password = indexOfPassword === -1 ? undefined : suri.slice(indexOfPassword + 3);
620
- if (password) suri = suri.slice(0, indexOfPassword);
621
-
622
- // split mnemonic and derivation path
623
- const indexOfSlash = suri.indexOf("/");
624
- const mnemonic = indexOfSlash === -1 ? suri : suri.slice(0, indexOfSlash);
625
- let derivationPath = indexOfSlash === -1 ? "" : suri.slice(indexOfSlash);
626
-
627
- // if BIP44, leading slash must be removed
628
- if (derivationPath.startsWith("/m/")) derivationPath = derivationPath.slice(1);
629
- if (!isValidMnemonic(mnemonic)) throw new Error("Invalid mnemonic");
630
- return {
631
- mnemonic,
632
- derivationPath,
633
- password
634
- };
623
+ address
624
+ } = deriveKeypair(seed, derivationPath, curve);
625
+ return address;
635
626
  };
636
627
  const removeHexPrefix = secretKey => {
637
628
  if (secretKey.startsWith("0x")) return secretKey.slice(2);
638
629
  return secretKey;
639
630
  };
640
- const parseSecretKey = (secretKey, curve) => {
641
- switch (curve) {
631
+ const parseSecretKey = (secretKey, platform) => {
632
+ switch (platform) {
642
633
  case "ethereum":
643
- return base.stringToBytes("hex", removeHexPrefix(secretKey));
644
- case "ed25519":
645
- case "sr25519":
646
- case "ecdsa":
647
- case "bitcoin-ecdsa":
648
- case "bitcoin-ed25519":
634
+ {
635
+ const privateKey = removeHexPrefix(secretKey);
636
+ return base.hex.decode(privateKey);
637
+ }
649
638
  case "solana":
639
+ {
640
+ const bytes = secretKey.startsWith("[") ?
641
+ // JSON bytes array (ex: solflare)
642
+ Uint8Array.from(JSON.parse(secretKey)) :
643
+ // base58 encoded string (ex: phantom)
644
+ base.base58.decode(secretKey);
645
+ if (bytes.length === 64) {
646
+ const privateKey = bytes.slice(0, 32);
647
+ const publicKey = bytes.slice(32, 64);
648
+ const computedPublicKey = getPublicKeySolana(privateKey);
649
+ if (!publicKey.every((b, i) => b === computedPublicKey[i])) throw new Error("Invalid Solana secret key: public key does not match");
650
+ return privateKey;
651
+ } else if (bytes.length === 32) return bytes;
652
+ throw new Error("Invalid Solana secret key length");
653
+ }
654
+ default:
650
655
  throw new Error("Not implemented");
651
656
  }
652
657
  };
@@ -661,7 +666,7 @@ const isValidDerivationPath = async (derivationPath, curve) => {
661
666
  }
662
667
  };
663
668
 
664
- const platformFromCurve = curve => {
669
+ const getAccountPlatformFromCurve = curve => {
665
670
  switch (curve) {
666
671
  case "sr25519":
667
672
  case "ed25519":
@@ -676,7 +681,7 @@ const platformFromCurve = curve => {
676
681
  return "solana";
677
682
  }
678
683
  };
679
- const platformFromEncoding = encoding => {
684
+ const getAccountPlatformFromEncoding = encoding => {
680
685
  switch (encoding) {
681
686
  case "ss58":
682
687
  return "polkadot";
@@ -686,28 +691,40 @@ const platformFromEncoding = encoding => {
686
691
  case "bech32":
687
692
  case "base58check":
688
693
  return "bitcoin";
689
- case "base58":
694
+ case "base58solana":
690
695
  return "solana";
691
696
  }
692
697
  };
693
- const platformFromAddress = address => {
698
+ const getAccountPlatformFromAddress = address => {
694
699
  const encoding = detectAddressEncoding(address);
695
- return platformFromEncoding(encoding);
700
+ return getAccountPlatformFromEncoding(encoding);
696
701
  };
697
702
 
698
- Object.defineProperty(exports, "bytesToString", {
703
+ Object.defineProperty(exports, "base58", {
704
+ enumerable: true,
705
+ get: function () { return base.base58; }
706
+ });
707
+ Object.defineProperty(exports, "base64", {
708
+ enumerable: true,
709
+ get: function () { return base.base64; }
710
+ });
711
+ Object.defineProperty(exports, "hex", {
712
+ enumerable: true,
713
+ get: function () { return base.hex; }
714
+ });
715
+ Object.defineProperty(exports, "utf8", {
699
716
  enumerable: true,
700
- get: function () { return base.bytesToString; }
717
+ get: function () { return base.utf8; }
701
718
  });
702
- Object.defineProperty(exports, "stringToBytes", {
719
+ Object.defineProperty(exports, "ed25519", {
703
720
  enumerable: true,
704
- get: function () { return base.stringToBytes; }
721
+ get: function () { return ed25519.ed25519; }
705
722
  });
706
723
  exports.DEV_MNEMONIC_ETHEREUM = DEV_MNEMONIC_ETHEREUM;
707
724
  exports.DEV_MNEMONIC_POLKADOT = DEV_MNEMONIC_POLKADOT;
708
725
  exports.addressEncodingFromCurve = addressEncodingFromCurve;
726
+ exports.addressFromMnemonic = addressFromMnemonic;
709
727
  exports.addressFromPublicKey = addressFromPublicKey;
710
- exports.addressFromSuri = addressFromSuri;
711
728
  exports.blake2b256 = blake2b256;
712
729
  exports.blake2b512 = blake2b512;
713
730
  exports.blake3 = blake3;
@@ -715,34 +732,35 @@ exports.checksumEthereumAddress = checksumEthereumAddress;
715
732
  exports.decodeSs58Address = decodeSs58Address;
716
733
  exports.deriveKeypair = deriveKeypair;
717
734
  exports.detectAddressEncoding = detectAddressEncoding;
718
- exports.encodeAddressBase58 = encodeAddressBase58;
719
735
  exports.encodeAddressEthereum = encodeAddressEthereum;
736
+ exports.encodeAddressSolana = encodeAddressSolana;
720
737
  exports.encodeAddressSs58 = encodeAddressSs58;
738
+ exports.encodeAnyAddress = encodeAnyAddress;
721
739
  exports.entropyToMnemonic = entropyToMnemonic;
722
740
  exports.entropyToSeed = entropyToSeed;
723
741
  exports.fromBase58Check = fromBase58Check;
724
742
  exports.fromBech32 = fromBech32;
725
743
  exports.fromBech32m = fromBech32m;
726
744
  exports.generateMnemonic = generateMnemonic;
745
+ exports.getAccountPlatformFromAddress = getAccountPlatformFromAddress;
746
+ exports.getAccountPlatformFromCurve = getAccountPlatformFromCurve;
747
+ exports.getAccountPlatformFromEncoding = getAccountPlatformFromEncoding;
727
748
  exports.getDevSeed = getDevSeed;
728
749
  exports.getPublicKeyFromSecret = getPublicKeyFromSecret;
729
750
  exports.getSafeHash = getSafeHash;
730
751
  exports.isAddressEqual = isAddressEqual;
731
- exports.isBase58Address = isBase58Address;
752
+ exports.isAddressValid = isAddressValid;
732
753
  exports.isBase58CheckAddress = isBase58CheckAddress;
733
754
  exports.isBech32Address = isBech32Address;
734
755
  exports.isBech32mAddress = isBech32mAddress;
735
756
  exports.isBitcoinAddress = isBitcoinAddress;
736
757
  exports.isEthereumAddress = isEthereumAddress;
758
+ exports.isSolanaAddress = isSolanaAddress;
737
759
  exports.isSs58Address = isSs58Address;
738
760
  exports.isValidDerivationPath = isValidDerivationPath;
739
761
  exports.isValidMnemonic = isValidMnemonic;
740
762
  exports.mnemonicToEntropy = mnemonicToEntropy;
741
763
  exports.normalizeAddress = normalizeAddress;
742
764
  exports.parseSecretKey = parseSecretKey;
743
- exports.parseSuri = parseSuri;
744
765
  exports.pbkdf2 = pbkdf2;
745
- exports.platformFromAddress = platformFromAddress;
746
- exports.platformFromCurve = platformFromCurve;
747
- exports.platformFromEncoding = platformFromEncoding;
748
766
  exports.removeHexPrefix = removeHexPrefix;
@@ -3,15 +3,15 @@
3
3
  var bip39 = require('@scure/bip39');
4
4
  var english = require('@scure/bip39/wordlists/english');
5
5
  var base = require('@scure/base');
6
+ var ed25519 = require('@noble/curves/ed25519');
7
+ var secp256k1 = require('@noble/curves/secp256k1');
6
8
  var bech32 = require('bech32');
7
9
  var bs58check = require('bs58check');
8
10
  var sha3 = require('@noble/hashes/sha3');
9
11
  var utils = require('@noble/hashes/utils');
10
12
  var blake2b = require('@noble/hashes/blake2b');
11
13
  var blake3$1 = require('@noble/hashes/blake3');
12
- var secp256k1 = require('@noble/curves/secp256k1');
13
14
  var scaleTs = require('scale-ts');
14
- var ed25519 = require('@noble/curves/ed25519');
15
15
  var bip32 = require('@scure/bip32');
16
16
  var hmac = require('@noble/hashes/hmac');
17
17
  var sha512 = require('@noble/hashes/sha512');
@@ -140,18 +140,18 @@ const addressEncodingFromCurve = curve => {
140
140
  case "ethereum":
141
141
  return "ethereum";
142
142
  case "solana":
143
- return "base58";
143
+ return "base58solana";
144
144
  }
145
145
  };
146
146
 
147
- const encodeAddressBase58 = publicKey => {
147
+ const encodeAddressSolana = publicKey => {
148
+ if (publicKey.length !== 32) throw new Error("Public key must be 32 bytes long for Solana base58 encoding");
148
149
  return base.base58.encode(publicKey);
149
150
  };
150
- /** Detect if address is base58 encoded (NOTE: also returns true for ss58 addresses) */
151
- function isBase58Address(address) {
151
+ function isSolanaAddress(address) {
152
152
  try {
153
- base.base58.decode(address);
154
- return true;
153
+ const bytes = base.base58.decode(address);
154
+ return bytes.length === 32;
155
155
  } catch (error) {
156
156
  return false;
157
157
  }
@@ -287,7 +287,7 @@ const blake2b512 = msg => blake2b.blake2b(msg, {
287
287
  const getSafeHash = bytes => {
288
288
  // cryptographically secure one way hash
289
289
  // outputs 44 characters without special characters
290
- return base.bytesToString("base58", blake3$1.blake3(bytes));
290
+ return base.base58.encode(blake3$1.blake3(bytes));
291
291
  };
292
292
 
293
293
  // Inspired from MIT licensed @polkadot-labs/hdkd-helpers
@@ -336,10 +336,10 @@ const CACHE$1 = new Map();
336
336
  const detectAddressEncodingInner = address => {
337
337
  if (isEthereumAddress(address)) return "ethereum";
338
338
  if (isSs58Address(address)) return "ss58";
339
+ if (isSolanaAddress(address)) return "base58solana";
339
340
  if (isBech32mAddress(address)) return "bech32m";
340
341
  if (isBech32Address(address)) return "bech32";
341
342
  if (isBase58CheckAddress(address)) return "base58check";
342
- if (isBase58Address(address)) return "base58";
343
343
  throw new Error(`Unknown address encoding`);
344
344
  };
345
345
  const detectAddressEncoding = address => {
@@ -353,12 +353,12 @@ const addressFromPublicKey = (publicKey, encoding, options) => {
353
353
  return encodeAddressSs58(publicKey, options?.ss58Prefix);
354
354
  case "ethereum":
355
355
  return encodeAddressEthereum(publicKey);
356
+ case "base58solana":
357
+ return encodeAddressSolana(publicKey);
356
358
  case "bech32m":
357
359
  case "bech32":
358
360
  case "base58check":
359
361
  throw new Error("addressFromPublicKey is not implemented for Bitcoin");
360
- case "base58":
361
- return encodeAddressBase58(publicKey);
362
362
  }
363
363
  };
364
364
 
@@ -382,7 +382,7 @@ const normalizeAnyAddress = address => {
382
382
  case "bech32m":
383
383
  case "bech32":
384
384
  case "base58check":
385
- case "base58":
385
+ case "base58solana":
386
386
  return address;
387
387
  case "ss58":
388
388
  {
@@ -401,6 +401,29 @@ const isAddressEqual = (address1, address2) => {
401
401
  }
402
402
  };
403
403
 
404
+ const encodeAnyAddress = (address, options) => {
405
+ // this leverages cache
406
+ const encoding = detectAddressEncoding(address);
407
+
408
+ // this does NOT leverage cache
409
+ if (encoding === "ss58" && options?.ss58Format !== undefined) {
410
+ const [publicKey] = decodeSs58Address(address);
411
+ return encodeAddressSs58(publicKey, options?.ss58Format ?? 42);
412
+ }
413
+
414
+ // this leverages cache
415
+ return normalizeAddress(address);
416
+ };
417
+
418
+ const isAddressValid = address => {
419
+ try {
420
+ detectAddressEncoding(address);
421
+ return true;
422
+ } catch {
423
+ return false;
424
+ }
425
+ };
426
+
404
427
  // Inspired from MIT licensed @polkadot-labs/hdkd helpers
405
428
  // https://github.com/polkadot-labs/hdkd/blob/3ef6e02827212d934b59a4e566d8aa61d3ba7b27/packages/hdkd-helpers/src/parseDerivations.ts#L1
406
429
 
@@ -535,7 +558,7 @@ const deriveSolana = (seed, derivationPath) => {
535
558
  type: "solana",
536
559
  secretKey,
537
560
  publicKey,
538
- address: addressFromPublicKey(publicKey, "base58")
561
+ address: addressFromPublicKey(publicKey, "base58solana")
539
562
  };
540
563
  };
541
564
  const getPublicKeySolana = secretKey => {
@@ -593,60 +616,42 @@ const getPublicKeyFromSecret = (secretKey, curve) => {
593
616
  return getPublicKeySolana(secretKey);
594
617
  }
595
618
  };
596
- const addressFromSuri = async (suri, type) => {
597
- const {
598
- mnemonic,
599
- derivationPath,
600
- password
601
- } = parseSuri(suri);
619
+ const addressFromMnemonic = async (mnemonic, derivationPath, curve) => {
602
620
  const entropy = mnemonicToEntropy(mnemonic);
603
- const seed = await entropyToSeed(entropy, type, password); // ~80ms
621
+ const seed = await entropyToSeed(entropy, curve);
604
622
  const {
605
- secretKey
606
- } = deriveKeypair(seed, derivationPath, type);
607
- const publicKey = getPublicKeyFromSecret(secretKey, type);
608
- const encoding = addressEncodingFromCurve(type);
609
- return addressFromPublicKey(publicKey, encoding);
610
- };
611
-
612
- /**
613
- * @dev we only expect suri to contain a mnemonic and derivation path.
614
- * for other cases see https://polkadot.js.org/docs/keyring/start/suri/
615
- */
616
- const parseSuri = suri => {
617
- // extract password if any
618
- const indexOfPassword = suri.indexOf("///");
619
- const password = indexOfPassword === -1 ? undefined : suri.slice(indexOfPassword + 3);
620
- if (password) suri = suri.slice(0, indexOfPassword);
621
-
622
- // split mnemonic and derivation path
623
- const indexOfSlash = suri.indexOf("/");
624
- const mnemonic = indexOfSlash === -1 ? suri : suri.slice(0, indexOfSlash);
625
- let derivationPath = indexOfSlash === -1 ? "" : suri.slice(indexOfSlash);
626
-
627
- // if BIP44, leading slash must be removed
628
- if (derivationPath.startsWith("/m/")) derivationPath = derivationPath.slice(1);
629
- if (!isValidMnemonic(mnemonic)) throw new Error("Invalid mnemonic");
630
- return {
631
- mnemonic,
632
- derivationPath,
633
- password
634
- };
623
+ address
624
+ } = deriveKeypair(seed, derivationPath, curve);
625
+ return address;
635
626
  };
636
627
  const removeHexPrefix = secretKey => {
637
628
  if (secretKey.startsWith("0x")) return secretKey.slice(2);
638
629
  return secretKey;
639
630
  };
640
- const parseSecretKey = (secretKey, curve) => {
641
- switch (curve) {
631
+ const parseSecretKey = (secretKey, platform) => {
632
+ switch (platform) {
642
633
  case "ethereum":
643
- return base.stringToBytes("hex", removeHexPrefix(secretKey));
644
- case "ed25519":
645
- case "sr25519":
646
- case "ecdsa":
647
- case "bitcoin-ecdsa":
648
- case "bitcoin-ed25519":
634
+ {
635
+ const privateKey = removeHexPrefix(secretKey);
636
+ return base.hex.decode(privateKey);
637
+ }
649
638
  case "solana":
639
+ {
640
+ const bytes = secretKey.startsWith("[") ?
641
+ // JSON bytes array (ex: solflare)
642
+ Uint8Array.from(JSON.parse(secretKey)) :
643
+ // base58 encoded string (ex: phantom)
644
+ base.base58.decode(secretKey);
645
+ if (bytes.length === 64) {
646
+ const privateKey = bytes.slice(0, 32);
647
+ const publicKey = bytes.slice(32, 64);
648
+ const computedPublicKey = getPublicKeySolana(privateKey);
649
+ if (!publicKey.every((b, i) => b === computedPublicKey[i])) throw new Error("Invalid Solana secret key: public key does not match");
650
+ return privateKey;
651
+ } else if (bytes.length === 32) return bytes;
652
+ throw new Error("Invalid Solana secret key length");
653
+ }
654
+ default:
650
655
  throw new Error("Not implemented");
651
656
  }
652
657
  };
@@ -661,7 +666,7 @@ const isValidDerivationPath = async (derivationPath, curve) => {
661
666
  }
662
667
  };
663
668
 
664
- const platformFromCurve = curve => {
669
+ const getAccountPlatformFromCurve = curve => {
665
670
  switch (curve) {
666
671
  case "sr25519":
667
672
  case "ed25519":
@@ -676,7 +681,7 @@ const platformFromCurve = curve => {
676
681
  return "solana";
677
682
  }
678
683
  };
679
- const platformFromEncoding = encoding => {
684
+ const getAccountPlatformFromEncoding = encoding => {
680
685
  switch (encoding) {
681
686
  case "ss58":
682
687
  return "polkadot";
@@ -686,28 +691,40 @@ const platformFromEncoding = encoding => {
686
691
  case "bech32":
687
692
  case "base58check":
688
693
  return "bitcoin";
689
- case "base58":
694
+ case "base58solana":
690
695
  return "solana";
691
696
  }
692
697
  };
693
- const platformFromAddress = address => {
698
+ const getAccountPlatformFromAddress = address => {
694
699
  const encoding = detectAddressEncoding(address);
695
- return platformFromEncoding(encoding);
700
+ return getAccountPlatformFromEncoding(encoding);
696
701
  };
697
702
 
698
- Object.defineProperty(exports, "bytesToString", {
703
+ Object.defineProperty(exports, "base58", {
704
+ enumerable: true,
705
+ get: function () { return base.base58; }
706
+ });
707
+ Object.defineProperty(exports, "base64", {
708
+ enumerable: true,
709
+ get: function () { return base.base64; }
710
+ });
711
+ Object.defineProperty(exports, "hex", {
712
+ enumerable: true,
713
+ get: function () { return base.hex; }
714
+ });
715
+ Object.defineProperty(exports, "utf8", {
699
716
  enumerable: true,
700
- get: function () { return base.bytesToString; }
717
+ get: function () { return base.utf8; }
701
718
  });
702
- Object.defineProperty(exports, "stringToBytes", {
719
+ Object.defineProperty(exports, "ed25519", {
703
720
  enumerable: true,
704
- get: function () { return base.stringToBytes; }
721
+ get: function () { return ed25519.ed25519; }
705
722
  });
706
723
  exports.DEV_MNEMONIC_ETHEREUM = DEV_MNEMONIC_ETHEREUM;
707
724
  exports.DEV_MNEMONIC_POLKADOT = DEV_MNEMONIC_POLKADOT;
708
725
  exports.addressEncodingFromCurve = addressEncodingFromCurve;
726
+ exports.addressFromMnemonic = addressFromMnemonic;
709
727
  exports.addressFromPublicKey = addressFromPublicKey;
710
- exports.addressFromSuri = addressFromSuri;
711
728
  exports.blake2b256 = blake2b256;
712
729
  exports.blake2b512 = blake2b512;
713
730
  exports.blake3 = blake3;
@@ -715,34 +732,35 @@ exports.checksumEthereumAddress = checksumEthereumAddress;
715
732
  exports.decodeSs58Address = decodeSs58Address;
716
733
  exports.deriveKeypair = deriveKeypair;
717
734
  exports.detectAddressEncoding = detectAddressEncoding;
718
- exports.encodeAddressBase58 = encodeAddressBase58;
719
735
  exports.encodeAddressEthereum = encodeAddressEthereum;
736
+ exports.encodeAddressSolana = encodeAddressSolana;
720
737
  exports.encodeAddressSs58 = encodeAddressSs58;
738
+ exports.encodeAnyAddress = encodeAnyAddress;
721
739
  exports.entropyToMnemonic = entropyToMnemonic;
722
740
  exports.entropyToSeed = entropyToSeed;
723
741
  exports.fromBase58Check = fromBase58Check;
724
742
  exports.fromBech32 = fromBech32;
725
743
  exports.fromBech32m = fromBech32m;
726
744
  exports.generateMnemonic = generateMnemonic;
745
+ exports.getAccountPlatformFromAddress = getAccountPlatformFromAddress;
746
+ exports.getAccountPlatformFromCurve = getAccountPlatformFromCurve;
747
+ exports.getAccountPlatformFromEncoding = getAccountPlatformFromEncoding;
727
748
  exports.getDevSeed = getDevSeed;
728
749
  exports.getPublicKeyFromSecret = getPublicKeyFromSecret;
729
750
  exports.getSafeHash = getSafeHash;
730
751
  exports.isAddressEqual = isAddressEqual;
731
- exports.isBase58Address = isBase58Address;
752
+ exports.isAddressValid = isAddressValid;
732
753
  exports.isBase58CheckAddress = isBase58CheckAddress;
733
754
  exports.isBech32Address = isBech32Address;
734
755
  exports.isBech32mAddress = isBech32mAddress;
735
756
  exports.isBitcoinAddress = isBitcoinAddress;
736
757
  exports.isEthereumAddress = isEthereumAddress;
758
+ exports.isSolanaAddress = isSolanaAddress;
737
759
  exports.isSs58Address = isSs58Address;
738
760
  exports.isValidDerivationPath = isValidDerivationPath;
739
761
  exports.isValidMnemonic = isValidMnemonic;
740
762
  exports.mnemonicToEntropy = mnemonicToEntropy;
741
763
  exports.normalizeAddress = normalizeAddress;
742
764
  exports.parseSecretKey = parseSecretKey;
743
- exports.parseSuri = parseSuri;
744
765
  exports.pbkdf2 = pbkdf2;
745
- exports.platformFromAddress = platformFromAddress;
746
- exports.platformFromCurve = platformFromCurve;
747
- exports.platformFromEncoding = platformFromEncoding;
748
766
  exports.removeHexPrefix = removeHexPrefix;
@@ -1,16 +1,17 @@
1
1
  import { mnemonicToEntropy as mnemonicToEntropy$1, entropyToMnemonic as entropyToMnemonic$1, validateMnemonic, generateMnemonic as generateMnemonic$1 } from '@scure/bip39';
2
2
  import { wordlist } from '@scure/bip39/wordlists/english';
3
- import { base58, bytesToString, stringToBytes } from '@scure/base';
4
- export { bytesToString, stringToBytes } from '@scure/base';
3
+ import { base58, hex } from '@scure/base';
4
+ export { base58, base64, hex, utf8 } from '@scure/base';
5
+ import { ed25519 } from '@noble/curves/ed25519';
6
+ export { ed25519 } from '@noble/curves/ed25519';
7
+ import { secp256k1 } from '@noble/curves/secp256k1';
5
8
  import { bech32m, bech32 } from 'bech32';
6
9
  import bs58check from 'bs58check';
7
10
  import { keccak_256 } from '@noble/hashes/sha3';
8
11
  import { bytesToHex, randomBytes } from '@noble/hashes/utils';
9
12
  import { blake2b } from '@noble/hashes/blake2b';
10
13
  import { blake3 as blake3$1 } from '@noble/hashes/blake3';
11
- import { secp256k1 } from '@noble/curves/secp256k1';
12
14
  import { Tuple, str, Bytes, u32 } from 'scale-ts';
13
- import { ed25519 } from '@noble/curves/ed25519';
14
15
  import { HDKey } from '@scure/bip32';
15
16
  import { hmac } from '@noble/hashes/hmac';
16
17
  import { sha512 } from '@noble/hashes/sha512';
@@ -135,18 +136,18 @@ const addressEncodingFromCurve = curve => {
135
136
  case "ethereum":
136
137
  return "ethereum";
137
138
  case "solana":
138
- return "base58";
139
+ return "base58solana";
139
140
  }
140
141
  };
141
142
 
142
- const encodeAddressBase58 = publicKey => {
143
+ const encodeAddressSolana = publicKey => {
144
+ if (publicKey.length !== 32) throw new Error("Public key must be 32 bytes long for Solana base58 encoding");
143
145
  return base58.encode(publicKey);
144
146
  };
145
- /** Detect if address is base58 encoded (NOTE: also returns true for ss58 addresses) */
146
- function isBase58Address(address) {
147
+ function isSolanaAddress(address) {
147
148
  try {
148
- base58.decode(address);
149
- return true;
149
+ const bytes = base58.decode(address);
150
+ return bytes.length === 32;
150
151
  } catch (error) {
151
152
  return false;
152
153
  }
@@ -282,7 +283,7 @@ const blake2b512 = msg => blake2b(msg, {
282
283
  const getSafeHash = bytes => {
283
284
  // cryptographically secure one way hash
284
285
  // outputs 44 characters without special characters
285
- return bytesToString("base58", blake3$1(bytes));
286
+ return base58.encode(blake3$1(bytes));
286
287
  };
287
288
 
288
289
  // Inspired from MIT licensed @polkadot-labs/hdkd-helpers
@@ -331,10 +332,10 @@ const CACHE$1 = new Map();
331
332
  const detectAddressEncodingInner = address => {
332
333
  if (isEthereumAddress(address)) return "ethereum";
333
334
  if (isSs58Address(address)) return "ss58";
335
+ if (isSolanaAddress(address)) return "base58solana";
334
336
  if (isBech32mAddress(address)) return "bech32m";
335
337
  if (isBech32Address(address)) return "bech32";
336
338
  if (isBase58CheckAddress(address)) return "base58check";
337
- if (isBase58Address(address)) return "base58";
338
339
  throw new Error(`Unknown address encoding`);
339
340
  };
340
341
  const detectAddressEncoding = address => {
@@ -348,12 +349,12 @@ const addressFromPublicKey = (publicKey, encoding, options) => {
348
349
  return encodeAddressSs58(publicKey, options?.ss58Prefix);
349
350
  case "ethereum":
350
351
  return encodeAddressEthereum(publicKey);
352
+ case "base58solana":
353
+ return encodeAddressSolana(publicKey);
351
354
  case "bech32m":
352
355
  case "bech32":
353
356
  case "base58check":
354
357
  throw new Error("addressFromPublicKey is not implemented for Bitcoin");
355
- case "base58":
356
- return encodeAddressBase58(publicKey);
357
358
  }
358
359
  };
359
360
 
@@ -377,7 +378,7 @@ const normalizeAnyAddress = address => {
377
378
  case "bech32m":
378
379
  case "bech32":
379
380
  case "base58check":
380
- case "base58":
381
+ case "base58solana":
381
382
  return address;
382
383
  case "ss58":
383
384
  {
@@ -396,6 +397,29 @@ const isAddressEqual = (address1, address2) => {
396
397
  }
397
398
  };
398
399
 
400
+ const encodeAnyAddress = (address, options) => {
401
+ // this leverages cache
402
+ const encoding = detectAddressEncoding(address);
403
+
404
+ // this does NOT leverage cache
405
+ if (encoding === "ss58" && options?.ss58Format !== undefined) {
406
+ const [publicKey] = decodeSs58Address(address);
407
+ return encodeAddressSs58(publicKey, options?.ss58Format ?? 42);
408
+ }
409
+
410
+ // this leverages cache
411
+ return normalizeAddress(address);
412
+ };
413
+
414
+ const isAddressValid = address => {
415
+ try {
416
+ detectAddressEncoding(address);
417
+ return true;
418
+ } catch {
419
+ return false;
420
+ }
421
+ };
422
+
399
423
  // Inspired from MIT licensed @polkadot-labs/hdkd helpers
400
424
  // https://github.com/polkadot-labs/hdkd/blob/3ef6e02827212d934b59a4e566d8aa61d3ba7b27/packages/hdkd-helpers/src/parseDerivations.ts#L1
401
425
 
@@ -530,7 +554,7 @@ const deriveSolana = (seed, derivationPath) => {
530
554
  type: "solana",
531
555
  secretKey,
532
556
  publicKey,
533
- address: addressFromPublicKey(publicKey, "base58")
557
+ address: addressFromPublicKey(publicKey, "base58solana")
534
558
  };
535
559
  };
536
560
  const getPublicKeySolana = secretKey => {
@@ -588,60 +612,42 @@ const getPublicKeyFromSecret = (secretKey, curve) => {
588
612
  return getPublicKeySolana(secretKey);
589
613
  }
590
614
  };
591
- const addressFromSuri = async (suri, type) => {
592
- const {
593
- mnemonic,
594
- derivationPath,
595
- password
596
- } = parseSuri(suri);
615
+ const addressFromMnemonic = async (mnemonic, derivationPath, curve) => {
597
616
  const entropy = mnemonicToEntropy(mnemonic);
598
- const seed = await entropyToSeed(entropy, type, password); // ~80ms
617
+ const seed = await entropyToSeed(entropy, curve);
599
618
  const {
600
- secretKey
601
- } = deriveKeypair(seed, derivationPath, type);
602
- const publicKey = getPublicKeyFromSecret(secretKey, type);
603
- const encoding = addressEncodingFromCurve(type);
604
- return addressFromPublicKey(publicKey, encoding);
605
- };
606
-
607
- /**
608
- * @dev we only expect suri to contain a mnemonic and derivation path.
609
- * for other cases see https://polkadot.js.org/docs/keyring/start/suri/
610
- */
611
- const parseSuri = suri => {
612
- // extract password if any
613
- const indexOfPassword = suri.indexOf("///");
614
- const password = indexOfPassword === -1 ? undefined : suri.slice(indexOfPassword + 3);
615
- if (password) suri = suri.slice(0, indexOfPassword);
616
-
617
- // split mnemonic and derivation path
618
- const indexOfSlash = suri.indexOf("/");
619
- const mnemonic = indexOfSlash === -1 ? suri : suri.slice(0, indexOfSlash);
620
- let derivationPath = indexOfSlash === -1 ? "" : suri.slice(indexOfSlash);
621
-
622
- // if BIP44, leading slash must be removed
623
- if (derivationPath.startsWith("/m/")) derivationPath = derivationPath.slice(1);
624
- if (!isValidMnemonic(mnemonic)) throw new Error("Invalid mnemonic");
625
- return {
626
- mnemonic,
627
- derivationPath,
628
- password
629
- };
619
+ address
620
+ } = deriveKeypair(seed, derivationPath, curve);
621
+ return address;
630
622
  };
631
623
  const removeHexPrefix = secretKey => {
632
624
  if (secretKey.startsWith("0x")) return secretKey.slice(2);
633
625
  return secretKey;
634
626
  };
635
- const parseSecretKey = (secretKey, curve) => {
636
- switch (curve) {
627
+ const parseSecretKey = (secretKey, platform) => {
628
+ switch (platform) {
637
629
  case "ethereum":
638
- return stringToBytes("hex", removeHexPrefix(secretKey));
639
- case "ed25519":
640
- case "sr25519":
641
- case "ecdsa":
642
- case "bitcoin-ecdsa":
643
- case "bitcoin-ed25519":
630
+ {
631
+ const privateKey = removeHexPrefix(secretKey);
632
+ return hex.decode(privateKey);
633
+ }
644
634
  case "solana":
635
+ {
636
+ const bytes = secretKey.startsWith("[") ?
637
+ // JSON bytes array (ex: solflare)
638
+ Uint8Array.from(JSON.parse(secretKey)) :
639
+ // base58 encoded string (ex: phantom)
640
+ base58.decode(secretKey);
641
+ if (bytes.length === 64) {
642
+ const privateKey = bytes.slice(0, 32);
643
+ const publicKey = bytes.slice(32, 64);
644
+ const computedPublicKey = getPublicKeySolana(privateKey);
645
+ if (!publicKey.every((b, i) => b === computedPublicKey[i])) throw new Error("Invalid Solana secret key: public key does not match");
646
+ return privateKey;
647
+ } else if (bytes.length === 32) return bytes;
648
+ throw new Error("Invalid Solana secret key length");
649
+ }
650
+ default:
645
651
  throw new Error("Not implemented");
646
652
  }
647
653
  };
@@ -656,7 +662,7 @@ const isValidDerivationPath = async (derivationPath, curve) => {
656
662
  }
657
663
  };
658
664
 
659
- const platformFromCurve = curve => {
665
+ const getAccountPlatformFromCurve = curve => {
660
666
  switch (curve) {
661
667
  case "sr25519":
662
668
  case "ed25519":
@@ -671,7 +677,7 @@ const platformFromCurve = curve => {
671
677
  return "solana";
672
678
  }
673
679
  };
674
- const platformFromEncoding = encoding => {
680
+ const getAccountPlatformFromEncoding = encoding => {
675
681
  switch (encoding) {
676
682
  case "ss58":
677
683
  return "polkadot";
@@ -681,13 +687,13 @@ const platformFromEncoding = encoding => {
681
687
  case "bech32":
682
688
  case "base58check":
683
689
  return "bitcoin";
684
- case "base58":
690
+ case "base58solana":
685
691
  return "solana";
686
692
  }
687
693
  };
688
- const platformFromAddress = address => {
694
+ const getAccountPlatformFromAddress = address => {
689
695
  const encoding = detectAddressEncoding(address);
690
- return platformFromEncoding(encoding);
696
+ return getAccountPlatformFromEncoding(encoding);
691
697
  };
692
698
 
693
- export { DEV_MNEMONIC_ETHEREUM, DEV_MNEMONIC_POLKADOT, addressEncodingFromCurve, addressFromPublicKey, addressFromSuri, blake2b256, blake2b512, blake3, checksumEthereumAddress, decodeSs58Address, deriveKeypair, detectAddressEncoding, encodeAddressBase58, encodeAddressEthereum, encodeAddressSs58, entropyToMnemonic, entropyToSeed, fromBase58Check, fromBech32, fromBech32m, generateMnemonic, getDevSeed, getPublicKeyFromSecret, getSafeHash, isAddressEqual, isBase58Address, isBase58CheckAddress, isBech32Address, isBech32mAddress, isBitcoinAddress, isEthereumAddress, isSs58Address, isValidDerivationPath, isValidMnemonic, mnemonicToEntropy, normalizeAddress, parseSecretKey, parseSuri, pbkdf2, platformFromAddress, platformFromCurve, platformFromEncoding, removeHexPrefix };
699
+ export { DEV_MNEMONIC_ETHEREUM, DEV_MNEMONIC_POLKADOT, addressEncodingFromCurve, addressFromMnemonic, addressFromPublicKey, blake2b256, blake2b512, blake3, checksumEthereumAddress, decodeSs58Address, deriveKeypair, detectAddressEncoding, encodeAddressEthereum, encodeAddressSolana, encodeAddressSs58, encodeAnyAddress, entropyToMnemonic, entropyToSeed, fromBase58Check, fromBech32, fromBech32m, generateMnemonic, getAccountPlatformFromAddress, getAccountPlatformFromCurve, getAccountPlatformFromEncoding, getDevSeed, getPublicKeyFromSecret, getSafeHash, isAddressEqual, isAddressValid, isBase58CheckAddress, isBech32Address, isBech32mAddress, isBitcoinAddress, isEthereumAddress, isSolanaAddress, isSs58Address, isValidDerivationPath, isValidMnemonic, mnemonicToEntropy, normalizeAddress, parseSecretKey, pbkdf2, removeHexPrefix };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@talismn/crypto",
3
- "version": "0.1.5",
3
+ "version": "0.2.1",
4
4
  "author": "Talisman",
5
5
  "homepage": "https://talisman.xyz",
6
6
  "license": "GPL-3.0-or-later",
@@ -15,8 +15,7 @@
15
15
  "main": "dist/talismn-crypto.cjs.js",
16
16
  "module": "dist/talismn-crypto.esm.js",
17
17
  "files": [
18
- "/dist",
19
- "/plugins"
18
+ "/dist"
20
19
  ],
21
20
  "engines": {
22
21
  "node": ">=18"
@@ -38,8 +37,8 @@
38
37
  "jest": "^29.7.0",
39
38
  "ts-jest": "^29.2.5",
40
39
  "typescript": "^5.6.3",
41
- "@talismn/tsconfig": "0.0.2",
42
- "@talismn/eslint-config": "0.0.3"
40
+ "@talismn/eslint-config": "0.0.3",
41
+ "@talismn/tsconfig": "0.0.2"
43
42
  },
44
43
  "preconstruct": {
45
44
  "entrypoints": [
@@ -53,8 +52,8 @@
53
52
  ]
54
53
  },
55
54
  "scripts": {
56
- "test": "jest",
55
+ "test": "jest --detectOpenHandles",
57
56
  "lint": "eslint src --max-warnings 0",
58
- "clean": "rm -rf dist plugins/dist .turbo node_modules"
57
+ "clean": "rm -rf dist .turbo node_modules"
59
58
  }
60
59
  }
@@ -1,3 +0,0 @@
1
- export declare const encodeAddressBase58: (publicKey: Uint8Array) => string;
2
- /** Detect if address is base58 encoded (NOTE: also returns true for ss58 addresses) */
3
- export declare function isBase58Address(address: string): boolean;