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
10 changes: 9 additions & 1 deletion packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
"test": "tsc --noEmit"
},
"dependencies": {
"@chakra-ui/react": "^2.8.2",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@fontsource/ibm-plex-mono": "^5.0.13",
"@latticexyz/common": "2.0.11",
"@latticexyz/dev-tools": "2.0.11",
"@latticexyz/react": "2.0.11",
Expand All @@ -21,11 +25,15 @@
"@latticexyz/store-sync": "2.0.11",
"@latticexyz/utils": "2.0.11",
"@latticexyz/world": "2.0.11",
"@rainbow-me/rainbowkit": "^2.1.1",
"@tanstack/react-query": "^5.37.1",
"contracts": "workspace:*",
"framer-motion": "^11.2.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"rxjs": "7.5.5",
"viem": "2.9.20"
"viem": "2.9.20",
"wagmi": "^2.9.6"
},
"devDependencies": {
"@types/react": "18.2.22",
Expand Down
30 changes: 2 additions & 28 deletions packages/client/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,5 @@
import { useComponentValue } from '@latticexyz/react';
import { singletonEntity } from '@latticexyz/store-sync/recs';

import { useMUD } from './MUDContext';
import { Welcome } from './components/Welcome';

export const App = (): JSX.Element => {
const {
components: { Counter },
systemCalls: { increment },
} = useMUD();

const counter = useComponentValue(Counter, singletonEntity);

return (
<>
<div>
Counter: <span>{counter?.value ?? '??'}</span>
</div>
<button
type="button"
onClick={async event => {
event.preventDefault();
// eslint-disable-next-line no-console
console.log('new counter value:', await increment());
}}
>
Increment
</button>
</>
);
return <Welcome />;
};
58 changes: 58 additions & 0 deletions packages/client/src/components/ConnectWalletButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Button, Flex, HStack, Text } from '@chakra-ui/react';
import { ConnectButton } from '@rainbow-me/rainbowkit';

export const ConnectWalletButton: React.FC = () => {
return (
<ConnectButton.Custom>
{({
account,
chain,
openAccountModal,
openChainModal,
openConnectModal,
mounted,
}) => {
const connected = mounted && account && chain;

return (
<Flex
{...(!mounted && {
'aria-hidden': true,
style: {
opacity: 0,
pointerEvents: 'none',
userSelect: 'none',
},
})}
>
{(() => {
if (!connected) {
return (
<Button onClick={openConnectModal} type="button">
Connect
</Button>
);
}

if (chain.unsupported) {
return (
<Button onClick={openChainModal} type="button">
Wrong Network
</Button>
);
}

return (
<Button onClick={openAccountModal} type="button">
<HStack>
<Text>{account.displayName}</Text>
</HStack>
</Button>
);
})()}
</Flex>
);
}}
</ConnectButton.Custom>
);
};
36 changes: 36 additions & 0 deletions packages/client/src/components/ConnectWalletModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalHeader,
ModalOverlay,
Text,
VStack,
} from '@chakra-ui/react';

import { ConnectWalletButton } from './ConnectWalletButton';

export const ConnectWalletModal = ({
isOpen,
onClose,
}: {
isOpen: boolean;
onClose: () => void;
}): JSX.Element => {
return (
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Connect Wallet</ModalHeader>
<ModalCloseButton />
<ModalBody>
<VStack p={10} spacing={10}>
<Text textAlign="center">Connect your wallet to play.</Text>
<ConnectWalletButton />
</VStack>
</ModalBody>
</ModalContent>
</Modal>
);
};
51 changes: 51 additions & 0 deletions packages/client/src/components/Welcome.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import {
Button,
Container,
Heading,
Text,
useDisclosure,
VStack,
} from '@chakra-ui/react';

import { ConnectWalletModal } from './ConnectWalletModal';

