@xchainjs/xchain-dash 2.2.3 → 2.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.esm.js CHANGED
@@ -1,8 +1,8 @@
1
- import { ExplorerProvider, Network, TxType, FeeOption, checkFeeBounds } from '@xchainjs/xchain-client';
2
- import { AssetType, assetToBase, assetAmount, baseAmount } from '@xchainjs/xchain-util';
1
+ import { ExplorerProvider, Network, FeeOption, checkFeeBounds } from '@xchainjs/xchain-client';
2
+ import { AssetType } from '@xchainjs/xchain-util';
3
3
  import { BlockcypherProvider, BlockcypherNetwork, BitgoProvider } from '@xchainjs/xchain-utxo-providers';
4
4
  import dashcore from '@dashevo/dashcore-lib';
5
- import { toBitcoinJS, Client as Client$1, UtxoTransactionValidator, UtxoError } from '@xchainjs/xchain-utxo';
5
+ import { toBitcoinJS, Client as Client$1, UtxoError, UtxoTransactionValidator } from '@xchainjs/xchain-utxo';
6
6
  import * as Dash from 'bitcoinjs-lib';
7
7
  import accumulative from 'coinselect/accumulative.js';
8
8
  import * as ecc from '@bitcoin-js/tiny-secp256k1-asmjs';
