mirror of
https://github.com/Ride-The-Lightning/RTL.git
synced 2025-02-20 13:34:43 +01:00
parent
d8835d2fcc
commit
d41e6d4a46
33 changed files with 400 additions and 16 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -9,8 +9,8 @@
|
|||
<link rel="icon" type="image/png" sizes="32x32" href="assets/images/favicon/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="assets/images/favicon/favicon-16x16.png">
|
||||
<link rel="manifest" href="assets/images/favicon/site.webmanifest">
|
||||
<link rel="stylesheet" href="styles.dc87b0a5f469f6ecc1b4.css"></head>
|
||||
<link rel="stylesheet" href="styles.e6b93e564e6b46dc016e.css"></head>
|
||||
<body>
|
||||
<rtl-app></rtl-app>
|
||||
<script src="runtime.987de13467a4c3a263de.js" defer></script><script src="polyfills-es5.37b2eeccc22c1df73ce7.js" nomodule defer></script><script src="polyfills.f1c3d2a0bcdfc4e93ca8.js" defer></script><script src="main.d1d565730bda0bc69787.js" defer></script></body>
|
||||
<script src="runtime.fd7f598087c4a68228d3.js" defer></script><script src="polyfills-es5.37b2eeccc22c1df73ce7.js" nomodule defer></script><script src="polyfills.f1c3d2a0bcdfc4e93ca8.js" defer></script><script src="main.ffc3e23c9362bb3a7234.js" defer></script></body>
|
||||
</html>
|
||||
|
|
File diff suppressed because one or more lines are too long
1
angular/main.ffc3e23c9362bb3a7234.js
Normal file
1
angular/main.ffc3e23c9362bb3a7234.js
Normal file
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],c=r[1],l=r[2],p=0,s=[];p<i.length;p++)a=i[p],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.push(o[a][0]),o[a]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,l||[]),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:"b78c4146e439be098e08",6:"1cabd441a095f3055cd4",7:"18eeb6e2c81e91aa476c"}[e]+".js"}(e);var c=new Error;u=function(r){i.onerror=i.onload=null,clearTimeout(l);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 l=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 l=0;l<i.length;l++)r(i[l]);var f=c;t()}([]);
|
||||
!function(e){function r(r){for(var n,a,i=r[0],c=r[1],f=r[2],p=0,s=[];p<i.length;p++)a=i[p],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.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);s.length;)s.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:"b78c4146e439be098e08",6:"f485795c2defda71fe9b",7:"ee799a9ee1d85d393fd3"}[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()}([]);
|
File diff suppressed because one or more lines are too long
1
angular/styles.e6b93e564e6b46dc016e.css
Normal file
1
angular/styles.e6b93e564e6b46dc016e.css
Normal file
File diff suppressed because one or more lines are too long
2
app.js
2
app.js
|
@ -26,6 +26,7 @@ const payReqRoutes = require("./routes/lnd/payReq");
|
|||
const paymentsRoutes = require("./routes/lnd/payments");
|
||||
const invoiceRoutes = require("./routes/lnd/invoices");
|
||||
const switchRoutes = require("./routes/lnd/switch");
|
||||
const messageRoutes = require("./routes/lnd/message");
|
||||
|
||||
const infoCLRoutes = require("./routes/c-lightning/getInfo");
|
||||
const feesCLRoutes = require("./routes/c-lightning/fees");
|
||||
|
@ -73,6 +74,7 @@ app.use(apiLNDRoot + "payreq", payReqRoutes);
|
|||
app.use(apiLNDRoot + "payments", paymentsRoutes);
|
||||
app.use(apiLNDRoot + "invoices", invoiceRoutes);
|
||||
app.use(apiLNDRoot + "switch", switchRoutes);
|
||||
app.use(apiLNDRoot + "message", messageRoutes);
|
||||
|
||||
app.use(apiCLRoot + "getinfo", infoCLRoutes);
|
||||
app.use(apiCLRoot + "fees", feesCLRoutes);
|
||||
|
|
57
controllers/lnd/message.js
Normal file
57
controllers/lnd/message.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
var request = require('request-promise');
|
||||
var common = require('../../common');
|
||||
var logger = require('../logger');
|
||||
var options = {};
|
||||
|
||||
exports.signMessage = (req, res, next) => {
|
||||
options = common.getOptions();
|
||||
options.url = common.getSelLNServerUrl() + '/signmessage';
|
||||
options.form = JSON.stringify({
|
||||
msg: Buffer.from(req.body.message).toString('base64')
|
||||
});
|
||||
request.post(options, (error, response, body) => {
|
||||
logger.info({fileName: 'Messages', msg: 'Message Signed: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
res.status(500).json({
|
||||
message: "Sign message failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
});
|
||||
} else {
|
||||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Messages', lineNum: 24, msg: 'Sign Message Failed: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Sign Message Failed!',
|
||||
error: err.error
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.verifyMessage = (req, res, next) => {
|
||||
options = common.getOptions();
|
||||
options.url = common.getSelLNServerUrl() + '/verifymessage';
|
||||
options.form = JSON.stringify({
|
||||
msg: Buffer.from(req.body.message).toString('base64'),
|
||||
signature: req.body.signature
|
||||
});
|
||||
request.post(options, (error, response, body) => {
|
||||
logger.info({fileName: 'Messages', msg: 'Message Verified: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
res.status(500).json({
|
||||
message: "Verify message failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
});
|
||||
} else {
|
||||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Messages', lineNum: 24, msg: 'Message Verification Failed: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Verify Message Failed!',
|
||||
error: err.error
|
||||
});
|
||||
});
|
||||
};
|
9
routes/lnd/message.js
Normal file
9
routes/lnd/message.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
const MessagesController = require("../../controllers/lnd/message");
|
||||
const express = require("express");
|
||||
const router = express.Router();
|
||||
const authCheck = require("../authCheck");
|
||||
|
||||
router.post("/sign", authCheck, MessagesController.signMessage);
|
||||
router.post("/verify", authCheck, MessagesController.verifyMessage);
|
||||
|
||||
module.exports = router;
|
|
@ -29,6 +29,9 @@ import { NodeLookupComponent } from './lookups/node-lookup/node-lookup.component
|
|||
import { BackupComponent } from './backup/backup.component';
|
||||
import { ChannelBackupTableComponent } from './backup/channel-backup-table/channel-backup-table.component';
|
||||
import { ChannelRestoreTableComponent } from './backup/channel-restore-table/channel-restore-table.component';
|
||||
import { SignVerifyMessageComponent } from './sign-verify-message/sign-verify-message.component';
|
||||
import { SignComponent } from './sign-verify-message/sign/sign.component';
|
||||
import { VerifyComponent } from './sign-verify-message/verify/verify.component';
|
||||
import { QueryRoutesComponent } from './transactions/query-routes/query-routes.component';
|
||||
import { ChannelOpenTableComponent } from './peers-channels/channels/channels-tables/channel-open-table/channel-open-table.component';
|
||||
import { UnlockWalletComponent } from './wallet/unlock/unlock.component';
|
||||
|
@ -69,8 +72,11 @@ import { LNDUnlockedGuard } from '../shared/services/auth.guard';
|
|||
NodeLookupComponent,
|
||||
BackupComponent,
|
||||
ChannelBackupTableComponent,
|
||||
QueryRoutesComponent,
|
||||
ChannelRestoreTableComponent,
|
||||
SignVerifyMessageComponent,
|
||||
SignComponent,
|
||||
VerifyComponent,
|
||||
QueryRoutesComponent,
|
||||
OnChainSendComponent,
|
||||
OnChainReceiveComponent,
|
||||
OnChainComponent,
|
||||
|
|
|
@ -10,10 +10,11 @@ import { LookupsComponent } from './lookups/lookups.component';
|
|||
import { RoutingComponent } from './routing/routing.component';
|
||||
import { OnChainComponent } from './on-chain/on-chain.component';
|
||||
import { NetworkInfoComponent } from './network-info/network-info.component';
|
||||
import { BackupComponent } from './backup/backup.component';
|
||||
import { SignVerifyMessageComponent } from './sign-verify-message/sign-verify-message.component';
|
||||
import { NotFoundComponent } from '../shared/components/not-found/not-found.component';
|
||||
|
||||
import { AuthGuard, LNDUnlockedGuard } from '../shared/services/auth.guard';
|
||||
import { NotFoundComponent } from '../shared/components/not-found/not-found.component';
|
||||
import { BackupComponent } from './backup/backup.component';
|
||||
|
||||
export const LndRoutes: Routes = [
|
||||
{ path: '', component: LNDRootComponent,
|
||||
|
@ -23,6 +24,7 @@ export const LndRoutes: Routes = [
|
|||
{ path: 'onchain', component: OnChainComponent, canActivate: [LNDUnlockedGuard] },
|
||||
{ path: 'peerschannels', component: PeersChannelsComponent, canActivate: [LNDUnlockedGuard] },
|
||||
{ path: 'transactions', component: TransactionsComponent, canActivate: [LNDUnlockedGuard] },
|
||||
{ path: 'signverify', component: SignVerifyMessageComponent, canActivate: [LNDUnlockedGuard] },
|
||||
{ path: 'backup', component: BackupComponent, canActivate: [LNDUnlockedGuard] },
|
||||
{ path: 'routing', component: RoutingComponent, canActivate: [LNDUnlockedGuard] },
|
||||
{ path: 'lookups', component: LookupsComponent, canActivate: [LNDUnlockedGuard] },
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
|
||||
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil, filter, take } from 'rxjs/operators';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<div fxLayout="row" fxLayoutAlign="start center" class="padding-gap-x page-title-container">
|
||||
<fa-icon [icon]="faUserCheck" class="page-title-img mr-1"></fa-icon>
|
||||
<span class="page-title">Sign/Verify Message</span>
|
||||
</div>
|
||||
<div fxLayout="column" class="padding-gap-x">
|
||||
<mat-card>
|
||||
<mat-card-content fxLayout="column">
|
||||
<mat-tab-group>
|
||||
<mat-tab label="Sign"><rtl-sign></rtl-sign></mat-tab>
|
||||
<mat-tab label="Verify"><rtl-verify></rtl-verify></mat-tab>
|
||||
</mat-tab-group>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SignVerifyMessageComponent } from './sign-verify-message.component';
|
||||
|
||||
describe('SignVerifyMessageComponent', () => {
|
||||
let component: SignVerifyMessageComponent;
|
||||
let fixture: ComponentFixture<SignVerifyMessageComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ SignVerifyMessageComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SignVerifyMessageComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,14 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { faUserCheck } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-sign-verify-message',
|
||||
templateUrl: './sign-verify-message.component.html',
|
||||
styleUrls: ['./sign-verify-message.component.scss']
|
||||
})
|
||||
export class SignVerifyMessageComponent {
|
||||
public faUserCheck = faUserCheck;
|
||||
|
||||
constructor() {}
|
||||
|
||||
}
|
16
src/app/lnd/sign-verify-message/sign/sign.component.html
Normal file
16
src/app/lnd/sign-verify-message/sign/sign.component.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch">
|
||||
<form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap" #form="ngForm">
|
||||
<mat-form-field fxFlex="100" fxLayoutAlign="start end">
|
||||
<textarea autoFocus matInput [(ngModel)]="message" rows="5" (focus)="signature=''" placeholder="Message" required tabindex="1" name="message"></textarea>
|
||||
<mat-error *ngIf="!message">Message is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<div fxLayout="column" fxFlex="100" fxLayoutAlign="start start" class="mt-1 bordered-box padding-gap-large">
|
||||
<p>{{signature}}</p>
|
||||
</div>
|
||||
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" class="mt-2">
|
||||
<button fxFlex="30" mat-stroked-button color="primary" tabindex="2" type="reset" (click)="resetData()" type="reset">Clear Field</button>
|
||||
<button fxFlex="30" mat-flat-button color="primary" (click)="onSign()" tabindex="3" type="submit">Sign</button>
|
||||
<button fxFlex="35" mat-flat-button color="primary" tabindex="4" rtlClipboard [payload]="signature" (copied)="onCopyField($event)" type="button">Copy Signature</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
6
src/app/lnd/sign-verify-message/sign/sign.component.scss
Normal file
6
src/app/lnd/sign-verify-message/sign/sign.component.scss
Normal file
|
@ -0,0 +1,6 @@
|
|||
.mat-column-channel_point {
|
||||
flex: 1 1 25%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
25
src/app/lnd/sign-verify-message/sign/sign.component.spec.ts
Normal file
25
src/app/lnd/sign-verify-message/sign/sign.component.spec.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SignComponent } from './sign.component';
|
||||
|
||||
describe('SignComponent', () => {
|
||||
let component: SignComponent;
|
||||
let fixture: ComponentFixture<SignComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ SignComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SignComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
44
src/app/lnd/sign-verify-message/sign/sign.component.ts
Normal file
44
src/app/lnd/sign-verify-message/sign/sign.component.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { MatSnackBar } from '@angular/material';
|
||||
|
||||
import { DataService } from '../../../shared/services/data.service';
|
||||
import { LoggerService } from '../../../shared/services/logger.service';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-sign',
|
||||
templateUrl: './sign.component.html',
|
||||
styleUrls: ['./sign.component.scss']
|
||||
})
|
||||
export class SignComponent implements OnInit, OnDestroy {
|
||||
public message = '';
|
||||
public signature = '';
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
|
||||
|
||||
constructor(private dataService: DataService, private snackBar: MatSnackBar, private logger: LoggerService) {}
|
||||
|
||||
ngOnInit() {}
|
||||
|
||||
onSign() {
|
||||
if (!this.message || this.message === '') { return true; }
|
||||
this.dataService.signMessage(this.message).pipe(takeUntil(this.unSubs[0])).subscribe(res => { this.signature = res; });
|
||||
}
|
||||
|
||||
onCopyField(payload: string) {
|
||||
this.snackBar.open('Signature copied.');
|
||||
this.logger.info('Copied Text: ' + payload);
|
||||
}
|
||||
|
||||
resetData() {
|
||||
this.message = '';
|
||||
this.signature = '';
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach(completeSub => {
|
||||
completeSub.next();
|
||||
completeSub.complete();
|
||||
});
|
||||
}
|
||||
}
|
19
src/app/lnd/sign-verify-message/verify/verify.component.html
Normal file
19
src/app/lnd/sign-verify-message/verify/verify.component.html
Normal file
|
@ -0,0 +1,19 @@
|
|||
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch">
|
||||
<form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap" #form="ngForm">
|
||||
<mat-form-field fxFlex="100" fxLayoutAlign="start end">
|
||||
<textarea autoFocus matInput [(ngModel)]="message" rows="5" (focus)="verifyRes=null" placeholder="Message" required tabindex="1" name="message"></textarea>
|
||||
<mat-error *ngIf="!message">Message is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="100" fxLayoutAlign="start end">
|
||||
<input matInput placeholder="Signature" name="signature" [(ngModel)]="signature" tabindex="2" required #sign="ngModel">
|
||||
<mat-error *ngIf="!signature">Signature is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<div fxLayout="column" fxFlex="100" fxLayoutAlign="start start" class="mt-1 bordered-box padding-gap-large" [ngClass]="{'border-valid': verifyRes?.valid, 'border-invalid': verifyRes?.pubkey && !verifyRes?.valid}">
|
||||
<p>{{!verifyRes?.pubkey ? '' : (verifyRes?.pubkey && verifyRes?.valid) ? 'Valid: ' : 'Invalid: '}}{{verifyRes?.pubkey}}</p>
|
||||
</div>
|
||||
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" class="mt-2">
|
||||
<button fxFlex="48" mat-stroked-button color="primary" tabindex="3" type="reset" (click)="resetData()" type="reset">Clear Field</button>
|
||||
<button fxFlex="48" mat-flat-button color="primary" (click)="onVerify()" tabindex="4" type="submit">Verify</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
|
@ -0,0 +1,6 @@
|
|||
.mat-column-channel_point {
|
||||
flex: 1 1 25%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { VerifyComponent } from './verify.component';
|
||||
|
||||
describe('VerifyComponent', () => {
|
||||
let component: VerifyComponent;
|
||||
let fixture: ComponentFixture<VerifyComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ VerifyComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(VerifyComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
39
src/app/lnd/sign-verify-message/verify/verify.component.ts
Normal file
39
src/app/lnd/sign-verify-message/verify/verify.component.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { DataService } from '../../../shared/services/data.service';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-verify',
|
||||
templateUrl: './verify.component.html',
|
||||
styleUrls: ['./verify.component.scss']
|
||||
})
|
||||
export class VerifyComponent implements OnInit, OnDestroy {
|
||||
public message = '';
|
||||
public signature = '';
|
||||
public verifyRes = {pubkey: '', valid: null};
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
|
||||
|
||||
constructor(private dataService: DataService) {}
|
||||
|
||||
ngOnInit() {}
|
||||
|
||||
onVerify() {
|
||||
if ((!this.message || this.message === '') || (!this.signature || this.signature === '')) { return true; }
|
||||
this.dataService.verifyMessage(this.message, this.signature).pipe(takeUntil(this.unSubs[0])).subscribe(res => { this.verifyRes = res; });
|
||||
}
|
||||
|
||||
resetData() {
|
||||
this.message = '';
|
||||
this.signature = '';
|
||||
this.verifyRes = null;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach(completeSub => {
|
||||
completeSub.next();
|
||||
completeSub.complete();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@
|
|||
<mat-card-content class="mt-5px">
|
||||
<form fxLayout="column">
|
||||
<div fxLayout="column" class="bordered-box my-2 p-2">
|
||||
<p fxLayoutAlign="start center" class="pb-1">Closing channel: {{channelToClose.channel_point}}</p>
|
||||
<p fxLayoutAlign="start center" class="pb-1 word-break">Closing channel: {{channelToClose.channel_point}}</p>
|
||||
<div fxLayoutAlign="space-between center">
|
||||
<mat-form-field fxFlex.gt-sm="48">
|
||||
<mat-select [(value)]="selTransType" tabindex="1">
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { faTachometerAlt, faLink, faBolt, faExchangeAlt, faUsers, faMapSigns, faQuestion, faSearch, faTools, faProjectDiagram, faDownload, faServer, faPercentage } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faTachometerAlt, faLink, faBolt, faExchangeAlt, faUsers, faMapSigns, faQuestion, faSearch, faTools, faProjectDiagram, faDownload, faServer, faPercentage, faUserCheck } from '@fortawesome/free-solid-svg-icons';
|
||||
import { UserPersonaEnum } from '../services/consts-enums-functions';
|
||||
|
||||
export const MENU_DATA: MenuRootNode = {
|
||||
|
@ -10,7 +10,8 @@ export const MENU_DATA: MenuRootNode = {
|
|||
{id: 32, parentId: 3, name: 'Transactions', iconType: 'FA', icon: faExchangeAlt, link: '/lnd/transactions', userPersona: UserPersonaEnum.ALL},
|
||||
{id: 33, parentId: 3, name: 'Routing', iconType: 'FA', icon: faMapSigns, link: '/lnd/routing', userPersona: UserPersonaEnum.ALL},
|
||||
{id: 34, parentId: 3, name: 'Graph Lookup', iconType: 'FA', icon: faSearch, link: '/lnd/lookups', userPersona: UserPersonaEnum.ALL},
|
||||
{id: 35, parentId: 3, name: 'Backup', iconType: 'FA', icon: faDownload, link: '/lnd/backup', userPersona: UserPersonaEnum.ALL}
|
||||
{id: 35, parentId: 3, name: 'Sign/Verify', iconType: 'FA', icon: faUserCheck, link: '/lnd/signverify', userPersona: UserPersonaEnum.ALL},
|
||||
{id: 36, parentId: 3, name: 'Backup', iconType: 'FA', icon: faDownload, link: '/lnd/backup', userPersona: UserPersonaEnum.ALL}
|
||||
]},
|
||||
{id: 5, parentId: 0, name: 'Network', iconType: 'FA', icon: faProjectDiagram, link: '/lnd/network', userPersona: UserPersonaEnum.OPERATOR},
|
||||
{id: 6, parentId: 0, name: 'Node/Network', iconType: 'FA', icon: faServer, link: '/lnd/network', userPersona: UserPersonaEnum.MERCHANT},
|
||||
|
|
|
@ -2,14 +2,21 @@ import { Injectable, OnInit, OnDestroy } from '@angular/core';
|
|||
import { HttpClient } from '@angular/common/http';
|
||||
import { Subject, of, Observable } from 'rxjs';
|
||||
import { take, map, takeUntil, catchError } from 'rxjs/operators';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
import { LoggerService } from '../../shared/services/logger.service';
|
||||
import { environment, API_URL } from '../../../environments/environment';
|
||||
|
||||
import * as RTLActions from '../../store/rtl.actions';
|
||||
import * as fromRTLReducer from '../../store/rtl.reducers';
|
||||
import { ErrorMessageComponent } from '../components/data-modal/error-message/error-message.component';
|
||||
|
||||
@Injectable()
|
||||
export class DataService implements OnInit, OnDestroy {
|
||||
private CHILD_API_URL = API_URL + '/lnd';
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
|
||||
|
||||
constructor(private httpClient: HttpClient) {}
|
||||
constructor(private httpClient: HttpClient, private store: Store<fromRTLReducer.RTLState>, private logger: LoggerService,) {}
|
||||
|
||||
ngOnInit() {}
|
||||
|
||||
|
@ -29,6 +36,62 @@ export class DataService implements OnInit, OnDestroy {
|
|||
return nodes$;
|
||||
}
|
||||
|
||||
signMessage(msg: string) {
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Signing Message...'));
|
||||
return this.httpClient.post(this.CHILD_API_URL + environment.MESSAGE_API + '/sign', {message: msg})
|
||||
.pipe(takeUntil(this.unSubs[1]),
|
||||
map((res: any) => {
|
||||
this.store.dispatch(new RTLActions.CloseSpinner());
|
||||
return res.signature;
|
||||
}),
|
||||
catchError(err => {
|
||||
this.handleErrorWithAlert('ERROR', 'Sign Message Failed', this.CHILD_API_URL + environment.MESSAGE_API + '/sign', err);
|
||||
throw err;
|
||||
}));
|
||||
}
|
||||
|
||||
verifyMessage(msg: string, sign: string) {
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Verifying Message...'));
|
||||
return this.httpClient.post(this.CHILD_API_URL + environment.MESSAGE_API + '/verify', {message: msg, signature: sign})
|
||||
.pipe(takeUntil(this.unSubs[2]),
|
||||
map((res: any) => {
|
||||
this.store.dispatch(new RTLActions.CloseSpinner());
|
||||
return res;
|
||||
}),
|
||||
catchError(err => {
|
||||
this.handleErrorWithAlert('ERROR', 'Verify Message Failed', this.CHILD_API_URL + environment.MESSAGE_API + '/verify', err);
|
||||
throw err;
|
||||
}));
|
||||
}
|
||||
|
||||
handleErrorWithoutAlert(actionName: string, err: { status: number, error: any }) {
|
||||
this.logger.error('ERROR IN: ' + actionName + '\n' + JSON.stringify(err));
|
||||
if (err.status === 401) {
|
||||
this.logger.info('Redirecting to Login');
|
||||
this.store.dispatch(new RTLActions.Logout());
|
||||
} else {
|
||||
this.store.dispatch(new RTLActions.EffectErrorLnd({ action: actionName, code: err.status.toString(), message: err.error.error }));
|
||||
}
|
||||
}
|
||||
|
||||
handleErrorWithAlert(alertType: string, alertTitle: string, errURL: string, err: { status: number, error: any }) {
|
||||
this.logger.error(err);
|
||||
if (err.status === 401) {
|
||||
this.logger.info('Redirecting to Login');
|
||||
this.store.dispatch(new RTLActions.Logout());
|
||||
} else {
|
||||
this.store.dispatch(new RTLActions.CloseSpinner());
|
||||
this.store.dispatch(new RTLActions.OpenAlert({
|
||||
data: {
|
||||
type: alertType,
|
||||
alertTitle: alertTitle,
|
||||
message: { code: err.status, message: err.error.error, URL: errURL },
|
||||
component: ErrorMessageComponent
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach(completeSub => {
|
||||
completeSub.next();
|
||||
|
|
|
@ -391,6 +391,7 @@
|
|||
border: 1px solid $foreground-divider;
|
||||
border-radius: 4px;
|
||||
background: none;
|
||||
min-height: 5.5rem;
|
||||
}
|
||||
|
||||
.mat-expansion-panel {
|
||||
|
|
|
@ -961,3 +961,11 @@ table {
|
|||
overflow-y: scroll;
|
||||
max-height: 600px;
|
||||
}
|
||||
|
||||
.border-valid {
|
||||
border: 1px solid $green-color !important;
|
||||
}
|
||||
|
||||
.border-invalid {
|
||||
border: 1px solid $red-color !important;
|
||||
}
|
||||
|
|
|
@ -22,5 +22,6 @@ export const environment = {
|
|||
INVOICES_API: '/invoices',
|
||||
SWITCH_API: '/switch',
|
||||
ON_CHAIN_API: '/onchain',
|
||||
MESSAGE_API: '/message',
|
||||
VERSION: VERSION
|
||||
};
|
||||
|
|
|
@ -22,5 +22,6 @@ export const environment = {
|
|||
INVOICES_API: '/invoices',
|
||||
SWITCH_API: '/switch',
|
||||
ON_CHAIN_API: '/onchain',
|
||||
MESSAGE_API: '/message',
|
||||
VERSION: VERSION
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue