Skip to content

Commit

Permalink
Merge pull request #644 from onflow:643-feature-correct-all-exception…
Browse files Browse the repository at this point in the history
…s-thrown-during-registration-process

643-feature-correct-all-exceptions-thrown-during-registration-process
  • Loading branch information
tombeckenham authored Mar 4, 2025
2 parents be8b4b2 + 19fd005 commit 33ac152
Show file tree
Hide file tree
Showing 12 changed files with 151 additions and 57 deletions.
56 changes: 36 additions & 20 deletions src/background/controller/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { type LoggedInAccount } from '@/shared/types/wallet-types';
import { ensureEvmAddressPrefix, isValidEthereumAddress, withPrefix } from '@/shared/utils/address';
import { getSignAlgo } from '@/shared/utils/algo';
import { convertToIntegerAmount, validateAmount } from '@/shared/utils/number';
import { retryOperation } from '@/shared/utils/retryOperation';
import {
keyringService,
preferenceService,
Expand Down Expand Up @@ -181,6 +182,24 @@ export class WalletController extends BaseController {
await this.refreshUserWallets();
// Refresh the child wallets
await this.setChildWallet(await this.checkUserChildAccount());
// Refresh the logged in account
const [keys, pubKTuple] = await Promise.all([this.getAccount(), this.getPubKey()]);
// Check if a child wallet is active (it shouldn't be...)
const anyActiveChild = await this.getActiveWallet();
// Get the current wallet
const currentWallet = await this.getCurrentWallet();
if (!currentWallet) {
throw new Error('Current wallet is undefined');
}
// Refresh the user info
let userInfo = {};
try {
userInfo = await retryOperation(async () => this.getUserInfo(true), 3, 1000);
} catch (error) {
console.error('Error refreshing user info:', error);
}
// Refresh the user info
await openapiService.freshUserInfo(currentWallet, keys, pubKTuple, userInfo, anyActiveChild);
};

retrievePk = async (password: string) => {
Expand Down Expand Up @@ -835,17 +854,14 @@ export class WalletController extends BaseController {
return preferenceService.updateIsFirstOpen();
};
// userinfo
getUserInfo = async (forceRefresh: boolean) => {
const data = await userInfoService.getUserInfo();

if (forceRefresh) {
return await this.fetchUserInfo();
}

if (data.username.length) {
return data;
getUserInfo = async (forceRefresh: boolean = false) => {
if (!forceRefresh) {
const data = userInfoService.getUserInfo();
if (data.username.length) {
return data;
}
}

// Either force refresh or the user info is not set
return await this.fetchUserInfo();
};

Expand Down Expand Up @@ -957,14 +973,6 @@ export class WalletController extends BaseController {
return domain;
};

updateUserInfo = (data: UserInfoStore) => {
userInfoService.updateUserInfo(data);
};

removeUserInfo = () => {
userInfoService.removeUserInfo();
};

getDashIndex = async () => {
const dashIndex = await userInfoService.getDashIndex();
return dashIndex;
Expand Down Expand Up @@ -1594,6 +1602,9 @@ export class WalletController extends BaseController {
};

getCurrentWallet = async (): Promise<BlockchainResponse | undefined> => {
if (!this.isBooted() || userWalletService.isLocked()) {
return;
}
const wallet = await userWalletService.getCurrentWallet();
if (!wallet?.address) {
const network = await this.getNetwork();
Expand Down Expand Up @@ -1641,6 +1652,9 @@ export class WalletController extends BaseController {
};

getMainAddress = async () => {
if (!this.isBooted() || userWalletService.isLocked()) {
return '';
}
const network = await this.getNetwork();
const address = await userWalletService.getMainWallet(network);
if (!address) {
Expand Down Expand Up @@ -3071,8 +3085,9 @@ export class WalletController extends BaseController {
};

checkNetwork = async () => {
const network = await this.getNetwork();
await this.switchNetwork(network);
if (!this.isBooted() || userWalletService.isLocked()) {
return;
}
};

switchMonitor = async (monitor: string) => {
Expand All @@ -3084,6 +3099,7 @@ export class WalletController extends BaseController {
};

refreshAll = async () => {
console.trace('refreshAll trace');
console.log('refreshAll');
await this.refreshUserWallets();
this.clearNFT();
Expand Down
26 changes: 22 additions & 4 deletions src/background/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,16 @@ async function restoreAppState() {
// Set the loaded flag to true so that the UI knows the app is ready
walletController.setLoaded(true);
console.log('restoreAppState chrome.runtime.sendMessage->');
chrome.runtime.sendMessage({ type: 'walletInitialized' });

chrome.runtime.sendMessage({ type: 'walletInitialized' }, (response) => {
if (chrome.runtime.lastError) {
console.log(
'chrome.runtime.sendMessage - Message delivery failed:',
chrome.runtime.lastError.message
);
} else {
console.log('chrome.runtime.sendMessage - Message delivered successfully:', response);
}
});
console.log('restoreAppState chrome.tabs.query->');
chrome.tabs
.query({
Expand All @@ -147,9 +155,19 @@ async function restoreAppState() {
.then((tabs) => {
tabs.forEach((tab) => {
const tabId = tab.id;
if (tabId) {
if (tabId && !tab.url?.match(/^chrome*/)) {
console.log('restoreAppState chrome.tabs.sendMessage->', tabId);
chrome.tabs.sendMessage(tabId, { type: 'walletInitialized' });
chrome.tabs.sendMessage(tabId, { type: 'walletInitialized' }, (response) => {
if (chrome.runtime.lastError) {
console.log(
'chrome.tabs.sendMessage - Message delivery failed:',
chrome.runtime.lastError.message
);
// You can implement retry logic or alternative actions here
} else {
console.log('chrome.tabs.sendMessage - Message delivered successfully:', response);
}
});
}
});
});
Expand Down
6 changes: 0 additions & 6 deletions src/background/service/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,6 @@ class UserInfo {
this.store = template;
};

updateUserInfo = (data: UserInfoStore) => {
this.store = data;
// identify the user
mixpanelTrack.identify(this.store.user_id);
};

setDashIndex = (data: number) => {
this.store.dashboardIndex = data;
};
Expand Down
9 changes: 9 additions & 0 deletions src/background/service/userWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,16 @@ class UserWallet {
};

reSign = async () => {
// Try to re-establish the session if the user's wallet is unlocked
if (this.isLocked()) {
// If the wallet is locked, we can't sign in
return;
}
const password = keyringService.password;
if (!password) {
// No password means the wallet is not unlocked
return;
}
const privateKey = await wallet.getPrivateKeyForCurrentAccount(password);
return await this.sigInWithPk(privateKey);
};
Expand Down
9 changes: 6 additions & 3 deletions src/shared/utils/retryOperation.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
export const retryOperation = async (
operation: () => Promise<any>,
export const retryOperation = async <T>(
operation: () => Promise<T>,
maxAttempts = 3,
delay = 1000
) => {
): Promise<T> => {
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await operation();
} catch (error) {
if (attempt === maxAttempts) throw error;
// eslint-disable-next-line no-console
console.log(`Attempt ${attempt} failed, retrying in ${delay}ms...`);
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
// Show never get here...
throw new Error('Operation failed after all attempts');
};
14 changes: 8 additions & 6 deletions src/ui/FRWComponent/LandingPages/RepeatPhrase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,12 @@ const RepeatPhrase = ({ handleSwitchTab, mnemonic }) => {
>
{repeatArray.map((word, i) => {
return (
<Box>
<Box key={`row${i}`} aria-label={`row${i}`}>
<Typography variant="body1" sx={{ padding: '12px 0 12px' }}>
{chrome.i18n.getMessage('Select_the_word_at')}
<Box display="inline" color="primary.main">
<Typography component="span" color="primary.main" display="inline">
{' #' + (chosenIndex[i] + 1) + ' '}
</Box>
</Typography>
</Typography>
<Box
sx={{
Expand All @@ -140,12 +140,14 @@ const RepeatPhrase = ({ handleSwitchTab, mnemonic }) => {
backgroundColor: '#333333',
transition: 'all .3s linear',
}}
key={i}
aria-label={`row${i}`}
>
{word.map((v, index) => {
return (
<Box sx={{ width: '33.3%', height: '100%' }} key={'key_' + index}>
<Box
sx={{ width: '33.3%', height: '100%' }}
key={`Select_the_word_at-${i}-${index}`}
aria-label={`Select_the_word_at-${i}-${index}`}
>
<Button
onClick={() => setSelected(i, v)}
sx={{
Expand Down
3 changes: 3 additions & 0 deletions src/ui/hooks/__tests__/useCoinHook.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ vi.mock('@/ui/utils/WalletContext', () => ({
useWalletLoaded: vi.fn().mockReturnValue(true),
useWallet: vi.fn().mockReturnValue({
refreshCoinList: vi.fn().mockResolvedValue(undefined),
isUnlocked: vi.fn().mockResolvedValue(true),
getMainWallet: vi.fn().mockResolvedValue('test-address'),
}),
}));

Expand Down Expand Up @@ -159,6 +161,7 @@ describe('useCoinHook', () => {
useWallet: () => ({
refreshCoinList: vi.fn().mockResolvedValue(undefined),
getMainWallet: vi.fn(),
isUnlocked: vi.fn().mockResolvedValue(true),
openapi: {
getAccountMinFlow: vi.fn(),
},
Expand Down
16 changes: 15 additions & 1 deletion src/ui/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
import { useCallback } from 'react';

import { useWalletLoaded } from '../utils/WalletContext';

import { useCoins } from './useCoinHook';
import { useNetworks } from './useNetworkHook';
import { useProfiles } from './useProfileHook';

export const useInitHook = () => {
const walletLoaded = useWalletLoaded();
const { fetchProfileData, freshUserWallet, fetchUserWallet } = useProfiles();
const { fetchNetwork } = useNetworks();
const { refreshCoinData } = useCoins();

const initializeStore = useCallback(async () => {
if (!walletLoaded) {
return;
}

await fetchNetwork();
await fetchProfileData();
await freshUserWallet();
await fetchUserWallet();
await refreshCoinData();
}, [fetchNetwork, fetchProfileData, freshUserWallet, fetchUserWallet, refreshCoinData]);
}, [
fetchNetwork,
fetchProfileData,
freshUserWallet,
fetchUserWallet,
refreshCoinData,
walletLoaded,
]);

return { initializeStore };
};
20 changes: 20 additions & 0 deletions src/ui/hooks/useCoinHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,16 @@ export const useCoins = () => {

const calculateAvailableBalance = useCallback(async () => {
try {
// Make sure the wallet is unlocked
if (!(await usewallet.isUnlocked())) {
console.log('calculateAvailableBalance - Wallet is locked');
return;
}
if (!(await usewallet.getMainWallet())) {
console.log('calculateAvailableBalance - No main wallet yet');
return;
}

const address = withPrefix(mainAddress) || '';
// TODO: need a controller for this
const minAmount = new BN(
Expand Down Expand Up @@ -96,6 +106,16 @@ export const useCoins = () => {
const refreshCoinData = useCallback(async () => {
if (!usewallet || !walletLoaded) return;

// Make sure the wallet is unlocked
if (!(await usewallet.isUnlocked())) {
console.log('Wallet is locked');
return;
}
if (!(await usewallet.getMainWallet())) {
console.log('No main wallet yet');
return;
}

try {
const refreshedCoinlist = await usewallet.refreshCoinList(60000);
if (Array.isArray(refreshedCoinlist) && refreshedCoinlist.length > 0) {
Expand Down
21 changes: 8 additions & 13 deletions src/ui/hooks/useProfileHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {
WalletResponse,
} from '@/shared/types/network-types';
import { ensureEvmAddressPrefix, withPrefix } from '@/shared/utils/address';
import { retryOperation } from '@/shared/utils/retryOperation';
import { useNetworks } from '@/ui/hooks/useNetworkHook';
import { useProfileStore } from '@/ui/stores/profileStore';
import { useWallet, useWalletLoaded } from '@/ui/utils/WalletContext';
Expand Down Expand Up @@ -109,6 +110,11 @@ export const useProfiles = () => {
const freshUserInfo = useCallback(async () => {
if (!usewallet || !walletLoaded) return;
try {
// Make sure the wallet is unlocked and has a main wallet
if (!(await usewallet.getMainWallet())) {
console.log('freshUserInfo - No main wallet yet');
return;
}
//TODO: should rethink the wording of the wallet functions, have it be parent evm and child or something similar. State name and should be the same frontend and background.
const [currentWallet, isChild, mainAddress] = await Promise.all([
usewallet.getCurrentWallet(),
Expand All @@ -117,7 +123,8 @@ export const useProfiles = () => {
]);

if (!currentWallet) {
throw new Error('Current wallet is undefined');
// We may not be logged in yet
return;
}
const mainwallet = await usewallet.returnMainWallet();
setParentWallet(mainwallet!);
Expand Down Expand Up @@ -233,15 +240,3 @@ export const useProfiles = () => {
mainAddressLoading,
};
};

const retryOperation = async (operation: () => Promise<any>, maxAttempts = 3, delay = 1000) => {
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await operation();
} catch (error) {
if (attempt === maxAttempts) throw error;
console.log(`Attempt ${attempt} failed, retrying in ${delay}ms...`);
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
};
Loading

0 comments on commit 33ac152

Please sign in to comment.