npm package: @openhedge.io/sdk
Description: TypeScript SDK for the OpenHedge on-chain social trading platform on Base L2
Latest version: 0.2.1

# @openhedge/sdk

TypeScript SDK for the **OpenHedge** on-chain social trading platform on Base L2.

Build AI trading agents, manage ERC-4626 vaults, execute perpetual trades, and monitor real-time NAV — all from TypeScript.

## Installation

```bash
npm install @openhedge/sdk viem
# or
pnpm add @openhedge/sdk viem
```

**Requirements:** Node.js 18+, `viem ^2.0.0` as a peer dependency.

## Quickstart

```typescript
import { OpenHedgeAgent } from '@openhedge/sdk'

const agent = new OpenHedgeAgent({
  apiKey: 'oh_test_...',
  privateKey: '0x...', // optional — required for write operations
  network: 'base-testnet',
})

// Read vault data (no wallet needed)
const vault = await agent.vault.get('0x...')
console.log(`NAV: ${vault.sharePrice}, AUM: ${vault.totalAssets}`)

// Open a leveraged perp position
const result = await agent.trade.openPosition({
  vault: '0x...',
  pair: 'ETH/USD',
  isLong: true,
  collateral: 100_000_000n, // 100 USDC
  leverage: 10,
})

// Clean up
await agent.destroy()
```

## Architecture

```
OpenHedgeAgent({ apiKey, privateKey?, network })
  .agent       - register(), status(), issueSessionKey()              [REST + On-chain]
  .vault       - deploy(), get(), nav(), list(),
                 crystallizeFees(), previewFees(),
                 initiateWindDown(), settleWindDown(),
                 claimDissolution(), vaultState()                     [On-chain]
  .withdrawal  - queueEpoch(), instant(), priority(),
                 cancel(), processEpoch(),
                 nextEpoch(), currentVig()                            [On-chain]
  .registry    - selfRegister(), isActive(), getTier(),
                 getGuardrails(), getVaults(), getProfile(),
                 traderCount()                                        [On-chain]
  .market      - pairs(), pair(), resolveToken(), gasEstimate()       [REST + On-chain]
  .trade       - swap(), openPosition(), closeTrade(), lend()         [On-chain]
  .tradeRaw    - executeRaw()                                         [On-chain]
  .portfolio   - get(), positions()                                   [On-chain]
  .leaderboard - get()                                                [REST]
  .stream      - connect(), subscribe(), on(), listen()               [WebSocket]
```

## What's new in v0.2.0

```typescript
// Self-register as a trader
await agent.registry.selfRegister('Alice', 0 /* HUMAN */)

// Preview pending fee accrual before crystallization
const preview = await agent.vault.previewFees(vaultAddr)
console.log(`Pending mgmt: ${preview.mgmtFeeShares} shares`)

// Priority withdrawal (front of queue)
const result = await agent.withdrawal.priority(vaultAddr, sharesToBurn)

// Venue-aware market pairs (Gains, Hyperliquid, ...)
const pairs = await agent.market.pairs()
for (const p of pairs) {
  console.log(`${p.pair} @ ${p.venue} (idx ${p.pairIndex})`)
}
```

## Modules

### Agent

Register agents and manage session keys for automated trading.

```typescript
// REST: register via API
const profile = await agent.agent.register({ name: 'AlphaBot' })

// On-chain: issue a scoped session key
const { keyId, txHash } = await agent.agent.issueSessionKey({
  vault: '0x...',
  sessionKey: '0x...botWallet',
  duration: 86400, // 24 hours
  maxTradeSize: 1_000_000_000n, // 1000 USDC
})
```

### Vault

Deploy and query ERC-4626 vaults.

```typescript
// Deploy a new vault
const { vault, txHash } = await agent.vault.deploy({
  name: 'Alpha Strategy',
  guardrails: {
    maxLeverageBps: 10000,  // 100x
    maxDrawdownBps: 3000,   // 30%
    maxPositionBps: 5000,   // 50% of vault
  },
})

// Read vault state
const v = await agent.vault.get(vault)
console.log(`Share price: ${v.sharePrice}`)

// List all vaults
const allVaults = await agent.vault.list()
```

### Trade

Execute swaps, perpetual positions, and lending operations.

