updates to ux

enumerate
lza_menace 2 years ago
parent 86e8f7d6d3
commit ca43da584c

@ -7,23 +7,25 @@
</script>
<main>
<div class="container">
<div class="row">
<div class="column">
<img src={ethereumLogo} class="logo ethereum" alt="Ethereum Logo" />
<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 class="card">
<Providers />
</div>
<Contracts />
</main>
<style>

@ -1,107 +1,181 @@
<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 IERC1155 from '@openzeppelin/contracts/build/contracts/IERC1155.json';
import SendIt from './lib/sendit.json';
const chain = 1337;
const nft = '0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9';
let errorMessage = '';
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 to = '0x7c83E906aDD18C093B4B01ED40b6BCb25d348ED9';
// const to = '0x7c83E906aDD18C093B4B01ED40b6BCb25d348ED9';
let amt = 10;
let gasLimit = 0;
let si_gasLimit = 0;
evm.attachContract('nft', nft, IERC721.abi);
evm.attachContract('sendit', sendit, SendIt.abi);
// evm.attachContract('nft', contractAddress, IERC721.abi);
// evm.attachContract('sendit', sendit, SendIt.abi);
const performCheck = async () => {
let tokenIds = [];
errorMessage = '';
const estimateCBT = async () => {
si_gasLimit = 0;
let tokenIndexes = [];
let recipients = [];
for (let i = 0; i < amt; i++) {
tokenIndexes[i] = i + 1;
recipients[i] = to;
// Check the contract is valid
try {
$web3.utils.toChecksumAddress(contractAddress)
} catch {
errorMessage = 'Invalid contract address supplied';
return;
}
let i = await $contracts.nft.methods.isApprovedForAll($selectedAccount, sendit).call({from: $selectedAccount});
if (!i) {
await $contracts.nft.methods.setApprovalForAll(sendit, true).send({from: $selectedAccount});
// Check approval on the contract
if (selectedStandard == 1) {
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 () => {
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;
});
// Check textarea syntax
let info = document.getElementById('recipientInfo').value;
let lines = info.split(/(\s+)/);
console.log(lines);
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() {
estimateCBT();
estimateSTF();
}
// const estimateCBT = async () => {
// si_gasLimit = 0;
// 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>
<div class="container">
{#if $selectedAccount}
<form>
<div class="row">
<div class="column mt-2">
{#if $selectedAccount }
{#if $chainId !== chain }
<p>
Your are connected to the wrong network.
</p>
{:else if $contracts.nft}
{#await $contracts.nft.methods.balanceOf($selectedAccount).call() }
<span>checking balance...</span>
{:then balance}
<p>
Gas Required to send {amt} NFTs via OpenZeppelin ERC721 safeTransferFrom: {gasLimit}
<br />
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 class="six columns">
<label for="contractAddress">Contract Address</label>
<input class="u-full-width" type="text" placeholder="0x..." id="contractAddress" bind:value={contractAddress}>
</div>
<div class="six columns">
<label for="tokenStandard">Token Standard</label>
<select class="u-full-width" id="tokenStandard" bind:value={selectedStandard} on:change="{() => checked = false}">
{#each tokenStandards as s}
<option value={s.id}>
{s.text}
</option>
{/each}
</select>
</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>
<div class="container">
<div class="row">
<div class="column mt-2">
{#if !$selectedAccount}
<button class="button" disabled={pending} on:click={connect}>{#if pending}connecting...{:else}Connect{/if}</button>
{:else}
<p>
Connected {$selectedAccount}
</p>
<button class="button" on:click={disconnect}>Disconnect</button>
{/if}
</div>
</div>
</div>
{#if !$selectedAccount}
<button class="button" disabled={pending} on:click={connect}>{#if pending}connecting...{:else}Connect{/if}</button>
{:else}
<p>
Connected {$selectedAccount}
<br /><br />
<button class="button" on:click={disconnect}>Disconnect</button>
</p>
{/if}
Loading…
Cancel
Save