"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateSignature = exports.computeSignatureHash = exports.parseSignature = exports.serializeEventSignature = exports.encodeParamWithIndexedFlag = exports.computeSignature = void 0;
const error_1 = require("../utils/error");
const datatypes_1 = require("./datatypes");
const wasm_1 = require("./wasm");
class InvalidSignatureError extends error_1.RuntimeError {
}
function computeSignature(abi) {
    var _a;
    if (abi.name == null) {
        throw new InvalidSignatureError('Cannot serialize ABI definition without name');
    }
    return `${abi.name}(${((_a = abi.inputs) !== null && _a !== void 0 ? _a : []).map(datatypes_1.encodeInputType).join(',')})`;
}
exports.computeSignature = computeSignature;
exports.encodeParamWithIndexedFlag = (input) => input.indexed ? `${datatypes_1.encodeInputType(input)} indexed` : datatypes_1.encodeInputType(input);
function serializeEventSignature(abi) {
    var _a;
    if (abi.name == null) {
        throw new InvalidSignatureError('Cannot serialize ABI event definition without name');
    }
    return `${abi.name}(${((_a = abi.inputs) !== null && _a !== void 0 ? _a : []).map(exports.encodeParamWithIndexedFlag).join(',')})`;
}
exports.serializeEventSignature = serializeEventSignature;
function parseSignature(signature, type) {
    return (type === 'event' ? wasm_1.parseEventSignature(signature) : wasm_1.parseFunctionSignature(signature));
}
exports.parseSignature = parseSignature;
function computeSignatureHash(signature, type) {
    const hash = wasm_1.sha3(signature);
    if (hash == null) {
        throw new InvalidSignatureError(`NULL signature hash for signature ${signature}`);
    }
    return type === 'event' ? hash.slice(2) : hash.slice(2, 10);
}
exports.computeSignatureHash = computeSignatureHash;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function validateSignature(signature, type) {
    const parsed = parseSignature(signature, type);
    for (const input of parsed.inputs) {
        if (!datatypes_1.isValidAbiType(input.type)) {
            throw new InvalidSignatureError(`Invalid data type: ${input.type}`);
        }
    }
    const serialized = computeSignature(parsed);
    if (type !== 'event' && serialized !== signature) {
        throw new InvalidSignatureError(`Serialized function signature does not match original`);
    }
}
exports.validateSignature = validateSignature;
