// Copyright 2024-2026 Tymofii Pidlisnyi. Apache-2.0 license. See LICENSE.
// ══════════════════════════════════════════════════════════════════
// Provisional Statement — createProvisional, withdrawProvisional, isBinding
// ══════════════════════════════════════════════════════════════════
import crypto from 'node:crypto';
import { sign, verify } from '../../crypto/keys.js';
import { canonicalize } from '../../core/canonical.js';
import { createHybridTimestamp } from '../../core/time.js';
/** Canonical payload an author signs to attest a provisional statement.
 *  Verifiers reconstruct this exact payload to check author_signature. */
export function statementSigningPayload(s) {
    return canonicalize({
        id: s.id,
        version: s.version,
        author: s.author,
        author_principal: s.author_principal,
        content: s.content,
        created_at: s.created_at,
        ...(s.dead_man_expires_at ? { dead_man_expires_at: s.dead_man_expires_at } : {}),
    });
}
export function createProvisional(params) {
    const id = params.id ?? crypto.randomBytes(16).toString('hex');
    const created_at = createHybridTimestamp(params.gatewayId);
    const base = {
        id,
        version: '1.0',
        author: params.author,
        author_principal: params.author_principal,
        content: params.content,
        created_at,
        ...(params.dead_man_expires_at ? { dead_man_expires_at: params.dead_man_expires_at } : {}),
    };
    const author_signature = sign(statementSigningPayload(base), params.authorPrivateKey);
    return {
        ...base,
        status: 'provisional',
        author_signature,
    };
}
/** Returns true only for promoted statements with a verifying promotion.
 *  Provisional and withdrawn statements are never binding. This check
 *  does not re-verify the PromotionEvent signature — use verifyPromotion
 *  for the full cryptographic check. */
export function isBinding(statement) {
    return statement.status === 'promoted' && !!statement.promotion;
}
/** Verify the author's signature over the statement's signed fields.
 *  Returns false if the content or any signed field was tampered with
 *  after signing. */
export function verifyAuthorSignature(statement) {
    const payload = statementSigningPayload(statement);
    return verify(payload, statement.author_signature, statement.author);
}
/** Withdraw a provisional statement. The caller must supply a signature
 *  from the author over the withdrawal payload. Already-promoted
 *  statements cannot be withdrawn. */
export function withdrawProvisional(statement, author_sig) {
    if (statement.status === 'promoted') {
        throw new Error('Cannot withdraw a promoted statement');
    }
    if (statement.status === 'withdrawn') {
        return statement;
    }
    const payload = canonicalize({ action: 'withdraw', statement_id: statement.id });
    if (!verify(payload, author_sig, statement.author)) {
        throw new Error('Invalid withdrawal signature');
    }
    return { ...statement, status: 'withdrawn' };
}
/** Compute the withdrawal payload an author must sign. */
export function withdrawalPayload(statement_id) {
    return canonicalize({ action: 'withdraw', statement_id });
}
//# sourceMappingURL=create.js.map