Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: GridPlus Lattice1 support #1538

Draft
wants to merge 40 commits into
base: master
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
06bb15b
feat(hw): add gridplus connect option
mrcnk Nov 21, 2023
0e91d8d
feat(gridplus): add a gridplus connector route
mrcnk Nov 22, 2023
d840b7e
feat(gridplus): add nested routes for gridplus onboarding
mrcnk Dec 4, 2023
a9969b0
feat(gridplus): connect gridplus routes
mrcnk Dec 4, 2023
1bf3bb9
feat(gridplus): unstub onboarding
mrcnk Dec 14, 2023
2055931
fix(conflicts): resolve
mrcnk Dec 14, 2023
bf6c40d
feat(gridplus): wrap up gridplus onboarding
mrcnk Dec 15, 2023
cc5f025
feat(gridplus): add styles to addresses choice
mrcnk Dec 15, 2023
8ff215d
feat(gridplus): add signTransactionFromGridPlus and sendTransactionFr…
mrcnk Jan 5, 2024
0633f1f
feat(gridplus): add a handler for personal signature
mrcnk Jan 17, 2024
fc486e3
feat(gridplus): wrap up typed data signing
mrcnk Jan 18, 2024
6c0ba38
fix(gridplus): fix personal sign
mrcnk Jan 18, 2024
cace361
chore(e2e): add semi-automatic testing for GridPlus
mrcnk Jan 24, 2024
44b9a96
chore(gridplus): update image assets
mrcnk Jan 26, 2024
052c74d
feat(gridplus): implement add by index
mrcnk Jan 30, 2024
36dd231
chore(gridplus): improve onboarding ui
mrcnk Feb 1, 2024
f5c1b8d
feat(gridplus): add informative labels for the onboarding
mrcnk Feb 2, 2024
7e64b4a
chore(gridplus): handle case of removed permissions in Lattice
mrcnk Feb 12, 2024
e2bcecc
chore(gridplus): sync up with latest origin
mrcnk Feb 15, 2024
589f968
Merge branch 'master' into feat/add-gridplus-lattice1
mrcnk Feb 26, 2024
520ce66
fix(gridplus): pr improvements
mrcnk Feb 28, 2024
2c8759c
fix(gridplus): revert trezor vendor lib linting changes
mrcnk Feb 28, 2024
c0a489d
fix(gridplus): revert checkbox changes
mrcnk Feb 28, 2024
0ebd883
chore(gridplus): add onboarding e2e flow mocks
mrcnk Feb 29, 2024
25bc5f4
Merge branch 'master' into feat/add-gridplus-lattice1
BrodyHughes Feb 29, 2024
fe5d6e7
fix(gridplus): apply pr feedback
mrcnk Mar 11, 2024
e20520e
Merge branch 'feat/add-gridplus-lattice1' of github.com:mrcnk/browser…
mrcnk Mar 11, 2024
21b75f8
Merge branch 'master' into feat/add-gridplus-lattice1
mrcnk Mar 14, 2024
ade3086
fix(gridplus): fix L2 transactions
mrcnk Apr 15, 2024
ad91af6
fix(conflicts): resolve
mrcnk Apr 15, 2024
7b47ed3
chore(gridplus): update logo in wallets & keys
mrcnk Apr 15, 2024
0d2cca3
Merge branch 'master' into feat/add-gridplus-lattice1
DanielSinclair May 1, 2024
03accfd
refactor AddressChoice
greg-schrammel Apr 22, 2024
b309e86
a
greg-schrammel Apr 22, 2024
52179a6
generate password (?)
greg-schrammel Apr 22, 2024
ed0d474
Merge branch 'master' into pr/1346
DanielSinclair May 7, 2024
ff61622
uniqueId as password ?
greg-schrammel May 13, 2024
a64e518
dont open in fullscreen
greg-schrammel May 13, 2024
fedf959
taking too long
greg-schrammel May 15, 2024
98cd1ea
taking too long i18n
greg-schrammel May 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
chore(gridplus): improve onboarding ui
mrcnk committed Feb 1, 2024

Verified

This commit was signed with the committer’s verified signature.
mrcnk Tomek Marciniak
commit 36dd23178ade04084cc2678758f959fffeb63398
16 changes: 15 additions & 1 deletion src/design-system/components/Text/Text.tsx
Original file line number Diff line number Diff line change
@@ -8,7 +8,18 @@ import { selectionStyle } from './Text.css';

