I found out how to sign an approval into Metamask,in conformity with EIP712:
const domain = [
{ name: "name", type: "string" },
{ name: "version", type: "string" },
{ name: "chainId", type: "uint256" },
{ name: "verifyingContract", type: "address" },
{ name: "salt", type: "bytes32" },
];
const bid = [
{ name: "makerToken", type: "address" },
{ name: "takerToken", type: "address" },
{ name: "makerAmount", type: "uint256" },
{ name: "takerAmount", type: "uint256" },
{ name: "takerTokenFeeAmount", type: "uint256" },
{ name: "maker", type: "address" },
{name: "taker", type: "address" },
{name: "sender", type: "address" },
{name: "feeRecipient", type: "address" },
{name: "pool", type: "bytes32" },
{ name: "expiry", type: "uint64" },
{ name: "salt", type: "uint256" },
{name: "verifyingContract", type: "address" },
{ name: "chainId", type: "uint256" },
];
const domainData = {
name: "myDomain",
version: "1",
chainId: 56,
verifyingContract: "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
salt: '0x1656319140'
};
var message = {
makerToken: '0x55d398326f99059ff775485246999027b3197955',
takerToken: '0xe9e7cea3dedca5984780bafc599bd69add087d56',
makerAmount: '1000000000000000000',
takerAmount: '990000000000000000',
takerTokenFeeAmount: '990000000000000',
maker: '0x1111111111111111111111111111111111111111', //my address
taker: '0x0000000000000000000000000000000000000000',
sender: '0x0000000000000000000000000000000000000000',
feeRecipient: '0x1111111111111111111111111111111111111111',
pool: '0x0000000000000000000000000000000000000000000000000000000000000037',
expiry: '1656319140',
salt: '0x1656319140',
verifyingContract: '0xdef1c0ded9bec7f1a1670819833240f027b25eff',
chainId: '56'
}
const data = JSON.stringify({
types: {
EIP712Domain: domain,
Bid: bid
},
domain: domainData,
primaryType: "Bid",
message: message
});
await web3.currentProvider.sendAsync(
{
method: "eth_signTypedData_v3",
params: [fromAddress, data],
from: fromAddress
},
function(err, result) {
if (err) {
return console.error(err);
}
const signature = result.result.substring(2);
const r = "0x" + signature.substring(0, 64);
const s = "0x" + signature.substring(64, 128);
const v = parseInt(signature.substring(128, 130), 16);
// The signature is now comprised of r, s, and v.
Then I wrap a JSON and request 0x API for this limit order, with the newly created signature:
json = [
{
"makerToken": "0x55d398326f99059ff775485246999027b3197955",
"takerToken": "0xe9e7cea3dedca5984780bafc599bd69add087d56",
"makerAmount": "100000000000000000",
"takerAmount": "99000000000000000",
"maker": "0x1111111111111111111111111111111111111111",
"taker": "0x0000000000000000000000000000000000000000",
"chainId": 56,
"verifyingContract": "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
"takerTokenFeeAmount": "99000000000000",
"sender": "0x0000000000000000000000000000000000000000",
"feeRecipient": "0x1111111111111111111111111111111111111111",
"pool": "0x0000000000000000000000000000000000000000000000000000000000000037",
"salt": "0x1656319140",
"expiry": "1656319140",
"signature": {
"r": r,
"s": s,
"v": v,
"signatureType": 2
}
}
];
axios.post('https://bsc.api.0x.org/orderbook/v1/orders', json);
The format of signature is valid (r, s, and v), However, 0x API's answers that the signature is not valid:
{"code":100,"reason":"Validation Failed","validationErrors":[{"code":1005,"field":"signedOrder[0]","reason":"InvalidSignature"}]}
What am I missing ? Should I change the approval's message to fit exactly the JSON request ? (Yet there are extra fields, so i'm not sure...)
Thanks in advance :-)