"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 });
exports.specOpThrowReviewActions = void 0;
exports.parseWalletOutpoint = parseWalletOutpoint;
exports.validateSatoshis = validateSatoshis;
exports.validateOptionalInteger = validateOptionalInteger;
exports.validateInteger = validateInteger;
exports.validatePositiveIntegerOrZero = validatePositiveIntegerOrZero;
exports.validateStringLength = validateStringLength;
exports.validateBase64String = validateBase64String;
exports.isHexString = isHexString;
exports.validateCreateActionInput = validateCreateActionInput;
exports.validateCreateActionOutput = validateCreateActionOutput;
exports.validateCreateActionOptions = validateCreateActionOptions;
exports.validateCreateActionArgs = validateCreateActionArgs;
exports.validateSignActionOptions = validateSignActionOptions;
exports.validateSignActionArgs = validateSignActionArgs;
exports.validateAbortActionArgs = validateAbortActionArgs;
exports.validateWalletPayment = validateWalletPayment;
exports.validateBasketInsertion = validateBasketInsertion;
exports.validateInternalizeOutput = validateInternalizeOutput;
exports.validateOriginator = validateOriginator;
exports.validateInternalizeActionArgs = validateInternalizeActionArgs;
exports.validateOptionalOutpointString = validateOptionalOutpointString;
exports.validateOutpointString = validateOutpointString;
exports.validateRelinquishOutputArgs = validateRelinquishOutputArgs;
exports.validateRelinquishCertificateArgs = validateRelinquishCertificateArgs;
exports.validateListCertificatesArgs = validateListCertificatesArgs;
exports.validateAcquireIssuanceCertificateArgs = validateAcquireIssuanceCertificateArgs;
exports.validateAcquireDirectCertificateArgs = validateAcquireDirectCertificateArgs;
exports.validateProveCertificateArgs = validateProveCertificateArgs;
exports.validateDiscoverByIdentityKeyArgs = validateDiscoverByIdentityKeyArgs;
exports.validateDiscoverByAttributesArgs = validateDiscoverByAttributesArgs;
exports.validateListOutputsArgs = validateListOutputsArgs;
exports.validateListActionsArgs = validateListActionsArgs;
const Utils = __importStar(require("../primitives/utils.js"));
const WERR_INVALID_PARAMETER_js_1 = __importDefault(require("./WERR_INVALID_PARAMETER.js"));
const Beef_js_1 = __importDefault(require("../transaction/Beef.js"));
function parseWalletOutpoint(outpoint) {
    const [txid, vout] = outpoint.split('.');
    return { txid, vout: Number(vout) };
}
function defaultTrue(v) {
    return v ?? true;
}
function defaultFalse(v) {
    return v ?? false;
}
function defaultZero(v) {
    return v ?? 0;
}
function default0xffffffff(v) {
    return v ?? 0xffffffff;
}
function defaultOne(v) {
    return v ?? 1;
}
function defaultEmpty(v) {
    return v ?? [];
}
function validateOptionalStringLength(s, name, min, max) {
    if (s === undefined)
        return undefined;
    return validateStringLength(s, name, min, max);
}
/**
 * Validate a satoshi amount.
 *
 * @param v - value to validate (integer number of satoshis)
 * @param name - parameter name used in error messages
 * @param min - optional minimum allowed satoshi value
 * @returns validated satoshi number
 * @throws WERR_INVALID_PARAMETER when invalid
 */
function validateSatoshis(v, name, min) {
    if (v === undefined || !Number.isInteger(v) || v < 0 || v > 21e14) {
        throw new WERR_INVALID_PARAMETER_js_1.default(name, 'a valid number of satoshis');
    }
    if (min !== undefined && v < min)
        throw new WERR_INVALID_PARAMETER_js_1.default(name, `at least ${min} satoshis.`);
    return v;
}
/**
 * Validate an optional integer. Returns undefined or the validated integer.
 *
 * @param v - value to validate (may be undefined)
 * @param name - parameter name used in error messages
 * @param min - optional minimum value
 * @param max - optional maximum value
 * @returns validated integer or undefined
 * @throws WERR_INVALID_PARAMETER when invalid
 */
function validateOptionalInteger(v, name, min, max) {
    if (v === undefined)
        return undefined;
    return validateInteger(v, name, undefined, min, max);
}
/**
 * Validate an integer, applying an optional default.
 *
 * @param v - value to validate (may be undefined)
 * @param name - parameter name used in error messages
 * @param defaultValue - value to return when v is undefined
 * @param min - optional minimum allowed value
 * @param max - optional maximum allowed value
 * @returns validated integer
 * @throws WERR_INVALID_PARAMETER when invalid
 */
function validateInteger(v, name, defaultValue, min, max) {
    if (v === undefined) {
        if (defaultValue !== undefined)
            return defaultValue;
        throw new WERR_INVALID_PARAMETER_js_1.default(name, 'a valid integer');
    }
    if (!Number.isInteger(v))
        throw new WERR_INVALID_PARAMETER_js_1.default(name, 'an integer');
    v = Number(v);
    if (min !== undefined && v < min)
        throw new WERR_INVALID_PARAMETER_js_1.default(name, `at least ${min} length.`);
    if (max !== undefined && v > max)
        throw new WERR_INVALID_PARAMETER_js_1.default(name, `no more than ${max} length.`);
    return v;
}
/**
 * Validate a non-negative integer (zero allowed).
 *
 * @param v - value to validate
 * @param name - parameter name used in error messages
 * @returns validated integer
 * @throws WERR_INVALID_PARAMETER when invalid
 */
function validatePositiveIntegerOrZero(v, name) {
    return validateInteger(v, name, 0, 0);
}
/**
 * Validate string length in bytes for UTF-8 encoded string.
 *
 * @param s - string to validate
 * @param name - parameter name used in error messages
 * @param min - optional minimum byte length
 * @param max - optional maximum byte length
 * @returns the original string when valid
 * @throws WERR_INVALID_PARAMETER when invalid
 */
function validateStringLength(s, name, min, max) {
    const bytes = Utils.toArray(s, 'utf8').length;
    if (min !== undefined && bytes < min)
        throw new WERR_INVALID_PARAMETER_js_1.default(name, `at least ${min} length.`);
    if (max !== undefined && bytes > max)
        throw new WERR_INVALID_PARAMETER_js_1.default(name, `no more than ${max} length.`);
    return s;
}
/**
 * Validate an optional basket string (1..300 bytes).
 *
 * @param s - basket string or undefined
 * @returns validated basket string or undefined
 */
function validateOptionalBasket(s) {
    if (s === undefined)
        return undefined;
    return validateBasket(s);
}
/**
 * Validate basket identifier (1..300 bytes).
 *
 * @param s - basket string
 * @returns validated basket string
 */
function validateBasket(s) {
    return validateIdentifier(s, 'basket', 1, 300);
}
/**
 * Validate label identifier (1..300 bytes).
 *
 * @param s - label string
 * @returns validated label string
 */
function validateLabel(s) {
    return validateIdentifier(s, 'label', 1, 300);
}
/**
 * Validate tag identifier (1..300 bytes).
 *
 * @param s - tag string
 * @returns validated tag string
 */
function validateTag(s) {
    return validateIdentifier(s, 'tag', 1, 300);
}
/**
 * Normalize and validate an identifier (trim, lowercase, byte length).
 *
 * @param s - input string
 * @param name - name used in errors
 * @param min - optional minimum byte length
 * @param max - optional maximum byte length
 * @returns normalized identifier
 * @throws WERR_INVALID_PARAMETER when invalid
 */
function validateIdentifier(s, name, min, max) {
    s = s.trim().toLowerCase();
    const bytes = Utils.toArray(s, 'utf8').length;
    if (min !== undefined && bytes < min)
        throw new WERR_INVALID_PARAMETER_js_1.default(name, `at least ${min} length.`);
    if (max !== undefined && bytes > max)
        throw new WERR_INVALID_PARAMETER_js_1.default(name, `no more than ${max} length.`);
    return s;
}
/**
 * Validate an optional Base64 encoded string.
 *
 * @param s - base64 string or undefined
 * @param name - parameter name used in error messages
 * @param min - optional minimum decoded byte length
 * @param max - optional maximum decoded byte length
 * @returns validated base64 string or undefined
 */
function validateOptionalBase64String(s, name, min, max) {
    if (s === undefined)
        return undefined;
    return validateBase64String(s, name, min, max);
}
/**
 * Validate a Base64 string (structure and decoded size).
 *
 * @param s - base64 string
 * @param name - parameter name used in error messages
 * @param min - optional minimum decoded byte length
 * @param max - optional maximum decoded byte length
 * @returns validated base64 string
 * @throws WERR_INVALID_PARAMETER when invalid
 */
function validateBase64String(s, name, min, max) {
    s = s.trim();
    if (s.length === 0) {
        throw new WERR_INVALID_PARAMETER_js_1.default(name, 'valid base64 string');
    }
    let paddingCount = 0;
    for (let i = 0; i < s.length; i++) {
        const char = s.codePointAt(i) ?? 0;
        if (char >= 65 && char <= 90)
            continue; // A-Z
        if (char >= 97 && char <= 122)
            continue; // a-z
        if (char >= 48 && char <= 57)
            continue; // 0-9
        if (char === 43)
            continue; // +
        if (char === 47)
            continue; // /
        if (char === 61) { // =
            if (i < s.length - 2) {
                throw new WERR_INVALID_PARAMETER_js_1.default(name, 'valid base64 string');
            }
            paddingCount++;
            continue;
        }
        throw new WERR_INVALID_PARAMETER_js_1.default(name, 'valid base64 string');
    }
    // Padding rules
    if (paddingCount > 2) {
        throw new WERR_INVALID_PARAMETER_js_1.default(name, 'valid base64 string');
    }
    if (paddingCount > 0 && s.length % 4 !== 0) {
        throw new WERR_INVALID_PARAMETER_js_1.default(name, 'valid base64 string');
    }
    // Length must be multiple of 4 if no padding, or valid with padding
    const mod = s.length % 4;
    if (mod !== 0 && mod !== (4 - paddingCount)) {
        throw new WERR_INVALID_PARAMETER_js_1.default(name, 'valid base64 string');
    }
    // Calculate decoded byte length: (valid chars * 6) / 8
    const encodedLength = s.length - paddingCount;
    const bytes = Math.floor(encodedLength * 3 / 4);
    if (min !== undefined && bytes < min) {
        throw new WERR_INVALID_PARAMETER_js_1.default(name, `at least ${min} bytes`);
    }
    if (max !== undefined && bytes > max) {
        throw new WERR_INVALID_PARAMETER_js_1.default(name, `no more than ${max} bytes`);
    }
    return s;
}
function validateOptionalHexString(s, name, min, max) {
    if (s === undefined)
        return undefined;
    return validateHexString(s, name, min, max);
}
/**
 * Validate a hex string (even length, hex chars) and optional length bounds (character count).
 *
 * @param s - hex string
 * @param name - parameter name used in error messages
 * @param min if valid, string length minimum (not bytes)
 * @param max if valid, string length maximum (not bytes)
 * @returns
 */
function validateHexString(s, name, min, max) {
    s = s.trim().toLowerCase();
    if (s.length % 2 === 1)
        throw new WERR_INVALID_PARAMETER_js_1.default(name, `even length, not ${s.length}.`);
    const hexRegex = /^[0-9A-Fa-f]+$/;
    if (!hexRegex.test(s))
        throw new WERR_INVALID_PARAMETER_js_1.default(name, 'hexadecimal string.');
    if (min !== undefined && s.length < min)
        throw new WERR_INVALID_PARAMETER_js_1.default(name, `at least ${min} length.`);
    if (max !== undefined && s.length > max)
        throw new WERR_INVALID_PARAMETER_js_1.default(name, `no more than ${max} length.`);
    return s;
}
/**
 * Check whether a string is a valid hex string (even length and hex characters).
 *
 * @param s - input string
 * @returns true when s is a valid hex string
 */
function isHexString(s) {
    s = s.trim();
    if (s.length % 2 === 1)
        return false;
    const hexRegex = /^[0-9A-Fa-f]+$/;
    if (!hexRegex.test(s))
        return false;
    return true;
}
/**
 * Validate a CreateActionInput structure.
 *
 * Ensures either unlockingScript or unlockingScriptLength is provided and consistent,
 * validates outpoint, description length, and sequence number.
 *
 * @param i - CreateActionInput to validate
 * @returns ValidCreateActionInput
 * @throws WERR_INVALID_PARAMETER when invalid
 */
function validateCreateActionInput(i) {
    if (i.unlockingScript === undefined && i.unlockingScriptLength === undefined) {
        throw new WERR_INVALID_PARAMETER_js_1.default('unlockingScript, unlockingScriptLength', 'at least one valid value.');
    }
    const unlockingScript = validateOptionalHexString(i.unlockingScript, 'unlockingScript');
    const unlockingScriptLength = i.unlockingScriptLength ?? (unlockingScript == null ? 0 : unlockingScript.length / 2);
    if (unlockingScript && unlockingScriptLength !== unlockingScript.length / 2) {
        throw new WERR_INVALID_PARAMETER_js_1.default('unlockingScriptLength', 'length unlockingScript if both valid.');
    }
    const vi = {
        outpoint: parseWalletOutpoint(i.outpoint),
        inputDescription: validateStringLength(i.inputDescription, 'inputDescription', 5, 2000),
        unlockingScript,
        unlockingScriptLength,
        sequenceNumber: default0xffffffff(i.sequenceNumber)
    };
    return vi;
}
/**
 * Validate CreateActionOutput fields: locking script, satoshis, description, basket, tags.
 *
 * @param o - CreateActionOutput to validate
 * @returns ValidCreateActionOutput
 * @throws WERR_INVALID_PARAMETER when invalid
 */
function validateCreateActionOutput(o) {
    const vo = {
        lockingScript: validateHexString(o.lockingScript, 'lockingScript'),
        satoshis: validateSatoshis(o.satoshis, 'satoshis'),
        outputDescription: validateStringLength(o.outputDescription, 'outputDescription', 5, 2000),
        basket: validateOptionalBasket(o.basket),
        customInstructions: o.customInstructions,
        tags: defaultEmpty(o.tags).map(t => validateTag(t))
    };
    return vo;
}
/**
 * Normalize and validate CreateActionOptions, applying defaults for booleans/numbers/arrays.
 *
 * @param options - CreateActionOptions or undefined
 * @returns ValidCreateActionOptions with defaults applied
 */
