Skip to content

Commit 5d37602

Browse files
authored
Adding NFT permit option (#363)
1 parent 21efc60 commit 5d37602

File tree

2 files changed

+131
-0
lines changed

2 files changed

+131
-0
lines changed

src/index.html

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,38 @@ <h4 class="card-title">
625625
</button>
626626
</div>
627627

628+
<div class="form-group">
629+
<label>NFT Permit</label>
630+
<button
631+
class="btn btn-primary btn-lg btn-block mb-3"
632+
id="sign721Permit"
633+
disabled
634+
>
635+
Sign
636+
</button>
637+
638+
<p class="info-text alert alert-warning">
639+
Result:
640+
<span id="sign721PermitResult"></span>
641+
<p class="info-text alert alert-warning" id="sign721PermitResultR">r: </p>
642+
<p class="info-text alert alert-warning" id="sign721PermitResultS">s: </p>
643+
<p class="info-text alert alert-warning" id="sign721PermitResultV">v: </p>
644+
</p>
645+
646+
<button
647+
class="btn btn-primary btn-lg btn-block mb-3"
648+
id="sign721PermitVerify"
649+
disabled
650+
>
651+
Verify
652+
</button>
653+
654+
<p class="info-text alert alert-warning">
655+
Recovery result:
656+
<span id="sign721PermitVerifyResult"></span>
657+
</p>
658+
</div>
659+
628660
<p class="info-text alert alert-secondary">
629661
ERC 721 methods result: <span id="nftsStatus"></span>
630662
</p>

src/index.js

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ const transferTokenInput = document.getElementById('transferTokenInput');
130130
const transferFromButton = document.getElementById('transferFromButton');
131131
const nftsStatus = document.getElementById('nftsStatus');
132132
const erc721TokenAddresses = document.getElementById('erc721TokenAddresses');
133+
// 721 Permit
134+
const sign721Permit = document.getElementById('sign721Permit');
135+
const sign721PermitResult = document.getElementById('sign721PermitResult');
136+
const sign721PermitResultR = document.getElementById('sign721PermitResultR');
137+
const sign721PermitResultS = document.getElementById('sign721PermitResultS');
138+
const sign721PermitResultV = document.getElementById('sign721PermitResultV');
139+
const sign721PermitVerify = document.getElementById('sign721PermitVerify');
140+
const sign721PermitVerifyResult = document.getElementById(
141+
'sign721PermitVerifyResult',
142+
);
133143

134144
// ERC 1155 Section
135145

@@ -376,6 +386,8 @@ const allConnectedButtons = [
376386
withdrawButton,
377387
deployNFTsButton,
378388
mintButton,
389+
sign721Permit,
390+
sign721PermitVerify,
379391
mintAmountInput,
380392
approveTokenInput,
381393
approveButton,
@@ -1081,6 +1093,7 @@ const updateContractElements = () => {
10811093
erc721TokenAddresses.innerHTML = nftsContract ? nftsContract.address : '';
10821094
nftsStatus.innerHTML = 'Deployed';
10831095
mintButton.disabled = false;
1096+
sign721Permit.disabled = false;
10841097
mintAmountInput.disabled = false;
10851098
approveTokenInput.disabled = false;
10861099
approveButton.disabled = false;
@@ -1308,6 +1321,7 @@ const initializeFormElements = () => {
13081321

13091322
nftsStatus.innerHTML = 'Deployed';
13101323
mintButton.disabled = false;
1324+
sign721Permit.disabled = false;
13111325
mintAmountInput.disabled = false;
13121326
};
13131327

@@ -1358,6 +1372,65 @@ const initializeFormElements = () => {
13581372
watchNFTButtons.innerHTML = '';
13591373
};
13601374

1375+
sign721Permit.onclick = async () => {
1376+
const from = accounts[0];
1377+
const msgParams = await getNFTMsgParams();
1378+
console.log(msgParams);
1379+
1380+
let sign;
1381+
let r;
1382+
let s;
1383+
let v;
1384+
1385+
try {
1386+
sign = await provider.request({
1387+
method: 'eth_signTypedData_v4',
1388+
params: [from, JSON.stringify(msgParams)],
1389+
});
1390+
const { _r, _s, _v } = splitSig(sign);
1391+
r = `0x${_r.toString('hex')}`;
1392+
s = `0x${_s.toString('hex')}`;
1393+
v = _v.toString();
1394+
1395+
sign721PermitResult.innerHTML = sign;
1396+
sign721PermitResultR.innerHTML = `r: ${r}`;
1397+
sign721PermitResultS.innerHTML = `s: ${s}`;
1398+
sign721PermitResultV.innerHTML = `v: ${v}`;
1399+
sign721PermitVerify.disabled = false;
1400+
} catch (err) {
1401+
console.error(err);
1402+
sign721PermitResult.innerHTML = `Error: ${err.message}`;
1403+
}
1404+
};
1405+
1406+
/**
1407+
* Sign Permit Verification
1408+
*/
1409+
sign721PermitVerify.onclick = async () => {
1410+
const from = accounts[0];
1411+
const msgParams = await getNFTMsgParams();
1412+
1413+
try {
1414+
const sign = sign721PermitResult.innerHTML;
1415+
const recoveredAddr = recoverTypedSignature({
1416+
data: msgParams,
1417+
signature: sign,
1418+
version: 'V4',
1419+
});
1420+
if (toChecksumAddress(recoveredAddr) === toChecksumAddress(from)) {
1421+
console.log(`Successfully verified signer as ${recoveredAddr}`);
1422+
sign721PermitVerifyResult.innerHTML = recoveredAddr;
1423+
} else {
1424+
console.log(
1425+
`Failed to verify signer when comparing ${recoveredAddr} to ${from}`,
1426+
);
1427+
}
1428+
} catch (err) {
1429+
console.error(err);
1430+
sign721PermitVerifyResult.innerHTML = `Error: ${err.message}`;
1431+
}
1432+
};
1433+
13611434
watchNFTButton.onclick = async () => {
13621435
let watchNftsResult;
13631436
try {
@@ -2661,6 +2734,32 @@ const initializeFormElements = () => {
26612734
};
26622735
}
26632736

2737+
async function getNFTMsgParams() {
2738+
return {
2739+
domain: {
2740+
name: 'My NFT',
2741+
version: '1',
2742+
chainId: chainIdInt,
2743+
verifyingContract: nftsContract.address,
2744+
},
2745+
types: {
2746+
Permit: [
2747+
{ name: 'spender', type: 'address' },
2748+
{ name: 'tokenId', type: 'uint256' },
2749+
{ name: 'nonce', type: 'uint256' },
2750+
{ name: 'deadline', type: 'uint256' },
2751+
],
2752+
},
2753+
primaryType: 'Permit',
2754+
message: {
2755+
spender: '0x0521797E19b8E274E4ED3bFe5254FAf6fac96F08',
2756+
tokenId: '3606393',
2757+
nonce: '0',
2758+
deadline: '1734995006',
2759+
},
2760+
};
2761+
}
2762+
26642763
function splitSig(sig) {
26652764
const pureSig = sig.replace('0x', '');
26662765

0 commit comments

Comments
 (0)