Skip to content

Commit 38d01f3

Browse files
authored
legacy mode additional fixes
1 parent 828a18c commit 38d01f3

File tree

40 files changed

+1318
-1124
lines changed

40 files changed

+1318
-1124
lines changed

apps/browser-extension-wallet/src/components/MainMenu/DropdownMenuOverlay/components/WalletAccounts.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import { getWalletAccountsQtyString } from '@src/utils/get-wallet-count-string';
2626

2727
const defaultAccountName = (accountNumber: number) => `Account #${accountNumber}`;
2828

29-
const NUMBER_OF_ACCOUNTS_PER_WALLET = 24;
29+
const NUMBER_OF_ACCOUNTS_PER_WALLET = 50;
3030
const HW_CONNECT_TIMEOUT_MS = 30_000;
3131

3232
type EnableAccountPasswordDialogData = {

apps/browser-extension-wallet/src/hooks/useWalletManager.ts

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
AddWalletProps,
2525
AnyBip32Wallet,
2626
AnyWallet,
27+
Bip32WalletAccount,
2728
WalletId,
2829
WalletManagerActivateProps,
2930
WalletManagerApi,
@@ -87,7 +88,7 @@ type WalletManagerAddAccountProps = {
8788
type ActivateWalletProps = Omit<WalletManagerActivateProps, 'chainId'>;
8889

8990
type CreateHardwareWalletRevampedParams = {
90-
accountIndex: number;
91+
accountIndexes: number[];
9192
name: string;
9293
connection: Wallet.HardwareWalletConnection;
9394
};
@@ -266,33 +267,37 @@ export const useWalletManager = (): UseWalletManager => {
266267
}, [currentChain]);
267268

268269
const createHardwareWalletRevamped = useCallback<CreateHardwareWalletRevamped>(
269-
async ({ accountIndex, connection, name }) => {
270-
let extendedAccountPublicKey;
271-
try {
272-
extendedAccountPublicKey = await Wallet.getHwExtendedAccountPublicKey(
273-
connection.type,
270+
async ({ accountIndexes, connection, name }) => {
271+
const accounts: Bip32WalletAccount<Wallet.AccountMetadata>[] = [];
272+
for (const accountIndex of accountIndexes) {
273+
let extendedAccountPublicKey;
274+
try {
275+
extendedAccountPublicKey = await Wallet.getHwExtendedAccountPublicKey(
276+
connection.type,
277+
accountIndex,
278+
connection.type === WalletType.Ledger ? connection.value : undefined
279+
);
280+
} catch (error: unknown) {
281+
throw error;
282+
}
283+
accounts.push({
284+
extendedAccountPublicKey,
274285
accountIndex,
275-
connection.type === WalletType.Ledger ? connection.value : undefined
276-
);
277-
} catch (error: unknown) {
278-
throw error;
286+
metadata: { name: defaultAccountName(accountIndex) }
287+
});
279288
}
289+
280290
const addWalletProps: AddWalletProps<Wallet.WalletMetadata, Wallet.AccountMetadata> = {
281-
metadata: { name, lastActiveAccountIndex: accountIndex },
291+
metadata: { name, lastActiveAccountIndex: accountIndexes[0] },
282292
type: connection.type,
283-
accounts: [
284-
{
285-
extendedAccountPublicKey,
286-
accountIndex,
287-
metadata: { name: defaultAccountName(accountIndex) }
288-
}
289-
]
293+
accounts
290294
};
295+
291296
const walletId = await walletRepository.addWallet(addWalletProps);
292297
await walletManager.activate({
293298
walletId,
294299
chainId: getCurrentChainId(),
295-
accountIndex
300+
accountIndex: accountIndexes[0]
296301
});
297302

298303
return {
@@ -323,7 +328,7 @@ export const useWalletManager = (): UseWalletManager => {
323328
connectedDevice
324329
}: CreateHardwareWallet): Promise<Wallet.CardanoWallet> =>
325330
createHardwareWalletRevamped({
326-
accountIndex,
331+
accountIndexes: [accountIndex],
327332
connection: {
328333
type: connectedDevice,
329334
value: typeof deviceConnection !== 'boolean' ? deviceConnection : undefined

apps/browser-extension-wallet/src/lib/scripts/background/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const backgroundServiceProperties: RemoteApiProperties<BackgroundService>
1313
tokenPrices$: RemoteApiPropertyType.HotObservable
1414
},
1515
handleOpenBrowser: RemoteApiPropertyType.MethodReturningPromise,
16+
handleOpenNamiBrowser: RemoteApiPropertyType.MethodReturningPromise,
1617
handleOpenPopup: RemoteApiPropertyType.MethodReturningPromise,
1718
handleChangeTheme: RemoteApiPropertyType.MethodReturningPromise,
1819
handleChangeMode: RemoteApiPropertyType.MethodReturningPromise,

apps/browser-extension-wallet/src/lib/scripts/background/services/utilityServices.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
Message,
88
MessageTypes,
99
OpenBrowserData,
10+
OpenNamiBrowserData,
1011
MigrationState,
1112
TokenPrices,
1213
CoinPrices,
@@ -87,11 +88,18 @@ const handleOpenBrowser = async (data: OpenBrowserData) => {
8788
case BrowserViewSections.NAMI_MIGRATION:
8889
path = walletRoutePaths.namiMigration.root;
8990
break;
91+
case BrowserViewSections.NAMI_HW_FLOW:
92+
path = walletRoutePaths.namiMigration.hwFlow;
93+
break;
9094
}
9195
const params = data.urlSearchParams ? `?${data.urlSearchParams}` : '';
9296
await tabs.create({ url: `app.html#${path}${params}` }).catch((error) => console.error(error));
9397
};
9498

99+
const handleOpenNamiBrowser = async (data: OpenNamiBrowserData) => {
100+
await tabs.create({ url: `popup.html#${data.path}` }).catch((error) => console.error(error));
101+
};
102+
95103
const handleOpenPopup = async () => {
96104
if (typeof chrome.action.openPopup !== 'function') return;
97105
await closeAllLaceWindows();
@@ -184,6 +192,7 @@ exposeApi<BackgroundService>(
184192
{
185193
api$: of({
186194
handleOpenBrowser,
195+
handleOpenNamiBrowser,
187196
handleOpenPopup,
188197
requestMessage$,
189198
migrationState$,

apps/browser-extension-wallet/src/lib/scripts/background/util.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,11 @@ export const getActiveWallet = async ({
122122
return { wallet, account };
123123
};
124124

125-
export const closeAllLaceWindows = async (): Promise<void> => {
125+
export const closeAllLaceWindows = async (shouldRemoveTab?: (url: string) => boolean): Promise<void> => {
126126
const openTabs = await tabs.query({ title: 'Lace' });
127127
// Close all previously opened lace dapp connector windows
128128
for (const tab of openTabs) {
129-
if (DAPP_CONNECTOR_REGEX.test(tab.url)) await tabs.remove(tab.id);
129+
if (!shouldRemoveTab || shouldRemoveTab(tab.url)) await tabs.remove(tab.id);
130130
}
131131
};
132132

@@ -143,7 +143,7 @@ export const ensureUiIsOpenAndLoaded = async (
143143
: undefined;
144144

145145
const windowType: Windows.CreateType = isHardwareWallet ? 'normal' : 'popup';
146-
await closeAllLaceWindows();
146+
await closeAllLaceWindows((tabUrl) => DAPP_CONNECTOR_REGEX.test(tabUrl));
147147

148148
const tab = await launchCip30Popup(url, windowType);
149149
if (tab.status !== 'complete') {

apps/browser-extension-wallet/src/lib/scripts/types/background-service.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,19 @@ export enum BrowserViewSections {
4343
FORGOT_PASSWORD = 'forgot_password',
4444
NEW_WALLET = 'new_wallet',
4545
ADD_SHARED_WALLET = 'add_shared_wallet',
46-
NAMI_MIGRATION = 'nami_migration'
46+
NAMI_MIGRATION = 'nami_migration',
47+
NAMI_HW_FLOW = 'nami_hw_flow'
4748
}
4849

4950
export interface OpenBrowserData {
5051
section: BrowserViewSections;
5152
urlSearchParams?: string;
5253
}
5354

55+
export interface OpenNamiBrowserData {
56+
path: string;
57+
}
58+
5459
interface ChangeThemeMessage {
5560
type: MessageTypes.CHANGE_THEME;
5661
data: ChangeThemeData;
@@ -73,6 +78,7 @@ export type Message = ChangeThemeMessage | HTTPConnectionMessage | OpenBrowserMe
7378
export type BackgroundService = {
7479
handleOpenBrowser: (data: OpenBrowserData, urlSearchParams?: string) => Promise<void>;
7580
handleOpenPopup: () => Promise<void>;
81+
handleOpenNamiBrowser: (data: OpenNamiBrowserData) => Promise<void>;
7682
requestMessage$: Subject<Message>;
7783
migrationState$: BehaviorSubject<MigrationState | undefined>;
7884
coinPrices: CoinPrices;

apps/browser-extension-wallet/src/popup.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ import { storage } from 'webextension-polyfill';
2929
const App = (): React.ReactElement => {
3030
const [mode, setMode] = useState<'lace' | 'nami'>();
3131
storage.onChanged.addListener((changes) => {
32-
const oldModeValue = changes.BACKGROUND_STORAGE.oldValue?.namiMigration;
33-
const newModeValue = changes.BACKGROUND_STORAGE.newValue?.namiMigration;
32+
const oldModeValue = changes.BACKGROUND_STORAGE?.oldValue?.namiMigration;
33+
const newModeValue = changes.BACKGROUND_STORAGE?.newValue?.namiMigration;
3434
if (oldModeValue?.mode !== newModeValue?.mode) {
3535
setMode(newModeValue);
3636
// Force back to original routing

apps/browser-extension-wallet/src/routes/wallet-paths.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ export const walletRoutePaths = {
3939
activating: '/nami/migration/activating',
4040
welcome: '/nami/migration/welcome',
4141
customize: '/nami/migration/customize',
42-
allDone: '/nami/migration/all-done'
42+
allDone: '/nami/migration/all-done',
43+
hwFlow: '/nami/nami-mode/hwTab'
4344
}
4445
};
4546

apps/browser-extension-wallet/src/views/browser-view/features/multi-wallet/hardware-wallet/context.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@ export const HardwareWalletProvider = ({ children }: HardwareWalletProviderProps
170170
try {
171171
cardanoWallet = await createHardwareWalletRevamped({
172172
connection,
173-
...walletData
173+
...walletData,
174+
accountIndexes: [walletData.accountIndex]
174175
});
175176
} catch (error) {
176177
console.error('ERROR creating hardware wallet', { error });

apps/browser-extension-wallet/src/views/nami-mode/NamiView.tsx

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ import { walletBalanceTransformer } from '@src/api/transformers';
2929
import { useObservable } from '@lace/common';
3030
import { getBackgroundStorage, setBackgroundStorage } from '@lib/scripts/background/storage';
3131
import { BackgroundStorage } from '@lib/scripts/types';
32+
import { isKeyHashAddress } from '@cardano-sdk/wallet';
33+
import { useWalletState } from '@hooks/useWalletState';
34+
import { certificateInspectorFactory } from '@src/features/dapp/components/confirm-transaction/utils';
35+
import { useWrapWithTimeout } from '../browser-view/features/multi-wallet/hardware-wallet/useWrapWithTimeout';
3236

3337
const { AVAILABLE_CHAINS, DEFAULT_SUBMIT_API } = config();
3438

@@ -37,15 +41,26 @@ export const NamiView = withDappContext((): React.ReactElement => {
3741
const { priceResult } = useFetchCoinPrice();
3842
const [namiMigration, setNamiMigration] = useState<BackgroundStorage['namiMigration']>();
3943
const backgroundServices = useBackgroundServiceAPIContext();
40-
const { createWallet, getMnemonic, deleteWallet, switchNetwork, enableCustomNode, addAccount, walletRepository } =
41-
useWalletManager();
44+
const {
45+
createWallet,
46+
getMnemonic,
47+
deleteWallet,
48+
switchNetwork,
49+
enableCustomNode,
50+
addAccount,
51+
walletRepository,
52+
connectHardwareWalletRevamped,
53+
createHardwareWalletRevamped,
54+
saveHardwareWallet
55+
} = useWalletManager();
4256
const {
4357
walletUI,
4458
inMemoryWallet,
59+
walletType,
4560
walletInfo,
4661
currentChain,
4762
environmentName,
48-
blockchainProvider: { stakePoolProvider }
63+
blockchainProvider: { stakePoolProvider, chainHistoryProvider }
4964
} = useWalletStore();
5065
const { theme, setTheme } = useTheme();
5166
const { handleAnalyticsChoice, isAnalyticsOptIn, sendEventToPostHog } = useAnalytics();
@@ -62,14 +77,18 @@ export const NamiView = withDappContext((): React.ReactElement => {
6277
const { txFee, isInitializing, initializeCollateralTx, submitCollateralTx } = useCollateral();
6378

6479
const cardanoPrice = priceResult.cardano.price;
65-
const walletAddress = walletInfo?.addresses[0].address.toString();
80+
const walletAddresses = walletInfo?.addresses
81+
.filter((address) => isKeyHashAddress(address))
82+
.map(({ address }) => address);
6683
const { setAvatar } = useWalletAvatar();
6784
const { delegationTxFee, setDelegationTxFee, setSelectedStakePool, setDelegationTxBuilder, delegationTxBuilder } =
6885
useDelegationStore();
6986
const { buildDelegation } = useBuildDelegation();
7087
const { signAndSubmitTransaction } = useDelegationTransaction();
7188
const { isBuildingTx, stakingError, setIsBuildingTx } = useStakePoolDetails();
89+
const walletState = useWalletState();
7290
const passwordUtil = useSecrets();
91+
const openExternalLink = useExternalLinkOpener();
7392
const getStakePoolInfo = useCallback(
7493
(id: Wallet.Cardano.PoolId) => getPoolInfos([id], stakePoolProvider),
7594
[stakePoolProvider]
@@ -90,7 +109,6 @@ export const NamiView = withDappContext((): React.ReactElement => {
90109
const { coinBalance: minAda } = walletBalanceTransformer(protocolParameters?.stakeKeyDeposit.toString());
91110
const coinBalance = balance?.total?.coinBalance && Number(balance?.total?.coinBalance);
92111
const hasNoFunds = (coinBalance < Number(minAda) && !isStakeRegistered) || (coinBalance === 0 && isStakeRegistered);
93-
const openExternalLink = useExternalLinkOpener();
94112

95113
useEffect(() => {
96114
getBackgroundStorage()
@@ -111,6 +129,24 @@ export const NamiView = withDappContext((): React.ReactElement => {
111129
namiMigration: migration
112130
});
113131
};
132+
const getTxInputsValueAndAddress = useCallback(
133+
async (inputs: Wallet.Cardano.TxIn[] | Wallet.Cardano.HydratedTxIn[]) =>
134+
await Wallet.getTxInputsValueAndAddress(inputs, chainHistoryProvider, inMemoryWallet),
135+
[chainHistoryProvider, inMemoryWallet]
136+
);
137+
138+
const sortedHistoryTx = useMemo(
139+
() => walletState?.transactions.history.sort((tx1, tx2) => tx2.blockHeader.slot - tx1.blockHeader.slot),
140+
[walletState]
141+
);
142+
143+
const openHWFlow = useCallback(
144+
(path: string) => {
145+
backgroundServices.handleOpenNamiBrowser({ path });
146+
},
147+
[backgroundServices]
148+
);
149+
const connectHW = useWrapWithTimeout(connectHardwareWalletRevamped);
114150

115151
return (
116152
<OutsideHandlesProvider
@@ -132,7 +168,6 @@ export const NamiView = withDappContext((): React.ReactElement => {
132168
setFiatCurrency,
133169
theme: theme.name,
134170
setTheme,
135-
walletAddress,
136171
inMemoryWallet,
137172
currentChain,
138173
cardanoPrice,
@@ -159,7 +194,17 @@ export const NamiView = withDappContext((): React.ReactElement => {
159194
hasNoFunds,
160195
setAvatar,
161196
switchWalletMode,
162-
openExternalLink
197+
openExternalLink,
198+
walletAddresses,
199+
transactions: sortedHistoryTx,
200+
eraSummaries: walletState?.eraSummaries,
201+
getTxInputsValueAndAddress,
202+
certificateInspectorFactory,
203+
openHWFlow,
204+
walletType,
205+
connectHW,
206+
createHardwareWalletRevamped,
207+
saveHardwareWallet
163208
}}
164209
>
165210
<Nami />

0 commit comments

Comments
 (0)