import { ethers } from 'ethers'; import { buildMerkleRoot, effectiveTokenOrNativeWei, paymentLeafV1Hash, } from '@dbis/checkpoint-core'; import type { PaymentLeaf } from './ingress/types'; export function effectiveValue(leaf: PaymentLeaf): bigint { return effectiveTokenOrNativeWei(leaf); } export function leafHashes(chainId: number, leaves: PaymentLeaf[]): string[] { return leaves.map((l) => paymentLeafV1Hash(chainId, { txHash: l.txHash, from: l.from, to: l.to, value: effectiveValue(l), blockNumber: l.blockNumber, blockTimestamp: l.blockTimestamp, gasUsed: l.gasUsed, success: l.success, }) ); } export function paymentsRoot(chainId: number, leaves: PaymentLeaf[]): string { return buildMerkleRoot(leafHashes(chainId, leaves)); } const PAYMENT_LEAF_TUPLE = 'tuple(bytes32,address,address,uint256,uint256,uint64,uint256,bool)'; export function leavesToTuples(leaves: PaymentLeaf[]): [ string, string, string, bigint, bigint, bigint, bigint, boolean, ][] { return leaves.map((l) => [ l.txHash, l.from, l.to, effectiveValue(l), BigInt(l.blockNumber), BigInt(l.blockTimestamp), l.gasUsed, l.success, ]); } export function encodeExtensionLeavesV1(leaves: PaymentLeaf[]): string { return ethers.AbiCoder.defaultAbiCoder().encode( [PAYMENT_LEAF_TUPLE + '[]'], [leavesToTuples(leaves)] ); } export function encodeExtensionLeavesV2(leaves: PaymentLeaf[]): string { const PAYMENT_LEAF_V2_TUPLE = 'tuple(bytes32,address,address,address,uint256,uint256,uint64,uint256,bool,uint32)'; const tuples = leaves.map((l) => [ l.txHash, l.from, l.to, l.token ?? ethers.ZeroAddress, effectiveValue(l), BigInt(l.blockNumber), BigInt(l.blockTimestamp), l.gasUsed, l.success, l.tokenLogIndex ?? 0, ]); return ethers.AbiCoder.defaultAbiCoder().encode( ['bytes1', PAYMENT_LEAF_V2_TUPLE + '[]'], [ethers.toBeHex(0x02, 1), tuples] ); }