Init wallet final

Init wallet final
pull/163/head
ShahanaFarooqui 5 years ago
parent 2216acebd4
commit 1fa8e16559

@ -125,6 +125,8 @@ THE SOFTWARE.
@angular/material/sort @angular/material/sort
@angular/material/stepper
@angular/material/table @angular/material/table
@angular/material/toolbar @angular/material/toolbar

@ -5,8 +5,8 @@
<title>RTL</title> <title>RTL</title>
<base href="/rtl/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <base href="/rtl/"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="assets/images/favicon.ico"> <link rel="icon" type="image/x-icon" href="assets/images/favicon.ico">
<link rel="stylesheet" href="styles.4ea35a27750bb09e5436.css"></head> <link rel="stylesheet" href="styles.83644e00292bcd08f710.css"></head>
<body> <body>
<rtl-app></rtl-app> <rtl-app></rtl-app>
<script type="text/javascript" src="runtime.26209474bfa8dc87a77c.js"></script><script type="text/javascript" src="polyfills.d68e8f4f73dfaef206f1.js"></script><script type="text/javascript" src="main.8018fd875c19dbad5d17.js"></script></body> <script type="text/javascript" src="runtime.26209474bfa8dc87a77c.js"></script><script type="text/javascript" src="polyfills.d68e8f4f73dfaef206f1.js"></script><script type="text/javascript" src="main.ba18f3e86d5ac8e29f3a.js"></script></body>
</html> </html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -24,28 +24,46 @@ common.getOptions = () => {
}; };
common.setOptions = () => { common.setOptions = () => {
if(common.nodes[0].options) { return; } if(undefined !== common.nodes[0].options && undefined !== common.nodes[0].options.headers) { return; }
common.nodes.forEach(node => { try {
node.options = { common.nodes.forEach(node => {
node.options = {
url: '',
rejectUnauthorized: false,
json: true,
headers: {
'Grpc-Metadata-macaroon': fs.readFileSync(node.macaroon_path + '/admin.macaroon').toString('hex'),
},
form: ''
};
});
// Options cannot be set before selected node initializes. Updating selected node's options separatly
common.selectedNode.options = {
url: '', url: '',
rejectUnauthorized: false, rejectUnauthorized: false,
json: true, json: true,
headers: { headers: {
'Grpc-Metadata-macaroon': fs.readFileSync(node.macaroon_path + '/admin.macaroon').toString('hex'), 'Grpc-Metadata-macaroon': fs.readFileSync(common.selectedNode.macaroon_path + '/admin.macaroon').toString('hex'),
}, },
form: '' form: ''
}; };
}); } catch(err) {
// Options cannot be set before selected node initializes. Updating selected node's options separatly common.nodes.forEach(node => {
common.selectedNode.options = { node.options = {
url: '', url: '',
rejectUnauthorized: false, rejectUnauthorized: false,
json: true, json: true,
headers: { form: ''
'Grpc-Metadata-macaroon': fs.readFileSync(common.selectedNode.macaroon_path + '/admin.macaroon').toString('hex'), };
}, });
form: '' // Options cannot be set before selected node initializes. Updating selected node's options separatly
}; common.selectedNode.options = {
url: '',
rejectUnauthorized: false,
json: true,
form: ''
};
}
} }
common.findNode = (selNodeIndex) => { common.findNode = (selNodeIndex) => {

@ -23,6 +23,7 @@ exports.getInfo = (req, res, next) => {
error: (undefined === body || search_idx > -1) ? 'Error From Server!' : body.error error: (undefined === body || search_idx > -1) ? 'Error From Server!' : body.error
}); });
} else { } else {
// res.status(200).json({});
res.status(200).json(body); res.status(200).json(body);
} }
}) })

