stxcity-sdk
Version:
SDK for interacting with Stxcity
141 lines • 7.14 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.sellBondingTokenHandler = void 0;
const axios_1 = __importDefault(require("axios"));
const connect_1 = require("@stacks/connect");
const transactions_1 = require("@stacks/transactions");
const hiroAPIHelpers_1 = __importDefault(require("../lib/hiroAPIHelpers"));
const config_1 = require("../config");
const constants_1 = require("../lib/constants");
const checkValidBondingTokenHandler_1 = require("./checkValidBondingTokenHandler");
const sellBondingTokenHandler = (params, context) => __awaiter(void 0, void 0, void 0, function* () {
try {
// Validate input parameters
const requiredFields = ['tokenAmount', 'dexContractId', 'senderAddress', 'tokenContractId', 'tokenSymbol', 'slippage'];
validateInputAndThrow(params, requiredFields);
// check valid token
try {
const isValidtoken = yield (0, checkValidBondingTokenHandler_1.checkValidBondingTokenHandler)(params.dexContractId, params.tokenContractId);
if (!isValidtoken)
throw new Error(config_1.MALICIOUS_TOKEN_MESSAGE);
}
catch (error) {
throw new Error(config_1.MALICIOUS_TOKEN_MESSAGE);
}
// Ensure tokenAmount is a positive number
if (params.tokenAmount <= 0) {
throw new Error("Token amount must be a positive number.");
}
const tokenAmountAfterDecimals = BigInt(Math.floor(params.tokenAmount * Math.pow(10, 6)));
if (tokenAmountAfterDecimals <= 0) {
throw new Error("Invalid token amount provided.");
}
const tokenAmountAfterDecimalsCV = (0, transactions_1.uintCV)(tokenAmountAfterDecimals);
const tokenAmountAfterDecimalsHex = (0, transactions_1.cvToHex)(tokenAmountAfterDecimalsCV);
const dexDeployer = params.dexContractId.split(".")[0];
const dexContractName = params.dexContractId.split(".")[1];
const response = yield getSellableToken(dexDeployer, dexContractName, params.senderAddress, tokenAmountAfterDecimalsHex);
// Check if the response is successful and data is available
if (!response || !response.data || !response.data.result) {
throw new Error("Failed to fetch sellable token information.");
}
const sellableInfoCV = (0, transactions_1.hexToCV)(response.data.result);
const sellableInfoData = (0, transactions_1.cvToJSON)(sellableInfoCV);
const sellableInfoObj = sellableInfoData.value.value;
const stxReceivableVal = parseInt(sellableInfoObj["receivable-stx"].value);
// Ensure stxReceivableVal is a positive number
if (stxReceivableVal <= 0) {
throw new Error("STX receivable value must be a positive number.");
}
const stxReceivable = Number(stxReceivableVal -
Math.floor((stxReceivableVal * params.slippage) / 100));
// Ensure stxReceivable is a positive number after applying slippage
if (stxReceivable <= 0) {
throw new Error("STX receivable value after slippage must be a positive number.");
}
// dex will send stx to users
const stxAmtWithSlip = Math.floor((stxReceivable * 96) / 100);
const sendSTXPostCondition = transactions_1.Pc.principal(params.dexContractId)
.willSendGte(stxAmtWithSlip)
.ustx();
const contractNameForPC = validateAndUseString(params.tokenContractId);
const sendFTCondition = transactions_1.Pc.principal(params.senderAddress)
.willSendEq(BigInt(tokenAmountAfterDecimals))
.ft(contractNameForPC, params.tokenSymbol);
const handleOnFinish = (data) => {
if (data) {
if (params.onFinish) {
const modifiedData = Object.assign(Object.assign({}, data), { status: "Sell token successfully" });
params.onFinish(modifiedData);
}
}
};
const handleOnCancel = () => {
if (params.onCancel) {
params.onCancel();
}
};
yield (0, connect_1.openContractCall)({
postConditionMode: transactions_1.PostConditionMode.Deny,
postConditions: [sendSTXPostCondition, sendFTCondition],
contractAddress: dexDeployer,
anchorMode: transactions_1.AnchorMode.OnChainOnly,
appDetails: constants_1.appDetails,
contractName: dexContractName,
functionName: "sell",
functionArgs: [
(0, transactions_1.principalCV)(params.tokenContractId), // token-x-trait
(0, transactions_1.uintCV)(tokenAmountAfterDecimals), // x value
],
network: context.network,
onFinish: handleOnFinish,
onCancel: handleOnCancel,
});
}
catch (error) {
throw error;
}
});
exports.sellBondingTokenHandler = sellBondingTokenHandler;
const getSellableToken = (dexDeployer, dexContractName, senderAdress, tokenAmountAfterDecimalsHex) => __awaiter(void 0, void 0, void 0, function* () {
const apiURL = `${config_1.configs.STACKS_NETWORK_API_HOST}/v2/contracts/call-read/${dexDeployer}/${dexContractName}/get-sellable-stx`;
const requestData = {
sender: senderAdress,
arguments: [tokenAmountAfterDecimalsHex],
};
return axios_1.default.post(apiURL, requestData, {
headers: (0, hiroAPIHelpers_1.default)(),
});
});
const validateAndUseString = (inputString) => {
const parts = inputString.split(".");
return inputString;
};
const validateInputAndThrow = (inputData, requiredFields) => {
requiredFields.forEach(field => {
if (!inputData.hasOwnProperty(field)) {
throw new Error(`Missing required field: ${field}`);
}
});
Object.keys(inputData).forEach((key) => {
if (inputData[key] === null || inputData[key] === undefined || inputData[key] === "") {
throw new Error(`Field "${key}" cannot be null, undefined or empty`);
}
});
if (inputData.slippage < 0 || inputData.slippage > 100) {
throw new Error("Slippage must be a number between 0 and 100.");
}
};
//# sourceMappingURL=sellBondingTokenHandler.js.map