"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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PeppolV1 = void 0;
const base64_js_1 = __importDefault(require("@root/encoding/base64.js"));
const core_1 = require("@ts-bitcoin/core");
const cbor_1 = __importDefault(require("cbor"));
const jose = __importStar(require("jose"));
const cbor_jose_js_1 = require("../../cbor-jose.js");
const lzma = __importStar(require("../../lzma.js"));
const utils_js_1 = require("../../utils.js");
class PeppolV1 {
    constructor(options) {
        this.createOptions = options.create;
        this.parseOptions = options.parse;
        this.info = options.info;
    }
    static async create(options) {
        var _a, _b;
        const { jwk: pubKeyJWK } = await (0, utils_js_1.JWKOrHexKeyToCryptoKeyAndJWK)(options.pubKey, 'ECDH', 'p256');
        const importedPubKey = await jose.importJWK(pubKeyJWK, 'ECDH-ES');
        const payload = cbor_1.default.encode([options.value, (_a = options.options) === null || _a === void 0 ? void 0 : _a.extra]);
        const compressed = await lzma.compress(payload, 9);
        const l0 = await new jose.GeneralEncrypt(compressed)
            .setProtectedHeader({ enc: 'A256GCM' })
            .addRecipient(importedPubKey)
            .setUnprotectedHeader({ alg: 'ECDH-ES+A256KW' })
            .encrypt();
        const cl0 = (0, cbor_jose_js_1.jose2cbor)(l0);
        let final = cl0;
        if (options.signingKey) {
            const _l1 = await new jose.GeneralSign(cl0);
            const { jwk, cryptoKey } = await (0, utils_js_1.JWKOrHexKeyToCryptoKeyAndJWK)(options.signingKey, 'ECDSA', 'p256');
            const kid = await jose.calculateJwkThumbprint(jwk);
            _l1.addSignature(cryptoKey).setProtectedHeader({ alg: 'ES256', kid: kid });
            const l1 = await _l1.sign();
            final = (0, cbor_jose_js_1.jose2cbor)(l1);
        }
        const uncompressedPublicKey = (0, utils_js_1.JWKToUncompressedHex)(pubKeyJWK);
        const info = {
            type: 'peppol',
            version: 1,
            options: {
                extra: (_b = options.options) === null || _b === void 0 ? void 0 : _b.extra,
            },
            pubKey: uncompressedPublicKey,
            value: options.value,
            encryptedData: final,
        };
        return new PeppolV1({ create: options, parse: null, info: info });
    }
    static async parse(options) {
        const { data, privateKey, verifyKey } = options;
        const importedPrivateKey = await jose.importJWK(privateKey, 'ECDH-ES');
        const l1 = (0, cbor_jose_js_1.cbor2jose)(data);
        let l0;
        if ('ciphertext' in l1) {
            l0 = l1;
        }
        else if ('signatures' in l1) {
            // Optionally verify
            if (verifyKey) {
                const l1verify = await jose.generalVerify(l1, await jose.importJWK(verifyKey, 'ES256'));
                l0 = (0, cbor_jose_js_1.cbor2jose)(l1verify.payload);
            }
            else {
                // Signature present but not choosing to verify
                l0 = (0, cbor_jose_js_1.cbor2jose)(base64_js_1.default.base64ToBuf(l1.payload));
            }
        }
        const l0decrypted = await jose.generalDecrypt(l0, importedPrivateKey, {});
        const l0decrypteddata = l0decrypted.plaintext;
        const decompressed = await lzma.decompress(l0decrypteddata);
        const [originaldata, extra] = cbor_1.default.decode(decompressed);
        const info = {
            type: 'peppol',
            encryptedData: data,
            options: {
                extra: extra,
            },
            pubKey: options.pubKey,
            value: originaldata,
            version: 1,
        };
        return new PeppolV1({ create: null, parse: options, info: info });
    }
    static async fromOpReturnScriptHex(script, options) {
        const s = core_1.Script.fromHex(script);
        return PeppolV1.parse({
            data: s.chunks[s.chunks.length - 2].buf,
            privateKey: options.privateKey,
            pubKey: s.chunks[s.chunks.length - 1].buf.toString('hex'),
            verifyKey: options.verifyKey,
        });
    }
    toOpReturnScriptHex() {
        const s = core_1.Script.fromSafeDataArray([
            Buffer.from(PeppolV1.PROTOCOL_ID),
            this.info.encryptedData,
            Buffer.from(this.info.pubKey),
        ]);
        return s.toHex();
    }
}
PeppolV1.PROTOCOL_ID = 'mB:peppol';
exports.PeppolV1 = PeppolV1;
//# sourceMappingURL=data:application/json;base64, 