Skip to content

Commit 5cd5850

Browse files
authoredMar 20, 2025··
Merge pull request #29 from hyperweb-io/vite-react
Vite react
2 parents 3bc792b + e3f8626 commit 5cd5850

29 files changed

+26545
-21217
lines changed
 

‎examples/injective-vue/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@
3131
"vite": "^6.0.0",
3232
"vue-tsc": "^2.1.10"
3333
}
34-
}
34+
}

‎examples/stake-tokens/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,4 @@
4444
"typescript": "^5.5.4"
4545
},
4646
"packageManager": "yarn@4.3.0"
47-
}
47+
}

‎examples/vite-react/.gitignore

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
19+
.DS_Store
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?

‎examples/vite-react/README.md

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
This is an Interchain App project bootstrapped with [`create-interchain-app`](https://github.com/hyperweb-io/create-interchain-app).
2+
3+
## Getting Started
4+
5+
First, install the packages and run the development server:
6+
7+
```bash
8+
yarn && yarn dev
9+
```
10+
11+
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
12+
13+
You can start editing the page by modifying `src/App.tsx`. The page auto-updates as you edit the file.
14+
15+
## Interchain JavaScript Stack
16+
17+
A unified toolkit for building applications and smart contracts in the Interchain ecosystem ⚛️
18+
19+
| Category | Tools | Description |
20+
|----------------------|------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------|
21+
| **Chain Information** | [**Chain Registry**](https://github.com/hyperweb-io/chain-registry), [**Utils**](https://www.npmjs.com/package/@chain-registry/utils), [**Client**](https://www.npmjs.com/package/@chain-registry/client) | Everything from token symbols, logos, and IBC denominations for all assets you want to support in your application. |
22+
| **Wallet Connectors**| [**Interchain Kit**](https://github.com/hyperweb-io/interchain-kit)<sup>beta</sup>, [**Cosmos Kit**](https://github.com/hyperweb.io/cosmos-kit) | Experience the convenience of connecting with a variety of web3 wallets through a single, streamlined interface. |
23+
| **Signing Clients** | [**InterchainJS**](https://github.com/hyperweb-io/interchainjs)<sup>beta</sup>, [**CosmJS**](https://github.com/cosmos/cosmjs) | A single, universal signing interface for any network |
24+
| **SDK Clients** | [**Telescope**](https://github.com/hyperweb.io/telescope) | Your Frontend Companion for Building with TypeScript with Cosmos SDK Modules. |
25+
| **Starter Kits** | [**Create Interchain App**](https://github.com/hyperweb-io/create-interchain-app)<sup>beta</sup>, [**Create Cosmos App**](https://github.com/hyperweb.io/create-cosmos-app) | Set up a modern Interchain app by running one command. |
26+
| **UI Kits** | [**Interchain UI**](https://github.com/hyperweb.io/interchain-ui) | The Interchain Design System, empowering developers with a flexible, easy-to-use UI kit. |
27+
| **Testing Frameworks** | [**Starship**](https://github.com/hyperweb.io/starship) | Unified Testing and Development for the Interchain. |
28+
| **TypeScript Smart Contracts** | [**Create Hyperweb App**](https://github.com/hyperweb-io/create-hyperweb-app) | Build and deploy full-stack blockchain applications with TypeScript |
29+
| **CosmWasm Contracts** | [**CosmWasm TS Codegen**](https://github.com/CosmWasm/ts-codegen) | Convert your CosmWasm smart contracts into dev-friendly TypeScript classes. |
30+
31+
## Credits
32+
33+
🛠 Built by Hyperweb (formerly Cosmology) — if you like our tools, please checkout and contribute to [our github ⚛️](https://github.com/hyperweb-io)
34+
35+
## Disclaimer
36+
37+
AS DESCRIBED IN THE LICENSES, THE SOFTWARE IS PROVIDED “AS IS”, AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND.
38+
39+
No developer or entity involved in creating this software will be liable for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of the code, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.

‎examples/vite-react/eslint.config.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import js from '@eslint/js'
2+
import globals from 'globals'
3+
import reactHooks from 'eslint-plugin-react-hooks'
4+
import reactRefresh from 'eslint-plugin-react-refresh'
5+
import tseslint from 'typescript-eslint'
6+
7+
export default tseslint.config(
8+
{ ignores: ['dist'] },
9+
{
10+
extends: [js.configs.recommended, ...tseslint.configs.recommended],
11+
files: ['**/*.{ts,tsx}'],
12+
languageOptions: {
13+
ecmaVersion: 2020,
14+
globals: globals.browser,
15+
},
16+
plugins: {
17+
'react-hooks': reactHooks,
18+
'react-refresh': reactRefresh,
19+
},
20+
rules: {
21+
...reactHooks.configs.recommended.rules,
22+
'react-refresh/only-export-components': [
23+
'warn',
24+
{ allowConstantExport: true },
25+
],
26+
},
27+
},
28+
)

‎examples/vite-react/index.html

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Vite + React + TS</title>
8+
</head>
9+
<body>
10+
<div id="root"></div>
11+
<script type="module" src="/src/main.tsx"></script>
12+
</body>
13+
</html>

‎examples/vite-react/package.json

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"name": "@hyperweb/vite-react",
3+
"private": true,
4+
"version": "1.0.0",
5+
"scripts": {
6+
"dev": "vite",
7+
"build": "tsc -b && vite build",
8+
"lint": "eslint .",
9+
"preview": "vite preview"
10+
},
11+
"dependencies": {
12+
"@chain-registry/v2": "^1.71.71",
13+
"@chakra-ui/icons": "^2.1.1",
14+
"@chakra-ui/react": "^2.8.2",
15+
"@emotion/react": "^11.11.4",
16+
"@emotion/styled": "^11.11.0",
17+
"@hookform/resolvers": "^3.3.4",
18+
"@interchain-kit/core": "0.2.206",
19+
"@interchain-kit/keplr-extension": "0.2.206",
20+
"@tanstack/react-query": "5.68.0",
21+
"buffer": "^6.0.3",
22+
"framer-motion": "^11.0.8",
23+
"react": "^18.3.1",
24+
"react-dom": "^18.3.1",
25+
"react-hook-form": "^7.51.0",
26+
"zod": "^3.22.4"
27+
},
28+
"devDependencies": {
29+
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
30+
"@eslint/js": "^9.9.1",
31+
"@types/react": "^18.3.5",
32+
"@types/react-dom": "^18.3.0",
33+
"@vitejs/plugin-react": "^4.3.1",
34+
"eslint": "^9.9.1",
35+
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
36+
"eslint-plugin-react-refresh": "^0.4.11",
37+
"globals": "^15.9.0",
38+
"typescript": "^5.5.3",
39+
"typescript-eslint": "^8.3.0",
40+
"vite": "^5.4.2"
41+
},
42+
"packageManager": "yarn@4.3.0"
43+
}

‎examples/vite-react/public/vite.svg

+1
Loading

‎examples/vite-react/src/App.css

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#root {
2+
max-width: 1280px;
3+
margin: 0 auto;
4+
padding: 2rem;
5+
text-align: center;
6+
}
7+
8+
.logo {
9+
height: 6em;
10+
padding: 1.5em;
11+
will-change: filter;
12+
transition: filter 300ms;
13+
}
14+
.logo:hover {
15+
filter: drop-shadow(0 0 2em #646cffaa);
16+
}
17+
.logo.react:hover {
18+
filter: drop-shadow(0 0 2em #61dafbaa);
19+
}
20+
21+
@keyframes logo-spin {
22+
from {
23+
transform: rotate(0deg);
24+
}
25+
to {
26+
transform: rotate(360deg);
27+
}
28+
}
29+
30+
@media (prefers-reduced-motion: no-preference) {
31+
a:nth-of-type(2) .logo {
32+
animation: logo-spin infinite 20s linear;
33+
}
34+
}
35+
36+
.card {
37+
padding: 2em;
38+
}
39+
40+
.read-the-docs {
41+
color: #888;
42+
}

‎examples/vite-react/src/App.tsx

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { useEffect } from 'react';
2+
import {
3+
Box,
4+
Button,
5+
Container,
6+
VStack,
7+
useColorMode,
8+
IconButton,
9+
Heading,
10+
Card,
11+
CardBody,
12+
} from '@chakra-ui/react';
13+
import { SunIcon, MoonIcon } from '@chakra-ui/icons';
14+
import { useForm } from 'react-hook-form';
15+
import { zodResolver } from '@hookform/resolvers/zod';
16+
import WalletDetails from './components/WalletDetails';
17+
import TransferForm from './components/TransferForm';
18+
import { transferFormSchema, type TransferFormData } from './utils/validation';
19+
import { useWalletManager } from './hooks/useWalletManager';
20+
import { useBalance } from './hooks/useBalance';
21+
import { useTransfer } from './hooks/useTransfer';
22+
23+
function App() {
24+
const { colorMode, toggleColorMode } = useColorMode();
25+
const { walletManager, address, connectWallet } = useWalletManager();
26+
const { balance, refetchBalance } = useBalance(address, walletManager);
27+
const transferMutation = useTransfer(address, walletManager, refetchBalance);
28+
29+
const { register, handleSubmit, formState: { errors }, reset } = useForm<TransferFormData>({
30+
resolver: zodResolver(transferFormSchema),
31+
defaultValues: { amount: '0.000001' },
32+
});
33+
34+
const onSubmit = (data: TransferFormData) => {
35+
if (!balance || Number(data.amount) > balance) {
36+
return;
37+
}
38+
transferMutation.mutate(data);
39+
reset();
40+
};
41+
42+
useEffect(() => {
43+
if (walletManager) {
44+
connectWallet();
45+
}
46+
}, [walletManager, connectWallet]);
47+
48+
return (
49+
<Container maxW="container.sm" py={8}>
50+
<VStack spacing={6} align="stretch">
51+
<Box display="flex" justifyContent="flex-end">
52+
<IconButton
53+
aria-label="Toggle color mode"
54+
icon={colorMode === 'light' ? <MoonIcon /> : <SunIcon />}
55+
onClick={toggleColorMode}
56+
/>
57+
</Box>
58+
<Card>
59+
<CardBody>
60+
<VStack spacing={4} align="stretch">
61+
<Heading size="md">Cosmos Wallet</Heading>
62+
{!address ? (
63+
<Button onClick={connectWallet}>Connect Keplr</Button>
64+
) : (
65+
<>
66+
<WalletDetails
67+
address={address}
68+
balance={balance ?? '0'}
69+
onRefresh={refetchBalance}
70+
/>
71+
<TransferForm
72+
register={register}
73+
errors={errors}
74+
handleSubmit={handleSubmit}
75+
onSubmit={onSubmit}
76+
isLoading={transferMutation.isMutating}
77+
/>
78+
</>
79+
)}
80+
</VStack>
81+
</CardBody>
82+
</Card>
83+
</VStack>
84+
</Container>
85+
);
86+
}
87+
88+
export default App;
+1
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { FormControl, FormLabel, Input, Text, VStack, Button } from '@chakra-ui/react';
2+
import { DENOM_DISPLAY } from '../utils/constants';
3+
import { TransferFormData } from '../utils/validation';
4+
5+
interface TransferFormProps {
6+
register: ReturnType<any>;
7+
errors: any;
8+
handleSubmit: (fn: (data: TransferFormData) => void) => (e?: React.BaseSyntheticEvent) => Promise<void>;
9+
onSubmit: (data: TransferFormData) => void;
10+
isLoading: boolean;
11+
}
12+
13+
const TransferForm = ({ register, errors, handleSubmit, onSubmit, isLoading }: TransferFormProps) => {
14+
return (
15+
<form onSubmit={handleSubmit(onSubmit)}>
16+
<VStack spacing={4}>
17+
<FormControl isInvalid={!!errors.recipient}>
18+
<FormLabel>Recipient Address</FormLabel>
19+
<Input {...register('recipient')} />
20+
{errors.recipient && <Text color="red.500">{errors.recipient.message}</Text>}
21+
</FormControl>
22+
<FormControl isInvalid={!!errors.amount}>
23+
<FormLabel>Amount ({DENOM_DISPLAY})</FormLabel>
24+
<Input {...register('amount')} type="number" step="0.000001" />
25+
{errors.amount && <Text color="red.500">{errors.amount.message}</Text>}
26+
</FormControl>
27+
<Button type="submit" colorScheme="blue" isLoading={isLoading} width="100%">
28+
Transfer
29+
</Button>
30+
</VStack>
31+
</form>
32+
);
33+
};
34+
35+
export default TransferForm;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { Box, Text, HStack, IconButton } from '@chakra-ui/react';
2+
import { RepeatIcon } from '@chakra-ui/icons';
3+
import { DENOM_DISPLAY } from '../utils/constants';
4+
5+
interface WalletDetailsProps {
6+
address: string;
7+
balance: number | string;
8+
onRefresh: () => void;
9+
}
10+
11+
const WalletDetails = ({ address, balance, onRefresh }: WalletDetailsProps) => {
12+
return (
13+
<Box>
14+
<Text>Address: {address}</Text>
15+
<HStack>
16+
<Text>
17+
Balance: {balance ?? '0'} {DENOM_DISPLAY}
18+
</Text>
19+
<IconButton
20+
aria-label="Refresh balance"
21+
icon={<RepeatIcon />}
22+
size="sm"
23+
onClick={onRefresh}
24+
/>
25+
</HStack>
26+
</Box>
27+
);
28+
};
29+
30+
export default WalletDetails;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { useQuery } from '@tanstack/react-query';
2+
import { useToast } from '@chakra-ui/react';
3+
import { createGetBalance } from 'interchainjs/cosmos/bank/v1beta1/query.rpc.func';
4+
import { DENOM, DECIMAL, RPC_ENDPOINT } from '../utils/constants';
5+
6+
export const useBalance = (address: string, walletManager: any) => {
7+
const toast = useToast();
8+
const { data, refetch } = useQuery({
9+
queryKey: ['balance', address],
10+
queryFn: async () => {
11+
if (!address) return null;
12+
try {
13+
const balanceQuery = createGetBalance(RPC_ENDPOINT);
14+
const { balance: atomBalance } = await balanceQuery({
15+
address,
16+
denom: DENOM,
17+
});
18+
return Number(atomBalance?.amount || 0) / Math.pow(10, DECIMAL);
19+
} catch (error) {
20+
console.error('Error fetching balance:', error);
21+
toast({
22+
title: 'Error fetching balance',
23+
description: (error as Error).message,
24+
status: 'error',
25+
duration: 5000,
26+
isClosable: true,
27+
});
28+
return null;
29+
}
30+
},
31+
enabled: !!address && !!walletManager,
32+
staleTime: 10000,
33+
refetchInterval: 30000,
34+
});
35+
36+
return { balance: data, refetchBalance: refetch };
37+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { useMutation } from '@tanstack/react-query';
2+
import { useToast, Link } from '@chakra-ui/react';
3+
import { createSend } from 'interchainjs/cosmos/bank/v1beta1/tx.rpc.func';
4+
import { DENOM, DECIMAL } from '../utils/constants';
5+
import { keplrWallet } from '@interchain-kit/keplr-extension';
6+
import { chain as cosmoshubChain } from '@chain-registry/v2/mainnet/cosmoshub';
7+
8+
export const useTransfer = (address: string, walletManager: any, refetchBalance: () => void) => {
9+
const toast = useToast();
10+
11+
const transferMutation = useMutation({
12+
mutationFn: async (data: { recipient: string; amount: string }) => {
13+
if (!window.keplr || !address) throw new Error('Keplr not connected');
14+
const amount = Math.floor(Number(data.amount) * Math.pow(10, DECIMAL));
15+
const fee = {
16+
amount: [{ denom: DENOM, amount: '5000' }],
17+
gas: '200000',
18+
};
19+
20+
const message = {
21+
fromAddress: address,
22+
toAddress: data.recipient,
23+
amount: [
24+
{
25+
denom: DENOM,
26+
amount: amount.toString(),
27+
},
28+
],
29+
};
30+
31+
const signingClient = await walletManager?.getSigningClient(
32+
keplrWallet.info?.name as string,
33+
cosmoshubChain.chainName
34+
);
35+
const txSend = createSend(signingClient);
36+
const res = await txSend(address, message, fee, '');
37+
// 等待链上确认
38+
await new Promise((resolve) => setTimeout(resolve, 6000));
39+
return (res as any).hash;
40+
},
41+
onSuccess: (txHash) => {
42+
toast({
43+
title: 'Transfer successful',
44+
description: (
45+
<Link
46+
href={`https://www.mintscan.io/cosmos/txs/${txHash}`}
47+
isExternal
48+
color="white"
49+
>
50+
<u>View transaction details</u>
51+
</Link>
52+
),
53+
status: 'success',
54+
duration: null,
55+
isClosable: true,
56+
});
57+
refetchBalance();
58+
},
59+
onError: (error: Error) => {
60+
console.error('Error transferring funds:', error);
61+
toast({
62+
title: 'Transfer failed',
63+
description: error.message,
64+
status: 'error',
65+
duration: 5000,
66+
isClosable: true,
67+
});
68+
},
69+
});
70+
71+
return { ...transferMutation, isMutating: transferMutation.status === 'pending' };
72+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { useState, useEffect, useCallback } from 'react';
2+
import { useToast } from '@chakra-ui/react';
3+
import { WalletManager } from '@interchain-kit/core';
4+
import { keplrWallet } from '@interchain-kit/keplr-extension';
5+
import { chain as cosmoshubChain, assetList as cosmoshubAssetList } from '@chain-registry/v2/mainnet/cosmoshub';
6+
import { RPC_ENDPOINT } from '../utils/constants';
7+
8+
export const useWalletManager = () => {
9+
const [walletManager, setWalletManager] = useState<WalletManager | null>(null);
10+
const [address, setAddress] = useState<string>('');
11+
const toast = useToast();
12+
13+
useEffect(() => {
14+
(async () => {
15+
try {
16+
const manager = await WalletManager.create(
17+
[cosmoshubChain],
18+
[cosmoshubAssetList],
19+
[keplrWallet],
20+
{},
21+
{
22+
endpoints: {
23+
cosmoshub: {
24+
rpc: [RPC_ENDPOINT],
25+
},
26+
},
27+
}
28+
);
29+
setWalletManager(manager);
30+
} catch (error) {
31+
console.error('Error initializing wallet manager:', error);
32+
toast({
33+
title: 'Wallet initialization failed',
34+
description: (error as Error).message,
35+
status: 'error',
36+
duration: 5000,
37+
isClosable: true,
38+
});
39+
}
40+
})();
41+
}, [toast]);
42+
43+
const connectWallet = useCallback(async () => {
44+
try {
45+
if (!window.keplr) {
46+
throw new Error('Please install Keplr extension');
47+
}
48+
await walletManager?.connect(keplrWallet.info?.name as string, cosmoshubChain.chainName);
49+
const account = await walletManager?.getAccount(
50+
keplrWallet.info?.name as string,
51+
cosmoshubChain.chainName
52+
);
53+
setAddress(account?.address as string);
54+
} catch (error) {
55+
console.error('Error connecting wallet:', error);
56+
toast({
57+
title: 'Connection failed',
58+
description: (error as Error).message,
59+
status: 'error',
60+
duration: 5000,
61+
isClosable: true,
62+
});
63+
}
64+
}, [walletManager, toast]);
65+
66+
return { walletManager, address, connectWallet };
67+
};

‎examples/vite-react/src/index.css

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
:root {
2+
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
3+
line-height: 1.5;
4+
font-weight: 400;
5+
6+
color-scheme: light dark;
7+
color: rgba(255, 255, 255, 0.87);
8+
background-color: #242424;
9+
10+
font-synthesis: none;
11+
text-rendering: optimizeLegibility;
12+
-webkit-font-smoothing: antialiased;
13+
-moz-osx-font-smoothing: grayscale;
14+
}
15+
16+
a {
17+
font-weight: 500;
18+
color: #646cff;
19+
text-decoration: inherit;
20+
}
21+
a:hover {
22+
color: #535bf2;
23+
}
24+
25+
body {
26+
margin: 0;
27+
display: flex;
28+
place-items: center;
29+
min-width: 320px;
30+
min-height: 100vh;
31+
}
32+
33+
h1 {
34+
font-size: 3.2em;
35+
line-height: 1.1;
36+
}
37+
38+
button {
39+
border-radius: 8px;
40+
border: 1px solid transparent;
41+
padding: 0.6em 1.2em;
42+
font-size: 1em;
43+
font-weight: 500;
44+
font-family: inherit;
45+
background-color: #1a1a1a;
46+
cursor: pointer;
47+
transition: border-color 0.25s;
48+
}
49+
button:hover {
50+
border-color: #646cff;
51+
}
52+
button:focus,
53+
button:focus-visible {
54+
outline: 4px auto -webkit-focus-ring-color;
55+
}
56+
57+
@media (prefers-color-scheme: light) {
58+
:root {
59+
color: #213547;
60+
background-color: #ffffff;
61+
}
62+
a:hover {
63+
color: #747bff;
64+
}
65+
button {
66+
background-color: #f9f9f9;
67+
}
68+
}

‎examples/vite-react/src/main.tsx

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { StrictMode } from 'react'
2+
import { createRoot } from 'react-dom/client'
3+
import { ChakraProvider, ColorModeScript } from '@chakra-ui/react'
4+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
5+
import App from './App.tsx'
6+
import theme from './theme'
7+
8+
const queryClient = new QueryClient()
9+
10+
createRoot(document.getElementById('root')!).render(
11+
<StrictMode>
12+
<QueryClientProvider client={queryClient}>
13+
<ChakraProvider theme={theme}>
14+
<ColorModeScript initialColorMode={theme.config.initialColorMode} />
15+
<App />
16+
</ChakraProvider>
17+
</QueryClientProvider>
18+
</StrictMode>,
19+
)

‎examples/vite-react/src/theme.ts

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { extendTheme, type ThemeConfig } from '@chakra-ui/react'
2+
3+
const config: ThemeConfig = {
4+
initialColorMode: 'system',
5+
useSystemColorMode: true,
6+
}
7+
8+
const theme = extendTheme({ config })
9+
10+
export default theme
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
declare interface Window {
2+
keplr: any;
3+
getOfflineSigner: any;
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export const CHAIN_ID = 'cosmoshub-4';
2+
export const RPC_ENDPOINT = 'https://cosmos-rpc.publicnode.com';
3+
export const REST_ENDPOINT = 'https://cosmos-rest.publicnode.com';
4+
export const DENOM = 'uatom';
5+
export const DENOM_DISPLAY = 'ATOM';
6+
export const DECIMAL = 6;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { z } from 'zod';
2+
3+
export const transferFormSchema = z.object({
4+
recipient: z.string().regex(/^cosmos[0-9a-z]{39}$/, 'Invalid Cosmos address'),
5+
amount: z.string().refine((val) => !isNaN(Number(val)) && Number(val) > 0, {
6+
message: 'Amount must be a positive number',
7+
}),
8+
});
9+
10+
export type TransferFormData = z.infer<typeof transferFormSchema>;

‎examples/vite-react/src/vite-env.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/// <reference types="vite/client" />

‎examples/vite-react/tsconfig.app.json

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2020",
4+
"useDefineForClassFields": true,
5+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
6+
"module": "ESNext",
7+
"skipLibCheck": true,
8+
9+
/* Bundler mode */
10+
"moduleResolution": "bundler",
11+
"allowImportingTsExtensions": true,
12+
"isolatedModules": true,
13+
"moduleDetection": "force",
14+
"noEmit": true,
15+
"jsx": "react-jsx",
16+
17+
/* Linting */
18+
"strict": true,
19+
"noUnusedLocals": true,
20+
"noUnusedParameters": true,
21+
"noFallthroughCasesInSwitch": true
22+
},
23+
"include": ["src"]
24+
}

‎examples/vite-react/tsconfig.json

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"files": [],
3+
"references": [
4+
{ "path": "./tsconfig.app.json" },
5+
{ "path": "./tsconfig.node.json" }
6+
]
7+
}
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2022",
4+
"lib": ["ES2023"],
5+
"module": "ESNext",
6+
"skipLibCheck": true,
7+
8+
/* Bundler mode */
9+
"moduleResolution": "bundler",
10+
"allowImportingTsExtensions": true,
11+
"isolatedModules": true,
12+
"moduleDetection": "force",
13+
"noEmit": true,
14+
15+
/* Linting */
16+
"strict": true,
17+
"noUnusedLocals": true,
18+
"noUnusedParameters": true,
19+
"noFallthroughCasesInSwitch": true
20+
},
21+
"include": ["vite.config.ts"]
22+
}

‎examples/vite-react/vite.config.ts

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { defineConfig } from 'vite'
2+
import react from '@vitejs/plugin-react'
3+
import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill';
4+
5+
// https://vitejs.dev/config/
6+
export default defineConfig({
7+
plugins: [react()],
8+
optimizeDeps: {
9+
esbuildOptions: {
10+
define: {
11+
global: 'globalThis'
12+
},
13+
plugins: [
14+
NodeGlobalsPolyfillPlugin({
15+
buffer: true,
16+
})
17+
]
18+
}
19+
},
20+
resolve: {
21+
alias: {
22+
buffer: 'buffer'
23+
}
24+
}
25+
})

‎examples/vote-proposal/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,4 @@
5050
"typescript": "^5.1.6"
5151
},
5252
"packageManager": "yarn@4.3.0"
53-
}
53+
}

‎yarn.lock

+25,826-21,214
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.