> ## Documentation Index
> Fetch the complete documentation index at: https://docs.0xmonaco.com/llms.txt
> Use this file to discover all available pages before exploring further.

# useCopyTrading

> Copy trading reads and writes, and live follow state via the copy WebSocket channel

```tsx theme={null}
import { useCopyEvents, useCopyTrading } from "@0xmonaco/react";

const {
  listLeadTraders,
  getLeadTrader,
  listLeadTraderClosedTrades,
  listLeadTraderOpenPositions,
  upsertFollow,
  stopFollow,
  listMyFollows,
  getFollow,
  listFollowLeaderPositions,
  previewFollow,
  upsertLeadTrader,
  getMyLeadTrader,
  listMyFollowers,
} = useCopyTrading();

const { relationships, relationshipsById, recentSkips, subscribed, error, clearError } = useCopyEvents();
```

For concepts see [Copy Trading](/developers/copy-trading).

## useCopyTrading

Returns the thirteen [`sdk.copyTrading`](/sdk/typescript/copy-trading) methods with the same signatures. Each throws `SDK not available` until the provider has built the SDK. The leaderboard, `getLeadTrader` and `listLeadTraderClosedTrades` need no session; every other method needs an authenticated one.

```tsx theme={null}
function Leaderboard() {
  const { listLeadTraders, upsertFollow } = useCopyTrading();
  const [leaders, setLeaders] = useState<LeadTraderListing[]>([]);

  useEffect(() => {
    listLeadTraders({ sort: "roi", window: "30d" }).then((page) => setLeaders(page.leaders));
  }, [listLeadTraders]);

  const follow = (handle: string) => upsertFollow({ leader: handle, allocation: "1000", slPct: "0.25" });
  // ...
}
```

An `upsertFollow` edit replaces the follow's settings: every optional setting left out reverts to its default. See [upsertFollow](/sdk/typescript/copy-trading).

## useCopyEvents

A typed subscription to the authenticated [`copy` channel](/sdk/typescript/websockets#copy-channel), wrapping `sdk.ws.copy()`. It streams to the **follower** only, and runs only while a user is signed in: it subscribes on login, and logout or an account switch clears the follows and skips before the next user's snapshot arrives.

On subscribe the channel delivers a [snapshot](/sdk/typescript/websockets#subscribe-time-snapshots) of your live follows (`ACTIVE` or `CLOSE_ONLY`). Each `copy_relationship_update` frame then carries a follow's full state and replaces its entry, unless its `version` is older than the stored one (a late frame). A follow stopped while the socket is up keeps its entry with status `STOPPED`. Each later snapshot (after a reconnect) replaces the whole set, so a follow that stopped while the socket was down leaves it.

`copy_skip` frames collect in `recentSkips`, newest first, up to `MAX_RECENT_COPY_SKIPS` (50). The snapshot carries no skips; read `getFollow(followId)` for a follow's persisted recent skips.

`cumNetRealized` and `hwm` on each follow are its profit-share basis, not the copy account's balance.

The subscription is torn down on unmount and re-established when `sdk.ws` or the signed-in user changes.

## Returns

<ResponseField name="relationships" type="CopyRelationshipEventData[]">
  Your follows as last reported, newest first by `startedAt`.
</ResponseField>

<ResponseField name="relationshipsById" type="Record<string, CopyRelationshipEventData>">
  The same entries keyed by `relationshipId` (the follow id, `Follow.followId` over REST).
</ResponseField>

<ResponseField name="recentSkips" type="CopySkipEventData[]">
  Leader fills your follows did not mirror while subscribed, newest first, capped at 50.
</ResponseField>

<ResponseField name="subscribed" type="boolean">
  Whether the `copy` subscription is registered. Not a connection indicator.
</ResponseField>

<ResponseField name="error" type="Error | null">
  A rejected subscription request. Connection loss and malformed frames never appear here.
</ResponseField>

<ResponseField name="clearError" type="() => void">
  Clear `error`.
</ResponseField>
