UNPKG

@exromany/lido-csm-sdk

Version:

[![GitHub license](https://img.shields.io/github/license/lidofinance/lido-csm-sdk?color=limegreen)](https://github.com/lidofinance/lido-csm-sdk/blob/main/LICENSE.txt) [![Version npm](https://img.shields.io/npm/v/@lidofinance/lido-csm-sdk?label=version)](h

167 lines 6.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.validateDepositDataSync = exports.validateDepositData = void 0; const compare_lowercase_js_1 = require("../common/utils/compare-lowercase.js"); const index_js_1 = require("../common/utils/index.js"); const types_js_1 = require("./types.js"); const constants_js_1 = require("./constants.js"); const signature_js_1 = require("./signature.js"); const validateBasicFields = (data, index, config) => { const errors = []; if (!(0, index_js_1.isHexadecimalString)(data.pubkey, constants_js_1.PUBKEY_LENGTH)) { errors.push({ index, field: 'pubkey', message: 'pubkey is not valid string', code: types_js_1.ValidationErrorCode.INVALID_PUBKEY, }); } if (!(0, index_js_1.isHexadecimalString)(data.signature, constants_js_1.SIGNATURE_LENGTH)) { errors.push({ index, field: 'signature', message: 'signature is not valid string', code: types_js_1.ValidationErrorCode.INVALID_SIGNATURE, }); } if (!(0, index_js_1.isHexadecimalString)(data.deposit_message_root, constants_js_1.DEPOSIT_ROOT_LENGTH)) { errors.push({ index, field: 'deposit_message_root', message: 'deposit_message_root is not a valid string', code: types_js_1.ValidationErrorCode.INVALID_DEPOSIT_ROOT, }); } if (!(0, index_js_1.isHexadecimalString)(data.deposit_data_root, constants_js_1.DEPOSIT_ROOT_LENGTH)) { errors.push({ index, field: 'deposit_data_root', message: 'deposit_data_root is not a valid string', code: types_js_1.ValidationErrorCode.INVALID_DEPOSIT_ROOT, }); } if (!(0, index_js_1.isHexadecimalString)(data.withdrawal_credentials, constants_js_1.WITHDRAWAL_CREDENTIALS_LENGTH)) { errors.push({ index, field: 'withdrawal_credentials', message: 'withdrawal_credentials is not a valid string', code: types_js_1.ValidationErrorCode.INVALID_WITHDRAWAL_CREDENTIALS, }); } else if (!(0, compare_lowercase_js_1.compareLowercase)((0, index_js_1.trimHexPrefix)(data.withdrawal_credentials), `${constants_js_1.FIXED_WC_PREFIX}${(0, index_js_1.trimHexPrefix)(config.withdrawalCredentials)}`) && !(0, compare_lowercase_js_1.compareLowercase)((0, index_js_1.trimHexPrefix)(data.withdrawal_credentials), (0, index_js_1.trimHexPrefix)(config.withdrawalCredentials))) { errors.push({ index, field: 'withdrawal_credentials', message: `withdrawal_credentials is not the Lido Withdrawal Vault`, code: types_js_1.ValidationErrorCode.INVALID_WITHDRAWAL_CREDENTIALS, }); } if (data.amount !== constants_js_1.FIXED_AMOUNT) { errors.push({ index, field: 'amount', message: 'amount is not equal to 32 eth', code: types_js_1.ValidationErrorCode.INVALID_AMOUNT, }); } const requiredNetworkName = constants_js_1.FIXED_NETWORK[config.chainId]; const networkName = data.network_name || data.eth2_network_name; if (!(networkName === requiredNetworkName)) { errors.push({ index, field: 'network_name', message: `network_name or eth2_network_name is not equal to ${requiredNetworkName}`, code: types_js_1.ValidationErrorCode.INVALID_NETWORK, }); } const forkVersion = constants_js_1.FIXED_FORK_VERSION[config.chainId]; if (data.fork_version !== forkVersion) { errors.push({ index, field: 'fork_version', message: `fork_version is not equal to ${forkVersion}`, code: types_js_1.ValidationErrorCode.INVALID_FORK_VERSION, }); } return errors; }; const processDuplicatePubkey = (config) => { const existingIndices = config.pubkeyMap.get(config.pubkey); if (!existingIndices) { config.pubkeyMap.set(config.pubkey, [config.index]); return; } existingIndices.push(config.index); existingIndices.forEach((idx) => { const hasExistingError = config.errors.some((e) => e.index === idx && e.code === types_js_1.ValidationErrorCode.DUPLICATE_PUBKEY); if (hasExistingError) { return; } config.errors.push({ index: idx, field: 'pubkey', message: 'pubkey is duplicated in deposit data', code: types_js_1.ValidationErrorCode.DUPLICATE_PUBKEY, }); }); }; const performBasicValidation = (depositData, config) => { const errors = []; const pubkeyMap = new Map(); for (const [i, data] of depositData.entries()) { if (!data) { errors.push({ index: i, message: 'deposit data item is missing', code: types_js_1.ValidationErrorCode.MISSING_FIELD, }); continue; } const basicErrors = validateBasicFields(data, i, config); errors.push(...basicErrors); const pubkey = data.pubkey?.toLowerCase(); if (pubkey) { processDuplicatePubkey({ pubkey, index: i, pubkeyMap, errors, }); } } return errors; }; const validateDepositData = async (depositData, options) => { const errors = performBasicValidation(depositData, { chainId: options.chainId, withdrawalCredentials: options.withdrawalCredentials, }); const signatureVerificationPromises = depositData.map((data, index) => { if (!data) { return Promise.resolve({ index, isValid: false }); } return (0, signature_js_1.verifyDepositSignature)(data, options.chainId) .then((isValid) => ({ index, isValid })) .catch(() => ({ index, isValid: false })); }); const signatureResults = await Promise.all(signatureVerificationPromises); signatureResults.forEach(({ index, isValid }) => { if (!isValid) { errors.push({ index, field: 'signature', message: 'invalid signature', code: types_js_1.ValidationErrorCode.INVALID_BLS_SIGNATURE, }); } }); return errors; }; exports.validateDepositData = validateDepositData; const validateDepositDataSync = (depositData, config) => { return performBasicValidation(depositData, config); }; exports.validateDepositDataSync = validateDepositDataSync; //# sourceMappingURL=validator.js.map