diff --git a/src/app/backend-api.service.ts b/src/app/backend-api.service.ts
index b2afa9e..aead80e 100644
--- a/src/app/backend-api.service.ts
+++ b/src/app/backend-api.service.ts
@@ -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,
+      },
+    );
+  }
 }
diff --git a/src/app/crypto.service.ts b/src/app/crypto.service.ts
index 00336da..a0e498f 100644
--- a/src/app/crypto.service.ts
+++ b/src/app/crypto.service.ts
@@ -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
+  }
 }
diff --git a/src/app/test-lbry-log-in/test-lbry-log-in.component.html b/src/app/test-lbry-log-in/test-lbry-log-in.component.html
index 069dac2..a2da138 100644
--- a/src/app/test-lbry-log-in/test-lbry-log-in.component.html
+++ b/src/app/test-lbry-log-in/test-lbry-log-in.component.html
@@ -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>
diff --git a/src/app/test-lbry-log-in/test-lbry-log-in.component.ts b/src/app/test-lbry-log-in/test-lbry-log-in.component.ts
index 09df5a3..d09efa0 100644
--- a/src/app/test-lbry-log-in/test-lbry-log-in.component.ts
+++ b/src/app/test-lbry-log-in/test-lbry-log-in.component.ts
@@ -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,
-    });
-  }
 }
diff --git a/src/environments/environment.ts b/src/environments/environment.ts
index 1be5e3b..5b06ca5 100644
--- a/src/environments/environment.ts
+++ b/src/environments/environment.ts
@@ -6,6 +6,7 @@ export const environment = {
   production: false,
   hostname: 'localhost:4201',
   nodeHostname: 'node.deso.org',  // TODO deleteme
+  walletSyncHostname: 'localhost:8091',
 };
 
 /*