Skip to content

Commit

Permalink
feat: providers are now consumed from the service worker instead of t…
Browse files Browse the repository at this point in the history
…he UI script
  • Loading branch information
AngelCastilloB committed Oct 31, 2024
1 parent d2f99ec commit 1ae1e80
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { useViewsFlowContext } from '@providers/ViewFlowProvider';
import { Wallet } from '@lace/cardano';
import { useAddressBookContext, withAddressBookContext } from '@src/features/address-book/context';
import { useWalletStore } from '@stores';
import { useFetchCoinPrice, useChainHistoryProvider } from '@hooks';
import { useFetchCoinPrice } from '@hooks';
import {
createTxInspector,
TransactionSummaryInspection,
Expand All @@ -25,7 +25,7 @@ import {
import { createWalletAssetProvider } from '@cardano-sdk/wallet';
import { Skeleton } from 'antd';

import { useCurrencyStore, useAppSettingsContext } from '@providers';
import { useCurrencyStore } from '@providers';
import { logger, walletRepository } from '@lib/wallet-api-ui';
import { useComputeTxCollateral } from '@hooks/useComputeTxCollateral';
import { utxoAndBackendChainHistoryResolver } from '@src/utils/utxo-chain-history-resolver';
Expand All @@ -34,6 +34,7 @@ import { AddressBookSchema, useDbStateValue } from '@lib/storage';
import { getAllWalletsAddresses } from '@src/utils/get-all-wallets-addresses';
import { useCexplorerBaseUrl, useDisallowSignTx } from './hooks';
import { NonRegisteredUserModal } from './NonRegisteredUserModal/NonRegisteredUserModal';
import { getProviders } from '@stores/slices';

interface DappTransactionContainerProps {
errorMessage?: string;
Expand Down Expand Up @@ -69,8 +70,6 @@ export const DappTransactionContainer = withAddressBookContext(
const { fiatCurrency } = useCurrencyStore();
const { priceResult } = useFetchCoinPrice();

const [{ chainName }] = useAppSettingsContext();

const [fromAddressTokens, setFromAddressTokens] = useState<
Map<Cardano.PaymentAddress, TokenTransferValue> | undefined
>();
Expand All @@ -81,7 +80,7 @@ export const DappTransactionContainer = withAddressBookContext(
TransactionSummaryInspection | undefined
>();

const chainHistoryProvider = useChainHistoryProvider({ chainName });
const { chainHistoryProvider } = getProviders();

const txInputResolver = useMemo(
() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ const mockWithAddressBookContext = jest.fn((children) => children);
const mockUseCurrencyStore = jest.fn().mockReturnValue({ fiatCurrency: { code: 'usd', symbol: '$' } });
const mockUseFetchCoinPrice = jest.fn().mockReturnValue({ priceResult: { cardano: { price: 2 }, tokens: new Map() } });
const mockUseComputeTxCollateral = jest.fn().mockReturnValue(BigInt(1_000_000));
const mockUseChainHistoryProvider = jest.fn().mockReturnValue({
transactionsByAddress: jest.fn().mockResolvedValue([]),
transactionsByHashes: jest.fn().mockResolvedValue([]),
blocksByHashes: jest.fn().mockResolvedValue([])
});
import * as React from 'react';
import { cleanup, render } from '@testing-library/react';
import { DappTransactionContainer } from '../DappTransactionContainer';
Expand Down Expand Up @@ -127,9 +122,19 @@ jest.mock('@providers/currency', (): typeof CurrencyProvider => ({
useCurrencyStore: mockUseCurrencyStore
}));

jest.mock('@hooks/useChainHistoryProvider', (): typeof CurrencyProvider => ({
...jest.requireActual<any>('@hooks/useChainHistoryProvider'),
useChainHistoryProvider: mockUseChainHistoryProvider
jest.mock('@stores/slices/blockchain-provider-slice', (): typeof CurrencyProvider => ({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
...jest.requireActual<any>('@stores/slices/blockchain-provider-slice'),
getProviders: () =>
({
chainHistoryProvider: {
transactionsByAddress: jest.fn().mockResolvedValue([]),
transactionsByHashes: jest.fn().mockResolvedValue([]),
blocksByHashes: jest.fn().mockResolvedValue([])
},
assetProvider
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} as any)
}));

jest.mock('@lace/core', () => {
Expand Down
1 change: 0 additions & 1 deletion apps/browser-extension-wallet/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export * from './useAssetInfo';
export * from './useUpdateAddressStatus';
export * from './useOnAddressSave';
export * from './useAppInit';
export * from './useChainHistoryProvider';
export * from './useWalletAvatar';
export * from './useActionExecution';
export * from './useCustomSubmitApi';
Expand Down
21 changes: 0 additions & 21 deletions apps/browser-extension-wallet/src/hooks/useChainHistoryProvider.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { runtime, storage as webStorage } from 'webextension-polyfill';
import { of, combineLatest, map, EMPTY } from 'rxjs';
import { of, combineLatest, map, EMPTY, from, switchMap, filter } from 'rxjs';
import { getProviders } from './config';
import {
DEFAULT_LOOK_AHEAD_SEARCH,
Expand Down Expand Up @@ -232,6 +232,28 @@ walletManager
},
{ logger, runtime }
);

exposeApi(
{
api$: walletManager.activeWallet$.pipe(
filter((activeWallet) => !!activeWallet),
switchMap((activeWallet) => {
if (!activeWallet) {
return;
}

const chainId = activeWallet.props.chainId;
const chainName: Wallet.ChainName = chainIdToChainName(chainId);

// eslint-disable-next-line consistent-return
return from(getProviders(chainName));
})
),
baseChannel: Wallet.walletProvidersChannel(process.env.WALLET_NAME),
properties: Wallet.walletProvidersProperties
},
{ logger, runtime }
);
})
.catch((error) => {
logger.error('Failed to initialize wallet manager', error);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { BlockchainProviderSlice, SliceCreator } from '../types';
import { Wallet } from '@lace/cardano';
import { getBaseUrlForChain } from '@src/utils/chain';
import axiosFetchAdapter from '@shiroyasha9/axios-fetch-adapter';
import { config } from '@src/config';

const { CHAIN } = config();
import { consumeRemoteApi } from '@cardano-sdk/web-extension';
import { runtime } from 'webextension-polyfill';

export interface IBlockchainProvider {
stakePoolProvider: Wallet.StakePoolProvider;
Expand All @@ -16,45 +13,38 @@ export interface IBlockchainProvider {
rewardsProvider: Wallet.RewardsProvider;
}

export type BlockchainProviderFactory = (chainName: Wallet.ChainName) => IBlockchainProvider;
export type BlockchainProviderFactory = () => IBlockchainProvider;

export const IBlockchainProvider = {
toWalletProviders: (providers: IBlockchainProvider): Wallet.WalletProvidersDependencies => ({
stakePoolProvider: providers.stakePoolProvider,
assetProvider: providers.assetProvider,
txSubmitProvider: providers.txSubmitProvider,
networkInfoProvider: providers.networkInfoProvider,
utxoProvider: providers.utxoProvider,
rewardsProvider: providers.rewardsProvider,
chainHistoryProvider: providers.chainHistoryProvider
stakePoolProvider: providers?.stakePoolProvider,
assetProvider: providers?.assetProvider,
txSubmitProvider: providers?.txSubmitProvider,
networkInfoProvider: providers?.networkInfoProvider,
utxoProvider: providers?.utxoProvider,
rewardsProvider: providers?.rewardsProvider,
chainHistoryProvider: providers?.chainHistoryProvider
}),
fromWalletProviders: (providers: Wallet.WalletProvidersDependencies): IBlockchainProvider => ({
txSubmitProvider: providers.txSubmitProvider,
assetProvider: providers.assetProvider,
stakePoolProvider: providers.stakePoolProvider,
networkInfoProvider: providers.networkInfoProvider,
utxoProvider: providers.utxoProvider,
rewardsProvider: providers.rewardsProvider,
chainHistoryProvider: providers.chainHistoryProvider
txSubmitProvider: providers?.txSubmitProvider,
assetProvider: providers?.assetProvider,
stakePoolProvider: providers?.stakePoolProvider,
networkInfoProvider: providers?.networkInfoProvider,
utxoProvider: providers?.utxoProvider,
rewardsProvider: providers?.rewardsProvider,
chainHistoryProvider: providers?.chainHistoryProvider
})
};

export const getProviderByChain: BlockchainProviderFactory = (chain = CHAIN) => {
const baseCardanoServicesUrl = getBaseUrlForChain(chain);

// TODO: LW-11761 reuse providers that are running in SW instead
const providers = Wallet.createProviders({
axiosAdapter: axiosFetchAdapter,
env: {
baseCardanoServicesUrl,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
blockfrostConfig: {} as any
},
experiments: {}
});
const providers = consumeRemoteApi<Wallet.WalletProvidersDependencies>(
{
baseChannel: Wallet.walletProvidersChannel(process.env.WALLET_NAME),
properties: Wallet.walletProvidersProperties
},
{ logger: console, runtime }
);

return IBlockchainProvider.fromWalletProviders(providers);
};
export const getProviders: BlockchainProviderFactory = () => IBlockchainProvider.fromWalletProviders(providers);

/**
* has all wallet info related actions and states
Expand All @@ -63,7 +53,7 @@ export const blockchainProviderSlice: SliceCreator<
BlockchainProviderSlice,
BlockchainProviderSlice,
{ currentChainName: Wallet.ChainName; blockchainProviderFactory?: BlockchainProviderFactory }
> = ({ set }, { currentChainName, blockchainProviderFactory = getProviderByChain }) => ({
blockchainProvider: blockchainProviderFactory(currentChainName),
setBlockchainProvider: (chain) => set({ blockchainProvider: blockchainProviderFactory(chain) })
> = ({ set }, { blockchainProviderFactory = getProviders }) => ({
blockchainProvider: blockchainProviderFactory(),
setBlockchainProvider: () => set({ blockchainProvider: blockchainProviderFactory() })
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@ import { useDrawer } from '../../stores';
import { getQRCodeOptions } from '@src/utils/qrCodeHelpers';
import { Banner, useKeyboardShortcut, useObservable } from '@lace/common';
import { getAssetImageUrl } from '@src/utils/get-asset-image-url';
import { useAnalyticsContext, useAppSettingsContext } from '@providers';
import { useAnalyticsContext } from '@providers';
import { PostHogAction } from '@providers/AnalyticsProvider/analyticsTracker';
import { Button, Flex } from '@input-output-hk/lace-ui-toolkit';
import { ExclamationCircleOutlined, PlusCircleOutlined } from '@ant-design/icons';
import { useChainHistoryProvider, useLocalStorage } from '@hooks';
import { useLocalStorage } from '@hooks';
import { Divider } from 'antd';
import { Wallet } from '@lace/cardano';
import { getTransactionTotalOutputByAddress } from '@src/utils/get-transaction-total-output';
import { getTotalAssetsByAddress } from '@src/utils/assets-transformers';
import { formatBalance } from '@src/utils/format-number';
import { getProviders } from '@stores/slices';

type WalletData = {
address: Wallet.Cardano.PaymentAddress;
Expand Down Expand Up @@ -99,8 +100,7 @@ export const QRInfoWalletDrawer = (): React.ReactElement => {
const [currentUnusedAddress, setCurrentUnusedAddress] = useState<Wallet.Cardano.PaymentAddress | undefined>();
const [, closeDrawer] = useDrawer();
const [isReceiveInAdvancedMode] = useLocalStorage('isReceiveInAdvancedMode', false);
const [{ chainName }] = useAppSettingsContext();
const chainHistoryProvider = useChainHistoryProvider({ chainName });
const { chainHistoryProvider } = getProviders();

useKeyboardShortcut(['Escape'], () => closeDrawer());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { Wallet } from '@lace/cardano';
import { compactNumberWithUnit } from '@src/utils/format-number';
import { PortfolioBalance } from '@src/views/browser-view/components';
import { addEllipsis, WarningBanner, toast } from '@lace/common';
import { getProviderByChain } from '@src/stores/slices';
import { getProviders } from '@src/stores/slices';
import { CARDANO_COIN_SYMBOL, COINGECKO_URL } from '@src/utils/constants';
import BigNumber from 'bignumber.js';
import styles from './WalletOverview.module.scss';
Expand Down Expand Up @@ -59,7 +59,7 @@ export const WalletOverview = (): JSX.Element => {
const getData = async () => {
if (!walletMetadata || !coinPricing.priceResult.cardano.price) return;
try {
const { utxoProvider } = getProviderByChain(walletMetadata.chain);
const { utxoProvider } = getProviders();
const utxos: Wallet.Cardano.Utxo[] = await utxoProvider.utxoByAddresses({
addresses: [walletMetadata.address]
});
Expand Down
43 changes: 43 additions & 0 deletions packages/cardano/src/wallet/lib/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
} from '@cardano-sdk/cardano-services-client';
import { BlockfrostClient, BlockfrostClientConfig, RateLimiter } from './blockfrost/blockfrost-client';
import { BlockfrostAssetProvider } from './blockfrost';
import { RemoteApiProperties, RemoteApiPropertyType } from '@cardano-sdk/web-extension';

const createTxSubmitProvider = (
httpProviderConfig: CreateHttpProviderConfig<Provider>,
Expand Down Expand Up @@ -159,3 +160,45 @@ export const createProviders = ({
rewardsProvider
};
};

export const walletProvidersChannel = (walletName: string): string => `${walletName}-providers`;
export const walletProvidersProperties: RemoteApiProperties<WalletProvidersDependencies> = {
stakePoolProvider: {
queryStakePools: RemoteApiPropertyType.MethodReturningPromise,
stakePoolStats: RemoteApiPropertyType.MethodReturningPromise,
healthCheck: RemoteApiPropertyType.MethodReturningPromise
},
assetProvider: {
getAsset: RemoteApiPropertyType.MethodReturningPromise,
getAssets: RemoteApiPropertyType.MethodReturningPromise,
healthCheck: RemoteApiPropertyType.MethodReturningPromise
},
txSubmitProvider: {
submitTx: RemoteApiPropertyType.MethodReturningPromise,
healthCheck: RemoteApiPropertyType.MethodReturningPromise
},
networkInfoProvider: {
ledgerTip: RemoteApiPropertyType.MethodReturningPromise,
protocolParameters: RemoteApiPropertyType.MethodReturningPromise,
genesisParameters: RemoteApiPropertyType.MethodReturningPromise,
lovelaceSupply: RemoteApiPropertyType.MethodReturningPromise,
stake: RemoteApiPropertyType.MethodReturningPromise,
eraSummaries: RemoteApiPropertyType.MethodReturningPromise,
healthCheck: RemoteApiPropertyType.MethodReturningPromise
},
utxoProvider: {
utxoByAddresses: RemoteApiPropertyType.MethodReturningPromise,
healthCheck: RemoteApiPropertyType.MethodReturningPromise
},
rewardsProvider: {
rewardsHistory: RemoteApiPropertyType.MethodReturningPromise,
rewardAccountBalance: RemoteApiPropertyType.MethodReturningPromise,
healthCheck: RemoteApiPropertyType.MethodReturningPromise
},
chainHistoryProvider: {
transactionsByAddresses: RemoteApiPropertyType.MethodReturningPromise,
transactionsByHashes: RemoteApiPropertyType.MethodReturningPromise,
blocksByHashes: RemoteApiPropertyType.MethodReturningPromise,
healthCheck: RemoteApiPropertyType.MethodReturningPromise
}
};

0 comments on commit 1ae1e80

Please sign in to comment.