zhereh-frontend

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit a8e1be4d1d31cc05cdc3f9842244b7c4b45fcd13
parent 324ac2cddc9f47552560eae172cf1ff7c17b1379
Author: William Muli <willi.wambu@gmail.com>
Date:   Tue, 20 Jun 2023 15:17:03 +0300

Added switch button

Diffstat:
Msrc/components/Nav.svelte | 44+++++++++++++++++++++++++++++++-------------
Msrc/options/nav-options.ts | 4++--
Msrc/routes/+layout.svelte | 44++++++++++++--------------------------------
Msrc/routes/+page.svelte | 21++++++++++++---------
Asrc/routes/edit-chain/+page.svelte | 8++++++++
Msrc/store.ts | 1+
6 files changed, 66 insertions(+), 56 deletions(-)

diff --git a/src/components/Nav.svelte b/src/components/Nav.svelte @@ -5,12 +5,13 @@ import { publicClient, walletClient } from "../client" import { NavOptions } from "../options/nav-options"; import { reduceAddress } from "../utils/reduce-address" - import { formatEther, formatUnits, getContract, type RequestAddressesReturnType } from "viem" + import { formatEther, formatUnits, getContract, numberToHex, type RequestAddressesReturnType } from "viem" import { erc20TokenAbi } from "../shared/erc20-token-abi" let networkModalOpen: boolean = false let tokenModalOpen: boolean = false let balance: bigint + let connectedChainId: string = '' $: ({ name, symbol, decimals, balance: erc20Balance } = $voteToken) $: ({ isConnected, userAddress } = $connectionDetails) @@ -51,7 +52,9 @@ } const connectWallet = async () => { + if(userAddress) return if (window.ethereum) { + const accounts = await walletClient($configuredChain).requestAddresses() if (accounts.length > 0) { @@ -64,24 +67,31 @@ } } + const updateConnectionDetails = (isConnected: true, accounts: RequestAddressesReturnType) => { + connectionDetails.update((value) => ({ ...value, isConnected , userAddress: accounts[0] })) + } + + const switchNetwork = async () => { + await walletClient($configuredChain).switchChain({ id: $configuredChain.id }) + } + onMount(async () => { if (window.ethereum) { + connectedChainId = numberToHex(await publicClient($configuredChain).getChainId()) + window.ethereum.on('chainChanged', (chainId: string) => { + connectedChainId = chainId + }) const accounts = await walletClient($configuredChain).getAddresses() if (accounts.length > 0) { updateConnectionDetails(true, accounts) - } - } - }) - - const updateConnectionDetails = (isConnected: true, accounts: RequestAddressesReturnType) => { - connectionDetails.update(() => ({ isConnected , userAddress: accounts[0] })) - } - + } + } + }) </script> <nav class="flex items-center justify-between flex-wrap bg-black p-6"> - <div class="flex items-center flex-shrink-0 text-white mr-6"> + <a class="flex items-center flex-shrink-0 text-white mr-6" href="/"> <svg class="fill-current h-8 w-8 mr-2" width="54" @@ -93,7 +103,7 @@ /></svg > <span class="font-semibold text-xl tracking-tight">EVM Token Vote</span> - </div> + </a> <div class="block lg:hidden"> <button class="flex items-center px-3 py-2 border rounded text-white border-teal-400 hover:text-white hover:border-white" @@ -115,6 +125,14 @@ {/each} </div> <div> + {#if connectedChainId !== numberToHex($configuredChain.id)} + <button + class="btn btn-error normal-case" + on:click={switchNetwork} + > + Switch to {$configuredChain.name} + </button>} + {/if} <button class="btn btn-secondary text-white normal-case" on:click={() => tokenModalOpen = true}> {name} Bal: {erc20Balance && decimals && `${formatUnits(erc20Balance, decimals)} ${symbol}`} <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> @@ -133,7 +151,7 @@ class="btn btn-md btn-primary text-white" on:click={connectWallet} > - {isConnected && userAddress ? reduceAddress(userAddress) : 'Connect wallet'} + {$connectionDetails.isConnected && $connectionDetails.userAddress ? reduceAddress($connectionDetails.userAddress) : 'Connect wallet'} </button > </div> @@ -168,7 +186,7 @@ </dialog> <dialog id="networkDetails" class="modal" open={tokenModalOpen}> - <div class="modal-box w-11/12"> + <div class="modal-box"> <button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2" on:click={() => tokenModalOpen = false}>✕</button> <h3 class="font-semibold text-lg">Token Vote Details</h3> <div class="divider my-1"></div> diff --git a/src/options/nav-options.ts b/src/options/nav-options.ts @@ -14,7 +14,7 @@ export const NavOptions: NavOption[] = [ url: 'activity' }, { - name: 'Add chain', - url: 'add-chain' + name: 'Edit chain', + url: 'edit-chain' } ] diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte @@ -4,10 +4,9 @@ import Nav from '../components/Nav.svelte' import '../app.css' import { PUBLIC_ERC20_CONTRACT_ADDRESS, PUBLIC_VOTE_CONTRACT_ADDRESS } from '$env/static/public' - import { erc20TokenAbi } from '../shared/erc20-token-abi' import { voteContractAbi } from '../shared/token-vote-abi' - import { configuredChain, connectionDetails, voteToken } from '../store' - + import { configuredChain, connectionDetails } from '../store' + const sendTransaction = async () => { if (!$connectionDetails.userAddress || !window.ethereum) return await walletClient($configuredChain).sendTransaction({ @@ -17,33 +16,6 @@ }) } - $: { - if ($connectionDetails.userAddress && configuredChain) { - const contract = getContract({ - address: PUBLIC_ERC20_CONTRACT_ADDRESS as `0x${string}`, - publicClient: publicClient($configuredChain), - walletClient: walletClient($configuredChain), - abi: erc20TokenAbi - }) - - contract.read.balanceOf([$connectionDetails.userAddress] as [`0x${string}`]) - .then(balance => voteToken.update(current => ({...current, balance }))) - .catch(err => console.log(err)) - - contract.read.name() - .then(name => voteToken.update(current => ({...current, name }))) - .catch(err => console.error(err)) - - contract.read.symbol() - .then(symbol => voteToken.update(current => ({...current, symbol }))) - .catch(err => console.error(err)) - - contract.read.decimals() - .then(decimals => voteToken.update(current => ({...current, decimals }))) - .catch(err => console.error(err)) - } - } - const createProposal = async () => { const description = stringToHex('Testing proposal creation', { size: 32 }) const blockWait = 100 @@ -72,11 +44,19 @@ } </script> +<svelte:head> + <title>EVM Token Vote</title> + <meta + name="description" + content="Vote on propositions with zero or more options using ERC20 tokens." + /> +</svelte:head> + <Nav /> {#if $connectionDetails.isConnected} - <button class="btn mt-1" on:click={sendTransaction}>Send transaction</button> + <!-- <button class="btn mt-1" on:click={sendTransaction}>Send transaction</button> <button class="btn mt-1" on:click={createProposal}>Create proposal</button> - <button class="btn mt-1" on:click={getCurrentProposal}>Get current proposal</button> + <button class="btn mt-1" on:click={getCurrentProposal}>Get current proposal</button> --> {/if} <slot /> diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte @@ -1,15 +1,18 @@ <script lang="ts"> + import { onMount } from 'svelte' + import { publicClient } from '../client' import NetworkForm from '../components/NetworkForm.svelte' + import { configuredChain } from '../store' + + let connectedChainId: number; + + onMount(() => { + publicClient($configuredChain).getChainId() + .then(chainId => connectedChainId = chainId) + }) -</script> -<svelte:head> - <title>EVM Token Vote</title> - <meta - name="description" - content="Vote on propositions with zero or more options using ERC20 tokens." - /> -</svelte:head> +</script> <div class="flex w-full min-h-screen"> - <NetworkForm /> + </div> \ No newline at end of file diff --git a/src/routes/edit-chain/+page.svelte b/src/routes/edit-chain/+page.svelte @@ -0,0 +1,7 @@ +<script lang="ts"> + import NetworkForm from '../../components/NetworkForm.svelte' + +</script> +<div class="flex w-full min-h-screen"> + <NetworkForm /> +</div> +\ No newline at end of file diff --git a/src/store.ts b/src/store.ts @@ -83,6 +83,7 @@ export const createConnectionDetails = () => { update } } + export const createVoteToken = () => { const { subscribe, update } = writable<VoteToken>({ name: '',