npm package: 1dex-js-sdk
Description: 1DEX JavaScript SDK
Author: 1DEX Inc.
Latest version: 1.0.16

## 1DEX JavaScript SDK

A powerful JavaScript SDK for integrating with the 1DEX decentralized exchange platform, providing seamless access to trading functionality and market data.

## Installation

```bash
npm install 1dex-js-sdk
```

## Getting Started

### Initializing the SDK

```typescript
import { DexKit, ETradeSide, EOrderType } from "1dex-js-sdk";

// Create a new DexKit instance
const dexKit = new DexKit({
  apiKey: "YOUR_API_KEY",
  secretKey: "YOUR_SECRET_KEY",
  enableProxy: false, // Optional, defaults to true
  apiClientConfig: {
    baseUrl: "https://api-v1.example.com", // Optional, defaults to 'https://api-v1.1dex.com'
  },
  blockchainRpcClientConfig: {
    chainID: "YOUR_CHAIN_ID", // Optional, defaults to 'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906'
    rpcUrl: "https://rpc.example.com", // Optional, defaults to 'https://spring-rpc.1dex.com'
  },
  devMode: false, // Optional, if set to true, it will output debug information of certain methods in the console
});

// Initialize the DexKit instance
await dexKit.initialize();
```

## DexKit Interface

The DexKit class provides methods for trading operations on 1DEX.

### Core Methods

#### `initialize()`

Initializes the DexKit instance by fetching system metadata, account information, and pool data.

```typescript
await dexKit.initialize();
```

#### `initializeWithProvidedConfig(config)`

Initializes the DexKit instance using the provided configuration instead of getting it from the server.

**All parameters are optional.**

```typescript
dexKit.initializeWithProvidedConfig({
  appContract: "app_contract", // app.1dex
  accountContract: "account_contract", // Your main account name
  pools: [
    {
      id: 1,
      baseToken: "TOKEN1",
      quoteToken: "TOKEN2",
      baseTokenContract: "token1.contract",
      quoteTokenContract: "token2.contract",
      baseTokenDecimals: 4,
      quoteTokenDecimals: 4,
      pricePrecision: 4,
    },
  ],
  proxyAccount: {
    name: "proxy.account",
    permission: "active",
  },
  account: {
    name: "user.account", // Your sub-account name
    permission: "trader", // Your sub-account permission
  },
});
```

#### `placeLimitOrder(params)`

Places a limit order on the specified pool.

If it is a **buy order**, the amount is the quantity of **quote coin**, if it is a **sell order**, the amount is the quantity of **base coin**.

For example, there is a BTC/USDT trading pair. If it is a buy order, 'amount = 80000' means '80000 USDT', if it is a sell order, 'amount = 1' means '1 BTC'.

Note: the amount will be **rounded up** to the precision unit, which means that if you enter **10.00001 EOS**, it will be formatted as **10.0001 EOS**, so it is recommended to enter the amount according to the token decimals.

```typescript
const { txID, clientOrderID } = await dexKit.placeLimitOrder({
  poolID: 1,
  side: ETradeSide.BUY, // or ETradeSide.SELL
  orderType: EOrderType.NO_RESTRICTION, // or EOrderType.IMMEDIATE_OR_CANCEL || EOrderType.FILL_OR_KILL || EOrderType.POST_ONLY
  amount: "10.0000", // if 'buy', amount is quote coin quantity; if 'sell', amount is base coin quantity
  price: "0.5000",
  clientOrderID: "your defined client order id", // optional
});
```

#### `placeMarketOrder(params)`

Places a market order on the specified pool.

If it is a **buy order**, the amount is the quantity of **quote coin**, if it is a **sell order**, the amount is the quantity of **base coin**.

For example, there is a BTC/USDT trading pair. If it is a buy order, 'amount = 80000' means '80000 USDT', if it is a sell order, 'amount = 1' means '1 BTC'.

Note: the amount will be **rounded up** to the precision unit, which means that if you enter **10.00001 EOS**, it will be formatted as **10.0001 EOS**, so it is recommended to enter the amount according to the token decimals.

```typescript
const { txID, clientOrderID } = await dexKit.placeMarketOrder({
  poolID: 1,
  side: ETradeSide.BUY, // or ETradeSide.SELL
  amount: "10.0000", // if 'buy', amount is quote coin quantity; if 'sell', amount is base coin quantity
  clientOrderID: "your defined client order id", // optional
});
```

#### `cancelOrder(params)`

Cancels an existing order.

```typescript
const txID = await dexKit.cancelOrder({
  poolID: 1,
  orderID: 1,
  side: ETradeSide.BUY, // or ETradeSide.SELL
});
```

#### `cancelOrderByCid(cid)`

Cancels an existing order by client order id.

Client order id will be returned by `placeMarketOrder` and `placeLimitOrder`.

```typescript
const txID = await dexKit.cancelOrderByCid(cid);
```

#### `batchCancelOrders(params)`

Cancels multiple open orders at once.

