diff --git a/background/backgroundComponents/externalMessageListener/index.ts b/background/backgroundComponents/externalMessageListener/index.ts
index 09afc1269..846eafc8f 100644
--- a/background/backgroundComponents/externalMessageListener/index.ts
+++ b/background/backgroundComponents/externalMessageListener/index.ts
@@ -2,6 +2,7 @@ import StellarSdk from "stellar-sdk";
import { ExternalRequest as Request } from "api/types";
import { EXTERNAL_SERVICE_TYPES } from "statics";
+import { removeQueryParam } from "helpers";
import { Sender, SendResponseInterface } from "../types";
import { responseQueue, uiData, transactionQueue } from "../messageListener";
@@ -21,7 +22,7 @@ export const externalMessageListener = (
const { tab } = sender;
const tabUrl = tab?.url ? tab.url : "";
- if (whitelist.includes(tabUrl)) {
+ if (whitelist.includes(removeQueryParam(tabUrl))) {
if (uiData.publicKey) {
// okay, the requester checks out and we have public key, send it
sendResponse({ publicKey: uiData.publicKey });
@@ -31,7 +32,6 @@ export const externalMessageListener = (
// otherwise, we need to confirm either url or password. Maybe both
const encodeOrigin = btoa(JSON.stringify(tab));
-
window.open(
chrome.runtime.getURL(`/index.html#/grant-access?${encodeOrigin}`),
"Lyra: Connect",
diff --git a/background/backgroundComponents/messageListener.ts b/background/backgroundComponents/messageListener.ts
index 3b830024b..aca7b6e17 100644
--- a/background/backgroundComponents/messageListener.ts
+++ b/background/backgroundComponents/messageListener.ts
@@ -4,6 +4,7 @@ import StellarSdk from "stellar-sdk";
import { fromMnemonic, generateMnemonic } from "stellar-hd-wallet";
import { SERVICE_TYPES, APPLICATION_STATE, SERVER_URL } from "statics";
import { Response as Request } from "api/types";
+import { removeQueryParam } from "helpers";
import { externalMessageListener } from "./externalMessageListener";
import { Sender, SendResponseInterface } from "./types";
@@ -183,18 +184,20 @@ const initMessageListener = () => {
const grantAccess = () => {
const { url = "" } = request;
+ const sanitizedUrl = removeQueryParam(url);
// TODO: right now we're just grabbing the last thing in the queue, but this should be smarter.
// Maybe we need to search through responses to find a matching reponse :thinking_face
const response = responseQueue.pop();
const whitelistStr = localStorage.getItem(WHITELIST_ID) || "";
const whitelist = whitelistStr.split(",");
- whitelist.push(url);
+ whitelist.push(sanitizedUrl);
localStorage.setItem(WHITELIST_ID, whitelist.join());
if (typeof response === "function") {
response(url);
+ sendResponse({});
} else {
sendResponse({ error: "Access was denied" });
}
@@ -240,6 +243,7 @@ const initMessageListener = () => {
const transactionResponse = responseQueue.pop();
if (typeof transactionResponse === "function") {
transactionResponse(response);
+ sendResponse({});
}
}
};
diff --git a/package.json b/package.json
index 4f8c36d80..a098ebf9c 100755
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
"buffer": "^5.6.0",
"eslint-loader": "^4.0.2",
"fetch": "^1.1.0",
+ "file-loader": "^6.0.0",
"lodash": "^4.17.15",
"react": "^16.12.0",
"react-copy-to-clipboard": "^5.0.2",
diff --git a/public/index.html b/public/index.html
index 6a9456ad0..5708f512b 100644
--- a/public/index.html
+++ b/public/index.html
@@ -8,6 +8,9 @@
name="description"
content="Web site created using create-react-app"
/>
+
React App
diff --git a/src/App.tsx b/src/App.tsx
index 3b0c0b7d9..d0878f6f8 100755
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -5,22 +5,27 @@ import { combineReducers } from "redux";
import { Provider } from "react-redux";
import styled, { createGlobalStyle } from "styled-components";
+import { COLOR_PALETTE } from "styles";
import { reducer as auth } from "ducks/authServices";
-import Menu from "components/Menu";
import Router from "./Router";
const GlobalStyle = createGlobalStyle`
+html, body, #root {
+ height: 100%;
+}
body {
+ background: ${COLOR_PALETTE.background};
overscroll-behavior: none;
- font-family: sans-serif;
- width: 357px;
- height: 600px;
+ font-family: 'Muli', sans-serif;
margin: 0;
}
`;
const Wrapper = styled.div`
- text-align: center;
+ display: flex;
+ flex-flow: column;
+ height: 100%;
+ text-align: left;
`;
const store = configureStore({
@@ -36,7 +41,6 @@ export function App() {
-
diff --git a/src/assets/copy.png b/src/assets/copy.png
new file mode 100644
index 000000000..ff37218b4
Binary files /dev/null and b/src/assets/copy.png differ
diff --git a/src/assets/download.png b/src/assets/download.png
new file mode 100644
index 000000000..addc3465e
Binary files /dev/null and b/src/assets/download.png differ
diff --git a/src/assets/spy.png b/src/assets/spy.png
new file mode 100644
index 000000000..be4621cd2
Binary files /dev/null and b/src/assets/spy.png differ
diff --git a/src/components/Layout/Fullscreen.tsx b/src/components/Layout/Fullscreen.tsx
new file mode 100644
index 000000000..82611efb7
--- /dev/null
+++ b/src/components/Layout/Fullscreen.tsx
@@ -0,0 +1,52 @@
+import React from "react";
+import styled from "styled-components";
+import Header from "./Header";
+
+const H1 = styled.h1`
+ font-weight: 200;
+ font-size: 2.5rem;
+ line-height: 3.4rem;
+ margin: 1rem 0;
+`;
+
+const Screen = styled.div`
+ align-content: center;
+ align-items: center;
+ display: flex;
+ justify-content: center;
+ padding: 100px 170px;
+`;
+
+const HalfScreen = styled.div`
+ padding: 0 30px;
+ width: 355px;
+
+ :nth-child(1) {
+ margin-top: -20px;
+ }
+`;
+
+const Fullscreen = ({
+ header,
+ icon: [src, alt],
+ children,
+}: {
+ header: string;
+ icon: [string, string];
+ children: JSX.Element;
+}) => {
+ return (
+ <>
+
+
+
+
+ {header}
+
+ {children}
+
+ >
+ );
+};
+
+export default Fullscreen;
diff --git a/src/components/Layout/Header/index.tsx b/src/components/Layout/Header/index.tsx
new file mode 100644
index 000000000..cd92191cd
--- /dev/null
+++ b/src/components/Layout/Header/index.tsx
@@ -0,0 +1,39 @@
+import React from "react";
+import styled from "styled-components";
+import { COLOR_PALETTE } from "styles";
+
+const HeaderEl = styled.header`
+ background: ${COLOR_PALETTE.primaryGradient};
+ box-sizing: border-box;
+ font-family: "Muli";
+ display: flex;
+ height: 6.2rem;
+ justify-content: space-between;
+ padding: 26px 54px;
+ text-align: left;
+`;
+
+const HeaderH1 = styled.h1`
+ color: #fff;
+ font-size: 2rem;
+ font-weight: 200;
+ line-height: 41px;
+ margin: 0;
+`;
+
+const NetworkEl = styled.h3`
+ opacity: 0.5;
+ color: #fff;
+ font-size: 1rem;
+ font-weight: 800;
+ line-height: 21px;
+`;
+
+const Header = () => (
+
+ Lyra
+ Test net
+
+);
+
+export default Header;
diff --git a/src/components/form/index.tsx b/src/components/form/index.tsx
index 7a864ed45..850b85a3c 100644
--- a/src/components/form/index.tsx
+++ b/src/components/form/index.tsx
@@ -1,5 +1,7 @@
import React from "react";
import styled from "styled-components";
+import { COLOR_PALETTE } from "styles";
+import { Button } from "styles/Basics";
const ErrorEl = styled.p`
color: red;
@@ -13,3 +15,15 @@ interface ErrorMessageProps {
export const ErrorMessage = ({ authError }: ErrorMessageProps) => (
<>{authError ? {authError} : null}>
);
+
+export const FormButton = styled(Button)`
+ background: ${COLOR_PALETTE.primaryGradient};
+ border-radius: 1.5rem;
+ color: #fff;
+ display: block;
+ font-size: 1.1rem;
+ font-weight: 600;
+ line-height: 1.3rem;
+ margin: 2rem auto;
+ padding: 1.6rem 6rem;
+`;
diff --git a/src/components/mnemonicPhrase/DisplayMnemonicPhrase.tsx b/src/components/mnemonicPhrase/DisplayMnemonicPhrase.tsx
index 31c98a74d..071c89d17 100644
--- a/src/components/mnemonicPhrase/DisplayMnemonicPhrase.tsx
+++ b/src/components/mnemonicPhrase/DisplayMnemonicPhrase.tsx
@@ -1,5 +1,35 @@
import React, { useState, useEffect } from "react";
import CopyToClipboard from "react-copy-to-clipboard";
+import styled from "styled-components";
+import { COLOR_PALETTE } from "styles";
+import Download from "assets/download.png";
+import Copy from "assets/copy.png";
+import { FormButton } from "components/form";
+import ActionButton from "./basics/ActionButton";
+
+const Warning = styled.strong`
+ color: ${COLOR_PALETTE.primary};
+`;
+
+const MnemonicDisplay = styled.div`
+ background: ${COLOR_PALETTE.primaryGradient};
+ border-radius: 30px;
+ color: #fff;
+ font-size: 1.125 rem;
+ line-height: 1.8rem;
+ margin: 3.5rem 0 1rem;
+ padding: 27px 37px;
+ text-align: center;
+`;
+
+const DisplayButtons = styled.div`
+ margin-right: 1rem;
+ text-align: right;
+
+ img {
+ margin-left: 0.5rem;
+ }
+`;
const DisplayMnemonicPhrase = ({
mnemonicPhrase,
@@ -29,20 +59,34 @@ const DisplayMnemonicPhrase = ({
return (
<>
- Secret backup Phrase
- {mnemonicPhrase}
- setCopied(true)}>
-
-
-
- {copied ? Copied! : null}
-
+
>
);
};
diff --git a/src/components/mnemonicPhrase/basics/ActionButton.tsx b/src/components/mnemonicPhrase/basics/ActionButton.tsx
new file mode 100644
index 000000000..ebaa443f1
--- /dev/null
+++ b/src/components/mnemonicPhrase/basics/ActionButton.tsx
@@ -0,0 +1,12 @@
+import styled from "styled-components";
+import { Button } from "styles/Basics";
+
+const ActionButton = styled(Button)`
+ color: #748098;
+ font-size: 0.875rem;
+ font-weight: 500;
+ line-height: 1.7rem;
+ opacity: 0.6;
+`;
+
+export default ActionButton;
diff --git a/src/helpers/index.ts b/src/helpers/index.ts
index dc16c80ca..1a7b39846 100644
--- a/src/helpers/index.ts
+++ b/src/helpers/index.ts
@@ -1 +1,2 @@
export const newTabHref = (path = "") => `index.html#${path}`;
+export const removeQueryParam = (url = "") => url.replace(/\?(.*)/, "");
diff --git a/src/styles/Basics/index.tsx b/src/styles/Basics/index.tsx
new file mode 100644
index 000000000..dcd80096b
--- /dev/null
+++ b/src/styles/Basics/index.tsx
@@ -0,0 +1,12 @@
+import styled from "styled-components";
+
+export const Button = styled.button`
+ background: none;
+ border: none;
+ cursor: pointer;
+ -webkit-appearance: none;
+
+ :focus {
+ outline: none;
+ }
+`;
diff --git a/src/styles/index.tsx b/src/styles/index.tsx
new file mode 100644
index 000000000..c9c5a51ec
--- /dev/null
+++ b/src/styles/index.tsx
@@ -0,0 +1,6 @@
+export const COLOR_PALETTE = {
+ background: "#F0F2F6",
+ text: "#060E1A",
+ primary: "#391EDA",
+ primaryGradient: "linear-gradient(90deg, #391EDA 100%, #5339ED 0%)",
+};
diff --git a/src/views/MnemonicPhrase/index.tsx b/src/views/MnemonicPhrase/index.tsx
index 7aa53bb10..4494aca05 100644
--- a/src/views/MnemonicPhrase/index.tsx
+++ b/src/views/MnemonicPhrase/index.tsx
@@ -2,6 +2,9 @@ import React, { useState } from "react";
import ConfirmMnemonicPhrase from "components/mnemonicPhrase/ConfirmMnemonicPhrase";
import useMnemonicPhrase from "hooks/useMnemonicPhrase";
import DisplayMnemonicPhrase from "components/mnemonicPhrase/DisplayMnemonicPhrase";
+import Fullscreen from "components/Layout/Fullscreen";
+
+import spy from "assets/spy.png";
const MnemonicPhrase = () => {
const [readyToConfirm, setReadyToConfirm] = useState(false);
@@ -9,7 +12,7 @@ const MnemonicPhrase = () => {
const mnemonicPhrase = useMnemonicPhrase();
return (
- <>
+
{readyToConfirm ? (
{
setReadyToConfirm={setReadyToConfirm}
/>
)}
- >
+
);
};
diff --git a/src/views/RecoverAccount/index.tsx b/src/views/RecoverAccount/index.tsx
index b191fd0e1..e63461e83 100644
--- a/src/views/RecoverAccount/index.tsx
+++ b/src/views/RecoverAccount/index.tsx
@@ -1,7 +1,6 @@
import React, { useEffect, useRef, useState, useCallback } from "react";
import { useDispatch, useSelector } from "react-redux";
import { Link } from "react-router-dom";
-import { history } from "App";
import {
authErrorSelector,
publicKeySelector,
@@ -44,7 +43,7 @@ const RecoverAccount = () => {
useEffect(() => {
if (publicKey) {
- history.push("/account");
+ window.close();
}
}, [publicKey]);
diff --git a/webpack.common.js b/webpack.common.js
index 5d3f9b1d3..6dc0dd533 100644
--- a/webpack.common.js
+++ b/webpack.common.js
@@ -44,6 +44,14 @@ const commonConfig = {
use: ["ts-loader", "eslint-loader"],
exclude: /node-modules/,
},
+ {
+ test: /\.png$/,
+ use: [
+ {
+ loader: "file-loader",
+ },
+ ],
+ },
{
test: /\.svg$/,
use: [
diff --git a/yarn.lock b/yarn.lock
index 2d2417b12..a54d9c265 100755
--- a/yarn.lock
+++ b/yarn.lock
@@ -4888,7 +4888,7 @@ file-loader@4.3.0:
loader-utils "^1.2.3"
schema-utils "^2.5.0"
-file-loader@~6.0.0:
+file-loader@^6.0.0, file-loader@~6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.0.0.tgz#97bbfaab7a2460c07bcbd72d3a6922407f67649f"
integrity sha512-/aMOAYEFXDdjG0wytpTL5YQLfZnnTmLNjn+AIrJ/6HVnTfDqLsVKUUwkDf4I4kgex36BvjuXEn/TX9B/1ESyqQ==