function validateCreateActionOptions(options) {
    const o = options ?? {};
    const vo = {
        signAndProcess: defaultTrue(o.signAndProcess),
        acceptDelayedBroadcast: defaultTrue(o.acceptDelayedBroadcast),
        knownTxids: defaultEmpty(o.knownTxids),
        returnTXIDOnly: defaultFalse(o.returnTXIDOnly),
        noSend: defaultFalse(o.noSend),
        noSendChange: defaultEmpty(o.noSendChange).map(nsc => parseWalletOutpoint(nsc)),
        sendWith: defaultEmpty(o.sendWith),
        randomizeOutputs: defaultTrue(o.randomizeOutputs)
    };
    return vo;
}
/**
 * Validate the arguments for creating a new action.
 *
 * @param args
 * @returns validated arguments
 * @throws primarily WERR_INVALID_PARAMETER if args are invalid.
 */
function validateCreateActionArgs(args, logger) {
    const vargs = {
        description: validateStringLength(args.description, 'description', 5, 2000),
        inputBEEF: args.inputBEEF,
        inputs: defaultEmpty(args.inputs).map(i => validateCreateActionInput(i)),
        outputs: defaultEmpty(args.outputs).map(o => validateCreateActionOutput(o)),
        lockTime: defaultZero(args.lockTime),
        version: defaultOne(args.version),
        labels: defaultEmpty(args.labels?.map(l => validateLabel(l))),
        options: validateCreateActionOptions(args.options),
        logger,
        isSendWith: false,
        isDelayed: false,
        isNoSend: false,
        isNewTx: false,
        isRemixChange: false,
        isSignAction: false,
        randomVals: undefined,
        includeAllSourceTransactions: false,
        isTestWerrReviewActions: false
    };
    vargs.isTestWerrReviewActions = vargs.labels.includes(exports.specOpThrowReviewActions);
    vargs.isSendWith = vargs.options.sendWith.length > 0;
    vargs.isRemixChange = !vargs.isSendWith && vargs.inputs.length === 0 && vargs.outputs.length === 0;
    vargs.isNewTx = vargs.isRemixChange || vargs.inputs.length > 0 || vargs.outputs.length > 0;
    vargs.isSignAction =
        vargs.isNewTx && (!vargs.options.signAndProcess || vargs.inputs.some(i => i.unlockingScript === undefined));
    vargs.isDelayed = vargs.options.acceptDelayedBroadcast;
    vargs.isNoSend = vargs.options.noSend;
    return vargs;
}
/**
 * Set all default true/false booleans to true or false if undefined.
 * Set all possibly undefined numbers to their default values.
 * Set all possibly undefined arrays to empty arrays.
 * Convert string outpoints to `{ txid: string, vout: number }`
 */
function validateSignActionOptions(options) {
    const o = options ?? {};
    const vo = {
        acceptDelayedBroadcast: defaultTrue(o.acceptDelayedBroadcast),
        returnTXIDOnly: defaultFalse(o.returnTXIDOnly),
        noSend: defaultFalse(o.noSend),
        sendWith: defaultEmpty(o.sendWith)
    };
    return vo;
}
/**
 * Validate SignActionArgs and apply defaults/flags.
 *
 * @param args - SignActionArgs to validate
 * @returns ValidSignActionArgs
 */
function validateSignActionArgs(args) {
    const vargs = {
        spends: args.spends,
        reference: args.reference,
        options: validateSignActionOptions(args.options),
        isSendWith: false,
        isDelayed: false,
        isNoSend: false,
        isNewTx: true,
        isRemixChange: false,
        isTestWerrReviewActions: false
    };
    vargs.isSendWith = vargs.options.sendWith.length > 0;
    vargs.isDelayed = vargs.options.acceptDelayedBroadcast;
    vargs.isNoSend = vargs.options.noSend;
    return vargs;
}
/**
 * Validate AbortActionArgs (ensures reference is a valid base64 string).
 *
 * @param args - AbortActionArgs
 * @returns ValidAbortActionArgs
 */
function validateAbortActionArgs(args) {
    const vargs = {
        reference: validateBase64String(args.reference, 'reference')
    };
    return vargs;
}
/**
 * Validate wallet payment remittance structure.
 *
 * @param args - WalletPayment or undefined
 * @returns ValidWalletPayment or undefined
 */
function validateWalletPayment(args) {
    if (args === undefined)
        return undefined;
    const v = {
        derivationPrefix: validateBase64String(args.derivationPrefix, 'derivationPrefix'),
        derivationSuffix: validateBase64String(args.derivationSuffix, 'derivationSuffix'),
        senderIdentityKey: validateHexString(args.senderIdentityKey, 'senderIdentityKey')
    };
    return v;
}
/**
 * Validate a BasketInsertion structure (basket, custom instructions, tags).
 *
 * @param args - BasketInsertion or undefined
 * @returns ValidBasketInsertion or undefined
 */
function validateBasketInsertion(args) {
    if (args === undefined)
        return undefined;
    const v = {
        basket: validateBasket(args.basket),
        customInstructions: validateOptionalStringLength(args.customInstructions, 'customInstructions', 0, 1000),
        tags: defaultEmpty(args.tags).map(t => validateTag(t))
    };
    return v;
}
/**
 * Validate an InternalizeOutput entry.
 *
 * @param args - InternalizeOutput to validate
 * @returns ValidInternalizeOutput
 */
function validateInternalizeOutput(args) {
    if (args.protocol !== 'basket insertion' && args.protocol !== 'wallet payment') {
        throw new WERR_INVALID_PARAMETER_js_1.default('protocol', '\'basket insertion\' or \'wallet payment\'');
    }
    const v = {
        outputIndex: validatePositiveIntegerOrZero(args.outputIndex, 'outputIndex'),
        protocol: args.protocol,
        paymentRemittance: validateWalletPayment(args.paymentRemittance),
        insertionRemittance: validateBasketInsertion(args.insertionRemittance)
    };
    return v;
}
/**
 * Validate originator string (trim/lowercase and part length checks).
 *
 * @param s - originator string or undefined
 * @returns normalized originator or undefined
 */
function validateOriginator(s) {
    if (s === undefined)
        return undefined;
    s = s.trim().toLowerCase();
    validateStringLength(s, 'originator', 1, 250);
    const sps = s.split('.');
    for (const sp of sps) {
        validateStringLength(sp, 'originator part', 1, 63);
    }
    return s;
}
/**
 * Validate InternalizeActionArgs: tx, outputs, description, labels, permission flag.
 *
 * @param args - InternalizeActionArgs to validate
 * @returns ValidInternalizeActionArgs
 * @throws WERR_INVALID_PARAMETER when invalid
 */
function validateInternalizeActionArgs(args) {
    const vargs = {
        tx: args.tx,
        outputs: args.outputs.map(o => validateInternalizeOutput(o)),
        description: validateStringLength(args.description, 'description', 5, 2000),
        labels: (args.labels ?? []).map(t => validateLabel(t)),
        seekPermission: defaultTrue(args.seekPermission)
    };
    try {
        const beef = Beef_js_1.default.fromBinary(vargs.tx);
        if (beef.txs.length < 1) {
            throw new WERR_INVALID_PARAMETER_js_1.default('tx', 'at least one transaction to internalize an output from');
        }
    }
    catch {
        throw new WERR_INVALID_PARAMETER_js_1.default('tx', 'valid with at least one transaction to internalize an output from');
    }
    if (vargs.outputs.length < 1) {
        throw new WERR_INVALID_PARAMETER_js_1.default('outputs', 'at least one output to internalize from the transaction');
    }
    return vargs;
}
/**
 * Validate an optional outpoint string (txid.vout).
 *
 * @param outpoint - outpoint string or undefined
 * @param name - parameter name used in error messages
 * @returns validated outpoint string or undefined
 */
function validateOptionalOutpointString(outpoint, name) {
    if (outpoint === undefined)
        return undefined;
    return validateOutpointString(outpoint, name);
}
/**
 * Validate an outpoint string of the form txid.vout.
 *
 * @param outpoint - outpoint string
 * @param name - parameter name used in error messages
 * @returns normalized outpoint string (validated txid and vout)
 * @throws WERR_INVALID_PARAMETER when invalid
 */
function validateOutpointString(outpoint, name) {
    const s = outpoint.split('.');
    if (s.length !== 2 || !Number.isInteger(Number(s[1]))) {
        throw new WERR_INVALID_PARAMETER_js_1.default(name, 'txid as hex string and numeric output index joined with \'.\'');
    }
    const txid = validateHexString(s[0], `${name} txid`, undefined, 64);
    const vout = validatePositiveIntegerOrZero(Number(s[1]), `${name} vout`);
    return `${txid}.${vout}`;
}
/**
 * Validate RelinquishOutputArgs (basket and output).
 *
 * @param args - RelinquishOutputArgs
 * @returns ValidRelinquishOutputArgs
 */
function validateRelinquishOutputArgs(args) {
    const vargs = {
        basket: validateBasket(args.basket),
        output: validateOutpointString(args.output, 'output')
    };
    return vargs;
}
/**
 * Validate RelinquishCertificateArgs (type, serialNumber, certifier).
 *
 * @param args - RelinquishCertificateArgs
 * @returns ValidRelinquishCertificateArgs
 */
function validateRelinquishCertificateArgs(args) {
    const vargs = {
        type: validateBase64String(args.type, 'type'),
        serialNumber: validateBase64String(args.serialNumber, 'serialNumber'),
        certifier: validateHexString(args.certifier, 'certifier')
    };
    return vargs;
}
/**
 * Validate ListCertificatesArgs: certifiers, types, paging, and optional privileged reason.
 *
 * @param args - ListCertificatesArgs
 * @returns ValidListCertificatesArgs
 */
function validateListCertificatesArgs(args) {
    const vargs = {
        certifiers: defaultEmpty(args.certifiers.map(c => validateHexString(c.trim(), 'certifiers'))),
        types: defaultEmpty(args.types.map(t => validateBase64String(t.trim(), 'types'))),
        limit: validateInteger(args.limit, 'limit', 10, 1, 10000),
        offset: validatePositiveIntegerOrZero(defaultZero(args.offset), 'offset'),
        privileged: defaultFalse(args.privileged),
        privilegedReason: validateOptionalStringLength(args.privilegedReason, 'privilegedReason', 5, 50),
        partial: undefined
    };
    return vargs;
}
function validateCertificateFields(fields) {
    for (const fieldName of Object.keys(fields)) {
        validateStringLength(fieldName, 'field name', 1, 50);
    }
    return fields;
}
function validateKeyringRevealer(kr, name) {
    if (kr === 'certifier')
        return kr;
    return validateHexString(kr, name);
}
function validateKeyringForSubject(kr, name) {
    for (const fn of Object.keys(kr)) {
        validateStringLength(fn, `${name} field name`, 1, 50);
        validateBase64String(kr[fn], `${name} field value`);
    }
    return kr;
}
/**
 * Validate issuance-specific acquire certificate args.
 *
 * @param args - AcquireCertificateArgs with acquisitionProtocol === 'issuance'
 * @returns ValidAcquireIssuanceCertificateArgs
 * @throws when args contain fields invalid for issuance
 */
function validateAcquireIssuanceCertificateArgs(args) {
    if (args.acquisitionProtocol !== 'issuance') {
        throw new Error('Only acquire certificate via issuance requests allowed here.');
    }
    if (args.serialNumber)
        throw new WERR_INVALID_PARAMETER_js_1.default('serialNumber', 'valid when acquisitionProtocol is "direct"');
    if (args.signature)
        throw new WERR_INVALID_PARAMETER_js_1.default('signature', 'valid when acquisitionProtocol is "direct"');
    if (args.revocationOutpoint) {
        throw new WERR_INVALID_PARAMETER_js_1.default('revocationOutpoint', 'valid when acquisitionProtocol is "direct"');
    }
    if (args.keyringRevealer) {
        throw new WERR_INVALID_PARAMETER_js_1.default('keyringRevealer', 'valid when acquisitionProtocol is "direct"');
    }
    if (args.keyringForSubject != null) {
        throw new WERR_INVALID_PARAMETER_js_1.default('keyringForSubject', 'valid when acquisitionProtocol is "direct"');
    }
    if (!args.certifierUrl) {
        throw new WERR_INVALID_PARAMETER_js_1.default('certifierUrl', 'valid when acquisitionProtocol is "issuance"');
    }
    if (args.privileged && !args.privilegedReason) {
        throw new WERR_INVALID_PARAMETER_js_1.default('privilegedReason', 'valid when \'privileged\' is true ');
    }
    const vargs = {
        type: validateBase64String(args.type, 'type'),
        certifier: validateHexString(args.certifier, 'certifier'),
        certifierUrl: args.certifierUrl,
        fields: validateCertificateFields(args.fields),
        privileged: defaultFalse(args.privileged),
        privilegedReason: validateOptionalStringLength(args.privilegedReason, 'privilegedReason', 5, 50),
        subject: ''
    };
    return vargs;
}
/**
 * Validate direct-acquisition-specific acquire certificate args.
 *
 * @param args - AcquireCertificateArgs with acquisitionProtocol === 'direct'
 * @returns ValidAcquireDirectCertificateArgs
 * @throws when args contain fields invalid for direct acquisition
 */
function validateAcquireDirectCertificateArgs(args) {
    if (args.acquisitionProtocol !== 'direct') {
        throw new Error('Only acquire direct certificate requests allowed here.');
    }
    if (!args.serialNumber)
        throw new WERR_INVALID_PARAMETER_js_1.default('serialNumber', 'valid when acquisitionProtocol is "direct"');
    if (!args.signature)
        throw new WERR_INVALID_PARAMETER_js_1.default('signature', 'valid when acquisitionProtocol is "direct"');
    if (!args.revocationOutpoint) {
        throw new WERR_INVALID_PARAMETER_js_1.default('revocationOutpoint', 'valid when acquisitionProtocol is "direct"');
    }
    if (!args.keyringRevealer) {
        throw new WERR_INVALID_PARAMETER_js_1.default('keyringRevealer', 'valid when acquisitionProtocol is "direct"');
    }
    if (args.keyringForSubject == null) {
        throw new WERR_INVALID_PARAMETER_js_1.default('keyringForSubject', 'valid when acquisitionProtocol is "direct"');
    }
    if (args.privileged && !args.privilegedReason) {
        throw new WERR_INVALID_PARAMETER_js_1.default('privilegedReason', 'valid when \'privileged\' is true ');
    }
    const vargs = {
        type: validateBase64String(args.type, 'type'),
        serialNumber: validateBase64String(args.serialNumber, 'serialNumber'),
        certifier: validateHexString(args.certifier, 'certifier'),
        revocationOutpoint: validateOutpointString(args.revocationOutpoint, 'revocationOutpoint'),
        fields: validateCertificateFields(args.fields),
        signature: validateHexString(args.signature, 'signature'),
        keyringRevealer: validateKeyringRevealer(args.keyringRevealer, 'keyringRevealer'),
        keyringForSubject: validateKeyringForSubject(args.keyringForSubject, 'keyringForSubject'),
        privileged: defaultFalse(args.privileged),
        privilegedReason: validateOptionalStringLength(args.privilegedReason, 'privilegedReason', 5, 50),
        subject: ''
    };
    return vargs;
}
/**
 * Validate ProveCertificateArgs including optional certificate fields and reveal list.
 *
 * @param args - ProveCertificateArgs
 * @returns ValidProveCertificateArgs
 */
function validateProveCertificateArgs(args) {
    if (args.privileged && !args.privilegedReason) {
        throw new WERR_INVALID_PARAMETER_js_1.default('privilegedReason', 'valid when \'privileged\' is true ');
    }
    const vargs = {
        type: validateOptionalBase64String(args.certificate.type, 'certificate.type'),
        serialNumber: validateOptionalBase64String(args.certificate.serialNumber, 'certificate.serialNumber'),
        certifier: validateOptionalHexString(args.certificate.certifier, 'certificate.certifier'),
        subject: validateOptionalHexString(args.certificate.subject, 'certificate.subject'),
        revocationOutpoint: validateOptionalOutpointString(args.certificate.revocationOutpoint, 'certificate.revocationOutpoint'),
        signature: validateOptionalHexString(args.certificate.signature, 'certificate.signature'),
        fieldsToReveal: defaultEmpty(args.fieldsToReveal).map(fieldName => validateStringLength(fieldName, `fieldsToReveal ${fieldName}`, 1, 50)),
        verifier: validateHexString(args.verifier, 'verifier'),
        privileged: defaultFalse(args.privileged),
        privilegedReason: validateOptionalStringLength(args.privilegedReason, 'privilegedReason', 5, 50)
    };
    return vargs;
}
/**
 * Validate DiscoverByIdentityKeyArgs, enforcing identity key length and defaults.
 *
 * @param args - DiscoverByIdentityKeyArgs
 * @returns ValidDiscoverByIdentityKeyArgs
 */
function validateDiscoverByIdentityKeyArgs(args) {
    const vargs = {
        identityKey: validateHexString(args.identityKey, 'identityKey', 66, 66),
        limit: validateInteger(args.limit, 'limit', 10, 1, 10000),
        offset: validatePositiveIntegerOrZero(defaultZero(args.offset), 'offset'),
        seekPermission: defaultFalse(args.seekPermission)
    };
    return vargs;
}
function validateAttributes(attributes) {
    for (const fieldName of Object.keys(attributes)) {
        validateStringLength(fieldName, `field name ${fieldName}`, 1, 50);
    }
    return attributes;
}
/**
 * Validate DiscoverByAttributesArgs: attributes, limit, offset, and permission flag.
 *
 * @param args - DiscoverByAttributesArgs
 * @returns ValidDiscoverByAttributesArgs
 */
function validateDiscoverByAttributesArgs(args) {
    const vargs = {
        attributes: validateAttributes(args.attributes),
        limit: validateInteger(args.limit, 'limit', 10, 1, 10000),
        offset: validatePositiveIntegerOrZero(defaultZero(args.offset), 'offset'),
        seekPermission: defaultFalse(args.seekPermission)
    };
    return vargs;
}
/**
 * @param {BasketStringUnder300Bytes} args.basket - Required. The associated basket name whose outputs should be listed.
 * @param {OutputTagStringUnder300Bytes[]} [args.tags] - Optional. Filter outputs based on these tags.
 * @param {'all' | 'any'} [args.tagQueryMode] - Optional. Filter mode, defining whether all or any of the tags must match. By default, any tag can match.
 * @param {'locking scripts' | 'entire transactions'} [args.include] - Optional. Whether to include locking scripts (with each output) or entire transactions (as aggregated BEEF, at the top level) in the result. By default, unless specified, neither are returned.
 * @param {BooleanDefaultFalse} [args.includeEntireTransactions] - Optional. Whether to include the entire transaction(s) in the result.
 * @param {BooleanDefaultFalse} [args.includeCustomInstructions] - Optional. Whether custom instructions should be returned in the result.
 * @param {BooleanDefaultFalse} [args.includeTags] - Optional. Whether the tags associated with the output should be returned.
 * @param {BooleanDefaultFalse} [args.includeLabels] - Optional. Whether the labels associated with the transaction containing the output should be returned.
 * @param {PositiveIntegerDefault10Max10000} [args.limit] - Optional limit on the number of outputs to return.
 * @param {number} [args.offset] - If positive or zero: Number of outputs to skip before starting to return results, oldest first.
 * If negative: Outputs are returned newest first and offset of -1 is the newest output.
 * When using negative offsets, caution is required as new outputs may be added between calls,
 * potentially causing outputs to be duplicated across calls.
 * @param {BooleanDefaultTrue} [args.seekPermission] — Optional. Whether to seek permission from the user for this operation if required. Default true, will return an error rather than proceed if set to false.
 */
