Skip to content

Commit

Permalink
Implement Ledger service with transfer functionality
Browse files Browse the repository at this point in the history
Minor updates - PR feedback

Add typesafe pick function for filtering unwanted parameters in storage

Make re-usable sign_and_process_tx function

Fixing extension tests

Fix Ledger balances after rebase

Fix account derivation error

Fix public key issue, update to latest 0.17.5

Add reveal pk tx

Move reveal pk to reusable method

Add reveal pk for submitting signed transfers
  • Loading branch information
jurevans committed Jul 6, 2023
1 parent d0a9da8 commit f26a160
Show file tree
Hide file tree
Showing 58 changed files with 1,581 additions and 742 deletions.
22 changes: 20 additions & 2 deletions apps/extension/src/App/Accounts/AccountListing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,39 @@ const textToClipboard = (content: string): void => {
navigator.clipboard.writeText(content);
};

const isChild = (type: AccountType, path: Bip44Path): boolean => {
// All PrivateKey accounts are child accounts
if (type === AccountType.PrivateKey) {
return true;
}

if (type === AccountType.Ledger) {
// If this is a Ledger account, a child account is any account
// with a path that isn't the default path (/0'/0/0). This is for display
// purposes only. If the sum of the path components is greater than
// zero, it is a child.
const { account, change, index = 0 } = path;
return account + change + index > 0;
}

return false;
};

const formatDerivationPath = (
isChildAccount: boolean,
{ account, change, index = 0 }: Bip44Path,
type: AccountType
): string =>
isChildAccount
? `/${account}'/${
type === AccountType.PrivateKey ? `${change}/` : ""
type !== AccountType.Mnemonic ? `${change}/` : ""
}${index}`
: "";

const AccountListing = ({ account, parentAlias }: Props): JSX.Element => {
const { address, alias, path, type } = account;
const navigate = useNavigate();
const isChildAccount = type !== AccountType.Mnemonic;
const isChildAccount = isChild(type, path);

return (
<AccountListingContainer>
Expand Down
8 changes: 5 additions & 3 deletions apps/extension/src/App/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,13 @@ export const App: React.FC = () => {
setStatus(Status.Pending);

try {
const parentId = await requester.sendMessage(
const parent = await requester.sendMessage(
Ports.Background,
new GetActiveAccountMsg()
);
const parentAccount = accounts.find((account) => account.id === parentId);
const parentAccount = accounts.find(
(account) => account.id === parent?.id
);
setParentAccount(parentAccount);
} catch (e) {
console.error(e);
Expand Down Expand Up @@ -115,7 +117,7 @@ export const App: React.FC = () => {
},
onFail: () => {
setError("An error occurred connecting to extension");
setStatus(Status.Failed);
setStatus(Status.Completed);
},
},
{ tries: 10, ms: 100 },
Expand Down
49 changes: 18 additions & 31 deletions apps/extension/src/App/Settings/ExtraSettings/ExtraSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ import { ExtensionRequester } from "extension";
import { Mode, ExtraSetting } from "./types";
import { ResetPassword } from "./ResetPassword";
import { DeleteAccount } from "./DeleteAccount";
import {
ExtraSettingsContainer,
CloseLink
} from "./ExtraSettings.components";
import { ExtraSettingsContainer, CloseLink } from "./ExtraSettings.components";

/**
* Container for additional settings forms such as the reset password form.
Expand All @@ -17,37 +14,27 @@ const ExtraSettings: React.FC<{
requester: ExtensionRequester;
onClose: () => void;
onDeleteAccount: (id: string) => void;
}> = ({
extraSetting,
requester,
onClose,
onDeleteAccount,
}) => {
}> = ({ extraSetting, requester, onClose, onDeleteAccount }) => {
return (
<ExtraSettingsContainer>
{extraSetting &&
<CloseLink onClick={onClose}>
Close
</CloseLink>}

{
extraSetting === null ? "" :

extraSetting.mode === Mode.ResetPassword ?
<ResetPassword
accountId={extraSetting.accountId}
requester={requester}
/> :

extraSetting.mode === Mode.DeleteAccount ?
<DeleteAccount
accountId={extraSetting.accountId}
requester={requester}
onDeleteAccount={onDeleteAccount}
/> :
{extraSetting && <CloseLink onClick={onClose}>Close</CloseLink>}

{extraSetting === null ? (
""
) : extraSetting.mode === Mode.ResetPassword ? (
<ResetPassword
accountId={extraSetting.accountId}
requester={requester}
/>
) : extraSetting.mode === Mode.DeleteAccount ? (
<DeleteAccount
accountId={extraSetting.accountId}
requester={requester}
onDeleteAccount={onDeleteAccount}
/>
) : (
assertNever(extraSetting.mode)
}
)}
</ExtraSettingsContainer>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { useState } from "react";
import {
Button,
ButtonVariant
} from "@anoma/components";
import zxcvbn, { ZXCVBNFeedback } from "zxcvbn";
import { Button, ButtonVariant } from "@anoma/components";
import zxcvbn from "zxcvbn";

import {
Input,
Expand All @@ -23,12 +20,12 @@ enum Status {
Unsubmitted,
Pending,
Complete,
Failed
};
Failed,
}

export type Props = {
accountId: string,
requester: ExtensionRequester
accountId: string;
requester: ExtensionRequester;
};

const ResetPassword: React.FC<Props> = ({ accountId, requester }) => {
Expand All @@ -42,8 +39,8 @@ const ResetPassword: React.FC<Props> = ({ accountId, requester }) => {

const match = newPassword === confirmNewPassword;
const { feedback } = zxcvbn(newPassword);
const hasFeedback = feedback.warning !== "" ||
feedback.suggestions.length > 0;
const hasFeedback =
feedback.warning !== "" || feedback.suggestions.length > 0;

const shouldDisableSubmit =
status === Status.Pending ||
Expand All @@ -52,7 +49,7 @@ const ResetPassword: React.FC<Props> = ({ accountId, requester }) => {
!match ||
(process.env.NODE_ENV !== "development" && hasFeedback);

const handleSubmit = async () => {
const handleSubmit = async (): Promise<void> => {
setStatus(Status.Pending);

const result = await requester.sendMessage<ResetPasswordMsg>(
Expand Down Expand Up @@ -87,7 +84,7 @@ const ResetPassword: React.FC<Props> = ({ accountId, requester }) => {
<Input
type="password"
value={currentPassword}
onChange={e => setCurrentPassword(e.target.value)}
onChange={(e) => setCurrentPassword(e.target.value)}
/>
</InputContainer>

Expand All @@ -96,52 +93,44 @@ const ResetPassword: React.FC<Props> = ({ accountId, requester }) => {
<Input
type="password"
value={newPassword}
onChange={e => setNewPassword(e.target.value)}
onChange={(e) => setNewPassword(e.target.value)}
/>

<InputFeedback className="warning">
{feedback.warning}
</InputFeedback>

{feedback.suggestions.map((suggestion, i) =>
{feedback.suggestions.map((suggestion, i) => (
<InputFeedback key={i}>{suggestion}</InputFeedback>
)}
))}
</InputContainer>

<InputContainer className="medium">
<Header5>Confirm new password</Header5>
<Input
type="password"
value={confirmNewPassword}
onChange={e => setConfirmNewPassword(e.target.value)}
onChange={(e) => setConfirmNewPassword(e.target.value)}
/>

{!match && (
<InputFeedback>Passwords do not match</InputFeedback>
)}
{!match && <InputFeedback>Passwords do not match</InputFeedback>}
</InputContainer>

{errorMessage && (
<ErrorFeedback>{errorMessage}</ErrorFeedback>
)}
{errorMessage && <ErrorFeedback>{errorMessage}</ErrorFeedback>}

<Button
variant={ButtonVariant.Contained}
onClick={handleSubmit}
disabled={shouldDisableSubmit}
>
{status === Status.Pending ?
"Pending..." :
"Reset password"}
{status === Status.Pending ? "Pending..." : "Reset password"}
</Button>
</>
)}

{status === Status.Complete && (
<p>Complete!</p>
)}
{status === Status.Complete && <p>Complete!</p>}
</>
);
}
};

export default ResetPassword;
4 changes: 2 additions & 2 deletions apps/extension/src/App/Settings/ExtraSettings/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
export enum Mode {
ResetPassword = "Reset password",
DeleteAccount = "Delete account",
};
}

export type ExtraSetting = {
mode: Mode;
accountId: string;
}
};
Loading

0 comments on commit f26a160

Please sign in to comment.