@@ -47,7 +47,7 @@ const AssetDASH = { chain: DASHChain, symbol: 'DASH', ticker: 'DASH', type: Asse
47
47
  /**
48
48
  * Explorer provider for Dash mainnet.
49
49
  */
50
- const DASH_MAINNET_EXPLORER = new ExplorerProvider('https://insight.dash.org/insight', 'https://insight.dash.org/insight/address/%%ADDRESS%%', 'https://insight.dash.org/insight/tx/%%TX_ID%%');
50
+ const DASH_MAINNET_EXPLORER = new ExplorerProvider('https://blockchair.com/dash', 'https://blockchair.com/dash/address/%%ADDRESS%%', 'https://blockchair.com/dash/transaction/%%TX_ID%%');
51
51
  /**
52
52
  * Explorer provider for Dash testnet.
53
53
  */
@@ -390,16 +390,16 @@ const G = getGlobal();
390
390
  const FormDataCtor = typeof G.FormData !== 'undefined' ? G.FormData : undefined;
391
391
 
392
392
  const isFormData = (thing) => {
393
- let kind;
394
- return thing && (
395
- (FormDataCtor && thing instanceof FormDataCtor) || (
396
- isFunction$1(thing.append) && (
397
- (kind = kindOf(thing)) === 'formdata' ||
398
- // detect form-data instance
399
- (kind === 'object' && isFunction$1(thing.toString) && thing.toString() === '[object FormData]')
400
- )
401
- )
402
- );
393
+ if (!thing) return false;
394
+ if (FormDataCtor && thing instanceof FormDataCtor) return true;
395
+ // Reject plain objects inheriting directly from Object.prototype so prototype-pollution gadgets can't spoof FormData (GHSA-6chq-wfr3-2hj9).
396
+ const proto = getPrototypeOf(thing);
397
+ if (!proto || proto === Object.prototype) return false;
398
+ if (!isFunction$1(thing.append)) return false;
399
+ const kind = kindOf(thing);
400
+ return kind === 'formdata' ||
401
+ // detect form-data instance
402
+ (kind === 'object' && isFunction$1(thing.toString) && thing.toString() === '[object FormData]');
403
403
  };
404
404
 
405
405
  /**
@@ -1066,40 +1066,40 @@ let AxiosError$1 = class AxiosError extends Error {
1066
1066
  return axiosError;
1067
1067
  }
1068
1068
 
1069
- /**
1070
- * Create an Error with the specified message, config, error code, request and response.
1071
- *
1072
- * @param {string} message The error message.
1073
- * @param {string} [code] The error code (for example, 'ECONNABORTED').
1074
- * @param {Object} [config] The config.
1075
- * @param {Object} [request] The request.
1076
- * @param {Object} [response] The response.
1077
- *
1078
- * @returns {Error} The created error.
1079
- */
1080
- constructor(message, code, config, request, response) {
1081
- super(message);
1082
-
1083
- // Make message enumerable to maintain backward compatibility
1084
- // The native Error constructor sets message as non-enumerable,
1085
- // but axios < v1.13.3 had it as enumerable
1086
- Object.defineProperty(this, 'message', {
1087
- value: message,
1088
- enumerable: true,
1089
- writable: true,
1090
- configurable: true
1091
- });
1092
-
1093
- this.name = 'AxiosError';
1094
- this.isAxiosError = true;
1095
- code && (this.code = code);
1096
- config && (this.config = config);
1097
- request && (this.request = request);
1098
- if (response) {
1099
- this.response = response;
1100
- this.status = response.status;
1101
- }
1069
+ /**
1070
+ * Create an Error with the specified message, config, error code, request and response.
1071
+ *
1072
+ * @param {string} message The error message.
1073
+ * @param {string} [code] The error code (for example, 'ECONNABORTED').
1074
+ * @param {Object} [config] The config.
1075
+ * @param {Object} [request] The request.
1076
+ * @param {Object} [response] The response.
1077
+ *
1078
+ * @returns {Error} The created error.
1079
+ */
1080
+ constructor(message, code, config, request, response) {
1081
+ super(message);
1082
+
1083
+ // Make message enumerable to maintain backward compatibility
1084
+ // The native Error constructor sets message as non-enumerable,
1085
+ // but axios < v1.13.3 had it as enumerable
1086
+ Object.defineProperty(this, 'message', {
1087
+ value: message,
1088
+ enumerable: true,
1089
+ writable: true,
1090
+ configurable: true,
1091
+ });
1092
+
1093
+ this.name = 'AxiosError';
1094
+ this.isAxiosError = true;
1095
+ code && (this.code = code);
1096
+ config && (this.config = config);
1097
+ request && (this.request = request);
1098
+ if (response) {
1099
+ this.response = response;
1100
+ this.status = response.status;
1102
1101
  }
1102
+ }
1103
1103
 
1104
1104
  toJSON() {
1105
1105
  return {
@@ -1135,6 +1135,7 @@ AxiosError$1.ERR_BAD_REQUEST = 'ERR_BAD_REQUEST';
1135
1135
  AxiosError$1.ERR_CANCELED = 'ERR_CANCELED';
1136
1136
  AxiosError$1.ERR_NOT_SUPPORT = 'ERR_NOT_SUPPORT';
1137
1137
  AxiosError$1.ERR_INVALID_URL = 'ERR_INVALID_URL';
1138
+ AxiosError$1.ERR_FORM_DATA_DEPTH_EXCEEDED = 'ERR_FORM_DATA_DEPTH_EXCEEDED';
1138
1139
 
1139
1140
  // eslint-disable-next-line strict
1140
1141
  var httpAdapter = null;
@@ -1249,6 +1250,7 @@ function toFormData$1(obj, formData, options) {
1249
1250
  const dots = options.dots;
1250
1251
  const indexes = options.indexes;
1251
1252
  const _Blob = options.Blob || (typeof Blob !== 'undefined' && Blob);
1253
+ const maxDepth = options.maxDepth === undefined ? 100 : options.maxDepth;
1252
1254
  const useBlob = _Blob && utils$1.isSpecCompliantForm(formData);
1253
1255
 
1254
1256
  if (!utils$1.isFunction(visitor)) {
@@ -1341,9 +1343,16 @@ function toFormData$1(obj, formData, options) {
1341
1343
  isVisitable,
1342
1344
  });
1343
1345
 
1344
- function build(value, path) {
1346
+ function build(value, path, depth = 0) {
1345
1347
  if (utils$1.isUndefined(value)) return;
1346
1348
 
1349
+ if (depth > maxDepth) {
1350
+ throw new AxiosError$1(
1351
+ 'Object is too deeply nested (' + depth + ' levels). Max depth: ' + maxDepth,
1352
+ AxiosError$1.ERR_FORM_DATA_DEPTH_EXCEEDED
1353
+ );
1354
+ }
1355
+
1347
1356
  if (stack.indexOf(value) !== -1) {
1348
1357
  throw Error('Circular reference detected in ' + path.join('.'));
1349
1358
  }
@@ -1356,7 +1365,7 @@ function toFormData$1(obj, formData, options) {
1356
1365
  visitor.call(formData, el, utils$1.isString(key) ? key.trim() : key, path, exposedHelpers);
1357
1366
 
1358
1367
  if (result === true) {
1359
- build(el, path ? path.concat(key) : [key]);
1368
+ build(el, path ? path.concat(key) : [key], depth + 1);
1360
1369
  }
1361
1370
  });
1362
1371
 
@@ -1388,9 +1397,8 @@ function encode$1(str) {
1388
1397
  ')': '%29',
1389
1398
  '~': '%7E',
1390
1399
  '%20': '+',
1391
- '%00': '\x00',
1392
1400
  };
1393
- return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) {
1401
+ return encodeURIComponent(str).replace(/[!'()~]|%20/g, function replacer(match) {
1394
1402
  return charMap[match];
1395
1403
  });
1396
1404
  }
@@ -1710,7 +1718,9 @@ function formDataToJSON(formData) {
1710
1718
 
1711
1719
  if (isLast) {
1712
1720
  if (utils$1.hasOwnProp(target, name)) {
1713
- target[name] = [target[name], value];
1721
+ target[name] = utils$1.isArray(target[name])
1722
+ ? target[name].concat(value)
1723
+ : [target[name], value];
1714
1724
  } else {
1715
1725
  target[name] = value;
1716
1726
  }
@@ -1744,6 +1754,8 @@ function formDataToJSON(formData) {
1744
1754
  return null;
1745
1755
  }
1746
1756
 
1757
+ const own = (obj, key) => (obj != null && utils$1.hasOwnProp(obj, key) ? obj[key] : undefined);
1758
+
1747
1759
  /**
1748
1760
  * It takes a string, tries to parse it, and if it fails, it returns the stringified version
1749
1761
  * of the input
@@ -1811,20 +1823,22 @@ const defaults = {
1811
1823
  let isFileList;
1812
1824
 
1813
1825
  if (isObjectPayload) {
1826
+ const formSerializer = own(this, 'formSerializer');
1814
1827
  if (contentType.indexOf('application/x-www-form-urlencoded') > -1) {
1815
- return toURLEncodedForm(data, this.formSerializer).toString();
1828
+ return toURLEncodedForm(data, formSerializer).toString();
1816
1829
  }
1817
1830
 
1818
1831
  if (
1819
1832
  (isFileList = utils$1.isFileList(data)) ||
1820
1833
  contentType.indexOf('multipart/form-data') > -1
1821
1834
  ) {
1822
- const _FormData = this.env && this.env.FormData;
1835
+ const env = own(this, 'env');
1836
+ const _FormData = env && env.FormData;
1823
1837
 
1824
1838
  return toFormData$1(
1825
1839
  isFileList ? { 'files[]': data } : data,
1826
1840
  _FormData && new _FormData(),
1827
- this.formSerializer
1841
+ formSerializer
1828
1842
  );
1829
1843
  }
1830
1844
  }
@@ -1840,9 +1854,10 @@ const defaults = {
1840
1854
 
1841
1855
  transformResponse: [
1842
1856
  function transformResponse(data) {
1843
- const transitional = this.transitional || defaults.transitional;
1857
+ const transitional = own(this, 'transitional') || defaults.transitional;
1844
1858
  const forcedJSONParsing = transitional && transitional.forcedJSONParsing;
1845
- const JSONRequested = this.responseType === 'json';
1859
+ const responseType = own(this, 'responseType');
1860
+ const JSONRequested = responseType === 'json';
1846
1861
 
1847
1862
  if (utils$1.isResponse(data) || utils$1.isReadableStream(data)) {
1848
1863
  return data;
@@ -1851,17 +1866,17 @@ const defaults = {
1851
1866
  if (
1852
1867
  data &&
1853
1868
  utils$1.isString(data) &&
1854
- ((forcedJSONParsing && !this.responseType) || JSONRequested)
1869
+ ((forcedJSONParsing && !responseType) || JSONRequested)
1855
1870
  ) {
1856
1871
  const silentJSONParsing = transitional && transitional.silentJSONParsing;
1857
1872
  const strictJSONParsing = !silentJSONParsing && JSONRequested;
1858
1873
 
1859
1874
  try {
1860
- return JSON.parse(data, this.parseReviver);
1875
+ return JSON.parse(data, own(this, 'parseReviver'));
1861
1876
  } catch (e) {
1862
1877
  if (strictJSONParsing) {
1863
1878
  if (e.name === 'SyntaxError') {
1864
- throw AxiosError$1.from(e, AxiosError$1.ERR_BAD_RESPONSE, this, null, this.response);
1879
+ throw AxiosError$1.from(e, AxiosError$1.ERR_BAD_RESPONSE, this, null, own(this, 'response'));
1865
1880
  }
1866
1881
  throw e;
1867
1882
  }
@@ -1973,41 +1988,41 @@ var parseHeaders = (rawHeaders) => {
1973
1988
 
1974
1989
  const $internals = Symbol('internals');
1975
1990
 
1976
- const isValidHeaderValue = (value) => !/[\r\n]/.test(value);
1991
+ const INVALID_HEADER_VALUE_CHARS_RE = /[^\x09\x20-\x7E\x80-\xFF]/g;
1977
1992
 
1978
- function assertValidHeaderValue(value, header) {
1979
- if (value === false || value == null) {
1980
- return;
1981
- }
1982
-
1983
- if (utils$1.isArray(value)) {
1984
- value.forEach((v) => assertValidHeaderValue(v, header));
1985
- return;
1986
- }
1993
+ function trimSPorHTAB(str) {
1994
+ let start = 0;
1995
+ let end = str.length;
1987
1996
 
1988
- if (!isValidHeaderValue(String(value))) {
1989
- throw new Error(`Invalid character in header content ["${header}"]`);
1990
- }
1991
- }
1997
+ while (start < end) {
1998
+ const code = str.charCodeAt(start);
1992
1999
 
1993
- function normalizeHeader(header) {
1994
- return header && String(header).trim().toLowerCase();
1995
- }
2000
+ if (code !== 0x09 && code !== 0x20) {
2001
+ break;
2002
+ }
1996
2003
 
1997
- function stripTrailingCRLF(str) {
1998
- let end = str.length;
2004
+ start += 1;
2005
+ }
1999
2006
 
2000
- while (end > 0) {
2001
- const charCode = str.charCodeAt(end - 1);
2007
+ while (end > start) {
2008
+ const code = str.charCodeAt(end - 1);
2002
2009
 
2003
- if (charCode !== 10 && charCode !== 13) {
2010
+ if (code !== 0x09 && code !== 0x20) {
2004
2011
  break;
2005
2012
  }
2006
2013
 
2007
2014
  end -= 1;
2008
2015
  }
2009
2016
 
2010
- return end === str.length ? str : str.slice(0, end);
2017
+ return start === 0 && end === str.length ? str : str.slice(start, end);
2018
+ }
2019
+
2020
+ function normalizeHeader(header) {
2021
+ return header && String(header).trim().toLowerCase();
2022
+ }
2023
+
2024
+ function sanitizeHeaderValue(str) {
2025
+ return trimSPorHTAB(str.replace(INVALID_HEADER_VALUE_CHARS_RE, ''));
2011
2026
  }
2012
2027
 
2013
2028
  function normalizeValue(value) {
@@ -2015,7 +2030,7 @@ function normalizeValue(value) {
2015
2030
  return value;
2016
2031
  }
2017
2032
 
2018
- return utils$1.isArray(value) ? value.map(normalizeValue) : stripTrailingCRLF(String(value));
2033
+ return utils$1.isArray(value) ? value.map(normalizeValue) : sanitizeHeaderValue(String(value));
2019
2034
  }
2020
2035
 
2021
2036
  function parseTokens(str) {
@@ -2097,7 +2112,6 @@ let AxiosHeaders$1 = class AxiosHeaders {
2097
2112
  _rewrite === true ||
2098
2113
  (_rewrite === undefined && self[key] !== false)
2099
2114
  ) {
2100
- assertValidHeaderValue(_value, _header);
2101
2115
  self[key || _header] = normalizeValue(_value);
2102
2116
  }
2103
2117
  }
@@ -2520,13 +2534,13 @@ const progressEventReducer = (listener, isDownloadStream, freq = 3) => {
2520
2534
  const _speedometer = speedometer(50, 250);
2521
2535
 
2522
2536
  return throttle((e) => {
2523
- const loaded = e.loaded;
2537
+ const rawLoaded = e.loaded;
2524
2538
  const total = e.lengthComputable ? e.total : undefined;
2525
- const progressBytes = loaded - bytesNotified;
2539
+ const loaded = total != null ? Math.min(rawLoaded, total) : rawLoaded;
2540
+ const progressBytes = Math.max(0, loaded - bytesNotified);
2526
2541
  const rate = _speedometer(progressBytes);
2527
- const inRange = loaded <= total;
2528
2542
 
2529
- bytesNotified = loaded;
2543
+ bytesNotified = Math.max(bytesNotified, loaded);
2530
2544
 
2531
2545
  const data = {
2532
2546
  loaded,
@@ -2534,7 +2548,7 @@ const progressEventReducer = (listener, isDownloadStream, freq = 3) => {
2534
2548
  progress: total ? loaded / total : undefined,
2535
2549
  bytes: progressBytes,
2536
2550
  rate: rate ? rate : undefined,
2537
- estimated: rate && total && inRange ? (total - loaded) / rate : undefined,
2551
+ estimated: rate && total ? (total - loaded) / rate : undefined,
2538
2552
  event: e,
2539
2553
  lengthComputable: total != null,
2540
2554
  [isDownloadStream ? 'download' : 'upload']: true,
@@ -2668,7 +2682,7 @@ function combineURLs(baseURL, relativeURL) {
2668
2682
  */
2669
2683
  function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {
2670
2684
  let isRelativeUrl = !isAbsoluteURL(requestedURL);
2671
- if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) {
2685
+ if (baseURL && (isRelativeUrl || allowAbsoluteUrls === false)) {
2672
2686
  return combineURLs(baseURL, requestedURL);
2673
2687
  }
2674
2688
  return requestedURL;
@@ -2688,7 +2702,18 @@ const headersToObject = (thing) => (thing instanceof AxiosHeaders$1 ? { ...thing
2688
2702
  function mergeConfig$1(config1, config2) {
2689
2703
  // eslint-disable-next-line no-param-reassign
2690
2704
  config2 = config2 || {};
2691
- const config = {};
2705
+
2706
+ // Use a null-prototype object so that downstream reads such as `config.auth`
2707
+ // or `config.baseURL` cannot inherit polluted values from Object.prototype
2708
+ // (see GHSA-q8qp-cvcw-x6jj). `hasOwnProperty` is restored as a non-enumerable
2709
+ // own slot to preserve ergonomics for user code that relies on it.
2710
+ const config = Object.create(null);
2711
+ Object.defineProperty(config, 'hasOwnProperty', {
2712
+ value: Object.prototype.hasOwnProperty,
2713
+ enumerable: false,
2714
+ writable: true,
2715
+ configurable: true,
2716
+ });
2692
2717
 
2693
2718
  function getMergedValue(target, source, prop, caseless) {
2694
2719
  if (utils$1.isPlainObject(target) && utils$1.isPlainObject(source)) {
@@ -2727,9 +2752,9 @@ function mergeConfig$1(config1, config2) {
2727
2752
 
2728
2753
  // eslint-disable-next-line consistent-return
2729
2754
  function mergeDirectKeys(a, b, prop) {
2730
- if (prop in config2) {
2755
+ if (utils$1.hasOwnProp(config2, prop)) {
2731
2756
  return getMergedValue(a, b);
2732
- } else if (prop in config1) {
2757
+ } else if (utils$1.hasOwnProp(config1, prop)) {
2733
2758
  return getMergedValue(undefined, a);
2734
2759
  }
2735
2760
  }
@@ -2761,6 +2786,7 @@ function mergeConfig$1(config1, config2) {
2761
2786
  httpsAgent: defaultToConfig2,
2762
2787
  cancelToken: defaultToConfig2,
2763
2788
  socketPath: defaultToConfig2,
2789
+ allowedSocketPaths: defaultToConfig2,
2764
2790
  responseEncoding: defaultToConfig2,
2765
2791
  validateStatus: mergeDirectKeys,
2766
2792
  headers: (a, b, prop) =>
@@ -2770,7 +2796,9 @@ function mergeConfig$1(config1, config2) {
2770
2796
  utils$1.forEach(Object.keys({ ...config1, ...config2 }), function computeConfigValue(prop) {
2771
2797
  if (prop === '__proto__' || prop === 'constructor' || prop === 'prototype') return;
2772
2798
  const merge = utils$1.hasOwnProp(mergeMap, prop) ? mergeMap[prop] : mergeDeepProperties;
2773
- const configValue = merge(config1[prop], config2[prop], prop);
2799
+ const a = utils$1.hasOwnProp(config1, prop) ? config1[prop] : undefined;
2800
+ const b = utils$1.hasOwnProp(config2, prop) ? config2[prop] : undefined;
2801
+ const configValue = merge(a, b, prop);
2774
2802
  (utils$1.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);
2775
2803
  });
2776
2804
 
@@ -2780,12 +2808,24 @@ function mergeConfig$1(config1, config2) {
2780
2808
  var resolveConfig = (config) => {
2781
2809
  const newConfig = mergeConfig$1({}, config);
2782
2810
 
2783
- let { data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth } = newConfig;
2811
+ // Read only own properties to prevent prototype pollution gadgets
2812
+ // (e.g. Object.prototype.baseURL = 'https://evil.com'). See GHSA-q8qp-cvcw-x6jj.
2813
+ const own = (key) => (utils$1.hasOwnProp(newConfig, key) ? newConfig[key] : undefined);
2814
+
2815
+ const data = own('data');
2816
+ let withXSRFToken = own('withXSRFToken');
2817
+ const xsrfHeaderName = own('xsrfHeaderName');
2818
+ const xsrfCookieName = own('xsrfCookieName');
2819
+ let headers = own('headers');
2820
+ const auth = own('auth');
2821
+ const baseURL = own('baseURL');
2822
+ const allowAbsoluteUrls = own('allowAbsoluteUrls');
2823
+ const url = own('url');
2784
2824
 
2785
2825
  newConfig.headers = headers = AxiosHeaders$1.from(headers);
2786
2826
 
2787
2827
  newConfig.url = buildURL(
2788
- buildFullPath(newConfig.baseURL, newConfig.url, newConfig.allowAbsoluteUrls),
2828
+ buildFullPath(baseURL, url, allowAbsoluteUrls),
2789
2829
  config.params,
2790
2830
  config.paramsSerializer
2791
2831
  );
@@ -2824,10 +2864,18 @@ var resolveConfig = (config) => {
2824
2864
  // Specifically not if we're in a web worker, or react-native.
2825
2865
 
2826
2866
  if (platform.hasStandardBrowserEnv) {
2827
- withXSRFToken && utils$1.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig));
2867
+ if (utils$1.isFunction(withXSRFToken)) {
2868
+ withXSRFToken = withXSRFToken(newConfig);
2869
+ }
2828
2870
 
2829
- if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(newConfig.url))) {
2830
- // Add xsrf header
2871
+ // Strict boolean check prevents proto-pollution gadgets (e.g. Object.prototype.withXSRFToken = 1)
2872
+ // and misconfigurations (e.g. "false") from short-circuiting the same-origin check and leaking
2873
+ // the XSRF token cross-origin. See GHSA-xx6v-rp6x-q39c.
2874
+ const shouldSendXSRF =
2875
+ withXSRFToken === true ||
2876
+ (withXSRFToken == null && isURLSameOrigin(newConfig.url));
2877
+
2878
+ if (shouldSendXSRF) {
2831
2879
  const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName);
2832
2880
 
2833
2881
  if (xsrfValue) {
@@ -3246,18 +3294,20 @@ const factory = (env) => {
3246
3294
  test(() => {
3247
3295
  let duplexAccessed = false;
3248
3296
 
3249
- const body = new ReadableStream$1();
3250
-
3251
- const hasContentType = new Request(platform.origin, {
3252
- body,
3297
+ const request = new Request(platform.origin, {
3298
+ body: new ReadableStream$1(),
3253
3299
  method: 'POST',
3254
3300
  get duplex() {
3255
3301
  duplexAccessed = true;
3256
3302
  return 'half';
3257
3303
  },
3258
- }).headers.has('Content-Type');
3304
+ });
3259
3305
 
3260
- body.cancel();
3306
+ const hasContentType = request.headers.has('Content-Type');
3307
+
3308
+ if (request.body != null) {
3309
+ request.body.cancel();
3310
+ }
3261
3311
 
3262
3312
  return duplexAccessed && !hasContentType;
3263
3313
  });
@@ -3401,6 +3451,19 @@ const factory = (env) => {
3401
3451
  // see https://github.com/cloudflare/workerd/issues/902
3402
3452
  const isCredentialsSupported = isRequestSupported && 'credentials' in Request.prototype;
3403
3453
 
3454
+ // If data is FormData and Content-Type is multipart/form-data without boundary,
3455
+ // delete it so fetch can set it correctly with the boundary
3456
+ if (utils$1.isFormData(data)) {
3457
+ const contentType = headers.getContentType();
3458
+ if (
3459
+ contentType &&
3460
+ /^multipart\/form-data/i.test(contentType) &&
3461
+ !/boundary=/i.test(contentType)
3462
+ ) {
3463
+ headers.delete('content-type');
3464
+ }
3465
+ }
3466
+
3404
3467
  const resolvedOptions = {
3405
3468
  ...fetchOptions,
3406
3469
  signal: composedSignal,
@@ -3709,7 +3772,7 @@ function dispatchRequest(config) {
3709
3772
  );
3710
3773
  }
3711
3774
 
3712
- const VERSION$1 = "1.15.0";
3775
+ const VERSION$1 = "1.15.2";
3713
3776
 
3714
3777
  const validators$1 = {};
3715
3778
 
@@ -3794,7 +3857,9 @@ function assertOptions(options, schema, allowUnknown) {
3794
3857
  let i = keys.length;
3795
3858
  while (i-- > 0) {
3796
3859
  const opt = keys[i];
3797
- const validator = schema[opt];
3860
+ // Use hasOwnProperty so a polluted Object.prototype.<opt> cannot supply
3861
+ // a non-function validator and cause a TypeError. See GHSA-q8qp-cvcw-x6jj.
3862
+ const validator = Object.prototype.hasOwnProperty.call(schema, opt) ? schema[opt] : undefined;
3798
3863
  if (validator) {
3799
3864
  const value = options[opt];
3800
3865
  const result = value === undefined || validator(value, opt, options);
@@ -4427,26 +4492,6 @@ const urlForNetwork = (network) => {
4427
4492
  return 'http://insight.testnet.networks.dash.org:3001/insight-api';
4428
4493
  }
4429
4494
  };
4430
- /**
4431
- * Fetch address details from the Insight API.
4432
- *
4433
- * @param {InsightAddressParams} p Parameters for fetching address details.
4434
- * @returns {Promise<InsightAddressResponse>} Address details fetched from the Insight API.
4435
- */
4436
- const getAddress = (p) => __awaiter(void 0, void 0, void 0, function* () {
4437
- const data = (yield axios.get(`${urlForNetwork(p.network)}/addr/${p.address}`)).data;
4438
- return data;
4439
- });
4440
- /**
4441
- * Fetch transactions associated with an address from the Insight API.
4442
- *
4443
- * @param {InsightAddressParams} p Parameters for fetching address transactions.
4444
- * @returns {Promise<{ txs: InsightTxResponse[]; pagesTotal: number }>} Transactions associated with the address.
4445
- */
4446
- const getAddressTxs = (p) => __awaiter(void 0, void 0, void 0, function* () {
4447
- const pageNum = (p === null || p === void 0 ? void 0 : p.pageNum) || 0;
4448
- return (yield axios.get(`${urlForNetwork(p.network)}/txs?address=${p.address}&pageNum=${pageNum}`)).data;
4449
- });
4450
4495
  /**
4451
4496
  * Fetch UTXOs associated with an address from the Insight API.
4452
4497
  *
@@ -4456,15 +4501,6 @@ const getAddressTxs = (p) => __awaiter(void 0, void 0, void 0, function* () {
4456
4501
  const getAddressUtxos = (p) => __awaiter(void 0, void 0, void 0, function* () {
4457
4502
  return (yield axios.get(`${urlForNetwork(p.network)}/addr/${p.address}/utxo`)).data;
4458
4503
  });
4459
- /**
4460
- * Fetch transaction details from the Insight API.
4461
- *
4462
- * @param {InsightTransactionParams} p Parameters for fetching transaction details.
4463
- * @returns {Promise<InsightTxResponse>} Transaction details fetched from the Insight API.
4464
- */
4465
- const getTx = (p) => __awaiter(void 0, void 0, void 0, function* () {
4466
- return (yield axios.get(`${urlForNetwork(p.network)}/tx/${p.txid}`)).data;
4467
- });
4468
4504
  /**
4469
4505
  * Fetch raw transaction data from the Insight API.
4470
4506
  *
@@ -4616,7 +4652,7 @@ const defaultDashParams = {
4616
4652
  network: Network.Mainnet,
4617
4653
  phrase: '',
4618
4654
  explorerProviders: explorerProviders,
4619
- dataProviders: [BitgoProviders, BlockcypherDataProviders],
4655
+ dataProviders: [BlockcypherDataProviders, BitgoProviders],
4620
4656
  rootDerivationPaths: {
4621
4657
  [Network.Mainnet]: `m/44'/5'/0'/0/`,
4622
4658
  [Network.Stagenet]: `m/44'/5'/0'/0/`,
@@ -4667,120 +4703,6 @@ class Client extends Client$1 {
4667
4703
  validateAddress(address) {
4668
4704
  return validateAddress(address, this.network);
4669
4705
  }
4670
- /**
4671
- * Asynchronously get the balance for a DASH address.
4672
- * @param {string} address The DASH address.
4673
- * @returns {Promise<Balance[]>} A promise resolving to an array of balances.
4674
- */
4675
- getBalance(address) {
4676
- return __awaiter(this, void 0, void 0, function* () {
4677
- const addressResponse = yield getAddress({ network: this.network, address });
4678
- const confirmed = baseAmount(addressResponse.balanceSat);
4679
- const unconfirmed = baseAmount(addressResponse.unconfirmedBalanceSat);
4680
- return [
4681
- {
4682
- asset: AssetDASH,
4683
- amount: confirmed.plus(unconfirmed),
4684
- },
4685
- ];
4686
- });
4687
- }
4688
- /**
4689
- * Asynchronously retrieves transactions for a given address.
4690
- * @param {TxHistoryParams} params - Parameters for transaction retrieval.
4691
- * @returns {Promise<TxsPage>} A promise resolving to a page of transactions.
4692
- */
4693
- getTransactions(params) {
4694
- return __awaiter(this, void 0, void 0, function* () {
4695
- var _a;
4696
- // Extract offset and limit from parameters or set default values
4697
- const offset = (_a = params === null || params === void 0 ? void 0 : params.offset) !== null && _a !== void 0 ? _a : 0;
4698
- const limit = (params === null || params === void 0 ? void 0 : params.limit) || 10;
4699
- // Insight uses pages rather than offset/limit indexes, so we have to
4700
- // iterate through each page within the offset/limit range.
4701
- const perPage = 10;
4702
- const startPage = Math.floor(offset / perPage);
4703
- const endPage = Math.floor((offset + limit - 1) / perPage);
4704
- const firstPageOffset = offset % perPage;
4705
- const lastPageLimit = (firstPageOffset + (limit - 1)) % perPage;
4706
- let totalPages = -1;
4707
- let lastPageTotal = -1;
4708
- let insightTxs = [];
4709
- // Iterate through each page within the offset/limit range
4710
- for (let pageNum = startPage; pageNum <= endPage; pageNum++) {
4711
- const response = yield getAddressTxs({
4712
- network: this.network,
4713
- address: `${params === null || params === void 0 ? void 0 : params.address}`,
4714
- pageNum,
4715
- });
4716
- let startIndex = 0;
4717
- let endIndex = perPage - 1;
4718
- if (pageNum == startPage) {
4719
- startIndex = firstPageOffset;
4720
- }
4721
- if (pageNum === endPage) {
4722
- endIndex = lastPageLimit;
4723
- }
4724
- insightTxs = [...insightTxs, ...response.txs.slice(startIndex, endIndex + 1)];
4725
- // Insight only returns the number of pages not the total number of
4726
- // transactions. If the last page is within the offset/limit range then we
4727
- // can set the lastPageTotal here and avoid having to send another request,
4728
- // otherwise we can fetch the last page later to determine the total
4729
- // transaction count
4730
- totalPages = response.pagesTotal;
4731
- if (pageNum === totalPages - 1) {
4732
- lastPageTotal = response.txs.length;
4733
- }
4734
- }
4735
- // Map insight transactions to XChain transactions
4736
- const txs = insightTxs.map(this.insightTxToXChainTx);
4737
- // Fetch transactions count for last page if not obtained
4738
- if (lastPageTotal < 0) {
4739
- const lastPageResponse = yield getAddressTxs({
4740
- network: this.network,
4741
- address: `${params === null || params === void 0 ? void 0 : params.address}`,
4742
- pageNum: totalPages - 1,
4743
- });
4744
- lastPageTotal = lastPageResponse.txs.length;
4745
- }
4746
- // Calculate total transactions count and return the page of transactions
4747
- return {
4748
- total: (totalPages - 1) * perPage + lastPageTotal,
4749
- txs,
4750
- };
4751
- });
4752
- }
4753
- /**
4754
- * Asynchronously retrieves transaction data for a given transaction ID.
4755
- * @param {string} txid - The transaction ID.
4756
- * @returns {Promise<Tx>} A promise resolving to the transaction data.
4757
- */
4758
- getTransactionData(txid) {
4759
- return __awaiter(this, void 0, void 0, function* () {
4760
- const tx = yield getTx({ network: this.network, txid });
4761
- return this.insightTxToXChainTx(tx);
4762
- });
4763
- }
4764
- /**
4765
- * Converts an Insight transaction response to XChain transaction.
4766
- * @param {InsightTxResponse} tx - The Insight transaction response.
4767
- * @returns {Tx} The XChain transaction.
4768
- */
4769
- insightTxToXChainTx(tx) {
4770
- return {
4771
- asset: AssetDASH,
4772
- from: tx.vin.map((i) => ({
4773
- from: i.addr,
4774
- amount: assetToBase(assetAmount(i.value)),
4775
- })),
4776
- to: tx.vout
4777
- .filter((i) => i.scriptPubKey.type !== 'nulldata')
4778
- .map((i) => { var _a; return ({ to: (_a = i.scriptPubKey.addresses) === null || _a === void 0 ? void 0 : _a[0], amount: assetToBase(assetAmount(i.value)) }); }),
4779
- date: new Date(tx.time * 1000),
4780
- type: TxType.Transfer,
4781
- hash: tx.txid,
4782
- };
4783
- }
4784
4706
  /**
4785
4707
  * Asynchronously prepares a transaction for sending assets.
4786
4708
  * @deprecated Use `prepareTxEnhanced` instead for better UTXO selection and error handling.
@@ -4850,6 +4772,15 @@ class Client extends Client$1 {
4850
4772
  // Ensure fee meets minimum requirement
4851
4773
  return fee > TX_MIN_FEE ? fee : TX_MIN_FEE;
4852
4774
  }
4775
+ getUtxoScriptHex(utxo) {
4776
+ var _a;
4777
+ // Providers may populate either scriptPubKey (Insight) or witnessUtxo.script (Blockcypher)
4778
+ const scriptHex = utxo.scriptPubKey || ((_a = utxo.witnessUtxo) === null || _a === void 0 ? void 0 : _a.script.toString('hex'));
4779
+ if (!scriptHex) {
4780
+ throw UtxoError.validationError(`UTXO ${utxo.hash}:${utxo.index} is missing scriptPubKey and witnessUtxo.script`);
4781
+ }
4782
+ return scriptHex;
4783
+ }
4853
4784
  // ==================== Enhanced Transaction Methods ====================
4854
4785
  /**
4855
4786
  * Prepare transaction with enhanced UTXO selection.
@@ -4885,7 +4816,7 @@ class Client extends Client$1 {
4885
4816
  const tx = new dashcore.Transaction().to(recipient, targetValue);
4886
4817
  // Add selected inputs
4887
4818
  for (const utxo of selectionResult.inputs) {
4888
- const scriptBuffer = Buffer.from(utxo.scriptPubKey || '', 'hex');
4819
+ const scriptBuffer = Buffer.from(this.getUtxoScriptHex(utxo), 'hex');
4889
4820
  const script = new dashcore.Script(scriptBuffer);
4890
4821
  const input = new dashcore.Transaction.Input.PublicKeyHash({
4891
4822
  prevTxId: Buffer.from(utxo.hash, 'hex'),
@@ -4946,7 +4877,7 @@ class Client extends Client$1 {
4946
4877
  const tx = new dashcore.Transaction().to(recipient, maxCalc.amount);
4947
4878
  // Add inputs
4948
4879
  for (const utxo of maxCalc.inputs) {
4949
- const scriptBuffer = Buffer.from(utxo.scriptPubKey || '', 'hex');
4880
+ const scriptBuffer = Buffer.from(this.getUtxoScriptHex(utxo), 'hex');
4950
4881
  const script = new dashcore.Script(scriptBuffer);
4951
4882
  const input = new dashcore.Transaction.Input.PublicKeyHash({
4952
4883
  prevTxId: Buffer.from(utxo.hash, 'hex'),
@@ -4983,37 +4914,6 @@ class Client extends Client$1 {
4983
4914
  }
4984
4915
  }
4985
4916
 
4986
- /**
4987
- * Function to broadcast a transaction to the Dash network.
4988
- *
4989
- * @param {BroadcastTxParams} params Parameters for broadcasting the transaction.
4990
- * @returns {Promise<TxHash>} Promise that resolves with the transaction hash if successful, or rejects with an error message if unsuccessful.
4991
- */
4992
- const broadcastTx = (params) => __awaiter(void 0, void 0, void 0, function* () {
4993
- const uniqueId = new Date().getTime().toString(); // Generate a unique identifier for the transaction request.
4994
- try {
4995
- const response = (yield axios.post(`${params.nodeUrl}/tx/send`, // URL endpoint for broadcasting the transaction.
4996
- {
4997
- jsonrpc: '2.0',
4998
- rawtx: [params.txHex], // Include the hexadecimal transaction in the request body.
4999
- id: uniqueId,
5000
- }, {
5001
- auth: params.auth, // Include authentication credentials if provided.
5002
- timeout: 30 * 1000, // Set a timeout for the request.
5003
- })).data;
5004
- if (response.error) {
5005
- // If there is an error in the response, reject the promise with the error message.
5006
- return Promise.reject(Error(`failed to broadcast a transaction: ${response.error}`));
5007
- }
5008
- // If no error, return the transaction ID indicating successful broadcast.
5009
- return response.txid;
5010
- }
5011
- catch (ex) {
5012
- // If an exception occurs during the request, reject the promise with the caught error message.
5013
- return Promise.reject(Error(`failed to broadcast a transaction caught: ${String(ex)}`));
5014
- }
5015
- });
5016
-
5017
4917
  const ECPair = ECPairFactory(ecc);
5018
4918
  class ClientKeystore extends Client {
5019
4919
  /**
@@ -5086,13 +4986,16 @@ class ClientKeystore extends Client {
5086
4986
  const tx = new dashcore.Transaction(rawUnsignedTx);
5087
4987
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
5088
4988
  tx.inputs.forEach((input, index) => {
4989
+ var _a;
5089
4990
  const insightUtxo = utxos.find((utxo) => {
5090
4991
  return utxo.hash === input.prevTxId.toString('hex') && utxo.index == input.outputIndex;
5091
4992
  });
5092
4993
  if (!insightUtxo) {
5093
4994
  throw new Error('Unable to match accumulative inputs with insight utxos');
5094
4995
  }
5095
- const scriptBuffer = Buffer.from(insightUtxo.scriptPubKey || '', 'hex');
4996
+ // Providers may populate either scriptPubKey (Insight) or witnessUtxo.script (Blockcypher)
4997
+ const scriptHex = insightUtxo.scriptPubKey || ((_a = insightUtxo.witnessUtxo) === null || _a === void 0 ? void 0 : _a.script.toString('hex')) || '';
4998
+ const scriptBuffer = Buffer.from(scriptHex, 'hex');
5096
4999
  const script = new dashcore.Script(scriptBuffer);
5097
5000
  tx.inputs[index] = new dashcore.Transaction.Input.PublicKeyHash({
5098
5001
  prevTxId: Buffer.from(insightUtxo.hash, 'hex'),
@@ -5107,11 +5010,7 @@ class ClientKeystore extends Client {
5107
5010
  const dashKeys = this.getDashKeys(this.phrase, fromAddressIndex);
5108
5011
  tx.sign(`${(_a = dashKeys.privateKey) === null || _a === void 0 ? void 0 : _a.toString('hex')}`);
5109
5012
  const txHex = tx.checkedSerialize({});
5110
- return yield broadcastTx({
5111
- txHex,
5112
- nodeUrl: this.nodeUrls[this.network],
5113
- auth: this.nodeAuth,
5114
- });
5013
+ return yield this.broadcastTx(txHex);
5115
5014
  });
5116
5015
  }
5117
5016
  /**
@@ -5144,13 +5043,16 @@ class ClientKeystore extends Client {
5144
5043
  const tx = new dashcore.Transaction(rawUnsignedTx);
5145
5044
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
5146
5045
  tx.inputs.forEach((input, index) => {
5046
+ var _a;
5147
5047
  const insightUtxo = utxos.find((utxo) => {
5148
5048
  return utxo.hash === input.prevTxId.toString('hex') && utxo.index == input.outputIndex;
5149
5049
  });
5150
5050
  if (!insightUtxo) {
5151
5051
  throw new Error('Unable to match accumulative inputs with insight utxos');
5152
5052
  }
5153
- const scriptBuffer = Buffer.from(insightUtxo.scriptPubKey || '', 'hex');
5053
+ // Providers may populate either scriptPubKey (Insight) or witnessUtxo.script (Blockcypher)
5054
+ const scriptHex = insightUtxo.scriptPubKey || ((_a = insightUtxo.witnessUtxo) === null || _a === void 0 ? void 0 : _a.script.toString('hex')) || '';
5055
+ const scriptBuffer = Buffer.from(scriptHex, 'hex');
5154
5056
  const script = new dashcore.Script(scriptBuffer);
5155
5057
  tx.inputs[index] = new dashcore.Transaction.Input.PublicKeyHash({
5156
5058
  prevTxId: Buffer.from(insightUtxo.hash, 'hex'),
@@ -5165,11 +5067,7 @@ class ClientKeystore extends Client {
5165
5067
  const dashKeys = this.getDashKeys(this.phrase, fromAddressIndex);
5166
5068
  tx.sign(`${(_a = dashKeys.privateKey) === null || _a === void 0 ? void 0 : _a.toString('hex')}`);
5167
5069
  const txHex = tx.checkedSerialize({});
5168
- const hash = yield broadcastTx({
5169
- txHex,
5170
- nodeUrl: this.nodeUrls[this.network],
5171
- auth: this.nodeAuth,
5172
- });
5070
+ const hash = yield this.broadcastTx(txHex);
5173
5071
  return { hash, maxAmount, fee };
5174
5072
  });
5175
5073
  }
@@ -5252,13 +5150,8 @@ class ClientLedger extends Client {
5252
5150
  useTrustedInputForSegwit: false,
5253
5151
  additionals: [],
5254
5152
  });
5255
- // Broadcast transaction
5256
- const txHash = yield broadcastTx({
5257
- txHex,
5258
- nodeUrl: this.nodeUrls[this.network],
5259
- auth: this.nodeAuth,
5260
- });
5261
- // Throw error if no transaction hash is received
5153
+ // Broadcast transaction via the configured data providers
5154
+ const txHash = yield this.broadcastTx(txHex);
5262
5155
  if (!txHash) {
5263
5156
  throw Error('No Tx hash');
5264
5157
  }
@@ -5306,11 +5199,7 @@ class ClientLedger extends Client {
5306
5199
  useTrustedInputForSegwit: false,
5307
5200
  additionals: [],
5308
5201
  });
5309
- const hash = yield broadcastTx({
5310
- txHex,
5311
- nodeUrl: this.nodeUrls[this.network],
5312
- auth: this.nodeAuth,
5313
- });
5202
+ const hash = yield this.broadcastTx(txHex);
5314
5203
  if (!hash) {
5315
5204
  throw Error('No Tx hash');
5316
5205
  }