UNPKG

@firefly-exchange/library-sui

Version:

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

165 lines (164 loc) 6.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const bcs_1 = require("@mysten/bcs"); const constants_1 = require("../../constants"); const library_1 = require("../../library"); const types_1 = require("../../types"); class Account { /** * Fetches the account details from on-chain from provided internal data store * @param suiClient Sui Client * @param storeID The id/address of the internal store * @param account The address of user to be fetched * @returns */ static async getAccount(suiClient, storeID, account) { const objDetails = await suiClient.getObject({ id: storeID, options: { showContent: true } }); // eslint-disable-next-line @typescript-eslint/no-explicit-any const userTable = objDetails.data.content.fields.accounts.fields.id.id; try { const userData = await suiClient.getDynamicFieldObject({ parentId: userTable, name: { type: "address", value: account } }); // parse the account // eslint-disable-next-line @typescript-eslint/no-explicit-any const fields = userData.data.content.fields.value.fields; return { address: fields.address, assets: fields.assets.map(asset => asset.fields), crossPositions: fields.cross_positions.map(position => Account.mapPosition(position.fields)), isolatedPositions: fields.isolated_positions.map(position => Account.mapPosition(position.fields)), authorized: fields.authorized }; } catch (e) { return { address: account, assets: [], crossPositions: [], isolatedPositions: [], authorized: [] }; } } /** * Fetches the user assets from on-chain from provided internal data store * @param suiClient Sui Client * @param storeID The id/address of the internal store * @param account The address of user to be fetched * @returns Array of Deposited Assets */ static async getAccountAssets(suiClient, storeID, account) { const data = await Account.getAccount(suiClient, storeID, account); return data.assets; } /** * Fetches the user margin from on-chain from provided internal data store * @param suiClient Sui Client * @param storeID The id/address of the internal store * @param account The address of user to be fetched * @returns The margin of the account in base number */ static async getAccountMargin(suiClient, storeID, account) { const data = await Account.getAccount(suiClient, storeID, account); return data.assets.length > 0 ? (0, library_1.toBaseNumber)(data.assets[0].quantity, constants_1.USDC_BASE_DECIMALS, constants_1.SUI_NATIVE_BASE) : 0; } /** * Returns the margin user has available for withdrawal on-chain * @param suiClient Sui Client * @param parser The deployment config parser * @param account The account address for which to query withdrawable balance * @param asset The name of the asset that is to be queried * @returns The user available margin for withdraw in base number */ static async getWithdrawableAssets(suiClient, parser, account, asset) { const txb = new types_1.TransactionBlock(); txb.moveCall({ arguments: [ txb.object(parser.getInternalDataStore()), txb.pure.address(account), txb.pure.string(asset) ], target: `${parser.getPackageId()}::margining_engine::get_withdrawable_assets` }); try { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const [availableMargin] = (await suiClient.devInspectTransactionBlock({ sender: account, transactionBlock: txb // eslint-disable-next-line @typescript-eslint/no-unused-vars })).results[0].returnValues.map(([bytes, _]) => (0, library_1.bigNumber)(bcs_1.bcs.u64().parse(Uint8Array.from(bytes)))); return (0, library_1.toBaseNumber)(availableMargin, 3, constants_1.SUI_NATIVE_BASE); } catch (e) { return 0; } } /** * Fetches the user positions from on-chain from provided internal data store * @param suiClient Sui Client * @param storeID The id/address of the internal store * @param account The address of user to be fetched * @returns */ static async getAccountCrossPositions(suiClient, storeID, account) { const data = await Account.getAccount(suiClient, storeID, account); return data.crossPositions; } /** * Fetches the user position for provided perpetual from on-chain from provided internal data store * @param suiClient Sui Client * @param storeID The id/address of the internal store * @param account The address of user to be fetched (address_1) * @param perpetual The address of the perpetual for which to fetch the position * @returns Position of the user on provided perp */ static async getAccountCrossPositionForPerpetual(suiClient, storeID, account, perpetual) { const data = await Account.getAccount(suiClient, storeID, account); for (const position of data.crossPositions) { if (position.perpetual == perpetual) return position; } throw `Account ${account} has not position on perpetual: ${perpetual}`; } /** * Fetches the list of accounts/address that are authorized for given account * @param suiClient Sui Client * @param storeID The id/address of the internal store * @param account The address of user to be fetched (address_1) * @returns list of addresses */ static async getAuthorizedAccounts(suiClient, storeID, account) { const data = await Account.getAccount(suiClient, storeID, account); return data.authorized; } /** * Method to parse the position * @param fields the position fields * @returns IPosition */ // eslint-disable-next-line @typescript-eslint/no-explicit-any static mapPosition(fields) { const position = { ...fields }; // eslint-disable-next-line @typescript-eslint/no-explicit-any const fundingFields = position.funding.fields; position.funding = { timestamp: fundingFields.timestamp, rate: { value: fundingFields.rate.fields.value, sign: fundingFields.rate.fields.sign } }; return position; } } exports.default = Account;