Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into fix/lw-9912-fix-old-f…
Browse files Browse the repository at this point in the history
…irmware-multidelegation-defect
  • Loading branch information
pczeglik-iohk committed Apr 23, 2024
2 parents 9cdaa64 + ccdec2a commit 9132359
Show file tree
Hide file tree
Showing 149 changed files with 2,492 additions and 1,766 deletions.
12 changes: 6 additions & 6 deletions apps/browser-extension-wallet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@
},
"dependencies": {
"@ant-design/icons": "^4.7.0",
"@cardano-sdk/cardano-services-client": "0.18.0",
"@cardano-sdk/cardano-services-client": "0.19.0",
"@cardano-sdk/core": "0.30.0",
"@cardano-sdk/dapp-connector": "0.12.14",
"@cardano-sdk/input-selection": "0.12.26",
"@cardano-sdk/tx-construction": "0.18.2",
"@cardano-sdk/input-selection": "0.12.27",
"@cardano-sdk/tx-construction": "0.18.3",
"@cardano-sdk/util": "0.15.0",
"@cardano-sdk/wallet": "0.35.2",
"@cardano-sdk/web-extension": "0.26.1",
"@cardano-sdk/wallet": "0.37.0",
"@cardano-sdk/web-extension": "0.27.0",
"@emurgo/cip14-js": "~3.0.1",
"@koralabs/handles-public-api-interfaces": "^1.6.6",
"@lace/cardano": "0.1.0",
Expand All @@ -59,7 +59,7 @@
"@vespaiach/axios-fetch-adapter": "^0.3.0",
"antd": "^4.24.10",
"are-you-es5": "^2.1.2",
"axios": "0.21.4",
"axios": "0.28.0",
"bignumber.js": "9.0.1",
"bip39": "^3.0.4",
"blake2b-no-wasm": "2.1.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Flex } from '@lace/ui';
import { useViewsFlowContext } from '@providers/ViewFlowProvider';

import { Wallet } from '@lace/cardano';
import { withAddressBookContext } from '@src/features/address-book/context';
import { useAddressBookContext, withAddressBookContext } from '@src/features/address-book/context';
import { useWalletStore } from '@stores';
import { useFetchCoinPrice, useChainHistoryProvider } from '@hooks';
import {
Expand All @@ -23,6 +23,7 @@ import { useCurrencyStore, useAppSettingsContext } from '@providers';
import { logger } from '@lib/wallet-api-ui';
import { useComputeTxCollateral } from '@hooks/useComputeTxCollateral';
import { utxoAndBackendChainHistoryResolver } from '@src/utils/utxo-chain-history-resolver';
import { AddressBookSchema, useDbStateValue } from '@lib/storage';

interface DappTransactionContainerProps {
errorMessage?: string;
Expand All @@ -43,6 +44,10 @@ export const DappTransactionContainer = withAddressBookContext(
walletState
} = useWalletStore();

const ownAddresses = useObservable(inMemoryWallet.addresses$)?.map((a) => a.address);
const { list: addressBook } = useAddressBookContext() as useDbStateValue<AddressBookSchema>;
const addressToNameMap = new Map(addressBook?.map((entry) => [entry.address as string, entry.name]));

const { fiatCurrency } = useCurrencyStore();
const { priceResult } = useFetchCoinPrice();

Expand Down Expand Up @@ -146,6 +151,8 @@ export const DappTransactionContainer = withAddressBookContext(
errorMessage={errorMessage}
toAddress={toAddressTokens}
collateral={txCollateral}
ownAddresses={ownAddresses}
addressToNameMap={addressToNameMap}
/>
) : (
<Skeleton loading />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ const hash = Crypto.Hash28ByteBase16(Buffer.from('dRepCredentialHashdRepCreden')
const getPubDRepKey = async () => await hash;

const inMemoryWallet = {
getPubDRepKey,
governance: {
getPubDRepKey
},
assetInfo$,
balance: {
utxo: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ import { DappTransactionContainer } from '../DappTransactionContainer';
import '@testing-library/jest-dom';
import { BehaviorSubject } from 'rxjs';
import { act } from 'react-dom/test-utils';
import { buildMockTx } from '@src/utils/mocks/tx';
import { buildMockTx, sendingAddress } from '@src/utils/mocks/tx';
import { Wallet } from '@lace/cardano';
import { SignTxData } from '../types';
import { getWrapper } from '../testing.utils';
import { TransactionWitnessRequest } from '@cardano-sdk/web-extension';
import { cardanoCoin } from '@src/utils/constants';
import { AddressBookSchema } from '@lib/storage';

const { Cardano, Crypto } = Wallet;

Expand All @@ -51,6 +52,7 @@ const mockedAssetsInfo = new Map([['id', 'data']]);
const assetInfo$ = new BehaviorSubject(mockedAssetsInfo);
const available$ = new BehaviorSubject([]);
const signed$ = new BehaviorSubject([]);
const addresses$ = new BehaviorSubject([sendingAddress]);
const rewardAccounts$ = new BehaviorSubject([
{
// eslint-disable-next-line unicorn/consistent-destructuring
Expand All @@ -65,6 +67,7 @@ const protocolParameters$ = new BehaviorSubject({
});

const inMemoryWallet = {
addresses$,
assetInfo$,
balance: {
utxo: {
Expand Down Expand Up @@ -133,12 +136,12 @@ jest.mock('react-i18next', () => {
};
});

const addressList = ['addressList'];
const addressBook: AddressBookSchema[] = [];
jest.mock('@src/features/address-book/context', () => ({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
...jest.requireActual<any>('@src/features/address-book/context'),
withAddressBookContext: mockWithAddressBookContext,
useAddressBookContext: () => ({ list: addressList })
useAddressBookContext: () => ({ list: addressBook })
}));

jest.mock('antd', () => {
Expand Down Expand Up @@ -332,7 +335,9 @@ describe('Testing DappTransactionContainer component', () => {
errorMessage,
coinSymbol: 'ADA',
collateral: BigInt(1_000_000),
txInspectionDetails
txInspectionDetails,
ownAddresses: [sendingAddress.address],
addressToNameMap: new Map()
},
{}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,9 @@ describe('Testing hooks', () => {
mockUseWalletStore.mockReset();
mockUseWalletStore.mockReturnValue({
inMemoryWallet: {
getPubDRepKey: jest.fn(async () => await ed25519PublicKeyHexMock)
governance: {
getPubDRepKey: jest.fn(async () => await ed25519PublicKeyHexMock)
}
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ export const useGetOwnPubDRepKeyHash = (): UseGetOwnPubDRepKeyHash => {
useEffect(() => {
if (!inMemoryWallet) return;
const get = async () => {
const ownPubDRepKey = await inMemoryWallet.getPubDRepKey();
const ownPubDRepKey = await inMemoryWallet.governance.getPubDRepKey();
const ownDRepKeyHash = await pubDRepKeyToHash(ownPubDRepKey);

setOwnPubDRepKeyHash(ownDRepKeyHash);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import SpyInstance = jest.SpyInstance;
const mockEmip3decrypt = jest.fn();
const mockEmip3encrypt = jest.fn();
const mockConnectDevice = jest.fn();
const mockGetHwExtendedAccountPublicKey = jest.fn();
const mockRestoreWalletFromKeyAgent = jest.fn();
const mockSwitchKeyAgents = jest.fn();
const mockLedgerCheckDeviceConnection = jest.fn();
Expand Down Expand Up @@ -80,6 +81,7 @@ jest.mock('@lace/cardano', () => {
restoreWalletFromKeyAgent: mockRestoreWalletFromKeyAgent,
switchKeyAgents: mockSwitchKeyAgents,
connectDevice: mockConnectDevice,
getHwExtendedAccountPublicKey: mockGetHwExtendedAccountPublicKey,
KeyManagement: {
...actual.Wallet.KeyManagement,
emip3decrypt: mockEmip3decrypt,
Expand Down Expand Up @@ -382,7 +384,7 @@ describe('Testing useWalletManager hook', () => {
describe('createHardwareWallet', () => {
test('should use cardano manager to create wallet', async () => {
const walletId = 'walletId';
mockLedgerGetXpub.mockResolvedValue('pubkey');
mockGetHwExtendedAccountPublicKey.mockResolvedValue('pubkey');
(walletApiUi.walletRepository as any).addWallet = jest.fn().mockResolvedValue(walletId);
(walletApiUi.walletRepository as any).addAccount = jest.fn().mockResolvedValue(undefined);
(walletApiUi.walletManager as any).activate = jest.fn().mockResolvedValue(undefined);
Expand Down Expand Up @@ -696,11 +698,11 @@ describe('Testing useWalletManager hook', () => {
},
{
type: WalletType.Trezor,
prepare: () => mockTrezorGetXpub.mockResolvedValueOnce(extendedAccountPublicKey)
prepare: () => mockGetHwExtendedAccountPublicKey.mockResolvedValueOnce(extendedAccountPublicKey)
},
{
type: WalletType.Ledger,
prepare: () => mockLedgerGetXpub.mockResolvedValueOnce(extendedAccountPublicKey)
prepare: () => mockGetHwExtendedAccountPublicKey.mockResolvedValueOnce(extendedAccountPublicKey)
}
];

Expand Down
96 changes: 51 additions & 45 deletions apps/browser-extension-wallet/src/hooks/useWalletManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,6 @@ export interface CreateWallet {
chainId?: Wallet.Cardano.ChainId;
}

export interface SetWallet {
walletInstance: Wallet.CardanoWallet;
chainName?: Wallet.ChainName;
mnemonicVerificationFrequency?: string;
}

export interface CreateHardwareWallet {
accountIndex?: number;
name: string;
Expand All @@ -66,6 +60,14 @@ type WalletManagerAddAccountProps = {

type ActivateWalletProps = Omit<WalletManagerActivateProps, 'chainId'>;

type CreateHardwareWalletRevampedParams = {
accountIndex: number;
name: string;
connection: Wallet.HardwareWalletConnection;
};

type CreateHardwareWalletRevamped = (params: CreateHardwareWalletRevampedParams) => Promise<Wallet.CardanoWallet>;

export interface UseWalletManager {
walletManager: WalletManagerApi;
walletRepository: WalletRepositoryApi<Wallet.WalletMetadata, Wallet.AccountMetadata>;
Expand All @@ -78,7 +80,9 @@ export interface UseWalletManager {
createWallet: (args: CreateWallet) => Promise<Wallet.CardanoWallet>;
activateWallet: (args: Omit<WalletManagerActivateProps, 'chainId'>) => Promise<void>;
createHardwareWallet: (args: CreateHardwareWallet) => Promise<Wallet.CardanoWallet>;
createHardwareWalletRevamped: CreateHardwareWalletRevamped;
connectHardwareWallet: (model: Wallet.HardwareWallets) => Promise<Wallet.DeviceConnection>;
connectHardwareWalletRevamped: typeof connectHardwareWalletRevamped;
saveHardwareWallet: (wallet: Wallet.CardanoWallet, chainName?: Wallet.ChainName) => Promise<void>;
/**
* @returns active wallet id after deleting the wallet; undefined if deleted the last wallet
Expand All @@ -95,27 +99,6 @@ const clearBytes = (bytes: Uint8Array) => {
}
};

const getHwExtendedAccountPublicKey = async (
walletType: Wallet.HardwareWallets,
accountIndex: number,
deviceConnection?: Wallet.DeviceConnection
) => {
switch (walletType) {
case WalletType.Ledger:
await Wallet.Ledger.LedgerKeyAgent.checkDeviceConnection(Wallet.KeyManagement.CommunicationType.Web);
return Wallet.Ledger.LedgerKeyAgent.getXpub({
communicationType: Wallet.KeyManagement.CommunicationType.Web,
deviceConnection: typeof deviceConnection !== 'boolean' ? deviceConnection : undefined,
accountIndex
});
case WalletType.Trezor:
return Wallet.Trezor.TrezorKeyAgent.getXpub({
communicationType: Wallet.KeyManagement.CommunicationType.Web,
accountIndex
});
}
};

const getExtendedAccountPublicKey = async (
wallet: AnyBip32Wallet<Wallet.WalletMetadata, Wallet.AccountMetadata>,
accountIndex: number,
Expand Down Expand Up @@ -143,7 +126,7 @@ const getExtendedAccountPublicKey = async (
}
case WalletType.Ledger:
case WalletType.Trezor:
return getHwExtendedAccountPublicKey(wallet.type, accountIndex);
return Wallet.getHwExtendedAccountPublicKey(wallet.type, accountIndex);
}
};

Expand Down Expand Up @@ -210,6 +193,9 @@ const encryptMnemonic = async (mnemonic: string[], passphrase: Uint8Array) => {
export const connectHardwareWallet = async (model: Wallet.HardwareWallets): Promise<Wallet.DeviceConnection> =>
await Wallet.connectDevice(model);

const connectHardwareWalletRevamped = async (usbDevice: USBDevice): Promise<Wallet.HardwareWalletConnection> =>
Wallet.connectDeviceRevamped(usbDevice);

export const useWalletManager = (): UseWalletManager => {
const {
walletLock,
Expand Down Expand Up @@ -241,25 +227,21 @@ export const useWalletManager = (): UseWalletManager => {
return (storedChain?.chainName && chainIdFromName(storedChain.chainName)) || DEFAULT_CHAIN_ID;
}, [currentChain]);

/**
* Creates a Ledger or Trezor hardware wallet
* and saves it in browser storage with the data to lock/unlock it
*/
const createHardwareWallet = useCallback(
async ({
accountIndex = 0,
deviceConnection,
name,
connectedDevice
}: CreateHardwareWallet): Promise<Wallet.CardanoWallet> => {
const extendedAccountPublicKey = await getHwExtendedAccountPublicKey(
connectedDevice,
accountIndex,
deviceConnection
);
const createHardwareWalletRevamped = useCallback<CreateHardwareWalletRevamped>(
async ({ accountIndex, connection, name }) => {
let extendedAccountPublicKey;
try {
extendedAccountPublicKey = await Wallet.getHwExtendedAccountPublicKey(
connection.type,
accountIndex,
connection.type === WalletType.Ledger ? connection.value : undefined
);
} catch (error: unknown) {
throw error;
}
const addWalletProps: AddWalletProps<Wallet.WalletMetadata, Wallet.AccountMetadata> = {
metadata: { name, lastActiveAccountIndex: accountIndex },
type: connectedDevice,
type: connection.type,
accounts: [
{
extendedAccountPublicKey,
Expand Down Expand Up @@ -291,6 +273,28 @@ export const useWalletManager = (): UseWalletManager => {
[getCurrentChainId]
);

/**
* Creates a Ledger or Trezor hardware wallet
* and saves it in browser storage with the data to lock/unlock it
*/
const createHardwareWallet = useCallback(
async ({
accountIndex = 0,
deviceConnection,
name,
connectedDevice
}: CreateHardwareWallet): Promise<Wallet.CardanoWallet> =>
createHardwareWalletRevamped({
accountIndex,
connection: {
type: connectedDevice,
value: typeof deviceConnection !== 'boolean' ? deviceConnection : undefined
},
name
}),
[createHardwareWalletRevamped]
);

const tryMigrateToWalletRepository = useCallback(async (): Promise<
AnyWallet<Wallet.WalletMetadata, Wallet.AccountMetadata>[] | undefined
> => {
Expand Down Expand Up @@ -742,7 +746,9 @@ export const useWalletManager = (): UseWalletManager => {
loadWallet,
createWallet,
createHardwareWallet,
createHardwareWalletRevamped,
connectHardwareWallet,
connectHardwareWalletRevamped,
saveHardwareWallet,
deleteWallet,
switchNetwork,
Expand Down
5 changes: 5 additions & 0 deletions apps/browser-extension-wallet/src/hooks/useWalletState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const combineObservable = ({ wallet }: Wallet.CardanoWallet): Observable<Observa
wallet.delegation.rewardsHistory$,
wallet.eraSummaries$,
wallet.genesisParameters$,
wallet.governance.isRegisteredAsDRep$,
wallet.handles$,
wallet.protocolParameters$,
wallet.publicStakeKeys$,
Expand Down Expand Up @@ -82,6 +83,7 @@ const combineObservable = ({ wallet }: Wallet.CardanoWallet): Observable<Observa
delegationRewardsHistory,
eraSummaries,
genesisParameters,
isRegisteredAsDRep,
handles,
protocolParameters,
publicStakeKeys,
Expand Down Expand Up @@ -117,6 +119,9 @@ const combineObservable = ({ wallet }: Wallet.CardanoWallet): Observable<Observa
},
eraSummaries,
genesisParameters,
governance: {
isRegisteredAsDRep
},
handles,
protocolParameters,
publicStakeKeys,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { runtime } from 'webextension-polyfill';
import { AllowedOrigins } from './types';

// Communicate from background script to popup
let port = runtime.connect({ name: 'trezor-connect' });
Expand All @@ -12,6 +13,7 @@ port.onDisconnect.addListener(() => {

// communicate from popup to background script
window.addEventListener('message', (event) => {
if (event.origin !== AllowedOrigins.TREZOR_CONNECT) throw new Error('Origin not allowed');
if (port && event.source === window && event.data) {
port.postMessage({ data: event.data });
}
Expand Down
Loading

0 comments on commit 9132359

Please sign in to comment.