UNPKG

@firefly-exchange/library-sui

Version:

Sui library housing helper methods, classes to interact with Bluefin protocol(s) deployed on Sui

190 lines (189 loc) 8.77 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MarginingEngineSimulator = void 0; const utils_1 = require("@noble/hashes/utils"); const bcs_1 = require("./bcs"); const blake2b_1 = require("@noble/hashes/blake2b"); const deployment_parser_1 = require("./deployment-parser"); const library_1 = require("../../library"); const _ = __importStar(require("lodash")); class MarginingEngineSimulator { constructor(suiClient, deployment) { /// 64 length blake2b hash of all tx processed till date this.sequenceHash = "0000000000000000000000000000000000000000000000000000000000000000"; this.suiClient = suiClient; this.parser = new deployment_parser_1.DeploymentParser(deployment); } /** * Initializes the sequencer by fetching the on-chain sequence hash */ async init() { const details = await this.suiClient.getObject({ id: this.parser.getInternalDataStore(), options: { showContent: true } }); this.sequenceHash = (0, utils_1.bytesToHex)(new Uint8Array(details.data.content.fields.sequence_hash)); } /** * Creates sequence hash for a transaction * @param Serialized payload to be used for sequence hash computation * @param update (optional) if true will update the stored sequence hash else will just return the new hash * @returns the new sequence hash */ computeSequenceHash(payload, update = true, sequenceHash) { const newSequenceHash = (0, utils_1.bytesToHex)((0, blake2b_1.blake2b)((0, library_1.hexToBuffer)(`${sequenceHash || this.sequenceHash}${payload}`), { dkLen: 32 })); if (update) { this.sequenceHash = newSequenceHash; } return newSequenceHash; } /** * Creates sequence hash for a deposit transaction * @param event AssetBankDeposit event * @param update (optional) if true will update the stored sequence hash else will just return the new hash * @returns the new sequence hash */ depositToInternalBank(event, update = true) { const serialized = bcs_1.BCSUtils.getSerializedDataHex({ ...event, tainted: false }, bcs_1.Deposit); return this.computeSequenceHash(serialized, update); } /** * Creates sequence hash for a deposit transaction * @param event AssetBankDeposit event * @param update (optional) if true will update the stored sequence hash else will just return the new hash * @returns the new sequence hash */ removeTaintedAsset(event, update = true) { const serialized = bcs_1.BCSUtils.getSerializedDataHex({ ...event, tainted: true }, bcs_1.Deposit); return this.computeSequenceHash(serialized, update); } /** * Creates sequence hash for sync perpetual state tx * @param event Event for any perpetual attribute update * @param update (optional) if true will update the stored sequence hash else will just return the new hash * @returns the new sequence hash */ // eslint-disable-next-line @typescript-eslint/no-explicit-any syncPerpetual(event, update = true) { let perpetual = { ...event.perpetual }; // set oracle price to zero during serialization as on-chain // we bcs serialize the perpetual struct stored in EDS which has the oracle price zero perpetual.oraclePrice = 0; perpetual.funding = { timestamp: 0, rate: { value: 0, sign: true } }; // the incoming event may have fields in snake_case perpetual = _.mapKeys(perpetual, (_v, k) => _.camelCase(k)); const serialized = bcs_1.BCSUtils.getSerializedDataHex(perpetual, bcs_1.PerpetualUpdate); return this.computeSequenceHash(serialized, update); } /** * Creates sequence hash for sync support asset tx * @param event Event for margin bank creation * @param update (optional) if true will update the stored sequence hash else will just return the new hash * @returns the new sequence hash */ syncSupportedAsset(event, update = true) { const serialized = bcs_1.BCSUtils.getSerializedDataHex(event.asset, bcs_1.AssetSupported); return this.computeSequenceHash(serialized, update); } /** * Creates sequence hash for trade tx * @param makerSignature The signature of the maker order * @param takerSignature The signature of the taker order * @param quantity The quantity of the trade bring filled * @param timestamp Timestamp in ms (this is sent to chain as well) * @param update (optional) if true will update the stored sequence hash else will just return the new hash * @param sequenceHash (optional) sequence hash to be used to compute the next sequence hash * @returns the new sequence hash */ performTrade(makerSignature, takerSignature, quantity, timestamp, update = true, sequenceHash) { const trade = { makerSignature: (0, library_1.hexStrToUint8)((0, library_1.base64ToHex)(makerSignature)), takerSignature: (0, library_1.hexStrToUint8)((0, library_1.base64ToHex)(takerSignature)), quantity, timestamp }; const serialized = bcs_1.BCSUtils.getSerializedDataHex(trade, bcs_1.TradeData); return this.computeSequenceHash(serialized, update, sequenceHash); } overwriteUserPosition(ids, account, position, timestamp, update = true, sequenceHash) { const overwriteUserPositionData = { ids, account, perpetual: position.perpetual, size: position.size, average_entry_price: position.average_entry_price, leverage: position.leverage, margin: position.margin, is_long: position.is_long, is_isolated: position.is_isolated, pending_funding_payment: position.pending_funding_payment, last_funding_timestamp: position.funding.timestamp, last_funding_rate_value: position.funding.rate.value, last_funding_rate_sign: position.funding.rate.sign, timestamp }; const serialized = bcs_1.BCSUtils.getSerializedDataHex(overwriteUserPositionData, bcs_1.OverwriteUserPosition); return this.computeSequenceHash(serialized, update, sequenceHash); } overwriteUserAssets(ids, account, amount, timestamp, update = true, sequenceHash) { const overwriteUserAssetsData = { ids, account, amount, timestamp }; const serialized = bcs_1.BCSUtils.getSerializedDataHex(overwriteUserAssetsData, bcs_1.OverwriteUserAssets); return this.computeSequenceHash(serialized, update, sequenceHash); } /** * Creates sequence hash for sync support asset tx * @param event Event for margin bank creation * @param update (optional) if true will update the stored sequence hash else will just return the new hash * @returns the new sequence hash */ syncOperator(event, update = true) { const serialized = bcs_1.BCSUtils.getSerializedDataHex({ operatorType: event.operator_type, previousOperator: event.previous_operator, newOperator: event.new_operator }, bcs_1.SyncOperator); return this.computeSequenceHash(serialized, update); } /// returns current sequence hash getSequenceHash() { return this.sequenceHash; } /// sets the sequence hash to the provided one setSequenceHash(sequenceHash) { this.sequenceHash = sequenceHash; } } exports.MarginingEngineSimulator = MarginingEngineSimulator;