npm package: @quantara/sdk
Description: JavaScript/TypeScript SDK for interacting with Quantara Protocol on Neura Testnet
Latest version: 1.4.8

# Quantara SDK

JavaScript/TypeScript SDK for interacting with Quantara Protocol on Neura Testnet.

## 🚀 Quick Start

### Installation

```bash
npm install @quantara/sdk
# or
yarn add @quantara/sdk
```

### Basic Usage

```typescript
import { QuantaraSdk } from "@quantara/sdk";

// Initialize SDK
const sdk = new QuantaraSdk({
  chainId: 267, // Neura Testnet
  account: "0x...", // Your wallet address
  oracleUrl: "https://anservice.quantara.gg/api",
  rpcUrl: "https://testnet.rpc.neuraprotocol.io/",
  subsquidUrl: "https://api.goldsky.com/api/public/project_cmfm8agsrmo7v01z9bh5y52qz/subgraphs/stats/0.0.1/gn",
});

// Get markets data
const markets = await sdk.markets.getMarkets();
console.log("Available markets:", markets.marketsAddresses);
```

### Using QuantaraPerps Widget

The SDK includes a ready-to-use React widget for opening positions:

```tsx
import { useAccount, useChainId, useWalletClient } from "wagmi";
import { QuantaraPerps } from "@quantara/sdk";

function App() {
  const chainId = useChainId();
  const { address } = useAccount();
  const { data: walletClient } = useWalletClient();

  return <QuantaraPerps account={address} chainId={chainId} walletClient={walletClient} />;
}
```

The widget automatically:

- Fetches markets and tokens data
- Calculates position amounts and fees
- Handles transaction signing and execution
- Shows transaction status with toast notifications

### Using QuantaraPositions Widget

The SDK includes a ready-to-use React widget for viewing and closing positions:

```tsx
import { useAccount, useChainId, useWalletClient } from "wagmi";
import { QuantaraPositions } from "@quantara/sdk";

function App() {
  const chainId = useChainId();
  const { address } = useAccount();
  const { data: walletClient } = useWalletClient();

  return <QuantaraPositions account={address} chainId={chainId} walletClient={walletClient} />;
}
```

The widget automatically:

- Fetches user positions with real-time updates
- Displays position details (size, PnL, leverage, liquidation price)
- Handles position closing transactions
- Shows transaction status with toast notifications
- Refreshes positions data every 30 seconds

### Vite Configuration

If you're using Vite, you need to configure it to handle CSS and SVG files from `node_modules`. Add this to your `vite.config.ts`:

```typescript
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
  optimizeDeps: {
    include: ["@quantara/sdk"],
  },
  ssr: {
    noExternal: ["@quantara/sdk"],
  },
});
```

This ensures that CSS and SVG assets from the SDK are properly bundled.

## 📊 Current Status

### ✅ Working Features

| Module        | Status           | Description                                                                           |
| ------------- | ---------------- | ------------------------------------------------------------------------------------- |
| **Accounts**  | ✅ Working       | Get governance token delegates                                                        |
| **Markets**   | ✅ Working (6/7) | Get markets data, markets info, config filters, deposit/withdrawal/shift transactions |
| **Tokens**    | ✅ Working       | Get tokens data, respect config overrides                                             |
| **Orders**    | ✅ Working       | Order validation, parameter handling and all transaction functions tested             |
| **Positions** | ✅ Working       | Get positions data and info                                                           |

### ⚠️ Partial Issues

| Module      | Issue                | Impact                    |
| ----------- | -------------------- | ------------------------- |
| **Markets** | GraphQL endpoint 404 | `getDailyVolumes()` fails |
| **Trades**  | GraphQL endpoint 404 | `getTradeHistory()` fails |

### 🔧 Configuration

The SDK supports the following configuration:

```typescript
interface QuantaraSdkConfig {
  chainId: number;
  account?: string;
  oracleUrl: string;
  rpcUrl: string;
  subsquidUrl: string;
  walletClient?: any; // viem wallet client
  markets?: Record<string, { isListed?: boolean }>;
  tokens?: Record<string, Partial<TokenData>>;
}
```

## 🏪 Available Markets

| Market    | Address                                      | Index Token | Long Token | Short Token |
| --------- | -------------------------------------------- | ----------- | ---------- | ----------- |
| WANKR/USD | `0x532e5f945F66bED4548E89Fff30391deCE5D3f55` | WANKR       | WANKR      | USN         |
| BTC/USD   | `0x49d7c1807e90F23C7c517bFFeD86a997047b51f8` | BTC         | BTC        | USN         |
| ETH/USD   | `0xEf9379b4B041796871C44b22211Bc91534Dd2297` | ETH         | WANKR      | USN         |

## 🪙 Available Tokens

| Token | Address                                      | Type      | Symbol |
| ----- | -------------------------------------------- | --------- | ------ |
| ANKR  | `0x0000000000000000000000000000000000000000` | Native    | ANKR   |
| WANKR | `0x422F5Eae5fEE0227FB31F149E690a73C4aD02dB8` | Wrapped   | WANKR  |
| USN   | `0xF22870a514b0c288A8E0cAf341146fc9E0f3D982` | Stable    | USN    |
| BTC   | `0x5e06D1bd47dd726A9bcd637e3D2F86B236e50c26` |           | BTC    |
| ETH   | `0x8C29a7E63723144066ce864B6085B2db538E59D7` | Synthetic | ETH    |

