hadeswap-sdk
Version:
HadeSwap SDK for interacting with protocol
234 lines (233 loc) • 12.3 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());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTradeTransactionsFromSignatures = exports.getTradeActivitiesBySignatures = exports.getTradeActivities = void 0;
const types_1 = require("../types");
const lodash_1 = require("lodash");
const getTradeActivities = ({ programId, fromThisSignature, untilThisSignature, limit, connection, }) => __awaiter(void 0, void 0, void 0, function* () {
const LIMIT = 100;
let allSignaturesInfos = [];
const currentLastSignatureInfo = (yield connection.getConfirmedSignaturesForAddress2(programId, {
limit: 1,
}, 'confirmed'))[0];
let currentLastSignature = currentLastSignatureInfo.signature;
let newSignatureInfosLatestToPast = yield connection.getConfirmedSignaturesForAddress2(programId, {
limit: LIMIT,
before: fromThisSignature || currentLastSignature,
until: untilThisSignature,
}, 'confirmed');
if (newSignatureInfosLatestToPast.length > 0)
currentLastSignature = newSignatureInfosLatestToPast[newSignatureInfosLatestToPast.length - 1].signature;
allSignaturesInfos = [...allSignaturesInfos, ...newSignatureInfosLatestToPast, currentLastSignatureInfo].filter((signatureInfo) => !signatureInfo.err);
while (newSignatureInfosLatestToPast.length === LIMIT) {
newSignatureInfosLatestToPast = yield connection.getConfirmedSignaturesForAddress2(programId, {
limit: LIMIT,
before: currentLastSignature,
until: untilThisSignature,
}, 'confirmed');
currentLastSignature = newSignatureInfosLatestToPast.filter((signatureInfo) => signatureInfo)[newSignatureInfosLatestToPast.length - 1].signature;
allSignaturesInfos = [...allSignaturesInfos, ...newSignatureInfosLatestToPast].filter((signatureInfo) => !signatureInfo.err);
if (limit !== undefined && allSignaturesInfos.length >= limit) {
break;
}
}
// allSignaturesInfos = allSignaturesInfos.filter((signatureInfo) => !signatureInfo.err);
const tradeTransactions = yield (0, exports.getTradeTransactionsFromSignatures)({
signatures: allSignaturesInfos
.filter((signatureInfo) => signatureInfo)
.map((signatureInfo) => signatureInfo.signature),
connection,
});
let allTradeActivities = [];
for (let tradeTxn of tradeTransactions) {
const tradeActivities = yield parseTransactionInfoToTradeActivities({ tradeTxn, connection, programId });
allTradeActivities = [...allTradeActivities, ...tradeActivities];
}
return allTradeActivities;
});
exports.getTradeActivities = getTradeActivities;
const getTradeActivitiesBySignatures = ({ signatures, connection, programId, }) => __awaiter(void 0, void 0, void 0, function* () {
const tradeTransactions = yield (0, exports.getTradeTransactionsFromSignatures)({
signatures,
connection,
});
let allTradeActivities = [];
for (let tradeTxn of tradeTransactions) {
const tradeActivities = yield parseTransactionInfoToTradeActivities({ tradeTxn, connection, programId });
allTradeActivities = [...allTradeActivities, ...tradeActivities];
}
return allTradeActivities;
});
exports.getTradeActivitiesBySignatures = getTradeActivitiesBySignatures;
const getTradeTransactionsFromSignatures = ({ signatures, connection, }) => __awaiter(void 0, void 0, void 0, function* () {
const tradeTransactions = [];
let count = 0;
for (let signature of signatures) {
try {
const currentTransactionInfo = yield connection.getParsedTransaction(signature, {
commitment: 'confirmed',
maxSupportedTransactionVersion: 0,
});
if (!currentTransactionInfo ||
!currentTransactionInfo.meta ||
currentTransactionInfo.meta.err !== null ||
!isTradeTransactionInfo(currentTransactionInfo)) {
continue;
}
tradeTransactions.push(currentTransactionInfo);
}
catch (err) {
console.log(err);
}
}
return tradeTransactions;
});
exports.getTradeTransactionsFromSignatures = getTradeTransactionsFromSignatures;
const isTradeTransactionInfo = (currentTransactionInfo) => {
var _a, _b;
return ((_b = (_a = currentTransactionInfo.meta) === null || _a === void 0 ? void 0 : _a.logMessages) === null || _b === void 0 ? void 0 : _b.find(isTradeInstructionLog)) !== undefined;
};
const parseTransactionInfoToTradeActivities = ({ tradeTxn, connection, programId, }) => __awaiter(void 0, void 0, void 0, function* () {
var _a, _b, _c;
const tradeLogs = (_b = (_a = tradeTxn.meta) === null || _a === void 0 ? void 0 : _a.logMessages) === null || _b === void 0 ? void 0 : _b.reduce((tradeLogs, log) => (isTradeInstructionLog(log) ? [...tradeLogs, log] : tradeLogs), []);
const innerInstructions = (_c = tradeTxn.meta) === null || _c === void 0 ? void 0 : _c.innerInstructions;
const programInstructions = tradeTxn.transaction.message.instructions.filter((ix) => ix.programId.toBase58() !== 'ComputeBudget111111111111111111111111111111' &&
ix.programId.toBase58() === programId.toBase58());
const tradeActivities = [];
for (let i = 0; i < innerInstructions.length; i++) {
const currentInnerInstruction = innerInstructions[i];
const currentProgramInstruction = programInstructions[i];
const currentLog = tradeLogs[i];
if (!currentProgramInstruction) {
continue;
}
const currentSignature = tradeTxn.transaction.signatures[0];
const blockTime = tradeTxn.blockTime;
if (!TRADE_TRANSACTION_PARSERS[currentLog])
continue;
const parsedTradeActivity = yield TRADE_TRANSACTION_PARSERS[currentLog]({
innerInstruction: currentInnerInstruction,
programInstruction: currentProgramInstruction,
signature: currentSignature,
blockTime,
connection,
});
if (!parsedTradeActivity)
continue;
tradeActivities.push(parsedTradeActivity);
}
return tradeActivities;
});
const isTradeInstructionLog = (log) => log === TradeInstruction.BuyNftFromPair ||
log === TradeInstruction.SellNftToTokenToNftPair ||
log === TradeInstruction.SellNftToLiquidityPair;
var TradeInstruction;
(function (TradeInstruction) {
TradeInstruction["BuyNftFromPair"] = "Program log: Instruction: BuyNftFromPair";
TradeInstruction["SellNftToTokenToNftPair"] = "Program log: Instruction: SellNftToTokenToNftPair";
TradeInstruction["SellNftToLiquidityPair"] = "Program log: Instruction: SellNftToLiquidityPair";
})(TradeInstruction || (TradeInstruction = {}));
const TRADE_TRANSACTION_PARSERS = {
[TradeInstruction.BuyNftFromPair]: ({ innerInstruction, programInstruction, signature, blockTime, connection, }) => __awaiter(void 0, void 0, void 0, function* () {
const { solAmount, feeAmount } = getTransferSolAndFeeAmountFromInnerInstructions(innerInstruction);
const orderType = types_1.OrderType.Buy;
const pair = programInstruction.accounts[1];
const userTaker = programInstruction.accounts[2];
const userMaker = programInstruction.accounts[9];
const nftMint = programInstruction.accounts[6];
return {
timestamp: blockTime,
signature: signature,
pair: pair ? pair.toBase58() : '',
orderType: orderType,
pairType: null,
nftMint: nftMint ? nftMint.toBase58() : '',
solAmount: solAmount,
userMaker: userMaker ? userMaker.toBase58() : '',
userTaker: userTaker ? userTaker.toBase58() : '',
poolFee: feeAmount,
};
}),
[TradeInstruction.SellNftToTokenToNftPair]: ({ innerInstruction, programInstruction, signature, blockTime, connection, }) => __awaiter(void 0, void 0, void 0, function* () {
const { solAmount, feeAmount } = getTransferSolAndFeeAmountFromInnerInstructions(innerInstruction);
const orderType = types_1.OrderType.Sell;
const pair = programInstruction.accounts[0];
const userTaker = programInstruction.accounts[2];
const userMaker = programInstruction.accounts[7];
const nftMint = programInstruction.accounts[3];
return {
timestamp: blockTime,
signature: signature,
pair: pair ? pair.toBase58() : '',
orderType: orderType,
pairType: types_1.PairType.TokenForNFT,
nftMint: nftMint ? nftMint.toBase58() : '',
solAmount: solAmount,
poolFee: feeAmount,
userMaker: userMaker ? userMaker.toBase58() : '',
userTaker: userTaker ? userTaker.toBase58() : '',
};
}),
[TradeInstruction.SellNftToLiquidityPair]: ({ innerInstruction, programInstruction, signature, blockTime, connection, }) => __awaiter(void 0, void 0, void 0, function* () {
// try {
const { solAmount, feeAmount } = getTransferSolAndFeeAmountFromInnerInstructions(innerInstruction);
const orderType = types_1.OrderType.Sell;
const pair = programInstruction.accounts[1];
const userTaker = programInstruction.accounts[3];
// const userMaker = programInstruction.accounts[7];
const nftMint = programInstruction.accounts[4];
return {
timestamp: blockTime,
signature: signature,
pair: pair ? pair.toBase58() : '',
orderType: orderType,
pairType: types_1.PairType.LiquidityProvision,
nftMint: nftMint ? nftMint.toBase58() : '',
solAmount: solAmount,
poolFee: feeAmount,
userMaker: null,
userTaker: userTaker ? userTaker.toBase58() : '',
};
// } catch(err) }
}),
};
const getTransferAmountFromInnerInstructions = (innerInstruction) => {
return innerInstruction.instructions
.filter((instruction) => instruction.program === InnerProgramTypes.System)
.filter((instruction) => instruction.parsed)
.filter((instruction) => instruction.parsed.type === InnerInstructionTypes.Transfer)
.reduce((amount, instruction) => {
return amount + instruction.parsed.info.lamports;
}, 0);
};
const getTransferSolAndFeeAmountFromInnerInstructions = (innerInstruction) => {
const transfers = innerInstruction.instructions
.filter((instruction) => instruction.program === InnerProgramTypes.System)
.filter((instruction) => instruction.parsed)
.filter((instruction) => instruction.parsed.type === InnerInstructionTypes.Transfer)
.filter((instruction) => instruction.parsed.info.lamports > 0);
const solAmount = transfers.reduce((amount, instruction) => {
return amount + instruction.parsed.info.lamports;
}, 0);
const feeAmount = transfers.length === 1 || !(0, lodash_1.minBy)(transfers, (transfer) => transfer.parsed.info.lamports)
? 0
: (0, lodash_1.minBy)(transfers, (transfer) => transfer.parsed.info.lamports).parsed.info.lamports;
return { solAmount, feeAmount };
};
var InnerProgramTypes;
(function (InnerProgramTypes) {
InnerProgramTypes["System"] = "system";
InnerProgramTypes["SplToken"] = "spl-token";
})(InnerProgramTypes || (InnerProgramTypes = {}));
var InnerInstructionTypes;
(function (InnerInstructionTypes) {
InnerInstructionTypes["Transfer"] = "transfer";
})(InnerInstructionTypes || (InnerInstructionTypes = {}));