npm package: @qubitronlabs/crypto-wallet
Description: A comprehensive React/Next.js SDK for wallet provider functionality with deposit, swap, and withdrawal capabilities
Author: Qubitron Labs
Latest version: 0.4.4

# Crypto Wallet SDK

![NPM Version](https://img.shields.io/npm/v/@qubitronlabs/crypto-wallet.svg)

[![License](https://img.shields.io/npm/l/@qubitronlabs/crypto-wallet.svg)](https:/qubitronlabs/crypto-wallet/blob/main/LICENSE)

A comprehensive React.js SDK for wallet provider functionality with deposit, swap, and withdrawal capabilities. This package is designed to integrate seamlessly with applications using Dynamic.xyz for authentication.

## What is this package for?

The `@qubitronlabs/crypto-wallet` SDK provides a set of pre-built React components and hooks to quickly add crypto wallet functionalities to your application. It handles complex logic for deposits, swaps, and withdrawals, and is built on top of Dynamic.xyz for robust user authentication and wallet management.

## Features

-   **Zero Configuration Styling**: CSS automatically bundled with JavaScript - no manual imports needed
-   **Wallet Integration**: Connect to user wallets via Dynamic.xyz
-   **Deposit**: UI and logic for handling crypto deposits
-   **Swap**: A complete swap interface for trading tokens
-   **Withdrawal**: Components and hooks for managing withdrawals
-   **State Management**: Built-in state management with Zustand for tokens, transactions, and network state
-   **Extensible**: Provides hooks and utility functions for building custom wallet features

## Installation

**Important:** Before installing `@qubitronlabs/crypto-wallet`, please add a `.npmrc` file to your project's root directory with the following content. This step is required to properly resolve private Font Awesome packages.

```properties
@awesome.me:registry=https://npm.fontawesome.com/
@fortawesome:registry=https://npm.fontawesome.com/
//npm.fontawesome.com/:_authToken=your_auth_token
```

You can install the package using npm or yarn:

```bash
npm install @qubitronlabs/crypto-wallet
```

or

```bash
yarn add @qubitronlabs/crypto-wallet
```

## Getting Started

### 1. Install Peer Dependencies

This package has several peer dependencies that you need to install in your project.

```bash
npm install @dynamic-labs/ethereum@^4.29.6 @dynamic-labs/sdk-react-core@^4.29.6 @dynamic-labs/wagmi-connector@^4.29.6 @tanstack/react-query@^5.85.8 react@>=18.0.0 react-dom@>=18.0.0 react-router-dom@>=6.0.0 viem@^2.37.1 wagmi@^2.16.9
```

### 2. Styling (No Setup Required)

**The SDK includes all styles automatically bundled in the JavaScript.** No CSS imports or Tailwind setup is required!

### 3. Set up Dynamic SDK

Your application must be wrapped with `DynamicContextProvider` from `@dynamic-labs/sdk-react-core`. This should be set up in your `main.tsx` file as part of the root rendering.

```tsx
// Example: in your main.tsx file
import { createRoot } from "react-dom/client";
import { DynamicContextProvider } from "@dynamic-labs/sdk-react-core";
import { EthereumWalletConnectors } from "@dynamic-labs/ethereum";
import App from "./App";

createRoot(document.getElementById("root")!).render(
	<DynamicContextProvider
		theme="auto"
		settings={{
			environmentId: "YOUR_DYNAMIC_ENVIRONMENT_ID",
			walletConnectors: [EthereumWalletConnectors],
			mobileExperience: "redirect",
			social: {
				strategy: "popup",
			},
		}}
	>
		<App />
	</DynamicContextProvider>
);
```

### 4. Configure the Crypto Wallet SDK

The SDK needs to be configured with your API details and feature flags. Import `setSdkConfig` from `@qubitronlabs/crypto-wallet` and call it once when your application starts. This should be done in your `main.tsx` file before rendering your app.

```typescript
// src/main.tsx - Configure the SDK before rendering
import { setSdkConfig } from "@qubitronlabs/crypto-wallet";

setSdkConfig
	networkId: 137,
	wsUrl: "",
	wsKey: "",
	apiKey: "",
	jwtType: "",
	apiBaseUrl: "",
	allowanceAddress: "",
	features: {
		enableNetworkStateSync: true,
		enableTokenStateSync: true,
		enableTransactionStateSync: true,
		enableWebSocketStateSync: true,
	},
;

// ... rest of your main.tsx setup
```

### 5. Wrap your application with Providers

The `AuthProvider` from this SDK provides authentication context and synchronizes wallet state. It should be placed inside the `DynamicContextProvider` and wrapped with all necessary providers in your `main.tsx` file.

```tsx
// Example: Complete setup in your main.tsx file
import App from "./App";
import "./index.css";
import { StrictMode } from "react";
import { createConfig, http, WagmiProvider } from "wagmi";
import { createRoot } from "react-dom/client";
import { EthereumWalletConnectors } from "@dynamic-labs/ethereum";
import { DynamicContextProvider } from "@dynamic-labs/sdk-react-core";
import { DynamicWagmiConnector } from "@dynamic-labs/wagmi-connector";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { BrowserRouter } from "react-router-dom";
import { AuthProvider, setSdkConfig } from "@qubitronlabs/crypto-wallet";

// Configure the SDK first
setSdkConfig({
	networkId: 137,
	wsUrl: "",
	wsKey: "",
	apiKey: "",
	jwtType: "",
	apiBaseUrl: "",
	allowanceAddress: "",
	features: {
		enableNetworkStateSync: true,
		enableTokenStateSync: true,
		enableTransactionStateSync: true,
		enableWebSocketStateSync: true,
	},
});

const queryClient = new QueryClient();

createRoot(document.getElementById("root")!).render(
	<StrictMode>
		<BrowserRouter>
			<DynamicContextProvider
				theme="auto"
				settings={{
					environmentId: import.meta.env.VITE_DYNAMIC_ENVIRONMENT_ID,
					walletConnectors: [EthereumWalletConnectors],
					mobileExperience: "redirect",
					social: {
						strategy: "popup",
					},
				}}
			>
				<WagmiProvider config={config}>
					<QueryClientProvider client={queryClient}>
						<DynamicWagmiConnector>
							<AuthProvider>
								<App />
							</AuthProvider>
						</DynamicWagmiConnector>
					</QueryClientProvider>
				</WagmiProvider>
			</DynamicContextProvider>
		</BrowserRouter>
	</StrictMode>
);
```

## Usage

A full implementation example:

```tsx
import App from "./App";
import "./index.css";
import { StrictMode } from "react";
import { createConfig, http, WagmiProvider } from "wagmi";
import { createRoot } from "react-dom/client";
import { EthereumWalletConnectors } from "@dynamic-labs/ethereum";
import { DynamicContextProvider } from "@dynamic-labs/sdk-react-core";
import { DynamicWagmiConnector } from "@dynamic-labs/wagmi-connector";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import {
	polygon,
	arbitrum,
	mainnet,
	optimism,
	base,
	avalanche,
	bsc,
	linea,
	zksync,
} from "wagmi/chains";
import { AuthProvider, setSdkConfig } from "@qubitronlabs/crypto-wallet";
import { BrowserRouter as Router } from "react-router-dom";

const queryClient = new QueryClient();

setSdkConfig({
	networkId: 137,
	wsUrl: "",
	wsKey: "",
	apiKey: "",
	jwtType: "",
	apiBaseUrl: "",
	allowanceAddress: "",
	features: {
		enableNetworkStateSync: true,
		enableTokenStateSync: true,
		enableTransactionStateSync: true,
		enableWebSocketStateSync: true,
	},
});

const networks = [
	polygon,
	arbitrum,
	mainnet,
	optimism,
	base,
	avalanche,
	bsc,
	linea,
	zksync,
] as const;

const config = createConfig({
	chains: networks,
	multiInjectedProviderDiscovery: false,
	transports: {
		[polygon.id]: http(),
		[arbitrum.id]: http(),
		[mainnet.id]: http(),
		[optimism.id]: http(),
		[base.id]: http(),
		[avalanche.id]: http(),
		[bsc.id]: http(),
		[linea.id]: http(),
		[zksync.id]: http(),
	},
});

createRoot(document.getElementById("root")!).render(
	<StrictMode>
		<Router>
			<DynamicContextProvider
				theme="auto"
				settings={{
					environmentId: "YOUR_DYNAMIC_ENVIRONMENT_ID",
					walletConnectors: [EthereumWalletConnectors],
					mobileExperience: "redirect",
					social: {
						strategy: "popup",
					},
				}}
			>
				<WagmiProvider config={config}>
					<QueryClientProvider client={queryClient}>
						<DynamicWagmiConnector>
							<AuthProvider>
								<App />
							</AuthProvider>
						</DynamicWagmiConnector>
					</QueryClientProvider>
				</WagmiProvider>
			</DynamicContextProvider>
		</Router>
	</StrictMode>
);
```

### Using UI Components

The SDK provides ready-to-use components. For example, you can use `DepositPanel`, `DepositPanelWeb2`, and `WithdrawPanel`.

```tsx
import {
	DepositPanel,
	DepositPanelWeb2,
	WithdrawPanel,
	Toaster,
	getDefaultTokens,
} from "@qubitronlabs/crypto-wallet";

function MyWalletPage() {
	const [usdtToken, usdcToken] = getDefaultTokens();

	return (
		<div>
			<h1>My Wallet</h1>
			<DepositPanel />
			<DepositPanelWeb2
				walletAddress="0x1234567890abcdef..."
				amount="100"
				tokens={[usdtToken, usdcToken]}
			/>
			<WithdrawPanel />
			{/* Add Toaster for notifications */}
			<Toaster position="top-center" />
		</div>
	);
}
```

#### DepositPanelWeb2 Component

The `DepositPanelWeb2` component provides a Web2-style deposit experience with the following features:

-   **QR Code Generation**: Automatically generates a QR code from the provided wallet address
-   **Network Selection**: Dropdown selector for choosing between supported blockchain networks
-   **Token Selection**: Dropdown selector for choosing between supported tokens (defaults to USDT/USDC)
-   **Amount Input**: Numeric input field with validation for displaying deposit amount
-   **Countdown Timer**: 30-minute session timer that automatically closes the modal when expired
-   **Copy Functionality**: One-click wallet address copying with toast notifications
-   **Modal Interface**: Clean popup interface that opens on button click

**Props:**

```tsx
interface DepositPanelWeb2Props {
	isOpen?: boolean; // Boolean responsible for opening the modal
	onClose?: () => void; // A function use to run side-effects when the modal closes
	countDown?: number; // An optional countDown prop for setting manual countdowns
	walletAddress: string; // Wallet address for QR code generation
	amount: string; // Default amount to display
	tokens: Token[]; // Array of supported tokens
	networks?: EvmNetwork[]; // Optional array of supported networks
	onTokenSelect: (token: Token) => void; // Callback for token selection
	onNetworkSelect?: (network: EvmNetwork) => void; // Callback for network selection
}
```

**Basic Usage:**

```tsx
<DepositPanelWeb2
	walletAddress="0x1234567890abcdef..."
	amount="100"
	tokens={[usdtToken, usdcToken]}
	onTokenSelect={handleTokenSelect}
/>
```

**Advanced Usage with Network Selection:**

```tsx
const networks = [
	{
		networkId: 1,
		name: "Ethereum",
		vanityName: "Ethereum Mainnet",
		chainId: 1,
		iconUrls: ["https://..."],
		rpcUrls: ["https://..."],
		nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
		blockExplorerUrls: ["https://etherscan.io"],
	},
	// ... more networks
];

const handleTokenSelect = (token: Token) => {
	console.log("Selected token:", token);
};

const handleNetworkSelect = (network: EvmNetwork) => {
	console.log("Selected network:", network);
	// Handle network switch logic here
};

<DepositPanelWeb2
	walletAddress="0x1234567890abcdef..."
	amount="100"
	tokens={[usdtToken, usdcToken]}
	networks={networks}
	onTokenSelect={handleTokenSelect}
	onNetworkSelect={handleNetworkSelect}
/>;
```

#### Toaster Component

The `Toaster` component provides toast notifications throughout your application using the Sonner library. It should be placed at the root level of your application to display notifications from anywhere.

**Features:**

-   **Multiple Types**: Success, error, warning, and info notifications
-   **Positioning**: Configurable positioning (top-center, bottom-right, etc.)
-   **Auto-dismiss**: Automatic dismissal with configurable duration
-   **Rich Content**: Support for titles, descriptions, and custom styling

**Usage:**

```tsx
import { Toaster } from "@qubitronlabs/crypto-wallet";

// Place at the root of your app
function App() {
	return (
		<div>
			{/* Your app content */}
			<Toaster position="top-center" />
		</div>
	);
}
```

**Triggering Notifications:**

```tsx
import { toast } from "sonner";

// Success notification
toast.success("Success!", {
	description: "Your action was completed successfully.",
	duration: 3000,
});

// Error notification
toast.error("Error occurred", {
	description: "Something went wrong. Please try again.",
	duration: 4000,
});

// Warning notification
toast.warning("Session Expired", {
	description: "Your session has expired. Please log in again.",
	duration: 5000,
});
```

### Using Hooks

For more custom implementations, you can use the provided hooks. For example, `useDynamicAuth` to access user and authentication status, or `useTokens` to get a list of available tokens.

```tsx
import { useDynamicAuth, useTokens } from "@qubitronlabs/crypto-wallet";

function UserProfile() {
	const { user, isWalletConnected } = useDynamicAuth();
	const { tokens } = useTokens();

	if (!isWalletConnected) {
		return <div>Please connect your wallet.</div>;
	}

	return (
		<div>
			<h2>Welcome, {user?.nickname}</h2>
			<h3>Available Tokens:</h3>
			<ul>
				{tokens.map((token) => (
					<li key={token.symbol}>{token.name}</li>
				))}
			</ul>
		</div>
	);
}
```

## Configuration Details

The `setSdkConfig` function accepts a configuration object with the following properties:

-   `apiBaseUrl` (string, required): The base URL for your backend API.
-   `apiKey` (string, required): Your API key for authenticated requests.
-   `wsUrl` (string): URL for the WebSocket server for real-time updates.
-   `wsKey` (string): Key for the WebSocket server.
-   `networkId` (number): The chain ID of the network to use.
-   `jwtType` (string): The type of JWT to use.
-   `allowanceAddress` (string): The address to grant allowance to.
-   `abi` (object, optional): Custom smart contract ABI to use for blockchain interactions. If not provided, defaults to the PandaByteCore ABI.
-   `withdrawFunctionName` (string, optional): The name of the withdrawal function in your smart contract. If not provided, defaults to "Withdraw_Web".
-   `features` (object): A set of flags to enable or disable certain features.
    -   `enableWebSocketStateSync` (boolean): Enables real-time state synchronization.
    -   `enableNetworkStateSync` (boolean): Enables network state synchronization.
    -   `enableTokenStateSync` (boolean): Enables token state synchronization.
    -   `enableTransactionStateSync` (boolean): Enables transaction state synchronization.
-   `logout` (object): Configuration for logout behavior.
    -   `keysToClear` (string[]): localStorage keys to clear on logout.
    -   `keyPrefixesToClear` (string[]): localStorage key prefixes to clear on logout.

## Full List of Exports

This package exports a variety of components, hooks, and utilities to help you build your crypto application.

### Configuration

-   `setSdkConfig`: A function to initialize the SDK with your configuration. This must be called once when your application starts.

### Providers & Context

-   `AuthProvider`: Provides authentication state and user context. Must be a child of Dynamic's `DynamicContextProvider` and `react-router-dom`'s `Router`.
-   `AuthContext`: The context for authentication data.

### UI Components

#### Feature Components

-   `DepositPanel`: A component that provides a UI for users to deposit assets.
-   `DepositPanelWeb2`: A Web2-style deposit component with QR code generation, network selection, token selection, and countdown timer for payment processing.
-   `DepositTransactionPending`: A component to display pending deposit transactions.
-   `SwapPanel`: A component that provides a UI for swapping tokens.
-   `SwapPanelSkeleton`: A skeleton loader for the `SwapPanel`.
-   `TabsSidebar`: A sidebar component with tabs for navigation.
-   `TransactionModal`: A modal for displaying transaction details.
-   `TransactionModalSkeleton`: A skeleton loader for the `TransactionModal`.
-   `WalletInfoPanel`: A panel to display wallet information.
-   `WalletInfoSkeleton`: A skeleton loader for the `WalletInfoPanel`.
-   `WithdrawPanel`: A component that provides a UI for withdrawing assets.
-   `WithdrawSummary`: A component to display a summary of a withdrawal.
-   `WithdrawTransactionPending`: A component to display pending withdrawal transactions.
-   `WithdrawalSuccessModal`: A modal to show that a withdrawal was successful.
-   `ProfileInfoCard`: A card component to display user profile information.
-   `ProfileInfoCardSkeleton`: A skeleton loader for the `ProfileInfoCard`.
-   `Toaster`: A toast notification component from Sonner for displaying user feedback messages.
-   `TipPanel`:A component that provides a UI for tipping other users or addresses. Includes token selection, amount input, balance display, USD estimate, and transaction status feedback.
-   `TipTransactionPending`:A component to display the pending or confirmed state of a tip transaction.

#### Common Components

-   `CopyWalletAddressButton`: A button that copies the user's wallet address to the clipboard.
-   `NetworkSelector`: A dropdown for selecting the active blockchain network.
-   `TokenListModal`: A modal dialog that displays a list of available tokens.
-   `TokenListRows`: The row components used within the `TokenListModal`.

#### State Synchronizers

-   `NetworkStateSynchronizer`: A component to keep network state in sync.
-   `TokenStateSynchronizer`: A component to keep token state in sync.
-   `TransactionStateSynchronizer`: A component to keep transaction state in sync.
-   `WebSocketStateSynchronizer`: A component to keep WebSocket state in sync.

<!-- #### UI Primitives

A set of basic, unstyled components used to build more complex UI elements.

-   `Alert`, `Avatar`, `Badge`, `Button`, `Card`, `Collapsible`, `Command`, `Dialog`, `DropdownMenu`, `Input`, `Label`, `Popover`, `Select`, `Separator`, `Skeleton`, `Sonner`, `Tabs`, `Tooltip` -->

### Hooks

#### Core Hooks

-   `useDynamicAuth`: Access user data, wallet connection status, and authentication functions.
<!-- -   `useWalletProvider`: Core hook for wallet connection and provider information. -->
-   `useTransactionModal`: Hook to control the transaction modal.
-   `useBlockExplorerUrl`: A utility hook to get URLs for block explorers.
-   `useDebounce`: A hook to debounce a value, useful for search inputs.
-   `useTokenActions`: Provides actions related to tokens.
-   `useTokens`: Hook to fetch and manage the list of tokens.
-   `useTokenSearch`: Hook to search for tokens from the token list.
-   `useWalletAddress`: Hook to get and manage the user's wallet address.

#### Deposit Hooks

-   `useDeposit`: Main hook for deposit logic.
-   `useDepositCalculations`: Hook for deposit-related calculations.
-   `useDepositFormState`: Hook to manage the state of the deposit form.
-   `useDepositTransaction`: Hook to handle deposit transactions.
-   `useGasManager`: Hook to manage gas fees for deposits.
-   `useSwapInfo`: Hook to get swap information related to deposits.

#### Swap Hooks

-   `useSwapNew`: Main hook for the new swap logic.
-   `useSwapAllowance`: Hook to check and manage token allowances for swaps.
-   `useSwapFormState`: Hook to manage the state of the swap form.
-   `useSwapGasManager`: Hook to manage gas fees for swaps.
-   `useSwapQuote`: Hook to get quotes for token swaps.
-   `useSwapTokenPrices`: Hook to fetch token prices for swaps.
-   `useSwapTransaction`: Hook to handle swap transactions.

#### Withdrawal Hooks

-   `useWithdraw`: Main hook for withdrawal logic.
-   `useWithdrawalNetworkCheck`: Hook to check if the withdrawal network is supported.
-   `useWithdrawCalculations`: Hook for withdrawal-related calculations.
-   `useWithdrawFormState`: Hook to manage the state of the withdrawal form.
-   `useWithdrawTransaction`: Hook to handle withdrawal transactions.

#### Tip Hooks

-   `useTip`: Main hook for Tip logic.
-   `useWithdrawFormState`: Hook to manage the state of the Tip form.
-   `useWithdrawTransaction`: Hook to handle tip transactions.

### State Management

-   `useAppStore`: The main Zustand store for global state management.
-   **Selectors**: `blockchain.selectors` for accessing specific parts of the blockchain state.

### Services

-   `ApiService`: Singleton for handling communication with your backend API.
-   `LocalStorageService`: Singleton for managing data in the browser's local storage.
-   `WebSocketService`: Singleton for handling WebSocket connections and communication.
-   `TransactionService`: Service for creating and managing blockchain transactions.

### Types

The package exports various TypeScript types for better type-safety and development experience.

-   `auth.types`, `swap.types`, `transactions.types`, `swap-hooks.types`, `transaction-service.types`, `wallet-provider.types`, `websockets.types`

### Utilities

-   `utils.ts`: General utility functions.
-   `auth.utlis.ts`: Authentication-related utility functions.
-   `wallet-provider.utils.ts`: Wallet provider related utility functions.

### ABIs

-   `erc20Abi`: The ABI for the standard ERC20 token contract.
-   `pandaByteCoreAbi`: The ABI for the PandaByteCore contract.

## License

This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.

## Contributing

Contributions are welcome! Please open an issue or submit a pull request on our GitHub repository.