diff --git a/packages/docs/src/tools/primitive-functions.ts b/packages/docs/src/tools/primitive-functions.ts index 158246e..2d0ab09 100644 --- a/packages/docs/src/tools/primitive-functions.ts +++ b/packages/docs/src/tools/primitive-functions.ts @@ -595,6 +595,15 @@ export const script = { models: [''], callback: (args: [string]) => Script.fromASM(...args), }, + { + label: 'From CashASM', + inputs: ['CashASM'], + models: [ + '// Script evaluations are also supported.\n<$(<"evaluateThisFirst"> OP_SHA256)> OP_SHA256', + ], + callback: (args: [string]) => Script.fromCashASM(...args), + extendedInput: true, + }, { label: 'From Hex', inputs: ['Hex'], diff --git a/packages/primitives/src/script.ts b/packages/primitives/src/script.ts index af85a0f..6d3497e 100644 --- a/packages/primitives/src/script.ts +++ b/packages/primitives/src/script.ts @@ -1,9 +1,11 @@ import { Bytes } from './bytes.js'; import { + type WalletTemplateVariable, assembleBytecodeBCH, disassembleBytecodeBCH, - compileCashAssembly, + createCompilerBCH, + stringify, } from '@bitauth/libauth'; /** @@ -113,20 +115,46 @@ export class Script { return new this(assembleResult.bytecode); } - // NOTE: In its current form, this is pretty useless because it does not allow OP_CODES. - // Disabling because it will probably just cause confusion. - /* - public static fromCashASM(cashASM: string) { - const result = compileCashAssembly(cashASM); + public static fromCashASM( + cashASM: string, + data?: Record, + ) { + // Create a BCH Compilation context. + const compiler = createCompilerBCH({ + scripts: { + // NOTE: We need to name the script, so we give it the name "_main". + _main: cashASM, + }, + variables: Object.keys(data || {}).reduce<{ + [name: string]: WalletTemplateVariable; + }>( + (acc, variableName: string) => { + acc[variableName] = { type: 'AddressData' }; + return acc; + }, + {}, // Initial value + ), + }); - if (typeof result === 'string') { - // TODO: Make error more detailed. - throw new Error(`Failed to parse CashASM: ${result}`); + // Attempt to compile the script called "main" + const compilationResult = compiler.generateBytecode({ + data: { + ...data, + }, + scriptId: '_main', + debug: true, + }); + + // If compilation failed... + if (!compilationResult.success) { + throw new Error( + `Failed to resolve CashASM: ${stringify(compilationResult)}`, + ); } - return new this(result); + // Return a new script instance containing the compiled bytecode. + return new Script(compilationResult.bytecode); } - */ /** * Create a Script Entity from the given bytes (as hexadecimal string).