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 (#1507)

* feat: providers are now consumed from the service worker instead of the UI script

* fixup! feat: providers are now consumed from the service worker instead of the UI script

* fixup! feat: providers are now consumed from the service worker instead of the UI script

* fixup! feat: providers are now consumed from the service worker instead of the UI script

* fixup! feat: providers are now consumed from the service worker instead of the UI script

* fixup! feat: providers are now consumed from the service worker instead of the UI script

---------

Co-authored-by: Martynas Kazlauskas <martynas.kazlauskas@iohk.io>
  • Loading branch information
AngelCastilloB and mkazlauskas authored Nov 7, 2024
1 parent bd4ee81 commit 00ec6ea
Show file tree
Hide file tree
Showing 16 changed files with 177 additions and 141 deletions.
6 changes: 3 additions & 3 deletions apps/browser-extension-wallet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@
},
"dependencies": {
"@ant-design/icons": "^4.7.0",
"@cardano-sdk/cardano-services-client": "0.21.6",
"@cardano-sdk/cardano-services-client": "0.21.7",
"@cardano-sdk/core": "0.41.2",
"@cardano-sdk/dapp-connector": "0.12.42",
"@cardano-sdk/input-selection": "0.13.25",
"@cardano-sdk/tx-construction": "0.21.10",
"@cardano-sdk/util": "0.15.5",
"@cardano-sdk/util-rxjs": "0.7.38",
"@cardano-sdk/wallet": "0.44.14",
"@cardano-sdk/web-extension": "0.34.13",
"@cardano-sdk/wallet": "0.44.15",
"@cardano-sdk/web-extension": "0.34.14",
"@emurgo/cip14-js": "~3.0.1",
"@input-output-hk/lace-ui-toolkit": "1.21.0",
"@lace/cardano": "0.1.0",
Expand Down
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
const mockProviders = {
chainHistoryProvider: {
transactionsByAddress: jest.fn().mockResolvedValue([]),
transactionsByHashes: jest.fn().mockResolvedValue([]),
blocksByHashes: jest.fn().mockResolvedValue([])
},
assetProvider
};

jest.mock('@stores/slices/blockchain-provider-slice', () => ({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
...jest.requireActual<any>('@stores/slices/blockchain-provider-slice'),
getProviders: () => mockProviders
}));

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.

19 changes: 17 additions & 2 deletions apps/browser-extension-wallet/src/lib/scripts/background/wallet.ts
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, BehaviorSubject } from 'rxjs';
import { getProviders } from './config';
import {
DEFAULT_LOOK_AHEAD_SEARCH,
Expand Down Expand Up @@ -60,17 +60,23 @@ const chainIdToChainName = (chainId: Cardano.ChainId): Wallet.ChainName => {
}
};

// eslint-disable-next-line unicorn/no-null
const currentWalletProviders$ = new BehaviorSubject<Wallet.WalletProvidersDependencies | null>(null);

const walletFactory: WalletFactory<Wallet.WalletMetadata, Wallet.AccountMetadata> = {
create: async ({ chainId, accountIndex }, wallet, { stores, witnesser }) => {
const chainName: Wallet.ChainName = chainIdToChainName(chainId);
const providers = await getProviders(chainName);

// Caches current wallet providers.
currentWalletProviders$.next(providers);

const baseUrl = getBaseUrlForChain(chainName);

// Sanchonet does not have a handle provider
const supportsHandleResolver = chainName !== 'Sanchonet';

// This is used in place of the handle provider for environments where the handle provider is not available
// This is used in place ofgetProviders the handle provider for environments where the handle provider is not available
const noopHandleResolver: HandleProvider = {
resolveHandles: async () => [],
healthCheck: async () => ({ ok: true }),
Expand Down Expand Up @@ -232,6 +238,15 @@ walletManager
},
{ logger, runtime }
);

exposeApi(
{
api$: currentWalletProviders$,
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
8 changes: 4 additions & 4 deletions packages/cardano/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,16 @@
"watch": "yarn build --watch"
},
"dependencies": {
"@cardano-sdk/cardano-services-client": "0.21.6",
"@cardano-sdk/cardano-services-client": "0.21.7",
"@cardano-sdk/core": "0.41.2",
"@cardano-sdk/crypto": "0.1.30",
"@cardano-sdk/hardware-ledger": "0.12.10",
"@cardano-sdk/hardware-trezor": "0.6.9",
"@cardano-sdk/key-management": "0.24.8",
"@cardano-sdk/tx-construction": "0.21.10",
"@cardano-sdk/util": "0.15.5",
"@cardano-sdk/wallet": "0.44.14",
"@cardano-sdk/web-extension": "0.34.13",
"@cardano-sdk/wallet": "0.44.15",
"@cardano-sdk/web-extension": "0.34.14",
"@lace/common": "0.1.0",
"@ledgerhq/devices": "^8.2.1",
"@stablelib/chacha20poly1305": "1.0.1",
Expand All @@ -73,7 +73,7 @@
},
"devDependencies": {
"@blockfrost/blockfrost-js": "^5.5.0",
"@cardano-sdk/util-dev": "0.23.8",
"@cardano-sdk/util-dev": "0.23.9",
"@emurgo/cardano-message-signing-browser": "1.0.1",
"@types/webextension-polyfill": "0.10.0",
"axios": "^1.7.4",
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
}
};
Loading

0 comments on commit 00ec6ea

Please sign in to comment.