Solidity smart contract that verifies an authorisation signature before forwarding the call to the destination contract. Can be used for backend-gated minting.
The relay is deployed on-chain and is configured with an operator
role (OPERATOR_ROLE
)
The backend signs an EIP-712 message of the following structure with an owner key:
struct RelayData {
bytes32 nonce;
address to;
uint256 validityStart;
uint256 validityEnd;
uint256 chainId;
bytes callData;
}
Where to
is the destination contract, callData
is the ABI-encoded calldata. The relay verifies that the recovered signature matches an owner role and executes the call on the destination contract.
The operator
address can be updated by the admin
(DEFAULT_ADMIN_ROLE
)
This example uses a test agains Sequence's ERC721 contract library.
See test/AuthenticatedRelay.t.sol
for details.
- Foundry: https://book.getfoundry.sh/
forge install
# build sequence contracts dependencies:
pushd lib/contracts-library
yarn && yarn build
popd
forge build
forge test
Set the environment variables:
RELAY_CONTRACT
: The authenticated relay addressOPERATOR_PRIVATE_KEY
: The operator private keyERC721_CONTRACT
: The ERC721 contract address. It has amint(address,uint256)
function that can only be called by the authenticated relayRECIPIENT
: The NFT recipientSENDER_PRIVATE_KEY
: The key of the wallet that will broadcast the transactionNONCE
: A nonce to prevent replays
Then run the script:
forge script script/MinterWithRelay.s.sol:MintWithRelay --broadcast --private-key $SENDER_PRIVATE_KEY