Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@harmoniclabs/uplc

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@harmoniclabs/uplc - npm Package Compare versions

Comparing version 1.0.1 to 1.1.0

dist/UPLCTerm/parseUPLCText.d.ts

2

dist/interfaces/ToUPLC.d.ts

@@ -1,4 +0,4 @@

import { UPLCTerm } from "../UPLCTerm/index.js";
import { UPLCTerm } from "../UPLCTerm/UPLCTerm.js";
export interface ToUPLC {
toUPLC: (dbn?: number | bigint) => UPLCTerm;
}

@@ -9,3 +9,3 @@ "use strict";

var UPLCVersion_1 = require("../UPLCProgram/UPLCVersion.js");
var UPLCTerm_1 = require("../UPLCTerm/index.js");
var UPLCTerm_1 = require("../UPLCTerm/UPLCTerm.js");
var Application_1 = require("../UPLCTerms/Application.js");

@@ -219,7 +219,10 @@ var Builtin_1 = require("../UPLCTerms/Builtin/Builtin.js");

partialUPLC += "(error)";
return new ErrorUPLC_1.ErrorUPLC("error got from deserialization;", {
debruijnLevel: currDbn,
byteIndex: currByteIndex(),
bitIndex: currPtr
});
return new ErrorUPLC_1.ErrorUPLC(
// "error got from deserialization;",
// {
// debruijnLevel: currDbn,
// byteIndex: currByteIndex(),
// bitIndex: currPtr
// }
);
case 7:

@@ -277,3 +280,10 @@ var bn_tag = Number(readNBits(7));

if ((0, ConstType_1.constTypeEq)(t, ConstType_1.constT.data)) {
return (0, plutus_data_1.dataFromCbor)(readConstValueOfType(ConstType_1.constT.byteStr).toBuffer());
var bytes = readConstValueOfType(ConstType_1.constT.byteStr).toBuffer();
// data > 64 bytes encoded as indefinite
if (bytes[0] === 0x5f &&
bytes.length > (64 + 2)) {
// Cbor.parse will parse the indefinite length bytes as a single buffer
bytes = cbor_1.Cbor.parse(bytes).buffer;
}
return (0, plutus_data_1.dataFromCbor)(bytes);
}

@@ -280,0 +290,0 @@ if ((0, ConstType_1.constTypeEq)(t, ConstType_1.constT.bool))

import { ConstValue } from "../UPLCTerms/UPLCConst/ConstValue/index.js";
import { PureUPLCTerm } from "../UPLCTerm/index.js";
import { UPLCTerm } from "../UPLCTerm/UPLCTerm.js";
import { UPLCProgram } from "../UPLCProgram/UPLCProgram.js";

@@ -26,3 +26,3 @@ import { UPLCVersion } from "../UPLCProgram/UPLCVersion.js";

encodeVersion(version: UPLCVersion): BitStream;
encodeTerm(term: PureUPLCTerm): BitStream;
encodeTerm(term: UPLCTerm): BitStream;
encodeUPLCVar(uplcVar: UPLCVar): BitStream;

@@ -51,2 +51,57 @@ encodeDelayTerm(delayed: Delay): BitStream;

* in the Plutus GitHub repository IOHK [2019] for a definitive implementation.
*
* from the `encodeData` source:
*
* {- Note [The 64-byte limit]
* We impose a 64-byte *on-the-wire* limit on the leaves of a serialized 'Data'. This prevents people from inserting
* Mickey Mouse entire.
*
* The simplest way of doing this is to check during deserialization that we never deserialize something that uses
* more than 64-bytes, and this is largely what we do. Then it's the user's problem to not produce something too big.
*
* But this is quite inconvenient, so see Note [Evading the 64-byte limit] for how we get around this.
* -}
* {- Note [Evading the 64-byte limit]
* Implementing Note [The 64-byte limit] naively would be quite annoying:
* - Users would be responsible for not creating Data values with leaves that were too big.
* - If a script *required* such a thing (e.g. a counter that somehow got above 64 bytes), then the user is totally
* stuck: the script demands something they cannot represent.
*
* This is unpleasant and introduces limits. Probably limits that nobody will hit, but it's nicer to just not have them.
* And it turns out that we can evade the problem with some clever encoding.
*
* The fundamental
* trick is that an *indefinite-length* CBOR bytestring is just as obfuscated as a list of bytestrings,
* since it consists of a list of definite-length chunks, and each definite-length chunk must be *tagged* (at least with the size).
* So we get a sequence like:
*
* <list start>
* <chunk length metadata>
* <chunk>
* <chunk length metadata>
* ...
* <list end>
*
* The chunk length metadata has a prescribed format, such that it's difficult to manipulate it so that it
* matches your "desired" data.
* So this effectively breaks up the bytestring in much the same way as a list of <64 byte bytestrings.
*
* So that solves the problem for bytestrings on the encoding side:
* - if they are <=64 bytes, we can just encode them as a normal bytestring
* - if they are >64 bytes, we encode them as indefinite-length bytestrings with 64-byte chunks
*
* On the decoding side, we need to check when we decode that we never decode a definite-length
* bytestring of >64 bytes. That covers our two cases:
* - Short definite-length bytestrings are fine
* - Long indefinite-length bytestrings are just made of short definite-length bytestings.
*
* * Unfortunately this all means that we have to write our own encoders/decoders so we can produce
* * chunks of the right size and check the sizes when we decode, but that's okay. Users need to do the same
* * thing: anyone encoding `Data` with their own encoders who doesn't split up big bytestrings in this way
* * will get failures when we decode them.
*
* For integers, we have two cases. Small integers (<=64bits) can be encoded normally. Big integers are already
* encoded *with a byte string*. The spec allows this to be an indefinite-length bytestring (although cborg doesn't
* like it), so we can reuse our trick. Again, we need to write some manual encoders/decoders.
* -}
*/

