function _generateSignature( uint256 signerPrvKey, address signer, ICyanPaymentPlan.Item memory item, ICyanPaymentPlan.Plan memory plan, uint256 planId, uint256 signedBlockNum ) private returns (bytes memory) { bytes32 itemHash = keccak256( abi.encodePacked( item.cyanVaultAddress, item.contractAddress, item.tokenId, item.amount, item.itemType ) ); bytes32 planHash = keccak256( abi.encodePacked( plan.amount, plan.downPaymentPercent, plan.interestRate, plan.serviceFeeRate, plan.term, plan.totalNumberOfPayments, plan.counterPaidPayments, plan.autoRepayStatus ) ); bytes32 msgHash = keccak256( abi.encodePacked(itemHash, planHash, planId, signedBlockNum) ); bytes32 signedHash = keccak256( abi.encodePacked("\x19Ethereum Signed Message:\n32", msgHash) ); vm.startPrank(signer); (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPrvKey, signedHash); vm.stopPrank(); bytes memory signature = abi.encodePacked(r, s, v); assertEq(signedHash.recover(signature), signer); return signature; }