> For the complete documentation index, see [llms.txt](https://optim-finance.gitbook.io/optim-finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://optim-finance.gitbook.io/optim-finance/oada-ui/tutorials/wallet-integration-and-state-management.md).

# Wallet Integration and State Management

This tutorial will guide you through implementing authentication and authorization in the OADA UI project. You'll learn how to handle user authentication through Cardano wallets and manage wallet state.

### Authentication Overview

The project uses:

* CIP-30 compliant Cardano wallet authentication
* WebSocket-based real-time updates
* Redux state management for wallet data
* Virtual UTxO management for pending transactions

### Supported Wallet Providers

The application supports multiple Cardano wallet providers:

* Nami
* Eternl
* Flint
* Gero
* Typhon
* Lode
* Exodus
* Vespr
* Lace
* NuFi

### Wallet Integration

#### 1. Wallet Provider Interface

```typescript
// src/store/wallet.ts
export interface WalletApiProvider {
  /**
   * Retrieves a wallet API instance for the specified provider
   *
   * @param name - Name of the wallet provider (e.g., 'nami', 'eternl', etc.)
   * @returns Promise resolving to a CIP-30 compliant WalletApi instance
   * @throws Error if provider is not supported or wallet is not available
   */
  getWalletApi(name: string): Promise<WalletApi>;
}

// Registry of supported wallet providers
const supportedProviders: { [key: string]: boolean } = {
  nami: true,
  flint: true,
  yoroi: true,
  gerowallet: true,
  eternl: true,
  typhoncip30: true,
  LodeWallet: true,
  exodus: true,
  vespr: true,
  lace: true,
  nufi: true,
};
```

#### 2. Wallet Connection Components

**ConnectWallet Component**

```typescript
// src/features/Topbar/ConnectWallet/index.tsx
export const ConnectWallet: FC<Props> = ({ fullWidth, className }) => {
  const [isOpen, setOpen] = useState(false);
  const [isChecked, setIsChecked] = useState(false);
  const dispatch = useAppDispatch();
  const ws = useContext(WebsocketContext);

  const dispatchSelectWallet = (walletName: string) => async () => {
    dispatch(setWalletByProvider({ name: walletName, ws }));
  };

  return (
    <div className={className}>
      <Button
        className={cn(fullWidth && "w-full", "text-sm")}
        size="sm"
        onClick={() => setOpen(!isOpen)}
      >
        Connect Wallet
      </Button>

      <Modal open={isOpen} blur={true} onClose={() => setOpen(false)}>
        {/* Terms acceptance and wallet selection UI */}
      </Modal>
    </div>
  );
};
```

#### 3. Wallet State Management

```typescript
// src/store/slices/walletSlice.ts
export const walletSlice = createSlice({
  name: "wallet",
  initialState,
  reducers: {
    setWalletFeeAddress: (state, action: PayloadAction<string | null>) => {
      state.feeAddress = action.payload;
    },
    toggleShowWalletSelect: (state) => {
      state.showWalletSelect = !state.showWalletSelect;
    },
    setRewardAccounts: (state, action: PayloadAction<RewardAccount[]>) => {
      state.rewardAccounts = action.payload;
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(updateWalletUtxosThunk.fulfilled, (state, action) => {
        // Handle UTxO updates
      })
      .addCase(setWalletByProvider.fulfilled, (state, action) => {
        state.wallet = action.payload;
        state.showWalletSelect = false;
      })
      .addCase(disconnectWalletThunk.fulfilled, (state, _action) => {
        if (state.wallet !== null) {
          state.wallet = null;
          state.partialWallet.utxos = [];
        }
      });
  },
});
```

#### 4. WebSocket Integration

```typescript
// src/websocket.tsx
const WebsocketProvider: FC<{ children: ReactNode }> = ({ children }) => {
  const wallet = useAppSelector(selectWallet);
  const url = `${wsUrl}`;
  const ws = new WebSocket(url);
  const dispatch = useAppDispatch();

  // Handle successful connection
  ws.addEventListener("open", (event) => {
    if (wallet !== null) {
      sendWalletConnectWsNotif(ws, wallet.address);
    }
    // Set up heartbeat mechanism
    const timer = setInterval(() => {
      if (ws.readyState === WebSocket.OPEN) {
        ws.send("ping");
      }
    }, 30000);
  });

  // Handle connection closure and errors
  ws.addEventListener("close", (event) => {
    setTimeout(() => setReconnectToggle(!reconnectToggle), 5000);
  });

  ws.addEventListener("error", (event) => {
    setTimeout(() => setReconnectToggle(!reconnectToggle), 5000);
  });

  // Handle incoming messages
  ws.addEventListener("message", (event) => {
    const data = event.data;
    if (data === "pong") return;

    const o = JSON.parse(data);
    if (isJsonRpcNotif("RewardDistsView", isRewardAccounts)(o)) {
      if (o.params !== undefined) {
        dispatch(setRewardAccounts(o.params));
      }
    }
  });

  return (
    <WebsocketContext.Provider value={ws}>{children}</WebsocketContext.Provider>
  );
};
```

### UTxO Management

The application includes comprehensive UTxO management for handling Cardano transactions:

1. **Virtual UTxO Tracking**: Maintains a map of pending transaction outputs
2. **UTxO Selection**: Optimizes UTxO selection for transactions
3. **State Synchronization**: Keeps wallet state in sync with the blockchain

```typescript
// src/utils/wallet-stuff.ts
export type WalletUtxoMap = {
  outputUtxosRefByWalletUtxoId: {
    [walletUtxoId: string]: string;
  };
  outputUtxosByOutputUtxosRef: {
    [outputUtxosRef: string]: Server.Utxo[];
  };
  walletUtxoIdsByOutputUtxosRef: {
    [outputUtxosRef: string]: Set<string>;
  };
};
```

### Best Practices

1. **Security**
   * Use CIP-30 compliant wallet providers
   * Implement proper error handling
   * Validate all blockchain interactions
   * Maintain secure WebSocket connections
2. **User Experience**
   * Provide clear wallet connection status
   * Handle connection errors gracefully
   * Show transaction progress
   * Maintain real-time state updates
3. **State Management**
   * Use Redux for centralized state
   * Handle async operations with thunks
   * Maintain WebSocket connection state
   * Track virtual UTxO state
4. **Testing**
   * Test wallet connections
   * Verify WebSocket functionality
   * Test UTxO management
   * Validate state updates

### Next Steps

Now that you understand the wallet integration and state management, you can proceed to:

1. API Integration and Services
2. Advanced UI Customization

### Additional Resources

* [CIP-30 Specification](https://cips.cardano.org/cips/cip30/)
* [Lucid Documentation](https://lucid.spacebudz.io/)
* [Redux Toolkit Documentation](https://redux-toolkit.js.org/)
* [WebSocket API Documentation](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)
