npm package: @solpulse/sdk-react
Description: React hooks for the SolPulse SDK
Latest version: 0.2.0

# @solpulse/sdk-react

React hooks for the SolPulse SDK. Provides ready-to-use hooks that wrap the `@solpulse/sdk` client with React state management and automatic polling.

## Installation

```bash
npm install @solpulse/sdk-react @solpulse/sdk react @solana/wallet-adapter-react
```

## Quick Start

Wrap your app with the Solana wallet adapter providers, then use the hooks:

```tsx
import { useSolPulseClient, usePoolState, useRaffleTimer, useUserStakeInfo } from "@solpulse/sdk-react";
import { useAnchorWallet } from "@solana/wallet-adapter-react";

function RafflePanel() {
  const client = useSolPulseClient();
  const { pool, loading } = usePoolState(client);
  const { secondsLeft, isExpired } = useRaffleTimer(pool?.endTime.toNumber() ?? 0);

  if (loading) return <p>Loading...</p>;

  return (
    <div>
      <p>Draw #{pool?.drawId.toNumber()}</p>
      <p>Prize pool: {pool?.totalSol.toNumber() ?? 0 / 1e9} SOL</p>
      <p>{isExpired ? "Draw closed" : `${secondsLeft}s remaining`}</p>
    </div>
  );
}

function StakingPanel() {
  const anchorWallet = useAnchorWallet();
  const client = useSolPulseClient();
  const { stakeInfo, pendingRewards, loading } = useUserStakeInfo(
    client,
    anchorWallet?.publicKey ?? null
  );

  if (loading) return <p>Loading...</p>;
  if (!stakeInfo) return <p>No active stake</p>;

  return (
    <div>
      <p>Staked: {stakeInfo.amount.toNumber() / 1e6} PULSE</p>
      <p>Pending rewards: {pendingRewards.toFixed(4)} PULSE</p>
    </div>
  );
}
```

## API Reference

### `useSolPulseClient(opts?)`

Creates and returns a `SolPulseClient` instance, or `null` when the wallet is not connected or the program ID is still a placeholder.

```typescript
import { useSolPulseClient } from "@solpulse/sdk-react";
import { PublicKey } from "@solana/web3.js";

const client = useSolPulseClient({
  programId: new PublicKey("..."),   // optional, defaults to SOLPULSE_PROGRAM_ID
  pulseMint: new PublicKey("..."),   // optional, defaults to PULSE_MINT
});
```

### `usePoolState(client)`

Fetches the current raffle pool state and polls every 15 seconds.

```typescript
const { pool, loading, refresh } = usePoolState(client);
// pool: RafflePoolAccount | null
// loading: boolean
// refresh: () => Promise<void>
```

### `useRaffleTimer(endTime)`

Returns a live countdown based on the pool's `endTime` Unix timestamp. Updates every second.

```typescript
const { secondsLeft, isExpired } = useRaffleTimer(pool?.endTime.toNumber() ?? 0);
// secondsLeft: number   — seconds remaining until draw closes
// isExpired: boolean    — true once the countdown hits 0
```

### `useUserStakeInfo(client, user)`

Fetches a user's staking account and computes pending rewards, polling every 15 seconds.

```typescript
const { stakeInfo, pendingRewards, loading, refresh } = useUserStakeInfo(client, walletPublicKey);
// stakeInfo: StakeAccountData | null
// pendingRewards: number   — estimated accrued PULSE (human-readable)
// loading: boolean
// refresh: () => Promise<void>
```

## Re-exports

`@solpulse/sdk-react` re-exports everything from `@solpulse/sdk`, so you can import constants, PDA helpers, types, and utility functions from a single package:

```typescript
import {
  useSolPulseClient,
  usePoolState,
  SOLPULSE_PROGRAM_ID,
  lamportsToSol,
  type RafflePoolAccount,
} from "@solpulse/sdk-react";
```