# Typescript SDK

Typescript SDK: <https://www.npmjs.com/package/gfx-perp-sdk>

GooseFX Perpetual Futures SDK is designed for market makers and trading enthusiasts, allowing interaction with the GooseFX on-chain perpetual futures.&#x20;

The Typescript SDK consists of three classes:

1. **Perp**
2. **Product**
3. **Trader**

### Perp

The Perp class is essential for initializing the connection and wallet used for subsequent interactions. Initializing the Perp class should always be the first step, regardless of the operation type.&#x20;

**Constructor**

```javascript
const perp = new Perp(connection, networkType, wallet);
```

| Parameter                 | Description                                                                                          |
| ------------------------- | ---------------------------------------------------------------------------------------------------- |
| `connection` (Connection) | An instance of the `Connection` class from `@solana/web3.js` to communicate with the Solana network. |
| `networkType` (string)    | A string indicating the network type, such as 'mainnet' or 'devnet'.                                 |
| `wallet` (Wallet)         | An instance of the `Wallet` class from `@project-serum/anchor` representing the user's wallet.       |

Methods

init()

Initializes the `Perp` instance by setting up necessary market and product group information.

```javascript
await perp.init();
```

**Returns:** `Promise<void>`

| Properties         | Description                                                                       |
| ------------------ | --------------------------------------------------------------------------------- |
| wallet             | The wallet instance passed during the construction of the `Perp` object.          |
| connection         | The connection instance to the Solana network.                                    |
| program            | The on-chain program associated with the perp market.                             |
| networkType        | The type of network the `Perp` instance is connected to.                          |
| marketProductGroup | The product group information for the market, undefined until `init()` is called. |

Here's an example of how to initialize the Perp class.

```javascript
const perp = new Perp(connection, 'mainnet', wallet);
await perp.init();
```

### Product

A Product instance represents one of the perpetual products we offer to trade. You can initialize the Product class in two ways: by index or by name. The Product instance can be used for various functions, such as getting the L2 and L3 orderbooks, and subscribing to the orderbook.

**Constructor**

```javascript
const product = new Product(perp);
```

| Parameters    | Desription                                                               |
| ------------- | ------------------------------------------------------------------------ |
| `perp` (Perp) | An instance of the Perp class representing the perpetual futures market. |

#### Methods

**initByIndex(index)**

Initializes the product by its index within the market.

```javascript
product.initByIndex(0);
```

| Parameters       | Description                                 |
| ---------------- | ------------------------------------------- |
| `index` (number) | The index of the product within the market. |

**Returns:** `void`

**getOrderbookL2()**

Retrieves the Level 2 order book for the product.

```javascript
const orderbook = await product.getOrderbookL2();
```

**Returns:** `Promise<Ordrbook>` - An object representing the Level 2 order book.

**getOrderbookL3()**

Retrieves the Level 3 order book for the product.

```javascript
const orderbook = await product.getOrderbookL3();
```

**Returns:** `Promise<Ordrbook>` - An object representing the Level 3 order book.

#### Initializing Product by Index:

```javascript
const perp = new Perp(connection, 'mainnet', wallet);
await perp.init();
const product = new Product(perp);
product.initByIndex(0);
```

#### Initializing Product by Name:

```javascript
const perp = new Perp(connection, 'mainnet', wallet);
await perp.init();
const product = new Product(perp);
product.initByName('SOL-PERP');
```

### Product Function Examples:

**1. Get L2 Orderbook**

```javascript
const orderbook = await product.getOrderbookL2();
```

**2. Get L3 Orderbook**

```javascript
const orderbook = await product.getOrderbookL3();
```

**3. Subscribe to Orderbook**

Subscribe to the orderbook account and listen to changes. Pass your function as the parameter to the `subscribeToOrderbook` function to handle orderbook changes. Don't forget to unsubscribe when it's no longer needed!

```javascript
async function handleAccountChange(){
    const res = await product.getOrderbookL2();
    console.log("Updated orderbook: ", res);
  }
  const subscribeId = product.subscribeToOrderbook(handleAccountChange);
  connection.removeAccountChangeListener(subscribeId); //To close the subscription
```

### Trader

The Trader class is necessary for obtaining instructions to send transactions to the program. Each wallet must have a unique trader account initialized to place orders and deposit funds. Create the trader account once using the `createTraderAccountIxs` instruction. After that, initialize the Trader class using the `init` function for all subsequent wallet interactions.

**Constructor**

```javascript
const trader = new Trader(perp);
```

| Parameters    | Description                                                   |
| ------------- | ------------------------------------------------------------- |
| `perp` (Perp) | An instance of the `Perp` class representing the perp market. |

#### Methods

**createTraderAccountIxs()**

Creates the transaction instructions and signers required to initialize a new trader account.

```javascript
const [ixs, signers] = await trader.createTraderAccountIxs();
```

**Returns:** `Promise<[TransactionInstruction[], Keypair[]]>` - An array containing the transaction instructions and signers.

**depositFundsIx(fractional)**

Creates a transaction instruction for depositing funds into the trader's account.

```javascript
const ix = await trader.depositFundsIx(fractional);
```

| Parameters                | Description                                        |
| ------------------------- | -------------------------------------------------- |
| `fractional` (Fractional) | An object representing the amount to be deposited. |

**Returns:** `Promise<[TransactionInstruction>` - The transaction instruction for depositing funds.

**withdrawFundsIx(fractional)**

Creates a transaction instruction for withdrawing funds from the trader's account.

```javascript
const ix = await trader.withdrawFundsIx(fractional);
```

| Parameters                | Description                                        |
| ------------------------- | -------------------------------------------------- |
| `fractional` (Fractional) | An object representing the amount to be withdrawn. |

**Returns:** `Promise<[TransactionInstruction>` - The transaction instruction for withdrawing funds.

**newOrderIx(size, price, side, type, product, ttl)**

Creates a transaction instruction for placing a new order.

{% code overflow="wrap" %}

```javascript
const ix = await trader.newOrderIx(size, price, side, type, product, ttl);
```

{% endcode %}

| Parameters           | Description                                                                              |
| -------------------- | ---------------------------------------------------------------------------------------- |
| `size` (Fractional)  | An object representing the size of the order                                             |
| `price` (Fractional) | An object representing the price of the order.                                           |
| `side` (string)      | The side of the order, either 'buy' or 'sell'.                                           |
| `type` (string)      | The type of the order, such as 'limit' or 'market'.                                      |
| `product` (Product)  | An instance of the Product class representing the product for which the order is placed. |
| `ttl` (number)       | Time to live for the order.                                                              |

**Returns:** `Promise<[TransactionInstruction>` - The transaction instruction for placing a new order.

**cancelOrderIx(orderId, product)**

Creates a transaction instruction for canceling an existing order.

```javascript
const ix = await trader.cancelOrderIx(orderId, product);
```

| Parameters          | Description                                                                          |
| ------------------- | ------------------------------------------------------------------------------------ |
| orderId (string)    | The ID of the order to be canceled.                                                  |
| `product` (Product) | n instance of the Product class representing the product for which the order exists. |

**Returns:** `Promise<[TransactionInstruction>` - The transaction instruction for canceling the order.

**getOpenOrders(product)**

Retrieves the open orders for the trader within a specific product.

```javascript
const orderbookData = await trader.getOpenOrders(product);
```

| Parameters          | Description                                                                                    |
| ------------------- | ---------------------------------------------------------------------------------------------- |
| `product` (Product) | An instance of the Product class representing the product for which open orders are retrieved. |

**Returns:** `Promise<OrderbookData>` - An object representing the open orders data.

| Properties          | Description                                     |
| ------------------- | ----------------------------------------------- |
| `perp`              | The `Perp` instance associated with the trader. |
| `totalDeposited`    | The total amount deposited by the trader.       |
| `totalWithdrawn`    | The total amount withdrawn by the trader.       |
| `marginAvailable`   | The available margin for trading.               |
| `totalTradedVolume` | The total volume traded by the trader.          |
| `traderPositions`   | The active positions held by the trader.        |

