146 lines
3.6 KiB
TypeScript
146 lines
3.6 KiB
TypeScript
import {
|
|
assembleBytecodeBCH,
|
|
disassembleBytecodeBCH,
|
|
base58AddressToLockingBytecode,
|
|
cashAddressToLockingBytecode,
|
|
binToHex,
|
|
hexToBin,
|
|
isHex,
|
|
} from '@bitauth/libauth';
|
|
|
|
/**
|
|
* Script Entity.
|
|
*/
|
|
export class Script {
|
|
public readonly bytes: Uint8Array;
|
|
|
|
/**
|
|
* Construct a new Script
|
|
*
|
|
* @param bytes {Uint8Array} The raw bytes of the Script.
|
|
*/
|
|
constructor(bytes: Uint8Array) {
|
|
this.bytes = bytes;
|
|
}
|
|
|
|
/**
|
|
* Create a Script Entity from the given Assembly String.
|
|
*
|
|
* @param asm {string} String of assembly code.
|
|
*
|
|
* @throws {Error} If script cannot be decoded.
|
|
*
|
|
* @returns {Script} The created Script Entity.
|
|
*/
|
|
public static fromASM(asm: string): Script {
|
|
// Attempt to convert the given ASM to bytecode.
|
|
const assembleResult = assembleBytecodeBCH(asm);
|
|
|
|
// If a string is returned, this indicates an error...
|
|
if (typeof assembleResult === 'string') {
|
|
throw new Error(assembleResult);
|
|
}
|
|
|
|
// If the success flag is not marked, this indicates an error...
|
|
if (!assembleResult.success) {
|
|
throw new Error('Could not assemble bytecode from assembly.');
|
|
}
|
|
|
|
// Return new Script Entity from the assembled bytecode.
|
|
return new Script(assembleResult.bytecode);
|
|
}
|
|
|
|
/**
|
|
* Create a Script Entity from the given bytes (as hexadecimal string).
|
|
*
|
|
* @param hex {string} Raw script bytes encoded as hexadecimal.
|
|
*
|
|
* @throws {Error} If script cannot be decoded.
|
|
*
|
|
* @returns {Script} The created Script Entity.
|
|
*/
|
|
public static fromHex(hex: string): Script {
|
|
// Ensure that the given string is hex.
|
|
if (!isHex(hex)) {
|
|
throw new Error(`The given string (${hex}) is not valid hexadecimal.`);
|
|
}
|
|
|
|
// Conver the given hex to binary (Uint8Array).
|
|
const scriptBin = hexToBin(hex);
|
|
|
|
// Return new Script entity constructed from the binary.
|
|
return new Script(scriptBin);
|
|
}
|
|
|
|
/**
|
|
* Create a Script Entity from the given CashAddr.
|
|
*
|
|
* @param cashAddr {string} The Address in CashAddr format.
|
|
*
|
|
* @throws {Error} If address cannot be decoded.
|
|
*
|
|
* @returns {Script} The created Script Entity.
|
|
*/
|
|
public static fromCashAddr(cashAddr: string): Script {
|
|
const decodeResult = cashAddressToLockingBytecode(cashAddr);
|
|
|
|
if (typeof decodeResult === 'string') {
|
|
throw new Error(decodeResult);
|
|
}
|
|
|
|
return new Script(decodeResult.bytecode);
|
|
}
|
|
|
|
/**
|
|
* Create a Script Entity from the given Legacy Address.
|
|
*
|
|
* @param legacyAddress {string} The Address in Legacy format.
|
|
*
|
|
* @throws {Error} If address cannot be decoded.
|
|
*
|
|
* @returns {Script} The created Script Entity.
|
|
*/
|
|
public static fromLegacyAddress(legacyAddress: string): Script {
|
|
const decodeResult = base58AddressToLockingBytecode(legacyAddress);
|
|
|
|
if (typeof decodeResult === 'string') {
|
|
throw new Error(decodeResult);
|
|
}
|
|
|
|
return new Script(decodeResult.bytecode);
|
|
}
|
|
|
|
/**
|
|
* Convert this script to a human-readable string of assembly.
|
|
*
|
|
* @returns {string} Human-readable assembly.
|
|
*/
|
|
public toASM(joinWith = '\n'): string {
|
|
const disassembledBytecode = disassembleBytecodeBCH(this.bytes);
|
|
|
|
if (joinWith) {
|
|
return disassembledBytecode.split(' ').join(joinWith);
|
|
}
|
|
|
|
return disassembledBytecode;
|
|
}
|
|
|
|
/**
|
|
* Get the raw bytecode for this script.
|
|
*
|
|
* @returns {Uint8Array} The compiled bytes.
|
|
*/
|
|
public toBytes(): Uint8Array {
|
|
return this.bytes;
|
|
}
|
|
|
|
/**
|
|
* Get the raw bytecode for this script as a hex string.
|
|
*
|
|
* @returns {string} The compiled bytes as a hex string.
|
|
*/
|
|
public toHex(): string {
|
|
return binToHex(this.bytes);
|
|
}
|
|
}
|