"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.genericSignRawOperation = void 0;
const rxjs_1 = require("rxjs");
const alpaca_1 = require("./alpaca");
const utils_1 = require("./utils");
const logs_1 = require("@ledgerhq/logs");
const bignumber_js_1 = __importDefault(require("bignumber.js"));
/**
 * Sign Transaction with Ledger hardware
 */
const genericSignRawOperation = (network, kind) => (signerContext) => ({ account, transaction, deviceId, }) => new rxjs_1.Observable(o => {
    async function main() {
        const alpacaApi = (0, alpaca_1.getAlpacaApi)(account.currency.id, kind);
        const signedInfo = await signerContext(deviceId, async (signer) => {
            const derivationPath = account.freshAddressPath;
            const { publicKey } = (await signer.getAddress(derivationPath));
            const sender = account.freshAddress;
            // TODO: should compute it and pass it down to craftTransaction (duplicate call right now)
            const sequenceNumber = await alpacaApi.getSequence(sender);
            /* Craft unsigned blob via Alpaca */
            const { transaction: unsigned } = await alpacaApi.craftRawTransaction(transaction, sender, publicKey, sequenceNumber);
            /* 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 alpacaApi.combine(signedInfo.unsigned, signedInfo.txnSig, signedInfo.publicKey);
        const operation = (0, utils_1.buildOptimisticOperation)(account, { family: account.currency.family, amount: new bignumber_js_1.default(0), recipient: "" }, signedInfo.sequence);
        if (!operation.id) {
            (0, logs_1.log)("Generic alpaca", "buildOptimisticOperation", operation);
        }
        // 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.genericSignRawOperation = genericSignRawOperation;
//# sourceMappingURL=signRawOperation.js.map