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

Merged
merged 16 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from 7 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
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
siibars marked this conversation as resolved.
Show resolved Hide resolved
}, [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
siibars marked this conversation as resolved.
Show resolved Hide resolved
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 {
siibars marked this conversation as resolved.
Show resolved Hide resolved
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