Added crowd fund progress tracking

This commit is contained in:
sairaj mote 2023-10-05 06:45:12 +05:30
parent 8bc58793ae
commit d43ae1dfe0
4 changed files with 363 additions and 102 deletions

View File

@ -17,7 +17,7 @@ body {
body {
--accent-color: #3d5afe;
--secondary-color: #ffac2e;
--text-color: 34, 34, 34;
--text-color: 54, 54, 54;
--foreground-color: 252, 253, 255;
--background-color: 241, 243, 248;
--danger-color: rgb(255, 75, 75);
@ -705,6 +705,9 @@ ul {
background: rgba(var(--text-color), 0.06);
margin: 1.5rem 0;
}
.card + .card {
margin-top: 0;
}
.card h2 {
margin-bottom: 1.5rem;
}
@ -881,18 +884,30 @@ header.grid-2 {
}
#highlights {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
gap: 1.5rem;
margin-top: 2rem;
}
#highlights .highlight-item {
position: relative;
opacity: 0;
display: flex;
flex-direction: column;
padding: 1rem 1.5rem;
border-left: 0.1rem solid rgba(var(--text-color), 0.2);
border-left: 1px solid var(--accent-color);
--animation-duration: 0.3s;
}
#highlights .highlight-item::before {
content: "";
position: absolute;
width: 0.2rem;
height: 1rem;
top: 0;
left: 0;
border-radius: 0 0.1rem 0.1rem 0;
display: inline-block;
background-color: var(--accent-color);
}
#highlights .highlight-item .label {
margin-top: auto;
}
@ -1021,6 +1036,9 @@ header.grid-2 {
.status.active::before {
background-color: var(--green);
}
.status.expired::before {
background-color: var(--yellow);
}
.status.closed::before {
background-color: var(--danger-color);
}
@ -1037,6 +1055,7 @@ header.grid-2 {
.address {
text-transform: none !important;
word-break: break-all;
font-weight: 700;
}
#winners_container {
@ -1142,7 +1161,7 @@ header.grid-2 {
#all_blocks_page,
#top_blocks_container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
gap: 1rem;
}
@ -1218,11 +1237,79 @@ header.grid-2 {
min-width: 12rem;
}
#goal_progress_wrapper {
position: relative;
display: flex;
height: 0.1rem;
background-color: rgba(var(--text-color), 0.3);
border-radius: 1rem;
}
.progress-bar {
position: relative;
background-color: var(--accent-color);
width: var(--progress);
border-radius: 1rem;
}
.progress-bar::before {
content: "";
position: absolute;
border-style: solid;
border-width: 0.3rem 0.3rem 0 0.3rem;
border-color: var(--accent-color) transparent transparent transparent;
width: 0;
height: 0;
left: calc(100% - 0.3rem);
bottom: 100%;
box-shadow: 0 0.3rem 0.3rem rgba(0, 0, 0, 0.1);
z-index: 1;
}
#progress_pin {
position: absolute;
bottom: calc(100% + 0.3rem);
padding: 0.4rem 0.6rem;
font-size: 0.85rem;
background-color: var(--accent-color);
font-weight: 500;
color: rgba(var(--foreground-color), 1);
border-radius: 0.3rem;
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.2);
z-index: 1;
}
.goal-milestone {
position: relative;
display: flex;
align-items: center;
padding-top: 1rem;
font-size: 0.9rem;
max-width: 6rem;
text-align: center;
}
.goal-milestone:last-of-type {
margin-left: auto;
text-align: end;
align-items: flex-end;
margin-top: -12rem;
}
.goal-milestone:last-of-type::before {
top: calc(100% + 1.07rem);
}
.goal-milestone::before {
content: "";
position: absolute;
width: 0.2rem;
height: 0.8rem;
top: -0.45rem;
background-color: var(--accent-color);
}
.smart-contract-list {
display: grid;
gap: 1rem;
margin-top: 1rem;
grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
}
.sc-card {

2
css/main.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -17,7 +17,7 @@ body {
body {
--accent-color: #3d5afe;
--secondary-color: #ffac2e;
--text-color: 34, 34, 34;
--text-color: 54, 54, 54;
--foreground-color: 252, 253, 255;
--background-color: 241, 243, 248;
--danger-color: rgb(255, 75, 75);
@ -658,6 +658,9 @@ ul {
border-radius: 0.5rem;
background: rgba(var(--text-color), 0.06);
margin: 1.5rem 0;
& + & {
margin-top: 0;
}
h2 {
margin-bottom: 1.5rem;
}
@ -802,15 +805,27 @@ header.grid-2 {
}
#highlights {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
gap: 1.5rem;
margin-top: 2rem;
.highlight-item {
position: relative;
opacity: 0;
display: flex;
flex-direction: column;
padding: 1rem 1.5rem;
border-left: 0.1rem solid rgba(var(--text-color), 0.2);
border-left: 1px solid var(--accent-color);
&::before {
content: "";
position: absolute;
width: 0.2rem;
height: 1rem;
top: 0;
left: 0;
border-radius: 0 0.1rem 0.1rem 0;
display: inline-block;
background-color: var(--accent-color);
}
.label {
margin-top: auto;
}
@ -932,6 +947,11 @@ header.grid-2 {
background-color: var(--green);
}
}
&.expired {
&::before {
background-color: var(--yellow);
}
}
&.closed {
&::before {
background-color: var(--danger-color);
@ -949,6 +969,7 @@ header.grid-2 {
.address {
text-transform: none !important;
word-break: break-all;
font-weight: 700;
}
#winners_container {
display: grid;
@ -1044,7 +1065,7 @@ header.grid-2 {
#all_blocks_page,
#top_blocks_container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
gap: 1rem;
}
.block-card {
@ -1110,6 +1131,70 @@ header.grid-2 {
min-width: 12rem;
}
}
#goal_progress_wrapper {
position: relative;
display: flex;
height: 0.1rem;
background-color: rgba(var(--text-color), 0.3);
border-radius: 1rem;
}
.progress-bar {
position: relative;
background-color: var(--accent-color);
width: var(--progress);
border-radius: 1rem;
&::before {
content: "";
position: absolute;
border-style: solid;
border-width: 0.3rem 0.3rem 0 0.3rem;
border-color: var(--accent-color) transparent transparent transparent;
width: 0;
height: 0;
left: calc(100% - 0.3rem);
bottom: 100%;
box-shadow: 0 0.3rem 0.3rem rgba(0, 0, 0, 0.1);
z-index: 1;
}
}
#progress_pin {
position: absolute;
bottom: calc(100% + 0.3rem);
padding: 0.4rem 0.6rem;
font-size: 0.85rem;
background-color: var(--accent-color);
font-weight: 500;
color: rgba(var(--foreground-color), 1);
border-radius: 0.3rem;
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.2);
z-index: 1;
}
.goal-milestone {
position: relative;
display: flex;
align-items: center;
padding-top: 1rem;
font-size: 0.9rem;
max-width: 6rem;
text-align: center;
&:last-of-type {
margin-left: auto;
text-align: end;
align-items: flex-end;
margin-top: -12rem;
&::before {
top: calc(100% + 1.07rem);
}
}
&::before {
content: "";
position: absolute;
width: 0.2rem;
height: 0.8rem;
top: -0.45rem;
background-color: var(--accent-color);
}
}
#smart_contract_page {
}
@ -1117,7 +1202,7 @@ header.grid-2 {
display: grid;
gap: 1rem;
margin-top: 1rem;
grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
}
.sc-card {
display: flex;
@ -1154,11 +1239,6 @@ header.grid-2 {
.sc-card__actions {
justify-content: flex-end;
padding-top: 1rem;
// .button {
// background-color: transparent;
// border: solid 1px var(--accent-color);
// padding: 0.5rem 1rem;
// }
}
.badge {
margin-right: auto;

View File

@ -139,7 +139,7 @@
</sm-popup>
<!-- Set urls for token and flo Apis -->
<script>
const testMode = false
const testMode = true
const floGlobals = {
blockchain: testMode ? "FLO_TEST" : "FLO",
tokenApiUrl: testMode ? 'https://ranchimallflo-testnet-blockbook.ranchimall.net' : 'https://ranchimallflo.ranchimall.net',
@ -213,6 +213,13 @@
let zIndex = 10
// function required for popups or modals to appear
function openPopup(popupId, pinned) {
if (popupStack.peek() === undefined) {
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
closePopup()
}
})
}
zIndex++
getRef(popupId).setAttribute('style', `z-index: ${zIndex}`)
getRef(popupId).show({ pinned })
@ -268,6 +275,12 @@
renderElem(getRef('filter_s_c_popup__content'), html``)
break;
}
if (popupStack.peek() === undefined)
document.removeEventListener('keydown', (e) => {
if (e.key === 'Escape') {
closePopup()
}
})
})
// displays a popup for asking permission. Use this instead of JS confirm
const getConfirmation = (title, options = {}) => {
@ -1349,34 +1362,52 @@
router.routeTo(location.hash)
closePopup()
}
function getSmartContractActions(smartContractAddress) {
function getSmartContractActions(smartContractAddress, priceType = 'predetermined', showAdminOptions = false) {
const { acceptingToken, sellingToken, contractSubType, status } = floGlobals.smartContractList[smartContractAddress]
if (status !== 'active') return '';
if (!showAdminOptions && status !== 'active') return ''
let actions = '';
switch (contractSubType) {
case 'tokenswap':
actions = html`
<div class="flex align-center gap-0-5 sc-card__actions">
if (contractSubType === 'tokenswap') {
actions = html`
<div class="flex align-center gap-0-5 sc-card__actions">
${status === 'active' ? html`
<button class="button button--small button--outlined" onclick=${() => handleSmartContractAction(smartContractAddress, 'deposit')}>
Sell ${sellingToken}
Swap ${sellingToken}
</button>
<button class="button button--small button--outlined" onclick=${() => handleSmartContractAction(smartContractAddress, 'participate')}>
Sell ${acceptingToken}
Swap ${acceptingToken}
</button>
</div>
`
break;
case 'time-trigger':
case 'external-trigger':
actions = html`
<div class="flex align-center gap-0-5 sc-card__actions">
`: ''}
${showAdminOptions && priceType === 'dynamic' ? html`
<button class="button button--small button--outlined" onclick=${() => handleSmartContractAction(smartContractAddress, 'updateprice')}>
Update price
</button>
`: ''}
</div>
`
} else if (contractSubType === 'time-trigger' && status === 'active') {
actions = html`
<div class="flex align-center gap-0-5 sc-card__actions">
<button class="button button--small button--outlined" onclick=${() => handleSmartContractAction(smartContractAddress, 'participate')}>
Participate
</button>
</div>
`
} else if (contractSubType === 'external-trigger') {
actions = html`
<div class="flex align-center gap-0-5 sc-card__actions">
${status === 'active' ? html`
<button class="button button--small button--outlined" onclick=${() => handleSmartContractAction(smartContractAddress, 'participate')}>
Participate
</button >
</div >
`
break;
};
</button>
`: ''}
${showAdminOptions && status === 'expired' ? html`
<button class="button button--small button--outlined" onclick=${() => handleSmartContractAction(smartContractAddress, 'trigger')}>
Trigger
</button>
`: ''}
</div>
`
}
return actions;
}
function renderSmartContracts(smartContracts) {
@ -1577,10 +1608,10 @@
const [contractId] = state.wildcards
if (!contractId) return;
const contractIdObj = splitContractNameAddress(contractId)
const {
let {
status, contract, contractType, contractSubtype, contractAddress, expiration, token,
participationFees, userChoices, payeeAddress, minAmount, maxAmount, acceptingToken,
sellingToken, numberOfDeposits, numberOfParticipants, totalHonorAmount, totalParticipationAmount,
sellingToken, numberOfDeposits, numberOfParticipants, totalHonorAmount, totalParticipationAmount = 0,
priceType, oracle_address, price, currentDepositBalance
} = await getContractInfo(contractIdObj)
const detailsToFetch = [getContractTransactions(contractIdObj), getContractParticipants(contractIdObj)]
@ -1613,11 +1644,48 @@
if (consolidatedParticipants[participant].winningAmount)
winners.push(render.contractChoiceCard(consolidatedParticipants[participant]))
}
const contractActions = getSmartContractActions(contractId)
const contractActions = getSmartContractActions(contractId, priceType, true)
const progress = Math.min((() => {
if (!minAmount && !maxAmount) return 0
if (minAmount && !maxAmount) return totalParticipationAmount / minAmount * 100
if (maxAmount) return totalParticipationAmount / maxAmount * 100
})(), 100)
let minGoal = 0
if (minAmount && maxAmount) {
minGoal = minAmount / maxAmount * 100
}
renderElem(getRef("page_container"), html`
<div id="contract_page" class="page">
${status ? html` <div class=${`status ${status}`}>${status}</div> ` : ''}
<h2 class="uppercase">${replaceDash(contract)}</h2>
${minAmount || maxAmount ? html`
<div class="card grid gap-2">
<div class='grid gap-0-5'>
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M12.36 6l.4 2H18v6h-3.36l-.4-2H7V6h5.36M14 4H5v17h2v-7h5.6l.4 2h7V6h-5.6L14 4z"/></svg>
<h3>Collection Goal</h3>
</div>
<div class='grid'>
<div id="goal_progress_wrapper">
<div id="goal_progress" class="progress-bar" style=${`width: ${progress}%`}></div>
<div id="progress_pin">${progress}%</div>
</div>
<div class="flex align-center gap-0-5">
${minAmount ? html`
<div class="flex flex-direction-column goal-milestone" style=${maxAmount ? `left: calc(${minGoal}% - 3rem)` : ''}>
<h5 class="label">Minimum</h5>
<h4>${formatAmount(minAmount)} ${token}</h4>
</div>
`: ''}
${maxAmount ? html`
<div class="flex flex-direction-column goal-milestone">
<h5 class="label">Maximum</h5>
<h4>${formatAmount(maxAmount)} ${token}</h4>
</div>
`: ''}
</div>
</div>
</div>
`: ''}
<div id="contract_info" class="card">
<div class="flex info-row">
<h5 class="label">Contract Type</h5>
@ -1653,21 +1721,9 @@
</div>
</div>
`: ''}
${minAmount ? html`
<div class="flex info-row">
<h5 class="label">Min. Subscription Amount</h5>
<h4>${formatAmount(minAmount)} ${token}</h4>
</div>
`: ''}
${maxAmount ? html`
<div class="flex info-row">
<h5 class="label">Max. Subscription Amount</h5>
<h4>${formatAmount(maxAmount)} ${token}</h4>
</div>
`: ''}
${participationFees ? html`
<div class="flex info-row">
<h5 class="label">Participation Fees</h5>
<h5 class="label">Participation Amount</h5>
<h4>${formatAmount(participationFees)} ${token}</h4>
</div>
`: ''}
@ -1766,6 +1822,10 @@
</div>
`);
getRef("page_title").textContent = "Contract";
// position progress pin on goal progress bar in percentage
if (getRef('progress_pin')) {
getRef('progress_pin').style.left = `calc(${progress}% - ${getRef('progress_pin').getBoundingClientRect().width / 2}px)`
}
} catch (e) {
console.trace(e)
renderElem(getRef("page_container"), html`${render.errorPage(e)}`);
@ -1778,23 +1838,34 @@
try {
const [blockInfo, blockTxs] = await Promise.all([getBlockInfo(blockId), getBlockTransactions(blockId)])
const { blockHeight, size, reward, hash, difficulty, nonce } = blockInfo;
console.log(blockInfo, blockTxs)
renderElem(getRef("page_container"), html`
<div id="block_page" class="page">
<h5 class="label">Block Height</h5>
<h2 class="block-height">${blockHeight}</h2>
<div class="card">
<h5 class="label">Relevant Transactions</h5>
<h4>${blockTxs.length}</h4>
<h5 class="label">Confirmations</h5>
<h4>${size}</h4>
<h5 class="label">Reward</h5>
<h4>${reward}</h4>
<h5 class="label">Block Hash</h5>
<sm-copy value=${hash} clip-text></sm-copy>
<h5 class="label">Difficulty</h5>
<h4>${difficulty}</h4>
<h5 class="label">Nonce</h5>
<h4>${nonce}</h4>
<div class="card grid gap-1-5">
<div class="flex flex-wrap gap-1-5">
<div class="grid">
<h5 class="label">Confirmations</h5>
<h4>${size}</h4>
</div>
<div class="grid">
<h5 class="label">Reward</h5>
<h4>${reward}</h4>
</div>
<div class="grid">
<h5 class="label">Difficulty</h5>
<h4>${difficulty}</h4>
</div>
<div class="grid">
<h5 class="label">Nonce</h5>
<h4>${nonce}</h4>
</div>
</div>
<div class="grid">
<h5 class="label">Block Hash</h5>
<sm-copy value=${hash} clip-text></sm-copy>
</div>
</div>
<h3 class="heading">Transactions</h3>
<ul id="block_transaction_container" class="grid gap-1 top-bottom-padding">
@ -2124,7 +2195,7 @@
}, contractAddress,
contractName
} = info
return {
const details = {
contract: contractName,
contractAddress,
contractType,
@ -2148,6 +2219,11 @@
price,
currentDepositBalance
}
floGlobals.smartContractList[`${contractName}-${contractAddress}`] = {
...details,
...floGlobals.smartContractList[`${contractName}-${contractAddress}`]
}
return details
}
async function getContractParticipants(contract) {
@ -2649,13 +2725,14 @@
openPopup('smart_contract_creation_popup', true)
}
function togglePrivateKeyVisibility(input) {
const target = input.closest('sm-input')
target.type = target.type === 'password' ? 'text' : 'password';
target.focusIn()
}
function handleSmartContractAction(smartContractAddress, action) {
renderElem(getRef('smart_contract_popup__content'), html`<sm-spinner></sm-spinner>`)
async function handleSmartContractAction(smartContractAddress, action) {
openPopup('smart_contract_popup')
switch (action) {
// TODO: check minimum amount
case 'deposit': {
@ -2683,15 +2760,30 @@
</sm-input>
</div>
<div class="multi-state-button">
<button id="deposit_button" class="button button--primary" onclick=${() => deposit(smartContractAddress)} type="submit" disabled>Sell</button>
<button id="deposit_button" class="button button--primary" onclick=${() => deposit(smartContractAddress)} type="submit" disabled>Swap</button>
</div>
`)
break;
}
case 'participate': {
const { price, contractName, contractAddress, acceptingToken, sellingToken, tokenIdentification, userChoices, contractSubType } = floGlobals.smartContractList[smartContractAddress]
let { price, contractName, contractAddress, acceptingToken, sellingToken, tokenIdentification, userChoices, contractSubType, participationFees } = floGlobals.smartContractList[smartContractAddress]
if (userChoices) {
getRef('smart_contract_popup__title').textContent = `Participate`
renderElem(getRef('smart_contract_popup__content'), html`<sm-spinner class="justify-self-center"></sm-spinner>`)
if (typeof participationFees === 'undefined') {
try {
// TODO: remove this when smart contract list api is updated
const details = await getContractInfo({
name: contractName,
address: contractAddress
})
participationFees = details.participationFees
} catch (err) {
console.error(err)
renderElem(getRef('smart_contract_popup__content'), html`<p class="error">Failed to fetch contract info</p>`)
return
}
}
}
if (contractSubType === 'tokenswap') {
getRef('smart_contract_popup__title').textContent = `Swap ${acceptingToken} with ${sellingToken}`
@ -2714,8 +2806,13 @@
<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>
<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>
${typeof participationFees !== 'undefined' ? html`
<span id="participation_amount_label" class="label">Pre-defined participation amount (${acceptingToken || tokenIdentification})</span>
<sm-input id="participation_amount" type="number" step="0.00000001" value=${participationFees} readonly required></sm-input>
`: html`
<span id="participation_amount_label" class="label">Participation amount (${acceptingToken || tokenIdentification})</span>
<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>
<div class="grid gap-0-5">
<span class="label">FLO private key</span>
@ -2728,7 +2825,7 @@
</sm-input>
</div>
<div class="multi-state-button">
<button id="participate_button" class="button button--primary" onclick=${() => participate(smartContractAddress)} type="submit" disabled>Sell</button>
<button id="participate_button" class="button button--primary" onclick=${() => participate(smartContractAddress)} type="submit" disabled>Swap</button>
</div>
`)
break;
@ -2737,33 +2834,31 @@
const { contractName, contractAddress, oracle_address, price, acceptingToken } = floGlobals.smartContractList[smartContractAddress]
getRef('smart_contract_popup__title').textContent = `Update price`
renderElem(getRef('smart_contract_popup__content'), html`
<sm-form>
<div class="grid gap-0-5">
<span class="label">Oracle FLO Address</span>
<sm-copy id="oracle_address" value=${oracle_address}></sm-copy>
</div>
<div class="grid gap-0-5">
<span class="label">Oracle FLO private key</span>
<sm-input id="oracle_private_key" class="password-field" type="password" data-private-key="" required="">
<label slot="right" class="interact">
<input type="checkbox" class="hidden" readonly="" onchange="togglePrivateKeyVisibility(this)">
<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>
<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>
</label>
</sm-input>
</div>
<p>
<span class="label">Current price: </span>
<span id="current_price" class="label">${price} ${acceptingToken}</span>
</p>
<div class="grid gap-0-5">
<span id="updated_price_label" class="label">Updated price (${acceptingToken})</span>
<sm-input id="updated_price" type="number" step="0.00000001" min="0.00000001" error-text="Minimum 0.00000001 required" required></sm-input>
</div>
<div class="multi-state-button">
<button id="update_price_button" class="button button--primary" type="submit" onclick=${() => updatePrice(smartContractAddress)} disabled>Update</button>
</div>
</sm-form>
<div class="grid gap-0-5">
<span class="label">Oracle FLO Address</span>
<sm-copy id="oracle_address" value=${oracle_address}></sm-copy>
</div>
<div class="grid gap-0-5">
<span class="label">Oracle FLO private key</span>
<sm-input id="oracle_private_key" class="password-field" type="password" data-private-key="" required="">
<label slot="right" class="interact">
<input type="checkbox" class="hidden" readonly="" onchange="togglePrivateKeyVisibility(this)">
<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>
<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>
</label>
</sm-input>
</div>
<p>
<span class="label">Current price: </span>
<span id="current_price" class="label">${price} ${acceptingToken}</span>
</p>
<div class="grid gap-0-5">
<span id="updated_price_label" class="label">Updated price (${acceptingToken})</span>
<sm-input id="updated_price" type="number" step="0.00000001" min="0.00000001" error-text="Minimum 0.00000001 required" required></sm-input>
</div>
<div class="multi-state-button">
<button id="update_price_button" class="button button--primary" type="submit" onclick=${() => updatePrice(smartContractAddress)} disabled>Update</button>
</div>
`)
break;
}
@ -2801,7 +2896,6 @@
break;
}
}
openPopup('smart_contract_popup')
}