ecash-quicksend 1.0.8 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/constants.js +3 -3
- package/dist/config/constants.js.map +1 -1
- package/dist/send/tokensend.d.ts.map +1 -1
- package/dist/send/tokensend.js +12 -41
- package/dist/send/tokensend.js.map +1 -1
- package/dist/send/xecsend.d.ts.map +1 -1
- package/dist/send/xecsend.js +2 -12
- package/dist/send/xecsend.js.map +1 -1
- package/dist/transaction/transaction-builder.d.ts +9 -5
- package/dist/transaction/transaction-builder.d.ts.map +1 -1
- package/dist/transaction/transaction-builder.js +37 -43
- package/dist/transaction/transaction-builder.js.map +1 -1
- package/dist/utxo/utxo-utils.d.ts.map +1 -1
- package/dist/utxo/utxo-utils.js +25 -13
- package/dist/utxo/utxo-utils.js.map +1 -1
- package/dist/wallet/mnemonic-utils.d.ts.map +1 -1
- package/dist/wallet/mnemonic-utils.js +0 -2
- package/dist/wallet/mnemonic-utils.js.map +1 -1
- package/dist/wallet/wallet-utils.d.ts.map +1 -1
- package/dist/wallet/wallet-utils.js +1 -2
- package/dist/wallet/wallet-utils.js.map +1 -1
- package/package.json +1 -1
package/dist/config/constants.js
CHANGED
|
@@ -23,7 +23,7 @@ exports.CONFIG = {
|
|
|
23
23
|
*/
|
|
24
24
|
function validateConfig() {
|
|
25
25
|
if (!exports.CONFIG.MNEMONIC) {
|
|
26
|
-
throw new Error('
|
|
26
|
+
throw new Error('MNEMONIC environment variable must be set');
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
// 注释掉自动验证,因为用户现在可以在代码中提供助记词
|
|
@@ -43,7 +43,7 @@ function getMnemonic() {
|
|
|
43
43
|
function getPrivateKeyWIF(addressIndex = 0, mnemonic) {
|
|
44
44
|
const finalMnemonic = mnemonic || getMnemonic();
|
|
45
45
|
if (!finalMnemonic) {
|
|
46
|
-
throw new Error('
|
|
46
|
+
throw new Error('Mnemonic not set: please set the MNEMONIC environment variable or provide it as a parameter');
|
|
47
47
|
}
|
|
48
48
|
const derived = (0, mnemonic_utils_1.deriveBuyerKey)(finalMnemonic, addressIndex);
|
|
49
49
|
return derived.wif;
|
|
@@ -56,7 +56,7 @@ function getPrivateKeyWIF(addressIndex = 0, mnemonic) {
|
|
|
56
56
|
function getDefaultUtxoAddress(addressIndex = 0, mnemonic) {
|
|
57
57
|
const finalMnemonic = mnemonic || getMnemonic();
|
|
58
58
|
if (!finalMnemonic) {
|
|
59
|
-
throw new Error('
|
|
59
|
+
throw new Error('Mnemonic not set: please set the MNEMONIC environment variable or provide it as a parameter');
|
|
60
60
|
}
|
|
61
61
|
const derived = (0, mnemonic_utils_1.deriveBuyerKey)(finalMnemonic, addressIndex);
|
|
62
62
|
return derived.address;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../config/constants.ts"],"names":[],"mappings":";;;;;;AAeA,wCAIC;AASD,kCAEC;AAOD,4CAOC;AAOD,sDAOC;AA1DD,oDAA4B;AAC5B,6DAA0D;AAC1D,gBAAM,CAAC,MAAM,EAAE,CAAC;AAEhB;;GAEG;AACU,QAAA,MAAM,GAAG;IACpB,gBAAgB;IAChB,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ;CAC/B,CAAC;AAEF;;GAEG;AACH,SAAgB,cAAc;IAC5B,IAAI,CAAC,cAAM,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../config/constants.ts"],"names":[],"mappings":";;;;;;AAeA,wCAIC;AASD,kCAEC;AAOD,4CAOC;AAOD,sDAOC;AA1DD,oDAA4B;AAC5B,6DAA0D;AAC1D,gBAAM,CAAC,MAAM,EAAE,CAAC;AAEhB;;GAEG;AACU,QAAA,MAAM,GAAG;IACpB,gBAAgB;IAChB,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ;CAC/B,CAAC;AAEF;;GAEG;AACH,SAAgB,cAAc;IAC5B,IAAI,CAAC,cAAM,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC;AAED,4BAA4B;AAC5B,oBAAoB;AAEpB;;;GAGG;AACH,SAAgB,WAAW;IACzB,OAAO,cAAM,CAAC,QAAQ,IAAI,IAAI,CAAC;AACjC,CAAC;AAED;;;;GAIG;AACH,SAAgB,gBAAgB,CAAC,eAAuB,CAAC,EAAE,QAAiB;IAC1E,MAAM,aAAa,GAAG,QAAQ,IAAI,WAAW,EAAE,CAAC;IAChD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,6FAA6F,CAAC,CAAC;IACjH,CAAC;IACD,MAAM,OAAO,GAAG,IAAA,+BAAc,EAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IAC5D,OAAO,OAAO,CAAC,GAAG,CAAC;AACrB,CAAC;AAED;;;;GAIG;AACH,SAAgB,qBAAqB,CAAC,eAAuB,CAAC,EAAE,QAAiB;IAC/E,MAAM,aAAa,GAAG,QAAQ,IAAI,WAAW,EAAE,CAAC;IAChD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,6FAA6F,CAAC,CAAC;IACjH,CAAC;IACD,MAAM,OAAO,GAAG,IAAA,+BAAc,EAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IAC5D,OAAO,OAAO,CAAC,OAAO,CAAC;AACzB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokensend.d.ts","sourceRoot":"","sources":["../../send/tokensend.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,SAAS,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"tokensend.d.ts","sourceRoot":"","sources":["../../send/tokensend.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,SAAS,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAmJjF;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAEnI;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAEnI"}
|
package/dist/send/tokensend.js
CHANGED
|
@@ -47,55 +47,33 @@ const transaction_utils_1 = require("../transaction/transaction-utils");
|
|
|
47
47
|
const transaction_builder_1 = require("../transaction/transaction-builder");
|
|
48
48
|
const { Script, SLP_FUNGIBLE, slpSend, ALP_STANDARD, alpSend, OP_RETURN, pushBytesOp, OP_RESERVED, } = ecashLib;
|
|
49
49
|
/**
|
|
50
|
-
*
|
|
50
|
+
* 构建代币交易输出(SLP/ALP 共用)
|
|
51
51
|
*/
|
|
52
|
-
function
|
|
52
|
+
function buildTokenOutputs(opReturnScript, recipients, tokenChange, dustLimit, walletP2pkh) {
|
|
53
53
|
const outputs = [];
|
|
54
|
-
|
|
55
|
-
outputs.push({ sats: 0n, script: slpSend(tokenId, SLP_FUNGIBLE, finalSendAmounts) });
|
|
56
|
-
// 接收方输出
|
|
54
|
+
outputs.push({ sats: 0n, script: opReturnScript });
|
|
57
55
|
recipients.forEach(recipient => {
|
|
58
56
|
outputs.push({
|
|
59
57
|
sats: BigInt(dustLimit),
|
|
60
|
-
script: (0, transaction_utils_1.createP2pkhScript)(recipient.address)
|
|
58
|
+
script: (0, transaction_utils_1.createP2pkhScript)(recipient.address),
|
|
61
59
|
});
|
|
62
60
|
});
|
|
63
|
-
// Token 找零输出
|
|
64
61
|
if (tokenChange > 0n) {
|
|
65
62
|
outputs.push({ sats: BigInt(dustLimit), script: walletP2pkh });
|
|
66
63
|
}
|
|
67
|
-
// 手续费找零脚本 - 保持原始逻辑!直接push脚本
|
|
68
64
|
outputs.push(walletP2pkh);
|
|
69
65
|
return outputs;
|
|
70
66
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
67
|
+
function buildSlpOutputs(tokenId, finalSendAmounts, recipients, tokenChange, dustLimit, walletP2pkh) {
|
|
68
|
+
return buildTokenOutputs(slpSend(tokenId, SLP_FUNGIBLE, finalSendAmounts), recipients, tokenChange, dustLimit, walletP2pkh);
|
|
69
|
+
}
|
|
74
70
|
function buildAlpOutputs(tokenId, finalSendAmounts, recipients, tokenChange, dustLimit, walletP2pkh) {
|
|
75
|
-
const outputs = [];
|
|
76
|
-
// 构造完整的 OP_RETURN 脚本
|
|
77
|
-
const opReturnPayload = alpSend(tokenId, ALP_STANDARD, finalSendAmounts);
|
|
78
71
|
const opReturnScript = Script.fromOps([
|
|
79
72
|
OP_RETURN,
|
|
80
73
|
OP_RESERVED,
|
|
81
|
-
pushBytesOp(
|
|
74
|
+
pushBytesOp(alpSend(tokenId, ALP_STANDARD, finalSendAmounts)),
|
|
82
75
|
]);
|
|
83
|
-
|
|
84
|
-
outputs.push({ sats: 0n, script: opReturnScript });
|
|
85
|
-
// 接收方输出
|
|
86
|
-
recipients.forEach(recipient => {
|
|
87
|
-
outputs.push({
|
|
88
|
-
sats: BigInt(dustLimit),
|
|
89
|
-
script: (0, transaction_utils_1.createP2pkhScript)(recipient.address)
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
// Token 找零输出
|
|
93
|
-
if (tokenChange > 0n) {
|
|
94
|
-
outputs.push({ sats: BigInt(dustLimit), script: walletP2pkh });
|
|
95
|
-
}
|
|
96
|
-
// 手续费找零脚本 - 保持原始逻辑!直接push脚本
|
|
97
|
-
outputs.push(walletP2pkh);
|
|
98
|
-
return outputs;
|
|
76
|
+
return buildTokenOutputs(opReturnScript, recipients, tokenChange, dustLimit, walletP2pkh);
|
|
99
77
|
}
|
|
100
78
|
/**
|
|
101
79
|
* 创建代币交易的通用函数
|
|
@@ -122,15 +100,6 @@ async function createTokenTransaction(recipients, options, tokenType = 'SLP') {
|
|
|
122
100
|
tokenStrategy: tokenStrategy
|
|
123
101
|
});
|
|
124
102
|
const { selectedTokenUtxos, selectedFeeUtxos, finalSendAmounts, tokenChange, dustLimit, summary } = tokenSelection;
|
|
125
|
-
// 记录交易摘要
|
|
126
|
-
(0, transaction_builder_1.logTransactionSummary)(tokenType, {
|
|
127
|
-
地址索引: addressIndex,
|
|
128
|
-
代币UTXOs数量: selectedTokenUtxos.length,
|
|
129
|
-
手续费UTXOs数量: selectedFeeUtxos.length,
|
|
130
|
-
接收方数量: recipients.length,
|
|
131
|
-
代币找零: tokenChange > 0n ? tokenChange.toString() : '无',
|
|
132
|
-
总输出数量: summary.totalOutputs
|
|
133
|
-
});
|
|
134
103
|
// 构建交易输入和输出
|
|
135
104
|
const inputs = (0, transaction_utils_1.buildTransactionInputs)([selectedTokenUtxos, selectedFeeUtxos], walletP2pkh, walletSk, walletPk);
|
|
136
105
|
let outputs;
|
|
@@ -140,8 +109,10 @@ async function createTokenTransaction(recipients, options, tokenType = 'SLP') {
|
|
|
140
109
|
else {
|
|
141
110
|
outputs = buildSlpOutputs(tokenId, finalSendAmounts, recipients, tokenChange, dustLimit, walletP2pkh);
|
|
142
111
|
}
|
|
112
|
+
// 用 EccDummy 验证输入能覆盖输出 + 真实手续费(保守上界)
|
|
113
|
+
(0, transaction_builder_1.verifyFee)([...selectedTokenUtxos, ...selectedFeeUtxos], outputs);
|
|
143
114
|
// 构建并广播交易
|
|
144
|
-
return await (0, transaction_builder_1.buildAndBroadcastTransaction)(inputs, outputs, { dustLimit, chronik: chronikClient });
|
|
115
|
+
return await (0, transaction_builder_1.buildAndBroadcastTransaction)(inputs, outputs, { dustLimit, chronik: chronikClient });
|
|
145
116
|
}
|
|
146
117
|
catch (error) {
|
|
147
118
|
console.error(`${tokenType} transaction creation failed:`, error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokensend.js","sourceRoot":"","sources":["../../send/tokensend.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"tokensend.js","sourceRoot":"","sources":["../../send/tokensend.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xecsend.d.ts","sourceRoot":"","sources":["../../send/xecsend.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAG7C,UAAU,iBAAiB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAGD,UAAU,oBAAqB,SAAQ,iBAAiB;IACtD,aAAa,EAAE,GAAG,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,KAAK,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;CACJ;AAED,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,iBAAiB,EAAE,EAC/B,YAAY,GAAE,MAAc,EAC5B,YAAY,GAAE,MAAU,EACxB,QAAQ,CAAC,EAAE,MAAM,EAAE,WAAW;AAC9B,aAAa,CAAC,EAAE,GAAG,GAClB,OAAO,CAAC,oBAAoB,CAAC,
|
|
1
|
+
{"version":3,"file":"xecsend.d.ts","sourceRoot":"","sources":["../../send/xecsend.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAG7C,UAAU,iBAAiB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAGD,UAAU,oBAAqB,SAAQ,iBAAiB;IACtD,aAAa,EAAE,GAAG,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,KAAK,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;CACJ;AAED,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,iBAAiB,EAAE,EAC/B,YAAY,GAAE,MAAc,EAC5B,YAAY,GAAE,MAAU,EACxB,QAAQ,CAAC,EAAE,MAAM,EAAE,WAAW;AAC9B,aAAa,CAAC,EAAE,GAAG,GAClB,OAAO,CAAC,oBAAoB,CAAC,CAkG/B"}
|
package/dist/send/xecsend.js
CHANGED
|
@@ -49,18 +49,6 @@ chronikClient // 新增:可选的chronik客户端参数 (使用any类型以避
|
|
|
49
49
|
const utxoSelection = (0, utxo_utils_1.selectUtxos)(utxos, totalSendAmount, utxoStrategy);
|
|
50
50
|
const { selectedUtxos } = utxoSelection;
|
|
51
51
|
// 记录交易摘要
|
|
52
|
-
(0, transaction_builder_1.logTransactionSummary)('XEC', {
|
|
53
|
-
地址索引: addressIndex,
|
|
54
|
-
策略: utxoStrategy,
|
|
55
|
-
接收方数量: recipients.length,
|
|
56
|
-
XEC接收方: xecRecipients.length,
|
|
57
|
-
代币接收方: tokenRecipients.length,
|
|
58
|
-
总发送金额: totalSendAmount,
|
|
59
|
-
UTXOs数量: selectedUtxos.length,
|
|
60
|
-
总输入: utxoSelection.totalInputValue,
|
|
61
|
-
预估手续费: utxoSelection.estimatedFee,
|
|
62
|
-
预计找零: utxoSelection.changeAmount
|
|
63
|
-
});
|
|
64
52
|
// 构建交易输入
|
|
65
53
|
const inputs = (0, transaction_utils_1.buildTransactionInputs)(selectedUtxos, walletP2pkh, walletSk, walletPk);
|
|
66
54
|
// 构建交易输出 - 为每个接收方创建输出
|
|
@@ -82,6 +70,8 @@ chronikClient // 新增:可选的chronik客户端参数 (使用any类型以避
|
|
|
82
70
|
});
|
|
83
71
|
// 添加找零脚本 - 保持原始逻辑!
|
|
84
72
|
outputs.push(walletP2pkh);
|
|
73
|
+
// 用 EccDummy 验证输入能覆盖输出 + 真实手续费(保守上界)
|
|
74
|
+
(0, transaction_builder_1.verifyFee)(selectedUtxos, outputs);
|
|
85
75
|
// 构建并广播交易
|
|
86
76
|
const result = await (0, transaction_builder_1.buildAndBroadcastTransaction)(inputs, outputs, { chronik: chronikClient }); // 传递chronik客户端
|
|
87
77
|
return {
|
package/dist/send/xecsend.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xecsend.js","sourceRoot":"","sources":["../../send/xecsend.ts"],"names":[],"mappings":";;;;;AAgCA,
|
|
1
|
+
{"version":3,"file":"xecsend.js","sourceRoot":"","sources":["../../send/xecsend.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { ChronikClient } from "chronik-client";
|
|
2
|
+
import { TransactionResult } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* 用 EccDummy 验证 UTXOs 能否覆盖 outputs + 真实手续费。
|
|
5
|
+
* EccDummy 签名长度固定为最大值(73字节),结果是保守上界,永远不低估。
|
|
6
|
+
* 如果验证失败,在广播前提前抛出,避免浪费网络请求。
|
|
7
|
+
*/
|
|
8
|
+
export declare function verifyFee(utxos: Array<{
|
|
9
|
+
value: number;
|
|
10
|
+
}>, outputs: any[], feePerKb?: bigint, dustSats?: bigint): void;
|
|
2
11
|
interface TransactionOptions {
|
|
3
12
|
feePerKb?: bigint;
|
|
4
13
|
dustSats?: bigint;
|
|
5
14
|
dustLimit?: number;
|
|
6
15
|
chronik?: ChronikClient;
|
|
7
16
|
}
|
|
8
|
-
interface TransactionResult {
|
|
9
|
-
explorerLink: string;
|
|
10
|
-
broadcastResult: string;
|
|
11
|
-
txid: string;
|
|
12
|
-
}
|
|
13
17
|
interface RequiredParamConfig {
|
|
14
18
|
key: string;
|
|
15
19
|
message: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction-builder.d.ts","sourceRoot":"","sources":["../../transaction/transaction-builder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"transaction-builder.d.ts","sourceRoot":"","sources":["../../transaction/transaction-builder.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAQ7C;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAC/B,OAAO,EAAE,GAAG,EAAE,EACd,QAAQ,GAAE,MAAgC,EAC1C,QAAQ,GAAE,MAA0B,GACnC,IAAI,CAmBN;AAGD,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAGD,UAAU,mBAAmB;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,GAAG,EAAE,EACb,OAAO,EAAE,GAAG,EAAE,EACd,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC,CAuC5B;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,mBAAmB,EAAE,GAAG,IAAI,CAMzF;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,IAAI,CAEtE"}
|
|
@@ -1,44 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.verifyFee = verifyFee;
|
|
36
4
|
exports.buildAndBroadcastTransaction = buildAndBroadcastTransaction;
|
|
37
5
|
exports.validateRequiredParams = validateRequiredParams;
|
|
38
6
|
exports.logTransactionSummary = logTransactionSummary;
|
|
39
7
|
const chronik_client_1 = require("../client/chronik-client");
|
|
40
|
-
const
|
|
41
|
-
|
|
8
|
+
const ecash_lib_1 = require("ecash-lib");
|
|
9
|
+
// EccDummy 使用固定最大签名长度(73字节),保证费用估算永远不低于实际
|
|
10
|
+
const _eccDummy = new ecash_lib_1.EccDummy();
|
|
11
|
+
const _DUMMY_SK = (0, ecash_lib_1.fromHex)('1122334455667788990011223344556677889900112233445566778899001122');
|
|
12
|
+
const _DUMMY_PK = _eccDummy.derivePubkey(_DUMMY_SK);
|
|
13
|
+
const _DUMMY_P2PKH = ecash_lib_1.Script.p2pkh(new Uint8Array(20).fill(0x11));
|
|
14
|
+
/**
|
|
15
|
+
* 用 EccDummy 验证 UTXOs 能否覆盖 outputs + 真实手续费。
|
|
16
|
+
* EccDummy 签名长度固定为最大值(73字节),结果是保守上界,永远不低估。
|
|
17
|
+
* 如果验证失败,在广播前提前抛出,避免浪费网络请求。
|
|
18
|
+
*/
|
|
19
|
+
function verifyFee(utxos, outputs, feePerKb = ecash_lib_1.DEFAULT_FEE_SATS_PER_KB, dustSats = ecash_lib_1.DEFAULT_DUST_SATS) {
|
|
20
|
+
const dummyInputs = utxos.map((utxo, i) => ({
|
|
21
|
+
input: {
|
|
22
|
+
prevOut: { txid: '00'.repeat(32), outIdx: i },
|
|
23
|
+
signData: { sats: BigInt(utxo.value), outputScript: _DUMMY_P2PKH },
|
|
24
|
+
},
|
|
25
|
+
signatory: (0, ecash_lib_1.P2PKHSignatory)(_DUMMY_SK, _DUMMY_PK, ecash_lib_1.ALL_BIP143),
|
|
26
|
+
}));
|
|
27
|
+
try {
|
|
28
|
+
const txBuilder = new ecash_lib_1.TxBuilder({ inputs: dummyInputs, outputs });
|
|
29
|
+
txBuilder.sign({ ecc: _eccDummy, feePerKb, dustSats });
|
|
30
|
+
}
|
|
31
|
+
catch (e) {
|
|
32
|
+
throw new Error(`Insufficient balance to cover outputs and fee: ${e instanceof Error ? e.message : String(e)}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
42
35
|
/**
|
|
43
36
|
* 构建并广播交易的通用函数
|
|
44
37
|
* @param inputs - 交易输入数组
|
|
@@ -52,23 +45,24 @@ async function buildAndBroadcastTransaction(inputs, outputs, options = {}) {
|
|
|
52
45
|
const client = chronikClient || chronik_client_1.chronik; // 使用传入的chronik客户端或默认的
|
|
53
46
|
try {
|
|
54
47
|
// 构建交易
|
|
55
|
-
const txBuild = new TxBuilder({ inputs, outputs });
|
|
48
|
+
const txBuild = new ecash_lib_1.TxBuilder({ inputs, outputs });
|
|
56
49
|
// 签名交易
|
|
57
50
|
const tx = txBuild.sign({
|
|
58
51
|
feePerKb,
|
|
59
52
|
dustSats: typeof dustSats === 'bigint' ? dustSats : BigInt(dustLimit)
|
|
60
53
|
});
|
|
61
54
|
// 序列化交易
|
|
62
|
-
const rawTxHex = toHex(tx.ser());
|
|
55
|
+
const rawTxHex = (0, ecash_lib_1.toHex)(tx.ser());
|
|
63
56
|
// 广播交易
|
|
64
|
-
const
|
|
65
|
-
if (!
|
|
57
|
+
const { txids } = await client.broadcastTxs([rawTxHex]);
|
|
58
|
+
if (!txids || txids.length === 0) {
|
|
66
59
|
throw new Error("Empty Chronik broadcast response");
|
|
67
60
|
}
|
|
61
|
+
const txid = txids[0];
|
|
68
62
|
return {
|
|
69
|
-
explorerLink: `https://explorer.e.cash/tx/${
|
|
70
|
-
broadcastResult:
|
|
71
|
-
txid
|
|
63
|
+
explorerLink: `https://explorer.e.cash/tx/${txid}`,
|
|
64
|
+
broadcastResult: txid,
|
|
65
|
+
txid,
|
|
72
66
|
};
|
|
73
67
|
}
|
|
74
68
|
catch (error) {
|
|
@@ -94,6 +88,6 @@ function validateRequiredParams(params, required) {
|
|
|
94
88
|
* @param summary - 摘要信息
|
|
95
89
|
*/
|
|
96
90
|
function logTransactionSummary(type, summary) {
|
|
97
|
-
console.log(`${type}
|
|
91
|
+
console.log(`${type} transaction summary:`, summary);
|
|
98
92
|
}
|
|
99
93
|
//# sourceMappingURL=transaction-builder.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction-builder.js","sourceRoot":"","sources":["../../transaction/transaction-builder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"transaction-builder.js","sourceRoot":"","sources":["../../transaction/transaction-builder.ts"],"names":[],"mappings":";;AAmBA,8BAwBC;AAwBD,oEA2CC;AAOD,wDAMC;AAOD,sDAEC;AApID,6DAAmD;AACnD,yCAGmB;AAInB,0CAA0C;AAC1C,MAAM,SAAS,GAAG,IAAI,oBAAQ,EAAE,CAAC;AACjC,MAAM,SAAS,GAAG,IAAA,mBAAO,EAAC,kEAAkE,CAAC,CAAC;AAC9F,MAAM,SAAS,GAAG,SAAS,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;AACpD,MAAM,YAAY,GAAG,kBAAM,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAEjE;;;;GAIG;AACH,SAAgB,SAAS,CACvB,KAA+B,EAC/B,OAAc,EACd,WAAmB,mCAAuB,EAC1C,WAAmB,6BAAiB;IAEpC,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1C,KAAK,EAAE;YACL,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;YAC7C,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE;SACnE;QACD,SAAS,EAAE,IAAA,0BAAc,EAAC,SAAS,EAAE,SAAS,EAAE,sBAAU,CAAC;KAC5D,CAAC,CAAC,CAAC;IAEJ,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,qBAAS,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC;QAClE,SAAS,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,kDACE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAC3C,EAAE,CACH,CAAC;IACJ,CAAC;AACH,CAAC;AAiBD;;;;;;GAMG;AACI,KAAK,UAAU,4BAA4B,CAChD,MAAa,EACb,OAAc,EACd,UAA8B,EAAE;IAEhC,MAAM,EACJ,QAAQ,GAAG,KAAK,EAChB,QAAQ,GAAG,IAAI,EACf,SAAS,GAAG,GAAG,EACf,OAAO,EAAE,aAAa,CAAC,eAAe;MACvC,GAAG,OAAO,CAAC;IAEZ,MAAM,MAAM,GAAG,aAAa,IAAI,wBAAO,CAAC,CAAC,sBAAsB;IAE/D,IAAI,CAAC;QACH,OAAO;QACP,MAAM,OAAO,GAAG,IAAI,qBAAS,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QAEnD,OAAO;QACP,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YACtB,QAAQ;YACR,QAAQ,EAAE,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;SACtE,CAAC,CAAC;QAEH,QAAQ;QACR,MAAM,QAAQ,GAAG,IAAA,iBAAK,EAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;QAEjC,OAAO;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QACxD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACtD,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAEtB,OAAO;YACL,YAAY,EAAE,8BAA8B,IAAI,EAAE;YAClD,eAAe,EAAE,IAAI;YACrB,IAAI;SACL,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAC;QAC5D,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,sBAAsB,CAAC,MAAW,EAAE,QAA+B;IACjF,KAAK,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,QAAQ,EAAE,CAAC;QACxD,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9D,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,qBAAqB,CAAC,IAAY,EAAE,OAAY;IAC9D,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,uBAAuB,EAAE,OAAO,CAAC,CAAC;AACvD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utxo-utils.d.ts","sourceRoot":"","sources":["../../utxo/utxo-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utxo-utils.d.ts","sourceRoot":"","sources":["../../utxo/utxo-utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAY,SAAS,EAAE,MAAM,UAAU,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAc/C,UAAU,aAAa;IACrB,aAAa,EAAE,IAAI,EAAE,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAGD,UAAU,cAAc;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,eAAe,CAAC;IAClD,aAAa,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,KAAK,CAAC;CAC/C;AAGD,UAAU,gBAAgB;IACxB,kBAAkB,EAAE,IAAI,EAAE,CAAC;IAC3B,gBAAgB,EAAE,IAAI,EAAE,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE;QACP,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,OAAO,CAAC;QACxB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAGD,UAAU,YAAY;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAGD,UAAU,cAAc;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,IAAI,EAAE,CAAC;IACpB,QAAQ,EAAE,IAAI,EAAE,CAAC;IACjB,aAAa,EAAE,YAAY,EAAE,CAAC;CAC/B;AAGD,KAAK,YAAY,GAAG,KAAK,GAAG,SAAS,GAAG,eAAe,CAAC;AAExD;;;;;GAKG;AACH,iBAAe,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAuBvF;AAED;;;;;;GAMG;AACH,iBAAS,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,GAAE,YAAoB,GAAG,aAAa,CA4DrG;AAED;;;;;;;;GAQG;AACH,iBAAS,cAAc,CACrB,KAAK,EAAE,IAAI,EAAE,EACb,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,SAAS,EAAE,EACvB,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,cAAmB,GAC3B,gBAAgB,CAkHlB;AAED;;;;;GAKG;AACH,iBAAe,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAqCxG;AAED,OAAO,EACL,QAAQ,EACR,WAAW,EACX,cAAc,EACd,iBAAiB,EAClB,CAAC"}
|
package/dist/utxo/utxo-utils.js
CHANGED
|
@@ -4,8 +4,18 @@ exports.getUtxos = getUtxos;
|
|
|
4
4
|
exports.selectUtxos = selectUtxos;
|
|
5
5
|
exports.selectSlpUtxos = selectSlpUtxos;
|
|
6
6
|
exports.getAddressBalance = getAddressBalance;
|
|
7
|
+
const ecash_lib_1 = require("ecash-lib");
|
|
7
8
|
const ecashaddrjs_1 = require("ecashaddrjs");
|
|
8
9
|
const chronik_client_1 = require("../client/chronik-client");
|
|
10
|
+
// P2PKH 交易字节大小常量
|
|
11
|
+
const P2PKH_INPUT_BYTES = 148; // txid(32) + vout(4) + scriptLen(1) + sig(72) + pubkey(33) + sequence(4) + varint(2)
|
|
12
|
+
const P2PKH_OUTPUT_BYTES = 34; // value(8) + scriptLen(1) + script(25)
|
|
13
|
+
const TX_OVERHEAD_BYTES = 10; // version(4) + locktime(4) + input/output count varints
|
|
14
|
+
/** 根据输入数和输出数估算交易手续费(satoshis) */
|
|
15
|
+
function estimateFee(nInputs, nOutputs) {
|
|
16
|
+
const txBytes = nInputs * P2PKH_INPUT_BYTES + nOutputs * P2PKH_OUTPUT_BYTES + TX_OVERHEAD_BYTES;
|
|
17
|
+
return Number((0, ecash_lib_1.calcTxFee)(txBytes, ecash_lib_1.DEFAULT_FEE_SATS_PER_KB));
|
|
18
|
+
}
|
|
9
19
|
/**
|
|
10
20
|
* Get UTXOs for a given address
|
|
11
21
|
* @param address - eCash address
|
|
@@ -45,7 +55,7 @@ function selectUtxos(utxos, sendAmount, strategy = 'all') {
|
|
|
45
55
|
// 过滤掉SLP代币UTXOs
|
|
46
56
|
const nonSlpUtxos = utxos.filter(utxo => !utxo.slpToken);
|
|
47
57
|
if (nonSlpUtxos.length === 0) {
|
|
48
|
-
throw new Error('
|
|
58
|
+
throw new Error('No non-SLP UTXOs available');
|
|
49
59
|
}
|
|
50
60
|
let selectedUtxos = [];
|
|
51
61
|
switch (strategy) {
|
|
@@ -60,8 +70,8 @@ function selectUtxos(utxos, sendAmount, strategy = 'all') {
|
|
|
60
70
|
for (const utxo of sortedUtxos) {
|
|
61
71
|
selectedUtxos.push(utxo);
|
|
62
72
|
accumulatedValue += utxo.value;
|
|
63
|
-
//
|
|
64
|
-
const estimatedFee = selectedUtxos.length
|
|
73
|
+
// 估算手续费:inputs + 2 outputs(接收方 + 找零)
|
|
74
|
+
const estimatedFee = estimateFee(selectedUtxos.length, 2);
|
|
65
75
|
if (accumulatedValue >= sendAmount + estimatedFee) {
|
|
66
76
|
break;
|
|
67
77
|
}
|
|
@@ -72,13 +82,13 @@ function selectUtxos(utxos, sendAmount, strategy = 'all') {
|
|
|
72
82
|
selectedUtxos = nonSlpUtxos.sort((a, b) => b.value - a.value);
|
|
73
83
|
break;
|
|
74
84
|
default:
|
|
75
|
-
throw new Error(
|
|
85
|
+
throw new Error(`Unknown UTXO selection strategy: ${strategy}`);
|
|
76
86
|
}
|
|
77
87
|
const totalInputValue = selectedUtxos.reduce((sum, utxo) => sum + utxo.value, 0);
|
|
78
|
-
const estimatedFee = selectedUtxos.length
|
|
88
|
+
const estimatedFee = estimateFee(selectedUtxos.length, 2);
|
|
79
89
|
// 检查余额是否足够
|
|
80
90
|
if (totalInputValue < sendAmount + estimatedFee) {
|
|
81
|
-
throw new Error(
|
|
91
|
+
throw new Error(`Insufficient balance. Total input: ${totalInputValue}, required: ${sendAmount + estimatedFee} (including estimated fee ${estimatedFee})`);
|
|
82
92
|
}
|
|
83
93
|
return {
|
|
84
94
|
selectedUtxos,
|
|
@@ -105,10 +115,10 @@ function selectSlpUtxos(utxos, tokenId, recipients, tokenDecimals, options = {})
|
|
|
105
115
|
const slpUtxos = utxos.filter(utxo => utxo.slpToken && utxo.slpToken.tokenId === tokenId);
|
|
106
116
|
const nonSlpUtxos = utxos.filter(utxo => !utxo.slpToken);
|
|
107
117
|
if (slpUtxos.length === 0) {
|
|
108
|
-
throw new Error(
|
|
118
|
+
throw new Error(`No SLP UTXOs available for token ${tokenId}`);
|
|
109
119
|
}
|
|
110
120
|
if (nonSlpUtxos.length === 0) {
|
|
111
|
-
throw new Error('
|
|
121
|
+
throw new Error('No non-SLP UTXOs available for fee payment');
|
|
112
122
|
}
|
|
113
123
|
// 计算需要发送的代币总量(直接使用基础单位,不进行小数转换)
|
|
114
124
|
const sendAmounts = recipients.map(r => BigInt(r.amount));
|
|
@@ -141,13 +151,13 @@ function selectSlpUtxos(utxos, tokenId, recipients, tokenDecimals, options = {})
|
|
|
141
151
|
return aAmount < bAmount ? -1 : aAmount > bAmount ? 1 : 0;
|
|
142
152
|
});
|
|
143
153
|
if (sortedSlpUtxos.length === 0) {
|
|
144
|
-
throw new Error('
|
|
154
|
+
throw new Error('Insufficient token balance');
|
|
145
155
|
}
|
|
146
156
|
selectedTokenUtxos = [sortedSlpUtxos[0]];
|
|
147
157
|
totalTokens = BigInt(sortedSlpUtxos[0].slpToken.atoms);
|
|
148
158
|
}
|
|
149
159
|
if (totalSendTokens > totalTokens) {
|
|
150
|
-
throw new Error(
|
|
160
|
+
throw new Error(`Insufficient token balance. Available: ${totalTokens.toString()}, required: ${totalSendTokens.toString()}`);
|
|
151
161
|
}
|
|
152
162
|
const tokenChange = totalTokens - totalSendTokens;
|
|
153
163
|
// 选择手续费UTXOs
|
|
@@ -162,11 +172,13 @@ function selectSlpUtxos(utxos, tokenId, recipients, tokenDecimals, options = {})
|
|
|
162
172
|
selectedFeeUtxos = feeSelection.selectedUtxos;
|
|
163
173
|
}
|
|
164
174
|
const totalFeeInputValue = selectedFeeUtxos.reduce((sum, utxo) => sum + utxo.value, 0);
|
|
165
|
-
|
|
175
|
+
// 估算手续费:所有输入 + OP_RETURN(1) + 接收方输出 + token找零(1) + XEC找零(1)
|
|
176
|
+
const nOutputs = 1 + recipients.length + (tokenChange > 0n ? 1 : 0) + 1;
|
|
177
|
+
const estimatedFee = estimateFee(selectedFeeUtxos.length + selectedTokenUtxos.length, nOutputs);
|
|
166
178
|
// 计算所需的最小金额
|
|
167
179
|
const requiredAmount = recipients.length * dustLimit + (tokenChange > 0n ? dustLimit : 0) + estimatedFee;
|
|
168
180
|
if (totalFeeInputValue < requiredAmount) {
|
|
169
|
-
throw new Error(
|
|
181
|
+
throw new Error(`Insufficient balance for fees. Total input: ${totalFeeInputValue}, required: ${requiredAmount} (including estimated fee ${estimatedFee})`);
|
|
170
182
|
}
|
|
171
183
|
// 构建最终的发送金额数组
|
|
172
184
|
const finalSendAmounts = [...sendAmounts];
|
|
@@ -231,7 +243,7 @@ async function getAddressBalance(address, chronikClient) {
|
|
|
231
243
|
};
|
|
232
244
|
}
|
|
233
245
|
catch (error) {
|
|
234
|
-
console.error('
|
|
246
|
+
console.error('Failed to get address balance:', error);
|
|
235
247
|
throw error;
|
|
236
248
|
}
|
|
237
249
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utxo-utils.js","sourceRoot":"","sources":["../../utxo/utxo-utils.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"utxo-utils.js","sourceRoot":"","sources":["../../utxo/utxo-utils.ts"],"names":[],"mappings":";;AAgWE,4BAAQ;AACR,kCAAW;AACX,wCAAc;AACd,8CAAiB;AAnWnB,yCAA+D;AAC/D,6CAAgD;AAChD,6DAAmD;AAInD,iBAAiB;AACjB,MAAM,iBAAiB,GAAG,GAAG,CAAC,CAAE,qFAAqF;AACrH,MAAM,kBAAkB,GAAG,EAAE,CAAC,CAAC,uCAAuC;AACtE,MAAM,iBAAiB,GAAG,EAAE,CAAC,CAAE,wDAAwD;AAEvF,iCAAiC;AACjC,SAAS,WAAW,CAAC,OAAe,EAAE,QAAgB;IACpD,MAAM,OAAO,GAAG,OAAO,GAAG,iBAAiB,GAAG,QAAQ,GAAG,kBAAkB,GAAG,iBAAiB,CAAC;IAChG,OAAO,MAAM,CAAC,IAAA,qBAAS,EAAC,OAAO,EAAE,mCAAuB,CAAC,CAAC,CAAC;AAC7D,CAAC;AA4DD;;;;;GAKG;AACH,KAAK,UAAU,QAAQ,CAAC,OAAe,EAAE,aAA6B;IACpE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,IAAA,+BAAiB,EAAC,OAAO,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,aAAa,IAAI,wBAAO,CAAC,CAAC,sBAAsB;IAE/D,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;QAE9D,IAAI,CAAC,aAAa,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QAED,MAAM,KAAK,GAAW,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACrD,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE;YACtC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM;YAC1B,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;YACxB,OAAO,EAAE,OAAO;YAChB,QAAQ,EAAE,IAAI,CAAC,KAAK;SACrB,CAAC,CAAC,CAAC;QACJ,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,qCAAqC,IAAI,EAAE,CAAC,CAAC;QACzD,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,WAAW,CAAC,KAAa,EAAE,UAAkB,EAAE,WAAyB,KAAK;IACpF,gBAAgB;IAChB,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEzD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,aAAa,GAAW,EAAE,CAAC;IAE/B,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,KAAK;YACR,wBAAwB;YACxB,aAAa,GAAG,WAAW,CAAC;YAC5B,MAAM;QAER,KAAK,SAAS;YACZ,sBAAsB;YACtB,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;YAC5E,IAAI,gBAAgB,GAAG,CAAC,CAAC;YAEzB,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;gBAC/B,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACzB,gBAAgB,IAAI,IAAI,CAAC,KAAK,CAAC;gBAE/B,qCAAqC;gBACrC,MAAM,YAAY,GAAG,WAAW,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;gBAE1D,IAAI,gBAAgB,IAAI,UAAU,GAAG,YAAY,EAAE,CAAC;oBAClD,MAAM;gBACR,CAAC;YACH,CAAC;YACD,MAAM;QAER,KAAK,eAAe;YAClB,eAAe;YACf,aAAa,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;YAC9D,MAAM;QAER;YACE,MAAM,IAAI,KAAK,CAAC,oCAAoC,QAAQ,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,eAAe,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACjF,MAAM,YAAY,GAAG,WAAW,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAE1D,WAAW;IACX,IAAI,eAAe,GAAG,UAAU,GAAG,YAAY,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CACb,sCAAsC,eAAe,eAAe,UAAU,GAAG,YAAY,6BAA6B,YAAY,GAAG,CAC1I,CAAC;IACJ,CAAC;IAED,OAAO;QACL,aAAa;QACb,eAAe;QACf,YAAY;QACZ,YAAY,EAAE,eAAe,GAAG,UAAU,GAAG,YAAY;QACzD,SAAS,EAAE,aAAa,CAAC,MAAM;KAChC,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,cAAc,CACrB,KAAa,EACb,OAAe,EACf,UAAuB,EACvB,aAAqB,EACrB,UAA0B,EAAE;IAE5B,MAAM,EACJ,SAAS,GAAG,GAAG,EACf,WAAW,GAAG,KAAK,EAAE,cAAc;IACnC,aAAa,GAAG,SAAS,CAAC,aAAa;MACxC,GAAG,OAAO,CAAC;IAEZ,mBAAmB;IACnB,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CACnC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,KAAK,OAAO,CACnD,CAAC;IACF,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEzD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,oCAAoC,OAAO,EAAE,CAAC,CAAC;IACjE,CAAC;IACD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IAED,gCAAgC;IAChC,MAAM,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1D,MAAM,eAAe,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;IAExE,YAAY;IACZ,IAAI,kBAAkB,GAAW,EAAE,CAAC;IACpC,IAAI,WAAW,GAAG,EAAE,CAAC;IAErB,IAAI,aAAa,KAAK,KAAK,EAAE,CAAC;QAC5B,gCAAgC;QAChC,kBAAkB,GAAG,QAAQ,CAAC;QAC9B,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,QAAS,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IACvF,CAAC;SAAM,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QACvC,gBAAgB;QAChB,MAAM,iBAAiB,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE;YACzD,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,QAAS,CAAC,KAAK,CAAC,CAAC;YACtD,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,QAAS,CAAC,KAAK,CAAC,CAAC;YAC9C,OAAO,aAAa,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;QACnD,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAChB,kBAAkB,GAAG,CAAC,iBAAiB,CAAC,CAAC;QACzC,WAAW,GAAG,MAAM,CAAC,iBAAiB,CAAC,QAAS,CAAC,KAAK,CAAC,CAAC;IAC1D,CAAC;SAAM,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QACvC,gBAAgB;QAChB,MAAM,cAAc,GAAG,QAAQ;aAC5B,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAS,CAAC,KAAK,CAAC,IAAI,eAAe,CAAC;aAC/D,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACb,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,QAAS,CAAC,KAAK,CAAC,CAAC;YAC1C,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,QAAS,CAAC,KAAK,CAAC,CAAC;YAC1C,OAAO,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QAEL,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,CAAC;QACD,kBAAkB,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;QACzC,WAAW,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,QAAS,CAAC,KAAK,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,eAAe,GAAG,WAAW,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,0CAA0C,WAAW,CAAC,QAAQ,EAAE,eAAe,eAAe,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC/H,CAAC;IAED,MAAM,WAAW,GAAG,WAAW,GAAG,eAAe,CAAC;IAElD,aAAa;IACb,IAAI,gBAAwB,CAAC;IAC7B,IAAI,WAAW,KAAK,KAAK,EAAE,CAAC;QAC1B,gBAAgB,GAAG,WAAW,CAAC;IACjC,CAAC;SAAM,CAAC;QACN,0BAA0B;QAC1B,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,GAAG,SAAS,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,YAAY;QAC3G,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;QACnE,gBAAgB,GAAG,YAAY,CAAC,aAAa,CAAC;IAChD,CAAC;IAED,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACvF,4DAA4D;IAC5D,MAAM,QAAQ,GAAG,CAAC,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACxE,MAAM,YAAY,GAAG,WAAW,CAAC,gBAAgB,CAAC,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAEhG,YAAY;IACZ,MAAM,cAAc,GAAG,UAAU,CAAC,MAAM,GAAG,SAAS,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC;IAEzG,IAAI,kBAAkB,GAAG,cAAc,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,+CAA+C,kBAAkB,eAAe,cAAc,6BAA6B,YAAY,GAAG,CAC3I,CAAC;IACJ,CAAC;IAED,cAAc;IACd,MAAM,gBAAgB,GAAG,CAAC,GAAG,WAAW,CAAC,CAAC;IAC1C,IAAI,WAAW,GAAG,EAAE,EAAE,CAAC;QACrB,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACrC,CAAC;IAED,OAAO;QACL,kBAAkB,EAAE,OAAO;QAC3B,gBAAgB;QAChB,kBAAkB;QAClB,YAAY;QACZ,eAAe,EAAE,kBAAkB,GAAG,cAAc,GAAG,YAAY;QACnE,WAAW;QACX,gBAAgB;QAChB,eAAe;QACf,WAAW;QACX,SAAS;QACT,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB,CAAC,MAAM,EAAE,OAAO;YAClD,YAAY,EAAE,gBAAgB,CAAC,MAAM;YACrC,cAAc,EAAE,UAAU,CAAC,MAAM;YACjC,cAAc,EAAE,WAAW,GAAG,EAAE;YAChC,YAAY,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,qDAAqD;SAC3H;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,iBAAiB,CAAC,OAAe,EAAE,aAA6B;IAC7E,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;QACrD,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAErD,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAE5E,mBAAmB;QACnB,MAAM,aAAa,GAAoC,EAAE,CAAC;QAC1D,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACtB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAS,CAAC,OAAO,CAAC;YACvC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC5B,aAAa,CAAC,OAAO,CAAC,GAAG;oBACvB,OAAO;oBACP,WAAW,EAAE,EAAE;oBACf,SAAS,EAAE,CAAC;oBACZ,KAAK,EAAE,EAAE;iBACV,CAAC;YACJ,CAAC;YACD,aAAa,CAAC,OAAO,CAAC,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,QAAS,CAAC,KAAK,CAAC,CAAC;YACnE,aAAa,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC;YACnC,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,OAAO;YACL,YAAY;YACZ,SAAS,EAAE,WAAW,CAAC,MAAM;YAC7B,YAAY,EAAE,QAAQ,CAAC,MAAM;YAC7B,WAAW;YACX,QAAQ;YACR,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC;SAC5C,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;QACvD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mnemonic-utils.d.ts","sourceRoot":"","sources":["../../wallet/mnemonic-utils.ts"],"names":[],"mappings":"AAKA,UAAU,UAAU;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,YAAY,GAAE,MAAU,EACxB,cAAc,GAAE,MAA2B,GAC1C,UAAU,
|
|
1
|
+
{"version":3,"file":"mnemonic-utils.d.ts","sourceRoot":"","sources":["../../wallet/mnemonic-utils.ts"],"names":[],"mappings":"AAKA,UAAU,UAAU;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,YAAY,GAAE,MAAU,EACxB,cAAc,GAAE,MAA2B,GAC1C,UAAU,CAkCZ;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAQ7E"}
|
|
@@ -46,7 +46,6 @@ const ecashaddrjs_1 = require("ecashaddrjs");
|
|
|
46
46
|
* @returns 包含 wif 和 address 的对象
|
|
47
47
|
*/
|
|
48
48
|
function deriveBuyerKey(mnemonic, addressIndex = 0, derivationPath = "m/44'/1899'/0'/0") {
|
|
49
|
-
console.log(`从助记词派生密钥...(地址索引: ${addressIndex})`);
|
|
50
49
|
// 将助记词转换为种子
|
|
51
50
|
const seed = (0, ecash_lib_1.mnemonicToSeed)(mnemonic);
|
|
52
51
|
// 从种子生成根 HD 节点
|
|
@@ -67,7 +66,6 @@ function deriveBuyerKey(mnemonic, addressIndex = 0, derivationPath = "m/44'/1899
|
|
|
67
66
|
privateKey: Buffer.from(privateKeyBuffer),
|
|
68
67
|
compressed: true
|
|
69
68
|
});
|
|
70
|
-
console.log(`密钥派生完成,地址索引 ${addressIndex}:`, ecashAddress);
|
|
71
69
|
return {
|
|
72
70
|
wif: buyerWIF,
|
|
73
71
|
address: ecashAddress,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mnemonic-utils.js","sourceRoot":"","sources":["../../wallet/mnemonic-utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBA,
|
|
1
|
+
{"version":3,"file":"mnemonic-utils.js","sourceRoot":"","sources":["../../wallet/mnemonic-utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBA,wCAsCC;AAOD,4CAQC;AAxED,yCAA8D;AAC9D,yCAA2B;AAC3B,6CAAgD;AAUhD;;;;;;GAMG;AACH,SAAgB,cAAc,CAC5B,QAAgB,EAChB,eAAuB,CAAC,EACxB,iBAAyB,kBAAkB;IAE3C,YAAY;IACZ,MAAM,IAAI,GAAG,IAAA,0BAAc,EAAC,QAAQ,CAAC,CAAC;IAEtC,eAAe;IACf,MAAM,MAAM,GAAG,kBAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAErC,mBAAmB;IACnB,MAAM,kBAAkB,GAAG,GAAG,cAAc,IAAI,YAAY,EAAE,CAAC;IAE/D,YAAY;IACZ,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAExD,mBAAmB;IACnB,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;IAClC,MAAM,UAAU,GAAG,IAAA,qBAAS,EAAC,MAAM,CAAC,CAAC;IACrC,MAAM,YAAY,GAAG,IAAA,+BAAiB,EAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IAErE,UAAU;IACV,MAAM,gBAAgB,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;IAE5C,8BAA8B;IAC9B,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC;QAC1B,OAAO,EAAE,IAAI;QACb,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC;QACzC,UAAU,EAAE,IAAI;KACjB,CAAC,CAAC;IAEH,OAAO;QACL,GAAG,EAAE,QAAQ;QACb,OAAO,EAAE,YAAY;QACrB,YAAY,EAAE,YAAY;QAC1B,cAAc,EAAE,kBAAkB;KACnC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAgB,gBAAgB,CAAC,QAAmC;IAClE,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3C,8BAA8B;IAC9B,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wallet-utils.d.ts","sourceRoot":"","sources":["../../wallet/wallet-utils.ts"],"names":[],"mappings":"AAaA,UAAU,UAAU;IAClB,GAAG,EAAE,GAAG,CAAC;IACT,QAAQ,EAAE,UAAU,CAAC;IACrB,QAAQ,EAAE,UAAU,CAAC;IACrB,SAAS,EAAE,UAAU,CAAC;IACtB,WAAW,EAAE,GAAG,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,GAAE,MAAU,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"wallet-utils.d.ts","sourceRoot":"","sources":["../../wallet/wallet-utils.ts"],"names":[],"mappings":"AAaA,UAAU,UAAU;IAClB,GAAG,EAAE,GAAG,CAAC;IACT,QAAQ,EAAE,UAAU,CAAC;IACrB,QAAQ,EAAE,UAAU,CAAC;IACrB,SAAS,EAAE,UAAU,CAAC;IACtB,WAAW,EAAE,GAAG,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,GAAE,MAAU,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,UAAU,CA6BxF"}
|
|
@@ -49,9 +49,8 @@ function initializeWallet(addressIndex = 0, mnemonic) {
|
|
|
49
49
|
// 如果提供了助记词参数就使用,否则从环境变量获取
|
|
50
50
|
const finalMnemonic = mnemonic || (0, constants_1.getMnemonic)();
|
|
51
51
|
if (!finalMnemonic) {
|
|
52
|
-
throw new Error('
|
|
52
|
+
throw new Error('Mnemonic not set: please set the MNEMONIC environment variable or provide it as a parameter');
|
|
53
53
|
}
|
|
54
|
-
console.log('使用助记词派生私钥...');
|
|
55
54
|
// 只调用一次 deriveBuyerKey,获取完整信息
|
|
56
55
|
const derived = (0, mnemonic_utils_1.deriveBuyerKey)(finalMnemonic, addressIndex);
|
|
57
56
|
const ecc = new Ecc();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wallet-utils.js","sourceRoot":"","sources":["../../wallet/wallet-utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,
|
|
1
|
+
{"version":3,"file":"wallet-utils.js","sourceRoot":"","sources":["../../wallet/wallet-utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,4CA6BC;AA1DD,mDAAkD;AAClD,qDAAkD;AAClD,yCAA2B;AAC3B,oDAAsC;AAEtC,MAAM,EACJ,GAAG,EACH,MAAM,EACN,OAAO,EACP,SAAS,GACV,GAAG,QAAQ,CAAC;AAab;;;;;GAKG;AACH,SAAgB,gBAAgB,CAAC,eAAuB,CAAC,EAAE,QAAiB;IAC1E,0BAA0B;IAC1B,MAAM,aAAa,GAAG,QAAQ,IAAI,IAAA,uBAAW,GAAE,CAAC;IAEhD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,6FAA6F,CAAC,CAAC;IACjH,CAAC;IAED,8BAA8B;IAC9B,MAAM,OAAO,GAAG,IAAA,+BAAc,EAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IAE5D,MAAM,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;IACtB,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACtC,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAE5C,OAAO;QACL,GAAG;QACH,QAAQ;QACR,QAAQ;QACR,SAAS;QACT,WAAW;QACX,OAAO,EAAE,OAAO,CAAC,OAAO,EAAG,YAAY;QACvC,YAAY;KACb,CAAC;AACJ,CAAC"}
|