Skip to content

Instantly share code, notes, and snippets.

@arefaslani
Created July 30, 2020 06:00
Show Gist options
  • Save arefaslani/88e9dc20ff004e2738bdc6140a363ba2 to your computer and use it in GitHub Desktop.
Save arefaslani/88e9dc20ff004e2738bdc6140a363ba2 to your computer and use it in GitHub Desktop.
import Web3 from "web3";
import biconomy from "utilities/biconomy";
const domainType = [
{ name: "name", type: "string" },
{ name: "version", type: "string" },
{ name: "chainId", type: "uint256" },
{ name: "verifyingContract", type: "address" }
];
const metaTransactionType = [
{ name: "nonce", type: "uint256" },
{ name: "from", type: "address" },
{ name: "functionSignature", type: "bytes" }
];
const domainData = {
name: "ERC1155",
version: "1",
verifyingContract: process.env.ETHEREUM_CONTRACT_ADDRESS,
chainId: process.env.ETHEREUM_CHAIN_ID
};
const web3 = new Web3(biconomy);
const contract = new web3.eth.Contract(
JSON.parse(process.env.ETHEREUM_CONTRACT_ABI),
process.env.ETHEREUM_CONTRACT_ADDRESS
);
const getSignatureParameters = signature => {
if (!web3.utils.isHexStrict(signature)) {
throw new Error(`Given value "${signature}" is not a valid hex string`);
}
const r = signature.slice(0, 66);
const s = "0x".concat(signature.slice(66, 130));
let v = "0x".concat(signature.slice(130, 132));
v = web3.utils.hexToNumber(v);
if (![27, 28].includes(v)) v += 27;
return { r, s, v };
};
const sendTransaction = async ({
from,
functionSignature,
r,
s,
v,
onTransactionCreated,
onComplete
}) => {
try {
const gasLimit = await contract.methods
.executeMetaTransaction(from, functionSignature, r, s, v)
.estimateGas({ from });
const gasPrice = await web3.eth.getGasPrice();
const tx = contract.methods
.executeMetaTransaction(from, functionSignature, r, s, v)
.send({
from,
gasPrice: web3.utils.toHex(gasPrice),
gasLimit: web3.utils.toHex(gasLimit)
});
tx.on("transactionHash", hash => {
onTransactionCreated(hash);
console.log(hash);
}).once("confirmation", (confirmationNumber, receipt) => {
onComplete(receipt);
console.log(receipt);
});
} catch (error) {
console.log(error);
}
};
export default {
mint: async ({
from,
id,
amount,
onTransactionCreated = () => {},
onComplete = () => {}
}) => {
const nonce = await contract.methods.getNonce(from).call();
const functionSignature = contract.methods
.mint(from, id, amount, "0x0")
.encodeABI();
const message = {
nonce: parseInt(nonce, 10),
from,
functionSignature
};
const dataToSign = JSON.stringify({
types: {
EIP712Domain: domainType,
MetaTransaction: metaTransactionType
},
domain: domainData,
primaryType: "MetaTransaction",
message
});
web3.currentProvider.send(
{
jsonrpc: "2.0",
id: 999999999999,
method: "eth_signTypedData_v4",
params: [from, dataToSign]
},
(error, response) => {
const { r, s, v } = getSignatureParameters(response.result);
sendTransaction({
from,
functionSignature,
r,
s,
v,
onTransactionCreated,
onComplete
});
}
);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment