Commit 9b283a06 authored by Pieterjan Vanhoof's avatar Pieterjan Vanhoof Committed by GitHub

Switch to Breeze.Api data (#42)

- Switched wallet interface to real API data
- Added basic validation
- Updated Angular
parents 8094747b 4f8265ed
...@@ -22,67 +22,67 @@ ...@@ -22,67 +22,67 @@
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/animations": "^4.0.1", "@angular/animations": "^4.1.0",
"@angular/common": "^4.0.1", "@angular/common": "^4.1.0",
"@angular/compiler": "^4.0.1", "@angular/compiler": "^4.1.0",
"@angular/compiler-cli": "^4.0.1", "@angular/compiler-cli": "^4.1.0",
"@angular/core": "^4.0.1", "@angular/core": "^4.1.0",
"@angular/forms": "^4.0.1", "@angular/forms": "^4.1.0",
"@angular/http": "^4.0.1", "@angular/http": "^4.1.0",
"@angular/platform-browser": "^4.0.1", "@angular/platform-browser": "^4.1.0",
"@angular/platform-browser-dynamic": "^4.0.1", "@angular/platform-browser-dynamic": "^4.1.0",
"@angular/platform-server": "^4.0.1", "@angular/platform-server": "^4.1.0",
"@angular/router": "^4.0.1", "@angular/router": "^4.1.0",
"bootstrap": "^4.0.0-alpha.6", "bootstrap": "^4.0.0-alpha.6",
"core-js": "^2.4.1", "core-js": "^2.4.1",
"rxjs": "^5.2.0", "rxjs": "^5.3.0",
"zone.js": "^0.8.5" "zone.js": "^0.8.9"
}, },
"devDependencies": { "devDependencies": {
"@angular/cli": "^1.0.0", "@angular/cli": "^1.0.1",
"@angular/compiler-cli": "^4.0.1", "@angular/compiler-cli": "^4.1.0",
"@types/electron": "^1.4.35", "@types/electron": "^1.4.37",
"@types/jasmine": "2.5.46", "@types/jasmine": "2.5.47",
"@types/node": "~7.0.12", "@types/node": "~7.0.15",
"autoprefixer": "^6.5.3", "autoprefixer": "^6.7.7",
"codelyzer": "~2.0.0", "codelyzer": "3.0.1",
"concurrently": "^3.4.0", "concurrently": "^3.4.0",
"copy-webpack-plugin": "^4.0.1", "copy-webpack-plugin": "4.0.1",
"css-loader": "^0.26.1", "css-loader": "^0.28.1",
"cssnano": "^3.10.0", "cssnano": "^3.10.0",
"electron": "^1.6.2", "electron": "^1.6.6",
"electron-packager": "^8.6.0", "electron-packager": "^8.7.0",
"exports-loader": "^0.6.3", "exports-loader": "^0.6.4",
"extract-text-webpack-plugin": "^2.1.0", "extract-text-webpack-plugin": "^2.1.0",
"file-loader": "^0.10.0", "file-loader": "^0.11.1",
"html-webpack-plugin": "^2.28.0", "html-webpack-plugin": "^2.28.0",
"istanbul-instrumenter-loader": "^2.0.0", "istanbul-instrumenter-loader": "^2.0.0",
"jasmine-core": "~2.5.2", "jasmine-core": "~2.6.1",
"jasmine-spec-reporter": "~3.2.0", "jasmine-spec-reporter": "~4.1.0",
"json-loader": "^0.5.4", "json-loader": "^0.5.4",
"karma": "~1.5.0", "karma": "~1.6.0",
"karma-chrome-launcher": "~2.0.0", "karma-chrome-launcher": "~2.0.0",
"karma-cli": "~1.0.1", "karma-cli": "~1.0.1",
"karma-coverage-istanbul-reporter": "^1.0.0", "karma-coverage-istanbul-reporter": "^1.2.1",
"karma-electron": "^5.1.1", "karma-electron": "^5.1.1",
"karma-jasmine": "~1.1.0", "karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2", "karma-jasmine-html-reporter": "^0.2.2",
"karma-sourcemap-loader": "^0.3.7", "karma-sourcemap-loader": "^0.3.7",
"less-loader": "^2.2.3", "less-loader": "^4.0.3",
"postcss-loader": "^0.13.0", "postcss-loader": "^1.3.3",
"postcss-url": "^5.1.2", "postcss-url": "^6.0.4",
"protractor": "~5.1.1", "protractor": "~5.1.1",
"raw-loader": "^0.5.1", "raw-loader": "^0.5.1",
"sass-loader": "^4.1.1", "sass-loader": "^6.0.3",
"script-loader": "^0.7.0", "script-loader": "^0.7.0",
"source-map-loader": "^0.1.5", "source-map-loader": "^0.2.1",
"style-loader": "^0.13.1", "style-loader": "^0.17.0",
"stylus-loader": "^2.4.0", "stylus-loader": "^3.0.1",
"ts-node": "~3.0.2", "ts-node": "~3.0.2",
"tslint": "~4.5.1", "tslint": "~5.1.0",
"typescript": "^2.2.2", "typescript": "^2.3.2",
"url-loader": "^0.5.7", "url-loader": "^0.5.8",
"webpack": "^2.3.2", "webpack": "^2.4.1",
"webpack-dev-server": "~2.3.0" "webpack-dev-server": "~2.4.5"
} }
} }
...@@ -46,7 +46,7 @@ export class LoginComponent implements OnInit { ...@@ -46,7 +46,7 @@ export class LoginComponent implements OnInit {
} }
private setGlobalWalletName(walletName: string) { private setGlobalWalletName(walletName: string) {
this.globalService.setCurrentWalletName(walletName); this.globalService.setWalletName(walletName);
} }
private getWalletFiles() { private getWalletFiles() {
...@@ -82,9 +82,10 @@ export class LoginComponent implements OnInit { ...@@ -82,9 +82,10 @@ export class LoginComponent implements OnInit {
this.apiService.loadWallet(walletLoad) this.apiService.loadWallet(walletLoad)
.subscribe( .subscribe(
response => { response => {
console.log(response);
if (response.status >= 200 && response.status < 400) { if (response.status >= 200 && response.status < 400) {
let responseMessage = response.json(); let responseMessage = response.json();
this.globalService.setWalletName(walletLoad.name)
this.globalService.setCoinType(0);
this.router.navigate(['/wallet']); this.router.navigate(['/wallet']);
} }
}, },
......
...@@ -6,10 +6,12 @@ ...@@ -6,10 +6,12 @@
<div class="form-group"> <div class="form-group">
<label>Name:</label> <label>Name:</label>
<input class="form-control" formControlName="walletName" type="text" placeholder="Enter a name for your wallet."> <input class="form-control" formControlName="walletName" type="text" placeholder="Enter a name for your wallet.">
<div *ngIf="formErrors.walletName" class="alert alert-danger">{{formErrors.walletName}}</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>Password:</label> <label>Password:</label>
<input class="form-control" formControlName="walletPassword" type="password" placeholder="Enter a password for your wallet."> <input class="form-control" formControlName="walletPassword" type="password" placeholder="Enter a password for your wallet.">
<div *ngIf="formErrors.walletPassword" class="alert alert-danger">{{formErrors.walletPassword}}</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>Network:</label> <label>Network:</label>
......
...@@ -16,11 +16,7 @@ import { Mnemonic } from '../../shared/classes/mnemonic'; ...@@ -16,11 +16,7 @@ import { Mnemonic } from '../../shared/classes/mnemonic';
export class CreateComponent { export class CreateComponent {
constructor(private globalService: GlobalService, private apiService: ApiService, private router: Router, private fb: FormBuilder) { constructor(private globalService: GlobalService, private apiService: ApiService, private router: Router, private fb: FormBuilder) {
this.createWalletForm = fb.group({ this.buildCreateForm();
"walletName": ["", Validators.required],
"walletPassword": ["", Validators.required],
"selectNetwork": ["main", Validators.required]
});
} }
private createWalletForm: FormGroup; private createWalletForm: FormGroup;
...@@ -29,6 +25,55 @@ export class CreateComponent { ...@@ -29,6 +25,55 @@ export class CreateComponent {
private responseMessage: string; private responseMessage: string;
private errorMessage: string; private errorMessage: string;
private buildCreateForm(): void {
this.createWalletForm = this.fb.group({
"walletName": ["", [
Validators.required,
Validators.minLength(3),
Validators.maxLength(24)
]
],
"walletPassword": ["", Validators.required],
"selectNetwork": ["main", Validators.required]
});
this.createWalletForm.valueChanges
.subscribe(data => this.onValueChanged(data));
this.onValueChanged();
}
onValueChanged(data?: any) {
if (!this.createWalletForm) { return; }
const form = this.createWalletForm;
for (const field in this.formErrors) {
this.formErrors[field] = '';
const control = form.get(field);
if (control && control.dirty && !control.valid) {
const messages = this.validationMessages[field];
for (const key in control.errors) {
this.formErrors[field] += messages[key] + ' ';
}
}
}
}
formErrors = {
'walletName': '',
'walletPassword': ''
};
validationMessages = {
'walletName': {
'required': 'Name is required.',
'minlength': 'Name must be at least 3 characters long.',
'maxlength': 'Name cannot be more than 24 characters long.'
},
'walletPassword': {
'required': 'A password is required.'
}
};
private onBackClicked() { private onBackClicked() {
this.router.navigate(["/setup"]); this.router.navigate(["/setup"]);
} }
......
export class WalletInfo {
constructor(walletName: string, coinType: number) {
this.walletName = walletName;
this.coinType = coinType;
}
public walletName: string;
public coinType: number;
}
...@@ -6,7 +6,7 @@ export class WalletLoad { ...@@ -6,7 +6,7 @@ export class WalletLoad {
this.name = name; this.name = name;
} }
private password: string; public password: string;
private folderPath: string; public folderPath: string;
private name: string; public name: string;
} }
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Http, Headers, Response } from '@angular/http'; import { Http, Headers, Response, RequestOptions, URLSearchParams} from '@angular/http';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map'; import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch'; import 'rxjs/add/operator/catch';
...@@ -7,6 +7,7 @@ import 'rxjs/add/operator/catch'; ...@@ -7,6 +7,7 @@ import 'rxjs/add/operator/catch';
import { WalletCreation } from '../classes/wallet-creation'; import { WalletCreation } from '../classes/wallet-creation';
import { WalletRecovery } from '../classes/wallet-recovery'; import { WalletRecovery } from '../classes/wallet-recovery';
import { WalletLoad } from '../classes/wallet-load'; import { WalletLoad } from '../classes/wallet-load';
import { WalletInfo } from '../classes/wallet-info';
import { Mnemonic } from '../classes/mnemonic'; import { Mnemonic } from '../classes/mnemonic';
/** /**
...@@ -62,34 +63,47 @@ export class ApiService { ...@@ -62,34 +63,47 @@ export class ApiService {
*/ */
getWalletStatus(): Observable<any> { getWalletStatus(): Observable<any> {
return this.http return this.http
.get(this.mockApiUrl + '/wallet/status') .get(this.webApiUrl + '/wallet/status')
.map((response: Response) => response); .map((response: Response) => response);
} }
/** /**
* Get wallet balance info from the API. * Get wallet balance info from the API.
*/ */
getWalletBalance(): Observable<any> { getWalletBalance(data: WalletInfo): Observable<any> {
let params: URLSearchParams = new URLSearchParams();
params.set('walletName', data.walletName);
params.set('coinType', data.coinType.toString());
return this.http return this.http
.get(this.mockApiUrl + '/wallet/balance') .get(this.webApiUrl + '/wallet/balance', new RequestOptions({headers: this.headers, search: params}))
.map((response: Response) => response); .map((response: Response) => response);
} }
/** /**
* Get a wallets transaction history info from the API. * Get a wallets transaction history info from the API.
*/ */
getWalletHistory(): Observable<any> { getWalletHistory(data: WalletInfo): Observable<any> {
let params: URLSearchParams = new URLSearchParams();
params.set('walletName', data.walletName);
params.set('coinType', data.coinType.toString());
return this.http return this.http
.get(this.mockApiUrl + '/wallet/history') .get(this.webApiUrl + '/wallet/history', new RequestOptions({headers: this.headers, search: params}))
.map((response: Response) => response); .map((response: Response) => response);
} }
/** /**
* Get unused receive addresses for a certain wallet from the API. * Get unused receive addresses for a certain wallet from the API.
*/ */
getUnusedReceiveAddresses(): Observable<any> { getUnusedReceiveAddress(data: WalletInfo): Observable<any> {
let params: URLSearchParams = new URLSearchParams();
params.set('walletName', data.walletName);
params.set('coinType', data.coinType.toString());
params.set('accountName', "account 0"); //temporary
return this.http return this.http
.get(this.mockApiUrl + '/wallet/receive') .get(this.webApiUrl + '/wallet/address', new RequestOptions({headers: this.headers, search: params}))
.map((response: Response) => response); .map((response: Response) => response);
} }
} }
...@@ -6,6 +6,7 @@ export class GlobalService { ...@@ -6,6 +6,7 @@ export class GlobalService {
private walletPath: string; private walletPath: string;
private currentWalletName: string; private currentWalletName: string;
private coinType: number;
getWalletPath() { getWalletPath() {
return this.walletPath; return this.walletPath;
...@@ -15,11 +16,19 @@ export class GlobalService { ...@@ -15,11 +16,19 @@ export class GlobalService {
this.walletPath = walletPath; this.walletPath = walletPath;
} }
getCurrentWalletName() { getWalletName() {
return this.currentWalletName; return this.currentWalletName;
} }
setCurrentWalletName(currentWalletName: string) { setWalletName(currentWalletName: string) {
this.currentWalletName = currentWalletName; this.currentWalletName = currentWalletName;
} }
}
\ No newline at end of file getCoinType () {
return this.coinType;
}
setCoinType (coinType: number) {
this.coinType = coinType;
}
}
<h1>History</h1> <h1>History</h1>
<table *ngIf="transactions"> <table *ngIf="transactions">
<thead> <thead>
<th>Timestamp</th> <th>Timestamp</th>
<th>Amount</th> <th>Amount</th>
...@@ -10,6 +10,6 @@ ...@@ -10,6 +10,6 @@
<td>{{ transaction.timestamp }}</td> <td>{{ transaction.timestamp }}</td>
<td>{{ transaction.amount }}</td> <td>{{ transaction.amount }}</td>
<td>{{ transaction.confirmed }}</td> <td>{{ transaction.confirmed }}</td>
<td>{{ transaction.txid }}</td> <td>{{ transaction.txId }}</td>
</tr> </tr>
</table> </table>
\ No newline at end of file
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ApiService } from '../../shared/services/api.service' import { ApiService } from '../../shared/services/api.service';
import { GlobalService } from '../../shared/services/global.service';
import { WalletInfo } from '../../shared/classes/wallet-info';
@Component({ @Component({
selector: 'history-component', selector: 'history-component',
...@@ -9,7 +12,7 @@ import { ApiService } from '../../shared/services/api.service' ...@@ -9,7 +12,7 @@ import { ApiService } from '../../shared/services/api.service'
}) })
export class HistoryComponent { export class HistoryComponent {
constructor(private apiService: ApiService) {} constructor(private apiService: ApiService, private globalService: GlobalService) {}
private transactions: any; private transactions: any;
private errorMessage: string; private errorMessage: string;
...@@ -19,11 +22,12 @@ export class HistoryComponent { ...@@ -19,11 +22,12 @@ export class HistoryComponent {
} }
private getWalletHistory() { private getWalletHistory() {
this.apiService.getWalletHistory() let walletInfo = new WalletInfo(this.globalService.getWalletName(), this.globalService.getCoinType())
this.apiService.getWalletHistory(walletInfo)
.subscribe( .subscribe(
response => { response => {
if (response.status >= 200 && response.status < 400) { if (response.status >= 200 && response.status < 400) {
this.transactions = response.json().history; this.transactions = response.json().transactions;
} }
}, },
error => { error => {
......
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ApiService } from '../../shared/services/api.service'; import { ApiService } from '../../shared/services/api.service';
import { GlobalService } from '../../shared/services/global.service';
import { WalletInfo } from '../../shared/classes/wallet-info';
@Component({ @Component({
selector: 'dashboard-component', selector: 'dashboard-component',
...@@ -7,8 +9,8 @@ import { ApiService } from '../../shared/services/api.service'; ...@@ -7,8 +9,8 @@ import { ApiService } from '../../shared/services/api.service';
styleUrls: ['./dashboard.component.css'], styleUrls: ['./dashboard.component.css'],
}) })
export class DashboardComponent { export class DashboardComponent {
constructor(private apiService: ApiService) {} constructor(private apiService: ApiService, private globalService: GlobalService) {}
private balanceResponse: any; private balanceResponse: any;
private confirmedBalance: number; private confirmedBalance: number;
private unconfirmedBalance: number; private unconfirmedBalance: number;
...@@ -19,21 +21,22 @@ export class DashboardComponent { ...@@ -19,21 +21,22 @@ export class DashboardComponent {
} }
private getWalletBalance() { private getWalletBalance() {
this.apiService.getWalletBalance() let walletInfo = new WalletInfo(this.globalService.getWalletName(), this.globalService.getCoinType())
.subscribe( this.apiService.getWalletBalance(walletInfo)
response => { .subscribe(
if (response.status >= 200 && response.status < 400) { response => {
this.balanceResponse = response.json(); if (response.status >= 200 && response.status < 400) {
this.confirmedBalance = this.balanceResponse.confirmed; this.balanceResponse = response.json();
this.unconfirmedBalance = this.balanceResponse.unconfirmed; this.confirmedBalance = this.balanceResponse.balances[0].amountConfirmed;
} this.unconfirmedBalance = this.balanceResponse.balances[0].amountUnconfirmed;
}, }
error => { },
if (error.status >= 400) { error => {
this.errorMessage = <any>error; if (error.status >= 400) {
console.log(this.errorMessage); this.errorMessage = <any>error;
} console.log(this.errorMessage);
} }
}
); );
} }
} }
...@@ -2,20 +2,14 @@ ...@@ -2,20 +2,14 @@
<h1>Receive</h1> <h1>Receive</h1>
<div> <div>
<div> <div>
<table *ngIf="addresses"> <table *ngIf="address">
<thead> <thead>
<th>Unused Receive Addresses: </th> <th>Receive address: </th>
</thead> </thead>
<tr *ngFor="let address of addresses"> <tr>
<td>{{ address }}</td> <td>{{ address }}</td>
</tr> </tr>
</table> </table>
</div> </div>
</div> </div>
<div> </div>
<label>Used Receive Addresses</label>
</div>
<div>
<label>Change Addresses</label>
</div>
</div>
\ No newline at end of file
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ApiService } from '../../shared/services/api.service' import { ApiService } from '../../shared/services/api.service';
import { GlobalService } from '../../shared/services/global.service';
import { WalletInfo } from '../../shared/classes/wallet-info';
@Component({ @Component({
selector: 'receive-component', selector: 'receive-component',
...@@ -9,9 +12,9 @@ import { ApiService } from '../../shared/services/api.service' ...@@ -9,9 +12,9 @@ import { ApiService } from '../../shared/services/api.service'
}) })
export class ReceiveComponent { export class ReceiveComponent {
constructor(private apiService: ApiService) {} constructor(private apiService: ApiService, private globalService: GlobalService) {}
private addresses: any; private address: any;
private errorMessage: string; private errorMessage: string;
ngOnInit() { ngOnInit() {
...@@ -19,11 +22,12 @@ export class ReceiveComponent { ...@@ -19,11 +22,12 @@ export class ReceiveComponent {
} }
private getUnusedReceiveAddresses() { private getUnusedReceiveAddresses() {
this.apiService.getUnusedReceiveAddresses() let walletInfo = new WalletInfo(this.globalService.getWalletName(), this.globalService.getCoinType())
this.apiService.getUnusedReceiveAddress(walletInfo)
.subscribe( .subscribe(
response => { response => {
if (response.status >= 200 && response.status < 400) { if (response.status >= 200 && response.status < 400) {
this.addresses = response.json().addresses; this.address = response.json();
} }
}, },
error => { error => {
...@@ -34,4 +38,4 @@ export class ReceiveComponent { ...@@ -34,4 +38,4 @@ export class ReceiveComponent {
} }
); );
} }
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment