Files
xo-stack/packages/primitives/src/script.ts
T
James Zuccon 2ac7af4069 Monorepo stuff
Signed-off-by: James Zuccon <zuccon@gmail.com>
2024-09-02 20:05:35 +10:00

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);
}
}