|
9 | 9 | Vue Composables No Modal Quick Start |
10 | 10 | </h2> |
11 | 11 |
|
12 | | - <button v-if="status !== ADAPTER_STATUS.CONNECTED" class="card" @click="login"> |
13 | | - Login |
14 | | - </button> |
| 12 | + <div v-if="!isConnected" class="card-container"> |
| 13 | + <button class="card" @click="connect(WALLET_CONNECTORS.AUTH, { authConnection: AUTH_CONNECTION.GOOGLE })"> |
| 14 | + Login |
| 15 | + </button> |
| 16 | + <div v-if="connectLoading" class="loading">Connecting...</div> |
| 17 | + <div v-if="connectError" class="error">{{ connectError.message }}</div> |
| 18 | + </div> |
15 | 19 |
|
16 | | - <div v-if="status === ADAPTER_STATUS.CONNECTED" class="flex-col"> |
| 20 | + <div v-if="isConnected" class="flex-col"> |
| 21 | + <h2>Connected to {{ connectorName }}</h2> |
17 | 22 | <div class="grid" style="grid-template-columns: repeat(auto-fill, minmax(150px, 1fr))"> |
18 | 23 | <div> |
19 | | - <button class="card" @click="getUserInfo"> |
| 24 | + <button class="card" @click="uiConsole(userInfo)"> |
20 | 25 | Get User Info |
21 | 26 | </button> |
22 | 27 | </div> |
23 | 28 | <div> |
24 | | - <button class="card" @click="getAccounts"> |
25 | | - Get Accounts |
26 | | - </button> |
27 | | - </div> |
28 | | - <div> |
29 | | - <button class="card" @click="getBalance"> |
30 | | - Get Balance |
31 | | - </button> |
32 | | - </div> |
33 | | - <div> |
34 | | - <button class="card" @click="signMessage"> |
35 | | - Sign Message |
36 | | - </button> |
37 | | - </div> |
38 | | - <div> |
39 | | - <button class="card" @click="sendTransaction"> |
40 | | - Send Transaction |
41 | | - </button> |
42 | | - </div> |
43 | | - <div> |
44 | | - <button class="card" @click="logout()"> |
45 | | - Logout |
| 29 | + <button class="card" @click="disconnect()"> |
| 30 | + Log Out |
46 | 31 | </button> |
| 32 | + <div v-if="disconnectLoading" class="loading">Disconnecting...</div> |
| 33 | + <div v-if="disconnectError" class="error">{{ disconnectError.message }}</div> |
47 | 34 | </div> |
48 | 35 | </div> |
49 | 36 | </div> |
| 37 | + <Account v-if="isConnected" /> |
| 38 | + <SendTransaction v-if="isConnected" /> |
| 39 | + <Balance v-if="isConnected" /> |
| 40 | + <SwitchNetwork v-if="isConnected" /> |
| 41 | + |
50 | 42 | <div id="console"> |
51 | 43 | <p></p> |
52 | 44 | </div> |
|
56 | 48 | target="_blank" rel="noopener noreferrer"> |
57 | 49 | Source code |
58 | 50 | </a> |
59 | | - <a |
60 | | - href="https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FWeb3Auth%2Fweb3auth-pnp-examples%2Ftree%2Fmain%2Fweb-no-modal-sdk%2Fquick-starts%2Fvue-composables-no-modal-quick-start&project-name=w3a-vue-modal&repository-name=w3a-vue-modal"> |
61 | | - <img src="https://vercel.com/button" alt="Deploy with Vercel" /> |
62 | | - </a> |
63 | 51 | </footer> |
64 | 52 | </main> |
65 | 53 | </div> |
66 | 54 | </template> |
67 | 55 |
|
68 | 56 | <script setup lang="ts"> |
69 | | -import { useWeb3Auth } from "@web3auth/no-modal-vue-composables"; |
70 | | -import { ADAPTER_STATUS, WALLET_ADAPTERS } from "@web3auth/base"; |
71 | | -const { status, connectTo, userInfo, provider, logout } = useWeb3Auth(); |
72 | | -
|
73 | | -const login = async () => { |
74 | | - // IMP START - Login |
75 | | - await connectTo(WALLET_ADAPTERS.AUTH, { |
76 | | - loginProvider: "google", |
77 | | - }); |
78 | | - // IMP END - Login |
79 | | -}; |
80 | | -
|
81 | | -const getUserInfo = async () => { |
82 | | - // IMP START - Get User Information |
83 | | - uiConsole(userInfo.value); |
84 | | - // IMP END - Get User Information |
85 | | -}; |
86 | | -
|
87 | | -// IMP START - Blockchain Calls |
88 | | -const getAccounts = async () => { |
89 | | - if (!provider) { |
90 | | - uiConsole("provider not initialized yet"); |
91 | | - return; |
92 | | - } |
93 | | - const address = await RPC.getAccounts(provider.value!); |
94 | | - uiConsole(address); |
95 | | -}; |
96 | | -
|
97 | | -const getBalance = async () => { |
98 | | - if (!provider) { |
99 | | - uiConsole("provider not initialized yet"); |
100 | | - return; |
101 | | - } |
102 | | - const balance = await RPC.getBalance(provider.value!); |
103 | | - uiConsole(balance); |
104 | | -}; |
105 | | -
|
106 | | -const signMessage = async () => { |
107 | | - if (!provider) { |
108 | | - uiConsole("provider not initialized yet"); |
109 | | - return; |
110 | | - } |
111 | | - const signedMessage = await RPC.signMessage(provider.value!); |
112 | | - uiConsole(signedMessage); |
113 | | -}; |
114 | | -
|
115 | | -
|
116 | | -const sendTransaction = async () => { |
117 | | - if (!provider) { |
118 | | - uiConsole("provider not initialized yet"); |
119 | | - return; |
120 | | - } |
121 | | - uiConsole("Sending Transaction..."); |
122 | | - const transactionReceipt = await RPC.sendTransaction(provider.value!); |
123 | | - uiConsole(transactionReceipt); |
124 | | -}; |
125 | | -// IMP END - Blockchain Calls |
126 | | -
|
127 | | -function uiConsole(...args: any[]): void { |
| 57 | +import { useWeb3AuthConnect, useWeb3AuthDisconnect, useWeb3AuthUser } from "@web3auth/no-modal/vue"; |
| 58 | +import { WALLET_CONNECTORS, AUTH_CONNECTION } from "@web3auth/no-modal"; |
| 59 | +import Account from './components/Account.vue'; |
| 60 | +import SendTransaction from './components/SendTransaction.vue'; |
| 61 | +import Balance from './components/Balance.vue'; |
| 62 | +import SwitchNetwork from './components/SwitchNetwork.vue'; |
| 63 | +// Web3Auth hooks (direct from library) |
| 64 | +const { |
| 65 | + connect, |
| 66 | + isConnected, |
| 67 | + connectorName, |
| 68 | + loading: connectLoading, |
| 69 | + error: connectError |
| 70 | +} = useWeb3AuthConnect(); |
| 71 | +
|
| 72 | +const { |
| 73 | + disconnect, |
| 74 | + loading: disconnectLoading, |
| 75 | + error: disconnectError |
| 76 | +} = useWeb3AuthDisconnect(); |
| 77 | +
|
| 78 | +const { userInfo } = useWeb3AuthUser(); |
| 79 | +
|
| 80 | +// Helper function for logging |
| 81 | +const uiConsole = (...args: any[]): void => { |
128 | 82 | const el = document.querySelector("#console>p"); |
129 | 83 | if (el) { |
130 | 84 | el.innerHTML = JSON.stringify(args || {}, null, 2); |
| 85 | + console.log(...args); |
131 | 86 | } |
132 | | - console.log(...args); |
133 | | -} |
| 87 | +}; |
134 | 88 | </script> |
135 | | - |
136 | | -<style scoped> |
137 | | -/* Container layout */ |
138 | | -.container { |
139 | | - width: 100%; |
140 | | - padding: 0 1rem; |
141 | | - margin: 0 auto; |
142 | | -} |
143 | | -
|
144 | | -.main { |
145 | | - min-height: 100vh; |
146 | | - padding: 2rem 0; |
147 | | - display: flex; |
148 | | - flex-direction: column; |
149 | | - align-items: center; |
150 | | -} |
151 | | -
|
152 | | -/* Typography */ |
153 | | -.title { |
154 | | - font-size: 1.75rem; |
155 | | - text-align: center; |
156 | | - margin: 1.5rem 0; |
157 | | - line-height: 1.2; |
158 | | - font-weight: 600; |
159 | | -} |
160 | | -
|
161 | | -.title a { |
162 | | - color: var(--primary-color); |
163 | | - text-decoration: none; |
164 | | -} |
165 | | -
|
166 | | -/* Buttons and Cards */ |
167 | | -button, .card { |
168 | | - display: inline-flex; |
169 | | - align-items: center; |
170 | | - justify-content: center; |
171 | | - padding: 0.75rem 1.25rem; |
172 | | - background-color: var(--bg-light); |
173 | | - border: 1px solid var(--border-color); |
174 | | - border-radius: var(--radius); |
175 | | - color: var(--text-color); |
176 | | - font-weight: 500; |
177 | | - font-size: 0.875rem; |
178 | | - cursor: pointer; |
179 | | - transition: all 0.2s ease; |
180 | | - box-shadow: var(--shadow-sm); |
181 | | - width: 100%; |
182 | | - margin: 0.5rem 0; |
183 | | - text-align: center; |
184 | | -} |
185 | | -
|
186 | | -button:hover, .card:hover { |
187 | | - background-color: var(--bg-hover); |
188 | | - box-shadow: var(--shadow-md); |
189 | | - transform: translateY(-1px); |
190 | | -} |
191 | | -
|
192 | | -/* Utils */ |
193 | | -.flex-row { |
194 | | - display: flex; |
195 | | - flex-wrap: wrap; |
196 | | - gap: 0.75rem; |
197 | | - width: 100%; |
198 | | -} |
199 | | -
|
200 | | -.flex-col { |
201 | | - display: flex; |
202 | | - flex-direction: column; |
203 | | - gap: 0.75rem; |
204 | | - width: 100%; |
205 | | -} |
206 | | -
|
207 | | -.grid { |
208 | | - display: grid; |
209 | | - gap: 1rem; |
210 | | - width: 100%; |
211 | | -} |
212 | | -
|
213 | | -/* Console output */ |
214 | | -#console { |
215 | | - width: 100%; |
216 | | - max-height: 250px; |
217 | | - overflow: auto; |
218 | | - word-wrap: break-word; |
219 | | - font-family: monospace; |
220 | | - font-size: 0.85rem; |
221 | | - padding: 1rem; |
222 | | - margin: 1.5rem 0; |
223 | | - background-color: var(--bg-light); |
224 | | - border-radius: var(--radius); |
225 | | - border: 1px solid var(--border-color); |
226 | | - text-align: left; |
227 | | -} |
228 | | -
|
229 | | -/* Footer */ |
230 | | -.footer { |
231 | | - width: 100%; |
232 | | - padding: 2rem 0; |
233 | | - border-top: 1px solid var(--border-color); |
234 | | - display: flex; |
235 | | - justify-content: center; |
236 | | - align-items: center; |
237 | | - gap: 1.5rem; |
238 | | - margin-top: 3rem; |
239 | | - flex-wrap: wrap; |
240 | | -} |
241 | | -
|
242 | | -.footer a { |
243 | | - color: var(--text-muted); |
244 | | - text-decoration: none; |
245 | | - font-size: 0.875rem; |
246 | | - transition: color 0.2s ease; |
247 | | -} |
248 | | -
|
249 | | -.footer a:hover { |
250 | | - color: var(--primary-color); |
251 | | -} |
252 | | -
|
253 | | -/* Responsive */ |
254 | | -@media (min-width: 640px) { |
255 | | - .container { |
256 | | - max-width: 640px; |
257 | | - } |
258 | | -} |
259 | | -
|
260 | | -@media (min-width: 768px) { |
261 | | - .container { |
262 | | - max-width: 768px; |
263 | | - } |
264 | | -} |
265 | | -
|
266 | | -@media (min-width: 1024px) { |
267 | | - .container { |
268 | | - max-width: 1024px; |
269 | | - } |
270 | | -} |
271 | | -</style> |
0 commit comments