Skip to content

Commit

Permalink
Merge pull request #757 from getAlby/feature/new-signup
Browse files Browse the repository at this point in the history
feat: new wallet account creation with lightning address
  • Loading branch information
bumi authored Mar 31, 2022
2 parents 34a178f + 2062916 commit 7de48b0
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 43 deletions.
44 changes: 41 additions & 3 deletions src/app/components/form/Input/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
import { useRef } from "react";

import { classNames } from "../../../utils";

type Props = {
suffix?: string;
};

export default function Input({
name,
id,
Expand All @@ -15,13 +23,22 @@ export default function Input({
disabled,
min,
max,
}: React.InputHTMLAttributes<HTMLInputElement>) {
return (
suffix,
}: React.InputHTMLAttributes<HTMLInputElement> & Props) {
const inputEl = useRef<HTMLInputElement>(null);
const outerStyles =
"shadow-sm rounded-md border border-gray-300 dark:bg-gray-200 focus:ring-orange-bitcoin focus:border-orange-bitcoin focus:ring-1 transition duration-300";

const inputNode = (
<input
ref={inputEl}
type={type}
name={name}
id={id}
className="shadow-sm focus:ring-orange-bitcoin focus:border-orange-bitcoin block w-full sm:text-sm border-gray-300 rounded-md placeholder-gray-400 dark:bg-gray-200 dark:placeholder-gray-600 dark:text-black transition duration-300"
className={classNames(
"sm:text-sm block w-full placeholder-gray-400 dark:placeholder-gray-600 dark:text-black",
!suffix ? outerStyles : "border-0 focus:ring-0"
)}
placeholder={placeholder}
required={required}
pattern={pattern}
Expand All @@ -37,4 +54,25 @@ export default function Input({
max={max}
/>
);

if (!suffix) return inputNode;

return (
<div
className={classNames(
"flex items-stretch overflow-hidden",
outerStyles.replace(/focus/g, "focus-within")
)}
>
{inputNode}
<span
className="flex items-center pr-3 font-medium"
onClick={() => {
inputEl.current?.focus();
}}
>
{suffix}
</span>
</div>
);
}
13 changes: 12 additions & 1 deletion src/app/components/form/TextField.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import Input from "./Input";

type Props = {
label: string;
suffix?: string;
};

const TextField = ({
id,
label,
Expand All @@ -15,9 +20,12 @@ const TextField = ({
autoFocus = false,
autoComplete = "off",
disabled,
minLength,
maxLength,
min,
max,
}: React.InputHTMLAttributes<HTMLInputElement> & { label: string }) => (
suffix,
}: React.InputHTMLAttributes<HTMLInputElement> & Props) => (
<>
<label
htmlFor={id}
Expand All @@ -41,8 +49,11 @@ const TextField = ({
autoFocus={autoFocus}
autoComplete={autoComplete}
disabled={disabled}
minLength={minLength}
maxLength={maxLength}
min={min}
max={max}
suffix={suffix}
/>
</div>
</>
Expand Down
6 changes: 4 additions & 2 deletions src/app/screens/Onboard/TestConnection/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const faucetMemo = "LN Faucet";
export default function TestConnection() {
const [accountInfo, setAccountInfo] = useState<{
alias: string;
name: string;
balance: number;
}>();
const [errorMessage, setErrorMessage] = useState();
Expand Down Expand Up @@ -89,10 +90,11 @@ export default function TestConnection() {
api
.getAccountInfo()
.then((response) => {
const name = response.name;
const { alias } = response.info;
const balance = parseInt(response.balance.balance);

setAccountInfo({ alias, balance });
setAccountInfo({ alias, balance, name });
})
.catch((e) => {
console.error(e);
Expand Down Expand Up @@ -200,7 +202,7 @@ export default function TestConnection() {
<div className="mt-6 shadow-lg p-4 rounded-xl">
<Card
color="bg-gray-100"
alias={accountInfo.alias}
alias={`${accountInfo.name} - ${accountInfo.alias}`}
satoshis={
typeof accountInfo.balance === "number"
? `${accountInfo.balance} sat`
Expand Down
10 changes: 7 additions & 3 deletions src/app/screens/Options/TestConnection/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ import Loading from "../../../components/Loading";
export default function TestConnection() {
const auth = useAuth();
const { getAccounts } = useAccounts();
const [accountInfo, setAccountInfo] =
useState<{ alias: string; balance: number }>();
const [accountInfo, setAccountInfo] = useState<{
alias: string;
name: string;
balance: number;
}>();
const [errorMessage, setErrorMessage] = useState("");
const [loading, setLoading] = useState(false);

Expand Down Expand Up @@ -42,6 +45,7 @@ export default function TestConnection() {
setAccountInfo({
alias: accountInfo.alias,
balance: accountInfo.balance,
name: accountInfo.name,
});
}
getAccounts();
Expand Down Expand Up @@ -110,7 +114,7 @@ export default function TestConnection() {
<div className="mt-6 shadow-lg p-4 rounded-xl">
<Card
color="bg-gray-100"
alias={accountInfo.alias}
alias={`${accountInfo.name} - ${accountInfo.alias}`}
satoshis={
typeof accountInfo.balance === "number"
? `${accountInfo.balance} sat`
Expand Down
128 changes: 94 additions & 34 deletions src/app/screens/connectors/NewWallet/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useState } from "react";
import Input from "../../../components/form/Input";
import TextField from "../../../components/form/TextField";
import { useNavigate } from "react-router-dom";
import QRCode from "react-qr-code";
Expand All @@ -16,8 +15,11 @@ export default function NewWallet() {
login: "",
password: "",
url: "",
lnAddress: "",
});
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [lnAddress, setLnAddress] = useState("");
const [loading, setLoading] = useState(false);
const navigate = useNavigate();

Expand All @@ -33,19 +35,23 @@ export default function NewWallet() {
return fetch(walletCreateUrl, {
method: "POST",
headers,
body: JSON.stringify({ email }),
body: JSON.stringify({
email,
password,
lightning_addresses_attributes: [{ address: lnAddress }], // address must be provided as array, in theory we support multiple addresses per account
}),
})
.then((res) => {
res.json().then((data) => {
if (data.lndhub?.login && data.lndhub?.password && data.lndhub?.url) {
setLndHubData(data.lndhub);
} else {
console.error(data);
alert(
"Failed to create a new wallet. Please try again and contact support."
);
}
});
.then((res) => res.json())
.then((data) => {
if (data.lndhub?.login && data.lndhub?.password && data.lndhub?.url) {
setLndHubData({
...data.lndhub,
lnAddress: data.lightning_address,
});
} else {
console.error(data);
alert(`Failed to create a new wallet. ${JSON.stringify(data)}`);
}
})
.catch((e) => {
console.error(e);
Expand All @@ -60,13 +66,15 @@ export default function NewWallet() {
setLoading(true);
event.preventDefault();

const { login, password, url } = lndHubData;
const { login, password, url, lnAddress } = lndHubData;
const name = lnAddress || "Alby"; // use the ln address as name or Alby to default
const account = {
name: "Alby",
name,
config: {
login,
password,
url,
lnAddress,
},
connector: "lndhub",
};
Expand Down Expand Up @@ -97,32 +105,34 @@ export default function NewWallet() {

return (
<ConnectorForm
title="Get a new lightning wallet"
title={
lndHubData.login === ""
? "Get a new lightning wallet"
: "🎉Your account is ready"
}
submitLabel={lndHubData.login ? "Continue" : "Create a wallet"}
submitLoading={loading}
onSubmit={lndHubData.login ? next : signup}
submitDisabled={password === "" || email === ""}
>
{lndHubData.login ? (
<>
<div className="mt-6">
<Input
name="uri"
type="text"
value={`lndhub://${lndHubData.login}:${lndHubData.password}@${lndHubData.url}/`}
disabled
/>
<div className="mt-6 dark:text-white">
<p>
<strong>
We have created a new wallet for you. <br />
</strong>
</p>
{lndHubData.lnAddress && (
<p>Your lightning address: {lndHubData.lnAddress}</p>
)}
</div>
<div className="mt-6 flex justify-center space-x-3 items-center dark:text-white">
<div className="flex-1">
<p className="my-2">
<strong>
We have created a new wallet for you. <br />
Please save this backup!
</strong>
</p>
If you loose access you will need this backup to recover your
wallet. You can also import the wallet into your BlueWallet mobile
app using the QR Code.
<strong>Want to use your wallet on your mobile?</strong>
<br />
Import the wallet into your BlueWallet mobile app using the QR
Code.
</div>
<div className="float-right">
<QRCode
Expand All @@ -136,21 +146,71 @@ export default function NewWallet() {
) : (
<>
<div className="mt-6 dark:text-white">
<strong>We host a lightning wallet for you!</strong>
<strong>Create a getAlby.com account</strong>
<br />
...but remember: not your keys, not your coins.
...and let us host a lightning wallet for you!
</div>

<div className="mt-6">
<TextField
id="email"
label="Email Address"
type="email"
required
onChange={(e) => {
setEmail(e.target.value.trim());
}}
/>
</div>
<div className="mt-6">
<TextField
id="password"
label="Password"
type="password"
minLength={6}
pattern=".{6,}"
title="at least 6 characters"
required
onChange={(e) => {
setPassword(e.target.value.trim());
}}
/>
</div>
<div className="mt-6">
<p className="mb-2 text-gray-500 dark:text-gray-400">
Your Alby account also comes with an optional{" "}
<a
className="underline"
href="https://lightningaddress.com/"
target="_blank"
rel="noreferrer"
>
Lightning Address
</a>
. This is a simple way for anyone to send you Bitcoin on the
Lightning Network. (
<a
className="underline"
href="https://lightningaddress.com/"
target="_blank"
rel="noreferrer"
>
learn more
</a>
)
</p>
<div>
<TextField
id="lnAddress"
label="Choose your Lightning Address (optional)"
suffix="@getalby.com"
type="text"
onChange={(e) => {
setLnAddress(e.target.value.trim().split("@")[0]); // in case somebody enters a full address we simple remove the domain
}}
/>
</div>
</div>
</>
)}
</ConnectorForm>
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface AccountInfo {
id: string;
alias: string;
balance: number;
name: string;
}

export interface MetaData {
Expand Down

0 comments on commit 7de48b0

Please sign in to comment.