Send fund coin selection #406 (#422)

Send fund coin selection #406
pull/423/head
ShahanaFarooqui 4 years ago committed by GitHub
parent da4d163d35
commit 1409042275
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -15,5 +15,5 @@
<link rel="stylesheet" href="styles.7f0a84d9b012559f3600.css"></head> <link rel="stylesheet" href="styles.7f0a84d9b012559f3600.css"></head>
<body> <body>
<rtl-app></rtl-app> <rtl-app></rtl-app>
<script src="runtime.f85917275662fd535bb6.js" defer></script><script src="polyfills-es5.2ac0d98b22574ae745b1.js" nomodule defer></script><script src="polyfills.5ae721a6ae5ab597a53d.js" defer></script><script src="main.930629deff965c22cb1b.js" defer></script></body> <script src="runtime.2493904abb92f5d5f622.js" defer></script><script src="polyfills-es5.2ac0d98b22574ae745b1.js" nomodule defer></script><script src="polyfills.5ae721a6ae5ab597a53d.js" defer></script><script src="main.8a5e79e0326ca1db85cb.js" defer></script></body>
</html> </html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
!function(e){function r(r){for(var n,u,i=r[0],c=r[1],f=r[2],p=0,s=[];p<i.length;p++)u=i[p],Object.prototype.hasOwnProperty.call(o,u)&&o[u]&&s.push(o[u][0]),o[u]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(l&&l(r);s.length;)s.shift()();return a.push.apply(a,f||[]),t()}function t(){for(var e,r=0;r<a.length;r++){for(var t=a[r],n=!0,i=1;i<t.length;i++)0!==o[t[i]]&&(n=!1);n&&(a.splice(r--,1),e=u(u.s=t[0]))}return e}var n={},o={0:0},a=[];function u(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,u),t.l=!0,t.exports}u.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var a,i=document.createElement("script");i.charset="utf-8",i.timeout=120,u.nc&&i.setAttribute("nonce",u.nc),i.src=function(e){return u.p+""+({}[e]||e)+"."+{1:"9bb271dd8dffd2d994a5",6:"34493377e46c62128b7c",7:"4a00e92294df28ac9ca1",8:"5ad5f94d29aeaf5781a7"}[e]+".js"}(e);var c=new Error;a=function(r){i.onerror=i.onload=null,clearTimeout(f);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),a=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+a+")",c.name="ChunkLoadError",c.type=n,c.request=a,t[1](c)}o[e]=void 0}};var f=setTimeout((function(){a({type:"timeout",target:i})}),12e4);i.onerror=i.onload=a,document.head.appendChild(i)}return Promise.all(r)},u.m=e,u.c=n,u.d=function(e,r,t){u.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},u.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},u.t=function(e,r){if(1&r&&(e=u(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(u.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)u.d(t,n,(function(r){return e[r]}).bind(null,n));return t},u.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return u.d(r,"a",r),r},u.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},u.p="",u.oe=function(e){throw console.error(e),e};var i=window.webpackJsonp=window.webpackJsonp||[],c=i.push.bind(i);i.push=r,i=i.slice();for(var f=0;f<i.length;f++)r(i[f]);var l=c;t()}([]);

@ -1 +0,0 @@
!function(e){function r(r){for(var n,a,i=r[0],c=r[1],f=r[2],p=0,d=[];p<i.length;p++)a=i[p],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&d.push(o[a][0]),o[a]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(l&&l(r);d.length;)d.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++)0!==o[t[i]]&&(n=!1);n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={0:0},u=[];function a(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,i=document.createElement("script");i.charset="utf-8",i.timeout=120,a.nc&&i.setAttribute("nonce",a.nc),i.src=function(e){return a.p+""+({}[e]||e)+"."+{1:"9bb271dd8dffd2d994a5",6:"006d3904cf050331e88e",7:"4a00e92294df28ac9ca1",8:"977dd110c527ac6c88c5"}[e]+".js"}(e);var c=new Error;u=function(r){i.onerror=i.onload=null,clearTimeout(f);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var f=setTimeout((function(){u({type:"timeout",target:i})}),12e4);i.onerror=i.onload=u,document.head.appendChild(i)}return Promise.all(r)},a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,(function(r){return e[r]}).bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="",a.oe=function(e){throw console.error(e),e};var i=window.webpackJsonp=window.webpackJsonp||[],c=i.push.bind(i);i.push=r,i=i.slice();for(var f=0;f<i.length;f++)r(i[f]);var l=c;t()}([]);

