@mirage-protocol/sdk
Version:
Typescript library for interacting with Mirage Protocol move contracts
1,420 lines (1,396 loc) • 196 kB
JavaScript
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