mirror of
https://github.com/cryptoadvance/specter-desktop.git
synced 2026-08-13 12:33:29 +02:00
feat:(*) lots of styles everywhere
This commit is contained in:
parent
26d1047739
commit
98a5661280
19 changed files with 350 additions and 248 deletions
|
|
@ -497,13 +497,22 @@ td,
|
|||
border-right-width: 1px;
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(27 28 33 / var(--tw-border-opacity));
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
padding-left: 0.75rem;
|
||||
padding-right: 0.75rem;
|
||||
padding-top: 0.375rem;
|
||||
padding-bottom: 0.375rem;
|
||||
text-align: left;
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(255 255 255 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
td:last-child,
|
||||
th:last-child {
|
||||
border-right-width: 0px;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
/* first:pl-4 last:pr-4 */
|
||||
}
|
||||
|
||||
|
|
@ -1000,7 +1009,7 @@ input[type="number"]::-webkit-outer-spin-button,
|
|||
}
|
||||
|
||||
.table-holder {
|
||||
margin: 0 calc((100vw - 1080px) / -2);
|
||||
margin: 20px calc((100vw - 1080px) / -2) 0;
|
||||
max-width: calc((100vw - 300px - 80px));
|
||||
}
|
||||
|
||||
|
|
@ -1224,6 +1233,10 @@ input[type="number"]::-webkit-outer-spin-button,
|
|||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.mt-2 {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.mr-4 {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
|
@ -1248,8 +1261,12 @@ input[type="number"]::-webkit-outer-spin-button,
|
|||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.mt-2 {
|
||||
margin-top: 0.5rem;
|
||||
.mb-1 {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.mr-0 {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.ml-2 {
|
||||
|
|
@ -1272,10 +1289,6 @@ input[type="number"]::-webkit-outer-spin-button,
|
|||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.mr-0 {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.mb-12 {
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
|
@ -1360,6 +1373,10 @@ input[type="number"]::-webkit-outer-spin-button,
|
|||
height: 2.25rem;
|
||||
}
|
||||
|
||||
.h-2 {
|
||||
height: 0.5rem;
|
||||
}
|
||||
|
||||
.h-10 {
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
|
@ -1380,6 +1397,10 @@ input[type="number"]::-webkit-outer-spin-button,
|
|||
height: 3rem;
|
||||
}
|
||||
|
||||
.h-20 {
|
||||
height: 5rem;
|
||||
}
|
||||
|
||||
.max-h-\[40px\] {
|
||||
max-height: 40px;
|
||||
}
|
||||
|
|
@ -1416,6 +1437,10 @@ input[type="number"]::-webkit-outer-spin-button,
|
|||
width: 24rem;
|
||||
}
|
||||
|
||||
.w-20 {
|
||||
width: 5rem;
|
||||
}
|
||||
|
||||
.w-\[344px\] {
|
||||
width: 344px;
|
||||
}
|
||||
|
|
@ -1472,14 +1497,6 @@ input[type="number"]::-webkit-outer-spin-button,
|
|||
width: 2.25rem;
|
||||
}
|
||||
|
||||
.w-40 {
|
||||
width: 10rem;
|
||||
}
|
||||
|
||||
.w-20 {
|
||||
width: 5rem;
|
||||
}
|
||||
|
||||
.min-w-\[300px\] {
|
||||
min-width: 300px;
|
||||
}
|
||||
|
|
@ -1560,6 +1577,12 @@ input[type="number"]::-webkit-outer-spin-button,
|
|||
resize: both;
|
||||
}
|
||||
|
||||
.appearance-none {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.grid-cols-4 {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
|
|
@ -1637,6 +1660,12 @@ input[type="number"]::-webkit-outer-spin-button,
|
|||
margin-bottom: calc(0.75rem * var(--tw-space-y-reverse));
|
||||
}
|
||||
|
||||
.space-x-2 > :not([hidden]) ~ :not([hidden]) {
|
||||
--tw-space-x-reverse: 0;
|
||||
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
|
||||
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
|
||||
}
|
||||
|
||||
.space-x-4 > :not([hidden]) ~ :not([hidden]) {
|
||||
--tw-space-x-reverse: 0;
|
||||
margin-right: calc(1rem * var(--tw-space-x-reverse));
|
||||
|
|
@ -1649,12 +1678,6 @@ input[type="number"]::-webkit-outer-spin-button,
|
|||
margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse)));
|
||||
}
|
||||
|
||||
.space-x-2 > :not([hidden]) ~ :not([hidden]) {
|
||||
--tw-space-x-reverse: 0;
|
||||
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
|
||||
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
|
||||
}
|
||||
|
||||
.space-y-5 > :not([hidden]) ~ :not([hidden]) {
|
||||
--tw-space-y-reverse: 0;
|
||||
margin-top: calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));
|
||||
|
|
@ -1701,10 +1724,6 @@ input[type="number"]::-webkit-outer-spin-button,
|
|||
word-break: break-all;
|
||||
}
|
||||
|
||||
.break-keep {
|
||||
word-break: keep-all;
|
||||
}
|
||||
|
||||
.rounded-lg {
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
|
@ -1809,10 +1828,20 @@ input[type="number"]::-webkit-outer-spin-button,
|
|||
background-color: rgb(20 21 26 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-dark-600 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(44 45 49 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-white\/10 {
|
||||
background-color: rgb(255 255 255 / 0.1);
|
||||
}
|
||||
|
||||
.bg-dark-500 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(63 64 68 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-dark-700 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(27 28 33 / var(--tw-bg-opacity));
|
||||
|
|
@ -1833,11 +1862,6 @@ input[type="number"]::-webkit-outer-spin-button,
|
|||
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-dark-600 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(44 45 49 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-black\/40 {
|
||||
background-color: rgb(0 0 0 / 0.4);
|
||||
}
|
||||
|
|
@ -1851,6 +1875,11 @@ input[type="number"]::-webkit-outer-spin-button,
|
|||
background-color: rgb(20 21 26 / 0.7);
|
||||
}
|
||||
|
||||
.bg-red-600 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(220 38 38 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.fill-current {
|
||||
fill: currentColor;
|
||||
}
|
||||
|
|
@ -1911,9 +1940,9 @@ input[type="number"]::-webkit-outer-spin-button,
|
|||
padding-right: 0.25rem;
|
||||
}
|
||||
|
||||
.px-4 {
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
.px-6 {
|
||||
padding-left: 1.5rem;
|
||||
padding-right: 1.5rem;
|
||||
}
|
||||
|
||||
.py-3 {
|
||||
|
|
@ -1921,6 +1950,11 @@ input[type="number"]::-webkit-outer-spin-button,
|
|||
padding-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.px-4 {
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
.py-5 {
|
||||
padding-top: 1.25rem;
|
||||
padding-bottom: 1.25rem;
|
||||
|
|
@ -2226,6 +2260,13 @@ input[type="number"]::-webkit-outer-spin-button,
|
|||
color: rgb(41 151 255 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.dark\:bg-gray-700 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(55 65 81 / var(--tw-bg-opacity));
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.lg\:flex {
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
|
||||
td,
|
||||
th {
|
||||
@apply px-2 py-1.5 text-white whitespace-nowrap text-left border-r border-dark-700; /* first:pl-4 last:pr-4 */
|
||||
@apply px-3 py-1.5 text-white whitespace-nowrap text-left border-r border-dark-700 last:border-r-0; /* first:pl-4 last:pr-4 */
|
||||
}
|
||||
|
||||
.table-key {
|
||||
|
|
@ -206,7 +206,7 @@
|
|||
}
|
||||
|
||||
.table-holder {
|
||||
margin: 0 calc((100vw - 1080px) / -2);
|
||||
margin: 20px calc((100vw - 1080px) / -2) 0;
|
||||
max-width: calc((100vw - 300px - 80px));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,10 +23,11 @@
|
|||
<h1>{{ _("Upload Keys") }}</h1>
|
||||
|
||||
{% if not existing_device %}
|
||||
<h2 class="mt-4 mb-8">
|
||||
{{ _("Name your Device: ") }}
|
||||
<input type="text" name="device_name" placeholder="My device" id="device_name" required/>
|
||||
</h2>
|
||||
<h3 class="mt-8">Information</h3>
|
||||
<div class="floating-wrapper mb-1">
|
||||
<input type="text" name="device_name" placeholder=" " class="floating-input peer" id="device_name" required/>
|
||||
<label class="floating-label">Device Name</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div id="coldcard-instructions" class="{%if device_class.device_type != 'coldcard' %}hidden{% endif %}">
|
||||
|
|
@ -77,7 +78,8 @@
|
|||
</p>
|
||||
</div>
|
||||
|
||||
<table class="mt-8">
|
||||
<h3 class="mt-8">Keys</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ _("Purpose") }}</th>
|
||||
|
|
|
|||
|
|
@ -77,10 +77,11 @@
|
|||
</ul>
|
||||
|
||||
<div class="flex items-center select-none">
|
||||
<div id="pagination-container" class="flex items-center mx-4">
|
||||
<div id="pagination-container" class="flex items-center mx-4 space-x-2">
|
||||
<a id="pagination-back" class="hidden cursor-pointer w-6">←</a>
|
||||
{{ _("Page") }} <input id="pagination-idx" class="text-center max-w-[40px] block max-h-[40px] mx-2" type="number" step="1" min="1" value="1"></input>
|
||||
<div id="pagination-counter" class="block break-keep"></div>
|
||||
<span>{{ _("Page") }}</span>
|
||||
<input id="pagination-idx" class="text-center max-w-[40px] block max-h-[40px] mx-2" type="number" step="1" min="1" value="1"></input>
|
||||
<div id="pagination-counter" class="block whitespace-nowrap"></div>
|
||||
<a id="pagination-next" class="hidden cursor-pointer w-6">→</a>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template id="coin-selection">
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='output.css') }}">
|
||||
<span class="toggle_coinselection cursor-pointer" data-cy="coin-selection-toggle">{{ _("Coin selection") }} {% if show_advanced_settings %}▼{% else %}▶{% endif %}</span>
|
||||
<span class="toggle_coinselection mt-3 cursor-pointer" data-cy="coin-selection-toggle">{{ _("Coin selection") }} {% if show_advanced_settings %}▼{% else %}▶{% endif %}</span>
|
||||
<div class="coinselection_div hidden">
|
||||
<div class="errorMessagesDiv">
|
||||
<message-box type="error" class="hidden"></message-box>
|
||||
|
|
|
|||
|
|
@ -1,45 +1,65 @@
|
|||
<template id="fee-selection">
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='output.css') }}">
|
||||
<div class="fee_container space-y-3">
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<label class="checkbox-wrapper">
|
||||
<input type="radio" class="checkbox-input" id="fee_option_dynamic" name="fee_options" value="dynamic" >
|
||||
<span class="checkbox-label">{{ _("Dynamic") }}</span>
|
||||
</label>
|
||||
<label class="checkbox-wrapper">
|
||||
<input type="radio" class="checkbox-input" id="fee_option_manual" name="fee_options" value="manual" >
|
||||
<span class="checkbox-label">{{ _("Manual") }}</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="fee_container">
|
||||
<div id="subtract_fees_div" data-style="display: flex">
|
||||
<label><input type="checkbox" class="inline" name="subtract" id="subtract" {% if subtract %}checked{% endif %}> {{ _("Subtract fees from amount") }}</label>
|
||||
<tool-tip width="200px">
|
||||
<h4 slot="title">{{ _("Subtract fees from amount") }}</h4>
|
||||
<div id="fee_manual" class="floating-wrapper" style="display: none">
|
||||
{% set min_fee = 0.1 if specter.is_liquid else 1 %}
|
||||
<input type="number" class="fee_rate floating-input peer" placeholder=" " name="fee_rate" id="fee_rate" min="{{min_fee}}" step="0.1" value="{{min_fee}}" autocomplete="off">
|
||||
<label class="floating-label">{{ _("Fee Rate") }} (sat/vbyte)</label>
|
||||
<tool-tip width="200px" class="floating-info">
|
||||
<span slot="paragraph">
|
||||
{{ _("If checked, the transaction fees will be paid off from the transaction amount.") }}
|
||||
{{ _("Otherwise, the fees will be paid in addition to the amount sent.") }}
|
||||
{{ _("{} sat/vbyte is the minimal fee rate.".format(min_fee)) }}
|
||||
</span>
|
||||
</tool-tip>
|
||||
</div>
|
||||
<span id="subtract_from" data-style="display: none">
|
||||
{{ _("Subtract from ") }}
|
||||
<select id="subtract_from_recipient_id_select" name="subtract_from_stale" data-style="width: 140px; min-width: 140px;"></select>
|
||||
</span>
|
||||
<div>
|
||||
{{ _("Fees:") }}
|
||||
<label><input type="radio" class="inline" data-style="margin: 0 10px 0 20px;" id="fee_option_dynamic" name="fee_options" value="dynamic" >{{ _("dynamic") }}</label>
|
||||
<label><input type="radio" class="inline" data-style="margin: 0 10px 0 20px" id="fee_option_manual" name="fee_options" value="manual" >{{ _("manual") }}</label>
|
||||
</div>
|
||||
<div id = "fee_manual" data-style="display: none">
|
||||
{{ _("Fee rate:") }}
|
||||
{% set min_fee = 0.1 if specter.is_liquid else 1 %}
|
||||
<input type="number" class="fee_rate" name="fee_rate" id="fee_rate" min="{{min_fee}}" step="0.1" value="{{min_fee}}" autocomplete="off"> sat/vbyte
|
||||
<div class="note">
|
||||
{{ _("{} sat/vbyte is the minimal fee rate.".format(min_fee)) }}
|
||||
</div>
|
||||
</div>
|
||||
<div id ="fee_dynamic" data-style="display: {% if fee_options_dynamic %}block{% else %}none{% endif %}">
|
||||
|
||||
<div id="fee_dynamic" style="display: {% if fee_options_dynamic %}block{% else %}none{% endif %}">
|
||||
<div id="blocks"></div>
|
||||
<input type="range" data-style="width: 12em" min="{{min_fee}}" max="" value="" step="0.1" id="fees_slider">
|
||||
<input type="hidden" id="fee_rate_dynamic" name="fee_rate_dynamic" value="{{min_fee}}">
|
||||
<div>
|
||||
{{ _("Estimated speed:") }} <span id="fee_rate_speed_text"></span>
|
||||
<span class="note">({{ _("Fee rate:") }} <span id="fee_rate_dynamic_text"></span> sat/vbyte)</span>
|
||||
|
||||
<div class="border-2 border-dark-700 bg-dark-800 rounded-lg px-6 py-3">
|
||||
<input type="range" min="{{min_fee}}" step="0.1" id="fees_slider" class="w-full h-2 bg-dark-500 rounded-lg appearance-none cursor-pointer dark:bg-gray-700">
|
||||
<div class="w-full text-center text-base mt-2 font-medium">
|
||||
{{ _("Estimated speed:") }} <span id="fee_rate_speed_text"></span>
|
||||
<span class="note">({{ _("Fee rate:") }} <span id="fee_rate_dynamic_text"></span> sat/vbyte)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<label class="rbf-label" data-style="display: none">
|
||||
<input type="checkbox" class="rbf-checkbox inline" name="rbf" id="rbf"> {{ _("RBF Enabled") }}
|
||||
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<div id="subtract_fees_div" data-style="display: flex">
|
||||
<label class="checkbox-wrapper">
|
||||
<input type="checkbox" class="checkbox-input" name="subtract" id="subtract" {% if subtract %}checked{% endif %}>
|
||||
<span class="checkbox-label">{{ _("Subtract fees from amount") }}</span>
|
||||
<tool-tip width="200px">
|
||||
<h4 slot="title">{{ _("Subtract fees from amount") }}</h4>
|
||||
<span slot="paragraph">
|
||||
{{ _("If checked, the transaction fees will be paid off from the transaction amount.") }}
|
||||
{{ _("Otherwise, the fees will be paid in addition to the amount sent.") }}
|
||||
</span>
|
||||
</tool-tip>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="floating-wrapper" id="subtract_from">
|
||||
<select class="floating-input peer" id="subtract_from_recipient_id_select" name="subtract_from_stale"></select>
|
||||
<label class="floating-label">Subtract From</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label class="rbf-label checkbox-wrapper-inline" style="display: none">
|
||||
<input type="checkbox" class="rbf-checkbox checkbox-input" name="rbf" id="rbf">
|
||||
<span class="checkbox-label">{{ _("RBF Enabled") }}</span>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
<div id="tx_broadcast" class="hidden">
|
||||
<h1>{{ _("Transaction is Ready to Broadcast") }}</h1>
|
||||
<div class="flex-center flex-column">
|
||||
<button id="broadcast_local_btn" class="btn flex-item" data-style="width: 190px;">{{ _("Send transaction") }}</button>
|
||||
<button type="button" id="broadcast_block_explorer_btn" class="btn flex-item {% if specter.chain == 'regtest' %}hidden{% endif %}" data-style="width: 190px;">{{ _("Send via block explorer") }}</button>
|
||||
<button type="button" id="broadcast_blockstream_btn" class="btn flex-item hidden" data-style="width: 190px;">{{ _("Send via blockstream.info") }}</button>
|
||||
<button type="button" id="broadcast_mempool_btn" class="btn flex-item hidden" data-style="width: 190px;">{{ _("Send via mempool.space") }}</button>
|
||||
<button type="button" id="broadcast_blockstream_tor_btn" class="btn flex-item hidden" data-style="width: 190px;">{{ _("Send via blockstream.info") }}<br>{{ _("over Tor hidden service") }}</button>
|
||||
<button type="button" id="broadcast_mempool_tor_btn" class="btn flex-item hidden" data-style="width: 190px;">{{ _("Send via mempool.space") }}<br>{{ _("over Tor hidden service") }}</button>
|
||||
<button type="button" id="broadcast_options_btn" class="btn flex-item hidden" data-style="width: 190px;">{{ _("Back to options") }}</button>
|
||||
<button id="save_psbt_btn" class="btn flex-item" data-style="width: 190px;">{{ _("Save as pending") }}</button>
|
||||
<button id="copy_final_tx_btn" class="btn flex-item" data-style="width: 190px;">{{ _("Copy raw transaction") }}</button>
|
||||
<div id="tx_broadcast" class="hidden p-4 rounded-lg bg-dark-800">
|
||||
<div class="flex justify-between mb-2">
|
||||
<h3 class="mb-0">{{ _("Broadcast Transaction") }}</h3>
|
||||
<p class="m-0 ml-4 cursor-pointer" onclick="hidePageOverlay()" class="cursor-pointer">Close</p>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<button type="button" id="broadcast_block_explorer_btn" class="button {% if specter.chain == 'regtest' %}hidden{% endif %}">{{ _("Send via block explorer") }}</button>
|
||||
<button type="button" id="broadcast_blockstream_btn" class="button hidden">{{ _("Send via blockstream.info") }}</button>
|
||||
<button type="button" id="broadcast_mempool_btn" class="button hidden">{{ _("Send via mempool.space") }}</button>
|
||||
<button type="button" id="broadcast_blockstream_tor_btn" class="button hidden">{{ _("Send via blockstream.info") }}<br>{{ _("over Tor hidden service") }}</button>
|
||||
<button type="button" id="broadcast_mempool_tor_btn" class="button hidden">{{ _("Send via mempool.space") }}<br>{{ _("over Tor hidden service") }}</button>
|
||||
<button type="button" id="broadcast_options_btn" class="button hidden">{{ _("Back to options") }}</button>
|
||||
<button type="button" id="save_psbt_btn" class="button ">{{ _("Save as pending") }}</button>
|
||||
<button type="button" id="copy_final_tx_btn" class="button">{{ _("Copy raw transaction") }}</button>
|
||||
<button type="button" id="broadcast_local_btn" class="button text-white bg-accent mb-0">{{ _("Send transaction") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<!-- <a href="#" id="page_overlay_popup_cancel_button" onclick="cancelOverlay()">{{ _("Cancel") }}</a> -->
|
||||
<!-- </div> -->
|
||||
|
||||
<div class="loader hidden" id="pacman">
|
||||
<div class="loader hidden absolute self-center z-100" id="pacman">
|
||||
<img src="{{ url_for('static', filename='img/loader.gif') }}"/>
|
||||
<div>{{ _("Loading... It may take a while...") }}</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,15 +8,20 @@
|
|||
#}
|
||||
{% macro sign_tx_method(wallet, device, psbt, chain) -%}
|
||||
{% set device_psbts = device.create_psbts(psbt['base64'], wallet) %}
|
||||
<div id="{{ device.alias }}_sign_tx_method" class="flex-center flex-column hidden">
|
||||
<h2>{{ _("Sign Transaction") }}</h2><br>
|
||||
<div>
|
||||
{{ _("Please choose a signing method for your") }} {{ device.name }}.
|
||||
<div id="{{ device.alias }}_sign_tx_method" class="p-4 bg-dark-800 rounded-lg flex-column hidden">
|
||||
<div class="flex justify-between mb-2">
|
||||
<h3 class="mb-0">{{ _("Sign Transaction") }}</h3>
|
||||
<p class="m-0 cursor-pointer" onclick="hidePageOverlay()" class="cursor-pointer">Close</p>
|
||||
</div>
|
||||
|
||||
<p>{{ _("Please choose a signing method for your") }} {{ device.name }}.</p>
|
||||
|
||||
{% if device.hwi_support %}
|
||||
<button id="{{ device.alias }}_hwi_sign_btn" class="btn flex-item" data-style="width: 190px; margin: 15px auto;">
|
||||
<img src="{{ url_for('static', filename='img/usb.svg') }}" data-style="width: 26px; margin-right: 2px;" class="svg-white">{{ _("Sign via USB (HWI)") }}
|
||||
<button id="{{ device.alias }}_hwi_sign_btn" class="button bg-accent mb-0 mr-0 text-white space-x-2">
|
||||
<img src="{{ url_for('static', filename='img/usb.svg') }}">
|
||||
<span>{{ _("Sign via USB (HWI)") }}</span>
|
||||
</button>
|
||||
|
||||
<script>
|
||||
document.getElementById("{{ device.alias }}_hwi_sign_btn").addEventListener("click", e => {
|
||||
e.preventDefault();
|
||||
|
|
@ -34,11 +39,14 @@
|
|||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
{% if device.sd_card_support %}
|
||||
{% include "includes/overlay/sd_card_sign.jinja" %}
|
||||
<button id="{{ device.alias }}_file_sign_btn" class="btn flex-item" data-style="width: 190px; margin: 15px auto;">
|
||||
<img src="{{ url_for('static', filename='img/sd-card.svg') }}" data-style="width: 26px; margin: 0px;" class="svg-white"> {{ _("Sign with SD Card file") }}
|
||||
<button id="{{ device.alias }}_file_sign_btn" class="button bg-accent mb-0 mr-0 text-white space-x-2">
|
||||
<img src="{{ url_for('static', filename='img/sd-card.svg') }}">
|
||||
<span>{{ _("Sign with SD Card file") }}</span>
|
||||
</button>
|
||||
|
||||
<script>
|
||||
document.getElementById("{{ device.alias }}_file_sign_btn").addEventListener("click", e => {
|
||||
e.preventDefault();
|
||||
|
|
@ -47,10 +55,12 @@
|
|||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
{% if device.qr_code_support %}
|
||||
{% include "includes/overlay/qr_code_sign.jinja" %}
|
||||
<button id="{{ device.alias }}_qr_sign_btn" class="btn flex-item" data-style="width: 190px; margin: 15px auto;">
|
||||
<img src="{{ url_for('static', filename='img/qr-code.svg') }}" data-style="width: 26px; margin: 0px;" class="svg-white"> {{ _("Sign with QR codes") }}
|
||||
<button id="{{ device.alias }}_qr_sign_btn" class="button bg-accent mb-0 mr-0 text-white space-x-2">
|
||||
<img src="{{ url_for('static', filename='img/qr-code.svg') }}">
|
||||
<span>{{ _("Sign with QR codes") }}</span>
|
||||
</button>
|
||||
<script>
|
||||
document.getElementById("{{ device.alias }}_qr_sign_btn").addEventListener("click", e => {
|
||||
|
|
@ -60,14 +70,15 @@
|
|||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
{% if device.hot_wallet %}
|
||||
<button id="{{ device.alias }}_hot_sign_btn" class="btn flex-item" data-style="width: 190px; margin: 15px auto;">
|
||||
<button id="{{ device.alias }}_hot_sign_btn" class="button mb-0 bg-accent text-white space-x-2 mr-0 w-full mt-3">
|
||||
{% if device.device_type == "bitcoincore" %}
|
||||
<img src="{{ url_for('static', filename='img/devices/bitcoincore_icon.svg') }}"/>
|
||||
{{ _("Sign with Bitcoin Core") }}
|
||||
<span>{{ _("Sign with Bitcoin Core") }}</span>
|
||||
{% else %}
|
||||
<img src="{{ url_for('static', filename='img/devices/elementscore_icon.svg') }}"/>
|
||||
{{ _("Sign with Elements Core") }}
|
||||
<span>{{ _("Sign with Elements Core") }}</span>
|
||||
{% endif %}
|
||||
</button>
|
||||
<script>
|
||||
|
|
@ -77,31 +88,36 @@
|
|||
showPageOverlay('{{ device.alias }}_hot_enter_passphrase')
|
||||
});
|
||||
</script>
|
||||
<div id="{{ device.alias }}_hot_enter_passphrase" class="hidden">
|
||||
|
||||
<div id="{{ device.alias }}_hot_enter_passphrase" class="hidden bg-dark-800 p-4">
|
||||
{% set is_encrypted = device.is_encrypted(wallet.manager) %}
|
||||
{% if is_encrypted %}
|
||||
<h2>{{ _("Enter decryption password") }}</h2>
|
||||
{% else %}
|
||||
<h2>{{ _("Proceed with signing") }}</h2>
|
||||
{% endif %}
|
||||
<div class="flex justify-between mb-2">
|
||||
{% if is_encrypted %}
|
||||
<h3 class="mb-0">{{ _("Enter decryption password") }}</h3>
|
||||
{% else %}
|
||||
<h3 class="mb-0">{{ _("Proceed with signing") }}</h3>
|
||||
{% endif %}
|
||||
<p class="m-0 cursor-pointer" onclick="hidePageOverlay()" class="cursor-pointer">Close</p>
|
||||
</div>
|
||||
|
||||
<form action="{{ url_for('wallets_endpoint.send_new', wallet_alias=wallet.alias) }}" method="POST" id="hot_enter_passphrase__content" class="flex-center flex-column">
|
||||
<input type="hidden" class="csrf-token" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||
<br/>
|
||||
<div>
|
||||
{% if is_encrypted %}
|
||||
<input name="passphrase" type="password" id="hwi_enter_passphrase__passphrase" />
|
||||
<div class="floating-wrapper">
|
||||
<input class="floating-input peer" placeholder=" " name="passphrase" type="password" id="hwi_enter_passphrase__passphrase" />
|
||||
<label class="floating-label">Passphrase</label>
|
||||
</div>
|
||||
{% else %}
|
||||
{{ _("Wallet is not encrypted, just click the button.") }}
|
||||
<input name="passphrase" type="hidden" id="hwi_enter_passphrase__passphrase" value="" />
|
||||
<p>{{ _("Wallet is not encrypted, just click the button.") }}</p>
|
||||
<input name="passphrase" type="hidden" id="hwi_enter_passphrase__passphrase" value="" />
|
||||
{% endif %}
|
||||
<input name="device" type="hidden" value="{{ device.alias }}" />
|
||||
<input name="psbt" type="hidden" value='{{ psbt|tojson|safe }}' />
|
||||
</div>
|
||||
<br/>
|
||||
<br/>
|
||||
<button id="hot_enter_passphrase__submit" class="btn" type="submit" name="action" value="signhotwallet">{{ _("Sign transaction") }}</button>
|
||||
<button id="hot_enter_passphrase__submit" class="button bg-accent text-white mb-0 mr-0 mt-3" type="submit" name="action" value="signhotwallet">{{ _("Sign transaction") }}</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{%- endmacro %}
|
||||
{%- endmacro %}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
<template id="qr-scanner">
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='output.css') }}">
|
||||
|
||||
<div style="display: none;"><!--<style>-->
|
||||
<style>
|
||||
#popup{
|
||||
position:fixed;
|
||||
top: 0px;
|
||||
|
|
@ -35,6 +35,8 @@
|
|||
align-content: center;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
border-radius: 12px;
|
||||
}
|
||||
#qr-progress{
|
||||
font-size: 30px;
|
||||
|
|
@ -46,12 +48,14 @@
|
|||
#qr-video{
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
:host,slot{
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
</div><!--</style>-->
|
||||
</style>
|
||||
<div class="popup" id="popup">
|
||||
<video muted playsinline id="qr-video" class="video"></video>
|
||||
<div id="qr-progress"></div>
|
||||
|
|
|
|||
|
|
@ -275,10 +275,11 @@
|
|||
</ul>
|
||||
|
||||
<div class="flex items-center select-none">
|
||||
<div id="pagination-container" class="flex items-center mx-4">
|
||||
<div id="pagination-container" class="flex items-center mx-4 space-x-2">
|
||||
<a id="pagination-back" class="hidden cursor-pointer w-6">←</a>
|
||||
{{ _("Page") }} <input id="pagination-idx" class="text-center max-w-[40px] block max-h-[40px] mx-2" type="number" step="1" min="1" value="1"></input>
|
||||
<div id="pagination-counter" class="block break-keep"></div>
|
||||
<span>{{ _("Page") }}</span>
|
||||
<input id="pagination-idx" class="text-center max-w-[40px] block max-h-[40px] mx-2" type="number" step="1" min="1" value="1"></input>
|
||||
<div id="pagination-counter" class="block whitespace-nowrap"></div>
|
||||
<a id="pagination-next" class="hidden cursor-pointer w-6">→</a>
|
||||
</div>
|
||||
|
||||
|
|
@ -289,7 +290,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="search-container">
|
||||
<div class="search-container hidden">
|
||||
<input class="search" type="text" placeholder="Search..."></input>
|
||||
|
||||
<!-- <div id="tooltip-container" class="tooltip-no-grow tooltip-width"> -->
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{% extends "base.jinja" %}
|
||||
{% block head %}
|
||||
<div style="display: none;"><!--<style>-->
|
||||
|
||||
{% block head %}
|
||||
<style>
|
||||
/* copied (and adapted for card-use) from here:
|
||||
* "Fork me on GitHub" CSS ribbon v0.2.3 | MIT License
|
||||
* https://github.com/simonwhitaker/github-fork-ribbon-css
|
||||
|
|
@ -127,13 +127,13 @@
|
|||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
</div><!--</style>-->
|
||||
</style>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% from 'services/components/plugin_card.jinja' import plugin_card %}
|
||||
|
||||
{% from 'services/components/plugin_card.jinja' import plugin_card %}
|
||||
<div style="display: none;"><!--<style>-->
|
||||
|
||||
.plugin_container {
|
||||
|
|
@ -182,74 +182,57 @@
|
|||
margin-top: 4em;
|
||||
}
|
||||
</div><!--</style>-->
|
||||
<h1 data-style="font-size: 2em;">{{ _("Plugins") }}</h1>
|
||||
|
||||
<h1>{{ _("Plugins") }}</h1>
|
||||
{% if is_login_disabled %}
|
||||
<div class="yellow_warn_box">
|
||||
<p>{{ _("Current Authentication method: \"None\"")}}</p>
|
||||
<p>{{ _("Service integrations require secure per-user storage. This is only possible with a user authentication method that is password protected (any method other than \"None\").") }}</p>
|
||||
<br/>
|
||||
<p>{{ _("Select a new method in:") }}<br/>
|
||||
<a class="btn" href="{{ url_for('settings_endpoint.auth', next=url_for('services_endpoint.choose')) }}">{{ _("Settings") }}</a></p>
|
||||
<p>{{ _("Select a new method in: ") }}
|
||||
<a class="btn inline-flex" href="{{ url_for('settings_endpoint.auth', next=url_for('services_endpoint.choose')) }}">{{ _("Settings") }}</a></p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="card center auto-width" data-style="min-width: 90%;">
|
||||
<hr>
|
||||
<h2>Plugins in Production</h2>
|
||||
<br>
|
||||
|
||||
<h3 class="mt-8 mb-3">Plugins in Production</h3>
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
{% for plugin in services %}
|
||||
{% if plugin.__class__.devstatus == "prod" %}
|
||||
{{ plugin_card(plugin.name, plugin.desc, url_for(plugin.id + '_endpoint' + '.static', filename=plugin.icon), url_for(plugin.id + '_endpoint' + '.index')) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% for plugin in services %}
|
||||
{% if plugin.__class__.devstatus == "prod" %}
|
||||
{{ plugin_card(plugin.name, plugin.desc, url_for(plugin.id + '_endpoint' + '.static', filename=plugin.icon), url_for(plugin.id + '_endpoint' + '.index')) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<h3 class="mt-8 mb-3">Plugins in Beta</h3>
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
{% for plugin in services %}
|
||||
{% if plugin.__class__.devstatus == "beta" %}
|
||||
{{ plugin_card(plugin.name, plugin.desc, url_for(plugin.id + '_endpoint' + '.static', filename=plugin.icon), url_for(plugin.id + '_endpoint' + '.index')) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{ plugin_card('Slush Pool', 'Import your mining rewards history', "https://github.com/kdmukai/slushpool-importer/raw/fc62445d9e1ac304cb7f0bc25ede9618bd9403dc/src/kdmukai/specterext/slushpool/static/slushpool/img/slushpool_icon.png", "https://github.com/kdmukai/slushpool-importer") }}
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<h2>Plugins in Beta</h2>
|
||||
<br>
|
||||
<h3 class="mt-8 mb-3">Plugins in Alpha</h3>
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
{% for plugin in services %}
|
||||
{% if plugin.__class__.devstatus == "alpha" %}
|
||||
{{ plugin_card(plugin.name, plugin.desc, url_for(plugin.id + '_endpoint' + '.static', filename=plugin.icon), url_for(plugin.id + '_endpoint' + '.index')) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{ plugin_card("Specter Dice", "Simulate Satoshi Dice on Regtest", "https://github.com/k9ert/specterext-dice/raw/v0.0.0-pre1/src/k9ert/specterext/dice/static/dice/dice_logo.png","https://github.com/k9ert/specterext-dice") }}
|
||||
{{ plugin_card('Spotbit', 'Price info service', "https://github.com/ahv15/spotbit/raw/spotbit-plugin/images/logos/spotbit_avatar.jpg", "https://github.com/ahv15/spotbit") }}
|
||||
{{ plugin_card('Warden', 'Portfolio tracker', "https://github.com/yogendra-17/specterext-warden/raw/20e834e32a533fd0693244efe3b2830a4cd1b79f/src/yogendra/specterext/warden/static/images/warden_square_logo.png", "https://github.com/yogendra-17/specterext-warden") }}
|
||||
</div>
|
||||
|
||||
{% for plugin in services %}
|
||||
{% if plugin.__class__.devstatus == "beta" %}
|
||||
{{ plugin_card(plugin.name, plugin.desc, url_for(plugin.id + '_endpoint' + '.static', filename=plugin.icon), url_for(plugin.id + '_endpoint' + '.index')) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<h3 class="mt-8 mb-3">Plugin Wishlist</h3>
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
{% include "services/components/wishlist.jinja" %}
|
||||
</div>
|
||||
|
||||
{{ plugin_card('Slush Pool', 'Import your mining rewards history', "https://github.com/kdmukai/slushpool-importer/raw/fc62445d9e1ac304cb7f0bc25ede9618bd9403dc/src/kdmukai/specterext/slushpool/static/slushpool/img/slushpool_icon.png", "https://github.com/kdmukai/slushpool-importer") }}
|
||||
|
||||
<hr>
|
||||
<h2>Plugins in Alpha</h2>
|
||||
<br>
|
||||
|
||||
{% for plugin in services %}
|
||||
{% if plugin.__class__.devstatus == "alpha" %}
|
||||
{{ plugin_card(plugin.name, plugin.desc, url_for(plugin.id + '_endpoint' + '.static', filename=plugin.icon), url_for(plugin.id + '_endpoint' + '.index')) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
{{ plugin_card("Specter Dice", "Simulate Satoshi Dice on Regtest", "https://github.com/k9ert/specterext-dice/raw/v0.0.0-pre1/src/k9ert/specterext/dice/static/dice/dice_logo.png","https://github.com/k9ert/specterext-dice") }}
|
||||
|
||||
{{ plugin_card('Spotbit', 'Price info service', "https://github.com/ahv15/spotbit/raw/spotbit-plugin/images/logos/spotbit_avatar.jpg", "https://github.com/ahv15/spotbit") }}
|
||||
|
||||
{{ plugin_card('Warden', 'Portfolio tracker', "https://github.com/yogendra-17/specterext-warden/raw/20e834e32a533fd0693244efe3b2830a4cd1b79f/src/yogendra/specterext/warden/static/images/warden_square_logo.png", "https://github.com/yogendra-17/specterext-warden") }}
|
||||
|
||||
<hr>
|
||||
<h2>Plugin Wishlist</h2>
|
||||
<br>
|
||||
|
||||
{% include "services/components/wishlist.jinja" %}
|
||||
|
||||
<div class="note endnote">
|
||||
<div class="mt-8">
|
||||
{{ _("Some plugins might not respect the Tor-only policy.") }}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
@ -1,14 +1,16 @@
|
|||
{% macro plugin_card(name, desc, img_url, external_url) -%}
|
||||
|
||||
<div class="inner-border" >
|
||||
<div class="plugin_container inner-border" {% if external_url.startswith("https://github") %}onclick="window.open('{{ external_url }}')" {% else %}onclick="location.href=`{{ external_url }}`"{% endif %} >
|
||||
<img src="{{ img_url }}" height="80px"><br/>
|
||||
{% if external_url.startswith("https://github") %}
|
||||
<a class="github-fork-ribbon" data-ribbon="Fork me on GitHub" title="Fork Me on GitHub"></a>
|
||||
{% endif %}
|
||||
<div class="plugin_name">{{ name }}</div>
|
||||
<div class="plugin_description">{{ desc }}</div>
|
||||
<div class="bg-dark-800 border-2 border-dark-700 cursor-pointer pt-3 rounded-xl p-4 flex items-center justify-start space-x-4 plugin_container inner-border" {% if external_url.startswith("https://github") %}onclick="window.open('{{ external_url }}')" {% else %}onclick="location.href=`{{ external_url }}`"{% endif %} >
|
||||
<img src="{{ img_url }}" class="w-12 h-12">
|
||||
|
||||
<div class="">
|
||||
<div class="plugin_name text-lg">{{ name }}</div>
|
||||
<div class="plugin_description text-sm">{{ desc }}</div>
|
||||
</div>
|
||||
|
||||
{% if external_url.startswith("https://github") %}
|
||||
<!-- <a class="github-fork-ribbon" data-ribbon="Fork me on GitHub" title="Fork Me on GitHub"></a> -->
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{%- endmacro %}
|
||||
{%- endmacro %}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
{% extends "wallet/components/wallet_tab.jinja" %}
|
||||
{% set tab = 'addresses' %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="table-holder">
|
||||
|
||||
{% include "includes/services-data.html" %}
|
||||
{% include "includes/hwi/hwi.jinja" %}
|
||||
{% include "includes/explorer-link.html" %}
|
||||
|
|
@ -19,7 +18,8 @@
|
|||
btc-unit="{{ specter.unit }}"
|
||||
hide-sensitive-info="{{ specter.hide_sensitive_info | lower }}"
|
||||
type="receive"
|
||||
wallet="{{ wallet.alias }}"></addresses-table>
|
||||
wallet="{{ wallet.alias }}">
|
||||
</addresses-table>
|
||||
</div>
|
||||
<div id="address-popup" class="hidden"></div>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -80,13 +80,13 @@
|
|||
<tr>
|
||||
<td data-style="display: flex;">
|
||||
<span>Immature:</span>
|
||||
<tool-tip width="200px">
|
||||
<h4 slot="title">{{ _("What are immature outputs?") }}</h4>
|
||||
<span slot="paragraph">
|
||||
{{ _('The UTXO of coinbase transactions (mining rewards) have the special condition that they cannot be spent for at least 100 blocks. Their amount is not included in the total balance here.') }}
|
||||
{% if specter.chain == "regtest" %}{{ _('You see these outputs because you are using regtest and have mined blocks.')}}{% endif %}
|
||||
</span>
|
||||
</tool-tip>
|
||||
<!-- <tool-tip width="200px"> -->
|
||||
<!-- <h4 slot="title">{{ _("What are immature outputs?") }}</h4> -->
|
||||
<!-- <span slot="paragraph"> -->
|
||||
<!-- {{ _('The UTXO of coinbase transactions (mining rewards) have the special condition that they cannot be spent for at least 100 blocks. Their amount is not included in the total balance here.') }} -->
|
||||
<!-- {% if specter.chain == "regtest" %}{{ _('You see these outputs because you are using regtest and have mined blocks.')}}{% endif %} -->
|
||||
<!-- </span> -->
|
||||
<!-- </tool-tip> -->
|
||||
<td class="right-align">{{ amount_immature | btcunitamount_fixed_decimals | safe }}</td>
|
||||
</td>
|
||||
<td>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
<h3>{{ _("Create Transaction") }}</h3>
|
||||
|
||||
<div>
|
||||
<div class="flex">
|
||||
<p>
|
||||
{{ _("Available funds:") }} {{wallet.amount_available | btcunitamount}}
|
||||
{% if specter.unit == 'sat' %}sats{% else %}{% if specter.is_testnet %}t{%endif%}{% if specter.is_liquid %}L{%endif%}BTC{% endif %}
|
||||
|
|
@ -59,13 +59,23 @@
|
|||
<div class="flex flex-col">
|
||||
<div id="recipients" class="mt-3 rounded-t-xl overflow-hidden {% if ui_option != 'ui' %}hidden{% else %} recipient_wrapper" {% endif %}></div>
|
||||
<div class="px-4 py-3 cursor-pointer hover:bg-dark-700 rounded-b-xl bg-dark-600 text-white mb-2" id="add-recipient" title="Add a recipient" class="recipient_button recipient_add" onclick="addRecipient('', '', 'btc', '')">+ Add Recipient</div>
|
||||
<!-- <img src="{{ url_for('static', filename='img/add-person.svg') }}" id="add-recipient" title="Add a recipient" class="recipient_button recipient_add" data-style="float:right" onclick="addRecipient('', '', 'btc', '')"> -->
|
||||
<div id="recipients-txt-container" {% if ui_option == 'ui' %}class="hidden"{% endif %}>
|
||||
{{ _("Unit:") }}
|
||||
<label><input type="radio" class="inline" data-style="margin: 0 5px;" name="amount_unit_text" value="sat" onchange="toggleTextUnit(this)" {% if specter.unit == 'sat' %}checked{% endif %}>sat</label>
|
||||
<label><input type="radio" class="inline" data-style="margin: 0 5px;" name="amount_unit_text" value="btc" onchange="toggleTextUnit(this)" {% if specter.unit != 'sat' %}checked{% endif %}>BTC</label>
|
||||
|
||||
<textarea id="recipients-txt" name="recipients" placeholder="{{ _('Enter recipient address, amount') }}" data-style="margin-top: 5px; font-size: 0.95em;" onblur="validateForm()">{{ recipients_txt }}</textarea>
|
||||
<div id="recipients-txt-container" {% if ui_option == 'ui' %}class="hidden"{% endif %}>
|
||||
<div class="flex justify-between my-2">
|
||||
<span class="text-base">Unit Selection</span>
|
||||
<div class="space-x-4 flex items-center">
|
||||
<label class="checkbox-wrapper-inline">
|
||||
<input type="radio" name="amount_unit_text" value="sat" onchange="toggleTextUnit(this)" {% if specter.unit == 'sat' %}checked{% endif %}>
|
||||
<span>sat</span>
|
||||
</label>
|
||||
<label class="checkbox-wrapper-inline">
|
||||
<input type="radio" name="amount_unit_text" value="btc" onchange="toggleTextUnit(this)" {% if specter.unit != 'sat' %}checked{% endif %}>
|
||||
<span>BTC</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<textarea id="recipients-txt" name="recipients" placeholder="{{ _('Enter recipient address, amount') }}" onblur="validateForm()">{{ recipients_txt }}</textarea>
|
||||
<p class="note" data-style="line-height: 2; background-color: #16202d; padding: 10px; border-radius: 7px;">
|
||||
{{ _("Enter each recipient address, amount as a new line:") }}<br>
|
||||
<{{ _("ADDRESS") }}1>, <{{ _("AMOUNT") }}1><br>
|
||||
|
|
@ -74,20 +84,26 @@
|
|||
</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<span id="calculated_tx_fee_label" onclick="calculateEstimatedFee()">{{ _("Calculate estimated fee") }}</span>
|
||||
<span id="calculated_tx_fee"></span>
|
||||
</p>
|
||||
|
||||
<span id="toggle_advanced">{{ _("Advanced") }} {% if show_advanced_settings %}▼{% else %}▶{% endif %}</span>
|
||||
<span class="cursor-pointer mt-3" id="toggle_advanced">{{ _("Advanced") }} {% if show_advanced_settings %}▼{% else %}▶{% endif %}</span>
|
||||
|
||||
<div id="advanced_settings" class="{% if not show_advanced_settings %}hidden{% endif %}">
|
||||
<div>{{ _("Transaction editor:") }}
|
||||
<label><input type="radio" class="inline" data-style="margin: 0 10px 0 20px;" name="ui_option" value="ui" onclick="toggleSendUIType(this)" {% if ui_option == 'ui' %}checked{% endif %} id="ui-radio-btn">UI</label>
|
||||
<label><input type="radio" class="inline" data-style="margin: 0 10px 0 20px;" name="ui_option" value="text" onclick="toggleSendUIType(this);" {% if ui_option != 'ui' %}checked{% endif %}>text</label>
|
||||
<h3 class="mt-5">{{ _("Transaction editor") }}</h3>
|
||||
<p class="mb-3">Select CSV to batch import several outputs for your transaction.</p>
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<label class="checkbox-wrapper">
|
||||
<input type="radio" class="checkbox-input peer" name="ui_option" value="ui" onclick="toggleSendUIType(this)" {% if ui_option == 'ui' %}checked{% endif %} id="ui-radio-btn">
|
||||
<span class="checkbox-label">Interface</span>
|
||||
</label>
|
||||
<label class="checkbox-wrapper">
|
||||
<input type="radio" class="peer checkbox-input" name="ui_option" value="text" onclick="toggleSendUIType(this);" {% if ui_option != 'ui' %}checked{% endif %}>
|
||||
<span>CSV</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<h3 class="mt-5">{{ _("Fee Selection") }}</h3>
|
||||
{% include "includes/fee-selection.html" %}
|
||||
<fee-selection id="fee-selection-component"></fee-selection>
|
||||
|
||||
<div class="row break-row-mobile" id="vertical-space-for-subtract-fees-from-amount-checkbox" data-style="margin-top: 0px;"></div>
|
||||
</div>
|
||||
|
||||
|
|
@ -97,14 +113,23 @@
|
|||
{% include "includes/tx-table.html" %}
|
||||
{% include "includes/coin_selection.html" %}
|
||||
|
||||
<coin-selection
|
||||
id="coinselection-webcomponent"
|
||||
wallet-alias="{{wallet.alias}}"
|
||||
spendable-amount='{{ wallet.full_available_balance | btcamount }}'
|
||||
is-liquid="{{specter.is_liquid}}"
|
||||
selected-coins="{{ selected_coins }}">
|
||||
</coin-selection>
|
||||
<button onclick="validateForm(true)" type="button" name="action" value="createpsbt" id="create_psbt_btn" class="self-end mt-8 button bg-accent text-white">{{ _('Create ')}}<span class="optional"> {{ _('unsigned')}} </span>{{ _('transaction') }}</button>
|
||||
<div class="mt-3">
|
||||
<coin-selection
|
||||
id="coinselection-webcomponent"
|
||||
wallet-alias="{{wallet.alias}}"
|
||||
spendable-amount='{{ wallet.full_available_balance | btcamount }}'
|
||||
is-liquid="{{specter.is_liquid}}"
|
||||
selected-coins="{{ selected_coins }}">
|
||||
</coin-selection>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-3 mt-8">
|
||||
<button class="button" onclick="calculateEstimatedFee()">
|
||||
<span id="calculated_tx_fee_label">{{ _("Calculate Estimated Fee") }}</span>
|
||||
<!-- <span id="calculated_tx_fee"></span> -->
|
||||
</button>
|
||||
<button onclick="validateForm(true)" type="button" name="action" value="createpsbt" id="create_psbt_btn" class="button bg-accent text-white">{{ _('Create ')}}<span class="optional"> {{ _('unsigned')}} </span>{{ _('transaction') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
@ -570,7 +595,7 @@
|
|||
}
|
||||
|
||||
async function calculateEstimatedFee() {
|
||||
document.getElementById('calculated_tx_fee').innerText = ``;
|
||||
document.getElementById('calculated_tx_fee_label').innerText = ``;
|
||||
if (await validateForm(true) !== true) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -584,22 +609,22 @@
|
|||
if (result.success) {
|
||||
let psbt = result.psbt;
|
||||
let fees = parseInt(psbt.fee * 1e8)
|
||||
document.getElementById('calculated_tx_fee').innerText = `: ${fees} sats`;
|
||||
document.getElementById('calculated_tx_fee_label').innerText = `: ${fees} sats`;
|
||||
if('{{ specter.price_check }}' == 'True'){
|
||||
let altRate = parseFloat('{{ specter.alt_rate }}');
|
||||
let altSymbol = '{{ specter.alt_symbol }}';
|
||||
let altAmount = parseFloat((altRate * fees / 1e8).toFixed(2))
|
||||
if (!isNaN(altAmount) && (altSymbol && altRate)) {
|
||||
document.getElementById('calculated_tx_fee').innerText = `: ${fees} sats (${altAmount}${altSymbol})`;
|
||||
document.getElementById('calculated_tx_fee_label').innerText = `: ${fees} sats (${altAmount}${altSymbol})`;
|
||||
}
|
||||
}
|
||||
return fees;
|
||||
} else {
|
||||
document.getElementById('calculated_tx_fee').innerText = `: ${result.error}`;
|
||||
document.getElementById('calculated_tx_fee_label').innerText = `: ${result.error}`;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
document.getElementById('calculated_tx_fee').innerText = `: {{ _("Failed to calculate transaction fees.") }}`;
|
||||
document.getElementById('calculated_tx_fee_label').innerText = `: {{ _("Failed to calculate transaction fees.") }}`;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,17 +35,17 @@
|
|||
{{ '{}/{}'.format(pending_psbt['sigs_count'], wallet.sigs_required) }}
|
||||
</td>
|
||||
<td width="170px">
|
||||
<div class="row">
|
||||
<div class="flex">
|
||||
<form action="{{ url_for('wallets_endpoint.send_pending',wallet_alias=wallet_alias) }}" method="POST">
|
||||
<input type="hidden" class="csrf-token" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||
<input type="hidden" name="pending_psbt" value='{{ pending_psbt|tojson|safe }}'>
|
||||
<button type="submit" name="action" value="openpsbt" class="btn" data-style="margin-right: 5px;">{{ _("Open") }}</button>
|
||||
<button type="submit" name="action" value="openpsbt" class="btn bg-dark-500">{{ _("Open") }}</button>
|
||||
</form>
|
||||
|
||||
<form action="{{ url_for('wallets_endpoint.send_pending',wallet_alias=wallet_alias) }}" method="POST">
|
||||
<input type="hidden" class="csrf-token" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||
<input type="hidden" name="pending_psbt" value='{{ pending_psbt|tojson|safe }}'>
|
||||
<button type="submit" name="action" value="deletepsbt" class="btn danger" data-style="margin-left: 5px;" onclick="javascript: form.action='./?pending=True';">{{ _("Delete") }}</button>
|
||||
<button type="submit" name="action" value="deletepsbt" class="btn bg-red-600" onclick="javascript: form.action='./?pending=True';">{{ _("Delete") }}</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
|
|
|
|||
|
|
@ -8,5 +8,5 @@
|
|||
<div class="table-holder">
|
||||
{% from 'wallet/send/pending/components/pending_psbt_table.jinja' import pending_psbt_table %}
|
||||
{{ pending_psbt_table(pending_psbts, wallet_alias, wallet, specter) }}
|
||||
</div><br>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -111,10 +111,10 @@
|
|||
<label for="showdetails" class="btn togglebtn">
|
||||
{{ _("transaction details") }}
|
||||
</label>
|
||||
<div class="toggle" id="tx_details" data-style="word-break: break-all;">
|
||||
<br>
|
||||
|
||||
<div class="hidden" id="tx_details" data-style="word-break: break-all;">
|
||||
<h2 class="tx_details_header">{{ _("Transaction Info") }}</h2>
|
||||
<p data-style="text-align: left; background-color: #131a24; padding: 10px; line-height: 2; border-radius: 15px;">
|
||||
<p>
|
||||
<b>{{ _("Total fee:") }}</b> {{ psbt['fee'] | btc2sat }} sats {% if specter.price_check %}<span class="note"> ({{ psbt['fee'] | altunit }})</span>{% endif %}<br>
|
||||
<b>{{ _("Fee rate:") }}</b>
|
||||
{% if 'tx_full_size' in psbt %}
|
||||
|
|
@ -176,21 +176,21 @@
|
|||
{% endfor %}
|
||||
{{ _("Raw PSBT:") }}<textarea id="raw-psbt" disabled data-style="background-color: #131a24;">{{ psbt['base64'] }}</textarea>
|
||||
<div class="row break-row-mobile" data-style="margin:auto">
|
||||
<a id="download-psbt-btn" class="btn"
|
||||
<a id="download-psbt-btn" class="button"
|
||||
download="binary_{{ psbt['tx']['hash'] }}.psbt" href="data:application/octet-stream;base64;content-disposition=attachment,{{ psbt['base64'] }}">
|
||||
<img src="{{ url_for('static', filename='img/file.svg') }}" data-style="width: 26px; margin: 0px;" class="svg-white">
|
||||
{{ _("Save binary") }}
|
||||
</a>
|
||||
<a id="download-psbt-btn" class="btn"
|
||||
<a id="download-psbt-btn" class="button"
|
||||
download="base64_{{ psbt['tx']['hash'] }}.psbt" href="data:text/plain;content-disposition=attachment,{{ psbt['base64'] }}">
|
||||
<img src="{{ url_for('static', filename='img/file.svg') }}" data-style="width: 26px; margin: 0px;" class="svg-white">
|
||||
{{ _("Save base64") }}
|
||||
</a>
|
||||
<a id="copy-raw-psbt-btn" class="btn">
|
||||
<a id="copy-raw-psbt-btn" class="button">
|
||||
<img src="{{ url_for('static', filename='img/copy.svg') }}" data-style="width: 26px; margin: 0px;" class="svg-white">
|
||||
{{ _("Copy Raw PSBT") }}
|
||||
</a>
|
||||
<a id="show-qr-psbt-btn" class="btn">
|
||||
<a id="show-qr-psbt-btn" class="button">
|
||||
<img src="{{ url_for('static', filename='img/qr-code.svg') }}" data-style="width: 26px; margin: 0px;" class="svg-white">
|
||||
{{ _("Show QR code") }}
|
||||
</a>
|
||||
|
|
@ -203,7 +203,7 @@
|
|||
{% for device in wallet.devices %}
|
||||
{% if device.type != "bitcoincore_watchonly" %}
|
||||
{% set device_signed = (device.alias in psbt.get("devices_signed")) %}
|
||||
<button type="button" class="btn signing-column-btn" id="{{ device.alias }}_tx_sign_btn" {% if device_signed %} disabled data-style="background-color:#303c49;" {% endif %}>
|
||||
<button type="button" class="button signing-column-btn" id="{{ device.alias }}_tx_sign_btn" {% if device_signed %} disabled data-style="background-color:#303c49;" {% endif %}>
|
||||
{{ device.name }} {% if device.alias in psbt.get('devices_signed',[]) %} (✔) {% endif %}
|
||||
</button>
|
||||
{% endif %}
|
||||
|
|
@ -218,24 +218,28 @@
|
|||
<div id="ready_container" class="output_option {% if not psbt['raw'] %}hidden{% endif %}">
|
||||
<p>{{ _("Transaction is ready to send") }} (✔)</p>
|
||||
<div class="output_option">
|
||||
<a class="btn centered" id="send_tx_btn">{{ _("Send transaction") }}</a>
|
||||
<a class="button bg-accent text-white" id="send_tx_btn">{{ _("Send Transaction") }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="paste_signed" class="output_option {% if psbt['raw'] %}hidden{% endif %}" data-style="margin-top:20px">
|
||||
<button type="button" onclick="showPageOverlay('paste-tx-popup')" class="btn centered" id="pastetx">{{ _("Paste signed transaction") }}</a>
|
||||
<button type="button" onclick="showPageOverlay('paste-tx-popup')" class="button centered" id="pastetx">{{ _("Paste signed transaction") }}</a>
|
||||
</div>
|
||||
<div class="hidden" id="paste-tx-popup">
|
||||
<h1>{{ _("Paste signed transaction") }}</h1>
|
||||
<input type="text" id="paste-tx-text" placeholder="{{ _('Paste your transaction here') }}">
|
||||
<br><br>
|
||||
<button type="button" onclick="currentSigningDevice = '';combine(document.getElementById('paste-tx-text').value);hidePageOverlay();document.getElementById('paste-tx-text').value='';" class="btn centered">{{ _("Confirm") }}</button>
|
||||
|
||||
<div class="hidden bg-dark-800 rounded-lg p-4" id="paste-tx-popup">
|
||||
<div class="flex justify-between mb-2">
|
||||
<h3 class="mb-0">{{ _("Paste signed transaction") }}</h3>
|
||||
<p class="m-0 cursor-pointer" onclick="hidePageOverlay()" class="cursor-pointer">Close</p>
|
||||
</div>
|
||||
<textarea type="text" class="mt-2" id="paste-tx-text" placeholder="{{ _('Paste your transaction here') }}"></textarea>
|
||||
<button class="mb-0 mt-2 button bg-accent text-white" type="button" onclick="currentSigningDevice = '';combine(document.getElementById('paste-tx-text').value);hidePageOverlay();document.getElementById('paste-tx-text').value='';">{{ _("Confirm") }}</button>
|
||||
</div>
|
||||
|
||||
{% include 'includes/overlay/broadcast_tx.jinja' %}
|
||||
|
||||
<div class="row padded">
|
||||
<input type="hidden" name="pending_psbt" value='{{psbt|tojson|safe}}'>
|
||||
<button id="deletepsbt_btn" type="submit" name="action" value="deletepsbt" class="btn danger centered" data-style="margin-left: 5px;">{{ _("Delete Transaction") }}</button>
|
||||
<button id="deletepsbt_btn" type="submit" name="action" value="deletepsbt" class="button danger centered" data-style="margin-left: 5px;">{{ _("Delete Transaction") }}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue