@firefly-exchange/library-sui
Version:
Sui library housing helper methods, classes to interact with Bluefin protocol(s) deployed on Sui
1,049 lines • 99.3 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OnChainCalls = void 0;
const utils_1 = require("@mysten/sui/utils");
const sdk_ts_1 = require("@7kprotocol/sdk-ts");
const sha256_1 = require("@noble/hashes/sha256");
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const constants_1 = require("../constants");
const defaults_1 = require("../defaults");
const library_1 = require("../library");
const types_1 = require("../types");
const utils_2 = require("../utils");
const transactions_1 = require("@mysten/sui/transactions");
const enums_1 = require("../enums");
const spot_1 = require("../spot");
const bcs_1 = require("@mysten/bcs");
const Transaction_1 = require("../classes/Transaction");
class OnChainCalls {
constructor(_signer, _deployment, suiClient, isZkLogin = false, zkPayload, walletAddress, is_wallet_extension = false, settlementCap) {
this.executeZkTransaction = async ({ tx, caller }) => {
tx.setSender(this.walletAddress);
const { bytes, signature: userSignature } = await tx.sign({
client: this.suiClient,
signer: caller
});
const zkSignature = (0, utils_2.createZkSignature)({
userSignature,
zkPayload: this.getZkPayload()
});
return this.suiClient.executeTransactionBlock({
transactionBlock: bytes,
signature: zkSignature,
options: {
showObjectChanges: true,
showEffects: true,
showEvents: true,
showInput: true
}
});
};
this.executeWalletTransaction = async ({ caller, tx }) => {
const { transactionBlockBytes, signature } = await caller.signTransactionBlock({
transactionBlock: tx
});
return await this.suiClient.executeTransactionBlock({
transactionBlock: transactionBlockBytes,
signature: signature,
options: {
showObjectChanges: true,
showEffects: true,
showEvents: true,
showInput: true
}
});
};
this.getZkPayload = () => {
return {
decodedJWT: this.decodedJWT,
proof: this.proof,
salt: this.salt,
maxEpoch: this.maxEpoch
};
};
this.signer = _signer;
this.deployment = _deployment;
this.is_zkLogin = isZkLogin;
if (isZkLogin && zkPayload) {
this.maxEpoch = zkPayload.maxEpoch;
this.proof = zkPayload.proof;
this.decodedJWT = zkPayload.decodedJWT;
this.salt = zkPayload.salt;
}
this.walletAddress = walletAddress || _signer.toSuiAddress();
this.settlementCap = settlementCap;
this.suiClient = suiClient;
this.is_wallet_extension = is_wallet_extension;
this.sequentialExecutors = new transactions_1.SerialTransactionExecutor({
client: this.suiClient,
signer: this.signer
});
}
async setExchangeAdmin(args, signer) {
const caller = signer || this.signer;
const tx = new types_1.TransactionBlock();
const callArgs = [];
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.pure.address(args.address));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::roles::set_exchange_admin`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setExchangeGuardian(args, signer) {
const caller = signer || this.signer;
const tx = new types_1.TransactionBlock();
const callArgs = [];
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(args.safeID || this.getSafeID()));
callArgs.push(tx.pure.address(args.address));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::roles::set_exchange_guardian`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setFundingRateOperator(args, signer) {
const caller = signer || this.signer;
const tx = new types_1.TransactionBlock();
const callArgs = [];
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(args.safeID || this.getSafeID()));
callArgs.push(tx.pure.address(args.operator));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::roles::set_funding_rate_operator_v2`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setPreLaunchMarketStatus(args, signer) {
const caller = signer || this.signer;
const callArgs = [];
const tx = new types_1.TransactionBlock();
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(this.getPerpetualID(args.market)));
callArgs.push(tx.pure.bool(args.status));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::perpetual::set_pre_launch_status`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setPreLaunchOraclePriceOperator(args, signer) {
const caller = signer || this.signer;
const tx = new types_1.TransactionBlock();
const callArgs = [];
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(args.safeID || this.getSafeID()));
callArgs.push(tx.pure.address(args.operator));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::roles::set_pre_launch_oracle_operator`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setPreLaunchMarketOraclePrice(args, signer) {
const caller = signer || this.signer;
const tx = new types_1.TransactionBlock();
const callArgs = [];
callArgs.push(tx.object(args.safeID || this.getSafeID()));
callArgs.push(tx.object(this.getPerpetualID(args.market)));
callArgs.push(tx.pure.u128(args.price));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
if (args.coinObjectId) {
const coinObject = await this.getOnChainObject(args.coinObjectId);
tx.setGasPayment([coinObject.data]);
}
tx.moveCall({
target: `${this.getPackageID()}::perpetual::set_oracle_price`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async createPerpetual(args, signer, gasBudget) {
const callArgs = [];
const tx = new types_1.TransactionBlock();
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(this.getBankID()));
callArgs.push(tx.pure.string(args.symbol || "ETH-PERP"));
callArgs.push(tx.pure.u128(args.minOrderPrice || (0, library_1.toBigNumberStr)(0.1)));
callArgs.push(tx.pure.u128(args.maxOrderPrice || (0, library_1.toBigNumberStr)(100000)));
callArgs.push(tx.pure.u128(args.tickSize || (0, library_1.toBigNumberStr)(0.001)));
callArgs.push(tx.pure.u128(args.minTradeQty || (0, library_1.toBigNumberStr)(0.1)));
callArgs.push(tx.pure.u128(args.maxTradeQtyLimit || (0, library_1.toBigNumberStr)(100000)));
callArgs.push(tx.pure.u128(args.maxTradeQtyMarket || (0, library_1.toBigNumberStr)(1000)));
callArgs.push(tx.pure.u128(args.stepSize || (0, library_1.toBigNumberStr)(0.1)));
callArgs.push(tx.pure.u128(args.mtbLong || (0, library_1.toBigNumberStr)(0.2)));
callArgs.push(tx.pure.u128(args.mtbShort || (0, library_1.toBigNumberStr)(0.2)));
callArgs.push(tx.pure.vector("u128", args.maxAllowedOIOpen || [
(0, library_1.toBigNumberStr)(1000000), //1x
(0, library_1.toBigNumberStr)(1000000), //2x
(0, library_1.toBigNumberStr)(500000), //3x
(0, library_1.toBigNumberStr)(500000), //4x
(0, library_1.toBigNumberStr)(250000), //5x
(0, library_1.toBigNumberStr)(250000), //6x
(0, library_1.toBigNumberStr)(250000), //7x
(0, library_1.toBigNumberStr)(250000), //8x
(0, library_1.toBigNumberStr)(100000), //9x
(0, library_1.toBigNumberStr)(100000) //10x
]));
callArgs.push(tx.pure.u128(args.initialMarginReq || (0, library_1.toBigNumberStr)(0.1)));
callArgs.push(tx.pure.u128(args.maintenanceMarginReq || (0, library_1.toBigNumberStr)(0.05)));
callArgs.push(tx.pure.u128(args.defaultMakerFee || (0, library_1.toBigNumberStr)(0.001)));
callArgs.push(tx.pure.u128(args.defaultTakerFee || (0, library_1.toBigNumberStr)(0.0045)));
callArgs.push(tx.pure.u128(args.maxFundingRate || (0, library_1.toBigNumberStr)(0.001)));
callArgs.push(tx.pure.u128(args.insurancePoolRatio || (0, library_1.toBigNumberStr)(0.3)));
callArgs.push(tx.pure.address(args.insurancePool ? args.insurancePool : defaults_1.DEFAULT.INSURANCE_POOL_ADDRESS));
callArgs.push(tx.pure.address(args.feePool ? args.feePool : defaults_1.DEFAULT.FEE_POOL_ADDRESS));
// time stamp in ms
callArgs.push(tx.pure.u64(args.tradingStartTime || Date.now()));
//Price Info Feed id converted from Hex String to just string
callArgs.push(tx.pure.string((0, library_1.hexToString)(args.priceInfoFeedId)));
const caller = signer || this.signer;
if (gasBudget)
tx.setGasBudget(gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::exchange::create_perpetual`,
arguments: callArgs,
typeArguments: [this.getCurrencyType()]
});
return this.executeTransactionBlock(caller, tx);
}
async setMinPrice(args, signer) {
const caller = signer || this.signer;
const callArgs = [];
const tx = new types_1.TransactionBlock();
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(this.getPerpetualID(args.market)));
callArgs.push(tx.pure.u128((0, library_1.toBigNumberStr)(args.minPrice)));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::perpetual::set_min_price_v2`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setMaxPrice(args, signer) {
const caller = signer || this.signer;
const callArgs = [];
const tx = new types_1.TransactionBlock();
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(this.getPerpetualID(args.market)));
callArgs.push(tx.pure.u128((0, library_1.toBigNumberStr)(args.maxPrice)));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::perpetual::set_max_price_v2`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setStepSize(args, signer) {
const caller = signer || this.signer;
const callArgs = [];
const tx = new types_1.TransactionBlock();
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(this.getPerpetualID(args.market)));
callArgs.push(tx.pure.u128((0, library_1.toBigNumberStr)(args.stepSize)));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::perpetual::set_step_size_v2`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setTickSize(args, signer) {
const caller = signer || this.signer;
const callArgs = [];
const tx = new types_1.TransactionBlock();
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(this.getPerpetualID(args.market)));
callArgs.push(tx.pure.u128((0, library_1.toBigNumberStr)(args.tickSize)));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::perpetual::set_tick_size_v2`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setMTBLong(args, signer) {
const caller = signer || this.signer;
const callArgs = [];
const tx = new types_1.TransactionBlock();
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(this.getPerpetualID(args.market)));
callArgs.push(tx.pure.u128((0, library_1.toBigNumberStr)(args.mtbLong)));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::perpetual::set_mtb_long_v2`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setMTBShort(args, signer) {
const caller = signer || this.signer;
const callArgs = [];
const tx = new types_1.TransactionBlock();
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(this.getPerpetualID(args.market)));
callArgs.push(tx.pure.u128((0, library_1.toBigNumberStr)(args.mtbShort)));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::perpetual::set_mtb_short_v2`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setMaxQtyLimit(args, signer) {
const caller = signer || this.signer;
const callArgs = [];
const tx = new types_1.TransactionBlock();
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(this.getPerpetualID(args.market)));
callArgs.push(tx.pure.u128((0, library_1.toBigNumberStr)(args.maxQtyLimit)));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::perpetual::set_max_qty_limit_v2`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setMaxQtyMarket(args, signer) {
const caller = signer || this.signer;
const callArgs = [];
const tx = new types_1.TransactionBlock();
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(this.getPerpetualID(args.market)));
callArgs.push(tx.pure.u128((0, library_1.toBigNumberStr)(args.maxQtyMarket)));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::perpetual::set_max_qty_market_v2`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setMinQty(args, signer) {
const caller = signer || this.signer;
const callArgs = [];
const tx = new types_1.TransactionBlock();
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(this.getPerpetualID(args.market)));
callArgs.push(tx.pure.u128((0, library_1.toBigNumberStr)(args.minQty)));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::perpetual::set_min_qty_v2`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setMaxAllowedOIOpen(args, signer) {
const caller = signer || this.signer;
const callArgs = [];
const tx = new types_1.TransactionBlock();
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(this.getPerpetualID(args.market)));
callArgs.push(tx.pure.vector("u128", args.maxLimit));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::perpetual::set_max_oi_open_v2`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setMaintenanceMarginRequired(args, signer) {
const caller = signer || this.signer;
const callArgs = [];
const tx = new types_1.TransactionBlock();
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(this.getPerpetualID(args.market)));
callArgs.push(tx.pure.u128(args.mmr));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::perpetual::set_maintenance_margin_required_v2`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setInitialMarginRequired(args, options) {
const caller = options?.signer || this.signer;
const txb = new types_1.TransactionBlock();
const callArgs = [];
callArgs.push(txb.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(txb.object(this.getPerpetualID(args.market)));
callArgs.push(txb.pure.u128(args.imr));
if (options?.gasBudget)
txb.setGasBudget(options?.gasBudget);
txb.moveCall({
arguments: callArgs,
target: `${this.getPackageID()}::perpetual::set_initial_margin_required_v2`
});
// if multi sig call return tx bytes
if (options?.multiSig) {
txb.setSender(options?.multiSig);
return (0, utils_1.toB64)(await txb.build({ client: this.suiClient, onlyTransactionKind: false }));
}
else {
return this.executeTxBlock(txb, caller);
}
}
async createSettlementOperator(args, options) {
const caller = options?.signer || this.signer;
const callArgs = [];
const txb = new types_1.TransactionBlock();
callArgs.push(txb.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(txb.object(args.safeID || this.getSafeID()));
callArgs.push(txb.pure.address(args.operator));
if (options?.gasBudget)
txb.setGasBudget(options?.gasBudget);
txb.moveCall({
arguments: callArgs,
target: `${this.getPackageID()}::roles::create_settlement_operator`
});
// if multi sig call return tx bytes
if (options?.multiSig) {
txb.setSender(options?.multiSig);
return (0, utils_1.toB64)(await txb.build({ client: this.suiClient, onlyTransactionKind: false }));
}
else {
return this.executeTxBlock(txb, caller);
}
}
async removeSettlementOperator(args, signer) {
const caller = signer || this.signer;
const callArgs = [];
const tx = new types_1.TransactionBlock();
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(args.safeID || this.getSafeID()));
callArgs.push(tx.object(args.capID));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::roles::remove_settlement_operator`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setFeePoolAddress(args, signer) {
const caller = signer || this.signer;
const callArgs = [];
const tx = new types_1.TransactionBlock();
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(this.getPerpetualID(args.market)));
callArgs.push(tx.pure.address(args.address));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::perpetual::set_fee_pool_address_v2`,
arguments: callArgs,
typeArguments: [this.getCurrencyType()]
});
return this.executeTransactionBlock(caller, tx);
}
async setInsurancePoolAddress(args, signer) {
const caller = signer || this.signer;
const callArgs = [];
const tx = new types_1.TransactionBlock();
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(this.getPerpetualID(args.market)));
callArgs.push(tx.pure.address(args.address));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::perpetual::set_insurance_pool_address_v2`,
arguments: callArgs,
typeArguments: [this.getCurrencyType()]
});
return this.executeTransactionBlock(caller, tx);
}
async setInsurancePoolPercentage(args, signer) {
const caller = signer || this.signer;
const callArgs = [];
const tx = new types_1.TransactionBlock();
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(this.getPerpetualID(args.market)));
callArgs.push(tx.pure.u128((0, library_1.toBigNumberStr)(args.percentage)));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::perpetual::set_insurance_pool_percentage_v2`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setMaxAllowedFundingRate(args, signer) {
const caller = signer || this.signer;
const callArgs = [];
const tx = new types_1.TransactionBlock();
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(this.getPerpetualID(args.market)));
callArgs.push(tx.pure.u128((0, library_1.toBigNumberStr)(args.maxFundingRate)));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::perpetual::set_max_allowed_funding_rate_v2`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async trade(args, signer) {
const caller = signer || this.signer;
const txBlock = new types_1.TransactionBlock();
const callArgs = [
txBlock.object(utils_1.SUI_CLOCK_OBJECT_ID),
txBlock.object(args.perpID || this.getPerpetualID(args.market)),
txBlock.object(args.bankID || this.getBankID()),
txBlock.object(args.safeID || this.getSafeID()),
txBlock.object(args.subAccountsMapID || this.getSubAccountsID()),
txBlock.object(this.getOrdersTableID()),
txBlock.object(this.getSequencer()),
txBlock.object(args.settlementCapID || this.settlementCap),
txBlock.object(this.getPriceOracleObjectId(args.market)),
txBlock.pure.u8((0, library_1.encodeOrderFlags)(args.makerOrder)),
txBlock.pure.u128(args.makerOrder.price.toFixed(0)),
txBlock.pure.u128(args.makerOrder.quantity.toFixed(0)),
txBlock.pure.u128(args.makerOrder.leverage.toFixed(0)),
txBlock.pure.u64(args.makerOrder.expiration.toFixed(0)),
txBlock.pure.u128(args.makerOrder.salt.toFixed(0)),
txBlock.pure.address(args.makerOrder.maker),
txBlock.pure.vector("u8", Array.from((0, library_1.hexStrToUint8)(args.makerSignature))),
txBlock.pure.vector("u8", Array.from((0, library_1.base64ToUint8)(args.makerPublicKey))),
txBlock.pure.u8((0, library_1.encodeOrderFlags)(args.takerOrder)),
txBlock.pure.u128(args.takerOrder.price.toFixed(0)),
txBlock.pure.u128(args.takerOrder.quantity.toFixed(0)),
txBlock.pure.u128(args.takerOrder.leverage.toFixed(0)),
txBlock.pure.u64(args.takerOrder.expiration.toFixed(0)),
txBlock.pure.u128(args.takerOrder.salt.toFixed(0)),
txBlock.pure.address(args.takerOrder.maker),
txBlock.pure.vector("u8", Array.from((0, library_1.hexStrToUint8)(args.takerSignature))),
txBlock.pure.vector("u8", Array.from((0, library_1.base64ToUint8)(args.takerPublicKey))),
txBlock.pure.u128(args.fillQuantity
? args.fillQuantity.toFixed(0)
: args.makerOrder.quantity.lte(args.takerOrder.quantity)
? args.makerOrder.quantity.toFixed(0)
: args.takerOrder.quantity.toFixed(0)),
txBlock.pure.u128(args.fillPrice
? args.fillPrice.toFixed(0)
: args.makerOrder.price.toFixed(0))
];
//need to check it again. On contract this is of vector type
callArgs.push(txBlock.pure.string(args.txHash ||
Buffer.from((0, sha256_1.sha256)(JSON.stringify([...callArgs, (0, utils_2.getSalt)()]))).toString("hex")));
if (args.gasBudget)
txBlock.setGasBudget(args.gasBudget);
txBlock.moveCall({
target: `${this.getPackageID()}::exchange::trade`,
arguments: callArgs,
typeArguments: [this.getCurrencyType()]
});
return this.executeTransactionBlock(caller, txBlock);
}
async batchTrade(args, options) {
const caller = options?.signer || this.signer;
let txBlock = options?.transactionBlock;
if (!options?.transactionBlock) {
txBlock = await this.buildBatchTradeTxBlock(args);
}
if (options?.gasBudget)
txBlock.setGasBudget(options.gasBudget);
return this.executeTxBlock(txBlock, caller);
}
async batchTradeUsingExecutors(args, options) {
const caller = this.signer;
let txBlock = options?.transactionBlock;
if (!options?.transactionBlock) {
txBlock = await this.buildBatchTradeTxBlock(args);
}
if (options?.gasBudget)
txBlock.setGasBudget(options.gasBudget);
const result = (await this.sequentialExecutors.executeTransaction(txBlock, {
showEvents: true,
showEffects: true
})).data;
return result;
}
async buildBatchTradeTxBlock(args, gasBudget) {
const txBlock = new types_1.TransactionBlock();
for (const arg of args) {
const callArgs = [
txBlock.object(utils_1.SUI_CLOCK_OBJECT_ID),
txBlock.object(arg.perpID || this.getPerpetualID(arg.market)),
txBlock.object(arg.bankID || this.getBankID()),
txBlock.object(arg.safeID || this.getSafeID()),
txBlock.object(arg.subAccountsMapID || this.getSubAccountsID()),
txBlock.object(this.getOrdersTableID()),
txBlock.object(this.getSequencer()),
txBlock.object(arg.settlementCapID || this.settlementCap),
txBlock.object(this.getPriceOracleObjectId(arg.market)),
txBlock.pure.u8((0, library_1.encodeOrderFlags)(arg.makerOrder)),
txBlock.pure.u128(arg.makerOrder.price.toFixed(0)),
txBlock.pure.u128(arg.makerOrder.quantity.toFixed(0)),
txBlock.pure.u128(arg.makerOrder.leverage.toFixed(0)),
txBlock.pure.u64(arg.makerOrder.expiration.toFixed(0)),
txBlock.pure.u128(arg.makerOrder.salt.toFixed(0)),
txBlock.pure.address(arg.makerOrder.maker),
txBlock.pure.vector("u8", Array.from((0, library_1.hexStrToUint8)(arg.makerSignature))),
txBlock.pure.vector("u8", Array.from((0, library_1.base64ToUint8)(arg.makerPublicKey))),
txBlock.pure.u8((0, library_1.encodeOrderFlags)(arg.takerOrder)),
txBlock.pure.u128(arg.takerOrder.price.toFixed(0)),
txBlock.pure.u128(arg.takerOrder.quantity.toFixed(0)),
txBlock.pure.u128(arg.takerOrder.leverage.toFixed(0)),
txBlock.pure.u64(arg.takerOrder.expiration.toFixed(0)),
txBlock.pure.u128(arg.takerOrder.salt.toFixed(0)),
txBlock.pure.address(arg.takerOrder.maker),
txBlock.pure.vector("u8", Array.from((0, library_1.hexStrToUint8)(arg.takerSignature))),
txBlock.pure.vector("u8", Array.from((0, library_1.base64ToUint8)(arg.takerPublicKey))),
txBlock.pure.u128(arg.fillQuantity
? arg.fillQuantity.toFixed(0)
: arg.makerOrder.quantity.lte(arg.takerOrder.quantity)
? arg.makerOrder.quantity.toFixed(0)
: arg.takerOrder.quantity.toFixed(0)),
txBlock.pure.u128(arg.fillPrice
? arg.fillPrice.toFixed(0)
: arg.makerOrder.price.toFixed(0))
];
//need to check it again. On contract this is of vector type
callArgs.push(txBlock.pure.string(arg.txHash ||
Buffer.from((0, sha256_1.sha256)(JSON.stringify([...callArgs, (0, utils_2.getSalt)()]))).toString("hex")));
txBlock.moveCall({
target: `${this.getPackageID()}::exchange::trade`,
arguments: callArgs,
typeArguments: [this.getCurrencyType()]
});
}
if (gasBudget)
txBlock.setGasBudget(gasBudget);
return txBlock;
}
async liquidate(args, signer) {
const caller = signer || this.signer;
const txBlock = new types_1.TransactionBlock();
const callArgs = [
txBlock.object(utils_1.SUI_CLOCK_OBJECT_ID),
txBlock.object(args.perpID || this.getPerpetualID(args.market)),
txBlock.object(this.getBankID()),
txBlock.object(args.subAccountsMapID || this.getSubAccountsID()),
txBlock.object(this.getSequencer()),
txBlock.object(this.getPriceOracleObjectId(args.market)),
txBlock.pure.address(args.liquidatee),
txBlock.pure.address(args.liquidator || caller.toSuiAddress()),
txBlock.pure.u128(args.quantity),
txBlock.pure.u128(args.leverage),
txBlock.pure.bool(args.allOrNothing === true)
];
//need to check it again. On contract this is of vector type
callArgs.push(txBlock.pure.string(args.txHash ||
Buffer.from((0, sha256_1.sha256)(JSON.stringify([...callArgs, (0, utils_2.getSalt)()]))).toString("hex")));
if (args.gasBudget)
txBlock.setGasBudget(args.gasBudget);
txBlock.moveCall({
target: `${this.getPackageID()}::exchange::liquidate`,
arguments: callArgs,
typeArguments: [this.getCurrencyType()]
});
return this.executeTransactionBlock(caller, txBlock);
}
async getBatchLiquidationTransactionBlock(args, gasBudget, signer) {
const caller = signer || this.signer;
const txBlock = new types_1.TransactionBlock();
for (const arg of args) {
const callArgs = [
txBlock.object(utils_1.SUI_CLOCK_OBJECT_ID),
txBlock.object(arg.perpID || this.getPerpetualID(arg.market)),
txBlock.object(this.getBankID()),
txBlock.object(arg.subAccountsMapID || this.getSubAccountsID()),
txBlock.object(this.getSequencer()),
txBlock.object(this.getPriceOracleObjectId(arg.market)),
txBlock.pure.address(arg.liquidatee),
txBlock.pure.address(arg.liquidator || caller.toSuiAddress()),
txBlock.pure.u128(arg.quantity),
txBlock.pure.u128(arg.leverage),
txBlock.pure.bool(arg.allOrNothing === true)
];
//need to check it again. On contract this is of vector type
callArgs.push(txBlock.pure.string(arg.txHash ||
Buffer.from((0, sha256_1.sha256)(JSON.stringify([...callArgs, (0, utils_2.getSalt)()]))).toString("hex")));
txBlock.moveCall({
target: `${this.getPackageID()}::exchange::liquidate`,
arguments: callArgs,
typeArguments: [this.getCurrencyType()]
});
}
if (gasBudget)
txBlock.setGasBudget(gasBudget);
return txBlock;
}
async batchLiquidate(args, gasBudget, signer) {
const caller = signer || this.signer;
const txBlock = await this.getBatchLiquidationTransactionBlock(args, gasBudget, signer);
return this.executeTxBlock(txBlock, caller);
}
async dryRun(txBlock, signer) {
const caller = signer || this.signer;
txBlock.setSenderIfNotSet(caller.toSuiAddress());
const builtTransactionBlock = await txBlock.build({
client: this.suiClient
});
return this.suiClient.dryRunTransactionBlock({
transactionBlock: builtTransactionBlock
});
}
async deleverage(args, signer) {
const caller = signer || this.signer;
const txBlock = new types_1.TransactionBlock();
const callArgs = [
txBlock.object(utils_1.SUI_CLOCK_OBJECT_ID),
txBlock.object(args.perpID || this.getPerpetualID(args.market)),
txBlock.object(this.getBankID()),
txBlock.object(args.safeID || this.getSafeID()),
txBlock.object(this.getSequencer()),
txBlock.object(args.deleveragingCapID || this.getDeleveragingCapID()),
txBlock.object(this.getPriceOracleObjectId(args.market)),
txBlock.pure.address(args.maker),
txBlock.pure.address(args.taker),
txBlock.pure.u128(args.quantity),
txBlock.pure.bool(args.allOrNothing === true)
];
//need to check it again. On contract this is of vector type
callArgs.push(txBlock.pure.string(args.txHash ||
Buffer.from((0, sha256_1.sha256)(JSON.stringify([...callArgs, (0, utils_2.getSalt)()]))).toString("hex")));
if (args.gasBudget)
txBlock.setGasBudget(args.gasBudget);
txBlock.moveCall({
target: `${this.getPackageID()}::exchange::deleverage`,
arguments: callArgs,
typeArguments: [this.getCurrencyType()]
});
return this.executeTransactionBlock(caller, txBlock);
}
async getBatchDeleveragingTransactionBlock(args, gasBudget, signer) {
const caller = signer || this.signer;
const txBlock = new types_1.TransactionBlock();
for (const arg of args) {
const callArgs = [
txBlock.object(utils_1.SUI_CLOCK_OBJECT_ID),
txBlock.object(arg.perpID || this.getPerpetualID(arg.market)),
txBlock.object(this.getBankID()),
txBlock.object(arg.safeID || this.getSafeID()),
txBlock.object(this.getSequencer()),
txBlock.object(arg.deleveragingCapID || this.getDeleveragingCapID()),
txBlock.object(this.getPriceOracleObjectId(arg.market)),
txBlock.pure.address(arg.maker),
txBlock.pure.address(arg.taker),
txBlock.pure.u128(arg.quantity),
txBlock.pure.bool(arg.allOrNothing === true)
];
//need to check it again. On contract this is of vector type
callArgs.push(txBlock.pure.string(arg.txHash ||
Buffer.from((0, sha256_1.sha256)(JSON.stringify([...callArgs, (0, utils_2.getSalt)()]))).toString("hex")));
txBlock.moveCall({
target: `${this.getPackageID()}::exchange::deleverage`,
arguments: callArgs,
typeArguments: [this.getCurrencyType()]
});
}
if (gasBudget)
txBlock.setGasBudget(gasBudget);
txBlock.setSenderIfNotSet(caller.toSuiAddress());
return txBlock;
}
async batchDeleverage(args, gasBudget, signer) {
const caller = signer || this.signer;
const txBlock = await this.getBatchDeleveragingTransactionBlock(args, gasBudget, signer);
return this.executeTxBlock(txBlock, caller);
}
async addMargin(args, signer) {
const caller = signer || this.signer;
const tx = new types_1.TransactionBlock();
const callArgs = [];
callArgs.push(tx.object(utils_1.SUI_CLOCK_OBJECT_ID));
callArgs.push(tx.object(args.perpID || this.getPerpetualID(args.market)));
callArgs.push(tx.object(this.getBankID()));
callArgs.push(tx.object(args.subAccountsMapID || this.getSubAccountsID()));
callArgs.push(tx.object(this.getSequencer()));
callArgs.push(tx.object(this.getPriceOracleObjectId(args.market)));
callArgs.push(tx.pure.address(args.account || caller.toSuiAddress()));
callArgs.push(tx.pure.u128((0, library_1.toBigNumberStr)(args.amount)));
callArgs.push(tx.pure.string(args.txHash ||
Buffer.from((0, sha256_1.sha256)(JSON.stringify([...callArgs, (0, utils_2.getSalt)()]))).toString("hex")));
const typeArgs = [this.getCurrencyType()];
if (args.sponsor) {
tx.setSender(caller.toSuiAddress());
tx.moveCall({
target: `${this.getPackageID()}::exchange::add_margin`,
arguments: callArgs,
typeArguments: typeArgs
});
return tx;
}
else {
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::exchange::add_margin`,
arguments: callArgs,
typeArguments: typeArgs
});
return this.executeTransactionBlock(caller, tx);
}
}
async removeMargin(args, signer) {
const caller = signer || this.signer;
const tx = new types_1.TransactionBlock();
const callArgs = [];
callArgs.push(tx.object(utils_1.SUI_CLOCK_OBJECT_ID));
callArgs.push(tx.object(args.perpID || this.getPerpetualID(args.market)));
callArgs.push(tx.object(this.getBankID()));
callArgs.push(tx.object(args.subAccountsMapID || this.getSubAccountsID()));
callArgs.push(tx.object(this.getSequencer()));
callArgs.push(tx.object(this.getPriceOracleObjectId(args.market)));
callArgs.push(tx.pure.address(args.account || caller.toSuiAddress()));
callArgs.push(tx.pure.u128((0, library_1.toBigNumberStr)(args.amount)));
callArgs.push(tx.pure.string(args.txHash ||
Buffer.from((0, sha256_1.sha256)(JSON.stringify([...callArgs, (0, utils_2.getSalt)()]))).toString("hex")));
const typeArgs = [this.getCurrencyType()];
if (args.sponsor) {
tx.setSender(caller.toSuiAddress());
tx.moveCall({
target: `${this.getPackageID()}::exchange::remove_margin`,
arguments: callArgs,
typeArguments: typeArgs
});
return tx;
}
else {
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::exchange::remove_margin`,
arguments: callArgs,
typeArguments: typeArgs
});
return this.executeTransactionBlock(caller, tx);
}
}
async adjustLeverage(args, signer) {
const caller = signer || this.signer;
const tx = new types_1.TransactionBlock();
const callArgs = [];
callArgs.push(tx.object(utils_1.SUI_CLOCK_OBJECT_ID));
callArgs.push(tx.object(args.perpID || this.getPerpetualID(args.market)));
callArgs.push(tx.object(this.getBankID()));
callArgs.push(tx.object(args.subAccountsMapID || this.getSubAccountsID()));
callArgs.push(tx.object(this.getSequencer()));
callArgs.push(tx.object(this.getPriceOracleObjectId(args.market)));
callArgs.push(tx.pure.address(args.account || caller.toSuiAddress()));
callArgs.push(tx.pure.u128((0, library_1.toBigNumberStr)(args.leverage)));
callArgs.push(tx.pure.string(args.txHash ||
Buffer.from((0, sha256_1.sha256)(JSON.stringify([...callArgs, (0, utils_2.getSalt)()]))).toString("hex")));
const typeArgs = [this.getCurrencyType()];
if (args.sponsor) {
tx.setSender(caller.toSuiAddress());
tx.moveCall({
target: `${this.getPackageID()}::exchange::adjust_leverage`,
arguments: callArgs,
typeArguments: typeArgs
});
return tx;
}
else {
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::exchange::adjust_leverage`,
arguments: callArgs,
typeArguments: typeArgs
});
return this.executeTransactionBlock(caller, tx);
}
}
async signAdjustLeverage(args, signer) {
const caller = signer || this.signer;
const txb = new types_1.TransactionBlock();
txb.setSender(this.walletAddress ?? caller.toSuiAddress());
if (args.gasBudget)
txb.setGasBudget(args.gasBudget);
const callArgs = [];
callArgs.push(txb.object(utils_1.SUI_CLOCK_OBJECT_ID));
callArgs.push(txb.object(args.perpID || this.getPerpetualID(args.market)));
callArgs.push(txb.object(this.getBankID()));
callArgs.push(txb.object(args.subAccountsMapID || this.getSubAccountsID()));
callArgs.push(txb.object(this.getSequencer()));
callArgs.push(txb.object(this.getPriceOracleObjectId(args.market)));
callArgs.push(txb.pure.address(args.account || caller.toSuiAddress()));
callArgs.push(txb.pure.u128((0, library_1.toBigNumberStr)(args.leverage)));
callArgs.push(txb.pure.string(args.txHash ||
Buffer.from((0, sha256_1.sha256)(JSON.stringify([...callArgs, (0, utils_2.getSalt)()]))).toString("hex")));
txb.moveCall({
arguments: callArgs,
target: `${this.getPackageID()}::exchange::adjust_leverage`,
typeArguments: [this.getCurrencyType()]
});
//ui wallet
if (this.is_wallet_extension) {
const response = await caller.signTransactionBlock({ transactionBlock: txb });
return {
bytes: response.transactionBlockBytes,
signature: response.signature
};
}
//signer
else {
const bytes = (0, utils_1.toB64)(await txb.build({ client: this.suiClient, onlyTransactionKind: false }));
return caller.signWithIntent((0, utils_1.fromB64)(bytes), "TransactionData");
}
}
/**
* Create signed transaction for whitelisting/removing of the subaccounts on-chain
*/
async signUpsertSubAccount(args, signer) {
const caller = signer || this.signer;
const txb = new types_1.TransactionBlock();
txb.setSender(this.walletAddress ?? caller.toSuiAddress());
if (args.gasBudget)
txb.setGasBudget(args.gasBudget);
if (args.account) {
const callArgs = [];
callArgs.push(txb.object(args.subAccountsMapID || this.getSubAccountsID()));
callArgs.push(txb.pure.address(args.account));
callArgs.push(txb.pure.bool(true));
txb.moveCall({
arguments: callArgs,
target: `${this.getPackageID()}::roles::set_sub_account`
});
}
for (const accountToRemove of args.accountsToRemove) {
const callArgs = [];
callArgs.push(txb.object(args.subAccountsMapID || this.getSubAccountsID()));
callArgs.push(txb.pure.address(accountToRemove));
callArgs.push(txb.pure.bool(false));
txb.moveCall({
arguments: callArgs,
target: `${this.getPackageID()}::roles::set_sub_account`
});
}
if (args.sponsor) {
return txb;
}
if (this.is_wallet_extension) {
const response = await caller.signTransactionBlock({ transactionBlock: txb });
return {
bytes: response.transactionBlockBytes,
signature: response.signature
};
}
else {
const bytes = (0, utils_1.toB64)(await txb.build({ client: this.suiClient, onlyTransactionKind: false }));
return caller.signWithIntent((0, utils_1.fromB64)(bytes), "TransactionData");
}
}
async cancelOrder(args, signer) {
const caller = signer || this.signer;
const tx = new types_1.TransactionBlock();
const callArgs = [];
callArgs.push(tx.object(args.subAccountsMapID || this.getSubAccountsID()));
callArgs.push(tx.object(this.getSequencer())),
callArgs.push(tx.object(this.getOrdersTableID()));
callArgs.push(tx.pure.address(args.order.market));
callArgs.push(tx.pure.u8((0, library_1.encodeOrderFlags)(args.order)));
callArgs.push(tx.pure.u128(args.order.price.toFixed(0)));
callArgs.push(tx.pure.u128(args.order.quantity.toFixed(0)));
callArgs.push(tx.pure.u128(args.order.leverage.toFixed(0)));
callArgs.push(tx.pure.u64(args.order.expiration.toFixed(0)));
callArgs.push(tx.pure.u128(args.order.salt.toFixed(0)));
callArgs.push(tx.pure.address(args.order.maker));
callArgs.push(tx.pure.vector("u8", Array.from((0, library_1.hexStrToUint8)(args.signature))));
callArgs.push(tx.pure.vector("u8", Array.from((0, library_1.base64ToUint8)(args.publicKey))));
callArgs.push(tx.pure.string(args.txHash ||
Buffer.from((0, sha256_1.sha256)(JSON.stringify([...callArgs, (0, utils_2.getSalt)()]))).toString("hex")));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::order::cancel_order`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setFundingRate(args, signer) {
const caller = signer || this.signer;
const tx = new types_1.TransactionBlock();
const callArgs = [];
callArgs.push(tx.object(utils_1.SUI_CLOCK_OBJECT_ID));
callArgs.push(tx.object(args.safeID || this.getSafeID()));
callArgs.push(tx.object(args.updateFRCapID || this.getFROperatorCapID()));
callArgs.push(tx.object(args.perpID || this.getPerpetualID(args.market)));
callArgs.push(tx.pure.u128(args.rate.absoluteValue().toString()));
callArgs.push(tx.pure.bool(args.rate.isPositive()));
callArgs.push(tx.object(this.getPriceOracleObjectId(args.market)));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::perpetual::set_funding_rate_v2`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setDeleveragingOperator(args, signer) {
const caller = signer || this.signer;
const tx = new types_1.TransactionBlock();
const callArgs = [];
callArgs.push(tx.object(args.adminID || this.getExchangeAdminCap()));
callArgs.push(tx.object(args.safeID || this.getSafeID()));
callArgs.push(tx.pure.address(args.operator));
if (args.gasBudget)
tx.setGasBudget(args.gasBudget);
tx.moveCall({
target: `${this.getPackageID()}::roles::set_deleveraging_operator`,
arguments: callArgs,
typeArguments: []
});
return this.executeTransactionBlock(caller, tx);
}
async setSubAccount(args, signer) {
const caller = signer