@btc-vision/wallet-sdk 1.0.0 → 1.0.4

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 (129) hide show
  1. package/es/bundle.js +1 -1
  2. package/es/bundle.js.LICENSE.txt +4 -4
  3. package/lib/address/index.js +50 -85
  4. package/lib/bitcoin-core.js +7 -37
  5. package/lib/constants.js +1 -4
  6. package/lib/error.js +6 -10
  7. package/lib/index.js +14 -43
  8. package/lib/keyring/hd-keyring.js +40 -79
  9. package/lib/keyring/index.js +4 -20
  10. package/lib/keyring/interfaces/SimpleKeyringOptions.js +16 -31
  11. package/lib/keyring/keystone-keyring.js +142 -201
  12. package/lib/keyring/simple-keyring.js +13 -18
  13. package/lib/message/bip322-simple.js +31 -71
  14. package/lib/message/deterministic-ecdsa.js +19 -40
  15. package/lib/message/ecdsa.js +10 -18
  16. package/lib/message/index.js +3 -19
  17. package/lib/network/index.js +12 -17
  18. package/lib/runes/index.js +1 -17
  19. package/lib/runes/rund_id.js +8 -13
  20. package/lib/runes/varint.js +6 -12
  21. package/lib/transaction/index.js +3 -19
  22. package/lib/transaction/inscription-utxo.js +45 -38
  23. package/lib/transaction/transaction.js +134 -139
  24. package/lib/transaction/utxo.js +13 -18
  25. package/lib/tx-helpers/index.js +8 -18
  26. package/lib/tx-helpers/send-atomicals-ft.js +45 -60
  27. package/lib/tx-helpers/send-atomicals-nft.js +29 -44
  28. package/lib/tx-helpers/send-btc.js +53 -71
  29. package/lib/tx-helpers/send-inscription.js +32 -47
  30. package/lib/tx-helpers/send-inscriptions.js +28 -43
  31. package/lib/tx-helpers/send-runes.js +83 -97
  32. package/lib/tx-helpers/split-inscription-utxo.js +39 -54
  33. package/lib/types.js +2 -5
  34. package/lib/utils.js +16 -29
  35. package/lib/wallet/abstract-wallet.js +1 -2
  36. package/lib/wallet/estimate-wallet.js +130 -147
  37. package/lib/wallet/index.js +3 -19
  38. package/lib/wallet/local-wallet.js +134 -150
  39. package/package.json +103 -95
  40. package/lib/address/index.d.ts +0 -37
  41. package/lib/bitcoin-core.d.ts +0 -5
  42. package/lib/constants.d.ts +0 -1
  43. package/lib/error.d.ts +0 -20
  44. package/lib/index.d.ts +0 -14
  45. package/lib/keyring/hd-keyring.d.ts +0 -50
  46. package/lib/keyring/index.d.ts +0 -4
  47. package/lib/keyring/interfaces/SimpleKeyringOptions.d.ts +0 -53
  48. package/lib/keyring/keystone-keyring.d.ts +0 -82
  49. package/lib/keyring/simple-keyring.d.ts +0 -11
  50. package/lib/message/bip322-simple.d.ts +0 -19
  51. package/lib/message/deterministic-ecdsa.d.ts +0 -2
  52. package/lib/message/ecdsa.d.ts +0 -3
  53. package/lib/message/index.d.ts +0 -3
  54. package/lib/network/index.d.ts +0 -14
  55. package/lib/runes/index.d.ts +0 -1
  56. package/lib/runes/rund_id.d.ts +0 -11
  57. package/lib/runes/varint.d.ts +0 -15
  58. package/lib/src/address/index.d.ts +0 -37
  59. package/lib/src/bitcoin-core.d.ts +0 -5
  60. package/lib/src/constants.d.ts +0 -1
  61. package/lib/src/error.d.ts +0 -20
  62. package/lib/src/index.d.ts +0 -14
  63. package/lib/src/keyring/hd-keyring.d.ts +0 -50
  64. package/lib/src/keyring/index.d.ts +0 -4
  65. package/lib/src/keyring/interfaces/SimpleKeyringOptions.d.ts +0 -53
  66. package/lib/src/keyring/keystone-keyring.d.ts +0 -82
  67. package/lib/src/keyring/simple-keyring.d.ts +0 -11
  68. package/lib/src/message/bip322-simple.d.ts +0 -19
  69. package/lib/src/message/deterministic-ecdsa.d.ts +0 -2
  70. package/lib/src/message/ecdsa.d.ts +0 -3
  71. package/lib/src/message/index.d.ts +0 -3
  72. package/lib/src/network/index.d.ts +0 -14
  73. package/lib/src/runes/index.d.ts +0 -1
  74. package/lib/src/runes/rund_id.d.ts +0 -11
  75. package/lib/src/runes/varint.d.ts +0 -15
  76. package/lib/src/transaction/index.d.ts +0 -3
  77. package/lib/src/transaction/inscription-utxo.d.ts +0 -33
  78. package/lib/src/transaction/transaction.d.ts +0 -52
  79. package/lib/src/transaction/utxo.d.ts +0 -35
  80. package/lib/src/tx-helpers/index.d.ts +0 -8
  81. package/lib/src/tx-helpers/send-atomicals-ft.d.ts +0 -16
  82. package/lib/src/tx-helpers/send-atomicals-nft.d.ts +0 -14
  83. package/lib/src/tx-helpers/send-btc.d.ts +0 -28
  84. package/lib/src/tx-helpers/send-inscription.d.ts +0 -16
  85. package/lib/src/tx-helpers/send-inscriptions.d.ts +0 -14
  86. package/lib/src/tx-helpers/send-runes.d.ts +0 -19
  87. package/lib/src/tx-helpers/split-inscription-utxo.d.ts +0 -15
  88. package/lib/src/types.d.ts +0 -59
  89. package/lib/src/utils.d.ts +0 -23
  90. package/lib/src/wallet/abstract-wallet.d.ts +0 -6
  91. package/lib/src/wallet/estimate-wallet.d.ts +0 -23
  92. package/lib/src/wallet/index.d.ts +0 -3
  93. package/lib/src/wallet/local-wallet.d.ts +0 -23
  94. package/lib/test/address/address.test.d.ts +0 -1
  95. package/lib/test/keyring/hd-keyring.test.d.ts +0 -1
  96. package/lib/test/keyring/keystone-keyring.test.d.ts +0 -1
  97. package/lib/test/keyring/simple-keyring.test.d.ts +0 -1
  98. package/lib/test/message/message.test.d.ts +0 -1
  99. package/lib/test/runes/varint.test.d.ts +0 -1
  100. package/lib/test/transaction/transaction.test.d.ts +0 -1
  101. package/lib/test/transaction/utxo.test.d.ts +0 -1
  102. package/lib/test/tx-helpers/send-atomicals-ft.test.d.ts +0 -1
  103. package/lib/test/tx-helpers/send-atomicals-nft.test.d.ts +0 -1
  104. package/lib/test/tx-helpers/send-btc.test.d.ts +0 -1
  105. package/lib/test/tx-helpers/send-inscription.test.d.ts +0 -1
  106. package/lib/test/tx-helpers/send-inscriptions.test.d.ts +0 -1
  107. package/lib/test/tx-helpers/send-runes.test.d.ts +0 -1
  108. package/lib/test/tx-helpers/split-inscription-utxo.test.d.ts +0 -1
  109. package/lib/test/tx-helpers/utils.d.ts +0 -217
  110. package/lib/test/utils.d.ts +0 -4
  111. package/lib/test/wallet/local-wallet.test.d.ts +0 -1
  112. package/lib/transaction/index.d.ts +0 -3
  113. package/lib/transaction/inscription-utxo.d.ts +0 -33
  114. package/lib/transaction/transaction.d.ts +0 -52
  115. package/lib/transaction/utxo.d.ts +0 -35
  116. package/lib/tx-helpers/index.d.ts +0 -8
  117. package/lib/tx-helpers/send-atomicals-ft.d.ts +0 -16
  118. package/lib/tx-helpers/send-atomicals-nft.d.ts +0 -14
  119. package/lib/tx-helpers/send-btc.d.ts +0 -28
  120. package/lib/tx-helpers/send-inscription.d.ts +0 -16
  121. package/lib/tx-helpers/send-inscriptions.d.ts +0 -14
  122. package/lib/tx-helpers/send-runes.d.ts +0 -19
  123. package/lib/tx-helpers/split-inscription-utxo.d.ts +0 -15
  124. package/lib/types.d.ts +0 -59
  125. package/lib/utils.d.ts +0 -23
  126. package/lib/wallet/abstract-wallet.d.ts +0 -6
  127. package/lib/wallet/estimate-wallet.d.ts +0 -23
  128. package/lib/wallet/index.d.ts +0 -3
  129. package/lib/wallet/local-wallet.d.ts +0 -23
