"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createAction = void 0;
const rxjs_1 = require("rxjs");
const operators_1 = require("rxjs/operators");
const react_1 = require("react");
const logs_1 = require("@ledgerhq/logs");
const errors_1 = require("@ledgerhq/errors");
const errors_2 = require("../../errors");
const account_1 = require("../../account");
const bridge_1 = require("../../bridge");
const app_1 = require("./app");
const mapResult = ({ device, signedOperation, transactionSignError, }) => signedOperation && device
    ? {
        signedOperation,
        device,
    }
    : transactionSignError
        ? {
            transactionSignError,
        }
        : null;
const initialState = {
    signedOperation: null,
    deviceSignatureRequested: false,
    deviceStreamingProgress: null,
    transactionSignError: null,
    transactionChecksOptInTriggered: false,
    transactionChecksOptIn: null,
};
const reducer = (state, e) => {
    switch (e.type) {
        case "error": {
            const { error } = e;
            const transactionSignError = error instanceof errors_1.TransportStatusError && error.statusCode === 0x6985
                ? new errors_2.TransactionRefusedOnDevice()
                : error;
            return { ...initialState, transactionSignError };
        }
        case "signed":
            return { ...state, signedOperation: e.signedOperation };
        case "device-signature-requested":
            return { ...state, deviceSignatureRequested: true };
        case "device-signature-granted":
            return { ...state, deviceSignatureRequested: false };
        case "device-streaming":
            return { ...state, deviceStreamingProgress: e.progress };
        case "transaction-checks-opt-in-triggered":
            return { ...state, transactionChecksOptInTriggered: true };
        case "transaction-checks-opt-in":
            return { ...state, transactionChecksOptIn: true };
        case "transaction-checks-opt-out":
            return { ...state, transactionChecksOptIn: false };
        default:
            return state;
    }
};
const createAction = (connectAppExec) => {
    const useHook = (reduxDevice, { account, parentAccount, transaction, appName, dependencies, requireLatestFirmware, manifestId, manifestName, }) => {
        const mainAccount = (0, account_1.getMainAccount)(account, parentAccount);
        const appState = (0, app_1.createAction)(connectAppExec).useHook(reduxDevice, {
            account: mainAccount,
            appName,
            dependencies,
            requireLatestFirmware,
        });
        const { device, opened, inWrongDeviceForAccount, error } = appState;
        const [state, setState] = (0, react_1.useState)(initialState);
        (0, react_1.useEffect)(() => {
            if (!device || !opened || inWrongDeviceForAccount || error) {
                setState(initialState);
                return;
            }
            const bridge = (0, bridge_1.getAccountBridge)(mainAccount);
            const sub = bridge
                .signRawOperation({
                account: mainAccount,
                transaction,
                deviceId: device.deviceId,
                deviceModelId: device.modelId,
            })
                .pipe((0, operators_1.catchError)(error => (0, rxjs_1.of)({
                type: "error",
                error,
            })), (0, operators_1.tap)((e) => (0, logs_1.log)("actions-transaction-event", e.type, e)), (0, operators_1.scan)(reducer, initialState))
                .subscribe((x) => setState(x));
            return () => {
                sub.unsubscribe();
            };
        }, [device, mainAccount, transaction, opened, inWrongDeviceForAccount, error]);
        return {
            ...appState,
            ...state,
            manifestId,
            manifestName,
            deviceStreamingProgress: state.signedOperation || state.transactionSignError
                ? null // when good app is opened, we start the progress so it doesn't "blink"
                : state.deviceStreamingProgress || (appState.opened ? 0 : null),
        };
    };
    return {
        useHook,
        mapResult,
    };
};
exports.createAction = createAction;
//# sourceMappingURL=rawTransaction.js.map