@dynamic-labs-wallet/btc-utils 1.1.28 → 1.1.30
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/index.cjs +178 -29
- package/index.esm.js +177 -30
- package/package.json +2 -2
- package/src/getFeeRates/getFeeRates.d.ts +12 -8
- package/src/getFeeRates/getFeeRates.d.ts.map +1 -1
- package/src/getUTXOs/getUTXOs.d.ts +2 -2
- package/src/getUTXOs/getUTXOs.d.ts.map +1 -1
- package/src/index.d.ts +2 -0
- package/src/index.d.ts.map +1 -1
- package/src/resolveRpcUrl/index.d.ts +2 -0
- package/src/resolveRpcUrl/index.d.ts.map +1 -0
- package/src/resolveRpcUrl/resolveRpcUrl.d.ts +14 -0
- package/src/resolveRpcUrl/resolveRpcUrl.d.ts.map +1 -0
- package/src/rpcFetch/index.d.ts +2 -0
- package/src/rpcFetch/index.d.ts.map +1 -0
- package/src/rpcFetch/rpcFetch.d.ts +9 -0
- package/src/rpcFetch/rpcFetch.d.ts.map +1 -0
package/index.cjs
CHANGED
|
@@ -182,7 +182,7 @@ function _instanceof$8(left, right) {
|
|
|
182
182
|
return left instanceof right;
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
-
function _type_of$
|
|
185
|
+
function _type_of$2(obj) {
|
|
186
186
|
"@swc/helpers - typeof";
|
|
187
187
|
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
188
188
|
}
|
|
@@ -207,7 +207,7 @@ function _type_of$1(obj) {
|
|
|
207
207
|
}
|
|
208
208
|
return result;
|
|
209
209
|
}
|
|
210
|
-
if ((typeof actualPubkey === "undefined" ? "undefined" : _type_of$
|
|
210
|
+
if ((typeof actualPubkey === "undefined" ? "undefined" : _type_of$2(actualPubkey)) === 'object' && actualPubkey !== null) {
|
|
211
211
|
return convertObjectToBuffer(actualPubkey);
|
|
212
212
|
}
|
|
213
213
|
throw new Error('Invalid public key format');
|
|
@@ -816,6 +816,54 @@ function _instanceof$3(left, right) {
|
|
|
816
816
|
return network === core.BitcoinNetwork.MAINNET ? 'https://mempool.space/api' : 'https://mempool.space/testnet/api';
|
|
817
817
|
};
|
|
818
818
|
|
|
819
|
+
var LOOPBACK_HOSTNAMES = new Set([
|
|
820
|
+
'localhost',
|
|
821
|
+
'127.0.0.1',
|
|
822
|
+
'[::1]'
|
|
823
|
+
]);
|
|
824
|
+
/**
|
|
825
|
+
* Resolves the Esplora-compatible base URL to use for a network.
|
|
826
|
+
* Falls back to the default (mempool.space) when no custom URL is given.
|
|
827
|
+
*
|
|
828
|
+
* @param network - The Bitcoin network
|
|
829
|
+
* @param rpcUrl - Optional custom Esplora-compatible base URL
|
|
830
|
+
* @returns The base URL without a trailing slash
|
|
831
|
+
*/ var resolveRpcUrl = function(param) {
|
|
832
|
+
var network = param.network, rpcUrl = param.rpcUrl;
|
|
833
|
+
if (!rpcUrl) {
|
|
834
|
+
return getDefaultRpcUrl(network);
|
|
835
|
+
}
|
|
836
|
+
var parsed;
|
|
837
|
+
try {
|
|
838
|
+
parsed = new URL(rpcUrl);
|
|
839
|
+
} catch (e) {
|
|
840
|
+
throw new Error('Invalid Bitcoin RPC URL');
|
|
841
|
+
}
|
|
842
|
+
var isSecure = parsed.protocol === 'https:';
|
|
843
|
+
var isLocalHttp = parsed.protocol === 'http:' && LOOPBACK_HOSTNAMES.has(parsed.hostname);
|
|
844
|
+
if (!isSecure && !isLocalHttp) {
|
|
845
|
+
throw new Error('Bitcoin RPC URL must use https (http is only allowed for localhost)');
|
|
846
|
+
}
|
|
847
|
+
// Manual trim: a /\/+$/ regex backtracks quadratically on long runs of slashes.
|
|
848
|
+
var end = rpcUrl.length;
|
|
849
|
+
while(end > 0 && rpcUrl[end - 1] === '/'){
|
|
850
|
+
end -= 1;
|
|
851
|
+
}
|
|
852
|
+
return rpcUrl.slice(0, end);
|
|
853
|
+
};
|
|
854
|
+
|
|
855
|
+
/**
|
|
856
|
+
* fetch wrapper for Esplora requests. Requests to a custom `rpcUrl` do not follow
|
|
857
|
+
* redirects, so they cannot be bounced to a host other than the configured backend.
|
|
858
|
+
*
|
|
859
|
+
* @param url - The full request URL
|
|
860
|
+
* @param rpcUrl - The custom RPC URL the request was built from, if any
|
|
861
|
+
*/ var rpcFetch = function(url, rpcUrl) {
|
|
862
|
+
return rpcUrl ? fetch(url, {
|
|
863
|
+
redirect: 'error'
|
|
864
|
+
}) : fetch(url);
|
|
865
|
+
};
|
|
866
|
+
|
|
819
867
|
function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
|
|
820
868
|
try {
|
|
821
869
|
var info = gen[key](arg);
|
|
@@ -941,11 +989,11 @@ function _ts_generator$1(thisArg, body) {
|
|
|
941
989
|
}
|
|
942
990
|
}
|
|
943
991
|
/**
|
|
944
|
-
* Fetches UTXOs for a given address using mempool.space
|
|
992
|
+
* Fetches UTXOs for a given address using an Esplora-compatible API (mempool.space by default)
|
|
945
993
|
*
|
|
946
994
|
* @param address - The address to fetch UTXOs for
|
|
947
995
|
* @param network - The Bitcoin network (default: MAINNET)
|
|
948
|
-
* @param rpcUrl - Optional custom RPC URL
|
|
996
|
+
* @param rpcUrl - Optional custom Esplora-compatible RPC URL
|
|
949
997
|
* @returns The list of UTXOs
|
|
950
998
|
*/ var getUTXOs = /*#__PURE__*/ function() {
|
|
951
999
|
var _ref = _async_to_generator$1(function(param) {
|
|
@@ -954,7 +1002,10 @@ function _ts_generator$1(thisArg, body) {
|
|
|
954
1002
|
switch(_state.label){
|
|
955
1003
|
case 0:
|
|
956
1004
|
address = param.address, _param_network = param.network, network = _param_network === void 0 ? core.BitcoinNetwork.MAINNET : _param_network, rpcUrl = param.rpcUrl;
|
|
957
|
-
baseUrl =
|
|
1005
|
+
baseUrl = resolveRpcUrl({
|
|
1006
|
+
network: network,
|
|
1007
|
+
rpcUrl: rpcUrl
|
|
1008
|
+
});
|
|
958
1009
|
_state.label = 1;
|
|
959
1010
|
case 1:
|
|
960
1011
|
_state.trys.push([
|
|
@@ -965,7 +1016,7 @@ function _ts_generator$1(thisArg, body) {
|
|
|
965
1016
|
]);
|
|
966
1017
|
return [
|
|
967
1018
|
4,
|
|
968
|
-
|
|
1019
|
+
rpcFetch("".concat(baseUrl, "/address/").concat(address, "/utxo"), rpcUrl)
|
|
969
1020
|
];
|
|
970
1021
|
case 2:
|
|
971
1022
|
response = _state.sent();
|
|
@@ -1003,30 +1054,30 @@ function _ts_generator$1(thisArg, body) {
|
|
|
1003
1054
|
};
|
|
1004
1055
|
}();
|
|
1005
1056
|
|
|
1006
|
-
function _array_like_to_array(arr, len) {
|
|
1057
|
+
function _array_like_to_array$1(arr, len) {
|
|
1007
1058
|
if (len == null || len > arr.length) len = arr.length;
|
|
1008
1059
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
1009
1060
|
return arr2;
|
|
1010
1061
|
}
|
|
1011
|
-
function _array_without_holes(arr) {
|
|
1012
|
-
if (Array.isArray(arr)) return _array_like_to_array(arr);
|
|
1062
|
+
function _array_without_holes$1(arr) {
|
|
1063
|
+
if (Array.isArray(arr)) return _array_like_to_array$1(arr);
|
|
1013
1064
|
}
|
|
1014
|
-
function _iterable_to_array(iter) {
|
|
1065
|
+
function _iterable_to_array$1(iter) {
|
|
1015
1066
|
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
1016
1067
|
}
|
|
1017
|
-
function _non_iterable_spread() {
|
|
1068
|
+
function _non_iterable_spread$1() {
|
|
1018
1069
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
1019
1070
|
}
|
|
1020
|
-
function _to_consumable_array(arr) {
|
|
1021
|
-
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
|
|
1071
|
+
function _to_consumable_array$1(arr) {
|
|
1072
|
+
return _array_without_holes$1(arr) || _iterable_to_array$1(arr) || _unsupported_iterable_to_array$1(arr) || _non_iterable_spread$1();
|
|
1022
1073
|
}
|
|
1023
|
-
function _unsupported_iterable_to_array(o, minLen) {
|
|
1074
|
+
function _unsupported_iterable_to_array$1(o, minLen) {
|
|
1024
1075
|
if (!o) return;
|
|
1025
|
-
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
1076
|
+
if (typeof o === "string") return _array_like_to_array$1(o, minLen);
|
|
1026
1077
|
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
1027
1078
|
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
1028
1079
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
1029
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
1080
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$1(o, minLen);
|
|
1030
1081
|
}
|
|
1031
1082
|
/**
|
|
1032
1083
|
* Simple greedy coin selection
|
|
@@ -1038,7 +1089,7 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
1038
1089
|
*/ var selectUTXOs = function(param) {
|
|
1039
1090
|
var utxos = param.utxos, amount = param.amount, feeRate = param.feeRate;
|
|
1040
1091
|
// Sort by value descending
|
|
1041
|
-
var sorted = _to_consumable_array(utxos).sort(function(a, b) {
|
|
1092
|
+
var sorted = _to_consumable_array$1(utxos).sort(function(a, b) {
|
|
1042
1093
|
return Number(b.value - a.value);
|
|
1043
1094
|
});
|
|
1044
1095
|
var inputs = [];
|
|
@@ -1084,6 +1135,14 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
1084
1135
|
throw new Error('Insufficient funds');
|
|
1085
1136
|
};
|
|
1086
1137
|
|
|
1138
|
+
function _array_like_to_array(arr, len) {
|
|
1139
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
1140
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
1141
|
+
return arr2;
|
|
1142
|
+
}
|
|
1143
|
+
function _array_without_holes(arr) {
|
|
1144
|
+
if (Array.isArray(arr)) return _array_like_to_array(arr);
|
|
1145
|
+
}
|
|
1087
1146
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
1088
1147
|
try {
|
|
1089
1148
|
var info = gen[key](arg);
|
|
@@ -1113,6 +1172,27 @@ function _async_to_generator(fn) {
|
|
|
1113
1172
|
});
|
|
1114
1173
|
};
|
|
1115
1174
|
}
|
|
1175
|
+
function _iterable_to_array(iter) {
|
|
1176
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
1177
|
+
}
|
|
1178
|
+
function _non_iterable_spread() {
|
|
1179
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
1180
|
+
}
|
|
1181
|
+
function _to_consumable_array(arr) {
|
|
1182
|
+
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
|
|
1183
|
+
}
|
|
1184
|
+
function _type_of$1(obj) {
|
|
1185
|
+
"@swc/helpers - typeof";
|
|
1186
|
+
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
1187
|
+
}
|
|
1188
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
1189
|
+
if (!o) return;
|
|
1190
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
1191
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
1192
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
1193
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
1194
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
1195
|
+
}
|
|
1116
1196
|
function _ts_generator(thisArg, body) {
|
|
1117
1197
|
var f, y, t, g, _ = {
|
|
1118
1198
|
label: 0,
|
|
@@ -1208,30 +1288,65 @@ function _ts_generator(thisArg, body) {
|
|
|
1208
1288
|
};
|
|
1209
1289
|
}
|
|
1210
1290
|
}
|
|
1291
|
+
// Block targets approximating mempool's fastest / half-hour / hour fees.
|
|
1292
|
+
var ESPLORA_TARGETS = {
|
|
1293
|
+
fast: 1,
|
|
1294
|
+
medium: 3,
|
|
1295
|
+
slow: 6
|
|
1296
|
+
};
|
|
1297
|
+
// Backends are untrusted input: reject anything that is not a positive finite number.
|
|
1298
|
+
var assertFeeRate = function(value) {
|
|
1299
|
+
if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) {
|
|
1300
|
+
throw new Error('invalid fee estimate');
|
|
1301
|
+
}
|
|
1302
|
+
return value;
|
|
1303
|
+
};
|
|
1304
|
+
var pickEstimate = function(estimates, target) {
|
|
1305
|
+
var targets = Object.keys(estimates).map(Number).filter(function(key) {
|
|
1306
|
+
return Number.isFinite(key);
|
|
1307
|
+
}).sort(function(a, b) {
|
|
1308
|
+
return a - b;
|
|
1309
|
+
});
|
|
1310
|
+
if (targets.length === 0) {
|
|
1311
|
+
throw new Error('empty fee estimates');
|
|
1312
|
+
}
|
|
1313
|
+
var _reverse_find;
|
|
1314
|
+
// Closest target not exceeding the wanted one, else the fastest available.
|
|
1315
|
+
var key = (_reverse_find = _to_consumable_array(targets).reverse().find(function(candidate) {
|
|
1316
|
+
return candidate <= target;
|
|
1317
|
+
})) !== null && _reverse_find !== void 0 ? _reverse_find : targets[0];
|
|
1318
|
+
return Math.ceil(assertFeeRate(estimates[String(key)]));
|
|
1319
|
+
};
|
|
1211
1320
|
/**
|
|
1212
|
-
* Fetches current fee rates
|
|
1213
|
-
*
|
|
1321
|
+
* Fetches current fee rates in sat/vByte.
|
|
1322
|
+
* Uses the mempool.space `/v1/fees/recommended` endpoint. For a custom Esplora-compatible
|
|
1323
|
+
* `rpcUrl` that does not serve it, falls back to the standard `/fee-estimates` endpoint
|
|
1324
|
+
* on the same backend. Never falls back to a different host.
|
|
1214
1325
|
*
|
|
1215
1326
|
* @param network - The Bitcoin network (default: MAINNET)
|
|
1216
|
-
* @param rpcUrl - Optional custom RPC URL
|
|
1327
|
+
* @param rpcUrl - Optional custom Esplora-compatible RPC URL
|
|
1217
1328
|
* @returns The fee rates for fast, medium, and slow transactions
|
|
1218
1329
|
*/ var getFeeRates = /*#__PURE__*/ function() {
|
|
1219
1330
|
var _ref = _async_to_generator(function(param) {
|
|
1220
|
-
var _param_network, network, rpcUrl, baseUrl, response, fees;
|
|
1331
|
+
var _param_network, network, rpcUrl, baseUrl, response, fees, fallback, estimates, rates;
|
|
1221
1332
|
return _ts_generator(this, function(_state) {
|
|
1222
1333
|
switch(_state.label){
|
|
1223
1334
|
case 0:
|
|
1224
1335
|
_param_network = param.network, network = _param_network === void 0 ? core.BitcoinNetwork.MAINNET : _param_network, rpcUrl = param.rpcUrl;
|
|
1225
|
-
baseUrl =
|
|
1336
|
+
baseUrl = resolveRpcUrl({
|
|
1337
|
+
network: network,
|
|
1338
|
+
rpcUrl: rpcUrl
|
|
1339
|
+
});
|
|
1226
1340
|
return [
|
|
1227
1341
|
4,
|
|
1228
|
-
|
|
1342
|
+
rpcFetch("".concat(baseUrl, "/v1/fees/recommended"), rpcUrl)
|
|
1229
1343
|
];
|
|
1230
1344
|
case 1:
|
|
1231
1345
|
response = _state.sent();
|
|
1232
|
-
if (!response.ok)
|
|
1233
|
-
|
|
1234
|
-
|
|
1346
|
+
if (!response.ok) return [
|
|
1347
|
+
3,
|
|
1348
|
+
3
|
|
1349
|
+
];
|
|
1235
1350
|
return [
|
|
1236
1351
|
4,
|
|
1237
1352
|
response.json()
|
|
@@ -1241,9 +1356,41 @@ function _ts_generator(thisArg, body) {
|
|
|
1241
1356
|
return [
|
|
1242
1357
|
2,
|
|
1243
1358
|
{
|
|
1244
|
-
fast: fees.fastestFee,
|
|
1245
|
-
medium: fees.halfHourFee,
|
|
1246
|
-
slow: fees.hourFee
|
|
1359
|
+
fast: assertFeeRate(fees.fastestFee),
|
|
1360
|
+
medium: assertFeeRate(fees.halfHourFee),
|
|
1361
|
+
slow: assertFeeRate(fees.hourFee)
|
|
1362
|
+
}
|
|
1363
|
+
];
|
|
1364
|
+
case 3:
|
|
1365
|
+
if (!rpcUrl) {
|
|
1366
|
+
throw new Error("Failed to fetch fee rates: ".concat(response.statusText));
|
|
1367
|
+
}
|
|
1368
|
+
return [
|
|
1369
|
+
4,
|
|
1370
|
+
rpcFetch("".concat(baseUrl, "/fee-estimates"), rpcUrl)
|
|
1371
|
+
];
|
|
1372
|
+
case 4:
|
|
1373
|
+
fallback = _state.sent();
|
|
1374
|
+
if (!fallback.ok) {
|
|
1375
|
+
// Report the origin only; custom URLs may embed credentials or API keys in the path.
|
|
1376
|
+
throw new Error("Failed to fetch fee rates from ".concat(new URL(baseUrl).origin, ": ").concat(fallback.statusText, ". ") + 'Provide an explicit feeRate to skip the fee lookup.');
|
|
1377
|
+
}
|
|
1378
|
+
return [
|
|
1379
|
+
4,
|
|
1380
|
+
fallback.json()
|
|
1381
|
+
];
|
|
1382
|
+
case 5:
|
|
1383
|
+
estimates = _state.sent();
|
|
1384
|
+
if ((typeof estimates === "undefined" ? "undefined" : _type_of$1(estimates)) !== 'object' || estimates === null || Array.isArray(estimates)) {
|
|
1385
|
+
throw new Error('invalid fee estimates response');
|
|
1386
|
+
}
|
|
1387
|
+
rates = estimates;
|
|
1388
|
+
return [
|
|
1389
|
+
2,
|
|
1390
|
+
{
|
|
1391
|
+
fast: pickEstimate(rates, ESPLORA_TARGETS.fast),
|
|
1392
|
+
medium: pickEstimate(rates, ESPLORA_TARGETS.medium),
|
|
1393
|
+
slow: pickEstimate(rates, ESPLORA_TARGETS.slow)
|
|
1247
1394
|
}
|
|
1248
1395
|
];
|
|
1249
1396
|
}
|
|
@@ -1796,6 +1943,8 @@ exports.normalizePublicKey = normalizePublicKey;
|
|
|
1796
1943
|
exports.privateKeyToWIF = privateKeyToWIF;
|
|
1797
1944
|
exports.publicKeyToBitcoinAddress = publicKeyToBitcoinAddress;
|
|
1798
1945
|
exports.resolveBitcoinAddressType = resolveBitcoinAddressType;
|
|
1946
|
+
exports.resolveRpcUrl = resolveRpcUrl;
|
|
1947
|
+
exports.rpcFetch = rpcFetch;
|
|
1799
1948
|
exports.selectUTXOs = selectUTXOs;
|
|
1800
1949
|
exports.toBitcoinNetwork = toBitcoinNetwork;
|
|
1801
1950
|
exports.toBuffer = toBuffer;
|
package/index.esm.js
CHANGED
|
@@ -162,7 +162,7 @@ function _instanceof$8(left, right) {
|
|
|
162
162
|
return left instanceof right;
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
|
-
function _type_of$
|
|
165
|
+
function _type_of$2(obj) {
|
|
166
166
|
"@swc/helpers - typeof";
|
|
167
167
|
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
168
168
|
}
|
|
@@ -187,7 +187,7 @@ function _type_of$1(obj) {
|
|
|
187
187
|
}
|
|
188
188
|
return result;
|
|
189
189
|
}
|
|
190
|
-
if ((typeof actualPubkey === "undefined" ? "undefined" : _type_of$
|
|
190
|
+
if ((typeof actualPubkey === "undefined" ? "undefined" : _type_of$2(actualPubkey)) === 'object' && actualPubkey !== null) {
|
|
191
191
|
return convertObjectToBuffer(actualPubkey);
|
|
192
192
|
}
|
|
193
193
|
throw new Error('Invalid public key format');
|
|
@@ -796,6 +796,54 @@ function _instanceof$3(left, right) {
|
|
|
796
796
|
return network === BitcoinNetwork.MAINNET ? 'https://mempool.space/api' : 'https://mempool.space/testnet/api';
|
|
797
797
|
};
|
|
798
798
|
|
|
799
|
+
var LOOPBACK_HOSTNAMES = new Set([
|
|
800
|
+
'localhost',
|
|
801
|
+
'127.0.0.1',
|
|
802
|
+
'[::1]'
|
|
803
|
+
]);
|
|
804
|
+
/**
|
|
805
|
+
* Resolves the Esplora-compatible base URL to use for a network.
|
|
806
|
+
* Falls back to the default (mempool.space) when no custom URL is given.
|
|
807
|
+
*
|
|
808
|
+
* @param network - The Bitcoin network
|
|
809
|
+
* @param rpcUrl - Optional custom Esplora-compatible base URL
|
|
810
|
+
* @returns The base URL without a trailing slash
|
|
811
|
+
*/ var resolveRpcUrl = function(param) {
|
|
812
|
+
var network = param.network, rpcUrl = param.rpcUrl;
|
|
813
|
+
if (!rpcUrl) {
|
|
814
|
+
return getDefaultRpcUrl(network);
|
|
815
|
+
}
|
|
816
|
+
var parsed;
|
|
817
|
+
try {
|
|
818
|
+
parsed = new URL(rpcUrl);
|
|
819
|
+
} catch (e) {
|
|
820
|
+
throw new Error('Invalid Bitcoin RPC URL');
|
|
821
|
+
}
|
|
822
|
+
var isSecure = parsed.protocol === 'https:';
|
|
823
|
+
var isLocalHttp = parsed.protocol === 'http:' && LOOPBACK_HOSTNAMES.has(parsed.hostname);
|
|
824
|
+
if (!isSecure && !isLocalHttp) {
|
|
825
|
+
throw new Error('Bitcoin RPC URL must use https (http is only allowed for localhost)');
|
|
826
|
+
}
|
|
827
|
+
// Manual trim: a /\/+$/ regex backtracks quadratically on long runs of slashes.
|
|
828
|
+
var end = rpcUrl.length;
|
|
829
|
+
while(end > 0 && rpcUrl[end - 1] === '/'){
|
|
830
|
+
end -= 1;
|
|
831
|
+
}
|
|
832
|
+
return rpcUrl.slice(0, end);
|
|
833
|
+
};
|
|
834
|
+
|
|
835
|
+
/**
|
|
836
|
+
* fetch wrapper for Esplora requests. Requests to a custom `rpcUrl` do not follow
|
|
837
|
+
* redirects, so they cannot be bounced to a host other than the configured backend.
|
|
838
|
+
*
|
|
839
|
+
* @param url - The full request URL
|
|
840
|
+
* @param rpcUrl - The custom RPC URL the request was built from, if any
|
|
841
|
+
*/ var rpcFetch = function(url, rpcUrl) {
|
|
842
|
+
return rpcUrl ? fetch(url, {
|
|
843
|
+
redirect: 'error'
|
|
844
|
+
}) : fetch(url);
|
|
845
|
+
};
|
|
846
|
+
|
|
799
847
|
function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
|
|
800
848
|
try {
|
|
801
849
|
var info = gen[key](arg);
|
|
@@ -921,11 +969,11 @@ function _ts_generator$1(thisArg, body) {
|
|
|
921
969
|
}
|
|
922
970
|
}
|
|
923
971
|
/**
|
|
924
|
-
* Fetches UTXOs for a given address using mempool.space
|
|
972
|
+
* Fetches UTXOs for a given address using an Esplora-compatible API (mempool.space by default)
|
|
925
973
|
*
|
|
926
974
|
* @param address - The address to fetch UTXOs for
|
|
927
975
|
* @param network - The Bitcoin network (default: MAINNET)
|
|
928
|
-
* @param rpcUrl - Optional custom RPC URL
|
|
976
|
+
* @param rpcUrl - Optional custom Esplora-compatible RPC URL
|
|
929
977
|
* @returns The list of UTXOs
|
|
930
978
|
*/ var getUTXOs = /*#__PURE__*/ function() {
|
|
931
979
|
var _ref = _async_to_generator$1(function(param) {
|
|
@@ -934,7 +982,10 @@ function _ts_generator$1(thisArg, body) {
|
|
|
934
982
|
switch(_state.label){
|
|
935
983
|
case 0:
|
|
936
984
|
address = param.address, _param_network = param.network, network = _param_network === void 0 ? BitcoinNetwork.MAINNET : _param_network, rpcUrl = param.rpcUrl;
|
|
937
|
-
baseUrl =
|
|
985
|
+
baseUrl = resolveRpcUrl({
|
|
986
|
+
network: network,
|
|
987
|
+
rpcUrl: rpcUrl
|
|
988
|
+
});
|
|
938
989
|
_state.label = 1;
|
|
939
990
|
case 1:
|
|
940
991
|
_state.trys.push([
|
|
@@ -945,7 +996,7 @@ function _ts_generator$1(thisArg, body) {
|
|
|
945
996
|
]);
|
|
946
997
|
return [
|
|
947
998
|
4,
|
|
948
|
-
|
|
999
|
+
rpcFetch("".concat(baseUrl, "/address/").concat(address, "/utxo"), rpcUrl)
|
|
949
1000
|
];
|
|
950
1001
|
case 2:
|
|
951
1002
|
response = _state.sent();
|
|
@@ -983,30 +1034,30 @@ function _ts_generator$1(thisArg, body) {
|
|
|
983
1034
|
};
|
|
984
1035
|
}();
|
|
985
1036
|
|
|
986
|
-
function _array_like_to_array(arr, len) {
|
|
1037
|
+
function _array_like_to_array$1(arr, len) {
|
|
987
1038
|
if (len == null || len > arr.length) len = arr.length;
|
|
988
1039
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
989
1040
|
return arr2;
|
|
990
1041
|
}
|
|
991
|
-
function _array_without_holes(arr) {
|
|
992
|
-
if (Array.isArray(arr)) return _array_like_to_array(arr);
|
|
1042
|
+
function _array_without_holes$1(arr) {
|
|
1043
|
+
if (Array.isArray(arr)) return _array_like_to_array$1(arr);
|
|
993
1044
|
}
|
|
994
|
-
function _iterable_to_array(iter) {
|
|
1045
|
+
function _iterable_to_array$1(iter) {
|
|
995
1046
|
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
996
1047
|
}
|
|
997
|
-
function _non_iterable_spread() {
|
|
1048
|
+
function _non_iterable_spread$1() {
|
|
998
1049
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
999
1050
|
}
|
|
1000
|
-
function _to_consumable_array(arr) {
|
|
1001
|
-
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
|
|
1051
|
+
function _to_consumable_array$1(arr) {
|
|
1052
|
+
return _array_without_holes$1(arr) || _iterable_to_array$1(arr) || _unsupported_iterable_to_array$1(arr) || _non_iterable_spread$1();
|
|
1002
1053
|
}
|
|
1003
|
-
function _unsupported_iterable_to_array(o, minLen) {
|
|
1054
|
+
function _unsupported_iterable_to_array$1(o, minLen) {
|
|
1004
1055
|
if (!o) return;
|
|
1005
|
-
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
1056
|
+
if (typeof o === "string") return _array_like_to_array$1(o, minLen);
|
|
1006
1057
|
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
1007
1058
|
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
1008
1059
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
1009
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
1060
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$1(o, minLen);
|
|
1010
1061
|
}
|
|
1011
1062
|
/**
|
|
1012
1063
|
* Simple greedy coin selection
|
|
@@ -1018,7 +1069,7 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
1018
1069
|
*/ var selectUTXOs = function(param) {
|
|
1019
1070
|
var utxos = param.utxos, amount = param.amount, feeRate = param.feeRate;
|
|
1020
1071
|
// Sort by value descending
|
|
1021
|
-
var sorted = _to_consumable_array(utxos).sort(function(a, b) {
|
|
1072
|
+
var sorted = _to_consumable_array$1(utxos).sort(function(a, b) {
|
|
1022
1073
|
return Number(b.value - a.value);
|
|
1023
1074
|
});
|
|
1024
1075
|
var inputs = [];
|
|
@@ -1064,6 +1115,14 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
1064
1115
|
throw new Error('Insufficient funds');
|
|
1065
1116
|
};
|
|
1066
1117
|
|
|
1118
|
+
function _array_like_to_array(arr, len) {
|
|
1119
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
1120
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
1121
|
+
return arr2;
|
|
1122
|
+
}
|
|
1123
|
+
function _array_without_holes(arr) {
|
|
1124
|
+
if (Array.isArray(arr)) return _array_like_to_array(arr);
|
|
1125
|
+
}
|
|
1067
1126
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
1068
1127
|
try {
|
|
1069
1128
|
var info = gen[key](arg);
|
|
@@ -1093,6 +1152,27 @@ function _async_to_generator(fn) {
|
|
|
1093
1152
|
});
|
|
1094
1153
|
};
|
|
1095
1154
|
}
|
|
1155
|
+
function _iterable_to_array(iter) {
|
|
1156
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
1157
|
+
}
|
|
1158
|
+
function _non_iterable_spread() {
|
|
1159
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
1160
|
+
}
|
|
1161
|
+
function _to_consumable_array(arr) {
|
|
1162
|
+
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
|
|
1163
|
+
}
|
|
1164
|
+
function _type_of$1(obj) {
|
|
1165
|
+
"@swc/helpers - typeof";
|
|
1166
|
+
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
1167
|
+
}
|
|
1168
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
1169
|
+
if (!o) return;
|
|
1170
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
1171
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
1172
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
1173
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
1174
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
1175
|
+
}
|
|
1096
1176
|
function _ts_generator(thisArg, body) {
|
|
1097
1177
|
var f, y, t, g, _ = {
|
|
1098
1178
|
label: 0,
|
|
@@ -1188,30 +1268,65 @@ function _ts_generator(thisArg, body) {
|
|
|
1188
1268
|
};
|
|
1189
1269
|
}
|
|
1190
1270
|
}
|
|
1271
|
+
// Block targets approximating mempool's fastest / half-hour / hour fees.
|
|
1272
|
+
var ESPLORA_TARGETS = {
|
|
1273
|
+
fast: 1,
|
|
1274
|
+
medium: 3,
|
|
1275
|
+
slow: 6
|
|
1276
|
+
};
|
|
1277
|
+
// Backends are untrusted input: reject anything that is not a positive finite number.
|
|
1278
|
+
var assertFeeRate = function(value) {
|
|
1279
|
+
if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) {
|
|
1280
|
+
throw new Error('invalid fee estimate');
|
|
1281
|
+
}
|
|
1282
|
+
return value;
|
|
1283
|
+
};
|
|
1284
|
+
var pickEstimate = function(estimates, target) {
|
|
1285
|
+
var targets = Object.keys(estimates).map(Number).filter(function(key) {
|
|
1286
|
+
return Number.isFinite(key);
|
|
1287
|
+
}).sort(function(a, b) {
|
|
1288
|
+
return a - b;
|
|
1289
|
+
});
|
|
1290
|
+
if (targets.length === 0) {
|
|
1291
|
+
throw new Error('empty fee estimates');
|
|
1292
|
+
}
|
|
1293
|
+
var _reverse_find;
|
|
1294
|
+
// Closest target not exceeding the wanted one, else the fastest available.
|
|
1295
|
+
var key = (_reverse_find = _to_consumable_array(targets).reverse().find(function(candidate) {
|
|
1296
|
+
return candidate <= target;
|
|
1297
|
+
})) !== null && _reverse_find !== void 0 ? _reverse_find : targets[0];
|
|
1298
|
+
return Math.ceil(assertFeeRate(estimates[String(key)]));
|
|
1299
|
+
};
|
|
1191
1300
|
/**
|
|
1192
|
-
* Fetches current fee rates
|
|
1193
|
-
*
|
|
1301
|
+
* Fetches current fee rates in sat/vByte.
|
|
1302
|
+
* Uses the mempool.space `/v1/fees/recommended` endpoint. For a custom Esplora-compatible
|
|
1303
|
+
* `rpcUrl` that does not serve it, falls back to the standard `/fee-estimates` endpoint
|
|
1304
|
+
* on the same backend. Never falls back to a different host.
|
|
1194
1305
|
*
|
|
1195
1306
|
* @param network - The Bitcoin network (default: MAINNET)
|
|
1196
|
-
* @param rpcUrl - Optional custom RPC URL
|
|
1307
|
+
* @param rpcUrl - Optional custom Esplora-compatible RPC URL
|
|
1197
1308
|
* @returns The fee rates for fast, medium, and slow transactions
|
|
1198
1309
|
*/ var getFeeRates = /*#__PURE__*/ function() {
|
|
1199
1310
|
var _ref = _async_to_generator(function(param) {
|
|
1200
|
-
var _param_network, network, rpcUrl, baseUrl, response, fees;
|
|
1311
|
+
var _param_network, network, rpcUrl, baseUrl, response, fees, fallback, estimates, rates;
|
|
1201
1312
|
return _ts_generator(this, function(_state) {
|
|
1202
1313
|
switch(_state.label){
|
|
1203
1314
|
case 0:
|
|
1204
1315
|
_param_network = param.network, network = _param_network === void 0 ? BitcoinNetwork.MAINNET : _param_network, rpcUrl = param.rpcUrl;
|
|
1205
|
-
baseUrl =
|
|
1316
|
+
baseUrl = resolveRpcUrl({
|
|
1317
|
+
network: network,
|
|
1318
|
+
rpcUrl: rpcUrl
|
|
1319
|
+
});
|
|
1206
1320
|
return [
|
|
1207
1321
|
4,
|
|
1208
|
-
|
|
1322
|
+
rpcFetch("".concat(baseUrl, "/v1/fees/recommended"), rpcUrl)
|
|
1209
1323
|
];
|
|
1210
1324
|
case 1:
|
|
1211
1325
|
response = _state.sent();
|
|
1212
|
-
if (!response.ok)
|
|
1213
|
-
|
|
1214
|
-
|
|
1326
|
+
if (!response.ok) return [
|
|
1327
|
+
3,
|
|
1328
|
+
3
|
|
1329
|
+
];
|
|
1215
1330
|
return [
|
|
1216
1331
|
4,
|
|
1217
1332
|
response.json()
|
|
@@ -1221,9 +1336,41 @@ function _ts_generator(thisArg, body) {
|
|
|
1221
1336
|
return [
|
|
1222
1337
|
2,
|
|
1223
1338
|
{
|
|
1224
|
-
fast: fees.fastestFee,
|
|
1225
|
-
medium: fees.halfHourFee,
|
|
1226
|
-
slow: fees.hourFee
|
|
1339
|
+
fast: assertFeeRate(fees.fastestFee),
|
|
1340
|
+
medium: assertFeeRate(fees.halfHourFee),
|
|
1341
|
+
slow: assertFeeRate(fees.hourFee)
|
|
1342
|
+
}
|
|
1343
|
+
];
|
|
1344
|
+
case 3:
|
|
1345
|
+
if (!rpcUrl) {
|
|
1346
|
+
throw new Error("Failed to fetch fee rates: ".concat(response.statusText));
|
|
1347
|
+
}
|
|
1348
|
+
return [
|
|
1349
|
+
4,
|
|
1350
|
+
rpcFetch("".concat(baseUrl, "/fee-estimates"), rpcUrl)
|
|
1351
|
+
];
|
|
1352
|
+
case 4:
|
|
1353
|
+
fallback = _state.sent();
|
|
1354
|
+
if (!fallback.ok) {
|
|
1355
|
+
// Report the origin only; custom URLs may embed credentials or API keys in the path.
|
|
1356
|
+
throw new Error("Failed to fetch fee rates from ".concat(new URL(baseUrl).origin, ": ").concat(fallback.statusText, ". ") + 'Provide an explicit feeRate to skip the fee lookup.');
|
|
1357
|
+
}
|
|
1358
|
+
return [
|
|
1359
|
+
4,
|
|
1360
|
+
fallback.json()
|
|
1361
|
+
];
|
|
1362
|
+
case 5:
|
|
1363
|
+
estimates = _state.sent();
|
|
1364
|
+
if ((typeof estimates === "undefined" ? "undefined" : _type_of$1(estimates)) !== 'object' || estimates === null || Array.isArray(estimates)) {
|
|
1365
|
+
throw new Error('invalid fee estimates response');
|
|
1366
|
+
}
|
|
1367
|
+
rates = estimates;
|
|
1368
|
+
return [
|
|
1369
|
+
2,
|
|
1370
|
+
{
|
|
1371
|
+
fast: pickEstimate(rates, ESPLORA_TARGETS.fast),
|
|
1372
|
+
medium: pickEstimate(rates, ESPLORA_TARGETS.medium),
|
|
1373
|
+
slow: pickEstimate(rates, ESPLORA_TARGETS.slow)
|
|
1227
1374
|
}
|
|
1228
1375
|
];
|
|
1229
1376
|
}
|
|
@@ -1743,4 +1890,4 @@ function _type_of(obj) {
|
|
|
1743
1890
|
return Buffer.from(formattedMessage).toString('hex');
|
|
1744
1891
|
};
|
|
1745
1892
|
|
|
1746
|
-
export { assertSighashAllowed, calculateBip322Hash, calculateTaprootTweak, collectPSBTInputData, computeBip322HashHex, convertSignatureToDER, convertSignatureToTaprootBuffer, createLegacyAddress, createNativeSegWitAddress, createSegWitAddress, createTaprootAddress, doesInputBelongToAddress, encodeBip322Signature, extractPsbtSighashes, extractPublicKeyHex, filterInputsBySigningIndexes, getAddressTypeFromAddress, getAddressTypeFromDerivationPath, getBitcoinNetwork, getDefaultRpcUrl, getFeeRates, getPublicKeyFromPrivateKey, getSegwitV0ScriptCode, getSigHashType, getUTXOs, initEccLib, isP2wshOutputScript, normalizeForCompressed, normalizeForTaproot, normalizePublicKey, privateKeyToWIF, publicKeyToBitcoinAddress, resolveBitcoinAddressType, selectUTXOs, toBitcoinNetwork, toBuffer, wifToPrivateKey };
|
|
1893
|
+
export { assertSighashAllowed, calculateBip322Hash, calculateTaprootTweak, collectPSBTInputData, computeBip322HashHex, convertSignatureToDER, convertSignatureToTaprootBuffer, createLegacyAddress, createNativeSegWitAddress, createSegWitAddress, createTaprootAddress, doesInputBelongToAddress, encodeBip322Signature, extractPsbtSighashes, extractPublicKeyHex, filterInputsBySigningIndexes, getAddressTypeFromAddress, getAddressTypeFromDerivationPath, getBitcoinNetwork, getDefaultRpcUrl, getFeeRates, getPublicKeyFromPrivateKey, getSegwitV0ScriptCode, getSigHashType, getUTXOs, initEccLib, isP2wshOutputScript, normalizeForCompressed, normalizeForTaproot, normalizePublicKey, privateKeyToWIF, publicKeyToBitcoinAddress, resolveBitcoinAddressType, resolveRpcUrl, rpcFetch, selectUTXOs, toBitcoinNetwork, toBuffer, wifToPrivateKey };
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs-wallet/btc-utils",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.30",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@dynamic-labs-wallet/core": "1.1.
|
|
8
|
+
"@dynamic-labs-wallet/core": "1.1.30",
|
|
9
9
|
"bitcoinjs-lib": "^7.0.0",
|
|
10
10
|
"bip322-js": "^3.0.0",
|
|
11
11
|
"@noble/hashes": "1.7.1",
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import { BitcoinNetwork } from '@dynamic-labs-wallet/core';
|
|
2
|
+
type FeeRates = {
|
|
3
|
+
fast: number;
|
|
4
|
+
medium: number;
|
|
5
|
+
slow: number;
|
|
6
|
+
};
|
|
2
7
|
/**
|
|
3
|
-
* Fetches current fee rates
|
|
4
|
-
*
|
|
8
|
+
* Fetches current fee rates in sat/vByte.
|
|
9
|
+
* Uses the mempool.space `/v1/fees/recommended` endpoint. For a custom Esplora-compatible
|
|
10
|
+
* `rpcUrl` that does not serve it, falls back to the standard `/fee-estimates` endpoint
|
|
11
|
+
* on the same backend. Never falls back to a different host.
|
|
5
12
|
*
|
|
6
13
|
* @param network - The Bitcoin network (default: MAINNET)
|
|
7
|
-
* @param rpcUrl - Optional custom RPC URL
|
|
14
|
+
* @param rpcUrl - Optional custom Esplora-compatible RPC URL
|
|
8
15
|
* @returns The fee rates for fast, medium, and slow transactions
|
|
9
16
|
*/
|
|
10
17
|
export declare const getFeeRates: ({ network, rpcUrl, }: {
|
|
11
18
|
network?: BitcoinNetwork;
|
|
12
19
|
rpcUrl?: string;
|
|
13
|
-
}) => Promise<
|
|
14
|
-
|
|
15
|
-
medium: number;
|
|
16
|
-
slow: number;
|
|
17
|
-
}>;
|
|
20
|
+
}) => Promise<FeeRates>;
|
|
21
|
+
export {};
|
|
18
22
|
//# sourceMappingURL=getFeeRates.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFeeRates.d.ts","sourceRoot":"","sources":["../../src/getFeeRates/getFeeRates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"getFeeRates.d.ts","sourceRoot":"","sources":["../../src/getFeeRates/getFeeRates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAI3D,KAAK,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AA2B/D;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,yBAGrB;IACD,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,KAAG,OAAO,CAAC,QAAQ,CAyCnB,CAAC"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { BitcoinNetwork } from '@dynamic-labs-wallet/core';
|
|
2
2
|
import type { UTXO } from '../types.js';
|
|
3
3
|
/**
|
|
4
|
-
* Fetches UTXOs for a given address using mempool.space
|
|
4
|
+
* Fetches UTXOs for a given address using an Esplora-compatible API (mempool.space by default)
|
|
5
5
|
*
|
|
6
6
|
* @param address - The address to fetch UTXOs for
|
|
7
7
|
* @param network - The Bitcoin network (default: MAINNET)
|
|
8
|
-
* @param rpcUrl - Optional custom RPC URL
|
|
8
|
+
* @param rpcUrl - Optional custom Esplora-compatible RPC URL
|
|
9
9
|
* @returns The list of UTXOs
|
|
10
10
|
*/
|
|
11
11
|
export declare const getUTXOs: ({ address, network, rpcUrl, }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getUTXOs.d.ts","sourceRoot":"","sources":["../../src/getUTXOs/getUTXOs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"getUTXOs.d.ts","sourceRoot":"","sources":["../../src/getUTXOs/getUTXOs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAIxC;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,kCAIlB;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,KAAG,OAAO,CAAC,IAAI,EAAE,CAmBjB,CAAC"}
|
package/src/index.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export { getUTXOs } from './getUTXOs/index.js';
|
|
|
12
12
|
export { selectUTXOs } from './selectUTXOs/index.js';
|
|
13
13
|
export { getFeeRates } from './getFeeRates/index.js';
|
|
14
14
|
export { getDefaultRpcUrl } from './getDefaultRpcUrl/index.js';
|
|
15
|
+
export { resolveRpcUrl } from './resolveRpcUrl/index.js';
|
|
16
|
+
export { rpcFetch } from './rpcFetch/index.js';
|
|
15
17
|
export { calculateTaprootTweak } from './calculateTaprootTweak/index.js';
|
|
16
18
|
export { convertSignatureToTaprootBuffer } from './convertSignatureToTaprootBuffer/index.js';
|
|
17
19
|
export { collectPSBTInputData } from './collectPSBTInputData/index.js';
|
package/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gCAAgC,EAAE,MAAM,6CAA6C,CAAC;AAC/F,OAAO,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAC5G,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,+BAA+B,EAAE,MAAM,4CAA4C,CAAC;AAC7F,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,4BAA4B,EAAE,MAAM,yCAAyC,CAAC;AACvF,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,YAAY,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAGvE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAG/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gCAAgC,EAAE,MAAM,6CAA6C,CAAC;AAC/F,OAAO,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAC5G,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,+BAA+B,EAAE,MAAM,4CAA4C,CAAC;AAC7F,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,4BAA4B,EAAE,MAAM,yCAAyC,CAAC;AACvF,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,YAAY,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAGvE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAG/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resolveRpcUrl/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BitcoinNetwork } from '@dynamic-labs-wallet/core';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves the Esplora-compatible base URL to use for a network.
|
|
4
|
+
* Falls back to the default (mempool.space) when no custom URL is given.
|
|
5
|
+
*
|
|
6
|
+
* @param network - The Bitcoin network
|
|
7
|
+
* @param rpcUrl - Optional custom Esplora-compatible base URL
|
|
8
|
+
* @returns The base URL without a trailing slash
|
|
9
|
+
*/
|
|
10
|
+
export declare const resolveRpcUrl: ({ network, rpcUrl }: {
|
|
11
|
+
network: BitcoinNetwork;
|
|
12
|
+
rpcUrl?: string;
|
|
13
|
+
}) => string;
|
|
14
|
+
//# sourceMappingURL=resolveRpcUrl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveRpcUrl.d.ts","sourceRoot":"","sources":["../../src/resolveRpcUrl/resolveRpcUrl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAKhE;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,wBAAyB;IAAE,OAAO,EAAE,cAAc,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,KAAG,MAwBjG,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rpcFetch/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fetch wrapper for Esplora requests. Requests to a custom `rpcUrl` do not follow
|
|
3
|
+
* redirects, so they cannot be bounced to a host other than the configured backend.
|
|
4
|
+
*
|
|
5
|
+
* @param url - The full request URL
|
|
6
|
+
* @param rpcUrl - The custom RPC URL the request was built from, if any
|
|
7
|
+
*/
|
|
8
|
+
export declare const rpcFetch: (url: string, rpcUrl?: string) => Promise<Response>;
|
|
9
|
+
//# sourceMappingURL=rpcFetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpcFetch.d.ts","sourceRoot":"","sources":["../../src/rpcFetch/rpcFetch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,QAAS,MAAM,WAAW,MAAM,KAAG,OAAO,CAAC,QAAQ,CACf,CAAC"}
|