UNPKG

@mirage-protocol/sdk

Version:

Typescript library for interacting with Mirage Protocol move contracts

1,420 lines (1,396 loc) 196 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; // src/client/base.ts import { Aptos as AptosClient3, AptosConfig as AptosConfig2, Network } from "@aptos-labs/ts-sdk"; // src/utils/index.ts import { AccountAddress as AccountAddress18, Deserializer, Identifier as Identifier13, StructTag as StructTag9, TypeTagStruct as TypeTagStruct9 } from "@aptos-labs/ts-sdk"; import BigNumber22 from "bignumber.js"; // src/utils/config.ts import { AccountAddress } from "@aptos-labs/ts-sdk"; // mirage_config_movement.json var mirage_config_movement_default = { chainId: 126, deployerAddress: "0x86d2ae026e602dbe39040457a6196ecdfc6308ab5b276d4379e10327b7204666", vaults: [ { name: "MOVE/mUSD CDP", address: "0x81821b61b14a7899e6417c9f9b6a2a8871d6d27a2fc66fee97942425185d546f", collateralSymbol: "MOVE", borrowSymbol: "mUSD", collateralOracle: "MOVE_PYTH", borrowOracle: "STABLE_ORACLE" } ], oracles: [ { name: "STABLE_ORACLE", address: "0xea497f66440058b553a3bfbc9eb8a7608fa58e0ab6d7c3a20042e07b9cb8b24d", priceFeedId: "", priceMultiplier: 1 }, { name: "MOVE_PYTH", address: "0x91faa0e4ffcbf9131e1e217d954aeb0fa8ed46585e6be33a6650df75b0856f0d", priceFeedId: "0x6bf748c908767baa762a1563d454ebec2d5108f8ee36d806aadacc8f0a075b6d", priceMultiplier: 1 } ], fungibleAssets: [ { coinType: "0x1::aptos_coin::AptosCoin", address: "0x000000000000000000000000000000000000000000000000000000000000000a", decimals: 8, name: "Move Coin", symbol: "MOVE" }, { address: "0xdd84125d1ebac8f1ecb2819801417fc392325e672be111ec03830c34d6ff82dd", decimals: 8, name: "mirage dollar", symbol: "mUSD" } ], markets: [ { address: "0xc3337a2be5d9e37fd79b075d6f4ad3d3bd4c76835fe3c2a879fac5b3e61c6e48", marginOracle: "STABLE_ORACLE", perpOracle: "MOVE_PYTH", perpSymbol: "MOVEPERP", marginSymbol: "mUSD", name: "MOVEPERP/mUSD" } ] }; // mirage_config_testnet.json var mirage_config_testnet_default = { chainId: 2, deployerAddress: "0x86d2ae026e602dbe39040457a6196ecdfc6308ab5b276d4379e10327b7204666", vaults: [ { name: "tUSDC/mUSD CDP", address: "0x8f3699188140d9d7acd406c9c3890f52569770178dfdfe26018f8818b547957f", collateralSymbol: "tUSDC", borrowSymbol: "mUSD", collateralOracle: "USDC_PYTH", borrowOracle: "STABLE_ORACLE" }, { name: "APT/mUSD CDP", address: "0xe1e13aa968df88dff6ac5227eaa6220c90a0e40e60ce274695a134f43966e2c0", collateralSymbol: "APT", borrowSymbol: "mUSD", collateralOracle: "APT_PYTH", borrowOracle: "STABLE_ORACLE" } ], oracles: [ { name: "STABLE_ORACLE", address: "0xea497f66440058b553a3bfbc9eb8a7608fa58e0ab6d7c3a20042e07b9cb8b24d", priceFeedId: "", priceMultiplier: 1 }, { name: "USDC_PYTH", address: "0x1681450aa712554c31321d23a5dfdc7c4ea4d3e04d2375cdda3a48e89dbce0f7", priceFeedId: "0x41f3625971ca2ed2263e78573fe5ce23e13d2558ed3f2e47ab0f84fb9e7ae722", priceMultiplier: 1 }, { name: "APT_PYTH", address: "0xc21bdf1a4c16a5a7aad7c4a4feefde7ddf3122a149a92369c0044664b195f9cd", priceFeedId: "0x44a93dddd8effa54ea51076c4e851b6cbbfd938e82eb90197de38fe8876bb66e", priceMultiplier: 1 }, { name: "BTC_PYTH", address: "0x910baf8c8e45b7ba6729849e41ae2372b5ef127686893baddb913b772ab30356", priceFeedId: "0xf9c0172ba10dfa4d19088d94f5bf61d3b54d5bd7483a322a982e1373ee8ea31b", priceMultiplier: 1 }, { name: "ETH_PYTH", address: "0x4ceeb1b954e75cece12d4a9241b1ee1f06bf79519379aaa58d8e7dfb32479c3b", priceFeedId: "0xca80ba6dc32e08d06f1aa886011eed1d77c77be9eb761cc10d72b7d0a2fd57a6", priceMultiplier: 1 }, { name: "SOL_PYTH", address: "0x4ab336dc2801e3a05ff23918c789eda5df33b5fbf16add4c0457bad0e322707f", priceFeedId: "0xfe650f0367d4a7ef9815a593ea15d36593f0643aaaf0149bb04be67ab851decd", priceMultiplier: 1 }, { name: "SUI_PYTH", address: "0xb8f097a769793a979325953ff4705a7f781ba06f0fc0b426570545c8d652e7d5", priceFeedId: "0x50c67b3fd225db8912a424dd4baed60ffdde625ed2feaaf283724f9608fea266", priceMultiplier: 1 }, { name: "MOVE_PYTH", address: "0x91faa0e4ffcbf9131e1e217d954aeb0fa8ed46585e6be33a6650df75b0856f0d", priceFeedId: "0xee0c08f6b500a5933e95f75169dcd8910d9ff8d4acc6d07c9f577113a2387b9c", priceMultiplier: 1 }, { name: "XAG_PYTH", address: "0x9570dec57b6e651ae5efdc130520326ddbfeaecfcce024d3bcca077ffc331ccd", priceFeedId: "0x321ba4d608fa75ba76d6d73daa715abcbdeb9dba02257f05a1b59178b49f599b", priceMultiplier: 1 }, { name: "XAU_PYTH", address: "0x7151fde0d67b70c66b366fbc7b04aa8bc0a2b10fd206eee0309286aa5de1f8a5", priceFeedId: "0x30a19158f5a54c0adf8fb7560627343f22a1bc852b89d56be1accdc5dbf96d0e", priceMultiplier: 1 }, { name: "EUR_PYTH", address: "0xb4a587bf47a5013fa5d92d57fd617f61e795f34676d0e69a7bca408d9230e9f9", priceFeedId: "0x30a19158f5a54c0adf8fb7560627343f22a1bc852b89d56be1accdc5dbf96d0e", priceMultiplier: 1 }, { name: "GBP_PYTH", address: "0xee9753655840b2c873bc100133de3298cf807f407d7ad31811c18058e3f0e014", priceFeedId: "0xbcbdc2755bd74a2065f9d3283c2b8acbd898e473bdb90a6764b3dbd467c56ecd", priceMultiplier: 1 } ], fungibleAssets: [ { address: "0x7409091bec340a49aa0b5f4b32bc4b1f6aec05607622ff868bf8b1720e11aa40", decimals: 8, name: "testnet usdc", symbol: "tUSDC" }, { address: "0xdd84125d1ebac8f1ecb2819801417fc392325e672be111ec03830c34d6ff82dd", decimals: 8, name: "mirage dollar", symbol: "mUSD" }, { coinType: "0x1::aptos_coin::AptosCoin", address: "0x000000000000000000000000000000000000000000000000000000000000000a", decimals: 8, name: "Aptos Coin", symbol: "APT" } ], markets: [ { address: "0xce54f046a632ce7a1ae5a53fc4ce85241b1b2c68e064b74a5e2d0d47c65f065e", marginOracle: "STABLE_ORACLE", perpOracle: "APT_PYTH", perpSymbol: "APTPERP", marginSymbol: "mUSD", name: "APTPERP/mUSD" }, { address: "0x611ce4102776d7dbeafbaace9b8a3ebe536ebcb616ceb94bee19e7b0c7949e2c", marginOracle: "STABLE_ORACLE", perpOracle: "BTC_PYTH", perpSymbol: "BTCPERP", marginSymbol: "mUSD", name: "BTCPERP/mUSD" }, { address: "0xe763c8309768c997a468bc8f263603d04a13487e0313c529cc85dc50ad2e95ff", marginOracle: "STABLE_ORACLE", perpOracle: "ETH_PYTH", perpSymbol: "ETHPERP", marginSymbol: "mUSD", name: "ETHPERP/mUSD" }, { address: "0xc3337a2be5d9e37fd79b075d6f4ad3d3bd4c76835fe3c2a879fac5b3e61c6e48", marginOracle: "STABLE_ORACLE", perpOracle: "MOVE_PYTH", perpSymbol: "MOVEPERP", marginSymbol: "mUSD", name: "MOVEPERP/mUSD" }, { address: "0xa833f96e42925f8277e4f2f23497bb36d01b1b3d9dd75c44dbbe7f351ef4e621", marginOracle: "STABLE_ORACLE", perpOracle: "SOL_PYTH", perpSymbol: "SOLPERP", marginSymbol: "mUSD", name: "SOLPERP/mUSD" }, { address: "0xb47405b6da07670ffccdf2139ae2b04e99d0bf537277b69ada59780ee656c9ce", marginOracle: "STABLE_ORACLE", perpOracle: "SUI_PYTH", perpSymbol: "SUIPERP", marginSymbol: "mUSD", name: "SUIPERP/mUSD" }, { address: "0x0517831dfa7e68715fbd0ff19306e95abfd31bf6a5d2e6bc6b6b47a8ea6c77bf", marginOracle: "STABLE_ORACLE", perpOracle: "XAG_PYTH", perpSymbol: "XAGPERP", marginSymbol: "mUSD", name: "XAGPERP/mUSD" }, { address: "0x866a8c0812e3f42cfae8baac28451d8e73ab766e2890b1ddc2826a2daa98cb3e", marginOracle: "STABLE_ORACLE", perpOracle: "XAU_PYTH", perpSymbol: "XAUPERP", marginSymbol: "mUSD", name: "XAUPERP/mUSD" }, { address: "0x5fb3c167f41e209ffd1e0f7e488aada6149cc503724d42799bc16932a9bac676", marginOracle: "STABLE_ORACLE", perpOracle: "EUR_PYTH", perpSymbol: "EURPERP", marginSymbol: "mUSD", name: "EURPERP/mUSD" }, { address: "0xe961a196130e73b2cb80d25ce4d76b3d6372e9db7c41263fee177fc7c8ef30bd", marginOracle: "STABLE_ORACLE", perpOracle: "GBP_PYTH", perpSymbol: "GBPPERP", marginSymbol: "mUSD", name: "GBPPERP/mUSD" } ] }; // mirage_mainnet_config.json var mirage_mainnet_config_default = { chainId: 1, deployerAddress: "0x86d2ae026e602dbe39040457a6196ecdfc6308ab5b276d4379e10327b7204666", vaults: [ { name: "APT/mUSD CDP", address: "0xe1e13aa968df88dff6ac5227eaa6220c90a0e40e60ce274695a134f43966e2c0", collateralSymbol: "APT", borrowSymbol: "mUSD", collateralOracle: "APT_PYTH", borrowOracle: "STABLE_ORACLE" }, { name: "USDC/mUSD CDP", address: "0x3fb56c8c18ad3f20acf1ac971edfca4dd2bef1144e363aec83a04587675752f5", collateralSymbol: "USDC", borrowSymbol: "mUSD", collateralOracle: "USDC_PYTH", borrowOracle: "STABLE_ORACLE" } ], oracles: [ { name: "STABLE_ORACLE", address: "0xea497f66440058b553a3bfbc9eb8a7608fa58e0ab6d7c3a20042e07b9cb8b24d", priceFeedId: "", priceMultiplier: 1 }, { name: "APT_PYTH", address: "0xc21bdf1a4c16a5a7aad7c4a4feefde7ddf3122a149a92369c0044664b195f9cd", priceFeedId: "0x03ae4db29ed4ae33d323568895aa00337e658e348b37509f5372ae51f0af00d5", priceMultiplier: 1 }, { name: "USDC_PYTH", address: "0x1681450aa712554c31321d23a5dfdc7c4ea4d3e04d2375cdda3a48e89dbce0f7", priceFeedId: "0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a", priceMultiplier: 1 } ], fungibleAssets: [ { coinType: "0x1::aptos_coin::AptosCoin", address: "0x000000000000000000000000000000000000000000000000000000000000000a", decimals: 8, name: "Aptos Coin", symbol: "APT" }, { address: "0xdd84125d1ebac8f1ecb2819801417fc392325e672be111ec03830c34d6ff82dd", decimals: 8, name: "mirage dollar", symbol: "mUSD" }, { address: "0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b", decimals: 6, name: "USDC", symbol: "USDC" } ], markets: [ { address: "0xce54f046a632ce7a1ae5a53fc4ce85241b1b2c68e064b74a5e2d0d47c65f065e", marginOracle: "STABLE_ORACLE", perpOracle: "APT_PYTH", perpSymbol: "APTPERP", marginSymbol: "mUSD", name: "APTPERP/mUSD" } ] }; // src/utils/config.ts var Deployment = /* @__PURE__ */ ((Deployment2) => { Deployment2["APTOS_TESTNET"] = "testnet"; Deployment2["APTOS_MAINNET"] = "mainnet"; Deployment2["MOVEMENT_MAINNET"] = "movement"; return Deployment2; })(Deployment || {}); var getDeploymentByChainId = (chainId) => { if (chainId == 1) { return "mainnet" /* APTOS_MAINNET */; } else if (chainId == 2) { return "testnet" /* APTOS_TESTNET */; } else if (chainId == 126) { return "movement" /* MOVEMENT_MAINNET */; } else { throw new Error("no deployment with chaindId"); } }; var getChainIdByDeployment = (deployment) => { switch (deployment) { case "mainnet" /* APTOS_MAINNET */: return 1; case "testnet" /* APTOS_TESTNET */: return 2; case "movement" /* MOVEMENT_MAINNET */: return 126; default: throw new Error("no deployment with chaindId"); } }; var MirageConfig = class { chainId; deployerAddress; markets; vaults; fungibleAssets; oracles; fullnodeUrl; indexerUrl; mirageIndexerUrl; pythUrl; aptosApiKey; deployment; constructor(options) { if (options.deployment) { this.deployment = options.deployment; } else { this.deployment = "testnet" /* APTOS_TESTNET */; } this.aptosApiKey = options.aptosApiKey; this.pythUrl = options.pythUrl || getDefaultPythUrl(this.deployment); this.mirageIndexerUrl = options.mirageIndexerUrl || getDefaultMirageIndexerUrl(this.deployment); this.fullnodeUrl = options.fullnodeUrl || getDefaultFullnodeUrl(this.deployment); this.indexerUrl = options.indexerUrl || getDefaultIndexerUrl(this.deployment); let config; if (options.customConfig) { config = options.customConfig; } else if (this.deployment == "testnet" /* APTOS_TESTNET */) { config = mirage_config_testnet_default; } else if (this.deployment == "mainnet" /* APTOS_MAINNET */) { config = mirage_mainnet_config_default; } else if (this.deployment == "movement" /* MOVEMENT_MAINNET */) { config = mirage_config_movement_default; } else { console.warn(`unrecognized deployment ${this.deployment}, defaulting to mirage testnet config`); config = mirage_config_testnet_default; } this.chainId = config.chainId; this.deployerAddress = AccountAddress.fromString(config.deployerAddress); this.markets = {}; this.vaults = {}; this.fungibleAssets = {}; this.oracles = {}; config.markets.forEach((market) => this.markets[market.name] = market); config.vaults.forEach((vault) => this.vaults[vault.name] = vault); config.fungibleAssets.forEach((token) => this.fungibleAssets[token.symbol] = token); config.oracles.forEach((oracle) => this.oracles[oracle.name] = oracle); } }; var defaultMirageNetworks = { mainnet: { fullnodeUrl: "https://fullnode.mainnet.aptoslabs.com/v1", indexerUrl: "https://api.mainnet.aptoslabs.com/v1/graphql", mirageIndexerUrl: "https://api-aptos-mainnet.mirage.money/v1/graphql", pythUrl: "https://hermes.pyth.network" }, testnet: { fullnodeUrl: "https://fullnode.testnet.aptoslabs.com/v1", indexerUrl: "https://api.testnet.aptoslabs.com/v1/graphql", mirageIndexerUrl: "https://api-aptos-testnet.mirage.money/v1/graphql", pythUrl: "https://hermes-beta.pyth.network" }, movement: { fullnodeUrl: "https://mainnet.movementnetwork.xyz/v1", indexerUrl: "https://indexer.mainnet.movementnetwork.xyz/v1/graphql", mirageIndexerUrl: "https://api-movement-mainnet.mirage.money/v1/graphql", pythUrl: "https://hermes.pyth.network" } }; var getDefaultFullnodeUrl = (deployment) => { switch (deployment) { case "mainnet" /* APTOS_MAINNET */: return defaultMirageNetworks["mainnet" /* APTOS_MAINNET */].fullnodeUrl; case "testnet" /* APTOS_TESTNET */: return defaultMirageNetworks["testnet" /* APTOS_TESTNET */].fullnodeUrl; case "movement" /* MOVEMENT_MAINNET */: return defaultMirageNetworks["movement" /* MOVEMENT_MAINNET */].fullnodeUrl; default: throw new Error(`cannot find deployment ${deployment}`); } }; var getDefaultIndexerUrl = (deployment) => { switch (deployment) { case "mainnet" /* APTOS_MAINNET */: return defaultMirageNetworks["mainnet" /* APTOS_MAINNET */].indexerUrl; case "testnet" /* APTOS_TESTNET */: return defaultMirageNetworks["testnet" /* APTOS_TESTNET */].indexerUrl; case "movement" /* MOVEMENT_MAINNET */: return defaultMirageNetworks["movement" /* MOVEMENT_MAINNET */].indexerUrl; default: throw new Error(`cannot find deployment ${deployment}`); } }; var getDefaultMirageIndexerUrl = (deployment) => { switch (deployment) { case "mainnet" /* APTOS_MAINNET */: return defaultMirageNetworks["mainnet" /* APTOS_MAINNET */].mirageIndexerUrl; case "testnet" /* APTOS_TESTNET */: return defaultMirageNetworks["testnet" /* APTOS_TESTNET */].mirageIndexerUrl; case "movement" /* MOVEMENT_MAINNET */: return defaultMirageNetworks["movement" /* MOVEMENT_MAINNET */].mirageIndexerUrl; default: throw new Error(`cannot find deployment ${deployment}`); } }; var getDefaultPythUrl = (deployment) => { switch (deployment) { case "mainnet" /* APTOS_MAINNET */: return defaultMirageNetworks["mainnet" /* APTOS_MAINNET */].pythUrl; case "testnet" /* APTOS_TESTNET */: return defaultMirageNetworks["testnet" /* APTOS_TESTNET */].pythUrl; case "movement" /* MOVEMENT_MAINNET */: return defaultMirageNetworks["movement" /* MOVEMENT_MAINNET */].pythUrl; default: throw new Error(`cannot find deployment ${deployment}`); } }; // src/utils/configBuilder.ts import { Aptos as AptosClient2, AptosConfig, parseEncodedStruct } from "@aptos-labs/ts-sdk"; import BigNumber19 from "bignumber.js"; // src/views/fungibleAssetViews.ts import BigNumber from "bignumber.js"; var userAssetBalanceView = async (userAddress, tokenMetadataAddress, coinType, tokenDecimals, aptosClient) => { const result = await aptosClient.getAccountCoinAmount({ accountAddress: userAddress, coinType, faMetadataAddress: tokenMetadataAddress }); const balance = BigNumber(result); return integerToDecimal(balance, tokenDecimals); }; var allMirageAssetsView = async (aptosClient, deployerAddress) => { const payload = { function: `${getModuleAddress("mirage_core" /* MIRAGE_CORE */, deployerAddress)}::registry::all_mirage_assets`, functionArguments: [] }; const result = (await aptosClient.view({ payload }))[0]; return result.map((value) => value.inner); }; var fATotalSupplyView = async (faMetadataAddress, faDecimals, aptosClient) => { const payload = { function: "0x1::fungible_asset::supply", functionArguments: [faMetadataAddress] }; const [val] = await aptosClient.view({ payload }); const val_option = val; const val_raw_num = val_option.unwrap(); return integerToDecimal(BigNumber(val_raw_num), faDecimals); }; // src/views/marketViews.ts import BigNumber14 from "bignumber.js"; // src/generated/aptos/graphql.ts import gql from "graphql-tag"; import * as Urql from "urql"; var GetCollectionsByOwnerDocument = gql` query GetCollectionsByOwner($OWNER: String!) { current_collection_ownership_v2_view(where: {creator_address: {_eq: $OWNER}}) { collection_name collection_id } } `; var GetCurrentOwnerBalancesDocument = gql` query getCurrentOwnerBalances($OWNER: String!, $ASSET_TYPES: [String!]!) { current_fungible_asset_balances( where: {_and: {owner_address: {_eq: $OWNER}, is_primary: {_eq: true}, asset_type: {_in: $ASSET_TYPES}}} ) { owner_address amount owner_address asset_type } } `; var GetTokenIdsFromCollectionByOwnerDocument = gql` query GetTokenIdsFromCollectionByOwner($COLLECTION: String!, $OWNER: String!) { current_token_datas_v2( where: {collection_id: {_eq: $COLLECTION}, current_token_ownerships: {owner_address: {_eq: $OWNER}}, is_deleted_v2: {_eq: false}} ) { token_data_id } } `; var GetTokenIdsFromCollectionsByOwnerDocument = gql` query GetTokenIdsFromCollectionsByOwner($COLLECTIONS: [String!]!, $OWNER: String!) { current_token_datas_v2( where: {collection_id: {_in: $COLLECTIONS}, current_token_ownerships: {owner_address: {_eq: $OWNER}}, is_deleted_v2: {_eq: false}} ) { token_data_id } } `; // src/transactions/index.ts import BigNumber13 from "bignumber.js"; import { U64 as U643 } from "@aptos-labs/ts-sdk"; // src/transactions/marketTransactions.ts import { Bool, MoveVector, AccountAddress as AccountAddress11, TransactionPayloadEntryFunction, ModuleId, Identifier as Identifier9, EntryFunction, U64 } from "@aptos-labs/ts-sdk"; // src/entities/market/limitOrder.ts import { Identifier as Identifier3, StructTag as StructTag3, TypeTagStruct as TypeTagStruct3 } from "@aptos-labs/ts-sdk"; import BigNumber4 from "bignumber.js"; // src/entities/market/position.ts import { AccountAddress as AccountAddress3, Identifier as Identifier2, StructTag as StructTag2, TypeTagStruct as TypeTagStruct2 } from "@aptos-labs/ts-sdk"; import BigNumber3 from "bignumber.js"; // src/entities/market/tpsl.ts import { Identifier, StructTag, TypeTagStruct } from "@aptos-labs/ts-sdk"; import BigNumber2 from "bignumber.js"; var TpSl = class { /** * The side of the order */ side; takeProfitPrice; stopLossPrice; marketObjectAddress; positionObjectAddress; objectAddress; /** * Construct a TpSl instance * @param tpslResources the data to parse */ constructor(tpslResources, objectAddress, deployerAddress) { this.objectAddress = objectAddress; const tpslOrderType = TpSl.getTpslType(deployerAddress).toString(); const findTpSl = tpslResources.find((resource) => resource.type === tpslOrderType); if (findTpSl == void 0) throw new Error("TpSl object not found"); const tpsl = findTpSl.data; const strategyType = `${getModuleAddress("market" /* MARKET */, deployerAddress)}::market::Strategy`; const strategy = tpslResources.find((resource) => resource.type === strategyType); if (strategy == void 0) throw new Error("Strategy object not found"); this.side = Boolean(tpsl.is_long).valueOf() ? 1 /* LONG */ : 2 /* SHORT */; this.takeProfitPrice = BigNumber2(tpsl.take_profit_price).div(PRECISION_8); this.stopLossPrice = BigNumber2(tpsl.stop_loss_price).div(PRECISION_8); this.positionObjectAddress = strategy.data.position.inner; this.marketObjectAddress = strategy.data.market.inner; } static getTpslType(deployerAddress) { return new TypeTagStruct( new StructTag( getModuleAddress("market" /* MARKET */, deployerAddress), new Identifier("tpsl"), new Identifier("TpSl"), [] ) ); } }; // src/entities/market/position.ts var PositionSide = /* @__PURE__ */ ((PositionSide2) => { PositionSide2[PositionSide2["UNKNOWN"] = 0] = "UNKNOWN"; PositionSide2[PositionSide2["LONG"] = 1] = "LONG"; PositionSide2[PositionSide2["SHORT"] = 2] = "SHORT"; return PositionSide2; })(PositionSide || {}); var OrderType = /* @__PURE__ */ ((OrderType2) => { OrderType2[OrderType2["UNKNOWN"] = 0] = "UNKNOWN"; OrderType2[OrderType2["MARKET"] = 1] = "MARKET"; OrderType2[OrderType2["LIMIT"] = 2] = "LIMIT"; OrderType2[OrderType2["STOP"] = 3] = "STOP"; OrderType2[OrderType2["FLIP"] = 4] = "FLIP"; return OrderType2; })(OrderType || {}); var stringToPositionSide = (str) => { str = str.toLowerCase(); if (str == "l" || str == "long") return 1 /* LONG */; else if (str == "s" || str == "short") return 2 /* SHORT */; return 0 /* UNKNOWN */; }; var stringToOrderType = (str) => { str = str.toLowerCase(); if (str == "m" || str == "market") return 1 /* MARKET */; else if (str == "l" || str == "limit") return 2 /* LIMIT */; else if (str == "s" || str == "stop") return 3 /* STOP */; return 0 /* UNKNOWN */; }; var Position = class { /** * The token id */ tokenId; /** * The market of the position */ market; /** * The positions side */ side; /** * The position data if open */ openingPrice; margin; positionSize; fundingAccrued; maintenanceMargin; strategyAddresses; /** * The fees paid by this position in margin token */ feesPaid; /** * The funding paid by this position in margin token */ fundingPaid; /** * The trade pnl (realized_pnl - feesPaid - funding) in margin token */ tradePnl; /** * The realized pnl of this position in margin token */ realizedPnl; tpsl; limitOrders; /** * The positions initial leverage */ leverage; objectAddress; /** * Construct an instance of a trader * @param positionObjectResources Resources from position object account * @param objectAddress the address of the vault collection object * @param config the mirage config */ constructor(positionObjectResources, strategyObjectsResources, market, objectAddress, deployerAddress) { this.limitOrders = []; this.tpsl = void 0; this.objectAddress = AccountAddress3.fromString(objectAddress).toStringShort(); this.market = market; const positionType = Position.getPositionType(deployerAddress).toString(); const tokenIdsType = "0x4::token::TokenIdentifiers"; const propertyMapType = "0x4::property_map::PropertyMap"; const position = positionObjectResources.find((resource) => resource.type === positionType); if (position == void 0) throw new Error("Position object not found"); const tokenIdentifiers = positionObjectResources.find((resource) => resource.type === tokenIdsType); if (tokenIdentifiers == void 0) throw new Error("TokenIdentifiers object not found"); this.tokenId = BigInt(tokenIdentifiers.data.index.value); const propertyMap = positionObjectResources.find((resource) => resource.type === propertyMapType); if (propertyMap == void 0) throw new Error("PropertyMap object not found"); this.feesPaid = getPropertyMapU64("fees_paid", propertyMap.data).div(PRECISION_8); this.fundingPaid = getPropertyMapSigned64("funding_paid", propertyMap.data).div(PRECISION_8); this.tradePnl = getPropertyMapSigned64("realized_pnl", propertyMap.data).div(PRECISION_8); this.realizedPnl = this.tradePnl.minus(this.feesPaid).minus(this.fundingPaid); this.leverage = getPropertyMapU64("leverage", propertyMap.data).div(PERCENT_PRECISION); this.openingPrice = BigNumber3(position.data.last_settled_price).div(PRECISION_8); const side = BigNumber3(position.data.side); if (side.eq(1)) { this.side = 2 /* SHORT */; } else if (side.eq(2)) { this.side = 1 /* LONG */; } else { this.side = 0 /* UNKNOWN */; } this.margin = BigNumber3(position.data.margin_amount).div(PRECISION_8); this.positionSize = BigNumber3(position.data.position_size).div(PRECISION_8); const marketFundingAccumulated = this.side == 1 /* LONG */ ? market.longFundingAccumulated : market.shortFundingAccumulated; const lastPositionFunding = BigNumber3(position.data.last_funding_accumulated.magnitude).times(position.data.last_funding_accumulated.negative ? -1 : 1).div(FEE_PRECISION).div(PRECISION_8); this.fundingAccrued = marketFundingAccumulated.minus(lastPositionFunding).times(this.positionSize); this.maintenanceMargin = ZERO; this.strategyAddresses = position.data.strategy_refs; for (const strategyObjectResources of strategyObjectsResources) { const strategyAddress = strategyObjectResources[0].data.transfer_events.guid.id.addr; for (const strategyObjectResource of strategyObjectResources) { if (strategyObjectResource.type === TpSl.getTpslType(deployerAddress).toString()) { const tpsl = new TpSl(strategyObjectResources, strategyAddress, deployerAddress); if (tpsl.positionObjectAddress == this.objectAddress) { this.tpsl = tpsl; } break; } if (strategyObjectResource.type === LimitOrder.getLimitOrderType(deployerAddress).toString()) { const limitOrder = new LimitOrder(strategyObjectResources, strategyAddress, deployerAddress); if (limitOrder.positionObjectAddress == this.objectAddress) { this.limitOrders.push(limitOrder); } break; } } } } static getStrategyAddresses(positionObjectResources, deployerAddress) { const positionType = Position.getPositionType(deployerAddress).toString(); const findPosition = positionObjectResources.find((resource) => resource.type === positionType); if (!findPosition) return []; const strategyAddresses = findPosition.data.strategy_refs; return strategyAddresses; } /** * Returns bool on if the position is open * @returns If the position is open */ isOpen() { return this.side != 0 /* UNKNOWN */; } /** * Calculates the leverage of a position given the prices * @param position The position * @param perpetualPrice The perpetual price * @param marginPrice The margin price * @returns The leverage, where 1 == 1x leverage */ static getLeverage(position, perpetualPrice, marginPrice) { return position.positionSize.div(position.margin).minus(position.fundingAccrued).times(perpetualPrice).div(marginPrice).toNumber(); } /** * Estimates a positions pnl in terms of the margin type * @param position The position * @param perpetualPrice The perpetual price * @param marginPrice The margin price * @returns The amount of pnl in terms of the margin of the market */ static estimatePnl(position, perpetualPrice, marginPrice) { return BigNumber3(perpetualPrice).minus(position.openingPrice).times(position.positionSize).div(marginPrice).times(position.side == 1 /* LONG */ ? 1 : -1).minus(position.fundingAccrued).toNumber(); } /** * Estimates a positions percent pnl in terms of the margin * @param position The position * @param perpetualPrice The perpetual price * @param marginPrice The margin price * @returns The percent pnl in terms of the margin of the market */ static estimatePercentPnl(position, perpetualPrice, marginPrice) { return Position.estimatePnl(position, perpetualPrice, marginPrice) * 100 / position.margin.toNumber(); } getPositionMaintenanceMarginMUSD(perpPrice, marginPrice) { if (!this.isOpen) { return ZERO; } const closeFee = this.market.getOpenCloseFee( this.side, true, // close this.positionSize, perpPrice, marginPrice ); const positionSizeMUSD = this.positionSize.times(perpPrice); return BigNumber3(this.market.maintenanceMargin).times(positionSizeMUSD).plus(closeFee); } getLiquidationPrice(perpPrice, marginPrice) { if (!this.isOpen) { return ZERO; } const pnl = Position.estimatePnl(this, perpPrice.toNumber(), marginPrice.toNumber()); const maintenanceMargin = this.getPositionMaintenanceMarginMUSD(perpPrice, marginPrice); const openingPrice = this.openingPrice; let rawMargin = this.margin; rawMargin = rawMargin.plus(pnl); const marginMUSD = rawMargin.times(marginPrice); if (marginMUSD.lte(maintenanceMargin)) { return this.side == 1 /* LONG */ ? BigNumber3(U64_MAX) : ZERO; } const marginScalar = marginMUSD.minus(maintenanceMargin).div(this.positionSize); if (this.side == 1 /* LONG */ && openingPrice.gt(marginScalar)) { return openingPrice.minus(marginScalar); } else if (this.side == 2 /* SHORT */ && marginScalar.plus(openingPrice).lt(BigNumber3(U64_MAX))) { return marginScalar.plus(openingPrice); } else if (this.side == 1 /* LONG */) { return ZERO; } else { return BigNumber3(U64_MAX); } } static getPositionType(deployerAddress) { return new TypeTagStruct2( new StructTag2( getModuleAddress("market" /* MARKET */, deployerAddress), new Identifier2("market"), new Identifier2("Position"), [] ) ); } }; // src/entities/market/limitOrder.ts var LimitOrder = class { /** * The side of the order */ side; /** * Is this a limit order only to decrease a position */ isDecreaseOnly; /** * Position size in units of the asset */ positionSize; /** * This trades margin amount */ margin; /** * The price this order gets triggered */ triggerPrice; /** * Will this order trigger above or below the triggerPrice */ triggersAbove; /** * The max price slippage on trigger for the order */ maxPriceSlippage; /** * The expiration time of the order */ expiration; marketObjectAddress; positionObjectAddress; objectAddress; /** * Construct a LimitOrder instance * @param limitOrderData the data to parse */ constructor(limitOrderResources, objectAddress, deployerAddress) { this.objectAddress = objectAddress; const limitOrderType = LimitOrder.getLimitOrderType(deployerAddress).toString(); const findLimitOrder = limitOrderResources.find((resource) => resource.type === limitOrderType); if (findLimitOrder == void 0) throw new Error("LimitOrder object not found"); const limitOrder = findLimitOrder.data; const strategyType = `${getModuleAddress("market" /* MARKET */, deployerAddress)}::market::Strategy`; const strategy = limitOrderResources.find((resource) => resource.type === strategyType); if (strategy == void 0) throw new Error("Strategy object not found"); this.side = Boolean(limitOrder.is_long).valueOf() ? 1 /* LONG */ : 2 /* SHORT */; this.isDecreaseOnly = limitOrder.is_decrease_only; this.positionSize = BigNumber4(limitOrder.position_size).div(PRECISION_8); this.triggersAbove = Boolean(limitOrder.triggers_above); this.triggerPrice = BigNumber4(limitOrder.trigger_price).div(PRECISION_8); this.maxPriceSlippage = BigNumber4(limitOrder.max_price_slippage).div(PRECISION_8); this.expiration = BigInt(limitOrder.expiration); this.margin = BigNumber4(strategy.data.strategy_margin_amount).div(PRECISION_8); this.positionObjectAddress = strategy.data.position.inner; this.marketObjectAddress = strategy.data.market.inner; } // Good-til-cancelled expiration (U64_MAX) static gtcExpiration() { return BigInt(U64_MAX); } // Whether this order has an expiration or is good-til-cancelled isGtc() { return this.expiration == LimitOrder.gtcExpiration(); } /** * Turn a percentage slippage into a price slippage * @param triggerPrice The trigger price of the trade * @param percentSlippage The allowed slippage in basis points * @returns The amount of price slippage allowed */ static percentSlippageToPriceSlippage(triggerPrice, percentSlippage) { return triggerPrice.times(percentSlippage).div(1e4); } static getLimitOrderType(deployerAddress) { return new TypeTagStruct3( new StructTag3( getModuleAddress("market" /* MARKET */, deployerAddress), new Identifier3("limit_order"), new Identifier3("LimitOrder"), [] ) ); } }; // src/entities/market/market.ts import BigNumber5 from "bignumber.js"; var Market = class { /** * The markets perp symbol */ perpSymbol; /** * The markets perp symbol */ marginTokenAddress; /** * The total long margin of a market */ totalLongMargin; /** * The total short margin of a market */ totalShortMargin; /** * Long open interest in musd */ longOpenInterest; /** * Short open interest in musd */ shortOpenInterest; /** * Long open interest in musd */ longFundingAccumulated; /** * Short open interest in musd */ shortFundingAccumulated; /** * The funding that will be taken next funding round */ nextFundingRate; /** * The time of the last funding round */ lastFundingRound; /** * Whether long positions are close only */ longCloseOnly; /** * Whether short positions are close only */ shortCloseOnly; // FeeInfo /** * Minimum taker fee at equal oi */ minTakerFee; /** * Maximum taker fee at the max_oi_imbalance */ maxTakerFee; /** * Min maker fee at large oi imbalance */ minMakerFee; /** * Max maker fee at equal oi */ maxMakerFee; // FundingInfo /** * The minimum funding rate */ minFundingRate; /** * The maximum funding rate */ maxFundingRate; /** * The maximum funding rate */ baseFundingRate; /** * The interval between funding payments */ fundingInterval; // MarketConfig /** * The max total oi allowed for the long & short sides */ maxOpenInterest; /** * The max allowed imbalance between long and short oi */ maxOpenInterestImbalance; /** * The base percent maintenance margin */ maintenanceMargin; /** * The max leverage for this market */ maxLeverage; /** * The min order size in mUSD for a trade */ minOrderSize; /** * The max order size in mUSD for a trade */ maxOrderSize; /** * The market collection address */ objectAddress; /** * Construct an instance of Market * @param marketObjectResources resources from the market token collection account * @param marginCoin the margin asset of the market * @param perpetualAsset the asset being traded */ constructor(marketObjectResources, objectAddress, deployerAddress) { this.objectAddress = objectAddress; const marketType = `${getModuleAddress("market" /* MARKET */, deployerAddress)}::market::Market`; const market = marketObjectResources.find((resource) => resource.type === marketType); if (market == void 0) throw new Error("Market object not found"); this.perpSymbol = market.data.perp_symbol; this.marginTokenAddress = market.data.margin_token.inner; this.totalLongMargin = new BigNumber5(market.data.totalLongMargin).div(PRECISION_8); this.totalShortMargin = new BigNumber5(market.data.totalShortMargin).div(PRECISION_8); this.longOpenInterest = new BigNumber5(market.data.long_oi).div(PRECISION_8); this.shortOpenInterest = new BigNumber5(market.data.short_oi).div(PRECISION_8); this.longFundingAccumulated = new BigNumber5(market.data.long_funding_accumulated_per_unit.magnitude).times(market.data.long_funding_accumulated_per_unit.negative ? -1 : 1).div(FEE_PRECISION).div(PRECISION_8); this.shortFundingAccumulated = new BigNumber5(market.data.short_funding_accumulated_per_unit.magnitude).times(market.data.short_funding_accumulated_per_unit.negative ? -1 : 1).div(FEE_PRECISION).div(PRECISION_8); this.nextFundingRate = new BigNumber5(market.data.next_funding_rate.magnitude).times(market.data.next_funding_rate.negative ? -1 : 1).div(FEE_PRECISION); this.lastFundingRound = new Date(new BigNumber5(market.data.last_funding_round).times(1e3).toNumber()); this.longCloseOnly = Boolean(market.data.is_long_close_only); this.shortCloseOnly = Boolean(market.data.is_short_close_only); this.minTakerFee = new BigNumber5(market.data.config.fees.min_taker_fee).div(FEE_PRECISION).toNumber(); this.maxTakerFee = new BigNumber5(market.data.config.fees.max_taker_fee).div(FEE_PRECISION).toNumber(); this.minMakerFee = new BigNumber5(market.data.config.fees.min_maker_fee).div(FEE_PRECISION).toNumber(); this.maxMakerFee = !!market ? new BigNumber5(market.data.config.fees.max_maker_fee).div(FEE_PRECISION).toNumber() : 0; this.minFundingRate = !!market ? new BigNumber5(market.data.config.funding.min_funding_rate).div(FEE_PRECISION).toNumber() : 0; this.maxFundingRate = !!market ? new BigNumber5(market.data.config.funding.max_funding_rate).div(FEE_PRECISION).toNumber() : 0; this.baseFundingRate = !!market ? new BigNumber5(market.data.config.funding.base_funding_rate).div(FEE_PRECISION).toNumber() : 0; this.fundingInterval = !!market ? new BigNumber5(market.data.config.funding.funding_interval) : ZERO; this.maxOpenInterest = !!market ? new BigNumber5(market.data.config.max_oi).div(PRECISION_8) : ZERO; this.maxOpenInterestImbalance = !!market ? new BigNumber5(market.data.config.max_oi_imbalance).div(PRECISION_8) : ZERO; this.maintenanceMargin = !!market ? new BigNumber5(market.data.config.maintenance_margin).div(PERCENT_PRECISION).toNumber() : 0; this.maxLeverage = !!market ? new BigNumber5(market.data.config.max_leverage).div(PERCENT_PRECISION).times(100).toNumber() : 0; this.minOrderSize = !!market ? new BigNumber5(market.data.config.min_order_size).div(PRECISION_8) : ZERO; this.maxOrderSize = !!market ? new BigNumber5(market.data.config.max_order_size).div(PRECISION_8) : ZERO; } getOpenCloseFee(side, isClose, positionSize, perpPrice, marginPrice) { const skew = this.getSkew(perpPrice, isClose); const positionSizeMUSD = positionSize.times(perpPrice); const fee = isClose ? this.getCloseFee(skew, side, positionSizeMUSD) : this.getOpenFee(skew, side, positionSizeMUSD); return fee.times(positionSizeMUSD).div(marginPrice); } getCloseFee(currSkew, side, positionSizeMUSD) { const skewedLong = currSkew.isPositive(); const longAndLongSkew = side == 1 /* LONG */ && skewedLong; const shortAndShortSkew = side == 2 /* SHORT */ && !skewedLong; const additionalSkew = positionSizeMUSD.times(side ? 1 : -1); const newSkew = currSkew.plus(additionalSkew); const taker = longAndLongSkew || shortAndShortSkew || skewedLong == newSkew.isNegative(); return this.calculateFee(newSkew, taker); } getOpenFee(currSkew, side, positionSizeMUSD) { const skewedLong = currSkew.isPositive(); const longAndLongSkew = side == 1 /* LONG */ && skewedLong; const shortAndShortSkew = side == 2 /* SHORT */ && !skewedLong; const additionalSkew = positionSizeMUSD.times(side == 1 /* LONG */ ? 1 : -1); const newSkew = currSkew.plus(additionalSkew); const taker = longAndLongSkew || shortAndShortSkew || skewedLong == newSkew.isNegative(); const newSkewAbs = newSkew.abs(); if (taker) { if (newSkewAbs.gte(this.maxOpenInterestImbalance)) { return BigNumber5(NaN); } } return this.calculateFee(newSkew, taker); } /// Get the the oi skew and if it skews long given a market price getSkew(perpPrice, isClose) { const maxOi = this.maxOpenInterestImbalance; const longOi = this.longOpenInterest; const shortOi = this.shortOpenInterest; const longOiMUSD = longOi.times(perpPrice); const shortOiMUSD = shortOi.times(perpPrice); if (!isClose && (longOiMUSD.gte(maxOi) || shortOiMUSD.gte(maxOi))) { return BigNumber5(NaN); } if (longOiMUSD.eq(shortOiMUSD)) { return ZERO; } else if (longOiMUSD.gt(shortOiMUSD)) { return longOiMUSD.minus(shortOiMUSD); } else { return shortOiMUSD.minus(longOiMUSD); } } calculateFee(skew, is_taker) { const maxSkew = this.maxOpenInterestImbalance; const newSkewAbs = skew.abs(); if (is_taker) { const min = BigNumber5(this.minTakerFee); const max = BigNumber5(this.maxTakerFee); if (newSkewAbs.gte(BigNumber5(max.minus(min)).times(maxSkew).div(max))) { return max; } else { const scaled = min.times(maxSkew).div(maxSkew.minus(newSkewAbs)); if (scaled.lte(min)) { return min; } else { return scaled; } } } else { const min = BigNumber5(this.minMakerFee); const max = BigNumber5(this.maxMakerFee); if (max.times(newSkewAbs).div(maxSkew).lte(min)) { return max; } else { return min.times(maxSkew).div(newSkewAbs); } } } }; // src/entities/mirageAsset.ts import { createObjectAddress } from "@aptos-labs/ts-sdk"; import BigNumber7 from "bignumber.js"; // src/entities/rebase.ts import BigNumber6 from "bignumber.js"; var Rebase = class { /** * The elastic part of the rebase */ elastic; /** * The base part of the rebase */ base; /** * Construct an instance of rebase * @param elastic the elastic part * @param base the base part */ constructor(elastic, base) { this.elastic = elastic; this.base = base; } /** * Get a elastic value represented in terms of the current rebase. * @param base the base value to convert * @param roundUp should we roundup the division * @returns the converted elastic part */ toElastic(base, roundUp) { if (this.base.isZero()) { return BigNumber6(0); } const scaledBase = base.times(PRECISION_8); let elastic = scaledBase.times(this.elastic).div(this.base); if (roundUp) { elastic = elastic.integerValue(BigNumber6.ROUND_CEIL); } else { elastic = elastic.integerValue(BigNumber6.ROUND_FLOOR); } return elastic.div(1e8); } /** * Get a base value represented in terms of the current rebase. * @param elastic the elastic value to convert * @param roundUp should we roundup the division * @returns the converted base part */ toBase(elastic, roundUp) { if (this.elastic.isZero()) { return BigNumber6(0); } const scaledElastic = elastic.multipliedBy(PRECISION_8); let base = scaledElastic.times(this.base).div(this.elastic); if (roundUp) { base = base.integerValue(BigNumber6.ROUND_CEIL); } else { base = base.integerValue(BigNumber6.ROUND_FLOOR); } return base.div(PRECISION_8); } }; // src/entities/mirageAsset.ts var MirageAsset = class { symbol; name; decimals; debtRebase; objectAddress; constructor(tokenObjectResources, deployerAddress) { const debtStoreType = `${getModuleAddress("mirage" /* MIRAGE */, deployerAddress)}::mirage::MirageDebtStore`; const debtStore = tokenObjectResources.find((resource) => resource.type === debtStoreType); if (debtStore == void 0) throw new Error("MirageDebtStore object not found"); this.debtRebase = new Rebase( BigNumber7(debtStore.data.debt.elastic), BigNumber7(debtStore.data.debt.base) ); const faMetadataType = `0x1::fungible_asset::Metadata`; const faMetadata = tokenObjectResources.find((resource) => resource.type === faMetadataType); if (faMetadata == void 0) throw new Error("Metadata object not found"); this.symbol = faMetadata.data.symbol; this.name = faMetadata.data.name; this.decimals = BigNumber7(faMetadata.data.decimals).toNumber(); this.objectAddress = MirageAsset.getMirageAssetAddress(this.symbol, deployerAddress); } static getMirageAssetAddress(symbol, deployerAddress) { const mirageModuleAddress = getModuleAddress("mirage_core" /* MIRAGE_CORE */, deployerAddress); return createObjectAddress(mirageModuleAddress, symbol); } }; var getMusdAddress = (deployerAddress) => { return MirageAsset.getMirageAssetAddress("mUSD", deployerAddress); }; // src/entities/vault/vault.ts import { AccountAddress as AccountAddress6, TypeTagStruct as TypeTagStruct4, StructTag as StructTag4, Identifier as Identifier4 } from "@aptos-labs/ts-sdk"; import BigNumber8 from "bignumber.js"; var Vault = class { /** * The amount of collateral deposited */ collateralAmount; /** * The amount borrowed */ borrowAmount; /** * The vaults pnl in the borrow token */ pnl; /** * The vaults fees in the borrow token */ feesPaid; /** * An instance of the VaultCollection for this Vault */ vaultCollection; objectAddress; /** * Construct an instance of Vault * @param vaultObjectResources resources from vault token account * @param vaultCollection a vault collection entity * @param objectAddress the vault object address */ constructor(vaultObjectResources, vaultCollection, deployerAddress) { this.vaultCollection = vaultCollection; const vaultType = Vault.getVaultType(deployerAddress).toString(); const propertyMapType = `0x4::property_map::PropertyMap`; const vault = vaultObjectResources.find((resource) => resource.type === vaultType); if (vault == void 0) throw new Error("Vault object not found"); const propertyMap = vaultObjectResources.find((resource) => resource.type === propertyMapType); if (propertyMap == void 0) throw new Error("PropertyMap object not found"); this.collateralAmount = integerToDecimal( BigNumber8(vault.data.collateral_amount), this.vaultCollection.collateralDecimals ); this.objectAddress = AccountAddress6.from(vault.data.burn_ref.inner.vec[0].self); this.borrowAmount = this.vaultCollection.mirage.debtRebase.toElastic( this.vaultCollection.borrowRebase.toElastic( new BigNumber8(vault.data.borrow_part.amount).div(PRECISION_8), true ), false ); const realizedPnl = getPropertyMapSigned64("realized_pnl", propertyMap.data).div(PRECISION_8); const lastBorrowAmount = getPropertyMapU64("last_borrow_amount", propertyMap.data).div(PRECISION_8); this.feesPaid = getPropertyMapU64("fees_paid", propertyMap.data).div(PRECISION_8); this.pnl = realizedPnl.plus(lastBorrowAmount).minus(this.borrowAmount); } getHealth(collateralPrice, borrowPrice) { return calculateVaultHealth( this.collateralAmount, this.borrowAmount, this.vaultCollection.maintenanceCollateralizationPercent, collateralPrice, borrowPrice ); } static getVaultType(deployerAddress) { return new TypeTagStruct4( new StructTag4( getModuleAddress("mirage" /* MIRAGE */, deployerAddress), new Identifier4("vault"), new Identifier4("Vault"), [] ) ); } }; function calculateVaultHealth(collateralAmount, borrowAmount, maintenanceCollateralizationPercent, collateralPrice, borrowPrice) { const exchangeRate = collateralPrice.div(borrowPrice); const ratio = collateralAmount.times(exchangeRate).div(maintenanceCollateralizationPercent / 100).div(borrowAmount); return ratio.minus(1).times(100).toNumber(); } // src/entities/vault/vaultCollection.ts import { StructTag as StructTag5, Identifier as Identifier5, TypeTagStruct as TypeTagStruct5, createObjectAddress as createObjectAddress2 } from "@aptos-labs/ts-sdk"; import BigNumber9 from "bignumber.js"; var VaultCollection = class { /** * The collateral asset of the vault */ collateralAddress; /** * The borrow asset of the vault (a mirage asset e.g. mUSD) */ borrowAddress; /** * The borrow asset of the vault (a mirage asset e.g. mUSD) */ borrowSymbol; /** * The collateral asset of the vault (a mirage asset e.g. mUSD) */ collateralSymbol; /** * The rebase representing the total borrow in the vault */ borrowReba