postchain-client 2.1.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/built/cjs/index.js +91 -40
  2. package/built/cjs/index.js.map +1 -1
  3. package/built/esm/index.js +90 -42
  4. package/built/esm/index.js.map +1 -1
  5. package/built/index.d.ts +1 -0
  6. package/built/index.js +1 -0
  7. package/built/index.js.map +1 -1
  8. package/built/src/blockchainClient/clientStub.js +2 -0
  9. package/built/src/blockchainClient/clientStub.js.map +1 -1
  10. package/built/src/blockchainClient/failoverStrategies.d.ts +6 -5
  11. package/built/src/blockchainClient/failoverStrategies.js +13 -8
  12. package/built/src/blockchainClient/failoverStrategies.js.map +1 -1
  13. package/built/src/blockchainClient/httpUtil.d.ts +1 -1
  14. package/built/src/blockchainClient/httpUtil.js +45 -21
  15. package/built/src/blockchainClient/httpUtil.js.map +1 -1
  16. package/built/src/blockchainClient/requestWithFailoverStrategy.d.ts +1 -1
  17. package/built/src/blockchainClient/requestWithFailoverStrategy.js +6 -6
  18. package/built/src/blockchainClient/requestWithFailoverStrategy.js.map +1 -1
  19. package/built/src/blockchainClient/types.d.ts +6 -0
  20. package/built/src/blockchainClient/utils.d.ts +6 -2
  21. package/built/src/blockchainClient/utils.js +20 -4
  22. package/built/src/blockchainClient/utils.js.map +1 -1
  23. package/built/test/integration/createClientIntegration.test.js +4 -0
  24. package/built/test/integration/createClientIntegration.test.js.map +1 -1
  25. package/built/test/unit/failoverStrategies.timeout.test.d.ts +1 -0
  26. package/built/test/unit/failoverStrategies.timeout.test.js +228 -0
  27. package/built/test/unit/failoverStrategies.timeout.test.js.map +1 -0
  28. package/built/test/unit/httpUtil.timeout.test.d.ts +1 -0
  29. package/built/test/unit/httpUtil.timeout.test.js +114 -0
  30. package/built/test/unit/httpUtil.timeout.test.js.map +1 -0
  31. package/built/umd/index.js +90 -39
  32. package/built/umd/index.js.map +1 -1
  33. package/changelog.md +27 -5
  34. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var merklehashts = require('merklehashts');
4
3
  var buffer = require('buffer');
4
+ var merklehashts = require('merklehashts');
5
5
  var bn_js = require('bn.js');
6
6
  var zod = require('zod');
7
7
  var crypto = require('crypto');
@@ -1362,13 +1362,22 @@ var __awaiter$8 = (undefined && undefined.__awaiter) || function (thisArg, _argu
1362
1362
  step((generator = generator.apply(thisArg, _arguments || [])).next());
1363
1363
  });
1364
1364
  };
