# @avalabs/avacloud-waas-react

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.

[![npm version](https://img.shields.io/npm/v/@avalabs/avacloud-waas-react.svg)](https://www.npmjs.com/package/@avalabs/avacloud-waas-react)
[![License](https://img.shields.io/npm/l/@avalabs/avacloud-waas-react.svg)](https://github.com/ava-labs/avacloud-waas-react/blob/main/LICENSE)


## Installation

```bash
# npm
npm install @avalabs/avacloud-waas-react

# yarn
yarn add @avalabs/avacloud-waas-react

# pnpm
pnpm add @avalabs/avacloud-waas-react
```

## Quick Start

Wrap your application with the `AvaCloudWalletProvider`:

```tsx
import { AvaCloudWalletProvider } from '@avalabs/avacloud-waas-react';

function App() {
  return (
    <AvaCloudWalletProvider 
      orgId="your-avacloud-org-id" // Required
      chainId={43113} // Avalanche Fuji Testnet
    >
      <YourApp />
    </AvaCloudWalletProvider>
  );
}
```

Use the wallet hooks and components in your application:

```tsx
import { useAvaCloudWallet, LoginButton, WalletDisplay } from '@avalabs/avacloud-waas-react';

function YourComponent() {
  const { isAuthenticated, isLoading, user, wallet } = useAvaCloudWallet();

  if (isLoading) {
    return <div>Loading...</div>;
  }

  return (
    <div>
      {isAuthenticated ? (
        <>
          <p>Welcome, {user?.email || 'User'}!</p>
          <WalletDisplay />
        </>
      ) : (
        <LoginButton />
      )}
    </div>
  );
}
```

## Core Components

### AvaCloudWalletProvider

The main provider component that wraps your application and provides wallet context.

```tsx
<AvaCloudWalletProvider
  orgId="your-avacloud-org-id" // Required - your AvaCloud organization ID
  chainId={43113}               // Optional - defaults to Avalanche Fuji Testnet
  darkMode={false}              // Optional - theme mode for UI components
  onAuthSuccess={(user) => console.log('Auth success', user)}
  onAuthError={(error) => console.error('Auth error', error)}
  onWalletUpdate={(wallet) => console.log('Wallet updated', wallet)}
>
  {children}
</AvaCloudWalletProvider>
```

#### Props

| Prop | Type | Description |
|------|------|-------------|
| `orgId` | `string` | **Required** - Your AvaCloud organization ID used to fetch wallet configuration |
| `env` | `'local' \| 'development' \| 'prod'` | Environment to use (default: `'prod'`) |
| `chainId` | `number` | EVM chain ID (default: `43113` - Avalanche Fuji Testnet) |
| `darkMode` | `boolean` | Enable dark mode for UI components (default: `false`) |
| `onAuthSuccess` | `(user: Auth0User) => void` | Callback on successful authentication |
| `onAuthError` | `(error: Error) => void` | Callback on authentication error |
| `onWalletUpdate` | `(wallet: WalletInfo) => void` | Callback when wallet information updates |

### UI Components

- `LoginButton`: Button component for initiating the login flow
- `WalletButton`: Button component for displaying wallet information and actions
- `WalletDisplay`: Component for displaying wallet address and balance
- `UserProfile`: Component for displaying user profile information
- `WalletCard`: Card component for displaying wallet information
- `TokensView`: Component for displaying token balances
- `SendView`: Component for sending tokens
- `ReceiveView`: Component for receiving tokens (displays QR code)
- `ExportView`: Component for exporting wallet information

## Hooks

### useAvaCloudWallet

The main hook for accessing wallet state and methods.

```tsx
const {
  isAuthenticated,
  isLoading,
  user,
  wallet,
  login,
  logout,
  addAccount,
} = useAvaCloudWallet();
```

### useAuth

Simplified hook for basic authentication state.

```tsx
const { isAuthenticated, login, logout } = useAuth();
```

### useSignMessage

Hook for signing messages with the connected wallet.

```tsx
const { signMessage, isLoading, error } = useSignMessage();

const handleSign = async () => {
  try {
    const signature = await signMessage('Hello, AvaCloud!');
    console.log('Signature:', signature);
  } catch (error) {
    console.error('Error signing message:', error);
  }
};
```

### useSignTransaction

Hook for signing transactions with the connected wallet.

```tsx
const { signTransaction, isLoading, error } = useSignTransaction();

const handleSignTx = async () => {
  try {
    const signedTx = await signTransaction({
      to: '0x...',
      value: '0.1',
      data: '0x...',
    });
    console.log('Signed transaction:', signedTx);
  } catch (error) {
    console.error('Error signing transaction:', error);
  }
};
```

### useTransferTokens

Hook for transferring tokens.

```tsx
const { transfer, isLoading, error } = useTransferTokens();

const handleTransfer = async () => {
  try {
    const txHash = await transfer({
      to: '0x...',
      amount: '0.1',
      tokenAddress: '0x...', // Optional, use null for native token
    });
    console.log('Transaction hash:', txHash);
  } catch (error) {
    console.error('Error transferring tokens:', error);
  }
};
```

### useUserWallets

Hook for accessing and managing user wallets.

```tsx
const { wallets, isLoading, error } = useUserWallets();
```

### useChainId

Hook for accessing and setting the current chain ID.

```tsx
const { chainId, setChainId } = useChainId();
```

## WAGMI Integration

This SDK includes a WAGMI connector that allows you to use AvaCloud wallets with WAGMI (React Ethereum Library).

### Prerequisites

Install the required WAGMI dependencies:

```bash
npm install wagmi viem@2.x @tanstack/react-query
```

### Setting up WAGMI with AvaCloud

```tsx
import { WagmiProvider, createConfig } from 'wagmi';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { avaCloudWallet } from '@avalabs/avacloud-waas-react';
import { avalancheFuji } from 'wagmi/chains';
import { http } from 'wagmi';

const queryClient = new QueryClient();

const config = createConfig({
  chains: [avalancheFuji],
  connectors: [
    avaCloudWallet(),
  ],
  transports: {
    [avalancheFuji.id]: http(),
  },
});

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <WagmiProvider config={config}>
        <AvaCloudWalletProvider orgId="your-avacloud-org-id">
          <YourApp />
        </AvaCloudWalletProvider>
      </WagmiProvider>
    </QueryClientProvider>
  );
}
```

### Using WAGMI Hooks

Once configured, use standard WAGMI hooks with your AvaCloud wallet:

```tsx
import { useAccount, useConnect, useDisconnect, useSignMessage } from 'wagmi';

function WagmiExample() {
  const { address, isConnected } = useAccount();
  const { connect, connectors } = useConnect();
  const { disconnect } = useDisconnect();
  const { signMessage } = useSignMessage();

  const handleConnect = () => {
    const avaCloudConnector = connectors.find(c => c.id === 'avaCloudWallet');
    if (avaCloudConnector) {
      connect({ connector: avaCloudConnector });
    }
  };

  const handleSign = async () => {
    const signature = await signMessage({ message: 'Hello from WAGMI!' });
    console.log('Signature:', signature);
  };

  return (
    <div>
      {isConnected ? (
        <>
          <p>Connected: {address}</p>
          <button onClick={() => disconnect()}>Disconnect</button>
          <button onClick={handleSign}>Sign Message</button>
        </>
      ) : (
        <button onClick={handleConnect}>Connect AvaCloud Wallet</button>
      )}
    </div>
  );
}
```

### Important Notes

- The AvaCloud WAGMI connector requires the `AvaCloudWalletProvider` to be present in your component tree
- Authentication is still managed through the AvaCloud SDK's authentication flow
- The connector automatically syncs with the wallet state from `AvaCloudWalletProvider`
- All standard WAGMI hooks and functionality are supported

## Advanced Usage

### Theme Customization

Use the `ThemeProvider` to customize the appearance of UI components:

```tsx
import { ThemeProvider } from '@avalabs/avacloud-waas-react';

function App() {
  return (
    <ThemeProvider darkMode={true}>
      <YourApp />
    </ThemeProvider>
  );
}
```

### Custom Authentication Flow

You can implement a custom authentication flow using the lower-level hooks:

```tsx
import { usePostMessage } from '@avalabs/avacloud-waas-react';

function CustomAuth() {
  const { sendMessage, lastMessage } = usePostMessage();

  const handleCustomLogin = () => {
    sendMessage({
      type: 'login',
      payload: {
        // Custom payload
      }
    });
  };

  // Handle response in useEffect
  useEffect(() => {
    if (lastMessage?.type === 'login_success') {
      // Handle successful login
    }
  }, [lastMessage]);

  return (
    <button onClick={handleCustomLogin}>
      Custom Login
    </button>
  );
}
```

## Browser Support

- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)

## Contributing

We welcome contributions! Please see [CONTRIBUTING.md](https://github.com/ava-labs/avacloud-waas-react/blob/main/CONTRIBUTING.md) for details.

## License

MIT © [Ava Labs, Inc.](https://github.com/ava-labs) 