"use strict";
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
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) {
    for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
        to[j] = from[i];
    return to;
};
var __values = (this && this.__values) || function(o) {
    var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
    if (m) return m.call(o);
    if (o && typeof o.length === "number") return {
        next: function () {
            if (o && i >= o.length) o = void 0;
            return { value: o && o[i++], done: !o };
        }
    };
    throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.decodePublicKeyBytes = exports.decodePublicKeyHashBytes = exports.decodeAddressBytes = exports.unpackDataBytes = exports.unpackData = exports.packDataBytes = exports.packData = void 0;
var michelson_validator_1 = require("./michelson-validator");
var utils_1 = require("./utils");
var primitives = ["parameter", "storage", "code", "False", "Elt", "Left", "None", "Pair",
    "Right", "Some", "True", "Unit", "PACK", "UNPACK", "BLAKE2B", "SHA256", "SHA512", "ABS", "ADD",
    "AMOUNT", "AND", "BALANCE", "CAR", "CDR", "CHECK_SIGNATURE", "COMPARE", "CONCAT", "CONS",
    "CREATE_ACCOUNT", "CREATE_CONTRACT", "IMPLICIT_ACCOUNT", "DIP", "DROP", "DUP", "EDIV", "EMPTY_MAP",
    "EMPTY_SET", "EQ", "EXEC", "FAILWITH", "GE", "GET", "GT", "HASH_KEY", "IF", "IF_CONS", "IF_LEFT",
    "IF_NONE", "INT", "LAMBDA", "LE", "LEFT", "LOOP", "LSL", "LSR", "LT", "MAP", "MEM", "MUL", "NEG",
    "NEQ", "NIL", "NONE", "NOT", "NOW", "OR", "PAIR", "PUSH", "RIGHT", "SIZE", "SOME", "SOURCE",
    "SENDER", "SELF", "STEPS_TO_QUOTA", "SUB", "SWAP", "TRANSFER_TOKENS", "SET_DELEGATE", "UNIT",
    "UPDATE", "XOR", "ITER", "LOOP_LEFT", "ADDRESS", "CONTRACT", "ISNAT", "CAST", "RENAME", "bool",
    "contract", "int", "key", "key_hash", "lambda", "list", "map", "big_map", "nat", "option", "or",
    "pair", "set", "signature", "string", "bytes", "mutez", "timestamp", "unit", "operation",
    "address", "SLICE", "DIG", "DUG", "EMPTY_BIG_MAP", "APPLY", "chain_id", "CHAIN_ID", "LEVEL",
    "SELF_ADDRESS", "never", "NEVER", "UNPAIR", "VOTING_POWER", "TOTAL_VOTING_POWER", "KECCAK",
    "SHA3", "PAIRING_CHECK", "bls12_381_g1", "bls12_381_g2", "bls12_381_fr", "sapling_state",
    "sapling_transaction", "SAPLING_EMPTY_STATE", "SAPLING_VERIFY_UPDATE", "ticket", "TICKET",
    "READ_TICKET", "SPLIT_TICKET", "JOIN_TICKETS", "GET_AND_UPDATE"];
var primTags = Object.assign.apply(Object, __spreadArray([{}], __read(primitives.map(function (v, i) {
    var _a;
    return (_a = {}, _a[v] = i, _a);
}))));
var Tag;
(function (Tag) {
    Tag[Tag["Int"] = 0] = "Int";
    Tag[Tag["String"] = 1] = "String";
    Tag[Tag["Sequence"] = 2] = "Sequence";
    Tag[Tag["Prim0"] = 3] = "Prim0";
    Tag[Tag["Prim0Annot"] = 4] = "Prim0Annot";
    Tag[Tag["Prim1"] = 5] = "Prim1";
    Tag[Tag["Prim1Annot"] = 6] = "Prim1Annot";
    Tag[Tag["Prim2"] = 7] = "Prim2";
    Tag[Tag["Prim2Annot"] = 8] = "Prim2Annot";
    Tag[Tag["Prim"] = 9] = "Prim";
    Tag[Tag["Bytes"] = 10] = "Bytes";
})(Tag || (Tag = {}));
var Writer = /** @class */ (function () {
    function Writer() {
        this.buffer = [];
    }
    Object.defineProperty(Writer.prototype, "length", {
        get: function () {
            return this.buffer.length;
        },
        enumerable: false,
        configurable: true
    });
    Writer.prototype.writeBytes = function (val) {
        var _a;
        (_a = this.buffer).push.apply(_a, __spreadArray([], __read(val.map(function (v) { return v & 0xff; }))));
    };
    Writer.prototype.writeUint8 = function (val) {
        var v = val | 0;
        this.buffer.push(v & 0xff);
    };
    Writer.prototype.writeUint16 = function (val) {
        var v = val | 0;
        this.buffer.push((v >> 8) & 0xff);
        this.buffer.push(v & 0xff);
    };
    Writer.prototype.writeUint32 = function (val) {
        var v = val | 0;
        this.buffer.push((v >> 24) & 0xff);
        this.buffer.push((v >> 16) & 0xff);
        this.buffer.push((v >> 8) & 0xff);
        this.buffer.push(v & 0xff);
    };
    Writer.prototype.writeInt8 = function (val) {
        this.writeUint8(val);
    };
    Writer.prototype.writeInt16 = function (val) {
        this.writeUint16(val);
    };
    Writer.prototype.writeInt32 = function (val) {
        this.writeUint32(val);
    };
    return Writer;
}());
var boundsErr = new Error("bounds out of range");
var Reader = /** @class */ (function () {
    function Reader(buffer, idx, cap) {
        if (idx === void 0) { idx = 0; }
        if (cap === void 0) { cap = buffer.length; }
        this.buffer = buffer;
        this.idx = idx;
        this.cap = cap;
    }
    Object.defineProperty(Reader.prototype, "length", {
        /** Remaining length */
        get: function () {
            return this.cap - this.idx;
        },
        enumerable: false,
        configurable: true
    });
    Reader.prototype.readBytes = function (len) {
        if (this.cap - this.idx < len) {
            throw boundsErr;
        }
        var ret = this.buffer.slice(this.idx, this.idx + len);
        this.idx += len;
        return ret;
    };
    Reader.prototype.reader = function (len) {
        if (this.cap - this.idx < len) {
            throw boundsErr;
        }
        var ret = new Reader(this.buffer, this.idx, this.idx + len);
        this.idx += len;
        return ret;
    };
    Reader.prototype.copy = function () {
        return new Reader(this.buffer, this.idx, this.cap);
    };
    Reader.prototype.readUint8 = function () {
        if (this.cap - this.idx < 1) {
            throw boundsErr;
        }
        return this.buffer[this.idx++] >>> 0;
    };
    Reader.prototype.readUint16 = function () {
        if (this.cap - this.idx < 2) {
            throw boundsErr;
        }
        var x0 = this.buffer[this.idx++];
        var x1 = this.buffer[this.idx++];
        return ((x0 << 8) | x1) >>> 0;
    };
    Reader.prototype.readUint32 = function () {
        if (this.cap - this.idx < 4) {
            throw boundsErr;
        }
        var x0 = this.buffer[this.idx++];
        var x1 = this.buffer[this.idx++];
        var x2 = this.buffer[this.idx++];
        var x3 = this.buffer[this.idx++];
        return ((x0 << 24) | (x1 << 16) | (x2 << 8) | x3) >>> 0;
    };
    Reader.prototype.readInt8 = function () {
        if (this.cap - this.idx < 1) {
            throw boundsErr;
        }
        var x = this.buffer[this.idx++];
        return (x << 24) >> 24;
    };
    Reader.prototype.readInt16 = function () {
        if (this.cap - this.idx < 2) {
            throw boundsErr;
        }
        var x0 = this.buffer[this.idx++];
        var x1 = this.buffer[this.idx++];
        return (((x0 << 8) | x1) << 16) >> 16;
    };
    Reader.prototype.readInt32 = function () {
        if (this.cap - this.idx < 4) {
            throw boundsErr;
        }
        var x0 = this.buffer[this.idx++];
        var x1 = this.buffer[this.idx++];
        var x2 = this.buffer[this.idx++];
        var x3 = this.buffer[this.idx++];
        return (x0 << 24) | (x1 << 16) | (x2 << 8) | x3;
    };
    return Reader;
}());
var ContractID;
(function (ContractID) {
    ContractID[ContractID["Implicit"] = 0] = "Implicit";
    ContractID[ContractID["Originated"] = 1] = "Originated";
})(ContractID || (ContractID = {}));
var PublicKeyHashID;
(function (PublicKeyHashID) {
    PublicKeyHashID[PublicKeyHashID["ED25519"] = 0] = "ED25519";
    PublicKeyHashID[PublicKeyHashID["SECP256K1"] = 1] = "SECP256K1";
    PublicKeyHashID[PublicKeyHashID["P256"] = 2] = "P256";
})(PublicKeyHashID || (PublicKeyHashID = {}));
function readPublicKeyHash(rd) {
    var type;
    var tag = rd.readUint8();
    switch (tag) {
        case PublicKeyHashID.ED25519:
            type = "ED25519PublicKeyHash";
            break;
        case PublicKeyHashID.SECP256K1:
            type = "SECP256K1PublicKeyHash";
            break;
        case PublicKeyHashID.P256:
            type = "P256PublicKeyHash";
            break;
        default:
            throw new Error("unknown public key hash tag: " + tag);
    }
    return { type: type, hash: rd.readBytes(20) };
}
function readAddress(rd) {
    var address;
    var tag = rd.readUint8();
    switch (tag) {
        case ContractID.Implicit:
            address = readPublicKeyHash(rd);
            break;
        case ContractID.Originated:
            address = {
                type: "ContractHash",
                hash: rd.readBytes(20),
            };
            rd.readBytes(1);
            break;
        default:
            throw new Error("unknown address tag: " + tag);
    }
    if (rd.length !== 0) {
        // entry point
        var dec = new TextDecoder();
        address.entryPoint = dec.decode(new Uint8Array(rd.readBytes(rd.length)));
    }
    return address;
}
function writePublicKeyHash(a, w) {
    var tag;
    switch (a.type) {
        case "ED25519PublicKeyHash":
            tag = PublicKeyHashID.ED25519;
            break;
        case "SECP256K1PublicKeyHash":
            tag = PublicKeyHashID.SECP256K1;
            break;
        case "P256PublicKeyHash":
            tag = PublicKeyHashID.P256;
            break;
        default:
            throw new Error("unexpected address type: " + a.type);
    }
    w.writeUint8(tag);
    w.writeBytes(Array.from(a.hash));
}
function writeAddress(a, w) {
    if (a.type === "ContractHash") {
        w.writeUint8(ContractID.Originated);
        w.writeBytes(Array.from(a.hash));
        w.writeUint8(0);
    }
    else {
        w.writeUint8(ContractID.Implicit);
        writePublicKeyHash(a, w);
    }
    if (a.entryPoint !== undefined && a.entryPoint !== "" && a.entryPoint !== "default") {
        var enc = new TextEncoder();
        var bytes = enc.encode(a.entryPoint);
        w.writeBytes(Array.from(bytes));
    }
}
var PublicKeyID;
(function (PublicKeyID) {
    PublicKeyID[PublicKeyID["ED25519"] = 0] = "ED25519";
    PublicKeyID[PublicKeyID["SECP256K1"] = 1] = "SECP256K1";
    PublicKeyID[PublicKeyID["P256"] = 2] = "P256";
})(PublicKeyID || (PublicKeyID = {}));
function readPublicKey(rd) {
    var ln;
    var type;
    var tag = rd.readUint8();
    switch (tag) {
        case PublicKeyID.ED25519:
            type = "ED25519PublicKey";
            ln = 32;
            break;
        case PublicKeyID.SECP256K1:
            type = "SECP256K1PublicKey";
            ln = 33;
            break;
        case PublicKeyID.P256:
            type = "P256PublicKey";
            ln = 33;
            break;
        default:
            throw new Error("unknown public key tag: " + tag);
    }
    return { type: type, publicKey: rd.readBytes(ln) };
}
function writePublicKey(pk, w) {
    var tag;
    switch (pk.type) {
        case "ED25519PublicKey":
            tag = PublicKeyID.ED25519;
            break;
        case "SECP256K1PublicKey":
            tag = PublicKeyID.SECP256K1;
            break;
        case "P256PublicKey":
            tag = PublicKeyID.P256;
            break;
        default:
            throw new Error("unexpected public key type: " + pk.type);
    }
    w.writeUint8(tag);
    w.writeBytes(Array.from(pk.publicKey));
}
function writeExpr(expr, wr, tf) {
    var e_1, _a, e_2, _b, e_3, _c;
    var _d, _e;
    var _f = __read(tf(expr), 2), e = _f[0], args = _f[1];
    if (Array.isArray(e)) {
        var w = new Writer();
        try {
            for (var e_4 = __values(e), e_4_1 = e_4.next(); !e_4_1.done; e_4_1 = e_4.next()) {
                var v = e_4_1.value;
                var a = args.next();
                if (a.done) {
                    throw new Error("REPORT ME: iterator is done");
                }
                writeExpr(v, w, a.value);
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (e_4_1 && !e_4_1.done && (_a = e_4.return)) _a.call(e_4);
            }
            finally { if (e_1) throw e_1.error; }
        }
        wr.writeUint8(Tag.Sequence);
        wr.writeUint32(w.length);
        wr.writeBytes(w.buffer);
        return;
    }
    if ("string" in e) {
        var enc = new TextEncoder();
        var bytes = enc.encode(e.string);
        wr.writeUint8(Tag.String);
        wr.writeUint32(bytes.length);
        wr.writeBytes(Array.from(bytes));
        return;
    }
    if ("int" in e) {
        wr.writeUint8(Tag.Int);
        var val = BigInt(e.int);
        var sign = val < 0;
        if (sign) {
            val = -val;
        }
        var i = 0;
        do {
            var bits = (i === 0) ? BigInt(6) : BigInt(7);
            var byte = val & ((BigInt(1) << bits) - BigInt(1));
            val >>= bits;
            if (val) {
                byte |= BigInt(0x80);
            }
            if (i === 0 && sign) {
                byte |= BigInt(0x40);
            }
            wr.writeUint8(Number(byte));
            i++;
        } while (val);
        return;
    }
    if ("bytes" in e) {
        var bytes = utils_1.parseHex(e.bytes);
        wr.writeUint8(Tag.Bytes);
        wr.writeUint32(bytes.length);
        wr.writeBytes(bytes);
        return;
    }
    var prim = primTags[e.prim];
    if (prim === undefined) {
        throw new TypeError("Can't encode primary: " + e.prim);
    }
    var tag = (((_d = e.args) === null || _d === void 0 ? void 0 : _d.length) || 0) < 3 ?
        Tag.Prim0 + (((_e = e.args) === null || _e === void 0 ? void 0 : _e.length) || 0) * 2 + (e.annots === undefined || e.annots.length === 0 ? 0 : 1) :
        Tag.Prim;
    wr.writeUint8(tag);
    wr.writeUint8(prim);
    if (e.args !== undefined) {
        if (e.args.length < 3) {
            try {
                for (var _g = __values(e.args), _h = _g.next(); !_h.done; _h = _g.next()) {
                    var v = _h.value;
                    var a = args.next();
                    if (a.done) {
                        throw new Error("REPORT ME: iterator is done");
                    }
                    writeExpr(v, wr, a.value);
                }
            }
            catch (e_2_1) { e_2 = { error: e_2_1 }; }
            finally {
                try {
                    if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
                }
                finally { if (e_2) throw e_2.error; }
            }
        }
        else {
            var w = new Writer();
            try {
                for (var _j = __values(e.args), _k = _j.next(); !_k.done; _k = _j.next()) {
                    var v = _k.value;
                    var a = args.next();
                    if (a.done) {
                        throw new Error("REPORT ME: iterator is done");
                    }
                    writeExpr(v, w, a.value);
                }
            }
            catch (e_3_1) { e_3 = { error: e_3_1 }; }
            finally {
                try {
                    if (_k && !_k.done && (_c = _j.return)) _c.call(_j);
                }
                finally { if (e_3) throw e_3.error; }
            }
            wr.writeUint32(w.length);
            wr.writeBytes(w.buffer);
        }
    }
    if (e.annots !== undefined && e.annots.length !== 0) {
        var enc = new TextEncoder();
        var bytes = enc.encode(e.annots.join(" "));
        wr.writeUint32(bytes.length);
        wr.writeBytes(Array.from(bytes));
    }
    else if (e.args !== undefined && e.args.length >= 3) {
        wr.writeUint32(0);
    }
}
function readExpr(rd, tf) {
    function passThrough() {
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    if (!true) return [3 /*break*/, 2];
                    return [4 /*yield*/, readPassThrough];
                case 1:
                    _a.sent();
                    return [3 /*break*/, 0];
                case 2: return [2 /*return*/];
            }
        });
    }
    var _a = __read(tf, 2), args = _a[0], tr = _a[1];
    var tag = rd.readUint8();
    switch (tag) {
        case Tag.Int:
            {
                var buf = [];
                var byte = void 0;
                do {
                    byte = rd.readInt8();
                    buf.push(byte);
                } while ((byte & 0x80) !== 0);
                var val = BigInt(0);
                var sign = false;
                for (var i = buf.length - 1; i >= 0; i--) {
                    var bits = (i === 0) ? BigInt(6) : BigInt(7);
                    var byte_1 = BigInt(buf[i]);
                    val <<= bits;
                    val |= byte_1 & ((BigInt(1) << bits) - BigInt(1));
                    if (i === 0) {
                        sign = !!(byte_1 & BigInt(0x40));
                    }
                }
                if (sign) {
                    val = -val;
                }
                return tr({ int: String(val) });
            }
        case Tag.String:
            {
                var length_1 = rd.readUint32();
                var bytes = rd.readBytes(length_1);
                var dec = new TextDecoder();
                return tr({ string: dec.decode(new Uint8Array(bytes)) });
            }
        case Tag.Bytes:
            {
                var length_2 = rd.readUint32();
                var bytes = rd.readBytes(length_2);
                var hex = utils_1.hexBytes(Array.from(bytes));
                return tr({ bytes: hex });
            }
        case Tag.Sequence:
            {
                var length_3 = rd.readUint32();
                var res = [];
                var savedrd = rd.copy();
                // make two passes
                var it_1 = passThrough();
                for (var n = 0; n < 2; n++) {
                    var r = savedrd.reader(length_3);
                    res = [];
                    while (r.length > 0) {
                        var a = it_1.next();
                        if (a.done) {
                            throw new Error("REPORT ME: iterator is done");
                        }
                        res.push(readExpr(r, a.value));
                    }
                    // make a second pass with injected side effects
                    it_1 = args(res);
                    savedrd = rd;
                }
                return tr(res);
            }
        default:
            {
                if (tag > 9) {
                    throw new Error("Unknown tag: " + tag);
                }
                var p = rd.readUint8();
                if (p >= primitives.length) {
                    throw new Error("Unknown primitive tag: " + p);
                }
                var prim = primitives[p];
                var argn = (tag - 3) >> 1;
                var res = { prim: prim };
                // make two passes
                var it_2 = passThrough();
                var savedrd = rd.copy();
                for (var n = 0; n < 2; n++) {
                    res = { prim: prim };
                    if (argn < 3) {
                        for (var i = 0; i < argn; i++) {
                            var a = it_2.next();
                            if (a.done) {
                                throw new Error("REPORT ME: iterator is done");
                            }
                            res.args = res.args || [];
                            res.args.push(readExpr(savedrd, a.value));
                        }
                    }
                    else {
                        res.args = res.args || [];
                        var length_4 = savedrd.readUint32();
                        var r = savedrd.reader(length_4);
                        while (r.length > 0) {
                            var a = it_2.next();
                            if (a.done) {
                                throw new Error("REPORT ME: iterator is done");
                            }
                            res.args.push(readExpr(r, a.value));
                        }
                    }
                    // make a second pass with injected side effects
                    it_2 = args(res);
                    savedrd = rd;
                }
                if (((tag - 3) & 1) === 1 || argn === 3) {
                    // read annotations
                    var length_5 = rd.readUint32();
                    if (length_5 !== 0) {
                        var bytes = rd.readBytes(length_5);
                        var dec = new TextDecoder();
                        res.annots = dec.decode(new Uint8Array(bytes)).split(" ");
                    }
                }
                return tr(res);
            }
    }
}
var isOrData = function (e) { return "prim" in e && (e.prim === "Left" || e.prim === "Right"); };
var isOptionData = function (e) { return "prim" in e && (e.prim === "Some" || e.prim === "None"); };
var getWriteTransformFunc = function (t) {
    if (utils_1.isPairType(t)) {
        return function (d) {
            if (!utils_1.isPairData(d)) {
                throw new utils_1.MichelsonTypeError(t, d, "pair expected: " + JSON.stringify(d));
            }
            michelson_validator_1.assertDataListIfAny(d);
            // combs aren't used in pack format
            var tc = utils_1.unpackComb("pair", t);
            var dc = utils_1.unpackComb("Pair", d);
            return [dc, (function () {
                    var _a, _b, a, e_5_1;
                    var e_5, _c;
                    return __generator(this, function (_d) {
                        switch (_d.label) {
                            case 0:
                                _d.trys.push([0, 5, 6, 7]);
                                _a = __values(tc.args), _b = _a.next();
                                _d.label = 1;
                            case 1:
                                if (!!_b.done) return [3 /*break*/, 4];
                                a = _b.value;
                                return [4 /*yield*/, getWriteTransformFunc(a)];
                            case 2:
                                _d.sent();
                                _d.label = 3;
                            case 3:
                                _b = _a.next();
                                return [3 /*break*/, 1];
                            case 4: return [3 /*break*/, 7];
                            case 5:
                                e_5_1 = _d.sent();
                                e_5 = { error: e_5_1 };
                                return [3 /*break*/, 7];
                            case 6:
                                try {
                                    if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
                                }
                                finally { if (e_5) throw e_5.error; }
                                return [7 /*endfinally*/];
                            case 7: return [2 /*return*/];
                        }
                    });
                })()];
        };
    }
    switch (t.prim) {
        case "or":
            return function (d) {
                if (!isOrData(d)) {
                    throw new utils_1.MichelsonTypeError(t, d, "or expected: " + JSON.stringify(d));
                }
                return [d, (function () {
                        return __generator(this, function (_a) {
                            switch (_a.label) {
                                case 0: return [4 /*yield*/, getWriteTransformFunc(t.args[d.prim === "Left" ? 0 : 1])];
                                case 1:
                                    _a.sent();
                                    return [2 /*return*/];
                            }
                        });
                    })()];
            };
        case "option":
            return function (d) {
                if (!isOptionData(d)) {
                    throw new utils_1.MichelsonTypeError(t, d, "option expected: " + JSON.stringify(d));
                }
                return [d, (function () {
                        var dd;
                        return __generator(this, function (_a) {
                            switch (_a.label) {
                                case 0:
                                    dd = d;
                                    if (!(dd.prim === "Some")) return [3 /*break*/, 2];
                                    return [4 /*yield*/, getWriteTransformFunc(t.args[0])];
                                case 1:
                                    _a.sent();
                                    _a.label = 2;
                                case 2: return [2 /*return*/];
                            }
                        });
                    })()];
            };
        case "list":
        case "set":
            return function (d) {
                if (!Array.isArray(d)) {
                    throw new utils_1.MichelsonTypeError(t, d, t.prim + " expected: " + JSON.stringify(d));
                }
                return [d, (function () {
                        var d_1, d_1_1, _v, e_6_1;
                        var e_6, _a;
                        return __generator(this, function (_b) {
                            switch (_b.label) {
                                case 0:
                                    _b.trys.push([0, 5, 6, 7]);
                                    d_1 = __values(d), d_1_1 = d_1.next();
                                    _b.label = 1;
                                case 1:
                                    if (!!d_1_1.done) return [3 /*break*/, 4];
                                    _v = d_1_1.value;
                                    return [4 /*yield*/, getWriteTransformFunc(t.args[0])];
                                case 2:
                                    _b.sent();
                                    _b.label = 3;
                                case 3:
                                    d_1_1 = d_1.next();
                                    return [3 /*break*/, 1];
                                case 4: return [3 /*break*/, 7];
                                case 5:
                                    e_6_1 = _b.sent();
                                    e_6 = { error: e_6_1 };
                                    return [3 /*break*/, 7];
                                case 6:
                                    try {
                                        if (d_1_1 && !d_1_1.done && (_a = d_1.return)) _a.call(d_1);
                                    }
                                    finally { if (e_6) throw e_6.error; }
                                    return [7 /*endfinally*/];
                                case 7: return [2 /*return*/];
                            }
                        });
                    })()];
            };
        case "map":
            return function (d) {
                if (!Array.isArray(d)) {
                    throw new utils_1.MichelsonTypeError(t, d, "map expected: " + JSON.stringify(d));
                }
                return [d, (function () {
                        var d_2, d_2_1, _elt, e_7_1;
                        var e_7, _a;
                        return __generator(this, function (_b) {
                            switch (_b.label) {
                                case 0:
                                    _b.trys.push([0, 5, 6, 7]);
                                    d_2 = __values(d), d_2_1 = d_2.next();
                                    _b.label = 1;
                                case 1:
                                    if (!!d_2_1.done) return [3 /*break*/, 4];
                                    _elt = d_2_1.value;
                                    return [4 /*yield*/, function (elt) {
                                            if (!("prim" in elt) || elt.prim !== "Elt") {
                                                throw new utils_1.MichelsonTypeError(t, elt, "map element expected: " + JSON.stringify(elt));
                                            }
                                            return [elt, (function () {
                                                    var _a, _b, a, e_8_1;
                                                    var e_8, _c;
                                                    return __generator(this, function (_d) {
                                                        switch (_d.label) {
                                                            case 0:
                                                                _d.trys.push([0, 5, 6, 7]);
                                                                _a = __values(t.args), _b = _a.next();
                                                                _d.label = 1;
                                                            case 1:
                                                                if (!!_b.done) return [3 /*break*/, 4];
                                                                a = _b.value;
                                                                return [4 /*yield*/, getWriteTransformFunc(a)];
                                                            case 2:
                                                                _d.sent();
                                                                _d.label = 3;
                                                            case 3:
                                                                _b = _a.next();
                                                                return [3 /*break*/, 1];
                                                            case 4: return [3 /*break*/, 7];
                                                            case 5:
                                                                e_8_1 = _d.sent();
                                                                e_8 = { error: e_8_1 };
                                                                return [3 /*break*/, 7];
                                                            case 6:
                                                                try {
                                                                    if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
                                                                }
                                                                finally { if (e_8) throw e_8.error; }
                                                                return [7 /*endfinally*/];
                                                            case 7: return [2 /*return*/];
                                                        }
                                                    });
                                                })()];
                                        }];
                                case 2:
                                    _b.sent();
                                    _b.label = 3;
                                case 3:
                                    d_2_1 = d_2.next();
                                    return [3 /*break*/, 1];
                                case 4: return [3 /*break*/, 7];
                                case 5:
                                    e_7_1 = _b.sent();
                                    e_7 = { error: e_7_1 };
                                    return [3 /*break*/, 7];
                                case 6:
                                    try {
                                        if (d_2_1 && !d_2_1.done && (_a = d_2.return)) _a.call(d_2);
                                    }
                                    finally { if (e_7) throw e_7.error; }
                                    return [7 /*endfinally*/];
                                case 7: return [2 /*return*/];
                            }
                        });
                    })()];
            };
        case "chain_id":
            return function (d) {
                if (!("bytes" in d) && !("string" in d)) {
                    throw new utils_1.MichelsonTypeError(t, d, "chain id expected: " + JSON.stringify(d));
                }
                var bytes;
                if ("string" in d) {
                    var id = utils_1.checkDecodeTezosID(d.string, "ChainID");
                    if (id === null) {
                        throw new utils_1.MichelsonTypeError(t, d, "chain id base58 expected: " + d.string);
                    }
                    bytes = { bytes: utils_1.hexBytes(id[1]) };
                }
                else {
                    bytes = d;
                }
                return [bytes, [][Symbol.iterator]()];
            };
        case "signature":
            return function (d) {
                if (!("bytes" in d) && !("string" in d)) {
                    throw new utils_1.MichelsonTypeError(t, d, "signature expected: " + JSON.stringify(d));
                }
                var bytes;
                if ("string" in d) {
                    var sig = utils_1.checkDecodeTezosID(d.string, "ED25519Signature", "SECP256K1Signature", "P256Signature", "GenericSignature");
                    if (sig === null) {
                        throw new utils_1.MichelsonTypeError(t, d, "signature base58 expected: " + d.string);
                    }
                    bytes = { bytes: utils_1.hexBytes(sig[1]) };
                }
                else {
                    bytes = d;
                }
                return [bytes, [][Symbol.iterator]()];
            };
        case "key_hash":
            return function (d) {
                if (!("bytes" in d) && !("string" in d)) {
                    throw new utils_1.MichelsonTypeError(t, d, "key hash expected: " + JSON.stringify(d));
                }
                var bytes;
                if ("string" in d) {
                    var pkh = utils_1.checkDecodeTezosID(d.string, "ED25519PublicKeyHash", "SECP256K1PublicKeyHash", "P256PublicKeyHash");
                    if (pkh === null) {
                        throw new utils_1.MichelsonTypeError(t, d, "key hash base58 expected: " + d.string);
                    }
                    var w = new Writer();
                    writePublicKeyHash({ type: pkh[0], hash: pkh[1] }, w);
                    bytes = { bytes: utils_1.hexBytes(w.buffer) };
                }
                else {
                    bytes = d;
                }
                return [bytes, [][Symbol.iterator]()];
            };
        case "key":
            return function (d) {
                if (!("bytes" in d) && !("string" in d)) {
                    throw new utils_1.MichelsonTypeError(t, d, "public key expected: " + JSON.stringify(d));
                }
                var bytes;
                if ("string" in d) {
                    var key = utils_1.checkDecodeTezosID(d.string, "ED25519PublicKey", "SECP256K1PublicKey", "P256PublicKey");
                    if (key === null) {
                        throw new utils_1.MichelsonTypeError(t, d, "public key base58 expected: " + d.string);
                    }
                    var w = new Writer();
                    writePublicKey({ type: key[0], publicKey: key[1] }, w);
                    bytes = { bytes: utils_1.hexBytes(w.buffer) };
                }
                else {
                    bytes = d;
                }
                return [bytes, [][Symbol.iterator]()];
            };
        case "address":
            return function (d) {
                if (!("bytes" in d) && !("string" in d)) {
                    throw new utils_1.MichelsonTypeError(t, d, "address expected: " + JSON.stringify(d));
                }
                var bytes;
                if ("string" in d) {
                    var s = d.string.split("%");
                    var address = utils_1.checkDecodeTezosID(s[0], "ED25519PublicKeyHash", "SECP256K1PublicKeyHash", "P256PublicKeyHash", "ContractHash");
                    if (address === null) {
                        throw new utils_1.MichelsonTypeError(t, d, "address base58 expected: " + d.string);
                    }
                    var w = new Writer();
                    writeAddress({ type: address[0], hash: address[1], entryPoint: s.length > 1 ? s[1] : undefined }, w);
                    bytes = { bytes: utils_1.hexBytes(w.buffer) };
                }
                else {
                    bytes = d;
                }
                return [bytes, [][Symbol.iterator]()];
            };
        case "timestamp":
            return function (d) {
                if (!("string" in d) && !("int" in d)) {
                    throw new utils_1.MichelsonTypeError(t, d, "timestamp expected: " + JSON.stringify(d));
                }
                var int;
                if ("string" in d) {
                    var p = utils_1.parseDate(d);
                    if (p === null) {
                        throw new utils_1.MichelsonTypeError(t, d, "can't parse date: " + d.string);
                    }
                    int = { int: String(Math.floor(p.getTime() / 1000)) };
                }
                else {
                    int = d;
                }
                return [int, [][Symbol.iterator]()];
            };
        default:
            return writePassThrough;
    }
};
var isPushInstruction = function (e) { return "prim" in e && e.prim === "PUSH"; };
var writePassThrough = function (e) {
    if (isPushInstruction(e)) {
        michelson_validator_1.assertMichelsonInstruction(e);
        // capture inlined type definition
        return [e, (function () {
                return __generator(this, function (_a) {
                    switch (_a.label) {
                        case 0: return [4 /*yield*/, writePassThrough];
                        case 1:
                            _a.sent();
                            return [4 /*yield*/, getWriteTransformFunc(e.args[0])];
                        case 2:
                            _a.sent();
                            return [2 /*return*/];
                    }
                });
            })()];
    }
    return [e, (function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!true) return [3 /*break*/, 2];
                        return [4 /*yield*/, writePassThrough];
                    case 1:
                        _a.sent();
                        return [3 /*break*/, 0];
                    case 2: return [2 /*return*/];
                }
            });
        })()];
};
/**
 * Serializes any value of packable type to its optimized binary representation
 * identical to the one used by PACK and UNPACK Michelson instructions.
 * Without a type definition (not recommended) the data will be encoded as a binary form of a generic Michelson expression.
 * Type definition allows some types like `timestamp` and `address` and other base58 representable types to be encoded to
 * corresponding optimized binary forms borrowed from the Tezos protocol
 *
 * ```typescript
 * const data: MichelsonData = {
 *     string: "KT1RvkwF4F7pz1gCoxkyZrG1RkrxQy3gmFTv%foo"
 * };
 *
 * const typ: MichelsonType = {
 *     prim: "address"
 * };
 *
 * const packed = packData(data, typ);
 *
 * // 050a0000001901be41ee922ddd2cf33201e49d32da0afec571dce300666f6f
 * ```
 *
 * Without a type definition the base58 encoded address will be treated as a string
 * ```typescript
 * const data: MichelsonData = {
 *     string: "KT1RvkwF4F7pz1gCoxkyZrG1RkrxQy3gmFTv%foo"
 * };
 *
 * const packed = packData(data);
 *
 * // 0501000000284b543152766b7746344637707a3167436f786b795a724731526b7278517933676d46547625666f6f
 * ```
 * @param d Data object
 * @param t Optional type definition
 * @returns Binary representation as numeric array
 */
