Skip to content

Commit a57ff96

Browse files
authored
Merge pull request #13 from Apillon/dev
Dev -> Master
2 parents 06ccdeb + fc43fa9 commit a57ff96

File tree

7 files changed

+691
-557
lines changed

7 files changed

+691
-557
lines changed

.prettierrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"arrowParens": "avoid",
3+
"singleQuote": true,
4+
"trailingComma": "es5",
5+
"semi": true,
6+
"printWidth": 180
7+
}

index.html

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@
1010
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;700&display=swap" rel="stylesheet" />
1111
<link href="./style/style.css" rel="stylesheet" />
1212
<link href="./style/tooltip.css" rel="stylesheet" />
13-
<script src="./js/abi.js" type="application/javascript"></script>
14-
<script src="./js/env.js" type="application/javascript"></script>
15-
<script src="./js/utils.js" type="application/javascript"></script>
16-
<script src="./js/render.js" type="application/javascript"></script>
17-
<script src="./js/script.js" type="application/javascript"></script>
13+
<script src="./js/abi.js" type="application/javascript" async></script>
14+
<script src="./js/env.js" type="application/javascript" async></script>
15+
<script src="./js/utils.js" type="application/javascript" async></script>
16+
<script src="./js/render.js" type="application/javascript" async></script>
17+
<script src="./js/script.js" type="application/javascript" async></script>
18+
<script src="./js/nestable.js" type="application/javascript" async></script>
1819
<script></script>
1920
</head>
2021
<body>
@@ -30,14 +31,29 @@ <h1>A matter of minutes. And zero developing costs. Want to build your own NFT c
3031
</div>
3132
<div class="box collection br text-center">
3233
<div id="collection"></div>
33-
<div class="drop" id="drop"></div>
3434
<div class="btn-connect-wrapper">
3535
<button id="btnConnect" onclick="connectWallet();">Connect wallet</button>
3636
<span id="connectError" class="error"></span>
3737
</div>
3838
<span id="generalError" class="error"></span>
3939
</div>
4040
<div id="actions" style="display: none">
41+
<div
42+
class="nestable-info"
43+
>
44+
<h3>
45+
The collection you are viewing supports nesting NFTs you own. To setup the nested
46+
relationship between NFTs, you first have to own them.
47+
</h3>
48+
<strong>Instructions:</strong>
49+
<ol>
50+
<li>Mint one or multiple NFTs</li>
51+
<li>Once minted, click on “My NFTs”</li>
52+
<li>The NFTs you own will be displayed</li>
53+
<li>Click on the NFT you want to set as a parent</li>
54+
<li>A window will open, allowing you to link child NFTs to that NFT</li>
55+
</ol>
56+
</div>
4157
<h2 class="text-center">Show NFTs:</h2>
4258
<div class="actions">
4359
<button id="btnAllNFTs" onclick="loadAllNFTs();">All nfts</button>