export interface TextProps {
align?: TextStyles['textAlign'];
as?: 'div' | 'p' | 'span' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'pre';
as?:
| 'div'
| 'p'
| 'span'
| 'h1'
| 'h2'
| 'h3'
| 'h4'
| 'h5'
| 'h6'
| 'pre'
| 'label';
children: React.ReactNode;
color?: TextStyles['color'];
size: TextStyles['fontSize'];
@@ -21,6 +32,7 @@ export interface TextProps {
whiteSpace?: TextStyles['whiteSpace'];
textShadow?: TextStyles['textShadow'];
fontFamily?: TextStyles['fontFamily'];
htmlFor?: string;
}

export function Text({
@@ -38,6 +50,7 @@ export function Text({
whiteSpace,
textShadow,
fontFamily = 'rounded',
htmlFor,
}: TextProps) {
return (
<Box
@@ -60,6 +73,7 @@ export function Text({
selectionStyle,
])}
testId={testId}
htmlFor={htmlFor}
marginVertical={webkitBackgroundClip === 'text' ? '-6px' : undefined}
paddingVertical={webkitBackgroundClip === 'text' ? '6px' : undefined}
>
13 changes: 12 additions & 1 deletion src/design-system/components/TextOverflow/TextOverflow.tsx
Original file line number Diff line number Diff line change
@@ -6,7 +6,18 @@ import { Inset } from '../Inset/Inset';

interface TextOverflowProps {
align?: TextStyles['textAlign'];
as?: 'div' | 'p' | 'span' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'pre';
as?:
| 'div'
| 'p'
| 'span'
| 'h1'
| 'h2'
| 'h3'
| 'h4'
| 'h5'
| 'h6'
| 'pre'
| 'label';
children: React.ReactNode;
color?: TextStyles['color'];
size: TextStyles['fontSize'];
3 changes: 3 additions & 0 deletions src/entries/popup/components/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@ export function Checkbox({
borderColor = 'separatorSecondary',
borderColorSelected = 'accent',
testId,
id,
}: {
selected: boolean;
onClick?: () => void;
@@ -26,9 +27,11 @@ export function Checkbox({
background?: 'accent' | BackgroundColor;
backgroundSelected?: 'accent' | BackgroundColor;
testId?: string;
id?: string;
}) {
return (
<Box
id={id}
borderRadius={borderRadius || '28px'}
background={selected ? backgroundSelected : background}
borderColor={selected ? borderColorSelected : borderColor}
3 changes: 3 additions & 0 deletions src/entries/popup/pages/hw/gridplus.tsx
Original file line number Diff line number Diff line change
@@ -82,6 +82,9 @@ export function ConnectGridPlus() {
display="flex"
flexDirection="column"
justifyContent="center"
alignItems="center"
flexGrow="1"
flexShrink="1"
gap="32px"
width="full"
>
89 changes: 63 additions & 26 deletions src/entries/popup/pages/hw/gridplus/addressChoice.tsx
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ import { truncateAddress } from '~/core/utils/address';
import { Box, Button, Text } from '~/design-system';
import { Checkbox } from '~/entries/popup/components/Checkbox/Checkbox';
import { Spinner } from '~/entries/popup/components/Spinner/Spinner';
import { useAccounts } from '~/entries/popup/hooks/useAccounts';

export type AddressesData = {
addresses: Address[];
@@ -19,11 +20,13 @@ export type AddressChoiceProps = {
};

export const AddressChoice = ({ onSelected }: AddressChoiceProps) => {
const { sortedAccounts } = useAccounts();
const [formData, setFormData] = useState({
selectedAddresses: [] as string[],
});
const [loadingAddresses, setLoadingAddresses] = useState(true);
const [addresses, setAddresses] = useState<AddressesData['addresses']>([]);
const disabled = loadingAddresses || formData.selectedAddresses.length === 0;
const toggleAddress = (address: string) => {
const selected = formData.selectedAddresses.includes(address);
if (selected)
@@ -44,48 +47,82 @@ export const AddressChoice = ({ onSelected }: AddressChoiceProps) => {
const fetchWalletAddresses = async () => {
setLoadingAddresses(true);
const fetchedAddresses = (await fetchAddresses()) as Address[];
const mixedCaseAddresses = fetchedAddresses.map((address) =>
getAddress(address),
);
setAddresses(mixedCaseAddresses);
const nonExistingAddresses = fetchedAddresses
.map((address) => getAddress(address))
.filter(
(address) =>
!sortedAccounts.map((account) => account.address).includes(address),
);
setAddresses(nonExistingAddresses);
setLoadingAddresses(false);
};
const setPersistedFormData = () => {
const persistedAddresses = JSON.parse(
sessionStorage.getItem('gridplusPersistedAddresses') ?? '[]',
) as string[];
if (persistedAddresses.length < 1) return;
setFormData({ selectedAddresses: persistedAddresses });
};
fetchWalletAddresses();
setPersistedFormData();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
sessionStorage.setItem(
'gridplusPersistedAddresses',
JSON.stringify(formData.selectedAddresses),
);
}, [formData.selectedAddresses]);
return (
<Box
as={motion.form}
display="flex"
flexDirection="column"
onSubmit={onSubmit}
gap="16px"
flexGrow="1"
flexShrink="1"
width="full"
paddingBottom="16px"
>
<Text size="20pt" weight="semibold">
{i18n.t('hw.gridplus_choose_addresses')}
</Text>
{loadingAddresses && <Spinner size={24} />}
<Box display="flex" flexDirection="column" gap="16px">
{addresses.map((address, i) => (
<Box key={address} display="flex" gap="8px" alignItems="center">
<Checkbox
borderColor="blue"
onClick={() => toggleAddress(address)}
selected={formData.selectedAddresses.includes(address)}
testId={`gridplus-address-${i}`}
/>
<Text size="14pt" weight="bold">
{truncateAddress(address)}
</Text>
</Box>
))}
<Box
display="flex"
flexDirection="column"
alignItems="center"
flexGrow="1"
flexShrink="1"
gap="24px"
>
<Text size="20pt" weight="semibold" align="center">
{i18n.t('hw.gridplus_choose_addresses')}
</Text>
{loadingAddresses && <Spinner size={24} />}
<Box display="flex" flexDirection="column" gap="16px">
{addresses.map((address, i) => (
<Box key={address} display="flex" gap="16px" alignItems="center">
<Checkbox
id={`gridplus-address-${i}`}
borderColor="blue"
onClick={() => toggleAddress(address)}
selected={formData.selectedAddresses.includes(address)}
testId={`gridplus-address-${i}`}
/>
<Text size="16pt" weight="medium">
#{i}:
</Text>
<Text size="16pt" weight="medium">
{truncateAddress(address)}
</Text>
</Box>
))}
</Box>
</Box>
<Button
height="36px"
variant="flat"
color="fill"
disabled={loadingAddresses || formData.selectedAddresses.length === 0}
color={disabled ? 'labelQuaternary' : 'accent'}
variant={disabled ? 'disabled' : 'flat'}
disabled={disabled}
testId="gridplus-submit"
width="full"
>
{i18n.t('hw.gridplus_export_addresses')}
</Button>
69 changes: 44 additions & 25 deletions src/entries/popup/pages/hw/gridplus/pairingSecret.tsx
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ export const PairingSecret = ({ onAfterPair }: PairingSecretProps) => {
const [formData, setFormData] = useState({
pairingCode: '',
});
const disabled = pairing || formData.pairingCode.length < 8;
const onSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
setPairing(true);
@@ -37,40 +38,58 @@ export const PairingSecret = ({ onAfterPair }: PairingSecretProps) => {
display="flex"
flexDirection="column"
onSubmit={onSubmit}
gap="16px"
flexGrow="1"
flexShrink="1"
width="full"
paddingBottom="16px"
>
<Text size="20pt" weight="semibold">
{i18n.t('hw.gridplus_check_device')}
</Text>
<Box as="fieldset" display="flex" flexDirection="column" gap="8px">
<Text size="14pt" weight="semibold">
{i18n.t('hw.gridplus_pairing_code')}
<Box
display="flex"
flexDirection="column"
alignItems="center"
flexGrow="1"
flexShrink="1"
gap="24px"
>
<Text size="16pt" weight="bold" color="label" align="center">
{i18n.t('hw.gridplus_check_device')}
</Text>
<Input
id="pairingCode"
height="40px"
variant="bordered"
placeholder="Pairing Code"
onChange={(e) =>
setFormData({ ...formData, pairingCode: e.target.value })
}
value={formData.pairingCode}
testId="gridplus-pairing-code"
autoFocus
/>
{formState.error && (
<Box
as="fieldset"
display="flex"
flexDirection="column"
gap="8px"
width="full"
>
<Text size="14pt" weight="semibold">
{i18n.t('hw.gridplus_wrong_code')}
{i18n.t('hw.gridplus_pairing_code')}
</Text>
)}
<Input
id="pairingCode"
height="40px"
variant="bordered"
placeholder="Pairing Code"
onChange={(e) =>
setFormData({ ...formData, pairingCode: e.target.value })
}
value={formData.pairingCode}
testId="gridplus-pairing-code"
autoFocus
/>
{formState.error && (
<Text size="14pt" weight="semibold">
{i18n.t('hw.gridplus_wrong_code')}
</Text>
)}
</Box>
</Box>
<Button
height="36px"
variant="flat"
color="fill"
testId="gridplus-submit"
disabled={pairing}
color={disabled ? 'labelQuaternary' : 'accent'}
variant={disabled ? 'disabled' : 'flat'}
disabled={disabled}
width="full"
>
{i18n.t('hw.gridplus_pair_device')}
</Button>
Loading