@teleportdao/bitcoin 2.0.5 → 2.0.8

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 (90) hide show
  1. package/dist/bitcoin-interface-ordinal.d.ts +108 -108
  2. package/dist/bitcoin-interface-ordinal.js +140 -140
  3. package/dist/bitcoin-interface-teleswap.d.ts +83 -101
  4. package/dist/bitcoin-interface-teleswap.d.ts.map +1 -1
  5. package/dist/bitcoin-interface-teleswap.js +119 -176
  6. package/dist/bitcoin-interface-teleswap.js.map +1 -1
  7. package/dist/bitcoin-interface-utils.d.ts +20 -20
  8. package/dist/bitcoin-interface-utils.js +45 -45
  9. package/dist/bitcoin-interface-wallet.d.ts +29 -28
  10. package/dist/bitcoin-interface-wallet.d.ts.map +1 -1
  11. package/dist/bitcoin-interface-wallet.js +126 -125
  12. package/dist/bitcoin-interface-wallet.js.map +1 -1
  13. package/dist/bitcoin-interface.d.ts +63 -66
  14. package/dist/bitcoin-interface.d.ts.map +1 -1
  15. package/dist/bitcoin-interface.js +112 -119
  16. package/dist/bitcoin-interface.js.map +1 -1
  17. package/dist/bitcoin-utils.d.ts +96 -96
  18. package/dist/bitcoin-utils.js +514 -514
  19. package/dist/bitcoin-wallet-base.d.ts +111 -111
  20. package/dist/bitcoin-wallet-base.d.ts.map +1 -1
  21. package/dist/bitcoin-wallet-base.js +258 -258
  22. package/dist/helper/brc20-helper.d.ts +42 -42
  23. package/dist/helper/brc20-helper.js +127 -127
  24. package/dist/helper/index.d.ts +3 -3
  25. package/dist/helper/index.js +29 -29
  26. package/dist/helper/ordinal-helper.d.ts +12 -12
  27. package/dist/helper/ordinal-helper.js +129 -129
  28. package/dist/helper/teleswap-helper.d.ts +95 -95
  29. package/dist/helper/teleswap-helper.js +186 -186
  30. package/dist/index.d.ts +12 -12
  31. package/dist/index.js +41 -41
  32. package/dist/ordinal-wallet.d.ts +492 -495
  33. package/dist/ordinal-wallet.d.ts.map +1 -1
  34. package/dist/ordinal-wallet.js +386 -386
  35. package/dist/ordinal-wallet.js.map +1 -1
  36. package/dist/sign/index.d.ts +1 -1
  37. package/dist/sign/index.js +8 -8
  38. package/dist/sign/sign-transaction.d.ts +12 -12
  39. package/dist/sign/sign-transaction.js +82 -82
  40. package/dist/teleswap-wallet.d.ts +45 -45
  41. package/dist/teleswap-wallet.js +68 -68
  42. package/dist/transaction-builder/bitcoin-transaction-builder.d.ts +9 -9
  43. package/dist/transaction-builder/bitcoin-transaction-builder.d.ts.map +1 -1
  44. package/dist/transaction-builder/bitcoin-transaction-builder.js +54 -54
  45. package/dist/transaction-builder/bitcoin-transaction-builder.js.map +1 -1
  46. package/dist/transaction-builder/index.d.ts +3 -3
  47. package/dist/transaction-builder/index.js +19 -19
  48. package/dist/transaction-builder/ordinal-transaction-builder.d.ts +63 -63
  49. package/dist/transaction-builder/ordinal-transaction-builder.js +125 -125
  50. package/dist/transaction-builder/transaction-builder.d.ts +223 -223
  51. package/dist/transaction-builder/transaction-builder.d.ts.map +1 -1
  52. package/dist/transaction-builder/transaction-builder.js +442 -447
  53. package/dist/transaction-builder/transaction-builder.js.map +1 -1
  54. package/dist/type.d.ts +55 -61
  55. package/dist/type.d.ts.map +1 -1
  56. package/dist/type.js +2 -2
  57. package/dist/utils/networks.d.ts +5 -5
  58. package/dist/utils/networks.js +53 -53
  59. package/dist/utils/tools.d.ts +18 -18
  60. package/dist/utils/tools.js +74 -74
  61. package/package.json +4 -4
  62. package/src/bitcoin-interface-ordinal.ts +185 -185
  63. package/src/bitcoin-interface-teleswap.ts +246 -251
  64. package/src/bitcoin-interface-utils.ts +60 -60
  65. package/src/bitcoin-interface-wallet.ts +112 -114
  66. package/src/bitcoin-interface.ts +146 -156
  67. package/src/bitcoin-utils.ts +591 -591
  68. package/src/bitcoin-wallet-base.ts +344 -344
  69. package/src/helper/brc20-helper.ts +179 -179
  70. package/src/helper/ordinal-helper.ts +118 -118
  71. package/src/index.ts +15 -15
  72. package/src/ordinal-wallet.ts +654 -659
  73. package/src/sign/index.ts +1 -1
  74. package/src/sign/sign-transaction.ts +108 -108
  75. package/src/teleswap-wallet.ts +133 -133
  76. package/src/transaction-builder/bitcoin-transaction-builder.ts +26 -26
  77. package/src/transaction-builder/index.ts +3 -3
  78. package/src/transaction-builder/ordinal-transaction-builder.ts +139 -139
  79. package/src/transaction-builder/transaction-builder.ts +686 -690
  80. package/src/type.ts +64 -74
  81. package/src/utils/networks.ts +33 -33
  82. package/src/utils/tools.ts +92 -92
  83. package/tsconfig.json +9 -9
  84. package/webpack.config.js +16 -16
  85. package/.tmp/block-parser.ts +0 -58
  86. package/.tmp/check.ts +0 -101
  87. package/.tmp/ordinal-helper.ts +0 -133
  88. package/.tmp/ordinal.ts +0 -25
  89. package/.tmp/psbt/sign-transaction.ts +0 -121
  90. package/.tmp/rbf.ts +0 -45