```typescript
const txID = await dexKit.batchCancelOrders({
  poolID: 1, // optional
  side: ETradeSide.SELL, // optional, ETradeSide.SELL or ETradeSide.BUY
  limit: 100, // optional, default is 500
});
```

### Resource Management

#### `getAccountResources(account)`

Gets the account resources including CPU, NET, and RAM information.

If name is empty, the default sub-account's name obtained during initialization is used.

```typescript
const resources = await dexKit.getAccountResources("name");
// Returns:
// {
//   cpuMax: string,
//   cpuAvailable: string,
//   netMax: string,
//   netAvailable: string,
//   ramQuota: string,
//   ramUsed: string
// }
```

#### `powerup(params)`

Powers up the account with CPU and NET resources.

```typescript
const txID = await dexKit.powerup({
  netEOS: 100000, // optional
  cpuEOS: 1000000000, // optional
  maxPayment: 100000, // optional
  days: 1, // optional, defaults to 1 day
});
```

### Constructor Options

When creating a new DexKit instance, you can provide various configuration options:

```typescript
const dexKit = new DexKit({
  apiKey: "your-api-key",
  secretKey: "your-secret-key",
  enableProxy: true, // optional, defaults to true
  devMode: false, // optional, defaults to false
  apiClientConfig: {
    // HTTP API client configuration
    baseUrl: "https://api-v1.example.com", // optional
    timeout: 30000, // optional
    headers: {
      ["key"]: "value",
    }, // optional
  },
  blockchainRpcClientConfig: {
    // Blockchain RPC client configuration
    chainID: "aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906", // optional
    rpcUrl: "https://spring-rpc.1dex.com", // optional
  },
  powerupConfig: {
    // Powerup payer account
    payer: "powerup.account", // optional
    permission: "active", // optional
    privateKey: "powerup-private-key", // optional
  },
});
```

## HTTP API Client

The DexKit instance exposes an `httpApiClient` property that provides access to various API endpoints for retrieving market data and account information.

### Account and Balance

#### `getAccount()`

Retrieves account information.

```typescript
const account = await dexKit.httpApiClient.getAccount();
```

#### `getBalance()`

Retrieves the user's balance information.

```typescript
const balance = await dexKit.httpApiClient.getBalance();
```

### Market Data

#### `getAllPools(params?)`

Retrieves all available trading pools.

```typescript
// Get all pools
const allPools = await dexKit.httpApiClient.getAllPools();

// Get pools filtered by base or quote coin
const filteredPools = await dexKit.httpApiClient.getAllPools({
  baseCoin: "EOS",
  quoteCoin: "USDT",
});
```

#### `getPoolInfo(symbolOrPoolID)`

Retrieves detailed information about a specific pool.

```typescript
// Get pool by ID
const poolInfo = await dexKit.httpApiClient.getPoolInfo(1);
```

#### `getDepth(params)`

Retrieves order book depth data for a specific pool.

```typescript
const depth = await dexKit.httpApiClient.getDepth({
  id: 1,
  precision: 0.001,
  limit: 20, // Optional
});
```

#### `getKline(params)`

Retrieves kline/candlestick data for a specific pool.

```typescript
const klineData = await dexKit.httpApiClient.getKline({
  poolID: 1,
  period: "1h", // Options: '1min', '5min', '15min', '30min', '1h', '4h', '1d', '1w', '1M'
  startTime: 1609459200, // Optional: Unix timestamp in seconds
  endTime: 1609545600, // Optional: Unix timestamp in seconds
});
```

#### `getLatestTrades(params)`

Retrieves the latest trades for a specific pool.

```typescript
const latestTrades = await dexKit.httpApiClient.getLatestTrades({
  poolID: 1,
  limit: 20, // Optional
});
```

### Order Management

#### `getOpenOrders(params)`

Retrieves open (active) orders.

```typescript
const openOrders = await dexKit.httpApiClient.getOpenOrders({
  poolID: 1,
  side: "buy", // Optional: 'buy' or 'sell'
});
```

#### `getOrderHistory(params)`

Retrieves order history.

```typescript
const orderHistory = await dexKit.httpApiClient.getOrderHistory({
  poolID: 1,
  side: "buy", // Optional: 'buy' or 'sell'
  type: "limit", // Optional: 'limit' or 'market'
  status: "full_filled", // Optional: 'canceled', 'full_filled', 'partially_filled'
});
```

#### `getOrderDetail(params)`

Retrieves detailed information about a specific order.

```typescript
const orderDetail = await dexKit.httpApiClient.getOrderDetail({
  poolID: 1,
  orderID: 1,
  side: "buy", // Required: 'buy' or 'sell'
});
```

#### `getOrderDetailByCid(cid)`

Retrieves detailed information about a specific order by client order id.

```typescript
const orderDetail = await dexKit.httpApiClient.getOrderDetailByCid(cid);
```

### Token Information

#### `getSupportedTokens()`

Retrieves all supported tokens.

```typescript
const tokens = await dexKit.httpApiClient.getSupportedTokens();
```

#### `getTokenInfo(token)`

Retrieves detailed information about a specific token.

```typescript
const tokenInfo = await dexKit.httpApiClient.getTokenInfo("EOS");
```

## Complete Trading Example

```typescript
import { DexKit, ETradeSide, EOrderType } from "1dex-js-sdk";

async function tradingExample() {
  // Initialize SDK
  const dexKit = new DexKit({
    apiKey: "YOUR_API_KEY",
    secretKey: "YOUR_SECRET_KEY",
    apiClientConfig: {
      baseUrl: "https://api-v1.example.com", // Optional
    },
    blockchainRpcClientConfig: {
      chainID: "YOUR_CHAIN_ID", // Default: 'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906'
      rpcUrl: "https://rpc.example.com", // Default: 'https://spring-rpc.1dex.com'
    },
  });

  await dexKit.initialize();

  // Get available pools
  const pools = await dexKit.httpApiClient.getAllPools();
  const poolID = pools[0].pool_id;

  // Check market depth
  const depth = await dexKit.httpApiClient.getDepth({
    id: poolID,
    precision: 0.001,
  });

  // Place a limit buy order
  const txID = await dexKit.placeLimitOrder({
    poolID,
    side: ETradeSide.BUY,
    orderType: EOrderType.NO_RESTRICTION,
    amount: "10.0000",
    price: depth.bids[0][0], // Using the best bid price
  });

  console.log(`Order placed with transaction ID: ${txID}`);

  // Check open orders
  const openOrders = await dexKit.httpApiClient.getOpenOrders({
    poolID,
    side: "buy",
  });

  if (openOrders.length > 0) {
    // Cancel the first open order
    const orderID = openOrders[0].order_id;

    const cancelTxID = await dexKit.cancelOrder({
      poolID,
      orderID,
      side: ETradeSide.BUY,
    });

    console.log(`Order cancelled with transaction ID: ${cancelTxID}`);
  }
}

tradingExample().catch(console.error);
```

## Powerup Example

```typescript
import { DexKit } from "1dex-js-sdk";

const dexKit = new DexKit({
  apiKey: "",
  secretKey: "",
  enableProxy: false,
  powerupConfig: {
    payer: "",
    permission: "",
    privateKey: "",
  },
});

const MAX_RETRY_COUNT = 3; // 3 times
const CHECK_INTERVAL = 1000; // 1 second
const POWERUP_AVAILABLE_RATE = 0.1; // 10%

const powerupExample = async () => {
  await dexKit.initialize();

  const checkAndPowerup = async () => {
    let retryCount = 0;

    const tryPowerup = async () => {
      try {
        await dexKit.powerup();
        console.log("Powerup successful");
        return true;
      } catch (error) {
        console.error(`Powerup attempt ${retryCount + 1} failed:`, error);
        return false;
      }
    };

    while (true) {
      try {
        const resources = await dexKit.getAccountResources();

        const cpuAvailable = parseFloat(resources.cpuAvailable);
        const cpuMax = parseFloat(resources.cpuMax);
        const netAvailable = parseFloat(resources.netAvailable);
        const netMax = parseFloat(resources.netMax);

        console.log(
          `Current resources - CPU: ${((cpuAvailable / cpuMax) * 100).toFixed(
            2
          )}%, NET: ${((netAvailable / netMax) * 100).toFixed(2)}%`
        );

        if (cpuMax === 0 || netMax === 0) {
          retryCount = 0;
          while (retryCount < MAX_RETRY_COUNT) {
            const result = await tryPowerup();
            if (result) break;
            retryCount++;
            if (retryCount < MAX_RETRY_COUNT) {
              await new Promise((resolve) => setTimeout(resolve, 1000)); // Wait 1s before retry
            }
          }
        } else {
          const cpuRate = cpuAvailable / cpuMax;
          const netRate = netAvailable / netMax;

          if (
            cpuRate < POWERUP_AVAILABLE_RATE ||
            netRate < POWERUP_AVAILABLE_RATE
          ) {
            retryCount = 0;
            while (retryCount < MAX_RETRY_COUNT) {
              const result = await tryPowerup();
              if (result) break;
              retryCount++;
              if (retryCount < MAX_RETRY_COUNT) {
                await new Promise((resolve) => setTimeout(resolve, 1000)); // Wait 1s before retry
              }
            }
          }
        }
      } catch (error) {
        console.error("Error checking resources:", error);
      }

      // Wait for the next check interval
      await new Promise((resolve) => setTimeout(resolve, CHECK_INTERVAL));
    }
  };

  // Start the continuous monitoring
  await checkAndPowerup();
};

powerupExample();
```

## Error Handling

The SDK uses standardized error handling. Errors thrown by the SDK include detailed information about what went wrong. It's recommended to use try-catch blocks when interacting with the SDK:

```typescript
try {
  await dexKit.placeLimitOrder({
    poolID: 1,
    side: ETradeSide.BUY,
    orderType: EOrderType.NO_RESTRICTION,
    amount: "10.0000",
    price: "0.5000",
  });
} catch (error) {
  console.error("Error placing order:", error.message);
}
```

## License

[License Information]