scryptlib
Version:
Javascript SDK for integration of Bitcoin SV Smart Contracts written in sCrypt language.
230 lines • 9.37 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.deserializeArgfromHex = exports.createArray = exports.createLibrary = exports.createStruct = exports.deserializer = exports.hex2bytes = exports.hex2bool = exports.hex2int = void 0;
const _1 = require(".");
const scryptTypes_1 = require("./scryptTypes");
const stateful_1 = require("./stateful");
const utils_1 = require("./utils");
/**
* little-endian signed magnitude to int
*/
function hex2int(hex) {
if (hex === '00') {
return (0, scryptTypes_1.Int)(0);
}
else if (hex === '4f') {
return (0, scryptTypes_1.Int)(-1);
}
else {
const b = utils_1.bsv.Script.fromHex(hex);
const chuck = b.chunks[0];
if (chuck.opcodenum >= 81 && chuck.opcodenum <= 96) {
return BigInt(chuck.opcodenum - 80);
}
return (0, _1.bin2num)(chuck.buf.toString('hex'));
}
}
exports.hex2int = hex2int;
function hex2bool(hex) {
if (hex === '51') {
return true;
}
else if (hex === '00') {
return false;
}
throw new Error(`invalid hex ${hex}`);
}
exports.hex2bool = hex2bool;
function hex2bytes(hex) {
if (hex === '00') {
return '';
}
const s = utils_1.bsv.Script.fromHex(hex);
const chuck = s.chunks[0];
if (chuck.opcodenum >= 81 && chuck.opcodenum <= 96) {
return Buffer.from([chuck.opcodenum - 80]).toString('hex');
}
return chuck.buf.toString('hex');
}
exports.hex2bytes = hex2bytes;
function deserializer(type, hex) {
switch (type) {
case scryptTypes_1.ScryptType.BOOL:
return (0, scryptTypes_1.Bool)(hex2bool(hex));
case scryptTypes_1.ScryptType.INT:
return (0, scryptTypes_1.Int)(hex2int(hex));
case scryptTypes_1.ScryptType.BYTES:
return (0, scryptTypes_1.Bytes)(hex2bytes(hex));
case scryptTypes_1.ScryptType.PRIVKEY:
return (0, scryptTypes_1.PrivKey)(hex2int(hex));
case scryptTypes_1.ScryptType.PUBKEY:
return (0, scryptTypes_1.PubKey)(hex2bytes(hex));
case scryptTypes_1.ScryptType.SIG:
return (0, scryptTypes_1.Sig)(hex2bytes(hex));
case scryptTypes_1.ScryptType.RIPEMD160:
return (0, scryptTypes_1.Ripemd160)(hex2bytes(hex));
case scryptTypes_1.ScryptType.SHA1:
return (0, scryptTypes_1.Sha1)(hex2bytes(hex));
case scryptTypes_1.ScryptType.SHA256:
return (0, scryptTypes_1.Sha256)(hex2bytes(hex));
case scryptTypes_1.ScryptType.SIGHASHTYPE:
return (0, scryptTypes_1.SigHashType)(Number(hex2int(hex)));
case scryptTypes_1.ScryptType.SIGHASHPREIMAGE:
return (0, scryptTypes_1.SigHashPreimage)(hex2bytes(hex));
case scryptTypes_1.ScryptType.OPCODETYPE:
return (0, scryptTypes_1.OpCodeType)(hex2bytes(hex));
default:
throw new Error(`<${type}> cannot be cast to ScryptType, only sCrypt native types supported`);
}
}
exports.deserializer = deserializer;
function createStruct(resolver, param, opcodesMap, options) {
const structTypeInfo = resolver(param.type);
const entity = structTypeInfo.info;
const obj = Object.create({});
entity.params.forEach(p => {
const typeInfo = resolver(p.type);
if ((0, _1.isArrayType)(typeInfo.finalType)) {
Object.assign(obj, {
[p.name]: createArray(resolver, typeInfo.finalType, `${param.name}.${p.name}`, opcodesMap, options)
});
}
else if (typeInfo.symbolType === _1.SymbolType.Struct) {
Object.assign(obj, {
[p.name]: createStruct(resolver, { name: `${param.name}.${p.name}`, type: p.type }, opcodesMap, options)
});
}
else if (typeInfo.symbolType === _1.SymbolType.Library) {
Object.assign(obj, {
[p.name]: createLibrary(resolver, { name: `${param.name}.${p.name}`, type: p.type }, opcodesMap, options)
});
}
else {
if (options.state) {
Object.assign(obj, {
[p.name]: stateful_1.default.deserializer(typeInfo.finalType, opcodesMap.get(`<${param.name}.${p.name}>`))
});
}
else {
Object.assign(obj, {
[p.name]: deserializer(typeInfo.finalType, opcodesMap.get(`<${param.name}.${p.name}>`))
});
}
}
});
return obj;
}
exports.createStruct = createStruct;
function createLibrary(resolver, param, opcodesMap, options) {
const libraryTypeInfo = resolver(param.type);
const entity = libraryTypeInfo.info;
if (options.state) {
const properties = {};
entity.properties.forEach(p => {
const typeInfo = resolver(p.type);
if ((0, _1.isArrayType)(typeInfo.finalType)) {
Object.assign(properties, {
[p.name]: createArray(resolver, p.type, `${param.name}.${p.name}`, opcodesMap, options)
});
}
else if (typeInfo.symbolType === _1.SymbolType.Struct) {
Object.assign(properties, {
[p.name]: createStruct(resolver, { name: `${param.name}.${p.name}`, type: p.type }, opcodesMap, options)
});
}
else if (typeInfo.symbolType === _1.SymbolType.Library) {
Object.assign(properties, {
[p.name]: createLibrary(resolver, { name: `${param.name}.${p.name}`, type: p.type }, opcodesMap, options)
});
}
else {
Object.assign(properties, {
[p.name]: stateful_1.default.deserializer(typeInfo.finalType, opcodesMap.get(`<${param.name}.${p.name}>`))
});
}
});
return properties;
}
else {
return entity.params.map(p => {
const typeInfo = resolver(p.type);
if ((0, _1.isArrayType)(typeInfo.finalType)) {
return createArray(resolver, typeInfo.finalType, `${param.name}.${p.name}`, opcodesMap, options);
}
else if (typeInfo.symbolType === _1.SymbolType.Struct) {
return createStruct(resolver, { name: `${param.name}.${p.name}`, type: p.type }, opcodesMap, options);
}
else if (typeInfo.symbolType === _1.SymbolType.Library) {
return createLibrary(resolver, { name: `${param.name}.${p.name}`, type: p.type }, opcodesMap, options);
}
else {
return deserializer(typeInfo.finalType, opcodesMap.get(`<${param.name}.${p.name}>`));
}
});
}
}
exports.createLibrary = createLibrary;
function createArray(resolver, type, name, opcodesMap, options) {
const arrays = [];
const [elemTypeName, sizes] = (0, _1.arrayTypeAndSize)(type);
const arraylen = sizes[0];
if (sizes.length === 1) {
for (let index = 0; index < arraylen; index++) {
const typeInfo = resolver(elemTypeName);
if (typeInfo.symbolType === _1.SymbolType.Struct) {
arrays.push(createStruct(resolver, {
name: `${name}[${index}]`,
type: typeInfo.finalType
}, opcodesMap, options));
}
else if (typeInfo.symbolType === _1.SymbolType.Library) {
arrays.push(createLibrary(resolver, {
name: `${name}[${index}]`,
type: typeInfo.finalType
}, opcodesMap, options));
}
else {
if (options.state) {
arrays.push(stateful_1.default.deserializer(typeInfo.finalType, opcodesMap.get(`<${name}[${index}]>`)));
}
else {
arrays.push(deserializer(typeInfo.finalType, opcodesMap.get(`<${name}[${index}]>`)));
}
}
}
}
else {
for (let index = 0; index < arraylen; index++) {
const finalType = resolver(elemTypeName).finalType;
const subArrayType = [finalType, sizes.slice(1).map(size => `[${size}]`).join('')].join('');
arrays.push(createArray(resolver, subArrayType, `${name}[${index}]`, opcodesMap, options));
}
}
return arrays;
}
exports.createArray = createArray;
function deserializeArgfromHex(resolver, arg, opcodesMap, options) {
let value;
const typeInfo = resolver(arg.type);
if ((0, _1.isArrayType)(typeInfo.finalType)) {
value = createArray(resolver, arg.type, arg.name, opcodesMap, options);
}
else if (typeInfo.symbolType === _1.SymbolType.Struct) {
value = createStruct(resolver, arg, opcodesMap, options);
}
else if (typeInfo.symbolType === _1.SymbolType.Library) {
value = createLibrary(resolver, arg, opcodesMap, options);
}
else {
if (options.state) {
value = stateful_1.default.deserializer(arg.type, opcodesMap.get(`<${arg.name}>`));
}
else {
value = deserializer(arg.type, opcodesMap.get(`<${arg.name}>`));
}
}
arg.value = value;
return arg;
}
exports.deserializeArgfromHex = deserializeArgfromHex;
//# sourceMappingURL=deserializer.js.map
;