Permit Approval

Permit support

The Items v2 standard supports the EIP-2612 which proposes the additional permit method for making approvals by way of signed messages rather than direct transactions.
The following code can be used as an integration example of the permit operation at the Frontend level to obtain the off-chain signature.
1
window.permit = async function permit(tokenAddress, spender, value, deadline) {
2
isNaN(deadline) && (deadline = window.numberToString((new Date().getTime() / 1000) + 300).split('.')[0]);
3
4
var token = tokenAddress.options ? tokenAddress : window.newContract(window.context.ERC20ABI, tokenAddress);
5
var owner = window.walletAddress;
6
7
var nonce = await token.methods.nonces(owner).call();
8
9
var EIP712Domain = [
10
{ name: 'name', type: 'string' },
11
{ name: 'version', type: 'string' },
12
{ name: 'chainId', type: 'uint256' },
13
{ name: 'verifyingContract', type: 'address' }
14
];
15
16
var domainSeparatorName = "Item";
17
var domainSeparatorVersion = "1";
18
19
try {
20
var domainSeparatorData = await token.methods.EIP712_PERMIT_DOMAINSEPARATOR_NAME_AND_VERSION().call();
21
domainSeparatorName = domainSeparatorData[0];
22
domainSeparatorVersion = domainSeparatorData[1];
23
} catch(e) {
24
}
25
26
var domain = {
27
name: domainSeparatorName,
28
version: domainSeparatorVersion,
29
chainId: await web3.eth.getChainId(),
30
verifyingContract: token.options.address
31
};
32
33
var Permit = [
34
{ name: 'owner', type: 'address' },
35
{ name: 'spender', type: 'address' },
36
{ name: 'value', type: 'uint256' },
37
{ name: 'nonce', type: 'uint256' },
38
{ name: 'deadline', type: 'uint256' }
39
];
40
41
var message = {
42
owner,
43
spender,
44
value,
45
nonce,
46
deadline
47
};
48
49
var data = {
50
types: {
51
EIP712Domain,
52
Permit
53
},
54
domain,
55
primaryType: 'Permit',
56
message
57
};
58
59
return await new Promise(async function(ok, ko) {
60
await web3.currentProvider.sendAsync({
61
method: 'eth_signTypedData_v4',
62
params: [owner, JSON.stringify(data)],
63
from: owner
64
}, function(e, signature) {
65
if (e) {
66
return ko(e);
67
}
68
signature = signature.result.substring(2);
69
return ok({
70
r: '0x' + signature.slice(0, 64),
71
s: '0x' + signature.slice(64, 128),
72
v: web3.utils.toDecimal('0x' + signature.slice(128, 130)),
73
...message
74
});
75
});
76
});
77
}
Copied!
According to this pattern, once the off-chain sign is generated the permit function can be called by any address to execute the on-chain transaction. Through the permit function the allowanced amount that the spender address can spend is registered and saved in the Main Interface contract.
1
itemData.allowance[owner][spender] = value;
Copied!
If the off-chain sign is correctly generated and signed by the owner but the permit function is not executed (passing all the parameters related to the sign and explained here) the spender address is not allowed to spend the owner's ITEMs amount.
Since the transaction can be performed by anyone (once the signature is correctly signed by the owner address), an ITEM v2 can be used to build also complex applications regarding gas-less transactions or meta-transactions that use a third party to execute the transaction and pay the gas fee.
Copy link