@ -1,11 +1,11 @@
var request = require('request'); var request = require('request-promise');
var options = require("../connect"); var options = require("../connect");
var common = require('../common'); var common = require('../common');
exports.getGraphInfo = (req, res, next) => { exports.getGraphInfo = (req, res, next) => {
options = common.getOptions(); options = common.getOptions();
options.url = common.getSelLNDServerUrl() + '/graph/info'; options.url = common.getSelLNDServerUrl() + '/graph/info';
request.get(options, (error, response, body) => { request(options).then((body) => {
const body_str = (undefined === body) ? '' : JSON.stringify(body); const body_str = (undefined === body) ? '' : JSON.stringify(body);
const search_idx = (undefined === body) ? -1 : body_str.search('Not Found'); const search_idx = (undefined === body) ? -1 : body_str.search('Not Found');
if(undefined === body || search_idx > -1 || body.error) { if(undefined === body || search_idx > -1 || body.error) {

@ -1,30 +1,66 @@
var request = require('request'); var request = require('request-promise');
var common = require('../common'); var common = require('../common');
var atob = require('atob');
var logger = require('./logger'); var logger = require('./logger');
var options = {}; var options = {};
exports.genSeed = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNDServerUrl() + '/genseed';
if (undefined !== req.params.passphrase) {
options.form = JSON.stringify({aezeed_passphrase: atob(req.params.passphrase)});
}
request(options).then((body) => {
if(undefined === body || body.error) {
res.status(500).json({
message: "Genseed failed!",
error: (undefined === body) ? 'Error From Server!' : body.error
});
} else {
res.status(200).json(body);
}
})
.catch(function (err) {
return res.status(500).json({
message: "Genseed failed!",
error: err.error
});
});
}
exports.operateWallet = (req, res, next) => { exports.operateWallet = (req, res, next) => {
options = common.getOptions(); options = common.getOptions();
var requestBody = { options.method = 'POST';
wallet_password: Buffer.from(req.body.wallet_password).toString('base64') if (undefined === req.params.operation || req.params.operation === 'unlockwallet') {
};
if (undefined === req.params.operation || req.params.operation === 'unlock') {
options.url = common.getSelLNDServerUrl() + '/unlockwallet'; options.url = common.getSelLNDServerUrl() + '/unlockwallet';
options.form = JSON.stringify(requestBody); options.form = JSON.stringify({
wallet_password: Buffer.from(atob(req.body.wallet_password)).toString('base64')
});
err_message = 'Unlocking wallet failed! Verify that lnd is running and the wallet is locked!'; err_message = 'Unlocking wallet failed! Verify that lnd is running and the wallet is locked!';
} else { } else {
options.url = common.getSelLNDServerUrl() + '/initwallet'; options.url = common.getSelLNDServerUrl() + '/initwallet';
options.form = JSON.stringify(requestBody); if (undefined !== req.body.aezeed_passphrase && req.body.aezeed_passphrase !== '') {
options.form = JSON.stringify({
wallet_password: Buffer.from(atob(req.body.wallet_password)).toString('base64'),
cipher_seed_mnemonic: req.body.cipher_seed_mnemonic,
aezeed_passphrase: Buffer.from(atob(req.body.aezeed_passphrase)).toString('base64')
});
} else {
options.form = JSON.stringify({
wallet_password: Buffer.from(atob(req.body.wallet_password)).toString('base64'),
cipher_seed_mnemonic: req.body.cipher_seed_mnemonic
});
}
err_message = 'Initializing wallet failed!'; err_message = 'Initializing wallet failed!';
} }
request.post(options, (error, response, body) => { request(options).then((body) => {
logger.info('\r\nWallet: 20: ' + JSON.stringify(Date.now()) + ': INFO: Unlock Wallet Response: ' + JSON.stringify(body)); logger.info('\r\nWallet: 20: ' + JSON.stringify(Date.now()) + ': INFO: Wallet Response: ' + JSON.stringify(body));
const body_str = (undefined === body) ? '' : JSON.stringify(body); const body_str = (undefined === body) ? '' : JSON.stringify(body);
const search_idx = (undefined === body) ? -1 : body_str.search('Not Found'); const search_idx = (undefined === body) ? -1 : body_str.search('Not Found');
if(undefined === body) { if(undefined === body) {
res.status(500).json({ res.status(500).json({
message: err_message, message: err_message,
error: err_message error: (error) ? error : err_message
}); });
} else if(search_idx > -1) { } else if(search_idx > -1) {
res.status(500).json({ res.status(500).json({
@ -33,7 +69,7 @@ exports.operateWallet = (req, res, next) => {
}); });
} else if(body.error) { } else if(body.error) {
if((body.code === 1 && body.error === 'context canceled') || (body.code === 14 && body.error === 'transport is closing')) { if((body.code === 1 && body.error === 'context canceled') || (body.code === 14 && body.error === 'transport is closing')) {
res.status(201).json({wallet: 'successful'}); res.status(201).json('Successful');
} else { } else {
res.status(500).json({ res.status(500).json({
message: err_message, message: err_message,
@ -41,7 +77,13 @@ exports.operateWallet = (req, res, next) => {
}); });
} }
} else { } else {
res.status(201).json({wallet: 'successful'}); res.status(201).json('Successful');
} }
}).catch(error => {
console.log(error.message);
res.status(500).json({
message: err_message,
error: error.message
});
}); });
}; };

2
package-lock.json generated

@ -1,6 +1,6 @@
{ {
"name": "rtl", "name": "rtl",
"version": "0.3.3-beta", "version": "0.4.0-beta",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

@ -1,6 +1,6 @@
{ {
"name": "rtl", "name": "rtl",
"version": "0.3.3-beta", "version": "0.4.0-beta",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",

@ -3,6 +3,7 @@ const express = require("express");
const router = express.Router(); const router = express.Router();
const authCheck = require("./authCheck"); const authCheck = require("./authCheck");
router.get("/genseed/:passphrase?", authCheck, WalletController.genSeed);
router.post("/:operation", authCheck, WalletController.operateWallet); router.post("/:operation", authCheck, WalletController.operateWallet);
module.exports = router; module.exports = router;

@ -132,7 +132,7 @@ export class HomeComponent implements OnInit, OnDestroy {
this.flgLoading[6] = false; this.flgLoading[6] = false;
} }
this.totalPeers = rtlStore.peers.length; this.totalPeers = (rtlStore.peers !== null) ? rtlStore.peers.length : 0;
this.logger.info(rtlStore); this.logger.info(rtlStore);
}); });

@ -28,12 +28,12 @@
<div *ngIf="insecureLND && !warnRes"> <div *ngIf="insecureLND && !warnRes">
<form fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign="start" fxLayoutAlign.gt-sm="space-between" class="mt-2"> <form fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign="start" fxLayoutAlign.gt-sm="space-between" class="mt-2">
<div fxFlex="65" fxLayoutAlign="start" class="insecure-message">Warning: Your connection is unsecure, it's not safe to generate private keys over this connection.Are you sure you want to proceed?</div> <div fxFlex="65" fxLayoutAlign="start" class="insecure-message">Warning: Your connection is unsecure, it's not safe to generate private keys over this connection.Are you sure you want to proceed?</div>
<button mat-raised-button fxFlex="15" color="primary" (click)="proceed=true;warnRes=true" tabindex="4">Proceed</button> <button mat-raised-button fxFlex="15" color="primary" type="submit" (click)="proceed=true;warnRes=true" tabindex="4">Proceed</button>
<button fxFlex="15" fxLayoutAlign="center center" mat-raised-button color="accent" tabindex="5" type="reset" (click)="proceed=false;warnRes=true">Cancel</button> <button fxFlex="15" fxLayoutAlign="center center" mat-raised-button color="accent" tabindex="5" type="reset" (click)="proceed=false;warnRes=true">Cancel</button>
</form> </form>
</div> </div>
<div *ngIf="warnRes && !proceed" fxFlex="100" fxLayoutAlign="start" class="insecure-message mt-2">Please reconfig & restart RTL after securing your LND connction. You can close this window now.</div> <div *ngIf="warnRes && !proceed" fxFlex="100" fxLayoutAlign="start" class="insecure-message mt-2">Please reconfig & restart RTL after securing your LND connction. You can close this window now.</div>
<mat-vertical-stepper *ngIf="warnRes && proceed" [linear]="true" #stepper> <mat-vertical-stepper *ngIf="(!insecureLND || (warnRes && proceed)) && genSeedResponse.length <= 0 && initWalletResponse === ''" [linear]="true" #stepper>
<mat-step [stepControl]="passwordFormGroup" label="Wallet Password" state="password"> <mat-step [stepControl]="passwordFormGroup" label="Wallet Password" state="password">
<form [formGroup]="passwordFormGroup" fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign="start" fxLayoutAlign.gt-sm="space-between"> <form [formGroup]="passwordFormGroup" fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign="start" fxLayoutAlign.gt-sm="space-between">
<mat-form-field fxFlex="44" fxLayoutAlign="start"> <mat-form-field fxFlex="44" fxLayoutAlign="start">
@ -44,7 +44,7 @@
<input matInput type="password" placeholder="Confirm Password" name="initWalletConfirmPassword" formControlName="initWalletConfirmPassword" tabindex="7" required> <input matInput type="password" placeholder="Confirm Password" name="initWalletConfirmPassword" formControlName="initWalletConfirmPassword" tabindex="7" required>
<mat-hint>Confirm Wallet Password</mat-hint> <mat-hint>Confirm Wallet Password</mat-hint>
</mat-form-field> </mat-form-field>
<button mat-raised-button color="primary" fxFlex="10" [disabled]="!passwordFormGroup.valid" matStepperNext>Next</button> <button mat-raised-button color="primary" fxFlex="10" [disabled]="!passwordFormGroup.valid" type="submit" matStepperNext>Next</button>
<div *ngIf="passwordFormGroup.controls.initWalletPassword.errors?.minlength && (passwordFormGroup.controls.initWalletPassword.touched || passwordFormGroup.controls.initWalletPassword.dirty)" class="validation-error-message"> <div *ngIf="passwordFormGroup.controls.initWalletPassword.errors?.minlength && (passwordFormGroup.controls.initWalletPassword.touched || passwordFormGroup.controls.initWalletPassword.dirty)" class="validation-error-message">
<mat-icon class="validation-error-icon red">cancel</mat-icon>Password must be at least 8 characters in length. <mat-icon class="validation-error-icon red">cancel</mat-icon>Password must be at least 8 characters in length.
</div> </div>
@ -57,23 +57,26 @@
<form [formGroup]="cipherFormGroup" fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign="start" fxLayoutAlign.gt-sm="space-between"> <form [formGroup]="cipherFormGroup" fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign="start" fxLayoutAlign.gt-sm="space-between">
<mat-checkbox fxFlex="20" fxFlex.gt-lg="10" tabindex="8" fxLayoutAlign="start center" class="chkbox-wallet" formControlName="existingCipher" name="existingCipher">Existing Cipher</mat-checkbox> <mat-checkbox fxFlex="20" fxFlex.gt-lg="10" tabindex="8" fxLayoutAlign="start center" class="chkbox-wallet" formControlName="existingCipher" name="existingCipher">Existing Cipher</mat-checkbox>
<mat-form-field fxFlex="58" fxFlex.gt-lg="58" fxLayoutAlign="start"> <mat-form-field fxFlex="58" fxFlex.gt-lg="58" fxLayoutAlign="start">
<input matInput type="input" placeholder="Cipher seed" name="cipherSeed" formControlName="cipherSeed" tabindex="9" required> <input matInput type="input" placeholder="Comma separated array of 24 words cipher seed" name="cipherSeed" formControlName="cipherSeed" tabindex="9" required>
<mat-hint>Cipher Seed</mat-hint> <mat-hint>Cipher Seed</mat-hint>
</mat-form-field> </mat-form-field>
<button mat-raised-button color="primary" fxFlex="10" [disabled]="!cipherFormGroup.valid" matStepperNext>Next</button> <button mat-raised-button color="primary" fxFlex="10" [disabled]="!cipherFormGroup.valid" type="submit" matStepperNext>Next</button>
<button mat-raised-button color="accent" fxFlex="10" matStepperPrevious>Back</button> <button mat-raised-button color="accent" fxFlex="10" type="reset" matStepperPrevious>Back</button>
<div *ngIf="cipherFormGroup.errors?.invalidCipher && cipherFormGroup.controls.existingCipher.value && (cipherFormGroup.controls.cipherSeed.touched || cipherFormGroup.controls.cipherSeed.dirty)" class="validation-error-message">
<mat-icon class="validation-error-icon red">cancel</mat-icon>Invalid Cipher. Enter comma separated 24 words cipher seed.
</div>
</form> </form>
</mat-step> </mat-step>
<mat-step [stepControl]="passphraseFormGroup" label="Passphrase" state="passphrase"> <mat-step [stepControl]="passphraseFormGroup" label="Passphrase" state="passphrase">
<form [formGroup]="passphraseFormGroup" fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign="start" fxLayoutAlign.gt-sm="space-between"> <form [formGroup]="passphraseFormGroup" fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign="start" fxLayoutAlign.gt-sm="space-between">
<mat-checkbox fxFlex="20" fxFlex.gt-lg="10" tabindex="10" fxLayoutAlign="start center" class="chkbox-wallet" formControlName="enterPassphrase" name="enterPassphrase">Enter Passphrase</mat-checkbox> <mat-checkbox fxFlex="20" fxFlex.gt-lg="10" tabindex="10" fxLayoutAlign="start center" class="chkbox-wallet" formControlName="enterPassphrase" name="enterPassphrase">Enter Passphrase</mat-checkbox>
<mat-form-field fxFlex="43" fxFlex.gt-lg="58" fxLayoutAlign="start"> <mat-form-field fxFlex="40" fxFlex.gt-lg="50" fxLayoutAlign="start">
<input matInput type="input" placeholder="Passphrase" name="passphrase" formControlName="passphrase" tabindex="11" required> <input matInput type="input" type="password" placeholder="Passphrase" name="passphrase" formControlName="passphrase" tabindex="11" required>
<mat-hint>Enter Passphrase</mat-hint> <mat-hint>Enter Passphrase</mat-hint>
</mat-form-field> </mat-form-field>
<button mat-raised-button fxFlex="15" color="primary" [disabled]="!passphraseFormGroup.valid" (click)="onInitWallet()" tabindex="12">Initialize Wallet</button> <button mat-raised-button fxFlex="15" fxFlex.gt-lg="14" color="primary" [disabled]="!passphraseFormGroup.valid" (click)="onInitWallet()" tabindex="12" type="submit">Initialize Wallet</button>
<button mat-raised-button fxFlex="10" color="accent" matStepperPrevious>Back</button> <button mat-raised-button fxFlex="10" fxFlex.gt-lg="9" color="accent" type="button" matStepperPrevious>Back</button>
<button fxFlex="10" fxLayoutAlign="center center" mat-raised-button color="accent" tabindex="13" type="reset" (click)="resetData()">Clear</button> <button fxFlex="10" fxFlex.gt-lg="9" fxLayoutAlign="center center" mat-raised-button color="warn" tabindex="13" type="reset" (click)="resetData()">Clear</button>
</form> </form>
</mat-step> </mat-step>
<ng-template matStepperIcon="password"> <ng-template matStepperIcon="password">
@ -86,6 +89,33 @@
<mat-icon>waves</mat-icon> <mat-icon>waves</mat-icon>
</ng-template> </ng-template>
</mat-vertical-stepper> </mat-vertical-stepper>
<div *ngIf="genSeedResponse.length > 0 && initWalletResponse !== ''">
<form fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign="start" fxLayoutAlign.gt-sm="space-between" class="mt-2">
<div fxFlex="100" fxLayoutAlign="start" class="insecure-message blinker">YOU MUST WRITE DOWN THIS SEED TO BE ABLE TO RESTORE THE WALLET!</div>
<div fxFlex="40" fxLayout="row wrap" class="mt-2">
<span *ngFor="let genSeed of genSeedResponse; index as i;" fxFlex="25" fxLayoutAlign="start" class="genseed-message">
{{genSeed}}
</span>
</div>
<div fxFlex="65" fxLayoutAlign="start" class="insecure-message mt-2">Wallet initialization is done.</div>
<div fxFlex="65" fxLayoutAlign="start" class="insecure-message mt-2">The node will be usable only after LND has synced completely with the network.</div>
<div fxFlex="65" fxLayoutAlign="start" class="insecure-message mt-2">Click continue only after writing down the seed.</div>
<button mat-raised-button fxFlex="15" color="primary" type="submit" (click)="onGoToHome()" tabindex="14">Go To Home</button>
</form>
</div>
<div *ngIf="genSeedResponse.length > 0 && initWalletResponse === ''">
<form fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign="start" fxLayoutAlign.gt-sm="space-between" class="mt-2">
<div fxFlex="65" fxLayoutAlign="start" class="insecure-message mt-2">Something went wrong! Unable to initialize wallet!</div>
<button fxFlex="10" fxLayoutAlign="center center" mat-raised-button color="warn" tabindex="15" type="reset" (click)="resetData()">Restart</button>
</form>
</div>
<div *ngIf="genSeedResponse.length <= 0 && initWalletResponse !== ''">
<form fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign="start" fxLayoutAlign.gt-sm="space-between" class="mt-2">
<div fxFlex="65" fxLayoutAlign="start" class="insecure-message mt-2">Wallet recovery is done.</div>
<div fxFlex="65" fxLayoutAlign="start" class="insecure-message mt-2">The node will be usable only after LND has synced completely with the network.</div>
<button mat-raised-button fxFlex="15" color="primary" type="submit" (click)="onGoToHome()" tabindex="14">Go To Home</button>
</form>
</div>
</ng-template> </ng-template>
</div> </div>
</mat-card-content> </mat-card-content>

@ -1,3 +1,12 @@
.chkbox-wallet:focus { .chkbox-wallet:focus {
outline: none !important; outline: none !important;
} }
.blinker {
animation: blink-animation 1s steps(5, start) infinite;
-webkit-animation: blink-animation 1s steps(5, start) infinite;
}
@keyframes blink-animation { to { visibility: hidden; }}
@-webkit-keyframes blink-animation { to { visibility: hidden; }}

@ -1,11 +1,13 @@
import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators'; import { takeUntil, take } from 'rxjs/operators';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { FormBuilder, FormGroup, Validators, ValidatorFn, AbstractControl, ValidationErrors } from '@angular/forms'; import { FormBuilder, FormGroup, Validators, ValidatorFn, AbstractControl, ValidationErrors } from '@angular/forms';
import { STEPPER_GLOBAL_OPTIONS } from '@angular/cdk/stepper'; import { STEPPER_GLOBAL_OPTIONS } from '@angular/cdk/stepper';
import { MatStepper } from '@angular/material'; import { MatStepper } from '@angular/material';
import { RTLEffects } from '../../shared/store/rtl.effects';
import * as RTLActions from '../../shared/store/rtl.actions'; import * as RTLActions from '../../shared/store/rtl.actions';
import * as fromRTLReducer from '../../shared/store/rtl.reducers'; import * as fromRTLReducer from '../../shared/store/rtl.reducers';
@ -15,6 +17,13 @@ export const matchedPasswords: ValidatorFn = (control: FormGroup): ValidationErr
return initWalletPassword && initWalletConfirmPassword && initWalletPassword.value !== initWalletConfirmPassword.value ? { 'unmatchedPasswords': true } : null; return initWalletPassword && initWalletConfirmPassword && initWalletPassword.value !== initWalletConfirmPassword.value ? { 'unmatchedPasswords': true } : null;
}; };
export const cipherSeedLength: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
const existingCipher = control.get('existingCipher');
const cipherSeed = control.get('cipherSeed');
const cipherArr = cipherSeed.value.toString().trim().split(',');
return existingCipher.value && cipherArr && cipherArr.length !== 24 ? { 'invalidCipher': true } : null;
};
@Component({ @Component({
selector: 'rtl-unlock-lnd', selector: 'rtl-unlock-lnd',
templateUrl: './unlock-lnd.component.html', templateUrl: './unlock-lnd.component.html',
@ -26,21 +35,19 @@ export const matchedPasswords: ValidatorFn = (control: FormGroup): ValidationErr
export class UnlockLNDComponent implements OnInit, OnDestroy { export class UnlockLNDComponent implements OnInit, OnDestroy {
@ViewChild(MatStepper) stepper: MatStepper; @ViewChild(MatStepper) stepper: MatStepper;
public insecureLND = false; public insecureLND = false;
public genSeedResponse = [];
public initWalletResponse = '';
walletOperation = 'init'; walletOperation = 'init';
walletPassword = ''; walletPassword = '';
passwordFormGroup: FormGroup; passwordFormGroup: FormGroup;
cipherFormGroup: FormGroup; cipherFormGroup: FormGroup;
passphraseFormGroup: FormGroup; passphraseFormGroup: FormGroup;
private unsubs = [new Subject(), new Subject(), new Subject()]; private unsubs = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private store: Store<fromRTLReducer.State>, private formBuilder: FormBuilder) {} constructor(private store: Store<fromRTLReducer.State>, private formBuilder: FormBuilder, private rtlEffects: RTLEffects, private router: Router) {}
ngOnInit() { ngOnInit() {
this.walletPassword = ''; this.walletPassword = '';
// this.passwordFormGroup = this.formBuilder.group({
// initWalletPassword: ['', [Validators.required, Validators.minLength(8)]],
// initWalletConfirmPassword: ['', [Validators.required, Validators.minLength(8)]]
// }, {updateOn: 'blur', validators: matchedPasswords});
this.passwordFormGroup = this.formBuilder.group({ this.passwordFormGroup = this.formBuilder.group({
initWalletPassword: ['', [Validators.required, Validators.minLength(8)]], initWalletPassword: ['', [Validators.required, Validators.minLength(8)]],
initWalletConfirmPassword: ['', [Validators.required, Validators.minLength(8)]] initWalletConfirmPassword: ['', [Validators.required, Validators.minLength(8)]]
@ -48,7 +55,7 @@ export class UnlockLNDComponent implements OnInit, OnDestroy {
this.cipherFormGroup = this.formBuilder.group({ this.cipherFormGroup = this.formBuilder.group({
existingCipher: [false], existingCipher: [false],
cipherSeed: [{value: '', disabled: true}] cipherSeed: [{value: '', disabled: true}]
}); }, {validators: cipherSeedLength});
this.passphraseFormGroup = this.formBuilder.group({ this.passphraseFormGroup = this.formBuilder.group({
enterPassphrase: [false], enterPassphrase: [false],
passphrase: [{value: '', disabled: true}] passphrase: [{value: '', disabled: true}]
@ -74,11 +81,29 @@ export class UnlockLNDComponent implements OnInit, OnDestroy {
} }
}); });
this.store.select('rtlRoot') this.insecureLND = !window.location.protocol.includes('https://');
this.rtlEffects.initWalletRes
.pipe(takeUntil(this.unsubs[2])) .pipe(takeUntil(this.unsubs[2]))
.subscribe((rtlStore: fromRTLReducer.State) => { .subscribe(initWalletResponse => {
if (rtlStore.selNode.settings.lndServerUrl) { this.initWalletResponse = initWalletResponse;
this.insecureLND = rtlStore.selNode.settings.lndServerUrl.includes('https://'); });
this.rtlEffects.genSeedResponse
.pipe(takeUntil(this.unsubs[3]))
.subscribe(genSeedRes => {
this.genSeedResponse = genSeedRes;
if (this.passphraseFormGroup.controls.enterPassphrase.value) {
this.store.dispatch(new RTLActions.InitWallet({
pwd: window.btoa(this.passwordFormGroup.controls.initWalletPassword.value),
cipher: this.genSeedResponse,
passphrase: window.btoa(this.passphraseFormGroup.controls.passphrase.value)
}));
} else {
this.store.dispatch(new RTLActions.InitWallet({
pwd: window.btoa(this.passwordFormGroup.controls.initWalletPassword.value),
cipher: this.genSeedResponse
}));
} }
}); });
@ -86,18 +111,46 @@ export class UnlockLNDComponent implements OnInit, OnDestroy {
onOperateWallet() { onOperateWallet() {
this.store.dispatch(new RTLActions.OpenSpinner('Unlocking...')); this.store.dispatch(new RTLActions.OpenSpinner('Unlocking...'));
this.store.dispatch(new RTLActions.OperateWallet({operation: 'unlock', pwd: this.walletPassword})); this.store.dispatch(new RTLActions.UnlockWallet({pwd: window.btoa(this.walletPassword)}));
} }
onInitWallet() { onInitWallet() {
this.store.dispatch(new RTLActions.OpenSpinner('Initializing...')); this.store.dispatch(new RTLActions.OpenSpinner('Initializing...'));
// this.store.dispatch(new RTLActions.OperateWallet({operation: 'init', pwd: this.initWalletPassword})); if (this.cipherFormGroup.controls.existingCipher.value) {
const cipherArr = this.cipherFormGroup.controls.cipherSeed.value.toString().trim().split(',');
if (this.passphraseFormGroup.controls.enterPassphrase.value) {
this.store.dispatch(new RTLActions.InitWallet({
pwd: window.btoa(this.passwordFormGroup.controls.initWalletPassword.value),
cipher: cipherArr,
passphrase: window.btoa(this.passphraseFormGroup.controls.passphrase.value)
}));
} else {
this.store.dispatch(new RTLActions.InitWallet({
pwd: window.btoa(this.passwordFormGroup.controls.initWalletPassword.value),
cipher: cipherArr
}));
}
} else {
if (this.passphraseFormGroup.controls.enterPassphrase.value) {
this.store.dispatch(new RTLActions.GenSeed(window.btoa(this.passphraseFormGroup.controls.passphrase.value)));
} else {
this.store.dispatch(new RTLActions.GenSeed(''));
}
}
}
onGoToHome() {
setTimeout(() => {
this.store.dispatch(new RTLActions.InitAppData());
this.router.navigate(['/']);
}, 1000 * 1);
} }
resetData() { resetData() {
this.walletOperation = 'init'; this.walletOperation = 'init';
this.walletPassword = ''; this.walletPassword = '';
this.stepper.reset(); this.genSeedResponse = [];
this.initWalletResponse = '';
} }
ngOnDestroy() { ngOnDestroy() {

@ -61,7 +61,11 @@ export const SET_GRAPH_NODE = 'SET_GRAPH_NODE';
export const GET_NEW_ADDRESS = 'GET_NEW_ADDRESS'; export const GET_NEW_ADDRESS = 'GET_NEW_ADDRESS';
export const SET_NEW_ADDRESS = 'SET_NEW_ADDRESS'; export const SET_NEW_ADDRESS = 'SET_NEW_ADDRESS';
export const SET_CHANNEL_TRANSACTION = 'SET_CHANNEL_TRANSACTION'; export const SET_CHANNEL_TRANSACTION = 'SET_CHANNEL_TRANSACTION';
export const OPERATE_WALLET = 'OPERATE_WALLET'; export const GEN_SEED = 'GEN_SEED';
export const GEN_SEED_RESPONSE = 'GEN_SEED_RESPONSE';
export const INIT_WALLET = 'INIT_WALLET';
export const INIT_WALLET_RESPONSE = 'INIT_WALLET_RESPONSE';
export const UNLOCK_WALLET = 'UNLOCK_WALLET';
export const FETCH_CONFIG = 'FETCH_CONFIG'; export const FETCH_CONFIG = 'FETCH_CONFIG';
export const SHOW_CONFIG = 'SHOW_CONFIG'; export const SHOW_CONFIG = 'SHOW_CONFIG';
export const IS_AUTHORIZED = 'IS_AUTHORIZED'; export const IS_AUTHORIZED = 'IS_AUTHORIZED';
@ -327,9 +331,29 @@ export class SetChannelTransaction implements Action {
constructor(public payload: ChannelsTransaction) {} constructor(public payload: ChannelsTransaction) {}
} }
export class OperateWallet implements Action { export class GenSeed implements Action {
readonly type = OPERATE_WALLET; readonly type = GEN_SEED;
constructor(public payload: {operation: string, pwd: string}) {} constructor(public payload: string) {}
}
export class GenSeedResponse implements Action {
readonly type = GEN_SEED_RESPONSE;
constructor(public payload: Array<string>) {}
}
export class InitWallet implements Action {
readonly type = INIT_WALLET;
constructor(public payload: {pwd: string, cipher?: Array<string>, passphrase?: string}) {}
}
export class InitWalletResponse implements Action {
readonly type = INIT_WALLET_RESPONSE;
constructor(public payload: string) {}
}
export class UnlockWallet implements Action {
readonly type = UNLOCK_WALLET;
constructor(public payload: {pwd: string}) {}
} }
export class FetchConfig implements Action { export class FetchConfig implements Action {
@ -413,6 +437,6 @@ export type RTLActions =
FetchPayments | SetPayments | SendPayment | FetchPayments | SetPayments | SendPayment |
DecodePayment | SetDecodedPayment | DecodePayment | SetDecodedPayment |
FetchGraphNode | SetGraphNode | FetchGraphNode | SetGraphNode |
GetNewAddress | SetNewAddress | SetChannelTransaction | OperateWallet | GetNewAddress | SetNewAddress | SetChannelTransaction | GenSeed | GenSeedResponse | InitWallet | InitWalletResponse | UnlockWallet |
FetchConfig | ShowConfig | PeerLookup | ChannelLookup | InvoiceLookup | SetLookup | FetchConfig | ShowConfig | PeerLookup | ChannelLookup | InvoiceLookup | SetLookup |
IsAuthorized | IsAuthorizedRes | Signin | Signout | InitAppData; IsAuthorized | IsAuthorizedRes | Signin | Signout | InitAppData;

@ -835,11 +835,79 @@ export class RTLEffects implements OnDestroy {
}) })
); );
@Effect()
genSeed = this.actions$.pipe(
ofType(RTLActions.GEN_SEED),
mergeMap((action: RTLActions.GenSeed) => {
return this.httpClient.get(environment.WALLET_API + '/genseed/' + action.payload)
.pipe(
map((postRes: any) => {
this.logger.info('Generated GenSeed!');
this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner());
return {
type: RTLActions.GEN_SEED_RESPONSE,
payload: postRes.cipher_seed_mnemonic
};
}),
catchError((err) => {
this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: {type: 'ERROR', titleMessage: err.error.message + ' ' + err.error.error.code}}));
this.logger.error(err.error.error);
return of();
})
);
}
));
@Effect({ dispatch: false })
genSeedResponse = this.actions$.pipe(
ofType(RTLActions.GEN_SEED_RESPONSE),
map((action: RTLActions.GenSeedResponse) => {
return action.payload;
})
);
@Effect({ dispatch: false })
initWalletRes = this.actions$.pipe(
ofType(RTLActions.INIT_WALLET_RESPONSE),
map((action: RTLActions.InitWalletResponse) => {
return action.payload;
})
);
@Effect()
initWallet = this.actions$.pipe(
ofType(RTLActions.INIT_WALLET),
mergeMap((action: RTLActions.InitWallet) => {
return this.httpClient.post(environment.WALLET_API + '/initwallet',
{ wallet_password: action.payload.pwd,
cipher_seed_mnemonic: action.payload.cipher ? action.payload.cipher : '',
aezeed_passphrase: action.payload.passphrase ? action.payload.passphrase : '' })
.pipe(
map((postRes) => {
this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner());
return {
type: RTLActions.INIT_WALLET_RESPONSE,
payload: postRes
};
}),
catchError((err) => {
this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: {type: 'ERROR', titleMessage: err.error.error}}));
this.logger.error(err.error.error);
return of();
})
);
}
));
@Effect({ dispatch : false }) @Effect({ dispatch : false })
operateWallet = this.actions$.pipe( unlockWallet = this.actions$.pipe(
ofType(RTLActions.OPERATE_WALLET), ofType(RTLActions.UNLOCK_WALLET),
mergeMap((action: RTLActions.OperateWallet) => { mergeMap((action: RTLActions.UnlockWallet) => {
return this.httpClient.post(environment.WALLET_API + '/' + action.payload.operation, { wallet_password: action.payload.pwd }) return this.httpClient.post(environment.WALLET_API + '/unlockwallet', { wallet_password: action.payload.pwd })
.pipe( .pipe(
map((postRes) => { map((postRes) => {
this.logger.info(postRes); this.logger.info(postRes);

@ -87,6 +87,12 @@
left: 4px; left: 4px;
} }
.genseed-message {
width:10%;
color: mat-color($accent);
font-size: 120%;
}
.insecure-message { .insecure-message {
width:100%; width:100%;
color: mat-color($accent); color: mat-color($accent);
@ -96,4 +102,5 @@
.mat-vertical-content { .mat-vertical-content {
padding: 0 4px 0 12px; padding: 0 4px 0 12px;
} }
} }

@ -1 +1 @@
export const VERSION = '0.3.3-beta'; export const VERSION = '0.4.0-beta';
Loading…
Cancel
Save