Skip to content

Commit cbb6482

Browse files
committed
Use-wallet-UI Update
1 parent d85910b commit cbb6482

7 files changed

Lines changed: 2179 additions & 1664 deletions

File tree

projects/Saver-frontend/package-lock.json

Lines changed: 2059 additions & 1544 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

projects/Saver-frontend/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,15 @@
3434
"vite": "^5.0.0"
3535
},
3636
"dependencies": {
37-
"@algorandfoundation/algokit-utils": "^6.0.2",
37+
"@algorandfoundation/algokit-utils": "^6.2.1",
3838
"@blockshake/defly-connect": "^1.1.6",
3939
"@daffiwallet/connect": "^1.0.3",
4040
"@perawallet/connect": "^1.3.1",
4141
"@txnlab/use-wallet": "^2.8.2",
42+
"@txnlab/use-wallet-react": "^4.1.0",
43+
"@txnlab/use-wallet-ui-react": "^0.2.3",
4244
"@walletconnect/modal-sign-html": "^2.6.1",
43-
"algosdk": "^2.7.0",
45+
"algosdk": "^3.3.1",
4446
"daisyui": "^4.0.0",
4547
"notistack": "^3.0.1",
4648
"react": "^18.2.0",

projects/Saver-frontend/src/App.tsx

Lines changed: 25 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,38 @@
1-
import { DeflyWalletConnect } from '@blockshake/defly-connect'
2-
import { DaffiWalletConnect } from '@daffiwallet/connect'
3-
import { PeraWalletConnect } from '@perawallet/connect'
4-
import { PROVIDER_ID, ProvidersArray, WalletProvider, useInitializeProviders } from '@txnlab/use-wallet'
5-
import algosdk from 'algosdk'
1+
import { NetworkId, WalletId, WalletManager, WalletProvider } from '@txnlab/use-wallet-react'
2+
import { WalletButton, WalletUIProvider } from '@txnlab/use-wallet-ui-react'
3+
import '@txnlab/use-wallet-ui-react/dist/style.css'
4+
65
import { SnackbarProvider } from 'notistack'
76
import { Route, BrowserRouter as Router, Routes } from 'react-router-dom'
7+
88
import Home from './Home'
9+
import AboutSaver from './components/AboutSaver'
910
import StartSaver from './components/StartSaver'
1011
import ViewSavings from './components/ViewSavings'
11-
import { getAlgodConfigFromViteEnvironment, getKmdConfigFromViteEnvironment } from './utils/network/getAlgoClientConfigs'
12-
import AboutSaver from './components/AboutSaver'
1312

14-
let providersArray: ProvidersArray
15-
16-
if (import.meta.env.VITE_ALGOD_NETWORK === '') {
17-
const kmdConfig = getKmdConfigFromViteEnvironment()
18-
providersArray = [
19-
{
20-
id: PROVIDER_ID.KMD,
21-
clientOptions: {
22-
wallet: kmdConfig.wallet,
23-
password: kmdConfig.password,
24-
host: kmdConfig.server,
25-
token: String(kmdConfig.token),
26-
port: String(kmdConfig.port),
27-
},
28-
},
29-
]
30-
} else {
31-
providersArray = [
32-
{ id: PROVIDER_ID.DEFLY, clientStatic: DeflyWalletConnect },
33-
{ id: PROVIDER_ID.PERA, clientStatic: PeraWalletConnect },
34-
{ id: PROVIDER_ID.DAFFI, clientStatic: DaffiWalletConnect },
35-
{ id: PROVIDER_ID.EXODUS },
36-
// For WalletConnect v2 provider, refer to https://github.com/TxnLab/use-wallet for integration instructions
37-
]
38-
}
13+
const walletManager = new WalletManager({
14+
wallets: [WalletId.PERA, WalletId.DEFLY, WalletId.EXODUS],
15+
defaultNetwork: NetworkId.TESTNET,
16+
})
3917

4018
export default function App() {
41-
const algodConfig = getAlgodConfigFromViteEnvironment()
42-
43-
const walletProviders = useInitializeProviders({
44-
providers: providersArray,
45-
nodeConfig: {
46-
network: algodConfig.network,
47-
nodeServer: algodConfig.server,
48-
nodePort: String(algodConfig.port),
49-
nodeToken: String(algodConfig.token),
50-
},
51-
algosdkStatic: algosdk,
52-
})
53-
5419
return (
5520
<SnackbarProvider maxSnack={3}>
56-
<WalletProvider value={walletProviders}>
57-
<Router>
58-
<Routes>
59-
<Route path="/" element={<Home />} />
60-
<Route path="/StartSuperSaver" element={<StartSaver openModal={true} setModalState={() => {}} />} />
61-
<Route path="/ViewSavings" element={<ViewSavings />} />
62-
<Route path="/AboutSaver" element={<AboutSaver />} />
63-
</Routes>
64-
</Router>
21+
<WalletProvider manager={walletManager}>
22+
<WalletUIProvider>
23+
<Router>
24+
{/* Wallet Connect Button (top right corner) */}
25+
<div data-wallet-ui style={{ position: 'fixed', top: 20, right: 20, zIndex: 1000 }}>
26+
<WalletButton />
27+
</div>
28+
<Routes>
29+
<Route path="/" element={<Home />} />
30+
<Route path="/StartSuperSaver" element={<StartSaver openModal={true} setModalState={() => {}} />} />
31+
<Route path="/ViewSavings" element={<ViewSavings />} />
32+
<Route path="/AboutSaver" element={<AboutSaver />} />
33+
</Routes>
34+
</Router>
35+
</WalletUIProvider>
6536
</WalletProvider>
6637
</SnackbarProvider>
6738
)

projects/Saver-frontend/src/Home.tsx

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import { useWallet } from '@txnlab/use-wallet'
1+
import { useWallet } from '@txnlab/use-wallet-react'
22
import React, { useState } from 'react'
33
import { useNavigate } from 'react-router-dom'
4-
import ConnectWallet from './components/ConnectWallet'
54

65
const Home: React.FC = () => {
76
const [openWalletModal, setOpenWalletModal] = useState(false)
@@ -32,26 +31,6 @@ const Home: React.FC = () => {
3231
<header className="bg-teal-500 text-white py-5 px-8 shadow-lg">
3332
<div className="flex justify-between items-center">
3433
<h1 className="text-3xl font-extrabold tracking-wide">Super Saver App</h1>
35-
<nav className="flex items-center space-x-5">
36-
<a href="#home" className="hover:underline">
37-
Home
38-
</a>
39-
<a href="/StartSuperSaver" className="hover:underline">
40-
Start Saving
41-
</a>
42-
<a href="/ViewSavings" className="hover:underline">
43-
Your Savings
44-
</a>
45-
<a href="/AboutSaver" className="hover:underline">
46-
About
47-
</a>
48-
<button
49-
className="btn btn-outline btn-sm bg-white text-teal-500 border-teal-500 hover:bg-teal-600 hover:text-white"
50-
onClick={toggleWalletModal}
51-
>
52-
{activeAddress ? 'Wallet Connected' : 'Connect Wallet'}
53-
</button>
54-
</nav>
5534
</div>
5635
</header>
5736

@@ -117,7 +96,7 @@ const Home: React.FC = () => {
11796
</footer>
11897

11998
{/* Wallet Modal */}
120-
<ConnectWallet openModal={openWalletModal} closeModal={toggleWalletModal} />
99+
{/* <ConnectWallet openModal={openWalletModal} closeModal={toggleWalletModal} /> */}
121100
</div>
122101
)
123102
}

projects/Saver-frontend/src/components/StartSaver.tsx

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as algokit from '@algorandfoundation/algokit-utils'
22
import { TransactionSignerAccount } from '@algorandfoundation/algokit-utils/types/account'
33
import { AppDetails } from '@algorandfoundation/algokit-utils/types/app-client'
4-
import { useWallet } from '@txnlab/use-wallet'
4+
import { useWallet } from '@txnlab/use-wallet-react'
55
import { useSnackbar } from 'notistack'
66
import { useEffect, useState } from 'react'
77
import { useNavigate } from 'react-router-dom'
@@ -23,58 +23,76 @@ const StartSaver = ({ openModal, setModalState }: AppCallsInterface) => {
2323

2424
const navigate = useNavigate()
2525
const { enqueueSnackbar } = useSnackbar()
26-
const { signer, activeAddress } = useWallet()
26+
const { activeAddress, transactionSigner } = useWallet()
27+
const signer = transactionSigner
2728

28-
const deployedAppID = 740800501
29+
const deployedAppID = 740800501n
2930
const appAddress = 'NSBKY7G5NNYVF2BKIJL6MAJ4QW6PZSDFMGNQ3EDULAKHBWX2MPK6YZLS2A'
3031
const algodClient = algokit.getAlgoClient(getAlgodConfigFromViteEnvironment())
3132

32-
const getAppDetails = (appId: number): AppDetails => ({
33-
resolveBy: 'id',
34-
sender: { signer, addr: activeAddress } as TransactionSignerAccount,
35-
id: appId,
36-
})
33+
const getAppDetails = (appId: bigint): AppDetails => {
34+
console.log('[AppDetails] Active address:', activeAddress)
35+
return {
36+
resolveBy: 'id',
37+
sender: { signer, addr: activeAddress! } as TransactionSignerAccount,
38+
id: Number(appId),
39+
}
40+
}
3741

3842
const showSnackbar = (message: string, variant: 'success' | 'error') => {
3943
enqueueSnackbar(message, { variant })
4044
}
4145

4246
const refreshState = async () => {
4347
if (!activeAddress) return
44-
45-
const appClient = new SaverClient(getAppDetails(deployedAppID), algodClient)
4648
try {
47-
const local = await appClient.getLocalState(activeAddress)
49+
const accountInfo = await algodClient.accountInformation(activeAddress).do()
50+
const appLocalState = accountInfo.appsLocalState?.find((app) => app.id === deployedAppID)
51+
const keyValue = appLocalState?.keyValue || []
52+
53+
const getUintValue = (key: string) => {
54+
const entry = keyValue.find((kv: any) => {
55+
const decodedKey = Buffer.from(kv.key, 'base64').toString()
56+
return decodedKey === key
57+
})
58+
return entry ? Number(entry.value.uint) : 0
59+
}
60+
4861
setAlreadyOptedIn(true)
49-
setCurrentGoal(local.userGoal?.asNumber() || null)
50-
setCurrentBalance(local.userBalance?.asNumber() || null)
51-
} catch {
62+
setCurrentGoal(getUintValue('user_goal'))
63+
setCurrentBalance(getUintValue('user_balance'))
64+
} catch (err) {
65+
console.error('[refreshState] Failed to get local state:', err)
5266
setAlreadyOptedIn(false)
5367
setCurrentGoal(null)
5468
setCurrentBalance(null)
5569
}
5670
}
5771

5872
useEffect(() => {
73+
console.log('[useEffect] activeAddress changed:', activeAddress)
5974
refreshState()
6075
}, [activeAddress])
6176

6277
const sendAppCall = async () => {
78+
if (!activeAddress) return showSnackbar('Connect your wallet first.', 'error')
6379
setLoading(true)
6480
try {
6581
const appClient = new SaverClient(getAppDetails(deployedAppID), algodClient)
6682
const optInResponse = await appClient.optIn
6783
await optInResponse.bare()
6884
showSnackbar('Successfully opted into the app!', 'success')
6985
await refreshState()
70-
} catch {
86+
} catch (err) {
87+
console.error('[sendAppCall] Error:', err)
7188
showSnackbar('Error during opt-in.', 'error')
7289
} finally {
7390
setLoading(false)
7491
}
7592
}
7693

7794
const sendGoalTxn = async () => {
95+
if (!activeAddress) return showSnackbar('Connect your wallet first.', 'error')
7896
setLoading(true)
7997
try {
8098
const goalAmount = parseInt(goalInput, 10)
@@ -87,14 +105,16 @@ const StartSaver = ({ openModal, setModalState }: AppCallsInterface) => {
87105
await appClient.createSaverJar({ goalAmount: microAlgos })
88106
showSnackbar('Savings goal set!', 'success')
89107
await refreshState()
90-
} catch {
108+
} catch (err) {
109+
console.error('[sendGoalTxn] Error:', err)
91110
showSnackbar('Error setting goal.', 'error')
92111
} finally {
93112
setLoading(false)
94113
}
95114
}
96115

97116
const depositFunds = async () => {
117+
if (!activeAddress) return showSnackbar('Connect your wallet first.', 'error')
98118
setLoading(true)
99119
try {
100120
const amount = parseInt(depositInput, 10)
@@ -105,45 +125,47 @@ const StartSaver = ({ openModal, setModalState }: AppCallsInterface) => {
105125
const appClient = new SaverClient(getAppDetails(deployedAppID), algodClient)
106126
const paymentTxn = await algokit.transferAlgos(
107127
{
108-
from: { addr: activeAddress || '', signer },
128+
from: { addr: activeAddress, signer },
109129
to: appAddress,
110130
amount: algokit.algos(amount),
111131
skipSending: true,
112132
},
113133
algodClient,
114134
)
115-
await appClient.deposit({ depositTxn: paymentTxn.transaction }, { sender: { addr: activeAddress!, signer } })
135+
await appClient.deposit({ depositTxn: paymentTxn.transaction }, { sender: { addr: activeAddress, signer } })
116136
showSnackbar('Deposit successful!', 'success')
117137
await refreshState()
118-
} catch {
138+
} catch (err) {
139+
console.error('[depositFunds] Error:', err)
119140
showSnackbar('Error during deposit.', 'error')
120141
} finally {
121142
setLoading(false)
122143
}
123144
}
124145

125146
const withdrawFunds = async () => {
147+
if (!activeAddress) return showSnackbar('Connect your wallet first.', 'error')
126148
setLoading(true)
127149
try {
128150
const appClient = new SaverClient(getAppDetails(deployedAppID), algodClient)
129151
await appClient.withdraw(
130152
{},
131153
{
132-
sender: { addr: activeAddress || '', signer },
154+
sender: { addr: activeAddress, signer },
133155
sendParams: { fee: algokit.microAlgos(2000) },
134156
},
135157
)
136158
showSnackbar('Withdrawal complete!', 'success')
137159
await refreshState()
138-
} catch {
160+
} catch (err) {
161+
console.error('[withdrawFunds] Error:', err)
139162
showSnackbar('Error during withdrawal.', 'error')
140163
} finally {
141164
setLoading(false)
142165
}
143166
}
144167

145168
const progressPercent = currentGoal && currentBalance ? Math.min(Math.round((currentBalance / currentGoal) * 100), 100) : 0
146-
147169
const progressColor = progressPercent >= 100 ? 'bg-green-500' : 'bg-blue-400'
148170

149171
return (

projects/Saver-frontend/src/components/Transact.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/*
12
import * as algokit from '@algorandfoundation/algokit-utils'
23
import { useWallet } from '@txnlab/use-wallet'
34
import algosdk from 'algosdk'
@@ -92,4 +93,6 @@ const Transact = ({ openModal, setModalState }: TransactInterface) => {
9293
)
9394
}
9495
96+
9597
export default Transact
98+
*/

0 commit comments

Comments
 (0)