Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/lw 12074 enable new input resolver in lace #1639

Merged
merged 4 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/browser-extension-wallet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
"@cardano-sdk/tx-construction": "0.24.4",
"@cardano-sdk/util": "0.15.5",
"@cardano-sdk/util-rxjs": "0.9.2",
"@cardano-sdk/wallet": "0.49.1",
"@cardano-sdk/web-extension": "0.37.4",
"@cardano-sdk/wallet": "0.49.2",
"@cardano-sdk/web-extension": "0.37.5",
"@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 @@ -28,7 +28,6 @@ import { Skeleton } from 'antd';
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';
import { eraSlotDateTime } from '@src/utils/era-slot-datetime';
import { AddressBookSchema, useDbStateValue } from '@lib/storage';
import { getAllWalletsAddresses } from '@src/utils/get-all-wallets-addresses';
Expand Down Expand Up @@ -80,17 +79,7 @@ export const DappTransactionContainer = withAddressBookContext(
TransactionSummaryInspection | undefined
>();

const { chainHistoryProvider } = getProviders();

const txInputResolver = useMemo(
() =>
utxoAndBackendChainHistoryResolver({
utxo: inMemoryWallet.utxo,
transactions: inMemoryWallet.transactions,
chainHistoryProvider
}),
[inMemoryWallet, chainHistoryProvider]
);
const { inputResolver } = getProviders();

const tx = useMemo(() => req?.transaction.toCore(), [req?.transaction]);

Expand All @@ -105,7 +94,7 @@ export const DappTransactionContainer = withAddressBookContext(
return () => subscription?.unsubscribe();
}, [inMemoryWallet?.governance?.isRegisteredAsDRep$, userAckNonRegisteredState, tx]);

const txCollateral = useComputeTxCollateral(walletState, tx);
const txCollateral = useComputeTxCollateral(inputResolver, walletState, tx);

const userAddresses = useMemo(() => walletInfo.addresses.map((v) => v.address), [walletInfo.addresses]);
const userRewardAccounts = useObservable(inMemoryWallet.delegation.rewardAccounts$);
Expand All @@ -122,7 +111,7 @@ export const DappTransactionContainer = withAddressBookContext(
const getTxSummary = async () => {
const inspector = createTxInspector({
tokenTransfer: tokenTransferInspector({
inputResolver: txInputResolver,
inputResolver,
fromAddressAssetProvider: createWalletAssetProvider({
assetProvider,
assetInfo$: inMemoryWallet.assetInfo$,
Expand All @@ -140,7 +129,7 @@ export const DappTransactionContainer = withAddressBookContext(
summary: transactionSummaryInspector({
addresses: userAddresses,
rewardAccounts: rewardAccountsAddresses,
inputResolver: txInputResolver,
inputResolver,
protocolParameters,
assetProvider: createWalletAssetProvider({
assetProvider,
Expand All @@ -166,7 +155,7 @@ export const DappTransactionContainer = withAddressBookContext(
walletInfo.addresses,
userAddresses,
rewardAccountsAddresses,
txInputResolver,
inputResolver,
protocolParameters,
assetProvider,
inMemoryWallet.assetInfo$,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ const inMemoryWallet = {
protocolParameters$,
governance: {
isRegisteredAsDRep$: new BehaviorSubject(true)
},
util: {
resolveInput: jest.fn().mockResolvedValue(null)
}
};
const REWARD_ACCOUNT = Cardano.RewardAccount('stake_test1uqrw9tjymlm8wrwq7jk68n6v7fs9qz8z0tkdkve26dylmfc2ux2hj');
Expand Down Expand Up @@ -129,7 +132,10 @@ const mockProviders = {
transactionsByHashes: jest.fn().mockResolvedValue([]),
blocksByHashes: jest.fn().mockResolvedValue([])
},
assetProvider
assetProvider,
inputResolver: {
resolveInput: jest.fn().mockResolvedValue(null)
}
};

jest.mock('@stores/slices/blockchain-provider-slice', () => ({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import { Wallet } from '@lace/cardano';
import { createHistoricalOwnInputResolver } from '@src/utils/own-input-resolver';
import { useState, useEffect } from 'react';
import { getCollateral } from '@cardano-sdk/core';
import { Cardano, getCollateral } from '@cardano-sdk/core';
import { ObservableWalletState } from './useWalletState';

export const useComputeTxCollateral = (wallet?: ObservableWalletState, tx?: Wallet.Cardano.Tx): bigint | undefined => {
export const useComputeTxCollateral = (
inputResolver: Cardano.InputResolver,
wallet?: ObservableWalletState,
tx?: Wallet.Cardano.Tx
): bigint | undefined => {
const [txCollateral, setTxCollateral] = useState<bigint>();

useEffect(() => {
if (!tx || !wallet) return;

const computeCollateral = async () => {
const inputResolver = createHistoricalOwnInputResolver({
addresses: wallet.addresses,
transactions: wallet.transactions
});

const collateral = await getCollateral(
tx,
inputResolver,
Expand All @@ -26,7 +24,7 @@ export const useComputeTxCollateral = (wallet?: ObservableWalletState, tx?: Wall
};

computeCollateral();
}, [tx, wallet]);
}, [tx, wallet, inputResolver]);

return txCollateral;
};
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const backgroundServiceProperties: RemoteApiProperties<BackgroundService>
const { BLOCKFROST_CONFIGS, BLOCKFROST_RATE_LIMIT_CONFIG } = config();
// Important to use the same rateLimiter object for all networks,
// because Blockfrost rate limit is per IP address, not per project id
const rateLimiter: RateLimiter = new Bottleneck({
export const rateLimiter: RateLimiter = new Bottleneck({
reservoir: BLOCKFROST_RATE_LIMIT_CONFIG.size,
reservoirIncreaseAmount: BLOCKFROST_RATE_LIMIT_CONFIG.increaseAmount,
reservoirIncreaseInterval: BLOCKFROST_RATE_LIMIT_CONFIG.increaseInterval,
Expand Down Expand Up @@ -68,7 +68,8 @@ export const getProviders = async (chainName: Wallet.ChainName): Promise<Wallet.
useBlockfrostRewardsProvider: isExperimentEnabled(ExperimentName.BLOCKFROST_REWARDS_PROVIDER),
useBlockfrostTxSubmitProvider: isExperimentEnabled(ExperimentName.BLOCKFROST_TX_SUBMIT_PROVIDER),
useBlockfrostUtxoProvider: isExperimentEnabled(ExperimentName.BLOCKFROST_UTXO_PROVIDER),
useBlockfrostAddressDiscovery: isExperimentEnabled(ExperimentName.BLOCKFROST_ADDRESS_DISCOVERY)
useBlockfrostAddressDiscovery: isExperimentEnabled(ExperimentName.BLOCKFROST_ADDRESS_DISCOVERY),
useBlockfrostInputResolver: isExperimentEnabled(ExperimentName.BLOCKFROST_INPUT_RESOLVER)
}
});
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,10 @@ export const walletRepository = new WalletRepository({
const currentWalletProviders$ = new BehaviorSubject<Wallet.WalletProvidersDependencies | null>(null);

const walletFactory: WalletFactory<Wallet.WalletMetadata, Wallet.AccountMetadata> = {
// eslint-disable-next-line complexity, max-statements
create: async ({ chainId, accountIndex }, wallet, { stores, witnesser }) => {
const chainName: Wallet.ChainName = networkMagicToChainName(chainId.networkMagic);
const providers = await getProviders(chainName);

// Caches current wallet providers.
currentWalletProviders$.next(providers);
let providers = await getProviders(chainName);

const baseUrl = getBaseUrlForChain(chainName);

Expand All @@ -130,11 +128,13 @@ const walletFactory: WalletFactory<Wallet.WalletMetadata, Wallet.AccountMetadata
});
}

const featureFlags = await getFeatureFlags(chainId.networkMagic);

if (wallet.type === WalletType.Script) {
const stakingScript = wallet.stakingScript as SharedWalletScriptKind;
const paymentScript = wallet.paymentScript as SharedWalletScriptKind;

return createSharedWallet(
const sharedWallet = createSharedWallet(
{ name: wallet.metadata.name },
{
...providers,
Expand All @@ -152,6 +152,12 @@ const walletFactory: WalletFactory<Wallet.WalletMetadata, Wallet.AccountMetadata
witnesser
}
);

// Caches current wallet providers.
providers = { ...providers, inputResolver: { resolveInput: sharedWallet.util.resolveInput } };
currentWalletProviders$.next(providers);

return sharedWallet;
}

const walletAccount = wallet.accounts.find((acc) => acc.accountIndex === accountIndex);
Expand All @@ -164,14 +170,13 @@ const walletFactory: WalletFactory<Wallet.WalletMetadata, Wallet.AccountMetadata
extendedAccountPublicKey: walletAccount.extendedAccountPublicKey
});

const featureFlags = await getFeatureFlags(chainId.networkMagic);
const useWebSocket = isExperimentEnabled(featureFlags, ExperimentName.WEBSOCKET_API);
const localPollingIntervalConfig = !Number.isNaN(Number(process.env.WALLET_POLLING_INTERVAL_IN_SEC))
? // eslint-disable-next-line no-magic-numbers
Number(process.env.WALLET_POLLING_INTERVAL_IN_SEC) * 1000
: DEFAULT_POLLING_CONFIG.pollInterval;

return createPersonalWallet(
const personalWallet = createPersonalWallet(
{
name: walletAccount.metadata.name,
polling: {
Expand All @@ -194,6 +199,12 @@ const walletFactory: WalletFactory<Wallet.WalletMetadata, Wallet.AccountMetadata
bip32Account
}
);

// Caches current wallet providers.
providers = { ...providers, inputResolver: { resolveInput: personalWallet.util.resolveInput } };
currentWalletProviders$.next(providers);

return personalWallet;
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const getDefaultFeatureFlags = (): FallbackConfiguration => ({
[ExperimentName.BLOCKFROST_TX_SUBMIT_PROVIDER]: false,
[ExperimentName.BLOCKFROST_UTXO_PROVIDER]: false,
[ExperimentName.BLOCKFROST_ADDRESS_DISCOVERY]: false,
[ExperimentName.BLOCKFROST_INPUT_RESOLVER]: false,
[ExperimentName.EXTENSION_STORAGE]: false,
[ExperimentName.USE_DREP_PROVIDER_OVERRIDE]: false,
[ExperimentName.DAPP_EXPLORER]: false
Expand Down Expand Up @@ -67,6 +68,10 @@ export const experiments: ExperimentsConfig = {
value: false,
default: false
},
[ExperimentName.BLOCKFROST_INPUT_RESOLVER]: {
value: false,
default: false
},
[ExperimentName.EXTENSION_STORAGE]: {
value: false,
default: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export enum ExperimentName {
BLOCKFROST_TX_SUBMIT_PROVIDER = 'blockfrost-tx-submit-provider',
BLOCKFROST_UTXO_PROVIDER = 'blockfrost-utxo-provider',
BLOCKFROST_ADDRESS_DISCOVERY = 'blockfrost-address-discovery',
BLOCKFROST_INPUT_RESOLVER = 'blockfrost-input-resolver',
EXTENSION_STORAGE = 'extension-storage',
USE_DREP_PROVIDER_OVERRIDE = 'use-drep-provider-override',
DAPP_EXPLORER = 'dapp-explorer'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { BlockchainProviderSlice, SliceCreator } from '../types';
import { Wallet } from '@lace/cardano';
import { consumeRemoteApi } from '@cardano-sdk/web-extension';
import { runtime } from 'webextension-polyfill';
import { DRepProvider } from '@cardano-sdk/core';
import { Cardano, DRepProvider } from '@cardano-sdk/core';

export interface IBlockchainProvider {
stakePoolProvider: Wallet.StakePoolProvider;
Expand All @@ -13,6 +13,7 @@ export interface IBlockchainProvider {
chainHistoryProvider: Wallet.ChainHistoryProvider;
rewardsProvider: Wallet.RewardsProvider;
drepProvider?: DRepProvider;
inputResolver: Cardano.InputResolver;
}

export type BlockchainProviderFactory = () => IBlockchainProvider;
Expand All @@ -26,7 +27,8 @@ export const IBlockchainProvider = {
utxoProvider: providers?.utxoProvider,
rewardsProvider: providers?.rewardsProvider,
chainHistoryProvider: providers?.chainHistoryProvider,
drepProvider: providers?.drepProvider
drepProvider: providers?.drepProvider,
inputResolver: providers?.inputResolver
}),
fromWalletProviders: (providers: Wallet.WalletProvidersDependencies): IBlockchainProvider => ({
txSubmitProvider: providers?.txSubmitProvider,
Expand All @@ -36,7 +38,8 @@ export const IBlockchainProvider = {
utxoProvider: providers?.utxoProvider,
rewardsProvider: providers?.rewardsProvider,
chainHistoryProvider: providers?.chainHistoryProvider,
drepProvider: providers?.drepProvider
drepProvider: providers?.drepProvider,
inputResolver: providers?.inputResolver
})
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { IWalletProvider } from '@lib/wallet-provider';
import { Wallet } from '@lace/cardano';
import { IBlockchainProvider } from '@src/stores/slices';
import { Cardano } from '@cardano-sdk/core';

/**
* Wallet Provider mock
Expand Down Expand Up @@ -53,5 +54,12 @@ export const mockBlockchainProviders = (blockchainProviders?: Partial<IBlockchai
utxoProvider: mockUtxoProvider(),
rewardsProvider: mockRewardsProvider(),
chainHistoryProvider: mockChainHistoryProvider(),
inputResolver: {
resolveInput: jest.fn().mockResolvedValue({
address: 'Addr' as Cardano.PaymentAddress,
/* eslint-disable no-magic-numbers */
value: { coins: BigInt(999) }
})
},
...blockchainProviders
});

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { CommonOutsideHandlesProvider, Main as Nami, OutsideHandlesProvider } from '@lace/nami';
import { useWalletStore } from '@src/stores';
import { config } from '@src/config';
import { createHistoricalOwnInputResolver } from '@src/utils/own-input-resolver';
import {
useBackgroundServiceAPIContext,
useCurrencyStore,
Expand Down Expand Up @@ -31,7 +32,7 @@ import { useDelegationTransaction, useRewardAccountsData } from '../browser-view
import { useSecrets } from '@lace/core';
import { useDelegationStore } from '@src/features/delegation/stores';
import { useStakePoolDetails } from '@src/features/stake-pool-details/store';
import { getPoolInfos } from '@src/stores/slices';
import { getPoolInfos, getProviders } from '@src/stores/slices';
import { Wallet } from '@lace/cardano';
import { walletBalanceTransformer } from '@src/api/transformers';
import { PostHogAction, useObservable } from '@lace/common';
Expand All @@ -43,7 +44,6 @@ import { isKeyHashAddress } from '@cardano-sdk/wallet';
import { BackgroundStorage } from '@lib/scripts/types';
import { getWalletAccountsQtyString } from '@src/utils/get-wallet-count-string';
import { useNetworkError } from '@hooks/useNetworkError';
import { createHistoricalOwnInputResolver } from '@src/utils/own-input-resolver';
import { walletRoutePaths } from '@routes';
import { StakingErrorType } from '@views/browser/features/staking/types';

Expand Down Expand Up @@ -184,6 +184,7 @@ export const NamiView = withDappContext((): React.ReactElement => {
}, [analytics, deleteWallet, setDeletingWallet, walletRepository]);

const { lockedStakeRewards } = useRewardAccountsData();
const { inputResolver } = getProviders();

const redirectToStaking = useRedirection(walletRoutePaths.earn);

Expand Down Expand Up @@ -219,6 +220,7 @@ export const NamiView = withDappContext((): React.ReactElement => {
availableChains: AVAILABLE_CHAINS,
enableCustomNode,
getCustomSubmitApiForNetwork,
createHistoricalOwnInputResolver,
defaultSubmitApi: DEFAULT_SUBMIT_API,
isValidURL,
buildDelegation,
Expand Down Expand Up @@ -248,9 +250,9 @@ export const NamiView = withDappContext((): React.ReactElement => {
chainHistoryProvider,
protocolParameters: walletState?.protocolParameters,
assetInfo: walletState?.assetInfo,
createHistoricalOwnInputResolver,
lockedStakeRewards,
redirectToStaking,
inputResolver,
govToolsUrl: GOV_TOOLS_URLS[environmentName]
}}
>
Expand Down
4 changes: 2 additions & 2 deletions packages/cardano/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
"@cardano-sdk/key-management": "0.25.1",
"@cardano-sdk/tx-construction": "0.24.4",
"@cardano-sdk/util": "0.15.5",
"@cardano-sdk/wallet": "0.49.1",
"@cardano-sdk/web-extension": "0.37.4",
"@cardano-sdk/wallet": "0.49.2",
"@cardano-sdk/web-extension": "0.37.5",
"@lace/common": "0.1.0",
"@ledgerhq/devices": "^8.4.4",
"@stablelib/chacha20poly1305": "1.0.1",
Expand Down
Loading
Loading