PHP WebShell

Текущая директория: /usr/lib/node_modules/bitgo/node_modules/@vechain/sdk-core/src/hdkey

Просмотр файла: HDKey.ts

import * as s_bip32 from '@scure/bip32';
import * as s_bip39 from '@scure/bip39';
import * as nc_utils from '@noble/curves/abstract/utils';
import { base58 } from '@scure/base';
import { FixedPointNumber } from '../vcdm/FixedPointNumber';
import { Sha256 } from '../vcdm/hash/Sha256';
import { HexUInt } from '../vcdm/HexUInt';
import { Secp256k1 } from '../secp256k1/Secp256k1';
import {
    InvalidHDKey,
    InvalidHDKeyMnemonic,
    InvalidSecp256k1PrivateKey
} from '@vechain/sdk-errors';

/**
 * This class extends the
 * [BIP32 Hierarchical Deterministic Key](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)
 * [HDKey](https://github.com/paulmillr/scure-bip32) class
 * to provide interoperability with
 * [ethers.js 6 HDNodeWallet](https://docs.ethers.org/v6/api/wallet/#HDNodeWallet).
 *
 * @extends s_bip32.HDKey
 */
class HDKey extends s_bip32.HDKey {
    /**
     * Prefix for extended private key
     */
    public static readonly EXTENDED_PRIVATE_KEY_PREFIX = HexUInt.of(
        '0488ade4000000000000000000'
    ).bytes;

    /**
     * Prefix for extended public key
     */
    public static readonly EXTENDED_PUBLIC_KEY_PREFIX = HexUInt.of(
        '0488b21e000000000000000000'
    ).bytes;

    /**
     * Default VET derivation path.
     *
     * See
     * [SLIP-0044 : Registered coin types for BIP-0044](https://github.com/satoshilabs/slips/blob/master/slip-0044.md)
     * for more info.
     */
    public static readonly VET_DERIVATION_PATH = "m/44'/818'/0'/0";

    /**
     * Creates a
     * [BIP32 Hierarchical Deterministic Key](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)
     * from
     * [BIP39 Mnemonic Words](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki)
     * and the given derivation path.
     *
     * @param {string[]} words - An array of words representing the mnemonic.
     * @param {string} path - The derivation path to derive the child node.
     * Default value is {@link VET_DERIVATION_PATH}.
     *
     * @return The derived child hierarchical deterministic key.
     *
     * @throws {InvalidHDKey} If `path` is not valid to derive a node wallet.
     * @throws {InvalidHDKeyMnemonic} If `words` is an invalid array mnemonic.
     *
     * @remarks Security auditable method, depends on
     * * [s_bip32.HDKey.derive](https://github.com/paulmillr/scure-bip32);
     * * [s_bip32.HDKey.fromMasterSeed](https://github.com/paulmillr/scure-bip32);
     * * [s_bip39.mnemonicToSeedSync](https://github.com/paulmillr/scure-bip39).
     */
    public static fromMnemonic(
        words: string[],
        path: string = this.VET_DERIVATION_PATH
    ): HDKey {
        let master: s_bip32.HDKey;
        try {
            master = s_bip32.HDKey.fromMasterSeed(
                s_bip39.mnemonicToSeedSync(words.join(' ').toLowerCase())
            );
        } catch (error) {
            // The error masks any mnemonic words leak.
            throw new InvalidHDKeyMnemonic(
                'HDNode.fromMnemonic',
                'Invalid mnemonic words given as input.',
                undefined,
                error
            );
        }
        try {
            return master.derive(path) as HDKey;
        } catch (error) {
            throw new InvalidHDKey(
                'HDNode.fromMnemonic',
                'Invalid derivation path given as input.',
                { derivationPath: path },
                error
            );
        }
    }