function validateListOutputsArgs(args) {
    let tagQueryMode;
    if (args.tagQueryMode === undefined || args.tagQueryMode === 'any')
        tagQueryMode = 'any';
    else if (args.tagQueryMode === 'all')
        tagQueryMode = 'all';
    else
        throw new WERR_INVALID_PARAMETER_js_1.default('tagQueryMode', 'undefined, \'any\', or \'all\'');
    const vargs = {
        basket: validateBasket(args.basket),
        tags: (args.tags ?? []).map(t => validateTag(t)),
        tagQueryMode,
        includeLockingScripts: args.include === 'locking scripts',
        includeTransactions: args.include === 'entire transactions',
        includeCustomInstructions: defaultFalse(args.includeCustomInstructions),
        includeTags: defaultFalse(args.includeTags),
        includeLabels: defaultFalse(args.includeLabels),
        limit: validateInteger(args.limit, 'limit', 10, 1, 10000),
        offset: validateInteger(args.offset, 'offset', 0),
        seekPermission: defaultTrue(args.seekPermission),
        knownTxids: []
    };
    return vargs;
}
/**
 * @param {LabelStringUnder300Bytes[]} args.labels - An array of labels used to filter actions.
 * @param {'any' | 'all'} [args.labelQueryMode] - Optional. Specifies how to match labels (default is any which matches any of the labels).
 * @param {BooleanDefaultFalse} [args.includeLabels] - Optional. Whether to include transaction labels in the result set.
 * @param {BooleanDefaultFalse} [args.includeInputs] - Optional. Whether to include input details in the result set.
 * @param {BooleanDefaultFalse} [args.includeInputSourceLockingScripts] - Optional. Whether to include input source locking scripts in the result set.
 * @param {BooleanDefaultFalse} [args.includeInputUnlockingScripts] - Optional. Whether to include input unlocking scripts in the result set.
 * @param {BooleanDefaultFalse} [args.includeOutputs] - Optional. Whether to include output details in the result set.
 * @param {BooleanDefaultFalse} [args.includeOutputLockingScripts] - Optional. Whether to include output locking scripts in the result set.
 * @param {PositiveIntegerDefault10Max10000} [args.limit] - Optional. The maximum number of transactions to retrieve.
 * @param {PositiveIntegerOrZero} [args.offset] - Optional. Number of transactions to skip before starting to return the results.
 * @param {BooleanDefaultTrue} [args.seekPermission] — Optional. Whether to seek permission from the user for this operation if required. Default true, will return an error rather than proceed if set to false.
 */
function validateListActionsArgs(args) {
    let labelQueryMode;
    if (args.labelQueryMode === undefined || args.labelQueryMode === 'any')
        labelQueryMode = 'any';
    else if (args.labelQueryMode === 'all')
        labelQueryMode = 'all';
    else
        throw new WERR_INVALID_PARAMETER_js_1.default('labelQueryMode', 'undefined, \'any\', or \'all\'');
    const vargs = {
        labels: (args.labels ?? []).map(t => validateLabel(t)),
        labelQueryMode,
        includeLabels: defaultFalse(args.includeLabels),
        includeInputs: defaultFalse(args.includeInputs),
        includeInputSourceLockingScripts: defaultFalse(args.includeInputSourceLockingScripts),
        includeInputUnlockingScripts: defaultFalse(args.includeInputUnlockingScripts),
        includeOutputs: defaultFalse(args.includeOutputs),
        includeOutputLockingScripts: defaultFalse(args.includeOutputLockingScripts),
        limit: validateInteger(args.limit, 'limit', 10, 1, 10000),
        offset: validateInteger(args.offset, 'offset', 0, 0),
        seekPermission: defaultTrue(args.seekPermission)
    };
    return vargs;
}
/**
 * `createAction` special operation label name value.
 *
 * Causes WERR_REVIEW_ACTIONS throw with dummy properties.
 *
 */
exports.specOpThrowReviewActions = 'a496e747fc3ad5fabdd4ae8f91184e71f87539bd3d962aa2548942faaaf0047a';
//# sourceMappingURL=validationHelpers.js.map