"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Auth = void 0;
exports.verifyRequestSignature = verifyRequestSignature;
const crypto_wallet_core_1 = require("@bitpay-labs/crypto-wallet-core");
const secp256k1_1 = __importDefault(require("secp256k1"));
const logger_1 = __importDefault(require("../logger"));
const chain_state_1 = require("../providers/chain-state");
const config_1 = require("../services/config");
function verifyRequestSignature(params) {
    const { message, pubKey, signature } = params;
    const pub = new crypto_wallet_core_1.BitcoreLib.PublicKey(pubKey).toBuffer();
    const messageHash = crypto_wallet_core_1.BitcoreLib.crypto.Hash.sha256sha256(Buffer.from(message));
    if (typeof signature === 'string') {
        return secp256k1_1.default.ecdsaVerify(Buffer.from(signature, 'hex'), messageHash, pub);
    }
    else {
        throw new Error('Signature must exist');
    }
}
const authenticateMiddleware = async (req, res, next) => {
    const { chain, network, pubKey } = req.params;
    logger_1.default.debug('Authenticating request with pubKey: %o', pubKey);
    let wallet;
    try {
        wallet = await chain_state_1.ChainStateProvider.getWallet({ chain, network, pubKey });
    }
    catch {
        return res.status(500).send('Problem authenticating wallet');
    }
    try {
        if (req.is('application/octet-stream')) {
            req.body = JSON.parse(req.body.toString());
        }
        if (!wallet) {
            return res.status(404).send('Wallet not found');
        }
        Object.assign(req, { wallet });
        const walletConfig = config_1.Config.for('api').wallets;
        if (walletConfig && walletConfig.allowUnauthenticatedCalls) {
            return next();
        }
        const validRequestSignature = verifyRequestSignature({
            message: [req.method, req.originalUrl, JSON.stringify(req.body)].join('|'),
            pubKey: wallet.pubKey,
            signature: req.headers['x-signature']
        });
        if (!validRequestSignature) {
            return res.status(401).send('Authentication failed');
        }
        return next();
    }
    catch (e) {
        logger_1.default.error('Unexpected error authenticating request: %o', e?.stack || e?.message || e);
        return res.status(401).send('Authentication failed');
    }
};
exports.Auth = {
    verifyRequestSignature,
    authenticateMiddleware
};
//# sourceMappingURL=auth.js.map