UNPKG

blub-sdk

Version:

A modular SDK for interacting with the BLUB ecosystem on the Sui blockchain.

195 lines (194 loc) 8.34 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CoinUtils = exports.SUI_SYSTEM_STATE_OBJECT_ID = exports.DEFAULT_NFT_TRANSFER_GAS_FEE = exports.GAS_SYMBOL = exports.GAS_TYPE_ARG_LONG = exports.GAS_TYPE_ARG = exports.DEFAULT_GAS_BUDGET_FOR_STAKE = exports.DEFAULT_GAS_BUDGET_FOR_TRANSFER_SUI = exports.DEFAULT_GAS_BUDGET_FOR_TRANSFER = exports.DEFAULT_GAS_BUDGET_FOR_MERGE = exports.DEFAULT_GAS_BUDGET_FOR_SPLIT = void 0; const contract_1 = require("./contract"); const COIN_TYPE = "0x2::coin::Coin"; const COIN_TYPE_ARG_REGEX = /^0x2::coin::Coin<(.+)>$/; exports.DEFAULT_GAS_BUDGET_FOR_SPLIT = 1000; exports.DEFAULT_GAS_BUDGET_FOR_MERGE = 500; exports.DEFAULT_GAS_BUDGET_FOR_TRANSFER = 100; exports.DEFAULT_GAS_BUDGET_FOR_TRANSFER_SUI = 100; exports.DEFAULT_GAS_BUDGET_FOR_STAKE = 1000; exports.GAS_TYPE_ARG = "0x2::sui::SUI"; exports.GAS_TYPE_ARG_LONG = "0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI"; exports.GAS_SYMBOL = "SUI"; exports.DEFAULT_NFT_TRANSFER_GAS_FEE = 450; exports.SUI_SYSTEM_STATE_OBJECT_ID = "0x0000000000000000000000000000000000000005"; /** * This class provides helper methods for working with coins. */ class CoinUtils { /**coin * Get the coin type argument from a SuiMoveObject. * * @param obj The SuiMoveObject to get the coin type argument from. * @returns The coin type argument, or null if it is not found. */ static getCoinTypeArg(obj) { const res = obj.type.match(COIN_TYPE_ARG_REGEX); return res ? res[1] : null; } /** * Get whether a SuiMoveObject is a SUI coin. * * @param obj The SuiMoveObject to check. * @returns Whether the SuiMoveObject is a SUI coin. */ static isSUI(obj) { const arg = CoinUtils.getCoinTypeArg(obj); return arg ? CoinUtils.getCoinSymbol(arg) === "SUI" : false; } /** * Get the coin symbol from a coin type argument. * * @param coinTypeArg The coin type argument to get the symbol from. * @returns The coin symbol. */ static getCoinSymbol(coinTypeArg) { return coinTypeArg.substring(coinTypeArg.lastIndexOf(":") + 1); } /** * Get the balance of a SuiMoveObject. * * @param obj The SuiMoveObject to get the balance from. * @returns The balance of the SuiMoveObject. */ static getBalance(obj) { return BigInt(obj.fields.balance); } /** * Get the total balance of a list of CoinAsset objects for a given coin address. * * @param objs The list of CoinAsset objects to get the total balance for. * @param coinAddress The coin address to get the total balance for. * @returns The total balance of the CoinAsset objects for the given coin address. */ static totalBalance(objs, coinAddress) { let balanceTotal = BigInt(0); objs.forEach((obj) => { if (coinAddress === obj.coinAddress) { balanceTotal += BigInt(obj.balance); } }); return balanceTotal; } /** * Get the ID of a SuiMoveObject. * * @param obj The SuiMoveObject to get the ID from. * @returns The ID of the SuiMoveObject. */ static getID(obj) { return obj.fields.id.id; } /** * Get the coin type from a coin type argument. * * @param coinTypeArg The coin type argument to get the coin type from. * @returns The coin type. */ static getCoinTypeFromArg(coinTypeArg) { return `${COIN_TYPE}<${coinTypeArg}>`; } /** * Get the CoinAsset objects for a given coin type. * * @param coinType The coin type to get the CoinAsset objects for. * @param allSuiObjects The list of all SuiMoveObjects. * @returns The CoinAsset objects for the given coin type. */ static getCoinAssets(coinType, allSuiObjects) { const coins = []; allSuiObjects.forEach((anObj) => { if ((0, contract_1.normalizeCoinType)(anObj.coinAddress) === (0, contract_1.normalizeCoinType)(coinType)) { coins.push(anObj); } }); return coins; } /** * Get whether a coin address is a SUI coin. * * @param coinAddress The coin address to check. * @returns Whether the coin address is a SUI coin. */ static isSuiCoin(coinAddress) { return (0, contract_1.extractStructTagFromType)(coinAddress).full_address === exports.GAS_TYPE_ARG; } /** * Select the CoinAsset objects from a list of CoinAsset objects that have a balance greater than or equal to a given amount. * * @param coins The list of CoinAsset objects to select from. * @param amount The amount to select CoinAsset objects with a balance greater than or equal to. * @param exclude A list of CoinAsset objects to exclude from the selection. * @returns The CoinAsset objects that have a balance greater than or equal to the given amount. */ static selectCoinObjectIdGreaterThanOrEqual(coins, amount, exclude = []) { const selectedResult = CoinUtils.selectCoinAssetGreaterThanOrEqual(coins, amount, exclude); const objectArray = selectedResult.selectedCoins.map((item) => item.coinObjectId); const remainCoins = selectedResult.remainingCoins; const amountArray = selectedResult.selectedCoins.map((item) => item.balance.toString()); return { objectArray, remainCoins, amountArray }; } /** * Select the CoinAsset objects from a list of CoinAsset objects that have a balance greater than or equal to a given amount. * * @param coins The list of CoinAsset objects to select from. * @param amount The amount to select CoinAsset objects with a balance greater than or equal to. * @param exclude A list of CoinAsset objects to exclude from the selection. * @returns The CoinAsset objects that have a balance greater than or equal to the given amount. */ static selectCoinAssetGreaterThanOrEqual(coins, amount, exclude = []) { const sortedCoins = CoinUtils.sortByBalance(coins.filter((c) => !exclude.includes(c.coinObjectId))); const total = CoinUtils.calculateTotalBalance(sortedCoins); if (total < amount) { return { selectedCoins: [], remainingCoins: sortedCoins }; } if (total === amount) { return { selectedCoins: sortedCoins, remainingCoins: [] }; } let sum = BigInt(0); const selectedCoins = []; const remainingCoins = [...sortedCoins]; while (sum < total) { const target = amount - sum; const coinWithSmallestSufficientBalanceIndex = remainingCoins.findIndex((c) => c.balance >= target); if (coinWithSmallestSufficientBalanceIndex !== -1) { selectedCoins.push(remainingCoins[coinWithSmallestSufficientBalanceIndex]); remainingCoins.splice(coinWithSmallestSufficientBalanceIndex, 1); break; } const coinWithLargestBalance = remainingCoins.pop(); if (coinWithLargestBalance.balance > 0) { selectedCoins.push(coinWithLargestBalance); sum += coinWithLargestBalance.balance; } } return { selectedCoins: CoinUtils.sortByBalance(selectedCoins), remainingCoins: CoinUtils.sortByBalance(remainingCoins), }; } /** * Sort the CoinAsset objects by their balance. * * @param coins The CoinAsset objects to sort. * @returns The sorted CoinAsset objects. */ static sortByBalance(coins) { return coins.sort((a, b) => a.balance < b.balance ? -1 : a.balance > b.balance ? 1 : 0); } static sortByBalanceDes(coins) { return coins.sort((a, b) => a.balance > b.balance ? -1 : a.balance < b.balance ? 0 : 1); } /** * Calculate the total balance of a list of CoinAsset objects. * * @param coins The list of CoinAsset objects to calculate the total balance for. * @returns The total balance of the CoinAsset objects. */ static calculateTotalBalance(coins) { return coins.reduce((partialSum, c) => partialSum + c.balance, BigInt(0)); } } exports.CoinUtils = CoinUtils;