## 📚 API Reference

### Markets Module

```typescript
// Get all markets
const markets = await sdk.markets.getMarkets();

// Get markets with additional info
const marketsInfo = await sdk.markets.getMarketsInfo();

// Create deposit to market
const deposit = await sdk.markets.createDeposit({
  account: "0x...",
  initialLongTokenAddress: "0x0000000000000000000000000000000000000000", // Native token
  initialShortTokenAddress: "0xF22870a514b0c288A8E0cAf341146fc9E0f3D982", // USN
  longTokenSwapPath: [],
  shortTokenSwapPath: [],
  marketTokenAddress: "0x532e5f945F66bED4548E89Fff30391deCE5D3f55",
  longTokenAmount: 1000000000000000000n, // 1 token
  shortTokenAmount: 1000000000000000000n, // 1 token
  minMarketTokens: 1000000000000000000n,
  executionFee: 1000000000000000n,
  executionGasLimit: 1000000n,
  allowedSlippage: 50, // 0.5%
  tokensData,
});

// Create withdrawal from market
const withdrawal = await sdk.markets.createWithdrawal({
  account: "0x...",
  marketTokenAddress: "0x532e5f945F66bED4548E89Fff30391deCE5D3f55",
  marketTokenAmount: 1000000000000000000n, // 1 market token
  initialLongTokenAddress: "0x0000000000000000000000000000000000000000",
  minLongTokenAmount: 1000000000000000000n,
  longTokenSwapPath: [],
  initialShortTokenAddress: "0xF22870a514b0c288A8E0cAf341146fc9E0f3D982",
  shortTokenSwapPath: [],
  minShortTokenAmount: 1000000000000000000n,
  executionFee: 1000000000000000n,
  executionGasLimit: 1000000n,
  allowedSlippage: 50, // 0.5%
  tokensData,
});

// Create shift between markets
const shift = await sdk.markets.createShift({
  account: "0x...",
  fromMarketTokenAddress: "0x532e5f945F66bED4548E89Fff30391deCE5D3f55",
  fromMarketTokenAmount: 1000000000000000000n,
  toMarketTokenAddress: "0x8C29a7E63723144066ce864B6085B2db538E59D7",
  minToMarketTokenAmount: 1000000000000000000n,
  executionFee: 1000000000000000n,
  executionGasLimit: 1000000n,
  allowedSlippage: 50, // 0.5%
  tokensData,
});
```

### Tokens Module

```typescript
// Get tokens data
const tokens = await sdk.tokens.getTokensData();

// Get native token
const nativeToken = sdk.tokens.getNativeToken();
```

### Positions Module

```typescript
// Get positions
const positions = await sdk.positions.getPositions({
  tokensData,
  marketsData,
});

// Get positions with PnL info
const positionsInfo = await sdk.positions.getPositionsInfo({
  tokensData,
  marketsInfoData,
  showPnlInLeverage: true,
});
```

### Orders Module

```typescript
// Create long position
const longOrder = await sdk.orders.long({
  payAmount: 1000n,
  marketAddress: "0x532e5f945F66bED4548E89Fff30391deCE5D3f55",
  payTokenAddress: "0x0000000000000000000000000000000000000000",
  collateralTokenAddress: "0xF22870a514b0c288A8E0cAf341146fc9E0f3D982",
  allowedSlippageBps: 125,
  leverage: 50000n,
  marketsInfoData,
  tokensData,
});

// Create short position
const shortOrder = await sdk.orders.short({
  payAmount: 1000n,
  marketAddress: "0x532e5f945F66bED4548E89Fff30391deCE5D3f55",
  payTokenAddress: "0x0000000000000000000000000000000000000000",
  collateralTokenAddress: "0xF22870a514b0c288A8E0cAf341146fc9E0f3D982",
  allowedSlippageBps: 125,
  leverage: 50000n,
  marketsInfoData,
  tokensData,
});

// Swap tokens
const swapOrder = await sdk.orders.swap({
  fromTokenAddress: "0x0000000000000000000000000000000000000000", // ANKR
  toTokenAddress: "0xF22870a514b0c288A8E0cAf341146fc9E0f3D982", // USN
  fromAmount: 1000n,
  allowedSlippageBps: 125,
  marketsInfoData,
  tokensData,
});

// Wrap/Unwrap native tokens
const wrapOrder = await sdk.orders.createWrapOrUnwrapOrder({
  amount: 1000n,
  isWrap: true, // Wrap ANKR to WANKR
});

// Cancel orders
await sdk.orders.cancelOrders(["0x1234567890123456789012345678901234567890123456789012345678901234"]);
```

#### Low-Level Transaction API (Advanced)

