import { ethers } from "ethers" ; import { hash , Json , toHexString } from "@chainsafe/ssz" ; import { phase0 , ssz } from "@chainsafe/lodestar-types" ; import { IChainForkConfig } from "@chainsafe/lodestar-config" ; import bls , { SecretKey , PublicKey } from "@chainsafe/bls" ; import { computeSigningRoot , computeDomain , ZERO_HASH } from "@chainsafe/lodestar-beacon-state-transition" ; import { BLS_WITHDRAWAL_PREFIX , DOMAIN_DEPOSIT } from "@chainsafe/lodestar-params" ; const depositFunctionFragment = "function deposit(bytes pubkey, bytes withdrawal_credentials, bytes signature, bytes32 deposit_data_root) external payable;" ; function getDepositInterface ( ) { return new ethers . utils . Interface ( [ depositFunctionFragment ] ) ; } export function decodeEth1TxData ( bytes , amount ) { const depositContract = getDepositInterface ( ) ; const inputs = depositContract . decodeFunctionData ( "deposit" , bytes ) ; const { deposit_data_root : root } = inputs ; const depositData = ssz . phase0 . DepositData . fromJson ( { ... inputs , amount } , { case : "snake" } ) ; const depositDataRoot = ssz . phase0 . DepositData . hashTreeRoot ( depositData ) ; if ( toHexString ( depositDataRoot ) !== root ) throw Error ( "deposit data root mismatch" ) ; return { depositData , root : root as string } ; } export function encodeDepositData ( amount , withdrawalPublicKey , signingKey , config ) { const pubkey = signingKey . toPublicKey ( ) . toBytes ( ) ; const withdrawalCredentials = Buffer . concat ( [ BLS_WITHDRAWAL_PREFIX , hash ( withdrawalPublicKey . toBytes ( ) ) . slice ( 1 ) ] ) ; const depositData = { pubkey , withdrawalCredentials , amount , signature : Buffer . alloc ( 96 ) , } ; const domain = computeDomain ( DOMAIN_DEPOSIT , config . GENESIS_FORK_VERSION , ZERO_HASH ) ; const signingroot = computeSigningRoot ( ssz . phase0 . DepositMessage , depositData , domain ) ; depositData . signature = bls . sign ( signingKey . toBytes ( ) , signingroot ) ; const depositDataRoot = ssz . phase0 . DepositData . hashTreeRoot ( depositData ) ; const depositContract = getDepositInterface ( ) ; return depositContract . encodeFunctionData ( "deposit" , [ pubkey , withdrawalCredentials , depositData . signature , depositDataRoot , ] ) ; }