ecash-quicksend 1.0.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.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +255 -0
  3. package/dist/client/chronik-client.d.ts +4 -0
  4. package/dist/client/chronik-client.d.ts.map +1 -0
  5. package/dist/client/chronik-client.js +14 -0
  6. package/dist/client/chronik-client.js.map +1 -0
  7. package/dist/config/constants.d.ts +21 -0
  8. package/dist/config/constants.d.ts.map +1 -0
  9. package/dist/config/constants.js +46 -0
  10. package/dist/config/constants.js.map +1 -0
  11. package/dist/index.d.ts +37 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +91 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/send/tokensend.d.ts +10 -0
  16. package/dist/send/tokensend.d.ts.map +1 -0
  17. package/dist/send/tokensend.js +121 -0
  18. package/dist/send/tokensend.js.map +1 -0
  19. package/dist/send/xecsend.d.ts +23 -0
  20. package/dist/send/xecsend.d.ts.map +1 -0
  21. package/dist/send/xecsend.js +99 -0
  22. package/dist/send/xecsend.js.map +1 -0
  23. package/dist/transaction/transaction-builder.d.ts +33 -0
  24. package/dist/transaction/transaction-builder.d.ts.map +1 -0
  25. package/dist/transaction/transaction-builder.js +59 -0
  26. package/dist/transaction/transaction-builder.js.map +1 -0
  27. package/dist/transaction/transaction-utils.d.ts +31 -0
  28. package/dist/transaction/transaction-utils.d.ts.map +1 -0
  29. package/dist/transaction/transaction-utils.js +37 -0
  30. package/dist/transaction/transaction-utils.js.map +1 -0
  31. package/dist/types.d.ts +79 -0
  32. package/dist/types.d.ts.map +1 -0
  33. package/dist/types.js +3 -0
  34. package/dist/types.js.map +1 -0
  35. package/dist/utxo/utxo-utils.d.ts +79 -0
  36. package/dist/utxo/utxo-utils.d.ts.map +1 -0
  37. package/dist/utxo/utxo-utils.js +230 -0
  38. package/dist/utxo/utxo-utils.js.map +1 -0
  39. package/dist/wallet/mnemonic-utils.d.ts +22 -0
  40. package/dist/wallet/mnemonic-utils.d.ts.map +1 -0
  41. package/dist/wallet/mnemonic-utils.js +54 -0
  42. package/dist/wallet/mnemonic-utils.js.map +1 -0
  43. package/dist/wallet/wallet-utils.d.ts +17 -0
  44. package/dist/wallet/wallet-utils.d.ts.map +1 -0
  45. package/dist/wallet/wallet-utils.js +34 -0
  46. package/dist/wallet/wallet-utils.js.map +1 -0
  47. package/package.json +67 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 ecash-sendlib
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,255 @@
1
+ # ecash-quicksend
2
+
3
+ [![npm version](https://badge.fury.io/js/ecash-quicksend.svg)](https://badge.fury.io/js/ecash-quicksend)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ A unified transaction manager for eCash (XEC), SLP, and ALP token transactions. Simplify your eCash blockchain interactions with a single, easy-to-use library.
7
+
8
+ ## Features
9
+
10
+ - ✅ **XEC Transactions**: Send eCash (XEC) with customizable UTXO strategies
11
+ - ✅ **SLP Token Support**: Full support for Simple Ledger Protocol tokens
12
+ - ✅ **ALP Token Support**: Advanced Ledger Protocol token transactions
13
+ - ✅ **TypeScript Support**: Full TypeScript definitions included
14
+ - ✅ **Unified API**: Single interface for all transaction types
15
+ - ✅ **Flexible Configuration**: Mnemonic-based wallet management
16
+ - ✅ **Automatic UTXO Management**: Smart UTXO selection strategies
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install ecash-quicksend
22
+ ```
23
+
24
+ ## Quick Start
25
+
26
+ ### 1. Environment Setup
27
+
28
+ Create a `.env` file in your project root:
29
+
30
+ ```env
31
+ # Required: Your wallet mnemonic (12-24 words)
32
+ MNEMONIC="your twelve word mnemonic phrase goes here and should be kept secret"
33
+ ```
34
+
35
+ ### 2. Basic Usage
36
+
37
+ ```javascript
38
+ import transactionManager from 'ecash-quicksend';
39
+
40
+ // Send XEC
41
+ const xecResult = await transactionManager.sendXec([
42
+ { address: 'ecash:qq...', amount: 1000 } // 1000 satoshis
43
+ ]);
44
+
45
+ // Send SLP tokens
46
+ const slpResult = await transactionManager.sendSlp([
47
+ { address: 'ecash:qq...', amount: 100 }
48
+ ], {
49
+ tokenId: 'your-slp-token-id',
50
+ tokenDecimals: 8
51
+ });
52
+
53
+ // Send ALP tokens
54
+ const alpResult = await transactionManager.sendAlp([
55
+ { address: 'ecash:qq...', amount: 100 }
56
+ ], {
57
+ tokenId: 'your-alp-token-id',
58
+ tokenDecimals: 8
59
+ });
60
+ ```
61
+
62
+ ## API Reference
63
+
64
+ ### TransactionManager
65
+
66
+ The main class that manages all transaction types.
67
+
68
+ #### Methods
69
+
70
+ ##### `sendXec(recipients, options?)`
71
+
72
+ Send eCash (XEC) to one or more recipients.
73
+
74
+ ```typescript
75
+ await transactionManager.sendXec(
76
+ [{ address: 'ecash:qq...', amount: 1000 }],
77
+ {
78
+ utxoStrategy: 'all', // 'all' | 'largest' | 'smallest'
79
+ addressIndex: 0
80
+ }
81
+ );
82
+ ```
83
+
84
+ **Parameters:**
85
+ - `recipients`: Array of `{ address: string, amount: number }`
86
+ - `options`: Optional configuration object
87
+
88
+ ##### `sendSlp(recipients, options)`
89
+
90
+ Send SLP tokens to one or more recipients.
91
+
92
+ ```typescript
93
+ await transactionManager.sendSlp(
94
+ [{ address: 'ecash:qq...', amount: 100 }],
95
+ {
96
+ tokenId: 'your-token-id',
97
+ tokenDecimals: 8,
98
+ addressIndex: 0,
99
+ feeStrategy: 'auto',
100
+ tokenStrategy: 'auto'
101
+ }
102
+ );
103
+ ```
104
+
105
+ ##### `sendAlp(recipients, options)`
106
+
107
+ Send ALP tokens to one or more recipients.
108
+
109
+ ```typescript
110
+ await transactionManager.sendAlp(
111
+ [{ address: 'ecash:qq...', amount: 100 }],
112
+ {
113
+ tokenId: 'your-token-id',
114
+ tokenDecimals: 8,
115
+ addressIndex: 0,
116
+ feeStrategy: 'auto',
117
+ tokenStrategy: 'auto'
118
+ }
119
+ );
120
+ ```
121
+
122
+ ##### `send(type, recipients, options?)`
123
+
124
+ Universal send method supporting all transaction types.
125
+
126
+ ```typescript
127
+ // Send XEC
128
+ await transactionManager.send('xec', recipients, {
129
+ utxoStrategy: 'all',
130
+ addressIndex: 0
131
+ });
132
+
133
+ // Send SLP
134
+ await transactionManager.send('slp', recipients, {
135
+ tokenId: 'your-token-id',
136
+ tokenDecimals: 8
137
+ });
138
+
139
+ // Send ALP
140
+ await transactionManager.send('alp', recipients, {
141
+ tokenId: 'your-token-id',
142
+ tokenDecimals: 8
143
+ });
144
+ ```
145
+
146
+ ## Types
147
+
148
+ ### Recipient
149
+
150
+ ```typescript
151
+ interface Recipient {
152
+ address: string; // eCash address (ecash:qq...)
153
+ amount: number; // Amount in base units (satoshis for XEC, token units for SLP/ALP)
154
+ }
155
+ ```
156
+
157
+ ### TransactionResult
158
+
159
+ ```typescript
160
+ interface TransactionResult {
161
+ txid: string; // Transaction ID
162
+ success: boolean; // Transaction success status
163
+ message?: string; // Optional status message
164
+ rawTx?: string; // Raw transaction hex
165
+ }
166
+ ```
167
+
168
+ ### Token Transaction Options
169
+
170
+ ```typescript
171
+ interface TokenTransactionOptions {
172
+ tokenId: string; // Token ID
173
+ tokenDecimals: number; // Token decimal places
174
+ addressIndex?: number; // Wallet address index (default: 0)
175
+ feeStrategy?: string; // Fee calculation strategy
176
+ tokenStrategy?: string; // Token UTXO selection strategy
177
+ }
178
+ ```
179
+
180
+ ### XEC Transaction Options
181
+
182
+ ```typescript
183
+ interface XecTransactionOptions {
184
+ utxoStrategy?: string; // 'all' | 'largest' | 'smallest'
185
+ addressIndex?: number; // Wallet address index (default: 0)
186
+ }
187
+ ```
188
+
189
+ ## Advanced Usage
190
+
191
+ ### Multiple Recipients
192
+
193
+ ```javascript
194
+ // Send to multiple recipients in a single transaction
195
+ await transactionManager.sendXec([
196
+ { address: 'ecash:qq...', amount: 1000 },
197
+ { address: 'ecash:qp...', amount: 2000 },
198
+ { address: 'ecash:qr...', amount: 500 }
199
+ ]);
200
+ ```
201
+
202
+ ### Custom UTXO Strategies
203
+
204
+ ```javascript
205
+ // Use largest UTXO first (good for consolidation)
206
+ await transactionManager.sendXec(recipients, { utxoStrategy: 'largest' });
207
+
208
+ // Use smallest UTXO first (good for privacy)
209
+ await transactionManager.sendXec(recipients, { utxoStrategy: 'smallest' });
210
+
211
+ // Use all available UTXOs (default)
212
+ await transactionManager.sendXec(recipients, { utxoStrategy: 'all' });
213
+ ```
214
+
215
+ ### Address Index Management
216
+
217
+ ```javascript
218
+ // Use different derived addresses
219
+ await transactionManager.sendXec(recipients, { addressIndex: 1 });
220
+ await transactionManager.sendSlp(recipients, options, { addressIndex: 2 });
221
+ ```
222
+
223
+ ## Error Handling
224
+
225
+ ```javascript
226
+ try {
227
+ const result = await transactionManager.sendXec(recipients);
228
+
229
+ if (result.success) {
230
+ console.log(`Transaction successful: ${result.txid}`);
231
+ } else {
232
+ console.error(`Transaction failed: ${result.message}`);
233
+ }
234
+ } catch (error) {
235
+ console.error('Transaction error:', error.message);
236
+ }
237
+ ```
238
+
239
+ ## Requirements
240
+
241
+ - Node.js >= 18.0.0
242
+ - A valid eCash wallet mnemonic phrase
243
+ - Network access to eCash blockchain
244
+
245
+ ## License
246
+
247
+ MIT
248
+
249
+ ## Contributing
250
+
251
+ Contributions are welcome! Please feel free to submit a Pull Request.
252
+
253
+ ## Support
254
+
255
+ If you encounter any issues or have questions, please [open an issue](https://github.com/alitayin/quicksend/issues) on GitHub.
@@ -0,0 +1,4 @@
1
+ import { ChronikClient } from "chronik-client";
2
+ declare const chronik: ChronikClient;
3
+ export { chronik };
4
+ //# sourceMappingURL=chronik-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chronik-client.d.ts","sourceRoot":"","sources":["../../client/chronik-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAa/C,QAAA,MAAM,OAAO,EAAE,aAA8C,CAAC;AAE9D,OAAO,EAAE,OAAO,EAAE,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { ChronikClient } from "chronik-client";
2
+ // 定义多个Chronik节点
3
+ const chronikUrls = [
4
+ 'https://chronik-native2.fabien.cash',
5
+ 'https://chronik-native3.fabien.cash',
6
+ 'https://chronik.pay2stay.com/xec2',
7
+ 'https://chronik-native1.fabien.cash',
8
+ 'https://chronik1.alitayin.com',
9
+ 'https://chronik2.alitayin.com',
10
+ ];
11
+ // 创建共享的Chronik客户端实例,支持多个节点
12
+ const chronik = new ChronikClient(chronikUrls);
13
+ export { chronik };
14
+ //# sourceMappingURL=chronik-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chronik-client.js","sourceRoot":"","sources":["../../client/chronik-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,gBAAgB;AAChB,MAAM,WAAW,GAAa;IAC1B,qCAAqC;IACrC,qCAAqC;IACrC,mCAAmC;IACnC,qCAAqC;IACrC,+BAA+B;IAC/B,+BAA+B;CAClC,CAAC;AAEF,2BAA2B;AAC3B,MAAM,OAAO,GAAkB,IAAI,aAAa,CAAC,WAAW,CAAC,CAAC;AAE9D,OAAO,EAAE,OAAO,EAAE,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * 应用程序配置常量
3
+ */
4
+ export declare const CONFIG: {
5
+ MNEMONIC: string;
6
+ };
7
+ /**
8
+ * 获取助记词
9
+ */
10
+ export declare function getMnemonic(): string;
11
+ /**
12
+ * 获取钱包私钥WIF (从助记词派生)
13
+ * @param addressIndex - 地址索引,默认为0
14
+ */
15
+ export declare function getPrivateKeyWIF(addressIndex?: number): string;
16
+ /**
17
+ * 获取默认的 UTXO 地址 (从助记词派生)
18
+ * @param addressIndex - 地址索引,默认为0
19
+ */
20
+ export declare function getDefaultUtxoAddress(addressIndex?: number): string;
21
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../config/constants.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,eAAO,MAAM,MAAM;;CAGlB,CAAC;AAcF;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAKpC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,GAAE,MAAU,GAAG,MAAM,CAGjE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,GAAE,MAAU,GAAG,MAAM,CAGtE"}
@@ -0,0 +1,46 @@
1
+ import dotenv from 'dotenv';
2
+ import { deriveBuyerKey } from '../wallet/mnemonic-utils';
3
+ dotenv.config();
4
+ /**
5
+ * 应用程序配置常量
6
+ */
7
+ export const CONFIG = {
8
+ // 钱包配置 - 只需要助记词
9
+ MNEMONIC: process.env.MNEMONIC,
10
+ };
11
+ /**
12
+ * 验证必需的环境变量
13
+ */
14
+ function validateConfig() {
15
+ if (!CONFIG.MNEMONIC) {
16
+ throw new Error('必须设置 MNEMONIC 环境变量');
17
+ }
18
+ }
19
+ // 在模块加载时自动验证配置
20
+ validateConfig();
21
+ /**
22
+ * 获取助记词
23
+ */
24
+ export function getMnemonic() {
25
+ if (!CONFIG.MNEMONIC) {
26
+ throw new Error('助记词未设置');
27
+ }
28
+ return CONFIG.MNEMONIC;
29
+ }
30
+ /**
31
+ * 获取钱包私钥WIF (从助记词派生)
32
+ * @param addressIndex - 地址索引,默认为0
33
+ */
34
+ export function getPrivateKeyWIF(addressIndex = 0) {
35
+ const derived = deriveBuyerKey(CONFIG.MNEMONIC, addressIndex);
36
+ return derived.wif;
37
+ }
38
+ /**
39
+ * 获取默认的 UTXO 地址 (从助记词派生)
40
+ * @param addressIndex - 地址索引,默认为0
41
+ */
42
+ export function getDefaultUtxoAddress(addressIndex = 0) {
43
+ const derived = deriveBuyerKey(CONFIG.MNEMONIC, addressIndex);
44
+ return derived.address;
45
+ }
46
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../config/constants.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,gBAAgB;IAChB,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ;CAC/B,CAAC;AAEF;;GAEG;AACH,SAAS,cAAc;IACrB,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;AAED,eAAe;AACf,cAAc,EAAE,CAAC;AAEjB;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC;AACzB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,eAAuB,CAAC;IACvD,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,QAAS,EAAE,YAAY,CAAC,CAAC;IAC/D,OAAO,OAAO,CAAC,GAAG,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,eAAuB,CAAC;IAC5D,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,QAAS,EAAE,YAAY,CAAC,CAAC;IAC/D,OAAO,OAAO,CAAC,OAAO,CAAC;AACzB,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { Recipient, TransactionResult, TokenTransactionOptions, XecOptions, GeneralSendOptions, TransactionType } from './types';
2
+ /**
3
+ * 统一交易管理器
4
+ * 支持 SLP、ALP 和 XEC 交易类型
5
+ */
6
+ declare class TransactionManager {
7
+ /**
8
+ * 发送 SLP 代币
9
+ * @param recipients - 接收方数组
10
+ * @param options - 交易选项
11
+ */
12
+ sendSlp(recipients: Recipient[], options: TokenTransactionOptions): Promise<TransactionResult>;
13
+ /**
14
+ * 发送 ALP 代币
15
+ * @param recipients - 接收方数组
16
+ * @param options - 交易选项
17
+ */
18
+ sendAlp(recipients: Recipient[], options: TokenTransactionOptions): Promise<TransactionResult>;
19
+ /**
20
+ * 发送 XEC (eCash)
21
+ * @param recipients - 接收方数组
22
+ * @param options - UTXO选择策略字符串或包含utxoStrategy和addressIndex的选项对象
23
+ */
24
+ sendXec(recipients: Recipient[], options?: XecOptions): Promise<TransactionResult>;
25
+ /**
26
+ * 通用发送方法
27
+ * @param type - 交易类型
28
+ * @param recipients - 接收方数组
29
+ * @param options - 交易选项
30
+ */
31
+ send(type: TransactionType, recipients: Recipient[], options?: GeneralSendOptions): Promise<TransactionResult>;
32
+ }
33
+ declare const transactionManager: TransactionManager;
34
+ export default transactionManager;
35
+ export { TransactionManager };
36
+ export declare const sendSlp: (recipients: Recipient[], options: TokenTransactionOptions) => Promise<TransactionResult>, sendAlp: (recipients: Recipient[], options: TokenTransactionOptions) => Promise<TransactionResult>, sendXec: (recipients: Recipient[], options?: XecOptions) => Promise<TransactionResult>, send: (type: TransactionType, recipients: Recipient[], options?: GeneralSendOptions) => Promise<TransactionResult>;
37
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,uBAAuB,EACvB,UAAU,EAEV,kBAAkB,EAClB,eAAe,EAChB,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AACH,cAAM,kBAAkB;IACtB;;;;OAIG;IACG,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAIpG;;;;OAIG;IACG,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAIpG;;;;OAIG;IACG,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,OAAO,GAAE,UAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAgB/F;;;;;OAKG;IACG,IAAI,CAAC,IAAI,EAAE,eAAe,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAkCzH;AAGD,QAAA,MAAM,kBAAkB,oBAA2B,CAAC;AAGpD,eAAe,kBAAkB,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAG9B,eAAO,MAAQ,OAAO,eApFM,SAAS,EAAE,WAAW,uBAAuB,KAAG,OAAO,CAAC,iBAAiB,CAAC,EAoF9E,OAAO,eA3EH,SAAS,EAAE,WAAW,uBAAuB,KAAG,OAAO,CAAC,iBAAiB,CAAC,EA2ErE,OAAO,eAlEZ,SAAS,EAAE,YAAW,UAAU,KAAW,OAAO,CAAC,iBAAiB,CAAC,EAkEvD,IAAI,SA5C3B,eAAe,cAAc,SAAS,EAAE,YAAW,kBAAkB,KAAQ,OAAO,CAAC,iBAAiB,CA4CpD,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,91 @@
1
+ import { createRawSlpTransaction, createRawAlpTransaction } from './send/tokensend';
2
+ import { createRawXecTransaction } from './send/xecsend.js';
3
+ /**
4
+ * 统一交易管理器
5
+ * 支持 SLP、ALP 和 XEC 交易类型
6
+ */
7
+ class TransactionManager {
8
+ /**
9
+ * 发送 SLP 代币
10
+ * @param recipients - 接收方数组
11
+ * @param options - 交易选项
12
+ */
13
+ async sendSlp(recipients, options) {
14
+ return await createRawSlpTransaction(recipients, options);
15
+ }
16
+ /**
17
+ * 发送 ALP 代币
18
+ * @param recipients - 接收方数组
19
+ * @param options - 交易选项
20
+ */
21
+ async sendAlp(recipients, options) {
22
+ return await createRawAlpTransaction(recipients, options);
23
+ }
24
+ /**
25
+ * 发送 XEC (eCash)
26
+ * @param recipients - 接收方数组
27
+ * @param options - UTXO选择策略字符串或包含utxoStrategy和addressIndex的选项对象
28
+ */
29
+ async sendXec(recipients, options = 'all') {
30
+ // 如果options是对象,提取相关参数;否则直接使用options作为策略
31
+ let utxoStrategy;
32
+ let addressIndex;
33
+ if (typeof options === 'object' && options !== null) {
34
+ utxoStrategy = options.utxoStrategy || 'all';
35
+ addressIndex = options.addressIndex || 0;
36
+ }
37
+ else {
38
+ utxoStrategy = options;
39
+ addressIndex = 0;
40
+ }
41
+ return await createRawXecTransaction(recipients, utxoStrategy, addressIndex);
42
+ }
43
+ /**
44
+ * 通用发送方法
45
+ * @param type - 交易类型
46
+ * @param recipients - 接收方数组
47
+ * @param options - 交易选项
48
+ */
49
+ async send(type, recipients, options = {}) {
50
+ switch (type.toLowerCase()) {
51
+ case 'slp':
52
+ if (!options.tokenId || !options.tokenDecimals) {
53
+ throw new Error('SLP transactions require tokenId and tokenDecimals');
54
+ }
55
+ return await this.sendSlp(recipients, {
56
+ tokenId: options.tokenId,
57
+ tokenDecimals: options.tokenDecimals,
58
+ addressIndex: options.addressIndex,
59
+ feeStrategy: options.feeStrategy,
60
+ tokenStrategy: options.tokenStrategy
61
+ });
62
+ case 'alp':
63
+ if (!options.tokenId || !options.tokenDecimals) {
64
+ throw new Error('ALP transactions require tokenId and tokenDecimals');
65
+ }
66
+ return await this.sendAlp(recipients, {
67
+ tokenId: options.tokenId,
68
+ tokenDecimals: options.tokenDecimals,
69
+ addressIndex: options.addressIndex,
70
+ feeStrategy: options.feeStrategy,
71
+ tokenStrategy: options.tokenStrategy
72
+ });
73
+ case 'xec':
74
+ const xecOptions = {
75
+ utxoStrategy: options.utxoStrategy,
76
+ addressIndex: options.addressIndex
77
+ };
78
+ return await this.sendXec(recipients, xecOptions);
79
+ default:
80
+ throw new Error(`Unsupported transaction type: ${type}`);
81
+ }
82
+ }
83
+ }
84
+ // 创建单例实例
85
+ const transactionManager = new TransactionManager();
86
+ // 导出实例和类
87
+ export default transactionManager;
88
+ export { TransactionManager };
89
+ // 便捷方法导出
90
+ export const { sendSlp, sendAlp, sendXec, send } = transactionManager;
91
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { Recipient, TokenTransactionOptions, TransactionResult } from "../types";
2
+ /**
3
+ * 创建SLP代币交易
4
+ */
5
+ export declare function createRawSlpTransaction(recipients: Recipient[], options: TokenTransactionOptions): Promise<TransactionResult>;
6
+ /**
7
+ * 创建ALP代币交易
8
+ */
9
+ export declare function createRawAlpTransaction(recipients: Recipient[], options: TokenTransactionOptions): Promise<TransactionResult>;
10
+ //# sourceMappingURL=tokensend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokensend.d.ts","sourceRoot":"","sources":["../../send/tokensend.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,SAAS,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAsKjF;;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"}
@@ -0,0 +1,121 @@
1
+ import dotenv from "dotenv";
2
+ dotenv.config();
3
+ import ecashLib from "ecash-lib";
4
+ import { getUtxos, selectSlpUtxos } from "../utxo/utxo-utils";
5
+ import { initializeWallet } from "../wallet/wallet-utils";
6
+ import { buildTransactionInputs, createP2pkhScript } from "../transaction/transaction-utils";
7
+ import { buildAndBroadcastTransaction, validateRequiredParams, logTransactionSummary } from "../transaction/transaction-builder";
8
+ const { Script, SLP_FUNGIBLE, slpSend, ALP_STANDARD, alpSend, OP_RETURN, pushBytesOp, OP_RESERVED, } = ecashLib;
9
+ /**
10
+ * 构建SLP交易输出
11
+ */
12
+ function buildSlpOutputs(tokenId, finalSendAmounts, recipients, tokenChange, dustLimit, walletP2pkh) {
13
+ const outputs = [];
14
+ // OP_RETURN 输出
15
+ outputs.push({ sats: 0n, script: slpSend(tokenId, SLP_FUNGIBLE, finalSendAmounts) });
16
+ // 接收方输出
17
+ recipients.forEach(recipient => {
18
+ outputs.push({
19
+ sats: BigInt(dustLimit),
20
+ script: createP2pkhScript(recipient.address)
21
+ });
22
+ });
23
+ // Token 找零输出
24
+ if (tokenChange > 0n) {
25
+ outputs.push({ sats: BigInt(dustLimit), script: walletP2pkh });
26
+ }
27
+ // 手续费找零脚本 - 保持原始逻辑!直接push脚本
28
+ outputs.push(walletP2pkh);
29
+ return outputs;
30
+ }
31
+ /**
32
+ * 构建ALP交易输出
33
+ */
34
+ function buildAlpOutputs(tokenId, finalSendAmounts, recipients, tokenChange, dustLimit, walletP2pkh) {
35
+ const outputs = [];
36
+ // 构造完整的 OP_RETURN 脚本
37
+ const opReturnPayload = alpSend(tokenId, ALP_STANDARD, finalSendAmounts);
38
+ const opReturnScript = Script.fromOps([
39
+ OP_RETURN,
40
+ OP_RESERVED,
41
+ pushBytesOp(opReturnPayload)
42
+ ]);
43
+ // OP_RETURN 输出
44
+ outputs.push({ sats: 0n, script: opReturnScript });
45
+ // 接收方输出
46
+ recipients.forEach(recipient => {
47
+ outputs.push({
48
+ sats: BigInt(dustLimit),
49
+ script: createP2pkhScript(recipient.address)
50
+ });
51
+ });
52
+ // Token 找零输出
53
+ if (tokenChange > 0n) {
54
+ outputs.push({ sats: BigInt(dustLimit), script: walletP2pkh });
55
+ }
56
+ // 手续费找零脚本 - 保持原始逻辑!直接push脚本
57
+ outputs.push(walletP2pkh);
58
+ return outputs;
59
+ }
60
+ /**
61
+ * 创建代币交易的通用函数
62
+ */
63
+ async function createTokenTransaction(recipients, options, tokenType = 'SLP') {
64
+ try {
65
+ // 验证必需参数
66
+ validateRequiredParams(options, [
67
+ { key: 'tokenId', message: 'tokenId is required' },
68
+ { key: 'tokenDecimals', message: 'tokenDecimals is required', checkUndefined: true }
69
+ ]);
70
+ const { tokenId, tokenDecimals, addressIndex = 0, feeStrategy = 'all', tokenStrategy = 'all' } = options;
71
+ // 初始化钱包 - 使用指定的地址索引
72
+ const { walletSk, walletPk, walletP2pkh, address: utxoAddress } = initializeWallet(addressIndex);
73
+ const utxos = await getUtxos(utxoAddress);
74
+ if (utxos.length === 0) {
75
+ throw new Error(`No UTXOs found for address index ${addressIndex}`);
76
+ }
77
+ // 选择代币UTXOs
78
+ const tokenSelection = selectSlpUtxos(utxos, tokenId, recipients, tokenDecimals, {
79
+ feeStrategy: feeStrategy,
80
+ tokenStrategy: tokenStrategy
81
+ });
82
+ const { selectedTokenUtxos, selectedFeeUtxos, finalSendAmounts, tokenChange, dustLimit, summary } = tokenSelection;
83
+ // 记录交易摘要
84
+ logTransactionSummary(tokenType, {
85
+ 地址索引: addressIndex,
86
+ 代币UTXOs数量: selectedTokenUtxos.length,
87
+ 手续费UTXOs数量: selectedFeeUtxos.length,
88
+ 接收方数量: recipients.length,
89
+ 代币找零: tokenChange > 0n ? tokenChange.toString() : '无',
90
+ 总输出数量: summary.totalOutputs
91
+ });
92
+ // 构建交易输入和输出
93
+ const inputs = buildTransactionInputs([selectedTokenUtxos, selectedFeeUtxos], walletP2pkh, walletSk, walletPk);
94
+ let outputs;
95
+ if (tokenType === 'ALP') {
96
+ outputs = buildAlpOutputs(tokenId, finalSendAmounts, recipients, tokenChange, dustLimit, walletP2pkh);
97
+ }
98
+ else {
99
+ outputs = buildSlpOutputs(tokenId, finalSendAmounts, recipients, tokenChange, dustLimit, walletP2pkh);
100
+ }
101
+ // 构建并广播交易
102
+ return await buildAndBroadcastTransaction(inputs, outputs, { dustLimit });
103
+ }
104
+ catch (error) {
105
+ console.error(`${tokenType} transaction creation failed:`, error);
106
+ throw error;
107
+ }
108
+ }
109
+ /**
110
+ * 创建SLP代币交易
111
+ */
112
+ export async function createRawSlpTransaction(recipients, options) {
113
+ return createTokenTransaction(recipients, options, 'SLP');
114
+ }
115
+ /**
116
+ * 创建ALP代币交易
117
+ */
118
+ export async function createRawAlpTransaction(recipients, options) {
119
+ return createTokenTransaction(recipients, options, 'ALP');
120
+ }
121
+ //# sourceMappingURL=tokensend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokensend.js","sourceRoot":"","sources":["../../send/tokensend.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,OAAO,QAAQ,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC7F,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACtB,qBAAqB,EACtB,MAAM,oCAAoC,CAAC;AAI5C,MAAM,EACJ,MAAM,EACN,YAAY,EACZ,OAAO,EACP,YAAY,EACZ,OAAO,EACP,SAAS,EACT,WAAW,EACX,WAAW,GACZ,GAAG,QAAQ,CAAC;AAEb;;GAEG;AACH,SAAS,eAAe,CACtB,OAAe,EACf,gBAA0B,EAC1B,UAAuB,EACvB,WAAmB,EACnB,SAAiB,EACjB,WAAgB;IAEhB,MAAM,OAAO,GAAU,EAAE,CAAC;IAE1B,eAAe;IACf,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE,YAAY,EAAE,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAErF,QAAQ;IACR,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;QAC7B,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC;YACvB,MAAM,EAAE,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC;SAC7C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,aAAa;IACb,IAAI,WAAW,GAAG,EAAE,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,4BAA4B;IAC5B,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAE1B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CACtB,OAAe,EACf,gBAA0B,EAC1B,UAAuB,EACvB,WAAmB,EACnB,SAAiB,EACjB,WAAgB;IAEhB,MAAM,OAAO,GAAU,EAAE,CAAC;IAE1B,qBAAqB;IACrB,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,EAAE,YAAY,EAAE,gBAAgB,CAAC,CAAC;IACzE,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC;QACpC,SAAS;QACT,WAAW;QACX,WAAW,CAAC,eAAe,CAAC;KAC7B,CAAC,CAAC;IAEH,eAAe;IACf,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;IAEnD,QAAQ;IACR,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;QAC7B,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC;YACvB,MAAM,EAAE,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC;SAC7C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,aAAa;IACb,IAAI,WAAW,GAAG,EAAE,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,4BAA4B;IAC5B,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAE1B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,sBAAsB,CACnC,UAAuB,EACvB,OAAgC,EAChC,YAA2B,KAAK;IAEhC,IAAI,CAAC;QACH,SAAS;QACT,sBAAsB,CAAC,OAAO,EAAE;YAC9B,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,qBAAqB,EAAE;YAClD,EAAE,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,2BAA2B,EAAE,cAAc,EAAE,IAAI,EAAE;SACrF,CAAC,CAAC;QAEH,MAAM,EACJ,OAAO,EACP,aAAa,EACb,YAAY,GAAG,CAAC,EAChB,WAAW,GAAG,KAAK,EACnB,aAAa,GAAG,KAAK,EACtB,GAAG,OAAO,CAAC;QAEZ,oBAAoB;QACpB,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAC,YAAY,CAAC,CAAC;QAEjG,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC1C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,oCAAoC,YAAY,EAAE,CAAC,CAAC;QACtE,CAAC;QAED,YAAY;QACZ,MAAM,cAAc,GAAG,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE;YAC/E,WAAW,EAAE,WAAkB;YAC/B,aAAa,EAAE,aAAoB;SACpC,CAAC,CAAC;QAEH,MAAM,EACJ,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,OAAO,EACR,GAAG,cAAc,CAAC;QAEnB,SAAS;QACT,qBAAqB,CAAC,SAAS,EAAE;YAC/B,IAAI,EAAE,YAAY;YAClB,SAAS,EAAE,kBAAkB,CAAC,MAAM;YACpC,UAAU,EAAE,gBAAgB,CAAC,MAAM;YACnC,KAAK,EAAE,UAAU,CAAC,MAAM;YACxB,IAAI,EAAE,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,GAAG;YACrD,KAAK,EAAE,OAAO,CAAC,YAAY;SAC5B,CAAC,CAAC;QAEH,YAAY;QACZ,MAAM,MAAM,GAAG,sBAAsB,CAAC,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAE/G,IAAI,OAAc,CAAC;QACnB,IAAI,SAAS,KAAK,KAAK,EAAE,CAAC;YACxB,OAAO,GAAG,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;QACxG,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;QACxG,CAAC;QAED,UAAU;QACV,OAAO,MAAM,4BAA4B,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IAE5E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,GAAG,SAAS,+BAA+B,EAAE,KAAK,CAAC,CAAC;QAClE,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,UAAuB,EAAE,OAAgC;IACrG,OAAO,sBAAsB,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;AAC5D,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,UAAuB,EAAE,OAAgC;IACrG,OAAO,sBAAsB,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;AAC5D,CAAC"}