aftermath-ts-sdk
Version:
Aftermath TypeScript SDK
1,110 lines (1,109 loc) • 48.9 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PerpetualsApi = void 0;
const transactions_1 = require("@mysten/sui/transactions");
const utils_1 = require("../../../general/utils");
const sui_1 = require("../../sui");
const eventsApiHelpers_1 = require("../../../general/apiHelpers/eventsApiHelpers");
const transactionsApiHelpers_1 = require("../../../general/apiHelpers/transactionsApiHelpers");
const bcs_1 = require("@mysten/sui/bcs");
class PerpetualsApi {
// =========================================================================
// Constructor
// =========================================================================
constructor(Provider) {
this.Provider = Provider;
// =========================================================================
// Transaction Commands
// =========================================================================
this.depositCollateralTx = (inputs) => {
const { tx, collateralCoinType, accountCapId } = inputs;
return tx.moveCall({
target: utils_1.Helpers.transactions.createTxTarget(this.addresses.perpetuals.packages.perpetuals, PerpetualsApi.constants.moduleNames.interface, "deposit_collateral"),
typeArguments: [collateralCoinType],
arguments: [
typeof accountCapId === "string"
? tx.object(accountCapId)
: accountCapId,
"coinBytes" in inputs
? tx.pure(inputs.coinBytes)
: typeof inputs.coinId === "string"
? tx.object(inputs.coinId)
: inputs.coinId,
],
});
};
this.allocateCollateralTx = (inputs) => {
const { tx, collateralCoinType, accountCapId, marketId, amount } = inputs;
return tx.moveCall({
target: utils_1.Helpers.transactions.createTxTarget(inputs.packageId, PerpetualsApi.constants.moduleNames.interface, "allocate_collateral"),
typeArguments: [collateralCoinType],
arguments: [
tx.sharedObjectRef({
objectId: marketId,
initialSharedVersion: inputs.marketInitialSharedVersion,
mutable: true,
}),
typeof accountCapId === "string"
? tx.object(accountCapId)
: accountCapId,
tx.pure.u64(amount),
],
});
};
this.deallocateCollateralTx = (inputs) => {
const { tx, collateralCoinType, accountCapId, marketId, amount } = inputs;
return tx.moveCall({
target: utils_1.Helpers.transactions.createTxTarget(inputs.packageId, PerpetualsApi.constants.moduleNames.interface, "deallocate_collateral"),
typeArguments: [collateralCoinType],
arguments: [
tx.sharedObjectRef({
objectId: marketId,
initialSharedVersion: inputs.marketInitialSharedVersion,
mutable: true,
}),
tx.object(accountCapId),
tx.object(inputs.basePriceFeedId),
tx.object(inputs.collateralPriceFeedId),
tx.object(sui_1.Sui.constants.addresses.suiClockId),
tx.pure.u64(amount),
],
});
};
this.createMarketPositionTx = (inputs) => {
const { tx, collateralCoinType, accountCapId, marketId } = inputs;
return tx.moveCall({
target: utils_1.Helpers.transactions.createTxTarget(inputs.packageId, PerpetualsApi.constants.moduleNames.interface, "create_market_position"),
typeArguments: [collateralCoinType],
arguments: [
tx.sharedObjectRef({
objectId: marketId,
initialSharedVersion: inputs.marketInitialSharedVersion,
mutable: true,
}),
typeof accountCapId === "string"
? tx.object(accountCapId)
: accountCapId,
],
});
};
this.shareClearingHouseTx = (inputs) => {
const { tx, collateralCoinType, marketId } = inputs;
return tx.moveCall({
target: utils_1.Helpers.transactions.createTxTarget(inputs.packageId, PerpetualsApi.constants.moduleNames.interface, "share_clearing_house"),
typeArguments: [collateralCoinType],
arguments: [
typeof marketId === "string" ? tx.object(marketId) : marketId,
],
});
};
this.startSessionTx = (inputs) => {
const { tx, collateralCoinType, accountCapId, marketId } = inputs;
return tx.moveCall({
target: utils_1.Helpers.transactions.createTxTarget(inputs.packageId, PerpetualsApi.constants.moduleNames.interface, "start_session"),
typeArguments: [collateralCoinType],
arguments: [
tx.sharedObjectRef({
objectId: marketId,
initialSharedVersion: inputs.marketInitialSharedVersion,
mutable: true,
}),
typeof accountCapId === "string"
? tx.object(accountCapId)
: accountCapId,
tx.object(inputs.basePriceFeedId),
tx.object(inputs.collateralPriceFeedId),
tx.object(sui_1.Sui.constants.addresses.suiClockId),
],
});
};
this.endSessionTx = (inputs) => {
const { tx, collateralCoinType, sessionPotatoId } = inputs;
return tx.moveCall({
target: utils_1.Helpers.transactions.createTxTarget(inputs.packageId, PerpetualsApi.constants.moduleNames.interface, "end_session"),
typeArguments: [collateralCoinType],
arguments: [
typeof sessionPotatoId === "string"
? tx.object(sessionPotatoId)
: sessionPotatoId,
],
});
};
this.placeMarketOrderTx = (inputs) => {
const { tx, collateralCoinType, sessionPotatoId, side, size } = inputs;
return tx.moveCall({
target: utils_1.Helpers.transactions.createTxTarget(inputs.packageId, PerpetualsApi.constants.moduleNames.interface, "place_market_order"),
typeArguments: [collateralCoinType],
arguments: [
typeof sessionPotatoId === "string"
? tx.object(sessionPotatoId)
: sessionPotatoId,
tx.pure.bool(Boolean(side)),
tx.pure.u64(size),
],
});
};
this.placeLimitOrderTx = (inputs) => {
const { tx, collateralCoinType, sessionPotatoId, side, size, price, orderType, } = inputs;
return tx.moveCall({
target: utils_1.Helpers.transactions.createTxTarget(inputs.packageId, PerpetualsApi.constants.moduleNames.interface, "place_limit_order"),
typeArguments: [collateralCoinType],
arguments: [
typeof sessionPotatoId === "string"
? tx.object(sessionPotatoId)
: sessionPotatoId,
tx.pure.bool(Boolean(side)),
tx.pure.u64(size),
tx.pure.u64(price),
tx.pure.u64(BigInt(orderType)),
],
});
};
this.cancelOrdersTx = (inputs) => {
const { tx, collateralCoinType, accountCapId, marketId, orderIds } = inputs;
return tx.moveCall({
target: utils_1.Helpers.transactions.createTxTarget(inputs.packageId, PerpetualsApi.constants.moduleNames.interface, "cancel_orders"),
typeArguments: [collateralCoinType],
arguments: [
tx.sharedObjectRef({
objectId: marketId,
initialSharedVersion: inputs.marketInitialSharedVersion,
mutable: true,
}),
tx.object(accountCapId),
tx.pure(bcs_1.bcs.vector(bcs_1.bcs.u128()).serialize(orderIds)),
],
});
};
this.reduceOrdersTx = (inputs) => {
const { tx, packageId, collateralCoinType, accountCapId, marketId, orderIds, sizesToSubtract, } = inputs;
return tx.moveCall({
target: utils_1.Helpers.transactions.createTxTarget(packageId, PerpetualsApi.constants.moduleNames.interface, "reduce_orders"),
typeArguments: [collateralCoinType],
arguments: [
tx.sharedObjectRef({
objectId: marketId,
initialSharedVersion: inputs.marketInitialSharedVersion,
mutable: true,
}),
tx.object(accountCapId),
tx.pure(bcs_1.bcs.vector(bcs_1.bcs.u128()).serialize(orderIds)),
tx.pure(bcs_1.bcs.vector(bcs_1.bcs.u64()).serialize(sizesToSubtract)),
],
});
};
this.withdrawCollateralTx = (inputs) => {
const { tx, collateralCoinType, accountCapId, amount } = inputs;
return tx.moveCall({
target: utils_1.Helpers.transactions.createTxTarget(this.addresses.perpetuals.packages.perpetuals, PerpetualsApi.constants.moduleNames.interface, "withdraw_collateral"),
typeArguments: [collateralCoinType],
arguments: [
typeof accountCapId === "string"
? tx.object(accountCapId)
: accountCapId,
tx.pure.u64(amount),
],
});
};
this.createAccountTx = (inputs) => {
const { tx, collateralCoinType } = inputs;
return tx.moveCall({
target: utils_1.Helpers.transactions.createTxTarget(this.addresses.perpetuals.packages.perpetuals, PerpetualsApi.constants.moduleNames.interface, "create_account"),
typeArguments: [collateralCoinType],
arguments: [tx.object(this.addresses.perpetuals.objects.registry)],
});
};
// public getHotPotatoFieldsTx = (
// inputs: {
// tx: Transaction;
// collateralCoinType: CoinType;
// sessionPotatoId: ObjectId | TransactionArgument;
// }
// /*
// (
// lot_size,
// tick_size,
// timestamp_ms,
// collateral_price,
// index_price,
// book_price,
// fills,
// post
// ): (
// u64,
// u64,
// u64,
// u64,
// u256,
// u256,
// u256,
// &vector<FillReceipt>,
// &PostReceipt
// )
// */
// ) => {
// const { tx, collateralCoinType, sessionPotatoId } = inputs;
// return tx.moveCall({
// target: Helpers.transactions.createTxTarget(
// inputs.packageId,
// PerpetualsApi.constants.moduleNames.clearingHouse,
// "get_hot_potato_fields"
// ),
// typeArguments: [collateralCoinType],
// arguments: [
// typeof sessionPotatoId === "string"
// ? tx.object(sessionPotatoId)
// : sessionPotatoId,
// ],
// });
// };
this.placeSLTPOrderTx = (inputs) => {
throw new Error("TODO");
// const { tx } = inputs;
// if ("price" in inputs) {
// this.placeLimitOrderTx({ ...inputs, tx });
// } else {
// this.placeMarketOrderTx({ ...inputs, tx });
// }
// const orderType = PerpetualsOrderType.PostOnly;
// const side =
// inputs.side === PerpetualsOrderSide.Ask
// ? PerpetualsOrderSide.Bid
// : PerpetualsOrderSide.Ask;
// const orderPrice =
// "price" in inputs ? inputs.price : inputs.marketPrice;
// if (
// "slPrice" in inputs &&
// ((inputs.side === PerpetualsOrderSide.Ask &&
// inputs.slPrice > orderPrice) ||
// (inputs.side === PerpetualsOrderSide.Bid &&
// inputs.slPrice < orderPrice))
// ) {
// this.placeLimitOrderTx({
// ...inputs,
// tx,
// orderType,
// side,
// price: inputs.slPrice,
// });
// }
// if (
// "tpPrice" in inputs &&
// ((inputs.side === PerpetualsOrderSide.Ask &&
// inputs.tpPrice < orderPrice) ||
// (inputs.side === PerpetualsOrderSide.Bid &&
// inputs.tpPrice > orderPrice))
// ) {
// this.placeLimitOrderTx({
// ...inputs,
// tx,
// orderType,
// side,
// price: inputs.tpPrice,
// });
// }
};
this.getPositionTx = (inputs) => {
const { tx, marketId, collateralCoinType } = inputs;
return tx.moveCall({
target: utils_1.Helpers.transactions.createTxTarget(inputs.packageId, PerpetualsApi.constants.moduleNames.clearingHouse, "get_position"),
typeArguments: [collateralCoinType],
arguments: [
tx.sharedObjectRef({
objectId: marketId,
initialSharedVersion: inputs.marketInitialSharedVersion,
mutable: false,
}),
tx.pure.u64(inputs.accountId),
],
});
};
this.getOrderbookTx = (inputs) => {
const { tx, collateralCoinType } = inputs;
return tx.moveCall({
target: utils_1.Helpers.transactions.createTxTarget(inputs.packageId, PerpetualsApi.constants.moduleNames.clearingHouse, "get_orderbook"),
typeArguments: [collateralCoinType],
arguments: [tx.object(inputs.marketId)],
});
};
this.getBookPriceTx = (inputs) => {
const { tx, marketId, collateralCoinType } = inputs;
return tx.moveCall({
target: utils_1.Helpers.transactions.createTxTarget(inputs.packageId, PerpetualsApi.constants.moduleNames.clearingHouse, "get_book_price"),
typeArguments: [collateralCoinType],
arguments: [
tx.object(marketId),
// tx.sharedObjectRef({
// objectId: marketId,
// initialSharedVersion: inputs.marketInitialSharedVersion,
// mutable: false,
// }),
],
});
};
this.getBestPriceTx = (inputs) => {
const { tx, marketId, collateralCoinType } = inputs;
return tx.moveCall({
target: utils_1.Helpers.transactions.createTxTarget(inputs.packageId, PerpetualsApi.constants.moduleNames.clearingHouse, "get_best_price"),
typeArguments: [collateralCoinType],
arguments: [
tx.sharedObjectRef({
objectId: marketId,
initialSharedVersion: inputs.marketInitialSharedVersion,
mutable: false,
}), // ClearingHouse
tx.pure.bool(Boolean(inputs.side)), // side
],
});
};
this.inspectOrdersTx = (inputs) => {
const { tx, orderbookId } = inputs;
return tx.moveCall({
target: utils_1.Helpers.transactions.createTxTarget(inputs.packageId, PerpetualsApi.constants.moduleNames.orderbook, "inspect_orders"),
typeArguments: [],
arguments: [
typeof orderbookId === "string"
? tx.object(orderbookId)
: orderbookId, // Orderbook
tx.pure.bool(Boolean(inputs.side)), // side
tx.pure.u64(inputs.fromPrice), // price_from
tx.pure.u64(inputs.toPrice), // price_to
],
});
};
this.getOrderSizeTx = (inputs) => {
const { tx, orderbookId } = inputs;
return tx.moveCall({
target: utils_1.Helpers.transactions.createTxTarget(inputs.packageId, PerpetualsApi.constants.moduleNames.orderbook, "get_order_size"),
typeArguments: [],
arguments: [
typeof orderbookId === "string"
? tx.object(orderbookId)
: orderbookId, // Orderbook
tx.pure.u128(inputs.orderId), // order_id
],
});
};
// =========================================================================
// Transaction Builders
// =========================================================================
this.fetchBuildDepositCollateralTx = (inputs) => __awaiter(this, void 0, void 0, function* () {
const tx = new transactions_1.Transaction();
tx.setSender(inputs.walletAddress);
const { walletAddress, collateralCoinType, amount } = inputs;
const coinId = yield this.Provider.Coin().fetchCoinWithAmountTx({
tx,
walletAddress,
coinType: collateralCoinType,
coinAmount: amount,
});
this.depositCollateralTx(Object.assign({ tx,
coinId }, inputs));
return tx;
});
this.buildCancelOrderTx = (inputs) => {
const { packageId, orderId, marketId, marketInitialSharedVersion, collateralChange, basePriceFeedId, collateralPriceFeedId } = inputs, otherInputs = __rest(inputs, ["packageId", "orderId", "marketId", "marketInitialSharedVersion", "collateralChange", "basePriceFeedId", "collateralPriceFeedId"]);
return this.buildCancelOrdersTx(Object.assign(Object.assign({}, otherInputs), { orderDatas: [
{
packageId,
orderId,
marketId,
marketInitialSharedVersion,
collateralChange,
basePriceFeedId,
collateralPriceFeedId,
},
] }));
};
this.buildCancelOrdersTx = (inputs) => {
const { orderDatas, collateralCoinType, accountCapId } = inputs;
if (orderDatas.length <= 0)
throw new Error("cannot have order datas of length zero");
const tx = new transactions_1.Transaction();
tx.setSender(inputs.walletAddress);
const marketIdToOrderIds = orderDatas.reduce((acc, order) => {
if (order.marketId in acc) {
return Object.assign(Object.assign({}, acc), { [order.marketId]: [...acc[order.marketId], order] });
}
return Object.assign(Object.assign({}, acc), { [order.marketId]: [order] });
}, {});
for (const [marketId, orders] of Object.entries(marketIdToOrderIds)) {
if (orders.length <= 0)
continue;
const marketInitialSharedVersion = orders[0].marketInitialSharedVersion;
const packageId = orders[0].packageId;
this.cancelOrdersTx({
tx,
collateralCoinType,
accountCapId,
marketId,
marketInitialSharedVersion,
packageId,
orderIds: orders.map((order) => order.orderId),
});
const netCollateralChange = utils_1.Helpers.sumBigInt(orders.map((order) => order.collateralChange));
if (netCollateralChange < BigInt(0)) {
this.deallocateCollateralTx({
tx,
accountCapId,
collateralCoinType,
marketId,
marketInitialSharedVersion,
packageId,
amount: utils_1.Helpers.absBigInt(netCollateralChange),
basePriceFeedId: orders[0].basePriceFeedId,
collateralPriceFeedId: orders[0].collateralPriceFeedId,
});
}
else if (netCollateralChange > BigInt(0)) {
this.allocateCollateralTx({
tx,
accountCapId,
collateralCoinType,
marketId,
marketInitialSharedVersion,
packageId,
amount: netCollateralChange,
});
}
else {
// no collateral change
}
}
return tx;
};
this.buildWithdrawCollateralTx = (inputs) => {
const tx = new transactions_1.Transaction();
tx.setSender(inputs.walletAddress);
const coin = this.withdrawCollateralTx(Object.assign({ tx }, inputs));
tx.transferObjects([coin], inputs.walletAddress);
return tx;
};
this.buildCreateAccountTx = (inputs) => {
const tx = new transactions_1.Transaction();
tx.setSender(inputs.walletAddress);
const accountCap = this.createAccountTx(Object.assign({ tx }, inputs));
tx.transferObjects([accountCap], inputs.walletAddress);
return tx;
};
this.fetchBuildPlaceSLTPOrderTx = (inputs) => {
throw new Error("TODO");
// const { tx, sessionPotatoId } = this.createTxAndStartSession(inputs);
// this.placeSLTPOrderTx({
// ...inputs,
// tx,
// sessionPotatoId,
// });
// return tx;
};
this.buildTransferCollateralTx = (inputs) => {
const { walletAddress, collateralCoinType, fromAccountCapId, toAccountCapId, amount, } = inputs;
const tx = new transactions_1.Transaction();
tx.setSender(walletAddress);
const coinId = this.withdrawCollateralTx({
tx,
collateralCoinType,
amount,
accountCapId: fromAccountCapId,
});
this.depositCollateralTx({
tx,
collateralCoinType,
coinId,
accountCapId: toAccountCapId,
});
return tx;
};
this.buildAllocateCollateralTx = transactionsApiHelpers_1.TransactionsApiHelpers.createBuildTxFunc(this.allocateCollateralTx);
this.buildDeallocateCollateralTx = transactionsApiHelpers_1.TransactionsApiHelpers.createBuildTxFunc(this.deallocateCollateralTx);
this.buildReduceOrdersTx = (inputs) => {
const { walletAddress, collateralChange, accountCapId, collateralCoinType, marketId, marketInitialSharedVersion, packageId, basePriceFeedId, collateralPriceFeedId, orderIds, sizesToSubtract, } = inputs;
const tx = new transactions_1.Transaction();
tx.setSender(walletAddress);
this.reduceOrdersTx({
tx,
packageId,
collateralCoinType,
accountCapId,
marketId,
marketInitialSharedVersion,
orderIds,
sizesToSubtract,
});
if (collateralChange < BigInt(0)) {
this.deallocateCollateralTx({
tx,
accountCapId,
collateralCoinType,
marketId,
marketInitialSharedVersion,
packageId,
basePriceFeedId,
collateralPriceFeedId,
amount: utils_1.Helpers.absBigInt(collateralChange),
});
}
else if (collateralChange > BigInt(0)) {
this.allocateCollateralTx({
tx,
accountCapId,
collateralCoinType,
marketId,
marketInitialSharedVersion,
packageId,
amount: collateralChange,
});
}
else {
// no collateral change
}
return tx;
};
// =========================================================================
// Helpers
// =========================================================================
this.getAccountCapType = (inputs) => {
return `${this.addresses.perpetuals.packages.events}::${PerpetualsApi.constants.moduleNames.account}::Account<${inputs.collateralCoinType}>`;
};
// =========================================================================
// Private Helpers
// =========================================================================
// private fetchOrdersSizes = async (inputs: {
// orderIds: PerpetualsOrderId[];
// collateralCoinType: ObjectId;
// marketId: PerpetualsMarketId;
// }): Promise<bigint[]> => {
// const { orderIds, marketId, collateralCoinType } = inputs;
// if (orderIds.length <= 0) return [];
// const tx = new Transaction();
// const orderbookId = this.getOrderbookTx({
// tx,
// collateralCoinType,
// marketId,
// });
// for (const orderId of orderIds) {
// this.getOrderSizeTx({
// tx,
// orderId,
// orderbookId,
// });
// }
// const { allBytes } =
// await this.Provider.Inspections().fetchAllBytesFromTx({
// tx,
// });
// const sizes = allBytes
// .slice(1)
// .map((bytes) => Casting.bigIntFromBytes(bytes[0]));
// return sizes;
// };
// private fetchOrderbookOrders = async (inputs: {
// collateralCoinType: ObjectId;
// marketId: PerpetualsMarketId;
// side: PerpetualsOrderSide;
// fromPrice: PerpetualsOrderPrice;
// toPrice: PerpetualsOrderPrice;
// }): Promise<PerpetualsOrderInfo[]> => {
// const { collateralCoinType, marketId, side, fromPrice, toPrice } =
// inputs;
// const tx = new Transaction();
// const orderbookId = this.getOrderbookTx({
// tx,
// collateralCoinType,
// marketId,
// });
// this.inspectOrdersTx({ tx, orderbookId, side, fromPrice, toPrice });
// const bytes =
// await this.Provider.Inspections().fetchFirstBytesFromTxOutput({
// tx,
// });
// const orderInfos: any[] = bcs
// .vector(perpetualsRegistry.OrderInfo)
// .parse(new Uint8Array(bytes));
// return orderInfos.map((orderInfo) =>
// Casting.perpetuals.orderInfoFromRaw(orderInfo)
// );
// };
// public fetchExecutionPrice = async (
// inputs: ApiPerpetualsExecutionPriceBody & {
// collateralCoinType: CoinType;
// marketId: PerpetualsMarketId;
// }
// ): Promise<ApiPerpetualsExecutionPriceResponse> => {
// const {
// // collateral,
// collateralCoinType,
// marketId,
// side,
// size,
// price,
// lotSize,
// basePriceFeedId,
// collateralPriceFeedId,
// } = inputs;
// // TODO: change this
// const collateral = BigInt(1000000000000000);
// // const accountCapId = perpetualsBcsRegistry
// // .ser(`Account<${collateralCoinType}>`, {
// // id: {
// // id: {
// // bytes: "0x0000000000000000000000000000000000000000000000000000000000000321",
// // },
// // },
// // accountId: 0,
// // collateral,
// // })
// // .toBytes();
// const depositCoinBytes = perpetualsRegistry.Coin.serialize({
// id: "0x0000000000000000000000000000000000000000000000000000000000000123",
// balance: {
// value: BigInt(1000000000000000),
// },
// }).toBytes();
// const walletAddress = InspectionsApiHelpers.constants.devInspectSigner;
// const tx = new Transaction();
// tx.setSender(walletAddress);
// const accountCapId = this.createAccountTx({
// ...inputs,
// tx,
// });
// this.depositCollateralTx({
// tx,
// collateralCoinType,
// accountCapId,
// coinBytes: depositCoinBytes,
// });
// const { sessionPotatoId } = this.createTxAndStartSession({
// tx,
// accountCapId,
// collateralCoinType,
// marketId,
// walletAddress,
// basePriceFeedId,
// collateralPriceFeedId,
// collateralChange: collateral,
// hasPosition: false,
// });
// this.placeLimitOrderTx({
// tx,
// side,
// size,
// collateralCoinType,
// sessionPotatoId,
// orderType: PerpetualsOrderType.Standard,
// price:
// price ??
// (side === PerpetualsOrderSide.Bid
// ? BigInt("0x7FFFFFFFFFFFFFFF") // 2^63 - 1
// : BigInt(1)),
// });
// this.getHotPotatoFieldsTx({
// tx,
// collateralCoinType,
// sessionPotatoId,
// });
// this.endSessionAndTransferAccount({
// ...inputs,
// tx,
// sessionPotatoId,
// walletAddress,
// collateralChange: BigInt(0),
// });
// const { events } =
// await this.Provider.Inspections().fetchAllBytesFromTx({
// tx,
// });
// const filledTakerEvent = EventsApiHelpers.findCastEventOrUndefined({
// events,
// eventType: this.eventTypes.filledTakerOrder,
// castFunction: Casting.perpetuals.filledTakerOrderEventFromOnChain,
// });
// const sizeNum = lotSize * Math.abs(Number(size));
// if (!filledTakerEvent) {
// return {
// executionPrice: 0,
// sizeFilled: 0,
// sizePosted: sizeNum,
// fills: [],
// };
// }
// const filledOrderEvents =
// Aftermath.helpers.events.findCastEventsOrUndefined({
// events,
// eventType: this.eventTypes.filledTakerOrder,
// castFunction:
// Casting.perpetuals.filledTakerOrderEventFromOnChain,
// });
// const fills: PerpetualsFilledOrderData[] = filledOrderEvents.map(
// (event) => {
// const size = Math.abs(
// Casting.IFixed.numberFromIFixed(event.baseAssetDelta)
// );
// const sizeUsd = Math.abs(
// Casting.IFixed.numberFromIFixed(event.quoteAssetDelta)
// );
// const price = sizeUsd / size;
// return {
// size,
// price,
// };
// }
// );
// const executionPrice = Perpetuals.calcEntryPrice(filledTakerEvent);
// const sizeFilled = Math.abs(
// Casting.IFixed.numberFromIFixed(filledTakerEvent.baseAssetDelta)
// );
// const sizePosted = sizeNum - sizeFilled;
// return {
// executionPrice,
// sizeFilled,
// sizePosted,
// fills,
// };
// // const { fillReceipts, postReceipt } =
// // await this.fetchMarketOrderReceipts(inputs);
// // const sizePosted = postReceipt !== undefined ? postReceipt.size : 0;
// // if (fillReceipts.length <= 0)
// // return price !== undefined
// // ? // simulating limit order
// // {
// // executionPrice: Perpetuals.orderPriceToPrice({
// // orderPrice: price,
// // lotSize,
// // tickSize,
// // }),
// // sizeFilled: 0,
// // sizePosted: Number(sizePosted),
// // }
// // : // simulating market order
// // {
// // executionPrice: 0,
// // sizeFilled: 0,
// // sizePosted: 0,
// // };
// // const sizeFilled = Helpers.sumBigInt(
// // fillReceipts.map((receipt) => receipt.size)
// // );
// // const executionPrice = fillReceipts.reduce((acc, receipt) => {
// // const orderPrice = PerpetualsOrderUtils.price(
// // receipt.orderId,
// // inputs.side === PerpetualsOrderSide.Ask
// // ? PerpetualsOrderSide.Bid
// // : PerpetualsOrderSide.Ask
// // );
// // const orderPriceNum = Perpetuals.orderPriceToPrice({
// // orderPrice,
// // lotSize,
// // tickSize,
// // });
// // return (
// // acc +
// // orderPriceNum * (Number(receipt.size) / Number(sizeFilled))
// // );
// // }, 0);
// // return {
// // executionPrice,
// // sizeFilled: Number(sizeFilled),
// // sizePosted: Number(sizePosted),
// // };
// };
// private createTxAndStartSession = (inputs: {
// tx?: Transaction;
// collateralCoinType: CoinType;
// accountCapId: ObjectId | TransactionArgument;
// marketId: PerpetualsMarketId;
// marketInitialSharedVersion: ObjectVersion;
// basePriceFeedId: ObjectId;
// collateralPriceFeedId: ObjectId;
// walletAddress: SuiAddress;
// collateralChange: Balance;
// hasPosition: boolean;
// }) => {
// const { collateralChange, walletAddress, hasPosition } = inputs;
// const { tx: inputsTx, ...nonTxInputs } = inputs;
// const tx = inputsTx ?? new Transaction();
// tx.setSender(walletAddress);
// if (!hasPosition) {
// this.createMarketPositionTx({
// ...nonTxInputs,
// tx,
// });
// }
// if (collateralChange > BigInt(0)) {
// this.allocateCollateralTx({
// ...nonTxInputs,
// tx,
// amount: collateralChange,
// });
// }
// const sessionPotatoId = this.startSessionTx({
// ...nonTxInputs,
// tx,
// });
// return { tx, sessionPotatoId };
// };
// private endSessionAndShareMarket = (inputs: {
// tx: Transaction;
// collateralCoinType: CoinType;
// sessionPotatoId: ObjectId | TransactionArgument;
// }) => {
// const marketId = this.endSessionTx(inputs);
// this.shareClearingHouseTx({
// ...inputs,
// marketId,
// });
// };
// =========================================================================
// Public Static Helpers
// =========================================================================
// public static bucketOrders = (inputs: {
// orders: PerpetualsOrderInfo[];
// side: PerpetualsOrderSide;
// lotSize: number;
// tickSize: number;
// priceBucketSize: number;
// initialBucketedOrders?: OrderbookDataPoint[];
// }): OrderbookDataPoint[] => {
// const {
// orders,
// side,
// lotSize,
// tickSize,
// priceBucketSize,
// initialBucketedOrders,
// } = inputs;
// let dataPoints: OrderbookDataPoint[] = initialBucketedOrders ?? [];
// const roundPrice = (price: number, bucketSize: number): number => {
// return Math.round(price / bucketSize) * bucketSize;
// };
// const comparePrices = (
// price1: number,
// price2: number,
// bucketSize: number
// ): boolean => {
// return Math.abs(price1 - price2) < bucketSize;
// };
// orders.forEach((order) => {
// const actualPrice = Perpetuals.orderPriceToPrice({
// lotSize,
// tickSize: Math.abs(tickSize),
// orderPrice: order.price,
// });
// const roundedPrice = roundPrice(actualPrice, priceBucketSize);
// const size =
// lotSize *
// Math.abs(Number(order.size)) *
// (tickSize < 0 ? -1 : 1);
// const sizeUsd = size * actualPrice;
// const placementIndex = dataPoints.findIndex(
// (dataPoint: OrderbookDataPoint) =>
// comparePrices(
// roundedPrice,
// dataPoint.price,
// priceBucketSize
// )
// );
// if (placementIndex < 0) {
// if (size > 0) {
// const newDataPoint: OrderbookDataPoint = {
// size,
// sizeUsd,
// totalSize: size,
// totalSizeUsd: sizeUsd,
// price: roundedPrice,
// };
// const insertIndex = dataPoints.findIndex((dataPoint) =>
// side === PerpetualsOrderSide.Ask
// ? roundedPrice < dataPoint.price
// : roundedPrice > dataPoint.price
// );
// if (insertIndex < 0) {
// dataPoints.push(newDataPoint);
// } else {
// dataPoints.splice(insertIndex, 0, newDataPoint);
// }
// }
// } else {
// dataPoints[placementIndex].size += size;
// dataPoints[placementIndex].sizeUsd += sizeUsd;
// dataPoints[placementIndex].totalSize += size;
// dataPoints[placementIndex].totalSizeUsd += sizeUsd;
// }
// });
// dataPoints = dataPoints.filter((data) => data.size >= lotSize);
// for (let index = 0; index < dataPoints.length; index++) {
// if (index > 0) {
// dataPoints[index].totalSize =
// dataPoints[index - 1].totalSize + dataPoints[index].size;
// dataPoints[index].totalSizeUsd =
// dataPoints[index - 1].totalSizeUsd +
// dataPoints[index].sizeUsd;
// } else {
// dataPoints[index].totalSize = dataPoints[index].size;
// dataPoints[index].totalSizeUsd = dataPoints[index].sizeUsd;
// }
// }
// if (side === PerpetualsOrderSide.Ask) {
// dataPoints.reverse();
// }
// return dataPoints;
// };
// =========================================================================
// Event Types
// =========================================================================
this.eventType = (eventName) => eventsApiHelpers_1.EventsApiHelpers.createEventType(this.addresses.perpetuals.packages.events, PerpetualsApi.constants.moduleNames.events, eventName);
const perpetuals = this.Provider.addresses.perpetuals;
const oracle = this.Provider.addresses.oracle;
if (!perpetuals || !oracle)
throw new Error("not all required addresses have been set in provider");
this.addresses = {
perpetuals,
oracle,
};
this.eventTypes = {
// Collateral
withdrewCollateral: this.eventType("WithdrewCollateral"),
depositedCollateral: this.eventType("DepositedCollateral"),
settledFunding: this.eventType("SettledFunding"),
allocatedCollateral: this.eventType("AllocatedCollateral"),
deallocatedCollateral: this.eventType("DeallocatedCollateral"),
// Liquidation
liquidated: this.eventType("LiquidatedPosition"),
filledTakerOrderLiquidator: this.eventType("FilledTakerOrderLiquidator"),
// Account
createdAccount: this.eventType("CreatedAccount"),
// Order
canceledOrder: this.eventType("CanceledOrder"),
postedOrder: this.eventType("PostedOrder"),
filledMakerOrder: this.eventType("FilledMakerOrder"),
filledTakerOrder: this.eventType("FilledTakerOrder"),
reducedOrder: this.eventType("ReducedOrder"),
// Order Receipts
postedOrderReceipt: this.eventType("OrderbookPostReceipt"),
// Twap
updatedPremiumTwap: this.eventType("UpdatedPremiumTwap"),
updatedSpreadTwap: this.eventType("UpdatedSpreadTwap"),
// Funding
updatedFunding: this.eventType("UpdatedFunding"),
// Version
updatedMarketVersion: this.eventType("UpdatedClearingHouseVersion"),
};
this.moveErrors = {
[this.addresses.perpetuals.packages.perpetuals]: {
// Clearing House
// Cannot deposit/withdraw zero coins to/from the account's collateral.
0: "Deposit Or Withdraw Amount Zero",
// Orderbook size or price are invalid values
1: "Invalid Size Or Price",
// When trying to access a particular insurance fund, but it does not exist.
2: "Invalid Insurance Fund Id",
// Index price returned from oracle is 0 or invalid value
3: "Bad Index Price",
// Registry already contains the specified collateral type
4: "Invalid Collateral Type",
// Order value in USD is too low
5: "Order Usd Value Too Low",
// Wrong number of sizes passed to liquidation.
// It must match the number of liqee's positions.
6: "Invalid Number Of Sizes",
// MarketManager
// Tried to create a new market with invalid parameters.
1000: "Invalid Market Parameters",
// Tried to call `update_funding` before enough time has passed since the
// last update.
1001: "Updating Funding Too Early",
// Margin ratio update proposal already exists for market
1002: "Proposal Already Exists",
// Margin ratio update proposal cannot be commited too early
1003: "Premature Proposal",
// Margin ratio update proposal delay is outside the valid range
1004: "Invalid Proposal Delay",
// Market does not exist
1005: "Market Does Not Exist",
// Tried to update a config with a value outside of the allowed range
1006: "Value Out Of Range",
// Margin ratio update proposal does not exist for market
1007: "Proposal Does Not Exist",
// Exchange has no available fees to withdraw
1008: "No Fees Accrued",
// Tried to withdraw more insurance funds than the allowed amount
1009: "Insufficient Insurance Surplus",
// Cannot create a market for which a price feed does not exist
1010: "No Price Feed For Market",
// Account Manager
// Tried accessing a nonexistent account.
2000: "Account Not Found",
// Tried accessing a nonexistent account position.
2001: "Position Not Found",
// Tried creating a new position when the account already has the maximum
// allowed number of open positions.
2002: "Max Positions Exceeded",
// An operation brought an account below initial margin requirements.
// 2003: "Initial Margin Requirement Violated",
2003: "Margin Requirements Violated, Try Lowering Size",
// Account is above MMR, so can't be liquidated.
2004: "Account Above MMR",
// Cannot realize bad debt via means other than calling 'liquidate'.
2005: "Account Bad Debt",
// Cannot withdraw more than the account's free collateral.
2006: "Insufficient Free Collateral",
// Cannot delete a position that is not worthless
2007: "Position Not Null",
// Tried placing a new pending order when the position already has the maximum
// allowed number of pending orders.
2008: "Max Pending Orders Exceeded",
// Used for checking both liqee and liqor positions during liquidation
2009: "Account Below IMR",
// When leaving liqee's account with a margin ratio above tolerance,
// meaning that liqor has overbought position
2010: "Account Above Tolerance",
// Orderbook & OrderedMap
// While searching for a key, but it doesn't exist.
3000: "Key Does Not Exist",
// While inserting already existing key.
3001: "Key Already Exists",
// When attempting to destroy a non-empty map
3002: "Destroying Not Empty Map",
// Invalid user tries to modify an order
3003: "Invalid User For Order",
// Orderbook flag requirements violated
3004: "Flag Requirements Violated",
// Minimum size matched not reached
3005: "Not Enough Liquidity",
},
};
}
}
exports.PerpetualsApi = PerpetualsApi;
// =========================================================================
// Class Members
// =========================================================================
PerpetualsApi.constants = {
moduleNames: {
interface: "interface",
orderbook: "orderbook",
events: "events",
clearingHouse: "clearing_house",
account: "account",
},
};