#### Creating a New Trader Account On-Chain:

```javascript
  const perp = new Perp(connection, 'mainnet', wallet);
  await perp.init();
  const trader = new Trader(perp);
  const [ixs, signers] = await trader.createTraderAccountIxs();
```

In this example, `ixs` is an array of required instructions and `signers` is an array of required keypairs for signature. The wallet must also sign the transaction along with the keypairs in the `signers` array.

#### Initializing a Trader Instance

Once you successfully create an account, initialize the Trader instance as follows:

### Fractional Data Type

The Fractional data type represents a fractional number based on its mantissa (m) and exponent (exp) using this formula: `number = mantissa / (10 ^ exponent)`.

### Trader Instructions

#### Depositing Funds

To place new orders, traders need to deposit collateral. This instruction transfers the required USDC from the wallet to the trader account, which will be used as collateral to place new orders.

The only parameter for this function is the amount of USDC to deposit:

```javascript
  const perp = new Perp(connection, 'mainnet', wallet);
  await perp.init();
  const trader = new Trader(perp);
  await trader.init();
  const ix = await trader.depositFundsIx(new Fractional({
    m: new BN(1),
    exp: new BN(0)
  }));
```

#### Withdrawing Funds

Similar to depositing funds, this function takes the amount of USDC to be withdrawn as the only parameter. This instruction transfers funds from the trader account to the wallet address:

```javascript
  const perp = new Perp(connection, 'mainnet', wallet);
  await perp.init();
  const trader = new Trader(perp);
  await trader.init();
  const ix = await trader.withdrawFundsIx(new Fractional({
    m: new BN(1),
    exp: new BN(0)
  }));java
```

**Note**: The deposit and withdraw instructions do not require a `product` instance as a parameter, as the market is cross collateralized and the amount of USDC deposited can be used across products. The following instructions, placing a new order and canceling an order, are specific to products and need a `product` instance as one of the parameters.

#### Getting Trader's Open Orders for a Product

To get all open orders for a `Trader` for a `product`:

```javascript
  const perp = new Perp(connection, 'mainnet', wallet);
  await perp.init();
  const product = new Product(perp);
  product.initByIndex(0);
  const trader = new Trader(perp);
  await trader.init();
  const orderbookData = await trader.getOpenOrders(product);
  console.log("orderbook: ", orderbookData);
```

#### Placing a New Order

The new order instruction requires the following parameters:

* Quantity (Fractional): *1 unit of the product is denoted by 1 \* 100,000 units. To buy 1 unit, pass the following parameter as quantity:*

```javascript
  new Fractional({
    m: new BN(100000),
    exp: new BN(0)
  })
```

* Price (Fractional)
* Order side ('buy' or 'sell')
* Order Type ('limit', 'market', 'immediateOrCancel', 'postOnly')
* Product instance

**Here's an example of placing a new order:**

```javascript
  const perp = new Perp(connection, "mainnet", wallet);
  await perp.init();
  const product = new Product(perp);
  product.initByIndex(0);
  const trader = new Trader(perp);
  await trader.init();
  const ix = await trader.newOrderIx(
    new Fractional({
      m: new BN(10000), //Implies 0.1 units
      exp: new BN(0),
    }),
    new Fractional({
      m: new BN(2245), //Price 22.45$
      exp: new BN(2),
    }),
    "buy",
    "limit",
    product
  );
```

#### Canceling an Order

The cancel order instruction requires the `orderId` in string format. Use `getOpenOrders()` to get open orders and their IDs to pass as a parameter to cancel the order:

```javascript
const perp = new Perp(connection, "mainnet", wallet);
  await perp.init();
  const product = new Product(perp);
  product.initByIndex(0);
  const trader = new Trader(perp);
  await trader.init();
  const ix = await trader.cancelOrderIx("7922816251444880503428103912726", product);
```

#### ***Checkout*** [***https://github.com/GooseFX1/gfx-perp-ts-sdk/blob/main/test/index.test.js***](https://github.com/GooseFX1/gfx-perp-ts-sdk/blob/main/test/index.test.js) ***for examples on the above functionalities!***
