Added smart contracts section to homepage

This commit is contained in:
sairaj mote 2023-10-05 02:24:07 +05:30
parent edaebbb8f1
commit 8bc58793ae
4 changed files with 387 additions and 349 deletions

View File

@ -709,132 +709,6 @@ ul {
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
} }
.transaction-container {
display: grid;
margin-top: 1.5rem;
gap: 0.5rem;
}
.label {
text-transform: capitalize;
font-size: 0.8rem;
margin-bottom: 0.3rem;
color: rgba(var(--text-color), 0.8);
margin-top: 1.5rem;
font-weight: 500;
}
.label:first-of-type {
margin-top: 0;
}
.label + :is(h1, h2, h3, h4, h5, h6, p, span, sm-copy, a) {
font-weight: 700;
}
.header {
justify-items: center;
flex-direction: column;
}
#homepage {
padding-top: 0;
}
#first_section {
display: grid;
}
header.grid-2 {
margin-top: 2rem;
}
@-webkit-keyframes flyInLeft {
from {
opacity: 0;
transform: translateX(-0.5rem);
}
to {
opacity: 1;
transform: none;
}
}
@keyframes flyInLeft {
from {
opacity: 0;
transform: translateX(-0.5rem);
}
to {
opacity: 1;
transform: none;
}
}
@-webkit-keyframes flyInRight {
from {
opacity: 0;
transform: translateX(0.5rem);
}
to {
opacity: 1;
transform: none;
}
}
@keyframes flyInRight {
from {
opacity: 0;
transform: translateX(0.5rem);
}
to {
opacity: 1;
transform: none;
}
}
#highlights {
padding: 1.5rem 0;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
gap: 1.5rem;
}
#highlights .highlight-item {
opacity: 0;
display: flex;
flex-direction: column;
padding: 1rem 1.5rem;
border-left: 0.1rem solid rgba(var(--text-color), 0.2);
--animation-duration: 0.3s;
}
#highlights .highlight-item .label {
margin-top: auto;
}
#highlights .highlight-item h1 {
font-size: 2rem;
letter-spacing: 0.1rem;
font-weight: 500;
text-transform: uppercase;
overflow-wrap: break-word;
}
#highlights .highlight-item:first-of-type {
text-transform: uppercase;
}
#highlights .highlight-item:nth-of-type(2) {
text-transform: capitalize;
}
#highlights .highlight-item:first-of-type {
-webkit-animation: flyInLeft var(--animation-duration) forwards;
animation: flyInLeft var(--animation-duration) forwards;
}
#highlights .highlight-item:nth-of-type(2) {
-webkit-animation: flyInLeft var(--animation-duration) 0.1s forwards;
animation: flyInLeft var(--animation-duration) 0.1s forwards;
}
#highlights .highlight-item:nth-of-type(3) {
-webkit-animation: flyInLeft var(--animation-duration) 0.2s forwards;
animation: flyInLeft var(--animation-duration) 0.2s forwards;
}
#highlights .highlight-item:last-of-type {
-webkit-animation: flyInLeft var(--animation-duration) 0.3s forwards;
animation: flyInLeft var(--animation-duration) 0.3s forwards;
}
#main_header { #main_header {
display: grid; display: grid;
grid-template-columns: 1fr auto; grid-template-columns: 1fr auto;
@ -924,6 +798,140 @@ theme-toggle {
margin-left: auto; margin-left: auto;
} }
.transaction-container {
display: grid;
margin-top: 1.5rem;
gap: 0.5rem;
}
.label {
text-transform: capitalize;
font-size: 0.8rem;
margin-bottom: 0.3rem;
color: rgba(var(--text-color), 0.8);
margin-top: 1.5rem;
font-weight: 500;
}
.label:first-of-type {
margin-top: 0;
}
.label + :is(h1, h2, h3, h4, h5, h6, p, span, sm-copy, a) {
font-weight: 700;
}
.header {
justify-items: center;
flex-direction: column;
}
#homepage {
display: grid;
gap: 3rem 1rem;
padding-top: 0;
}
#first_section {
display: grid;
}
header.grid-2 {
margin-top: 2rem;
}
@-webkit-keyframes flyInLeft {
from {
opacity: 0;
transform: translateX(-0.5rem);
}
to {
opacity: 1;
transform: none;
}
}
@keyframes flyInLeft {
from {
opacity: 0;
transform: translateX(-0.5rem);
}
to {
opacity: 1;
transform: none;
}
}
@-webkit-keyframes flyInRight {
from {
opacity: 0;
transform: translateX(0.5rem);
}
to {
opacity: 1;
transform: none;
}
}
@keyframes flyInRight {
from {
opacity: 0;
transform: translateX(0.5rem);
}
to {
opacity: 1;
transform: none;
}
}
#highlights {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
gap: 1.5rem;
margin-top: 2rem;
}
#highlights .highlight-item {
opacity: 0;
display: flex;
flex-direction: column;
padding: 1rem 1.5rem;
border-left: 0.1rem solid rgba(var(--text-color), 0.2);
--animation-duration: 0.3s;
}
#highlights .highlight-item .label {
margin-top: auto;
}
#highlights .highlight-item h1 {
font-size: 2rem;
letter-spacing: 0.1rem;
font-weight: 500;
text-transform: uppercase;
overflow-wrap: break-word;
}
#highlights .highlight-item:first-of-type {
text-transform: uppercase;
}
#highlights .highlight-item:nth-of-type(2) {
text-transform: capitalize;
}
#highlights .highlight-item:first-of-type {
-webkit-animation: flyInLeft var(--animation-duration) forwards;
animation: flyInLeft var(--animation-duration) forwards;
}
#highlights .highlight-item:nth-of-type(2) {
-webkit-animation: flyInLeft var(--animation-duration) 0.1s forwards;
animation: flyInLeft var(--animation-duration) 0.1s forwards;
}
#highlights .highlight-item:nth-of-type(3) {
-webkit-animation: flyInLeft var(--animation-duration) 0.2s forwards;
animation: flyInLeft var(--animation-duration) 0.2s forwards;
}
#highlights .highlight-item:last-of-type {
-webkit-animation: flyInLeft var(--animation-duration) 0.3s forwards;
animation: flyInLeft var(--animation-duration) 0.3s forwards;
}
#top_smart_contracts_container {
display: grid;
gap: 1rem;
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
}
#page_header { #page_header {
padding: 1rem 0; padding: 1rem 0;
align-items: center; align-items: center;
@ -1136,7 +1144,6 @@ theme-toggle {
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
gap: 1rem; gap: 1rem;
margin-top: 1rem;
} }
.block-card { .block-card {
@ -1215,7 +1222,7 @@ theme-toggle {
display: grid; display: grid;
gap: 1rem; gap: 1rem;
margin-top: 1rem; margin-top: 1rem;
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr)); grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
} }
.sc-card { .sc-card {
@ -1299,32 +1306,33 @@ theme-toggle {
display: none; display: none;
} }
fieldset {
padding: 0.5rem;
border-radius: 0.5rem;
border: solid 1px rgba(var(--text-color), 0.3);
}
fieldset legend {
padding: 0 0.5rem;
}
fieldset label {
padding: 0.3rem 0.5rem;
}
fieldset label:has(input:not(:disabled):not(:checked)) {
cursor: pointer;
}
fieldset input[type=radio] {
height: 1.1em;
width: 1.1em;
margin-right: 0.5rem;
accent-color: var(--accent-color);
}
#smart_contract_creation_popup { #smart_contract_creation_popup {
--width: min(32rem, 100%); --width: min(32rem, 100%);
} }
#smart_contract_creation_popup::part(popup) { #smart_contract_creation_popup::part(popup) {
view-transition-name: sc-popup; view-transition-name: sc-popup;
} }
#smart_contract_creation_popup fieldset {
padding: 0.5rem;
border-radius: 0.5rem;
border: solid 1px rgba(var(--text-color), 0.3);
}
#smart_contract_creation_popup fieldset legend {
padding: 0 0.5rem;
}
#smart_contract_creation_popup label {
padding: 0.3rem 0.5rem;
}
#smart_contract_creation_popup label:has(input:not(:disabled):not(:checked)) {
cursor: pointer;
}
#smart_contract_creation_popup input[type=radio] {
height: 1.1em;
width: 1.1em;
margin-right: 0.5rem;
accent-color: var(--accent-color);
}
::view-transition-group(sc-popup) { ::view-transition-group(sc-popup) {
-webkit-animation-duration: 0.3s; -webkit-animation-duration: 0.3s;
@ -1563,7 +1571,10 @@ theme-toggle {
@media only screen and (min-width: 1280px) { @media only screen and (min-width: 1280px) {
.margin, .margin,
.page { .page {
margin: 0 10vw; margin: 0 8vw;
}
#homepage {
grid-template-columns: 1fr 22rem;
} }
} }
@media (hover: hover) { @media (hover: hover) {

2
css/main.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -662,100 +662,6 @@ ul {
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
} }
} }
.transaction-container {
display: grid;
margin-top: 1.5rem;
gap: 0.5rem;
}
.label {
text-transform: capitalize;
font-size: 0.8rem;
margin-bottom: 0.3rem;
color: rgba(var(--text-color), 0.8);
margin-top: 1.5rem;
font-weight: 500;
&:first-of-type {
margin-top: 0;
}
& + :is(h1, h2, h3, h4, h5, h6, p, span, sm-copy, a) {
font-weight: 700;
}
}
.header {
justify-items: center;
flex-direction: column;
}
#homepage {
padding-top: 0;
}
#first_section {
display: grid;
}
header.grid-2 {
margin-top: 2rem;
}
@keyframes flyInLeft {
from {
opacity: 0;
transform: translateX(-0.5rem);
}
to {
opacity: 1;
transform: none;
}
}
@keyframes flyInRight {
from {
opacity: 0;
transform: translateX(0.5rem);
}
to {
opacity: 1;
transform: none;
}
}
#highlights {
padding: 1.5rem 0;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
gap: 1.5rem;
.highlight-item {
opacity: 0;
display: flex;
flex-direction: column;
padding: 1rem 1.5rem;
border-left: 0.1rem solid rgba(var(--text-color), 0.2);
.label {
margin-top: auto;
}
h1 {
font-size: 2rem;
letter-spacing: 0.1rem;
font-weight: 500;
text-transform: uppercase;
overflow-wrap: break-word;
}
&:first-of-type {
text-transform: uppercase;
}
&:nth-of-type(2) {
text-transform: capitalize;
}
--animation-duration: 0.3s;
&:first-of-type {
animation: flyInLeft var(--animation-duration) forwards;
}
&:nth-of-type(2) {
animation: flyInLeft var(--animation-duration) 0.1s forwards;
}
&:nth-of-type(3) {
animation: flyInLeft var(--animation-duration) 0.2s forwards;
}
&:last-of-type {
animation: flyInLeft var(--animation-duration) 0.3s forwards;
}
}
}
#main_header { #main_header {
display: grid; display: grid;
grid-template-columns: 1fr auto; grid-template-columns: 1fr auto;
@ -840,6 +746,107 @@ theme-toggle {
margin-left: auto; margin-left: auto;
} }
} }
.transaction-container {
display: grid;
margin-top: 1.5rem;
gap: 0.5rem;
}
.label {
text-transform: capitalize;
font-size: 0.8rem;
margin-bottom: 0.3rem;
color: rgba(var(--text-color), 0.8);
margin-top: 1.5rem;
font-weight: 500;
&:first-of-type {
margin-top: 0;
}
& + :is(h1, h2, h3, h4, h5, h6, p, span, sm-copy, a) {
font-weight: 700;
}
}
.header {
justify-items: center;
flex-direction: column;
}
#homepage {
display: grid;
gap: 3rem 1rem;
padding-top: 0;
}
#first_section {
display: grid;
}
header.grid-2 {
margin-top: 2rem;
}
@keyframes flyInLeft {
from {
opacity: 0;
transform: translateX(-0.5rem);
}
to {
opacity: 1;
transform: none;
}
}
@keyframes flyInRight {
from {
opacity: 0;
transform: translateX(0.5rem);
}
to {
opacity: 1;
transform: none;
}
}
#highlights {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
gap: 1.5rem;
margin-top: 2rem;
.highlight-item {
opacity: 0;
display: flex;
flex-direction: column;
padding: 1rem 1.5rem;
border-left: 0.1rem solid rgba(var(--text-color), 0.2);
.label {
margin-top: auto;
}
h1 {
font-size: 2rem;
letter-spacing: 0.1rem;
font-weight: 500;
text-transform: uppercase;
overflow-wrap: break-word;
}
&:first-of-type {
text-transform: uppercase;
}
&:nth-of-type(2) {
text-transform: capitalize;
}
--animation-duration: 0.3s;
&:first-of-type {
animation: flyInLeft var(--animation-duration) forwards;
}
&:nth-of-type(2) {
animation: flyInLeft var(--animation-duration) 0.1s forwards;
}
&:nth-of-type(3) {
animation: flyInLeft var(--animation-duration) 0.2s forwards;
}
&:last-of-type {
animation: flyInLeft var(--animation-duration) 0.3s forwards;
}
}
}
#top_smart_contracts_container {
display: grid;
gap: 1rem;
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
}
#page_header { #page_header {
padding: 1rem 0; padding: 1rem 0;
align-items: center; align-items: center;
@ -1039,7 +1046,6 @@ theme-toggle {
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
gap: 1rem; gap: 1rem;
margin-top: 1rem;
} }
.block-card { .block-card {
grid-template-columns: 5rem 1fr auto; grid-template-columns: 5rem 1fr auto;
@ -1111,7 +1117,7 @@ theme-toggle {
display: grid; display: grid;
gap: 1rem; gap: 1rem;
margin-top: 1rem; margin-top: 1rem;
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr)); grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
} }
.sc-card { .sc-card {
display: flex; display: flex;
@ -1198,18 +1204,12 @@ theme-toggle {
} }
} }
#smart_contract_creation_popup { fieldset {
--width: min(32rem, 100%); padding: 0.5rem;
&::part(popup) { border-radius: 0.5rem;
view-transition-name: sc-popup; border: solid 1px rgba(var(--text-color), 0.3);
} legend {
fieldset { padding: 0 0.5rem;
padding: 0.5rem;
border-radius: 0.5rem;
border: solid 1px rgba(var(--text-color), 0.3);
legend {
padding: 0 0.5rem;
}
} }
label { label {
padding: 0.3rem 0.5rem; padding: 0.3rem 0.5rem;
@ -1224,6 +1224,12 @@ theme-toggle {
accent-color: var(--accent-color); accent-color: var(--accent-color);
} }
} }
#smart_contract_creation_popup {
--width: min(32rem, 100%);
&::part(popup) {
view-transition-name: sc-popup;
}
}
::view-transition-group(sc-popup) { ::view-transition-group(sc-popup) {
animation-duration: 0.3s; animation-duration: 0.3s;
} }
@ -1439,7 +1445,10 @@ theme-toggle {
@media only screen and (min-width: 1280px) { @media only screen and (min-width: 1280px) {
.margin, .margin,
.page { .page {
margin: 0 10vw; margin: 0 8vw;
}
#homepage {
grid-template-columns: 1fr 22rem;
} }
} }
@media (hover: hover) { @media (hover: hover) {

View File

@ -1255,14 +1255,14 @@
const { topToken, totalTransactions, walletAddresses } = data; const { topToken, totalTransactions, walletAddresses } = data;
renderElem(getRef("page_container"), html` renderElem(getRef("page_container"), html`
<div id="homepage" class="page"> <div id="homepage" class="page">
<section id="first_section"> <section id="first_section" class="full-bleed">
<div id="highlights"> <div id="highlights">
<div class="highlight-item"> <div class="highlight-item">
<h4 class="label">top token</h4> <h4 class="label">top token</h4>
<h2 class="token"><a href=${`#/token/${topToken}`} class="">${topToken}</a> </h2> <h2 class="token"><a href=${`#/token/${topToken}`} class="">${topToken}</a> </h2>
</div> </div>
<div class="highlight-item"> <div class="highlight-item">
<h4 class="label">Total transactions</h4> <h4 class="label">Total token transactions</h4>
<h2>${totalTransactions}</h2> <h2>${totalTransactions}</h2>
</div> </div>
<div class="highlight-item"> <div class="highlight-item">
@ -1275,18 +1275,27 @@
</div> </div>
</div> </div>
</section> </section>
<section id="latest_transaction_section" class="margin-bottom-2"> <section id="latest_smart_contracts_section" class="full-bleed flex flex-direction-column gap-1">
<header class="flex align-center space-between">
<h3>Recent smart contracts</h3>
<a href=${`#/smart-contracts`} class="button button--small button--colored">View all</a>
</header>
<div id="top_smart_contracts_container">
${renderSmartContracts()[0].slice(0, 3)}
</div>
</section>
<section id="latest_transaction_section" class="flex flex-direction-column gap-1">
<header class="flex align-center space-between"> <header class="flex align-center space-between">
<h3>Recent token transactions</h3> <h3>Recent token transactions</h3>
<a id='all_trans_btn' href=${`#/transactions`} class="button button--small button--colored">View all</a> <a id='all_trans_btn' href=${`#/transactions`} class="button button--small button--colored">View all</a>
</header> </header>
<ul id="top_transaction_container" class="transaction-container"> <ul id="top_transaction_container" class="grid gap-0-5">
${renderTransactions(latestTxs)} ${renderTransactions(latestTxs)}
</ul> </ul>
</section> </section>
<section id="latest_blocks_section"> <section id="latest_blocks_section" class="flex flex-direction-column gap-1">
<header class="flex align-center space-between"> <header class="flex align-center space-between">
<h3>Recent token transaction blocks</h3> <h3>Recent token blocks</h3>
<a id='all_blocks_btn' href=${`#/blocks`} class="button button--small button--colored">View all</a> <a id='all_blocks_btn' href=${`#/blocks`} class="button button--small button--colored">View all</a>
</header> </header>
<div id="top_blocks_container"> <div id="top_blocks_container">
@ -1349,36 +1358,30 @@
actions = html` actions = html`
<div class="flex align-center gap-0-5 sc-card__actions"> <div class="flex align-center gap-0-5 sc-card__actions">
<button class="button button--small button--outlined" onclick=${() => handleSmartContractAction(smartContractAddress, 'deposit')}> <button class="button button--small button--outlined" onclick=${() => handleSmartContractAction(smartContractAddress, 'deposit')}>
Sell ${acceptingToken} Sell ${sellingToken}
</button> </button>
<button class="button button--small button--outlined" onclick=${() => handleSmartContractAction(smartContractAddress, 'participate')}> <button class="button button--small button--outlined" onclick=${() => handleSmartContractAction(smartContractAddress, 'participate')}>
Sell ${sellingToken} Sell ${acceptingToken}
</button> </button>
</div> </div>
` `
break; break;
case 'time-trigger': case 'time-trigger':
case 'external-trigger':
actions = html` actions = html`
<div class="flex align-center gap-0-5 sc-card__actions"> <div class="flex align-center gap-0-5 sc-card__actions">
<button class="button button--small button--outlined" onclick=${() => handleSmartContractAction(smartContractAddress, 'participate')}> <button class="button button--small button--outlined" onclick=${() => handleSmartContractAction(smartContractAddress, 'participate')}>
Participate Participate
</button> </button >
</div> </div >
` `
break;
case 'external-trigger':
actions = html`
<div class="flex align-center gap-0-5 sc-card__actions">
<button class="button button--small button--outlined" onclick=${() => openPopup('external_trigger_popup', contract)}>
Participate
</button>
</div>
`
break; break;
}; };
return actions; return actions;
} }
router.addRoute('smart-contracts', async state => { function renderSmartContracts(smartContracts) {
if (!smartContracts)
smartContracts = Object.values(floGlobals.smartContractList).sort((a, b) => b.blockNumber - a.blockNumber)
let activeContracts = [] let activeContracts = []
let inactiveContracts = [] let inactiveContracts = []
filterSmartContracts().forEach(contract => { filterSmartContracts().forEach(contract => {
@ -1387,19 +1390,15 @@
const smartContractAddress = `${contractName}-${contractAddress}`; const smartContractAddress = `${contractName}-${contractAddress}`;
let type = ''; let type = '';
let actions = getSmartContractActions(smartContractAddress); let actions = getSmartContractActions(smartContractAddress);
switch (contractSubType) { if (contractSubType === 'tokenswap') {
case 'tokenswap': type = 'Token Swap';
type = 'Token Swap' } else if (contractSubType === 'time-trigger') {
break; type = 'Timed Event';
case 'time-trigger': } else if (contractSubType === 'external-trigger') {
type = 'Timed Event' type = 'External Trigger';
break; }
case 'external-trigger':
type = 'External Trigger'
break;
};
const rendered = html` const rendered = html`
<li class=${`sc-card ${status}`} .dataset=${{ address: `${contractName}-${contractAddress}` }}> <li class=${`sc-card ${status}`} .dataset=${{ address: smartContractAddress }}>
${status !== 'active' ? html` <div class="badge">${status}</div> ` : ''} ${status !== 'active' ? html` <div class="badge">${status}</div> ` : ''}
<div class="flex align-center space-between"> <div class="flex align-center space-between">
<p class="sc-card__type">${type}</p> <p class="sc-card__type">${type}</p>
@ -1434,6 +1433,10 @@
else else
inactiveContracts.push(rendered) inactiveContracts.push(rendered)
}) })
return [activeContracts, inactiveContracts]
}
router.addRoute('smart-contracts', async state => {
const [activeContracts, inactiveContracts] = renderSmartContracts(filterSmartContracts())
const { tokens, types } = floGlobals.appliedFilters const { tokens, types } = floGlobals.appliedFilters
const totalFilters = tokens.size + types.size const totalFilters = tokens.size + types.size
renderElem(getRef("page_container"), html` renderElem(getRef("page_container"), html`
@ -2652,6 +2655,7 @@
target.focusIn() target.focusIn()
} }
function handleSmartContractAction(smartContractAddress, action) { function handleSmartContractAction(smartContractAddress, action) {
renderElem(getRef('smart_contract_popup__content'), html`<sm-spinner></sm-spinner>`)
switch (action) { switch (action) {
// TODO: check minimum amount // TODO: check minimum amount
case 'deposit': { case 'deposit': {
@ -2693,45 +2697,47 @@
getRef('smart_contract_popup__title').textContent = `Swap ${acceptingToken} with ${sellingToken}` getRef('smart_contract_popup__title').textContent = `Swap ${acceptingToken} with ${sellingToken}`
} }
renderElem(getRef('smart_contract_popup__content'), html` renderElem(getRef('smart_contract_popup__content'), html`
${userChoices ? html` <h4 class="wrap-around">${contractName.replace(/-/g, ' ')}-${contractAddress}</h4>
<fieldset> ${userChoices ? html`
<legend>Choices</legend> <fieldset>
<div class="grid gap-0-5"> <legend>Choices</legend>
${userChoices.map(choice => html` <div class="grid gap-0-5">
<label class="flex align-center"> ${userChoices.map(choice => html`
<input type="radio" name="choice" value="${choice}" required> <label class="flex align-center">
<span class="capitalize">${choice}</span> <input type="radio" name="choice" value="${choice}" required>
</label> <span class="capitalize">${choice}</span>
`)} </label>
</div> `)}
`: ''} </div>
${contractSubType === 'tokenswap' ? html` `: ''}
<strong>Exchange rate: 1 ${sellingToken} = ${price} ${acceptingToken}</strong> ${contractSubType === 'tokenswap' ? html`
`: ''} <strong>Exchange rate: 1 ${sellingToken} = ${price} ${acceptingToken}</strong>
<div class="grid gap-0-5"> `: ''}
<span id="participation_amount_label" class="label">Participation amount (${acceptingToken || tokenIdentification})</span> <div class="grid gap-0-5">
<sm-input id="participation_amount" type="number" step="0.00000001" min="0.00000001" error-text="The amount should be above 0.00000001" required></sm-input> <span id="participation_amount_label" class="label">Participation amount (${acceptingToken || tokenIdentification})</span>
</div> <sm-input id="participation_amount" type="number" step="0.00000001" min="0.00000001" error-text="The amount should be above 0.00000001" required></sm-input>
<div class="grid gap-0-5"> </div>
<span class="label">FLO private key</span> <div class="grid gap-0-5">
<sm-input id="participant_private_key" class="password-field" type="password" data-private-key required> <span class="label">FLO private key</span>
<label slot="right" class="interact"> <sm-input id="participant_private_key" class="password-field" type="password" data-private-key required>
<input type="checkbox" class="hidden" readonly onchange="togglePrivateKeyVisibility(this)"> <label slot="right" class="interact">
<svg class="icon invisible" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"> <title>Hide password</title> <path d="M0 0h24v24H0zm0 0h24v24H0zm0 0h24v24H0zm0 0h24v24H0z" fill="none"></path> <path d="M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z"></path> </svg> <input type="checkbox" class="hidden" readonly onchange="togglePrivateKeyVisibility(this)">
<svg class="icon visible" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"> <title>Show password</title> <path d="M0 0h24v24H0z" fill="none"></path> <path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"></path> </svg> <svg class="icon invisible" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"> <title>Hide password</title> <path d="M0 0h24v24H0zm0 0h24v24H0zm0 0h24v24H0zm0 0h24v24H0z" fill="none"></path> <path d="M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z"></path> </svg>
</label> <svg class="icon visible" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"> <title>Show password</title> <path d="M0 0h24v24H0z" fill="none"></path> <path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"></path> </svg>
</sm-input> </label>
</div> </sm-input>
<div class="multi-state-button"> </div>
<button id="participate_button" class="button button--primary" onclick=${() => participate(smartContractAddress)} type="submit" disabled>Sell</button> <div class="multi-state-button">
</div> <button id="participate_button" class="button button--primary" onclick=${() => participate(smartContractAddress)} type="submit" disabled>Sell</button>
`) </div>
`)
break; break;
} }
case 'updateprice': { case 'updateprice': {
const { contractName, contractAddress, oracle_address, price, acceptingToken } = floGlobals.smartContractList[smartContractAddress] const { contractName, contractAddress, oracle_address, price, acceptingToken } = floGlobals.smartContractList[smartContractAddress]
getRef('smart_contract_popup__title').textContent = `Update price` getRef('smart_contract_popup__title').textContent = `Update price`
renderElem(getRef('smart_contract_update_form'), html` renderElem(getRef('smart_contract_popup__content'), html`
<sm-form>
<div class="grid gap-0-5"> <div class="grid gap-0-5">
<span class="label">Oracle FLO Address</span> <span class="label">Oracle FLO Address</span>
<sm-copy id="oracle_address" value=${oracle_address}></sm-copy> <sm-copy id="oracle_address" value=${oracle_address}></sm-copy>
@ -2755,15 +2761,17 @@
<sm-input id="updated_price" type="number" step="0.00000001" min="0.00000001" error-text="Minimum 0.00000001 required" required></sm-input> <sm-input id="updated_price" type="number" step="0.00000001" min="0.00000001" error-text="Minimum 0.00000001 required" required></sm-input>
</div> </div>
<div class="multi-state-button"> <div class="multi-state-button">
<button id="update_price_button" class="button button--primary" type="submit" onclick=${updatePrice} disabled>Update</button> <button id="update_price_button" class="button button--primary" type="submit" onclick=${() => updatePrice(smartContractAddress)} disabled>Update</button>
</div> </div>
`) </sm-form>
`)
break; break;
} }
case 'trigger': { case 'trigger': {
const { contractName, contractAddress, price, tokenIdentification, userChoices } = floGlobals.smartContractList[smartContractAddress] const { contractName, contractAddress, price, tokenIdentification, userChoices } = floGlobals.smartContractList[smartContractAddress]
getRef('smart_contract_popup__title').textContent = `Trigger` getRef('smart_contract_popup__title').textContent = `Trigger`
renderElem(getRef('smart_contract_trigger_form'), html` renderElem(getRef('smart_contract_popup__content'), html`
<sm-form>
<fieldset> <fieldset>
<legend>Select outcome</legend> <legend>Select outcome</legend>
<div class="grid gap-0-5"> <div class="grid gap-0-5">
@ -2786,9 +2794,10 @@
</sm-input> </sm-input>
</div> </div>
<div class="multi-state-button"> <div class="multi-state-button">
<button id="trigger_contract_button" class="button button--primary" onclick=${triggerContract} type="submit" disabled>Trigger</button> <button id="trigger_contract_button" class="button button--primary" onclick=${() => triggerContract(smartContractAddress)} type="submit" disabled>Trigger</button>
</div> </div>
`) </sm-form>
`)
break; break;
} }
} }
@ -2810,16 +2819,16 @@
buttonLoader('deposit_button', false) buttonLoader('deposit_button', false)
return notify(`Insufficient balance.\n You have ${balance} ${sellingToken}`, 'error') return notify(`Insufficient balance.\n You have ${balance} ${sellingToken}`, 'error')
} }
getConfirmation('Deposit', { getConfirmation('Deposit for swap', {
message: `Are you sure you want to deposit ${depositAmount} ${sellingToken} in ${contractName}?`, message: `Are you sure you want to send ${depositAmount} ${sellingToken} to ${contractName} (${contractAddress})?`,
confirmText: 'Deposit', confirmText: 'Deposit',
}).then(res => { }).then(res => {
if (!res) return if (!res) return
floBlockchainAPI.sendTx(depositorAddress, contractAddress, floGlobals.sendAmt, depositorPrivateKey, floData).then(txid => { floBlockchainAPI.sendTx(depositorAddress, contractAddress, floGlobals.sendAmt, depositorPrivateKey, floData).then(txid => {
closePopup() closePopup()
showTransactionResult(true, txid, { showTransactionResult(true, txid, {
title: `${sellingToken} tokens deposited`, title: `${sellingToken} tokens sent`,
description: `If your tokens are not exchanged before the expiry time, you will get them back.` description: `If your tokens are not swapped before the expiry time, you will get them back.`
}) })
}).catch(error => { }).catch(error => {
closePopup() closePopup()
@ -2847,14 +2856,24 @@
switch (contractSubType) { switch (contractSubType) {
case 'time-trigger': case 'time-trigger':
floData = `send ${participationAmount} ${tokenIdentification}# to ${contractName}@` floData = `send ${participationAmount} ${tokenIdentification}# to ${contractName}@`
description = html`You have participated in the event. Check out details <a href=${`https://ranchimall.github.io/floscout/#/contract/${contractName}-${contractAddress}`} target='_blank'>here</a>` description = html`
<div class="grid gap-0-5">
<p>You have participated in ${contractName} with ${participationAmount} ${tokenIdentification}</p>
<a href=${`#/contract/${contractName}-${contractAddress}`} class="button button--small button--primary">Check your participation</a>
</div>
`
break break
case 'external-trigger': case 'external-trigger':
const userChoice = getRef('smart_contract_participate_form').querySelector('input[name="choice"]:checked').value const userChoice = getRef('smart_contract_participate_form').querySelector('input[name="choice"]:checked').value
if (!userChoice) if (!userChoice)
return notify('Please select a choice', 'error') return notify('Please select a choice', 'error')
floData = `send ${participationAmount} ${tokenIdentification}# to ${contractName}@ to FLO address ${contractAddress} with the userchoice: ${userChoice}` floData = `send ${participationAmount} ${tokenIdentification}# to ${contractName}@ to FLO address ${contractAddress} with the userchoice: ${userChoice}`
description = html`You have casted your vote. Check out details <a href=${`https://ranchimall.github.io/floscout/#/contract/${contractName}-${contractAddress}`} target='_blank'>here</a>` description = html`
<div class="grid gap-0-5">
<p>You have casted your vote for ${userChoice} in ${contractName} with ${participationAmount} ${tokenIdentification}</p>
<a href=${`#/contract/${contractName}-${contractAddress}`} class="button button--small button--primary">Check your vote</a>
</div>
`
break break
} }
} }
@ -2864,10 +2883,12 @@
case 'tokenswap': case 'tokenswap':
floData = `send ${participationAmount} ${acceptingToken}# to ${contractName}@` floData = `send ${participationAmount} ${acceptingToken}# to ${contractName}@`
title = 'Token swap initiated' title = 'Token swap initiated'
description = html`Check your transactions and token balance <a href=${`https://ranchimall.github.io/flowallet/#/transactions/${participantAddress}`} target='_blank'>here</a>` description = html`
break; <div class="grid gap-0-5">
<p>You have initiated a token swap in ${contractName} with ${participationAmount} ${acceptingToken}</p>
default: <a href=${`#/contract/${contractName}-${contractAddress}`} class="button button--small button--primary">Check swap status</a>
</div>
`
break; break;
} }
} }
@ -2904,12 +2925,10 @@
}) })
} }
function updatePrice(e) { function updatePrice(smartContractAddress) {
const selectedSmartContract = getRef('selected_smart_contract').value const { contractName, contractAddress, acceptingToken } = floGlobals.smartContractList[smartContractAddress]
const [contractName, contractAddress] = (selectedSmartContract).split('_')
const oraclePrivateKey = getRef('oracle_private_key').value.trim() const oraclePrivateKey = getRef('oracle_private_key').value.trim()
const oracleAddress = getRef('oracle_address').value const oracleAddress = getRef('oracle_address').value
const { acceptingToken } = getScDetails(contractName, contractAddress)
if (!floCrypto.verifyPrivKey(oraclePrivateKey, oracleAddress)) { if (!floCrypto.verifyPrivKey(oraclePrivateKey, oracleAddress)) {
return notify(`Private key doesn't match with Oracle address`, 'error') return notify(`Private key doesn't match with Oracle address`, 'error')
} }
@ -2936,12 +2955,11 @@
}) })
} }
function triggerContract(e) { function triggerContract(smartContractAddress) {
const selectedSmartContract = getRef('selected_smart_contract').value const { contractName, contractAddress } = floGlobals.smartContractList[smartContractAddress]
const [contractName, contractAddress] = (selectedSmartContract).split('_')
const triggerPrivateKey = getRef('trigger_private_key').value.trim() const triggerPrivateKey = getRef('trigger_private_key').value.trim()
const triggerAddress = floCrypto.getFloID(triggerPrivateKey) const triggerAddress = floCrypto.getFloID(triggerPrivateKey)
const triggerOutcome = getRef('smart_contract_trigger_form').querySelector('input[name="outcome"]:checked').value const triggerOutcome = getRef('smart_contract_popup__content').querySelector('input[name="outcome"]:checked').value
const floData = `${contractName}@ triggerCondition:"${triggerOutcome}"` const floData = `${contractName}@ triggerCondition:"${triggerOutcome}"`
console.log(floData) console.log(floData)
// if (contractAddress !== triggerAddress) { // if (contractAddress !== triggerAddress) {