<commit_before>(function () {
    'use strict';

    /**
     * @param {Base} Base
     * @param {app.utils} utils
     * @param {EventManager} eventManager
     * @param {User} user
     * @param {ConfigService} configService
     * @return {BaseNodeComponent}
     */
    const factory = function (Base, utils, eventManager, user, configService) {

        const ds = require('data-service');
        const { Money } = require('@waves/data-entities');
        const { currentFeeFactory, SIGN_TYPE } = require('@waves/signature-adapter');
        const { libs } = require('@waves/waves-transactions');
        const { address, base58decode } = libs.crypto;
        const { path } = require('ramda');
        const { BigNumber } = require('@waves/bignumber');

        const MULTY_FEE_TRANSACTIONS = {
            [SIGN_TYPE.TRANSFER]: true
        };


        class BaseNodeComponent extends Base {

            get matcher() {
                return user.getSetting('network.matcher');
            }

            get node() {
                return user.getSetting('network.node');
            }


            /**
             * Get list of available fee for transaction
             * @param {*} tx
             * @return {Promise<Money[]>}
             * @protected
             */
            _feeList({ tx }) {
                const feeConfig = configService.getFeeConfig();
                const currentFee = currentFeeFactory(feeConfig);

                return this._fillTransaction(tx)
                    .then(tx => {

                        return Promise.all([
                            this._getAssets(tx)
                                .then(assetList => assetList.filter(asset => asset.hasScript))
                                .then(assetList => assetList.map(asset => asset.id)),
                            ds.signature.getSignatureApi().makeSignable({ type: tx.type, data: tx }).getBytes(),
                            ds.api.assets.get('WAVES'),
                            this._isSmartAccount(tx)
                        ]).then(([smartAssetsIdList, bytes, wavesAsset, hasScript]) => {
                            const bigNumberFee = currentFee(tx, bytes, hasScript, smartAssetsIdList);
                            const count = bigNumberFee
                                .div(feeConfig.calculate_fee_rules.default.fee)
                                .roundTo(0, BigNumber.ROUND_MODE.ROUND_UP);

                            const fee = new Money(bigNumberFee, wavesAsset);
                            const feeList = ds.utils.getTransferFeeList()
                                .map(money => money.cloneWithTokens(money.getTokens().mul(count)));

                            return MULTY_FEE_TRANSACTIONS[tx.type] ? [fee, ...feeList] : [fee];
                        });
                    });
            }

            /**
             * @param {*} tx
             * @param {Money} [fee]
             * @return {Promise<Money>}
             */
            getFee(tx, fee) {
                return this._feeList({ tx })
                    .then((list) => {
                        if (fee) {
                            const hash = utils.toHash(list, 'asset.id');
                            if (hash[fee.asset.id] && hash[fee.asset.id].getTokens().lte(fee.getTokens())) {
                                return fee;
                            } else {
                                throw new Error('Wrong fee!');
                            }
                        } else {
                            return list[0];
                        }
                    });
            }

            /**
             * @param {*} tx
             * @return {Promise<Money[]>}
             */
            getFeeList(tx) {
                return this._feeList({ tx });
            }

            /**
             * @param tx
             * @return {Promise<boolean>}
             * @private
             */
            _isSmartAccount(tx) {
                const publicKey = tx.senderPublicKey;

                if (!publicKey || user.publicKey === publicKey) {
                    return Promise.resolve(user.hasScript());
                }

                const wavesAddress = address(base58decode(publicKey), WavesApp.network.code);

                return ds.api.address.getScriptInfo(wavesAddress)
                    .then(data => data.extraFee.getTokens().gt(0));
            }

            /**<commit_msg>CLIENT-1867: fix crypto<commit_after>(function () {
    'use strict';

    /**
     * @param {Base} Base
     * @param {app.utils} utils
     * @param {EventManager} eventManager
     * @param {User} user
     * @param {ConfigService} configService
     * @return {BaseNodeComponent}
     */
    const factory = function (Base, utils, eventManager, user, configService) {

        const ds = require('data-service');
        const { Money } = require('@waves/data-entities');
        const { currentFeeFactory, SIGN_TYPE } = require('@waves/signature-adapter');
        const { libs } = require('@waves/waves-transactions');
        const { address } = libs.crypto;
        const { path } = require('ramda');
        const { BigNumber } = require('@waves/bignumber');

        const MULTY_FEE_TRANSACTIONS = {
            [SIGN_TYPE.TRANSFER]: true
        };


        class BaseNodeComponent extends Base {

            get matcher() {
                return user.getSetting('network.matcher');
            }

            get node() {
                return user.getSetting('network.node');
            }


            /**
             * Get list of available fee for transaction
             * @param {*} tx
             * @return {Promise<Money[]>}
             * @protected
             */
            _feeList({ tx }) {
                const feeConfig = configService.getFeeConfig();
                const currentFee = currentFeeFactory(feeConfig);

                return this._fillTransaction(tx)
                    .then(tx => {

                        return Promise.all([
                            this._getAssets(tx)
                                .then(assetList => assetList.filter(asset => asset.hasScript))
                                .then(assetList => assetList.map(asset => asset.id)),
                            ds.signature.getSignatureApi().makeSignable({ type: tx.type, data: tx }).getBytes(),
                            ds.api.assets.get('WAVES'),
                            this._isSmartAccount(tx)
                        ]).then(([smartAssetsIdList, bytes, wavesAsset, hasScript]) => {
                            const bigNumberFee = currentFee(tx, bytes, hasScript, smartAssetsIdList);
                            const count = bigNumberFee
                                .div(feeConfig.calculate_fee_rules.default.fee)
                                .roundTo(0, BigNumber.ROUND_MODE.ROUND_UP);

                            const fee = new Money(bigNumberFee, wavesAsset);
                            const feeList = ds.utils.getTransferFeeList()
                                .map(money => money.cloneWithTokens(money.getTokens().mul(count)));

                            return MULTY_FEE_TRANSACTIONS[tx.type] ? [fee, ...feeList] : [fee];
                        });
                    });
            }

            /**
             * @param {*} tx
             * @param {Money} [fee]
             * @return {Promise<Money>}
             */
            getFee(tx, fee) {
                return this._feeList({ tx })
                    .then((list) => {
                        if (fee) {
                            const hash = utils.toHash(list, 'asset.id');
                            if (hash[fee.asset.id] && hash[fee.asset.id].getTokens().lte(fee.getTokens())) {
                                return fee;
                            } else {
                                throw new Error('Wrong fee!');
                            }
                        } else {
                            return list[0];
                        }
                    });
            }

            /**
             * @param {*} tx
             * @return {Promise<Money[]>}
             */
            getFeeList(tx) {
                return this._feeList({ tx });
            }

            /**
             * @param tx
             * @return {Promise<boolean>}
             * @private
             */
            _isSmartAccount(tx) {
                const publicKey = tx.senderPublicKey;

                if (!publicKey || user.publicKey === publicKey) {
                    return Promise.resolve(user.hasScript());
                }

                const wavesAddress = address({ publicKey }, WavesApp.network.code);

                return ds.api.address.getScriptInfo(wavesAddress)
                    .then(data => data.extraFee.getTokens().gt(0));
            }

            /**
{'fraction_non_alphanumeric': 0.11597300337457818, 'fraction_numerical': 0.0015748031496062992, 'mean_word_length': 1.1711843711843712, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1792009', 'n_tokens_mistral': 2291, 'n_tokens_neox': 2175, 'n_words': 404}