Skip to content

Instantly share code, notes, and snippets.

@developeruche
Created June 15, 2023 08:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save developeruche/4fa14dc6f5a1a73113e9597285ba2ea4 to your computer and use it in GitHub Desktop.
Save developeruche/4fa14dc6f5a1a73113e9597285ba2ea4 to your computer and use it in GitHub Desktop.
import {ethers} from "hardhat";
import ethSigUtil from 'eth-sig-util';
import axios from 'axios';
const EIP712Domain = [
{ name: 'name', type: 'string' },
{ name: 'version', type: 'string' },
{ name: 'chainId', type: 'uint256' },
{ name: 'verifyingContract', type: 'address' }
];
const ForwardRequest = [
{ name: 'from', type: 'address' },
{ name: 'to', type: 'address' },
{ name: 'value', type: 'uint256' },
{ name: 'gas', type: 'uint256' },
{ name: 'nonce', type: 'uint256' },
{ name: 'data', type: 'bytes' },
];
function getMetaTxTypeData(chainId: any, verifyingContract: any) {
return {
types: {
EIP712Domain,
ForwardRequest,
},
domain: {
name: 'MinimalForwarder',
version: '0.0.1',
chainId,
verifyingContract,
},
primaryType: 'ForwardRequest',
}
};
async function signTypedData(signer: any, from: any, data: any) {
// If signer is a private key, use it to sign
if (typeof(signer) === 'string') {
const privateKey = Buffer.from(signer.replace(/^0x/, ''), 'hex');
return ethSigUtil.signTypedMessage(privateKey, { data });
}
// Otherwise, send the signTypedData RPC call
// Note that hardhatvm and metamask require different EIP712 input
const isHardhat = data.domain.chainId == 31337;
const [method, argData] = isHardhat
? ['eth_signTypedData', data]
: ['eth_signTypedData_v4', JSON.stringify(data)]
return await signer.send(method, [from, argData]);
}
async function signMetaTxRequest(signer:any, forwarder:any, input:any) {
const request = await buildRequest(forwarder, input);
console.log('request', request)
const toSign = await buildTypedData(forwarder, request);
console.log('toSign', toSign)
const signature = await signTypedData(signer, input.from, toSign);
console.log('signature', signature)
return { signature, request };
}
async function buildRequest(forwarder:any, input:any) {
const nonce = await forwarder.getNonce(input.from).then((nonce: any) => nonce.toString());
return { value: 0, gas: 1e6, nonce, ...input };
}
async function buildTypedData(forwarder:any, request:any) {
const chainId = await forwarder.provider.getNetwork().then((n:any) => n.chainId);
const typeData = getMetaTxTypeData(chainId, forwarder.address);
return { ...typeData, message: request };
}
const forwarderAbi = [];
const forwarderAddress = "0xE8b992C779C7AbF5FaEeD81AB7B425FDA78A1856";
const url = "https://api.defender.openzeppelin.com/autotasks/c892d48f-5432-4f06-8721-37151deb7c20/runs/webhook/72e3ea12-98b4-47d3-b317-212e3ce70193/SRBGhSaLmzadNbeqiwbWpo";
async function sendMetaTx(signer: any) {
const forwarder = await ethers.getContractAt("MeProtocolForwarder", forwarderAddress);
const from = await signer.getAddress();
const data = "0x";
const to = "0x02B59f28f6bA119dc7Ef1D62C90259a20626e719";
const request = await signMetaTxRequest(signer.provider, forwarder, { to, from, data });
// return fetch(url, {
// method: 'POST',
// body: JSON.stringify(request),
// headers: { 'Content-Type': 'application/json' },
// });
return axios.post(url, request);
}
const run = async () => {
const [signer] = await ethers.getSigners();
await sendMetaTx(signer);
}
run()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment