Remove local stack extensions
This commit is contained in:
175
src/xo-extensions/hd-public-node.ts
Normal file
175
src/xo-extensions/hd-public-node.ts
Normal file
@@ -0,0 +1,175 @@
|
||||
import { PublicKey } from '@xocash/stack';
|
||||
|
||||
import {
|
||||
encodeHdPublicKey,
|
||||
decodeHdPublicKey,
|
||||
deriveHdPath,
|
||||
deriveHdPathRelative,
|
||||
} from '@bitauth/libauth';
|
||||
|
||||
import type {
|
||||
DecodedHdKey,
|
||||
HdKeyNetwork,
|
||||
HdPublicNodeValid,
|
||||
} from '@bitauth/libauth';
|
||||
|
||||
/**
|
||||
* Hierarchically Deterministic Public Node Entity.
|
||||
*/
|
||||
export class HDPublicNode {
|
||||
// The HD Public Node.
|
||||
protected readonly node: HdPublicNodeValid;
|
||||
|
||||
/**
|
||||
* Construct a new HD Public Node.
|
||||
*
|
||||
* @param node {HdPublicNode} The HD Public Node.
|
||||
*/
|
||||
protected constructor(node: HdPublicNodeValid) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a HD Public Node from the given XPriv Key.
|
||||
*
|
||||
* @param xpub {string} The XPriv Key.
|
||||
*
|
||||
* @throws {Error} If HD Public Node cannot be created.
|
||||
*
|
||||
* @returns {HDPrivateNode} The created HD Public Node.
|
||||
*/
|
||||
public static fromXPub(xpub: string): HDPublicNode {
|
||||
// Attempt to decode the XPub Key.
|
||||
const decodeResult = decodeHdPublicKey(xpub);
|
||||
|
||||
// If a string is returned, this indicates an error...
|
||||
if (typeof decodeResult === 'string') {
|
||||
throw new Error(decodeResult);
|
||||
}
|
||||
|
||||
// Return a new HD Public Node from the given XPub.
|
||||
return new HDPublicNode(decodeResult.node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a HDPublicNode instance from a raw object representation (LibAuth's HdPublicNodeValid).
|
||||
*
|
||||
* @remarks This method is UNSAFE and MUST only be used where input is already verified or trusted.
|
||||
*
|
||||
* @param obj - LibAuth Object of type HdPublicNodeValid
|
||||
* @returns A new HDPublicNode instance
|
||||
*/
|
||||
public static fromRaw(node: HdPublicNodeValid) {
|
||||
return new this(node);
|
||||
}
|
||||
|
||||
public static isXPub(xpub: string): boolean {
|
||||
try {
|
||||
this.fromXPub(xpub);
|
||||
return true;
|
||||
} catch (_error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Public Key Entity for this node.
|
||||
*
|
||||
* @returns The Public Key Entity for this node.
|
||||
*/
|
||||
public toPublicKey(): PublicKey {
|
||||
// Return a Public Key Entity from the public key of our node.
|
||||
return PublicKey.fromRaw(this.node.publicKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this node to an XPub Key for export.
|
||||
*
|
||||
* @param network The network to encode for.
|
||||
*
|
||||
* @returns The XPub Key.
|
||||
*/
|
||||
public toXPub(network: HdKeyNetwork = 'mainnet'): string {
|
||||
// Create our node info structure.
|
||||
const nodeInfo = {
|
||||
network: network,
|
||||
node: this.node,
|
||||
} as DecodedHdKey<HdPublicNodeValid>;
|
||||
|
||||
// Encode the XPub from our node info.
|
||||
return encodeHdPublicKey(nodeInfo).hdPublicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XPub string for this node.
|
||||
*
|
||||
* @returns {string} The XPub string for this node.
|
||||
*/
|
||||
public toString(): string {
|
||||
// Return the Mainnet XPub.
|
||||
return this.toXPub();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the HDPublicKey to its raw Libauth representation (HDPublicNodeValid).
|
||||
*
|
||||
* @returns A LibAuth HDPublicNodeValid object
|
||||
*/
|
||||
public toRaw(): HdPublicNodeValid {
|
||||
return { ...this.node };
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives a HD Public Node from the given BIP32 path.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* This method automatically detects whether the path is absolute (starts with 'm/')
|
||||
* or relative (e.g. '0/1') and uses the appropriate derivation method.
|
||||
*
|
||||
* @param path The BIP32 Path (e.g. m/44'/145'/0'/0/1 or 0/1).
|
||||
*
|
||||
* @throws {Error} If HD Public Node cannot be derived.
|
||||
*
|
||||
* @returns The derived HD Public Node
|
||||
*/
|
||||
public derivePath(path: string): HDPublicNode {
|
||||
// Determine if this is an absolute path (starts with 'm' or 'M').
|
||||
const isAbsolutePath = path.startsWith('m') || path.startsWith('M');
|
||||
|
||||
// Use the appropriate derivation function.
|
||||
const derivePathResult = isAbsolutePath
|
||||
? deriveHdPath(this.node, path)
|
||||
: deriveHdPathRelative(this.node, path);
|
||||
|
||||
// If a string is returned, this indicates an error...
|
||||
if (typeof derivePathResult === 'string') {
|
||||
throw new Error(derivePathResult);
|
||||
}
|
||||
|
||||
// Return a new HD Public Node Entity derived from the given path.
|
||||
return new HDPublicNode(derivePathResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives a HD Public Node from the given relative BIP32 path.
|
||||
*
|
||||
* @param path The relative BIP32 Path (e.g. 0/0 or 0/1).
|
||||
*
|
||||
* @throws {Error} If HD Public Node cannot be derived.
|
||||
*
|
||||
* @returns The derived HD Public Node
|
||||
*/
|
||||
public deriveRelativePath(path: string): HDPublicNode {
|
||||
// Attempt to derive the given relative path.
|
||||
const derivePathResult = deriveHdPathRelative(this.node, path);
|
||||
|
||||
// If a string is returned, this indicates an error...
|
||||
if (typeof derivePathResult === 'string') {
|
||||
throw new Error(derivePathResult);
|
||||
}
|
||||
|
||||
// Return a new HD Public Node Entity derived from the given path.
|
||||
return new HDPublicNode(derivePathResult);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user