UNPKG

@harmoniclabs/plu-ts-onchain

Version:

An embedded DSL for Cardano smart contracts creation coupled with a library for Cardano transactions, all in Typescript

313 lines (312 loc) 15 kB
"use strict"; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.pappArgToTerm = void 0; var utils_1 = require("../type_system/utils.js"); var pfn_1 = require("./pfn.js"); var const_1 = require("./std/list/const/index.js"); var pPair_1 = require("./std/pair/pPair.js"); var pByteString_1 = require("./std/bs/pByteString.js"); var pStr_1 = require("./std/str/pStr.js"); var pBool_1 = require("./std/bool/pBool.js"); var pInt_1 = require("./std/int/pInt.js"); var pmakeUnit_1 = require("./std/unit/pmakeUnit.js"); var Term_1 = require("../Term/index.js"); var type_system_1 = require("../type_system/index.js"); var uint8array_utils_1 = require("@harmoniclabs/uint8array-utils"); var bytestring_1 = require("@harmoniclabs/bytestring"); var cbor_1 = require("@harmoniclabs/cbor"); var obj_utils_1 = require("@harmoniclabs/obj-utils"); var pair_1 = require("@harmoniclabs/pair"); var assert_1 = require("../../utils/assert.js"); var clearAsData_1 = require("../type_system/tyArgs/clearAsData.js"); function pappArgToTerm(arg, mustExtend) { if (mustExtend === void 0) { mustExtend = (0, type_system_1.tyVar)("pappArgToTerm_mustExtend_any"); } if (!(0, type_system_1.isWellFormedGenericType)(mustExtend)) { throw new Error("can't convert argument for `papp` to invalid type"); } // same of `arg instanceof Term` but typescript doesn't knows it // ( after `arg instanceof Term` typescript marked arg as `never` ) if (Term_1.Term.prototype.isPrototypeOf(arg)) { if (!(0, type_system_1.typeExtends)(arg.type, mustExtend)) { // TODO: add proper error throw new Error("pappArgToTerm :: `arg` was a term of type " + (0, utils_1.termTypeToString)(arg.type) + "; which doesn't extends expected `" + (0, utils_1.termTypeToString)(mustExtend) + "`"); } return arg; } // PUnit if (arg === undefined || arg === null) { if (!(0, type_system_1.typeExtends)(mustExtend, type_system_1.unit) || typeof mustExtend[0] === "symbol") { // TODO: add proper error throw new Error("pappArgToTerm :: `arg` was `undefined` (a possible `unit`); which doesn't extends expected type `" + (0, utils_1.termTypeToString)(mustExtend) + "`"); } return (0, pmakeUnit_1.pmakeUnit)(); } // PInt if (typeof arg === "number" || typeof arg === "bigint") { if (!(0, type_system_1.typeExtends)(type_system_1.int, mustExtend)) { // TODO: add proper error throw new Error("pappArgToTerm :: `arg` was a possible `int`; which doesn't extends expected type " + (0, utils_1.termTypeToString)(mustExtend)); } return (0, pInt_1.pInt)(arg); } // PBool if (typeof arg === "boolean") { if (!(0, type_system_1.typeExtends)(type_system_1.bool, mustExtend)) { // TODO: add proper error throw new Error("pappArgToTerm :: `arg` was a possible `bool`; which doesn't extends expected type " + (0, utils_1.termTypeToString)(mustExtend)); } return (0, pBool_1.pBool)(arg); } // PStr if (typeof arg === "string") { // if must extend any if ((0, type_system_1.isTypeParam)(mustExtend)) { // first try ByteStrings if (bytestring_1.ByteString.isValidHexValue(arg) && arg.length % 2 === 0) { return (0, pByteString_1.pByteString)((0, uint8array_utils_1.fromHex)(arg)); } // otherwise return plain string return (0, pStr_1.pStr)(arg); } // if must be a bytestring if ((0, type_system_1.typeExtends)(mustExtend, type_system_1.bs)) { // first tries plain hex if (bytestring_1.ByteString.isValidHexValue(arg) && arg.length % 2 === 0) { return (0, pByteString_1.pByteString)((0, uint8array_utils_1.fromHex)(arg)); } // otherwise interpret as ascii return (0, pByteString_1.pByteString)(bytestring_1.ByteString.fromAscii(arg)); } // if must be a string if ((0, type_system_1.typeExtends)(mustExtend, type_system_1.str)) { return (0, pStr_1.pStr)(arg); } // TODO: add proper error throw new Error("pappArgToTerm :: `arg` was a possible `str` or `bs`; which doesn't extends expected type " + (0, utils_1.termTypeToString)(mustExtend)); } // PByteString if ((0, uint8array_utils_1.isUint8Array)(arg) || arg instanceof Uint8Array || arg instanceof ArrayBuffer || (arg instanceof bytestring_1.ByteString && !(arg instanceof cbor_1.CborString))) { if (!(0, type_system_1.typeExtends)(type_system_1.bs, mustExtend)) { // TODO: add proper error throw new Error("pappArgToTerm :: `arg` was a possible `bs`; which doesn't extends expected type " + (0, utils_1.termTypeToString)(mustExtend)); } if (arg instanceof bytestring_1.ByteString) { return (0, pByteString_1.pByteString)(arg); } return (0, pByteString_1.pByteString)((0, uint8array_utils_1.isUint8Array)(arg) ? arg : new Uint8Array(arg)); } // PLam if (typeof arg === "function") { var funcNArgs = arg.length; if ( // if must extend any (0, type_system_1.isTypeParam)(mustExtend) || // or must extend something different than a function mustExtend[0] !== type_system_1.PrimType.Lambda || // or missing args funcNArgs <= 0) { throw new Error("pappArgToTerm :: `arg` was a possible `lam` or `fn`; however it was not possible to check the type"); } ; var nLambdaArgs = (0, utils_1.getNRequiredLambdaArgs)(mustExtend); if (!(funcNArgs <= nLambdaArgs)) throw new Error("can't convert a ts function expecting ".concat(funcNArgs, " arguments ") + "to a plu-ts function that requires ".concat(nLambdaArgs, " arguments; ") + "expected lambda type was: ".concat((0, utils_1.termTypeToString)(mustExtend))); var outTy = mustExtend; var fnInputsTys = []; for (var i = 0; i < funcNArgs; i++) { if (outTy[0] !== type_system_1.PrimType.Lambda) { throw new Error("unexpected `outTy` while constructing `pfn`; " + "only ".concat(fnInputsTys.length, " inputs out of ").concat(funcNArgs, " expected where collected") + "`outTy`: ".concat((0, utils_1.termTypeToString)(outTy), "; ") + "`inputsTypes`:".concat(fnInputsTys.map(utils_1.termTypeToString)) + "target function type: ".concat((0, utils_1.termTypeToString)(mustExtend))); } fnInputsTys.push(outTy[1]); outTy = outTy[2]; } return (0, pfn_1.pfn)(fnInputsTys, outTy)(arg); } if (Array.isArray(arg)) { if (!(arg.every(function (elem) { return elem instanceof Term_1.Term ? elem.isConstant === true : true; }))) throw new Error("pappArgToTerm :: `arg` was a possible `list` or `pair`; " + "however not all the elments of the array where constants; " + "plu-ts is only able to automatically trasform constant values"); // if must extend any if ((0, type_system_1.isTypeParam)(mustExtend)) { if (arg.length === 2) // might be pair { var _a = __read(arg, 2), fst = _a[0], snd = _a[1]; var fstT = tryGetConstantableType(fst); var sndT = tryGetConstantableType(snd); return (0, pPair_1.pPair)(fstT, sndT)(pappArgToTerm(fst, fstT), pappArgToTerm(snd, sndT)); } // try list var elemsT_1 = tryInferElemsT(arg); return (0, const_1.pList)(elemsT_1)(arg.map(function (elem) { return pappArgToTerm(elem, elemsT_1); })); } if (mustExtend[0] === type_system_1.PrimType.Pair) { if (arg.length !== 2) throw new Error("an array that doesn't have exactly two elements can't be converted to pair"); var _b = __read(arg, 2), fst = _b[0], snd = _b[1]; var fstT = (0, type_system_1.isWellFormedType)(mustExtend[1]) ? mustExtend[1] : tryGetConstantableType(fst); var sndT = (0, type_system_1.isWellFormedType)(mustExtend[2]) ? mustExtend[2] : tryGetConstantableType(snd); // maybe ???? fstT = (0, clearAsData_1.clearAsData)(fstT); sndT = (0, clearAsData_1.clearAsData)(sndT); return (0, pPair_1.pPair)(fstT, sndT)(pappArgToTerm(fst, fstT), pappArgToTerm(snd, sndT)); } if (mustExtend[0] === type_system_1.PrimType.List) { var elemsT_2 = (0, type_system_1.isWellFormedType)(mustExtend[1]) ? mustExtend[1] : tryInferElemsT(arg); return (0, const_1.pList)(elemsT_2)(arg.map(function (elem) { return pappArgToTerm(elem, elemsT_2); })); } } if (arg instanceof pair_1.Pair || (0, obj_utils_1.has_n_determined_keys)(arg, 2, "fst", "snd")) { var _c = (arg instanceof pair_1.Pair ? { fst: arg.fst, snd: arg.snd } : arg), fst = _c.fst, snd = _c.snd; //if must extend any if ((0, type_system_1.isTypeParam)(mustExtend)) { var fstT = tryGetConstantableType(fst); var sndT = tryGetConstantableType(snd); return (0, pPair_1.pPair)(fstT, sndT)(pappArgToTerm(fst, fstT), pappArgToTerm(snd, sndT)); } if (mustExtend[0] === type_system_1.PrimType.Pair) { var fstT = (0, type_system_1.isWellFormedType)(mustExtend[1]) ? mustExtend[1] : tryGetConstantableType(fst); var sndT = (0, type_system_1.isWellFormedType)(mustExtend[2]) ? mustExtend[2] : tryGetConstantableType(snd); return (0, pPair_1.pPair)(fstT, sndT)(pappArgToTerm(fst, fstT), pappArgToTerm(snd, sndT)); } } console.error(arg, arg.type); throw new Error("pappArgToTerm :: it was not possible to transform `arg` to a plu-ts value" + "; `arg` was " + arg + "; `mustExtend` plu-ts type was: " + (0, utils_1.termTypeToString)(mustExtend)); } exports.pappArgToTerm = pappArgToTerm; function getPossiblePlutsTypesOf(value) { if (Term_1.Term.prototype.isPrototypeOf(value)) { return [value.type]; } if (value === undefined || value === null) return [type_system_1.unit]; if (typeof value === "number" || typeof value === "bigint") return [type_system_1.int]; if (typeof value === "boolean") return [type_system_1.bool]; if ( // hex string case covered below (0, uint8array_utils_1.isUint8Array)(value) || value instanceof Uint8Array || value instanceof ArrayBuffer) return [type_system_1.bs]; if (typeof value === "function" && value.length !== 0) { return [ (0, type_system_1.fn)((new Array(value.length)) .map(function (_, i) { return (0, type_system_1.tyVar)("arg_" + i); }), (0, type_system_1.tyVar)("fn_output")) ]; } var types = []; if (typeof value === "string") { types.push(type_system_1.str); // normal strings also can be byetstrings (ascii) if specified // // if( ByteString.isValidHexValue( value ) && (value as string).length % 2 === 0 ) types.push(type_system_1.bs); return types; } return types; } function tryGetConstantableType(someValue) { var tys = getPossiblePlutsTypesOf(someValue); if (tys.length !== 1) throw new Error("pappArgToTerm :: `arg` type was ambigous; try to specify a plu-ts type"); var t = tys[0]; if (!(0, type_system_1.isWellFormedType)(t)) throw new Error("inferred type was not constantable: type: " + (0, utils_1.termTypeToString)(t)); return t; } function tryInferElemsT(arg) { if (arg.length === 0) throw new Error("it was not possible to infer the type of the element of a possible plu-ts `list`; try to specify a type"); var elemsT = undefined; var inferrefOptions; for (var i = 0; i < arg.length; i++) { inferrefOptions = getPossiblePlutsTypesOf(arg[i]); if (inferrefOptions.length === 1) { elemsT = inferrefOptions[0]; break; } } ; if (elemsT === undefined) throw new Error("elements type of a possible plu-ts `list` was ambigous; try to specify a type"); if (!(0, type_system_1.isWellFormedType)(elemsT)) throw new Error("inferred type was not constantable: type: " + (0, utils_1.termTypeToString)(elemsT)); (0, assert_1.assert)(arg.every(function (elem) { // @ts-ignore Type instantiation is excessively deep and possibly infinite. return isTsValueAssignableToPlutsType(elem, elemsT); }), "types in the array where incongruent; expected type was: " + (0, utils_1.termTypeToString)((0, type_system_1.list)(elemsT))); return elemsT; } function isTsValueAssignableToPlutsType(value, plutsType) { if (!(0, type_system_1.isWellFormedType)(plutsType)) return false; // same of `value instanceof Term` but typescript doesn't knows it // ( after `value instanceof Term` typescript marked arg as `never` ) if (Term_1.Term.prototype.isPrototypeOf(value)) { return (0, type_system_1.typeExtends)(value.type, plutsType); } if ((0, type_system_1.typeExtends)(plutsType, type_system_1.int)) { return (typeof value === "number" || typeof value === "bigint"); } if ((0, type_system_1.typeExtends)(plutsType, type_system_1.unit)) { return (value === undefined || value === null); } if ((0, type_system_1.typeExtends)(plutsType, type_system_1.bool)) { return typeof value === "boolean"; } if ((0, type_system_1.typeExtends)(plutsType, type_system_1.bs)) { return ((typeof value === "string" && bytestring_1.ByteString.isValidHexValue(value) && value.length % 2 === 0) || (0, uint8array_utils_1.isUint8Array)(value) || value instanceof Uint8Array || value instanceof ArrayBuffer); } return false; }