forked from viction-developers/wallet-kit
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
3,534 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"name": "wallet-kit", | ||
"version": "1.0.0", | ||
"description": "", | ||
"main": "index.js", | ||
"scripts": { | ||
"start": "webpack serve --mode development", | ||
"build": "webpack --mode production" | ||
}, | ||
"keywords": [], | ||
"author": "", | ||
"license": "ISC", | ||
"dependencies": { | ||
"@emotion/react": "^11.13.0", | ||
"@emotion/styled": "^11.13.0", | ||
"@types/react": "^18.3.3", | ||
"@types/react-dom": "^18.3.0", | ||
"framer-motion": "^11.3.8", | ||
"react": "^18.3.1", | ||
"react-dom": "^18.3.1", | ||
"react-modal": "^3.16.1", | ||
"typescript": "^5.5.3", | ||
"viem": "^2.17.9" | ||
}, | ||
"devDependencies": { | ||
"@types/react-modal": "^3.16.3", | ||
"html-webpack-plugin": "^5.6.0", | ||
"ts-loader": "^9.2.3", | ||
"webpack": "^5.51.1", | ||
"webpack-cli": "^4.8.0", | ||
"webpack-dev-server": "^4.0.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// src/App.tsx | ||
import React from 'react'; | ||
import ConnectButton from './components/ConnectButton'; | ||
import styled from '@emotion/styled'; | ||
|
||
const Container = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: center; | ||
height: 100vh; | ||
background-color: #f3f4f6; | ||
`; | ||
|
||
const App: React.FC = () => { | ||
return ( | ||
<Container> | ||
<h1>Viction Kit</h1> | ||
<ConnectButton /> | ||
</Container> | ||
); | ||
}; | ||
|
||
export default App; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { createPublicClient, http } from "viem"; | ||
import { Chain } from "viem/chains"; | ||
|
||
const VictionMainnet: Chain = { | ||
id: 88, | ||
name: "Viction Mainnet", | ||
nativeCurrency: { | ||
decimals: 18, | ||
name: "Viction", | ||
symbol: "VIC", | ||
}, | ||
rpcUrls: { | ||
default: { | ||
http: ["https://rpc.viction.xyz"], | ||
webSocket: ["wss://ws.viction.xyz"], | ||
}, | ||
}, | ||
blockExplorers: { | ||
default: { name: "Explorer", url: "https://vicscan.xyz" }, | ||
}, | ||
testnet: true, | ||
}; | ||
|
||
const VictionTestnet: Chain = { | ||
id: 89, | ||
name: "Viction Testnet", | ||
nativeCurrency: { | ||
decimals: 18, | ||
name: "Viction", | ||
symbol: "VIC", | ||
}, | ||
rpcUrls: { | ||
default: { | ||
http: ["https://rpc-testnet.viction.xyz"], | ||
webSocket: ["wss://ws-testnet.viction.xyz"], | ||
}, | ||
}, | ||
blockExplorers: { | ||
default: { name: "Explorer", url: "https://testnet.vicscan.xyz" }, | ||
}, | ||
testnet: true, | ||
}; | ||
|
||
export const networks: any = { | ||
MAINNET: VictionMainnet, | ||
TESTNET: VictionTestnet, | ||
}; | ||
|
||
export const client = createPublicClient({ | ||
chain: VictionMainnet, | ||
transport: http(), | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// src/components/ConnectButton.tsx | ||
import React, { useState } from 'react'; | ||
import MetaMaskConnector from '../connectors/MetaMaskConnector'; | ||
import WalletModal from './WalletModal'; | ||
import styled from '@emotion/styled'; | ||
|
||
const ConnectButtonStyled = styled.button` | ||
padding: 10px 20px; | ||
font-size: 16px; | ||
border: none; | ||
border-radius: 4px; | ||
cursor: pointer; | ||
background-color: #3b82f6; | ||
color: white; | ||
&:hover { | ||
background-color: #2563eb; | ||
} | ||
`; | ||
|
||
const AccountInfo = styled.div` | ||
text-align: center; | ||
p { | ||
margin: 5px 0; | ||
} | ||
`; | ||
|
||
const ErrorMessage = styled.div` | ||
color: red; | ||
margin-top: 10px; | ||
`; | ||
|
||
const ConnectButton: React.FC = () => { | ||
const [account, setAccount] = useState<string | null>(null); | ||
const [balance, setBalance] = useState<string | null>(null); | ||
const [modalIsOpen, setModalIsOpen] = useState<boolean>(false); | ||
const [error, setError] = useState<string | null>(null); | ||
const connector = new MetaMaskConnector(); | ||
|
||
const connectWallet = async () => { | ||
try { | ||
await connector.connect(); | ||
const acc = await connector.getAccount(); | ||
setAccount(acc); | ||
const bal = await connector.getBalance(acc); | ||
setBalance(bal); | ||
closeModal(); | ||
} catch (error: any) { | ||
if (error.message === 'User rejected the request.') { | ||
setError('Connection request was rejected by the user.'); | ||
} else { | ||
setError(error.message); | ||
} | ||
} | ||
}; | ||
|
||
const disconnectWallet = () => { | ||
connector.disconnect(); | ||
setAccount(null); | ||
setBalance(null); | ||
}; | ||
|
||
const openModal = () => { | ||
setError(null); // Clear previous errors | ||
setModalIsOpen(true); | ||
}; | ||
|
||
const closeModal = () => { | ||
setModalIsOpen(false); | ||
}; | ||
|
||
return ( | ||
<div> | ||
{account ? ( | ||
<AccountInfo> | ||
<p>Account: {account}</p> | ||
<p>Balance: {balance} ETH</p> | ||
<ConnectButtonStyled onClick={disconnectWallet}> | ||
Disconnect | ||
</ConnectButtonStyled> | ||
</AccountInfo> | ||
) : ( | ||
<div> | ||
<ConnectButtonStyled onClick={openModal}> | ||
Connect Wallet | ||
</ConnectButtonStyled> | ||
{error && <ErrorMessage>{error}</ErrorMessage>} | ||
</div> | ||
)} | ||
<WalletModal | ||
isOpen={modalIsOpen} | ||
onRequestClose={closeModal} | ||
connectWallet={connectWallet} | ||
/> | ||
</div> | ||
); | ||
}; | ||
|
||
export default ConnectButton; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// src/components/WalletModal.tsx | ||
import React from 'react'; | ||
import Modal from 'react-modal'; | ||
import { motion } from 'framer-motion'; | ||
import styled from '@emotion/styled'; | ||
|
||
const customStyles = { | ||
content: { | ||
top: '50%', | ||
left: '50%', | ||
right: 'auto', | ||
bottom: 'auto', | ||
marginRight: '-50%', | ||
transform: 'translate(-50%, -50%)', | ||
border: 'none', | ||
borderRadius: '8px', | ||
padding: '0', | ||
overflow: 'hidden', | ||
}, | ||
overlay: { | ||
backgroundColor: 'rgba(0, 0, 0, 0.75)', | ||
}, | ||
}; | ||
|
||
const Container = styled.div` | ||
width: 300px; | ||
padding: 20px; | ||
background-color: white; | ||
border-radius: 8px; | ||
`; | ||
|
||
const Header = styled.div` | ||
font-size: 20px; | ||
font-weight: bold; | ||
margin-bottom: 20px; | ||
text-align: center; | ||
`; | ||
|
||
const Button = styled.button` | ||
width: 100%; | ||
padding: 10px; | ||
margin: 5px 0; | ||
font-size: 16px; | ||
border: none; | ||
border-radius: 4px; | ||
cursor: pointer; | ||
background-color: #3b82f6; | ||
color: white; | ||
&:hover { | ||
background-color: #2563eb; | ||
} | ||
`; | ||
|
||
interface WalletModalProps { | ||
isOpen: boolean; | ||
onRequestClose: () => void; | ||
connectWallet: () => void; | ||
} | ||
|
||
const WalletModal: React.FC<WalletModalProps> = ({ | ||
isOpen, | ||
onRequestClose, | ||
connectWallet, | ||
}) => { | ||
return ( | ||
<Modal | ||
isOpen={isOpen} | ||
onRequestClose={onRequestClose} | ||
style={customStyles} | ||
ariaHideApp={false} | ||
> | ||
<motion.div | ||
initial={{ opacity: 0, scale: 0.9 }} | ||
animate={{ opacity: 1, scale: 1 }} | ||
transition={{ duration: 0.3 }} | ||
> | ||
<Container> | ||
<Header>Connect Your Wallet</Header> | ||
<Button onClick={connectWallet}>Connect MetaMask</Button> | ||
<Button onClick={onRequestClose}>Cancel</Button> | ||
</Container> | ||
</motion.div> | ||
</Modal> | ||
); | ||
}; | ||
|
||
export default WalletModal; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import { createPublicClient, createWalletClient, custom, http } from 'viem'; | ||
// src/connectors/MetaMaskConnector.ts | ||
import { formatEther } from 'viem'; | ||
import { networks } from '../chains'; | ||
|
||
interface WalletConnector { | ||
connect(): Promise<void>; | ||
disconnect(): void; | ||
getAccount(): Promise<string>; | ||
getBalance(account: string): Promise<string>; | ||
sendTransaction(tx: any): Promise<any>; | ||
} | ||
|
||
class MetaMaskConnector implements WalletConnector { | ||
private client: any; | ||
private walletClient: any; | ||
|
||
constructor() { | ||
this.client = createPublicClient({ | ||
chain: networks.MAINNET, | ||
transport: http() | ||
}); | ||
this.walletClient = createWalletClient({ | ||
chain: networks.MAINNET, | ||
transport: custom(window.ethereum!) | ||
}) | ||
} | ||
|
||
async connect(): Promise<void> { | ||
if (this.client) { | ||
try { | ||
await this.walletClient.requestAddresses() | ||
} catch (error) { | ||
console.log(`${error}`) | ||
throw new Error('User rejected the request.'); | ||
} | ||
} else { | ||
throw new Error('MetaMask is not installed'); | ||
} | ||
} | ||
|
||
disconnect(): void { | ||
this.client = null; | ||
} | ||
|
||
async getAccount(): Promise<string> { | ||
if (!this.client) { | ||
throw new Error('Wallet not connected'); | ||
} | ||
const accounts = await this.client.request({ method: 'eth_accounts' }); | ||
return accounts[0]; | ||
} | ||
|
||
async getBalance(account: string): Promise<string> { | ||
if (!this.client) { | ||
throw new Error('Wallet not connected'); | ||
} | ||
const balance = await this.client.getBalance({ | ||
address: account, | ||
}) | ||
const balanceAsEther = formatEther(balance) | ||
return formatEther(balance); | ||
} | ||
|
||
async sendTransaction(tx: any): Promise<any> { | ||
if (!this.client) { | ||
throw new Error('Wallet not connected'); | ||
} | ||
return this.client.request({ | ||
method: 'eth_sendTransaction', | ||
params: [tx], | ||
}); | ||
} | ||
} | ||
|
||
export default MetaMaskConnector; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
// src/global.d.ts | ||
interface Window { | ||
ethereum: any; | ||
} |
Oops, something went wrong.