Skip to content

Commit

Permalink
Merge branch 'main' into feat/lw-10157-show-collateral-deposits-fee-o…
Browse files Browse the repository at this point in the history
…utside-tx-summary
  • Loading branch information
lucas-barros committed Apr 25, 2024
2 parents b5bd0db + 92eabfb commit 9369c0b
Show file tree
Hide file tree
Showing 67 changed files with 654 additions and 316 deletions.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import React, { useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { Button, PostHogAction } from '@lace/common';
import { Button, PostHogAction, WarningBanner } from '@lace/common';
import Fail from '../../../assets/icons/exclamation-circle.svg';
import styles from './Layout.module.scss';
import { Image } from 'antd';
import { useAnalyticsContext } from '@providers';
import { TX_CREATION_TYPE_KEY, TxCreationType } from '@providers/AnalyticsProvider/analyticsTracker';
import { useWalletStore } from '@stores';
import { useCustomSubmitApi } from '@hooks';

export const DappTransactionFail = (): React.ReactElement => {
const { t } = useTranslation();
const analytics = useAnalyticsContext();
const { environmentName } = useWalletStore();
const onClose = async () => {
await analytics?.sendEventToPostHog(PostHogAction.SendSomethingWentWrongCancelClick, {
[TX_CREATION_TYPE_KEY]: TxCreationType.External
});
window.close();
};
const { getCustomSubmitApiForNetwork } = useCustomSubmitApi();

useEffect(() => {
analytics?.sendEventToPostHog(PostHogAction.SendSomethingWentWrongView, {
Expand All @@ -33,6 +37,9 @@ export const DappTransactionFail = (): React.ReactElement => {
<div data-testid="dapp-sign-tx-fail-description" className={styles.description}>
{t('dapp.sign.failure.description')}
</div>
{getCustomSubmitApiForNetwork(environmentName).status && (
<WarningBanner message={t('browserView.transaction.send.customSubmitApiBannerText')} />
)}
</div>
<div className={styles.footer}>
<Button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
letter-spacing: 0.02em;
line-height: size_unit(3);
margin-top: size_unit(2);
margin-bottom: size_unit(4);
text-align: center;
padding: 0 size_unit(4);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
useExternalLinkOpener,
useTheme
} from '@providers';
import { useBalances, useFetchCoinPrice, useLocalStorage, useStakingRewards } from '@hooks';
import { useBalances, useCustomSubmitApi, useFetchCoinPrice, useLocalStorage, useStakingRewards } from '@hooks';
import { useDelegationStore } from '@src/features/delegation/stores';
import { usePassword, useSubmitingState } from '@views/browser/features/send-transaction';
import { networkInfoStatusSelector, useWalletStore } from '@stores';
Expand Down Expand Up @@ -37,6 +37,7 @@ export const MultiDelegationStakingPopup = (): JSX.Element => {
const { priceResult } = useFetchCoinPrice();
const { balance } = useBalances(priceResult?.cardano?.price);
const stakingRewards = useStakingRewards();
const { getCustomSubmitApiForNetwork } = useCustomSubmitApi();
const {
walletType,
inMemoryWallet,
Expand All @@ -48,7 +49,8 @@ export const MultiDelegationStakingPopup = (): JSX.Element => {
networkInfo,
blockchainProvider,
walletInfo,
currentChain
currentChain,
environmentName
} = useWalletStore((state) => ({
walletType: state.walletType,
inMemoryWallet: state.inMemoryWallet,
Expand All @@ -60,7 +62,8 @@ export const MultiDelegationStakingPopup = (): JSX.Element => {
fetchNetworkInfo: state.fetchNetworkInfo,
blockchainProvider: state.blockchainProvider,
walletInfo: state.walletInfo,
currentChain: state.currentChain
currentChain: state.currentChain,
environmentName: state.environmentName
}));
const sendAnalytics = useCallback(() => {
// TODO implement analytics for the new flow
Expand Down Expand Up @@ -140,7 +143,8 @@ export const MultiDelegationStakingPopup = (): JSX.Element => {
compactNumber: compactNumberWithUnit,
walletAddress,
currentChain,
isMultidelegationSupportedByDevice
isMultidelegationSupportedByDevice,
isCustomSubmitApiEnabled: getCustomSubmitApiForNetwork(environmentName).status
}}
>
<ContentLayout
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ describe('Testing useWalletManager hook', () => {
]
});
expect(clearBackgroundStorage).toBeCalledWith({
except: ['fiatPrices', 'userId', 'usePersistentUserId', 'experimentsConfiguration']
except: ['fiatPrices', 'userId', 'usePersistentUserId', 'experimentsConfiguration', 'customSubmitTxUrl']
});
expect(resetWalletLock).toBeCalledWith();
expect(setCardanoWallet).toBeCalledWith();
Expand Down
2 changes: 2 additions & 0 deletions apps/browser-extension-wallet/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ export * from './useOnAddressSave';
export * from './useAppInit';
export * from './useChainHistoryProvider';
export * from './useWalletAvatar';
export * from './useActionExecution';
export * from './useCustomSubmitApi';
11 changes: 11 additions & 0 deletions apps/browser-extension-wallet/src/hooks/useAppInit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { isKeyHashAddress } from '@cardano-sdk/wallet';
import { AddressesDiscoveryStatus } from '@lib/communication/addresses-discoverer';
import { useWalletManager } from './useWalletManager';
import { useWalletState } from './useWalletState';
import { setBackgroundStorage } from '@lib/scripts/background/storage';
import { useCustomSubmitApi } from '@hooks/useCustomSubmitApi';

export const useAppInit = (): void => {
const {
Expand All @@ -19,6 +21,8 @@ export const useAppInit = (): void => {
} = useWalletStore();
const { loadWallet, walletManager, walletRepository } = useWalletManager();
const walletState = useWalletState();
const { environmentName } = useWalletStore();
const { getCustomSubmitApiForNetwork } = useCustomSubmitApi();

useEffect(() => {
setWalletState(walletState);
Expand Down Expand Up @@ -46,6 +50,13 @@ export const useAppInit = (): void => {
}
}, [walletInfo, initialHdDiscoveryCompleted, setAddressesDiscoveryCompleted]);

useEffect(() => {
(async () => {
environmentName &&
(await setBackgroundStorage({ customSubmitTxUrl: getCustomSubmitApiForNetwork(environmentName).url }));
})();
}, [environmentName, getCustomSubmitApiForNetwork]);

const wallets = useObservable(walletRepository.wallets$);
const activeWalletProps = useObservable(walletManager.activeWalletId$);
useEffect(() => {
Expand Down
26 changes: 26 additions & 0 deletions apps/browser-extension-wallet/src/hooks/useCustomSubmitApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useLocalStorage } from '@hooks/useLocalStorage';
import { EnvironmentTypes } from '@stores';
import { CustomSubmitApiConfig } from '@types';

interface useCustomSubmitApiReturn {
getCustomSubmitApiForNetwork: (network: EnvironmentTypes) => CustomSubmitApiConfig;
updateCustomSubmitApi: (network: EnvironmentTypes, data: CustomSubmitApiConfig) => void;
}

export const useCustomSubmitApi = (): useCustomSubmitApiReturn => {
const [isCustomSubmitApiEnabled, { updateLocalStorage: updateCustomSubmitApiEnabled }] =
useLocalStorage('isCustomSubmitApiEnabled');

const getCustomSubmitApiForNetwork = (network: EnvironmentTypes) => {
const networkConfig = isCustomSubmitApiEnabled?.[network];
const status = networkConfig?.status || false;
const url = networkConfig?.url || '';
return { status, url };
};

const updateCustomSubmitApi = (network: EnvironmentTypes, data: CustomSubmitApiConfig) => {
updateCustomSubmitApiEnabled({ ...isCustomSubmitApiEnabled, [network]: data });
};

return { getCustomSubmitApiForNetwork, updateCustomSubmitApi };
};
50 changes: 46 additions & 4 deletions apps/browser-extension-wallet/src/hooks/useWalletManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/* eslint-disable unicorn/no-null */
import { useCallback } from 'react';
import { Wallet } from '@lace/cardano';
import { useWalletStore } from '@stores';
import { EnvironmentTypes, useWalletStore } from '@stores';
import { useAppSettingsContext } from '@providers/AppSettings';
import { useBackgroundServiceAPIContext } from '@providers/BackgroundServiceAPI';
import { AddressBookSchema, addressBookSchema, NftFoldersSchema, nftFoldersSchema, useDbState } from '@src/lib/storage';
Expand Down Expand Up @@ -32,6 +32,8 @@ import {
import { deepEquals, HexBlob } from '@cardano-sdk/util';
import { BackgroundService } from '@lib/scripts/types';
import { getChainName } from '@src/utils/get-chain-name';
import { useCustomSubmitApi } from '@hooks/useCustomSubmitApi';
import { setBackgroundStorage } from '@lib/scripts/background/storage';

const { AVAILABLE_CHAINS, CHAIN } = config();
const DEFAULT_CHAIN_ID = Wallet.Cardano.ChainIds[CHAIN];
Expand Down Expand Up @@ -89,8 +91,15 @@ export interface UseWalletManager {
*/
deleteWallet: (isForgotPasswordFlow?: boolean) => Promise<WalletManagerActivateProps | undefined>;
switchNetwork: (chainName: Wallet.ChainName) => Promise<void>;

/**
* Force the wallet to recreate all providers and reload. This is useful for changing
* provider properties or configurations without switching the wallet.
*/
reloadWallet: () => Promise<void>;
addAccount: (props: WalletManagerAddAccountProps) => Promise<void>;
getMnemonic: (passphrase: Uint8Array) => Promise<string[]>;
enableCustomNode: (network: EnvironmentTypes, value: string) => Promise<void>;
}

const clearBytes = (bytes: Uint8Array) => {
Expand Down Expand Up @@ -219,6 +228,7 @@ export const useWalletManager = (): UseWalletManager => {
} = useDbState<NftFoldersSchema, NftFoldersSchema>([], nftFoldersSchema);
const backgroundService = useBackgroundServiceAPIContext();
const userIdService = getUserIdService();
const { getCustomSubmitApiForNetwork, updateCustomSubmitApi } = useCustomSubmitApi();

const getCurrentChainId = useCallback(() => {
if (currentChain) return currentChain;
Expand Down Expand Up @@ -592,7 +602,7 @@ export const useWalletManager = (): UseWalletManager => {
deleteFromLocalStorage('userInfo');
deleteFromLocalStorage('keyAgentData');
await backgroundService.clearBackgroundStorage({
except: ['fiatPrices', 'userId', 'usePersistentUserId', 'experimentsConfiguration']
except: ['fiatPrices', 'userId', 'usePersistentUserId', 'experimentsConfiguration', 'customSubmitTxUrl']
});
resetWalletLock();
setCardanoWallet();
Expand Down Expand Up @@ -639,6 +649,12 @@ export const useWalletManager = (): UseWalletManager => {
]
);

const reloadWallet = useCallback(async (): Promise<void> => {
const activeWallet = await firstValueFrom(walletManager.activeWalletId$);

await walletManager.activate(activeWallet, true);
}, []);

/**
* Deactivates current wallet and activates it again with the new network
*/
Expand All @@ -651,11 +667,22 @@ export const useWalletManager = (): UseWalletManager => {

setAddressesDiscoveryCompleted(false);
updateAppSettings({ ...settings, chainName });
const customSubmitApi = getCustomSubmitApiForNetwork(chainName);
await setBackgroundStorage({ customSubmitTxUrl: customSubmitApi.url });
await reloadWallet();

setCurrentChain(chainName);
setCardanoCoin(chainId);
},
[setAddressesDiscoveryCompleted, updateAppSettings, settings, setCurrentChain, setCardanoCoin]
[
setAddressesDiscoveryCompleted,
updateAppSettings,
settings,
getCustomSubmitApiForNetwork,
reloadWallet,
setCurrentChain,
setCardanoCoin
]
);

/**
Expand Down Expand Up @@ -738,6 +765,19 @@ export const useWalletManager = (): UseWalletManager => {
[getCurrentChainId]
);

const enableCustomNode = useCallback(
async (network: EnvironmentTypes, value: string) => {
const customApiData = {
status: !!value,
url: value
};
updateCustomSubmitApi(network, customApiData);
await backgroundService.setBackgroundStorage({ customSubmitTxUrl: value });
await reloadWallet();
},
[backgroundService, reloadWallet, updateCustomSubmitApi]
);

return {
activateWallet,
addAccount,
Expand All @@ -751,9 +791,11 @@ export const useWalletManager = (): UseWalletManager => {
connectHardwareWalletRevamped,
saveHardwareWallet,
deleteWallet,
reloadWallet,
switchNetwork,
walletManager,
walletRepository,
getMnemonic
getMnemonic,
enableCustomNode
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Wallet } from '@lace/cardano';
import { RemoteApiProperties, RemoteApiPropertyType } from '@cardano-sdk/web-extension';
import { getBaseUrlForChain } from '@src/utils/chain';
import { BackgroundService, UserIdService as UserIdServiceInterface } from '../types';
import { getBackgroundStorage } from '@lib/scripts/background/storage';

export const backgroundServiceProperties: RemoteApiProperties<BackgroundService> = {
requestMessage$: RemoteApiPropertyType.HotObservable,
Expand All @@ -20,16 +21,16 @@ export const backgroundServiceProperties: RemoteApiProperties<BackgroundService>
backendFailures$: RemoteApiPropertyType.HotObservable
};

export const getProviders = (chainName: Wallet.ChainName): Wallet.WalletProvidersDependencies => {
export const getProviders = async (chainName: Wallet.ChainName): Promise<Wallet.WalletProvidersDependencies> => {
const baseCardanoServicesUrl = getBaseUrlForChain(chainName);
const { customSubmitTxUrl } = await getBackgroundStorage();

return Wallet.createProviders({
axiosAdapter: axiosFetchAdapter,
baseUrl: baseCardanoServicesUrl
baseUrl: baseCardanoServicesUrl,
customSubmitTxUrl
});
};
export const ownOrigin = globalThis.location.origin;

export const BASE_EXTENSION_APP_URL = 'app.html';

export const cip30WalletProperties = {
// eslint-disable-next-line max-len
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const chainIdToChainName = (chainId: Cardano.ChainId): Wallet.ChainName => {
const walletFactory: WalletFactory<Wallet.WalletMetadata, Wallet.AccountMetadata> = {
create: async ({ chainId, accountIndex }, wallet, { stores, witnesser }) => {
const chainName: Wallet.ChainName = chainIdToChainName(chainId);
const providers = getProviders(chainName);
const providers = await getProviders(chainName);
if (wallet.type === WalletType.Script || typeof accountIndex !== 'number') {
throw new NotImplementedError('Script wallet support is not implemented');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export interface BackgroundStorage {
userId?: string;
usePersistentUserId?: boolean;
experimentsConfiguration?: Record<string, string | boolean>;
customSubmitTxUrl?: string;
}

export type BackgroundStorageKeys = keyof BackgroundStorage;
Expand Down
18 changes: 18 additions & 0 deletions apps/browser-extension-wallet/src/lib/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@
"core.dappTransaction.deposit": "Deposit",
"core.dappTransaction.returnedDeposit": "Returned deposit",
"core.dappTransaction.items": "item(s)",
"core.dappTransaction.assetId": "AssetId:",
"core.dappTransaction.policyId": "PolicyId:",
"core.dappTransaction.adaTooltip": "Ada is Cardano's native token and does not have an asset and policy ID.",
"tab.main.title": "Tab extension",
"general.buttons.back": "Back",
"general.button.cancel": "Cancel",
Expand Down Expand Up @@ -754,6 +757,7 @@
"browserView.transaction.send.confirmationTitle": "Transaction confirmation",
"browserView.transaction.send.signTransactionWithPassword": "Please sign the transaction with your password.",
"browserView.transaction.send.enterWalletPasswordToConfirmTransaction": "Enter your wallet password to confirm transaction",
"browserView.transaction.send.customSubmitApiBannerText": "Custom submit API enabled to send transactions. To disable, go to Settings >> Custom submit API",
"browserView.settings.heading": "Settings",
"browserView.settings.wallet.title": "Wallet",
"browserView.settings.wallet.about.title": "About",
Expand Down Expand Up @@ -800,6 +804,20 @@
"browserView.settings.wallet.network.description": "Switch from mainnet to testnet",
"browserView.settings.wallet.network.drawerDescription": "Select the network you would like your wallet to operate on.",
"browserView.settings.wallet.network.networkSwitched": "Switched network",
"browserView.settings.wallet.customSubmitApi.title": "Custom submit API",
"browserView.settings.wallet.customSubmitApi.description": "Ensure your local node is on the same network as your wallet and fully synced to submit transactions.",
"browserView.settings.wallet.customSubmitApi.descriptionLink": "Learn more about Cardano-submit-API",
"browserView.settings.wallet.customSubmitApi.defaultAddress": "Default address: {{url}}",
"browserView.settings.wallet.customSubmitApi.settingsLinkTitle": "Custom Submit API",
"browserView.settings.wallet.customSubmitApi.settingsLinkDescription": "Send transactions through a local Cardano node and cardano-submit-api",
"browserView.settings.wallet.customSubmitApi.usingCustomTxSubmitEndpoint": "You custom submit API is enabled to submit transactions",
"browserView.settings.wallet.customSubmitApi.usingStandardTxSubmitEndpoint": "You custom submit API is disabled. Lace will send transactions through its infrastructure",
"browserView.settings.wallet.customSubmitApi.inputLabel": "Insert the URL here",
"browserView.settings.wallet.customSubmitApi.enable": "Enable",
"browserView.settings.wallet.customSubmitApi.disable": "Disable",
"browserView.settings.wallet.customSubmitApi.enabled": "Enabled",
"browserView.settings.wallet.customSubmitApi.disabled": "Disabled",
"browserView.settings.wallet.customSubmitApi.validationError": "Invalid URL",
"browserView.settings.wallet.authorizedDApps.title": "Authorized DApps",
"browserView.settings.wallet.authorizedDApps.description": "See and manage authorized DApps",
"browserView.settings.wallet.walletSync.description": "Sync new addresses of your HD wallet. This may be needed if you're using other HD wallets at the same time as Lace",
Expand Down

0 comments on commit 9369c0b

Please sign in to comment.