parent
5421631d12
commit
125099fe08
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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
!function(e){function r(r){for(var n,a,i=r[0],f=r[1],c=r[2],p=0,s=[];p<i.length;p++)o[a=i[p]]&&s.push(o[a][0]),o[a]=0;for(n in f)Object.prototype.hasOwnProperty.call(f,n)&&(e[n]=f[n]);for(l&&l(r);s.length;)s.shift()();return u.push.apply(u,c||[]),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:"180f16dffe826f0afab2",6:"ed6f619a753cd468a3f1",7:"3b3d365a0c96df4907d8"}[e]+".js"}(e);var f=new Error;u=function(r){i.onerror=i.onload=null,clearTimeout(c);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;f.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",f.name="ChunkLoadError",f.type=n,f.request=u,t[1](f)}o[e]=void 0}};var c=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||[],f=i.push.bind(i);i.push=r,i=i.slice();for(var c=0;c<i.length;c++)r(i[c]);var l=f;t()}([]);
|
||||
!function(e){function r(r){for(var n,a,i=r[0],f=r[1],c=r[2],p=0,s=[];p<i.length;p++)o[a=i[p]]&&s.push(o[a][0]),o[a]=0;for(n in f)Object.prototype.hasOwnProperty.call(f,n)&&(e[n]=f[n]);for(l&&l(r);s.length;)s.shift()();return u.push.apply(u,c||[]),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:"180f16dffe826f0afab2",6:"6461d7eefa28dc4efa39",7:"84ad670c3bfef8117d18"}[e]+".js"}(e);var f=new Error;u=function(r){i.onerror=i.onload=null,clearTimeout(c);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;f.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",f.name="ChunkLoadError",f.type=n,f.request=u,t[1](f)}o[e]=void 0}};var c=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||[],f=i.push.bind(i);i.push=r,i=i.slice();for(var c=0;c<i.length;c++)r(i[c]);var l=f;t()}([]);
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +1,2 @@
|
||||
<router-outlet></router-outlet>
|
||||
<mat-progress-bar *ngIf="loading" color="primary" mode="indeterminate"></mat-progress-bar>
|
||||
<router-outlet *ngIf="!loading"></router-outlet>
|
||||
|
@ -1 +1,2 @@
|
||||
<router-outlet></router-outlet>
|
||||
<mat-progress-bar *ngIf="loading" color="primary" mode="indeterminate"></mat-progress-bar>
|
||||
<router-outlet *ngIf="!loading"></router-outlet>
|
||||
|
@ -0,0 +1,15 @@
|
||||
<div fxLayout="column">
|
||||
<div fxLayout="row" fxLayoutAlign="space-between end" fxLayoutAlign.gt-sm="start end">
|
||||
<mat-form-field fxFlex="48" fxFlex.gt-sm="25" fxLayoutAlign="start end">
|
||||
<mat-select [(ngModel)]="selectedAddress" placeholder="Address Type" name="address_type" tabindex="1">
|
||||
<mat-option *ngFor="let addressType of addressTypes" [value]="addressType">
|
||||
{{addressType.addressTp}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div class="mt-2" fxFlex="48" fxFlex.gt-sm="25">
|
||||
<button fxFlex="100" fxLayoutAlign="center center" mat-raised-button color="primary" (click)="onGenerateAddress()" [disabled]="undefined === selectedAddress.addressId" tabindex="2" class="top-minus-15px">Generate Address</button>
|
||||
</div>
|
||||
</div>
|
||||
<rtl-on-chain-transaction-history fxLayout="row" fxFlex="100"></rtl-on-chain-transaction-history>
|
||||
</div>
|
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { OnChainReceiveComponent } from './on-chain-receive.component';
|
||||
|
||||
describe('OnChainReceiveComponent', () => {
|
||||
let component: OnChainReceiveComponent;
|
||||
let fixture: ComponentFixture<OnChainReceiveComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ OnChainReceiveComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(OnChainReceiveComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,184 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil, take } from 'rxjs/operators';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
import { SelNodeChild } from '../../../shared/models/RTLconfig';
|
||||
import { GetInfo, Balance, ChannelsTransaction, AddressType } from '../../../shared/models/lndModels';
|
||||
import { RTLConfiguration } from '../../../shared/models/RTLconfig';
|
||||
import { LoggerService } from '../../../shared/services/logger.service';
|
||||
import * as sha256 from 'sha256';
|
||||
|
||||
import { LNDEffects } from '../../store/lnd.effects';
|
||||
import { RTLEffects } from '../../../store/rtl.effects';
|
||||
import * as RTLActions from '../../../store/rtl.actions';
|
||||
import * as fromRTLReducer from '../../../store/rtl.reducers';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-on-chain-receive',
|
||||
templateUrl: './on-chain-receive.component.html',
|
||||
styleUrls: ['./on-chain-receive.component.scss']
|
||||
})
|
||||
export class OnChainReceiveComponent implements OnInit, OnDestroy {
|
||||
public selNode: SelNodeChild = {};
|
||||
public appConfig: RTLConfiguration;
|
||||
public addressTypes = [];
|
||||
public flgLoadingWallet: Boolean | 'error' = true;
|
||||
public selectedAddress: AddressType = {};
|
||||
public blockchainBalance: Balance = {};
|
||||
public information: GetInfo = {};
|
||||
public newAddress = '';
|
||||
public transaction: ChannelsTransaction = {};
|
||||
public transTypes = [{id: '1', name: 'Target Confirmation Blocks'}, {id: '2', name: 'Fee'}];
|
||||
public selTransType = '1';
|
||||
public flgCustomAmount = '1';
|
||||
private unsub: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
|
||||
|
||||
constructor(private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private rtlEffects: RTLEffects, private lndEffects: LNDEffects) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.store.select('root')
|
||||
.pipe(takeUntil(this.unsub[0]))
|
||||
.subscribe((rootStore) => {
|
||||
this.appConfig = rootStore.appConfig;
|
||||
this.logger.info(rootStore);
|
||||
});
|
||||
|
||||
this.store.select('lnd')
|
||||
.pipe(takeUntil(this.unsub[0]))
|
||||
.subscribe((rtlStore) => {
|
||||
rtlStore.effectErrorsLnd.forEach(effectsErr => {
|
||||
if (effectsErr.action === 'FetchBalance/blockchain') {
|
||||
this.flgLoadingWallet = 'error';
|
||||
}
|
||||
});
|
||||
this.selNode = rtlStore.nodeSettings;
|
||||
this.information = rtlStore.information;
|
||||
this.addressTypes = rtlStore.addressTypes;
|
||||
|
||||
this.blockchainBalance = rtlStore.blockchainBalance;
|
||||
if (undefined === this.blockchainBalance.total_balance) {
|
||||
this.blockchainBalance.total_balance = 0;
|
||||
}
|
||||
if (undefined === this.blockchainBalance.confirmed_balance) {
|
||||
this.blockchainBalance.confirmed_balance = 0;
|
||||
}
|
||||
if (undefined === this.blockchainBalance.unconfirmed_balance) {
|
||||
this.blockchainBalance.unconfirmed_balance = 0;
|
||||
}
|
||||
if (this.flgLoadingWallet !== 'error') {
|
||||
this.flgLoadingWallet = false;
|
||||
}
|
||||
|
||||
this.logger.info(rtlStore);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
onGenerateAddress() {
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Getting New Address...'));
|
||||
this.store.dispatch(new RTLActions.GetNewAddress(this.selectedAddress));
|
||||
this.lndEffects.setNewAddress
|
||||
.pipe(takeUntil(this.unsub[1]))
|
||||
.subscribe(newAddress => {
|
||||
this.newAddress = newAddress;
|
||||
});
|
||||
}
|
||||
|
||||
onSendFunds() {
|
||||
const confirmationMsg = {
|
||||
'BTC Address': this.transaction.address,
|
||||
};
|
||||
if (!+this.flgCustomAmount) {
|
||||
confirmationMsg['Sweep All'] = 'True';
|
||||
this.transaction.sendAll = true;
|
||||
} else {
|
||||
confirmationMsg['Amount (' + this.information.smaller_currency_unit + ')'] = this.transaction.amount;
|
||||
this.transaction.sendAll = false;
|
||||
}
|
||||
if (this.selTransType === '1') {
|
||||
delete this.transaction.fees;
|
||||
confirmationMsg['Target Confirmation Blocks'] = this.transaction.blocks;
|
||||
} else {
|
||||
delete this.transaction.blocks;
|
||||
confirmationMsg['Fee (' + this.information.smaller_currency_unit + '/Byte)'] = this.transaction.fees;
|
||||
}
|
||||
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data:
|
||||
{type: 'CONFIRM', message: JSON.stringify(confirmationMsg), noBtnText: 'Cancel', yesBtnText: 'Send'}
|
||||
}));
|
||||
|
||||
this.rtlEffects.closeConfirm
|
||||
.pipe(takeUntil(this.unsub[2]))
|
||||
.subscribe(confirmRes => {
|
||||
if (confirmRes) {
|
||||
if (this.transaction.sendAll && !+this.appConfig.sso.rtlSSO) {
|
||||
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data:
|
||||
{type: 'CONFIRM', titleMessage: 'Enter Login Password', noBtnText: 'Cancel', yesBtnText: 'Authorize', flgShowInput: true, getInputs: [
|
||||
{placeholder: 'Enter Login Password', inputType: 'password', inputValue: ''}
|
||||
]}
|
||||
}));
|
||||
this.rtlEffects.closeConfirm
|
||||
.pipe(takeUntil(this.unsub[3]))
|
||||
.subscribe(pwdConfirmRes => {
|
||||
if (pwdConfirmRes) {
|
||||
const pwd = pwdConfirmRes[0].inputValue;
|
||||
this.store.dispatch(new RTLActions.IsAuthorized(sha256(pwd)));
|
||||
this.rtlEffects.isAuthorizedRes
|
||||
.pipe(take(1))
|
||||
.subscribe(authRes => {
|
||||
if (authRes !== 'ERROR') {
|
||||
this.dispatchToSendFunds();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.dispatchToSendFunds();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
dispatchToSendFunds() {
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Sending Funds...'));
|
||||
this.store.dispatch(new RTLActions.SetChannelTransaction(this.transaction));
|
||||
this.transaction = {address: '', amount: 0, blocks: 0, fees: 0};
|
||||
}
|
||||
|
||||
get invalidValues(): boolean {
|
||||
return (undefined === this.transaction.address || this.transaction.address === '')
|
||||
|| (+this.flgCustomAmount && (undefined === this.transaction.amount || this.transaction.amount <= 0))
|
||||
|| (this.selTransType === '1' && (undefined === this.transaction.blocks || this.transaction.blocks <= 0))
|
||||
|| (this.selTransType === '2' && (undefined === this.transaction.fees || this.transaction.fees <= 0));
|
||||
}
|
||||
|
||||
onCustomClicked() {
|
||||
this.flgCustomAmount = '1';
|
||||
}
|
||||
|
||||
onOptionChange(event) {
|
||||
if (!+this.flgCustomAmount) {
|
||||
delete this.transaction.amount;
|
||||
}
|
||||
}
|
||||
|
||||
resetData() {
|
||||
this.transaction.address = '';
|
||||
this.transaction.amount = 0;
|
||||
this.transaction.blocks = 0;
|
||||
this.transaction.fees = 0;
|
||||
}
|
||||
|
||||
resetReceiveData() {
|
||||
this.selectedAddress = {};
|
||||
this.newAddress = '';
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unsub.forEach(completeSub => {
|
||||
completeSub.next();
|
||||
completeSub.complete();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
<div fxLayout="column" fxLayout.gt-sm="row wrap">
|
||||
<div fxFlex="100" class="padding-gap">
|
||||
<div fxLayout="column" fxLayout.gt-sm="row wrap">
|
||||
<div fxFlex="58" fxLayoutAlign="start end">
|
||||
<mat-form-field fxFlex="99">
|
||||
<input matInput [(ngModel)]="transaction.address" placeholder="Bitcoin Address"
|
||||
tabindex="1" name="address" #address="ngModel">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<!-- <div fxFlex="38" fxLayoutAlign="start end">
|
||||
<mat-radio-group fxFlex="100" fxLayoutAlign="space-between center" (change)="onOptionChange($event)" [(ngModel)]="flgCustomAmount">
|
||||
<mat-radio-button fxFlex="35" value="0">Sweep All</mat-radio-button>
|
||||
<mat-radio-button fxFlex="60" value="1">
|
||||
<mat-form-field fxFlex="70"><input matInput [(ngModel)]="transaction.amount" (click)="onCustomClicked()" placeholder="Amount ({{information?.smaller_currency_unit}})" name="amount" type="number" step="100" min="0" tabindex="5" #amount="ngModel"></mat-form-field>
|
||||
</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
</div> -->
|
||||
<div fxFlex="30" fxLayoutAlign="start end">
|
||||
<mat-form-field fxFlex="70">
|
||||
<input matInput [(ngModel)]="transaction.amount" placeholder="Amount" name="amount" type="number" step="100" min="0" tabindex="2" #amount="ngModel">
|
||||
<span matSuffix> {{selAmountUnit}} </span>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<mat-form-field fxFlex="10" fxLayoutAlign="start end">
|
||||
<mat-select [value]="selAmountUnit" tabindex="3" required name="amountUnit" (selectionChange)="onAmountUnitChange($event)">
|
||||
<mat-option *ngFor="let amountUnit of amountUnits" [value]="amountUnit">{{amountUnit}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div fxLayout="column" fxLayout.gt-sm="row wrap">
|
||||
<div fxFlex="30" fxLayoutAlign="start start">
|
||||
<mat-form-field fxFlex="99">
|
||||
<mat-select [(value)]="selTransType" tabindex="4">
|
||||
<mat-option *ngFor="let transType of transTypes" [value]="transType.id">
|
||||
{{transType.name}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div fxFlex="30" fxLayoutAlign="start start">
|
||||
<mat-form-field fxFlex="99" *ngIf="selTransType=='1'">
|
||||
<input matInput [(ngModel)]="transaction.blocks" placeholder="Target Confirmation Blocks" type="number"
|
||||
name="blocks" step="1" min="0" required tabindex="5" #blocks="ngModel">
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="99" *ngIf="selTransType=='2'">
|
||||
<input matInput [(ngModel)]="transaction.fees"
|
||||
placeholder="Fee ({{information?.smaller_currency_unit}}/Byte)" type="number" name="fees" step="1"
|
||||
min="0" required tabindex="6" #fees="ngModel">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div fxFlex="40" fxLayoutAlign="space-between start">
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="7"
|
||||
type="reset" (click)="resetData()">Clear Fields</button>
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary"
|
||||
[disabled]="invalidValues" type="submit" tabindex="8" (click)="onSendFunds()">
|
||||
<p *ngIf="invalidValues && (address.touched || address.dirty) && (amount.touched || amount.dirty); else sendText">
|
||||
Invalid Values</p>
|
||||
<ng-template #sendText>
|
||||
<p>Send Funds</p>
|
||||
</ng-template>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ng-template #withoutData>
|
||||
<h3>Sats</h3>
|
||||
</ng-template>
|
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { OnChainSendComponent } from './on-chain-send.component';
|
||||
|
||||
describe('OnChainSendComponent', () => {
|
||||
let component: OnChainSendComponent;
|
||||
let fixture: ComponentFixture<OnChainSendComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ OnChainSendComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(OnChainSendComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,196 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil, take } from 'rxjs/operators';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
import { SelNodeChild } from '../../../shared/models/RTLconfig';
|
||||
import { GetInfo, Balance, ChannelsTransaction, AddressType } from '../../../shared/models/lndModels';
|
||||
import { CURRENCY_UNITS } from '../../../shared/models/enums';
|
||||
import { RTLConfiguration } from '../../../shared/models/RTLconfig';
|
||||
import { LoggerService } from '../../../shared/services/logger.service';
|
||||
import * as sha256 from 'sha256';
|
||||
|
||||
import { LNDEffects } from '../../store/lnd.effects';
|
||||
import { RTLEffects } from '../../../store/rtl.effects';
|
||||
import * as RTLActions from '../../../store/rtl.actions';
|
||||
import * as fromRTLReducer from '../../../store/rtl.reducers';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-on-chain-send',
|
||||
templateUrl: './on-chain-send.component.html',
|
||||
styleUrls: ['./on-chain-send.component.scss']
|
||||
})
|
||||
export class OnChainSendComponent implements OnInit, OnDestroy {
|
||||
public selNode: SelNodeChild = {};
|
||||
public appConfig: RTLConfiguration;
|
||||
public addressTypes = [];
|
||||
public flgLoadingWallet: Boolean | 'error' = true;
|
||||
public selectedAddress: AddressType = {};
|
||||
public blockchainBalance: Balance = {};
|
||||
public information: GetInfo = {};
|
||||
public newAddress = '';
|
||||
public transaction: ChannelsTransaction = {};
|
||||
public transTypes = [{id: '1', name: 'Target Confirmation Blocks'}, {id: '2', name: 'Fee'}];
|
||||
public selTransType = '1';
|
||||
public flgCustomAmount = '1';
|
||||
public amountUnits = CURRENCY_UNITS;
|
||||
public selAmountUnit = CURRENCY_UNITS[0];
|
||||
public currConvertorRate = {};
|
||||
public unitConversionValue = 0;
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
|
||||
|
||||
constructor(private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private rtlEffects: RTLEffects, private httpClient: HttpClient) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.store.select('root')
|
||||
.pipe(takeUntil(this.unSubs[0]))
|
||||
.subscribe((rootStore) => {
|
||||
this.appConfig = rootStore.appConfig;
|
||||
this.logger.info(rootStore);
|
||||
});
|
||||
}
|
||||
|
||||
onSendFunds() {
|
||||
const confirmationMsg = {
|
||||
'BTC Address': this.transaction.address,
|
||||
};
|
||||
if (!+this.flgCustomAmount) {
|
||||
confirmationMsg['Sweep All'] = 'True';
|
||||
this.transaction.sendAll = true;
|
||||
} else {
|
||||
confirmationMsg['Amount (' + this.information.smaller_currency_unit + ')'] = this.transaction.amount;
|
||||
this.transaction.sendAll = false;
|
||||
}
|
||||
if (this.selTransType === '1') {
|
||||
delete this.transaction.fees;
|
||||
confirmationMsg['Target Confirmation Blocks'] = this.transaction.blocks;
|
||||
} else {
|
||||
delete this.transaction.blocks;
|
||||
confirmationMsg['Fee (' + this.information.smaller_currency_unit + '/Byte)'] = this.transaction.fees;
|
||||
}
|
||||
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data:
|
||||
{type: 'CONFIRM', message: JSON.stringify(confirmationMsg), noBtnText: 'Cancel', yesBtnText: 'Send'}
|
||||
}));
|
||||
|
||||
this.rtlEffects.closeConfirm
|
||||
.pipe(takeUntil(this.unSubs[2]))
|
||||
.subscribe(confirmRes => {
|
||||
if (confirmRes) {
|
||||
if (this.transaction.sendAll && !+this.appConfig.sso.rtlSSO) {
|
||||
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data:
|
||||
{type: 'CONFIRM', titleMessage: 'Enter Login Password', noBtnText: 'Cancel', yesBtnText: 'Authorize', flgShowInput: true, getInputs: [
|
||||
{placeholder: 'Enter Login Password', inputType: 'password', inputValue: ''}
|
||||
]}
|
||||
}));
|
||||
this.rtlEffects.closeConfirm
|
||||
.pipe(takeUntil(this.unSubs[3]))
|
||||
.subscribe(pwdConfirmRes => {
|
||||
if (pwdConfirmRes) {
|
||||
const pwd = pwdConfirmRes[0].inputValue;
|
||||
this.store.dispatch(new RTLActions.IsAuthorized(sha256(pwd)));
|
||||
this.rtlEffects.isAuthorizedRes
|
||||
.pipe(take(1))
|
||||
.subscribe(authRes => {
|
||||
if (authRes !== 'ERROR') {
|
||||
this.dispatchToSendFunds();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.dispatchToSendFunds();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
dispatchToSendFunds() {
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Sending Funds...'));
|
||||
this.store.dispatch(new RTLActions.SetChannelTransaction(this.transaction));
|
||||
this.transaction = {address: '', amount: 0, blocks: 0, fees: 0};
|
||||
}
|
||||
|
||||
get invalidValues(): boolean {
|
||||
return (undefined === this.transaction.address || this.transaction.address === '')
|
||||
|| (+this.flgCustomAmount && (undefined === this.transaction.amount || this.transaction.amount <= 0))
|
||||
|| (this.selTransType === '1' && (undefined === this.transaction.blocks || this.transaction.blocks <= 0))
|
||||
|| (this.selTransType === '2' && (undefined === this.transaction.fees || this.transaction.fees <= 0));
|
||||
}
|
||||
|
||||
onCustomClicked() {
|
||||
this.flgCustomAmount = '1';
|
||||
}
|
||||
|
||||
onOptionChange(event) {
|
||||
if (!+this.flgCustomAmount) {
|
||||
delete this.transaction.amount;
|
||||
}
|
||||
}
|
||||
|
||||
resetData() {
|
||||
this.transaction.address = '';
|
||||
this.transaction.amount = 0;
|
||||
this.transaction.blocks = 0;
|
||||
this.transaction.fees = 0;
|
||||
}
|
||||
|
||||
resetReceiveData() {
|
||||
this.selectedAddress = {};
|
||||
this.newAddress = '';
|
||||
}
|
||||
|
||||
onAmountUnitChange(event: any) {
|
||||
if(this.transaction.amount && this.selAmountUnit !== event.value) {
|
||||
switch (this.selAmountUnit) {
|
||||
case this.amountUnits[0]:
|
||||
switch (event.value) {
|
||||
case this.amountUnits[1]:
|
||||
this.transaction.amount = this.transaction.amount * 0.00000001;
|
||||
break;
|
||||
case this.amountUnits[2]:
|
||||
// this.transaction.amount = +this.currencyConvert.transform(this.transaction.amount.toString(), this.currConvertorRate[this.amountUnits[2]].last * 0.00000001);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case this.amountUnits[1]:
|
||||
switch (event.value) {
|
||||
case this.amountUnits[0]:
|
||||
this.transaction.amount = this.transaction.amount * 100000000;
|
||||
break;
|
||||
case this.amountUnits[2]:
|
||||
// this.transaction.amount = +this.currencyConvert.transform(this.transaction.amount.toString(), this.currConvertorRate[this.amountUnits[2]].last);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case this.amountUnits[2]:
|
||||
switch (event.value) {
|
||||
case this.amountUnits[0]:
|
||||
// this.transaction.amount = +this.currencyConvert.transform(this.transaction.amount.toString(), this.currConvertorRate[this.amountUnits[2]].last) * 10000000;
|
||||
break;
|
||||
case this.amountUnits[1]:
|
||||
// this.transaction.amount = +this.currencyConvert.transform(this.transaction.amount.toString(), this.currConvertorRate[this.amountUnits[2]].last);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.selAmountUnit = event.value;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach(completeSub => {
|
||||
completeSub.next();
|
||||
completeSub.complete();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
<div fxLayout="column" fxFlex="100" fxLayoutAlign="start start">
|
||||
<div fxLayout="row" fxFlex="100" fxLayoutAlign="start center" class="padding-gap-x page-sub-title-container mt-2 w-100">
|
||||
<div fxFlex="70">
|
||||
<fa-icon [icon]="faHistory" class="page-title-img mr-1"></fa-icon>
|
||||
<span class="page-title">Transaction History</span>
|
||||
</div>
|
||||
<mat-form-field fxFlex="30">
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayoutAlign="start center" class="w-100">
|
||||
<div perfectScrollbar class="table-container" fxFlex="100">
|
||||
<mat-progress-bar *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar>
|
||||
<table mat-table #table [dataSource]="listTransactions" matSort
|
||||
[ngClass]="{'overflow-auto error-border': flgLoading[0]==='error','overflow-auto': true}">
|
||||
<ng-container matColumnDef="time_stamp_str">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Date/Time </th>
|
||||
<td mat-cell *matCellDef="let transaction">{{transaction.time_stamp_str}}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Amount (Sats) </th>
|
||||
<td mat-cell *matCellDef="let transaction"><span fxLayoutAlign="end center">{{transaction.amount | number}}</span></td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="num_confirmations">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Confirmations </th>
|
||||
<td mat-cell *matCellDef="let transaction"><span fxLayoutAlign="end center">
|
||||
{{transaction?.num_confirmations | number}} </span></td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef class="pl-3 pr-3"><span fxLayoutAlign="end center">Actions</span></th>
|
||||
<td mat-cell *matCellDef="let transaction" class="pl-3">
|
||||
<button mat-stroked-button color="primary" type="button" tabindex="4"
|
||||
(click)="onTransactionClick(transaction, $event)">View Info</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
<mat-paginator [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions" showFirstLastButtons class="mb-4"></mat-paginator>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,4 @@
|
||||
.mat-column-actions {
|
||||
flex: 0 0 5%;
|
||||
width: 5%;
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { OnChainTransactionHistoryComponent } from './on-chain-transaction-history.component';
|
||||
|
||||
describe('OnChainTransactionHistoryComponent', () => {
|
||||
let component: OnChainTransactionHistoryComponent;
|
||||
let fixture: ComponentFixture<OnChainTransactionHistoryComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ OnChainTransactionHistoryComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(OnChainTransactionHistoryComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,115 @@
|
||||
import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil, filter } from 'rxjs/operators';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Actions } from '@ngrx/effects';
|
||||
import { faHistory } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
import { MatTableDataSource, MatSort, MatPaginator, MatPaginatorIntl } from '@angular/material';
|
||||
import { Transaction } from '../../../shared/models/lndModels';
|
||||
import { LoggerService } from '../../../shared/services/logger.service';
|
||||
|
||||
import { RTLEffects } from '../../../store/rtl.effects';
|
||||
import * as RTLActions from '../../../store/rtl.actions';
|
||||
import * as fromRTLReducer from '../../../store/rtl.reducers';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-on-chain-transaction-history',
|
||||
templateUrl: './on-chain-transaction-history.component.html',
|
||||
styleUrls: ['./on-chain-transaction-history.component.scss']
|
||||
})
|
||||
export class OnChainTransactionHistoryComponent implements OnInit, OnDestroy {
|
||||
@ViewChild(MatSort, { static: true }) sort: MatSort;
|
||||
@ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;
|
||||
faHistory = faHistory;
|
||||
public displayedColumns = [];
|
||||
public listTransactions: any;
|
||||
public flgLoading: Array<Boolean | 'error'> = [true];
|
||||
public flgSticky = false;
|
||||
public pageSize = 10;
|
||||
public pageSizeOptions = [5, 10, 25, 100];
|
||||
private unsub: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
|
||||
|
||||
constructor(private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private rtlEffects: RTLEffects, private actions$: Actions) {
|
||||
switch (true) {
|
||||
case (window.innerWidth <= 415):
|
||||
this.displayedColumns = ['time_stamp_str', 'amount', 'actions'];
|
||||
break;
|
||||
case (window.innerWidth > 415 && window.innerWidth <= 730):
|
||||
this.displayedColumns = ['time_stamp_str', 'amount', 'num_confirmations', 'actions'];
|
||||
break;
|
||||
case (window.innerWidth > 730 && window.innerWidth <= 1024):
|
||||
this.displayedColumns = ['time_stamp_str', 'amount', 'num_confirmations', 'actions'];
|
||||
break;
|
||||
case (window.innerWidth > 1024 && window.innerWidth <= 1280):
|
||||
this.flgSticky = true;
|
||||
this.displayedColumns = ['time_stamp_str', 'amount', 'num_confirmations', 'actions'];
|
||||
break;
|
||||
default:
|
||||
this.flgSticky = true;
|
||||
this.displayedColumns = ['time_stamp_str', 'amount', 'num_confirmations', 'actions'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.store.dispatch(new RTLActions.FetchTransactions());
|
||||
this.actions$.pipe(takeUntil(this.unsub[2]), filter((action) => action.type === RTLActions.RESET_LND_STORE)).subscribe((resetLndStore: RTLActions.ResetLNDStore) => {
|
||||
this.store.dispatch(new RTLActions.FetchTransactions());
|
||||
});
|
||||
|
||||
this.store.select('lnd')
|
||||
.pipe(takeUntil(this.unsub[0]))
|
||||
.subscribe((rtlStore) => {
|
||||
rtlStore.effectErrorsLnd.forEach(effectsErr => {
|
||||
if (effectsErr.action === 'FetchTransactions') {
|
||||
this.flgLoading[0] = 'error';
|
||||
}
|
||||
});
|
||||
if (undefined !== rtlStore.transactions) {
|
||||
this.loadTransactionsTable(rtlStore.transactions);
|
||||
}
|
||||
if (this.flgLoading[0] !== 'error') {
|
||||
this.flgLoading[0] = (undefined !== rtlStore.transactions) ? false : true;
|
||||
}
|
||||
this.logger.info(rtlStore);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
applyFilter(selFilter: string) {
|
||||
this.listTransactions.filter = selFilter;
|
||||
}
|
||||
|
||||
onTransactionClick(selRow: Transaction, event: any) {
|
||||
const flgExpansionClicked = event.target.className.includes('mat-expansion-panel-header') || event.target.className.includes('mat-expansion-indicator');
|
||||
if (flgExpansionClicked) {
|
||||
return;
|
||||
}
|
||||
const selTransaction = this.listTransactions.data.filter(transaction => {
|
||||
return transaction.tx_hash === selRow.tx_hash;
|
||||
})[0];
|
||||
const reorderedTransactions = JSON.parse(JSON.stringify(selTransaction, [
|
||||
'dest_addresses', 'time_stamp_str', 'num_confirmations', 'total_fees', 'block_hash', 'block_height', 'tx_hash', 'amount'
|
||||
] , 2));
|
||||
this.store.dispatch(new RTLActions.OpenAlert({ config: { width: '75%', data: {
|
||||
type: 'INFO',
|
||||
message: JSON.stringify(reorderedTransactions)
|
||||
}}}));
|
||||
}
|
||||
|
||||
loadTransactionsTable(transactions) {
|
||||
this.listTransactions = new MatTableDataSource<Transaction>([...transactions]);
|
||||
this.listTransactions.sort = this.sort;
|
||||
this.listTransactions.paginator = this.paginator;
|
||||
this.logger.info(this.listTransactions);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unsub.forEach(completeSub => {
|
||||
completeSub.next();
|
||||
completeSub.complete();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
<div fxLayout="row" fxLayoutAlign="start center" class="padding-gap-x page-title-container">
|
||||
<fa-icon [icon]="faChartPie" class="page-title-img mr-1"></fa-icon>
|
||||
<span class="page-title">On-chain Balance</span>
|
||||
</div>
|
||||
<div fxLayout="column" class="padding-gap-x mb-4">
|
||||
<mat-card>
|
||||
<mat-card-content fxLayout="column">
|
||||
<rtl-currency-unit-converter [values]="balances" [currencyUnits]="selNode.currencyUnits"></rtl-currency-unit-converter>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayoutAlign="start center" class="padding-gap-x page-title-container">
|
||||
<fa-icon [icon]="faExchangeAlt" class="page-title-img mr-1"></fa-icon>
|
||||
<span class="page-title">On-chain Transactions</span>
|
||||
</div>
|
||||
<div fxLayout="column" class="padding-gap-x">
|
||||
<mat-card>
|
||||
<mat-card-content fxLayout="column">
|
||||
<mat-tab-group>
|
||||
<mat-tab label="Send">
|
||||
<rtl-on-chain-send></rtl-on-chain-send>
|
||||
</mat-tab>
|
||||
<mat-tab label="Receive">
|
||||
<rtl-on-chain-receive></rtl-on-chain-receive>
|
||||
</mat-tab>
|
||||
<mat-tab label="Sweep All">
|
||||
<rtl-on-chain-send></rtl-on-chain-send>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { OnChainComponent } from './on-chain.component';
|
||||
|
||||
describe('OnChainComponent', () => {
|
||||
let component: OnChainComponent;
|
||||
let fixture: ComponentFixture<OnChainComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ OnChainComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(OnChainComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,75 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil, filter } from 'rxjs/operators';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Actions } from '@ngrx/effects';
|
||||
import { faExchangeAlt, faChartPie } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
import { SelNodeChild } from '../../shared/models/RTLconfig';
|
||||
import { GetInfo, Balance, ChannelsTransaction, AddressType } from '../../shared/models/lndModels';
|
||||
import { RTLConfiguration } from '../../shared/models/RTLconfig';
|
||||
import * as fromRTLReducer from '../../store/rtl.reducers';
|
||||
import * as RTLActions from '../../store/rtl.actions';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-on-chain',
|
||||
templateUrl: './on-chain.component.html',
|
||||
styleUrls: ['./on-chain.component.scss']
|
||||
})
|
||||
export class OnChainComponent implements OnInit, OnDestroy {
|
||||
public selNode: SelNodeChild = {};
|
||||
public appConfig: RTLConfiguration;
|
||||
public addressTypes = [];
|
||||
public flgLoadingWallet: Boolean | 'error' = true;
|
||||
public selectedAddress: AddressType = {};
|
||||
public blockchainBalance: Balance = {};
|
||||
public information: GetInfo = {};
|
||||
public newAddress = '';
|
||||
public transaction: ChannelsTransaction = {};
|
||||
public transTypes = [{id: '1', name: 'Target Confirmation Blocks'}, {id: '2', name: 'Fee'}];
|
||||
public selTransType = '1';
|
||||
public flgCustomAmount = '1';
|
||||
faExchangeAlt = faExchangeAlt;
|
||||
faChartPie = faChartPie;
|
||||
balances = [{title: 'Total Balance', dataValue: 0}, {title: 'Confirmed', dataValue: 0}, {title: 'Unconfirmed', dataValue: 0}];
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];
|
||||
|
||||
constructor(private store: Store<fromRTLReducer.RTLState>, private actions$: Actions) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.store.select('lnd')
|
||||
.pipe(takeUntil(this.unSubs[1]))
|
||||
.subscribe((rtlStore) => {
|
||||
rtlStore.effectErrorsLnd.forEach(effectsErr => {
|
||||
if (effectsErr.action === 'FetchBalance/blockchain') {
|
||||
this.flgLoadingWallet = 'error';
|
||||
}
|
||||
});
|
||||
this.selNode = rtlStore.nodeSettings;
|
||||
this.information = rtlStore.information;
|
||||
this.addressTypes = rtlStore.addressTypes;
|
||||
this.blockchainBalance = rtlStore.blockchainBalance;
|
||||
if (undefined === this.blockchainBalance.total_balance) {
|
||||
this.blockchainBalance.total_balance = 0;
|
||||
}
|
||||
if (undefined === this.blockchainBalance.confirmed_balance) {
|
||||
this.blockchainBalance.confirmed_balance = 0;
|
||||
}
|
||||
if (undefined === this.blockchainBalance.unconfirmed_balance) {
|
||||
this.blockchainBalance.unconfirmed_balance = 0;
|
||||
}
|
||||
this.balances = [{title: 'Total Balance', dataValue: this.blockchainBalance.total_balance}, {title: 'Confirmed', dataValue: this.blockchainBalance.confirmed_balance}, {title: 'Unconfirmed', dataValue: this.blockchainBalance.unconfirmed_balance}];
|
||||
if (this.flgLoadingWallet !== 'error') {
|
||||
this.flgLoadingWallet = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach(completeSub => {
|
||||
completeSub.next();
|
||||
completeSub.complete();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
.tree-invisible {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lookup-tree ul,
|
||||
.lookup-tree li {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.pl-3 {
|
||||
padding-left: 3rem;
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
<mat-tab-group>
|
||||
<mat-tab *ngFor="let currencyUnit of currencyUnits" [label]="currencyUnit">
|
||||
<mat-tab *ngFor="let currencyUnit of currencyUnits" label="{{ currencyUnit }}">
|
||||
<div fxLayout="row" fxFlex="100">
|
||||
<div fxLayout="column" *ngFor="let value of values" [matTooltip]="value.tooltip" [matTooltipPosition]="'below'" class="cc-data-block">
|
||||
<div class="cc-data-title">{{value.title}}</div>
|
||||
<span class="cc-data-value" *ngIf="currencyUnit === CurrencyUnitEnum.SATS">{{value.dataValue | number}}</span>
|
||||
<span class="cc-data-value" *ngIf="currencyUnit === CurrencyUnitEnum.BTC">{{value.dataValue | unitconvert:0.00000001 | number:'1.6-6'}}</span>
|
||||
<span class="cc-data-value" *ngIf="currencyUnit !== CurrencyUnitEnum.SATS && currencyUnit !== CurrencyUnitEnum.BTC">{{value.dataValue | unitconvert:(unitConversionValue * 0.00000001) | number:'1.2-2'}}</span>
|
||||
<span class="cc-data-value" *ngIf="currencyUnit === currencyUnitEnum.SATS">{{value.dataValue | number}}</span>
|
||||
<span class="cc-data-value" *ngIf="currencyUnit === currencyUnitEnum.BTC">{{value.dataValueBTC | number:'1.6-6'}}</span>
|
||||
<span class="cc-data-value" *ngIf="currencyUnit !== currencyUnitEnum.SATS && currencyUnit !== currencyUnitEnum.BTC">{{value.dataValueOTHER | number:'1.2-2'}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</mat-tab>
|
||||
|
@ -0,0 +1,17 @@
|
||||
import { AfterContentInit, Directive, ElementRef, Input } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[autoFocus]'
|
||||
})
|
||||
export class AutoFocusDirective implements AfterContentInit {
|
||||
@Input() public appAutoFocus: boolean;
|
||||
|
||||
public constructor(private el: ElementRef) {}
|
||||
|
||||
public ngAfterContentInit() {
|
||||
setTimeout(() => {
|
||||
this.el.nativeElement.focus();
|
||||
}, 500);
|
||||
}
|
||||
|
||||
}
|
@ -1,11 +1,23 @@
|
||||
export const CURRENCY_UNITS = [ 'SATS', 'BTC' ];
|
||||
|
||||
export const TIME_UNITS = ['SECS', 'MINS', 'HOURS', 'DAYS'];
|
||||
|
||||
export enum AuthenticateWith {
|
||||
TOKEN = 'TOKEN',
|
||||
PASSWORD = 'PASSWORD'
|
||||
}
|
||||
|
||||
export enum CurrencyUnit {
|
||||
export enum TimeUnitEnum {
|
||||
SECS = 'SECS',
|
||||
MINS = 'MINS',
|
||||
HOURS = 'HOURS',
|
||||
DAYS = 'DAYS'
|
||||
}
|
||||
|
||||
export enum CurrencyUnitEnum {
|
||||
SATS = 'SATS',
|
||||
BTC = 'BTC'
|
||||
BTC = 'BTC',
|
||||
LITOSHIS = 'LITOSHIS',
|
||||
LTC = 'LTC',
|
||||
OTHER = 'OTHER'
|
||||
}
|
||||
|
Loading…
Reference in New Issue