export const Welcome = (): JSX.Element => {
const { isOpen, onOpen, onClose } = useDisclosure();

return (
<Container maxW="800px">
<VStack
justifyContent="center"
mb={10}
mt={{ base: 20, sm: 32 }}
spacing={{ base: 12, sm: 20 }}
>
<Heading px={4} textAlign="center">
Welcome to Ultimate Dominion
</Heading>
<VStack spacing={6} textAlign="center">
<Text size={{ base: 'xs', sm: 'sm', md: 'md' }}>
As you awaken, your eyes flutter open to the stark, eerie ambiance
of a dimly lit cave. Confusion clouds your mind; the cold, hard
ground beneath you offers no comfort. Glimpses of blood and bruises
on your body only deepen the mystery, painting a silent story of
unseen struggles.
</Text>
<Text size={{ base: 'xs', sm: 'sm', md: 'md' }}>
Where are you? How did you end up here?
</Text>
<Text size={{ base: 'xs', sm: 'sm', md: 'md' }}>
The shadows around you hold secrets, whispering tales of survival
and discovery. Gathering your strength, you rise, the weight of
uncertainty heavy on your shoulders yet igniting a spark of
determination within. With a deep breath, you take your first step
into the unknown, embarking on a journey where every choice carves
your path through the darkness.
</Text>
</VStack>
<Button onClick={onOpen}>Play</Button>
</VStack>
<ConnectWalletModal isOpen={isOpen} onClose={onClose} />
</Container>
);
};
48 changes: 48 additions & 0 deletions packages/client/src/contexts/Web3Provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use client';

import {
connectorsForWallets,
darkTheme,
getDefaultWallets,
RainbowKitProvider,
} from '@rainbow-me/rainbowkit';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { createConfig, http, WagmiProvider } from 'wagmi';

import {
SUPPORTED_CHAINS,
WALLET_CONNECT_PROJECT_ID,
} from '../lib/web3/constants';

const { wallets } = getDefaultWallets();

const connectors = connectorsForWallets(wallets, {
appName: 'Ultimate Dominion',
projectId: WALLET_CONNECT_PROJECT_ID,
});

const transports = Object.fromEntries(
SUPPORTED_CHAINS.map(chain => {
return [chain.id, http()];
}),
);

const wagmiConfig = createConfig({
chains: SUPPORTED_CHAINS,
connectors,
transports,
});

const queryClient = new QueryClient();

export const Web3Provider: React.FC<React.PropsWithChildren> = ({
children,
}) => {
return (
<WagmiProvider config={wagmiConfig}>
<QueryClientProvider client={queryClient}>
<RainbowKitProvider theme={darkTheme()}>{children}</RainbowKitProvider>
</QueryClientProvider>
</WagmiProvider>
);
};
24 changes: 21 additions & 3 deletions packages/client/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
import '@fontsource/ibm-plex-mono/100.css';
import '@fontsource/ibm-plex-mono/200.css';
import '@fontsource/ibm-plex-mono/300.css';
import '@fontsource/ibm-plex-mono/400.css';
import '@fontsource/ibm-plex-mono/500.css';
import '@fontsource/ibm-plex-mono/600.css';
import '@fontsource/ibm-plex-mono/700.css';
import '@rainbow-me/rainbowkit/styles.css';

import { ChakraProvider } from '@chakra-ui/react';
import { Global } from '@emotion/react';
import mudConfig from 'contracts/mud.config';
import { createRoot } from 'react-dom/client';

import { App } from './App';
import { Web3Provider } from './contexts/Web3Provider';
import { setup } from './mud/setup';
import { MUDProvider } from './MUDContext';
import { globalStyles, theme } from './utils/theme';

const rootElement = document.getElementById('react-root');
if (!rootElement) throw new Error('React root not found');
Expand All @@ -12,9 +25,14 @@ const root = createRoot(rootElement);
// TODO: figure out if we actually want this to be async or if we should render something else in the meantime
setup().then(async result => {
root.render(
<MUDProvider value={result}>
<App />
</MUDProvider>,
<ChakraProvider resetCSS theme={theme}>
<Global styles={globalStyles} />
<Web3Provider>
<MUDProvider value={result}>
<App />
</MUDProvider>
</Web3Provider>
</ChakraProvider>,
);

// https://vitejs.dev/guide/env-and-mode.html
Expand Down
23 changes: 23 additions & 0 deletions packages/client/src/lib/web3/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { anvil, baseSepolia, Chain } from 'wagmi/chains';

export const WALLET_CONNECT_PROJECT_ID = import.meta.env
.VITE_WALLET_CONNECT_PROJECT_ID;

const getSupportedChains = () => {
if (import.meta.env.DEV) {
return [anvil] as const;
}

return [baseSepolia] as const;
};

export const SUPPORTED_CHAINS: readonly [Chain, ...Chain[]] =
getSupportedChains();

const validateConfig = () => {
if (!WALLET_CONNECT_PROJECT_ID) {
throw new Error('VITE_WALLET_CONNECT_PROJECT_ID is not set');
}
};

validateConfig();
Loading