A bit of half-backed wallet sync stuff, but commented out.
This commit is contained in:
parent
dadeb066c8
commit
205411adda
5 changed files with 187 additions and 29 deletions
|
@ -19,6 +19,8 @@ export class User {
|
|||
providedIn: 'root'
|
||||
})
|
||||
export class BackendAPIService {
|
||||
walletSyncEndpoint = `https://${environment.walletSyncHostname}/api/v0`;
|
||||
|
||||
endpoint = `https://${environment.nodeHostname}/api/v0`;
|
||||
|
||||
constructor(
|
||||
|
@ -67,4 +69,34 @@ export class BackendAPIService {
|
|||
return of(usernames);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO - WIP, not using for now.
|
||||
|
||||
// This isn't what the current wallet sync API looks like, but it will
|
||||
// likely change anyway. So this is an approximation with a stub for the time being.
|
||||
WalletSyncLogin(
|
||||
username: string,
|
||||
password: string,
|
||||
): Observable<{bodyJson: string, signature: string} | null> {
|
||||
|
||||
// A stub for now
|
||||
const wallet : object | null = this.cryptoService.getWallet(this.globalVars.hostname);
|
||||
if (wallet === null) {
|
||||
return of(null)
|
||||
}
|
||||
|
||||
return of({
|
||||
bodyJson: JSON.stringify(wallet, null, 2),
|
||||
signature: "",
|
||||
})
|
||||
|
||||
// Later we'll do something like this...
|
||||
return this.httpClient.post<any>(
|
||||
`${this.walletSyncEndpoint}/log-in`,
|
||||
{
|
||||
username: username,
|
||||
password: password,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import HDNode from 'hdkey';
|
||||
import * as bip39 from 'bip39';
|
||||
import HDKey from 'hdkey';
|
||||
import {ec as EC} from 'elliptic';
|
||||
import bs58check from 'bs58check';
|
||||
import {CookieService} from 'ngx-cookie';
|
||||
import {createHmac, createCipher, createDecipher, randomBytes} from 'crypto';
|
||||
import {AccessLevel, Network} from '../types/identity';
|
||||
import {AccessLevel, PrivateAccountInfo} from '../types/identity';
|
||||
import { GlobalVarsService } from './global-vars.service';
|
||||
|
||||
@Injectable({
|
||||
|
@ -76,7 +73,8 @@ export class CryptoService {
|
|||
}
|
||||
}
|
||||
|
||||
getWallet(hostname: string): object | null {
|
||||
// TODO define a wallet type, and/or use a type defined by json-schema
|
||||
getWallet(hostname: string): {accounts: [PrivateAccountInfo]} | null {
|
||||
const storageKey = this.walletStorageKey(hostname);
|
||||
let walletStr
|
||||
if (this.mustUseStorageAccess()) {
|
||||
|
@ -169,4 +167,16 @@ export class CryptoService {
|
|||
|
||||
return new Buffer(publicKeyEC.getPublic('array'));
|
||||
}
|
||||
|
||||
// TODO check that the signature for the walletStr is valid
|
||||
checkSig(walletStr: string, walletSignature: string): boolean {
|
||||
throw "implement me"
|
||||
return true
|
||||
}
|
||||
|
||||
// TODO find errors in the wallet. missing fields, etc. json-schema
|
||||
validateWallet(wallet: object): string | null {
|
||||
throw "implement me"
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,51 @@
|
|||
<p>
|
||||
<b>wallet me</b>: <textarea id="wallet" rows="20" cols="150"></textarea><button type="button" (click)="saveWallet()">Go.</button>
|
||||
</p>
|
||||
<app-banner></app-banner>
|
||||
|
||||
<div class="page-container" *ngIf="globalVars.inTab || globalVars.webview || globalVars.callback">
|
||||
|
||||
<!--
|
||||
<div class="title-text">
|
||||
Log into the LBRY wallet sync service
|
||||
</div>
|
||||
|
||||
<p class="main-text mb-20px">
|
||||
Log in to {{ globalVars.environment.walletSyncHostname }}:
|
||||
</p>
|
||||
|
||||
<div *ngIf="loginError" class="alert alert-danger mt-15px">
|
||||
{{ loginError }}
|
||||
</div>
|
||||
|
||||
<div class="text-input-container">
|
||||
<textarea [(ngModel)]="loginUsername"
|
||||
class="text-input"
|
||||
rows="4"
|
||||
placeholder="Username"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="text-input-container">
|
||||
<textarea [(ngModel)]="loginPassword"
|
||||
class="text-input"
|
||||
rows="4"
|
||||
placeholder="Password"></textarea>
|
||||
</div>
|
||||
|
||||
<button (click)="clickLogin()"
|
||||
class="button button-primary button-large">
|
||||
Log In
|
||||
</button>
|
||||
|
||||
<hr>
|
||||
-->
|
||||
|
||||
<div class="title-text">
|
||||
Paste your wallet directly
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<textarea [value]="walletDumpInitial" id="wallet-dump" rows="20" cols="150"></textarea>
|
||||
<button (click)="loginWithWalletDump()"
|
||||
class="button button-primary button-large">
|
||||
Log In
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -1,8 +1,17 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { CryptoService } from '../crypto.service';
|
||||
import { SigningService } from '../signing.service';
|
||||
import { IdentityService } from '../identity.service';
|
||||
import { GlobalVarsService } from '../global-vars.service';
|
||||
import {BackendAPIService} from '../backend-api.service';
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {CryptoService} from '../crypto.service';
|
||||
import {GlobalVarsService} from '../global-vars.service';
|
||||
import {Router} from '@angular/router';
|
||||
import {RouteNames} from '../app-routing.module';
|
||||
import {of} from 'rxjs';
|
||||
|
||||
// This is logging into the wallet sync, not the app
|
||||
// TODO rename this component to wallet-sync-log-in
|
||||
|
||||
// This component handles two ways of logging in:
|
||||
// * Wallet Sync (currently commented out)
|
||||
// * Paste Wallet (temporary measure for initial version)
|
||||
|
||||
@Component({
|
||||
selector: 'app-test-lbry-log-in',
|
||||
|
@ -10,32 +19,90 @@ import { GlobalVarsService } from '../global-vars.service';
|
|||
styleUrls: ['./test-lbry-log-in.component.scss']
|
||||
})
|
||||
export class TestLbryLogInComponent implements OnInit {
|
||||
walletDumpInitial = this.getWalletDumpInitial();
|
||||
|
||||
loginError = '';
|
||||
loginUsername = '';
|
||||
loginPassword = '';
|
||||
|
||||
constructor(
|
||||
private backendApi: BackendAPIService,
|
||||
private cryptoService: CryptoService,
|
||||
private signingService: SigningService,
|
||||
private identityService: IdentityService,
|
||||
private globalVars: GlobalVarsService,
|
||||
public globalVars: GlobalVarsService,
|
||||
private router: Router,
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
const wallet : object | null = this.cryptoService.getWallet(this.globalVars.hostname);
|
||||
(<HTMLInputElement>document.getElementById("wallet")).value = JSON.stringify(wallet, null, 2) || "";
|
||||
ngOnInit(): void {}
|
||||
|
||||
// Wallet Sync (WIP, unused atm)
|
||||
|
||||
clickLogin() {
|
||||
// Store username and password locally because we clear them below and otherwise
|
||||
// they don't get saved in local storage reliably
|
||||
const loginUsername = this.loginUsername;
|
||||
const loginPassword = this.loginPassword;
|
||||
|
||||
if (loginUsername.length === 0) {
|
||||
this.loginError = 'Enter a username';
|
||||
return of();
|
||||
}
|
||||
|
||||
if (loginPassword.length === 0) {
|
||||
this.loginError = 'Enter a password';
|
||||
return of();
|
||||
}
|
||||
|
||||
// Returning the observable only because I'm in the habit of returning
|
||||
// promises. But maybe it's not needed here.
|
||||
return this.backendApi.WalletSyncLogin(loginUsername, loginPassword).subscribe(
|
||||
(res => {
|
||||
if (res === null) {
|
||||
this.loginError = "Login Error. Try again?"
|
||||
return
|
||||
}
|
||||
|
||||
const walletStr = res.bodyJson
|
||||
const walletSignature = res.signature
|
||||
|
||||
if (!this.cryptoService.checkSig(walletStr, walletSignature)) {
|
||||
this.loginError = 'Wallet signature failed!';
|
||||
return
|
||||
}
|
||||
const wallet = JSON.parse(res.bodyJson)
|
||||
const walletError: string | null = this.cryptoService.validateWallet(wallet);
|
||||
|
||||
if (walletError !== null) {
|
||||
this.loginError = "Wallet error: " + walletError;
|
||||
return
|
||||
}
|
||||
|
||||
this.cryptoService.putWallet(this.globalVars.hostname, wallet);
|
||||
|
||||
// Clear the form
|
||||
this.loginUsername = '';
|
||||
this.loginPassword = '';
|
||||
|
||||
this.router.navigate(['/', RouteNames.LOG_IN], {queryParamsHandling: 'merge'});
|
||||
}),
|
||||
(() => {
|
||||
this.loginError = "Login Error. Try again?"
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
saveWallet(): void {
|
||||
const walletStr = (<HTMLInputElement>document.getElementById("wallet")).value;
|
||||
// Paste Wallet (temporary measure for initial version)
|
||||
|
||||
getWalletDumpInitial() {
|
||||
const wallet : object | null = this.cryptoService.getWallet(this.globalVars.hostname);
|
||||
return JSON.stringify(wallet, null, 2) || ""
|
||||
}
|
||||
|
||||
loginWithWalletDump(): void {
|
||||
const walletStr = (<HTMLInputElement>document.getElementById("wallet-dump")).value;
|
||||
const wallet = JSON.parse(walletStr)
|
||||
this.cryptoService.putWallet(this.globalVars.hostname, wallet);
|
||||
|
||||
const addresses = this.signingService.getAddresses(wallet)
|
||||
this.finishFlow(addresses)
|
||||
this.router.navigate(['/', RouteNames.LOG_IN], {queryParamsHandling: 'merge'});
|
||||
}
|
||||
|
||||
finishFlow(addresses: string[]): void {
|
||||
this.identityService.login({
|
||||
accounts: this.accountService.getPublicAccounts(),
|
||||
addresses,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ export const environment = {
|
|||
production: false,
|
||||
hostname: 'localhost:4201',
|
||||
nodeHostname: 'node.deso.org', // TODO deleteme
|
||||
walletSyncHostname: 'localhost:8091',
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue