Source

modules/OrderManager.ts

import {
  CreateOrderEntity,
  CreateOrderV2Params,
  DeleteOrderApiPayload,
  OrderHashType,
  OrderType,
  SplitSignature,
  UpdateOrderPrice,
  UpdateOrderPriceParams,
  UpdateOrderPriceResponse,
} from "../types/OrderTypes";
import { IMyriaClient, MyriaClient } from "../clients/MyriaClient";
import { OrderAPI } from "../core/apis/order.api";
import {
  CreateOrderAPIRequest,
  DeleteOrderPayload,
  GetOrderById,
  OrderEntity,
  SignableOrderInput,
  SignableOrderResponseData,
} from "../types/OrderTypes";
import { CommonModule } from "./CommonModule";
import { APIResponseType } from "../types/APIResponseType";
import { convertAmountToQuantizedAmount } from "../utils/Converter";
import { CommonAPI } from "../core/apis";
import { TokenType } from "../types";
import { DEFAULT_QUANTUM } from "../utils";
import { TransactionManager } from "./TransactionManager";

// const StarkwareLib = require("@starkware-industries/starkware-crypto-utils");

/**
 * Create OrderManager instance object
 * @class OrderManager
 * @param {MyriaClient} MyriaClient Interface of Myria Client
 * @example <caption>Constructor for OrderManager</caption>
 * 
 * 
 // Approach #1
  const mClient: IMyriaClient = {
      networkId: Network.SEPOLIA,
      provider: web3Instance.currentProvider,
      web3: web3Instance,
      env: EnvTypes.STAGING,
  };

  const moduleFactory = ModuleFactory.getInstance(mClient);
  const orderManager = moduleFactory.getOrderManager();

  // Approach #2
  const mClient: IMyriaClient = {
      networkId: Network.SEPOLIA,
      provider: web3Instance.currentProvider,
      web3: web3Instance,
      env: EnvTypes.STAGING,
  };

  const myriaClient = new MyriaClient(mClient);
  const orderManager = new OrderManager(myriaClient);
 */
export class OrderManager {
  private orderAPI: OrderAPI;
  private myriaClient: MyriaClient;

  private commonModule: CommonModule;
  private commonAPI: CommonAPI;

  private transactionManager: TransactionManager;

  constructor(mClient: IMyriaClient) {
    this.myriaClient = new MyriaClient(mClient);
    this.orderAPI = new OrderAPI(mClient.env);
    this.commonAPI = new CommonAPI(mClient.env);
    this.commonModule = new CommonModule(mClient);
    this.transactionManager = new TransactionManager(mClient);
  }

  /**
   * @summary Create order V2 (supported both of listing NFTs by ETH/MYR)
   * @param {CreateOrderV2Params} params Create order v2 params including the price/nft/assets information
   * @returns {OrderEntity} Details order information including fees and Asset_ID_Buy/Asset_ID_Sell/AmountBuy/AmountSell
   * @throws {string} Exception: Order type is required
   * @throws {string} Exception: Owner wallet address is required
   * @throws {string} Exception: Owner stark key is required
   * @throws {string} Exception: Price must be define and must be > 0
   * @throws {string} Exception: Asset Ref ID in Marketplace is required
   * @throws {string} Exception: Order is only supported for MINTABLE_ERC721
   * @throws {string} Exception: Token address is required for listing MINTABLE_ERC721
   * @throws {string} Exception: Token ID is required for listing MINTABLE_ERC721
   * @throws {string} Exception: Required the token received to be well-defined and tokenAddress is mandatory
   * @throws {string} Exception: New listing method for ERC20 isn't available on Mainnet yet. Please try with Testnet only.
   * @example <caption>Sample of createOrderV2({}) on Staging env</caption> 
   * 
   * const mClient: IMyriaClient = {
      networkId: Network.SEPOLIA,
      provider: web3Instance.currentProvider,
      web3: web3Instance,
      env: EnvTypes.STAGING,
  };
    const orderManager: OrderManager = new OrderManager(mClient);
    
    // Define createOrderV2 params
    const feeData: FeeDto[] = [
      {
        feeType: AssetDetailsInfo?.fee?.[0].feeType, // FeeType in asset details info
        percentage: AssetDetailsInfo?.fee?.[0].feeType, // Percentage of Fee as apart of asset details info
        address: AssetDetailsInfo?.fee?.[0].address, // The destination wallet address which would receive the percentage of Fee
      },
    ];

    const paramCreateOrder: CreateOrderV2Params = {
      orderType: OrderType.SELL,
      ownerWalletAddress: 'owner_wallet_address_that_own_nft',
      ownerStarkKey: 'owner_stark_key_0x...',
      assetRefId: 'Reference asset ID that intend to listing',
      tokenSell: {
        tokenType: TokenType.MINTABLE_ERC721,
        data: {
          tokenId: 'id of token',
          tokenAddress: 'token address of NFT',
        },
      },
      tokenReceived: {
        tokenType: 'TokenType.ETH or TokenType.ERC20',
        data: {
          tokenAddress: 'token address of currency',
        },
      },
      price: "100", // Set the price for the NFTs
      fees: feeData, // Only having data or undefined
    };

    const createdOrderResponse: OrderEntity = await orderManager.createOrderV2(paramCreateOrder);

    console.log("Order details response:");
    console.log(JSON.stringify(data, null, 2));
   */
  public async createOrderV2(
    params: CreateOrderV2Params
  ): Promise<OrderEntity> {
    if (!params.orderType) {
      throw new Error("Order type is required");
    }
    if (!params.ownerWalletAddress) {
      throw new Error("Owner wallet address is required");
    }
    if (!params.ownerStarkKey) {
      throw new Error("Owner stark key is required");
    }
    if (!params.price || params.price == "0") {
      throw new Error("Price must be define and must be > 0");
    }
    if (!params.assetRefId) {
      throw new Error("Asset Ref ID in Marketplace is required");
    }
    if (params.tokenSell.tokenType !== TokenType.MINTABLE_ERC721) {
      throw new Error("Order is only supported for MINTABLE_ERC721");
    }
    if (!params.tokenSell.data.tokenAddress) {
      throw new Error("Token address is required for listing MINTABLE_ERC721");
    }
    if (!params.tokenSell.data.tokenId) {
      throw new Error("Token ID is required for listing MINTABLE_ERC721");
    }

    if (!params.tokenReceived.data) {
      throw new Error('Token Receiver is required to specify');
    }

    if (
      params.tokenReceived.tokenType !== TokenType.ETH &&
      !params.tokenReceived.data.tokenAddress
    ) {
      throw new Error(
        "Required the token received to be well-defined and tokenAddress is mandatory"
      );
    }

    /**
     * Disable listing myria token in Prod until services get new deployment
     */
    // if ((this.myriaClient.env === EnvTypes.PREPROD || this.myriaClient.env === EnvTypes.PRODUCTION)
    //   && params.tokenReceived.tokenType === TokenType.ERC20) {
    //     throw new Error("New listing method for ERC20 isn't available on Mainnet yet. Please try with Testnet only.");
    // }

    const buildSignablePayload: SignableOrderInput = {
      orderType: params.orderType,
      ethAddress: params.ownerWalletAddress,
      assetRefId: params.assetRefId,
      starkKey: params.ownerStarkKey,
      tokenSell: {
        type: params.tokenSell.tokenType,
        data: params.tokenSell.data,
      },
      amountSell: "1", // Default as always for nFT
      tokenBuy: {
        type: params.tokenReceived.tokenType,
        data: {
          quantum: DEFAULT_QUANTUM,
          tokenAddress: params.tokenReceived.data.tokenAddress,
        },
      },
      amountBuy: params.price + "",
      includeFees: params.fees ? true : false,
      fees: params.fees,
    };

    const signableData: SignableOrderResponseData = await this.signableOrder(
      buildSignablePayload
    );
    const feeSign = signableData?.feeInfo
      ? {
          feeLimit: signableData?.feeInfo?.feeLimit,
          feeToken: signableData?.feeInfo?.assetId,
          feeVaultId: signableData?.feeInfo?.sourceVaultId,
        }
      : undefined;

    const feeData = signableData?.feeInfo
      ? [
          {
            feeType: params.fees[0].feeType,
            percentage: params.fees[0].percentage,
            address: params.fees[0].address,
          },
        ]
      : undefined;

    if (!signableData) {
      throw new Error(
        "Exception during fetch signable order data - cant execute further operation"
      );
    }

    // Check if asset type is available for listing
    let isAssetIdBuySupportListing = false;
    const availableAssetForListing =
      await this.transactionManager.getSupportedTokens();
    if (availableAssetForListing.status === "success") {
      availableAssetForListing.data.forEach((asset) => {
        if (
          asset.assetType.toLowerCase() === signableData.assetIdBuy?.toLowerCase() && asset.isSupportListing) {
          isAssetIdBuySupportListing = true;
        }
      });
    } else {
      throw new Error(
        "Fetch assets listing supported failed, cannot create order currently."
      );
    }

    if (!isAssetIdBuySupportListing) {
      throw new Error("This currency token is not supporting for listing yet");
    }

    const paramCreateOrder: CreateOrderEntity = {
      assetRefId: params.assetRefId,
      orderType: params.orderType,
      feeSign: feeSign,
      includeFees: feeData ? true : false,
      amountSell: signableData.amountSell,
      amountBuy: signableData.amountBuy,
      sellerStarkKey: params.ownerStarkKey,
      vaultIdSell: signableData.vaultIdSell,
      vaultIdBuy: signableData.vaultIdBuy,
      sellerAddress: params.ownerWalletAddress,
      nonce: signableData.nonce,
      assetIdBuy: signableData.assetIdBuy,
      assetIdSell: signableData.assetIdSell,
      fees: feeData,
    };
    const orderResponse = await this.createOrder(paramCreateOrder);

    return orderResponse;
  }

  public async createOrder(payload: CreateOrderEntity): Promise<OrderEntity> {
    let createOrderData;

    if (!payload.assetRefId) {
      throw new Error("Asset reference Id is required");
    }

    if (!payload.sellerAddress) {
      throw new Error("Seller address is not defined");
    }

    if (!payload.sellerStarkKey) {
      throw new Error("Seller stark key is not defined");
    }

    if (!payload.amountBuy) {
      throw new Error("Amount for buyer shoud be defined.");
    }

    if (!payload.amountSell) {
      throw new Error("Amount for seller should be defined.");
    }

    if (!payload.assetIdBuy) {
      throw new Error("Missing the assetIDBuy");
    }

    if (!payload.assetIdSell) {
      throw new Error("Missing the assetIDSell");
    }

    if (!payload.vaultIdBuy) {
      throw new Error("Missing the vaultIdBuy");
    }

    if (!payload.vaultIdSell) {
      throw new Error("Missing the vaultIdSell");
    }

    // Check if asset type is available for listing
    let isAssetIdBuySupportListing = false;
    const availableAssetForListing =
      await this.transactionManager.getSupportedTokens();
    if (availableAssetForListing.status === "success") {
      availableAssetForListing.data.forEach((asset) => {
        if (
          asset.assetType.toLowerCase() === payload.assetIdBuy?.toLowerCase() &&
          asset.isSupportListing
        ) {
          isAssetIdBuySupportListing = true;
        }
      });
    } else {
      throw new Error(
        "Fetch assets listing supported failed, cannot create order currently."
      );
    }

    if (!isAssetIdBuySupportListing) {
      throw new Error("This currency token is not supporting for listing yet");
    }

    // SET EXPIRATION TO BE EXPIRE IN 12 YEARS
    const expirationTimestamp = new Date();
    expirationTimestamp.setFullYear(expirationTimestamp.getFullYear() + 12);
    const expirationTime = Math.floor(
      expirationTimestamp.getTime() / (3600 * 1000)
    ).toString();

    try {
      // TODO - update with new API to get nonce
      // const nonceByStarkKey = await this.commonAPI.getNonceByStarkKey(payload.sellerStarkKey);
      const nonce = payload.nonce || Math.floor(Math.random() * 100000000) + 1;

      const quantizedAmountBuy = convertAmountToQuantizedAmount(
        String(payload.amountBuy)
      );
      const amountBuyNonFee =
        quantizedAmountBuy - Number(payload?.feeSign?.feeLimit);

      // console.log("Amount Buy Non Fee ->", amountBuyNonFee);
      // const quantizedAmountSell = convertAmountToQuantizedAmount(payload.amountSell);

      let orderPayload: OrderHashType = {
        includeFees: false,
        walletAddress: "",
        vaultIdSell: 0,
        vaultIdBuy: 0,
        amountSell: "",
        amountBuy: "",
        assetIdSell: "",
        assetIdBuy: "",
        nonce: 0,
        expirationTimestamp: 0,
      };

      let starkSignature: SplitSignature | undefined;

      if (payload?.includeFees && payload?.feeSign) {
        orderPayload = {
          includeFees: true,
          walletAddress: payload.sellerAddress,
          vaultIdSell: payload.vaultIdSell,
          vaultIdBuy: payload.vaultIdBuy,
          amountSell: String(payload.amountSell),
          amountBuy: String(amountBuyNonFee),
          assetIdSell: payload.assetIdSell,
          assetIdBuy: payload.assetIdBuy,
          nonce: nonce,
          expirationTimestamp: parseInt(expirationTime),
          fee: {
            feeLimit: payload?.feeSign?.feeLimit,
            feeToken: payload?.feeSign?.feeToken,
            feeVaultId: payload?.feeSign?.feeVaultId,
          },
        };
        console.log("orderPayload with fee Sign => ", orderPayload);
        starkSignature =
          await this.commonModule.generateStarkSignatureForOrderWithFee(
            orderPayload
          );
        if (!starkSignature) {
          throw new Error("Stark signature generation error ");
        }
      } else {
        orderPayload = {
          includeFees: false,
          walletAddress: payload.sellerAddress,
          vaultIdSell: payload.vaultIdSell,
          vaultIdBuy: payload.vaultIdBuy,
          amountSell: String(payload.amountSell),
          amountBuy: String(quantizedAmountBuy),
          assetIdSell: payload.assetIdSell,
          assetIdBuy: payload.assetIdBuy,
          nonce: nonce,
          expirationTimestamp: parseInt(expirationTime),
        };
        console.log("orderPayload => ", orderPayload);
        starkSignature = await this.commonModule.generateStarkSignatureForOrder(
          orderPayload
        );
        if (!starkSignature) {
          throw new Error("Stark signature generation error ");
        }
      }
      console.log("orderPayload ->", JSON.stringify(orderPayload));

      const requestBody: CreateOrderAPIRequest = {
        assetRefId: payload.assetRefId,
        quantizedAmountBuy: Number(quantizedAmountBuy),
        quantizedAmountSell: payload.amountSell,
        nonQuantizedAmountSell: payload.amountSell,
        nonQuantizedAmountBuy: payload.amountBuy,
        assetIdBuy: payload.assetIdBuy,
        assetIdSell: payload.assetIdSell,
        fees: payload.fees,
        includeFees: payload.includeFees,
        nonce: nonce,
        orderType: payload.orderType,
        starkKey: payload.sellerStarkKey,
        vaultIdBuy: payload.vaultIdBuy,
        vaultIdSell: payload.vaultIdSell,
        starkSignature: starkSignature,
        expirationTimestamp: expirationTime,
        sellerAddress: payload.sellerAddress,
      };

      const createOrderRes = await this.orderAPI.createOrder(requestBody);

      if (createOrderRes?.status === "success") {
        createOrderData = createOrderRes?.data;
      } else {
        throw new Error("Create Orders failure");
      }
    } catch (err) {
      throw new Error(err);
    }

    return createOrderData;
  }

  public async signableOrder(
    payload: SignableOrderInput
  ): Promise<SignableOrderResponseData> {
    if (!payload.orderType) {
      throw new Error("One field is missing: orderType");
    }

    if (payload.includeFees && !payload.assetRefId) {
      throw new Error("Missing asset ref id for fee");
    }

    if (!payload.ethAddress) {
      throw new Error("One field is missing: ethAddress");
    }

    if (!payload.starkKey) {
      throw new Error("One field is missing: starkKey");
    }

    if (!payload.tokenSell) {
      throw new Error("One field is missing: tokenSell");
    }

    if (!payload.amountSell) {
      throw new Error("One field is missing: amountSell");
    }

    if (!payload.tokenBuy) {
      throw new Error("One field is missing: tokenBuy");
    }

    if (!payload.amountBuy) {
      throw new Error("One field is missing: amountBuy");
    }

    try {
      const response = await this.orderAPI.signableOrder(payload);
      if (response.status === "success") {
        return response.data;
      } else {
        throw new Error("Creaate signable order failed!");
      }
    } catch (err) {
      throw new Error(err);
    }
  }

  public async getOrders(): Promise<OrderEntity[]> {
    let ordersData;
    try {
      const getOrdersRes = await this.orderAPI.getOrders();
      if (getOrdersRes) {
        ordersData = getOrdersRes;
      } else {
        throw new Error("Get Orders failed!");
      }
    } catch (err) {
      throw new Error(err);
    }

    return ordersData;
  }

