updates to ux

enumerate
lza_menace 2 years ago
parent 86e8f7d6d3
commit ca43da584c

@ -7,23 +7,25 @@
</script> </script>
<main> <main>
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="column"> <div class="column">
<img src={ethereumLogo} class="logo ethereum" alt="Ethereum Logo" /> <img src={ethereumLogo} class="logo ethereum" alt="Ethereum Logo" />
<h1>SendIt!</h1> <h1>SendIt!</h1>
<p>A bulk NFT transfer utility made for transferring ERC-721 and ERC-1155 tokens between accounts easily.</p> <p>
A bulk NFT transfer utility made for transferring ERC-721 and ERC-1155 tokens between accounts easily.
<br />
Made by <a href="https://lzahq.tech" target="_blank">lza_menace</a> and the <a href="https://art101.io" target="_blank">Art101</a> team.
</p>
<Providers />
</div>
</div>
<div class="row">
<div class="column">
<Contracts />
</div> </div>
</div> </div>
</div> </div>
<div class="card">
<Providers />
</div>
<Contracts />
</main> </main>
<style> <style>

@ -1,107 +1,181 @@
<script> <script>
import { defaultEvmStores as evm, selectedAccount, chainId, contracts } from 'svelte-web3'; import { defaultEvmStores as evm, selectedAccount, contracts, web3 } from 'svelte-web3';
import IERC721 from '@openzeppelin/contracts/build/contracts/IERC721.json'; import IERC721 from '@openzeppelin/contracts/build/contracts/IERC721.json';
import IERC1155 from '@openzeppelin/contracts/build/contracts/IERC1155.json';
import SendIt from './lib/sendit.json'; import SendIt from './lib/sendit.json';
const chain = 1337; let errorMessage = '';
const nft = '0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9'; let successMessage = '';
let contractAddress = '';
let contractApproved = false;
let checked = false;
let selectedStandard = 1;
let tokenStandards = [
{ id: 1, text: 'ERC-721' },
{ id: 2, text: 'ERC-1155' }
]
// 0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9
const sendit = '0x0165878A594ca255338adfa4d48449f69242Eb8F'; const sendit = '0x0165878A594ca255338adfa4d48449f69242Eb8F';
const to = '0x7c83E906aDD18C093B4B01ED40b6BCb25d348ED9'; // const to = '0x7c83E906aDD18C093B4B01ED40b6BCb25d348ED9';
let amt = 10; let amt = 10;
let gasLimit = 0; let gasLimit = 0;
let si_gasLimit = 0; let si_gasLimit = 0;
evm.attachContract('nft', nft, IERC721.abi); // evm.attachContract('nft', contractAddress, IERC721.abi);
evm.attachContract('sendit', sendit, SendIt.abi); // evm.attachContract('sendit', sendit, SendIt.abi);
const performCheck = async () => {
let tokenIds = [];
errorMessage = '';
const estimateCBT = async () => { // Check the contract is valid
si_gasLimit = 0; try {
let tokenIndexes = []; $web3.utils.toChecksumAddress(contractAddress)
let recipients = []; } catch {
for (let i = 0; i < amt; i++) { errorMessage = 'Invalid contract address supplied';
tokenIndexes[i] = i + 1; return;
recipients[i] = to;
} }
let i = await $contracts.nft.methods.isApprovedForAll($selectedAccount, sendit).call({from: $selectedAccount}); // Check approval on the contract
if (!i) { if (selectedStandard == 1) {
await $contracts.nft.methods.setApprovalForAll(sendit, true).send({from: $selectedAccount}); evm.attachContract('nft', contractAddress, IERC721.abi);
} else {
evm.attachContract('nft', contractAddress, IERC1155.abi);
}
try {
let r = await $contracts.nft.methods.isApprovedForAll($selectedAccount, sendit);
console.log(r);
} catch {
errorMessage = 'Unable to check contract approvals';
return;
} }
await $contracts.sendit.methods.contractBulkTransfer(nft, tokenIndexes, recipients, false).estimateGas({from: $selectedAccount}, function(err, gas){
si_gasLimit += gas;
});
}
const estimateSTF = async () => { // Check textarea syntax
gasLimit = 0; let info = document.getElementById('recipientInfo').value;
for (let i = 0; i < amt; i++) { let lines = info.split(/(\s+)/);
await $contracts.nft.methods.safeTransferFrom($selectedAccount, to, i + 1).estimateGas({from: $selectedAccount}, function(err, gas){ console.log(lines);
gasLimit += gas; if (lines.length < 2) { errorMessage = 'Invalid recipient info.'; return; }
}); for (let i = 0; i < lines.length; i++) {
let line = lines[i].split(',');
if (line.length == 2) {
let recipient = line[0];
let tokenId = line[1];
try {
$web3.utils.toChecksumAddress(recipient)
} catch {
errorMessage = `Invalid recipient address supplied (line ${i + 1})`;
return;
}
// Check ownership of tokens
if (selectedStandard == 1) {
try {
let owner = await $contracts.nft.methods.ownerOf(tokenId).call();
if (owner.toLowerCase() != $selectedAccount.toLowerCase()) { throw new Error(`You must own the token in order to send it (token ${tokenId})`); }
if (tokenIds.includes(tokenId)) { throw new Error(`Duplicate token ID found (token ${tokenId})`); }
tokenIds.push(tokenId);
} catch(e) {
errorMessage = e;
return;
}
} else {
try {
let balance = await $contracts.nft.methods.balanceOf($selectedAccount, tokenId).call();
if (Number(balance) < 1) { throw new Error(`You must own the token in order to send it (token ${tokenId}, balance ${balance})`); }
if (tokenIds.length < Number(balance)) { throw new Error(`Provided more tokens than balance(token ${tokenId}, balance ${balance})`); }
tokenIds.push(tokenId);
} catch(e) {
errorMessage = e;
return;
}
}
}
} }
// Check gas consumption forecasts
// Show results
} }
function estimateGas() { // const estimateCBT = async () => {
estimateCBT(); // si_gasLimit = 0;
estimateSTF(); // let tokenIndexes = [];
} // let recipients = [];
// for (let i = 0; i < amt; i++) {
// tokenIndexes[i] = i + 1;
// recipients[i] = to;
// }
// let i = await $contracts.nft.methods.isApprovedForAll($selectedAccount, sendit).call({from: $selectedAccount});
// if (!i) {
// await $contracts.nft.methods.setApprovalForAll(sendit, true).send({from: $selectedAccount});
// }
// await $contracts.sendit.methods.contractBulkTransfer(nft, tokenIndexes, recipients, false).estimateGas({from: $selectedAccount}, function(err, gas){
// si_gasLimit += gas;
// });
// }
// const estimateSTF = async () => {
// gasLimit = 0;
// for (let i = 0; i < amt; i++) {
// await $contracts.nft.methods.safeTransferFrom($selectedAccount, to, i + 1).estimateGas({from: $selectedAccount}, function(err, gas){
// gasLimit += gas;
// });
// }
// }
// function estimateGas() {
// estimateCBT();
// estimateSTF();
// }
</script> </script>
<div class="container"> {#if $selectedAccount}
<form>
<div class="row"> <div class="row">
<div class="column mt-2"> <div class="six columns">
{#if $selectedAccount } <label for="contractAddress">Contract Address</label>
{#if $chainId !== chain } <input class="u-full-width" type="text" placeholder="0x..." id="contractAddress" bind:value={contractAddress}>
<p> </div>
Your are connected to the wrong network. <div class="six columns">
</p> <label for="tokenStandard">Token Standard</label>
{:else if $contracts.nft} <select class="u-full-width" id="tokenStandard" bind:value={selectedStandard} on:change="{() => checked = false}">
{#await $contracts.nft.methods.balanceOf($selectedAccount).call() } {#each tokenStandards as s}
<span>checking balance...</span> <option value={s.id}>
{:then balance} {s.text}
<p> </option>
Gas Required to send {amt} NFTs via OpenZeppelin ERC721 safeTransferFrom: {gasLimit} {/each}
<br /> </select>
Gas Required to send {amt} NFTs via SendIt ERC721 contractBulkTransfer: {si_gasLimit}
<br />
{$selectedAccount} has {balance} NFTs on local net (anvil).
</p>
<input bind:value={amt}>
<button class="button" on:click={estimateGas}>Test</button>
{/await}
{/if}
{:else}
<p>
Please first connect your wallet to be able to use this page.
</p>
{/if}
<form>
<div class="row">
<div class="six columns">
<label for="exampleEmailInput">Your email</label>
<input class="u-full-width" type="email" placeholder="test@mailbox.com" id="exampleEmailInput">
</div>
<div class="six columns">
<label for="exampleRecipientInput">Reason for contacting</label>
<select class="u-full-width" id="exampleRecipientInput">
<option value="Option 1">Questions</option>
<option value="Option 2">Admiration</option>
<option value="Option 3">Can I get your number?</option>
</select>
</div>
</div>
<label for="exampleMessage">Message</label>
<textarea class="u-full-width" placeholder="Hi Dave …" id="exampleMessage"></textarea>
<label class="example-send-yourself-copy">
<input type="checkbox">
<span class="label-body">Send a copy to yourself</span>
</label>
<input class="button-primary" type="submit" value="Submit">
</form>
</div> </div>
</div> </div>
</div> <label for="recipientInfo">Recipient Address, Token ID</label>
<textarea class="u-full-width" placeholder="0x653D2d1D10c79017b2eA5F5a6F02D9Ab6e725395,90
0x653D2d1D10c79017b2eA5F5a6F02D9Ab6e725395,1775" id="recipientInfo"></textarea>
<br />
{#if checked}
<input class="button-primary" type="submit" value="Transfer">
{:else}
<input class="button" type="submit" value="Check" on:click|preventDefault={performCheck}>
{/if}
</form>
{/if}
{#if errorMessage}
<p id="errorMessage">{errorMessage}</p>
{/if}
{#if errorMessage}
<p id="successMessage">{successMessage}</p>
{/if}
<style>
#errorMessage {
color: red;
}
#successMessage {
color: green;
}
</style>

@ -20,17 +20,13 @@
} }
</script> </script>
<div class="container"> {#if !$selectedAccount}
<div class="row"> <button class="button" disabled={pending} on:click={connect}>{#if pending}connecting...{:else}Connect{/if}</button>
<div class="column mt-2"> {:else}
{#if !$selectedAccount} <p>
<button class="button" disabled={pending} on:click={connect}>{#if pending}connecting...{:else}Connect{/if}</button> Connected {$selectedAccount}
{:else} <br /><br />
<p> <button class="button" on:click={disconnect}>Disconnect</button>
Connected {$selectedAccount} </p>
</p>
<button class="button" on:click={disconnect}>Disconnect</button> {/if}
{/if}
</div>
</div>
</div>
Loading…
Cancel
Save