function packData(d, t) {
    var w = new Writer();
    w.writeUint8(5);
    writeExpr(d, w, t !== undefined ? getWriteTransformFunc(t) : writePassThrough);
    return w.buffer;
}
exports.packData = packData;
/**
 * Serializes any value of packable type to its optimized binary representation
 * identical to the one used by PACK and UNPACK Michelson instructions.
 * Same as {@link packData} but returns a `bytes` Michelson data literal instead of an array
 *
 * ```typescript
 * const data: MichelsonData = {
 *     string: "2019-09-26T10:59:51Z"
 * };
 *
 * const typ: MichelsonType = {
 *     prim: "timestamp"
 * };
 *
 * const packed = packDataBytes(data, typ);
 *
 * // { bytes: "0500a7e8e4d80b" }
 * ```
 * @param d Data object
 * @param t Optional type definition
 * @returns Binary representation as a bytes literal
 */
function packDataBytes(d, t) {
    return { bytes: utils_1.hexBytes(packData(d, t)) };
}
exports.packDataBytes = packDataBytes;
var getReadTransformFuncs = function (t) {
    if (utils_1.isPairType(t)) {
        var args_1 = Array.isArray(t) ? t : t.args;
        return [
            function (d) {
                if (!utils_1.isPairData(d)) {
                    throw new utils_1.MichelsonTypeError(t, d, "pair expected: " + JSON.stringify(d));
                }
                return (function () {
                    var args_2, args_2_1, a, e_9_1;
                    var e_9, _a;
                    return __generator(this, function (_b) {
                        switch (_b.label) {
                            case 0:
                                _b.trys.push([0, 5, 6, 7]);
                                args_2 = __values(args_1), args_2_1 = args_2.next();
                                _b.label = 1;
                            case 1:
                                if (!!args_2_1.done) return [3 /*break*/, 4];
                                a = args_2_1.value;
                                return [4 /*yield*/, getReadTransformFuncs(a)];
                            case 2:
                                _b.sent();
                                _b.label = 3;
                            case 3:
                                args_2_1 = args_2.next();
                                return [3 /*break*/, 1];
                            case 4: return [3 /*break*/, 7];
                            case 5:
                                e_9_1 = _b.sent();
                                e_9 = { error: e_9_1 };
                                return [3 /*break*/, 7];
                            case 6:
                                try {
                                    if (args_2_1 && !args_2_1.done && (_a = args_2.return)) _a.call(args_2);
                                }
                                finally { if (e_9) throw e_9.error; }
                                return [7 /*endfinally*/];
                            case 7: return [2 /*return*/];
                        }
                    });
                })();
            },
            function (d) { return d; }
        ];
    }
    switch (t.prim) {
        case "or":
            return [
                function (d) {
                    if (!isOrData(d)) {
                        throw new utils_1.MichelsonTypeError(t, d, "or expected: " + JSON.stringify(d));
                    }
                    return (function () {
                        return __generator(this, function (_a) {
                            switch (_a.label) {
                                case 0: return [4 /*yield*/, getReadTransformFuncs(t.args[d.prim === "Left" ? 0 : 1])];
                                case 1:
                                    _a.sent();
                                    return [2 /*return*/];
                            }
                        });
                    })();
                },
                function (d) { return d; }
            ];
        case "option":
            return [
                function (d) {
                    if (!isOptionData(d)) {
                        throw new utils_1.MichelsonTypeError(t, d, "option expected: " + JSON.stringify(d));
                    }
                    return (function () {
                        return __generator(this, function (_a) {
                            switch (_a.label) {
                                case 0:
                                    if (!(d.prim === "Some")) return [3 /*break*/, 2];
                                    return [4 /*yield*/, getReadTransformFuncs(t.args[0])];
                                case 1:
                                    _a.sent();
                                    _a.label = 2;
                                case 2: return [2 /*return*/];
                            }
                        });
                    })();
                },
                function (d) { return d; }
            ];
        case "list":
        case "set":
            return [
                function (d) {
                    if (!Array.isArray(d)) {
                        throw new utils_1.MichelsonTypeError(t, d, t.prim + " expected: " + JSON.stringify(d));
                    }
                    return (function () {
                        return __generator(this, function (_a) {
                            switch (_a.label) {
                                case 0:
                                    if (!true) return [3 /*break*/, 2];
                                    return [4 /*yield*/, getReadTransformFuncs(t.args[0])];
                                case 1:
                                    _a.sent();
                                    return [3 /*break*/, 0];
                                case 2: return [2 /*return*/];
                            }
                        });
                    })();
                },
                function (d) { return d; }
            ];
        case "map":
            return [
                function (d) {
                    if (!Array.isArray(d)) {
                        throw new utils_1.MichelsonTypeError(t, d, "map expected: " + JSON.stringify(d));
                    }
                    return (function () {
                        return __generator(this, function (_a) {
                            switch (_a.label) {
                                case 0:
                                    if (!true) return [3 /*break*/, 2];
                                    return [4 /*yield*/, [
                                            function (elt) {
                                                if (!("prim" in elt) || elt.prim !== "Elt") {
                                                    throw new utils_1.MichelsonTypeError(t, elt, "map element expected: " + JSON.stringify(elt));
                                                }
                                                return (function () {
                                                    var _a, _b, a, e_10_1;
                                                    var e_10, _c;
                                                    return __generator(this, function (_d) {
                                                        switch (_d.label) {
                                                            case 0:
                                                                _d.trys.push([0, 5, 6, 7]);
                                                                _a = __values(t.args), _b = _a.next();
                                                                _d.label = 1;
                                                            case 1:
                                                                if (!!_b.done) return [3 /*break*/, 4];
                                                                a = _b.value;
                                                                return [4 /*yield*/, getReadTransformFuncs(a)];
                                                            case 2:
                                                                _d.sent();
                                                                _d.label = 3;
                                                            case 3:
                                                                _b = _a.next();
                                                                return [3 /*break*/, 1];
                                                            case 4: return [3 /*break*/, 7];
                                                            case 5:
                                                                e_10_1 = _d.sent();
                                                                e_10 = { error: e_10_1 };
                                                                return [3 /*break*/, 7];
                                                            case 6:
                                                                try {
                                                                    if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
                                                                }
                                                                finally { if (e_10) throw e_10.error; }
                                                                return [7 /*endfinally*/];
                                                            case 7: return [2 /*return*/];
                                                        }
                                                    });
                                                })();
                                            },
                                            function (elt) { return elt; }
                                        ]];
                                case 1:
                                    _a.sent();
                                    return [3 /*break*/, 0];
                                case 2: return [2 /*return*/];
                            }
                        });
                    })();
                },
                function (d) { return d; }
            ];
        case "chain_id":
            return [
                function () { return [][Symbol.iterator](); },
                function (d) {
                    if (!("bytes" in d) && !("string" in d)) {
                        throw new utils_1.MichelsonTypeError(t, d, "chain id expected: " + JSON.stringify(d));
                    }
                    if ("string" in d) {
                        return d;
                    }
                    var bytes = utils_1.parseBytes(d.bytes);
                    if (bytes === null) {
                        throw new utils_1.MichelsonTypeError(t, d, "can't parse bytes: " + d.bytes);
                    }
                    return { string: utils_1.encodeTezosID("ChainID", bytes) };
                }
            ];
        case "signature":
            return [
                function () { return [][Symbol.iterator](); },
                function (d) {
                    if (!("bytes" in d) && !("string" in d)) {
                        throw new utils_1.MichelsonTypeError(t, d, "signature expected: " + JSON.stringify(d));
                    }
                    if ("string" in d) {
                        return d;
                    }
                    var bytes = utils_1.parseBytes(d.bytes);
                    if (bytes === null) {
                        throw new utils_1.MichelsonTypeError(t, d, "can't parse bytes: " + d.bytes);
                    }
                    return { string: utils_1.encodeTezosID("GenericSignature", bytes) };
                }
            ];
        case "key_hash":
            return [
                function () { return [][Symbol.iterator](); },
                function (d) {
                    if (!("bytes" in d) && !("string" in d)) {
                        throw new utils_1.MichelsonTypeError(t, d, "key hash expected: " + JSON.stringify(d));
                    }
                    if ("string" in d) {
                        return d;
                    }
                    var bytes = utils_1.parseBytes(d.bytes);
                    if (bytes === null) {
                        throw new utils_1.MichelsonTypeError(t, d, "can't parse bytes: " + d.bytes);
                    }
                    var rd = new Reader(new Uint8Array(bytes));
                    var addr = readPublicKeyHash(rd);
                    return { string: utils_1.encodeTezosID(addr.type, addr.hash) + (addr.entryPoint ? "%" + addr.entryPoint : "") };
                }
            ];
        case "key":
            return [
                function () { return [][Symbol.iterator](); },
                function (d) {
                    if (!("bytes" in d) && !("string" in d)) {
                        throw new utils_1.MichelsonTypeError(t, d, "public key expected: " + JSON.stringify(d));
                    }
                    if ("string" in d) {
                        return d;
                    }
                    var bytes = utils_1.parseBytes(d.bytes);
                    if (bytes === null) {
                        throw new utils_1.MichelsonTypeError(t, d, "can't parse bytes: " + d.bytes);
                    }
                    var rd = new Reader(new Uint8Array(bytes));
                    var pk = readPublicKey(rd);
                    return { string: utils_1.encodeTezosID(pk.type, pk.publicKey) };
                }
            ];
        case "address":
            return [
                function () { return [][Symbol.iterator](); },
                function (d) {
                    if (!("bytes" in d) && !("string" in d)) {
                        throw new utils_1.MichelsonTypeError(t, d, "address expected: " + JSON.stringify(d));
                    }
                    if ("string" in d) {
                        return d;
                    }
                    var bytes = utils_1.parseBytes(d.bytes);
                    if (bytes === null) {
                        throw new utils_1.MichelsonTypeError(t, d, "can't parse bytes: " + d.bytes);
                    }
                    var rd = new Reader(new Uint8Array(bytes));
                    var addr = readAddress(rd);
                    return { string: utils_1.encodeTezosID(addr.type, addr.hash) + (addr.entryPoint ? "%" + addr.entryPoint : "") };
                }
            ];
        case "timestamp":
            return [
                function () { return [][Symbol.iterator](); },
                function (d) {
                    if (!("int" in d) && !("string" in d)) {
                        throw new utils_1.MichelsonTypeError(t, d, "address expected: " + JSON.stringify(d));
                    }
                    if ("string" in d) {
                        return d;
                    }
                    var date = new Date(parseInt(d.int, 10) * 1000);
                    return { string: date.toISOString().slice(0, 19) + "Z" };
                }
            ];
        default:
            return readPassThrough;
    }
};
var readPassThrough = [
    function (e) {
        if (isPushInstruction(e)) {
            michelson_validator_1.assertMichelsonInstruction(e);
            // capture inlined type definition
            return (function () {
                return __generator(this, function (_a) {
                    switch (_a.label) {
                        case 0: return [4 /*yield*/, readPassThrough];
                        case 1:
                            _a.sent();
                            return [4 /*yield*/, getReadTransformFuncs(e.args[0])];
                        case 2:
                            _a.sent();
                            return [2 /*return*/];
                    }
                });
            })();
        }
        return (function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!true) return [3 /*break*/, 2];
                        return [4 /*yield*/, readPassThrough];
                    case 1:
                        _a.sent();
                        return [3 /*break*/, 0];
                    case 2: return [2 /*return*/];
                }
            });
        })();
    },
    function (e) { return e; }
];
/**
 * Deserialize a byte array into the corresponding Michelson value.
 * Without a type definition (not recommended) the binary data will be treated as a binary form of a generic Michelson expression and returned as is.
 * Type definition allows some types like `timestamp` and `address` and other types usually encoded in optimized binary forms to be transformed
 * back to their string representations like base58 and ISO timestamps.
 *
 * ```typescript
 * const src = [0x05, 0x00, 0xa7, 0xe8, 0xe4, 0xd8, 0x0b];
 *
 * const typ: MichelsonType = {
 *     prim: "timestamp"
 * };
 *
 * const data = unpackData(src, typ);
 *
 * // { string: "2019-09-26T10:59:51Z" }
 * ```
 *
 * Same binary data without a type definition
 * ```typescript
 * const src = [0x05, 0x00, 0xa7, 0xe8, 0xe4, 0xd8, 0x0b];
 *
 * const data = unpackData(src);
 *
 * // { int: "1569495591" }
 * ```
 * @param src Byte array
 * @param t Optional type definition
 * @returns Deserialized data
 */
