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

# React Example

> Example React integration using Ostium transaction builders, order polling, and live position updates.

This example focuses on a client-side application where your UI builds transactions and the connected wallet signs them.

## Build transaction data for the wallet

Create a build-only client using addresses instead of private keys. This lets your app use the SDK to construct the correct calldata without submitting through the SDK.

```ts theme={null}
import { OrderType, OstiumClient } from '@ostium/builder-sdk';

const client = await OstiumClient.createSelfAndSelf({
  traderAddress: '0xTraderAddress',
  builder: {
    address: '0xYourBuilderAddress',
    feeBps: 20,
  },
});
```

Build the trade request:

```ts theme={null}
const tx = client.getOpenTradeTx({
  pairId: 0,
  buy: true,
  price: '65000',
  collateral: '100',
  leverage: '5',
  type: OrderType.Market,
});
```

If `tx.kind === 'eoa'`, pass it to the wallet:

```ts theme={null}
await window.ethereum.request({
  method: 'eth_sendTransaction',
  params: [
    {
      from: tx.from,
      to: tx.to,
      data: tx.data,
      value: `0x${tx.value.toString(16)}`,
    },
  ],
});
```

The same pattern works for `getCloseTradeTx()`, `getModifyOrderTx()`, `getCancelOrderTx()`, and `getUpdateCollateralTx()`.

## Stream live position updates

Fetch the current positions once, then stream price-driven updates over WebSocket.

```ts theme={null}
const positions = await client.getOpenPositions({ user: '0xTraderAddress' });
const stream = client.streamPositionUpdates(positions);

stream.onUpdate(next => {
  renderMarginSummary(next.marginSummary);
  renderPositions(next.pairPositions);
});

stream.onError(error => {
  console.error('position stream error', error);
});
```

The stream only subscribes to the unique `pairId` values present in the current positions response, so it is usually lighter than subscribing to the full price feed.

## Poll trade status after wallet submission

Once a wallet sends the transaction, poll `getOrders()` by `initiatedTxHashes` until the order leaves the pending state.

```ts theme={null}
async function pollTrade(txHash: `0x${string}`) {
  while (true) {
    const orders = await client.getOrders({ initiatedTxHashes: [txHash] });
    const order = orders[0];

    if (order && !order.isPending) {
      return order;
    }

    await new Promise(resolve => setTimeout(resolve, 2000));
  }
}
```

This is the usual pattern for showing submitted, filled, or cancelled state in the UI after a wallet signature flow.
