Skip to main content

Universal Wallet Adapter

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 a universal wallet adapter hosted here, which is largely based on Demox Labs' Leo Wallet Adapter.

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

Installation

First, install the required packages:

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

Setup

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 (wallets is required):

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

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

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

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

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 Hook

After setup, you can use the useWallet hook from @demox-labs/aleo-wallet-adapter-react. The hook provides the following interface:

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.