"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
require("source-map-support/register");
const sinon_1 = __importDefault(require("sinon"));
const chai_1 = require("chai");
const supertest_1 = __importDefault(require("supertest"));
const crypto_wallet_core_1 = require("@bitpay-labs/crypto-wallet-core");
const routes_1 = __importDefault(require("../../../src/routes"));
const eth_routes_1 = require("../../../src/modules/ethereum/api/eth-routes");
const csp_1 = require("../../../src/modules/ethereum/api/csp");
const aaveApi = __importStar(require("../../../src/providers/chain-state/evm/api/aave"));
const integration_1 = require("../../helpers/integration");
const helpers_1 = require("../../helpers");
const config_1 = require("../../../src/services/config");
describe('EVM Routes', function () {
    const sandbox = sinon_1.default.createSandbox();
    routes_1.default.use(eth_routes_1.EthRoutes);
    const request = (0, supertest_1.default)(routes_1.default);
    before(async function () {
        this.timeout(15000);
        await (0, integration_1.intBeforeHelper)();
        await (0, helpers_1.resetDatabase)();
    });
    after(async () => (0, integration_1.intAfterHelper)());
    afterEach(() => {
        sandbox.restore();
    });
    describe('GET getAccountNonce', function () {
        it('should get account nonce', done => {
            request.get('/api/ETH/regtest/address/0x9bb6f7fdf81afbd8876d37f3e5e37df416bf8da1/txs/count')
                .expect(200)
                .end((err, res) => {
                if (err)
                    return done(res.error || err);
                (0, chai_1.expect)(res.body).to.have.property('nonce');
                (0, chai_1.expect)(res.body.nonce).to.be.a('number');
                (0, chai_1.expect)(isNaN(res.body.nonce)).to.be.false;
                done();
            });
        });
    });
    describe('POST estimateGas', function () {
        it('should get gas estimate', done => {
            request.post('/api/ETH/regtest/gas')
                .send({
                from: '0x9bb6f7fdf81afbd8876d37f3e5e37df416bf8da1',
                to: '0xb0d38874081344C810e502Ed487c9bc98637f6D8',
                value: '0x9184e72a000', // 0.01 ETH
            })
                .expect(200)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.body).to.be.a('number');
                (0, chai_1.expect)(isNaN(res.body)).to.be.false;
                done();
            });
        });
    });
    describe('POST estimateL1Fee', function () {
        const rawTx = '0xf86c07840a21fe808252089439acd4a7e19b34bb8266e573bfb44872913a087c872bdc545d6b4b8880820a96a0ee09eaa08b5f2593a8dde87ef9a8e35aefaf147eead392e9071ea5dc8e80e379a008e44ba5c43adc58dc2e24dbf8f1e25273e8a84fd2bd17cb88417ac3d869877e';
        let l1Fee;
        beforeEach(() => {
            sandbox.spy(config_1.Config, 'chainConfig');
        });
        it('should get L1 gas estimate', done => {
            request.post('/api/BASE/testnet/l1/fee')
                .send({ rawTx })
                .expect(200)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.body).to.be.a('string');
                (0, chai_1.expect)(isNaN(res.body)).to.be.false;
                (0, chai_1.expect)(config_1.Config.chainConfig.called).to.be.true;
                (0, chai_1.expect)(config_1.Config.chainConfig.returnValues[0].needsL1Fee).to.be.true;
                l1Fee = parseInt(res.body);
                done();
            });
        });
        it('should get safe L1 gas estimate', done => {
            request.post('/api/BASE/testnet/l1/fee?safe=true')
                .send({ rawTx })
                .expect(200)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.body).to.be.a('string');
                (0, chai_1.expect)(isNaN(res.body)).to.be.false;
                (0, chai_1.expect)(parseInt(res.body)).to.be.greaterThan(l1Fee);
                (0, chai_1.expect)(config_1.Config.chainConfig.called).to.be.true;
                (0, chai_1.expect)(config_1.Config.chainConfig.returnValues[0].needsL1Fee).to.be.true;
                done();
            });
        });
        it('should not need L1 gas estimate', done => {
            request.post('/api/ETH/regtest/l1/fee')
                .send({ rawTx })
                .expect(200)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.body).to.equal('0');
                (0, chai_1.expect)(config_1.Config.chainConfig.called).to.be.true;
                (0, chai_1.expect)(config_1.Config.chainConfig.returnValues[0].needsL1Fee).to.be.undefined;
                done();
            });
        });
    });
    describe('GET getTokenInfo', function () {
        it('should get token info', done => {
            request.get('/api/BASE/testnet/token/0x036CbD53842c5426634e7929541eC2318f3dCF7e')
                .expect(200)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.body).to.have.property('name', 'USDC');
                (0, chai_1.expect)(res.body).to.have.property('symbol', 'USDC');
                (0, chai_1.expect)(res.body).to.have.property('decimals', 6);
                done();
            });
        });
    });
    describe('GET getERC20TokenAllowance', function () {
        it('should get token allowance', done => {
            request.get('/api/BASE/testnet/token/0x036CbD53842c5426634e7929541eC2318f3dCF7e/allowance/0x9bb6f7fdf81afbd8876d37f3e5e37df416bf8da1/for/0xb0d38874081344C810e502Ed487c9bc98637f6D8')
                .expect(200)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.body).to.be.a('number');
                (0, chai_1.expect)(isNaN(res.body)).to.be.false;
                done();
            });
        });
    });
    describe('GET getPriorityFee', function () {
        it('should get priority fee', done => {
            request.get('/api/ETH/regtest/priorityFee/3')
                .expect(200)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.body).to.have.property('feerate');
                (0, chai_1.expect)(res.body.feerate).to.be.a('number');
                (0, chai_1.expect)(isNaN(res.body.feerate)).to.be.false;
                done();
            });
        });
    });
    describe('GET getAaveUserAccountData', function () {
        const address = '0x856BC683A7e2fF87192B896c7dA99DdA5ab81E6C';
        const v2PoolMainnet = '0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9';
        it('should get v2 account-data shape using hardcoded public ETH mainnet RPC', function (done) {
            this.timeout(30000);
            // Keep route network as sepolia (configured in test config), but force a mainnet v2 web3/pool path in-test.
            const web3 = new crypto_wallet_core_1.Web3('https://ethereum.publicnode.com');
            sandbox.stub(csp_1.ETH, 'getWeb3').resolves({ web3 });
            sandbox.stub(aaveApi, 'getAavePoolAddress').returns(v2PoolMainnet);
            request.get(`/api/ETH/sepolia/aave/account/${address}?version=v2`)
                .expect(200)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.body).to.include.keys([
                    'totalCollateralETH',
                    'totalDebtETH',
                    'availableBorrowsETH',
                    'currentLiquidationThreshold',
                    'ltv',
                    'healthFactor'
                ]);
                (0, chai_1.expect)(res.body.totalCollateralETH).to.be.a('string');
                (0, chai_1.expect)(res.body.totalDebtETH).to.be.a('string');
                (0, chai_1.expect)(res.body.availableBorrowsETH).to.be.a('string');
                (0, chai_1.expect)(csp_1.ETH.getWeb3.calledOnceWith('sepolia')).to.be.true;
                done();
            });
        });
        it('should return 400 for unsupported chain/network on v2', done => {
            request.get(`/api/ETH/sepolia/aave/account/${address}?version=v2`)
                .expect(400)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.text).to.equal('Unsupported chain or network for Aave');
                done();
            });
        });
        it('should get v3 account-data shape', function (done) {
            this.timeout(30000);
            request.get(`/api/ETH/sepolia/aave/account/${address}?version=v3`)
                .expect(200)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.body).to.include.keys([
                    'totalCollateralBase',
                    'totalDebtBase',
                    'availableBorrowsBase',
                    'currentLiquidationThreshold',
                    'ltv',
                    'healthFactor'
                ]);
                done();
            });
        });
        it('should return 400 for unsupported chain/network on v3', done => {
            request.get(`/api/ETH/regtest/aave/account/${address}?version=v3`)
                .expect(400)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.text).to.equal('Unsupported chain or network for Aave');
                done();
            });
        });
        it('should return 400 for unsupported Aave version', done => {
            request.get(`/api/ETH/sepolia/aave/account/${address}?version=v9`)
                .expect(400)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.text).to.equal('Unsupported Aave version');
                done();
            });
        });
    });
    describe('GET aave/reserve', function () {
        // USDC on ETH mainnet (V2 only — V2 not deployed on sepolia)
        const usdcMainnet = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
        const v2PoolMainnet = '0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9';
        // Aave test USDC on sepolia (V3 is deployed on sepolia)
        const usdcSepolia = '0x94a9D9AC8a22534E3FaCa9F4e7F2E2cf85d5E4C8';
        it('should return currentVariableBorrowRate for v2 using hardcoded public ETH mainnet RPC', function (done) {
            this.timeout(30000);
            const web3 = new crypto_wallet_core_1.Web3('https://ethereum.publicnode.com');
            sandbox.stub(csp_1.ETH, 'getWeb3').resolves({ web3 });
            sandbox.stub(aaveApi, 'getAavePoolAddress').returns(v2PoolMainnet);
            request.get(`/api/ETH/sepolia/aave/reserve/${usdcMainnet}?version=v2`)
                .expect(200)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.body).to.have.keys(['currentVariableBorrowRate']);
                done();
            });
        });
        it('should return currentVariableBorrowRate for v3 on sepolia', function (done) {
            this.timeout(30000);
            request.get(`/api/ETH/sepolia/aave/reserve/${usdcSepolia}?version=v3`)
                .expect(200)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.body).to.have.keys(['currentVariableBorrowRate']);
                done();
            });
        });
        it('should return 400 for unsupported chain or network', done => {
            request.get(`/api/ETH/regtest/aave/reserve/${usdcMainnet}?version=v3`)
                .expect(400)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.text).to.equal('Unsupported chain or network for Aave');
                done();
            });
        });
        it('should return 400 for unsupported Aave version', done => {
            request.get(`/api/ETH/sepolia/aave/reserve/${usdcMainnet}?version=v9`)
                .expect(400)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.text).to.equal('Unsupported Aave version');
                done();
            });
        });
    });
    describe('GET aave/reserve-tokens', function () {
        // USDC on ETH mainnet (V2 only — V2 not deployed on sepolia)
        const usdcMainnet = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
        const v2PoolMainnet = '0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9';
        // Aave test USDC on sepolia (V3 is deployed on sepolia)
        const usdcSepolia = '0x94a9D9AC8a22534E3FaCa9F4e7F2E2cf85d5E4C8';
        it('should return variableDebtTokenAddress for v2 using hardcoded public ETH mainnet RPC', function (done) {
            this.timeout(30000);
            const web3 = new crypto_wallet_core_1.Web3('https://ethereum.publicnode.com');
            sandbox.stub(csp_1.ETH, 'getWeb3').resolves({ web3 });
            sandbox.stub(aaveApi, 'getAavePoolAddress').returns(v2PoolMainnet);
            request.get(`/api/ETH/sepolia/aave/reserve-tokens/${usdcMainnet}?version=v2`)
                .expect(200)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.body).to.have.keys(['variableDebtTokenAddress']);
                done();
            });
        });
        it('should return variableDebtTokenAddress for v3 on sepolia', function (done) {
            this.timeout(30000);
            request.get(`/api/ETH/sepolia/aave/reserve-tokens/${usdcSepolia}?version=v3`)
                .expect(200)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.body).to.have.keys(['variableDebtTokenAddress']);
                done();
            });
        });
        it('should return 400 for unsupported chain or network', done => {
            request.get(`/api/ETH/regtest/aave/reserve-tokens/${usdcSepolia}?version=v3`)
                .expect(400)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.text).to.equal('Unsupported chain or network for Aave');
                done();
            });
        });
        it('should return 400 for unsupported Aave version', done => {
            request.get(`/api/ETH/sepolia/aave/reserve-tokens/${usdcSepolia}?version=v9`)
                .expect(400)
                .end((err, res) => {
                if (err)
                    return done(err);
                (0, chai_1.expect)(res.text).to.equal('Unsupported Aave version');
                done();
            });
        });
    });
});
//# sourceMappingURL=evm.test.js.map