```typescript
import {
  createIncreaseOrderTxn,
  createDecreaseOrderTxn,
  createSwapOrderTxn,
  createWrapOrUnwrapTxn,
  updateOrderTxn,
  cancelOrdersTxn,
  createDepositTxn,
  createWithdrawalTxn,
  createShiftTxn,
} from "@quantara/sdk/transactions";

// Create increase order (low-level)
await createIncreaseOrderTxn(sdk, {
  account: "0x...",
  marketAddress: "0x532e5f945F66bED4548E89Fff30391deCE5D3f55",
  initialCollateralAddress: "0xF22870a514b0c288A8E0cAf341146fc9E0f3D982",
  initialCollateralAmount: 1000n,
  targetCollateralAddress: "0xF22870a514b0c288A8E0cAf341146fc9E0f3D982",
  collateralDeltaAmount: 1000n,
  swapPath: [],
  sizeDeltaUsd: 10000n,
  sizeDeltaInTokens: 1000n,
  triggerPrice: undefined,
  acceptablePrice: 1000000000000000000000n,
  isLong: true,
  orderType: OrderType.MarketIncrease,
  executionFee: 1000000000000000000n,
  allowedSlippage: 125,
  referralCode: undefined,
  indexToken: market.indexToken,
  tokensData,
});

// Create decrease order (low-level)
await createDecreaseOrderTxn(sdk, {
  account: "0x...",
  marketAddress: "0x532e5f945F66bED4548E89Fff30391deCE5D3f55",
  initialCollateralAddress: "0xF22870a514b0c288A8E0cAf341146fc9E0f3D982",
  initialCollateralDeltaAmount: 1000n,
  swapPath: ["0x532e5f945F66bED4548E89Fff30391deCE5D3f55"],
  receiveTokenAddress: "0xF22870a514b0c288A8E0cAf341146fc9E0f3D982",
  sizeDeltaUsd: 10000n,
  sizeDeltaInTokens: 1000n,
  acceptablePrice: 1000000000000000000000n,
  triggerPrice: undefined,
  minOutputUsd: 0n,
  isLong: true,
  decreasePositionSwapType: DecreasePositionSwapType.SwapPnlTokenToCollateralToken,
  orderType: OrderType.MarketDecrease,
  executionFee: 1000000000000000000n,
  allowedSlippage: 125,
  referralCode: undefined,
  indexToken: market.indexToken,
  tokensData,
  autoCancel: false,
});

// Update existing order
await updateOrderTxn(sdk, {
  orderKey: "0x1234567890123456789012345678901234567890123456789012345678901234",
  indexToken: market.indexToken,
  sizeDeltaUsd: 10000n,
  triggerPrice: 1000000000000000000000n,
  acceptablePrice: 1000000000000000000000n,
  minOutputAmount: 0n,
  executionFee: 1000000000000000000n,
  autoCancel: false,
});

// Cancel multiple orders
await cancelOrdersTxn(sdk, {
  orderKeys: [
    "0x1234567890123456789012345678901234567890123456789012345678901234",
    "0x2345678901234567890123456789012345678901234567890123456789012345",
  ],
});

// Create deposit (low-level)
await createDepositTxn(sdk, {
  account: "0x...",
  initialLongTokenAddress: "0x0000000000000000000000000000000000000000",
  initialShortTokenAddress: "0xF22870a514b0c288A8E0cAf341146fc9E0f3D982",
  longTokenSwapPath: [],
  shortTokenSwapPath: [],
  marketTokenAddress: "0x532e5f945F66bED4548E89Fff30391deCE5D3f55",
  longTokenAmount: 1000000000000000000n,
  shortTokenAmount: 1000000000000000000n,
  minMarketTokens: 1000000000000000000n,
  executionFee: 1000000000000000n,
  executionGasLimit: 1000000n,
  allowedSlippage: 50,
  tokensData,
});

// Create withdrawal (low-level)
await createWithdrawalTxn(sdk, {
  account: "0x...",
  marketTokenAddress: "0x532e5f945F66bED4548E89Fff30391deCE5D3f55",
  marketTokenAmount: 1000000000000000000n,
  initialLongTokenAddress: "0x0000000000000000000000000000000000000000",
  minLongTokenAmount: 1000000000000000000n,
  longTokenSwapPath: [],
  initialShortTokenAddress: "0xF22870a514b0c288A8E0cAf341146fc9E0f3D982",
  shortTokenSwapPath: [],
  minShortTokenAmount: 1000000000000000000n,
  executionFee: 1000000000000000n,
  executionGasLimit: 1000000n,
  allowedSlippage: 50,
  tokensData,
});

// Create shift (low-level)
await createShiftTxn(sdk, {
  account: "0x...",
  fromMarketTokenAddress: "0x532e5f945F66bED4548E89Fff30391deCE5D3f55",
  fromMarketTokenAmount: 1000000000000000000n,
  toMarketTokenAddress: "0x8C29a7E63723144066ce864B6085B2db538E59D7",
  minToMarketTokenAmount: 1000000000000000000n,
  executionFee: 1000000000000000n,
  executionGasLimit: 1000000n,
  allowedSlippage: 50,
  tokensData,
});
```

## 🧪 Testing

Run tests to verify functionality:

```bash
# Run all tests
yarn test
```

## License

MIT