Merge branch 'primitive_fixes' into 'development'
Misc Primitive Fixes See merge request GeneralProtocols/xo/stack!18
This commit is contained in:
@@ -41,6 +41,8 @@ function toPascalCase(str: string) {
|
||||
}
|
||||
|
||||
function convertNavToPascalCase(nav: Array<any>) {
|
||||
console.log(nav);
|
||||
|
||||
return nav.map((item) => {
|
||||
const result = { ...item };
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@ body {
|
||||
}
|
||||
|
||||
.vp-doc h4 {
|
||||
font-size: 14px;
|
||||
opacity: 0.75;
|
||||
font-size: 18px;
|
||||
opacity: 1;
|
||||
color: var(--primary);
|
||||
padding-top: 3em;
|
||||
border-top: 1px solid var(--vp-c-text-1);
|
||||
|
||||
@@ -19,12 +19,14 @@
|
||||
"enumMembersFormat": "table",
|
||||
"useCodeBlocks": true,
|
||||
"sort": ["static-first"],
|
||||
"groupOrder": ["Methods", "Properties", "*"],
|
||||
"exclude": "**/*+(index|.spec|.e2e|.browser|.node|.types).ts",
|
||||
"excludeInternal": true,
|
||||
"excludeProtected": true,
|
||||
"excludePrivate": true,
|
||||
"excludeReferences": true,
|
||||
"outputFileStrategy": "modules",
|
||||
"hidePageTitle": true,
|
||||
"hideGroupHeadings": true
|
||||
/*
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ export const DEFAULT_ADDRESS_PREFIXES = [
|
||||
* Address Entity.
|
||||
*/
|
||||
export class Address {
|
||||
public readonly addressContents: KnownAddressTypeContents;
|
||||
protected readonly addressContents: KnownAddressTypeContents;
|
||||
|
||||
protected constructor(addressContents: KnownAddressTypeContents) {
|
||||
this.addressContents = addressContents;
|
||||
@@ -102,7 +102,7 @@ export class Address {
|
||||
}
|
||||
|
||||
// Return new instance of address.
|
||||
return new Address({ payload: decodeResult.payload, type: encodeType });
|
||||
return new this({ payload: decodeResult.payload, type: encodeType });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,7 +140,7 @@ export class Address {
|
||||
throw new Error(`Unsupported address type: ${decodeResult.version}`);
|
||||
}
|
||||
|
||||
return new Address({ payload: decodeResult.payload, type: encodeType });
|
||||
return new this({ payload: decodeResult.payload, type: encodeType });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -47,8 +47,8 @@ export class BlockHeader {
|
||||
*/
|
||||
public static from(blockHeader: Uint8Array | string) {
|
||||
return blockHeader instanceof Uint8Array
|
||||
? BlockHeader.fromBytes(blockHeader)
|
||||
: BlockHeader.fromHex(blockHeader);
|
||||
? this.fromBytes(blockHeader)
|
||||
: this.fromHex(blockHeader);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,7 +85,7 @@ export class BlockHeader {
|
||||
throw new Error('The given string is not valid hexadecimal.');
|
||||
}
|
||||
|
||||
return BlockHeader.fromBytes(hexToBin(hex));
|
||||
return this.fromBytes(hexToBin(hex));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,7 +97,7 @@ export class BlockHeader {
|
||||
* @returns A new BlockHeader instance
|
||||
*/
|
||||
static fromRaw(obj: BlockHeaderRaw): BlockHeader {
|
||||
return new BlockHeader(
|
||||
return new this(
|
||||
obj.version,
|
||||
obj.previousBlockHash,
|
||||
obj.merkleRoot,
|
||||
@@ -116,7 +116,7 @@ export class BlockHeader {
|
||||
*/
|
||||
public static isValid(blockHeader: Uint8Array | string): boolean {
|
||||
try {
|
||||
BlockHeader.from(blockHeader);
|
||||
this.from(blockHeader);
|
||||
} catch (_error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
* Bytes Primitive.
|
||||
*/
|
||||
export class Bytes {
|
||||
public readonly bytes: Uint8Array;
|
||||
protected readonly bytes: Uint8Array;
|
||||
|
||||
/**
|
||||
* Instantiate Bytes from a Uint8Array.
|
||||
|
||||
@@ -24,7 +24,7 @@ import type {
|
||||
*/
|
||||
export class HDPrivateNode {
|
||||
// The HD Private Node.
|
||||
public readonly node: HdPrivateNodeValid;
|
||||
protected readonly node: HdPrivateNodeValid;
|
||||
|
||||
/**
|
||||
* Construct a new HD Private Node.
|
||||
|
||||
@@ -17,7 +17,7 @@ import type {
|
||||
*/
|
||||
export class HDPublicNode {
|
||||
// The HD Public Node.
|
||||
public readonly node: HdPublicNodeValid;
|
||||
protected readonly node: HdPublicNodeValid;
|
||||
|
||||
/**
|
||||
* Construct a new HD Public Node.
|
||||
|
||||
@@ -14,7 +14,7 @@ export type MnemonicRaw = {
|
||||
* Supports 12, 15, 18, 21, and 24 word phrases with optional passphrase.
|
||||
*/
|
||||
export class Mnemonic {
|
||||
public static VALID_WORD_COUNTS = new Set([12, 15, 18, 21, 24]);
|
||||
protected static VALID_WORD_COUNTS = new Set([12, 15, 18, 21, 24]);
|
||||
|
||||
/**
|
||||
* Instantiate Mnemonic from a phrase string.
|
||||
@@ -40,12 +40,9 @@ export class Mnemonic {
|
||||
phraseOrWords: string | Array<string>,
|
||||
wordList: Array<string> = bip39WordListEnglish,
|
||||
) {
|
||||
// If this is a list of words...
|
||||
if (Array.isArray(phraseOrWords)) {
|
||||
return this.fromWords(phraseOrWords, wordList);
|
||||
}
|
||||
|
||||
return this.fromPhrase(phraseOrWords, wordList);
|
||||
return Array.isArray(phraseOrWords)
|
||||
? this.fromWords(phraseOrWords, wordList)
|
||||
: this.fromPhrase(phraseOrWords, wordList);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Bytes } from './bytes.js';
|
||||
import { PublicKey } from './public-key.js';
|
||||
|
||||
import {
|
||||
@@ -5,9 +6,6 @@ import {
|
||||
decodePrivateKeyWif,
|
||||
encodePrivateKeyWif,
|
||||
generatePrivateKey,
|
||||
hexToBin,
|
||||
isHex,
|
||||
utf8ToBin,
|
||||
bigIntToCompactUint,
|
||||
secp256k1,
|
||||
sha256,
|
||||
@@ -23,7 +21,7 @@ import type {
|
||||
*/
|
||||
export class PrivateKey {
|
||||
// The raw bytes representing the Private Key.
|
||||
public readonly bytes: Uint8Array;
|
||||
protected readonly bytes: Uint8Array;
|
||||
|
||||
/**
|
||||
* Construct a new Private Key.
|
||||
@@ -54,14 +52,14 @@ export class PrivateKey {
|
||||
*/
|
||||
public static from(privateKey: Uint8Array | string) {
|
||||
if (privateKey instanceof Uint8Array) {
|
||||
return PrivateKey.fromBytes(privateKey);
|
||||
return this.fromBytes(privateKey);
|
||||
}
|
||||
|
||||
if (PrivateKey.isWIF(privateKey)) {
|
||||
return PrivateKey.fromWIF(privateKey);
|
||||
if (this.isWIF(privateKey)) {
|
||||
return this.fromWIF(privateKey);
|
||||
}
|
||||
|
||||
return PrivateKey.fromHex(privateKey);
|
||||
return this.fromHex(privateKey);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,7 +72,7 @@ export class PrivateKey {
|
||||
* @returns {PrivateKey} The created Private Key Entity.
|
||||
*/
|
||||
public static fromBytes(privateKeyBytes: Uint8Array): PrivateKey {
|
||||
return new PrivateKey(privateKeyBytes);
|
||||
return new this(privateKeyBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,18 +85,11 @@ export class PrivateKey {
|
||||
* @returns {PrivateKey} The created Private Key Entity.
|
||||
*/
|
||||
public static fromHex(privateKeyHex: string): PrivateKey {
|
||||
// Ensure that the given string is hex.
|
||||
if (!isHex(privateKeyHex)) {
|
||||
throw new Error(
|
||||
`The given string (${privateKeyHex}) is not valid hexadecimal.`,
|
||||
);
|
||||
}
|
||||
|
||||
// Convert the hex to binary (Uint8Array).
|
||||
const privateKeyBin = hexToBin(privateKeyHex);
|
||||
const privateKeyBin = Bytes.fromHex(privateKeyHex).toBytes();
|
||||
|
||||
// Create a Private Key Entity from the binary.
|
||||
return new PrivateKey(privateKeyBin);
|
||||
return new this(privateKeyBin);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,7 +133,7 @@ export class PrivateKey {
|
||||
}
|
||||
|
||||
// Return a new Private Key entity.
|
||||
return new PrivateKey(decodeResult.privateKey);
|
||||
return new this(decodeResult.privateKey);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,7 +157,7 @@ export class PrivateKey {
|
||||
public static generateRandom(): PrivateKey {
|
||||
const bytes = generatePrivateKey();
|
||||
|
||||
return new PrivateKey(bytes);
|
||||
return new this(bytes);
|
||||
}
|
||||
|
||||
public static isWIF(wif: string, removePrefixes = ['bitcoincash:', 'wif:']) {
|
||||
@@ -261,7 +252,7 @@ export class PrivateKey {
|
||||
*/
|
||||
public signMessageRecoverableCompact(message: Uint8Array | string) {
|
||||
if (typeof message === 'string') {
|
||||
message = utf8ToBin(message);
|
||||
message = Bytes.fromUtf8(message).toBytes();
|
||||
}
|
||||
|
||||
const messageHash = sha256.hash(message);
|
||||
@@ -281,7 +272,7 @@ export class PrivateKey {
|
||||
*/
|
||||
public signMessageCompact(message: Uint8Array | string) {
|
||||
if (typeof message === 'string') {
|
||||
message = utf8ToBin(message);
|
||||
message = Bytes.fromUtf8(message).toBytes();
|
||||
}
|
||||
|
||||
const messageHash = sha256.hash(message);
|
||||
@@ -301,7 +292,7 @@ export class PrivateKey {
|
||||
*/
|
||||
public signMessageSchnorr(message: Uint8Array | string) {
|
||||
if (typeof message === 'string') {
|
||||
message = utf8ToBin(message);
|
||||
message = Bytes.fromUtf8(message).toBytes();
|
||||
}
|
||||
|
||||
const messageHash = sha256.hash(message);
|
||||
@@ -321,7 +312,7 @@ export class PrivateKey {
|
||||
*/
|
||||
public signMessageDER(message: Uint8Array | string) {
|
||||
if (typeof message === 'string') {
|
||||
message = utf8ToBin(message);
|
||||
message = Bytes.fromUtf8(message).toBytes();
|
||||
}
|
||||
|
||||
const messageHash = sha256.hash(message);
|
||||
@@ -344,8 +335,10 @@ export class PrivateKey {
|
||||
*/
|
||||
public signMessageElectron(message: string): Uint8Array {
|
||||
// Compile the message.
|
||||
const magicBytes = utf8ToBin('\x18Bitcoin Signed Message:\n');
|
||||
const messageBytes = utf8ToBin(message);
|
||||
const magicBytes = Bytes.fromUtf8(
|
||||
'\x18Bitcoin Signed Message:\n',
|
||||
).toBytes();
|
||||
const messageBytes = Bytes.fromUtf8(message).toBytes();
|
||||
const messageLengthBytes = bigIntToCompactUint(BigInt(messageBytes.length)); // hexToBin(messageBytes.length.toString(16)); //
|
||||
const messageFinal = new Uint8Array([
|
||||
...magicBytes,
|
||||
@@ -385,7 +378,11 @@ export class PrivateKey {
|
||||
// If a string was given, convert it from hex to bytes.
|
||||
// TODO: Consider using Bytes class - it ensures valid hex.
|
||||
if (typeof messageHash === 'string') {
|
||||
messageHash = hexToBin(messageHash);
|
||||
messageHash = Bytes.fromHex(messageHash).toBytes();
|
||||
}
|
||||
|
||||
if (messageHash.length !== 32) {
|
||||
throw new Error('messageHash must be a hash of length 32 bytes');
|
||||
}
|
||||
|
||||
// Attempt to sign the message.
|
||||
@@ -416,7 +413,11 @@ export class PrivateKey {
|
||||
// If a string was given, convert it from hex to bytes.
|
||||
// TODO: Consider using Bytes class - it ensures valid hex.
|
||||
if (typeof messageHash === 'string') {
|
||||
messageHash = hexToBin(messageHash);
|
||||
messageHash = Bytes.fromHex(messageHash).toBytes();
|
||||
}
|
||||
|
||||
if (messageHash.length !== 32) {
|
||||
throw new Error('messageHash must be a hash of length 32 bytes');
|
||||
}
|
||||
|
||||
// Attempt to sign the message.
|
||||
@@ -447,7 +448,11 @@ export class PrivateKey {
|
||||
// If a string was given, convert it from hex to bytes.
|
||||
// TODO: Consider using Bytes class - it ensures valid hex.
|
||||
if (typeof messageHash === 'string') {
|
||||
messageHash = hexToBin(messageHash);
|
||||
messageHash = Bytes.fromHex(messageHash).toBytes();
|
||||
}
|
||||
|
||||
if (messageHash.length !== 32) {
|
||||
throw new Error('messageHash must be a hash of length 32 bytes');
|
||||
}
|
||||
|
||||
// Attempt to sign the message.
|
||||
@@ -478,7 +483,11 @@ export class PrivateKey {
|
||||
// If a string was given, convert it from hex to bytes.
|
||||
// TODO: Consider using Bytes class - it ensures valid hex.
|
||||
if (typeof messageHash === 'string') {
|
||||
messageHash = hexToBin(messageHash);
|
||||
messageHash = Bytes.fromHex(messageHash).toBytes();
|
||||
}
|
||||
|
||||
if (messageHash.length !== 32) {
|
||||
throw new Error('messageHash must be a hash of length 32 bytes');
|
||||
}
|
||||
|
||||
const signResult = secp256k1.signMessageHashDER(this.bytes, messageHash);
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
*/
|
||||
export class PublicKey {
|
||||
// The raw bytes representing the Public Key.
|
||||
public readonly bytes: Uint8Array;
|
||||
protected readonly bytes: Uint8Array;
|
||||
|
||||
/**
|
||||
* Construct a new Public Key.
|
||||
@@ -37,8 +37,8 @@ export class PublicKey {
|
||||
*/
|
||||
public static from(publicKey: Uint8Array | string) {
|
||||
return publicKey instanceof Uint8Array
|
||||
? PublicKey.fromBytes(publicKey)
|
||||
: PublicKey.fromHex(publicKey);
|
||||
? this.fromBytes(publicKey)
|
||||
: this.fromHex(publicKey);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,7 +56,7 @@ export class PublicKey {
|
||||
throw new Error(`Invalid Public Key.`);
|
||||
}
|
||||
|
||||
return new PublicKey(publicKeyBytes);
|
||||
return new this(publicKeyBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,7 +80,7 @@ export class PublicKey {
|
||||
const publicKey = hexToBin(publicKeyHex);
|
||||
|
||||
// Create a Public Key Entity from the binary.
|
||||
return new PublicKey(publicKey);
|
||||
return new this(publicKey);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,7 @@ export type BCHUnits = ['sats', 'bits', 'mBCH', 'BCH'];
|
||||
* Satoshis Primitive
|
||||
*/
|
||||
export class Satoshis {
|
||||
public readonly satoshis: bigint;
|
||||
protected readonly satoshis: bigint;
|
||||
|
||||
/**
|
||||
* Construct a new instance of Satoshis.
|
||||
@@ -26,7 +26,7 @@ export class Satoshis {
|
||||
* @returns {Satoshis} New instance of Satoshis.
|
||||
*/
|
||||
public static fromSats(satoshis: bigint | number): Satoshis {
|
||||
return new Satoshis(satoshis);
|
||||
return new this(satoshis);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,7 +39,7 @@ export class Satoshis {
|
||||
* @returns {Satoshis} New instance of Satoshis.
|
||||
*/
|
||||
public static fromSatoshis(satoshis: bigint | number): Satoshis {
|
||||
return new Satoshis(satoshis);
|
||||
return new this(satoshis);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,7 +52,7 @@ export class Satoshis {
|
||||
public static fromBits(bits: number): Satoshis {
|
||||
const satoshis = Satoshis.roundToDigits(bits * 100, 0);
|
||||
|
||||
return new Satoshis(satoshis);
|
||||
return new this(satoshis);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,7 +65,7 @@ export class Satoshis {
|
||||
public static fromMBCH(mBCH: number): Satoshis {
|
||||
const satoshis = Satoshis.roundToDigits(mBCH * 100_000, 0);
|
||||
|
||||
return new Satoshis(satoshis);
|
||||
return new this(satoshis);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,7 +78,7 @@ export class Satoshis {
|
||||
public static fromBCH(bch: number): Satoshis {
|
||||
const satoshis = Satoshis.roundToDigits(bch * 100_000_000, 0);
|
||||
|
||||
return new Satoshis(satoshis);
|
||||
return new this(satoshis);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
* Script Entity.
|
||||
*/
|
||||
export class Script {
|
||||
public readonly bytes: Uint8Array;
|
||||
protected readonly bytes: Uint8Array;
|
||||
|
||||
/**
|
||||
* Construct a new Script
|
||||
@@ -32,8 +32,8 @@ export class Script {
|
||||
*/
|
||||
public static from(script: Uint8Array | string) {
|
||||
return script instanceof Uint8Array
|
||||
? Script.fromBytes(script)
|
||||
: Script.fromHex(script);
|
||||
? this.fromBytes(script)
|
||||
: this.fromHex(script);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,7 +46,7 @@ export class Script {
|
||||
* @returns {Script} The created Script Entity.
|
||||
*/
|
||||
public static fromBytes(bytes: Uint8Array): Script {
|
||||
return new Script(bytes);
|
||||
return new this(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,7 +73,7 @@ export class Script {
|
||||
}
|
||||
|
||||
// Return new Script Entity from the assembled bytecode.
|
||||
return new Script(assembleResult.bytecode);
|
||||
return new this(assembleResult.bytecode);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,7 +95,7 @@ export class Script {
|
||||
const scriptBin = hexToBin(hex);
|
||||
|
||||
// Return new Script entity constructed from the binary.
|
||||
return new Script(scriptBin);
|
||||
return new this(scriptBin);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,7 @@ import { binToHex, hexToBin, hashTransaction, isHex } from '@bitauth/libauth';
|
||||
* Transaction Hash Primitive.
|
||||
*/
|
||||
export class TransactionHash {
|
||||
public readonly bytes: Uint8Array;
|
||||
protected readonly bytes: Uint8Array;
|
||||
|
||||
/**
|
||||
* Instantiates TransactionHash from a Transaction Hash's bytes.
|
||||
@@ -26,8 +26,8 @@ export class TransactionHash {
|
||||
*/
|
||||
public static from(hash: Uint8Array | string) {
|
||||
return hash instanceof Uint8Array
|
||||
? TransactionHash.fromBytes(hash)
|
||||
: TransactionHash.fromHex(hash);
|
||||
? this.fromBytes(hash)
|
||||
: this.fromHex(hash);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,7 +47,7 @@ export class TransactionHash {
|
||||
);
|
||||
}
|
||||
|
||||
return new TransactionHash(bytes);
|
||||
return new this(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,8 +80,8 @@ export class TransactionHash {
|
||||
*/
|
||||
public static fromTransaction(transaction: Uint8Array | string) {
|
||||
return transaction instanceof Uint8Array
|
||||
? TransactionHash.fromTransactionBytes(transaction)
|
||||
: TransactionHash.fromTransactionHex(transaction);
|
||||
? this.fromTransactionBytes(transaction)
|
||||
: this.fromTransactionHex(transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,7 +96,7 @@ export class TransactionHash {
|
||||
): TransactionHash {
|
||||
const transactionHash = hashTransaction(transactionBytes);
|
||||
|
||||
return new TransactionHash(hexToBin(transactionHash));
|
||||
return new this(hexToBin(transactionHash));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,7 +115,7 @@ export class TransactionHash {
|
||||
|
||||
const bytes = hexToBin(transactionHex);
|
||||
|
||||
return TransactionHash.fromTransactionBytes(bytes);
|
||||
return this.fromTransactionBytes(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,8 +29,8 @@ export class Transaction {
|
||||
*/
|
||||
public static from(transaction: Uint8Array | string) {
|
||||
return transaction instanceof Uint8Array
|
||||
? Transaction.fromBytes(transaction)
|
||||
: Transaction.fromHex(transaction);
|
||||
? this.fromBytes(transaction)
|
||||
: this.fromHex(transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,7 +52,7 @@ export class Transaction {
|
||||
}
|
||||
|
||||
// Return a new instance of the Transaction Primitive created from the decode result.
|
||||
return new Transaction(decodeResult);
|
||||
return new this(decodeResult);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,7 +74,7 @@ export class Transaction {
|
||||
const bytes = hexToBin(hex);
|
||||
|
||||
// Return the transaction constructed from our bytes.
|
||||
return Transaction.fromBytes(bytes);
|
||||
return this.fromBytes(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,7 +99,7 @@ export class Transaction {
|
||||
*/
|
||||
public static isValid(transaction: Uint8Array | string): boolean {
|
||||
try {
|
||||
Transaction.from(transaction);
|
||||
this.from(transaction);
|
||||
} catch (_error) {
|
||||
return false;
|
||||
}
|
||||
@@ -159,35 +159,6 @@ export class Transaction {
|
||||
return { ...this.transaction };
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this transaction is a Coinbase Transaction.
|
||||
*
|
||||
* @remarks UNTESTED
|
||||
*
|
||||
* @experimental
|
||||
*
|
||||
* @returns True if this is a Coinbase Transaction
|
||||
*/
|
||||
public isCoinbase(): boolean {
|
||||
// A coinbase transaction MUST only have one input
|
||||
if (this.getInputs().length !== 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const input = this.getInputs()[0];
|
||||
|
||||
// Check if the outpoint transaction hash is all zeros (32 bytes of 0x00)
|
||||
const isOutpointZero = input.outpointTransactionHash.every(
|
||||
(byte) => byte === 0x00,
|
||||
);
|
||||
|
||||
// Check if the outpoint index is 0xFFFFFFFF (or -1 in signed 32-bit integer representation)
|
||||
const isOutpointIndexMax = input.outpointIndex === 0xffffffff;
|
||||
|
||||
// Both conditions must be true for a coinbase transaction
|
||||
return isOutpointZero && isOutpointIndexMax;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the version for this transaction.
|
||||
*
|
||||
@@ -231,4 +202,33 @@ export class Transaction {
|
||||
public getLocktime() {
|
||||
return this.transaction.locktime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this transaction is a Coinbase Transaction.
|
||||
*
|
||||
* @remarks UNTESTED
|
||||
*
|
||||
* @experimental
|
||||
*
|
||||
* @returns True if this is a Coinbase Transaction
|
||||
*/
|
||||
public isCoinbase(): boolean {
|
||||
// A coinbase transaction MUST only have one input
|
||||
if (this.getInputs().length !== 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const input = this.getInputs()[0];
|
||||
|
||||
// Check if the outpoint transaction hash is all zeros (32 bytes of 0x00)
|
||||
const isOutpointZero = input.outpointTransactionHash.every(
|
||||
(byte) => byte === 0x00,
|
||||
);
|
||||
|
||||
// Check if the outpoint index is 0xFFFFFFFF (or -1 in signed 32-bit integer representation)
|
||||
const isOutpointIndexMax = input.outpointIndex === 0xffffffff;
|
||||
|
||||
// Both conditions must be true for a coinbase transaction
|
||||
return isOutpointZero && isOutpointIndexMax;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user