function unpackData(src, t) {
    var r = new Reader(src);
    if (r.readUint8() !== 5) {
        throw new Error("incorrect packed data magic number");
    }
    var ex = readExpr(r, t !== undefined ? getReadTransformFuncs(t) : readPassThrough);
    if (michelson_validator_1.assertMichelsonData(ex)) {
        return ex;
    }
    throw new Error(); // never
}
exports.unpackData = unpackData;
/**
 * Deserialize a byte array into the corresponding Michelson value.
 * Same as {@link unpackData} but takes a `bytes` Michelson data literal instead of an array
 *
 * ```typescript
 * const src = { bytes: "0500a7e8e4d80b" };
 *
 * const typ: MichelsonType = {
 *     prim: "timestamp"
 * };
 *
 * const data = unpackDataBytes(src, typ);
 *
 * // { string: "2019-09-26T10:59:51Z" }
 * ```
 * @param src Bytes object
 * @param t Optional type definition
 * @returns Deserialized data
 */
function unpackDataBytes(src, t) {
    var bytes = utils_1.parseBytes(src.bytes);
    if (bytes === null) {
        throw new Error("can't parse bytes: \"" + src.bytes + "\"");
    }
    return unpackData(bytes, t);
}
exports.unpackDataBytes = unpackDataBytes;
// helper functions also used by validator
function decodeAddressBytes(b) {
    var bytes = utils_1.parseBytes(b.bytes);
    if (bytes === null) {
        throw new Error("can't parse bytes: \"" + b.bytes + "\"");
    }
    var rd = new Reader(new Uint8Array(bytes));
    return readAddress(rd);
}
exports.decodeAddressBytes = decodeAddressBytes;
function decodePublicKeyHashBytes(b) {
    var bytes = utils_1.parseBytes(b.bytes);
    if (bytes === null) {
        throw new Error("can't parse bytes: \"" + b.bytes + "\"");
    }
    var rd = new Reader(new Uint8Array(bytes));
    return readPublicKeyHash(rd);
}
exports.decodePublicKeyHashBytes = decodePublicKeyHashBytes;
function decodePublicKeyBytes(b) {
    var bytes = utils_1.parseBytes(b.bytes);
    if (bytes === null) {
        throw new Error("can't parse bytes: \"" + b.bytes + "\"");
    }
    var rd = new Reader(new Uint8Array(bytes));
    return readPublicKey(rd);
}
exports.decodePublicKeyBytes = decodePublicKeyBytes;
//# sourceMappingURL=binary.js.map