@@ -1,448 +1,443 @@
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 (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
- return new (P || (P = Promise))(function (resolve, reject) {
28
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
- step((generator = generator.apply(thisArg, _arguments || [])).next());
32
- });
33
- };
34
- Object.defineProperty(exports, "__esModule", { value: true });
35
- exports.BaseTransactionBuilder = exports.DUST = exports.componentBytes = void 0;
36
- const bitcoin = __importStar(require("bitcoinjs-lib"));
37
- const bitcoin_utils_1 = require("../bitcoin-utils");
38
- const coinselect = require("coinselect");
39
- const coinselectSplit = require("coinselect/split");
40
- const coinselectAccumulative = require("coinselect/accumulative");
41
- exports.componentBytes = {
42
- bytePerInput: {
43
- p2pkh: 148,
44
- p2wpkh: 68,
45
- "p2sh-p2wpkh": 91,
46
- p2tr: 58,
47
- default: 100,
48
- },
49
- baseTxBytes: 10 + 5,
50
- bytePerOutput: {
51
- p2pkh: 34,
52
- p2wpkh: 31,
53
- p2sh: 32,
54
- p2tr: 43,
55
- default: 35,
56
- max: 45,
57
- },
58
- scriptExtraBytes: {
59
- lessThan255: 12,
60
- moreThan255: 15,
61
- },
62
- };
63
- exports.DUST = 1000;
64
- function coinSelectInOrder(utxos, outputs, feeRate) {
65
- let response = coinselectAccumulative(utxos, outputs, 1);
66
- return Object.assign(Object.assign({}, response), { fee: +(+response.fee * feeRate).toFixed() });
67
- }
68
- class BaseTransactionBuilder {
69
- constructor({ network, testnet, feeMin = 0, dustLimit, maximumNumberOfOutputsInTransaction = 50, }) {
70
- this.testnet = testnet;
71
- this.network = network;
72
- this.maximumNumberOfOutputsInTransaction = maximumNumberOfOutputsInTransaction;
73
- this.feeMin = feeMin;
74
- this.dustLimit = dustLimit || 1 * 2 * exports.componentBytes.bytePerInput.p2pkh;
75
- }
76
- _getTransactionHex(transactionId) {
77
- return __awaiter(this, void 0, void 0, function* () {
78
- throw new Error("Do not call abstract method directly");
79
- });
80
- }
81
- createAddressObject(input) {
82
- return (0, bitcoin_utils_1.createAddressObjectByPublicKey)(input, this.network);
83
- }
84
- validateAddress(address) {
85
- try {
86
- (0, bitcoin_utils_1.getAddressType)(address, this.network);
87
- return true;
88
- }
89
- catch (error) {
90
- return false;
91
- }
92
- }
93
- getOpReturnTarget(dataHex) {
94
- if (!(dataHex.length > 0))
95
- throw new Error("invalid data in hex");
96
- const embed = bitcoin.payments.embed({
97
- data: [Buffer.from(dataHex, "hex")],
98
- network: this.network,
99
- });
100
- return {
101
- script: embed.output,
102
- value: 0,
103
- };
104
- }
105
- calculateTxSize(inputTypes, outputs, changeAddressType = "default") {
106
- const inputsSizes = inputTypes.map((addressType) => exports.componentBytes.bytePerInput[addressType]);
107
- const outputSizes = outputs.map((outP) => {
108
- if (outP.address) {
109
- let addressType = "default";
110
- try {
111
- addressType = (0, bitcoin_utils_1.getAddressType)(outP.address, this.network);
112
- }
113
- catch (_a) {
114
- addressType = "default";
115
- }
116
- return exports.componentBytes.bytePerOutput[addressType];
117
- }
118
- if (outP.script) {
119
- if (outP.script.byteLength < 255) {
120
- return outP.script.byteLength + exports.componentBytes.scriptExtraBytes.lessThan255;
121
- }
122
- return outP.script.byteLength + exports.componentBytes.scriptExtraBytes.moreThan255;
123
- }
124
- return exports.componentBytes.bytePerOutput[changeAddressType];
125
- });
126
- const txSize = exports.componentBytes.baseTxBytes +
127
- inputsSizes.reduce((a, c) => a + c, 0) +
128
- outputSizes.reduce((a, c) => a + c, 0);
129
- return txSize;
130
- }
131
- helperHandleInputsAndOutputs({ targets, extendedUtxo, feeRate, changeObject, selectType = "normal", }) {
132
- const filteredUtxo = extendedUtxo.filter((u) => u.value >
133
- +feeRate *
134
- exports.componentBytes.bytePerInput[u.signerInfo.addressType]);
135
- let selectResponse;
136
- switch (selectType) {
137
- case "normal":
138
- selectResponse = coinselect(filteredUtxo, targets, Math.round(feeRate));
139
- break;
140
- case "accumulative":
141
- selectResponse = coinselectAccumulative(filteredUtxo, targets, Math.round(feeRate));
142
- break;
143
- case "inOrder":
144
- selectResponse = coinSelectInOrder(filteredUtxo, targets, Math.round(feeRate));
145
- break;
146
- case "full":
147
- if (!targets[0].address) {
148
- throw new Error();
149
- }
150
- selectResponse = coinselectSplit(filteredUtxo, [{ address: targets[0].address }], Math.round(feeRate));
151
- break;
152
- default:
153
- break;
154
- }
155
- let { inputs, outputs, fee, } = selectResponse;
156
- if (!inputs || !outputs) {
157
- inputs = filteredUtxo;
158
- outputs = targets;
159
- fee = inputs.reduce((a, b) => a + b.value, 0) - outputs.reduce((a, b) => a + b.value, 0);
160
- }
161
- let changeAddressType = "default";
162
- try {
163
- changeAddressType = (0, bitcoin_utils_1.getAddressType)((changeObject === null || changeObject === void 0 ? void 0 : changeObject.address) || "", this.network);
164
- }
165
- catch (_a) {
166
- changeAddressType = "default";
167
- }
168
- const txSize = this.calculateTxSize(inputs.map((i) => i.signerInfo.addressType), outputs, changeAddressType) + exports.componentBytes.bytePerOutput.default;
169
- let txFee = Math.round(txSize * feeRate);
170
- if (Math.round(feeRate) === 1) {
171
- txFee = Math.round(txFee + txFee * 0.1);
172
- }
173
- if (inputs.reduce((a, b) => a + b.value, 0) -
174
- outputs.filter((o) => o.address || o.script).reduce((a, b) => a + b.value, 0) -
175
- txFee <
176
- 0) {
177
- let spendableBalance = inputs.reduce((a, b) => a + b.value, 0);
178
- let totalOutputAmount = outputs
179
- .filter((o) => o.address || o.script)
180
- .reduce((a, b) => a + b.value, 0);
181
- let need = spendableBalance - totalOutputAmount - txFee;
182
- throw new Error(`not enough balance. details: ${JSON.stringify({ spendableBalance, totalOutputAmount, txFee, need }, null, 2)}`);
183
- }
184
- let diff = fee - txFee;
185
- let changeIndex = outputs.findIndex((x) => !(x === null || x === void 0 ? void 0 : x.address) && !x.script && (x.value || 0) > 0);
186
- let change;
187
- if (changeIndex >= 0 || diff > exports.DUST) {
188
- if (changeIndex >= 0) {
189
- diff = diff + exports.componentBytes.bytePerOutput.default * Math.round(feeRate);
190
- }
191
- if (diff < 0) {
192
- diff = 0;
193
- }
194
- if (selectType === "full") {
195
- outputs[0].value = outputs[0].value + diff;
196
- fee = fee - diff;
197
- }
198
- else {
199
- if (!changeObject)
200
- throw new Error("change not exist");
201
- change = {
202
- address: changeObject.address,
203
- value: changeIndex >= 0 ? outputs[changeIndex].value + diff : diff,
204
- };
205
- fee = fee - diff;
206
- }
207
- if (changeIndex >= 0) {
208
- outputs.splice(changeIndex, 1);
209
- }
210
- }
211
- return {
212
- inputs,
213
- fee,
214
- outputs: outputs,
215
- change,
216
- };
217
- }
218
- filterAndConvertTxDataToStandardFormat({ extendedUtxo, targets, changeObject, feeRate, selectType, }) {
219
- return __awaiter(this, void 0, void 0, function* () {
220
- let { inputs: filteredInputs, outputs, change, fee, } = this.helperHandleInputsAndOutputs({
221
- targets,
222
- extendedUtxo,
223
- feeRate,
224
- changeObject,
225
- selectType,
226
- });
227
- let inputs = yield this.convertExtendedUtxoToInputs(filteredInputs);
228
- return {
229
- inputs,
230
- outputs,
231
- change,
232
- fee,
233
- feeRate,
234
- };
235
- });
236
- }
237
- convertExtendedUtxoToInputs(baseInputs = []) {
238
- var _a;
239
- return __awaiter(this, void 0, void 0, function* () {
240
- let inputs = baseInputs;
241
- const transactionHex = {};
242
- for (let i in inputs) {
243
- let { address, publicKey, derivationPath, masterFingerprint, addressType } = inputs[i].signerInfo;
244
- let addressObject = this.createAddressObject({
245
- publicKey: Buffer.from(publicKey, "hex"),
246
- addressType,
247
- });
248
- if (derivationPath && masterFingerprint && addressObject.pubkey) {
249
- inputs[i].bip32Derivation = [
250
- {
251
- path: derivationPath,
252
- pubkey: addressObject.pubkey,
253
- masterFingerprint: Buffer.from(masterFingerprint, "hex"),
254
- },
255
- ];
256
- }
257
- if (addressType === "p2pkh") {
258
- const txHex = transactionHex[inputs[i].hash] || (yield this._getTransactionHex(inputs[i].hash));
259
- transactionHex[inputs[i].hash] = txHex;
260
- inputs[i].nonWitnessUtxo = Buffer.from(txHex, "hex");
261
- }
262
- else if (addressType === "p2wpkh") {
263
- if (!addressObject.output)
264
- throw new Error("invalid signer info");
265
- inputs[i].witnessUtxo = {
266
- script: addressObject.output,
267
- value: inputs[i].value,
268
- };
269
- if (inputs[i].signerInfo.includeHex) {
270
- const txHex = transactionHex[inputs[i].hash] || (yield this._getTransactionHex(inputs[i].hash));
271
- transactionHex[inputs[i].hash] = txHex;
272
- inputs[i].nonWitnessUtxo = Buffer.from(txHex, "hex");
273
- }
274
- }
275
- else if (addressType === "p2sh-p2wpkh") {
276
- if (!addressObject.output)
277
- throw new Error("invalid signer info");
278
- inputs[i].witnessUtxo = {
279
- script: addressObject.output,
280
- value: inputs[i].value,
281
- };
282
- if (!((_a = addressObject === null || addressObject === void 0 ? void 0 : addressObject.redeem) === null || _a === void 0 ? void 0 : _a.output))
283
- throw new Error("invalid signer info for p2sh address");
284
- inputs[i].redeemScript = addressObject.redeem.output;
285
- if (inputs[i].signerInfo.includeHex) {
286
- const txHex = transactionHex[inputs[i].hash] || (yield this._getTransactionHex(inputs[i].hash));
287
- transactionHex[inputs[i].hash] = txHex;
288
- inputs[i].nonWitnessUtxo = Buffer.from(txHex, "hex");
289
- }
290
- }
291
- else if (addressType === "p2tr") {
292
- if (!addressObject.output)
293
- throw new Error("invalid signer info");
294
- inputs[i].witnessUtxo = {
295
- script: addressObject.output,
296
- value: inputs[i].value,
297
- };
298
- if (!addressObject.pubkey)
299
- throw new Error("invalid signer info for p2tr address (pubkey)");
300
- inputs[i].tapInternalKey = addressObject.internalPubkey;
301
- if (inputs[i].signerInfo.includeHex) {
302
- const txHex = transactionHex[inputs[i].hash] || (yield this._getTransactionHex(inputs[i].hash));
303
- transactionHex[inputs[i].hash] = txHex;
304
- inputs[i].nonWitnessUtxo = Buffer.from(txHex, "hex");
305
- }
306
- }
307
- }
308
- return inputs;
309
- });
310
- }
311
- createUnsignedTransaction({ inputs, outputs, change, fee, feeRate, }) {
312
- const sequence = 0xffffffff - 2;
313
- const { network } = this;
314
- const newPsbt = new bitcoin.Psbt({ network });
315
- newPsbt.setMaximumFeeRate(+(feeRate + feeRate / 100).toFixed());
316
- for (const input of inputs) {
317
- let { addressType } = input.signerInfo;
318
- switch (addressType) {
319
- case "p2pkh": {
320
- let i = {
321
- hash: input.hash,
322
- index: Number(input.index),
323
- nonWitnessUtxo: input.nonWitnessUtxo,
324
- sequence,
325
- bip32Derivation: input.bip32Derivation,
326
- };
327
- if (!i.bip32Derivation)
328
- delete i.bip32Derivation;
329
- newPsbt.addInput(i);
330
- break;
331
- }
332
- case "p2wpkh": {
333
- let i = {
334
- hash: input.hash,
335
- index: Number(input.index),
336
- witnessUtxo: input.witnessUtxo,
337
- nonWitnessUtxo: input.nonWitnessUtxo,
338
- sequence,
339
- bip32Derivation: input.bip32Derivation,
340
- };
341
- if (!i.bip32Derivation)
342
- delete i.bip32Derivation;
343
- if (!i.nonWitnessUtxo)
344
- delete i.nonWitnessUtxo;
345
- newPsbt.addInput(i);
346
- break;
347
- }
348
- case "p2sh-p2wpkh": {
349
- let i = {
350
- hash: input.hash,
351
- index: Number(input.index),
352
- witnessUtxo: input.witnessUtxo,
353
- nonWitnessUtxo: input.nonWitnessUtxo,
354
- redeemScript: input.redeemScript,
355
- sequence,
356
- bip32Derivation: input.bip32Derivation,
357
- };
358
- if (!i.bip32Derivation)
359
- delete i.bip32Derivation;
360
- if (!i.nonWitnessUtxo)
361
- delete i.nonWitnessUtxo;
362
- newPsbt.addInput(i);
363
- break;
364
- }
365
- case "p2tr": {
366
- let i = {
367
- hash: input.hash,
368
- index: Number(input.index),
369
- witnessUtxo: input.witnessUtxo,
370
- nonWitnessUtxo: input.nonWitnessUtxo,
371
- tapInternalKey: input.tapInternalKey,
372
- sequence,
373
- bip32Derivation: input.bip32Derivation,
374
- };
375
- if (!i.bip32Derivation)
376
- delete i.bip32Derivation;
377
- if (!i.nonWitnessUtxo)
378
- delete i.nonWitnessUtxo;
379
- newPsbt.addInput(i);
380
- break;
381
- }
382
- default:
383
- throw new Error("address type is incorrect");
384
- }
385
- }
386
- for (const target of outputs) {
387
- newPsbt.addOutput(target);
388
- }
389
- if (change && Object.keys(change).length !== 0) {
390
- newPsbt.addOutput(change);
391
- }
392
- if (change && Object.keys(change).length !== 0) {
393
- if (newPsbt.txOutputs[outputs.length].address !== change.address) {
394
- throw new Error("error change address");
395
- }
396
- }
397
- const unsignedPsbtBaseText = newPsbt.toBase64();
398
- const safeAddressTypeForPossibleTxId = ["p2wpkh", "p2tr"];
399
- const isPossibleTxId = inputs.reduce((a, b) => a && safeAddressTypeForPossibleTxId.includes(b.signerInfo.addressType), true);
400
- return {
401
- unsignedTransaction: unsignedPsbtBaseText,
402
- outputs,
403
- inputs: inputs.map((utx) => ({
404
- hash: utx.hash,
405
- value: Number(utx.value),
406
- index: utx.index,
407
- signerInfo: utx.signerInfo,
408
- })),
409
- fee,
410
- change,
411
- possibleTxId: isPossibleTxId ? this.getUnsignedPsbtTxId(unsignedPsbtBaseText) : undefined,
412
- };
413
- }
414
- processUnsignedTransaction({ extendedUtxo, targets = [], changeAddress = undefined, fullAmount = false, feeRate, selectType = "normal", }) {
415
- return __awaiter(this, void 0, void 0, function* () {
416
- if (!changeAddress && targets.length === 0)
417
- throw new Error("no target");
418
- let changeObject = typeof changeAddress === "string"
419
- ? {
420
- address: changeAddress,
421
- }
422
- : changeAddress;
423
- const { inputs, outputs, change, fee } = yield this.filterAndConvertTxDataToStandardFormat({
424
- extendedUtxo,
425
- targets,
426
- changeObject,
427
- feeRate,
428
- selectType: fullAmount ? "full" : selectType,
429
- });
430
- let unsignedTransaction = this.createUnsignedTransaction({
431
- inputs,
432
- outputs,
433
- change,
434
- fee,
435
- feeRate,
436
- });
437
- return unsignedTransaction;
438
- });
439
- }
440
- getUnsignedPsbtTxId(unsignedPsbt) {
441
- let psbt = bitcoin.Psbt.fromBase64(unsignedPsbt, {
442
- network: this.network,
443
- });
444
- return psbt.__CACHE.__TX.getId();
445
- }
446
- }
447
- exports.BaseTransactionBuilder = BaseTransactionBuilder;
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 (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ exports.BaseTransactionBuilder = exports.DUST = exports.componentBytes = void 0;
36
+ const bitcoin = __importStar(require("bitcoinjs-lib"));
37
+ const bitcoin_utils_1 = require("../bitcoin-utils");
38
+ const coinselect = require("coinselect");
39
+ const coinselectSplit = require("coinselect/split");
40
+ const coinselectAccumulative = require("coinselect/accumulative");
41
+ exports.componentBytes = {
42
+ bytePerInput: {
43
+ p2pkh: 148,
44
+ p2wpkh: 68,
45
+ "p2sh-p2wpkh": 91,
46
+ p2tr: 58,
47
+ default: 100,
48
+ },
49
+ baseTxBytes: 10 + 5,
50
+ bytePerOutput: {
51
+ p2pkh: 34,
52
+ p2wpkh: 31,
53
+ p2sh: 32,
54
+ p2tr: 43,
55
+ default: 35,
56
+ max: 45,
57
+ },
58
+ scriptExtraBytes: {
59
+ lessThan255: 12,
60
+ moreThan255: 15,
61
+ },
62
+ };
63
+ exports.DUST = 1000;
64
+ function coinSelectInOrder(utxos, outputs, feeRate) {
65
+ let response = coinselectAccumulative(utxos, outputs, 1);
66
+ return Object.assign(Object.assign({}, response), { fee: +(+response.fee * feeRate).toFixed() });
67
+ }
68
+ class BaseTransactionBuilder {
69
+ constructor({ network, testnet, feeMin = 0, dustLimit, maximumNumberOfOutputsInTransaction = 50, }) {
70
+ this.testnet = testnet;
71
+ this.network = network;
72
+ this.maximumNumberOfOutputsInTransaction = maximumNumberOfOutputsInTransaction;
73
+ this.feeMin = feeMin;
74
+ this.dustLimit = dustLimit || 1 * 2 * exports.componentBytes.bytePerInput.p2pkh;
75
+ }
76
+ createAddressObject(input) {
77
+ return (0, bitcoin_utils_1.createAddressObjectByPublicKey)(input, this.network);
78
+ }
79
+ validateAddress(address) {
80
+ try {
81
+ (0, bitcoin_utils_1.getAddressType)(address, this.network);
82
+ return true;
83
+ }
84
+ catch (error) {
85
+ return false;
86
+ }
87
+ }
88
+ getOpReturnTarget(dataHex) {
89
+ if (!(dataHex.length > 0))
90
+ throw new Error("invalid data in hex");
91
+ const embed = bitcoin.payments.embed({
92
+ data: [Buffer.from(dataHex, "hex")],
93
+ network: this.network,
94
+ });
95
+ return {
96
+ script: embed.output,
97
+ value: 0,
98
+ };
99
+ }
100
+ calculateTxSize(inputTypes, outputs, changeAddressType = "default") {
101
+ const inputsSizes = inputTypes.map((addressType) => exports.componentBytes.bytePerInput[addressType]);
102
+ const outputSizes = outputs.map((outP) => {
103
+ if (outP.address) {
104
+ let addressType = "default";
105
+ try {
106
+ addressType = (0, bitcoin_utils_1.getAddressType)(outP.address, this.network);
107
+ }
108
+ catch (_a) {
109
+ addressType = "default";
110
+ }
111
+ return exports.componentBytes.bytePerOutput[addressType];
112
+ }
113
+ if (outP.script) {
114
+ if (outP.script.byteLength < 255) {
115
+ return outP.script.byteLength + exports.componentBytes.scriptExtraBytes.lessThan255;
116
+ }
117
+ return outP.script.byteLength + exports.componentBytes.scriptExtraBytes.moreThan255;
118
+ }
119
+ return exports.componentBytes.bytePerOutput[changeAddressType];
120
+ });
121
+ const txSize = exports.componentBytes.baseTxBytes +
122
+ inputsSizes.reduce((a, c) => a + c, 0) +
123
+ outputSizes.reduce((a, c) => a + c, 0);
124
+ return txSize;
125
+ }
126
+ helperHandleInputsAndOutputs({ targets, extendedUtxo, feeRate, changeObject, selectType = "normal", }) {
127
+ const filteredUtxo = extendedUtxo.filter((u) => u.value >
128
+ +feeRate *
129
+ exports.componentBytes.bytePerInput[u.signerInfo.addressType]);
130
+ let selectResponse;
131
+ switch (selectType) {
132
+ case "normal":
133
+ selectResponse = coinselect(filteredUtxo, targets, Math.round(feeRate));
134
+ break;
135
+ case "accumulative":
136
+ selectResponse = coinselectAccumulative(filteredUtxo, targets, Math.round(feeRate));
137
+ break;
138
+ case "inOrder":
139
+ selectResponse = coinSelectInOrder(filteredUtxo, targets, Math.round(feeRate));
140
+ break;
141
+ case "full":
142
+ if (!targets[0].address) {
143
+ throw new Error();
144
+ }
145
+ selectResponse = coinselectSplit(filteredUtxo, [{ address: targets[0].address }], Math.round(feeRate));
146
+ break;
147
+ default:
148
+ break;
149
+ }
150
+ let { inputs, outputs, fee, } = selectResponse;
151
+ if (!inputs || !outputs) {
152
+ inputs = filteredUtxo;
153
+ outputs = targets;
154
+ fee = inputs.reduce((a, b) => a + b.value, 0) - outputs.reduce((a, b) => a + b.value, 0);
155
+ }
156
+ let changeAddressType = "default";
157
+ try {
158
+ changeAddressType = (0, bitcoin_utils_1.getAddressType)((changeObject === null || changeObject === void 0 ? void 0 : changeObject.address) || "", this.network);
159
+ }
160
+ catch (_a) {
161
+ changeAddressType = "default";
162
+ }
163
+ const txSize = this.calculateTxSize(inputs.map((i) => i.signerInfo.addressType), outputs, changeAddressType) + exports.componentBytes.bytePerOutput.default;
164
+ let txFee = Math.round(txSize * feeRate);
165
+ if (Math.round(feeRate) === 1) {
166
+ txFee = Math.round(txFee + txFee * 0.1);
167
+ }
168
+ if (inputs.reduce((a, b) => a + b.value, 0) -
169
+ outputs.filter((o) => o.address || o.script).reduce((a, b) => a + b.value, 0) -
170
+ txFee <
171
+ 0) {
172
+ let spendableBalance = inputs.reduce((a, b) => a + b.value, 0);
173
+ let totalOutputAmount = outputs
174
+ .filter((o) => o.address || o.script)
175
+ .reduce((a, b) => a + b.value, 0);
176
+ let need = spendableBalance - totalOutputAmount - txFee;
177
+ throw new Error(`not enough balance. details: ${JSON.stringify({ spendableBalance, totalOutputAmount, txFee, need }, null, 2)}`);
178
+ }
179
+ let diff = fee - txFee;
180
+ let changeIndex = outputs.findIndex((x) => !(x === null || x === void 0 ? void 0 : x.address) && !x.script && (x.value || 0) > 0);
181
+ let change;
182
+ if (changeIndex >= 0 || diff > exports.DUST) {
183
+ if (changeIndex >= 0) {
184
+ diff = diff + exports.componentBytes.bytePerOutput.default * Math.round(feeRate);
185
+ }
186
+ if (diff < 0) {
187
+ diff = 0;
188
+ }
189
+ if (selectType === "full") {
190
+ outputs[0].value = outputs[0].value + diff;
191
+ fee = fee - diff;
192
+ }
193
+ else {
194
+ if (!changeObject)
195
+ throw new Error("change not exist");
196
+ change = {
197
+ address: changeObject.address,
198
+ value: changeIndex >= 0 ? outputs[changeIndex].value + diff : diff,
199
+ };
200
+ fee = fee - diff;
201
+ }
202
+ if (changeIndex >= 0) {
203
+ outputs.splice(changeIndex, 1);
204
+ }
205
+ }
206
+ return {
207
+ inputs,
208
+ fee,
209
+ outputs: outputs,
210
+ change,
211
+ };
212
+ }
213
+ filterAndConvertTxDataToStandardFormat({ extendedUtxo, targets, changeObject, feeRate, selectType, }) {
214
+ return __awaiter(this, void 0, void 0, function* () {
215
+ let { inputs: filteredInputs, outputs, change, fee, } = this.helperHandleInputsAndOutputs({
216
+ targets,
217
+ extendedUtxo,
218
+ feeRate,
219
+ changeObject,
220
+ selectType,
221
+ });
222
+ let inputs = yield this.convertExtendedUtxoToInputs(filteredInputs);
223
+ return {
224
+ inputs,
225
+ outputs,
226
+ change,
227
+ fee,
228
+ feeRate,
229
+ };
230
+ });
231
+ }
232
+ convertExtendedUtxoToInputs(baseInputs = []) {
233
+ var _a;
234
+ return __awaiter(this, void 0, void 0, function* () {
235
+ let inputs = baseInputs;
236
+ const transactionHex = {};
237
+ for (let i in inputs) {
238
+ let { address, publicKey, derivationPath, masterFingerprint, addressType } = inputs[i].signerInfo;
239
+ let addressObject = this.createAddressObject({
240
+ publicKey: Buffer.from(publicKey, "hex"),
241
+ addressType,
242
+ });
243
+ if (derivationPath && masterFingerprint && addressObject.pubkey) {
244
+ inputs[i].bip32Derivation = [
245
+ {
246
+ path: derivationPath,
247
+ pubkey: addressObject.pubkey,
248
+ masterFingerprint: Buffer.from(masterFingerprint, "hex"),
249
+ },
250
+ ];
251
+ }
252
+ if (addressType === "p2pkh") {
253
+ const txHex = transactionHex[inputs[i].hash] || (yield this._getTransactionHex(inputs[i].hash));
254
+ transactionHex[inputs[i].hash] = txHex;
255
+ inputs[i].nonWitnessUtxo = Buffer.from(txHex, "hex");
256
+ }
257
+ else if (addressType === "p2wpkh") {
258
+ if (!addressObject.output)
259
+ throw new Error("invalid signer info");
260
+ inputs[i].witnessUtxo = {
261
+ script: addressObject.output,
262
+ value: inputs[i].value,
263
+ };
264
+ if (inputs[i].signerInfo.includeHex) {
265
+ const txHex = transactionHex[inputs[i].hash] || (yield this._getTransactionHex(inputs[i].hash));
266
+ transactionHex[inputs[i].hash] = txHex;
267
+ inputs[i].nonWitnessUtxo = Buffer.from(txHex, "hex");
268
+ }
269
+ }
270
+ else if (addressType === "p2sh-p2wpkh") {
271
+ if (!addressObject.output)
272
+ throw new Error("invalid signer info");
273
+ inputs[i].witnessUtxo = {
274
+ script: addressObject.output,
275
+ value: inputs[i].value,
276
+ };
277
+ if (!((_a = addressObject === null || addressObject === void 0 ? void 0 : addressObject.redeem) === null || _a === void 0 ? void 0 : _a.output))
278
+ throw new Error("invalid signer info for p2sh address");
279
+ inputs[i].redeemScript = addressObject.redeem.output;
280
+ if (inputs[i].signerInfo.includeHex) {
281
+ const txHex = transactionHex[inputs[i].hash] || (yield this._getTransactionHex(inputs[i].hash));
282
+ transactionHex[inputs[i].hash] = txHex;
283
+ inputs[i].nonWitnessUtxo = Buffer.from(txHex, "hex");
284
+ }
285
+ }
286
+ else if (addressType === "p2tr") {
287
+ if (!addressObject.output)
288
+ throw new Error("invalid signer info");
289
+ inputs[i].witnessUtxo = {
290
+ script: addressObject.output,
291
+ value: inputs[i].value,
292
+ };
293
+ if (!addressObject.pubkey)
294
+ throw new Error("invalid signer info for p2tr address (pubkey)");
295
+ inputs[i].tapInternalKey = addressObject.internalPubkey;
296
+ if (inputs[i].signerInfo.includeHex) {
297
+ const txHex = transactionHex[inputs[i].hash] || (yield this._getTransactionHex(inputs[i].hash));
298
+ transactionHex[inputs[i].hash] = txHex;
299
+ inputs[i].nonWitnessUtxo = Buffer.from(txHex, "hex");
300
+ }
301
+ }
302
+ }
303
+ return inputs;
304
+ });
305
+ }
306
+ createUnsignedTransaction({ inputs, outputs, change, fee, feeRate, }) {
307
+ const sequence = 0xffffffff - 2;
308
+ const { network } = this;
309
+ const newPsbt = new bitcoin.Psbt({ network });
310
+ newPsbt.setMaximumFeeRate(+(feeRate + feeRate / 100).toFixed());
311
+ for (const input of inputs) {
312
+ let { addressType } = input.signerInfo;
313
+ switch (addressType) {
314
+ case "p2pkh": {
315
+ let i = {
316
+ hash: input.hash,
317
+ index: Number(input.index),
318
+ nonWitnessUtxo: input.nonWitnessUtxo,
319
+ sequence,
320
+ bip32Derivation: input.bip32Derivation,
321
+ };
322
+ if (!i.bip32Derivation)
323
+ delete i.bip32Derivation;
324
+ newPsbt.addInput(i);
325
+ break;
326
+ }
327
+ case "p2wpkh": {
328
+ let i = {
329
+ hash: input.hash,
330
+ index: Number(input.index),
331
+ witnessUtxo: input.witnessUtxo,
332
+ nonWitnessUtxo: input.nonWitnessUtxo,
333
+ sequence,
334
+ bip32Derivation: input.bip32Derivation,
335
+ };
336
+ if (!i.bip32Derivation)
337
+ delete i.bip32Derivation;
338
+ if (!i.nonWitnessUtxo)
339
+ delete i.nonWitnessUtxo;
340
+ newPsbt.addInput(i);
341
+ break;
342
+ }
343
+ case "p2sh-p2wpkh": {
344
+ let i = {
345
+ hash: input.hash,
346
+ index: Number(input.index),
347
+ witnessUtxo: input.witnessUtxo,
348
+ nonWitnessUtxo: input.nonWitnessUtxo,
349
+ redeemScript: input.redeemScript,
350
+ sequence,
351
+ bip32Derivation: input.bip32Derivation,
352
+ };
353
+ if (!i.bip32Derivation)
354
+ delete i.bip32Derivation;
355
+ if (!i.nonWitnessUtxo)
356
+ delete i.nonWitnessUtxo;
357
+ newPsbt.addInput(i);
358
+ break;
359
+ }
360
+ case "p2tr": {
361
+ let i = {
362
+ hash: input.hash,
363
+ index: Number(input.index),
364
+ witnessUtxo: input.witnessUtxo,
365
+ nonWitnessUtxo: input.nonWitnessUtxo,
366
+ tapInternalKey: input.tapInternalKey,
367
+ sequence,
368
+ bip32Derivation: input.bip32Derivation,
369
+ };
370
+ if (!i.bip32Derivation)
371
+ delete i.bip32Derivation;
372
+ if (!i.nonWitnessUtxo)
373
+ delete i.nonWitnessUtxo;
374
+ newPsbt.addInput(i);
375
+ break;
376
+ }
377
+ default:
378
+ throw new Error("address type is incorrect");
379
+ }
380
+ }
381
+ for (const target of outputs) {
382
+ newPsbt.addOutput(target);
383
+ }
384
+ if (change && Object.keys(change).length !== 0) {
385
+ newPsbt.addOutput(change);
386
+ }
387
+ if (change && Object.keys(change).length !== 0) {
388
+ if (newPsbt.txOutputs[outputs.length].address !== change.address) {
389
+ throw new Error("error change address");
390
+ }
391
+ }
392
+ const unsignedPsbtBaseText = newPsbt.toBase64();
393
+ const safeAddressTypeForPossibleTxId = ["p2wpkh", "p2tr"];
394
+ const isPossibleTxId = inputs.reduce((a, b) => a && safeAddressTypeForPossibleTxId.includes(b.signerInfo.addressType), true);
395
+ return {
396
+ unsignedTransaction: unsignedPsbtBaseText,
397
+ outputs,
398
+ inputs: inputs.map((utx) => ({
399
+ hash: utx.hash,
400
+ value: Number(utx.value),
401
+ index: utx.index,
402
+ signerInfo: utx.signerInfo,
403
+ })),
404
+ fee,
405
+ change,
406
+ possibleTxId: isPossibleTxId ? this.getUnsignedPsbtTxId(unsignedPsbtBaseText) : undefined,
407
+ };
408
+ }
409
+ processUnsignedTransaction({ extendedUtxo, targets = [], changeAddress = undefined, fullAmount = false, feeRate, selectType = "normal", }) {
410
+ return __awaiter(this, void 0, void 0, function* () {
411
+ if (!changeAddress && targets.length === 0)
412
+ throw new Error("no target");
413
+ let changeObject = typeof changeAddress === "string"
414
+ ? {
415
+ address: changeAddress,
416
+ }
417
+ : changeAddress;
418
+ const { inputs, outputs, change, fee } = yield this.filterAndConvertTxDataToStandardFormat({
419
+ extendedUtxo,
420
+ targets,
421
+ changeObject,
422
+ feeRate,
423
+ selectType: fullAmount ? "full" : selectType,
424
+ });
425
+ let unsignedTransaction = this.createUnsignedTransaction({
426
+ inputs,
427
+ outputs,
428
+ change,
429
+ fee,
430
+ feeRate,
431
+ });
432
+ return unsignedTransaction;
433
+ });
434
+ }
435
+ getUnsignedPsbtTxId(unsignedPsbt) {
436
+ let psbt = bitcoin.Psbt.fromBase64(unsignedPsbt, {
437
+ network: this.network,
438
+ });
439
+ return psbt.__CACHE.__TX.getId();
440
+ }
441
+ }
442
+ exports.BaseTransactionBuilder = BaseTransactionBuilder;
448
443
  //# sourceMappingURL=transaction-builder.js.map