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

101 lines 3.98 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.verifyDepositSignature = void 0; const ssz_1 = require("@chainsafe/ssz"); const bls_eth_wasm_1 = __importDefault(require("bls-eth-wasm")); const viem_1 = require("viem"); const constants_js_1 = require("./constants.js"); const DepositMessageSSZ = new ssz_1.ContainerType({ pubkey: new ssz_1.ByteVectorType(48), withdrawal_credentials: new ssz_1.ByteVectorType(32), amount: new ssz_1.UintBigintType(8), }); const ForkDataSSZ = new ssz_1.ContainerType({ current_version: new ssz_1.ByteVectorType(4), genesis_validators_root: new ssz_1.ByteVectorType(32), }); const SigningDataSSZ = new ssz_1.ContainerType({ object_root: new ssz_1.ByteVectorType(32), domain: new ssz_1.ByteVectorType(32), }); let blsInitialized = false; const ensureBLSInit = async () => { if (!blsInitialized) { await bls_eth_wasm_1.default.init(bls_eth_wasm_1.default.BLS12_381); blsInitialized = true; } }; const ensureHex = (value) => { return (value.startsWith('0x') ? value : `0x${value}`); }; const getForkVersion = (chainId) => { const version = constants_js_1.FIXED_FORK_VERSION[chainId]; if (!version) { throw new Error(`Fork version not found for chain ${chainId}`); } const hex = version.padStart(8, '0'); return (0, viem_1.hexToBytes)(ensureHex(hex)); }; const computeForkDataRoot = (currentVersion, genesisValidatorsRoot) => { const forkData = { current_version: currentVersion, genesis_validators_root: genesisValidatorsRoot, }; return ForkDataSSZ.hashTreeRoot(forkData); }; const computeDomain = (domainType, forkVersion, genesisValidatorsRoot) => { const forkDataRoot = computeForkDataRoot(forkVersion, genesisValidatorsRoot); const domain = new Uint8Array(32); domain.set(domainType, 0); domain.set(forkDataRoot.slice(0, 28), 4); return domain; }; const computeSigningRoot = (objectRoot, domain) => { const signingData = { object_root: objectRoot, domain: domain, }; return SigningDataSSZ.hashTreeRoot(signingData); }; const computeDepositMessageRoot = (message) => { return DepositMessageSSZ.hashTreeRoot(message); }; const verifyDepositSignature = async (data, chainId) => { try { await ensureBLSInit(); const pubkey = (0, viem_1.hexToBytes)(data.pubkey); const signature = (0, viem_1.hexToBytes)(data.signature); const withdrawalCredentials = (0, viem_1.hexToBytes)(data.withdrawal_credentials); const amount = BigInt(data.amount); if (pubkey.length !== 48 || signature.length !== 96 || withdrawalCredentials.length !== 32) { return false; } const depositMessage = { pubkey, withdrawal_credentials: withdrawalCredentials, amount, }; const messageRoot = computeDepositMessageRoot(depositMessage); if ((0, viem_1.toHex)(messageRoot).toLowerCase() !== data.deposit_message_root.toLowerCase()) { return false; } const forkVersion = getForkVersion(chainId); const genesisValidatorsRoot = new Uint8Array(32); const domainType = (0, viem_1.hexToBytes)(constants_js_1.DOMAIN_DEPOSIT); const domain = computeDomain(domainType, forkVersion, genesisValidatorsRoot); const signingRoot = computeSigningRoot(messageRoot, domain); const publicKey = new bls_eth_wasm_1.default.PublicKey(); publicKey.deserialize(pubkey); const sig = new bls_eth_wasm_1.default.Signature(); sig.deserialize(signature); return publicKey.verify(sig, signingRoot); } catch { return false; } }; exports.verifyDepositSignature = verifyDepositSignature; //# sourceMappingURL=signature.js.map