contract, or delegating it to another contract and doing some memory access
calculations, like querying a mapping.
### Recipient example
```solidity
contract RecipientExample {
function purchaseItem(uint256 itemId) external {
address sender = _msgSender();
... perform the purchase for sender
}
address immutable _trustedForwarder;
constructor(address trustedForwarder) internal {
_trustedForwarder = trustedForwarder;
}
function isTrustedForwarder(address forwarder) external returns(bool) {
return forwarder == _trustedForwarder;
}
function _msgSender() internal view returns (address payable signer) {
signer = msg.sender;
if (isTrustedForwarder(signer)) {
bytes memory data = msg.data;
uint256 length = msg.data.length;
assembly { signer := mload(add(data, length))) }
}
}
}
```
## Rationale
* Make it easy for contract developers to add support for meta
transactions by standardizing the simplest viable contract interface.
* Without support for meta transactions in the recipient contract, an externally owned
account can not use meta transactions to interact with the recipient contract.
* Without a standard contract interface, there is no standard way for a client
to discover whether a recipient supports meta transactions.
* Without a standard contract interface, there is no standard way to send a
meta transaction to a recipient.
* Without the ability to leverage a trusted forwarder every recipient contract
has to internally implement the logic required to accept meta transactions securely.
* Without a discovery protocol, there is no mechanism for a client to discover
whether a recipient supports a specific forwarder.
* Making the contract interface agnostic to the internal implementation
details of the trusted forwarder, makes it possible for a recipient contract
to support multiple forwarders with no change to code.
## Security Considerations
A bad forwarder may allow forgery of the `msg.sender` returned from
`_msgSender()` and allow transactions to appear to be coming from any address.
This means a recipient contract should be very careful which forwarder it
trusts and whether this can be modified. The power to change the forwarder
trusted by a recipient is equivalent to giving full control over the contract.
If this kind of control over the recipient is acceptable, it is recommended
that only the owner of the recipient contract be able to modify which forwarder
is trusted. Otherwise best to leave it unmodifiable, as in the example above.
## Implementations
An implementation of a base class for a recipient: [BaseRelayRecipient.sol](https://github.com/opengsn/forwarder/blob/master/contracts/BaseRelayRecipient.sol)