mirror of
https://github.com/Ride-The-Lightning/RTL.git
synced 2024-11-19 09:50:36 +01:00
Query Routes
Query Routes
This commit is contained in:
parent
a9e8ca6a75
commit
e89ca32109
@ -8,5 +8,5 @@
|
||||
<link rel="stylesheet" href="styles.95c3afc83be2d91ee834.css"></head>
|
||||
<body>
|
||||
<rtl-app></rtl-app>
|
||||
<script src="runtime-es2015.703a23e48ad83c851e49.js" type="module"></script><script src="polyfills-es2015.2a0da12c7706d5c3e2aa.js" type="module"></script><script src="runtime-es5.465c2333d355155ec5f3.js" nomodule></script><script src="polyfills-es5.84431ea76d33490d0941.js" nomodule></script><script src="main-es2015.ad87193d8f17c92a2f4d.js" type="module"></script><script src="main-es5.4b5fee64a9fad1d3dbb7.js" nomodule></script></body>
|
||||
<script src="runtime-es2015.703a23e48ad83c851e49.js" type="module"></script><script src="polyfills-es2015.2a0da12c7706d5c3e2aa.js" type="module"></script><script src="runtime-es5.465c2333d355155ec5f3.js" nomodule></script><script src="polyfills-es5.84431ea76d33490d0941.js" nomodule></script><script src="main-es2015.7a9b6c3237c1d92ddad5.js" type="module"></script><script src="main-es5.c018dbcea6ce8bc8a2ad.js" nomodule></script></body>
|
||||
</html>
|
||||
|
1
angular/main-es2015.7a9b6c3237c1d92ddad5.js
Normal file
1
angular/main-es2015.7a9b6c3237c1d92ddad5.js
Normal file
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
angular/main-es5.c018dbcea6ce8bc8a2ad.js
Normal file
1
angular/main-es5.c018dbcea6ce8bc8a2ad.js
Normal file
File diff suppressed because one or more lines are too long
@ -13,7 +13,7 @@ exports.getInfo = (req, res, next) => {
|
||||
} else {
|
||||
logger.info({fileName:'GetInfo', msg: 'Single Node Setup!'});
|
||||
}
|
||||
common.nodes.map(node => { connect.getAllNodeAllChannelBackup(node); });
|
||||
common.nodes.map(node => { if (node.lnImplementation === 'LND') { connect.getAllNodeAllChannelBackup(node); }});
|
||||
logger.info({fileName: 'GetInfo', msg: 'Calling getinfo from lnd server url: ' + options.url});
|
||||
request(options).then((body) => {
|
||||
logger.info({fileName: 'GetInfo', msg: JSON.stringify(body)});
|
||||
|
@ -3,6 +3,19 @@ var common = require('../common');
|
||||
var logger = require('./logger');
|
||||
var options = {};
|
||||
|
||||
getAliasFromPubkey = (hop) => {
|
||||
return new Promise(function(resolve, reject) {
|
||||
options.url = common.getSelLNDServerUrl() + '/graph/node/' + hop.pub_key;
|
||||
request(options)
|
||||
.then(function(aliasBody) {
|
||||
logger.info({fileName: 'Graph', msg: 'Alias: ' + JSON.stringify(aliasBody.node.alias)});
|
||||
hop.pubkey_alias = aliasBody.node.alias;
|
||||
resolve(hop);
|
||||
})
|
||||
.catch(err => resolve(''));
|
||||
});
|
||||
}
|
||||
|
||||
exports.getDescribeGraph = (req, res, next) => {
|
||||
options = common.getOptions();
|
||||
options.url = common.getSelLNDServerUrl() + '/graph';
|
||||
@ -108,22 +121,39 @@ exports.getQueryRoutes = (req, res, next) => {
|
||||
options = common.getOptions();
|
||||
options.url = common.getSelLNDServerUrl() + '/graph/routes/' + req.params.destPubkey + '/' + req.params.amount;
|
||||
request(options).then((body) => {
|
||||
logger.info({fileName: 'Graph', msg: 'Edge Info Received: ' + JSON.stringify(body)});
|
||||
logger.info({fileName: 'Graph', msg: 'Query Routes Received: ' + JSON.stringify(body)});
|
||||
if(undefined === body || body.error) {
|
||||
res.status(500).json({
|
||||
message: "Fetching Edge Info Failed!",
|
||||
message: "Fetching Query Routes Failed!",
|
||||
error: (undefined === body) ? 'Error From Server!' : body.error
|
||||
});
|
||||
}
|
||||
if (undefined !== body) {
|
||||
body.last_update_str = (undefined === body.last_update) ? '' : common.convertTimestampToDate(body.last_update);
|
||||
if (undefined !== body.routes) {
|
||||
body.routes.forEach(route => {
|
||||
if (undefined !== route.hops) {
|
||||
Promise.all(
|
||||
route.hops.map((hop, i) => {
|
||||
hop.hop_sequence = i + 1;
|
||||
return getAliasFromPubkey(hop);
|
||||
})
|
||||
)
|
||||
.then(function(values) {
|
||||
logger.info({fileName: 'Graph', msg: 'Hops with Alias: ' + JSON.stringify(body)});
|
||||
res.status(200).json(body);
|
||||
}).catch(err => {
|
||||
return res.status(500).json({
|
||||
message: "Fetching Query Routes Failed!",
|
||||
error: err.error
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
res.status(200).json(body);
|
||||
})
|
||||
.catch((err) => {
|
||||
return res.status(500).json({
|
||||
message: "Fetching Edge Info Failed!",
|
||||
message: "Fetching Query Routes Failed!",
|
||||
error: err.error
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
@ -31,7 +31,7 @@ import { InvoicesComponent } from './pages/invoices/invoices.component';
|
||||
import { ServerConfigComponent } from './pages/server-config/server-config.component';
|
||||
import { HelpComponent } from './pages/help/help.component';
|
||||
import { UnlockLNDComponent } from './pages/unlock-lnd/unlock-lnd.component';
|
||||
import { PaymentsComponent } from './pages/payments/payments.component';
|
||||
import { PaymentsComponent } from './pages/payments/send-receive/payments.component';
|
||||
import { SideNavigationComponent } from './pages/navigation/side-navigation/side-navigation.component';
|
||||
import { TopMenuComponent } from './pages/navigation/top-menu/top-menu.component';
|
||||
import { HorizontalNavigationComponent } from './pages/navigation/horizontal-navigation/horizontal-navigation.component';
|
||||
@ -54,6 +54,7 @@ import { RoutingPeersComponent } from './pages/routing-peers/routing-peers.compo
|
||||
import { ChannelLookupComponent } from './pages/lookups/channel-lookup/channel-lookup.component';
|
||||
import { NodeLookupComponent } from './pages/lookups/node-lookup/node-lookup.component';
|
||||
import { ChannelBackupComponent } from './pages/channels/channel-backup/channel-backup.component';
|
||||
import { QueryRoutesComponent } from './pages/payments/query-routes/query-routes.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -94,7 +95,8 @@ import { ChannelBackupComponent } from './pages/channels/channel-backup/channel-
|
||||
RoutingPeersComponent,
|
||||
ChannelLookupComponent,
|
||||
NodeLookupComponent,
|
||||
ChannelBackupComponent
|
||||
ChannelBackupComponent,
|
||||
QueryRoutesComponent
|
||||
],
|
||||
providers: [
|
||||
{ provide: LoggerService, useClass: ConsoleLoggerService },
|
||||
|
@ -11,7 +11,8 @@ import { ChannelPendingComponent } from './pages/channels/channel-pending/channe
|
||||
import { PeersComponent } from './pages/peers/peers.component';
|
||||
import { SendReceiveTransComponent } from './pages/transactions/send-receive/send-receive-trans.component';
|
||||
import { ListTransactionsComponent } from './pages/transactions/list-transactions/list-transactions.component';
|
||||
import { PaymentsComponent } from './pages/payments/payments.component';
|
||||
import { PaymentsComponent } from './pages/payments/send-receive/payments.component';
|
||||
import { QueryRoutesComponent } from './pages/payments/query-routes/query-routes.component';
|
||||
import { ServerConfigComponent } from './pages/server-config/server-config.component';
|
||||
import { HelpComponent } from './pages/help/help.component';
|
||||
import { InvoicesComponent } from './pages/invoices/invoices.component';
|
||||
@ -35,7 +36,8 @@ export const routes: Routes = [
|
||||
{ path: 'chnlbackup', component: ChannelBackupComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
|
||||
{ path: 'transsendreceive', component: SendReceiveTransComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
|
||||
{ path: 'translist', component: ListTransactionsComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
|
||||
{ path: 'payments', component: PaymentsComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
|
||||
{ path: 'paymentsendreceive', component: PaymentsComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
|
||||
{ path: 'queryroutes', component: QueryRoutesComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
|
||||
{ path: 'invoices', component: InvoicesComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
|
||||
{ path: 'switch', component: ForwardingHistoryComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
|
||||
{ path: 'routingpeers', component: RoutingPeersComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
|
||||
|
@ -8,7 +8,7 @@
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<div fxLayout="column" fxLayout.gt-sm="row wrap" fxFlex="100" fxLayoutAlign="space-between start">
|
||||
<h3 fxFlex="100">Backup folder location: {{this.selNode.settings.channelBackupPath}}</h3>
|
||||
<h4 fxFlex="100">Backup folder location: {{this.selNode.settings.channelBackupPath}}</h4>
|
||||
<button fxFlex="49" fxLayoutAlign="center center" mat-raised-button color="primary" tabindex="1" (click)="onBackupChannels({})">Backup</button>
|
||||
<button fxFlex="49" fxLayoutAlign="center center" mat-raised-button color="accent" tabindex="2" (click)="onVerifyChannels({})">Verify Backup</button>
|
||||
</div>
|
||||
|
@ -0,0 +1,79 @@
|
||||
<div fxLayout="column">
|
||||
<div class="padding-gap">
|
||||
<mat-card>
|
||||
<mat-card-header>
|
||||
<mat-card-subtitle>
|
||||
<h2>Query Routes</h2>
|
||||
</mat-card-subtitle>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-md="row wrap"
|
||||
(ngSubmit)="queryRoutesForm.form.valid && onQueryRoutes()" #queryRoutesForm="ngForm">
|
||||
<mat-form-field fxFlex="50" fxLayoutAlign="start end">
|
||||
<input matInput placeholder="Destination Pubkey" name="destinationPubkey" [(ngModel)]="destinationPubkey"
|
||||
tabindex="1" required #destPubkey="ngModel">
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="20" fxLayoutAlign="start end">
|
||||
<input matInput placeholder="Amount (Sats)" name="amount" [(ngModel)]="amount" tabindex="2" type="number"
|
||||
step="1000" min="0" required #destAmount="ngModel">
|
||||
</mat-form-field>
|
||||
<div fxFlex="15" fxLayoutAlign="start start">
|
||||
<button fxFlex="90" fxLayoutAlign="center center" mat-raised-button color="primary"
|
||||
[disabled]="destPubkey.invalid || destAmount.invalid" type="submit" tabindex="3">
|
||||
<p *ngIf="(destPubkey.invalid && (destPubkey.dirty || destPubkey.touched) || (destAmount.invalid && (destAmount.dirty || destAmount.touched))); else queryText">Invalid Pubkey/Amount
|
||||
</p>
|
||||
<ng-template #queryText>
|
||||
<p>Query</p>
|
||||
</ng-template>
|
||||
</button>
|
||||
</div>
|
||||
<div fxFlex="15" fxLayoutAlign="start start">
|
||||
<button fxFlex="90" fxLayoutAlign="center center" mat-raised-button color="accent" tabindex="4" type="reset"
|
||||
(click)="resetData()">Clear</button>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
<div class="padding-gap">
|
||||
<mat-card>
|
||||
<mat-card-content class="table-card-content">
|
||||
<div perfectScrollbar class="table-container mat-elevation-z8">
|
||||
<mat-progress-bar *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar>
|
||||
<table mat-table #table [dataSource]="qrHops" matSort
|
||||
[ngClass]="{'mat-elevation-z8 overflow-x-auto error-border': flgLoading[0]==='error','mat-elevation-z8 overflow-x-auto': true}">
|
||||
<ng-container matColumnDef="hop_sequence">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Hop </th>
|
||||
<td mat-cell *matCellDef="let hop"> {{hop?.hop_sequence}} </td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="pubkey_alias">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Node </th>
|
||||
<td mat-cell *matCellDef="let hop"> {{hop?.pubkey_alias}} </td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="chan_id">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Channel </th>
|
||||
<td mat-cell *matCellDef="let hop"> {{hop?.chan_id}} </td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="chan_capacity">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Capacity (sats) </th>
|
||||
<td mat-cell *matCellDef="let hop"><span fxLayoutAlign="end center"> {{hop?.chan_capacity | number}}
|
||||
</span></td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="amt_to_forward_msat">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Amount To Fwd (msats) </th>
|
||||
<td mat-cell *matCellDef="let hop"><span fxLayoutAlign="end center"> {{hop?.amt_to_forward_msat | number}}
|
||||
</span></td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="fee_msat">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Fee (msat) </th>
|
||||
<td mat-cell *matCellDef="let hop"><span fxLayoutAlign="end center"> {{hop?.fee_msat | number}} </span>
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;" (click)="onHopClick(row, $event)"></tr>
|
||||
</table>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,3 @@
|
||||
table {
|
||||
width:100%;
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { QueryRoutesComponent } from './query-routes.component';
|
||||
|
||||
describe('QueryRoutesComponent', () => {
|
||||
let component: QueryRoutesComponent;
|
||||
let fixture: ComponentFixture<QueryRoutesComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ QueryRoutesComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(QueryRoutesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
103
src/app/pages/payments/query-routes/query-routes.component.ts
Normal file
103
src/app/pages/payments/query-routes/query-routes.component.ts
Normal file
@ -0,0 +1,103 @@
|
||||
import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
|
||||
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil, take } from 'rxjs/operators';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Actions } from '@ngrx/effects';
|
||||
|
||||
import { MatTableDataSource, MatSort } from '@angular/material';
|
||||
import { Hop } from '../../../shared/models/lndModels';
|
||||
import { LoggerService } from '../../../shared/services/logger.service';
|
||||
|
||||
import { RTLEffects } from '../../../shared/store/rtl.effects';
|
||||
import * as RTLActions from '../../../shared/store/rtl.actions';
|
||||
import * as fromRTLReducer from '../../../shared/store/rtl.reducers';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-query-routes',
|
||||
templateUrl: './query-routes.component.html',
|
||||
styleUrls: ['./query-routes.component.scss']
|
||||
})
|
||||
export class QueryRoutesComponent implements OnInit, OnDestroy {
|
||||
@ViewChild(MatSort, { static: true }) sort: MatSort;
|
||||
public destinationPubkey = '';
|
||||
public amount = null;
|
||||
public qrHops: any;
|
||||
public flgSticky = false;
|
||||
public displayedColumns = [];
|
||||
public flgLoading: Array<Boolean | 'error'> = [false]; // 0: peers
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
|
||||
|
||||
constructor(private logger: LoggerService, private store: Store<fromRTLReducer.State>, private rtlEffects: RTLEffects, private actions$: Actions) {
|
||||
switch (true) {
|
||||
case (window.innerWidth <= 415):
|
||||
this.displayedColumns = ['hop_sequence', 'pubkey_alias', 'fee_msat'];
|
||||
break;
|
||||
case (window.innerWidth > 415 && window.innerWidth <= 730):
|
||||
this.displayedColumns = ['hop_sequence', 'pubkey_alias', 'chan_id', 'fee_msat'];
|
||||
break;
|
||||
case (window.innerWidth > 730 && window.innerWidth <= 1024):
|
||||
this.displayedColumns = ['hop_sequence', 'pubkey_alias', 'chan_id', 'chan_capacity', 'amt_to_forward_msat', 'fee_msat'];
|
||||
break;
|
||||
case (window.innerWidth > 1024 && window.innerWidth <= 1280):
|
||||
this.flgSticky = true;
|
||||
this.displayedColumns = ['hop_sequence', 'pubkey_alias', 'chan_id', 'chan_capacity', 'amt_to_forward_msat', 'fee_msat'];
|
||||
break;
|
||||
default:
|
||||
this.flgSticky = true;
|
||||
this.displayedColumns = ['hop_sequence', 'pubkey_alias', 'chan_id', 'chan_capacity', 'amt_to_forward_msat', 'fee_msat'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.store.select('rtlRoot')
|
||||
.pipe(takeUntil(this.unSubs[0]))
|
||||
.subscribe((rtlStore: fromRTLReducer.State) => {
|
||||
this.logger.info(rtlStore);
|
||||
});
|
||||
this.rtlEffects.setQueryRoutes
|
||||
.pipe(takeUntil(this.unSubs[1]))
|
||||
.subscribe(queryRoute => {
|
||||
this.qrHops = new MatTableDataSource([]);
|
||||
this.qrHops.data = [];
|
||||
if (undefined !== queryRoute.routes && undefined !== queryRoute.routes[0].hops) {
|
||||
this.flgLoading[0] = false;
|
||||
this.qrHops = new MatTableDataSource<Hop>([...queryRoute.routes[0].hops]);
|
||||
this.qrHops.data = queryRoute.routes[0].hops;
|
||||
} else {
|
||||
this.flgLoading[0] = 'error';
|
||||
}
|
||||
this.qrHops.sort = this.sort;
|
||||
});
|
||||
}
|
||||
|
||||
onQueryRoutes() {
|
||||
this.flgLoading[0] = true;
|
||||
this.store.dispatch(new RTLActions.GetQueryRoutes({destPubkey: this.destinationPubkey, amount: this.amount}));
|
||||
}
|
||||
|
||||
resetData() {
|
||||
this.destinationPubkey = '';
|
||||
this.amount = null;
|
||||
this.flgLoading[0] = false;
|
||||
}
|
||||
|
||||
onHopClick(selRow: Hop, event: any) {
|
||||
const selHop = this.qrHops.data.filter(hop => {
|
||||
return hop.hop_sequence === selRow.hop_sequence;
|
||||
})[0];
|
||||
const reorderedHop = JSON.parse(JSON.stringify(selHop, [
|
||||
'hop_sequence', 'pubkey_alias', 'pub_key', 'chan_id', 'chan_capacity', 'expiry', 'amt_to_forward', 'amt_to_forward_msat', 'fee_msat'
|
||||
] , 2));
|
||||
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { type: 'INFO', message: JSON.stringify(reorderedHop)}}));
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach(completeSub => {
|
||||
completeSub.next();
|
||||
completeSub.complete();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -5,14 +5,14 @@ import { takeUntil, take } from 'rxjs/operators';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
import { MatTableDataSource, MatSort } from '@angular/material';
|
||||
import { Node } from '../../shared/models/RTLconfig';
|
||||
import { GetInfo, Payment, PayRequest } from '../../shared/models/lndModels';
|
||||
import { LoggerService } from '../../shared/services/logger.service';
|
||||
import { Node } from '../../../shared/models/RTLconfig';
|
||||
import { GetInfo, Payment, PayRequest } from '../../../shared/models/lndModels';
|
||||
import { LoggerService } from '../../../shared/services/logger.service';
|
||||
|
||||
import { newlyAddedRowAnimation } from '../../shared/animation/row-animation';
|
||||
import { RTLEffects } from '../../shared/store/rtl.effects';
|
||||
import * as RTLActions from '../../shared/store/rtl.actions';
|
||||
import * as fromRTLReducer from '../../shared/store/rtl.reducers';
|
||||
import { newlyAddedRowAnimation } from '../../../shared/animation/row-animation';
|
||||
import { RTLEffects } from '../../../shared/store/rtl.effects';
|
||||
import * as RTLActions from '../../../shared/store/rtl.actions';
|
||||
import * as fromRTLReducer from '../../../shared/store/rtl.reducers';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-payments',
|
@ -7,7 +7,7 @@
|
||||
</mat-card-subtitle>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<form fxLayout="column" fxLayout.gt-sm="row wrap" (ngSubmit)="connectPeerForm.form.valid && onConnectPeer(connectPeerForm)" #connectPeerForm="ngForm">
|
||||
<form fxLayout="column" fxLayout.gt-sm="row wrap" (ngSubmit)="connectPeerForm.form.valid && onConnectPeer()" #connectPeerForm="ngForm">
|
||||
<mat-form-field fxFlex="70" fxLayoutAlign="start end">
|
||||
<input matInput placeholder="Lightning Address (pubkey OR pubkey@ip:port)" name="peerAddress" [(ngModel)]="peerAddress" tabindex="1" required #peerAdd="ngModel">
|
||||
</mat-form-field>
|
||||
|
@ -87,7 +87,7 @@ export class PeersComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
|
||||
onConnectPeer(form: any) {
|
||||
onConnectPeer() {
|
||||
this.flgAnimate = true;
|
||||
const pattern = '^([a-zA-Z0-9]){1,66}@(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):[0-9]+$';
|
||||
const deviderIndex = this.peerAddress.search('@');
|
||||
|
@ -280,6 +280,32 @@ export interface Peer {
|
||||
ping_time?: number;
|
||||
}
|
||||
|
||||
export interface QueryRoutes {
|
||||
routes?: Route[];
|
||||
}
|
||||
|
||||
export interface Hop {
|
||||
hop_sequence?: number;
|
||||
pubkey_alias?: string;
|
||||
chan_id?: string;
|
||||
chan_capacity?: string;
|
||||
amt_to_forward?: string;
|
||||
fee?: string;
|
||||
expiry?: number;
|
||||
amt_to_forward_msat?: string;
|
||||
fee_msat?: string;
|
||||
pub_key?: string;
|
||||
}
|
||||
|
||||
export interface Route {
|
||||
total_time_lock?: number;
|
||||
total_fees?: string;
|
||||
total_amt?: string;
|
||||
hops?: Hop[];
|
||||
total_fees_msat?: string;
|
||||
total_amt_msat?: string;
|
||||
}
|
||||
|
||||
export interface RouteHint {
|
||||
hop_hints?: HopHint[];
|
||||
}
|
||||
|
@ -17,7 +17,10 @@ export const MENU_DATA: MenuNode = {
|
||||
{id: 43, parentId: 4, name: 'Closed', icon: 'watch_later', link: '/chnlclosed'},
|
||||
{id: 44, parentId: 4, name: 'Backup', icon: 'cloud_circle', link: '/chnlbackup'}
|
||||
]},
|
||||
{id: 5, parentId: 0, name: 'Payments', icon: 'payment', link: '/payments'},
|
||||
{id: 5, parentId: 0, name: 'Payments', icon: 'payment', link: '/paymentsendreceive', children: [
|
||||
{id: 51, parentId: 5, name: 'Send/Receive', icon: 'compare_arrows', link: '/paymentsendreceive'},
|
||||
{id: 52, parentId: 5, name: 'Query Routes', icon: 'explore', link: '/queryroutes'}
|
||||
]},
|
||||
{id: 6, parentId: 0, name: 'Invoices', icon: 'receipt', link: '/invoices'},
|
||||
{id: 7, parentId: 0, name: 'Forwarding History', icon: 'timeline', link: '/switch'},
|
||||
{id: 8, parentId: 0, name: 'Routing Peers', icon: 'group_work', link: '/routingpeers'},
|
||||
|
@ -3,7 +3,7 @@ import { RTLConfiguration, Settings, Node } from '../models/RTLconfig';
|
||||
import { ErrorPayload } from '../models/errorPayload';
|
||||
import {
|
||||
GetInfo, Peer, Balance, NetworkInfo, Fees, Channel, Invoice, ListInvoices, Payment, GraphNode, AddressType,
|
||||
PayRequest, ChannelsTransaction, PendingChannels, ClosedChannel, Transaction, SwitchReq, SwitchRes
|
||||
PayRequest, ChannelsTransaction, PendingChannels, ClosedChannel, Transaction, SwitchReq, SwitchRes, QueryRoutes
|
||||
} from '../models/lndModels';
|
||||
import { MatDialogConfig } from '@angular/material';
|
||||
|
||||
@ -83,6 +83,8 @@ export const INVOICE_LOOKUP = 'INVOICE_LOOKUP';
|
||||
export const SET_LOOKUP = 'SET_LOOKUP';
|
||||
export const GET_FORWARDING_HISTORY = 'GET_FORWARDING_HISTORY';
|
||||
export const SET_FORWARDING_HISTORY = 'SET_FORWARDING_HISTORY';
|
||||
export const GET_QUERY_ROUTES = 'GET_QUERY_ROUTES';
|
||||
export const SET_QUERY_ROUTES = 'SET_QUERY_ROUTES';
|
||||
|
||||
export class ClearEffectError implements Action {
|
||||
readonly type = CLEAR_EFFECT_ERROR;
|
||||
@ -420,6 +422,16 @@ export class SetForwardingHistory implements Action {
|
||||
constructor(public payload: SwitchRes) {}
|
||||
}
|
||||
|
||||
export class GetQueryRoutes implements Action {
|
||||
readonly type = GET_QUERY_ROUTES;
|
||||
constructor(public payload: {destPubkey: string, amount: number}) {}
|
||||
}
|
||||
|
||||
export class SetQueryRoutes implements Action {
|
||||
readonly type = SET_QUERY_ROUTES;
|
||||
constructor(public payload: QueryRoutes) {}
|
||||
}
|
||||
|
||||
export class IsAuthorized implements Action {
|
||||
readonly type = IS_AUTHORIZED;
|
||||
constructor(public payload: string) {} // payload = password
|
||||
@ -461,7 +473,8 @@ export type RTLActions =
|
||||
FetchInvoices | SetInvoices | SetTotalInvoices |
|
||||
FetchPayments | SetPayments | SendPayment |
|
||||
DecodePayment | SetDecodedPayment |
|
||||
FetchGraphNode | SetGraphNode |
|
||||
GetNewAddress | SetNewAddress | SetChannelTransaction | GenSeed | GenSeedResponse | InitWallet | InitWalletResponse | UnlockWallet |
|
||||
FetchGraphNode | SetGraphNode | GetQueryRoutes | SetQueryRoutes |
|
||||
GetNewAddress | SetNewAddress | SetChannelTransaction |
|
||||
GenSeed | GenSeedResponse | InitWallet | InitWalletResponse | UnlockWallet |
|
||||
FetchConfig | ShowConfig | PeerLookup | ChannelLookup | InvoiceLookup | SetLookup |
|
||||
IsAuthorized | IsAuthorizedRes | Signin | Signout | InitAppData;
|
||||
|
@ -11,7 +11,7 @@ import { MatDialog } from '@angular/material';
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { LoggerService } from '../services/logger.service';
|
||||
import { Settings } from '../models/RTLconfig';
|
||||
import { GetInfo, Fees, Balance, NetworkInfo, Payment, Invoice, GraphNode, Transaction, SwitchReq, ListInvoices } from '../models/lndModels';
|
||||
import { GetInfo, Fees, Balance, NetworkInfo, Payment, GraphNode, Transaction, SwitchReq, ListInvoices } from '../models/lndModels';
|
||||
|
||||
import { SpinnerDialogComponent } from '../components/spinner-dialog/spinner-dialog.component';
|
||||
import { AlertMessageComponent } from '../components/alert-message/alert-message.component';
|
||||
@ -901,6 +901,42 @@ export class RTLEffects implements OnDestroy {
|
||||
})
|
||||
);
|
||||
|
||||
@Effect()
|
||||
queryRoutesFetch = this.actions$.pipe(
|
||||
ofType(RTLActions.GET_QUERY_ROUTES),
|
||||
mergeMap((action: RTLActions.GetQueryRoutes) => {
|
||||
return this.httpClient.get(environment.NETWORK_API + '/routes/' + action.payload.destPubkey + '/' + action.payload.amount)
|
||||
.pipe(
|
||||
map((qrRes: any) => {
|
||||
this.logger.info(qrRes);
|
||||
return {
|
||||
type: RTLActions.SET_QUERY_ROUTES,
|
||||
payload: qrRes
|
||||
};
|
||||
}),
|
||||
catchError((err: any) => {
|
||||
this.store.dispatch(new RTLActions.SetQueryRoutes({}));
|
||||
this.logger.error(err);
|
||||
return of(
|
||||
{
|
||||
type: RTLActions.OPEN_ALERT,
|
||||
payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Get Query Routes Failed',
|
||||
message: JSON.stringify({code: err.status, Message: err.error.error.error, URL: environment.NETWORK_API})}}
|
||||
}
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
));
|
||||
|
||||
@Effect({ dispatch: false })
|
||||
setQueryRoutes = this.actions$.pipe(
|
||||
ofType(RTLActions.SET_QUERY_ROUTES),
|
||||
map((action: RTLActions.SetQueryRoutes) => {
|
||||
return action.payload;
|
||||
})
|
||||
);
|
||||
|
||||
@Effect()
|
||||
genSeed = this.actions$.pipe(
|
||||
ofType(RTLActions.GEN_SEED),
|
||||
|
@ -3,7 +3,7 @@ import * as RTLActions from './rtl.actions';
|
||||
import { ErrorPayload } from '../models/errorPayload';
|
||||
import { RTLConfiguration, Node } from '../models/RTLconfig';
|
||||
import {
|
||||
GetInfo, GetInfoChain, Peer, AddressType, Fees, NetworkInfo, Balance, Channel, Payment, ListInvoices, PendingChannels, ClosedChannel, Transaction, SwitchRes
|
||||
GetInfo, GetInfoChain, Peer, AddressType, Fees, NetworkInfo, Balance, Channel, Payment, ListInvoices, PendingChannels, ClosedChannel, Transaction, SwitchRes, QueryRoutes
|
||||
} from '../models/lndModels';
|
||||
|
||||
export interface State {
|
||||
|
Loading…
Reference in New Issue
Block a user