"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vector_types_1 = require("@connext/vector-types");
const vector_utils_1 = require("@connext/vector-utils");
const constants_1 = require("@ethersproject/constants");
const providers_1 = require("@ethersproject/providers");
const ethers_1 = require("ethers");
const sinon_1 = require("sinon");
const ethService_1 = require("./ethService");
let storeMock;
let signer;
let ethService;
let provider1337;
let provider1338;
let sendTxWithRetriesMock;
let approveMock;
let getCodeMock;
let getOnchainBalanceMock;
let channelState;
const assertResult = (result, isError, unwrappedVal) => {
    var _a;
    if (isError) {
        vector_utils_1.expect(result.isError).to.be.true;
        if (unwrappedVal) {
            vector_utils_1.expect((_a = result.getError()) === null || _a === void 0 ? void 0 : _a.message).to.be.eq(unwrappedVal);
        }
    }
    else {
        vector_utils_1.expect(result.isError).to.be.false;
        if (unwrappedVal) {
            vector_utils_1.expect(result.getValue()).to.deep.eq(unwrappedVal);
        }
    }
};
const _txResponse = {
    chainId: 1337,
    confirmations: 1,
    data: "0x",
    from: constants_1.AddressZero,
    gasLimit: constants_1.One,
    gasPrice: constants_1.One,
    hash: vector_utils_1.mkHash(),
    nonce: 1,
    value: constants_1.Zero,
    wait: () => Promise.resolve({}),
};
const txResponse = Object.assign(Object.assign({}, _txResponse), { completed: () => Promise.resolve(vector_types_1.Result.ok({})) });
const { log } = vector_utils_1.getTestLoggers("ethService");
describe("ethService", () => {
    beforeEach(() => {
        storeMock = sinon_1.createStubInstance(vector_utils_1.MemoryStoreService);
        signer = sinon_1.createStubInstance(vector_utils_1.ChannelSigner);
        signer.connect.returns(signer);
        signer._isSigner = true;
        const _provider = sinon_1.createStubInstance(providers_1.JsonRpcProvider);
        _provider.getTransaction.resolves(_txResponse);
        provider1337 = _provider;
        provider1338 = _provider;
        signer.provider = provider1337;
        ethService = new ethService_1.EthereumChainService(storeMock, {
            1337: provider1337,
            1338: provider1338,
        }, signer, log);
        getCodeMock = sinon_1.stub(ethService, "getCode").resolves(vector_types_1.Result.ok("0x"));
        approveMock = sinon_1.stub(ethService, "approveTokens").resolves(vector_types_1.Result.ok(txResponse));
        getOnchainBalanceMock = sinon_1.stub(ethService, "getOnchainBalance").resolves(vector_types_1.Result.ok(ethers_1.BigNumber.from("100")));
        const test = vector_utils_1.createTestChannelState("create");
        channelState = test.channel;
        channelState.networkContext.chainId = 1337;
        signer.getAddress.resolves(channelState.alice);
    });
    afterEach(() => {
        sinon_1.restore();
        sinon_1.reset();
    });
    describe("sendDeployChannelTx", () => {
        beforeEach(() => {
            sendTxWithRetriesMock = sinon_1.stub(ethService, "sendTxWithRetries").resolves(vector_types_1.Result.ok(txResponse));
        });
        it("errors if cannot get a signer", async () => {
            channelState.networkContext.chainId = 1234;
            const result = await ethService.sendDeployChannelTx(channelState);
            assertResult(result, true, vector_types_1.ChainError.reasons.SignerNotFound);
        });
        it("errors if multisig code cannot be retrieved", async () => {
            getCodeMock.resolves(vector_types_1.Result.fail(new vector_types_1.ChainError("getCode error")));
            const result = await ethService.sendDeployChannelTx(channelState);
            assertResult(result, true, "getCode error");
        });
        it("errors if multisig is already deployed", async () => {
            getCodeMock.resolves(vector_types_1.Result.ok(vector_utils_1.mkHash("0xabc")));
            const result = await ethService.sendDeployChannelTx(channelState);
            assertResult(result, true, vector_types_1.ChainError.reasons.MultisigDeployed);
        });
        it("errors if multisig deployment fails without deposit", async () => {
            sendTxWithRetriesMock.resolves(vector_types_1.Result.fail(new vector_types_1.ChainError(vector_types_1.ChainError.reasons.TxReverted)));
            const result = await ethService.sendDeployChannelTx(channelState);
            assertResult(result, true, vector_types_1.ChainError.reasons.TxReverted);
        });
        it("errors if multisig deployment returns nothing", async () => {
            sendTxWithRetriesMock.resolves(vector_types_1.Result.ok(undefined));
            const result = await ethService.sendDeployChannelTx(channelState);
            assertResult(result, true, vector_types_1.ChainError.reasons.MultisigDeployed);
        });
        it("errors if deposit and is not alice", async () => {
            signer.getAddress.resolves(channelState.bob);
            const result = await ethService.sendDeployChannelTx(channelState, {
                amount: "1",
                assetId: constants_1.AddressZero,
            });
            assertResult(result, true, vector_types_1.ChainError.reasons.FailedToDeploy);
        });
        it("errors if deposit and cannot get onchain balance", async () => {
            getOnchainBalanceMock.resolves(vector_types_1.Result.fail(new vector_types_1.ChainError(vector_types_1.ChainError.reasons.TxNotFound)));
            const result = await ethService.sendDeployChannelTx(channelState, {
                amount: "1",
                assetId: constants_1.AddressZero,
            });
            assertResult(result, true, vector_types_1.ChainError.reasons.TxNotFound);
        });
        it("errors if deposit and not enough onchain balance", async () => {
            getOnchainBalanceMock.resolves(vector_types_1.Result.ok(ethers_1.BigNumber.from("9")));
            const result = await ethService.sendDeployChannelTx(channelState, {
                amount: "10",
                assetId: constants_1.AddressZero,
            });
            assertResult(result, true, vector_types_1.ChainError.reasons.NotEnoughFunds);
        });
        it("errors if error on approve", async () => {
            approveMock.resolves(vector_types_1.Result.fail(new vector_types_1.ChainError(vector_types_1.ChainError.reasons.NotEnoughFunds)));
            const result = await ethService.sendDeployChannelTx(channelState, {
                amount: "1",
                assetId: vector_utils_1.mkAddress("0xa"),
            });
            assertResult(result, true, vector_types_1.ChainError.reasons.NotEnoughFunds);
        });
        it("happy: alice can deploy channel without deposit", async () => {
            const result = await ethService.sendDeployChannelTx(channelState);
            assertResult(result, false, txResponse);
            const call = sendTxWithRetriesMock.getCall(0);
            vector_utils_1.expect(call.args[0]).to.eq(channelState.channelAddress);
            vector_utils_1.expect(call.args[1]).to.eq(channelState.networkContext.chainId);
            vector_utils_1.expect(call.args[2]).to.eq(vector_types_1.TransactionReason.deploy);
        });
        it("happy: bob can deploy channel without deposit", async () => {
            signer.getAddress.resolves(channelState.bob);
            const result = await ethService.sendDeployChannelTx(channelState);
            assertResult(result, false, txResponse);
            const call = sendTxWithRetriesMock.getCall(0);
            vector_utils_1.expect(call.args[0]).to.eq(channelState.channelAddress);
            vector_utils_1.expect(call.args[1]).to.eq(channelState.networkContext.chainId);
            vector_utils_1.expect(call.args[2]).to.eq(vector_types_1.TransactionReason.deploy);
        });
        it("happy: calls createChannelAndDepositAlice with native asset if 0x000... deposit", async () => {
            const result = await ethService.sendDeployChannelTx(channelState, {
                amount: "1",
                assetId: constants_1.AddressZero,
            });
            assertResult(result, false, txResponse);
            const call = sendTxWithRetriesMock.getCall(0);
            vector_utils_1.expect(call.args[0]).to.eq(channelState.channelAddress);
            vector_utils_1.expect(call.args[1]).to.eq(channelState.networkContext.chainId);
            vector_utils_1.expect(call.args[2]).to.eq(vector_types_1.TransactionReason.deployWithDepositAlice);
        });
        it("happy: calls createChannelAndDepositAlice with tokens if token deposit", async () => {
            const result = await ethService.sendDeployChannelTx(channelState, {
                amount: "1",
                assetId: vector_utils_1.mkAddress("0xa"),
            });
            assertResult(result, false);
            const approveCall = approveMock.getCall(0);
            vector_utils_1.expect(approveCall.args[0]).to.eq(channelState.channelAddress);
            vector_utils_1.expect(approveCall.args[1]).to.eq(channelState.networkContext.channelFactoryAddress);
            vector_utils_1.expect(approveCall.args[2]).to.eq(channelState.alice);
            vector_utils_1.expect(approveCall.args[3]).to.eq("1");
            vector_utils_1.expect(approveCall.args[4]).to.eq(vector_utils_1.mkAddress("0xa"));
            vector_utils_1.expect(approveCall.args[5]).to.eq(channelState.networkContext.chainId);
            const call = sendTxWithRetriesMock.getCall(0);
            vector_utils_1.expect(call.args[0]).to.eq(channelState.channelAddress);
            vector_utils_1.expect(call.args[1]).to.eq(channelState.networkContext.chainId);
            vector_utils_1.expect(call.args[2]).to.eq("deployWithDepositAlice");
        });
    });
    describe("sendWithdrawTx", () => {
        const minTx = {
            data: vector_utils_1.mkBytes32("0xabc"),
            to: constants_1.AddressZero,
            value: 0,
        };
        let sendDeployChannelTxMock;
        beforeEach(() => {
            sendDeployChannelTxMock = sinon_1.stub(ethService, "sendDeployChannelTx").resolves(vector_types_1.Result.ok(txResponse));
            sendTxWithRetriesMock = sinon_1.stub(ethService, "sendTxWithRetries").resolves(vector_types_1.Result.ok(txResponse));
        });
        it("errors if cannot get a signer", async () => {
            channelState.networkContext.chainId = 1234;
            const result = await ethService.sendWithdrawTx(channelState, minTx);
            assertResult(result, true, vector_types_1.ChainError.reasons.SignerNotFound);
        });
        it("errors if multisig code cannot be retrieved", async () => {
            getCodeMock.resolves(vector_types_1.Result.fail(new vector_types_1.ChainError("getCode error")));
            const result = await ethService.sendWithdrawTx(channelState, minTx);
            assertResult(result, true, "getCode error");
        });
        it("errors if channel deployment fails", async () => {
            sendDeployChannelTxMock.resolves(vector_types_1.Result.fail(new vector_types_1.ChainError(vector_types_1.ChainError.reasons.NotEnoughFunds)));
            const result = await ethService.sendWithdrawTx(channelState, minTx);
            assertResult(result, true, vector_types_1.ChainError.reasons.FailedToDeploy);
        });
        it("errors if deploy tx receipt is status = 0", async () => {
            sendDeployChannelTxMock.resolves(vector_types_1.Result.ok(Object.assign(Object.assign({}, txResponse), { wait: () => Promise.resolve({ status: 0 }) })));
            const result = await ethService.sendWithdrawTx(channelState, minTx);
            assertResult(result, true, vector_types_1.ChainError.reasons.TxReverted);
        });
        it("errors if deploy tx throws an error", async () => {
            sendDeployChannelTxMock.resolves(vector_types_1.Result.ok(Object.assign(Object.assign({}, txResponse), { wait: () => Promise.reject("Booo") })));
            const result = await ethService.sendWithdrawTx(channelState, minTx);
            assertResult(result, true, vector_types_1.ChainError.reasons.FailedToDeploy);
        });
        it("happy: if channel is deployed, send withdrawal tx", async () => {
            getCodeMock.resolves(vector_types_1.Result.ok(vector_utils_1.mkHash("0xabc")));
            const result = await ethService.sendWithdrawTx(channelState, minTx);
            vector_utils_1.expect(sendDeployChannelTxMock.callCount).to.eq(0);
            assertResult(result, false, txResponse);
        });
        it("happy: if channel is not deployed, deploy channel then send withdrawal tx", async () => {
            const result = await ethService.sendWithdrawTx(channelState, minTx);
            vector_utils_1.expect(sendDeployChannelTxMock.callCount).to.eq(1);
            vector_utils_1.expect(sendDeployChannelTxMock.getCall(0).firstArg).to.deep.eq(channelState);
            assertResult(result, false, txResponse);
        });
    });
    describe("sendDepositTx", () => {
        let sendDeployChannelTxMock;
        let sendDepositATxMock;
        let sendDepositBTxMock;
        beforeEach(() => {
            sendDeployChannelTxMock = sinon_1.stub(ethService, "sendDeployChannelTx").resolves(vector_types_1.Result.ok(txResponse));
            sendDepositATxMock = sinon_1.stub(ethService, "sendDepositATx").resolves(vector_types_1.Result.ok(txResponse));
            sendDepositBTxMock = sinon_1.stub(ethService, "sendDepositBTx").resolves(vector_types_1.Result.ok(txResponse));
            sendTxWithRetriesMock = sinon_1.stub(ethService, "sendTxWithRetries").resolves(vector_types_1.Result.ok(txResponse));
        });
        it("errors if cannot get a signer", async () => {
            channelState.networkContext.chainId = 1234;
            const result = await ethService.sendDepositTx(channelState, channelState.alice, "1", constants_1.AddressZero);
            assertResult(result, true, vector_types_1.ChainError.reasons.SignerNotFound);
        });
        it("errors if sender is not in channel", async () => {
            const result = await ethService.sendDepositTx(channelState, vector_utils_1.mkAddress("0xababab"), "1", constants_1.AddressZero);
            assertResult(result, true, vector_types_1.ChainError.reasons.SenderNotInChannel);
        });
        it("errors if deposit amount is negative", async () => {
            const result = await ethService.sendDepositTx(channelState, channelState.alice, "-1", constants_1.AddressZero);
            assertResult(result, true, vector_types_1.ChainError.reasons.NegativeDepositAmount);
        });
        it("errors if multisig code cannot be retrieved", async () => {
            getCodeMock.resolves(vector_types_1.Result.fail(new vector_types_1.ChainError("getCode error")));
            const result = await ethService.sendDepositTx(channelState, channelState.alice, "1", constants_1.AddressZero);
            assertResult(result, true, "getCode error");
        });
        it("errors if onchain balance returns an error", async () => {
            getCodeMock.resolves(vector_types_1.Result.ok(vector_utils_1.mkHash("0xabc")));
            getOnchainBalanceMock.resolves(vector_types_1.Result.fail(new Error("getOnchainBalance error")));
            const result = await ethService.sendDepositTx(channelState, channelState.alice, "1", constants_1.AddressZero);
            assertResult(result, true, "getOnchainBalance error");
        });
        it("errors if channel is deployed and onchain balance is < send amount", async () => {
            getCodeMock.resolves(vector_types_1.Result.ok(vector_utils_1.mkHash("0xabc")));
            getOnchainBalanceMock.resolves(vector_types_1.Result.ok(ethers_1.BigNumber.from(5)));
            const result = await ethService.sendDepositTx(channelState, channelState.alice, "6", constants_1.AddressZero);
            assertResult(result, true, vector_types_1.ChainError.reasons.NotEnoughFunds);
        });
        it("happy: alice deploys channel with deposit if not deployed", async () => {
            const result = await ethService.sendDepositTx(channelState, channelState.alice, "1", constants_1.AddressZero);
            assertResult(result, false, txResponse);
            vector_utils_1.expect(sendDeployChannelTxMock.callCount).to.eq(1);
            const call = sendDeployChannelTxMock.getCall(0);
            vector_utils_1.expect(call.args[0]).to.deep.eq(channelState);
            vector_utils_1.expect(call.args[1]).to.deep.eq({ amount: "1", assetId: constants_1.AddressZero });
        });
        it("happy: alice calls sendDepositATx if multisig is deployed", async () => {
            getCodeMock.resolves(vector_types_1.Result.ok(vector_utils_1.mkHash("0xabc")));
            const result = await ethService.sendDepositTx(channelState, channelState.alice, "1", constants_1.AddressZero);
            assertResult(result, false, txResponse);
            vector_utils_1.expect(sendDepositATxMock.callCount).to.eq(1);
            const call = sendDepositATxMock.getCall(0);
            vector_utils_1.expect(call.args[0]).to.deep.eq(channelState);
            vector_utils_1.expect(call.args[1]).to.deep.eq("1");
            vector_utils_1.expect(call.args[2]).to.deep.eq(constants_1.AddressZero);
        });
        it("happy: bob calls sendDepositBTx if multisig is deployed", async () => {
            getCodeMock.resolves(vector_types_1.Result.ok(vector_utils_1.mkHash("0xabc")));
            const result = await ethService.sendDepositTx(channelState, channelState.bob, "1", constants_1.AddressZero);
            assertResult(result, false, txResponse);
            vector_utils_1.expect(sendDepositBTxMock.callCount).to.eq(1);
            const call = sendDepositBTxMock.getCall(0);
            vector_utils_1.expect(call.args[0]).to.deep.eq(channelState);
            vector_utils_1.expect(call.args[1]).to.deep.eq("1");
            vector_utils_1.expect(call.args[2]).to.deep.eq(constants_1.AddressZero);
        });
        it("happy: bob calls sendDepositBTx if multisig is not deployed", async () => {
            const result = await ethService.sendDepositTx(channelState, channelState.bob, "1", constants_1.AddressZero);
            assertResult(result, false, txResponse);
            vector_utils_1.expect(sendDepositBTxMock.callCount).to.eq(1);
            const call = sendDepositBTxMock.getCall(0);
            vector_utils_1.expect(call.args[0]).to.deep.eq(channelState);
            vector_utils_1.expect(call.args[1]).to.deep.eq("1");
            vector_utils_1.expect(call.args[2]).to.deep.eq(constants_1.AddressZero);
        });
    });
    describe("speedUpTx", () => {
        const minTx = {
            data: vector_utils_1.mkBytes32("0xabc"),
            to: vector_utils_1.mkAddress("0xbca"),
            value: 0,
            transactionHash: vector_utils_1.mkBytes32("0xfff"),
            nonce: 8,
        };
        beforeEach(() => {
            sendTxWithRetriesMock = sinon_1.stub(ethService, "sendTxWithRetries").resolves(vector_types_1.Result.ok(txResponse));
        });
        it("errors if cannot get a signer", async () => {
            const result = await ethService.speedUpTx(1234, minTx);
            assertResult(result, true, vector_types_1.ChainError.reasons.SignerNotFound);
        });
        it("errors if cannot get transaction", async () => {
            provider1337.getTransaction.rejects("Boooo");
            const result = await ethService.speedUpTx(1337, minTx);
            assertResult(result, true, vector_types_1.ChainError.reasons.TxNotFound);
        });
        it("errors if transaction is confirmed", async () => {
            provider1337.getTransaction.resolves({ confirmations: 1 });
            const result = await ethService.speedUpTx(1337, minTx);
            assertResult(result, true, vector_types_1.ChainError.reasons.TxAlreadyMined);
        });
        it("happy: speeds up tx", async () => {
            provider1337.getTransaction.resolves({ confirmations: 0 });
            const result = await ethService.speedUpTx(1337, minTx);
            assertResult(result, false, txResponse);
            vector_utils_1.expect(sendTxWithRetriesMock.callCount).to.eq(1);
            const call = sendTxWithRetriesMock.getCall(0);
            vector_utils_1.expect(call.args[0]).to.eq(minTx.to);
            vector_utils_1.expect(call.args[1]).to.eq(1337);
            vector_utils_1.expect(call.args[2]).to.eq(vector_types_1.TransactionReason.speedUpTransaction);
        });
    });
    describe("sendTxWithRetries", () => {
        let sendTxAndParseResponseMock;
        beforeEach(() => {
            sendTxAndParseResponseMock = sinon_1.stub(ethService, "sendTxAndParseResponse").resolves(vector_types_1.Result.ok(txResponse));
        });
        it("errors if sendTxAndParseResponse errors", async () => {
            sendTxAndParseResponseMock.resolves(vector_types_1.Result.fail(new vector_types_1.ChainError(vector_types_1.ChainError.reasons.NotEnoughFunds)));
            const result = await ethService.sendTxWithRetries(channelState.channelAddress, channelState.networkContext.chainId, "allowance", () => {
                return Promise.resolve(_txResponse);
            });
            assertResult(result, true, vector_types_1.ChainError.reasons.NotEnoughFunds);
        });
        it("retries if it's a retryable error", async () => {
            sendTxAndParseResponseMock
                .onFirstCall()
                .resolves(vector_types_1.Result.fail(new vector_types_1.ChainError('processing response error (body="{"jsonrpc":"2.0","error":{"code":-32000,"message":"Block information is incomplete while ancient block sync is still in progress, before it\'s finished we can\'t determine the existence of requested item."},"id":14890}\n", error={"code":-32000}, requestBody="{"method":"eth_getTransactionReceipt","params":["0x8731c46fafd569bb65c6c26cd3960ad418d88310a41a03c5c4f4a0dcce15cd8a"],"id":14890,"jsonrpc":"2.0"}", requestMethod="POST", url="https://rpc.xdaichain.com/", code=SERVER_ERROR, version=web/5.1.0)')));
            sendTxAndParseResponseMock.resolves(vector_types_1.Result.ok(txResponse));
            const result = await ethService.sendTxWithRetries(channelState.channelAddress, channelState.networkContext.chainId, "allowance", () => {
                return Promise.resolve(_txResponse);
            });
            assertResult(result, false, txResponse);
        });
        it("happy: should work when sendTxAndParseResponse works on the first try", async () => {
            const result = await ethService.sendTxWithRetries(channelState.channelAddress, channelState.networkContext.chainId, "allowance", () => {
                return Promise.resolve(_txResponse);
            });
            assertResult(result, false, txResponse);
        });
    });
    describe("sendTxAndParseResponse", () => {
        it("if txFn returns undefined, returns undefined", async () => {
            const result = await ethService.sendTxAndParseResponse(constants_1.AddressZero, 111, "allowance", async () => {
                return undefined;
            });
            assertResult(result, false, undefined);
        });
        it("if txFn errors, returns error", async () => {
            const result = await ethService.sendTxAndParseResponse(constants_1.AddressZero, 111, "allowance", async () => {
                throw new Error("Boooo");
            });
            assertResult(result, true, "Boooo");
        });
        it("if txFn errors, with not enough funds, return special error", async () => {
            const result = await ethService.sendTxAndParseResponse(constants_1.AddressZero, 111, "allowance", async () => {
                throw new Error("sender doesn't have enough funds");
            });
            assertResult(result, true, vector_types_1.ChainError.reasons.NotEnoughFunds);
        });
        it("if receipt status = 0, saves response with error", async () => {
            const t = Object.assign(Object.assign({}, _txResponse), { wait: async () => {
                    return { status: 0 };
                } });
            const result = await ethService.sendTxAndParseResponse(constants_1.AddressZero, 111, "allowance", async () => {
                return t;
            });
            vector_utils_1.expect(storeMock.saveTransactionResponse.callCount).eq(1);
            const saveTransactionResponseCall = storeMock.saveTransactionResponse.getCall(0);
            vector_utils_1.expect(saveTransactionResponseCall.args[0]).eq(constants_1.AddressZero);
            vector_utils_1.expect(saveTransactionResponseCall.args[1]).eq("allowance");
            vector_utils_1.expect(saveTransactionResponseCall.args[2]).deep.eq(t);
            vector_utils_1.expect(storeMock.saveTransactionFailure.callCount).eq(1);
            const saveTransactionFailureCall = storeMock.saveTransactionFailure.getCall(0);
            vector_utils_1.expect(saveTransactionFailureCall.args[0]).eq(constants_1.AddressZero);
            vector_utils_1.expect(saveTransactionFailureCall.args[1]).eq(t.hash);
            vector_utils_1.expect(saveTransactionFailureCall.args[2]).eq("Tx reverted");
            assertResult(result, false);
        });
        it("if receipt wait fn errors, saves response with error", async () => {
            const t = Object.assign(Object.assign({}, _txResponse), { wait: async () => {
                    throw new Error("Booooo");
                } });
            const result = await ethService.sendTxAndParseResponse(constants_1.AddressZero, 111, "allowance", async () => {
                return t;
            });
            vector_utils_1.expect(storeMock.saveTransactionResponse.callCount).eq(1);
            const saveTransactionResponseCall = storeMock.saveTransactionResponse.getCall(0);
            vector_utils_1.expect(saveTransactionResponseCall.args[0]).eq(constants_1.AddressZero);
            vector_utils_1.expect(saveTransactionResponseCall.args[1]).eq("allowance");
            vector_utils_1.expect(saveTransactionResponseCall.args[2]).deep.eq(t);
            assertResult(result, false);
            vector_utils_1.expect(storeMock.saveTransactionFailure.callCount).eq(1);
            const saveTransactionFailureCall = storeMock.saveTransactionFailure.getCall(0);
            vector_utils_1.expect(saveTransactionFailureCall.args[0]).eq(constants_1.AddressZero);
            vector_utils_1.expect(saveTransactionFailureCall.args[1]).eq(t.hash);
            vector_utils_1.expect(saveTransactionFailureCall.args[2]).eq("Booooo");
            assertResult(result, false);
        });
        it("happy: saves responses", async () => {
            const result = await ethService.sendTxAndParseResponse(constants_1.AddressZero, 111, "allowance", async () => {
                return _txResponse;
            });
            vector_utils_1.expect(storeMock.saveTransactionResponse.callCount).eq(1);
            const saveTransactionResponseCall = storeMock.saveTransactionResponse.getCall(0);
            vector_utils_1.expect(saveTransactionResponseCall.args[0]).eq(constants_1.AddressZero);
            vector_utils_1.expect(saveTransactionResponseCall.args[1]).eq("allowance");
            vector_utils_1.expect(saveTransactionResponseCall.args[2]).deep.eq(_txResponse);
            assertResult(result, false);
            vector_utils_1.expect(storeMock.saveTransactionReceipt.callCount).eq(1);
            const saveTransactionReceiptCall = storeMock.saveTransactionReceipt.getCall(0);
            vector_utils_1.expect(saveTransactionReceiptCall.args[0]).eq(constants_1.AddressZero);
            assertResult(result, false);
        });
    });
});
//# sourceMappingURL=ethService.spec.js.map