UNPKG

scryptlib

Version:

Javascript SDK for integration of Bitcoin SV Smart Contracts written in sCrypt language.

256 lines 9.51 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.readLaunchJson = exports.parseLiteral = exports.stringToBytes = exports.toJSON = exports.genLaunchConfigFile = void 0; const internal_1 = require("./internal"); const utils_1 = require("./utils"); const fs = require("fs"); const os_1 = require("os"); const path_1 = require("path"); function genLaunchConfigFile(resolver, constructorArgs, pubFuncArgs, pubFunc, name, program, txContext, asmArgs) { // some artifact without sourceMap will not have file property. if (!program) { return ''; } const debugConfig = { type: 'scrypt', request: 'launch', internalConsoleOptions: 'openOnSessionStart', name: name, program: program, constructorArgs: constructorArgs.map(a => toJSON(a, resolver)), pubFunc: pubFunc, pubFuncArgs: pubFuncArgs.map(a => toJSON(a, resolver)) }; const debugTxContext = {}; if (!(0, utils_1.isEmpty)(txContext)) { const inputIndex = txContext.inputIndex || 0; if (txContext.tx) { const inputSatoshis = txContext.inputSatoshis; Object.assign(debugTxContext, { hex: txContext.tx.toString(), inputIndex, inputSatoshis }); } if (txContext.opReturn) { Object.assign(debugTxContext, { opReturn: txContext.opReturn }); } else if (txContext.opReturnHex) { Object.assign(debugTxContext, { opReturnHex: txContext.opReturnHex }); } } if (!(0, utils_1.isEmpty)(asmArgs)) { Object.assign(debugConfig, { asmArgs: asmArgs }); } if (!(0, utils_1.isEmpty)(debugTxContext)) { Object.assign(debugConfig, { txContext: debugTxContext }); } const launch = { version: '0.2.0', configurations: [debugConfig] }; const jsonstr = JSON.stringify(launch, (key, value) => (typeof value === 'bigint' ? value.toString() : value // return everything else unchanged ), 2); if ((0, utils_1.isNode)()) { const filename = `${name}-launch.json`; const file = (0, path_1.join)(fs.mkdtempSync(`${(0, os_1.tmpdir)()}${path_1.sep}sCrypt.`), filename); fs.writeFileSync(file, jsonstr); return (0, utils_1.path2uri)(file); } else { console.error(`${pubFunc}() call fail, see launch.json`, jsonstr); } } exports.genLaunchConfigFile = genLaunchConfigFile; function toJSON(arg, resolver) { const typeInfo = resolver(arg.type); if ((0, utils_1.isArrayType)(typeInfo.finalType)) { const v = arg.value; /* eslint-disable @typescript-eslint/no-unused-vars */ const [_, arraySizes] = (0, internal_1.arrayTypeAndSize)(typeInfo.finalType); const subType = (0, internal_1.subArrayType)(typeInfo.finalType); return v.map((val, i) => toJSON({ name: `${arg.name}${(0, internal_1.subscript)(i, arraySizes)}`, type: subType, value: val }, resolver)); } else if (typeInfo.symbolType === internal_1.SymbolType.Library) { const l = []; const entity = (0, internal_1.deduceGenericLibrary)(arg, typeInfo.info, resolver); if (entity instanceof Error) { throw entity; } entity.params.forEach((p, i) => { l.push(toJSON({ name: p.name, type: p.type, value: arg.value[i] }, resolver)); }); return l; } else if (typeInfo.symbolType === internal_1.SymbolType.Struct) { const copy = {}; const entity = (0, internal_1.deduceGenericStruct)(arg, typeInfo.info, resolver); if (entity instanceof Error) { throw entity; } entity.params.forEach(p => { Object.assign(copy, { [p.name]: toJSON({ name: p.name, type: p.type, value: arg.value[p.name] }, resolver) }); }); return copy; } else if (typeInfo.symbolType === internal_1.SymbolType.ScryptType) { switch (typeInfo.finalType) { case internal_1.ScryptType.BOOL: return arg.value; case internal_1.ScryptType.INT: { if (arg.value >= BigInt(Number.MIN_SAFE_INTEGER) && arg.value <= BigInt(Number.MAX_SAFE_INTEGER)) { return Number(arg.value); } else { return arg.value.toString(); } } case internal_1.ScryptType.BYTES: { return `b'${arg.value.toString()}'`; } case internal_1.ScryptType.PRIVKEY: { return `PrivKey(${arg.value.toString()})`; } case internal_1.ScryptType.SIG: case internal_1.ScryptType.RIPEMD160: case internal_1.ScryptType.SHA1: case internal_1.ScryptType.SHA256: case internal_1.ScryptType.SIGHASHPREIMAGE: case internal_1.ScryptType.OPCODETYPE: case internal_1.ScryptType.SIGHASHTYPE: case internal_1.ScryptType.PUBKEY: { return `${typeInfo.finalType}(b'${arg.value.toString()}')`; } } } } exports.toJSON = toJSON; function stringToBytes(str) { const encoder = new TextEncoder(); const uint8array = encoder.encode(str); return (0, internal_1.getValidatedHexString)(Buffer.from(uint8array).toString('hex')); } exports.stringToBytes = stringToBytes; function parseLiteral(l, supportInt = false) { // bool if (l === 'false') { return [false, internal_1.ScryptType.BOOL]; } if (l === 'true') { return [true, internal_1.ScryptType.BOOL]; } if (supportInt) { // hex int let m = /^(0x[0-9a-fA-F]+)$/.exec(l); if (m) { return [BigInt(m[1]), internal_1.ScryptType.INT]; } // decimal int m = /^(-?\d+)$/.exec(l); if (m) { return [BigInt(m[1]), internal_1.ScryptType.INT]; } } else { const m = /^([\da-fA-F]*)$/.exec(l); if (m) { return [(0, internal_1.Bytes)(l), internal_1.ScryptType.BYTES]; } } // bytes // note: special handling of empty bytes b'' let m = /^b'([\da-fA-F]*)'$/.exec(l); if (m) { return [(0, internal_1.Bytes)(m[1]), internal_1.ScryptType.BYTES]; } // String m = /^"([\s\S]*)"$/.exec(l); if (m) { return [stringToBytes(m[1]), internal_1.ScryptType.BYTES]; } // PrivKey // 1) decimal int m = /^PrivKey\((-?\d+)\)$/.exec(l); if (m) { return [BigInt(m[1]), internal_1.ScryptType.PRIVKEY]; } // 2) hex int m = /^PrivKey\((0x[0-9a-fA-F]+)\)$/.exec(l); if (m) { return [BigInt(m[1]), internal_1.ScryptType.PRIVKEY]; } // PubKey m = /^PubKey\(b'([\da-fA-F]+)'\)$/.exec(l); if (m) { const value = (0, internal_1.getValidatedHexString)(m[1]); return [(0, internal_1.Bytes)(value), internal_1.ScryptType.PUBKEY]; } // Sig m = /^Sig\(b'([\da-fA-F]+)'\)$/.exec(l); if (m) { const value = (0, internal_1.getValidatedHexString)(m[1]); return [(0, internal_1.Bytes)(value), internal_1.ScryptType.SIG]; } // Ripemd160 m = /^Ripemd160\(b'([\da-fA-F]+)'\)$/.exec(l); if (m) { const value = (0, internal_1.getValidatedHexString)(m[1]); return [(0, internal_1.Bytes)(value), internal_1.ScryptType.RIPEMD160]; } // Sha1 m = /^Sha1\(b'([\da-fA-F]+)'\)$/.exec(l); if (m) { const value = (0, internal_1.getValidatedHexString)(m[1]); return [(0, internal_1.Bytes)(value), internal_1.ScryptType.SHA1]; } // Sha256 m = /^Sha256\(b'([\da-fA-F]+)'\)$/.exec(l); if (m) { const value = (0, internal_1.getValidatedHexString)(m[1]); return [(0, internal_1.Bytes)(value), internal_1.ScryptType.SHA256]; } // SigHashType m = /^SigHashType\(b'([\da-fA-F]+)'\)$/.exec(l); if (m) { const value = (0, internal_1.getValidatedHexString)(m[1]); return [(0, internal_1.Bytes)(value), internal_1.ScryptType.SIGHASHTYPE]; } // SigHashPreimage m = /^SigHashPreimage\(b'([\da-fA-F]+)'\)$/.exec(l); if (m) { const value = (0, internal_1.getValidatedHexString)(m[1]); return [(0, internal_1.Bytes)(value), internal_1.ScryptType.SIGHASHPREIMAGE]; } // OpCodeType m = /^OpCodeType\(b'([\da-fA-F]+)'\)$/.exec(l); if (m) { const value = (0, internal_1.getValidatedHexString)(m[1]); return [(0, internal_1.Bytes)(value), internal_1.ScryptType.OPCODETYPE]; } throw new Error(`<${l}> cannot be cast to ASM format, only sCrypt native types supported`); } exports.parseLiteral = parseLiteral; const LINKPATTERN = /(\[((!\[[^\]]*?\]\(\s*)([^\s()]+?)\s*\)\]|(?:\\\]|[^\]])*\])\(\s*)(([^\s()]|\([^\s()]*?\))+)\s*(".*?")?\)/g; function readLaunchJson(error) { for (const match of error.matchAll(LINKPATTERN)) { if (match[5] && match[5].startsWith('scryptlaunch')) { const file = match[5].replace(/scryptlaunch/, 'file'); return JSON.parse(fs.readFileSync((0, utils_1.uri2path)(file)).toString()); } } return undefined; } exports.readLaunchJson = readLaunchJson; //# sourceMappingURL=launchConfig.js.map