@@ -53,0 +108,0 @@ encodeConstValueData(data: Data): BitStream;

@@ -10,3 +10,3 @@ "use strict";

var UPLCBuiltinTag_1 = require("../UPLCTerms/Builtin/UPLCBuiltinTag.js");
var UPLCTerm_1 = require("../UPLCTerm/index.js");
var UPLCTerm_1 = require("../UPLCTerm/UPLCTerm.js");
var Application_1 = require("../UPLCTerms/Application.js");

@@ -68,3 +68,3 @@ var Builtin_1 = require("../UPLCTerms/Builtin/Builtin.js");

// no idea why deBruijn indicies start form 1...s
// can dev do something?
// can devs do something?
uplcVar.deBruijn + BigInt(1)));

@@ -126,21 +126,2 @@ return result;

// ------------------------------------------------------------------------------------------------------------------- //
function properlyCloneUPLC(uplc) {
if (uplc instanceof UPLCVar_1.UPLCVar)
return new UPLCVar_1.UPLCVar(uplc.deBruijn);
if (uplc instanceof Delay_1.Delay)
return new Delay_1.Delay(properlyCloneUPLC(uplc.delayedTerm));
if (uplc instanceof Lambda_1.Lambda)
return new Lambda_1.Lambda(properlyCloneUPLC(uplc.body));
if (uplc instanceof Application_1.Application)
return new Application_1.Application(properlyCloneUPLC(uplc.funcTerm), properlyCloneUPLC(uplc.argTerm));
if (uplc instanceof UPLCConst_1.UPLCConst)
return new UPLCConst_1.UPLCConst(uplc.type, uplc.value);
if (uplc instanceof Force_1.Force)
return new Force_1.Force(properlyCloneUPLC(uplc.termToForce));
if (uplc instanceof ErrorUPLC_1.ErrorUPLC)
return new ErrorUPLC_1.ErrorUPLC(uplc.msg, uplc.addInfos);
if (uplc instanceof Builtin_1.Builtin)
return new Builtin_1.Builtin(uplc.tag);
throw new Error("unknown UPLC in 'properlyCloneUPLC'");
}
var UPLCEncoder = /** @class */ (function () {

@@ -158,3 +139,3 @@ function UPLCEncoder() {

if (!(0, UPLCTerm_1.isPureUPLCTerm)(uplc)) {
throw new Error("'replaceHoisteTerm' did not returned a 'PureUPLCTerm'");
throw new Error("'replaceHoisteTerm' did not return an 'UPLCTerm'");
}

@@ -334,7 +315,74 @@ result.append(this.encodeTerm(uplc));

* in the Plutus GitHub repository IOHK [2019] for a definitive implementation.
*
* from the `encodeData` source:
*
* {- Note [The 64-byte limit]
* We impose a 64-byte *on-the-wire* limit on the leaves of a serialized 'Data'. This prevents people from inserting
* Mickey Mouse entire.
*
* The simplest way of doing this is to check during deserialization that we never deserialize something that uses
* more than 64-bytes, and this is largely what we do. Then it's the user's problem to not produce something too big.
*
* But this is quite inconvenient, so see Note [Evading the 64-byte limit] for how we get around this.
* -}
* {- Note [Evading the 64-byte limit]
* Implementing Note [The 64-byte limit] naively would be quite annoying:
* - Users would be responsible for not creating Data values with leaves that were too big.
* - If a script *required* such a thing (e.g. a counter that somehow got above 64 bytes), then the user is totally
* stuck: the script demands something they cannot represent.
*
* This is unpleasant and introduces limits. Probably limits that nobody will hit, but it's nicer to just not have them.
* And it turns out that we can evade the problem with some clever encoding.
*
* The fundamental
* trick is that an *indefinite-length* CBOR bytestring is just as obfuscated as a list of bytestrings,
* since it consists of a list of definite-length chunks, and each definite-length chunk must be *tagged* (at least with the size).
* So we get a sequence like:
*
* <list start>
* <chunk length metadata>
* <chunk>
* <chunk length metadata>
* ...
* <list end>
*
* The chunk length metadata has a prescribed format, such that it's difficult to manipulate it so that it
* matches your "desired" data.
* So this effectively breaks up the bytestring in much the same way as a list of <64 byte bytestrings.
*
* So that solves the problem for bytestrings on the encoding side:
* - if they are <=64 bytes, we can just encode them as a normal bytestring
* - if they are >64 bytes, we encode them as indefinite-length bytestrings with 64-byte chunks
*
* On the decoding side, we need to check when we decode that we never decode a definite-length
* bytestring of >64 bytes. That covers our two cases:
* - Short definite-length bytestrings are fine
* - Long indefinite-length bytestrings are just made of short definite-length bytestings.
*
* * Unfortunately this all means that we have to write our own encoders/decoders so we can produce
* * chunks of the right size and check the sizes when we decode, but that's okay. Users need to do the same
* * thing: anyone encoding `Data` with their own encoders who doesn't split up big bytestrings in this way
* * will get failures when we decode them.
*
* For integers, we have two cases. Small integers (<=64bits) can be encoded normally. Big integers are already
* encoded *with a byte string*. The spec allows this to be an indefinite-length bytestring (although cborg doesn't
* like it), so we can reuse our trick. Again, we need to write some manual encoders/decoders.
* -}
*/
UPLCEncoder.prototype.encodeConstValueData = function (data) {
var cborBytes = (0, plutus_data_1.dataToCbor)(data).asBytes;
if (cborBytes.length < 64)
var cborBytes = (0, plutus_data_1.dataToCbor)(data).toBuffer();
// - if they are <=64 bytes, we can just encode them as a normal bytestring
if (cborBytes.length <= 64)
return this.encodeConstValueByteString(new bytestring_1.ByteString(cborBytes));
/*
Large (>= 4 bytes) data encoding fixed in 1.1.0^
- if they are >64 bytes, we encode them as indefinite-length bytestrings with 64-byte chunks
*/
/*
**NOTE**
this is only an UPLC serialization problem;
UPLC builtin `serialiseData` just resutlts in a normal CBOR bytestring, no matter the length
*/
var head = cborBytes.at(0);

@@ -353,12 +401,12 @@ if (head === undefined)

nLenBytes = 1;
var ptr = nLenBytes + 1 + 1;
var ptr = 0;
var largeCborData = "5f";
while (ptr < cborBytes.length) {
var chunkSize = Math.min(62, cborBytes.length);
var chunkSize = Math.min(64, cborBytes.length - ptr);
var chunkEnd = ptr + chunkSize;
var header = "";
if (chunkSize < 24)
header = (64 & chunkSize).toString(16);
header = (64 | chunkSize).toString(16).padStart(2, "0");
else
header = "58" + chunkSize.toString(16);
header = "58" + chunkSize.toString(16).padStart(2, "0");
largeCborData = largeCborData +

@@ -380,3 +428,2 @@ header +

var missingBytes = bs.toString();
var isBadOne = missingBytes === "d87982d87981582066f225ce3f1acd5e9b133a09b571af99ea4f0742741d008e482d3d33a7329da300";
var hexChunks = [];

@@ -383,0 +430,0 @@ while ((missingBytes.length / 2) > 255) {

@@ -1,2 +0,2 @@

import { UPLCTerm } from "../UPLCTerm/index.js";
import { UPLCTerm } from "../UPLCTerm/UPLCTerm.js";
import { CanBeUInteger } from "../utils/ints.js";

@@ -3,0 +3,0 @@ import { UPLCVersion } from "./UPLCVersion.js";

@@ -1,53 +0,2 @@

import { UPLCVar } from "../UPLCTerms/UPLCVar/index.js";
import { Delay } from "../UPLCTerms/Delay.js";
import { Lambda } from "../UPLCTerms/Lambda.js";
import { Application } from "../UPLCTerms/Application.js";
import { UPLCConst } from "../UPLCTerms/UPLCConst/UPLCConst.js";
import { Force } from "../UPLCTerms/Force.js";
import { ErrorUPLC } from "../UPLCTerms/ErrorUPLC.js";
import { Builtin } from "../UPLCTerms/Builtin/Builtin.js";
import { ConstType } from "../UPLCTerms/UPLCConst/ConstType/index.js";
import { ConstValue } from "../UPLCTerms/UPLCConst/ConstValue/index.js";
export type UPLCTerm = UPLCVar | Delay | Lambda | Application | UPLCConst | Force | ErrorUPLC | Builtin;
/**
* @deprecated alias for `UPLCTerm` use that instead
*/
export type PureUPLCTerm = UPLCTerm;
/**
* **_O(1)_**
* @param {UPLCTerm} t ```UPLCTerm``` to check
* @returns {boolean} ```true``` if the argument is instance of any of the ```UPLCTerm``` constructors, ```false``` otherwise
*/
export declare function isUPLCTerm(t: object): t is UPLCTerm;
/**
* **_O(n)_**
* @param {UPLCTerm} t ```UPLCTerm``` to check
* @returns {boolean} ```true``` if the AST contains only plutus-core terms, ```false``` otherwise
*/
export declare function isPureUPLCTerm(t: UPLCTerm): t is PureUPLCTerm;
export declare function isClosedTerm(term: UPLCTerm): boolean;
export declare function showUPLCConstValue(v: ConstValue): string;
export declare function showConstType(t: ConstType): string;
export declare function showUPLC(term: UPLCTerm): string;
export declare function prettyUPLC(term: UPLCTerm, _indent?: number): string;
/**
*
* @param {number | bigint} varDeBruijn ```number | bigint```; debruijn level (at the term level) of the variable to search for
* @param {UPLCTerm} t ```UPLCTerm``` to search in
* @returns {boolean} ```true``` if the variable has **at least** 1 or more references; ```false``` otherwise
*/
export declare function hasAnyRefsInTerm(varDeBruijn: number | bigint, t: UPLCTerm): boolean;
/**
*
* @param {number | bigint} varDeBruijn ```number | bigint```; debruijn level (at the term level) of the variable to search for
* @param {UPLCTerm} term ```UPLCTerm``` to search in
* @returns {boolean} ```true``` if the variable has 2 or more references; ```false``` otherwise
*/
export declare function hasMultipleRefsInTerm(varDeBruijn: number | bigint, t: Readonly<UPLCTerm>): boolean;
/**
*
* @param {number | bigint} varDeBruijn ```number | bigint```; debruijn level (at the term level) of the variable to search for
* @param {UPLCTerm} term ```UPLCTerm``` to search in
* @returns {number} number of references to the variable
*/
export declare function getUPLCVarRefsInTerm(term: UPLCTerm, varDeBruijn?: number | bigint): number;
export * from "./UPLCTerm.js";
export * from "./parseUPLCText.js";
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getUPLCVarRefsInTerm = exports.hasMultipleRefsInTerm = exports.hasAnyRefsInTerm = exports.prettyUPLC = exports.showUPLC = exports.showConstType = exports.showUPLCConstValue = exports.isClosedTerm = exports.isPureUPLCTerm = exports.isUPLCTerm = void 0;
var UPLCVar_1 = require("../UPLCTerms/UPLCVar/index.js");
var Delay_1 = require("../UPLCTerms/Delay.js");
var Lambda_1 = require("../UPLCTerms/Lambda.js");
var Application_1 = require("../UPLCTerms/Application.js");
var UPLCConst_1 = require("../UPLCTerms/UPLCConst/UPLCConst.js");
var Force_1 = require("../UPLCTerms/Force.js");
var ErrorUPLC_1 = require("../UPLCTerms/ErrorUPLC.js");
var Builtin_1 = require("../UPLCTerms/Builtin/Builtin.js");
var ConstType_1 = require("../UPLCTerms/UPLCConst/ConstType/index.js");
var UPLCBuiltinTag_1 = require("../UPLCTerms/Builtin/UPLCBuiltinTag.js");
var ConstValue_1 = require("../UPLCTerms/UPLCConst/ConstValue/index.js");
var bytestring_1 = require("@harmoniclabs/bytestring");
var pair_1 = require("@harmoniclabs/pair");
var plutus_data_1 = require("@harmoniclabs/plutus-data");
var assert_1 = require("../utils/assert.js");
/**
* **_O(1)_**
* @param {UPLCTerm} t ```UPLCTerm``` to check
* @returns {boolean} ```true``` if the argument is instance of any of the ```UPLCTerm``` constructors, ```false``` otherwise
*/
function isUPLCTerm(t) {
var proto = Object.getPrototypeOf(t);
// only strict instances
return (proto === UPLCVar_1.UPLCVar.prototype ||
proto === Delay_1.Delay.prototype ||
proto === Lambda_1.Lambda.prototype ||
proto === Application_1.Application.prototype ||
proto === UPLCConst_1.UPLCConst.prototype ||
proto === Force_1.Force.prototype ||
proto === ErrorUPLC_1.ErrorUPLC.prototype ||
proto === Builtin_1.Builtin.prototype);
}
exports.isUPLCTerm = isUPLCTerm;
/**
* **_O(n)_**
* @param {UPLCTerm} t ```UPLCTerm``` to check
* @returns {boolean} ```true``` if the AST contains only plutus-core terms, ```false``` otherwise
*/
function isPureUPLCTerm(t) {
if (!isUPLCTerm(t))
return false;
if (t instanceof UPLCVar_1.UPLCVar)
return true;
if (t instanceof Delay_1.Delay)
return isPureUPLCTerm(t.delayedTerm);
if (t instanceof Lambda_1.Lambda)
return isPureUPLCTerm(t.body);
if (t instanceof Application_1.Application)
return (isPureUPLCTerm(t.argTerm) && isPureUPLCTerm(t.funcTerm));
if (t instanceof UPLCConst_1.UPLCConst)
return true;
if (t instanceof Force_1.Force)
return isPureUPLCTerm(t.termToForce);
if (t instanceof ErrorUPLC_1.ErrorUPLC)
return true;
if (t instanceof Builtin_1.Builtin)
return true;
return false;
}
exports.isPureUPLCTerm = isPureUPLCTerm;
function isClosedTerm(term) {
function _isClosedTerm(maxDeBruijn, t) {
(0, assert_1.assert)(isUPLCTerm(t), "'isClosedTerm' functions only works on **raw** UPLCTerms");
if (t instanceof UPLCVar_1.UPLCVar)
// deBruijn variables are 0 indexed (as arrays)
return maxDeBruijn > t.deBruijn;
else if (t instanceof Delay_1.Delay)
return _isClosedTerm(maxDeBruijn, t.delayedTerm);
else if (t instanceof Lambda_1.Lambda)
// increment max debruijn
return _isClosedTerm(maxDeBruijn + BigInt(1), t.body);
else if (t instanceof Application_1.Application)
return _isClosedTerm(maxDeBruijn, t.funcTerm) && _isClosedTerm(maxDeBruijn, t.argTerm);
else if (t instanceof UPLCConst_1.UPLCConst)
// `UPLCConst` has no variables in it, ence always closed
return true;
else if (t instanceof Force_1.Force)
return _isClosedTerm(maxDeBruijn, t.termToForce);
else if (t instanceof ErrorUPLC_1.ErrorUPLC)
// `ErrorUPLC` has no variables in it, ence always closed
return true;
else if (t instanceof Builtin_1.Builtin)
// builtin per-se is just the function (ence a valid value),
// arguments are passed using the `Apply` Term
// so it is the `t instanceof Apply` case job
// to be sure the arguments are closed
return true;
else
throw new Error("unexpected execution flow in 'isClodeTerm'; all possibilieties should have already been handled; input term is: " + t.toString());
}
return _isClosedTerm(BigInt(0), term);
}
exports.isClosedTerm = isClosedTerm;
function showUPLCConstValue(v) {
if (v === undefined)
return "()";
if ((0, ConstValue_1.isConstValueInt)(v))
return v.toString();
if (typeof v === "string")
return "\"".concat(v, "\"");
if (typeof v === "boolean")
return v ? "True" : "False";
if (v instanceof bytestring_1.ByteString)
return "#" + v.toString();
if ((0, plutus_data_1.isData)(v))
return "#" + (0, plutus_data_1.dataToCbor)(v).toString();
if (Array.isArray(v))
return "[" + v.map(showUPLCConstValue).join(',') + "]";
if (v instanceof pair_1.Pair)
return "(".concat(showUPLCConstValue(v.fst), ",").concat(showUPLCConstValue(v.snd), ")");
throw new Error("'showUPLCConstValue' did not matched any possible constant value");
}
exports.showUPLCConstValue = showUPLCConstValue;
function showConstType(t) {
if (t[0] === ConstType_1.ConstTyTag.list) {
return "list( ".concat(showConstType(ConstType_1.constListTypeUtils.getTypeArgument(t)), " )");
}
if (t[0] === ConstType_1.ConstTyTag.pair) {
return "pair( ".concat(showConstType(ConstType_1.constPairTypeUtils.getFirstTypeArgument(t)), ", ").concat(showConstType(ConstType_1.constPairTypeUtils.getSecondTypeArgument(t)), " )");
}
return (0, ConstType_1.constTypeToStirng)(t);
}
exports.showConstType = showConstType;
var vars = "abcdefghilmopqrstuvzwxyjkABCDEFGHILJMNOPQRSTUVZWXYJK".split('');
function getVarNameForDbn(dbn) {
if (dbn < 0)
return "(".concat(dbn, ")");
if (dbn < vars.length)
return vars[dbn];
return vars[Math.floor(dbn / vars.length)] + getVarNameForDbn(dbn - vars.length);
}
function showUPLC(term) {
function loop(t, dbn) {
if (t instanceof UPLCVar_1.UPLCVar) {
return getVarNameForDbn(dbn - 1 - Number(t.deBruijn));
}
if (t instanceof Delay_1.Delay)
return "(delay ".concat(loop(t.delayedTerm, dbn), ")");
if (t instanceof Lambda_1.Lambda) {
return "(lam ".concat(getVarNameForDbn(dbn), " ").concat(loop(t.body, dbn + 1), ")");
}
if (t instanceof Application_1.Application)
return "[".concat(loop(t.funcTerm, dbn), " ").concat(loop(t.argTerm, dbn), "]");
if (t instanceof UPLCConst_1.UPLCConst)
return "(con ".concat(showConstType(t.type), " ").concat(showUPLCConstValue(t.value), ")");
if (t instanceof Force_1.Force)
return "(force ".concat(loop(t.termToForce, dbn), ")");
if (t instanceof ErrorUPLC_1.ErrorUPLC)
return "(error)";
if (t instanceof Builtin_1.Builtin) {
var nForces = (0, UPLCBuiltinTag_1.getNRequiredForces)(t.tag);
return "(force ".repeat(nForces) + "(builtin ".concat((0, UPLCBuiltinTag_1.builtinTagToString)(t.tag), ")") + ')'.repeat(nForces);
}
return "";
}
return loop(term, 0);
}
exports.showUPLC = showUPLC;
function prettyUPLC(term, _indent) {
if (_indent === void 0) { _indent = 2; }
if (!Number.isSafeInteger(_indent) || _indent < 1)
return showUPLC(term);
var indentStr = " ".repeat(_indent);
function getVarNameForDbn(dbn) {
if (dbn < 0)
return "(".concat(dbn, ")");
if (dbn < vars.length)
return vars[dbn];
return vars[Math.floor(dbn / vars.length)] + getVarNameForDbn(dbn - vars.length);
}
function loop(t, dbn, depth) {
var indent = "\n".concat(indentStr.repeat(depth));
if (t instanceof UPLCVar_1.UPLCVar) {
return indent + getVarNameForDbn(dbn - 1 - Number(t.deBruijn));
}
if (t instanceof Delay_1.Delay)
return "".concat(indent, "(delay ").concat(loop(t.delayedTerm, dbn, depth + 1)).concat(indent, ")");
if (t instanceof Lambda_1.Lambda) {
return "".concat(indent, "(lam ").concat(getVarNameForDbn(dbn), " ").concat(loop(t.body, dbn + 1, depth + 1)).concat(indent, ")");
}
if (t instanceof Application_1.Application)
return "".concat(indent, "[").concat(loop(t.funcTerm, dbn, depth + 1), " ").concat(loop(t.argTerm, dbn, depth + 1)).concat(indent, "]");
if (t instanceof UPLCConst_1.UPLCConst)
return "".concat(indent, "(con ").concat(showConstType(t.type), " ").concat(showUPLCConstValue(t.value), ")");
if (t instanceof Force_1.Force)
return "".concat(indent, "(force ").concat(loop(t.termToForce, dbn, depth + 1)).concat(indent, ")");
if (t instanceof ErrorUPLC_1.ErrorUPLC)
return "(error)";
if (t instanceof Builtin_1.Builtin) {
var nForces = (0, UPLCBuiltinTag_1.getNRequiredForces)(t.tag);
return indent + "(force ".repeat(nForces) + "(builtin ".concat((0, UPLCBuiltinTag_1.builtinTagToString)(t.tag), ")") + ')'.repeat(nForces);
}
return "";
}
return loop(term, 0, 0);
}
exports.prettyUPLC = prettyUPLC;
/**
*
* @param {number | bigint} varDeBruijn ```number | bigint```; debruijn level (at the term level) of the variable to search for
* @param {UPLCTerm} t ```UPLCTerm``` to search in
* @returns {boolean} ```true``` if the variable has **at least** 1 or more references; ```false``` otherwise
*/
function hasAnyRefsInTerm(varDeBruijn, t) {
(0, assert_1.assert)(isUPLCTerm(t), "'getUPLCVarRefsInTerm' expects an UPLCTerms");
var dbn = BigInt(varDeBruijn);
if (t instanceof UPLCVar_1.UPLCVar)
return t.deBruijn === dbn;
if (t instanceof Delay_1.Delay)
return hasAnyRefsInTerm(dbn, t.delayedTerm);
if (t instanceof Lambda_1.Lambda)
return hasAnyRefsInTerm(dbn + BigInt(1), t.body);
if (t instanceof Application_1.Application)
return hasAnyRefsInTerm(dbn, t.funcTerm) || hasAnyRefsInTerm(dbn, t.argTerm);
if (t instanceof UPLCConst_1.UPLCConst)
return false;
if (t instanceof Force_1.Force)
return hasAnyRefsInTerm(dbn, t.termToForce);
if (t instanceof ErrorUPLC_1.ErrorUPLC)
return false;
if (t instanceof Builtin_1.Builtin)
return false;
throw new Error("'hasAnyRefsInTerm' did not matched any possible 'UPLCTerm' constructor");
}
exports.hasAnyRefsInTerm = hasAnyRefsInTerm;
/**
*
* @param {number | bigint} varDeBruijn ```number | bigint```; debruijn level (at the term level) of the variable to search for
* @param {UPLCTerm} term ```UPLCTerm``` to search in
* @returns {boolean} ```true``` if the variable has 2 or more references; ```false``` otherwise
*/
function hasMultipleRefsInTerm(varDeBruijn, t) {
(0, assert_1.assert)(isUPLCTerm(t), "'getUPLCVarRefsInTerm' expects an UPLCTerms");
var dbn = BigInt(varDeBruijn);
if (t instanceof UPLCVar_1.UPLCVar)
return false; // single ref; case of multple refs is handled in 'Application' using 'hasAnyRefsInTerm'
if (t instanceof Delay_1.Delay)
return hasMultipleRefsInTerm(dbn, t.delayedTerm);
if (t instanceof Lambda_1.Lambda)
return hasMultipleRefsInTerm(dbn + BigInt(1), t.body);
if (t instanceof Application_1.Application)
return ((hasAnyRefsInTerm(dbn, t.funcTerm) && hasAnyRefsInTerm(dbn, t.argTerm)) || // referenced at least once in both terms
hasMultipleRefsInTerm(dbn, t.funcTerm) || // referenced multiple times in func
hasMultipleRefsInTerm(dbn, t.argTerm) // referenced multiple times in arg
);
if (t instanceof UPLCConst_1.UPLCConst)
return false;
if (t instanceof Force_1.Force)
return hasMultipleRefsInTerm(dbn, t.termToForce);
if (t instanceof ErrorUPLC_1.ErrorUPLC)
return false;
if (t instanceof Builtin_1.Builtin)
return false;
throw new Error("getUPLCVarRefsInTerm did not matched any possible 'UPLCTerm' constructor");
}
exports.hasMultipleRefsInTerm = hasMultipleRefsInTerm;
/**
*
* @param {number | bigint} varDeBruijn ```number | bigint```; debruijn level (at the term level) of the variable to search for
* @param {UPLCTerm} term ```UPLCTerm``` to search in
* @returns {number} number of references to the variable
*/
function getUPLCVarRefsInTerm(term, varDeBruijn) {
if (varDeBruijn === void 0) { varDeBruijn = 0; }
function _getUPLCVarRefsInTerm(dbn, t, countedUntilNow) {
(0, assert_1.assert)(isUPLCTerm(t), "'getUPLCVarRefsInTerm' expects an UPLCTerms");
if (t instanceof UPLCVar_1.UPLCVar)
return countedUntilNow + (t.deBruijn === dbn ? 1 : 0);
if (t instanceof Delay_1.Delay)
return _getUPLCVarRefsInTerm(dbn, t.delayedTerm, countedUntilNow);
if (t instanceof Lambda_1.Lambda)
return _getUPLCVarRefsInTerm(dbn + BigInt(1), t.body, countedUntilNow);
if (t instanceof Application_1.Application)
return _getUPLCVarRefsInTerm(dbn, t.funcTerm, countedUntilNow) + _getUPLCVarRefsInTerm(dbn, t.argTerm, countedUntilNow);
if (t instanceof UPLCConst_1.UPLCConst)
return countedUntilNow;
if (t instanceof Force_1.Force)
return _getUPLCVarRefsInTerm(dbn, t.termToForce, countedUntilNow);
if (t instanceof ErrorUPLC_1.ErrorUPLC)
return countedUntilNow;
if (t instanceof Builtin_1.Builtin)
return countedUntilNow;
throw new Error("getUPLCVarRefsInTerm did not matched any possible 'UPLCTerm' constructor");
}
return _getUPLCVarRefsInTerm(BigInt(varDeBruijn), term, 0);
}
exports.getUPLCVarRefsInTerm = getUPLCVarRefsInTerm;
__exportStar(require("./UPLCTerm.js"), exports);
__exportStar(require("./parseUPLCText.js"), exports);

@@ -1,2 +0,2 @@

import { UPLCTerm } from "../UPLCTerm/index.js";
import { UPLCTerm } from "../UPLCTerm/UPLCTerm.js";
import { UPLCVar } from "./UPLCVar/index.js";

@@ -3,0 +3,0 @@ import { Lambda } from "./Lambda.js";

@@ -66,1 +66,2 @@ export type UPLCBuiltinTagNumber = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53;

export declare function builtinTagToString(tag: UPLCBuiltinTag): string;
export declare function builtinTagFromString(tag: string): UPLCBuiltinTag;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.builtinTagToString = exports.isV2Supported = exports.isV1Supported = exports.getNRequiredForces = exports.isUPLCBuiltinTag = exports.UPLCBuiltinTag = void 0;
exports.builtinTagFromString = exports.builtinTagToString = exports.isV2Supported = exports.isV1Supported = exports.getNRequiredForces = exports.isUPLCBuiltinTag = exports.UPLCBuiltinTag = void 0;
var assert_1 = require("../../utils/assert.js");

@@ -179,1 +179,63 @@ /**

exports.builtinTagToString = builtinTagToString;
function builtinTagFromString(tag) {
switch (tag) {
case "addInteger": return UPLCBuiltinTag.addInteger;
case "subtractInteger": return UPLCBuiltinTag.subtractInteger;
case "multiplyInteger": return UPLCBuiltinTag.multiplyInteger;
case "divideInteger": return UPLCBuiltinTag.divideInteger;
case "quotientInteger": return UPLCBuiltinTag.quotientInteger;
case "remainderInteger": return UPLCBuiltinTag.remainderInteger;
case "modInteger": return UPLCBuiltinTag.modInteger;
case "equalsInteger": return UPLCBuiltinTag.equalsInteger;
case "lessThanInteger": return UPLCBuiltinTag.lessThanInteger;
case "lessThanEqualInteger": return UPLCBuiltinTag.lessThanEqualInteger;
case "appendByteString": return UPLCBuiltinTag.appendByteString;
case "consByteString": return UPLCBuiltinTag.consByteString;
case "sliceByteString": return UPLCBuiltinTag.sliceByteString;
case "lengthOfByteString": return UPLCBuiltinTag.lengthOfByteString;
case "indexByteString": return UPLCBuiltinTag.indexByteString;
case "equalsByteString": return UPLCBuiltinTag.equalsByteString;
case "lessThanByteString": return UPLCBuiltinTag.lessThanByteString;
case "lessThanEqualsByteString": return UPLCBuiltinTag.lessThanEqualsByteString;
case "sha2_256": return UPLCBuiltinTag.sha2_256;
case "sha3_256": return UPLCBuiltinTag.sha3_256;
case "blake2b_256": return UPLCBuiltinTag.blake2b_256;
case "verifyEd25519Signature": return UPLCBuiltinTag.verifyEd25519Signature;
case "appendString": return UPLCBuiltinTag.appendString;
case "equalsString": return UPLCBuiltinTag.equalsString;
case "encodeUtf8": return UPLCBuiltinTag.encodeUtf8;
case "decodeUtf8": return UPLCBuiltinTag.decodeUtf8;
case "ifThenElse": return UPLCBuiltinTag.ifThenElse;
case "chooseUnit": return UPLCBuiltinTag.chooseUnit;
case "trace": return UPLCBuiltinTag.trace;
case "fstPair": return UPLCBuiltinTag.fstPair;
case "sndPair": return UPLCBuiltinTag.sndPair;
case "chooseList": return UPLCBuiltinTag.chooseList;
case "mkCons": return UPLCBuiltinTag.mkCons;
case "headList": return UPLCBuiltinTag.headList;
case "tailList": return UPLCBuiltinTag.tailList;
case "nullList": return UPLCBuiltinTag.nullList;
case "chooseData": return UPLCBuiltinTag.chooseData;
case "constrData": return UPLCBuiltinTag.constrData;
case "mapData": return UPLCBuiltinTag.mapData;
case "listData": return UPLCBuiltinTag.listData;
case "iData": return UPLCBuiltinTag.iData;
case "bData": return UPLCBuiltinTag.bData;
case "unConstrData": return UPLCBuiltinTag.unConstrData;
case "unMapData": return UPLCBuiltinTag.unMapData;
case "unListData": return UPLCBuiltinTag.unListData;
case "unIData": return UPLCBuiltinTag.unIData;
case "unBData": return UPLCBuiltinTag.unBData;
case "equalsData": return UPLCBuiltinTag.equalsData;
case "mkPairData": return UPLCBuiltinTag.mkPairData;
case "mkNilData": return UPLCBuiltinTag.mkNilData;
case "mkNilPairData": return UPLCBuiltinTag.mkNilPairData;
case "serialiseData": return UPLCBuiltinTag.serialiseData;
case "verifyEcdsaSecp256k1Signature": return UPLCBuiltinTag.verifyEcdsaSecp256k1Signature;
case "verifySchnorrSecp256k1Signature": return UPLCBuiltinTag.verifySchnorrSecp256k1Signature;
default:
// tag; // check that is of type 'never'
throw new Error("unknow builtin: " + tag);
}
}
exports.builtinTagFromString = builtinTagFromString;
import { BitStream } from "@harmoniclabs/bitstream";
import { UPLCTerm } from "../UPLCTerm/index.js";
import { UPLCTerm } from "../UPLCTerm/UPLCTerm.js";
export declare class Delay {

@@ -4,0 +4,0 @@ static get UPLCTag(): BitStream;

@@ -1,2 +0,2 @@

import { UPLCTerm } from "../UPLCTerm/index.js";
import { UPLCTerm } from "../UPLCTerm/UPLCTerm.js";
import { Delay } from "./Delay.js";

@@ -3,0 +3,0 @@ import { UPLCVar } from "./UPLCVar/index.js";

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isUPLCForce = exports.Force = exports.isForceableTerm = void 0;
var UPLCTerm_1 = require("../UPLCTerm/index.js");
var UPLCTerm_1 = require("../UPLCTerm/UPLCTerm.js");
var Delay_1 = require("./Delay.js");

@@ -6,0 +6,0 @@ var UPLCVar_1 = require("./UPLCVar/index.js");

import { BitStream } from "@harmoniclabs/bitstream";
import { UPLCTerm } from "../UPLCTerm/index.js";
import { UPLCTerm } from "../UPLCTerm/UPLCTerm.js";
export declare class Lambda {

@@ -4,0 +4,0 @@ static get UPLCTag(): BitStream;

{
"name": "@harmoniclabs/uplc",
"version": "1.0.1",
"version": "1.1.0",
"description": "",

@@ -5,0 +5,0 @@ "main": "./dist/index.js",

@@ -13,2 +13,4 @@ # @harmoniclabs/uplc

### parse serialized UPLC
parse and print uplc form flat hex ([`@harmoniclabs/uint8array-utils`](https://github.com/HarmonicLabs/uint8array-utils) works in every js runtime)

@@ -54,5 +56,38 @@ ```ts

compile UPLC
### parse textual UPLC
```ts
import { parseUPLCText, prettyUPLC } from "@harmoniclabs/uplc";
const uplc_source = `
[
(lam a
[
[
(builtin addInteger)
(con integer 2)
]
[
[
(builtin multiplyInteger)
(con integer 10)
]
a
]
]
)
(con integer 4)
]`;
const uplc = parseUPLCText( uplc_source );
// expected output: true
console.log(
prettyUPLC( uplc, 4 ) === uplc_source
);
```
### compile UPLC to flat bytes
```ts
import { toHex } from "@harmoniclabs/uint8array-utils";

@@ -59,0 +94,0 @@ import { Application, Builtin, UPLCConst, compileUPLC, UPLCProgram } from "@harmoniclabs/uplc";

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc