# 6.4 Wallet Adapter

In your web based decentralized applications you will need to interact with your users wallet extensions, to call program functions, sign messages, decypt records... This is the role of wallet adapters library.

While different wallets provide their own adapter SDKs, applications typically want to support multiple wallets to give users flexibility in choosing their preferred wallet. The Aleo community has developed an universal wallet adapter that is hosted [here](https://github.com/arcane-finance-defi/aleo-wallet-adapters), which is largely based on [Demox Labs' Leo Wallet Adapter](https://github.com/demox-labs/aleo-wallet-adapter/tree/pierre-docs-update).

This guide demonstrates how to implement the universal wallet adapter in React applications.

### Installation[​](https://developer.aleo.org/guides/wallets/universal_wallet_adapter#installation) <a href="#installation" id="installation"></a>

First, install the required packages:

```bash
npm install --save \
    @demox-labs/aleo-wallet-adapter-base \
    @demox-labs/aleo-wallet-adapter-react \
    @demox-labs/aleo-wallet-adapter-reactui \
    aleo-adapters
```

### Setup[​](https://developer.aleo.org/guides/wallets/universal_wallet_adapter#setup) <a href="#setup" id="setup"></a>

To use the wallet adapter, wrap your app with both `WalletProvider` and `WalletModalProvider` components. These provide the wallet functionality and UI context respectively.

The `WalletProvider` accepts the following [properties](https://docs.leo.app/aleo-wallet-adapter/packages/core/react/docs/interfaces/walletproviderprops) (`wallets` is required):

```typescript
export interface WalletProviderProps {
    children: ReactNode;
    wallets: Adapter[];             // Required
    decryptPermission?: DecryptPermission;
    programs?: string[];
    network?: WalletAdapterNetwork;
    autoConnect?: boolean;
    onError?: (error: WalletError) => void;
    localStorageKey?: string;
}
```

You can import `DecryptPermission` and `WalletAdapterNetwork` types from `@demox-labs/aleo-wallet-adapter-base`.

### Wallet Configuration[​](https://developer.aleo.org/guides/wallets/universal_wallet_adapter#wallet-configuration) <a href="#wallet-configuration" id="wallet-configuration"></a>

When creating wallet adapters, you can configure them with the following options:

```typescript
export interface LeoWalletAdapterConfig {
    appName?: string;
    isMobile?: boolean;
    mobileWebviewUrl?: string;
}

export interface FoxWalletAdapterConfig {
    appName?: string;
    isMobile?: boolean;
    mobileWebviewUrl?: string;
}

export interface SoterWalletAdapterConfig {
    appName?: string;
}

export interface PuzzleWalletAdapterConfig {
    appName?: string;
    appIconUrl?: string;
    appDescription?: string;
    programIdPermissions: Partial<Record<WalletAdapterNetwork, string[]>>;
}
```

### Implementation Example[​](https://developer.aleo.org/guides/wallets/universal_wallet_adapter#implementation-example) <a href="#implementation-example" id="implementation-example"></a>

Here's a complete example showing how to set up the wallet adapter:

```typescript
import { WalletModalProvider } from "@demox-labs/aleo-wallet-adapter-reactui";
import { WalletProvider } from "@demox-labs/aleo-wallet-adapter-react";
import { DecryptPermission, WalletAdapterNetwork } from "@demox-labs/aleo-wallet-adapter-base";
import { useMemo } from "react";
import { 
  PuzzleWalletAdapter, 
  LeoWalletAdapter, 
  FoxWalletAdapter,
  SoterWalletAdapter 
} from 'aleo-adapters';

export default function Providers({ children }: { children: React.ReactNode }) {
  const wallets = useMemo(
    () => [
      new LeoWalletAdapter({
        appName: 'Aleo app',
      }),
      new PuzzleWalletAdapter({
        programIdPermissions: {
          [WalletAdapterNetwork.MainnetBeta]: ['dApp_1.aleo', 'dApp_1_import.aleo', 'dApp_1_import_2.aleo'],
          [WalletAdapterNetwork.TestnetBeta]: ['dApp_1_test.aleo', 'dApp_1_test_import.aleo', 'dApp_1_test_import_2.aleo']
        },
        appName: 'Aleo app',
        appDescription: 'A privacy-focused DeFi app',
        appIconUrl: ''
      }),
      new FoxWalletAdapter({
        appName: 'Aleo app',
      }),
      new SoterWalletAdapter({
        appName: 'Aleo app',
      })
    ],
    []
  );

  return (
    <WalletProvider
      wallets={wallets}
      decryptPermission={DecryptPermission.UponRequest}
      network={WalletAdapterNetwork.MainnetBeta}
      autoConnect
    >
      <WalletModalProvider>
        {children}
      </WalletModalProvider>
    </WalletProvider>
  );
} 
```

### Using the Wallet Button[​](https://developer.aleo.org/guides/wallets/universal_wallet_adapter#using-the-wallet-button) <a href="#using-the-wallet-button" id="using-the-wallet-button"></a>

Demox Labs provides a pre-built wallet button component that you can easily add to your application. To use it, import the `WalletMultiButton` component from `@demox-labs/aleo-wallet-adapter-reactui` along with its CSS styles.

```typescript
import { WalletMultiButton } from "@demox-labs/aleo-wallet-adapter-reactui";
import "@demox-labs/aleo-wallet-adapter-reactui/dist/styles.css";

export default function WalletButton() {
  return <WalletMultiButton />;
}
```

### Using the Wallet Hook[​](https://developer.aleo.org/guides/wallets/universal_wallet_adapter#using-the-wallet-hook) <a href="#using-the-wallet-hook" id="using-the-wallet-hook"></a>

Once user connected through the wallet button, you can use `useWallet` hook from `@demox-labs/aleo-wallet-adapter-react` to enable access to functions that helps connect and interact with the Aleo network. The hook provides the following interface:

```typescript
export interface WalletContextState {
    autoConnect: boolean;
    wallets: Wallet[];
    wallet: Wallet | null;
    publicKey: string | null;
    connecting: boolean;
    connected: boolean;
    disconnecting: boolean;
    select(walletName: WalletName): void;
    connect(decryptPermission: DecryptPermission, network: WalletAdapterNetwork, programs?: string[]): Promise<void>;
    disconnect(): Promise<void>;
    signMessage(message: Uint8Array): Promise<Uint8Array>;
    decrypt(cipherText: string, tpk?: string, programId?: string, functionName?: string, index?: number): Promise<string>;
    requestRecords(program: string): Promise<any[]>;
    requestTransaction(transaction: AleoTransaction): Promise<string>;
    requestExecution(transaction: AleoTransaction): Promise<string>;
    requestBulkTransactions(transactions: AleoTransaction[]): Promise<string[]>;
    requestDeploy(deployment: AleoDeployment): Promise<string>;
    transactionStatus(transactionId: string): Promise<string>;
    getExecution(transactionId: string): Promise<string>;
    requestRecordPlaintexts(program: string): Promise<any[]>;
}
```

For detailed examples of using these methods, please refer to the [Demox Labs Leo Wallet documentation](https://docs.leo.app/aleo-wallet-adapter).

<br>
