"use strict";
// tslint:disable:max-line-length
/*
"TODO: Remove this
ReferenceError: regeneratorRuntime is not defined
  at node_modules/@ledgerhq/hw-transport-u2f/lib/TransportU2F.js:120:50      at node_modules/@ledgerhq/hw-transport-u2f/lib/TransportU2F.js:142:6
  at Object.<anonymous> (node_modules/@ledgerhq/hw-transport-u2f/lib/TransportU2F.js:228:2)
  at Object.<anonymous> (node_modules/@0xproject/subproviders/src/index.ts:2:1)
*/
// tslint:enable:max-line-length
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const order_utils_1 = require("@0x/order-utils");
const bignumber_js_1 = require("bignumber.js");
const constants_1 = require("@0x/order-utils/lib/src/constants");
const token_math_1 = require("@melonproject/token-math");
const evm_1 = require("../../../../../utils/evm");
const getAssetProxy_1 = require("../calls/getAssetProxy");
const getToken_1 = require("../../../../dependencies/token/calls/getToken");
const approve_1 = require("../../../../dependencies/token/transactions/approve");
/**
 * For Ethfinex orders: The makerQuantity.token has to be the
 * Ethfinex Wrapper contract
 */
const createOrder = (environment, exchange, { makerQuantity, takerQuantity, duration = 24 * 60 * 60, makerAddress: givenMakerAddress, feeRecipientAddress, takerFee, }) => __awaiter(this, void 0, void 0, function* () {
    const makerAssetData = order_utils_1.assetDataUtils.encodeERC20AssetData(makerQuantity.token.address);
    const takerAssetData = order_utils_1.assetDataUtils.encodeERC20AssetData(takerQuantity.token.address);
    const latestBlock = yield evm_1.getLatestBlock(environment);
    const makerAddress = givenMakerAddress || environment.wallet.address;
    const formattedTakerFee = takerFee
        ? new bignumber_js_1.BigNumber(`${takerFee}`)
        : constants_1.constants.ZERO_AMOUNT;
    // tslint:disable:object-literal-sort-keys
    const order = {
        exchangeAddress: `${exchange.toLowerCase()}`,
        makerAddress: `${makerAddress.toLowerCase()}`,
        takerAddress: constants_1.constants.NULL_ADDRESS,
        senderAddress: constants_1.constants.NULL_ADDRESS,
        feeRecipientAddress: (feeRecipientAddress || constants_1.constants.NULL_ADDRESS).toLowerCase(),
        expirationTimeSeconds: new bignumber_js_1.BigNumber(token_math_1.add(token_math_1.toBI(latestBlock.timestamp), token_math_1.toBI(duration)).toString()),
        salt: order_utils_1.generatePseudoRandomSalt(),
        makerAssetAmount: new bignumber_js_1.BigNumber(`${makerQuantity.quantity}`),
        takerAssetAmount: new bignumber_js_1.BigNumber(`${takerQuantity.quantity}`),
        makerAssetData,
        takerAssetData,
        makerFee: constants_1.constants.ZERO_AMOUNT,
        takerFee: formattedTakerFee,
    };
    return order;
});
exports.createOrder = createOrder;
const approveOrder = (environment, exchange, order) => __awaiter(this, void 0, void 0, function* () {
    const erc20Proxy = yield getAssetProxy_1.getAssetProxy(environment, exchange);
    const makerTokenAddress = order_utils_1.assetDataUtils.decodeERC20AssetData(order.makerAssetData).tokenAddress;
    const makerToken = yield getToken_1.getToken(environment, makerTokenAddress);
    const makerQuantity = token_math_1.createQuantity(makerToken, order.makerAssetAmount.toString());
    yield approve_1.approve(environment, { howMuch: makerQuantity, spender: erc20Proxy });
});
exports.approveOrder = approveOrder;
const isValidSignatureOffChain = (environment, order, signature, makerAddress) => __awaiter(this, void 0, void 0, function* () {
    const orderHashHex = order_utils_1.orderHashUtils.getOrderHashHex(order);
    return order_utils_1.signatureUtils.isValidSignatureAsync(environment.eth.currentProvider, orderHashHex, signature, (makerAddress || environment.wallet.address).toString());
});
exports.isValidSignatureOffChain = isValidSignatureOffChain;
