Skip to content
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
9 changes: 6 additions & 3 deletions apps/evm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"zustand": "^5.0.0"
},
"devDependencies": {
"@babel/core": "^7.29.0",
"@biomejs/biome": "1.6.4",
"@changesets/cli": "^2.27.1",
"@dotenvx/dotenvx": "^1.26.2",
Expand All @@ -94,7 +95,7 @@
"@graphql-codegen/client-preset": "^4.5.1",
"@graphql-codegen/typed-document-node": "^6.0.2",
"@graphql-codegen/typescript-operations": "^4.0.1",
"@rollup/plugin-inject": "^5.0.3",
"@rolldown/plugin-babel": "^0.2.3",
"@storybook/addon-essentials": "8.6.14",
"@storybook/addon-interactions": "8.6.14",
"@storybook/addon-links": "8.6.14",
Expand All @@ -106,6 +107,7 @@
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.3.0",
"@types/babel__core": "^7.20.5",
"@types/get-pixels": "^3.3.4",
"@types/lodash-es": "^4.17.12",
"@types/react": "^19.1.5",
Expand All @@ -123,8 +125,9 @@
"@venusprotocol/typescript-config": "*",
"@venusprotocol/venus-periphery": "^1.1.0",
"@venusprotocol/venus-protocol": "10.2.0-slim-dev.2",
"@vitejs/plugin-react": "^4.3.3",
"@vitejs/plugin-react": "^6.0.2",
"@vitest/coverage-v8": "^2.1.5",
"babel-plugin-react-compiler": "^1.0.0",
"c8": "^10.0.0",
"fs": "^0.0.1-security",
"genversion": "^3.1.1",
Expand All @@ -150,7 +153,7 @@
"tsx": "^4.1.2",
"tw-animate-css": "^1.4.0",
"typescript": "^5.1.6",
"vite": "^6.2.5",
"vite": "^8.0.16",
"vite-plugin-svgr": "^4.3.0",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.1.1",
Expand Down
2 changes: 1 addition & 1 deletion apps/evm/src/components/Icon/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,4 @@ export { default as protectionShield } from './protectionShield';
export { default as resilientOracle } from './resilientOracle';
export { default as sunset } from './sunset';
export { default as fullScreen } from './fullScreen';
export { default as switch } from './switch';
export { default as swap } from './swap';
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { SVGProps } from 'react';

const SvgSwitch = (props: SVGProps<SVGSVGElement>) => (
const SvgSwap = (props: SVGProps<SVGSVGElement>) => (
<svg
width="16"
height="16"
Expand All @@ -26,4 +26,4 @@ const SvgSwitch = (props: SVGProps<SVGSVGElement>) => (
</svg>
);

export default SvgSwitch;
export default SvgSwap;
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { type ChainId, chains as chainMetadata } from '@venusprotocol/chains';

import { Icon, Toggle } from 'components';
import { useTranslation } from 'libs/translations';
import { store } from 'store';
import { useStore } from 'store';

export interface GaslessTransactionSettingProps {
chainId: ChainId;
Expand All @@ -13,8 +13,8 @@ export const GaslessTransactionSetting: React.FC<GaslessTransactionSettingProps>
}) => {
const { t } = useTranslation();

const userSettings = store.use.userSettings()[chainId];
const setUserSettings = store.use.setUserSettings();
const userSettings = useStore(state => state.userSettings)[chainId];
const setUserSettings = useStore(state => state.setUserSettings);

const chainName = chainMetadata[chainId].name;

Expand Down
6 changes: 3 additions & 3 deletions apps/evm/src/containers/Layout/ScrollToTop/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { cn } from '@venusprotocol/ui';
import { Button, Icon } from 'components';
import { PAGE_CONTAINER_ID } from 'constants/layout';

import { store } from 'containers/Layout/store';
import { useStore } from 'containers/Layout/store';
import { forwardRef } from 'react';

const ScrollToTop = forwardRef<HTMLButtonElement>((_, ref) => {
const isVisible = store.use.isScrollToTopVisible();
const isCloseToBottom = store.use.isCloseToBottom();
const isVisible = useStore(state => state.isScrollToTopVisible);
const isCloseToBottom = useStore(state => state.isCloseToBottom);
const scrollElem = document.getElementById(PAGE_CONTAINER_ID);

return (
Expand Down
10 changes: 5 additions & 5 deletions apps/evm/src/containers/Layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Header } from './Header';
import { NavBar } from './NavBar';
import ScrollToTop from './ScrollToTop';
import { TestEnvWarning } from './TestEnvWarning';
import { store } from './store';
import { useStore } from './store';

const NO_WRAPPER_PATHNAMES = [Subdirectory.LANDING] as string[];

Expand All @@ -20,10 +20,10 @@ export const Layout: React.FC = () => {

const { pathname } = useLocation();

const isCloseToBottomState = store.use.isCloseToBottom();
const setIsCloseToBottom = store.use.setIsCloseToBottom();
const setScrollToTopVisible = store.use.setScrollToTopVisible();
const isScrollToTopVisible = store.use.isScrollToTopVisible();
const isCloseToBottomState = useStore(state => state.isCloseToBottom);
const setIsCloseToBottom = useStore(state => state.setIsCloseToBottom);
const setScrollToTopVisible = useStore(state => state.setScrollToTopVisible);
const isScrollToTopVisible = useStore(state => state.isScrollToTopVisible);
const viewportHeight = window.innerHeight;

const handleScroll = (event: React.UIEvent<HTMLDivElement>) => {
Expand Down
4 changes: 2 additions & 2 deletions apps/evm/src/containers/Layout/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ interface State {
setIsCloseToBottom: (isCloseToBottom: State['isCloseToBottom']) => void;
}

const useStore = create<State>()(set => ({
const store = create<State>()(set => ({
isScrollToTopVisible: false,
setScrollToTopVisible: (v: boolean) => set({ isScrollToTopVisible: v }),
isCloseToBottom: false,
setIsCloseToBottom: (v: boolean) => set({ isCloseToBottom: v }),
}));

export const store = createStoreSelectors(useStore);
export const useStore = createStoreSelectors(store);
4 changes: 2 additions & 2 deletions apps/evm/src/containers/ResendPayingGasModal/Modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Button, Icon, Modal as ModalComp, type ModalProps as ModalCompProps } f
import { useSendTransaction } from 'hooks/useSendTransaction';
import { handleError } from 'libs/errors';
import { useTranslation } from 'libs/translations';
import { store } from '../store';
import { useStore } from '../store';
import type { LastFailedGaslessTransaction } from '../types';

export interface ModalProps<TMutateInput extends Record<string, unknown> | void>
Expand All @@ -15,7 +15,7 @@ export function Modal<TMutateInput extends Record<string, unknown> | void>({
...otherProps
}: ModalProps<TMutateInput>) {
const { t } = useTranslation();
const closeModal = store.use.closeModal();
const closeModal = useStore(state => state.closeModal);
const { mutateAsync: sendTransaction, isPending: isSendingTransaction } = useSendTransaction<
TMutateInput,
any,
Expand Down
4 changes: 2 additions & 2 deletions apps/evm/src/containers/ResendPayingGasModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Modal } from './Modal';
import { store } from './store';
import { useStore } from './store';

const ResendPayingGasModal: React.FC = () => {
const lastFailedGaslessTransaction = store.use.lastFailedGaslessTransaction();
const lastFailedGaslessTransaction = useStore(state => state.lastFailedGaslessTransaction);

if (lastFailedGaslessTransaction) {
return <Modal lastFailedGaslessTransaction={lastFailedGaslessTransaction} />;
Expand Down
4 changes: 2 additions & 2 deletions apps/evm/src/containers/ResendPayingGasModal/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { create } from 'zustand';
import { createStoreSelectors } from 'utilities/createStoreSelectors';
import type { StoreState } from '../types';

const useStore = create<StoreState<any>>()(set => ({
const store = create<StoreState<any>>()(set => ({
lastFailedGaslessTransaction: undefined,
openModal: ({ lastFailedGaslessTransaction }) => set({ lastFailedGaslessTransaction }),
closeModal: () => set({ lastFailedGaslessTransaction: undefined }),
}));

export const store = createStoreSelectors(useStore);
export const useStore = createStoreSelectors(store);
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import fakeAccountAddress from '__mocks__/models/address';
import fakeContractTransaction from '__mocks__/models/contractTransaction';
import { txData } from '__mocks__/models/transactionData';
import { useGetPaymasterInfo } from 'clients/api';
import { store } from 'containers/ResendPayingGasModal/store';
import { type UseIsFeatureEnabledInput, useIsFeatureEnabled } from 'hooks/useIsFeatureEnabled';
import { defaultUserChainSettings, useUserChainSettings } from 'hooks/useUserChainSettings';
import { VError } from 'libs/errors';
Expand All @@ -25,6 +24,7 @@ vi.mock('../sendTransaction');

const mockWalletClient = {} as unknown as WalletClient;
const mockPublicClient = {} as unknown as PublicClient;
const mockOpenModal = vi.fn();

vi.mock('wagmi', async () => {
const actual = await vi.importActual('wagmi');
Expand All @@ -38,9 +38,11 @@ vi.mock('wagmi', async () => {
});

vi.mock('containers/ResendPayingGasModal/store', () => ({
store: {
use: { openModal: vi.fn() },
},
useStore: vi.fn((selector: (state: { openModal: typeof mockOpenModal }) => unknown) =>
selector({
openModal: mockOpenModal,
}),
),
}));

const fakeHookInput = {
Expand All @@ -52,6 +54,8 @@ const fakeMutationInput = {};

describe('useSendTransaction - Feature enabled: gaslessTransactions', () => {
beforeEach(() => {
mockOpenModal.mockReset();

(useIsFeatureEnabled as Mock).mockImplementation(
({ name }: UseIsFeatureEnabledInput) => name === 'gaslessTransactions',
);
Expand Down Expand Up @@ -126,9 +130,6 @@ describe('useSendTransaction - Feature enabled: gaslessTransactions', () => {
}),
);

const openModalMock = vi.fn();
(store.use.openModal as Mock).mockImplementation(() => openModalMock);

const customFakeHookInput = {
...fakeHookInput,
options: {
Expand Down Expand Up @@ -160,8 +161,8 @@ describe('useSendTransaction - Feature enabled: gaslessTransactions', () => {

expect(refetchMock).toHaveBeenCalledTimes(1);

expect(openModalMock).toHaveBeenCalledTimes(1);
expect(openModalMock).toHaveBeenCalledWith(
expect(mockOpenModal).toHaveBeenCalledTimes(1);
expect(mockOpenModal).toHaveBeenCalledWith(
expect.objectContaining({
lastFailedGaslessTransaction: {
...customFakeHookInput,
Expand Down
4 changes: 2 additions & 2 deletions apps/evm/src/hooks/useSendTransaction/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { type MutationObserverOptions, useMutation } from '@tanstack/react-query
import type { TransactionType } from 'types';

import { useGetPaymasterInfo } from 'clients/api';
import { store as resendPayingGasModalStore } from 'containers/ResendPayingGasModal/store';
import { useStore as useResendPayingGasModalStore } from 'containers/ResendPayingGasModal/store';
import { useIsFeatureEnabled } from 'hooks/useIsFeatureEnabled';
import { useUserChainSettings } from 'hooks/useUserChainSettings';
import { VError, logError } from 'libs/errors';
Expand Down Expand Up @@ -92,7 +92,7 @@ export const useSendTransaction = <
);
const meeClient = data?.meeClient;

const openResendPayingGasModalStoreModal = resendPayingGasModalStore.use.openModal();
const openResendPayingGasModalStoreModal = useResendPayingGasModalStore(state => state.openModal);

const [userChainSettings] = useUserChainSettings();

Expand Down
29 changes: 14 additions & 15 deletions apps/evm/src/hooks/useUserChainSettings/__tests__/index.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
import type { Mock } from 'vitest';

import { store } from 'store';
import type { UserChainSettings } from 'store';
import { renderHook as renderHookWithContext } from 'testUtils/render';
import { ChainId } from 'types';
import { useUserChainSettings } from '..';

vi.unmock('hooks/useUserChainSettings');

const mockSetUserSettings = vi.fn();
const mockStoreState = {
setUserSettings: mockSetUserSettings,
userSettings: {} as Partial<Record<ChainId, Partial<UserChainSettings>>>,
};

vi.mock('store', () => ({
store: {
use: {
setUserSettings: vi.fn(() => vi.fn()),
userSettings: vi.fn(() => ({
gaslessTransactions: true,
})),
},
},
useStore: vi.fn((selector: (state: typeof mockStoreState) => unknown) =>
selector(mockStoreState),
),
}));

describe('useUserChainSettings', () => {
it('returns correct settings from the store', () => {
(store.use.userSettings as Mock).mockReturnValue({
mockStoreState.userSettings = {
[ChainId.BSC_TESTNET]: {
gaslessTransactions: true,
},
});
};

const {
result: {
Expand All @@ -36,7 +35,7 @@ describe('useUserChainSettings', () => {
});

it('calls setState when updating settings', () => {
(store.use.setUserSettings as Mock).mockReturnValue(vi.fn(() => vi.fn()));
mockSetUserSettings.mockReset();

const {
result: {
Expand All @@ -46,7 +45,7 @@ describe('useUserChainSettings', () => {

setUserChainSettings({ gaslessTransactions: false });

expect(store.use.setUserSettings()).toHaveBeenCalledWith({
expect(mockSetUserSettings).toHaveBeenCalledWith({
settings: {
gaslessTransactions: false,
},
Expand Down
6 changes: 3 additions & 3 deletions apps/evm/src/hooks/useUserChainSettings/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DEFAULT_SLIPPAGE_TOLERANCE_PERCENTAGE } from 'constants/swap';
import { useAccountAddress, useChainId } from 'libs/wallet';
import { type State, type UserChainSettings, store } from 'store';
import { type State, type UserChainSettings, useStore } from 'store';

export const defaultUserChainSettings: UserChainSettings = {
gaslessTransactions: false,
Expand All @@ -17,14 +17,14 @@ export const useUserChainSettings = () => {
const { chainId } = useChainId();
const { accountAddress } = useAccountAddress();

const userSettings = store.use.userSettings();
const userSettings = useStore(state => state.userSettings);
const userChainSettings: UserChainSettings = {
...defaultUserChainSettings,
...userSettings[chainId],
showUserAssetsOnly: !!accountAddress && !!userSettings[chainId]?.showUserAssetsOnly,
};

const setUserSettings = store.use.setUserSettings();
const setUserSettings = useStore(state => state.setUserSettings);

const setUserChainSettings = (input: Parameters<State['setUserSettings']>[0]['settings']) =>
setUserSettings({
Expand Down
7 changes: 6 additions & 1 deletion apps/evm/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import App from 'App';
// biome-ignore lint/style/useNodejsImportProtocol: Vite browser client must resolve the npm buffer polyfill instead of Node's builtin module
import { Buffer } from 'buffer';
import { createRoot } from 'react-dom/client';

import 'assets/styles/index.css';

import App from 'App';
import initializeLibraries from './initializeLibraries';

// Some wallet SDK dependencies still expect Buffer on the browser global.
globalThis.Buffer ??= Buffer;
Comment thread
therealemjy marked this conversation as resolved.

initializeLibraries();

const container = document.getElementById('root');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { renderComponent } from 'testUtils/render';

import { store } from 'libs/notifications/store';
import { useStore } from 'libs/notifications/store';

import NotificationCenter from '..';
import { notifications as fakeNotifications } from '../../__mocks__/models/notifications';
Expand All @@ -13,7 +13,7 @@ describe('NotificationCenter', () => {

it('renders notifications correctly', () => {
// Add fake notifications to the store
store.setState({
useStore.setState({
notifications: fakeNotifications,
});

Expand Down
4 changes: 2 additions & 2 deletions apps/evm/src/libs/notifications/NotificationCenter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import { createPortal } from 'react-dom';

import { Notice } from 'components/Notice';

import { store } from '../store';
import { useStore } from '../store';
import TEST_IDS from './testIds';

const ANIMATION_BASE_DURATION_S = 0.75;
const EASE = [0.23, 1, 0.32, 1];

const NotificationCenter: React.FC = () => {
const notifications = store.use.notifications();
const notifications = useStore(state => state.notifications);

return createPortal(
<ul
Expand Down
Loading
Loading