ecash-quicksend
Version:
A unified transaction manager for eCash (XEC), SLP, and ALP token transactions
163 lines • 7 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createRawSlpTransaction = createRawSlpTransaction;
exports.createRawAlpTransaction = createRawAlpTransaction;
const dotenv_1 = __importDefault(require("dotenv"));
dotenv_1.default.config();
const ecashLib = __importStar(require("ecash-lib"));
const utxo_utils_1 = require("../utxo/utxo-utils");
const wallet_utils_1 = require("../wallet/wallet-utils");
const transaction_utils_1 = require("../transaction/transaction-utils");
const transaction_builder_1 = require("../transaction/transaction-builder");
const { Script, SLP_FUNGIBLE, slpSend, ALP_STANDARD, alpSend, OP_RETURN, pushBytesOp, OP_RESERVED, } = ecashLib;
/**
* 构建SLP交易输出
*/
function buildSlpOutputs(tokenId, finalSendAmounts, recipients, tokenChange, dustLimit, walletP2pkh) {
const outputs = [];
// OP_RETURN 输出
outputs.push({ sats: 0n, script: slpSend(tokenId, SLP_FUNGIBLE, finalSendAmounts) });
// 接收方输出
recipients.forEach(recipient => {
outputs.push({
sats: BigInt(dustLimit),
script: (0, transaction_utils_1.createP2pkhScript)(recipient.address)
});
});
// Token 找零输出
if (tokenChange > 0n) {
outputs.push({ sats: BigInt(dustLimit), script: walletP2pkh });
}
// 手续费找零脚本 - 保持原始逻辑!直接push脚本
outputs.push(walletP2pkh);
return outputs;
}
/**
* 构建ALP交易输出
*/
function buildAlpOutputs(tokenId, finalSendAmounts, recipients, tokenChange, dustLimit, walletP2pkh) {
const outputs = [];
// 构造完整的 OP_RETURN 脚本
const opReturnPayload = alpSend(tokenId, ALP_STANDARD, finalSendAmounts);
const opReturnScript = Script.fromOps([
OP_RETURN,
OP_RESERVED,
pushBytesOp(opReturnPayload)
]);
// OP_RETURN 输出
outputs.push({ sats: 0n, script: opReturnScript });
// 接收方输出
recipients.forEach(recipient => {
outputs.push({
sats: BigInt(dustLimit),
script: (0, transaction_utils_1.createP2pkhScript)(recipient.address)
});
});
// Token 找零输出
if (tokenChange > 0n) {
outputs.push({ sats: BigInt(dustLimit), script: walletP2pkh });
}
// 手续费找零脚本 - 保持原始逻辑!直接push脚本
outputs.push(walletP2pkh);
return outputs;
}
/**
* 创建代币交易的通用函数
*/
async function createTokenTransaction(recipients, options, tokenType = 'SLP') {
try {
// 验证必需参数
(0, transaction_builder_1.validateRequiredParams)(options, [
{ key: 'tokenId', message: 'tokenId is required' },
{ key: 'tokenDecimals', message: 'tokenDecimals is required', checkUndefined: true }
]);
const { tokenId, tokenDecimals, addressIndex = 0, feeStrategy = 'all', tokenStrategy = 'all', mnemonic, // 从选项中提取助记词
chronik: chronikClient // 新增:从选项中提取chronik客户端
} = options;
// 初始化钱包 - 使用指定的地址索引和可选的助记词
const { walletSk, walletPk, walletP2pkh, address: utxoAddress } = (0, wallet_utils_1.initializeWallet)(addressIndex, mnemonic);
const utxos = await (0, utxo_utils_1.getUtxos)(utxoAddress, chronikClient); // 传递chronik客户端
if (utxos.length === 0) {
throw new Error(`No UTXOs found for address index ${addressIndex}`);
}
// 选择代币UTXOs
const tokenSelection = (0, utxo_utils_1.selectSlpUtxos)(utxos, tokenId, recipients, tokenDecimals, {
feeStrategy: feeStrategy,
tokenStrategy: tokenStrategy
});
const { selectedTokenUtxos, selectedFeeUtxos, finalSendAmounts, tokenChange, dustLimit, summary } = tokenSelection;
// 记录交易摘要
(0, transaction_builder_1.logTransactionSummary)(tokenType, {
地址索引: addressIndex,
代币UTXOs数量: selectedTokenUtxos.length,
手续费UTXOs数量: selectedFeeUtxos.length,
接收方数量: recipients.length,
代币找零: tokenChange > 0n ? tokenChange.toString() : '无',
总输出数量: summary.totalOutputs
});
// 构建交易输入和输出
const inputs = (0, transaction_utils_1.buildTransactionInputs)([selectedTokenUtxos, selectedFeeUtxos], walletP2pkh, walletSk, walletPk);
let outputs;
if (tokenType === 'ALP') {
outputs = buildAlpOutputs(tokenId, finalSendAmounts, recipients, tokenChange, dustLimit, walletP2pkh);
}
else {
outputs = buildSlpOutputs(tokenId, finalSendAmounts, recipients, tokenChange, dustLimit, walletP2pkh);
}
// 构建并广播交易
return await (0, transaction_builder_1.buildAndBroadcastTransaction)(inputs, outputs, { dustLimit, chronik: chronikClient }); // 传递chronik客户端
}
catch (error) {
console.error(`${tokenType} transaction creation failed:`, error);
throw error;
}
}
/**
* 创建SLP代币交易
*/
async function createRawSlpTransaction(recipients, options) {
return createTokenTransaction(recipients, options, 'SLP');
}
/**
* 创建ALP代币交易
*/
async function createRawAlpTransaction(recipients, options) {
return createTokenTransaction(recipients, options, 'ALP');
}
//# sourceMappingURL=tokensend.js.map