  public async getOrderById(payload: GetOrderById): Promise<OrderEntity> {
    let orderByIdData;
    if (payload.id) {
      try {
        const orderByIdResponse = await this.orderAPI.getOrderById(payload);
        if (orderByIdResponse) {
          orderByIdData = orderByIdResponse;
        } else {
          throw new Error("Get Order By Id failed!");
        }
      } catch (err) {
        throw new Error(err);
      }
    } else {
      throw new Error("Id shoud be provided.");
    }

    return orderByIdData;
  }

  public async deleteOrderById(
    payload: DeleteOrderPayload
  ): Promise<OrderEntity> {
    let deletedOrder;

    const orderDetails = await this.orderAPI.getOrderById({
      id: payload.orderId,
    });
    console.log("[Core-SDK] order details", JSON.stringify(orderDetails));

    if (!payload.orderId) {
      throw new Error("One field is missing: orderId");
    }

    if (!payload.sellerWalletAddress) {
      throw new Error("One field is missing: sellerWalletAddress");
    }

    try {
      const orderHashPayload: OrderHashType = {
        vaultIdSell: 0,
        vaultIdBuy: 0,
        amountBuy: "0",
        amountSell: "0",
        assetIdSell: orderDetails.assetIdSell,
        assetIdBuy: orderDetails.assetIdBuy,
        nonce: orderDetails.nonce,
        expirationTimestamp: 0,
        includeFees: false,
        walletAddress: payload.sellerWalletAddress,
      };
      console.log(
        "[Core-SDK] order hash payload ->",
        JSON.stringify(orderHashPayload)
      );
      const starkSignature =
        await this.commonModule.generateStarkSignatureForOrder(
          orderHashPayload
        );

      const requestPayload: DeleteOrderApiPayload = {
        orderId: payload.orderId,
        nonce: orderDetails.nonce,
        signature: starkSignature,
      };

      const deleteOrderRes = await this.orderAPI.deleteOrderById(
        requestPayload
      );

      if (deleteOrderRes) {
        deletedOrder = deleteOrderRes;
      } else {
        throw new Error("Delete Order failed!");
      }
    } catch (err) {
      throw new Error(err);
    }

    return deletedOrder;
  }

  public async updateOrderPrice(
    orderId: string,
    payload: UpdateOrderPriceParams
  ): Promise<APIResponseType<UpdateOrderPriceResponse> | undefined> {
    let orderData: any;

    if (!orderId) {
      throw new Error("One field is missing: orderId");
    }

    const currentOrder = await this.orderAPI.getOrderById({
      id: Number(orderId),
    });

    if (!currentOrder.assetIdBuy) {
      throw new Error("One field is missing: assetIdBuy");
    }

    if (!currentOrder.assetIdSell) {
      throw new Error("One field is missing: assetIdSell");
    }

    if (!payload.newAmountBuy || Number(payload.newAmountBuy) == 0) {
      throw new Error("New amount should be defined and greater 0");
    }

    if (!payload.sellerWalletAddress) {
      throw new Error("WalletAddress should be provided.");
    }

    if (!payload.sellerStarkKey) {
      throw new Error("Seller starkKey is required!");
    }

    if (!payload.tokenBuy) {
      throw new Error('Token buy is required')
    } else if (payload.tokenBuy.type === TokenType.ERC20 && !payload.tokenBuy.data.tokenAddress) {
      throw new Error ("Token buy with ERC20 is required token address");
    }

    if (!payload.tokenSell) {
      throw new Error("Token sell is required");
    } else if (payload.tokenSell.type !== TokenType.MINTABLE_ERC721) {
      throw new Error("Only support sell MINTABLE_ERC721 tokens for now");
    }

    const newQuantizedAmountBuy = String(
      convertAmountToQuantizedAmount(payload.newAmountBuy)
    );

    // Get signable order
    const buildSignablePayload: SignableOrderInput = {
      orderType: OrderType.SELL,
      ethAddress: payload.sellerWalletAddress,
      assetRefId: currentOrder.assetRefId,
      starkKey: payload.sellerStarkKey,
      tokenSell: {
        type: TokenType.MINTABLE_ERC721,
        data: {
          tokenAddress: payload.tokenSell.data.tokenAddress,
          tokenId: payload.tokenSell.data.tokenId,
        },
      },
      amountSell: "1", // Default as always for nFT
      tokenBuy: {
        type: payload.tokenBuy.type,
        data: {
          quantum: DEFAULT_QUANTUM,
          tokenAddress: payload.tokenBuy.data.tokenAddress,
        },
      },
      amountBuy: payload.newAmountBuy + "",
      includeFees: payload.fees ? true : false,
      fees: payload.fees,
    };

    const signableData: SignableOrderResponseData = await this.signableOrder(
      buildSignablePayload
    );


    try {
      // get expirationTimestamp
      let expiredAt;
      expiredAt = new Date();
      expiredAt.setFullYear(expiredAt.getFullYear() + 12);
      expiredAt = Math.floor(expiredAt.getTime() / 3600 / 1000);

      // TODO - update with new API to get nonce
      // const nonceByStarkKey = await this.commonAPI.getNonceByStarkKey(payload.sellerStarkKey);
      const nonceData = payload.nonce || Math.floor(Math.random() * 100000000) + 1;
      
      let sellOrderMsg: OrderHashType;

      // stark signature of created sell order
      let starkSignatureSell;
      if (buildSignablePayload?.includeFees && signableData?.feeInfo) {
        const amountBuyNonFee = Number(newQuantizedAmountBuy) - Number(signableData.feeInfo.feeLimit);
        sellOrderMsg = {
          includeFees: true,
          walletAddress: payload.sellerWalletAddress,
          vaultIdSell: signableData.vaultIdSell,
          vaultIdBuy: signableData.vaultIdBuy,
          amountSell: String(signableData.amountSell),
          amountBuy: String(amountBuyNonFee),
          assetIdSell: signableData.assetIdSell,
          assetIdBuy: signableData.assetIdBuy,
          nonce: signableData.nonce ?? Number(nonceData),
          expirationTimestamp: Number(expiredAt),
          fee: {
            feeLimit: signableData.feeInfo.feeLimit,
            feeToken: signableData.feeInfo.assetId,
            feeVaultId: signableData.feeInfo.sourceVaultId,
          },
        };
        starkSignatureSell = await this.commonModule.generateStarkSignatureForOrderWithFee(sellOrderMsg);
      } else {
        sellOrderMsg = {
          includeFees: false,
          walletAddress: payload.sellerWalletAddress,
          vaultIdSell: currentOrder.vaultIdSell,
          vaultIdBuy: currentOrder.vaultIdBuy,
          amountSell: String(currentOrder.amountSell),
          amountBuy: newQuantizedAmountBuy,
          assetIdSell: currentOrder.assetIdSell,
          assetIdBuy: currentOrder.assetIdBuy,
          nonce: signableData.nonce ?? Number(nonceData),
          expirationTimestamp: expiredAt,
        };
        starkSignatureSell = await this.commonModule.generateStarkSignatureForOrder(sellOrderMsg);
      }
      
      console.log("orderPayload ->", JSON.stringify(sellOrderMsg));
      

      // stark signature of sell order which is going to be canceled
      const cancelOrderMsg: OrderHashType = {
        includeFees: false,
        walletAddress: payload.sellerWalletAddress,
        vaultIdBuy: 0,
        vaultIdSell: 0,
        amountBuy: "0",
        amountSell: "0",
        assetIdBuy: currentOrder.assetIdBuy,
        assetIdSell: currentOrder.assetIdSell,
        nonce: currentOrder.nonce,
        expirationTimestamp: 0,
      };
      const starkSignatureCancel =
        await this.commonModule.generateStarkSignatureForOrder(cancelOrderMsg);

      if (payload.expirationTimestamp) {
        expiredAt = payload.expirationTimestamp;
      }

      if (starkSignatureCancel && starkSignatureSell) {
        const upatePricePayload: UpdateOrderPrice = {
          expirationTimestamp: expiredAt,
          newAmountBuy: newQuantizedAmountBuy,
          nonQuantizedAmountBuy: payload.newAmountBuy,
          nonce: signableData.nonce ?? Number(nonceData),
          starkKey: payload.sellerStarkKey,
          starkSignatureCancelOrder: starkSignatureCancel,
          starkSignatureSellOrder: starkSignatureSell,
          nonQuantizedAmountSell: "1",
          orderType: OrderType.SELL,
          includeFees: sellOrderMsg.includeFees,
          fees: payload.fees
        };

        const orderRes = await this.orderAPI.requestUpdateOrderPrice(
          orderId,
          upatePricePayload
        );
        if (orderRes?.status === "success") {
          orderData = orderRes?.data;
        } else {
          throw new Error("Update Order Price failure");
        }
      } else {
        throw new Error("Signaturing Error!");
      }
    } catch (error) {
      throw new Error(error);
    }
    return orderData;
  }
}