@avalabs/avacloud-waas-react 1.0.0-canary.1

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.
package/README.md ADDED
@@ -0,0 +1,447 @@
1
+ # @avalabs/avacloud-waas-react
2
+
3
+ Official React SDK for AvaCloud Wallet-as-a-Service (WaaS) integration. This library provides a seamless way to integrate AvaCloud wallet functionality into your React applications.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@avalabs/avacloud-waas-react.svg)](https://www.npmjs.com/package/@avalabs/avacloud-waas-react)
6
+ [![License](https://img.shields.io/npm/l/@avalabs/avacloud-waas-react.svg)](https://github.com/ava-labs/avacloud-waas-react/blob/main/LICENSE)
7
+
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ # npm
13
+ npm install @avalabs/avacloud-waas-react
14
+
15
+ # yarn
16
+ yarn add @avalabs/avacloud-waas-react
17
+
18
+ # pnpm
19
+ pnpm add @avalabs/avacloud-waas-react
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ Wrap your application with the `AvaCloudWalletProvider`:
25
+
26
+ ```tsx
27
+ import { AvaCloudWalletProvider } from '@avalabs/avacloud-waas-react';
28
+
29
+ function App() {
30
+ return (
31
+ <AvaCloudWalletProvider
32
+ orgId="your-avacloud-org-id" // Required
33
+ chainId={43113} // Avalanche Fuji Testnet
34
+ >
35
+ <YourApp />
36
+ </AvaCloudWalletProvider>
37
+ );
38
+ }
39
+ ```
40
+
41
+ Use the wallet hooks and components in your application:
42
+
43
+ ```tsx
44
+ import { useAvaCloudWallet, LoginButton, WalletDisplay } from '@avalabs/avacloud-waas-react';
45
+
46
+ function YourComponent() {
47
+ const { isAuthenticated, isLoading, user, wallet } = useAvaCloudWallet();
48
+
49
+ if (isLoading) {
50
+ return <div>Loading...</div>;
51
+ }
52
+
53
+ return (
54
+ <div>
55
+ {isAuthenticated ? (
56
+ <>
57
+ <p>Welcome, {user?.email || 'User'}!</p>
58
+ <WalletDisplay />
59
+ </>
60
+ ) : (
61
+ <LoginButton />
62
+ )}
63
+ </div>
64
+ );
65
+ }
66
+ ```
67
+
68
+ ## Core Components
69
+
70
+ ### AvaCloudWalletProvider
71
+
72
+ The main provider component that wraps your application and provides wallet context.
73
+
74
+ ```tsx
75
+ <AvaCloudWalletProvider
76
+ orgId="your-avacloud-org-id" // Required - your AvaCloud organization ID
77
+ chainId={43113} // Optional - defaults to Avalanche Fuji Testnet
78
+ darkMode={false} // Optional - theme mode for UI components
79
+ onAuthSuccess={(user) => console.log('Auth success', user)}
80
+ onAuthError={(error) => console.error('Auth error', error)}
81
+ onWalletUpdate={(wallet) => console.log('Wallet updated', wallet)}
82
+ >
83
+ {children}
84
+ </AvaCloudWalletProvider>
85
+ ```
86
+
87
+ #### Props
88
+
89
+ | Prop | Type | Description |
90
+ |------|------|-------------|
91
+ | `orgId` | `string` | **Required** - Your AvaCloud organization ID used to fetch wallet configuration |
92
+ | `env` | `'local' \| 'development' \| 'prod'` | Environment to use (default: `'prod'`) |
93
+ | `chainId` | `number` | EVM chain ID (default: `43113` - Avalanche Fuji Testnet) |
94
+ | `darkMode` | `boolean` | Enable dark mode for UI components (default: `false`) |
95
+ | `onAuthSuccess` | `(user: Auth0User) => void` | Callback on successful authentication |
96
+ | `onAuthError` | `(error: Error) => void` | Callback on authentication error |
97
+ | `onWalletUpdate` | `(wallet: WalletInfo) => void` | Callback when wallet information updates |
98
+
99
+ ### UI Components
100
+
101
+ - `LoginButton`: Button component for initiating the login flow
102
+ - `WalletButton`: Button component for displaying wallet information and actions
103
+ - `WalletDisplay`: Component for displaying wallet address and balance
104
+ - `UserProfile`: Component for displaying user profile information
105
+ - `WalletCard`: Card component for displaying wallet information
106
+ - `TokensView`: Component for displaying token balances
107
+ - `SendView`: Component for sending tokens
108
+ - `ReceiveView`: Component for receiving tokens (displays QR code)
109
+ - `ExportView`: Component for exporting wallet information
110
+
111
+ ## Hooks
112
+
113
+ ### useAvaCloudWallet
114
+
115
+ The main hook for accessing wallet state and methods.
116
+
117
+ ```tsx
118
+ const {
119
+ isAuthenticated,
120
+ isLoading,
121
+ user,
122
+ wallet,
123
+ login,
124
+ logout,
125
+ addAccount,
126
+ } = useAvaCloudWallet();
127
+ ```
128
+
129
+ ### useAuth
130
+
131
+ Simplified hook for basic authentication state.
132
+
133
+ ```tsx
134
+ const { isAuthenticated, login, logout } = useAuth();
135
+ ```
136
+
137
+ ### useSignMessage
138
+
139
+ Hook for signing messages with the connected wallet.
140
+
141
+ ```tsx
142
+ const { signMessage, isLoading, error } = useSignMessage();
143
+
144
+ const handleSign = async () => {
145
+ try {
146
+ const signature = await signMessage('Hello, AvaCloud!');
147
+ console.log('Signature:', signature);
148
+ } catch (error) {
149
+ console.error('Error signing message:', error);
150
+ }
151
+ };
152
+ ```
153
+
154
+ ### useSignTransaction
155
+
156
+ Hook for signing transactions with the connected wallet.
157
+
158
+ ```tsx
159
+ const { signTransaction, isLoading, error } = useSignTransaction();
160
+
161
+ const handleSignTx = async () => {
162
+ try {
163
+ const signedTx = await signTransaction({
164
+ to: '0x...',
165
+ value: '0.1',
166
+ data: '0x...',
167
+ });
168
+ console.log('Signed transaction:', signedTx);
169
+ } catch (error) {
170
+ console.error('Error signing transaction:', error);
171
+ }
172
+ };
173
+ ```
174
+
175
+ ### useTransferTokens
176
+
177
+ Hook for transferring tokens.
178
+
179
+ ```tsx
180
+ const { transfer, isLoading, error } = useTransferTokens();
181
+
182
+ const handleTransfer = async () => {
183
+ try {
184
+ const txHash = await transfer({
185
+ to: '0x...',
186
+ amount: '0.1',
187
+ tokenAddress: '0x...', // Optional, use null for native token
188
+ });
189
+ console.log('Transaction hash:', txHash);
190
+ } catch (error) {
191
+ console.error('Error transferring tokens:', error);
192
+ }
193
+ };
194
+ ```
195
+
196
+ ### useUserWallets
197
+
198
+ Hook for accessing and managing user wallets.
199
+
200
+ ```tsx
201
+ const { wallets, isLoading, error } = useUserWallets();
202
+ ```
203
+
204
+ ### useChainId
205
+
206
+ Hook for accessing and setting the current chain ID.
207
+
208
+ ```tsx
209
+ const { chainId, setChainId } = useChainId();
210
+ ```
211
+
212
+ ### useGaslessTransaction
213
+
214
+ Hook for sending gasless (meta-)transactions through AvaCloud's gas relayer.
215
+
216
+ ```tsx
217
+ import { useGaslessTransaction, useGlacier } from '@avalabs/avacloud-waas-react';
218
+
219
+ function CounterExample() {
220
+ // Retrieve the current subnet RPC URL from Glacier
221
+ const { blockchain } = useGlacier();
222
+
223
+ const gaslessConfig = {
224
+ relayerUrl: 'https://gas-relayer.avax-test.network/printedapr/testnet/rpc', // AvaCloud relayer RPC
225
+ subnetRpcUrl: blockchain?.rpcUrl || '', // Target subnet RPC
226
+ forwarderAddress: '0x52ec85e43d09889b2bf9e431935356e06f023680', // AvaCloud forwarder
227
+ domainName: 'Counter',
228
+ domainVersion: '1',
229
+ requestType: 'Message',
230
+ suffixType: 'bytes32', // Optional – request suffix type
231
+ suffixName: 'XMKUCJONOFSUSFCYHTYHCLX', // Optional – request suffix name
232
+ } as const;
233
+
234
+ // Counter contract information
235
+ const COUNTER_CONTRACT_ADDRESS = '0xe4bB5F15dc278197FcE9B21e5aC0442a95e25b5f';
236
+ const COUNTER_INCREMENT_ABI = [
237
+ {
238
+ inputs: [],
239
+ name: 'increment',
240
+ outputs: [],
241
+ stateMutability: 'nonpayable',
242
+ type: 'function',
243
+ },
244
+ ] as const;
245
+
246
+ const {
247
+ sendGaslessTransaction,
248
+ isLoading,
249
+ error,
250
+ txHash,
251
+ reset,
252
+ } = useGaslessTransaction({
253
+ gaslessConfig,
254
+ contractAddress: COUNTER_CONTRACT_ADDRESS,
255
+ abi: COUNTER_INCREMENT_ABI,
256
+ });
257
+
258
+ const handleIncrement = () =>
259
+ sendGaslessTransaction({ functionName: 'increment' });
260
+
261
+ return (
262
+ <div>
263
+ <button onClick={handleIncrement} disabled={isLoading}>
264
+ Increment counter (no gas)
265
+ </button>
266
+
267
+ {isLoading && <p>Sending transaction…</p>}
268
+ {txHash && <p>Transaction hash: {txHash}</p>}
269
+ {error && <p style={{ color: 'red' }}>{error}</p>}
270
+
271
+ <button onClick={reset}>Reset</button>
272
+ </div>
273
+ );
274
+ }
275
+ ```
276
+
277
+ **Parameters returned by the hook**
278
+
279
+ | Property | Type | Description |
280
+ |----------|------|-------------|
281
+ | `sendGaslessTransaction` | `(params: { functionName: string; args?: unknown[]; abi?: unknown; contractAddress?: string }) => Promise<void>` | Sends the meta-transaction |
282
+ | `isLoading` | `boolean` | `true` while the transaction is being prepared or broadcast |
283
+ | `error` | `string \| null` | Error message, if any |
284
+ | `txHash` | `string \| null` | Transaction hash once broadcast |
285
+ | `reset` | `() => void` | Resets the hook state |
286
+
287
+
288
+ ## WAGMI Integration
289
+
290
+ This SDK includes a WAGMI connector that allows you to use AvaCloud wallets with WAGMI (React Ethereum Library).
291
+
292
+ ### Prerequisites
293
+
294
+ Install the required WAGMI dependencies:
295
+
296
+ ```bash
297
+ npm install wagmi viem@2.x @tanstack/react-query
298
+ ```
299
+
300
+ ### Setting up WAGMI with AvaCloud
301
+
302
+ ```tsx
303
+ import { WagmiProvider, createConfig } from 'wagmi';
304
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
305
+ import { avaCloudWallet } from '@avalabs/avacloud-waas-react';
306
+ import { avalancheFuji } from 'wagmi/chains';
307
+ import { http } from 'wagmi';
308
+
309
+ const queryClient = new QueryClient();
310
+
311
+ const config = createConfig({
312
+ chains: [avalancheFuji],
313
+ connectors: [
314
+ avaCloudWallet(),
315
+ ],
316
+ transports: {
317
+ [avalancheFuji.id]: http(),
318
+ },
319
+ });
320
+
321
+ function App() {
322
+ return (
323
+ <QueryClientProvider client={queryClient}>
324
+ <WagmiProvider config={config}>
325
+ <AvaCloudWalletProvider orgId="your-avacloud-org-id">
326
+ <YourApp />
327
+ </AvaCloudWalletProvider>
328
+ </WagmiProvider>
329
+ </QueryClientProvider>
330
+ );
331
+ }
332
+ ```
333
+
334
+ ### Using WAGMI Hooks
335
+
336
+ Once configured, use standard WAGMI hooks with your AvaCloud wallet:
337
+
338
+ ```tsx
339
+ import { useAccount, useConnect, useDisconnect, useSignMessage } from 'wagmi';
340
+
341
+ function WagmiExample() {
342
+ const { address, isConnected } = useAccount();
343
+ const { connect, connectors } = useConnect();
344
+ const { disconnect } = useDisconnect();
345
+ const { signMessage } = useSignMessage();
346
+
347
+ const handleConnect = () => {
348
+ const avaCloudConnector = connectors.find(c => c.id === 'avaCloudWallet');
349
+ if (avaCloudConnector) {
350
+ connect({ connector: avaCloudConnector });
351
+ }
352
+ };
353
+
354
+ const handleSign = async () => {
355
+ const signature = await signMessage({ message: 'Hello from WAGMI!' });
356
+ console.log('Signature:', signature);
357
+ };
358
+
359
+ return (
360
+ <div>
361
+ {isConnected ? (
362
+ <>
363
+ <p>Connected: {address}</p>
364
+ <button onClick={() => disconnect()}>Disconnect</button>
365
+ <button onClick={handleSign}>Sign Message</button>
366
+ </>
367
+ ) : (
368
+ <button onClick={handleConnect}>Connect AvaCloud Wallet</button>
369
+ )}
370
+ </div>
371
+ );
372
+ }
373
+ ```
374
+
375
+ ### Important Notes
376
+
377
+ - The AvaCloud WAGMI connector requires the `AvaCloudWalletProvider` to be present in your component tree
378
+ - Authentication is still managed through the AvaCloud SDK's authentication flow
379
+ - The connector automatically syncs with the wallet state from `AvaCloudWalletProvider`
380
+ - All standard WAGMI hooks and functionality are supported
381
+
382
+ ## Advanced Usage
383
+
384
+ ### Theme Customization
385
+
386
+ Use the `ThemeProvider` to customize the appearance of UI components:
387
+
388
+ ```tsx
389
+ import { ThemeProvider } from '@avalabs/avacloud-waas-react';
390
+
391
+ function App() {
392
+ return (
393
+ <ThemeProvider darkMode={true}>
394
+ <YourApp />
395
+ </ThemeProvider>
396
+ );
397
+ }
398
+ ```
399
+
400
+ ### Custom Authentication Flow
401
+
402
+ You can implement a custom authentication flow using the lower-level hooks:
403
+
404
+ ```tsx
405
+ import { usePostMessage } from '@avalabs/avacloud-waas-react';
406
+
407
+ function CustomAuth() {
408
+ const { sendMessage, lastMessage } = usePostMessage();
409
+
410
+ const handleCustomLogin = () => {
411
+ sendMessage({
412
+ type: 'login',
413
+ payload: {
414
+ // Custom payload
415
+ }
416
+ });
417
+ };
418
+
419
+ // Handle response in useEffect
420
+ useEffect(() => {
421
+ if (lastMessage?.type === 'login_success') {
422
+ // Handle successful login
423
+ }
424
+ }, [lastMessage]);
425
+
426
+ return (
427
+ <button onClick={handleCustomLogin}>
428
+ Custom Login
429
+ </button>
430
+ );
431
+ }
432
+ ```
433
+
434
+ ## Browser Support
435
+
436
+ - Chrome (latest)
437
+ - Firefox (latest)
438
+ - Safari (latest)
439
+ - Edge (latest)
440
+
441
+ ## Contributing
442
+
443
+ We welcome contributions! Please see [CONTRIBUTING.md](https://github.com/ava-labs/avacloud-waas-react/blob/main/CONTRIBUTING.md) for details.
444
+
445
+ ## License
446
+
447
+ MIT © [Ava Labs, Inc.](https://github.com/ava-labs)
Binary file