@meshsdk/bitcoin 1.9.0-beta.81 → 1.9.0-beta.83

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -3700,7 +3700,7 @@ var parseHttpError = function(error) {
3700
3700
  status: error.response.status
3701
3701
  });
3702
3702
  }
3703
- if (error.request && !_instanceof(error.request, XMLHttpRequest)) {
3703
+ if (error.request) {
3704
3704
  return JSON.stringify(error.request);
3705
3705
  }
3706
3706
  return JSON.stringify({
@@ -4012,6 +4012,57 @@ var BlockstreamProvider = /*#__PURE__*/ function() {
4012
4012
  }).call(this);
4013
4013
  }
4014
4014
  },
4015
+ {
4016
+ key: "fetchFeeEstimates",
4017
+ value: /**
4018
+ * Get fee estimates for confirmation within a specified number of blocks.
4019
+ * Returns fee rate in sat/vB based on Blockstream's fee estimates API.
4020
+ * @param blocks - Confirmation target in blocks (1-25, 144, 504, 1008)
4021
+ * @returns Fee rate in sat/vB
4022
+ */ function fetchFeeEstimates(blocks) {
4023
+ return _async_to_generator(function() {
4024
+ var _ref, data, status, feeEstimates, availableTargets, closestTarget, error;
4025
+ return _ts_generator(this, function(_state) {
4026
+ switch(_state.label){
4027
+ case 0:
4028
+ _state.trys.push([
4029
+ 0,
4030
+ 2,
4031
+ ,
4032
+ 3
4033
+ ]);
4034
+ return [
4035
+ 4,
4036
+ this._axiosInstance.get("/fee-estimates")
4037
+ ];
4038
+ case 1:
4039
+ _ref = _state.sent(), data = _ref.data, status = _ref.status;
4040
+ if (status === 200) {
4041
+ feeEstimates = data;
4042
+ availableTargets = Object.keys(feeEstimates).map(Number).sort(function(a, b) {
4043
+ return a - b;
4044
+ });
4045
+ closestTarget = availableTargets.find(function(target) {
4046
+ return target >= blocks;
4047
+ }) || availableTargets[availableTargets.length - 1];
4048
+ return [
4049
+ 2,
4050
+ feeEstimates[closestTarget.toString()] || 10
4051
+ ];
4052
+ }
4053
+ throw parseHttpError(data);
4054
+ case 2:
4055
+ error = _state.sent();
4056
+ throw parseHttpError(error);
4057
+ case 3:
4058
+ return [
4059
+ 2
4060
+ ];
4061
+ }
4062
+ });
4063
+ }).call(this);
4064
+ }
4065
+ },
4015
4066
  {
4016
4067
  key: "submitTx",
4017
4068
  value: /**
@@ -4063,16 +4114,29 @@ var BlockstreamProvider = /*#__PURE__*/ function() {
4063
4114
  }();
4064
4115
  // src/providers/maestro.ts
4065
4116
  var MaestroProvider = /*#__PURE__*/ function() {
4066
- function MaestroProvider(param) {
4067
- var network = param.network, apiKey = param.apiKey;
4117
+ function MaestroProvider() {
4118
+ for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
4119
+ args[_key] = arguments[_key];
4120
+ }
4068
4121
  _class_call_check(this, MaestroProvider);
4069
- this._axiosInstance = axios_default.create({
4070
- baseURL: "https://xbt-".concat(network, ".gomaestro-api.org/v0"),
4071
- headers: {
4072
- "api-key": apiKey
4073
- }
4074
- });
4075
- this._network = network;
4122
+ if (typeof args[0] === "string" && (args[0].startsWith("http") || args[0].startsWith("/"))) {
4123
+ this._axiosInstance = axios_default.create({
4124
+ baseURL: args[0],
4125
+ headers: {
4126
+ "api-key": args[1]
4127
+ }
4128
+ });
4129
+ this._network = args[0].includes("testnet") ? "testnet" : "mainnet";
4130
+ } else {
4131
+ var _args_ = args[0], network = _args_.network, apiKey = _args_.apiKey;
4132
+ this._axiosInstance = axios_default.create({
4133
+ baseURL: "https://xbt-".concat(network, ".gomaestro-api.org/v0"),
4134
+ headers: {
4135
+ "api-key": apiKey
4136
+ }
4137
+ });
4138
+ this._network = network;
4139
+ }
4076
4140
  }
4077
4141
  _create_class(MaestroProvider, [
4078
4142
  {
@@ -4335,8 +4399,7 @@ var MaestroProvider = /*#__PURE__*/ function() {
4335
4399
  },
4336
4400
  {
4337
4401
  key: "fetchFeeEstimates",
4338
- value: // Additional Bitcoin-specific methods (beyond IBitcoinProvider)
4339
- /**
4402
+ value: /**
4340
4403
  * Get fee estimates for Bitcoin transactions.
4341
4404
  * @param blocks - The number of blocks to estimate fees for (default: 6).
4342
4405
  * @returns FeeEstimateResponse containing the estimated fee rate.
@@ -4361,7 +4424,7 @@ var MaestroProvider = /*#__PURE__*/ function() {
4361
4424
  _ref = _state.sent(), data = _ref.data, status = _ref.status;
4362
4425
  if (status === 200) return [
4363
4426
  2,
4364
- data
4427
+ data.data.feerate
4365
4428
  ];
4366
4429
  throw parseHttpError(data);
4367
4430
  case 2:
@@ -4378,7 +4441,8 @@ var MaestroProvider = /*#__PURE__*/ function() {
4378
4441
  },
4379
4442
  {
4380
4443
  key: "fetchSatoshiActivity",
4381
- value: /**
4444
+ value: // Additional Bitcoin-specific methods (beyond IBitcoinProvider)
4445
+ /**
4382
4446
  * Fetch satoshi activity for a Bitcoin address (transaction history).
4383
4447
  * @param address - The Bitcoin address.
4384
4448
  * @param options - Optional parameters for filtering and pagination.
@@ -4982,7 +5046,18 @@ var import_bip39 = require("bip39");
4982
5046
  var EmbeddedWallet = /*#__PURE__*/ function() {
4983
5047
  function EmbeddedWallet(options) {
4984
5048
  _class_call_check(this, EmbeddedWallet);
4985
- this._network = options.testnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin;
5049
+ switch(options.network){
5050
+ case "Testnet":
5051
+ this._network = bitcoin.networks.testnet;
5052
+ break;
5053
+ case "Regtest":
5054
+ this._network = bitcoin.networks.regtest;
5055
+ break;
5056
+ case "Mainnet":
5057
+ default:
5058
+ this._network = bitcoin.networks.bitcoin;
5059
+ break;
5060
+ }
4986
5061
  if (options.key.type === "mnemonic") {
4987
5062
  var _options_path;
4988
5063
  this._wallet = _derive(options.key.words, (_options_path = options.path) !== null && _options_path !== void 0 ? _options_path : "m/84'/0'/0'/0/0", this._network);
@@ -4995,24 +5070,56 @@ var EmbeddedWallet = /*#__PURE__*/ function() {
4995
5070
  }
4996
5071
  _create_class(EmbeddedWallet, [
4997
5072
  {
4998
- /**
4999
- * Returns the wallet's SegWit (P2WPKH) address and associated public key.
5073
+ key: "getAddresses",
5074
+ value: /**
5075
+ * Returns the wallet's Bitcoin addresses following Xverse API format.
5000
5076
  *
5001
- * @returns {Address} The wallet address object including address, public key, and metadata.
5002
- * @throws {Error} If internal address or public key is not properly initialized.
5003
- */ key: "getAddress",
5004
- value: function getAddress() {
5005
- if (this._isReadOnly && this._address) {
5006
- return {
5007
- address: this._address,
5008
- purpose: "payment",
5009
- addressType: "p2wpkh"
5010
- };
5011
- }
5012
- if (!this._wallet) {
5013
- throw new Error("Wallet not initialized properly.");
5014
- }
5015
- return resolveAddress(this._wallet.publicKey, this._network);
5077
+ * @param purposes Array of address purposes to request:
5078
+ * - `'ordinals'` for managing ordinals (should return P2TR taproot address)
5079
+ * - `'payment'` for managing bitcoin (returns P2WPKH address)
5080
+ * TODO: Should follow Xverse docs to return taproot address for ordinals purpose
5081
+ * @param message Optional message to display in request prompt (ignored for embedded wallets)
5082
+ * @returns {Promise<GetAddressResult[]>} Array of address objects with address, publicKey, purpose, addressType, network, and walletType
5083
+ * @throws {Error} If wallet is not properly initialized.
5084
+ */ function getAddresses(purposes, message) {
5085
+ return _async_to_generator(function() {
5086
+ var addressInfo;
5087
+ return _ts_generator(this, function(_state) {
5088
+ if (this._isReadOnly && this._address) {
5089
+ return [
5090
+ 2,
5091
+ [
5092
+ {
5093
+ address: this._address,
5094
+ publicKey: "",
5095
+ // Not available for read-only wallets
5096
+ purpose: "payment",
5097
+ addressType: "p2wpkh",
5098
+ network: this._getNetworkString(),
5099
+ walletType: "software"
5100
+ }
5101
+ ]
5102
+ ];
5103
+ }
5104
+ if (!this._wallet) {
5105
+ throw new Error("Wallet not initialized properly.");
5106
+ }
5107
+ addressInfo = resolveAddress(this._wallet.publicKey, this._network);
5108
+ return [
5109
+ 2,
5110
+ [
5111
+ {
5112
+ address: addressInfo.address,
5113
+ publicKey: addressInfo.publicKey || this._wallet.publicKey.toString("hex"),
5114
+ purpose: "payment",
5115
+ addressType: addressInfo.addressType,
5116
+ network: this._getNetworkString(),
5117
+ walletType: "software"
5118
+ }
5119
+ ]
5120
+ ];
5121
+ });
5122
+ }).call(this);
5016
5123
  }
5017
5124
  },
5018
5125
  {
@@ -5035,13 +5142,26 @@ var EmbeddedWallet = /*#__PURE__*/ function() {
5035
5142
  {
5036
5143
  /**
5037
5144
  * Returns the network identifier of the wallet.
5038
- * 0': Indicates the Bitcoin mainnet.
5039
- * 1': Indicates the Bitcoin testnet.
5145
+ * 0: Indicates the Bitcoin testnet.
5146
+ * 1: Indicates the Bitcoin mainnet.
5147
+ * 2: Indicates the Bitcoin regtest.
5040
5148
  *
5041
- * @returns {0 | 1} The Bitcoin network ID.
5149
+ * @returns {0 | 1 | 2} The Bitcoin network ID.
5042
5150
  */ key: "getNetworkId",
5043
5151
  value: function getNetworkId() {
5044
- return this._network === bitcoin.networks.testnet ? 1 : 0;
5152
+ if (this._network === bitcoin.networks.testnet) return 0;
5153
+ if (this._network === bitcoin.networks.regtest) return 2;
5154
+ return 1;
5155
+ }
5156
+ },
5157
+ {
5158
+ /**
5159
+ * Returns the network type as a string for API responses.
5160
+ */ key: "_getNetworkString",
5161
+ value: function _getNetworkString() {
5162
+ if (this._network === bitcoin.networks.testnet) return "testnet";
5163
+ if (this._network === bitcoin.networks.regtest) return "regtest";
5164
+ return "mainnet";
5045
5165
  }
5046
5166
  },
5047
5167
  {
@@ -5055,15 +5175,20 @@ var EmbeddedWallet = /*#__PURE__*/ function() {
5055
5175
  return _ts_generator(this, function(_state) {
5056
5176
  switch(_state.label){
5057
5177
  case 0:
5058
- address = this.getAddress();
5178
+ return [
5179
+ 4,
5180
+ this.getAddresses()
5181
+ ];
5182
+ case 1:
5183
+ address = _state.sent();
5059
5184
  if (this._provider === void 0) {
5060
5185
  throw new Error("`provider` is not defined. Provide a BitcoinProvider.");
5061
5186
  }
5062
5187
  return [
5063
5188
  4,
5064
- this._provider.fetchAddressUTxOs(address.address)
5189
+ this._provider.fetchAddressUTxOs(address[0].address)
5065
5190
  ];
5066
- case 1:
5191
+ case 2:
5067
5192
  return [
5068
5193
  2,
5069
5194
  _state.sent()
@@ -5074,17 +5199,21 @@ var EmbeddedWallet = /*#__PURE__*/ function() {
5074
5199
  }
5075
5200
  },
5076
5201
  {
5077
- key: "signData",
5202
+ key: "signMessage",
5078
5203
  value: /**
5079
- * Signs a given message using the wallet's private key.
5204
+ * Signs a message following Xverse API format.
5080
5205
  *
5081
- * @param message - The message to be signed.
5082
- * @returns The signature of the message as a string.
5206
+ * @param params - Object containing address, message, and optional protocol
5207
+ * @returns Promise resolving to signature result
5083
5208
  * @throws {Error} If the wallet is read-only or private key is not available.
5084
- */ function signData(message) {
5209
+ */ function signMessage(params) {
5085
5210
  return _async_to_generator(function() {
5086
- var keyPair, messageBuffer, bufferToHash, hash, signature;
5211
+ var address, message, _params_protocol, protocol, keyPair, messageBuffer, bufferToHash, hash, signature;
5087
5212
  return _ts_generator(this, function(_state) {
5213
+ address = params.address, message = params.message, _params_protocol = params.protocol, protocol = _params_protocol === void 0 ? "ECDSA" : _params_protocol;
5214
+ if (protocol === "BIP322") {
5215
+ throw new Error("BIP322 protocol is not yet supported. Only ECDSA is currently available.");
5216
+ }
5088
5217
  if (this._isReadOnly) {
5089
5218
  throw new Error("Cannot sign data with a read-only wallet.");
5090
5219
  }
@@ -5103,52 +5232,233 @@ var EmbeddedWallet = /*#__PURE__*/ function() {
5103
5232
  signature = keyPair.sign(hash);
5104
5233
  return [
5105
5234
  2,
5106
- signature.toString("base64")
5235
+ {
5236
+ signature: signature.toString("base64"),
5237
+ messageHash: hash.toString("hex"),
5238
+ address: address
5239
+ }
5107
5240
  ];
5108
5241
  });
5109
5242
  }).call(this);
5110
5243
  }
5111
5244
  },
5112
5245
  {
5113
- key: "signTx",
5246
+ key: "signPsbt",
5114
5247
  value: /**
5115
- * Sign a transaction payload.
5116
- * @param payload - The transaction payload to sign.
5117
- * @returns The signed transaction in hex format.
5248
+ * Sign a PSBT following Xverse API format.
5249
+ * @param params - Object containing PSBT and signing instructions
5250
+ * @returns Promise resolving to signed PSBT result
5118
5251
  * @throws {Error} If the wallet is read-only or private key is not available.
5119
- */ function signTx(payload) {
5252
+ */ function signPsbt(params) {
5120
5253
  return _async_to_generator(function() {
5121
- var psbt, p2wpkh, ecPair, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, input, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, output, i;
5254
+ var _this, psbtBase64, signInputs, _params_broadcast, broadcast, psbt, ecPair, allInputIndexes, signedPsbt, txHex, txid;
5122
5255
  return _ts_generator(this, function(_state) {
5123
- if (this._isReadOnly) {
5124
- throw new Error("Cannot sign transactions with a read-only wallet.");
5256
+ switch(_state.label){
5257
+ case 0:
5258
+ _this = this;
5259
+ psbtBase64 = params.psbt, signInputs = params.signInputs, _params_broadcast = params.broadcast, broadcast = _params_broadcast === void 0 ? false : _params_broadcast;
5260
+ if (this._isReadOnly) {
5261
+ throw new Error("Cannot sign transactions with a read-only wallet.");
5262
+ }
5263
+ if (!this._wallet || !this._wallet.privateKey) {
5264
+ throw new Error("Private key is not available for signing.");
5265
+ }
5266
+ psbt = bitcoin.Psbt.fromBase64(psbtBase64, {
5267
+ network: this._network
5268
+ });
5269
+ ecPair = ECPair.fromPrivateKey(this._wallet.privateKey, {
5270
+ network: this._network
5271
+ });
5272
+ allInputIndexes = Object.values(signInputs).flat();
5273
+ allInputIndexes.forEach(function(inputIndex) {
5274
+ psbt.signInput(inputIndex, _this._wallet);
5275
+ psbt.validateSignaturesOfInput(inputIndex, function(pubkey, hash, signature) {
5276
+ return ecPair.publicKey.equals(pubkey) && ecPair.verify(hash, signature);
5277
+ });
5278
+ });
5279
+ signedPsbt = psbt.toBase64();
5280
+ if (!broadcast) return [
5281
+ 3,
5282
+ 2
5283
+ ];
5284
+ if (!this._provider) {
5285
+ throw new Error("`provider` is not defined. Provide a BitcoinProvider for broadcasting.");
5286
+ }
5287
+ psbt.finalizeAllInputs();
5288
+ txHex = psbt.extractTransaction().toHex();
5289
+ return [
5290
+ 4,
5291
+ this._provider.submitTx(txHex)
5292
+ ];
5293
+ case 1:
5294
+ txid = _state.sent();
5295
+ return [
5296
+ 2,
5297
+ {
5298
+ psbt: signedPsbt,
5299
+ txid: txid
5300
+ }
5301
+ ];
5302
+ case 2:
5303
+ return [
5304
+ 2,
5305
+ {
5306
+ psbt: signedPsbt
5307
+ }
5308
+ ];
5125
5309
  }
5310
+ });
5311
+ }).call(this);
5312
+ }
5313
+ },
5314
+ {
5315
+ key: "sendTransfer",
5316
+ value: /**
5317
+ * Send Bitcoin to recipients following Xverse API format.
5318
+ * @param params - Object containing recipients array
5319
+ * @returns Promise resolving to transaction result
5320
+ * @throws {Error} If the wallet is read-only or provider is not available.
5321
+ */ function sendTransfer(params) {
5322
+ return _async_to_generator(function() {
5323
+ var recipients, _ref, addresses, utxos, walletAddress, psbt, inputCount, signInputs, signResult;
5324
+ return _ts_generator(this, function(_state) {
5325
+ switch(_state.label){
5326
+ case 0:
5327
+ if (this._isReadOnly) {
5328
+ throw new Error("Cannot send transactions with a read-only wallet.");
5329
+ }
5330
+ if (!this._provider) {
5331
+ throw new Error("`provider` is not defined. Provide a BitcoinProvider for sending.");
5332
+ }
5333
+ if (!this._wallet) {
5334
+ throw new Error("Wallet not initialized properly.");
5335
+ }
5336
+ recipients = params.recipients;
5337
+ return [
5338
+ 4,
5339
+ Promise.all([
5340
+ this.getAddresses(),
5341
+ this.getUTxOs()
5342
+ ])
5343
+ ];
5344
+ case 1:
5345
+ _ref = _sliced_to_array.apply(void 0, [
5346
+ _state.sent(),
5347
+ 2
5348
+ ]), addresses = _ref[0], utxos = _ref[1];
5349
+ walletAddress = addresses[0].address;
5350
+ return [
5351
+ 4,
5352
+ this._buildTransferPsbt(utxos, recipients, walletAddress)
5353
+ ];
5354
+ case 2:
5355
+ psbt = _state.sent();
5356
+ inputCount = psbt.inputCount;
5357
+ signInputs = _define_property({}, walletAddress, Array.from({
5358
+ length: inputCount
5359
+ }, function(_, i) {
5360
+ return i;
5361
+ }));
5362
+ return [
5363
+ 4,
5364
+ this.signPsbt({
5365
+ psbt: psbt.toBase64(),
5366
+ signInputs: signInputs,
5367
+ broadcast: true
5368
+ })
5369
+ ];
5370
+ case 3:
5371
+ signResult = _state.sent();
5372
+ return [
5373
+ 2,
5374
+ {
5375
+ txid: signResult.txid
5376
+ }
5377
+ ];
5378
+ }
5379
+ });
5380
+ }).call(this);
5381
+ }
5382
+ },
5383
+ {
5384
+ key: "getBalance",
5385
+ value: /**
5386
+ * Get wallet balance following Xverse API format.
5387
+ * @returns Promise resolving to balance information
5388
+ * @throws {Error} If provider is not available.
5389
+ */ function getBalance() {
5390
+ return _async_to_generator(function() {
5391
+ var addresses, address, addressInfo, confirmed, unconfirmed, total;
5392
+ return _ts_generator(this, function(_state) {
5393
+ switch(_state.label){
5394
+ case 0:
5395
+ if (!this._provider) {
5396
+ throw new Error("`provider` is not defined. Provide a BitcoinProvider for balance.");
5397
+ }
5398
+ return [
5399
+ 4,
5400
+ this.getAddresses()
5401
+ ];
5402
+ case 1:
5403
+ addresses = _state.sent();
5404
+ address = addresses[0].address;
5405
+ return [
5406
+ 4,
5407
+ this._provider.fetchAddress(address)
5408
+ ];
5409
+ case 2:
5410
+ addressInfo = _state.sent();
5411
+ confirmed = addressInfo.chain_stats.funded_txo_sum - addressInfo.chain_stats.spent_txo_sum;
5412
+ unconfirmed = addressInfo.mempool_stats.funded_txo_sum - addressInfo.mempool_stats.spent_txo_sum;
5413
+ total = confirmed + unconfirmed;
5414
+ return [
5415
+ 2,
5416
+ {
5417
+ confirmed: confirmed.toString(),
5418
+ unconfirmed: unconfirmed.toString(),
5419
+ total: total.toString()
5420
+ }
5421
+ ];
5422
+ }
5423
+ });
5424
+ }).call(this);
5425
+ }
5426
+ },
5427
+ {
5428
+ key: "signMultipleTransactions",
5429
+ value: /**
5430
+ * Sign multiple transactions (Xverse custom method).
5431
+ * @param params - Object containing network, message, and PSBTs array
5432
+ * @returns Promise resolving to signed PSBTs
5433
+ * @throws {Error} If the wallet is read-only or private key is not available.
5434
+ */ function signMultipleTransactions(params) {
5435
+ return _async_to_generator(function() {
5436
+ var _this, psbts, results, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _this1, _loop, _iterator, _step;
5437
+ return _ts_generator(this, function(_state) {
5438
+ _this = this;
5126
5439
  if (!this._wallet || !this._wallet.privateKey) {
5127
5440
  throw new Error("Private key is not available for signing.");
5128
5441
  }
5129
- psbt = new bitcoin.Psbt({
5130
- network: this._network
5131
- });
5132
- p2wpkh = bitcoin.payments.p2wpkh({
5133
- pubkey: this._wallet.publicKey,
5134
- network: this._network
5135
- });
5136
- ecPair = ECPair.fromPrivateKey(this._wallet.privateKey, {
5137
- network: this._network
5138
- });
5442
+ psbts = params.psbts;
5443
+ results = [];
5139
5444
  _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
5140
5445
  try {
5141
- for(_iterator = payload.inputs[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
5142
- input = _step.value;
5143
- psbt.addInput({
5144
- hash: input.txid,
5145
- index: input.vout,
5146
- witnessUtxo: {
5147
- script: p2wpkh.output,
5148
- value: input.value
5149
- }
5446
+ _loop = function() {
5447
+ var psbtInfo = _step.value;
5448
+ var psbt = bitcoin.Psbt.fromBase64(psbtInfo.psbtBase64, {
5449
+ network: _this1._network
5150
5450
  });
5151
- }
5451
+ var inputIndexes = psbtInfo.inputsToSign.flatMap(function(input) {
5452
+ return input.signingIndexes;
5453
+ });
5454
+ inputIndexes.forEach(function(index) {
5455
+ return psbt.signInput(index, _this._wallet);
5456
+ });
5457
+ results.push({
5458
+ psbt: psbt.toBase64()
5459
+ });
5460
+ };
5461
+ for(_iterator = psbts[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true)_this1 = this, _loop();
5152
5462
  } catch (err) {
5153
5463
  _didIteratorError = true;
5154
5464
  _iteratorError = err;
@@ -5163,43 +5473,150 @@ var EmbeddedWallet = /*#__PURE__*/ function() {
5163
5473
  }
5164
5474
  }
5165
5475
  }
5166
- _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
5167
- try {
5168
- for(_iterator1 = payload.outputs[Symbol.iterator](); !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
5169
- output = _step1.value;
5170
- psbt.addOutput({
5171
- address: output.address,
5172
- value: output.value
5173
- });
5174
- }
5175
- } catch (err) {
5176
- _didIteratorError1 = true;
5177
- _iteratorError1 = err;
5178
- } finally{
5179
- try {
5180
- if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
5181
- _iterator1.return();
5182
- }
5183
- } finally{
5184
- if (_didIteratorError1) {
5185
- throw _iteratorError1;
5186
- }
5187
- }
5188
- }
5189
- for(i = 0; i < payload.inputs.length; i++){
5190
- psbt.signInput(i, this._wallet);
5191
- psbt.validateSignaturesOfInput(i, function(pubkey, hash, signature) {
5192
- return ecPair.publicKey.equals(pubkey) && ecPair.verify(hash, signature);
5193
- });
5194
- }
5195
- psbt.finalizeAllInputs();
5196
5476
  return [
5197
5477
  2,
5198
- psbt.extractTransaction().toHex()
5478
+ results
5199
5479
  ];
5200
5480
  });
5201
5481
  }).call(this);
5202
5482
  }
5483
+ },
5484
+ {
5485
+ /**
5486
+ * Simple largest-first coin selection algorithm.
5487
+ * Selects UTXOs in descending order by value until target amount + fees is reached.
5488
+ *
5489
+ * @param utxos Available UTXOs
5490
+ * @param targetAmount Amount needed in satoshis
5491
+ * @param feeRate Fee rate in sat/vByte
5492
+ * @returns Selected UTXOs and change amount
5493
+ */ key: "_selectUtxosLargestFirst",
5494
+ value: function _selectUtxosLargestFirst(utxos, targetAmount, feeRate) {
5495
+ var sortedUtxos = _to_consumable_array(utxos).sort(function(a, b) {
5496
+ return b.value - a.value;
5497
+ });
5498
+ var selectedValue = 0;
5499
+ var selectedUtxos = [];
5500
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
5501
+ try {
5502
+ for(var _iterator = sortedUtxos[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
5503
+ var utxo = _step.value;
5504
+ selectedUtxos.push(utxo);
5505
+ selectedValue += utxo.value;
5506
+ var estimatedTxSize = selectedUtxos.length * 150 + 2 * 34 + 10;
5507
+ var fee = Math.ceil(estimatedTxSize * feeRate);
5508
+ if (selectedValue >= targetAmount + fee) {
5509
+ var finalFee = Math.ceil((selectedUtxos.length * 150 + 2 * 34 + 10) * feeRate);
5510
+ var change = selectedValue - targetAmount - finalFee;
5511
+ return {
5512
+ selectedUtxos: selectedUtxos,
5513
+ change: change
5514
+ };
5515
+ }
5516
+ }
5517
+ } catch (err) {
5518
+ _didIteratorError = true;
5519
+ _iteratorError = err;
5520
+ } finally{
5521
+ try {
5522
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
5523
+ _iterator.return();
5524
+ }
5525
+ } finally{
5526
+ if (_didIteratorError) {
5527
+ throw _iteratorError;
5528
+ }
5529
+ }
5530
+ }
5531
+ throw new Error("Insufficient funds for transaction.");
5532
+ }
5533
+ },
5534
+ {
5535
+ key: "_buildTransferPsbt",
5536
+ value: /**
5537
+ * Build PSBT for transfer using optimal coin selection.
5538
+ * @param utxos Available UTXOs
5539
+ * @param recipients Transfer recipients
5540
+ * @param walletAddress Wallet address for change
5541
+ * @returns Built PSBT ready for signing
5542
+ */ function _buildTransferPsbt(utxos, recipients, walletAddress) {
5543
+ return _async_to_generator(function() {
5544
+ var feeRate, error, targetAmount, _this__selectUtxosLargestFirst, selectedUtxos, change, psbt, p2wpkh;
5545
+ return _ts_generator(this, function(_state) {
5546
+ switch(_state.label){
5547
+ case 0:
5548
+ feeRate = 10;
5549
+ if (!this._provider) return [
5550
+ 3,
5551
+ 4
5552
+ ];
5553
+ _state.label = 1;
5554
+ case 1:
5555
+ _state.trys.push([
5556
+ 1,
5557
+ 3,
5558
+ ,
5559
+ 4
5560
+ ]);
5561
+ return [
5562
+ 4,
5563
+ this._provider.fetchFeeEstimates(6)
5564
+ ];
5565
+ case 2:
5566
+ feeRate = _state.sent();
5567
+ return [
5568
+ 3,
5569
+ 4
5570
+ ];
5571
+ case 3:
5572
+ error = _state.sent();
5573
+ console.warn("Fee estimation failed, using default rate:", error);
5574
+ return [
5575
+ 3,
5576
+ 4
5577
+ ];
5578
+ case 4:
5579
+ targetAmount = recipients.reduce(function(sum, r) {
5580
+ return sum + r.amount;
5581
+ }, 0);
5582
+ _this__selectUtxosLargestFirst = this._selectUtxosLargestFirst(utxos, targetAmount, feeRate), selectedUtxos = _this__selectUtxosLargestFirst.selectedUtxos, change = _this__selectUtxosLargestFirst.change;
5583
+ psbt = new bitcoin.Psbt({
5584
+ network: this._network
5585
+ });
5586
+ p2wpkh = bitcoin.payments.p2wpkh({
5587
+ pubkey: this._wallet.publicKey,
5588
+ network: this._network
5589
+ });
5590
+ selectedUtxos.forEach(function(utxo) {
5591
+ psbt.addInput({
5592
+ hash: utxo.txid,
5593
+ index: utxo.vout,
5594
+ witnessUtxo: {
5595
+ script: p2wpkh.output,
5596
+ value: utxo.value
5597
+ }
5598
+ });
5599
+ });
5600
+ recipients.forEach(function(recipient) {
5601
+ psbt.addOutput({
5602
+ address: recipient.address,
5603
+ value: recipient.amount
5604
+ });
5605
+ });
5606
+ if (change > 0) {
5607
+ psbt.addOutput({
5608
+ address: walletAddress,
5609
+ value: change
5610
+ });
5611
+ }
5612
+ return [
5613
+ 2,
5614
+ psbt
5615
+ ];
5616
+ }
5617
+ });
5618
+ }).call(this);
5619
+ }
5203
5620
  }
5204
5621
  ], [
5205
5622
  {