Skip to content

Commit

Permalink
Merge pull request #4 from vitelabs/v1.0.5
Browse files Browse the repository at this point in the history
v1.0.5
  • Loading branch information
wepsree authored Sep 23, 2022
2 parents 6d4ee3a + 2d45642 commit 1d98827
Show file tree
Hide file tree
Showing 17 changed files with 98 additions and 922 deletions.
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "Vite Passport",
"version": "1.0.4",
"version": "1.0.5",
"icons": {
"1024": "src/assets/logo-blue-1024.png"
},
Expand Down
7 changes: 0 additions & 7 deletions src/components/TransactionModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,6 @@ const TransactionModal = ({
onClick={async () => {
try {
sendingTxSet(true);
// await vitePassport.writeAccountBlock('send', {
// address: 'vite_2daedeee8d0a41085dee136e36052f48d8e6122b9fec075639',
// toAddress: 'vite_f30697191707a723c70d0652ab80304195e5928dcf71fcab99',
// tokenId: 'tti_5649544520544f4b454e6e40',
// amount: 1 + '0'.repeat(17), // 0.1 VITE
// });

unsentBlock.setProvider(viteApi);
unsentBlock.setPrivateKey(activeAccount.privateKey);
await unsentBlock.autoSetPreviousAccountBlock();
Expand Down
3 changes: 1 addition & 2 deletions src/containers/ResetWalletModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,12 @@ const ResetWalletModal = ({
buttonText={i18n.confirm}
onButtonClick={async () => {
const storage = await getValue(null);
removeKeys(Object.keys(storage) as StorageFields[]);
removeKeys(Object.keys(storage));
setValue(defaultStorage);
setState({
...defaultStorage,
secrets: undefined,
activeAccount: undefined,
accountList: undefined,
});
sendBgScriptPortMessage({ type: 'lock' });
navigate('/', { replace: true });
Expand Down
1 change: 1 addition & 0 deletions src/containers/SendTokenFlow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ const SendTokenFlow = ({
<TextInput
numeric
_ref={amountRef}
maxDecimals={selectedToken.decimal}
label={i18n.amount}
getIssue={(v) => {
if (+v > +selectedTokenBalance!) {
Expand Down
12 changes: 6 additions & 6 deletions src/containers/TextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,15 @@ type Props = State &
compact?: boolean;
};

const normalizeNumericInput = (str: string, decimals = 6, removeInsignificantZeros = false) => {
const normalizeNumericInput = (str: string, decimals: number, removeInsignificantZeros = false) => {
if (Number.isNaN(+str) || !str) {
return '';
}
const firstDotIndex = str.indexOf('.');
if (str.slice(firstDotIndex + 1).length > decimals) {
str = str.slice(0, firstDotIndex + decimals + 1);
let firstDotIndex = str.indexOf('.');
if (firstDotIndex === -1) {
firstDotIndex = str.length;
}
str = str.slice(0, firstDotIndex + decimals + 1);
if (removeInsignificantZeros) {
str = +str + '';
}
Expand All @@ -71,7 +72,7 @@ const TextInput = ({
showPasswordRequirements,
initialValue,
resizable,
maxDecimals,
maxDecimals = 0,
disabled,
label,
placeholder = '',
Expand Down Expand Up @@ -156,7 +157,6 @@ const TextInput = ({
if (numeric && value) {
// eslint-disable-next-line
value = value.replace(/[^0123456789\.]/g, '');
// value = value.replace(/\.+/g, '.');
value = normalizeNumericInput(value, maxDecimals);
}
value = maxLength ? value.slice(0, maxLength) : value;
Expand Down
3 changes: 2 additions & 1 deletion src/containers/WalletContents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Checkbox from '../components/Checkbox';
import DeterministicIcon from '../components/DeterministicIcon';
import Modal from '../components/Modal';
import QR from '../components/QR';
import { defaultStorage, defaultTokenList, getTokenFuzzySearchApiUrl } from '../utils/constants';
import { defaultTokenList, getTokenFuzzySearchApiUrl } from '../utils/constants';
import { connect } from '../utils/global-context';
import { debounceAsync, formatPrice, getTokenApiInfo } from '../utils/misc';
import { setValue } from '../utils/storage';
Expand Down Expand Up @@ -292,6 +292,7 @@ const WalletContents = ({
numeric
_ref={amountRef}
label={i18n.amount}
maxDecimals={selectedToken.decimal}
value={amount}
onUserInput={(v) => amountSet(v)}
/>
Expand Down
15 changes: 8 additions & 7 deletions src/contentScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ window.addEventListener('vitePassportMethodCalled', (async (
) => {
const hostname = getHostname(window.location.href);
const { connectedDomains } = await getValue('connectedDomains');
const { accountList, activeAccountIndex } = await getValue(['accountList', 'activeAccountIndex']);
const activeAccount = accountList ? accountList[activeAccountIndex!] : undefined;
const domainConnected = !activeAccount
? false
: !!connectedDomains?.[activeAccount.address]?.[hostname];
const { derivedAddresses, activeAccountIndex } = await getValue([
'derivedAddresses',
'activeAccountIndex',
]);
const activeAddress = derivedAddresses ? derivedAddresses[activeAccountIndex!] : undefined;
const domainConnected = !activeAddress ? false : !!connectedDomains?.[activeAddress]?.[hostname];

const reply = (message: Omit<ContentResponse, '_messageId'>) => {
window.postMessage({
Expand All @@ -43,11 +44,11 @@ window.addEventListener('vitePassportMethodCalled', (async (
switch (event.detail.method) {
case 'getConnectedAddress':
if (!domainConnected) return reply({ result: undefined });
reply({ result: activeAccount!.address });
reply({ result: activeAddress });
break;
case 'disconnectWallet':
if (!domainConnected) return connectError();
delete connectedDomains![activeAccount!.address][hostname];
delete connectedDomains![activeAddress!][hostname];
setValue({ connectedDomains });
reply({ result: undefined });
break;
Expand Down
26 changes: 21 additions & 5 deletions src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import './styles/classes.css';
import './styles/theme.ts';

import { injectedScriptEventData, BgScriptPortMessage, State } from './utils/types';
import { getValue, setValue } from './utils/storage';
import { getValue, removeKeys, setValue } from './utils/storage';
import { wallet } from '@vite/vitejs';
import { defaultStorage, i18nDict } from './utils/constants';
import { getCurrentTab } from './utils/misc';
Expand All @@ -20,9 +20,13 @@ const listen = async (message: BgScriptPortMessage) => {
chromePort.onMessage.removeListener(listen);
const storage = await getValue(null);

(Object.keys(defaultStorage) as (keyof typeof defaultStorage)[]).forEach((key) => {
Object.keys(storage).forEach((key) => {
if (!(key in defaultStorage)) {
removeKeys(key);
}
});
Object.keys(defaultStorage).forEach((key) => {
if (storage[key] === undefined) {
// @ts-ignore
storage[key] = defaultStorage[key];
setValue({ [key]: defaultStorage[key] });
}
Expand All @@ -37,18 +41,19 @@ const listen = async (message: BgScriptPortMessage) => {
window.onbeforeunload = () => {
// this rejects any pending promises in injectedScript.ts
// @ts-ignore
chrome.tabs.sendMessage(tabIdToInteractWith, { type: 'disconnect' }).catch((e) => {});
chrome.tabs.sendMessage(tabIdToInteractWith, { type: 'disconnect' }).catch(() => {});
};

const state: Partial<State> = {
...defaultStorage,
...storage,
chromePort,
i18n: i18nDict[storage.language!],
activeNetwork: storage.networkList![storage.activeNetworkIndex!],
sendBgScriptPortMessage: (message: BgScriptPortMessage) => chromePort.postMessage(message),
triggerInjectedScriptEvent: async (event: injectedScriptEventData) => {
// @ts-ignore
chrome.tabs.sendMessage(tabIdToInteractWith, event).catch((e) => {});
chrome.tabs.sendMessage(tabIdToInteractWith, event).catch(() => {});
},
};

Expand All @@ -59,6 +64,17 @@ const listen = async (message: BgScriptPortMessage) => {
});
state.secrets = message.secrets;
state.sendBgScriptPortMessage!({ type: 'reopen' });
// NOTE: eventually this `if` block can be deleted. It's necessary now for
// the users of v1.0.4 and before when derivedAddresses didn't exist
if (!storage.derivedAddresses) {
const addressEndIndex = storage.activeAccountIndex || defaultStorage.activeAccountIndex;
const derivedAddresses: string[] = [];
for (let i = 0; i <= addressEndIndex; i++) {
derivedAddresses.push(wallet.deriveAddress({ ...message.secrets, index: i }).address);
}
state.derivedAddresses = derivedAddresses;
setValue({ derivedAddresses });
}
}

root.render(
Expand Down
11 changes: 8 additions & 3 deletions src/pages/Connect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { State } from '../utils/types';
const Connect = ({
i18n,
contacts,
accountList,
derivedAddresses,
activeAccountIndex,
triggerInjectedScriptEvent,
connectedDomains,
Expand All @@ -21,6 +21,11 @@ const Connect = ({
if (!hostname) {
throw new Error('hostname not provided in search params');
}
if (!derivedAddresses) {
// This should never happen. If the wallet does not exist and a dapp tries to connect to VP,
// the user should be prompted with `/` route
throw new Error('derivedAddresses does not exist');
}

return (
<div className="h-full flex flex-col">
Expand All @@ -31,7 +36,7 @@ const Connect = ({
</div>
</div>
<div className="flex-1 overflow-scroll">
{accountList.map(({ address }, i) => {
{derivedAddresses.map((address, i) => {
const active = i === lastActiveAccountIndex;
return (
<ModalListItem
Expand All @@ -53,7 +58,7 @@ const Connect = ({
theme="highlight"
label={i18n.confirm}
onClick={async () => {
const activeAddress = accountList[lastActiveAccountIndex].address;
const activeAddress = derivedAddresses[lastActiveAccountIndex];
triggerInjectedScriptEvent({ type: 'connectWallet', payload: { domain: hostname } });
triggerInjectedScriptEvent({
type: 'accountChange',
Expand Down
21 changes: 8 additions & 13 deletions src/pages/Create2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@ import Checkbox from '../components/Checkbox';
import { encrypt } from '../utils/encryption';
import { wallet } from '@vite/vitejs';
import { setValue } from '../utils/storage';
import { defaultStorage } from '../utils/constants';
import { useState } from 'react';
import Button from '../components/Button';
import { AddressObj } from '@vite/vitejs/distSrc/utils/type';

const Create2 = ({ i18n, sendBgScriptPortMessage, setState, secrets }: State) => {
const navigate = useNavigate();
const {
state: { routeAfterUnlock },
} = useLocation() as {
const { state } = useLocation() as {
state: { routeAfterUnlock?: string };
};
const [agreesToTerms, agreesToTermsSet] = useState(false);
Expand Down Expand Up @@ -75,24 +73,21 @@ const Create2 = ({ i18n, sendBgScriptPortMessage, setState, secrets }: State) =>
if (valid) {
sendBgScriptPortMessage({ secrets, type: 'updateSecrets' });
const encryptedSecrets = await encrypt(JSON.stringify(secrets), passwordRef.value);
const account = wallet.deriveAddress({
const account: AddressObj = wallet.deriveAddress({
...secrets,
index: 0,
});
const { privateKey } = account;
delete account.privateKey;
const accountList = [account];
const derivedAddresses = [account.address];
const contacts = { [account.address]: 'Account 0' };
setValue({ ...defaultStorage, encryptedSecrets, accountList, contacts });
setValue({ encryptedSecrets, derivedAddresses, contacts });
setState({
...defaultStorage,
secrets,
encryptedSecrets,
accountList,
derivedAddresses,
contacts,
activeAccount: { ...account, privateKey },
activeAccount: account,
});
navigate(routeAfterUnlock || '/home');
navigate(state.routeAfterUnlock || '/home');
}
}}
/>
Expand Down
46 changes: 27 additions & 19 deletions src/pages/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
} from '@heroicons/react/outline';
import { ExternalLinkIcon } from '@heroicons/react/solid';
import { wallet } from '@vite/vitejs';
import { AddressObj } from '@vite/vitejs/distSrc/utils/type';
import { useEffect, useMemo, useState } from 'react';
import ViteLogo from '../assets/ViteLogo';
import A from '../components/A';
Expand All @@ -29,7 +30,7 @@ import {
validateHttpUrl,
validateWsUrl,
} from '../utils/strings';
import { State, TokenApiInfo } from '../utils/types';
import { State, Storage, TokenApiInfo } from '../utils/types';

// constant.Contracts.StakeForQuota_V1
// constant.Contracts.StakeForQuota
Expand All @@ -44,7 +45,7 @@ const Home = ({
copyWithToast,
networkList,
activeNetworkIndex,
accountList,
derivedAddresses,
contacts,
toastSuccess,
triggerInjectedScriptEvent,
Expand Down Expand Up @@ -88,6 +89,11 @@ const Home = ({
getCurrentTab().then((tab) => hostnameSet(getHostname(tab.url)));
}, []);

if (!derivedAddresses) {
// This should never happen. Wallet should be created before they can view `/home` route.
throw new Error('derivedAddresses does not exist');
}

return (
<TabContainer>
<div className="bg-skin-middleground shadow-md z-10 p-4">
Expand Down Expand Up @@ -326,25 +332,22 @@ const Home = ({
onClose={() => changingActiveAccountSet(false)}
buttonText={i18n.deriveAddress}
onButtonClick={() => {
const newAccount = wallet.deriveAddress({
const newAccount: AddressObj = wallet.deriveAddress({
...secrets!,
index: accountList.length,
index: derivedAddresses.length,
});
delete newAccount.privateKey;
const newAccountList = [...accountList, newAccount];
const newContacts = {
...contacts,
[newAccount.address]: `Account ${accountList.length}`,
};
const data = {
accountList: newAccountList,
contacts: newContacts,
const data: Partial<Storage> = {
derivedAddresses: [...derivedAddresses, newAccount.address],
contacts: {
...contacts,
[newAccount.address]: `Account ${derivedAddresses.length}`,
},
};
setState(data);
setValue(data);
}}
>
{accountList.map(({ address }, i) => {
{derivedAddresses.map((address, i) => {
const active = i === activeAccountIndex;
return (
<ModalListItem
Expand All @@ -370,7 +373,7 @@ const Home = ({
});
setValue(data);
const { connectedDomains } = await getValue('connectedDomains');
const newActiveAddress = accountList[i].address;
const newActiveAddress = derivedAddresses[i];
const newActiveAccountConnected =
!!connectedDomains?.[newActiveAddress]?.[hostname];
const lastAccountWasConnected =
Expand All @@ -390,13 +393,18 @@ const Home = ({
changingActiveAccountSet(false);
}}
onX={
i + 1 !== accountList.length || i === 0
i + 1 !== derivedAddresses.length || i === 0
? undefined
: () => {
const data = {
accountList: [...accountList].slice(0, accountList.length - 1),
const data: Partial<Storage> = {
derivedAddresses: [...derivedAddresses].slice(
0,
derivedAddresses.length - 1
),
activeAccountIndex:
activeAccountIndex === accountList.length - 1 ? 0 : activeAccountIndex,
activeAccountIndex === derivedAddresses.length - 1
? 0
: activeAccountIndex,
};
setState(data);
setValue(data);
Expand Down
Loading

0 comments on commit 1d98827

Please sign in to comment.