js/nestable.js

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
// Nestable NFTs on UI
2+
3+
async function mintWrapper() {
4+
btnLoader($(`#mint`), true);
5+
await childMint(contractAddress, 1);
6+
btnLoader($(`#mint`), false);
7+
}
8+
async function childMintWrapper() {
9+
btnLoader($(`#childMint`), true);
10+
11+
const address = $(`#address`).val();
12+
if (checkInputAddress(address)) {
13+
await childMint(address, 1);
14+
}
15+
16+
btnLoader($(`#childMint`), false);
17+
}
18+
19+
async function childNestMintWrapper(destinationId, fieldId = '') {
20+
btnLoader($(`#childNestMint${fieldId}`), true);
21+
const address = $(`#addressNestMint${fieldId}`).val();
22+
23+
if (checkInputAddress(address, fieldId)) {
24+
const status = await childNestMint(address, 1, destinationId);
25+
transactionStatus(status, fieldId);
26+
}
27+
28+
btnLoader($(`#childNestMint${fieldId}`), false);
29+
}
30+
31+
async function acceptChildWrapper(parentId, childAddress, childId, fieldId) {
32+
if (!childAddress) {
33+
return;
34+
}
35+
btnLoader($(`#acceptChild${fieldId}`), true);
36+
37+
const status = await acceptChild(parentId, 0, childAddress, childId);
38+
transactionStatus(status, fieldId);
39+
40+
btnLoader($(`#acceptChild${fieldId}`), false);
41+
}
42+
43+
async function rejectAllChildrenWrapper(parentId, pendingChildrenNum = 1, fieldId = '') {
44+
btnLoader($(`#rejectAllChildren${fieldId}`), true);
45+
46+
const status = await rejectAllChildren(parentId, pendingChildrenNum);
47+
transactionStatus(status, fieldId);
48+
49+
btnLoader($(`#rejectAllChildren${fieldId}`), false);
50+
}
51+
52+
async function nestTransferFromWrapper(destinationId, fieldId = '', contractAddress = '') {
53+
btnLoader($(`#nestTransferFrom${fieldId}`), true);
54+
55+
const address = $(`#addressTransferFrom${fieldId}`).val() || contractAddress;
56+
const tokenId = $(`#tokenTransferFrom${fieldId}`).val() || $(`input[type="radio"][name="nest${fieldId}"]:checked`).val();
57+
58+
if (checkInputAddress(address, fieldId) && checkInputToken(tokenId, fieldId)) {
59+
const status = await nestTransferFrom(address, nftContract.address, tokenId, destinationId, '0x');
60+
transactionStatus(status, fieldId);
61+
}
62+
63+
btnLoader($(`#nestTransferFrom${fieldId}`), false);
64+
}
65+
66+
async function transferChildWrapper(parentId, contractAddress, childId, fieldId = '') {
67+
btnLoader($(`#transfer${fieldId}`), true);
68+
69+
const status = await transferChild(parentId, walletAddress, 0, 0, contractAddress, childId, false, '0x');
70+
transactionStatus(status, fieldId);
71+
72+
btnLoader($(`#transfer${fieldId}`), false);
73+
}
74+
75+
// NESTABLE NFTs ACTIONS
76+
77+
async function isTokenNestable(contract) {
78+
try {
79+
return await contract.supportsInterface('0x42b0e56f');
80+
} catch (e) {
81+
console.warn(e);
82+
return false;
83+
}
84+
}
85+
86+
async function childMint(tokenAddress, quantity) {
87+
const childNftContract = getNftContract(tokenAddress);
88+
const isNestable = await isTokenNestable(childNftContract);
89+
if (!isNestable) {
90+
console.error('Child token is not nestable');
91+
return;
92+
}
93+
const price = await nftContract.pricePerMint();
94+
const value = price.mul(ethers.BigNumber.from(quantity));
95+
try {
96+
const gasLimit = await nftContract.connect(provider.getSigner()).estimateGas.mint(walletAddress, quantity, { value });
97+
98+
const tx = await childNftContract.connect(provider.getSigner()).mint(walletAddress, quantity, {
99+
value,
100+
gasLimit: gasLimit.mul(11).div(10),
101+
});
102+
await tx.wait();
103+
104+
await refreshState();
105+
} catch (e) {
106+
console.debug(e);
107+
}
108+
}
109+
110+
async function childNestMint(tokenAddress, quantity, destinationId) {
111+
const childNftContract = getNftContract(tokenAddress);
112+
const isNestable = await isTokenNestable(childNftContract);
113+
if (!isNestable) {
114+
console.error('Child token is not nestable');
115+
return 'Child token is not nestable';
116+
}
117+
const price = await childNftContract.pricePerMint();
118+
const value = price.mul(ethers.BigNumber.from(quantity));
119+
try {
120+
const tx = await childNftContract.connect(provider.getSigner()).nestMint(nftContract.address, quantity, destinationId, { value });
121+
await tx.wait();
122+
123+
await refreshState();
124+
125+
return '';
126+
} catch (e) {
127+
console.debug(e);
128+
const defaultMsg = 'Token could not be minted! Check contract address.';
129+
return transactionError(defaultMsg, e);
130+
}
131+
}
132+
133+
async function childrenOf(parentId, tokenAddress = null) {
134+
try {
135+
const contract = !tokenAddress ? nftContract : getNftContract(tokenAddress);
136+
return await contract.connect(provider.getSigner()).childrenOf(parentId);
137+
} catch (e) {
138+
console.debug(e);
139+
return 0;
140+
}
141+
}
142+
143+
async function pendingChildrenOf(parentId, tokenAddress = null) {
144+
try {
145+
const contract = !tokenAddress ? nftContract : getNftContract(tokenAddress);
146+
return await contract.connect(provider.getSigner()).pendingChildrenOf(parentId);
147+
} catch (e) {
148+
console.debug(e);
149+
return 0;
150+
}
151+
}
152+
153+
async function acceptChild(parentId, childIndex, childAddress, childId) {
154+
try {
155+
const tx = await nftContract.connect(provider.getSigner()).acceptChild(parentId, childIndex, childAddress, childId);
156+
await tx.wait();
157+
158+
await refreshState();
159+
160+
return '';
161+
} catch (e) {
162+
console.debug(e);
163+
return transactionError('Token could not be accepted!', e);
164+
}
165+
}
166+
167+
async function rejectAllChildren(parentId, maxRejections) {
168+
try {
169+
const tx = await nftContract.connect(provider.getSigner()).rejectAllChildren(parentId, maxRejections);
170+
await tx.wait();
171+
172+
await refreshState();
173+
174+
return '';
175+
} catch (e) {
176+
console.debug(e);
177+
return transactionError('Token could not be rejected!', e);
178+
}
179+
}
180+
181+
async function nestTransferFrom(tokenAddress, toAddress, tokenId, destinationId, data) {
182+
const childNftContract = getNftContract(tokenAddress);
183+
const isNestable = await isTokenNestable(childNftContract);
184+
if (!isNestable) {
185+
console.error('Child token is not nestable');
186+
return 'Child token is not nestable';
187+
}
188+
189+
try {
190+
const tx = await childNftContract.connect(provider.getSigner()).nestTransferFrom(walletAddress, toAddress, tokenId, destinationId, data);
191+
await tx.wait();
192+
193+
await refreshState();
194+
return '';
195+
} catch (e) {
196+
console.debug(e);
197+
const defaultMsg = 'Token could not be transferred! Wrong token address or token ID.';
198+
return transactionError(defaultMsg, e);
199+
}
200+
}
201+
202+
async function transferChild(tokenId, toAddress, destinationId, childIndex, childAddress, childId, isPending, data) {
203+
try {
204+
const tx = await nftContract.connect(provider.getSigner()).transferChild(tokenId, toAddress, destinationId, childIndex, childAddress, childId, isPending, data);
205+
await tx.wait();
206+
207+
await refreshState();
208+
await refreshState();
209+
210+
return '';
211+
} catch (e) {
212+
console.debug(e);
213+
const defaultMsg = 'Token could not be transferred!';
214+
return transactionError(defaultMsg, e);
215+
}
216+
}

0 commit comments

Comments
 (0)