blub-sdk
Version:
A modular SDK for interacting with the BLUB ecosystem on the Sui blockchain.
195 lines (194 loc) • 8.34 kB
JavaScript
;
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;