UI changes required for auto fee calculation
This commit is contained in:
parent
4c06604f4b
commit
72916bae0f
File diff suppressed because one or more lines are too long
@ -241,20 +241,24 @@ sm-option {
|
|||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
strip-select {
|
sm-chips {
|
||||||
--gap: 0;
|
--gap: 0;
|
||||||
background-color: rgba(var(--text-color), 0.06);
|
background-color: rgba(var(--text-color), 0.06);
|
||||||
border-radius: 0.3rem;
|
border-radius: 0.3rem;
|
||||||
padding: 0.3rem;
|
padding: 0.3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
strip-option {
|
sm-chip {
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
--border-radius: 0.2rem;
|
--border-radius: 0.2rem;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-moz-user-select: none;
|
-moz-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
sm-chip[selected] {
|
||||||
|
color: rgba(var(--background-color), 1);
|
||||||
|
--background: var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
ul,
|
ul,
|
||||||
ol {
|
ol {
|
||||||
|
|||||||
2
css/main.min.css
vendored
2
css/main.min.css
vendored
File diff suppressed because one or more lines are too long
@ -222,16 +222,20 @@ sm-select {
|
|||||||
sm-option {
|
sm-option {
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
strip-select {
|
sm-chips {
|
||||||
--gap: 0;
|
--gap: 0;
|
||||||
background-color: rgba(var(--text-color), 0.06);
|
background-color: rgba(var(--text-color), 0.06);
|
||||||
border-radius: 0.3rem;
|
border-radius: 0.3rem;
|
||||||
padding: 0.3rem;
|
padding: 0.3rem;
|
||||||
}
|
}
|
||||||
strip-option {
|
sm-chip {
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
--border-radius: 0.2rem;
|
--border-radius: 0.2rem;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
&[selected] {
|
||||||
|
color: rgba(var(--background-color), 1);
|
||||||
|
--background: var(--accent-color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ul,
|
ul,
|
||||||
ol {
|
ol {
|
||||||
|
|||||||
136
index.html
136
index.html
@ -104,11 +104,11 @@
|
|||||||
<div class="flex align-center space-between margin-bottom-1 sticky top-0"
|
<div class="flex align-center space-between margin-bottom-1 sticky top-0"
|
||||||
style="background-color: rgba(var(--foreground-color), 1);">
|
style="background-color: rgba(var(--foreground-color), 1);">
|
||||||
<h5>Transactions</h5>
|
<h5>Transactions</h5>
|
||||||
<strip-select id="filter_selector">
|
<sm-chips id="filter_selector">
|
||||||
<strip-option value="all" selected>All</strip-option>
|
<sm-chip value="all" selected>All</sm-chip>
|
||||||
<strip-option value="sent">Sent</strip-option>
|
<sm-chip value="sent">Sent</sm-chip>
|
||||||
<strip-option value="received">Received</strip-option>
|
<sm-chip value="received">Received</sm-chip>
|
||||||
</strip-select>
|
</sm-chips>
|
||||||
</div>
|
</div>
|
||||||
<ul id="transactions_list" class="observe-empty-state"></ul>
|
<ul id="transactions_list" class="observe-empty-state"></ul>
|
||||||
<div class="empty-state align-self-center text-center">Balance and transactions will appear here
|
<div class="empty-state align-self-center text-center">Balance and transactions will appear here
|
||||||
@ -153,17 +153,15 @@
|
|||||||
<div class="grid gap-0-5">
|
<div class="grid gap-0-5">
|
||||||
<div class="flex align-center space-between">
|
<div class="flex align-center space-between">
|
||||||
<h4>Fees</h4>
|
<h4>Fees</h4>
|
||||||
<strip-select id="fees_selector">
|
<sm-chips id="fees_selector">
|
||||||
<strip-option value="suggested" selected>Suggested</strip-option>
|
<sm-chip value="suggested" selected>Suggested</sm-chip>
|
||||||
<!-- <strip-option value="optimum">Optimum</strip-option> -->
|
<sm-chip value="custom">Custom</sm-chip>
|
||||||
<strip-option value="custom">Custom</strip-option>
|
</sm-chips>
|
||||||
</strip-select>
|
</div>
|
||||||
|
<div id="fees_wrapper" class="grid gap-0-5 align-center">
|
||||||
|
<h4 id="recommended_fee"></h4>
|
||||||
|
<p>Fees will be calculated when above form is properly filled</p>
|
||||||
</div>
|
</div>
|
||||||
<p id="selected_fee_tip">Estimated time of confirmation is 1hr</p>
|
|
||||||
<sm-input type="number" id="send_fee" placeholder="Fee" min="0.00000001" step="0.00000001"
|
|
||||||
error-text="Please enter valid fees" readonly animate required>
|
|
||||||
<div class="currency-symbol flex" slot="icon"></div>
|
|
||||||
</sm-input>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="multi-state-button margin-bottom-1-5">
|
<div class="multi-state-button margin-bottom-1-5">
|
||||||
<button id="send_transaction" type="submit" class="button button--primary cta w-100"
|
<button id="send_transaction" type="submit" class="button button--primary cta w-100"
|
||||||
@ -794,9 +792,7 @@
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'send':
|
case 'send':
|
||||||
getExchangeRate().then(() => {
|
getExchangeRate().catch(e => {
|
||||||
calculateFee()
|
|
||||||
}).catch(e => {
|
|
||||||
console.error(e)
|
console.error(e)
|
||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
@ -1127,14 +1123,8 @@
|
|||||||
<div class="transaction__receiver">${transactionReceiver}</div>
|
<div class="transaction__receiver">${transactionReceiver}</div>
|
||||||
<div class="transaction__id wrap-around">TXID: <a href="${`#/check_details?query=${txid}`}">${txid}</a></div>
|
<div class="transaction__id wrap-around">TXID: <a href="${`#/check_details?query=${txid}`}">${txid}</a></div>
|
||||||
${!block ? html`<p class="pending-badge">Confirmation pending: amount will be deducted after transaction is confirmed</p>` : ''}
|
${!block ? html`<p class="pending-badge">Confirmation pending: amount will be deducted after transaction is confirmed</p>` : ''}
|
||||||
</li>
|
</li>
|
||||||
`;
|
`;
|
||||||
// ${!block ? html`
|
|
||||||
// <p class="flex align-center unconfirmed-wrapper">
|
|
||||||
// <span class="margin-right-0-5">Confirmation taking too long? </span>
|
|
||||||
// <button class="button button--small">Increase fees</button>
|
|
||||||
// </p>
|
|
||||||
// `: ''}
|
|
||||||
},
|
},
|
||||||
async transactions(address) {
|
async transactions(address) {
|
||||||
try {
|
try {
|
||||||
@ -1323,17 +1313,6 @@
|
|||||||
const result = parseFloat((amount * globalExchangeRate[getRef('currency_selector').value]).toFixed(8))
|
const result = parseFloat((amount * globalExchangeRate[getRef('currency_selector').value]).toFixed(8))
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
function calculateFee() {
|
|
||||||
fetch('https://bitcoiner.live/api/fees/estimates/latest').then(res => res.json()).then(data => {
|
|
||||||
const satPerByte = data.estimates['60'].sat_per_vbyte;
|
|
||||||
const legacyBytes = 200;
|
|
||||||
const segwitBytes = 77;
|
|
||||||
const fees = (legacyBytes * satPerByte + (0.25 * satPerByte) * segwitBytes) / Math.pow(10, 8);
|
|
||||||
getRef('send_fee').value = getConvertedAmount(fees);
|
|
||||||
}).catch(e => {
|
|
||||||
console.error(e)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
getRef('currency_selector').addEventListener('change', async e => {
|
getRef('currency_selector').addEventListener('change', async e => {
|
||||||
if (!globalExchangeRate.hasOwnProperty(e.target.value))
|
if (!globalExchangeRate.hasOwnProperty(e.target.value))
|
||||||
await getExchangeRate();
|
await getExchangeRate();
|
||||||
@ -1342,7 +1321,6 @@
|
|||||||
document.querySelectorAll('.amount-shown').forEach(el => {
|
document.querySelectorAll('.amount-shown').forEach(el => {
|
||||||
el.textContent = formatAmount(getConvertedAmount(el.dataset.btcAmount))
|
el.textContent = formatAmount(getConvertedAmount(el.dataset.btcAmount))
|
||||||
})
|
})
|
||||||
calculateFee();
|
|
||||||
})
|
})
|
||||||
getRef('filter_selector').addEventListener('change', async e => {
|
getRef('filter_selector').addEventListener('change', async e => {
|
||||||
const address = getRef('search_query_input').value;
|
const address = getRef('search_query_input').value;
|
||||||
@ -1389,7 +1367,6 @@
|
|||||||
return notify('Please enter BTC address', 'error');
|
return notify('Please enter BTC address', 'error');
|
||||||
}
|
}
|
||||||
const type = coinjs.addressDecode(btc_bech).type
|
const type = coinjs.addressDecode(btc_bech).type
|
||||||
const isLegacy = /\w{34,35}$/.test(btc_bech)
|
|
||||||
if (type === 'standard') {
|
if (type === 'standard') {
|
||||||
getRef('convert_flo_input').value = btcOperator.convert.legacy2legacy(btc_bech, 0x23);
|
getRef('convert_flo_input').value = btcOperator.convert.legacy2legacy(btc_bech, 0x23);
|
||||||
} else if (type === 'bech32') {
|
} else if (type === 'bech32') {
|
||||||
@ -1488,44 +1465,81 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
getRef('fees_selector').addEventListener('change', e => {
|
getRef('fees_selector').addEventListener('change', e => {
|
||||||
if (e.target.value !== 'custom') {
|
|
||||||
getRef('send_fee').readOnly = true;
|
|
||||||
}
|
|
||||||
switch (e.target.value) {
|
switch (e.target.value) {
|
||||||
case 'custom':
|
case 'custom':
|
||||||
getRef('send_fee').readOnly = false;
|
renderElem(getRef('fees_wrapper'), html`
|
||||||
getRef('send_fee').focusIn();
|
<p id="selected_fee_tip">Set custom fee</p>
|
||||||
getRef('selected_fee_tip').textContent = 'Set custom fee';
|
<sm-input type="number" id="send_fee" placeholder="Fee" min="0.00000001" step="0.00000001"
|
||||||
|
error-text="Please enter valid fees" animate required>
|
||||||
|
<div class="currency-symbol flex" slot="icon"></div>
|
||||||
|
</sm-input>
|
||||||
|
`)
|
||||||
|
document.getElementById('send_fee').focusIn();
|
||||||
|
getRef('fees_wrapper').querySelector('.currency-symbol').innerHTML = currencyIcons[getRef('currency_selector').value];
|
||||||
break;
|
break;
|
||||||
case 'suggested':
|
case 'suggested':
|
||||||
getRef('selected_fee_tip').textContent = 'Estimated time of confirmation is 1hr'
|
if (getRef('send_transaction').disabled) {
|
||||||
calculateFee();
|
renderElem(getRef('fees_wrapper'), html`
|
||||||
|
<h4 id="recommended_fee"></h4>
|
||||||
|
<p>Fees will be calculated when above form is properly filled</p>
|
||||||
|
`)
|
||||||
|
} else {
|
||||||
|
renderElem(getRef('fees_wrapper'), html`
|
||||||
|
<h4 id="recommended_fee"></h4>
|
||||||
|
`)
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function getTransactionInputs() {
|
||||||
|
const senders = [...new Set([...getRef('sender_container').querySelectorAll('.sender-input')].map(input => input.value.trim()))];
|
||||||
|
const privKeys = [...getRef('sender_container').querySelectorAll('.priv-key-input')].map(input => input.value.trim());
|
||||||
|
const receivers = [...getRef('receiver_container').querySelectorAll('.receiver-input')].map(input => input.value.trim());
|
||||||
|
const amounts = [...getRef('receiver_container').querySelectorAll('.amount-input')].map(input => {
|
||||||
|
return parseFloat(input.value.trim()) / globalExchangeRate[getRef('currency_selector').value]
|
||||||
|
});
|
||||||
|
console.debug(senders, receivers, amounts); //for automatic fee calc, set fee = null
|
||||||
|
return [senders, privKeys, receivers, amounts]
|
||||||
|
}
|
||||||
|
function calculateFees() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const [senders, privKeys, receivers, amounts] = getTransactionInputs();
|
||||||
|
btcOperator.createSignedTx(senders, privKeys, receivers, amounts).then(fees => {
|
||||||
|
document.getElementById('recommended_fee').textContent = formatAmount(getConvertedAmount(fees));
|
||||||
|
resolve(fees)
|
||||||
|
}).catch(e => {
|
||||||
|
notify(e, 'error')
|
||||||
|
reject(e)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getRef('send_tx').addEventListener('valid', e => {
|
||||||
|
if (getRef('fees_selector').value === 'suggested') {
|
||||||
|
calculateFees()
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
getRef('send_tx').addEventListener('invalid', e => {
|
||||||
|
console.debug(e)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
getRef('send_transaction').onclick = evt => {
|
getRef('send_transaction').onclick = evt => {
|
||||||
buttonLoader('send_transaction', true)
|
buttonLoader('send_transaction', true)
|
||||||
getExchangeRate().then(exchangeRate => {
|
getExchangeRate().then(async exchangeRate => {
|
||||||
const senders = [...new Set([...getRef('sender_container').querySelectorAll('.sender-input')].map(input => input.value.trim()))];
|
const [senders, privKeys, receivers, amounts] = getTransactionInputs();
|
||||||
const privKeys = [...getRef('sender_container').querySelectorAll('.priv-key-input')].map(input => input.value.trim());
|
let fee = null;
|
||||||
const receivers = [...getRef('receiver_container').querySelectorAll('.receiver-input')].map(input => input.value.trim());
|
if (getRef('fees_selector').value === 'custom') {
|
||||||
const amounts = [...getRef('receiver_container').querySelectorAll('.amount-input')].map(input => {
|
fee = parseFloat((parseFloat(getRef('send_fee').value.trim()) / globalExchangeRate[getRef('currency_selector').value]).toFixed(8));
|
||||||
return parseFloat(input.value.trim()) / globalExchangeRate[getRef('currency_selector').value]
|
}
|
||||||
});
|
|
||||||
const fee = parseFloat((parseFloat(getRef('send_fee').value.trim()) / globalExchangeRate[getRef('currency_selector').value]).toFixed(8));
|
|
||||||
console.debug(senders, receivers, amounts, fee); //for automatic fee calc, set fee = null
|
|
||||||
btcOperator.sendTx(senders, privKeys, receivers, amounts, fee).then(result => {
|
btcOperator.sendTx(senders, privKeys, receivers, amounts, fee).then(result => {
|
||||||
console.log(result);
|
console.log(result);
|
||||||
getRef('txid').value = result.txid;
|
getRef('txid').value = result.txid;
|
||||||
openPopup('txid_popup');
|
openPopup('txid_popup');
|
||||||
getRef('send_tx').reset()
|
getRef('send_tx').reset()
|
||||||
getExchangeRate().then(() => {
|
|
||||||
calculateFee()
|
|
||||||
}).catch(e => {
|
|
||||||
console.error(e)
|
|
||||||
})
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
notify(`Error sending transaction \n ${error}`, 'error');
|
notify(`Error sending transaction \n ${error}`, 'error');
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user