TransactionManager - Adherence to EIP-712  Won't Fix
`fulfill` function requires the user signature on a `transactionId`. While currently, the user SDK code is using a cryptographically secured pseudo-random function to generate the `transactionId`, it should not be counted upon and measures should be placed on the smart-contract level to ensure replay-attack protection.\\n```\\nfunction recoverSignature(\\n  bytes32 transactionId,\\n  uint256 relayerFee,\\n  string memory functionIdentifier,\\n  bytes calldata signature\\n) internal pure returns (address) {\\n  // Create the signed payload\\n  SignedData memory payload = SignedData({\\n    transactionId: transactionId,\\n    relayerFee: relayerFee,\\n    functionIdentifier: functionIdentifier\\n  });\\n\\n  // Recover\\n  return ECDSA.recover(ECDSA.toEthSignedMessageHash(keccak256(abi.encode(payload))), signature);\\n}\\n```\\n
Consider adhering to EIP-712, or at least including `address(this), block.chainId` as part of the data signed by the user.
```\\nfunction recoverSignature(\\n  bytes32 transactionId,\\n  uint256 relayerFee,\\n  string memory functionIdentifier,\\n  bytes calldata signature\\n) internal pure returns (address) {\\n  // Create the signed payload\\n  SignedData memory payload = SignedData({\\n    transactionId: transactionId,\\n    relayerFee: relayerFee,\\n    functionIdentifier: functionIdentifier\\n  });\\n\\n  // Recover\\n  return ECDSA.recover(ECDSA.toEthSignedMessageHash(keccak256(abi.encode(payload))), signature);\\n}\\n```\\n