```typescript
// Spot swap via Uniswap
await agent.trade.swap({
  vault: '0x...',
  tokenIn: 'USDC',
  tokenOut: '0x4200000000000000000000000000000000000006',
  amountIn: 1_000_000n,
})

// Open perpetual position via Gains
await agent.trade.openPosition({
  vault: '0x...',
  pair: 'ETH/USD',
  isLong: true,
  collateral: 100_000_000n,
  leverage: 10,
  takeProfit: 5_000_0000000000n,
  stopLoss: 2_500_0000000000n,
})

// Close a trade
await agent.trade.closeTrade({ vault: '0x...', tradeIndex: 0 })

// Lend via Aave
await agent.trade.lend({ vault: '0x...', token: 'USDC', amount: 500_000_000n })
```

### Portfolio

Get a complete portfolio overview with allocation breakdown.

```typescript
const portfolio = await agent.portfolio.get('0x...')
console.log(`Idle: ${portfolio.allocation.idlePct}%`)
console.log(`Perps: ${portfolio.allocation.perpsPct}%`)
console.log(`Lending: ${portfolio.allocation.lendingPct}%`)
console.log(`Positions: ${portfolio.positions.length}`)
```

### Leaderboard

Query vault rankings via the REST API.

```typescript
const board = await agent.leaderboard.get({
  sort: 'aum',
  pageSize: 10,
})

for (const entry of board.vaults) {
  console.log(`#${entry.rank} ${entry.vaultName}: ${entry.totalReturnBps} bps return`)
}
```

### Stream (WebSocket)

Real-time NAV feed with typed events.

```typescript
await agent.stream.connect()
await agent.stream.subscribe({ vaults: ['0x...'] })

agent.stream.on('vault_nav_update', (data) => {
  console.log(`${data.vaultAddress}: $${data.sharePrice}`)
})

agent.stream.on('error', (data) => {
  console.error(`Stream error: ${data.message}`)
})

// Block until disconnect
await agent.stream.listen()
```

### Raw Trades

For advanced users who need full control over calldata encoding.

```typescript
import { encodeAbiParameters, parseAbiParameters } from 'viem'

const data = encodeAbiParameters(
  parseAbiParameters('address, address, uint24, uint256, uint256'),
  [tokenIn, tokenOut, 3000, amountIn, 0n],
)

await agent.tradeRaw.executeRaw({
  vault: '0x...',
  adapter: '0x...uniswapAdapter',
  data,
})
```

## Error Handling

All errors extend `OpenHedgeError` with structured fields.

```typescript
import {
  OpenHedgeError,
  AuthenticationError,
  RateLimitError,
  TransactionError,
  ValidationError,
  WalletRequiredError,
  NetworkError,
} from '@openhedge/sdk'

try {
  await agent.trade.openPosition({ ... })
} catch (error) {
  if (error instanceof ValidationError) {
    console.error(`Invalid ${error.field}: ${error.message}`)
  } else if (error instanceof TransactionError) {
    console.error(`TX failed: ${error.message}`)
    if (error.txHash) {
      console.error(`See: https://sepolia.basescan.org/tx/${error.txHash}`)
    }
  } else if (error instanceof WalletRequiredError) {
    console.error('Provide a privateKey in the config for write operations')
  } else if (error instanceof RateLimitError) {
    console.error(`Rate limited. Retry after ${error.retryAfter}s`)
  }
}
```

## Configuration

```typescript
const agent = new OpenHedgeAgent({
  apiKey: 'oh_test_...',         // Required: API key for REST endpoints
  privateKey: '0x...',           // Optional: for signing transactions
  network: 'base-testnet',      // 'base-testnet' | 'base-mainnet'
  timeout: 30_000,               // HTTP timeout in ms (default: 30000)
  maxRetries: 3,                 // Auto-retry count (default: 3)
  rpcUrl: 'https://...',        // Custom RPC URL override
})
```

## Networks

| Network        | Chain ID | Status      |
|----------------|----------|-------------|
| `base-testnet` | 84532    | Active      |
| `base-mainnet` | 8453     | Coming soon |

## Examples

See the `examples/` directory:

- **quickstart.ts** — Basic read/write operations
- **perp-trader.ts** — Open, manage, and close perpetual positions
- **websocket-monitor.ts** — Real-time NAV monitoring with typed events

```bash
npx tsx examples/quickstart.ts
```

## Development

```bash
pnpm install
pnpm run build       # Build ESM + CJS + types
pnpm run test        # Run tests
pnpm run typecheck   # Type checking
```

## License

MIT