@goplausible/openclaw-algorand-plugin 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +112 -0
  3. package/index.ts +361 -0
  4. package/lib/mcp-servers.ts +14 -0
  5. package/lib/x402-fetch.ts +213 -0
  6. package/memory/algorand-plugin.md +82 -0
  7. package/openclaw.plugin.json +30 -0
  8. package/package.json +41 -0
  9. package/setup.ts +80 -0
  10. package/skills/algorand-development/SKILL.md +90 -0
  11. package/skills/algorand-development/references/build-smart-contracts-reference.md +79 -0
  12. package/skills/algorand-development/references/build-smart-contracts.md +52 -0
  13. package/skills/algorand-development/references/create-project-reference.md +86 -0
  14. package/skills/algorand-development/references/create-project.md +89 -0
  15. package/skills/algorand-development/references/implement-arc-standards-arc32-arc56.md +396 -0
  16. package/skills/algorand-development/references/implement-arc-standards-arc4.md +265 -0
  17. package/skills/algorand-development/references/implement-arc-standards.md +92 -0
  18. package/skills/algorand-development/references/search-algorand-examples-reference.md +119 -0
  19. package/skills/algorand-development/references/search-algorand-examples.md +89 -0
  20. package/skills/algorand-development/references/troubleshoot-errors-contract.md +373 -0
  21. package/skills/algorand-development/references/troubleshoot-errors-transaction.md +599 -0
  22. package/skills/algorand-development/references/troubleshoot-errors.md +105 -0
  23. package/skills/algorand-development/references/use-algokit-cli-reference.md +228 -0
  24. package/skills/algorand-development/references/use-algokit-cli.md +64 -0
  25. package/skills/algorand-interaction/SKILL.md +223 -0
  26. package/skills/algorand-interaction/references/algorand-mcp.md +743 -0
  27. package/skills/algorand-interaction/references/examples-algorand-mcp.md +647 -0
  28. package/skills/algorand-python/SKILL.md +95 -0
  29. package/skills/algorand-python/references/build-smart-contracts-decorators.md +413 -0
  30. package/skills/algorand-python/references/build-smart-contracts-reference.md +55 -0
  31. package/skills/algorand-python/references/build-smart-contracts-storage.md +452 -0
  32. package/skills/algorand-python/references/build-smart-contracts-transactions.md +445 -0
  33. package/skills/algorand-python/references/build-smart-contracts-types.md +438 -0
  34. package/skills/algorand-python/references/build-smart-contracts.md +82 -0
  35. package/skills/algorand-python/references/create-project-reference.md +55 -0
  36. package/skills/algorand-python/references/create-project.md +75 -0
  37. package/skills/algorand-python/references/implement-arc-standards-arc32-arc56.md +101 -0
  38. package/skills/algorand-python/references/implement-arc-standards-arc4.md +154 -0
  39. package/skills/algorand-python/references/implement-arc-standards.md +39 -0
  40. package/skills/algorand-python/references/troubleshoot-errors-contract.md +355 -0
  41. package/skills/algorand-python/references/troubleshoot-errors-transaction.md +430 -0
  42. package/skills/algorand-python/references/troubleshoot-errors.md +46 -0
  43. package/skills/algorand-python/references/use-algokit-utils-reference.md +350 -0
  44. package/skills/algorand-python/references/use-algokit-utils.md +76 -0
  45. package/skills/algorand-typescript/SKILL.md +131 -0
  46. package/skills/algorand-typescript/references/algorand-ts-migration-from-beta.md +448 -0
  47. package/skills/algorand-typescript/references/algorand-ts-migration-from-tealscript.md +487 -0
  48. package/skills/algorand-typescript/references/algorand-ts-migration.md +102 -0
  49. package/skills/algorand-typescript/references/algorand-typescript-syntax-methods-and-abi.md +134 -0
  50. package/skills/algorand-typescript/references/algorand-typescript-syntax-reference.md +58 -0
  51. package/skills/algorand-typescript/references/algorand-typescript-syntax-storage.md +154 -0
  52. package/skills/algorand-typescript/references/algorand-typescript-syntax-transactions.md +187 -0
  53. package/skills/algorand-typescript/references/algorand-typescript-syntax-types-and-values.md +150 -0
  54. package/skills/algorand-typescript/references/algorand-typescript-syntax.md +84 -0
  55. package/skills/algorand-typescript/references/build-smart-contracts-reference.md +52 -0
  56. package/skills/algorand-typescript/references/build-smart-contracts.md +74 -0
  57. package/skills/algorand-typescript/references/call-smart-contracts-reference.md +237 -0
  58. package/skills/algorand-typescript/references/call-smart-contracts.md +183 -0
  59. package/skills/algorand-typescript/references/create-project-reference.md +53 -0
  60. package/skills/algorand-typescript/references/create-project.md +86 -0
  61. package/skills/algorand-typescript/references/deploy-react-frontend-examples.md +527 -0
  62. package/skills/algorand-typescript/references/deploy-react-frontend-reference.md +412 -0
  63. package/skills/algorand-typescript/references/deploy-react-frontend.md +239 -0
  64. package/skills/algorand-typescript/references/implement-arc-standards-arc32-arc56.md +73 -0
  65. package/skills/algorand-typescript/references/implement-arc-standards-arc4.md +126 -0
  66. package/skills/algorand-typescript/references/implement-arc-standards.md +44 -0
  67. package/skills/algorand-typescript/references/test-smart-contracts-examples.md +245 -0
  68. package/skills/algorand-typescript/references/test-smart-contracts-unit-tests.md +147 -0
  69. package/skills/algorand-typescript/references/test-smart-contracts.md +127 -0
  70. package/skills/algorand-typescript/references/troubleshoot-errors-contract.md +296 -0
  71. package/skills/algorand-typescript/references/troubleshoot-errors-transaction.md +438 -0
  72. package/skills/algorand-typescript/references/troubleshoot-errors.md +56 -0
  73. package/skills/algorand-typescript/references/use-algokit-utils-reference.md +342 -0
  74. package/skills/algorand-typescript/references/use-algokit-utils.md +74 -0
  75. package/skills/algorand-x402-python/SKILL.md +113 -0
  76. package/skills/algorand-x402-python/references/create-python-x402-client-examples.md +469 -0
  77. package/skills/algorand-x402-python/references/create-python-x402-client-reference.md +313 -0
  78. package/skills/algorand-x402-python/references/create-python-x402-client.md +207 -0
  79. package/skills/algorand-x402-python/references/create-python-x402-facilitator-examples.md +924 -0
  80. package/skills/algorand-x402-python/references/create-python-x402-facilitator-reference.md +629 -0
  81. package/skills/algorand-x402-python/references/create-python-x402-facilitator.md +408 -0
  82. package/skills/algorand-x402-python/references/create-python-x402-server-examples.md +703 -0
  83. package/skills/algorand-x402-python/references/create-python-x402-server-reference.md +303 -0
  84. package/skills/algorand-x402-python/references/create-python-x402-server.md +221 -0
  85. package/skills/algorand-x402-python/references/explain-algorand-x402-python-examples.md +605 -0
  86. package/skills/algorand-x402-python/references/explain-algorand-x402-python-reference.md +315 -0
  87. package/skills/algorand-x402-python/references/explain-algorand-x402-python.md +167 -0
  88. package/skills/algorand-x402-python/references/use-python-x402-core-avm-examples.md +554 -0
  89. package/skills/algorand-x402-python/references/use-python-x402-core-avm-reference.md +278 -0
  90. package/skills/algorand-x402-python/references/use-python-x402-core-avm.md +166 -0
  91. package/skills/algorand-x402-typescript/SKILL.md +129 -0
  92. package/skills/algorand-x402-typescript/references/create-typescript-x402-client-examples.md +879 -0
  93. package/skills/algorand-x402-typescript/references/create-typescript-x402-client-reference.md +371 -0
  94. package/skills/algorand-x402-typescript/references/create-typescript-x402-client.md +236 -0
  95. package/skills/algorand-x402-typescript/references/create-typescript-x402-facilitator-examples.md +875 -0
  96. package/skills/algorand-x402-typescript/references/create-typescript-x402-facilitator-reference.md +461 -0
  97. package/skills/algorand-x402-typescript/references/create-typescript-x402-facilitator.md +270 -0
  98. package/skills/algorand-x402-typescript/references/create-typescript-x402-nextjs-examples.md +1181 -0
  99. package/skills/algorand-x402-typescript/references/create-typescript-x402-nextjs-reference.md +360 -0
  100. package/skills/algorand-x402-typescript/references/create-typescript-x402-nextjs.md +251 -0
  101. package/skills/algorand-x402-typescript/references/create-typescript-x402-paywall-examples.md +870 -0
  102. package/skills/algorand-x402-typescript/references/create-typescript-x402-paywall-reference.md +323 -0
  103. package/skills/algorand-x402-typescript/references/create-typescript-x402-paywall.md +281 -0
  104. package/skills/algorand-x402-typescript/references/create-typescript-x402-server-examples.md +1135 -0
  105. package/skills/algorand-x402-typescript/references/create-typescript-x402-server-reference.md +382 -0
  106. package/skills/algorand-x402-typescript/references/create-typescript-x402-server.md +216 -0
  107. package/skills/algorand-x402-typescript/references/explain-algorand-x402-typescript-examples.md +616 -0
  108. package/skills/algorand-x402-typescript/references/explain-algorand-x402-typescript-reference.md +323 -0
  109. package/skills/algorand-x402-typescript/references/explain-algorand-x402-typescript.md +232 -0
  110. package/skills/algorand-x402-typescript/references/use-typescript-x402-core-avm-examples.md +1417 -0
  111. package/skills/algorand-x402-typescript/references/use-typescript-x402-core-avm-reference.md +504 -0
  112. package/skills/algorand-x402-typescript/references/use-typescript-x402-core-avm.md +158 -0
@@ -0,0 +1,527 @@
1
+ # React Frontend Examples
2
+
3
+ Complete, minimal examples for Algorand React frontends.
4
+
5
+ ## Example 1: Minimal Wallet Connection
6
+
7
+ Basic wallet connection without contract interaction.
8
+
9
+ ### App.tsx
10
+
11
+ ```tsx
12
+ import { NetworkId, WalletId, WalletManager, WalletProvider } from '@txnlab/use-wallet-react'
13
+ import { WalletConnect } from './WalletConnect'
14
+
15
+ const walletManager = new WalletManager({
16
+ wallets: [WalletId.PERA, WalletId.DEFLY],
17
+ defaultNetwork: NetworkId.TESTNET,
18
+ })
19
+
20
+ export default function App() {
21
+ return (
22
+ <WalletProvider manager={walletManager}>
23
+ <WalletConnect />
24
+ </WalletProvider>
25
+ )
26
+ }
27
+ ```
28
+
29
+ ### WalletConnect.tsx
30
+
31
+ ```tsx
32
+ import { useWallet } from '@txnlab/use-wallet-react'
33
+
34
+ export function WalletConnect() {
35
+ const { wallets, activeAddress, activeWallet } = useWallet()
36
+
37
+ if (activeAddress) {
38
+ return (
39
+ <div>
40
+ <p>Connected: {activeAddress.slice(0, 8)}...{activeAddress.slice(-4)}</p>
41
+ <button onClick={() => activeWallet?.disconnect()}>Disconnect</button>
42
+ </div>
43
+ )
44
+ }
45
+
46
+ return (
47
+ <div>
48
+ <h2>Connect Wallet</h2>
49
+ {wallets.map((wallet) => (
50
+ <button key={wallet.id} onClick={() => wallet.connect()}>
51
+ {wallet.metadata.name}
52
+ </button>
53
+ ))}
54
+ </div>
55
+ )
56
+ }
57
+ ```
58
+
59
+ ---
60
+
61
+ ## Example 2: Contract Interaction (Existing App)
62
+
63
+ Connect to an already-deployed contract by App ID.
64
+
65
+ ### App.tsx
66
+
67
+ ```tsx
68
+ import { NetworkId, WalletId, WalletManager, WalletProvider } from '@txnlab/use-wallet-react'
69
+ import { ContractDemo } from './ContractDemo'
70
+
71
+ const walletManager = new WalletManager({
72
+ wallets: [WalletId.PERA, WalletId.DEFLY],
73
+ defaultNetwork: NetworkId.TESTNET,
74
+ })
75
+
76
+ export default function App() {
77
+ return (
78
+ <WalletProvider manager={walletManager}>
79
+ <ContractDemo />
80
+ </WalletProvider>
81
+ )
82
+ }
83
+ ```
84
+
85
+ ### ContractDemo.tsx
86
+
87
+ ```tsx
88
+ import { useState } from 'react'
89
+ import { useWallet } from '@txnlab/use-wallet-react'
90
+ import { AlgorandClient } from '@algorandfoundation/algokit-utils'
91
+ import { HelloWorldClient } from './contracts/HelloWorldClient'
92
+
93
+ const APP_ID = 12345n // Replace with your App ID
94
+
95
+ export function ContractDemo() {
96
+ const { transactionSigner, activeAddress, wallets } = useWallet()
97
+ const [result, setResult] = useState<string>('')
98
+ const [loading, setLoading] = useState(false)
99
+
100
+ const callContract = async () => {
101
+ if (!activeAddress || !transactionSigner) return
102
+
103
+ setLoading(true)
104
+ try {
105
+ const algorand = AlgorandClient.testNet()
106
+ algorand.setSigner(activeAddress, transactionSigner)
107
+
108
+ const appClient = algorand.client.getTypedAppClientById(HelloWorldClient, {
109
+ appId: APP_ID,
110
+ defaultSender: activeAddress,
111
+ })
112
+
113
+ const response = await appClient.send.hello({ args: { name: 'World' } })
114
+ setResult(response.return ?? 'No return value')
115
+ } catch (error) {
116
+ setResult(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`)
117
+ } finally {
118
+ setLoading(false)
119
+ }
120
+ }
121
+
122
+ if (!activeAddress) {
123
+ return (
124
+ <div>
125
+ <h2>Connect Wallet</h2>
126
+ {wallets.map((wallet) => (
127
+ <button key={wallet.id} onClick={() => wallet.connect()}>
128
+ {wallet.metadata.name}
129
+ </button>
130
+ ))}
131
+ </div>
132
+ )
133
+ }
134
+
135
+ return (
136
+ <div>
137
+ <p>Connected: {activeAddress.slice(0, 8)}...</p>
138
+ <button onClick={callContract} disabled={loading}>
139
+ {loading ? 'Calling...' : 'Call hello()'}
140
+ </button>
141
+ {result && <p>Result: {result}</p>}
142
+ </div>
143
+ )
144
+ }
145
+ ```
146
+
147
+ ---
148
+
149
+ ## Example 3: Deploy and Call Contract
150
+
151
+ Deploy a new contract instance from the frontend.
152
+
153
+ ### DeployContract.tsx
154
+
155
+ ```tsx
156
+ import { useState } from 'react'
157
+ import { useWallet } from '@txnlab/use-wallet-react'
158
+ import { AlgorandClient } from '@algorandfoundation/algokit-utils'
159
+ import { HelloWorldFactory } from './contracts/HelloWorldClient'
160
+
161
+ export function DeployContract() {
162
+ const { transactionSigner, activeAddress } = useWallet()
163
+ const [appId, setAppId] = useState<bigint | null>(null)
164
+ const [loading, setLoading] = useState(false)
165
+
166
+ const deployContract = async () => {
167
+ if (!activeAddress || !transactionSigner) return
168
+
169
+ setLoading(true)
170
+ try {
171
+ const algorand = AlgorandClient.testNet()
172
+ algorand.setSigner(activeAddress, transactionSigner)
173
+
174
+ const factory = new HelloWorldFactory({
175
+ algorand,
176
+ defaultSender: activeAddress,
177
+ })
178
+
179
+ const { appClient } = await factory.deploy({
180
+ onSchemaBreak: 'append',
181
+ onUpdate: 'append',
182
+ })
183
+
184
+ setAppId(appClient.appId)
185
+ } catch (error) {
186
+ console.error('Deploy failed:', error)
187
+ } finally {
188
+ setLoading(false)
189
+ }
190
+ }
191
+
192
+ if (!activeAddress) {
193
+ return <p>Please connect your wallet first.</p>
194
+ }
195
+
196
+ return (
197
+ <div>
198
+ <button onClick={deployContract} disabled={loading}>
199
+ {loading ? 'Deploying...' : 'Deploy Contract'}
200
+ </button>
201
+ {appId && <p>Deployed! App ID: {appId.toString()}</p>}
202
+ </div>
203
+ )
204
+ }
205
+ ```
206
+
207
+ ---
208
+
209
+ ## Example 4: Send Payment
210
+
211
+ Send ALGO to another address.
212
+
213
+ ### SendPayment.tsx
214
+
215
+ ```tsx
216
+ import { useState } from 'react'
217
+ import { useWallet } from '@txnlab/use-wallet-react'
218
+ import { AlgorandClient, algo } from '@algorandfoundation/algokit-utils'
219
+
220
+ export function SendPayment() {
221
+ const { transactionSigner, activeAddress } = useWallet()
222
+ const [receiver, setReceiver] = useState('')
223
+ const [loading, setLoading] = useState(false)
224
+ const [txId, setTxId] = useState('')
225
+
226
+ const sendPayment = async () => {
227
+ if (!activeAddress || !transactionSigner || !receiver) return
228
+
229
+ setLoading(true)
230
+ try {
231
+ const algorand = AlgorandClient.testNet()
232
+
233
+ const result = await algorand.send.payment({
234
+ sender: activeAddress,
235
+ receiver: receiver,
236
+ amount: algo(1),
237
+ signer: transactionSigner,
238
+ })
239
+
240
+ setTxId(result.txIds[0])
241
+ } catch (error) {
242
+ console.error('Payment failed:', error)
243
+ } finally {
244
+ setLoading(false)
245
+ }
246
+ }
247
+
248
+ if (!activeAddress) {
249
+ return <p>Please connect your wallet first.</p>
250
+ }
251
+
252
+ return (
253
+ <div>
254
+ <input
255
+ type="text"
256
+ placeholder="Receiver address"
257
+ value={receiver}
258
+ onChange={(e) => setReceiver(e.target.value)}
259
+ />
260
+ <button onClick={sendPayment} disabled={loading || receiver.length !== 58}>
261
+ {loading ? 'Sending...' : 'Send 1 ALGO'}
262
+ </button>
263
+ {txId && <p>Sent! TX: {txId}</p>}
264
+ </div>
265
+ )
266
+ }
267
+ ```
268
+
269
+ ---
270
+
271
+ ## Example 5: Multiple Account Selection
272
+
273
+ Handle wallets with multiple accounts.
274
+
275
+ ### AccountSelector.tsx
276
+
277
+ ```tsx
278
+ import { useWallet } from '@txnlab/use-wallet-react'
279
+
280
+ export function AccountSelector() {
281
+ const { activeWallet, activeWalletAccounts, activeAddress } = useWallet()
282
+
283
+ if (!activeWallet || activeWalletAccounts.length <= 1) {
284
+ return null
285
+ }
286
+
287
+ return (
288
+ <div>
289
+ <label>Select Account:</label>
290
+ <select
291
+ value={activeAddress ?? ''}
292
+ onChange={(e) => activeWallet.setActiveAccount(e.target.value)}
293
+ >
294
+ {activeWalletAccounts.map((account) => (
295
+ <option key={account.address} value={account.address}>
296
+ {account.name || account.address.slice(0, 8) + '...'}
297
+ </option>
298
+ ))}
299
+ </select>
300
+ </div>
301
+ )
302
+ }
303
+ ```
304
+
305
+ ---
306
+
307
+ ## Example 6: Contract with Arguments
308
+
309
+ Call a contract method with typed arguments.
310
+
311
+ ### CounterContract.tsx
312
+
313
+ ```tsx
314
+ import { useState } from 'react'
315
+ import { useWallet } from '@txnlab/use-wallet-react'
316
+ import { AlgorandClient } from '@algorandfoundation/algokit-utils'
317
+ import { CounterClient } from './contracts/CounterClient'
318
+
319
+ const APP_ID = 12345n
320
+
321
+ export function CounterContract() {
322
+ const { transactionSigner, activeAddress } = useWallet()
323
+ const [count, setCount] = useState<bigint | null>(null)
324
+
325
+ const getClient = () => {
326
+ if (!activeAddress || !transactionSigner) return null
327
+
328
+ const algorand = AlgorandClient.testNet()
329
+ algorand.setSigner(activeAddress, transactionSigner)
330
+
331
+ return algorand.client.getTypedAppClientById(CounterClient, {
332
+ appId: APP_ID,
333
+ defaultSender: activeAddress,
334
+ })
335
+ }
336
+
337
+ const increment = async () => {
338
+ const client = getClient()
339
+ if (!client) return
340
+
341
+ const result = await client.send.increment()
342
+ setCount(result.return ?? 0n)
343
+ }
344
+
345
+ const add = async (value: bigint) => {
346
+ const client = getClient()
347
+ if (!client) return
348
+
349
+ const result = await client.send.add({ args: { value } })
350
+ setCount(result.return ?? 0n)
351
+ }
352
+
353
+ const readCount = async () => {
354
+ const client = getClient()
355
+ if (!client) return
356
+
357
+ const result = await client.send.getCount()
358
+ setCount(result.return ?? 0n)
359
+ }
360
+
361
+ if (!activeAddress) {
362
+ return <p>Connect wallet to interact with counter.</p>
363
+ }
364
+
365
+ return (
366
+ <div>
367
+ <p>Count: {count?.toString() ?? 'Unknown'}</p>
368
+ <button onClick={readCount}>Read Count</button>
369
+ <button onClick={increment}>Increment</button>
370
+ <button onClick={() => add(5n)}>Add 5</button>
371
+ <button onClick={() => add(10n)}>Add 10</button>
372
+ </div>
373
+ )
374
+ }
375
+ ```
376
+
377
+ ---
378
+
379
+ ## Example 7: Read Global State
380
+
381
+ Read contract global state without sending a transaction.
382
+
383
+ ### ReadState.tsx
384
+
385
+ ```tsx
386
+ import { useState, useEffect } from 'react'
387
+ import { useWallet } from '@txnlab/use-wallet-react'
388
+ import { AlgorandClient } from '@algorandfoundation/algokit-utils'
389
+ import { MyContractClient } from './contracts/MyContractClient'
390
+
391
+ const APP_ID = 12345n
392
+
393
+ export function ReadState() {
394
+ const { activeAddress } = useWallet()
395
+ const [globalState, setGlobalState] = useState<Record<string, unknown>>({})
396
+
397
+ useEffect(() => {
398
+ const fetchState = async () => {
399
+ const algorand = AlgorandClient.testNet()
400
+
401
+ // Reading state doesn't require a signer
402
+ const appClient = algorand.client.getTypedAppClientById(MyContractClient, {
403
+ appId: APP_ID,
404
+ })
405
+
406
+ // Access typed state if available
407
+ const state = await appClient.state.global.getAll()
408
+ setGlobalState(state as Record<string, unknown>)
409
+ }
410
+
411
+ fetchState()
412
+ }, [])
413
+
414
+ return (
415
+ <div>
416
+ <h3>Global State</h3>
417
+ <pre>{JSON.stringify(globalState, null, 2)}</pre>
418
+ </div>
419
+ )
420
+ }
421
+ ```
422
+
423
+ ---
424
+
425
+ ## Example 8: Custom Hook for Contract
426
+
427
+ Create a reusable hook for contract interactions.
428
+
429
+ ### useContract.ts
430
+
431
+ ```tsx
432
+ import { useMemo } from 'react'
433
+ import { useWallet } from '@txnlab/use-wallet-react'
434
+ import { AlgorandClient } from '@algorandfoundation/algokit-utils'
435
+ import { MyContractClient } from './contracts/MyContractClient'
436
+
437
+ const APP_ID = 12345n
438
+
439
+ export function useContract() {
440
+ const { transactionSigner, activeAddress, isReady } = useWallet()
441
+
442
+ const client = useMemo(() => {
443
+ if (!activeAddress || !transactionSigner || !isReady) return null
444
+
445
+ const algorand = AlgorandClient.testNet()
446
+ algorand.setSigner(activeAddress, transactionSigner)
447
+
448
+ return algorand.client.getTypedAppClientById(MyContractClient, {
449
+ appId: APP_ID,
450
+ defaultSender: activeAddress,
451
+ })
452
+ }, [activeAddress, transactionSigner, isReady])
453
+
454
+ return {
455
+ client,
456
+ isConnected: !!activeAddress,
457
+ address: activeAddress,
458
+ }
459
+ }
460
+ ```
461
+
462
+ ### Usage
463
+
464
+ ```tsx
465
+ import { useContract } from './useContract'
466
+
467
+ function MyComponent() {
468
+ const { client, isConnected } = useContract()
469
+
470
+ const callMethod = async () => {
471
+ if (!client) return
472
+ const result = await client.send.myMethod({ args: { value: 42n } })
473
+ console.log(result.return)
474
+ }
475
+
476
+ if (!isConnected) return <p>Connect wallet first</p>
477
+
478
+ return <button onClick={callMethod}>Call Method</button>
479
+ }
480
+ ```
481
+
482
+ ---
483
+
484
+ ## Project Structure
485
+
486
+ Recommended file organization:
487
+
488
+ ```
489
+ src/
490
+ ├── App.tsx # Root with WalletProvider
491
+ ├── components/
492
+ │ ├── WalletConnect.tsx # Wallet connection UI
493
+ │ ├── AccountSelector.tsx # Multi-account selection
494
+ │ └── ContractInteraction.tsx
495
+ ├── contracts/
496
+ │ └── MyContractClient.ts # Generated typed client
497
+ ├── hooks/
498
+ │ └── useContract.ts # Custom contract hook
499
+ └── config/
500
+ └── wallet.ts # WalletManager configuration
501
+ ```
502
+
503
+ ### config/wallet.ts
504
+
505
+ ```tsx
506
+ import { NetworkId, WalletId, WalletManager } from '@txnlab/use-wallet-react'
507
+
508
+ export const walletManager = new WalletManager({
509
+ wallets: [WalletId.PERA, WalletId.DEFLY, WalletId.EXODUS],
510
+ defaultNetwork: NetworkId.TESTNET,
511
+ })
512
+ ```
513
+
514
+ Then in App.tsx:
515
+
516
+ ```tsx
517
+ import { WalletProvider } from '@txnlab/use-wallet-react'
518
+ import { walletManager } from './config/wallet'
519
+
520
+ export default function App() {
521
+ return (
522
+ <WalletProvider manager={walletManager}>
523
+ <YourApp />
524
+ </WalletProvider>
525
+ )
526
+ }
527
+ ```