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: Add StakeSdkProvider with stake-sdk #11668

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { renderScreen } from '../../../../../util/test/renderWithProvider';
import Routes from '../../../../../constants/navigation/Routes';
import { backgroundState } from '../../../../../util/test/initial-root-state';
import { BN } from 'ethereumjs-util';
import { Stake } from '../../sdk/stakeSdkProvider';

function render(Component: React.ComponentType) {
return renderScreen(
Expand Down Expand Up @@ -51,6 +52,17 @@ jest.mock('../../../../../selectors/currencyRateController.ts', () => ({
}));

const mockBalanceBN = new BN('1500000000000000000');

jest.mock('../../hooks/useStakeContext.ts', () => ({
useStakeContext: jest.fn(() => {
const stakeContext: Stake = {
setSdkType: jest.fn(),
sdkService: undefined
}
return stakeContext
})
}))

jest.mock('../../hooks/useBalance', () => ({
__esModule: true,
default: () => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import styleSheet from './StakeInputView.styles';
import useStakingInputHandlers from '../../hooks/useStakingInput';
import useBalance from '../../hooks/useBalance';
import InputDisplay from '../../components/InputDisplay';
import { useStakeContext } from '../../hooks/useStakeContext';

const StakeInputView = () => {
const title = strings('stake.stake_eth');
Expand All @@ -43,6 +44,9 @@ const StakeInputView = () => {
estimatedAnnualRewards,
} = useStakingInputHandlers(balanceWei);


const { sdkService } = useStakeContext();

const navigateToLearnMoreModal = () => {
navigation.navigate('StakeModals', {
screen: Routes.STAKING.MODALS.LEARN_MORE,
Expand All @@ -57,7 +61,8 @@ const StakeInputView = () => {
amountFiat: fiatAmount,
},
});
}, [amountWei, fiatAmount, navigation]);
// eslint-disable-next-line react-hooks/exhaustive-deps
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure a navigation needs to be wrapped on a useCallback, since it's not an high resources computational function, we could remove the useCallback, and also the disable of eslint

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi, the eslint react-hooks/exhaustive-deps exclude comment is only about the sdkService being added in the dependency list and not used yet, but will as soon as this pr is merged

}, [amountWei, fiatAmount, navigation, sdkService]);

const balanceText = strings('stake.balance');

Expand Down
2 changes: 1 addition & 1 deletion app/components/UI/Stake/hooks/useBalance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const useBalance = () => {
[balanceWei, conversionRate],
);

return { balance, balanceFiat, balanceWei, balanceFiatNumber };
return { balance, balanceFiat, balanceWei, balanceFiatNumber, conversionRate, currentCurrency };
};

export default useBalance;
7 changes: 7 additions & 0 deletions app/components/UI/Stake/hooks/useStakeContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { useContext } from 'react';
import { Stake, StakeContext } from '../sdk/stakeSdkProvider';

export const useStakeContext = () => {
const context = useContext(StakeContext);
return context as Stake;
};
44 changes: 26 additions & 18 deletions app/components/UI/Stake/routes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import LearnMoreModal from '../components/LearnMoreModal';
import Routes from '../../../../constants/navigation/Routes';
import StakeConfirmationView from '../Views/StakeConfirmationView/StakeConfirmationView';
import UnstakeInputView from '../Views/UnstakeInputView/UnstakeInputView';
import { StakeSDKProvider } from '../sdk/stakeSdkProvider';
const Stack = createStackNavigator();
const ModalStack = createStackNavigator();

Expand All @@ -18,28 +19,35 @@ const clearStackNavigatorOptions = {

// Regular Stack for Screens
const StakeScreenStack = () => (
<Stack.Navigator>
<Stack.Screen name={Routes.STAKING.STAKE} component={StakeInputView} />
<Stack.Screen name={Routes.STAKING.UNSTAKE} component={UnstakeInputView} />
<Stack.Screen
name={Routes.STAKING.STAKE_CONFIRMATION}
component={StakeConfirmationView}
/>
</Stack.Navigator>
<StakeSDKProvider>
<Stack.Navigator>
<Stack.Screen name={Routes.STAKING.STAKE} component={StakeInputView} />
<Stack.Screen
name={Routes.STAKING.UNSTAKE}
component={UnstakeInputView}
/>
<Stack.Screen
name={Routes.STAKING.STAKE_CONFIRMATION}
component={StakeConfirmationView}
/>
</Stack.Navigator>
</StakeSDKProvider>
);

// Modal Stack for Modals
const StakeModalStack = () => (
<ModalStack.Navigator
mode={'modal'}
screenOptions={clearStackNavigatorOptions}
>
<ModalStack.Screen
name={Routes.STAKING.MODALS.LEARN_MORE}
component={LearnMoreModal}
options={{ headerShown: false }}
/>
</ModalStack.Navigator>
<StakeSDKProvider>
<ModalStack.Navigator
mode={'modal'}
screenOptions={clearStackNavigatorOptions}
>
<ModalStack.Screen
name={Routes.STAKING.MODALS.LEARN_MORE}
component={LearnMoreModal}
options={{ headerShown: false }}
/>
</ModalStack.Navigator>
</StakeSDKProvider>
);

export { StakeScreenStack, StakeModalStack };
71 changes: 71 additions & 0 deletions app/components/UI/Stake/sdk/UseSdkProvider.test.tsx
siibars marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: This file is testing the hook useSdkProvider, but it's Pascal Case, can we re write it in camel?

ChainId,
PooledStakingContract,
StakingType,
} from '@metamask/stake-sdk';
import renderWithProvider from '../../../../util/test/renderWithProvider';
import { backgroundState } from '../../../../util/test/initial-root-state';
import { Stake } from '../sdk/stakeSdkProvider';
// eslint-disable-next-line import/no-namespace
import * as useStakeContextHook from '../hooks/useStakeContext';
import { Contract } from '@ethersproject/contracts';
import { StakeModalStack, StakeScreenStack } from '../routes';

const mockPooledStakingContractService: PooledStakingContract = {
chainId: ChainId.ETHEREUM,
connectSignerOrProvider: jest.fn(),
contract: new Contract('0x0000000000000000000000000000000000000000', []),
convertToShares: jest.fn(),
encodeClaimExitedAssetsTransactionData: jest.fn(),
encodeDepositTransactionData: jest.fn(),
encodeEnterExitQueueTransactionData: jest.fn(),
encodeMulticallTransactionData: jest.fn(),
estimateClaimExitedAssetsGas: jest.fn(),
estimateDepositGas: jest.fn(),
estimateEnterExitQueueGas: jest.fn(),
estimateMulticallGas: jest.fn(),
};

const mockSDK: Stake = {
sdkService: mockPooledStakingContractService,
sdkType: StakingType.POOLED,
setSdkType: jest.fn(),
};

jest.mock('../../Stake/constants', () => ({
isPooledStakingFeatureEnabled: jest.fn().mockReturnValue(true),
}));

describe('Stake Modals With Stake Sdk Provider', () => {
const initialState = {
engine: {
backgroundState,
},
};
it('should render correctly stake screen with stake sdk provider and resolve the stake context', () => {
const useStakeContextSpy = jest
.spyOn(useStakeContextHook, 'useStakeContext')
.mockReturnValue(mockSDK);

const { toJSON } = renderWithProvider(StakeScreenStack(), {
state: initialState,
});

expect(toJSON()).toMatchSnapshot();
expect(useStakeContextSpy).toHaveBeenCalled();
});

it('should render correctly stake modal with stake sdk provider and resolve the stake context', () => {
const useStakeContextSpy = jest
.spyOn(useStakeContextHook, 'useStakeContext')
.mockReturnValue(mockSDK);

const { toJSON } = renderWithProvider(StakeModalStack(), {
state: initialState,
});

expect(toJSON()).toMatchSnapshot();
expect(useStakeContextSpy).toHaveBeenCalledTimes(0);

});
});
Loading
Loading