"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.genericSignOperation = void 0;
const rxjs_1 = require("rxjs");
const alpaca_1 = require("./alpaca");
const utils_1 = require("./utils");
const errors_1 = require("@ledgerhq/errors");
/**
 * Sign Transaction with Ledger hardware
 */
const genericSignOperation = (network, kind) => (signerContext) => ({ account, transaction, deviceId, }) => new rxjs_1.Observable(o => {
    async function main() {
        if (!transaction["fees"])
            throw new errors_1.FeeNotLoaded();
        const signedInfo = await signerContext(deviceId, async (signer) => {
            const derivationPath = account.freshAddressPath;
            const { publicKey } = (await signer.getAddress(derivationPath));
            const transactionIntent = (0, utils_1.transactionToIntent)(account, transaction);
            transactionIntent.senderPublicKey = publicKey;
            // NOTE: is setting the memo here instead of transactionToIntent sensible?
            const txWithMemo = transactionIntent;
            if (transaction["tag"]) {
                const txMemo = String(transaction["tag"]);
                txWithMemo.memo = {
                    type: "map",
                    memos: new Map(),
                };
                txWithMemo.memo.memos.set("destinationTag", txMemo);
            }
            /* Craft unsigned blob via Alpaca */
            const unsigned = await (0, alpaca_1.getAlpacaApi)(network, kind).craftTransaction(transactionIntent);
            // TODO: should compute it and pass it down to craftTransaction (duplicate call right now)
            const accountInfo = await (0, alpaca_1.getAlpacaApi)(network, kind).getAccountInfo(transactionIntent.sender);
            const sequenceNumber = accountInfo.sequence;
            /* Notify UI that the device is now showing the tx */
            o.next({ type: "device-signature-requested" });
            /* Sign on Ledger device */
            const txnSig = await signer.signTransaction(derivationPath, unsigned);
            return { unsigned, txnSig, publicKey, sequence: sequenceNumber };
        });
        /* If the user cancelled inside signerContext */
        if (!signedInfo)
            return;
        o.next({ type: "device-signature-granted" });
        /* Combine payload + signature for broadcast */
        const combined = await (0, alpaca_1.getAlpacaApi)(network, kind).combine(signedInfo.unsigned, signedInfo.txnSig, signedInfo.publicKey);
        const operation = (0, utils_1.buildOptimisticOperation)(account, transaction, signedInfo.sequence);
        // NOTE: we set the transactionSequenceNumber before on the operation
        // now that we create it in craftTransaction, we might need to return it back from craftTransaction also
        o.next({
            type: "signed",
            signedOperation: {
                operation,
                signature: combined,
            },
        });
    }
    main().then(() => o.complete(), e => o.error(e));
});
exports.genericSignOperation = genericSignOperation;
//# sourceMappingURL=signOperation.js.map