@@ -1,29 +1,18 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.Transaction = void 0;
13
- const address_1 = require("../address");
14
- const bitcoin_core_1 = require("../bitcoin-core");
15
- const constants_1 = require("../constants");
16
- const error_1 = require("../error");
17
- const network_1 = require("../network");
18
- const types_1 = require("../types");
19
- const utils_1 = require("../utils");
20
- const wallet_1 = require("../wallet");
21
- const utxo_1 = require("./utxo");
1
+ import { payments } from 'bitcoinjs-lib';
2
+ import { addressToScriptPk } from '../address';
3
+ import { bitcoin } from '../bitcoin-core';
4
+ import { UTXO_DUST } from '../constants';
5
+ import { ErrorCodes, WalletUtilsError } from '../error';
6
+ import { NetworkType, toPsbtNetwork } from '../network';
7
+ import { AddressType } from '../types';
8
+ import { toXOnly } from '../utils';
9
+ import { EstimateWallet } from '../wallet';
10
+ import { utxoHelper } from './utxo';
22
11
  /**
23
12
  * Convert UnspentOutput to PSBT TxInput
24
13
  */
25
14
  function utxoToInput(utxo, estimate) {
26
- if (utxo.addressType === types_1.AddressType.P2TR || utxo.addressType === types_1.AddressType.M44_P2TR) {
15
+ if (utxo.addressType === AddressType.P2TR || utxo.addressType === AddressType.M44_P2TR) {
27
16
  const data = {
28
17
  hash: utxo.txid,
29
18
  index: utxo.vout,
@@ -31,14 +20,14 @@ function utxoToInput(utxo, estimate) {
31
20
  value: utxo.satoshis,
32
21
  script: Buffer.from(utxo.scriptPk, 'hex')
33
22
  },
34
- tapInternalKey: (0, utils_1.toXOnly)(Buffer.from(utxo.pubkey, 'hex'))
23
+ tapInternalKey: toXOnly(Buffer.from(utxo.pubkey, 'hex'))
35
24
  };
36
25
  return {
37
26
  data,
38
27
  utxo
39
28
  };
40
29
  }
41
- else if (utxo.addressType === types_1.AddressType.P2WPKH || utxo.addressType === types_1.AddressType.M44_P2WPKH) {
30
+ else if (utxo.addressType === AddressType.P2WPKH || utxo.addressType === AddressType.M44_P2WPKH) {
42
31
  const data = {
43
32
  hash: utxo.txid,
44
33
  index: utxo.vout,
@@ -52,7 +41,7 @@ function utxoToInput(utxo, estimate) {
52
41
  utxo
53
42
  };
54
43
  }
55
- else if (utxo.addressType === types_1.AddressType.P2PKH) {
44
+ else if (utxo.addressType === AddressType.P2PKH) {
56
45
  if (!utxo.rawtx || estimate) {
57
46
  const data = {
58
47
  hash: utxo.txid,
@@ -79,8 +68,8 @@ function utxoToInput(utxo, estimate) {
79
68
  };
80
69
  }
81
70
  }
82
- else if (utxo.addressType === types_1.AddressType.P2SH_P2WPKH) {
83
- const redeemData = bitcoin_core_1.bitcoin.payments.p2wpkh({
71
+ else if (utxo.addressType === AddressType.P2SH_P2WPKH) {
72
+ const redeemData = bitcoin.payments.p2wpkh({
84
73
  pubkey: Buffer.from(utxo.pubkey, 'hex')
85
74
  });
86
75
  const data = {
@@ -97,21 +86,36 @@ function utxoToInput(utxo, estimate) {
97
86
  utxo
98
87
  };
99
88
  }
89
+ else {
90
+ return {
91
+ data: {
92
+ hash: utxo.txid,
93
+ index: utxo.vout,
94
+ witnessUtxo: {
95
+ value: utxo.satoshis,
96
+ script: Buffer.from(utxo.scriptPk, 'hex')
97
+ }
98
+ },
99
+ utxo
100
+ };
101
+ }
100
102
  }
101
103
  /**
102
104
  * Transaction
103
105
  */
104
- class Transaction {
105
- constructor() {
106
- this.utxos = [];
107
- this.inputs = [];
108
- this.outputs = [];
109
- this.changeOutputIndex = -1;
110
- this.enableRBF = true;
111
- this._cacheNetworkFee = 0;
112
- this._cacheBtcUtxos = [];
113
- this._cacheToSignInputs = [];
114
- }
106
+ export class Transaction {
107
+ outputs = [];
108
+ changedAddress = '';
109
+ utxos = [];
110
+ inputs = [];
111
+ changeOutputIndex = -1;
112
+ networkType = NetworkType.MAINNET;
113
+ feeRate = 1;
114
+ enableRBF = true;
115
+ _cacheNetworkFee = 0;
116
+ _cacheBtcUtxos = [];
117
+ _cacheToSignInputs = [];
118
+ constructor() { }
115
119
  setNetworkType(network) {
116
120
  this.networkType = network;
117
121
  }
@@ -141,13 +145,11 @@ class Transaction {
141
145
  getUnspent() {
142
146
  return this.getTotalInput() - this.getTotalOutput();
143
147
  }
144
- calNetworkFee() {
145
- return __awaiter(this, void 0, void 0, function* () {
146
- const psbt = yield this.createEstimatePsbt();
147
- const txSize = psbt.extractTransaction(true).virtualSize();
148
- const fee = Math.ceil(txSize * this.feeRate);
149
- return fee;
150
- });
148
+ async calNetworkFee() {
149
+ const psbt = await this.createEstimatePsbt();
150
+ const txSize = psbt.extractTransaction(true).virtualSize();
151
+ const fee = Math.ceil(txSize * this.feeRate);
152
+ return fee;
151
153
  }
152
154
  addOutput(address, value) {
153
155
  this.outputs.push({
@@ -156,7 +158,7 @@ class Transaction {
156
158
  });
157
159
  }
158
160
  addOpreturn(data) {
159
- const embed = bitcoin_core_1.bitcoin.payments.embed({ data });
161
+ const embed = payments.embed({ data });
160
162
  this.outputs.push({
161
163
  script: embed.output,
162
164
  value: 0
@@ -193,10 +195,10 @@ class Transaction {
193
195
  this.outputs.splice(-count);
194
196
  }
195
197
  toPsbt() {
196
- const network = (0, network_1.toPsbtNetwork)(this.networkType);
197
- const psbt = new bitcoin_core_1.bitcoin.Psbt({ network });
198
+ const network = toPsbtNetwork(this.networkType);
199
+ const psbt = new bitcoin.Psbt({ network });
198
200
  this.inputs.forEach((v, index) => {
199
- if (v.utxo.addressType === types_1.AddressType.P2PKH) {
201
+ if (v.utxo.addressType === AddressType.P2PKH) {
200
202
  if (v.data.witnessUtxo) {
201
203
  //@ts-ignore
202
204
  psbt.__CACHE.__UNSAFE_SIGN_NONSEGWIT = true;
@@ -234,91 +236,66 @@ class Transaction {
234
236
  tx.outputs = this.outputs.map((v) => v);
235
237
  return tx;
236
238
  }
237
- createEstimatePsbt() {
238
- return __awaiter(this, void 0, void 0, function* () {
239
- const estimateWallet = wallet_1.EstimateWallet.fromRandom(this.inputs[0].utxo.addressType, this.networkType);
240
- const scriptPk = (0, address_1.addressToScriptPk)(estimateWallet.address, this.networkType).toString('hex');
241
- const tx = this.clone();
242
- tx.utxos.forEach((v) => {
243
- v.pubkey = estimateWallet.pubkey;
244
- v.scriptPk = scriptPk;
245
- });
246
- tx.inputs = [];
247
- tx.utxos.forEach((v) => {
248
- const input = utxoToInput(v, true);
249
- tx.inputs.push(input);
250
- });
251
- const psbt = tx.toPsbt();
252
- const toSignInputs = tx.inputs.map((v, index) => ({
253
- index,
254
- publicKey: estimateWallet.pubkey
255
- }));
256
- yield estimateWallet.signPsbt(psbt, {
257
- autoFinalized: true,
258
- toSignInputs: toSignInputs
259
- });
260
- return psbt;
239
+ async createEstimatePsbt() {
240
+ const estimateWallet = EstimateWallet.fromRandom(this.inputs[0].utxo.addressType, this.networkType);
241
+ const scriptPk = addressToScriptPk(estimateWallet.address, this.networkType).toString('hex');
242
+ const tx = this.clone();
243
+ tx.utxos.forEach((v) => {
244
+ v.pubkey = estimateWallet.pubkey;
245
+ v.scriptPk = scriptPk;
246
+ });
247
+ tx.inputs = [];
248
+ tx.utxos.forEach((v) => {
249
+ const input = utxoToInput(v, true);
250
+ tx.inputs.push(input);
261
251
  });
252
+ const psbt = tx.toPsbt();
253
+ const toSignInputs = tx.inputs.map((v, index) => ({
254
+ index,
255
+ publicKey: estimateWallet.pubkey
256
+ }));
257
+ await estimateWallet.signPsbt(psbt, {
258
+ autoFinalized: true,
259
+ toSignInputs: toSignInputs
260
+ });
261
+ return psbt;
262
262
  }
263
- selectBtcUtxos() {
264
- const totalInput = this.getTotalInput();
265
- const totalOutput = this.getTotalOutput() + this._cacheNetworkFee;
266
- if (totalInput < totalOutput) {
267
- const { selectedUtxos, remainingUtxos } = utxo_1.utxoHelper.selectBtcUtxos(this._cacheBtcUtxos, totalOutput - totalInput);
268
- if (selectedUtxos.length == 0) {
269
- throw new error_1.WalletUtilsError(error_1.ErrorCodes.INSUFFICIENT_BTC_UTXO);
270
- }
271
- selectedUtxos.forEach((v) => {
272
- this.addInput(v);
273
- this._cacheToSignInputs.push({
274
- index: this.inputs.length - 1,
275
- publicKey: v.pubkey
276
- });
277
- this._cacheNetworkFee += utxo_1.utxoHelper.getAddedVirtualSize(v.addressType) * this.feeRate;
278
- });
279
- this._cacheBtcUtxos = remainingUtxos;
263
+ async addSufficientUtxosForFee(btcUtxos, forceAsFee) {
264
+ if (btcUtxos.length > 0) {
265
+ this._cacheBtcUtxos = btcUtxos;
266
+ const dummyBtcUtxo = Object.assign({}, btcUtxos[0]);
267
+ dummyBtcUtxo.satoshis = 2100000000000000;
268
+ this.addInput(dummyBtcUtxo);
269
+ this.addChangeOutput(0);
270
+ const networkFee = await this.calNetworkFee();
271
+ const dummyBtcUtxoSize = utxoHelper.getAddedVirtualSize(dummyBtcUtxo.addressType);
272
+ this._cacheNetworkFee = networkFee - dummyBtcUtxoSize * this.feeRate;
273
+ this.removeLastInput();
280
274
  this.selectBtcUtxos();
281
275
  }
282
- }
283
- addSufficientUtxosForFee(btcUtxos, forceAsFee) {
284
- return __awaiter(this, void 0, void 0, function* () {
285
- if (btcUtxos.length > 0) {
286
- this._cacheBtcUtxos = btcUtxos;
287
- const dummyBtcUtxo = Object.assign({}, btcUtxos[0]);
288
- dummyBtcUtxo.satoshis = 2100000000000000;
289
- this.addInput(dummyBtcUtxo);
290
- this.addChangeOutput(0);
291
- const networkFee = yield this.calNetworkFee();
292
- const dummyBtcUtxoSize = utxo_1.utxoHelper.getAddedVirtualSize(dummyBtcUtxo.addressType);
293
- this._cacheNetworkFee = networkFee - dummyBtcUtxoSize * this.feeRate;
294
- this.removeLastInput();
295
- this.selectBtcUtxos();
296
- }
297
- else {
298
- if (forceAsFee) {
299
- throw new error_1.WalletUtilsError(error_1.ErrorCodes.INSUFFICIENT_BTC_UTXO);
300
- }
301
- if (this.getTotalInput() < this.getTotalOutput()) {
302
- throw new error_1.WalletUtilsError(error_1.ErrorCodes.INSUFFICIENT_BTC_UTXO);
303
- }
304
- this._cacheNetworkFee = yield this.calNetworkFee();
305
- }
306
- const changeAmount = this.getTotalInput() - this.getTotalOutput() - Math.ceil(this._cacheNetworkFee);
307
- if (changeAmount > constants_1.UTXO_DUST) {
308
- this.removeChangeOutput();
309
- this.addChangeOutput(changeAmount);
276
+ else {
277
+ if (forceAsFee) {
278
+ throw new WalletUtilsError(ErrorCodes.INSUFFICIENT_BTC_UTXO);
310
279
  }
311
- else {
312
- this.removeChangeOutput();
280
+ if (this.getTotalInput() < this.getTotalOutput()) {
281
+ throw new WalletUtilsError(ErrorCodes.INSUFFICIENT_BTC_UTXO);
313
282
  }
314
- return this._cacheToSignInputs;
315
- });
283
+ this._cacheNetworkFee = await this.calNetworkFee();
284
+ }
285
+ const changeAmount = this.getTotalInput() - this.getTotalOutput() - Math.ceil(this._cacheNetworkFee);
286
+ if (changeAmount > UTXO_DUST) {
287
+ this.removeChangeOutput();
288
+ this.addChangeOutput(changeAmount);
289
+ }
290
+ else {
291
+ this.removeChangeOutput();
292
+ }
293
+ return this._cacheToSignInputs;
316
294
  }
317
- dumpTx(psbt) {
318
- return __awaiter(this, void 0, void 0, function* () {
319
- const tx = psbt.extractTransaction();
320
- const feeRate = psbt.getFeeRate();
321
- console.log(`
295
+ async dumpTx(psbt) {
296
+ const tx = psbt.extractTransaction();
297
+ const feeRate = psbt.getFeeRate();
298
+ console.log(`
322
299
  =============================================================================================
323
300
  Summary
324
301
  txid: ${tx.getId()}
@@ -329,30 +306,48 @@ Summary
329
306
  ----------------------------------------------------------------------------------------------
330
307
  Inputs
331
308
  ${this.inputs
332
- .map((input, index) => {
333
- const str = `
309
+ .map((input, index) => {
310
+ const str = `
334
311
  =>${index} ${input.data.witnessUtxo.value} Sats
335
312
  lock-size: ${input.data.witnessUtxo.script.length}
336
313
  via ${input.data.hash} [${input.data.index}]
337
314
  `;
338
- return str;
339
- })
340
- .join('')}
315
+ return str;
316
+ })
317
+ .join('')}
341
318
  total: ${this.getTotalInput()} Sats
342
319
  ----------------------------------------------------------------------------------------------
343
320
  Outputs
344
321
  ${this.outputs
345
- .map((output, index) => {
346
- const str = `
322
+ .map((output, index) => {
323
+ const str = `
347
324
  =>${index} ${output.address} ${output.value} Sats`;
348
- return str;
349
- })
350
- .join('')}
325
+ return str;
326
+ })
327
+ .join('')}
351
328
 
352
329
  total: ${this.getTotalOutput()} Sats
353
330
  =============================================================================================
354
331
  `);
355
- });
332
+ }
333
+ selectBtcUtxos() {
334
+ const totalInput = this.getTotalInput();
335
+ const totalOutput = this.getTotalOutput() + this._cacheNetworkFee;
336
+ if (totalInput < totalOutput) {
337
+ const { selectedUtxos, remainingUtxos } = utxoHelper.selectBtcUtxos(this._cacheBtcUtxos, totalOutput - totalInput);
338
+ if (selectedUtxos.length == 0) {
339
+ throw new WalletUtilsError(ErrorCodes.INSUFFICIENT_BTC_UTXO);
340
+ }
341
+ selectedUtxos.forEach((v) => {
342
+ this.addInput(v);
343
+ this._cacheToSignInputs.push({
344
+ index: this.inputs.length - 1,
345
+ publicKey: v.pubkey
346
+ });
347
+ this._cacheNetworkFee += utxoHelper.getAddedVirtualSize(v.addressType) * this.feeRate;
348
+ });
349
+ this._cacheBtcUtxos = remainingUtxos;
350
+ this.selectBtcUtxos();
351
+ }
356
352
  }
357
353
  }
358
- exports.Transaction = Transaction;
@@ -1,9 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.utxoHelper = exports.getAddressUtxoDust = exports.getUtxoDust = void 0;
4
- const address_1 = require("../address");
5
- const network_1 = require("../network");
6
- const types_1 = require("../types");
1
+ import { decodeAddress } from '../address';
2
+ import { NetworkType } from '../network';
3
+ import { AddressType } from '../types';
7
4
  function hasInscription(utxos) {
8
5
  if (utxos.find((v) => v.inscriptions.length > 0)) {
9
6
  return true;
@@ -62,39 +59,37 @@ function selectBtcUtxos(utxos, targetAmount) {
62
59
  * return the added virtual size of the utxo
63
60
  */
64
61
  function getAddedVirtualSize(addressType) {
65
- if (addressType === types_1.AddressType.P2WPKH || addressType === types_1.AddressType.M44_P2WPKH) {
62
+ if (addressType === AddressType.P2WPKH || addressType === AddressType.M44_P2WPKH) {
66
63
  return 41 + (1 + 1 + 72 + 1 + 33) / 4;
67
64
  }
68
- else if (addressType === types_1.AddressType.P2TR || addressType === types_1.AddressType.M44_P2TR) {
65
+ else if (addressType === AddressType.P2TR || addressType === AddressType.M44_P2TR) {
69
66
  return 41 + (1 + 1 + 64) / 4;
70
67
  }
71
- else if (addressType === types_1.AddressType.P2PKH) {
68
+ else if (addressType === AddressType.P2PKH) {
72
69
  return 41 + 1 + 1 + 72 + 1 + 33;
73
70
  }
74
- else if (addressType === types_1.AddressType.P2SH_P2WPKH) {
71
+ else if (addressType === AddressType.P2SH_P2WPKH) {
75
72
  return 41 + 24 + (1 + 1 + 72 + 1 + 33) / 4;
76
73
  }
77
74
  throw new Error('unknown address type');
78
75
  }
79
- function getUtxoDust(addressType) {
80
- if (addressType === types_1.AddressType.P2WPKH || addressType === types_1.AddressType.M44_P2WPKH) {
76
+ export function getUtxoDust(addressType) {
77
+ if (addressType === AddressType.P2WPKH || addressType === AddressType.M44_P2WPKH) {
81
78
  return 294;
82
79
  }
83
- else if (addressType === types_1.AddressType.P2TR || addressType === types_1.AddressType.M44_P2TR) {
80
+ else if (addressType === AddressType.P2TR || addressType === AddressType.M44_P2TR) {
84
81
  return 330;
85
82
  }
86
83
  else {
87
84
  return 546;
88
85
  }
89
86
  }
90
- exports.getUtxoDust = getUtxoDust;
91
87
  // deprecated
92
88
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
93
- function getAddressUtxoDust(address, networkType = network_1.NetworkType.MAINNET) {
94
- return (0, address_1.decodeAddress)(address).dust;
89
+ export function getAddressUtxoDust(address, networkType = NetworkType.MAINNET) {
90
+ return decodeAddress(address).dust;
95
91
  }
96
- exports.getAddressUtxoDust = getAddressUtxoDust;
97
- exports.utxoHelper = {
92
+ export const utxoHelper = {
98
93
  hasAtomicalsFT,
99
94
  hasAtomicalsNFT,
100
95
  hasAtomicals,
@@ -1,18 +1,8 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.splitInscriptionUtxo = exports.sendRunes = exports.sendInscriptions = exports.sendInscription = exports.sendBTC = exports.sendAtomicalsNFT = exports.sendAtomicalsFT = exports.sendAllBTC = void 0;
4
- const send_atomicals_ft_1 = require("./send-atomicals-ft");
5
- Object.defineProperty(exports, "sendAtomicalsFT", { enumerable: true, get: function () { return send_atomicals_ft_1.sendAtomicalsFT; } });
6
- const send_atomicals_nft_1 = require("./send-atomicals-nft");
7
- Object.defineProperty(exports, "sendAtomicalsNFT", { enumerable: true, get: function () { return send_atomicals_nft_1.sendAtomicalsNFT; } });
8
- const send_btc_1 = require("./send-btc");
9
- Object.defineProperty(exports, "sendAllBTC", { enumerable: true, get: function () { return send_btc_1.sendAllBTC; } });
10
- Object.defineProperty(exports, "sendBTC", { enumerable: true, get: function () { return send_btc_1.sendBTC; } });
11
- const send_inscription_1 = require("./send-inscription");
12
- Object.defineProperty(exports, "sendInscription", { enumerable: true, get: function () { return send_inscription_1.sendInscription; } });
13
- const send_inscriptions_1 = require("./send-inscriptions");
14
- Object.defineProperty(exports, "sendInscriptions", { enumerable: true, get: function () { return send_inscriptions_1.sendInscriptions; } });
15
- const send_runes_1 = require("./send-runes");
16
- Object.defineProperty(exports, "sendRunes", { enumerable: true, get: function () { return send_runes_1.sendRunes; } });
17
- const split_inscription_utxo_1 = require("./split-inscription-utxo");
18
- Object.defineProperty(exports, "splitInscriptionUtxo", { enumerable: true, get: function () { return split_inscription_utxo_1.splitInscriptionUtxo; } });
1
+ import { sendAtomicalsFT } from './send-atomicals-ft';
2
+ import { sendAtomicalsNFT } from './send-atomicals-nft';
3
+ import { sendAllBTC, sendBTC } from './send-btc';
4
+ import { sendInscription } from './send-inscription';
5
+ import { sendInscriptions } from './send-inscriptions';
6
+ import { sendRunes } from './send-runes';
7
+ import { splitInscriptionUtxo } from './split-inscription-utxo';
8
+ export { sendAllBTC, sendAtomicalsFT, sendAtomicalsNFT, sendBTC, sendInscription, sendInscriptions, sendRunes, splitInscriptionUtxo };
@@ -1,66 +1,51 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.sendAtomicalsFT = void 0;
13
- const error_1 = require("../error");
14
- const transaction_1 = require("../transaction");
1
+ import { ErrorCodes, WalletUtilsError } from '../error';
2
+ import { Transaction, utxoHelper } from '../transaction';
15
3
  // only one arc20 can be send
16
- function sendAtomicalsFT(params) {
17
- return __awaiter(this, void 0, void 0, function* () {
18
- const { assetUtxos, btcUtxos, toAddress, networkType, changeAssetAddress, sendAmount, changeAddress, feeRate, enableRBF = true } = params;
19
- // safe check
20
- if (transaction_1.utxoHelper.hasAtomicalsNFT(assetUtxos) || transaction_1.utxoHelper.hasInscription(assetUtxos)) {
21
- throw new error_1.WalletUtilsError(error_1.ErrorCodes.NOT_SAFE_UTXOS);
22
- }
23
- if (transaction_1.utxoHelper.hasAnyAssets(btcUtxos)) {
24
- throw new error_1.WalletUtilsError(error_1.ErrorCodes.NOT_SAFE_UTXOS);
4
+ export async function sendAtomicalsFT(params) {
5
+ const { assetUtxos, btcUtxos, toAddress, networkType, changeAssetAddress, sendAmount, changeAddress, feeRate, enableRBF = true } = params;
6
+ // safe check
7
+ if (utxoHelper.hasAtomicalsNFT(assetUtxos) || utxoHelper.hasInscription(assetUtxos)) {
8
+ throw new WalletUtilsError(ErrorCodes.NOT_SAFE_UTXOS);
9
+ }
10
+ if (utxoHelper.hasAnyAssets(btcUtxos)) {
11
+ throw new WalletUtilsError(ErrorCodes.NOT_SAFE_UTXOS);
12
+ }
13
+ const tx = new Transaction();
14
+ tx.setNetworkType(networkType);
15
+ tx.setFeeRate(feeRate);
16
+ tx.setEnableRBF(enableRBF);
17
+ tx.setChangeAddress(changeAddress);
18
+ const toSignInputs = [];
19
+ let totalInputFTAmount = 0;
20
+ assetUtxos.forEach((v) => {
21
+ if (v.atomicals.length > 1) {
22
+ throw new WalletUtilsError(ErrorCodes.ONLY_ONE_ARC20_CAN_BE_SENT);
25
23
  }
26
- const tx = new transaction_1.Transaction();
27
- tx.setNetworkType(networkType);
28
- tx.setFeeRate(feeRate);
29
- tx.setEnableRBF(enableRBF);
30
- tx.setChangeAddress(changeAddress);
31
- const toSignInputs = [];
32
- let totalInputFTAmount = 0;
33
- assetUtxos.forEach((v) => {
34
- if (v.atomicals.length > 1) {
35
- throw new error_1.WalletUtilsError(error_1.ErrorCodes.ONLY_ONE_ARC20_CAN_BE_SENT);
24
+ v.atomicals.forEach((w) => {
25
+ if (!w.atomicalValue) {
26
+ w.atomicalValue = v.satoshis;
36
27
  }
37
- v.atomicals.forEach((w) => {
38
- if (!w.atomicalValue) {
39
- w.atomicalValue = v.satoshis;
40
- }
41
- totalInputFTAmount += w.atomicalValue;
42
- });
43
- });
44
- if (sendAmount > totalInputFTAmount) {
45
- throw new error_1.WalletUtilsError(error_1.ErrorCodes.INSUFFICIENT_ASSET_UTXO);
46
- }
47
- // add assets
48
- assetUtxos.forEach((v, index) => {
49
- tx.addInput(v);
50
- toSignInputs.push({ index, publicKey: v.pubkey });
28
+ totalInputFTAmount += w.atomicalValue;
51
29
  });
52
- // add receiver
53
- tx.addOutput(toAddress, sendAmount);
54
- // add change
55
- const changeArc20Amount = totalInputFTAmount - sendAmount;
56
- if (changeArc20Amount > 0) {
57
- tx.addOutput(changeAssetAddress, changeArc20Amount);
58
- }
59
- // add btc
60
- const _toSignInputs = yield tx.addSufficientUtxosForFee(btcUtxos, true);
61
- toSignInputs.push(..._toSignInputs);
62
- const psbt = tx.toPsbt();
63
- return { psbt, toSignInputs };
64
30
  });
31
+ if (sendAmount > totalInputFTAmount) {
32
+ throw new WalletUtilsError(ErrorCodes.INSUFFICIENT_ASSET_UTXO);
33
+ }
34
+ // add assets
35
+ assetUtxos.forEach((v, index) => {
36
+ tx.addInput(v);
37
+ toSignInputs.push({ index, publicKey: v.pubkey });
38
+ });
39
+ // add receiver
40
+ tx.addOutput(toAddress, sendAmount);
41
+ // add change
42
+ const changeArc20Amount = totalInputFTAmount - sendAmount;
43
+ if (changeArc20Amount > 0) {
44
+ tx.addOutput(changeAssetAddress, changeArc20Amount);
45
+ }
46
+ // add btc
47
+ const _toSignInputs = await tx.addSufficientUtxosForFee(btcUtxos, true);
48
+ toSignInputs.push(..._toSignInputs);
49
+ const psbt = tx.toPsbt();
50
+ return { psbt, toSignInputs };
65
51
  }
66
- exports.sendAtomicalsFT = sendAtomicalsFT;
@@ -1,45 +1,30 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.sendAtomicalsNFT = void 0;
13
- const error_1 = require("../error");
14
- const transaction_1 = require("../transaction");
15
- function sendAtomicalsNFT(params) {
16
- return __awaiter(this, void 0, void 0, function* () {
17
- const { assetUtxo, btcUtxos, toAddress, networkType, changeAddress, feeRate, enableRBF = true } = params;
18
- // safe check
19
- if (transaction_1.utxoHelper.hasAtomicalsFT([assetUtxo]) || transaction_1.utxoHelper.hasInscription([assetUtxo])) {
20
- throw new error_1.WalletUtilsError(error_1.ErrorCodes.NOT_SAFE_UTXOS);
21
- }
22
- if (transaction_1.utxoHelper.hasAnyAssets(btcUtxos)) {
23
- throw new error_1.WalletUtilsError(error_1.ErrorCodes.NOT_SAFE_UTXOS);
24
- }
25
- if (assetUtxo.atomicals.length !== 1) {
26
- throw new error_1.WalletUtilsError(error_1.ErrorCodes.NOT_SAFE_UTXOS);
27
- }
28
- const tx = new transaction_1.Transaction();
29
- tx.setNetworkType(networkType);
30
- tx.setFeeRate(feeRate);
31
- tx.setEnableRBF(enableRBF);
32
- tx.setChangeAddress(changeAddress);
33
- const toSignInputs = [];
34
- // add asset
35
- tx.addInput(assetUtxo);
36
- toSignInputs.push({ index: 0, publicKey: assetUtxo.pubkey });
37
- tx.addOutput(toAddress, assetUtxo.satoshis);
38
- // add btc
39
- const _toSignInputs = yield tx.addSufficientUtxosForFee(btcUtxos, true);
40
- toSignInputs.push(..._toSignInputs);
41
- const psbt = tx.toPsbt();
42
- return { psbt, toSignInputs };
43
- });
1
+ import { ErrorCodes, WalletUtilsError } from '../error';
2
+ import { Transaction, utxoHelper } from '../transaction';
3
+ export async function sendAtomicalsNFT(params) {
4
+ const { assetUtxo, btcUtxos, toAddress, networkType, changeAddress, feeRate, enableRBF = true } = params;
5
+ // safe check
6
+ if (utxoHelper.hasAtomicalsFT([assetUtxo]) || utxoHelper.hasInscription([assetUtxo])) {
7
+ throw new WalletUtilsError(ErrorCodes.NOT_SAFE_UTXOS);
8
+ }
9
+ if (utxoHelper.hasAnyAssets(btcUtxos)) {
10
+ throw new WalletUtilsError(ErrorCodes.NOT_SAFE_UTXOS);
11
+ }
12
+ if (assetUtxo.atomicals.length !== 1) {
13
+ throw new WalletUtilsError(ErrorCodes.NOT_SAFE_UTXOS);
14
+ }
15
+ const tx = new Transaction();
16
+ tx.setNetworkType(networkType);
17
+ tx.setFeeRate(feeRate);
18
+ tx.setEnableRBF(enableRBF);
19
+ tx.setChangeAddress(changeAddress);
20
+ const toSignInputs = [];
21
+ // add asset
22
+ tx.addInput(assetUtxo);
23
+ toSignInputs.push({ index: 0, publicKey: assetUtxo.pubkey });
24
+ tx.addOutput(toAddress, assetUtxo.satoshis);
25
+ // add btc
26
+ const _toSignInputs = await tx.addSufficientUtxosForFee(btcUtxos, true);
27
+ toSignInputs.push(..._toSignInputs);
28
+ const psbt = tx.toPsbt();
29
+ return { psbt, toSignInputs };
44
30
  }
45
- exports.sendAtomicalsNFT = sendAtomicalsNFT;