1365
- function handleRequest(method, path, endpoint, postObject) {
1365
+ function createTimeoutController(timeout) {
1366
+ if (!timeout)
1367
+ return { controller: undefined, timeoutId: undefined };
1368
+ const controller = new AbortController();
1369
+ const timeoutError = new Error(`Request timeout after ${timeout}ms`);
1370
+ timeoutError.name = 'TimeoutError';
1371
+ const timeoutId = setTimeout(() => controller.abort(timeoutError), timeout);
1372
+ return { controller, timeoutId };
1373
+ }
1374
+ function handleRequest(method, path, endpoint, timeout, postObject) {
1366
1375
  return __awaiter$8(this, void 0, void 0, function* () {
1367
1376
  if (method == Method.GET) {
1368
- return yield get(path, endpoint);
1377
+ return yield get(path, endpoint, timeout);
1369
1378
  }
1370
1379
  else {
1371
- return yield post(path, endpoint, postObject);
1380
+ return yield post(path, endpoint, timeout, postObject);
1372
1381
  }
1373
1382
  });
1374
1383
  }
@@ -1376,12 +1385,18 @@ function handleRequest(method, path, endpoint, postObject) {
1376
1385
  * Sends request to get data from a given API endpoint.
1377
1386
  * @param path API endpoint of Rell backend
1378
1387
  * @param endpoint
1388
+ * @param timeout
1379
1389
  */
1380
- function get(path, endpoint) {
1390
+ function get(path, endpoint, timeout) {
1381
1391
  return __awaiter$8(this, void 0, void 0, function* () {
1382
1392
  debug(`GET URL ${new URL(path, endpoint).href}`);
1383
1393
  try {
1384
- const response = yield fetch(new URL(path, endpoint).href);
1394
+ const { controller, timeoutId } = createTimeoutController(timeout);
1395
+ const response = yield fetch(new URL(path, endpoint).href, {
1396
+ signal: controller === null || controller === void 0 ? void 0 : controller.signal,
1397
+ });
1398
+ if (timeoutId)
1399
+ clearTimeout(timeoutId);
1385
1400
  const contentType = response.headers.get("Content-Type");
1386
1401
  const transactionTimestamp = response.headers.get("X-Transaction-Timestamp");
1387
1402
  let rspBody = null;
@@ -1403,18 +1418,35 @@ function get(path, endpoint) {
1403
1418
  }
1404
1419
  });
1405
1420
  }
1421
+ function constructBufferResponseBody(response) {
1422
+ return __awaiter$8(this, void 0, void 0, function* () {
1423
+ const contentType = response.headers.get("content-type");
1424
+ if (contentType === "application/octet-stream") {
1425
+ const responseBuffer = yield response.arrayBuffer();
1426
+ const buffer$1 = buffer.Buffer.from(responseBuffer);
1427
+ return decodeValue(buffer$1);
1428
+ }
1429
+ if (contentType === "application/json") {
1430
+ return yield response.json();
1431
+ }
1432
+ const responseText = yield response.text();
1433
+ return responseText ? responseText : response.statusText;
1434
+ });
1435
+ }
1406
1436
  /**
1407
1437
  * Sends request to post data to a given API endpoint.
1408
1438
  * @param path API endpoint of Rell backend
1409
1439
  * @param endpoint
1440
+ * @param timeout
1410
1441
  * @param requestBody request body
1411
1442
  */
1412
- function post(path, endpoint, requestBody) {
1443
+ function post(path, endpoint, timeout, requestBody) {
1413
1444
  return __awaiter$8(this, void 0, void 0, function* () {
1414
1445
  debug(`POST URL ${new URL(path, endpoint).href}`);
1415
1446
  debug(`POST body ${JSON.stringify(requestBody)}`);
1416
1447
  if (buffer.Buffer.isBuffer(requestBody)) {
1417
1448
  try {
1449
+ const { controller, timeoutId } = createTimeoutController(timeout);
1418
1450
  const requestOptions = {
1419
1451
  method: "post",
1420
1452
  body: new Uint8Array(requestBody),
@@ -1422,8 +1454,11 @@ function post(path, endpoint, requestBody) {
1422
1454
  Accept: "application/octet-stream",
1423
1455
  "Content-Type": "application/octet-stream",
1424
1456
  },
1457
+ signal: controller === null || controller === void 0 ? void 0 : controller.signal,
1425
1458
  };
1426
1459
  const response = yield fetch(new URL(path, endpoint).href, requestOptions);
1460
+ if (timeoutId)
1461
+ clearTimeout(timeoutId);
1427
1462
  const transactionTimestamp = response.headers.get("X-Transaction-Timestamp");
1428
1463
  return createResponseObject(null, response.status, yield constructBufferResponseBody(response), transactionTimestamp);
1429
1464
  }
@@ -1433,6 +1468,7 @@ function post(path, endpoint, requestBody) {
1433
1468
  }
1434
1469
  else {
1435
1470
  try {
1471
+ const { controller, timeoutId } = createTimeoutController(timeout);
1436
1472
  const response = yield fetch(new URL(path, endpoint).href, {
1437
1473
  method: "post",
1438
1474
  body: JSON.stringify(requestBody),
@@ -1440,7 +1476,10 @@ function post(path, endpoint, requestBody) {
1440
1476
  Accept: "application/json",
1441
1477
  "Content-Type": "application/json",
1442
1478
  },
1479
+ signal: controller === null || controller === void 0 ? void 0 : controller.signal,
1443
1480
  });
1481
+ if (timeoutId)
1482
+ clearTimeout(timeoutId);
1444
1483
  const transactionTimestamp = response.headers.get("X-Transaction-Timestamp");
1445
1484
  return createResponseObject(null, response.status, yield constructBufferResponseBody(response), transactionTimestamp);
1446
1485
  }
@@ -1450,21 +1489,6 @@ function post(path, endpoint, requestBody) {
1450
1489
  }
1451
1490
  });
1452
1491
  }
1453
- function constructBufferResponseBody(response) {
1454
- return __awaiter$8(this, void 0, void 0, function* () {
1455
- const contentType = response.headers.get("content-type");
1456
- if (contentType === "application/octet-stream") {
1457
- const responseBuffer = yield response.arrayBuffer();
1458
- const buffer$1 = buffer.Buffer.from(responseBuffer);
1459
- return decodeValue(buffer$1);
1460
- }
1461
- if (contentType === "application/json") {
1462
- return yield response.json();
1463
- }
1464
- const responseText = yield response.text();
1465
- return responseText ? responseText : response.statusText;
1466
- });
1467
- }
1468
1492
  function createResponseObject(error, statusCode, rspBody, transactionTimestamp) {
1469
1493
  let finalStatusCode = statusCode;
1470
1494
  // Handle browser network errors as a specific status code for smart timeout logic
@@ -1550,24 +1574,26 @@ function getUnreachableDuration(statusCode, error) {
1550
1574
  }
1551
1575
  }
1552
1576
  function abortOnError(_a) {
1553
- return __awaiter$7(this, arguments, void 0, function* ({ method, path, config, postObject, }) {
1577
+ return __awaiter$7(this, arguments, void 0, function* ({ method, path, config, postObject, timeoutOverride, }) {
1554
1578
  return yield retryRequest({
1555
1579
  method,
1556
1580
  path,
1557
1581
  config,
1558
1582
  postObject,
1583
+ timeoutOverride,
1559
1584
  useNextNodeOnError: false,
1560
1585
  recoveryThreshold: config.recoveryThreshold, // Use user config or let nodeManager use default
1561
1586
  });
1562
1587
  });
1563
1588
  }
1564
1589
  function tryNextOnError(_a) {
1565
- return __awaiter$7(this, arguments, void 0, function* ({ method, path, config, postObject, }) {
1590
+ return __awaiter$7(this, arguments, void 0, function* ({ method, path, config, postObject, timeoutOverride, }) {
1566
1591
  return yield retryRequest({
1567
1592
  method,
1568
1593
  path,
1569
1594
  config,
1570
1595
  postObject,
1596
+ timeoutOverride,
1571
1597
  useNextNodeOnError: true,
1572
1598
  recoveryThreshold: config.recoveryThreshold,
1573
1599
  });
@@ -1580,7 +1606,7 @@ function calculateBftMajorityThreshold(endpointPoolLength) {
1580
1606
  return endpointPoolLength - (endpointPoolLength - 1) / 3;
1581
1607
  }
1582
1608
  function queryMajority(_a) {
1583
- return __awaiter$7(this, arguments, void 0, function* ({ method, path, config, postObject, }) {
1609
+ return __awaiter$7(this, arguments, void 0, function* ({ method, path, config, postObject, timeoutOverride, }) {
1584
1610
  var _b;
1585
1611
  // Set up constants
1586
1612
  const bftMajorityThreshold = calculateBftMajorityThreshold(config.endpointPool.length);
@@ -1591,7 +1617,8 @@ function queryMajority(_a) {
1591
1617
  const outcomes = [];
1592
1618
  const promises = availableNodes.map((node) => __awaiter$7(this, void 0, void 0, function* () {
1593
1619
  try {
1594
- const response = yield handleRequest(method, path, node.url, postObject);
1620
+ const requestTimeout = timeoutOverride !== null && timeoutOverride !== void 0 ? timeoutOverride : config.responseTimeout;
1621
+ const response = yield handleRequest(method, path, node.url, requestTimeout, postObject);
1595
1622
  const { statusCode } = response;
1596
1623
  if (statusCode && isSuccessfulStatusCode(statusCode)) {
1597
1624
  outcomes.push({ type: "SUCCESS", result: response });
@@ -1651,7 +1678,7 @@ function queryMajority(_a) {
1651
1678
  });
1652
1679
  }
1653
1680
  function singleEndpoint(_a) {
1654
- return __awaiter$7(this, arguments, void 0, function* ({ method, path, config, postObject, }) {
1681
+ return __awaiter$7(this, arguments, void 0, function* ({ method, path, config, postObject, timeoutOverride, }) {
1655
1682
  let statusCode = null;
1656
1683
  let rspBody = null;
1657
1684
  let error = null;
@@ -1661,7 +1688,8 @@ function singleEndpoint(_a) {
1661
1688
  throw new Error("No nodes available after recovery attempt. Check node configuration.");
1662
1689
  }
1663
1690
  for (let attempt = 0; attempt < config.attemptsPerEndpoint; attempt++) {
1664
- const response = yield handleRequest(method, path, endpoint.url, postObject);
1691
+ const requestTimeout = timeoutOverride !== null && timeoutOverride !== void 0 ? timeoutOverride : config.responseTimeout;
1692
+ const response = yield handleRequest(method, path, endpoint.url, requestTimeout, postObject);
1665
1693
  if (response) {
1666
1694
  ({ error, statusCode, rspBody, transactionTimestamp } = response);
1667
1695
  }
@@ -1678,7 +1706,7 @@ function singleEndpoint(_a) {
1678
1706
  });
1679
1707
  }
1680
1708
  function retryRequest(_a) {
1681
- return __awaiter$7(this, arguments, void 0, function* ({ method, path, config, postObject, useNextNodeOnError, recoveryThreshold, }) {
1709
+ return __awaiter$7(this, arguments, void 0, function* ({ method, path, config, postObject, useNextNodeOnError, recoveryThreshold, timeoutOverride, }) {
1682
1710
  var _b, _c, _d;
1683
1711
  let statusCode = null;
1684
1712
  let rspBody = null;
@@ -1688,7 +1716,8 @@ function retryRequest(_a) {
1688
1716
  const availableNodes = nodeManager.getAvailableNodes(recoveryThreshold);
1689
1717
  for (const node of availableNodes) {
1690
1718
  for (let attempt = 0; attempt < config.attemptsPerEndpoint; attempt++) {
1691
- const response = yield handleRequest(method, path, node.url, postObject);
1719
+ const requestTimeout = timeoutOverride !== null && timeoutOverride !== void 0 ? timeoutOverride : config.responseTimeout;
1720
+ const response = yield handleRequest(method, path, node.url, requestTimeout, postObject);
1692
1721
  error = (_b = response === null || response === void 0 ? void 0 : response.error) !== null && _b !== void 0 ? _b : null;
1693
1722
  statusCode = (_c = response === null || response === void 0 ? void 0 : response.statusCode) !== null && _c !== void 0 ? _c : null;
1694
1723
  rspBody = (_d = response === null || response === void 0 ? void 0 : response.rspBody) !== null && _d !== void 0 ? _d : null;
@@ -1812,19 +1841,19 @@ var __awaiter$6 = (undefined && undefined.__awaiter) || function (thisArg, _argu
1812
1841
  });
1813
1842
  };
1814
1843
  function requestWithFailoverStrategy(method_1, path_1, config_1, postObject_1) {
1815
- return __awaiter$6(this, arguments, void 0, function* (method, path, config, postObject, forceSingleEndpoint = false) {
1844
+ return __awaiter$6(this, arguments, void 0, function* (method, path, config, postObject, forceSingleEndpoint = false, timeoutOverride) {
1816
1845
  switch (config.failoverStrategy) {
1817
1846
  case exports.FailoverStrategy.AbortOnError:
1818
- return yield abortOnError({ method, path, config, postObject });
1847
+ return yield abortOnError({ method, path, config, postObject, timeoutOverride });
1819
1848
  case exports.FailoverStrategy.TryNextOnError:
1820
- return yield tryNextOnError({ method, path, config, postObject });
1849
+ return yield tryNextOnError({ method, path, config, postObject, timeoutOverride });
1821
1850
  case exports.FailoverStrategy.SingleEndpoint:
1822
- return yield singleEndpoint({ method, path, config, postObject });
1851
+ return yield singleEndpoint({ method, path, config, postObject, timeoutOverride });
1823
1852
  case exports.FailoverStrategy.QueryMajority:
1824
1853
  if (forceSingleEndpoint) {
1825
- return yield singleEndpoint({ method, path, config, postObject });
1854
+ return yield singleEndpoint({ method, path, config, postObject, timeoutOverride });
1826
1855
  }
1827
- return yield queryMajority({ method, path, config, postObject });
1856
+ return yield queryMajority({ method, path, config, postObject, timeoutOverride });
1828
1857
  default:
1829
1858
  throw new Error(`Unsupported failover strategy: ${config.failoverStrategy}`);
1830
1859
  }
@@ -1865,6 +1894,8 @@ function getClientConfigFromSettings(settings) {
1865
1894
  endpointPool,
1866
1895
  chainId: settings.blockchainIid,
1867
1896
  merkleHashVersion: (_a = settings.merkleHashVersion) !== null && _a !== void 0 ? _a : MERKLE_HASH_VERSIONS.UNSET,
1897
+ connectTimeout: settings.connectTimeout,
1898
+ responseTimeout: settings.responseTimeout,
1868
1899
  });
1869
1900
  }
1870
1901
  throw new MissingBlockchainIdentifierError();
@@ -1880,6 +1911,8 @@ function getClientConfigFromSettings(settings) {
1880
1911
  endpointPool,
1881
1912
  chainId: directoryChainIid,
1882
1913
  merkleHashVersion: (_a = settings.merkleHashVersion) !== null && _a !== void 0 ? _a : MERKLE_HASH_VERSIONS.UNSET,
1914
+ connectTimeout: settings.connectTimeout,
1915
+ responseTimeout: settings.responseTimeout,
1883
1916
  });
1884
1917
  }))();
1885
1918
  return {
@@ -1896,13 +1929,16 @@ function getClientConfigFromSettings(settings) {
1896
1929
  attemptInterval: ((_h = settings.failOverConfig) === null || _h === void 0 ? void 0 : _h.attemptInterval) || defaultFailoverConfig.attemptInterval,
1897
1930
  unreachableDuration: ((_j = settings.failOverConfig) === null || _j === void 0 ? void 0 : _j.unreachableDuration) || defaultFailoverConfig.unreachableDuration,
1898
1931
  directoryChainRid: settings.directoryChainRid || directoryChainRid,
1932
+ connectTimeout: settings.connectTimeout,
1933
+ responseTimeout: settings.responseTimeout,
1899
1934
  };
1900
1935
  });
1901
1936
  }
1902
1937
  function getMerkleHashVersionFromDapp(config) {
1903
1938
  return __awaiter$5(this, void 0, void 0, function* () {
1939
+ var _a;
1904
1940
  try {
1905
- const response = yield requestWithFailoverStrategy(Method.GET, `/config/${config.blockchainRid}/features`, config);
1941
+ const response = yield requestWithFailoverStrategy(Method.GET, `/config/${config.blockchainRid}/features`, config, undefined, false, (_a = config.connectTimeout) !== null && _a !== void 0 ? _a : config.responseTimeout);
1906
1942
  const validatedResponse = validateMerkleHash(response.rspBody);
1907
1943
  return validatedResponse.merkle_hash_version;
1908
1944
  }
@@ -1913,7 +1949,7 @@ function getMerkleHashVersionFromDapp(config) {
1913
1949
  });
1914
1950
  }
1915
1951
  function nodeDiscovery(_a) {
1916
- return __awaiter$5(this, arguments, void 0, function* ({ nodeManager, directoryEndpointPool, failOverConfig, blockchainRid, blockchainIid, }) {
1952
+ return __awaiter$5(this, arguments, void 0, function* ({ nodeManager, directoryEndpointPool, failOverConfig, blockchainRid, blockchainIid, connectTimeout, responseTimeout, }) {
1917
1953
  if (directoryEndpointPool.length === 0) {
1918
1954
  throw new DirectoryNodeUrlPoolException();
1919
1955
  }
@@ -1926,6 +1962,8 @@ function nodeDiscovery(_a) {
1926
1962
  endpointPool: directoryEndpointPool,
1927
1963
  chainId: directoryIid,
1928
1964
  failOverConfig,
1965
+ connectTimeout,
1966
+ responseTimeout,
1929
1967
  });
1930
1968
  const blockchainRidToUse = yield (() => __awaiter$5(this, void 0, void 0, function* () {
1931
1969
  if (blockchainRid) {
@@ -1937,6 +1975,8 @@ function nodeDiscovery(_a) {
1937
1975
  endpointPool: directoryEndpointPool,
1938
1976
  chainId: blockchainIid,
1939
1977
  failOverConfig,
1978
+ connectTimeout,
1979
+ responseTimeout,
1940
1980
  });
1941
1981
  }
1942
1982
  throw new MissingBlockchainIdentifierError();
@@ -2094,6 +2134,8 @@ function getNodeUrlsFromSettings(settings) {
2094
2134
  failOverConfig: settings.failOverConfig,
2095
2135
  blockchainRid: settings.blockchainRid,
2096
2136
  blockchainIid: settings.blockchainIid,
2137
+ connectTimeout: settings.connectTimeout,
2138
+ responseTimeout: settings.responseTimeout,
2097
2139
  });
2098
2140
  return discoveredNodes;
2099
2141
  }
@@ -2353,7 +2395,8 @@ function handlePostResponse(error$1, statusCode, responseObject, callback) {
2353
2395
  }
2354
2396
  }
2355
2397
  function getBlockchainRidFromIid(_a) {
2356
- return __awaiter$5(this, arguments, void 0, function* ({ endpointPool, chainId, failOverConfig = {}, nodeManager, }) {
2398
+ return __awaiter$5(this, arguments, void 0, function* ({ endpointPool, chainId, failOverConfig = {}, nodeManager, connectTimeout, responseTimeout, }) {
2399
+ var _b;
2357
2400
  const mergedFailOverConfig = Object.assign(Object.assign({}, defaultFailoverConfig), failOverConfig);
2358
2401
  const config = {
2359
2402
  endpointPool,
@@ -2367,8 +2410,10 @@ function getBlockchainRidFromIid(_a) {
2367
2410
  attemptInterval: mergedFailOverConfig.attemptInterval,
2368
2411
  unreachableDuration: mergedFailOverConfig.unreachableDuration,
2369
2412
  merkleHashVersion: MERKLE_HASH_VERSIONS.UNSET,
2413
+ connectTimeout,
2414
+ responseTimeout,
2370
2415
  };
2371
- const { error, statusCode, rspBody } = yield requestWithFailoverStrategy(Method.GET, `/brid/iid_${chainId}`, config);
2416
+ const { error, statusCode, rspBody } = yield requestWithFailoverStrategy(Method.GET, `/brid/iid_${chainId}`, config, undefined, false, (_b = config.connectTimeout) !== null && _b !== void 0 ? _b : config.responseTimeout);
2372
2417
  const blockchainRid = isString(rspBody);
2373
2418
  if (!blockchainRid) {
2374
2419
  throw error;
@@ -3585,6 +3630,8 @@ function createStubClient() {
3585
3630
  attemptInterval: 5000,
3586
3631
  unreachableDuration: 30000,
3587
3632
  directoryChainRid: "1111111111111111111111111111111111111111111111111111111111111111",
3633
+ connectTimeout: 1000,
3634
+ responseTimeout: 1000,
3588
3635
  },
3589
3636
  query() {
3590
3637
  return __awaiter(this, void 0, void 0, function* () {
@@ -3750,6 +3797,10 @@ function decodeTransactionToGtx(encodedTransaction) {
3750
3797
  return gtx$1;
3751
3798
  }
3752
3799
 
3800
+ Object.defineProperty(exports, 'Buffer', {
3801
+ enumerable: true,
3802
+ get: function () { return buffer.Buffer; }
3803
+ });
3753
3804
  exports.AlreadySignedTransactionException = AlreadySignedTransactionException;
3754
3805
  exports.BlockAnchoringException = BlockAnchoringException;
3755
3806
  exports.BlockchainUrlUndefinedException = BlockchainUrlUndefinedException;