scryptlib
Version:
Javascript SDK for integration of Bitcoin SV Smart Contracts written in sCrypt language.
256 lines • 9.51 kB
JavaScript
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
;