@ -53,7 +53,7 @@ exports.onChainWithdraw = (req, res, next) => {
logger.error({fileName: 'OnChain', lineNum: 51, msg: 'OnChain Withdraw Error: ' + JSON.stringify(err)}); logger.error({fileName: 'OnChain', lineNum: 51, msg: 'OnChain Withdraw Error: ' + JSON.stringify(err)});
return res.status(500).json({ return res.status(500).json({
message: 'OnChain Withdraw Failed!', message: 'OnChain Withdraw Failed!',
error: err.error error: err
}); });
}); });
} }
@ -62,6 +62,7 @@ exports.getTransactions = (req, res, next) => {
options = common.getOptions(); options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/listFunds'; options.url = common.getSelLNServerUrl() + '/listFunds';
request(options).then((body) => { request(options).then((body) => {
if (body.outputs) { body.outputs = common.sortDescByStrKey(body.outputs, 'status'); }
res.status(200).json(body); res.status(200).json(body);
}).catch(errRes => { }).catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); let err = JSON.parse(JSON.stringify(errRes));

@ -7,43 +7,64 @@
<button tabindex="8" fxFlex="5" fxLayoutAlign="center" class="btn-close-x p-0" [mat-dialog-close]="false" default mat-button>X</button> <button tabindex="8" fxFlex="5" fxLayoutAlign="center" class="btn-close-x p-0" [mat-dialog-close]="false" default mat-button>X</button>
</mat-card-header> </mat-card-header>
<mat-card-content class="mt-5px"> <mat-card-content class="mt-5px">
<form fxLayout="row wrap" fxFlex="100" fxLayoutAlign="space-between start" class="padding-gap overflow-x-hidden" (submit)="onSendFunds()" (reset)="resetData()" #form="ngForm"> <form fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch" class="padding-gap overflow-x-hidden" (submit)="onSendFunds()" (reset)="resetData()" #form="ngForm">
<mat-form-field fxFlex="55"> <div fxLayout="row wrap" fxFlex="100" fxLayoutAlign="space-between start">
<input matInput autoFocus [(ngModel)]="transaction.address" placeholder="Bitcoin Address" tabindex="1" name="address" required #address="ngModel"> <mat-form-field fxFlex="55">
<mat-error *ngIf="!transaction.address">Bitcoin address is required.</mat-error> <input matInput autoFocus [(ngModel)]="transaction.address" placeholder="Bitcoin Address" tabindex="1" name="address" required #address="ngModel">
</mat-form-field> <mat-error *ngIf="!transaction.address">Bitcoin address is required.</mat-error>
<mat-form-field fxFlex="30"> </mat-form-field>
<input matInput [(ngModel)]="transaction.satoshis" placeholder="Amount" name="amount" type="number" step="100" min="0" tabindex="2" required #amount="ngModel"> <mat-form-field fxFlex="30">
<span matSuffix> {{selAmountUnit}} </span> <input matInput [(ngModel)]="transaction.satoshis" placeholder="Amount" name="amount" type="number" step="100" min="0" tabindex="2" required #amount="ngModel">
<mat-error *ngIf="!transaction.satoshis">Amount is required.</mat-error> <span matSuffix> {{selAmountUnit}} </span>
</mat-form-field> <mat-error *ngIf="!transaction.satoshis">Amount is required.</mat-error>
<mat-form-field fxFlex="10" fxLayoutAlign="start end"> </mat-form-field>
<mat-select [value]="selAmountUnit" tabindex="3" required name="amountUnit" (selectionChange)="onAmountUnitChange($event)"> <mat-form-field fxFlex="10" fxLayoutAlign="start end">
<mat-option *ngFor="let amountUnit of amountUnits" [value]="amountUnit">{{amountUnit}}</mat-option> <mat-select [value]="selAmountUnit" tabindex="3" required name="amountUnit" (selectionChange)="onAmountUnitChange($event)">
</mat-select> <mat-option *ngFor="let amountUnit of amountUnits" [value]="amountUnit">{{amountUnit}}</mat-option>
</mat-form-field>
<div fxFlex="60" fxLayoutAlign="space-between stretch" fxLayout="row wrap">
<mat-form-field fxFlex="48" fxLayoutAlign="start end">
<mat-select tabindex="6" placeholder="Fee Rate" [(value)]="transaction.feeRate" [disabled]="flgMinConf">
<mat-option *ngFor="let feeRateType of feeRateTypes" [value]="feeRateType.feeRateId">
{{feeRateType.feeRateType}}
</mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<div fxFlex="48" fxLayout="row" fxLayoutAlign="start center"> <div fxFlex="60" fxLayoutAlign="space-between stretch" fxLayout="row wrap">
<mat-checkbox fxFlex="2" tabindex="7" color="primary" [(ngModel)]="flgMinConf" (change)="transaction.feeRate=null" name="flgMinConf" fxLayoutAlign="stretch start" class="mr-2"></mat-checkbox> <mat-form-field fxFlex="48" fxLayoutAlign="start end">
<mat-form-field fxFlex="98"> <mat-select tabindex="6" placeholder="Fee Rate" [(value)]="transaction.feeRate" [disabled]="flgMinConf">
<input matInput [(ngModel)]="transaction.minconf" placeholder="Min Confirmation Blocks" type="number" name="blocks" step="1" min="0" tabindex="8" #blocks="ngModel" [required]="flgMinConf" [disabled]="!flgMinConf"> <mat-option *ngFor="let feeRateType of feeRateTypes" [value]="feeRateType.feeRateId">
<mat-error *ngIf="flgMinConf && !transaction.minconf">Min Confirmation Blocks is required.</mat-error> {{feeRateType.feeRateType}}
</mat-option>
</mat-select>
</mat-form-field> </mat-form-field>
<div fxFlex="48" fxLayout="row" fxLayoutAlign="start center">
<mat-checkbox fxFlex="2" tabindex="7" color="primary" [(ngModel)]="flgMinConf" (change)="transaction.feeRate=null" name="flgMinConf" fxLayoutAlign="stretch start" class="mr-2"></mat-checkbox>
<mat-form-field fxFlex="98">
<input matInput [(ngModel)]="transaction.minconf" placeholder="Min Confirmation Blocks" type="number" name="blocks" step="1" min="0" tabindex="8" #blocks="ngModel" [required]="flgMinConf" [disabled]="!flgMinConf">
<mat-error *ngIf="flgMinConf && !transaction.minconf">Min Confirmation Blocks is required.</mat-error>
</mat-form-field>
</div>
</div> </div>
</div> </div>
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between stretch">
<mat-expansion-panel fxLayout="column" fxFlex="100" class="flat-expansion-panel mt-2" expanded="false" (closed)="onAdvancedPanelToggle(true)" (opened)="onAdvancedPanelToggle(false)">
<mat-expansion-panel-header>
<mat-panel-title>
<span>{{advancedTitle}}</span>
</mat-panel-title>
</mat-expansion-panel-header>
<div fxLayout="column" fxFlex="100" fxLayoutAlign="start stretch">
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between center">
<mat-form-field fxFlex="30" fxLayoutAlign="start end">
<mat-select tabindex="8" placeholder="Coin Selection" (selectionChange)="onUTXOSelectionChange($event)" [(value)]="selUTXOs" multiple>
<mat-select-trigger>{{totalSelectedUTXOAmount | number}} Sats ({{selUTXOs.length > 1 ? selUTXOs.length + ' UTXOs' : '1 UTXO'}})</mat-select-trigger>
<mat-option *ngFor="let transaction of transactions" [value]="transaction">{{transaction.value | number}} Sats</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</mat-expansion-panel>
</div>
<div fxLayout="column" fxFlex="100" fxLayoutAlign="start stretch"></div> <div fxLayout="column" fxFlex="100" fxLayoutAlign="start stretch"></div>
<div fxFlex="100" class="alert alert-danger mt-1" *ngIf="sendFundError !== ''"> <div fxFlex="100" class="alert alert-danger mt-1" *ngIf="sendFundError !== ''">
<fa-icon [icon]="faExclamationTriangle" class="mr-1 alert-icon"></fa-icon> <fa-icon [icon]="faExclamationTriangle" class="mr-1 alert-icon"></fa-icon>
<span *ngIf="sendFundError !== ''">{{sendFundError}}</span> <span *ngIf="sendFundError !== ''">{{sendFundError}}</span>
</div> </div>
<div fxLayout="row" fxFlex="100" fxLayoutAlign="end center"> <div class="mt-2" fxLayout="row" fxFlex="100" fxLayoutAlign="end center">
<button class="mr-1" mat-stroked-button color="primary" tabindex="7" type="reset">Clear Fields</button> <button class="mr-1" mat-stroked-button color="primary" tabindex="7" type="reset">Clear Fields</button>
<button mat-flat-button color="primary" type="submit" tabindex="8">Send Funds</button> <button mat-flat-button color="primary" type="submit" tabindex="8">Send Funds</button>
</div> </div>

@ -1,6 +1,6 @@
import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
import { DecimalPipe } from '@angular/common'; import { DecimalPipe } from '@angular/common';
import { Subject } from 'rxjs'; import { Subject, combineLatest } from 'rxjs';
import { takeUntil, filter } from 'rxjs/operators'; import { takeUntil, filter } from 'rxjs/operators';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { Actions } from '@ngrx/effects'; import { Actions } from '@ngrx/effects';
@ -8,7 +8,7 @@ import { MatDialogRef } from '@angular/material/dialog';
import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons'; import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
import { SelNodeChild, GetInfoRoot } from '../../../shared/models/RTLconfig'; import { SelNodeChild, GetInfoRoot } from '../../../shared/models/RTLconfig';
import { GetInfo, Balance, OnChain } from '../../../shared/models/clModels'; import { GetInfo, Balance, OnChain, Transaction } from '../../../shared/models/clModels';
import { CURRENCY_UNITS, CurrencyUnitEnum, CURRENCY_UNIT_FORMATS, ADDRESS_TYPES, FEE_RATE_TYPES } from '../../../shared/services/consts-enums-functions'; import { CURRENCY_UNITS, CurrencyUnitEnum, CURRENCY_UNIT_FORMATS, ADDRESS_TYPES, FEE_RATE_TYPES } from '../../../shared/services/consts-enums-functions';
import { RTLConfiguration } from '../../../shared/models/RTLconfig'; import { RTLConfiguration } from '../../../shared/models/RTLconfig';
import { CommonService } from '../../../shared/services/common.service'; import { CommonService } from '../../../shared/services/common.service';
@ -30,6 +30,9 @@ export class CLOnChainSendComponent implements OnInit, OnDestroy {
public appConfig: RTLConfiguration; public appConfig: RTLConfiguration;
public nodeData: GetInfoRoot; public nodeData: GetInfoRoot;
public addressTypes = []; public addressTypes = [];
public transactions: Transaction[] = [];
public selUTXOs = [];
public totalSelectedUTXOAmount = 0;
public flgLoadingWallet: Boolean | 'error' = true; public flgLoadingWallet: Boolean | 'error' = true;
public selectedAddress = ADDRESS_TYPES[1]; public selectedAddress = ADDRESS_TYPES[1];
public blockchainBalance: Balance = {}; public blockchainBalance: Balance = {};
@ -45,24 +48,30 @@ export class CLOnChainSendComponent implements OnInit, OnDestroy {
public currConvertorRate = {}; public currConvertorRate = {};
public unitConversionValue = 0; public unitConversionValue = 0;
public currencyUnitFormats = CURRENCY_UNIT_FORMATS; public currencyUnitFormats = CURRENCY_UNIT_FORMATS;
public advancedTitle = 'Advanced Options';
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()]; private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(public dialogRef: MatDialogRef<CLOnChainSendComponent>, private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private commonService: CommonService, private decimalPipe: DecimalPipe, private actions$: Actions) {} constructor(public dialogRef: MatDialogRef<CLOnChainSendComponent>, private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private commonService: CommonService, private decimalPipe: DecimalPipe, private actions$: Actions) {}
ngOnInit() { ngOnInit() {
this.store.select('root') combineLatest(
this.store.select('root'),
this.store.select('cl'))
.pipe(takeUntil(this.unSubs[0])) .pipe(takeUntil(this.unSubs[0]))
.subscribe((rootStore) => { .subscribe(([rootStore, rtlStore]) => {
this.fiatConversion = rootStore.selNode.settings.fiatConversion; this.fiatConversion = rootStore.selNode.settings.fiatConversion;
this.amountUnits = rootStore.selNode.settings.currencyUnits; this.amountUnits = rootStore.selNode.settings.currencyUnits;
this.appConfig = rootStore.appConfig; this.appConfig = rootStore.appConfig;
this.nodeData = rootStore.nodeData; this.nodeData = rootStore.nodeData;
this.transactions = this.commonService.sortAscByKey(rtlStore.transactions.filter(tran => tran.status === 'confirmed'), 'value');
this.logger.info(rootStore); this.logger.info(rootStore);
this.logger.info(rtlStore);
}); });
this.actions$.pipe(takeUntil(this.unSubs[1]), this.actions$.pipe(takeUntil(this.unSubs[1]),
filter(action => action.type === CLActions.EFFECT_ERROR_CL || action.type === CLActions.SET_CHANNEL_TRANSACTION_RES_CL)) filter(action => action.type === CLActions.EFFECT_ERROR_CL || action.type === CLActions.SET_CHANNEL_TRANSACTION_RES_CL))
.subscribe((action: CLActions.EffectError | CLActions.SetChannelTransactionRes) => { .subscribe((action: CLActions.EffectError | CLActions.SetChannelTransactionRes) => {
if (action.type === CLActions.SET_CHANNEL_TRANSACTION_RES_CL) { if (action.type === CLActions.SET_CHANNEL_TRANSACTION_RES_CL) {
this.store.dispatch(new CLActions.FetchTransactions());
this.store.dispatch(new RTLActions.OpenSnackBar('Fund Sent Successfully!')); this.store.dispatch(new RTLActions.OpenSnackBar('Fund Sent Successfully!'));
this.dialogRef.close(); this.dialogRef.close();
} }
@ -76,6 +85,10 @@ export class CLOnChainSendComponent implements OnInit, OnDestroy {
onSendFunds() { onSendFunds() {
if(this.invalidValues) { return true; } if(this.invalidValues) { return true; }
this.sendFundError = ''; this.sendFundError = '';
if (this.selUTXOs.length && this.selUTXOs.length > 0) {
this.transaction.utxos = [];
this.selUTXOs.forEach(utxo => this.transaction.utxos.push(utxo.txid + ':' + utxo.output));
}
this.store.dispatch(new RTLActions.OpenSpinner('Sending Funds...')); this.store.dispatch(new RTLActions.OpenSpinner('Sending Funds...'));
if(this.transaction.satoshis && this.selAmountUnit !== CurrencyUnitEnum.SATS) { if(this.transaction.satoshis && this.selAmountUnit !== CurrencyUnitEnum.SATS) {
this.commonService.convertCurrency(this.transaction.satoshis, this.selAmountUnit === this.amountUnits[2] ? CurrencyUnitEnum.OTHER : this.selAmountUnit, this.amountUnits[2], this.fiatConversion) this.commonService.convertCurrency(this.transaction.satoshis, this.selAmountUnit === this.amountUnits[2] ? CurrencyUnitEnum.OTHER : this.selAmountUnit, this.amountUnits[2], this.fiatConversion)
@ -100,6 +113,15 @@ export class CLOnChainSendComponent implements OnInit, OnDestroy {
this.sendFundError = ''; this.sendFundError = '';
this.transaction = {}; this.transaction = {};
this.flgMinConf = false; this.flgMinConf = false;
this.totalSelectedUTXOAmount = 0;
this.selUTXOs = [];
}
onUTXOSelectionChange(event: any) {
let utxoNew = {value: 0};
if (this.selUTXOs.length && this.selUTXOs.length > 0) {
this.totalSelectedUTXOAmount = this.selUTXOs.reduce((a, b) => {utxoNew.value = a.value + b.value; return utxoNew;}).value;
}
} }
onAmountUnitChange(event: any) { onAmountUnitChange(event: any) {
@ -116,6 +138,14 @@ export class CLOnChainSendComponent implements OnInit, OnDestroy {
this.selAmountUnit = event.value; this.selAmountUnit = event.value;
} }
onAdvancedPanelToggle(isClosed: boolean) {
if (isClosed) {
this.advancedTitle = (this.selUTXOs.length && this.selUTXOs.length > 0) ? 'Advanced Options | Selected UTXOs: ' + this.selUTXOs.length + ' | Total Amount: ' + this.decimalPipe.transform(this.totalSelectedUTXOAmount) + ' Sats' : 'Advanced Options';
} else {
this.advancedTitle = 'Advanced Options';
}
}
ngOnDestroy() { ngOnDestroy() {
this.unSubs.forEach(completeSub => { this.unSubs.forEach(completeSub => {
completeSub.next(); completeSub.next();

@ -109,6 +109,7 @@ export interface OnChain {
satoshis?: number; satoshis?: number;
feeRate?: string; feeRate?: string;
minconf?: number; minconf?: number;
utxos?: string[];
} }
export interface Hop { export interface Hop {

@ -32,6 +32,14 @@ export class CommonService implements OnInit {
}); });
} }
sortAscByKey(array, key) {
return array.sort(function (a, b) {
const x = +a[key];
const y = +b[key];
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
});
}
camelCase(str) { camelCase(str) {
return str.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => { return str.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => {
return index == 0 ? word.toLowerCase() : word.toUpperCase(); return index == 0 ? word.toLowerCase() : word.toUpperCase();

Loading…
Cancel
Save