@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 +447 -0
- package/dist/avacloud.png +0 -0
- package/dist/index.d.mts +622 -0
- package/dist/index.d.ts +622 -0
- package/dist/index.js +5014 -0
- package/dist/index.mjs +5034 -0
- package/package.json +64 -0
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
|
+
[](https://www.npmjs.com/package/@avalabs/avacloud-waas-react)
|
|
6
|
+
[](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
|