import { verify_psig } from '@cmdcode/musig2';
import { parse_txout } from '../lib/tx.js';
import { parse_covenant } from '../lib/parse.js';
import { get_entry } from '../lib/util.js';
import { get_close_tx_template } from '../lib/deposit.js';
import { get_path_mutexes, get_return_mutex, get_session_pnonce, verify_mutex_psig } from '../lib/session.js';
import * as assert from '../assert.js';
export function validate_covenant(covenant) {
    parse_covenant(covenant);
}
export function verify_covenant(context, contract, deposit, dp_agent, ct_agent) {
    const { agent_pn } = contract;
    const { covenant } = deposit;
    assert.exists(covenant);
    assert.ok(covenant.cid === contract.cid, 'Covenant cid does not match the contract!');
    check_deposit_agent(dp_agent, deposit);
    check_contract_agent(ct_agent, contract);
    const pnonces = [covenant.pnonce, agent_pn];
    const txout = parse_txout(deposit);
    const entries = get_path_mutexes(context, contract, pnonces, txout);
    check_deposit_psigs(entries, covenant.psigs);
}
export function verify_close(dp_agent, deposit, request) {
    const { agent_pn, spend_xpub, value } = deposit;
    const { pnonce, psig, txfee } = request;
    check_deposit_agent(dp_agent, deposit);
    const pnonces = [pnonce, agent_pn];
    const txhex = get_close_tx_template(txfee, value, spend_xpub);
    const mutex = get_return_mutex(deposit, pnonces, txhex);
    verify_mutex_psig(mutex, psig);
}
function check_deposit_agent(agent, deposit) {
    const { agent_id, agent_pk } = deposit;
    assert.ok(agent_id === agent.id, 'Agent ID does not match deposit.');
    assert.ok(agent_pk === agent.pubkey, 'Agent pubkey does not match deposit.');
}
function check_contract_agent(agent, contract) {
    const { agent_id, cid, agent_pn } = contract;
    assert.ok(agent_id === agent.id, 'Agent ID does not match session.');
    const pnonce = get_session_pnonce(agent.id, cid, agent);
    assert.ok(pnonce.hex === agent_pn, 'Agent pnonce does not match session.');
}
function check_deposit_psigs(mutexes, psigs) {
    psigs.forEach(([label, psig]) => {
        const ctx = get_entry(label, mutexes);
        assert.ok(verify_psig(ctx.mutex, psig), 'psig verification failed for path: ' + label);
    });
}
