@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 +522 -105
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +190 -67
- package/dist/index.d.ts +190 -67
- package/dist/index.js +522 -105
- package/dist/index.js.map +1 -1
- package/package.json +5 -2
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
|
|
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(
|
|
4067
|
-
var
|
|
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
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
5073
|
+
key: "getAddresses",
|
|
5074
|
+
value: /**
|
|
5075
|
+
* Returns the wallet's Bitcoin addresses following Xverse API format.
|
|
5000
5076
|
*
|
|
5001
|
-
* @
|
|
5002
|
-
*
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
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
|
|
5039
|
-
* 1
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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: "
|
|
5202
|
+
key: "signMessage",
|
|
5078
5203
|
value: /**
|
|
5079
|
-
* Signs a
|
|
5204
|
+
* Signs a message following Xverse API format.
|
|
5080
5205
|
*
|
|
5081
|
-
* @param
|
|
5082
|
-
* @returns
|
|
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
|
|
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
|
-
|
|
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: "
|
|
5246
|
+
key: "signPsbt",
|
|
5114
5247
|
value: /**
|
|
5115
|
-
* Sign a
|
|
5116
|
-
* @param
|
|
5117
|
-
* @returns
|
|
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
|
|
5252
|
+
*/ function signPsbt(params) {
|
|
5120
5253
|
return _async_to_generator(function() {
|
|
5121
|
-
var
|
|
5254
|
+
var _this, psbtBase64, signInputs, _params_broadcast, broadcast, psbt, ecPair, allInputIndexes, signedPsbt, txHex, txid;
|
|
5122
5255
|
return _ts_generator(this, function(_state) {
|
|
5123
|
-
|
|
5124
|
-
|
|
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
|
-
|
|
5130
|
-
|
|
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
|
-
|
|
5142
|
-
|
|
5143
|
-
psbt.
|
|
5144
|
-
|
|
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
|
-
|
|
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
|
{
|