@harmoniclabs/plu-ts-onchain
Version:
An embedded DSL for Cardano smart contracts creation coupled with a library for Cardano transactions, all in Typescript
198 lines (197 loc) • 11.1 kB
JavaScript
;
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;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Precompiled = void 0;
var LitteralPurpose_1 = require("../LitteralPurpose.js");
var type_system_1 = require("../../type_system/index.js");
var getFnTypes_1 = require("./getFnTypes.js");
var uplc_1 = require("@harmoniclabs/uplc");
var plutus_machine_1 = require("@harmoniclabs/plutus-machine");
var conversion_1 = require("../../lib/std/data/conversion/index.js");
var cloneTermType_1 = require("../../type_system/cloneTermType.js");
var uint8array_utils_1 = require("@harmoniclabs/uint8array-utils");
var obj_utils_1 = require("@harmoniclabs/obj-utils");
var crypto_1 = require("@harmoniclabs/crypto");
var cbor_1 = require("@harmoniclabs/cbor");
var Precompiled = /** @class */ (function () {
function Precompiled(purpose, fullType, precompiled, pulutsVersion) {
if (pulutsVersion === void 0) { pulutsVersion = "PlutusScriptV2"; }
if (!(0, LitteralPurpose_1.isLitteralPurpose)(purpose))
throw new Error("invalid purpose passed to Precompiled constructor");
var tys = (0, getFnTypes_1.getFnTypes)(fullType);
var outT = tys[tys.length - 1][0];
if (!(outT === type_system_1.PrimType.Bool ||
outT === type_system_1.PrimType.Unit))
throw new Error("invalid return type for typed or untyped validator");
if ((purpose === "spend" && tys.length < 4) || tys.length < 3)
throw new Error("invalid term to precompile");
var paramsTys = purpose === "spend" ? tys.slice(0, tys.length - 4) : tys.slice(0, tys.length - 3);
var validatorArgs = purpose === "spend" ? tys.slice(tys.length - 4, tys.length - 1) : tys.slice(tys.length - 3, tys.length - 1);
var validatorType = (0, type_system_1.fn)(validatorArgs, [outT]);
var _hash = undefined;
var _getHash = function () {
if (!(_hash instanceof Uint8Array))
_hash = new Uint8Array((0, crypto_1.blake2b_224)(new Uint8Array(__spreadArray([
pulutsVersion === "PlutusScriptV2" ? 0x02 : 0x01
], __read(cbor_1.Cbor.encode(new cbor_1.CborBytes(precompiled)).toBuffer()), false))));
return Uint8Array.prototype.slice.call(_hash);
};
Object.defineProperties(this, {
params: {
get: function () { return paramsTys.map(cloneTermType_1.cloneTermType); },
set: function () { },
enumerable: true,
configurable: false
},
validatorType: {
get: function () { return (0, cloneTermType_1.cloneTermType)(validatorType); },
set: function () { },
enumerable: true,
configurable: false
},
outputType: {
get: function () { return [outT]; },
set: function () { },
enumerable: true,
configurable: false
},
precompiled: {
get: function () { return precompiled.slice(); },
set: function () { },
enumerable: true,
configurable: false
},
purpose: {
value: purpose,
writable: false,
enumerable: true,
configurable: false
},
hash: {
get: _getHash,
set: function () { },
enumerable: true,
configurable: false
}
});
Object.defineProperty(this, "apply", {
value: function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (paramsTys.length === 0)
return precompiled;
if (args.length < paramsTys.length)
throw new Error("required ".concat(paramsTys.length, " arguments in order to instantiate a precompiled script, but only ").concat(args.length, " where passed"));
var wrongTypeIdx = paramsTys.findIndex(function (t, i) { return !(0, type_system_1.typeExtends)(args[i].type, t); });
if (wrongTypeIdx >= 0)
throw new Error("parameter at position ".concat(wrongTypeIdx, " was expected to be of type: \"").concat((0, type_system_1.termTypeToString)(paramsTys[wrongTypeIdx]), "\" but was instead of type \"").concat((0, type_system_1.termTypeToString)(args[wrongTypeIdx].type), "\""));
var _a = uplc_1.UPLCDecoder.parse(precompiled), version = _a.version, body = _a.body;
for (var i = paramsTys.length - 1; i >= 0; i--) {
var theArg = args[i];
var theParamT = paramsTys[i];
while ((0, type_system_1.isTaggedAsAlias)(theParamT))
theParamT = (0, type_system_1.unwrapAlias)(theParamT);
var uplcArg = void 0;
if (theParamT[0] === type_system_1.PrimType.Lambda ||
theParamT[0] === type_system_1.PrimType.Delayed) {
uplcArg = theArg.toUPLC();
}
else {
uplcArg = plutus_machine_1.Machine.evalSimple(theArg);
if (!(uplcArg instanceof plutus_machine_1.CEKConst))
throw new Error("applied parameter did not evaluate to a constant");
uplcArg = new uplc_1.UPLCConst(uplcArg.type, uplcArg.value);
}
body = new uplc_1.Application(body, uplcArg);
}
if (outT === type_system_1.PrimType.Unit) // already untyped
{
return uplc_1.UPLCEncoder.compile(new uplc_1.UPLCProgram(version, body)).toBuffer().buffer;
}
// else typed validator
if (purpose === "spend") {
var _b = __read(tys.slice(tys.length - 4, tys.length - 1), 3), datumType = _b[0], redeemerType_1 = _b[1], ctxType_1 = _b[2];
var datumUplc = (0, type_system_1.typeExtends)(datumType, type_system_1.data) ?
new uplc_1.UPLCVar(2) :
new uplc_1.Application((0, conversion_1.ptoData)(datumType).toUPLC(), new uplc_1.UPLCVar(2));
var redeemerUplc_1 = (0, type_system_1.typeExtends)(redeemerType_1, type_system_1.data) ?
new uplc_1.UPLCVar(1) :
new uplc_1.Application((0, conversion_1.ptoData)(redeemerType_1).toUPLC(), new uplc_1.UPLCVar(1));
var ctxUplc_1 = (0, type_system_1.typeExtends)(ctxType_1, type_system_1.data) ?
new uplc_1.UPLCVar(0) :
new uplc_1.Application((0, conversion_1.ptoData)(ctxType_1).toUPLC(), new uplc_1.UPLCVar(0));
body =
new uplc_1.Lambda(// datum
new uplc_1.Lambda(//redeemer
new uplc_1.Lambda(// ctx
new uplc_1.Force(new uplc_1.Application(new uplc_1.Application(new uplc_1.Application(uplc_1.Builtin.ifThenElse, new uplc_1.Application(new uplc_1.Application(new uplc_1.Application(body, datumUplc), redeemerUplc_1), ctxUplc_1)), new uplc_1.Delay(uplc_1.UPLCConst.unit)), new uplc_1.Delay(new uplc_1.ErrorUPLC))))));
return uplc_1.UPLCEncoder.compile(new uplc_1.UPLCProgram(version, body)).toBuffer().buffer;
}
// else redeemer validator
var _c = __read(tys.slice(tys.length - 3, tys.length - 1), 2), redeemerType = _c[0], ctxType = _c[1];
var redeemerUplc = (0, type_system_1.typeExtends)(redeemerType, type_system_1.data) ?
new uplc_1.UPLCVar(1) :
new uplc_1.Application((0, conversion_1.ptoData)(redeemerType).toUPLC(), new uplc_1.UPLCVar(1));
var ctxUplc = (0, type_system_1.typeExtends)(ctxType, type_system_1.data) ?
new uplc_1.UPLCVar(0) :
new uplc_1.Application((0, conversion_1.ptoData)(ctxType).toUPLC(), new uplc_1.UPLCVar(0));
body =
new uplc_1.Lambda(//redeemer
new uplc_1.Lambda(// ctx
new uplc_1.Force(new uplc_1.Application(new uplc_1.Application(new uplc_1.Application(uplc_1.Builtin.ifThenElse, new uplc_1.Application(new uplc_1.Application(body, redeemerUplc), ctxUplc)), new uplc_1.Delay(uplc_1.UPLCConst.unit)), new uplc_1.Delay(new uplc_1.ErrorUPLC)))));
return uplc_1.UPLCEncoder.compile(new uplc_1.UPLCProgram(version, body)).toBuffer().buffer;
},
writable: false,
enumerable: true,
configurable: false
});
}
Precompiled.prototype.toJSON = function () { return this.toJson(); };
Precompiled.prototype.toJson = function () {
return {
purpose: this.purpose,
params: this.params.map(type_system_1.termTypeToJson),
validatorType: (0, type_system_1.termTypeToJson)(this.validatorType),
precompiledHex: (0, uint8array_utils_1.toHex)(this.precompiled)
};
};
Precompiled.fromJson = function (json) {
if (!(0, obj_utils_1.isObject)(json))
throw new Error("'Precompiled.formJson' espects an object as argument");
var params = json["params"].map(type_system_1.termTypeFromJson);
var validatroType = (0, type_system_1.termTypeFromJson)(json["validatorType"]);
var validatorTypes = (0, getFnTypes_1.getFnTypes)(validatroType);
var outT = validatorTypes[validatorTypes.length - 1];
var validatorArgs = validatorTypes.slice(0, validatorTypes.length - 1);
var fullType = (0, type_system_1.fn)(__spreadArray(__spreadArray([], __read(params), false), __read(validatorArgs), false), outT);
return new Precompiled(json["purpose"], fullType, (0, uint8array_utils_1.fromHex)(json["precompiledHex"]));
};
return Precompiled;
}());
exports.Precompiled = Precompiled;