    /**
     * Creates a
     * [BIP32 Hierarchical Deterministic Key](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)
     * from a private key and chain code.
     *
     * @param {Uint8Array} - privateKey The private key.
     * @param {Uint8Array} - chainCode The chain code.
     *
     * @returns Returns the hierarchical deterministic key from `privateKey` and `chainCode`.
     *
     * @throws {InvalidSecp256k1PrivateKey} If the `privateKey` is invalid.
     *
     * @remarks **This method wipes `privateKey`** for security reasons.
     * @remarks Security auditable method, depends on
     * * [base58.encode](https://github.com/paulmillr/scure-base);
     * * {@link Sha256};
     * * [s_bip32.HDKey.fromExtendedKey](https://github.com/paulmillr/scure-bip32).
     */
    public static fromPrivateKey(
        privateKey: Uint8Array,
        chainCode: Uint8Array
    ): HDKey {
        if (privateKey.length === 32) {
            const header = nc_utils.concatBytes(
                this.EXTENDED_PRIVATE_KEY_PREFIX,
                chainCode,
                Uint8Array.of(0),
                privateKey
            );
            privateKey.fill(0); // Clear the private key from memory.
            const checksum = Sha256.of(Sha256.of(header).bytes).bytes.subarray(
                0,
                4
            );
            const expandedPrivateKey = nc_utils.concatBytes(header, checksum);
            try {
                return s_bip32.HDKey.fromExtendedKey(
                    base58.encode(expandedPrivateKey)
                ) as HDKey;
            } catch {
                throw new InvalidSecp256k1PrivateKey(
                    'HDNode.fromPrivateKey',
                    'Invalid private key path given as input.',
                    undefined
                );
            }
        }

        // We reach this case if privateKey length is not exactly 32 bytes.
        privateKey.fill(0); // Clear the private key from memory, albeit it is invalid.
        throw new InvalidSecp256k1PrivateKey(
            'HDNode.fromPrivateKey()',
            'Invalid private key path given as input. Length must be exactly 32 bytes.',
            undefined
        );
    }

    /**
     * Creates a
     * [BIP32 Hierarchical Deterministic Key](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)
     * key from a public key and chain code.
     *
     * @param {Uint8Array} publicKey - The public key bytes.
     * @param {Uint8Array} chainCode - The chain code bytes.
     *
     * @returns {HDKey} Returns the hierarchical deterministic key from `public` and `chainCode`.
     *
     * @throws {InvalidHDKey} if the `publicKey` is invalid.
     *
     * @remarks Security auditable method, depends on
     * * [base58.encode](https://github.com/paulmillr/scure-base);
     * * {@link Secp256k1.compressPublicKey};
     * * {@link Sha256};
     * * [HDKey.fromExtendedKey](https://github.com/paulmillr/scure-bip32).
     */
    public static fromPublicKey(
        publicKey: Uint8Array,
        chainCode: Uint8Array
    ): HDKey {
        if (chainCode.length === 32) {
            const header = nc_utils.concatBytes(
                this.EXTENDED_PUBLIC_KEY_PREFIX,
                chainCode,
                Secp256k1.compressPublicKey(publicKey)
            );
            const checksum = Sha256.of(Sha256.of(header).bytes).bytes.subarray(
                0,
                4
            );
            const expandedPublicKey = nc_utils.concatBytes(header, checksum);
            try {
                return s_bip32.HDKey.fromExtendedKey(
                    base58.encode(expandedPublicKey)
                ) as HDKey;
            } catch (error) {
                throw new InvalidHDKey(
                    'HDNode.fromPublicKey()',
                    'Invalid public key path given as input.',
                    { publicKey },
                    error
                );
            }
        }

        // We reach this case if chainCode length is not exactly 32 bytes.
        throw new InvalidHDKey(
            'HDNode.fromPublicKey()',
            'Invalid chain code given as input. Length must be exactly 32 bytes.',
            { chainCode }
        );
    }

    /**
     * Checks if derivation path single component is valid
     *
     * @param component - Derivation path single component to check
     * @param index - Derivation path single component index
     *
     * @returns `true`` if derivation path single component is valid, otherwise `false`.
     *
     */
    private static isDerivationPathComponentValid(
        component: string,
        index: number
    ): boolean {
        // Zero component can be "m" or "number" or "number'", other components can be only "number" or "number'"
        return (
            // m
            (index === 0 ? component === 'm' : false) ||
            // "number"
            FixedPointNumber.isNaturalExpression(component) ||
            // "number'"
            (FixedPointNumber.isNaturalExpression(component.slice(0, -1)) &&
                component.endsWith("'"))
        );
    }

    /**
     * Checks if BIP32 derivation path is valid.
     *
     * @param derivationPath - Derivation path to check.
     *
     * @returns `true` if derivation path is valid, otherwise `false`.
     */
    public static isDerivationPathValid(derivationPath: string): boolean {
        const bip32Regex = /^m(\/\d+'?){3}(\/\d+){1,2}$/;
        return bip32Regex.test(derivationPath);
    }
}

export { HDKey };

Выполнить команду


Для локальной разработки. Не используйте в интернете!