Added script-path address creation
This commit is contained in:
parent
13fd4bb6e3
commit
aea2979bee
51
css/main.css
51
css/main.css
@ -1051,15 +1051,41 @@ body.loaded .nav-item__indicator {
|
|||||||
border: solid thin rgba(var(--text-color), 0.3);
|
border: solid thin rgba(var(--text-color), 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#creation_menu {
|
||||||
|
display: grid;
|
||||||
|
grid-area: 0.5rem;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
.primary-action {
|
.primary-action {
|
||||||
padding: 0.6rem 0.8rem 0.6rem 0.6rem;
|
display: grid;
|
||||||
gap: 0.5rem;
|
grid-template-columns: auto 1fr;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: max(1rem, 1.5vw);
|
||||||
|
gap: 0.5rem 1rem;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
font-size: 0.9rem;
|
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border: thin solid rgba(var(--accent-color-rgb), 0.2);
|
border: thin solid rgba(var(--accent-color-rgb), 0.2);
|
||||||
text-align: start;
|
text-align: start;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.primary-action .icon {
|
||||||
|
height: 1.5rem;
|
||||||
|
width: 1.5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
grid-row: 1/3;
|
||||||
|
}
|
||||||
|
.primary-action h4 {
|
||||||
|
grid-column: 2;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
.primary-action p {
|
||||||
|
grid-column: 2;
|
||||||
|
font-weight: 400;
|
||||||
|
color: rgba(var(--text-color), 0.8);
|
||||||
|
margin-bottom: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#flo_id_warning {
|
#flo_id_warning {
|
||||||
@ -1293,16 +1319,22 @@ body.loaded .nav-item__indicator {
|
|||||||
#main_card:not(.nav-hidden) {
|
#main_card:not(.nav-hidden) {
|
||||||
grid-template-columns: auto 1fr;
|
grid-template-columns: auto 1fr;
|
||||||
grid-template-rows: auto 1fr;
|
grid-template-rows: auto 1fr;
|
||||||
grid-template-areas: "nav header" "nav .";
|
grid-template-areas: "header header" "nav .";
|
||||||
}
|
}
|
||||||
#main_header {
|
#main_header {
|
||||||
grid-area: header;
|
grid-area: header;
|
||||||
|
border-bottom: solid thin rgba(var(--text-color), 0.2);
|
||||||
|
padding: 0.8rem 1rem;
|
||||||
|
}
|
||||||
|
#main_header .app-brand {
|
||||||
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
#main_navbar {
|
#main_navbar {
|
||||||
grid-area: nav;
|
grid-area: nav;
|
||||||
border-top: none;
|
border-top: none;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background-color: rgba(37, 110, 255, 0.03);
|
background-color: transparent;
|
||||||
|
border-right: solid thin rgba(var(--text-color), 0.2);
|
||||||
}
|
}
|
||||||
#main_navbar ul {
|
#main_navbar ul {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -1313,6 +1345,7 @@ body.loaded .nav-item__indicator {
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
padding: 0.8rem 1rem 0.8rem 0.5rem;
|
padding: 0.8rem 1rem 0.8rem 0.5rem;
|
||||||
|
min-width: 10rem;
|
||||||
}
|
}
|
||||||
.nav-item__indicator {
|
.nav-item__indicator {
|
||||||
width: 0.25rem;
|
width: 0.25rem;
|
||||||
@ -1321,9 +1354,6 @@ body.loaded .nav-item__indicator {
|
|||||||
border-radius: 0 1rem 1rem 0;
|
border-radius: 0 1rem 1rem 0;
|
||||||
bottom: auto;
|
bottom: auto;
|
||||||
}
|
}
|
||||||
body[data-theme=dark] #main_navbar {
|
|
||||||
background-color: rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
|
||||||
#transactions_list {
|
#transactions_list {
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
@ -1335,7 +1365,7 @@ body.loaded .nav-item__indicator {
|
|||||||
#increase_fee_popup {
|
#increase_fee_popup {
|
||||||
--width: 30rem;
|
--width: 30rem;
|
||||||
}
|
}
|
||||||
#generate_address_popup,
|
#generate_key_path_address_popup,
|
||||||
#convert_to_taproot_popup {
|
#convert_to_taproot_popup {
|
||||||
--width: min(36rem, 100%);
|
--width: min(36rem, 100%);
|
||||||
}
|
}
|
||||||
@ -1359,6 +1389,9 @@ body.loaded .nav-item__indicator {
|
|||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
|
#generate_script_path_address_popup {
|
||||||
|
--width: 36rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@media only screen and (min-width: 1280px) {
|
@media only screen and (min-width: 1280px) {
|
||||||
.page {
|
.page {
|
||||||
|
|||||||
2
css/main.min.css
vendored
2
css/main.min.css
vendored
File diff suppressed because one or more lines are too long
@ -983,16 +983,40 @@ body.loaded .nav-item {
|
|||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
border: solid thin rgba(var(--text-color), 0.3);
|
border: solid thin rgba(var(--text-color), 0.3);
|
||||||
}
|
}
|
||||||
|
#creation_menu {
|
||||||
|
display: grid;
|
||||||
|
grid-area: 0.5rem;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
|
||||||
|
}
|
||||||
.primary-action {
|
.primary-action {
|
||||||
padding: 0.6rem 0.8rem 0.6rem 0.6rem;
|
display: grid;
|
||||||
gap: 0.5rem;
|
grid-template-columns: auto 1fr;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: max(1rem, 1.5vw);
|
||||||
|
gap: 0.5rem 1rem;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
font-size: 0.9rem;
|
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border: thin solid rgba(var(--accent-color-rgb), 0.2);
|
border: thin solid rgba(var(--accent-color-rgb), 0.2);
|
||||||
text-align: start;
|
text-align: start;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
.icon {
|
||||||
|
height: 1.5rem;
|
||||||
|
width: 1.5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
grid-row: 1/3;
|
||||||
|
}
|
||||||
|
h4 {
|
||||||
|
grid-column: 2;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
grid-column: 2;
|
||||||
|
font-weight: 400;
|
||||||
|
color: rgba(var(--text-color), 0.8);
|
||||||
|
margin-bottom: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#flo_id_warning {
|
#flo_id_warning {
|
||||||
padding-bottom: 1.5rem;
|
padding-bottom: 1.5rem;
|
||||||
@ -1196,7 +1220,7 @@ body.loaded .nav-item {
|
|||||||
&:not(.nav-hidden) {
|
&:not(.nav-hidden) {
|
||||||
grid-template-columns: auto 1fr;
|
grid-template-columns: auto 1fr;
|
||||||
grid-template-rows: auto 1fr;
|
grid-template-rows: auto 1fr;
|
||||||
grid-template-areas: "nav header" "nav .";
|
grid-template-areas: "header header" "nav .";
|
||||||
}
|
}
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -1205,12 +1229,18 @@ body.loaded .nav-item {
|
|||||||
}
|
}
|
||||||
#main_header {
|
#main_header {
|
||||||
grid-area: header;
|
grid-area: header;
|
||||||
|
border-bottom: solid thin rgba(var(--text-color), 0.2);
|
||||||
|
padding: 0.8rem 1rem;
|
||||||
|
.app-brand {
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#main_navbar {
|
#main_navbar {
|
||||||
grid-area: nav;
|
grid-area: nav;
|
||||||
border-top: none;
|
border-top: none;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background-color: rgba(37 110 255/ 0.03);
|
background-color: transparent;
|
||||||
|
border-right: solid thin rgba(var(--text-color), 0.2);
|
||||||
ul {
|
ul {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
@ -1221,6 +1251,7 @@ body.loaded .nav-item {
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
padding: 0.8rem 1rem 0.8rem 0.5rem;
|
padding: 0.8rem 1rem 0.8rem 0.5rem;
|
||||||
|
min-width: 10rem;
|
||||||
&__indicator {
|
&__indicator {
|
||||||
width: 0.25rem;
|
width: 0.25rem;
|
||||||
height: 50%;
|
height: 50%;
|
||||||
@ -1229,11 +1260,6 @@ body.loaded .nav-item {
|
|||||||
bottom: auto;
|
bottom: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
body[data-theme="dark"] {
|
|
||||||
#main_navbar {
|
|
||||||
background-color: rgba(0 0 0/ 0.2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#transactions_list {
|
#transactions_list {
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
@ -1245,7 +1271,7 @@ body.loaded .nav-item {
|
|||||||
#increase_fee_popup {
|
#increase_fee_popup {
|
||||||
--width: 30rem;
|
--width: 30rem;
|
||||||
}
|
}
|
||||||
#generate_address_popup,
|
#generate_key_path_address_popup,
|
||||||
#convert_to_taproot_popup {
|
#convert_to_taproot_popup {
|
||||||
--width: min(36rem, 100%);
|
--width: min(36rem, 100%);
|
||||||
}
|
}
|
||||||
@ -1270,6 +1296,9 @@ body.loaded .nav-item {
|
|||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
|
#generate_script_path_address_popup {
|
||||||
|
--width: 36rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@media only screen and (min-width: 1280px) {
|
@media only screen and (min-width: 1280px) {
|
||||||
.page {
|
.page {
|
||||||
|
|||||||
231
index.html
231
index.html
@ -94,10 +94,23 @@
|
|||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#/create" class="nav-item interactive">
|
||||||
|
<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="M13 7h-2v4H7v2h4v4h2v-4h4v-2h-4V7zm-1-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z" />
|
||||||
|
</svg>
|
||||||
|
<span class="nav-item__title">
|
||||||
|
Create
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</main>
|
</main>
|
||||||
<sm-popup id="generate_address_popup">
|
<sm-popup id="generate_key_path_address_popup">
|
||||||
<header slot="header" class="popup__header">
|
<header slot="header" class="popup__header">
|
||||||
<div class="flex align-center">
|
<div class="flex align-center">
|
||||||
<button class="popup__header__close" onclick="closePopup()">
|
<button class="popup__header__close" onclick="closePopup()">
|
||||||
@ -123,6 +136,21 @@
|
|||||||
<div id="generated_btc_addr" class="generated-id-card"></div>
|
<div id="generated_btc_addr" class="generated-id-card"></div>
|
||||||
</div>
|
</div>
|
||||||
</sm-popup>
|
</sm-popup>
|
||||||
|
<sm-popup id="generate_script_path_address_popup">
|
||||||
|
<header slot="header" class="popup__header">
|
||||||
|
<div class="flex align-center">
|
||||||
|
<button class="popup__header__close" onclick="closePopup()">
|
||||||
|
<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="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div id="generate_script_path_address_popup__content"></div>
|
||||||
|
</sm-popup>
|
||||||
<sm-popup id="convert_to_taproot_popup">
|
<sm-popup id="convert_to_taproot_popup">
|
||||||
<header slot="header" class="popup__header">
|
<header slot="header" class="popup__header">
|
||||||
<div class="flex align-center">
|
<div class="flex align-center">
|
||||||
@ -251,19 +279,86 @@
|
|||||||
|
|
||||||
document.addEventListener('popupopened', e => {
|
document.addEventListener('popupopened', e => {
|
||||||
switch (e.target.id) {
|
switch (e.target.id) {
|
||||||
case 'generate_address_popup':
|
case 'generate_key_path_address_popup': {
|
||||||
const { wif, tr: { address } } = getTaprootAddress()
|
const { wif, tr: { address } } = getTaprootAddress()
|
||||||
renderElem(getRef('generated_btc_addr'), html`
|
renderElem(getRef('generated_btc_addr'), html`
|
||||||
<div>
|
<div>
|
||||||
<h5>BTC Address</h5>
|
<h5>BTC Address</h5>
|
||||||
<sm-copy value="${address}"></sm-copy>
|
<sm-copy value="${address}"></sm-copy>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h5>Private Key</h5>
|
<h5>Private Key</h5>
|
||||||
<sm-copy value="${wif}"></sm-copy>
|
<sm-copy value="${wif}"></sm-copy>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case 'generate_script_path_address_popup': {
|
||||||
|
const { wif, tr: { address } } = getTaprootAddress()
|
||||||
|
const privateKey = coinjs.wif2privkey(wif).privkey
|
||||||
|
console.log(wif, address)
|
||||||
|
const scriptInputs = [1];
|
||||||
|
const renderScriptInput = (index) => html`
|
||||||
|
<div class="flex gap-0-5">
|
||||||
|
<sm-input class="member-script-input flex-1" placeholder=${`Member script #${index + 1} (Hex)`} pattern="^[0-9A-Fa-f]+$" error-text="Only hexadecimal values are allowed" animate required></sm-input>
|
||||||
|
${index ? html`
|
||||||
|
<button class="button button--danger" onclick=${() => removeScriptInput(index)} title="Remove">
|
||||||
|
<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="M16 9v10H8V9h8m-1.5-6h-5l-1 1H5v2h14V4h-3.5l-1-1zM18 7H6v12c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7z"/></svg>
|
||||||
|
</button>
|
||||||
|
`: ''}
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
function addMemberScriptInput() {
|
||||||
|
scriptInputs.push(scriptInputs.length + 1)
|
||||||
|
renderScriptInputList()
|
||||||
|
}
|
||||||
|
function removeScriptInput(index) {
|
||||||
|
scriptInputs.splice(index, 1)
|
||||||
|
renderScriptInputList()
|
||||||
|
}
|
||||||
|
function generateScriptPathAddress() {
|
||||||
|
const schnorrPublicKey = secp256k1_schnorr.getPublicKey(hex.decode(privateKey));
|
||||||
|
const taprootTree = [...document.querySelectorAll('.member-script-input')].map(input => {
|
||||||
|
return {
|
||||||
|
script: input.value.trim(),
|
||||||
|
leafVersion: 0xc0,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const { address } = taproot.p2tr(
|
||||||
|
schnorrPublicKey,
|
||||||
|
taprootTree,
|
||||||
|
undefined,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
renderElem(getRef('generate_script_path_address_popup__content'), html`
|
||||||
|
<div class="grid gap-1">
|
||||||
|
<h4>Generated Taproot script-path address</h4>
|
||||||
|
<sm-copy value="${address}"></sm-copy>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
function renderScriptInputList() {
|
||||||
|
renderElem(getRef('generate_script_path_address_popup__content'), html`
|
||||||
|
<sm-form>
|
||||||
|
<div class="grid gap-1">
|
||||||
|
<h4>Add member scripts</h4>
|
||||||
|
<div id="member_input_container" class="grid gap-0-5">
|
||||||
|
${scriptInputs.map((no, index) => renderScriptInput(index))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-0-5">
|
||||||
|
<button class="button button--colored margin-right-auto" onclick=${addMemberScriptInput}>
|
||||||
|
Add member
|
||||||
|
</button>
|
||||||
|
<button id="create_script_path_address_button" class="button button--primary flex-1" onclick=${generateScriptPathAddress} type="submit" disabled>Create</button>
|
||||||
|
</div>
|
||||||
|
</sm-form>
|
||||||
|
`);
|
||||||
|
getRef('create_script_path_address_button').scrollIntoView({ behavior: 'smooth' })
|
||||||
|
}
|
||||||
|
renderScriptInputList()
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
document.addEventListener('popupclosed', e => {
|
document.addEventListener('popupclosed', e => {
|
||||||
@ -1170,6 +1265,9 @@
|
|||||||
const { page } = state
|
const { page } = state
|
||||||
if (!page)
|
if (!page)
|
||||||
page = 'search'
|
page = 'search'
|
||||||
|
if (page !== 'send') {
|
||||||
|
taprootScriptTxDetails = {}
|
||||||
|
}
|
||||||
const previousTarget = getRef('main_navbar').querySelector('.nav-item--active')
|
const previousTarget = getRef('main_navbar').querySelector('.nav-item--active')
|
||||||
if (previousTarget) {
|
if (previousTarget) {
|
||||||
previousTarget.classList.remove('nav-item--active')
|
previousTarget.classList.remove('nav-item--active')
|
||||||
@ -1201,20 +1299,6 @@
|
|||||||
<svg slot="icon" 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> <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path> </svg>
|
<svg slot="icon" 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> <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path> </svg>
|
||||||
</button>
|
</button>
|
||||||
</sm-form>
|
</sm-form>
|
||||||
<menu class="flex gap-0-5">
|
|
||||||
<li>
|
|
||||||
<button class="button button--colored primary-action" onclick="openPopup('generate_address_popup')">
|
|
||||||
<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 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z" /> </svg>
|
|
||||||
Create new address
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<button class="button button--colored primary-action" onclick="openPopup('convert_to_taproot_popup')">
|
|
||||||
<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="M6.99 11L3 15l3.99 4v-3H14v-2H6.99v-3zM21 9l-3.99-4v3H10v2h7.01v3L21 9z" /> </svg>
|
|
||||||
Retrieve Taproot address
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
</menu>
|
|
||||||
<div id="address_details" class="hidden flex flex-direction-column gap-1">
|
<div id="address_details" class="hidden flex flex-direction-column gap-1">
|
||||||
<div id="address_balance_card" class="grid gap-1 hidden">
|
<div id="address_balance_card" class="grid gap-1 hidden">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
@ -1357,6 +1441,7 @@
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
taprootScriptTxDetails = {}
|
||||||
form = html`
|
form = html`
|
||||||
<sm-form id="send_tx_form" onvalid=${() => calculateSuggestedFee('key-path')} oninvalid=${handleInvalidForm} ?skip-submit=${feeType() === 'suggested'}>
|
<sm-form id="send_tx_form" onvalid=${() => calculateSuggestedFee('key-path')} oninvalid=${handleInvalidForm} ?skip-submit=${feeType() === 'suggested'}>
|
||||||
<fieldset class="flex flex-direction-column gap-0-5">
|
<fieldset class="flex flex-direction-column gap-0-5">
|
||||||
@ -2068,6 +2153,33 @@
|
|||||||
buttonLoader(document.getElementById('increase_fee'), false)
|
buttonLoader(document.getElementById('increase_fee'), false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
router.addRoute('create', state => {
|
||||||
|
renderElem(getRef('page_container'), html`
|
||||||
|
<menu id="creation_menu" class="flex gap-0-5">
|
||||||
|
<li>
|
||||||
|
<button class="button button--colored primary-action" onclick="openPopup('generate_key_path_address_popup')">
|
||||||
|
<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 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z" /> </svg>
|
||||||
|
<h4> Create key-path address </h4>
|
||||||
|
<p> Generates a Taproot address and private key pair </p>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button class="button button--colored primary-action" onclick="openPopup('generate_script_path_address_popup')">
|
||||||
|
<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 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z" /> </svg>
|
||||||
|
<h4> Create script-path address </h4>
|
||||||
|
<p> Generates a Taproot address with given member scripts </p>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button class="button button--colored primary-action" onclick="openPopup('convert_to_taproot_popup')">
|
||||||
|
<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="M6.99 11L3 15l3.99 4v-3H14v-2H6.99v-3zM21 9l-3.99-4v3H10v2h7.01v3L21 9z" /> </svg>
|
||||||
|
<h4>Retrieve Taproot address</h4>
|
||||||
|
<p>Get Taproot address corresponding to given BTC private key</p>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</menu>
|
||||||
|
`)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
const DUST_AMT = 546,
|
const DUST_AMT = 546,
|
||||||
@ -2322,73 +2434,8 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<!-- 029000b275209997a497d964fc1a62885b05a51166a65a90df00492c8d7cf61d6accf54803beac -->
|
||||||
<script>
|
<!-- a8206c60f404f8167a38fc70eaf8aa17ac351023bef86bcb9d1086a19afe95bd533388204edfcf9dfe6c0b5c83d1ab3f78d1b39a46ebac6798e08e19761f5ed89ec83c10ac -->
|
||||||
keyPairFromSecret = (hexSecretKey) => {
|
|
||||||
const secretKey = hex.decode(hexSecretKey);
|
|
||||||
const schnorrPublicKey = secp256k1_schnorr.getPublicKey(secretKey);
|
|
||||||
return {
|
|
||||||
schnorrPublicKey,
|
|
||||||
secretKey,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
// generate new private key
|
|
||||||
internalKeyPair = keyPairFromSecret(
|
|
||||||
'1229101a0fcf2104e8808dab35661134aa5903867d44deb73ce1c7e4eb925be8'
|
|
||||||
);
|
|
||||||
|
|
||||||
preimage = hashmini.sha256(
|
|
||||||
hex.decode('107661134f21fc7c02223d50ab9eb3600bc3ffc3712423a1e47bb1f9a9dbf55f')
|
|
||||||
);
|
|
||||||
|
|
||||||
aliceKeyPair = keyPairFromSecret(
|
|
||||||
'2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90'
|
|
||||||
);
|
|
||||||
|
|
||||||
bobKeyPair = keyPairFromSecret(
|
|
||||||
'81b637d8fcd2c6da6359e6963113a1170de795e4b725b84d1e0b4cfd9ec58ce9'
|
|
||||||
);
|
|
||||||
|
|
||||||
scriptAlice = new Uint8Array([
|
|
||||||
0x02,
|
|
||||||
144,
|
|
||||||
0x00,
|
|
||||||
btc.OP.CHECKSEQUENCEVERIFY,
|
|
||||||
btc.OP.DROP,
|
|
||||||
0x20,
|
|
||||||
...aliceKeyPair.schnorrPublicKey,
|
|
||||||
0xac,
|
|
||||||
]);
|
|
||||||
|
|
||||||
scriptBob = new Uint8Array([
|
|
||||||
btc.OP.SHA256,
|
|
||||||
0x20,
|
|
||||||
...preimage,
|
|
||||||
btc.OP.EQUALVERIFY,
|
|
||||||
0x20,
|
|
||||||
...bobKeyPair.schnorrPublicKey,
|
|
||||||
0xac,
|
|
||||||
]);
|
|
||||||
|
|
||||||
taprootTree = btc.taprootListToTree([
|
|
||||||
{
|
|
||||||
script: scriptAlice,
|
|
||||||
leafVersion: 0xc0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
script: scriptBob,
|
|
||||||
leafVersion: 0xc0,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
|
|
||||||
taprootCommitment = btc.p2tr(
|
|
||||||
internalKeyPair.schnorrPublicKey,
|
|
||||||
taprootTree,
|
|
||||||
undefined,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
Loading…
Reference in New Issue
Block a user